diff options
| author | 2026-01-01 11:50:48 +0330 | |
|---|---|---|
| committer | 2026-01-01 11:50:48 +0330 | |
| commit | 0cee860019a7475c46eeb68271ef62beccff4fc7 (patch) | |
| tree | 0625f4395736b0a2ba1bbbd5093ffb280c9dcd98 | |
| parent | update log update (diff) | |
sw+firstpaint+smooth+nostyles3
| -rw-r--r-- | index.html | 23 | ||||
| -rw-r--r-- | serviceWorker.js | 61 | ||||
| -rw-r--r-- | styles.css | 56 | ||||
| -rw-r--r-- | styles3.css | 258 | ||||
| -rw-r--r-- | tempo.md | 9 |
5 files changed, 98 insertions, 309 deletions
@@ -2,7 +2,7 @@ <html lang='en'> <head> - <style> + <style id="noFlashbang"> body { background: #000; color: #fff; @@ -13,7 +13,7 @@ <title>tempo</title> <link rel="prefetch" href="/tempo.md" as="fetch"> <link rel="prefetch" href="/symbols.txt" as="fetch"> - <link rel="stylesheet" href="styles3.css"> + <link rel="stylesheet" href="styles.css"> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="shortcut icon" href="bell.png"> </head> @@ -50,6 +50,12 @@ localStorage.setItem('theme', 'light') } }) + + window.addEventListener('load', () => { + noFlashbang.innerHTML += `*, body, html { + transition: 0.25s color, 0.25s background-color, 0.25s border; + }` + }) </script> <noscript> @@ -65,6 +71,7 @@ <div id='warnings'></div> <div id='content'> rendering content... + <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> </div> <div> tempo is licensed under creative-commons. @@ -84,8 +91,15 @@ if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/serviceWorker.js') - .then(reg => console.log('Service Worker registered')) - .catch(err => console.log('SW registration failed', err)) + .then(reg => console.log('sw registered')) + .catch(err => console.log('sw register failed', err)) + + navigator.serviceWorker.addEventListener('message', e => { + if (e.data && e.data.type === 'REFRESH') { + console.log(`updated content found for ${e.data.url}`) + window.location.reload() + } + }) }) } else { console.log('[warn] no service worker support') @@ -113,6 +127,7 @@ if (i % 2 === 0) { let chunk = escapeHTML(parts[i]) chunk = chunk.replace(/\*\*(.*?)\*\*/g, '<b>$1</b>') + chunk = chunk.replace(/\~\~(.*?)\~\~/g, '<s>$1</s>') chunk = chunk.replace(/__(.*?)__/g, '<u>$1</u>') chunk = chunk.replace(/\*(.*?)\*/g, '<i>$1</i>') chunk = chunk.replace(/\[\[(.*?)\]\]/g, '<span style="user-select:none">🔎 </span><b>"$1"</b>') diff --git a/serviceWorker.js b/serviceWorker.js index ba9ca7a..ce8ed7e 100644 --- a/serviceWorker.js +++ b/serviceWorker.js @@ -23,30 +23,59 @@ self.addEventListener('activate', e => { e.waitUntil(self.clients.claim()) }) +const checkChange = (r1, r2) => { + const h1 = r1.headers + const h2 = r2.headers + if (h1.get('etag') && h2.get('etag')) return h1.get('etag') !== h2.get('etag') + if (h1.get('last-modified') && h2.get('last-modified')) return h1.get('last-modified') !== h2.get('last-modified') + return h1.get('content-length') !== h2.get('content-length') +} + self.addEventListener('fetch', e => { const url = new URL(e.request.url) const isTarget = ASSETS.includes(url.pathname) || url.pathname.startsWith('/fonts/') if (!isTarget) return - e.respondWith( - caches.open(CACHE_NAME).then(async cache => { - const cachedResponse = await cache.match(e.request) + e.respondWith((async () => { + const cache = await caches.open(CACHE_NAME) + const cachedResponse = await cache.match(e.request) + + const networkFetch = fetch(e.request, { cache: 'no-cache' }).then(async networkResponse => { + if (!networkResponse.ok) return networkResponse + + const freshCopy = networkResponse.clone() + let changed = false - if (cachedResponse) console.log(`cache ${url.pathname}`) - else console.log(`fetch ${url.pathname}`) + if (cachedResponse) { + changed = checkChange(cachedResponse, networkResponse) + } else { + console.log(`fetch ${url.pathname}`) + } - const networkFetch = fetch(e.request).then(networkResponse => { - if (networkResponse.ok) { - console.log(`updating ${url.pathname}`) - cache.put(e.request, networkResponse.clone()) - } - return networkResponse - }).catch(err => { - console.error(`failed ${url.pathname}:`, err) - }) + await cache.put(e.request, freshCopy) - return cachedResponse || networkFetch + if (changed) { + console.log(`content changed, signaling refresh: ${url.pathname}`) + const clients = await self.clients.matchAll() + clients.forEach(client => { + client.postMessage({ + type: 'REFRESH', + url: url.pathname + }) + }) + } + return networkResponse + }).catch(err => { + console.error(`failed ${url.pathname}:`, err) }) - ) + + if (cachedResponse) { + console.log(`cache ${url.pathname}`) + e.waitUntil(networkFetch) + return cachedResponse + } + + return networkFetch + })()) })
\ No newline at end of file @@ -1,29 +1,29 @@ @font-face { - font-family: 'Charter'; - src: url('fonts/Charter/Charter Regular.ttf') format('truetype'); - font-weight: normal; - font-style: normal; + font-family: 'Charter'; + src: url('fonts/Charter/Charter Regular.ttf') format('truetype'); + font-weight: normal; + font-style: normal; } @font-face { - font-family: 'Charter'; - src: url('fonts/Charter/Charter Italic.ttf') format('truetype'); - font-weight: normal; - font-style: italic; + font-family: 'Charter'; + src: url('fonts/Charter/Charter Italic.ttf') format('truetype'); + font-weight: normal; + font-style: italic; } @font-face { - font-family: 'Charter'; - src: url('fonts/Charter/Charter Bold.ttf') format('truetype'); - font-weight: bold; - font-style: normal; + font-family: 'Charter'; + src: url('fonts/Charter/Charter Bold.ttf') format('truetype'); + font-weight: bold; + font-style: normal; } @font-face { - font-family: 'Charter'; - src: url('fonts/Charter/Charter Bold Italic.ttf') format('truetype'); - font-weight: bold; - font-style: italic; + font-family: 'Charter'; + src: url('fonts/Charter/Charter Bold Italic.ttf') format('truetype'); + font-weight: bold; + font-style: italic; } @font-face { @@ -81,18 +81,18 @@ body.dark-mode { top: 20px; right: 20px; padding: 8px 16px; - background: var(--code-bg); + background-color: var(--code-bg); border: 1px solid var(--border); cursor: pointer; font-family: 'Roboto Mono', monospace; font-size: 0.85rem; border-radius: 4px; z-index: 1000; - transition: 0.5s background; + transition: 0.5s background-color; } #themeToggle:hover { - background: var(--code-bg-faint); + background-color: var(--code-bg-faint); } a { @@ -113,7 +113,7 @@ body { max-width: 720px; margin: 40px auto; padding: 0 20px; - background: var(--bg); + background-color: var(--bg); } h1 { @@ -133,7 +133,7 @@ h2 { code { font-family: "Roboto Mono", "Charter", serif; - background: var(--code-bg); + background-color: var(--code-bg); padding: 0px 8px; /* border-radius: 3px; */ font-size: 0.95em; @@ -143,7 +143,7 @@ code { } pre { - background: var(--code-bg); + background-color: var(--code-bg); padding: 1.5rem; border-left: 3px solid var(--accent); overflow-x: auto; @@ -154,7 +154,7 @@ pre { } pre code { - background: transparent; + background-color: transparent; padding: 0; border: none; font-size: 0.9rem; @@ -175,7 +175,7 @@ block { display: block; margin-bottom: 1.5rem; padding: 1rem; - background: var(--block-bg); + background-color: var(--block-bg); border: 1px solid var(--border); } @@ -195,7 +195,7 @@ header { header span.def-name { color: var(--def-name); - background: var(--eng-bg); + background-color: var(--eng-bg); padding: 0px 8px; border: 1px solid var(--border); font-size: 0.95em; @@ -207,7 +207,7 @@ header span.def-name { .eng-text { font-weight: normal; color: var(--eng-text); - background: var(--eng-bg); + background-color: var(--eng-bg); padding: 0px 8px; border: 1px solid var(--border); font-size: 0.95em; @@ -228,7 +228,7 @@ desc { align-items: center; gap: 8px; padding: 6px 12px; - background: var(--code-bg); + background-color: var(--code-bg); border: 2.3px dashed #ff6600; border-radius: 20px; font-family: "Roboto Mono", monospace; @@ -252,7 +252,7 @@ body.dark-mode .timestamp-badge { bottom: 20px; left: 20px; color: red; - background: var(--code-bg); + background-color: var(--code-bg); border: 2px solid var(--code-bg-faint); padding: 5px 10px; }
\ No newline at end of file diff --git a/styles3.css b/styles3.css deleted file mode 100644 index c150343..0000000 --- a/styles3.css +++ /dev/null @@ -1,258 +0,0 @@ -@font-face { - font-family: 'Charter'; - src: url('fonts/Charter/Charter Regular.ttf') format('truetype'); - font-weight: normal; - font-style: normal; -} - -@font-face { - font-family: 'Charter'; - src: url('fonts/Charter/Charter Italic.ttf') format('truetype'); - font-weight: normal; - font-style: italic; -} - -@font-face { - font-family: 'Charter'; - src: url('fonts/Charter/Charter Bold.ttf') format('truetype'); - font-weight: bold; - font-style: normal; -} - -@font-face { - font-family: 'Charter'; - src: url('fonts/Charter/Charter Bold Italic.ttf') format('truetype'); - font-weight: bold; - font-style: italic; -} - -@font-face { - font-family: "Roboto Mono"; - src: url("fonts/Roboto/RobotoMono-VariableFont_wght.ttf") format("truetype"); - font-weight: 100 900; - font-style: normal; -} - -@font-face { - font-family: "Roboto Mono"; - src: url("fonts/Roboto/RobotoMono-Italic-VariableFont_wght.ttf") format("truetype"); - font-weight: 100 900; - font-style: italic; -} - -:root { - --bg: #ffffff; - --text: #000000; - --accent: #000000; - --code-bg: #fafafa; - --code-bg-faint: #f4f4f4; - --border: #d0d0d0; - --def-name: #ff6600; - --link: #00aaee; - --link-hover: #0088ff; - --quote-text: #333; - --desc-text: #222; - --badge-text: #444; - --eng-text: #666; - --eng-bg: #fdfdfd; - --block-bg: #ffffff; -} - -body.dark-mode { - --bg: #050505; - --text: #e0e0e0; - --accent: #ffffff; - --code-bg: #101010; - --code-bg-faint: #2a2a2a; - --border: #404040; - --def-name: #ff5f33; - --link: #33bbff; - --link-hover: #55ccff; - --quote-text: #b0b0b0; - --desc-text: #d0d0d0; - --badge-text: #cfcfcf; - --eng-text: #999; - --eng-bg: #111; - --block-bg: #1f1f1f; -} - -#themeToggle { - position: fixed; - top: 20px; - right: 20px; - padding: 8px 16px; - background: var(--code-bg); - border: 1px solid var(--border); - cursor: pointer; - font-family: 'Roboto Mono', monospace; - font-size: 0.85rem; - border-radius: 4px; - z-index: 1000; - transition: 0.5s background; -} - -#themeToggle:hover { - background: var(--code-bg-faint); -} - -a { - /* text-decoration: none; */ - color: var(--link); - transition: 0.5s color; -} - -a:hover { - color: var(--link-hover); -} - -body { - font-family: "Charter", "Bitstream Charter", "Sitka Text", Georgia, serif; - font-weight: 400; - line-height: 1.6; - color: var(--text); - max-width: 720px; - margin: 40px auto; - padding: 0 20px; - background: var(--bg); -} - -h1 { - font-size: 2.2rem; - font-weight: 700; - text-align: center; - margin-bottom: 0.5rem; - letter-spacing: -0.02em; -} - -h2 { - font-variant: small-caps; - border-bottom: 2px solid #ff5b5b; - margin-top: 2rem; - letter-spacing: 0.05em; -} - -code { - font-family: "Roboto Mono", "Charter", serif; - background: var(--code-bg); - padding: 0px 8px; - /* border-radius: 3px; */ - font-size: 0.95em; - border: 1px solid var(--border); - font-weight: 450 !important; - margin: 0 2px; -} - -pre { - background: var(--code-bg); - padding: 1.5rem; - border-left: 3px solid var(--accent); - overflow-x: auto; - /* border-radius: 0 4px 4px 0; */ - white-space: pre; - border: 1px solid var(--border); - border-left-width: 3px; -} - -pre code { - background: transparent; - padding: 0; - border: none; - font-size: 0.9rem; -} - -pre * { - font-family: "Roboto Mono", monospace !important; -} - -blockquote { - margin: 1rem 0; - padding-left: 1.5rem; - border-left: 2px solid var(--border); - color: var(--quote-text); -} - -block { - display: block; - margin-bottom: 1.5rem; - padding: 1rem; - background: var(--block-bg); - border: 1px solid var(--border); -} - -header { - display: flex; - justify-content: space-between; - align-items: baseline; - font-weight: bold; - font-family: "Charter", serif; -} - -.header-left { - display: flex; - align-items: baseline; - gap: 8px; -} - -header span.def-name { - color: var(--def-name); - background: var(--eng-bg); - padding: 0px 8px; - border: 1px solid var(--border); - font-size: 0.95em; - /* border-radius: 2px; */ - font-weight: normal; - font-family: 'Roboto Mono'; -} - -.eng-text { - font-weight: normal; - color: var(--eng-text); - background: var(--eng-bg); - padding: 0px 8px; - border: 1px solid var(--border); - font-size: 0.95em; -} - -desc { - display: block; - margin-top: 0.5rem; - font-size: 0.95rem; - color: var(--desc-text); - padding-left: 32px; -} - -.timestamp-badge { - /* margin-top: -10px !important; */ - margin-bottom: -10px !important; - display: inline-flex; - align-items: center; - gap: 8px; - padding: 6px 12px; - background: var(--code-bg); - border: 2.3px dashed #ff6600; - border-radius: 20px; - font-family: "Roboto Mono", monospace; - font-size: 0.85rem; - color: var(--badge-text); - margin: 1rem 0; - user-select: none; -} - -.timestamp-badge .clock { - filter: grayscale(100%); -} - -body.dark-mode .timestamp-badge { - border-color: #ff8833; -} - -#warnings { - display: block; - position: fixed; - bottom: 20px; - left: 20px; - color: red; - background: var(--code-bg); - border: 2px solid var(--code-bg-faint); - padding: 5px 10px; -}
\ No newline at end of file @@ -29,7 +29,7 @@ in tempo, everything is interpreted as left-to-right. an axiom can have 0 to an arbitrary number of inputs, which indicates that the axiom is basically a catch-all. arguments are taken in the format of `[arg1 arg2 arg3 ...]` in the definition. the usage section of an axiom describes how arguments are taken in. -the complex axiom assertion bears a cognitive load: it allows assigning names to the time slice of an axiom. for example: `A = .` returns a random (or non-random) object in the enclosing set of the context. +the composite axiom assertion bears a cognitive load: it allows assigning names to the time slice of an axiom. for example: `A = .` returns a random (or non-random) object in the enclosing set of the context. in our world, this could be an atom, an apple, an idea, a time, a memory, a sound, anything. it also serves as a filter, in which `A=. A=.\prop\\me\apple` would filter the first statement, `A=.`, such that A is a property of an apple (since tempo doesn't define apples yet, we contractually import it from our own language as `\me\apple`). @@ -243,9 +243,10 @@ def \matter\ `A=. A\neq\0 \static\\id\A A\almost\\energy\` - more coming soon. // Timestamp: 2026-01-01 10:36:31 UTC+3:30 -- added a git hook such that pushing the repository automatically updates the website as well. +- added a smooth css transition for theme changing. +- added a service worker with a serve-cache-then-update strategy. ~~this means you might need two refreshes of the website for new content~~ (the website auto-reloads on new content), but it's worth it. - added first-paint rendering so that you get the content as fast as possible, without having to wait for a full markdown render. -- added a service worker with a serve-cache-then-update strategy. this means you might need two refreshes of the website for new content, but it's worth it. +- added a git hook such that pushing the repository automatically updates the website as well. // Timestamp: 2025-12-30 22:19:43 UTC+3:30 - added a few new axioms. moved old ones around. @@ -286,4 +287,6 @@ thank you for reading. this website is configured in a way such that web scrapers will be able to archive all of its contents, including the <a href="tempo.md">tempo.md</a> file. a copy of tempo can be found on the wayback machine. +this website has a git repository on <a href="https://git.coffin.ir/moon/tempo">my git mirror</a>. + email: moon@coffin.ir
\ No newline at end of file |
