From 5ea7101499fcf617b13ca8acb20852c748396549 Mon Sep 17 00:00:00 2001 From: "planetrenox@protonmail.com" Date: Mon, 19 Oct 2026 21:21:14 +0000 Subject: [PATCH] Drop duplicated info, clarify sun marker and epoch - Remove PRT day/week cards (same as days/weeks unit cards); weeks card gets the 7-day pips and day x/7 - Merge Elapsed into Epoch card, shown in local time with local weekday - Drop declination (same as subsolar latitude) and converter weekday row - Label the subsolar dot 'sun overhead' - Converter defaults to the Unix epoch instead of now Co-Authored-By: Claude Opus 5.5 --- app.js | 45 ++++++++++++++++++--------------------------- index.html | 15 ++++++--------- style.css | 7 +++++-- 3 files changed, 29 insertions(+), 38 deletions(-) diff --git a/app.js b/app.js index 70663cc..ad7fb82 100644 --- a/app.js +++ b/app.js @@ -14,7 +14,7 @@ const dur = t => { return (d ? d + 'd ' : '') + [floor(s / 3600) % 24, floor(s / 60) % 60, s % 60].map(pad).join(':') } const SHORT = { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' } -const LONG = { ...SHORT, second: '2-digit', timeZoneName: 'short' } +const LONG = { weekday: 'short', ...SHORT, second: '2-digit', timeZoneName: 'short' } const loc = (t, o = SHORT) => new Date(t).toLocaleString(undefined, o) const iso = t => new Date(t).toISOString().replace('T', ' ').slice(0, 19) + ' UTC' const set = (id, h) => { const e = $(id); e.innerHTML != h && (e.innerHTML = h) } @@ -95,6 +95,7 @@ const draw = () => { } B.forEach((p, i) => (cx.fillStyle = COL[i], cx.fill(p))) sunEl.style.left = sx / W * 100 + '%', sunEl.style.top = sy / H * 100 + '%' + sunEl.classList.toggle('r', sx / W > .85) } cv.addEventListener('pointermove', e => { @@ -112,7 +113,7 @@ setInterval(draw, 5e3) // Unit cards const KS = Object.keys(UNITS).slice(1) -$('units').innerHTML = KS.map(u => ``).join('') +$('units').innerHTML = KS.map(u => ``).join('') const last = {} const toast = m => { const t = $('toast'); t.textContent = m, t.hidden = false, clearTimeout(toast.t), toast.t = setTimeout(() => t.hidden = true, 1400) } const copy = v => navigator.clipboard?.writeText(String(v)).then(() => toast('Copied ' + nf.format(v))) @@ -124,9 +125,8 @@ $('ms').addEventListener('click', () => copy(PRT.now())) $('npm').addEventListener('click', () => navigator.clipboard?.writeText('npm i ortus').then(() => toast('Copied npm i ortus'))) // Static bits -$('ep').textContent = `A Saturday · ${loc(E, LONG)} local` -$('pips').innerHTML = ''.repeat(7) -const pips = [...$('pips').children] +$('ep').textContent = loc(E, { weekday: 'short', ...SHORT, timeZoneName: 'short' }) +const pips = [...document.querySelectorAll('.pips i')] // Milestones: next round number per unit (2 significant digits), plus the trillion const miles = now => { @@ -152,22 +152,12 @@ const age = now => { } const slow = now => { - set('utc', iso(now)) - set('loc', loc(now, LONG)) - set('age', age(now)) - set('unix', `Unix ${num(floor(now / 1e3))} s · epoch ${num(E)} ms`) - const d = PRT.fromUnixMs(now, 'd'), d0 = PRT.toUnixMs(d, 'd'), d1 = PRT.toUnixMs(d + 1, 'd') - set('day', `#${num(d)}`) - $('dayb').style.transform = `scaleX(${(now - d0) / (d1 - d0)})` - set('daym', `began ${loc(d0, { hour: '2-digit', minute: '2-digit' })} · ends in ${dur(d1 - now)}`) - const w = PRT.fromUnixMs(now, 'w'), wd = ((d % 7) + 7) % 7 - set('wk', `#${num(w)} · day ${wd + 1}/7`) - set('wkm', `Weeks start Saturday 03:00 UTC · next in ${dur(PRT.toUnixMs(w + 1, 'w') - now)}`) - pips.forEach((p, i) => p.className = i < wd ? 'on' : i == wd ? 'cur' : '') - const s = sun(now) + set('loc', loc(now, { ...LONG, weekday: undefined })) + set('utc', `${iso(now)} · Unix ${num(floor(now / 1e3))} s`) + set('age', `${age(now)} ago · Unix ${num(E)} ms`) + const s = sun(now), [sn, st] = season(now) set('ss', `${ll(s.dec / D, 'N', 'S')} ${ll(s.lon / D, 'E', 'W')}`) - const [sn, st] = season(now) - set('ssm', `Subsolar point · declination ${(s.dec / D).toFixed(2)}°
${sn} ≈ ${loc(st)} · in ${dur(st - now)}`) + set('ssm', `${sn} in ${dur(st - now)}
≈ ${loc(st)}`) set('miles', miles(now).map(([t, l]) => `
  • ${l.join(' = ')}${loc(t)}in ${dur(t - now)}
  • `).join('')) } @@ -180,7 +170,9 @@ const tick = () => { for (const u of KS) { const v = PRT.fromUnixMs(now, u), a = PRT.toUnixMs(v, u), b = PRT.toUnixMs(v + 1, u) last[u] != v && ($('v' + u).innerHTML = num(last[u] = v)) - $('b' + u).style.transform = `scaleX(${(now - a) / (b - a)})` + const wd = floor((now - a) / 864e5) + u == 'w' ? (pips.forEach((p, i, c) => (c = i < wd ? 'on' : i == wd ? 'cur' : '', p.className != c && (p.className = c))), set('wd', `day ${wd + 1}/7`)) + : $('b' + u).style.transform = `scaleX(${(now - a) / (b - a)})` set('n' + u, u == 's' ? `next in ${((b - now) / 1e3).toFixed(1)}s` : `next in ${dur(b - now)}`) } floor(now / 1e3) != sec && slow(now, sec = floor(now / 1e3)) @@ -204,12 +196,11 @@ const conv = () => { const pconv = () => { try { const n = Number($('pin').value.replace(/[\s,_]/g, '')), t = PRT.toUnixMs(n, $('pu').value) - $('pout').innerHTML = dl([['UTC', iso(t)], ['local', loc(t, LONG)], ['day', new Date(t).toLocaleDateString(undefined, { weekday: 'long' })], ['unix', num(t) + ' ms']]) + $('pout').innerHTML = dl([['UTC', iso(t)], ['local', loc(t, LONG)], ['unix', num(t) + ' ms']]) } catch (e) { $('pout').innerHTML = err(e) } } -const fill = () => $('cin').value = $('cz').checked ? new Date().toISOString().slice(0, 23) : toLocalInput(Date.now()) -$('cnow').onclick = () => (fill(), conv()) -$('cz').onchange = () => (fill(), conv()) -$('cin').oninput = conv +$('cnow').onclick = () => ($('cin').value = $('cz').checked ? new Date().toISOString().slice(0, 23) : toLocalInput(Date.now()), conv()) +$('cin').value = '1970-01-01T00:00:00.000' // Unix epoch, shows PRT going negative +$('cin').oninput = $('cz').onchange = conv $('pin').oninput = $('pu').onchange = pconv -fill(), conv(), pconv() +conv(), pconv() diff --git a/index.html b/index.html index 2bd1079..7da2437 100644 --- a/index.html +++ b/index.html @@ -31,7 +31,7 @@

    Milliseconds since 1998-03-14 03:00:00 UTC

    -
    +
    sun overhead
    @@ -43,18 +43,15 @@
    -

    Epoch

    1998-03-14 03:00:00 UTC

    -

    Now

    –

    -

    Elapsed

    –

    -

    PRT day

    –

    -

    PRT week

    –

    -

    Sun

    –

    +

    Now

    –

    +

    Epoch, your time

    –

    +

    Sun overhead

    –

    Upcoming milestones

      Convert

      - +
      @@ -69,7 +66,7 @@
      -

      Integers, floored toward −∞ · negative before the epoch · 1 d = 86,400,000 ms · 1 w = 7 d · leap seconds ignored

      +

      Integers, floored toward −∞ · negative before the epoch · days start 03:00 UTC, weeks on Saturdays · 1 d = 86,400,000 ms · leap seconds ignored

      diff --git a/style.css b/style.css index 4167994..5ec131e 100644 --- a/style.css +++ b/style.css @@ -37,6 +37,8 @@ h1 { font-weight: 500; font-size: clamp(28px, 4.4vw, 48px); letter-spacing: -.02 } #map { display: block; width: 100%; aspect-ratio: 360 / 142; cursor: crosshair; touch-action: pan-y } #sun { position: absolute; width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%; background: #fff; box-shadow: 0 0 10px 3px #bfe8ff, 0 0 40px 12px rgba(80, 170, 255, .55); pointer-events: none } +#sun span { position: absolute; left: 18px; top: 50%; transform: translateY(-50%); font: 500 10px var(--mono); letter-spacing: .12em; text-transform: uppercase; color: #bfe3ff; white-space: nowrap; text-shadow: 0 0 8px #030815 } +#sun.r span { left: auto; right: 18px } #sun::after { content: ''; position: absolute; inset: -5px; border-radius: 50%; border: 1px solid rgba(180, 225, 255, .8); animation: ping 2.6s ease-out infinite } @keyframes ping { to { inset: -26px; opacity: 0 } } #tip { position: absolute; transform: translate(14px, -50%); padding: 7px 10px; border-radius: 8px; background: rgba(6, 16, 42, .88); border: 1px solid var(--line); backdrop-filter: blur(8px); font: 12px/1.45 var(--mono); color: var(--mute); white-space: nowrap; pointer-events: none } @@ -56,6 +58,7 @@ h1 { font-weight: 500; font-size: clamp(28px, 4.4vw, 48px); letter-spacing: -.02 .unit:hover { border-color: rgba(127, 214, 255, .45); transform: translateY(-2px) } .ul { display: flex; justify-content: space-between; color: var(--mute); font-size: 13px; letter-spacing: .06em; text-transform: uppercase } .ul em { font: 500 12px var(--mono); color: var(--cyan); text-transform: none } +.ul b { font-weight: 400; color: var(--dim); margin-right: 10px } .uv { font: 400 clamp(18px, 1.9vw, 26px)/1.1 var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -.02em; white-space: nowrap } .un { font: 12px var(--mono); color: var(--dim) } .bar { display: block; height: 3px; border-radius: 3px; background: rgba(90, 140, 255, .14); overflow: hidden } @@ -67,8 +70,7 @@ h1 { font-weight: 500; font-size: clamp(28px, 4.4vw, 48px); letter-spacing: -.02 h2 { font: 500 12px var(--sans); letter-spacing: .14em; text-transform: uppercase; color: var(--mute); margin-bottom: 10px } .v { font: 400 18px/1.35 var(--mono); font-variant-numeric: tabular-nums } .m { margin-top: 8px; font-size: 13px; color: var(--mute) } -.card .bar { margin-top: 12px } -.pips { display: flex; gap: 5px; margin-top: 12px } +.pips { display: flex; gap: 5px } .pips i { flex: 1; height: 3px; border-radius: 3px; background: rgba(90, 140, 255, .14) } .pips .on { background: #2f6bff } .pips .cur { background: var(--cyan); box-shadow: 0 0 10px var(--cyan) } @@ -115,6 +117,7 @@ footer { display: flex; align-items: center; justify-content: space-between; gap .unit:last-child { grid-column: span 2 } .grid, .cv, #miles { grid-template-columns: minmax(0, 1fr) } .wide { grid-column: auto } + .v { font-size: 16px } .map { margin: 22px -20px 0 } footer { flex-direction: column; align-items: flex-start } }