From f771534aaa7ede7d3b997ec15d58ee1adc2f2d57 Mon Sep 17 00:00:00 2001
From: Jess Sullivan
Date: Wed, 10 Jun 2026 22:52:26 -0400
Subject: [PATCH] docs(helix): copy, Cmd-K keywords, and comment hygiene for
the time-helix era (PR3)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The component swap landed in #432; this sweeps the prose that still said
'twilight gantt' / EphemerisGantt where it described the PRESENT:
- Sky-lens tour step: 'Open the time helix … now sits at the center; drag
the ribbon' (was 'Open the twilight gantt')
- Cmd-K 'Toggle Twilight strip' keywords gain 'time helix' (gantt kept as
an alias)
- /docs route: three Sky-lens/ephemeris mentions now say time helix
- docs/ux/command-deck.md: present-tense DOCK prose updated (notes the row
keeps its .gantt smoke contract); historical W-logs left as history
- 15 stale comments across app.css, viewportGrid, cache/badge, MapToolbar,
SkyCompass, ResponsiveDock, horizonAwareEvents, twilight-phases,
+page.svelte — each reworded to be true today (e.g. badge.ts notes the
cache pill has no consumer while TimeHelix V1 defers it; the TIN-1810
app.css note records the ~200px figure as gantt-era history and why the
reserve rule stays)
No behavior change; just check green; the .gantt/.bar/.stripe contract and
ganttRow/ganttBlock/dock-gantt-row names are untouched by design.
---
docs/ux/command-deck.md | 4 ++--
src/app.css | 19 +++++++++++--------
src/lib/cache/badge.ts | 10 ++++++----
src/lib/components/MapToolbar.svelte | 3 ++-
src/lib/components/ResponsiveDock.svelte | 6 +++---
src/lib/components/SkyCompass.svelte | 2 +-
src/lib/ephemeris/horizonAwareEvents.ts | 2 +-
src/lib/ephemeris/twilight-phases.ts | 4 ++--
src/lib/viewportGrid.ts | 5 +++--
src/routes/+page.svelte | 8 ++++----
src/routes/docs/+page.svelte | 10 +++++-----
11 files changed, 40 insertions(+), 33 deletions(-)
diff --git a/docs/ux/command-deck.md b/docs/ux/command-deck.md
index d3cc091..c7474bb 100644
--- a/docs/ux/command-deck.md
+++ b/docs/ux/command-deck.md
@@ -66,7 +66,7 @@ never occluded, at every breakpoint.
lead value** → support sections (full weight) → "More — N sections ▾"
(collapsed-but-obvious, full contrast) → TOOLS. Deep tools open **inside this
column** (master-detail) or shrink the stage — never as a `bottom:0 z12` sheet.
-- **DOCK** (bottom, full width): the twilight gantt as its **own reserved row** at
+- **DOCK** (bottom, full width): the time helix (the twilight strip — `TimeHelix.svelte`, née the twilight gantt; the row keeps its `.gantt` smoke contract) as its **own reserved row** at
every breakpoint — so "X floats over the twilight strip" is structurally
impossible. Deletes the ~120 lines of `--field-panel-*` math + `!important`
overrides + the portrait clearance special-case.
@@ -110,7 +110,7 @@ pre-fills the deep tool with `{lat,lon,et,lens,layers,boresight,horizon}` with z
re-entry. Hover-to-**peek** (ephemeral), click-to-**pin** (commit + enable CTAs);
value + its one CTA share one large target (Fitts).
-- ◐ **Sky** "dark window here" — **≤1 click** (hover=0): inspector leads Bortle + tonight's dark-window inline; full gantt always in the DOCK.
+- ◐ **Sky** "dark window here" — **≤1 click** (hover=0): inspector leads Bortle + tonight's dark-window inline; the full time helix always in the DOCK.
- ☁ **Air** "AQI here" — **≤1 click**: smog field present on Air-lens entry; inspector leads driving pollutant + NowCast-labeled AQI; AQ summary docked in-inspector.
- 📡 **Links** "link margin" — **≤2 clicks**: click → path-AOD→T→dB line; "Design a link" → boresight + Tx/Rx + loss breakdown expand *into* the inspector.
- 🛰 **Orbit** "next pass" — **≤2 clicks**: next DEM-gated pass on pin regardless of lens; "Plan a pass" → polar az/el track + pass list expand in-inspector.
diff --git a/src/app.css b/src/app.css
index 8385c5c..afc6cab 100644
--- a/src/app.css
+++ b/src/app.css
@@ -88,12 +88,15 @@ html {
html {
--field-bottom-reserve: 8.75rem;
--map-toolbar-inset-rem: 5rem;
- /* The mobile twilight gantt is ~200px tall — taller than --field-bottom-reserve
- (8.75rem ≈ 140px), so a tall readout-only state would dip ~60px into it
- (TIN-1810). The readout-only portrait rule clears the gantt by anchoring its
- bottom at this reserve instead; the gantt/attribution/toolbar keep
- --field-bottom-reserve. Tuned against real-font render (the GF cell is
- fontless so the overlap never shows in CI). */
+ /* TIN-1810 (gantt era): the old mobile twilight gantt was ~200px tall —
+ taller than --field-bottom-reserve (8.75rem ≈ 140px) — so a tall
+ readout-only state dipped ~60px into it. The readout-only portrait rule
+ clears the strip by anchoring its bottom at this reserve instead; the
+ strip/attribution/toolbar keep --field-bottom-reserve. The TimeHelix
+ strip is ~100px (comfortably inside the reserve) but the rule stays —
+ it is the structural guarantee, not a height tweak. Tuned against
+ real-font render (the GF cell is fontless so the overlap never shows
+ in CI). */
--gantt-reserve-rem: 13rem;
}
}
@@ -406,7 +409,7 @@ pre.shiki span {
owns layout. Five named, non-overlapping regions —
'header header header' / 'rail stage inspector' / 'dock dock dock',
tracks [20rem][1fr][22rem] — so overlap is impossible by construction: the
- map (grid-area:stage) + the twilight gantt (its own DOCK row) can only be
+ map (grid-area:stage) + the time helix (its own DOCK row) can only be
SHRUNK, never occluded. The old z4→z13 ladder + the `.field-hud` scrim are
deleted; the surfaces flow into grid cells. The only remaining fixed/absolute
overlays clip to the STAGE cell (toolbar, sky compass, deep-tool sheets,
@@ -420,7 +423,7 @@ pre.shiki span {
─────── ─────────────────── ─────────────────────────────
5 attribution bottom-left
6 SkyCompass top-right (hidden ≤560px)
- 6 EphemerisGantt strip bottom, full width (minus toolbar inset)
+ 6 TimeHelix strip bottom, full width (minus toolbar inset)
8 MapToolbar bottom-right
8 MapErrorToast bottom-left
9 LayerRail backdrop full (mobile drawer only)
diff --git a/src/lib/cache/badge.ts b/src/lib/cache/badge.ts
index 27b7ee6..11951c4 100644
--- a/src/lib/cache/badge.ts
+++ b/src/lib/cache/badge.ts
@@ -3,7 +3,7 @@
*
* Field users need to glance at the map and tell whether a given
* overlay is showing fresh data, cached data, stale data, or nothing
- * at all. The bottom rail in `EphemerisGantt.svelte` already grew a
+ * at all. The old `EphemerisGantt.svelte` bottom rail grew a
* one-off `RangeBadge` for the twilight viewport-summary; this module
* generalizes the same idea into a reusable contract so every overlay
* surface — LayerRail health pills, future per-overlay chips, the
@@ -47,7 +47,8 @@ export interface CacheBadgeInputs {
/**
* Human "… ago" string for a stored/computed timestamp. Exported so the
- * EphemerisGantt viewport-summary pill (which this module generalizes) shares
+ * twilight viewport-summary pill (the old EphemerisGantt surface this
+ * module generalizes; deferred in TimeHelix V1) shares
* one age formatter — including the >24h day rollover — instead of its own copy.
*/
export const fmtAge = (storedAtMs: number, nowMs: number): string => {
@@ -136,8 +137,9 @@ export const buildCacheBadge = (inputs: CacheBadgeInputs, nowMs: number = Date.n
};
/**
- * Map a `CacheBadgeTone` to the `.cache-pill` modifier classes used by
- * `EphemerisGantt.svelte`. Exported so a Svelte component can apply
+ * Map a `CacheBadgeTone` to the `.cache-pill` modifier classes the old
+ * `EphemerisGantt.svelte` wore (no consumer while TimeHelix V1 defers the
+ * cache pill). Exported so a Svelte component can apply
* the right tonal class without re-typing the union.
*/
export const cachePillToneClass = (tone: CacheBadgeTone): string => `cache-pill-${tone}`;
diff --git a/src/lib/components/MapToolbar.svelte b/src/lib/components/MapToolbar.svelte
index 9b5a102..c2c639f 100644
--- a/src/lib/components/MapToolbar.svelte
+++ b/src/lib/components/MapToolbar.svelte
@@ -2,7 +2,8 @@
/**
* MapToolbar — vertical stack of map-overlay toggles in the
* bottom-right corner. Replaces the two standalone time / sun-moon
- * buttons that fought the EphemerisGantt + TimeDock for the same space.
+ * buttons that fought the twilight strip (now TimeHelix) + TimeDock for
+ * the same space.
*
* The toolbar publishes its width via the `--toolbar-w-rem` CSS
* custom property on `:host`. The gantt + dock read that variable
diff --git a/src/lib/components/ResponsiveDock.svelte b/src/lib/components/ResponsiveDock.svelte
index 46f912d..0d8e785 100644
--- a/src/lib/components/ResponsiveDock.svelte
+++ b/src/lib/components/ResponsiveDock.svelte
@@ -229,7 +229,7 @@
with PEEK / HALF / FULL detents (CSS scroll-snap). The map de-fixes into the
stage behind it (a map strip is ALWAYS visible at the top — FULL ≈ 88vh, never
100%). A [Layers · Readout · Tools] segmented control SWAPS the single sheet's
- content; switching never spawns a 2nd panel. The twilight gantt is a thin
+ content; switching never spawns a 2nd panel. The time helix is a thin
always-present row ABOVE the sheet peek at every detent. Marked
.responsive-dock + data-responsive-dock so W4a's tolerant HUD-overlap assertion
keys off it. -->
@@ -264,7 +264,7 @@
{@render lensStrip()}
{/if}
-
{#if ganttRow}
{@render ganttRow()}
@@ -437,7 +437,7 @@
}
/* The gantt's OWN thin row, pinned above the tabs + body — always present. The
- EphemerisGantt's COMPACT default is position:fixed at the viewport bottom; here
+ TimeHelix's COMPACT default is position:fixed at the viewport bottom; here
it must flow inside the sheet as a thin row, so de-float it (it keeps its
.gantt class + aria-label — only positioning changes). */
.dock-gantt-row {
diff --git a/src/lib/components/SkyCompass.svelte b/src/lib/components/SkyCompass.svelte
index 09f63a6..2369700 100644
--- a/src/lib/components/SkyCompass.svelte
+++ b/src/lib/components/SkyCompass.svelte
@@ -441,7 +441,7 @@
{:else if moonHorizonDelta}
h {fmtAlt(moonHorizonDelta.horizonAlt)}
{/if}
-
diff --git a/src/lib/ephemeris/horizonAwareEvents.ts b/src/lib/ephemeris/horizonAwareEvents.ts
index a06b21c..8c4997b 100644
--- a/src/lib/ephemeris/horizonAwareEvents.ts
+++ b/src/lib/ephemeris/horizonAwareEvents.ts
@@ -3,7 +3,7 @@
*
* Flat-horizon sunrise = the instant the sun's geocentric altitude
* crosses 0°. That's what astronomy-engine's `SearchAltitude` /
- * `SearchRiseSet` return — and it's what the EphemerisGantt shows
+ * `SearchRiseSet` return — and it's what the TimeHelix shows
* today. For dark-sky / spectroscopy field work the answer that
* actually matters is the instant the sun crosses the *local*
* horizon at its azimuth, which is what a HorizonPolygon encodes.
diff --git a/src/lib/ephemeris/twilight-phases.ts b/src/lib/ephemeris/twilight-phases.ts
index c51f0d2..6a5b012 100644
--- a/src/lib/ephemeris/twilight-phases.ts
+++ b/src/lib/ephemeris/twilight-phases.ts
@@ -29,8 +29,8 @@ export interface PhaseDefinition {
/**
* Canonical phase table. Colors mirror the Photographer's Ephemeris
- * palette previously inlined in `EphemerisGantt.svelte` so the visual
- * appearance does not change.
+ * palette inlined in the old `EphemerisGantt.svelte` (the TimeHelix ribbon
+ * consumes it now) so the visual appearance does not change.
*/
export const PHASE_DEFINITIONS: Readonly> = {
night: {
diff --git a/src/lib/viewportGrid.ts b/src/lib/viewportGrid.ts
index 9996a9d..8b2ef25 100644
--- a/src/lib/viewportGrid.ts
+++ b/src/lib/viewportGrid.ts
@@ -1,7 +1,8 @@
/**
* Viewport sampling helpers.
*
- * The EphemerisGantt's per-event range pill samples ephemeris at a
+ * The twilight viewport-summary (born as the EphemerisGantt's range
+ * pill; its TimeHelix successor defers the pill UI) samples ephemeris at a
* 4×4 grid of points inside the visible viewport. The math is in a
* pure helper here so it can be unit-tested independently from the
* Svelte component — which matters because the bug it fixes (silent
@@ -28,7 +29,7 @@ const canonicalizeLon = (lon: number): number => ((((lon + 180) % 360) + 360) %
* Returns the empty array for degenerate viewports (zero or negative
* span on either axis).
*
- * Caller picks N (the EphemerisGantt uses 4 for ephemeris range
+ * Caller picks N (the viewport summary uses 4 for ephemeris range
* sampling — 16 calls is cheap and covers the variability that
* matters for state-scale viewports).
*/
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 59cba3c..07bf145 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -267,7 +267,7 @@
{
anchor: '[data-tour="toolbar"]',
title: 'Twilight & ephemeris',
- body: 'Open the twilight gantt for sun/moon timing and the sky compass — plan the session around the dark hours.',
+ body: 'Open the time helix for sun/moon timing and the sky compass — now sits at the center; drag the ribbon to plan the session around the dark hours.',
},
],
// Air (weather/smog): atmosphere overlays + PM2.5 field, NowCast vs 24-h, AQ tools.
@@ -436,7 +436,7 @@
{
id: 'tool-twilight',
label: 'Toggle Twilight strip',
- keywords: 'sun moon timing dark window ephemeris gantt',
+ keywords: 'sun moon timing dark window ephemeris gantt time helix',
run: () => (ephemerisOpen = !ephemerisOpen),
},
{
@@ -2759,7 +2759,7 @@
{/if}
-
@@ -3311,7 +3311,7 @@
}
/* De-fix the region children at MEDIUM+WIDE: the lens chips + geocoder
- (HEADER), the PointReadout (INSPECTOR), and the twilight gantt (DOCK) drop
+ (HEADER), the PointReadout (INSPECTOR), and the time helix (DOCK) drop
their own position:fixed/inset/z-index and flow into their grid cells. Their
own <640px float positioning is untouched (the COMPACT fallback). The stage
overlays (toolbar, sky, sheets) stay fixed at COMPACT; here they clip to the
diff --git a/src/routes/docs/+page.svelte b/src/routes/docs/+page.svelte
index 6ccebee..ab8c3e9 100644
--- a/src/routes/docs/+page.svelte
+++ b/src/routes/docs/+page.svelte
@@ -23,7 +23,7 @@
persona: 'Astro instrumentation & astrophotography',
question: 'When and where is tonight dark, clear, and steady enough for my target?',
tools:
- 'VIIRS + Falchi radiance → Bortle / SQM · ephemeris & twilight gantt · SkyCompass · DEM horizon · T(λ) extinction',
+ 'VIIRS + Falchi radiance → Bortle / SQM · ephemeris & time helix · SkyCompass · DEM horizon · T(λ) extinction',
cta: 'Open the Sky lens',
},
{
@@ -121,8 +121,8 @@
-
- ◐ Sky — astronomers & astrophotographers: VIIRS + Falchi radiance → Bortle / SQM, the twilight
- gantt + sky compass, and the real DEM horizon for a dark-sky site.
+ ◐ Sky — astronomers & astrophotographers: VIIRS + Falchi radiance → Bortle / SQM, the time helix
+ + sky compass, and the real DEM horizon for a dark-sky site.
-
☁ Air — weather, pollen & smog analysts: GIBS cloud / aerosol / water-vapor overlays plus a modeled
@@ -164,8 +164,8 @@
readout (with Bortle / class mapping)
-
- Per-view ephemeris — sun + moon position, twilight gantt (astro / nautical / civil), sky compass
- with sun trajectory arc + moon position + atmospheric airmass
+ Per-view ephemeris — sun + moon position, the now-centered time helix (astro / nautical / civil twilight),
+ sky compass with sun trajectory arc + moon position + atmospheric airmass
-
Real-terrain horizon — 36-ray, 10-distance raycast over AWS Mapzen Terrarium tiles; sun / moon altitude