/* public/css/40-sky.css — Bars, sunset, season, sky
 *
 * Part of the old public/oracle.css, which reached 4,761 lines. Split at its own section
 * boundaries; no rule was reordered, reindented or rewritten, so the cascade is unchanged.
 * THE FILES ARE ORDER-DEPENDENT. index.html links them in numeric order and that order is the
 * cascade — concatenating them in it reproduces the original file byte for byte, which is
 * asserted in test/stylesheet.test.js. Renumbering or reordering the <link> tags changes which
 * rules win.
 *
 * What goes under a bar; the sunset row and its palette strip, meter and breakdown; the season
 * word; the Oracle's notes; the sign picker; the five naked-eye planets; the cosmos tab.
 */
        /* ══ What goes under a bar ══
              There used to be one rule here, .cd-daybar-caption, and it was `space-between`
              holding however many facts a tab had. That is fine for two items and quietly
              wrong for three: the bar's cells are evenly divided, so three facts pushed edge
              to edge land under cell boundaries and read as LABELS FOR THE CELLS. On the Day
              tab, "8% through the day · 15h 1m of day left · sets 21:02" looked like it was
              naming three of the five stages above it.

              The burn-down bar on the Galaxy tab never had the problem, because its caption is
              exactly two items and they are the two ENDS of the bar. It is an axis, not a row
              of labels. So there are two shapes now and no third — see buildBarAxis and
              buildBarLede in core.js. */

        /* Exactly two, and they must genuinely be the bar's ends. Anchored hard left and hard
           right so the pairing with the bar's ends is unmistakable. */
        .cd-baraxis {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: 0.6rem;
            margin-top: 0.4rem;
            font-size: 0.68rem;
            letter-spacing: 0.04em;
            color: var(--text-secondary);
            font-variant-numeric: tabular-nums;
        }
        .cd-baraxis strong { color: var(--accent-cyan); font-weight: 600; }
        .cd-baraxis-dim { color: var(--text-dim); }
        /* Explicit, so a long value still reads as belonging to its end of the bar rather than
           drifting toward the middle when it wraps. */
        .cd-baraxis-start { text-align: left; }
        .cd-baraxis-end { text-align: right; }

        /* The single headline number. Centred, because centred cannot align to a cell — which
           is the entire point of it not being in the axis row. */
        /* ── The one line under the axis ──
              Day and Year each get exactly one, and it is the same kind of statement on both:
              the next thing worth knowing on this timescale. They used to be different objects
              — Golden hour was a full-width tinted strip with a glowing swatch, "37 days until
              autumn" was a bare centred sentence — so switching tabs changed the furniture as
              well as the content. Same pill now; only the colour differs. */
        .cd-barpill {
            display: block;
            width: fit-content;
            max-width: 100%;
            margin: 0.6rem auto;
            padding: 0.34rem 0.85rem;
            border-radius: 999px;
            text-align: center;
            font-size: 0.74rem;
            line-height: 1.45;
            letter-spacing: 0.02em;
            color: var(--text-secondary);
            background: rgba(167,139,250,0.08);
            text-wrap: pretty;
        }
        .cd-barpill strong {
            color: var(--accent-cyan);
            font-weight: 600;
            font-variant-numeric: tabular-nums;
        }
        /* The one line on the whole dashboard that is a reason to stand up, so it wears the
           light's own colour instead of the page's. */
        .cd-barpill.golden {
            color: rgba(255,205,150,0.95);
            background: rgba(255,168,80,0.12);
        }
        .cd-barpill.golden strong { color: #ffd79a; }
        /* Golden hour's opposite number, and the other line here that is a reason to stand up.
           Cold pale blue against the gold, because it is the same kind of statement about the
           other half of the day — and because that is roughly what a properly dark sky looks
           like once your eyes have adjusted. */
        .cd-barpill.dark {
            color: rgba(186,214,255,0.95);
            background: rgba(120,160,235,0.12);
        }
        .cd-barpill.dark strong { color: #cfe2ff; }
        /* The midsummer case: no astronomical night at all. It is a statement about an absence,
           so it steps back rather than announcing itself the way a live window does. */
        .cd-barpill.dark.faint {
            color: var(--text-dim);
            background: rgba(120,160,235,0.05);
        }
        .cd-barpill.dark.faint strong { color: var(--text-secondary); }
        .cd-barpill.season strong { color: var(--accent-cyan); }

        /* ── The sunset row's lede ──
              ONE sentence about tonight, with Listen beside it. The Oracle's own if it has
              written one; the score's canned line only when it hasn't. It used to be both at
              once, stacked — see the note in core.js. */
        .sunset-lede {
            display: flex;
            flex-direction: column;
            align-items: flex-start;
            gap: 0.4rem;
            margin-bottom: 0.75rem;
        }
        .sunset-lede .sunset-verdict {
            font-size: 0.85rem;
            line-height: 1.5;
            color: var(--text-primary);
            text-wrap: pretty;
        }
        /* (.sunset-listen went on 30 Sept: the sunset's Listen button is in its card's head now,
            styled as the Today card's is, with .daily-card-listen.) */

        /* ── Tonight's palette, at last shown at a size you can see ──
              The device predicts the sky's colours and then wears them. On the page that
              forecast had been a 10px dot and a tint inside the score pips: used to decorate
              other numbers, never shown as itself. Chips share the width equally and sit flush,
              so the strip reads as one band of sky while still showing where each colour stops —
              which is what nineteen discrete LEDs actually do. */
        .sunset-palette { margin: 0 0 0.85rem; }
        .sunset-palette-head {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: 0.5rem;
            margin-bottom: 0.4rem;
        }
        .sunset-palette-name {
            font-size: 0.72rem;
            font-weight: 600;
            letter-spacing: 0.02em;
            color: rgba(255,180,100,0.95);
        }
        .sunset-palette-count {
            font-size: 0.62rem;
            letter-spacing: 0.12em;
            text-transform: uppercase;
            color: var(--text-dim);
            white-space: nowrap;
        }
        .sunset-palette-strip {
            display: flex;
            align-items: stretch;
            gap: 0;
            border-radius: 8px;
            overflow: hidden;
        }
        .sunset-palette-chip {
            flex: 1 1 0;
            min-width: 0;
            display: flex;
            flex-direction: column;
        }
        .sunset-palette-swatch { display: block; height: 2.6rem; }
        /* The hex sits on the tinted card behind the strip rather than on the colour itself —
           there is no single text colour that stays legible on a palette running from cream to
           near-black, and outlining it would be four decorations to solve one problem. */
        .sunset-palette-hex {
            padding: 0.28rem 0.1rem 0;
            text-align: center;
            font-size: 0.62rem;
            letter-spacing: 0.04em;
            text-transform: uppercase;
            color: var(--text-dim);
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        .sunset-palette-note {
            margin-top: 0.4rem;
            font-size: 0.62rem;
            color: var(--text-dim);
        }

        /* ── "The Oracle Foretells" ──
              The card was called "What's Coming", which read like a listings page for
              something that had been worked out from first principles. */
        /* ══ The Oracle's word for the season ══
              A fold now, the same shape as Today's theme — the two are the only things on the
              dashboard the Oracle actually WROTE, so they should read as siblings. It used to
              stand open here as an amber inset panel, which put a three-month-old paragraph of
              prose above the live season bar and made it look like the tab's headline.

              The amber left border stays: it belongs to the Sun's clock — the solstices and
              equinoxes — and amber is what every other seasonal mark on this page uses. It is
              the one thing distinguishing this fold from the theme fold, which is enough. */
        .cd-seasonword {
            /*
            border-left: 2px solid rgba(244, 162, 97, 0.4);
            border-radius: 0 10px 10px 0;
            background: rgba(244, 162, 97, 0.06);
            */
        }
        /* The mark and the label travel together on the summary line, so they need to be one
           flex item inside the summary's own space-between layout — otherwise the skull sits at
           one end of the row and its label at the other. */
        .cd-seasonword-sum {
            display: inline-flex;
            align-items: center;
            gap: 0.4rem;
        }
        /* Smaller than the reading cards' 24px mark: this is a fold summary, and the mark
           should read as a signature rather than a headline. Never below 16 — the sprite is
           16 squares and anything smaller drops whole rows of it. */
        .cd-seasonword-skull { width: 16px; height: 16px; flex-shrink: 0; }
        .cd-seasonword-text {
            font-size: 0.85rem;
            line-height: 1.6;
            text-wrap: pretty;
            margin: 0 0 0.5rem;
            color: var(--text-primary);
        }
        .cd-seasonword-foot {
            font-size: 0.62rem;
            letter-spacing: 0.04em;
            color: var(--text-dim);
            text-wrap: pretty;
        }

        /* (The intention block's styles are gone with the feature — the text box that asked
           "What do you want done by Autumn?". It was the only place on the whole page that
           asked the reader to produce something, which is exactly why it went: an unanswered
           prompt on a page you open before coffee is a small debt every time you scroll past
           it. See the note in core.js where its storage used to live.) */

        /* ── Sunset rating, on the closed row ──
              Gold and small. It sits inline after the time, so the row reads "Sunset · 21:04
              ★★★★☆" — a verdict you get without opening anything, which is the whole point:
              a rare sunset and a flat one used to look identical until you tapped. Dimmed at
              one and two stars so a bad night is quiet rather than shouting five hollow slots
              at you. */
        /* Bigger than the title it sits beside, not smaller. It was 0.72rem — below the row's
           own text — which made the one thing on the row you are meant to read at a glance the
           hardest thing on it to read. Stars are a shape rather than words, so they can take
           the size without shouting, and the extra letter-spacing stops five glyphs at this
           size fusing into one amber smear. */
        .ft-stars {
            margin-left: 0.45rem;
            font-size: 0.95rem;
            letter-spacing: 0.08em;
            line-height: 1;
            color: var(--accent-amber);
            white-space: nowrap;
        }
        .ft-stars.stars-1, .ft-stars.stars-2 { opacity: 0.62; }
        .ft-stars.stars-5 { text-shadow: 0 0 8px rgba(244, 162, 97, 0.5); }

        /* ── "in Libra" ──
              This is now the MAIN carrier, not the caption to a tint. It began as words to go
              with the colour, because a colour nobody was told the meaning of is a code rather
              than a signal — and then the colour went (see .ft-row.yours in 30-timeline.css:
              two lines of recoloured text plus a badge plus a mark was four devices for one
              fact, in a section where every row is already a highlight). The badge and the
              tinted mark are what is left. Uses the same "this is yours" blue as the sign marks
              elsewhere. */
        .ft-yours-tag {
            margin-left: auto;
            padding: 0.05rem 0.35rem;
            border-radius: 999px;
            border: 1px solid rgba(96, 165, 250, 0.35);
            background: rgba(96, 165, 250, 0.12);
            color: rgba(147, 197, 253, 0.95);
            font-size: 0.62rem;
            letter-spacing: 0.06em;
            text-transform: lowercase;
            white-space: nowrap;
            vertical-align: middle;
        }

        /* (.ft-minor-note and .foretell-sub are both gone with the lines they styled — the
           "N other sign changes this month" footnote and the "calculated, not looked up"
           standing claim. Each was a sentence about the page's own editorial policy printed on
           a card the reader came to for dates. The method claim is made properly in the About
           modal, where somebody asking "how does it know that" is actually looking.) */

        /* ══ The Oracle's Notes ══
              Sits above the three dashboard cards and says whose notes they are. Deliberately
              NOT a .cosmic-dashboard-card: it is the label on the stack, and giving it the same
              panel treatment as the things it labels would make it look like a fourth card that
              had lost its contents. No background, no border, no glyph — the cards below wear
              ✧ and ☉ and a third symbol here would compete with what it is framing.

              It does NOT carry the skull either. That mark means "the Oracle said this" (see
              .daily-card-skull), and these are notes it read rather than words it wrote. */
        .oracle-notes-head {
            margin: 0 0 0.9rem;
            padding: 0 0.2rem;
            text-align: center;
        }
        /* A tier above the card headings rather than a copy of them. Those are 0.72rem caps at
           0.22em, centred, in half-opacity purple; this keeps the caps and the centring so it
           reads as the same family, and takes a little more size and opacity so the stack has a
           top rather than four things shouting equally. */
        .oracle-notes-head h2 {
            margin: 0;
            font-size: 0.8rem;
            letter-spacing: 0.22em;
            text-transform: uppercase;
            font-weight: 500;
            color: rgba(167,139,250,0.85);
        }
        .oracle-notes-sub {
            margin: 0.3rem auto 0;
            max-width: 34ch;
            font-size: 0.66rem;
            line-height: 1.45;
            color: var(--text-dim);
            text-wrap: pretty;
        }

        /* ══ The sign picker ══
              Was twelve tiny glyph tiles. Now: grouped by element, dates leading, glyph as a
              large quiet mark. Rows rather than a grid because a date range needs horizontal
              room and because twelve rows in four labelled groups scan faster than a 3×4 block
              of symbols you have to decode one at a time. */
        .sign-picker { display: flex; flex-direction: column; gap: 0.9rem; }
        .sign-group-head {
            display: flex;
            align-items: center;
            gap: 0.4rem;
            font-size: 0.62rem;
            letter-spacing: 0.18em;
            text-transform: uppercase;
            color: var(--text-dim);
            margin-bottom: 0.35rem;
        }
        .sign-group-dot { width: 0.45rem; height: 0.45rem; border-radius: 50%; }
        .sign-group-fire  .sign-group-dot { background: #ff8a5e; }
        .sign-group-earth .sign-group-dot { background: #9bc47a; }
        .sign-group-air   .sign-group-dot { background: #8fb6f0; }
        .sign-group-water .sign-group-dot { background: #6fd8d0; }
        .sign-group-rows { display: flex; flex-direction: column; gap: 0.25rem; }
        .sign-row {
            display: flex;
            align-items: center;
            gap: 0.7rem;
            width: 100%;
            padding: 0.5rem 0.7rem;
            border-radius: 10px;
            border: 1px solid rgba(255,255,255,0.07);
            background: rgba(255,255,255,0.02);
            color: var(--text-secondary);
            font-family: inherit;
            text-align: left;
            cursor: pointer;
            transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;
        }
        .sign-row:hover { background: rgba(255,255,255,0.05); border-color: rgba(255,255,255,0.16); }
        .sign-row:active { transform: scale(0.995); }
        .sign-row-main { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; flex: 1; }
        .sign-row-name { font-size: 0.86rem; color: var(--text-primary); letter-spacing: 0.02em; }
        /* The primary information, despite being the smaller text — it's what the question
           actually is. */
        .sign-row-dates { font-size: 0.68rem; color: var(--text-dim); font-variant-numeric: tabular-nums; }
        .sign-row-tick { opacity: 0; color: var(--accent-yours); font-size: 0.9rem; transition: opacity 0.15s ease; }
        .sign-row.active {
            border-color: rgba(37,180,243,0.55);
            background: rgba(37,180,243,0.1);
        }
        .sign-row.active .sign-row-name { color: var(--accent-yours); font-weight: 600; }
        .sign-row.active .sign-row-tick { opacity: 1; }

        /* ── The tab strip as a ladder ──
              Each tab is a longer view than the last, and until the scale words went in
              nothing said so — four tabs read as four unrelated widgets rather than as one
              zoom-out. Two lines per button, the scale line quiet enough to be read once and
              then ignored. */
        .cd-tab-btn {
            display: flex;
            flex-direction: row;
            justify-content: center;
            align-items: center;
            gap: 0.1rem;
            line-height: 1.2;
        }

        /* (.cd-moonvis is gone. It was a standalone panel saying whether the Moon was up,
            which made sense when the Moon had a tab to itself. The Moon is now the first row
            of the Tonight list and answers the same question in the same shape as the five
            planets under it, so the panel had nothing left to do.) */

        /* ══ The five naked-eye planets ══
              The one block on the page that answers "could I walk outside and find it", which
              is the only version of a planet's position anybody can actually check. Rows go
              dim by default and light up when the planet is genuinely visible, so the shape of
              the block IS the answer — on an ordinary night most of it is grey and one or two
              rows are lit, and you can tell that before reading a word. */
        /* (.cd-tonight and .cd-tonight-head had their own spacing and their own micro-label.
            Both come from the shared .cd-fold / .cd-subhead grammar now, so this section head
            looks like the other three on the card instead of being a fourth invention.) */
        .cd-tonight-none {
            font-size: 0.72rem;
            line-height: 1.5;
            color: var(--text-secondary);
            margin-bottom: 0.6rem;
            text-wrap: pretty;
        }
        /* (.cd-tonight-none-sub is gone with the second sentence it styled — "Venus, Jupiter,
            Mars and Mercury are up there, but not worth the coat yet." The line above it now
            names the next planet and the time it arrives, which is what that sentence was
            circling around without ever saying.) */

        /* name · when · flags, on ONE line each.
           This used to be three columns with the note wrapping underneath across the full
           width, which made every planet two lines and the block ten. The note has moved into
           the "how to tell them apart" fold below, so a row is now a name, a time and a
           direction — and five planets read as five lines. */
        .cd-tonight-row {
            display: grid;
            grid-template-columns: minmax(5.2rem, auto) 1fr auto;
            align-items: baseline;
            gap: 0.2rem 0.6rem;
            padding: 0.4rem 0;
            border-top: 1px solid rgba(255,255,255,0.045);
            opacity: 0.62;
            transition: opacity 0.2s ease;
        }
        .cd-tonight-row:first-of-type { border-top: 0; }
        .cd-tonight-row.visible { opacity: 1; }

        .cd-tonight-name {
            font-size: 0.8rem;
            font-weight: 600;
            color: var(--text-secondary);
        }
        .cd-tonight-row.visible .cd-tonight-name { color: var(--text-primary); }

        .cd-tonight-where {
            font-size: 0.7rem;
            color: var(--text-dim);
            font-variant-numeric: tabular-nums;
        }
        .cd-tonight-row.visible .cd-tonight-where { color: var(--text-secondary); }
        .cd-tonight-where strong { color: var(--accent-cyan); font-weight: 600; }

        .cd-tonight-flags { justify-self: end; }
        /* When a visible body goes back down. Only shown while it is actually up — a set time
           for something below the horizon is a fact about tomorrow dressed as a fact about now. */
        .cd-tonight-when {
            font-size: 0.62rem;
            color: var(--text-dim);
            white-space: nowrap;
            font-variant-numeric: tabular-nums;
        }
        .cd-tonight-row.visible .cd-tonight-when { color: var(--text-secondary); }
        /* Deliberately NOT amber. Amber means "about you" everywhere on this page — your sign,
           a planet arriving in it — and it only works because it appears once or twice in the
           whole dashboard. A conjunction is about the sky, not the reader. */
        .cd-tonight-moon {
            font-size: 0.62rem;
            letter-spacing: 0.04em;
            padding: 0.1rem 0.4rem;
            border-radius: 999px;
            white-space: nowrap;
            color: #cbd5e1;
            border: 1px dashed rgba(203,213,225,0.4);
            background: rgba(203,213,225,0.07);
        }

        /* ── The Moon's note, and only the Moon's ──
              The planets lost theirs when their rows went to one line — five greyed-out
              sentences of charm was the thing that made this block unreadable, and the
              descriptions moved into the "how to tell them apart" fold below.
              The Moon keeps one, because its note is not charm: it is "Last Quarter, 22% lit —
              full in 20 days", which is a different fact every night and the reason anybody
              looks at the row. Scoped to the moon row rather than left as a bare
              .cd-tonight-note, so it cannot drift back onto the planets. */
        .cd-tonight-row-moon .cd-tonight-note {
            grid-column: 1 / -1;
            font-size: 0.66rem;
            line-height: 1.45;
            color: var(--text-dim);
            text-wrap: pretty;
        }

        /* A planet with no window in the next 24 hours. Dimmer than the merely-not-yet rows,
           because "not tonight" and "from 21:40" are different answers and the block should say
           which is which before a word is read — same principle as the lit rows, one rung down.
           Never colour alone: the row also says the words "not tonight". */
        .cd-tonight-row-out { opacity: 0.45; }

        /* "in 40m" beside the clock time. The house rule is that a relative figure never
           travels without its real one, so this is an addition to the time and never a
           replacement — it is sized and coloured to read as an aside to the number it follows. */
        .cd-tonight-soon {
            font-size: 0.62rem;
            color: var(--accent-cyan);
            opacity: 0.75;
            margin-left: 0.15rem;
        }

        /* (.cd-tonight-lore and .cd-tonight-lore-row are gone with the "how to tell them apart"
           fold they set — see buildVisiblePlanetRows in core.js. Removed rather than left
           orphaned: an unused rule is a rule somebody later reuses for something it was not
           shaped for, and this one carried a two-column grid that only made sense for that
           fold's name/sentence pairs. The mobile override below went with it.) */

        /* ── Several of them at once ──
              Sits under the five one-planet rows and answers the question they cannot add up
              to. Tinted rather than bordered: it belongs to the block above it, and a boxed
              element beside a list of plain rows reads as a visitor (the galactic-centre pill
              on the Galaxy tab made exactly that mistake and was un-boxed for it). */
        /* ── The corners, which were fighting the rule ──
              Dan: "it has border left highlight but rounded corners so looks naff." A 10px
              radius on all four corners curves the top and bottom of the left edge AWAY from
              the 2px rule sitting on it, so the rule floats off the tint at both ends and the
              whole thing reads as a box someone drew badly rather than a marked block.
              Squared on the left, rounded on the free side: the rule now runs the full height
              of the edge it belongs to. Same lesson as the headline card losing its box —
              pick one device and let it do the job. */
        .cd-gathering {
            margin-top: 0.75rem;
            padding: 0.6rem 0.7rem;
            border-radius: 0 10px 10px 0;
            background: rgba(94,234,212,0.06);
            border-left: 2px solid rgba(94,234,212,0.5);
        }
        .cd-gathering-head {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: 0.6rem;
        }
        .cd-gathering-count {
            font-size: 0.8rem;
            font-weight: 600;
            color: var(--accent-cyan);
        }
        .cd-gathering-when {
            font-size: 0.66rem;
            color: var(--text-dim);
            font-variant-numeric: tabular-nums;
            white-space: nowrap;
        }
        .cd-gathering-who {
            margin-top: 0.3rem;
            font-size: 0.74rem;
            color: var(--text-primary);
            line-height: 1.5;
        }
        .cd-gathering-run {
            margin-top: 0.2rem;
            font-size: 0.68rem;
            color: var(--text-secondary);
            font-variant-numeric: tabular-nums;
        }
        /* The two that turn a four-planet morning into a "six-planet parade" in every headline
           you will read about it. Quiet, because it is a correction rather than the news. */
        .cd-gathering-faint {
            margin-top: 0.35rem;
            font-size: 0.66rem;
            line-height: 1.5;
            color: var(--text-dim);
            text-wrap: pretty;
        }

        @media (max-width: 400px) {
            .cd-tonight-row { grid-template-columns: 1fr auto; }
            .cd-tonight-flags { grid-column: 2; grid-row: 1; }
            .cd-tonight-where { grid-column: 1 / -1; }
        }

        /* ══ Cosmos ══
              (The odometer's huge centred readout is gone. It was the largest type on the
               dashboard and the whole tab rested on it, which stopped being true once the Sun's
               fuel became the bar — two showstoppers on one tab is neither. The live count
               survives as the tab's one .cd-barpill line, so the number still climbs while you
               read; it just no longer shouts over the thing above it.) */

        /* Four frames, slowest to fastest. The bar is proportional across all four, so the
           spin you could almost believe is a sliver and the ones you can't are not. */
        .cd-speeds { display: flex; flex-direction: column; gap: 0.4rem; margin: 0.8rem 0; }
        .cd-speed-row {
            display: grid;
            grid-template-columns: 4.4rem 1fr auto;
            grid-template-areas: 'verb bar val' 'frame frame frame';
            align-items: center;
            gap: 0.2rem 0.55rem;
        }
        .cd-speed-verb {
            grid-area: verb;
            font-size: 0.66rem;
            letter-spacing: 0.06em;
            text-transform: uppercase;
            color: var(--text-secondary);
        }
        .cd-speed-bar {
            grid-area: bar;
            height: 4px;
            border-radius: 999px;
            background: rgba(167,139,250,0.12);
            overflow: hidden;
        }
        .cd-speed-fill {
            display: block;
            height: 100%;
            border-radius: 999px;
            background: linear-gradient(90deg, var(--accent-cyan), var(--accent-purple));
        }
        .cd-speed-val {
            grid-area: val;
            font-size: 0.76rem;
            font-weight: 600;
            color: var(--text-primary);
            font-variant-numeric: tabular-nums;
        }
        .cd-speed-unit { font-size: 0.62rem; color: var(--text-dim); margin-left: 0.15em; font-weight: 400; }
        .cd-speed-frame {
            grid-area: frame;
            font-size: 0.62rem;
            color: var(--text-dim);
            padding-left: 4.95rem;
        }

        /* ── The Sun's life, burning DOWN not filling up ──
              Every other bar on the site fills as you progress, because progress through a day
              or a season is an accumulation. This one isn't: the Sun is spending a fixed amount
              of hydrogen, so a bar that fills up reads exactly backwards — it says "getting
              fuller" about something getting emptier. Inverted here: the years already burned
              are ash, and what's left is still alight. */
        .cd-burndown .cd-segbar-cell .cd-segbar-tick {
            background: var(--accent-amber);
            box-shadow: 0 0 8px rgba(244,162,97,0.35);
        }
        .cd-burndown .cd-segbar-cell.past .cd-segbar-tick {
            background: rgba(120,110,110,0.28);
            box-shadow: none;
        }
        .cd-burndown .cd-segbar-cell.active .cd-segbar-tick {
            background: var(--accent-amber);
            box-shadow: 0 0 8px rgba(244,162,97,0.35);
        }
        /* The fill marks how much of the CURRENT billion years is already spent, so it is the
           ash colour eating into the flame rather than the other way round. */
        .cd-burndown .cd-segbar-cell.active .cd-segbar-fill { background: rgba(120,110,110,0.5); }
        .cd-burndown-head {
            font-size: 0.66rem;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            color: var(--text-secondary);
            margin-bottom: 0.35rem;
        }

        /* ── The Sun's laps of the galaxy ──
              The same span as the burndown bar above, counted in trips rather than in billions
              of years — because a trip is a unit everyone owns, a birthday being one. Two big
              figures and one line tying them to a human lifetime. No bar: the progress is
              already drawn six lines up, and drawing it twice in two units is the "two views of
              one thing" that the sunset row had to lose. */
        .cd-laps { margin-top: 1rem; }
        .cd-laps-row {
            display: flex;
            gap: 1.4rem;
            align-items: baseline;
        }
        .cd-laps-fig {
            font-size: 0.72rem;
            color: var(--text-dim);
        }
        .cd-laps-fig strong {
            display: block;
            font-size: 1.5rem;
            line-height: 1.15;
            color: var(--accent-amber);
            font-variant-numeric: tabular-nums;
            font-weight: 600;
        }
        .cd-laps-note {
            margin-top: 0.5rem;
            font-size: 0.72rem;
            line-height: 1.6;
            color: var(--text-secondary);
            text-wrap: pretty;
        }
        /* (.cd-burndown-caption is gone — it was a two-ended caption under a bar, which is
            exactly what .cd-baraxis does for Day and Year, and in fact the shape that one was
            generalised from. The Sun's fuel uses the shared object now.) */

        /* Where Sagittarius A* is — the same sum the skull runs in compass mode. */
        /* ── What the Sun is doing, inside the Sun's own row ──
              The wind, the Kp index it drives, and the storm warnings that are nearly always
              about both. They used to be warehoused in a fold at the foot of the page under the
              heading "Space Weather", which is a category rather than a place. Here they are
              simply the Sun's news, one tap into the row for the body producing them. */
        .cd-solarwx {
        /*    margin-top: 0.7rem;
            padding-top: 0.6rem;
            border-top: 1px solid rgba(255,255,255,0.06); */
        }
        .cd-solarwx-rows { display: flex; flex-direction: column; gap: 0.25rem; }
        .cd-solarwx-row {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: 0.6rem;
            font-size: 0.72rem;
        }
        .cd-solarwx-label { color: var(--text-dim); }
        .cd-solarwx-val {
            color: var(--text-secondary);
            font-variant-numeric: tabular-nums;
        }
        .cd-solarwx-val strong { color: var(--accent-amber); font-weight: 600; }
        /* Only a real storm gets to shout. "Quiet" is the answer on most days and should look
           like the ordinary reading it is. */
        .cd-solarwx-val.storm { color: var(--accent-red); }
        .cd-solarwx-val.storm strong { color: var(--accent-red); }
        /* ── The aurora line ──
              Green, and the only green on this row: every other reading here is a number in
              the site's purple/cyan, and this is the one that means "stop reading and go
              outside". It gets a tinted panel rather than another label/value row because it
              is not a measurement — it is the conclusion drawn from one, and it should not
              look like a third statistic stacked under Kp. Rare enough that the extra weight
              costs nothing on the 360 nights it isn't there. */
        .cd-aurora {
            display: flex;
            align-items: flex-start;
            gap: 0.45rem;
            margin-top: 0.55rem;
            padding: 0.5rem 0.6rem;
            border-radius: 8px;
            border: 1px solid rgba(56, 161, 105, 0.35);
            background: rgba(56, 161, 105, 0.10);
            font-size: 0.68rem;
            line-height: 1.45;
            color: var(--text-secondary);
            text-wrap: pretty;
        }
        .cd-aurora-mark { color: #4ade80; flex-shrink: 0; }
        /* A severe storm is the one case worth shouting about. */
        .cd-aurora.level-strong {
            border-color: rgba(74, 222, 128, 0.6);
            background: rgba(56, 161, 105, 0.18);
            color: var(--text-primary);
        }
        .cd-aurora.level-marginal { opacity: 0.85; }

        .cd-solarwx-alerts { margin-top: 0.5rem; display: flex; flex-direction: column; gap: 0.3rem; }
        .cd-solarwx-alert {
            display: flex;
            align-items: baseline;
            gap: 0.4rem;
            font-size: 0.68rem;
            line-height: 1.45;
            color: var(--text-secondary);
            text-wrap: pretty;
        }

        /* Head-then-content, the same shape the Sun's-fuel bar and the speed rows use. It was
           a tinted rounded pill, which made it the only boxed thing on the tab and therefore
           the only thing that looked borrowed from somewhere else. */
        .cd-galcentre { margin-top: 1.1rem; }
        .cd-galcentre-head {
            font-size: 0.62rem;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            color: var(--text-dim);
            margin-bottom: 0.35rem;
        }
        .cd-galcentre-row {
            display: flex;
            align-items: baseline;
            gap: 0.55rem;
        }
        .cd-galcentre-dot {
            flex-shrink: 0;
            align-self: center;
            width: 0.5rem;
            height: 0.5rem;
            border-radius: 50%;
            background: #fff;
            box-shadow: 0 0 12px 3px rgba(255,255,255,0.5);
        }
        .cd-galcentre-val { font-size: 0.76rem; color: var(--text-secondary); }
        .cd-galcentre-val strong { color: var(--accent-purple); font-weight: 600; }
        .cd-galcentre-far {
            margin-left: auto;
            font-size: 0.66rem;
            color: var(--text-dim);
            font-variant-numeric: tabular-nums;
        }

        /* ── The drawn sky heroes ──
              Wider than tall, because a sky is. Pixelated scaling so the bands stay hard-edged
              at display size — the whole point is that it is the same hand as the planets. */
        /* Both heroes are square canvases clipped to a disc IN THE DRAWING, so there is no
           border-radius here — rounding the element would round the square pixels themselves
           and read as a rendering fault rather than as a shape. */
        .cd-hero-sky-px,
        .cd-galaxy-px,
        .cd-year-earth {
            display: block;
            width: 70px;
            height: 70px;
            margin: 0 auto 0.35rem;
            image-rendering: pixelated;
            image-rendering: crisp-edges;
        }
        .cd-hero-sky-px { filter: drop-shadow(0 4px 14px rgba(0,0,0,0.5)); }
        .cd-galaxy-px { filter: drop-shadow(0 0 16px rgba(120,150,255,0.28)); }

        /* ── The sun/moon disc ──
              One glyph for the whole day, recoloured to the sky's colour for the current
              stage. Replaces the emoji, which at hero size was a photograph of some buildings
              and at bar size was an orange smudge. Works identically at both. */
        .cd-hero-sky {
            display: inline-block;
            line-height: 1;
            /* text-shadow: 0 0 18px currentColor; */
        }
        .cd-hero-sky.sky-early-morning { color: #ffd79a; }
        .cd-hero-sky.sky-late-morning  { color: #fff4cf; }
        .cd-hero-sky.sky-afternoon     { color: #ffc978; }
        /* Retired keys — a cached payload from before the morning split still colours. */
        .cd-hero-sky.sky-dawn          { color: #f3a6a0; }
        .cd-hero-sky.sky-morning       { color: #ffd79a; }
        .cd-hero-sky.sky-midday        { color: #fff4cf; }
        .cd-hero-sky.sky-early-evening { color: #ff9a5e; }
        .cd-hero-sky.sky-late-evening  { color: #c98fdc; }
        .cd-hero-sky.sky-night         { color: #8ea0e8; }
        .cd-hero-sky.sky-small-hours   { color: #7280d8; }
        .cd-hero-sky.sky-before-dawn   { color: #9aabe8; }

        /* (.cd-nameday is gone — see the note in core.js. The Oracle still reads the name day
            before it writes; the dashboard no longer prints it as a labelled row.) */

        /* The named moon, as one line under the Moon tab's so-what. */
        /* Footer of the Tonight block now, not a caption on a tab of its own — so it needs the
           rule above it that separates it from the last planet row. */
        .cd-namedmoon {
            margin-top: 0.6rem;
            padding-top: 0.55rem;
            border-top: 1px solid rgba(255,255,255,0.045);
            /* text-align: center; */
            font-size: 0.72rem;
            color: var(--text-secondary);
        }
        .cd-namedmoon strong { color: var(--accent-amber); font-weight: 600; }

        /* Which sign it turns full in, and when and which way to look — four values in a row
           rather than in a sentence. Wraps as whole facts instead of mid-phrase, which is the
           point of the flex: a broken line here would read as prose again. */
        .cd-moonwhere {
            display: flex;
            flex-wrap: wrap;
            align-items: baseline;
            gap: 0 0.45rem;
            margin-top: 0.4rem;
            font-size: 0.72rem;
            line-height: 1.6;
            color: var(--text-secondary);
        }
        .cd-moonwhere strong { color: var(--accent-cyan); font-weight: 600; }

        /* ── The meaning, as two terms ──
              Body and sign, side by side, so two open planets can be compared without reading
              two sentences. Wraps as whole terms, never mid-phrase. */
        /* Stacked, not flowed. These were two terms side by side with the planet's definition
           on a line beneath, which read as though the definition belonged to whichever term was
           nearest it — usually the sign, which never has one. One term per row, each carrying
           its own gloss indented under it, and the ambiguity has nowhere to live. */
        .cd-meaning-terms {
            display: flex;
            flex-direction: column;
            gap: 0.45rem;
            margin-bottom: 0.35rem;
        }
        .cd-meaning-term { font-size: 0.78rem; color: var(--text-secondary); }
        .cd-meaning-term b { color: var(--text-primary); font-weight: 600; }
        /* The long form, tied to the term above it by indent rather than by proximity. */
        .cd-meaning-sub {
            display: block;
            margin-top: 0.1rem;
            padding-left: 0.7rem;
            border-left: 1px solid rgba(167,139,250,0.2);
            font-size: 0.7rem;
            line-height: 1.45;
            color: var(--text-dim);
            text-wrap: pretty;
        }
        /* The long form, demoted — present for whoever wants it, quiet enough to skip. */
        .cd-meaning-gloss { font-size: 0.72rem !important; color: var(--text-dim) !important; }
        .cd-moonwhere-sep { color: var(--text-dim); opacity: 0.62; }

        /* ── "So what?" — the applied line under each cycle ──
           The blocks above it answer "where are we", which is trivia on its own. This answers
           "why would I care", so it's the one thing on the tab that gets a rule down its side
           and a label: it should read as advice, not as another grey footnote. */
        /* A fold now, not a filled card. There is one of these per tab and each was two or
           three lines of advice standing between the reader and the bar they came to look at.
           Shut, it is a single dim line; open, it is exactly what it always was. */
        /* (The .cd-sowhat family is gone. Its last two users were the zodiac dial's
           "Why it drifts" and "How the top-down view is drawn" folds; both moved to the About
           modal, which is where this page keeps the long version of every mechanism. The
           original "So what?" lines the classes were built for went earlier.) */

        /* (.sunset-meter and its pips were here: "Sunset quality" as five pips lit to the same
            count as the five stars in the row's summary, tinted from the palette the chips
            already show. One rating printed twice; cut 29 Sept. Its hedge moved into the author
            line below.) */

        /* ── Who made this forecast, and how sure ──
              One quiet line under the palette. It exists because the card's whole claim changed:
              the forecast used to come from a fixed set of thresholds on the device, and it is
              now a prediction a model made this morning from the three cloud layers, the
              visibility and the dew point. That is the most interesting fact on the card and it
              is invisible in the forecast itself, so it gets said — with the hedge on a doubtful
              evening, and the model that answered. Deliberately small and quiet: provenance, not
              a headline. */
        .sunset-author {
            margin-top: 0.55rem;
            font-size: 0.62rem;
            letter-spacing: 0.04em;
            color: var(--text-dim);
            text-wrap: pretty;
        }
        .sunset-author-model {
            margin-left: 0.25rem;
            letter-spacing: 0.06em;
            text-transform: uppercase;
            opacity: 0.82;
        }

        /* (.cd-two-forecasts is gone, and so is .cd-read-fallback that replaced it. The first
            printed the Oracle's score and the device algorithm's score as a two-row table and
            explained the gap; the second cut that to one quiet line naming itself as the
            off-network fallback. Both were attempts to make a second number sit politely under
            the first, and there is no polite way to do that — a reader does not see two
            forecasters, they see the Oracle contradicting itself. The device's score is off the
            page entirely now; it is still on the insight blob as `device_score` and still what
            the lights run off-network. See buildSunsetBreakdown in core.js.) */

        /* The one line that says what to do about the number. */
        .sunset-verdict {
            display: block;
            margin-top: 0.45rem;
            font-size: 0.72rem;
            line-height: 1.5;
            color: var(--text-secondary);
            text-wrap: pretty;
        }
        /* The palette's caption — what the four colours do, and when. It sits directly under the
           chips it describes since 29 Sept, so it is plain text now, not a box of its own: a
           caption in a frame reads as a separate card. */
        .cd-sunset-insight {
            margin-top: 0.45rem;
        }
        .cd-sunset-insight p {
            font-size: 0.72rem;
            color: var(--text-secondary);
            line-height: 1.55;
            margin-bottom: 0.35rem;
            text-wrap: pretty;
        }
        .cd-sunset-insight p:last-child { margin-bottom: 0; }
        .oracle-source-tag {
            font-size: 0.66rem;
            letter-spacing: 0.06em;
            text-transform: uppercase;
            color: var(--text-dim);
            opacity: 0.82;
            margin-top: 0.2rem;
        }
        /* A reading written with no model reachable. It stays quiet — this is a footnote, not
           an error banner — but amber rather than grey, because "nothing answered today" is a
           different claim from "gemini answered" and shouldn't look identical to it. */
        .oracle-source-tag.fallback {
            color: var(--accent-amber);
            text-transform: none;
            letter-spacing: 0.02em;
            opacity: 0.75;
        }

        /* ── Planets strip ──
           The tracks are defined here, on the list, not on each row: every row was its own
           grid container, so a row carrying three badges resolved its own 1fr columns
           narrower than a row carrying none, and nothing lined up down the page. The rows
           borrow these tracks via subgrid, so the badge column is as wide as the widest
           badge set and the other three columns are identical on every row. */
        .cd-planets {
            /* display: grid; */
            /* grid-template-columns: minmax(5.5rem, 1fr) minmax(5.5rem, 1fr) 3.6rem auto; */
            gap: 0.15rem 1rem;
            font-size: 0.82rem;
            margin-bottom: 0.5rem;
            /* padding: 0.8rem 0;
            border-top: 1px solid rgba(167,139,250,0.07);
            border-bottom: 1px solid rgba(167,139,250,0.07); */
        }
        
        @media (min-width: 480px) {
            .cd-planets {
                /* grid-template-columns: 1fr; single column so the tap-to-open detail spans full width */
            }
        }
        
        /* Fixed column track (name · sign · degrees · flags) so the values line up down the
           list and the eye can scan one column at a time, instead of every row wrapping to
           its own width. */
        .cd-planet-row {
            /* grid-column: 1 / -1; */
            display: flex;
            /* grid-template-columns: subgrid; */
            align-items: center;
            gap: 0.5rem;
            cursor: pointer;
            padding: 0.34rem 0.4rem;
            margin: 0 -0.4rem;
            /* border-radius: 6px; */
            transition: background 0.15s ease, border-left 0.15s ease;
            border-left: 2px solid transparent;
        }
        /* The inline detail spans the whole row rather than sitting in the first column. */
        .cd-planet-detail { grid-column: 1 / -1; }
        /* Pre-subgrid browsers keep the old per-row tracks — imperfect alignment, but every
           row still renders in the right order with the right widths. */
        @supports not (grid-template-columns: subgrid) {
            .cd-planets { grid-template-columns: 1fr; }
            .cd-planet-row {
                grid-template-columns: minmax(5.5rem, 1fr) minmax(5.5rem, 1fr) 3.6rem auto;
            }
        }
        /* Each planet is its own <details> now — see the loop in core.js. The row is the
           summary, so it takes the pointer and the marker suppression.

           The hairline is the same one .ft-row uses in the foretelling timeline, and for the
           same reason: eight collapsible rows with nothing between them read as one paragraph
           of text at a glance, so the eye has no idea where a row starts, which matters twice
           as much when any of them can be open. Two lists of tappable rows on one page should
           not be two different objects. */
        .cd-planet-item { display: block; }
        .cd-planet-item + .cd-planet-item,
        .cd-planet-row { list-style: none; }
        .cd-planet-row::-webkit-details-marker { display: none; }
        .cd-planet-row:hover {
            background: rgba(167,139,250,0.05);
        }
        .cd-planet-chev {
            margin-left: 0.4rem;
            font-size: 0.7rem;
            color: var(--text-dim);
            transition: transform 0.18s ease;
            flex-shrink: 0;
        }
        .cd-planet-item[open] > .cd-planet-row .cd-planet-chev { transform: rotate(90deg); }
