/* public/css/20-dashboard.css — The dashboard, and the shared visual grammar
 *
 * 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.
 *
 * The biggest of the seven, and the one to read first when adding a block. The card, subhead,
 * fold, tab and bar shapes defined here are what CLAUDE.md means by "the visual grammar" — a new
 * block should join these rather than invent a shape. Also the dial and the planet fold.
 */
        /* ======================
           COSMIC DASHBOARD
           ====================== */

        /* ── Weather-widget card shell ── */
        .cosmic-dashboard-card {
            background: linear-gradient(160deg, rgba(12,14,26,0.98) 0%, rgba(18,20,36,0.95) 100%);
            border: 1px solid rgba(167,139,250,0.15);
            border-radius: 8px;
            padding: 1.6rem 1.4rem 1.2rem;
            margin-bottom: 1rem;
            position: relative;
            overflow: hidden;
            /* animation: fadeIn 0.5s ease both; */
            box-shadow: 0 8px 40px rgba(0,0,0,0.45), inset 0 1px 0 rgba(255,255,255,0.04);
        }
        .cosmic-dashboard-card::before {
            content: '';
            position: absolute;
            top: 0; left: 10%; right: 10%;
            height: 1px;
            background: linear-gradient(90deg, transparent, rgba(167,139,250,0.5), transparent);
        }
        .cosmic-dashboard-card::after {
            content: '';
            position: absolute;
            bottom: -60px; right: -60px;
            width: 180px; height: 180px;
            border-radius: 50%;
            background: radial-gradient(circle, rgba(167,139,250,0.06) 0%, transparent 70%);
            pointer-events: none;
        }

        /* Arcane heading */
        /* The dashboard card heading — "Cycles", "Planets", "The Oracle Foretells", the sign name.
           (Restored: a dead-CSS sweep removed this rule's declaration block because the LAST
           selector in the list, .insight-card h2, was dead — leaving the two live selectors
           above it dangling with no body, and the card headings unstyled. The dead selector is
           gone from the list; the rule is otherwise exactly as it was.) */
        .cosmic-dashboard-card h2,
        .card h2 {
            font-size: 0.72rem;
            letter-spacing: 0.22em;
            text-transform: uppercase;
            color: rgba(167,139,250,0.5);
            text-align: center;
            font-weight: 500;
            margin-bottom: 1.2rem;
        }

        /* ── Hero blocks — Moon, Sun, Earth. One shape repeated three times: big glyph, name,
              quiet sub-line, then a segmented bar underneath for that hero's cycle. ── */
        .cd-hero {
            display: flex;
            align-items: flex-start;
            justify-content: space-between;
            gap: 1rem;
            margin-bottom: 0.9rem;
        }
        .cd-hero-fig {
            flex: 1;
        }
        .cd-hero-glyph {
            font-size: 3rem;
            line-height: 1;
            display: block;
            margin-bottom: 0.3rem;
            filter: drop-shadow(0 0 12px rgba(167,139,250,0.4));
        }
        .cd-hero-name {
            font-size: 0.82rem;
            color: var(--text-primary);
            font-weight: 600;
            margin-bottom: 0.1rem;
        }
        .cd-hero-sub {
            font-size: 0.76rem;
            color: var(--text-dim);
        }
        /* The quantity inside the sub-line, lit. "1h 29m of daylight left" is a sentence with
           one fact in it, and set flat the eye had to read the words to find the number. Bigger
           and at full contrast, the figure is what you land on and the words become its unit.
           Tabular so it does not jitter as the minutes tick down on a repaint. */
        .cd-hero-figure {
            font-size: 0.95rem;
            font-weight: 600;
            color: var(--text-primary);
            font-variant-numeric: tabular-nums;
        }
        /* Solo hero: nothing balances it on the right, so it sits centred. */
        .cd-hero-solo { justify-content: center; text-align: center; }
        .cd-hero-solo .cd-hero-fig { flex: 0 1 auto; }

        /* The line naming what the bar above it just counted. */
        .cd-hero-caption {
            display: flex;
            flex-wrap: wrap;
            align-items: baseline;
            justify-content: center;
            gap: 0.2rem 0.5rem;
            margin-top: 0.55rem;
            text-align: center;
            text-wrap: balance
        }
        .cd-hero-caption-title {
            font-size: 0.72rem;
            color: var(--text-primary);
            font-weight: 600;
        }
        .cd-hero-caption-sub {
            font-size: 0.68rem;
            color: var(--text-dim);
        }

        /* ── Local conditions strip — device-led weather snapshot, deliberately quiet ── */
        .cd-conditions {
            display: flex;
            flex-wrap: wrap;
            align-items: baseline;
            justify-content: center;
            gap: 0.35rem 0.7rem;
            margin-bottom: 1.1rem;
            font-size: 0.74rem;
            color: var(--text-dim);
        }
        .cd-conditions-line { color: var(--text-secondary); }
        .cd-conditions-stamp { color: var(--text-dim); opacity: 0.75; font-size: 0.68rem; }
        /* Conditions sit as a footer inside the opened sunset fold — divider above, no big
           bottom gap. */

        /* ── Section subheadings inside the Cosmic Conditions card (Planets vs Earth & Space) ── */
        .cd-subhead {
            font-size: 0.7rem;
            text-transform: uppercase;
            letter-spacing: 0.14em;
            color: var(--text-dim);
            margin: 1.5rem 0 0.7rem;
            padding-bottom: 0.4rem;
            border-bottom: 1px solid var(--border);
        }
        /* (cd-subhead is now only worn by the two fold summaries — the in-card section heads it
            was written for became tabs and card titles.) */

        /* ── Cycle tabs — one hero at a time. Same switch as the planets' Meaning/Telemetry
              control, widened to fill the card so three options stay tappable. ── */
        .cd-tabs {
            display: flex;
            width: 100%;
            margin-bottom: 1.1rem;
        }
        .cd-tab-btn { flex: 1 1 0; }
        .cd-tab-panel { display: none; animation: fadeIn 0.5s ease both; }
        .cd-tab-panel.active { display: block; }

        /* Set for the two frames around a background repaint (see paintContainer in core.js).
           A fade is right when *you* did something — switched tab, opened a planet. It's wrong
           when the page quietly refetched, where it reads as the whole screen flinching. */
        .cd-no-entry-anim,
        .cd-no-entry-anim * { animation: none !important; }

        /* Planets card header — title and the view switch on one line. */
        /* ── Stacked and centred, like the card above ──
              This was a flex row with the h2 pushed left and the Meaning/Telemetry switch
              pushed right, which left "Where They Are" (now "Planets") as the only left-aligned
              heading on the page — sitting directly under "✧ Where We Are ✧" (now "✧ Cycles ✧"),
              which is centred. The two cards
              are deliberately a matched pair and the headings were the one thing giving that
              away. Column now: title centred, its control centred underneath, exactly the shape
              the cycles card makes with its tab strip. */
        .cd-planets-head {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 0.7rem;
            margin-bottom: 1rem;
        }
        .cd-planets-head h2 { margin-bottom: 0; }

        /* ── "what does 'in Leo' mean?" — the dial, one tap from the sign names ──
              Every row on this card ends in a sign name and nothing on the page said what a
              sign IS; a colleague of Dan's read it and asked out loud. The answer is the zodiac
              dial (see #dial-modal), which has been either the largest thing on the page or
              four screens into About, and is now behind this.

              Deliberately quiet: it is a question somebody either has or doesn't, and the rows
              below are what the card is for. Sits in the head's centred column, so it needs no
              layout of its own — the parent's gap places it. Underlined rather than boxed,
              because a box here would read as a third control on a card that already has the
              sign block at its foot, and a question is a link-shaped thing. */
        .cd-dial-open {
            border: none;
            background: none;
            padding: 0;
            font-family: var(--mono);
            font-size: 0.68rem;
            color: var(--text-dim);
            text-decoration: underline;
            text-decoration-color: rgba(37,180,243,0.4);
            text-underline-offset: 3px;
            cursor: pointer;
        }
        .cd-dial-open:hover { color: var(--accent-cyan); text-decoration-color: var(--accent-cyan); }

        /* ── Collapsible Earth & Space block — one quiet line when nothing's happening ── */
        /* ══ The one fold shape ══
              Was .cd-space-fold, named after the only two things using it. The "Where They Are"
              card grew three more sections — the planet grid, Tonight, and the sign report —
              and each had invented its own way of introducing itself: a bordered subhead here,
              a micro-label with a top rule there. Five sections, four grammars, on one card.
              This is now the grammar for all of them, so a section head looks like a section
              head wherever it appears and the chevron always means the same thing. */
        .cd-fold { margin-top: 1.5rem; }
        .cd-fold-summary {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 0.6rem;
            cursor: pointer;
            list-style: none;
            margin-top: 0;
        }
        .cd-fold-summary::-webkit-details-marker { display: none; }
        .cd-fold-summary::after {
            content: '▸';
            font-size: 0.7rem;
            transition: transform 0.15s ease;
        }
        .cd-fold[open] .cd-fold-summary::after { transform: rotate(90deg); }
        .cd-fold-state {
            margin-left: auto;
            font-size: 0.62rem;
            letter-spacing: 0.06em;
            color: var(--text-dim);
            text-transform: none;
        }
        .cd-fold-state.alert { color: var(--accent-amber); }
        /* The peek, when there is something in there worth opening for. A shut fold has to say
           whether it is worth the tap — "2 planets · moon up" is a reason, "nothing up" is an
           answer, and both beat a bare chevron. */
        .cd-fold-state.lit { color: var(--text-secondary); }
        .cd-fold-body { padding-top: 0.7rem; }
        /* The sign report is the reader's own information, so its head keeps the amber that
           means "about you" everywhere else on this page. */
        .cd-yoursign > .cd-fold-summary { color: var(--accent-yours); }
        .cd-yoursign > .cd-fold-summary .cd-fold-state.lit { color: var(--accent-yours); }

        /* ══ The dial — twelve directions from Earth ══════════════════════════════════════
              Opens the sign card. The planet rows below it each show a passage through three
              cells; this shows that all twelve passages are readings off one circle, which no
              number of bars can say. See buildZodiacDial in core.js for why it runs clockwise
              from the top and why the labels are letters rather than glyphs. */
        .cd-dial { margin: 0 0 1.1rem; }
        /* ── Bigger ──
              It was min(230px, 74vw), which on a phone left a quarter of the card empty on
              either side of the one genuinely graphic thing on it. There was never a reason for
              that: the diagram is the subject of this card, the sector labels are three letters
              at 0.5rem and want the room, and every planet dot is 3.8px on a 200-unit viewBox.
              Capped so it cannot outgrow the card on a desktop, where 92vw would be enormous. */
        .cd-dial-plot {
            position: relative;
            width: min(340px, 92vw);
            margin: 0 auto;
            aspect-ratio: 1;
        }
        .cd-dial-svg { display: block; width: 100%; height: 100%; overflow: visible; }
        /* Scenery again. The sectors briefly carried the constellation myths as a tap-detail and
           wore a cursor, a hover lift and a focus ring to say so; the myths are gone, so the
           affordances went with them rather than being left promising something. They are what
           they were always best as: the fixed scale the two vantage points are measured
           against. */
        .cd-dial-sector { transition: fill-opacity 0.25s ease; }
        /* ── The vantage toggle ──
              Two views of one instant: bearings from Earth, or the solar system to scale. The
              frame buttons only exist in the second, because "how far out do you want to see"
              is a question the geocentric view has no answer to. */
        .cd-dial-controls {
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            justify-content: center;
            gap: 0.3rem 0.55rem;
            margin: 0 0 0.6rem;
        }
        .cd-dial-controls:empty { display: none; }
        .cd-dial-views,
        .cd-dial-frames { display: flex; align-items: center; gap: 2px; }
        /* Names what the buttons beside it control. Without it, "to Mars / to Pluto" reads as a
           destination rather than a zoom — the same small-uppercase-label-before-the-value the
           rest of the page uses. */
        .cd-dial-ctl-label {
            margin-right: 0.35rem;
            font-size: 0.62rem;
            letter-spacing: 0.12em;
            text-transform: uppercase;
            color: var(--text-dim);
            opacity: 0.75;
        }
        .cd-dial-btn {
            font-family: inherit;
            font-size: 0.62rem;
            letter-spacing: 0.05em;
            text-transform: uppercase;
            color: var(--text-dim);
            background: rgba(8,10,20,0.5);
            border: 1px solid rgba(255,255,255,0.09);
            border-radius: 7px;
            padding: 0.26rem 0.6rem;
            cursor: pointer;
            transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
        }
        .cd-dial-btn:hover { color: var(--text-secondary); border-color: rgba(255,255,255,0.18); }
        .cd-dial-btn.active {
            color: var(--text-primary);
            border-color: rgba(94,234,212,0.42);
            background: rgba(94,234,212,0.1);
        }
        /* The frame buttons answer a follow-up question, so they sit a step quieter than the
           two that choose the view itself. */
        .cd-dial-btn.small { font-size: 0.62rem; padding: 0.2rem 0.45rem; opacity: 0.8; }
        .cd-dial-label {
            font-size: 8px;
            letter-spacing: 0.04em;
            fill: var(--text-dim);
            text-transform: uppercase;
            pointer-events: none;
        }
        /* The ordinal — "Libra is seven". Bigger than the name, because the number is the part
           worth remembering and the letters are only there to say which number this is. */
        .cd-dial-num {
            font-size: 10px;
            font-weight: 700;
            fill: var(--text-secondary);
            pointer-events: none;
        }
        /* Your own sector is the one thing on this card that has to be findable in a glance,
           so it takes the sign colour the rest of the page already uses for "about you". */
        .cd-dial-label.mine,
        .cd-dial-num.mine { fill: var(--accent-yours); font-weight: 700; }
        /* The spoke is the whole argument — it turns a dot at a bearing into a direction you
           could stand in the garden and point along. Faint, because there are ten of them. */
        /* The spoke is the whole argument — it turns a dot at a bearing into a direction you
           could stand in the garden and point along. It runs all the way to the sign ring now,
           so it visibly lands somewhere; that extra length is paid for by dropping the opacity,
           because ten lines reaching the rim would otherwise read as a starburst. */
        .cd-dial-spoke { stroke-width: 0.9; stroke-opacity: 0.16; }
        .cd-dial-spoke.focus { stroke-width: 1.3; stroke-opacity: 0.85; }
        .cd-dial-dot { stroke: rgba(6,6,12,0.75); stroke-width: 1; cursor: pointer; }
        .cd-dial-dot.yours { stroke: var(--accent-yours); stroke-width: 1.6; }
        .cd-dial-dot.focus { stroke: rgba(255,255,255,0.75); stroke-width: 1.4; }
        .cd-dial-dot.moon { cursor: pointer; }
        /* Us, in the top-down view. Not clickable — Earth has no sign to look up, it is the
           place every other reading on this diagram is taken from. */
        .cd-dial-dot.vantage { cursor: default; stroke: rgba(255,255,255,0.5); stroke-width: 1.2; }
        .cd-dial-dot:focus-visible,
        .cd-dial-spoke:focus-visible { outline: 2px solid var(--accent-cyan); outline-offset: 2px; }
        /* Orbits, drawn as circles through each body's current distance. Faint: they are the
           graph paper, and the bodies standing on them are the reading. */
        .cd-dial-orbit {
            fill: none;
            stroke: rgba(255,255,255,0.14);
            stroke-width: 0.6;
        }
        /* At the outer frame, everything from Mercury to Mars — us included — fits inside this.
           Dashed, so it reads as a boundary drawn round something rather than another orbit. */
        .cd-dial-huddle {
            fill: rgba(94,234,212,0.07);
            stroke: rgba(94,234,212,0.4);
            stroke-width: 0.7;
            stroke-dasharray: 2 2;
        }
        /* The real line of sight, from where we actually are — and the same bearing taken from
           the middle of the ring, which is the one that reaches the sectors. Always parallel. */
        .cd-dial-sight { stroke-width: 1.4; stroke-opacity: 0.9; }
        .cd-dial-bearing { stroke-width: 1.1; stroke-opacity: 0.5; stroke-dasharray: 3 3; }
        /* The body at the centre IS the view: Earth from here, the Sun from above. The real
           pixel disc rather than a drawn circle, so it is the same object as the one in the
           grid. Width and height come from the markup — they change with the frame. */
        .cd-dial-centre {
            position: absolute;
            top: 50%;
            left: 50%;
            width: 15%;
            height: 15%;
            transform: translate(-50%, -50%);
            image-rendering: pixelated;
            image-rendering: crisp-edges;
        }
        /* ── Why these are prefixed with .cd-dial ──
              The dial is painted into the About modal now, which means every paragraph in it
              sits inside an .about-card — and `.about-card p` is (0,1,1) while each of these
              rules is a single class, (0,1,0). Left bare, the focus line, the scale note and
              the tap hint would all lose and come out as 0.8rem About-modal body prose.
              The ancestor makes them (0,2,0), which wins. It is a specificity fix and nothing
              else: no values changed, so there is still one place to edit each of them. */
        /* The one line that says something different in each view: a bearing in one, a position
           and the reason behind it in the other. */
        .cd-dial .cd-dial-focus {
            display: flex;
            align-items: baseline;
            justify-content: center;
            flex-wrap: wrap;
            gap: 0.3rem;
            margin: 0.55rem auto 0;
            max-width: 30rem;
            font-size: 0.63rem;
            line-height: 1.5;
            text-align: center;
            color: var(--text-dim);
            text-wrap: pretty;
        }
        .cd-dial-focus strong { color: var(--text-secondary); font-weight: 600; }
        .cd-dial-focus-dot {
            width: 7px;
            height: 7px;
            border-radius: 50%;
            align-self: center;
            flex: 0 0 auto;
        }
        /* The sentence the outer frame cannot draw for itself. Quieter than the focus line,
           because it describes the picture rather than anything you picked. */
        .cd-dial .cd-dial-note {
            margin: 0.35rem auto 0;
            max-width: 28rem;
            font-size: 0.62rem;
            line-height: 1.55;
            text-align: center;
            color: var(--text-dim);
            opacity: 0.85;
            text-wrap: pretty;
        }
        .cd-dial .cd-dial-caption {
            margin: 0.7rem auto 0;
            max-width: 32rem;
            text-align: center;
            font-size: 0.66rem;
            line-height: 1.6;
            color: var(--text-secondary);
            text-wrap: pretty;
        }
        .cd-dial .cd-dial-caption p { margin: 0 0 0.4rem; }
        .cd-dial .cd-dial-caption p:last-child { margin-bottom: 0; }
        .cd-dial-caption strong { color: var(--text-primary); font-weight: 600; }
        /* The two taps, as a key to the diagram rather than a sentence about it. Same
           small-dim-uppercase treatment as .cd-dial-ctl-label above the plot, so the thing
           under the picture and the thing over it read as the same kind of annotation. */
        .cd-dial .cd-dial-hint {
            margin-top: 0.45rem !important;
            font-size: 0.62rem;
            letter-spacing: 0.1em;
            text-transform: uppercase;
            color: var(--text-dim);
            opacity: 0.7;
        }
        /* (.cd-dial-caveat is gone. It styled the eclipse method note at the foot of the
           "Further ahead" fold — a paragraph about the machinery under a list of dates, on a
           fold people open to find out when the next eclipse is. It is in the About modal now,
           with the rest of the ledger.) */

        /* (The .cd-dial-lore family is gone with the constellation myths — first a standing
           list under the diagram, then a tap-detail on the sectors, now nothing. See signs.js.) */

        /* ── A fold that ends a cycle tab, not one that heads a section ──
              Day and Year both finish on the purple "So what?" fold. Galaxy finishes on
              "☉ The numbers", which is the same gesture in the same card in the same position —
              and it was wearing .cd-subhead, the bordered grey rule the PLANETS card uses to
              introduce a section. So switching to the third tab changed the furniture for no
              reason the reader could see.
              It keeps the .cd-fold layout, because the peek on the right still needs the
              space-between row. Only the type changes, to the so-what label's. */
        /* (.cd-daytheme-lens / -why / -anchors lived here: the body of the day's-theme fold at
            the foot of the reading card. The fold was cut — its one line of reason restated
            the reading on all five mornings it was read back. See "Today's theme — cut" in
            core.js.) */

        /* ── The record, closing the Day tab under the sunset ──
              Same .cd-fold-quiet shell the theme fold used to wear, for the same reason: background
              material, shut on arrival, its state on the summary line. Only the body is new.

              A four-column grid rather than a table. The columns are day, lens, score, palette
              name — fixed for the three short ones so the scores line up into a column you can
              read down, which is the whole point of printing a fortnight at once. The palette
              name takes the remainder and truncates, because it is the one field with no
              length discipline (the Oracle names it in two or three words, usually).

              Type floors observed: nothing here is below 0.62rem and nothing sits under 0.62
              opacity. That is easy to reintroduce one rule at a time in a dense block like this,
              and this block is denser than most. */
        .cd-record-rows {
            display: flex;
            flex-direction: column;
            gap: 0.28rem;
        }
        .cd-record-row {
            display: grid;
            /* Four: day, word, score, palette name. (A fifth, what the airfield saw, came and went
               on 29 Sept — the check moved to "forecast vs sky" in the sunset row.) */
            grid-template-columns: 3.4rem 1fr 1.9rem minmax(0, 5.5rem);
            gap: 0.5rem;
            align-items: baseline;
            font-size: 0.66rem;
            line-height: 1.4;
        }
        .cd-record-day {
            color: var(--text-dim);
            white-space: nowrap;
        }
        .cd-record-theme {
            color: var(--text-secondary);
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        /* Right-aligned so the scores form a column. Banded to the same three steps the trend
           bars use, so a score means the same thing in both places on one tab. */
        .cd-record-score {
            text-align: right;
            font-variant-numeric: tabular-nums;
        }
        .cd-record-score.high { color: var(--accent-amber); }
        .cd-record-score.mid  { color: var(--text-secondary); }
        .cd-record-score.low  { color: var(--text-dim); }
        .cd-record-score.none { color: var(--text-dim); opacity: 0.7; }
        .cd-record-palette {
            color: var(--text-dim);
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        .cd-record-notes {
            margin-top: 0.6rem;
            padding-top: 0.5rem;
            border-top: 1px solid var(--border);
        }
        .cd-record-note {
            margin: 0 0 0.25rem;
            font-size: 0.62rem;
            line-height: 1.45;
            color: var(--text-dim);
            text-wrap: pretty;
        }
        .cd-record-note:last-child { margin-bottom: 0; }

        .cd-fold-quiet { margin-top: 0.7rem; }
        .cd-fold-quiet > .cd-fold-summary {
            font-size: 0.65rem;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            color: rgba(167,139,250,0.8);
            transition: color 0.2s ease;
        }
        .cd-fold-quiet > .cd-fold-summary:hover { color: var(--accent-purple); }
        .cd-fold-quiet > .cd-fold-summary::after { font-size: 0.62rem; margin-left: 0.3rem; }
        .cd-fold-quiet > .cd-fold-body { padding-top: 0.45rem; }
        /* Segmented switch — two mutually exclusive views, active one filled. Reads as
           "this replaces that", which a lone checkbox did not. */
        .cd-mode-switch {
            display: inline-flex;
            border: 2px solid var(--border);
            border-radius: 20px;
            /* padding: 2px;
            gap: 2px; */
        }
        .cd-mode-opt {
            font: inherit;
            font-size: 0.7rem;
            letter-spacing: 0.04em;
            text-transform: none;
            color: var(--text-dim);
            background: transparent;
            border: 0;
            border-radius: 20px;
            padding: 0.18rem 0.6rem;
            cursor: pointer;
            white-space: nowrap;
            transition: background 0.15s ease, color 0.15s ease;
        }
        .cd-mode-opt:hover { color: var(--text-secondary); }
        .cd-mode-opt.active {
            background: rgba(167,139,250,0.16);
            color: var(--accent-purple);
        }
        /* Same four roles as the planets grid below (see the block by .cd-planet-row.active).
           These rows announce things that HAVEN'T HAPPENED YET, so the whole card belongs to
           the CHANGE COMING family — purple for a planet turning, cyan for one changing sign —
           and amber is reserved for the rows that are about the reader. It previously ran
           amber / green / cyan / purple across four row types, which meant the one row in your
           own sign had no colour left to distinguish it. */
        /* (Two .cd-station-alert selectors led this list and have gone with that whole
           retired component — they were dangling here after the same bad sweep that took the
           card-heading rule below.) */
        /* The trigger for the sign picker — a dotted underline so it reads as something you
           can question, without turning into a full button mid-sentence. */
        .cd-station-yours {
            font: inherit;
            font-weight: 600;
            color: var(--accent-yours);
            background: transparent;
            border: 0;
            border-bottom: 1px dotted var(--accent-yours);
            padding: 0;
            cursor: pointer;
            font-size: 12px;
        }
        .cd-station-yours:hover { border-bottom-style: solid; }

        .cd-planet-meaning, .cd-planet-telemetry {
            margin: 0.6rem 0;
            padding: 0.6rem;
            /* border: 1px solid rgba(167,139,250,0.18); */
            border-top: 0;
            /* border-radius: 10px; */
            /* background: rgba(167,139,250,0.04); */
        }

        /* (Where-to-look is a compact chip now — see .cd-where-chip in the planet-fold block.
            The old full-sentence .cd-planet-where treatment was cut as too wordy for a fold
            that's meant to read at a glance.) */

        /* The numbers, one tap further in — a quiet sub-fold under the meaning. Reset the
           telemetry panel's own top margin/border since the fold already frames it. */
        .cd-tel-fold { margin-top: 0.5rem; }
        /* Same treatment as the "So what?" fold — these are the same gesture (one tap for the
           words you asked for) and were wearing two different costumes. */
        .cd-tel-fold-summary {
            display: inline-block;
            font-size: 0.65rem;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            color: rgba(167,139,250,0.8);
            cursor: pointer;
            list-style: none;
            border-bottom: 1px dotted rgba(167,139,250,0.35);
            padding-bottom: 1px;
            transition: color 0.2s ease;
        }
        .cd-tel-fold-summary::-webkit-details-marker { display: none; }
        .cd-tel-fold-summary::after { content: ' ▸'; }
        .cd-tel-fold[open] > .cd-tel-fold-summary::after { content: ' ▾'; }
        .cd-tel-fold-summary:hover { color: var(--accent-purple); }
        .cd-tel-fold { margin-top: 0.6rem; }
        .cd-tel-fold .cd-planet-telemetry {
            margin: 0.4rem 0 0.2rem;
            padding-top: 0.6rem;
        }

        /* ══ The planet fold, built like a tab panel ══════════════════════════════════════
              A Day/Year tab in miniature, and it works for the same reason: almost nothing to
              read, and a stepped bar that places you. 70px disc, one word, a where-to-look chip,
              the twelve-sign bar, the coordinate pill. The wordy parts are folded away. */
        /* Space above and below, so the opened fold is clearly its own thing and not welded to
           the rows either side of it. */
        .cd-planet-detail { padding: 1.5rem 0.1rem 3rem; }
        .cd-planet-fold { text-align: center; }
        .cd-planet-hero { margin-bottom: 0.6rem; }
        /* 50, not 70. At 70 the disc dominated a fold whose job is the bar and the words
           under it; at 50 it reads as an illustration rather than a portrait. */
        /* ── Per-body hero size ──
              The disc renderer keeps every body in a square of the same size, so a ringed
              planet has to shrink its disc to fit the rings in — which left Saturn reading as
              the smallest thing in the set when it is the one with the most to show. It gets a
              bigger box. The Moon goes the other way: it is the one body everybody knows is
              small, and at the same size as Jupiter it looked like an error. */
        .cd-planet-px-lg {
            width: 50px;
            height: 50px;
            image-rendering: pixelated;
            image-rendering: crisp-edges;
        }
        .cd-planet-px-xl { width: 100px; height: 100px; }
        .cd-planet-px-sm { width: 38px; height: 38px; }
        .cd-planet-hero .cd-hero-name { font-size: 0.94rem; margin-bottom: 0.15rem; }
        /* (.cd-planet-word is gone with the keyword it styled — "DISCIPLINE" set in amber caps
           directly under "Saturn ℞ retrograde", as the first thing the row said about the
           planet. It was the one place on this dashboard that led with an interpretation
           instead of a position. The keyword still exists, in the meaning fold below the row,
           where it is answering a question rather than labelling one.) */
        .cd-planet-hero-state {
            display: inline-block;
            font-size: 0.62rem;
            letter-spacing: 0.04em;
            padding: 0.05rem 0.4rem;
            border-radius: 999px;
            vertical-align: 0.12em;
            white-space: nowrap;
        }
        .cd-planet-hero-state.retro { color: var(--accent-purple); border: 1px solid rgba(167,139,250,0.4); }
        .cd-planet-hero-state.stationary { color: var(--accent-cyan); border: 1px solid rgba(94,234,212,0.4); }

        /* Where to look — a chip, not a sentence. A direction and a height, or the one reason
           you can't. Cyan (the page's observational colour) when it's actually up to be seen. */
        .cd-where-chip {
            display: inline-flex;
            align-items: center;
            gap: 0.3rem;
            margin: 0 auto 0.6rem;
            padding: 0.2rem 0.6rem;
            border-radius: 999px;
            font-size: 0.68rem;
            color: var(--text-dim);
            border: 1px solid var(--border);
            font-variant-numeric: tabular-nums;
        }
        .cd-where-chip.visible {
            color: var(--accent-cyan);
            border-color: rgba(94,234,212,0.4);
            background: rgba(94,234,212,0.07);
        }
        /* (.cd-where-icon is gone with the 🔭 it sized. The chip says "up now" or "visible
           from" in words instead — a telescope glyph on the naked-eye planets was telling
           people they needed equipment for Jupiter. See buildWhereChip in core.js.) */

        /* ── The twelve-sign bar ── the whole zodiac as one stepped bar (buildSegmentedBar), the
              planet's sign lit and filling by its degrees — its place in the great circle, the
              way the Day bar shows the hour. The eleven signs it isn't in are tinted by their
              element (fire/earth/air/water), the way the Year bar tints the seasons; the sign
              it's in stays the accent, so the lit one still wins. Scoped to .cd-signbar and to
              :not(.active) so it never touches the Day/Year bars or the lit cell. */
        .cd-signbar { margin: 0.1rem 0 0.2rem; }
        /* ── The sign bar fills in the sign's own colour ──
              Same treatment as the seasons bar: the track carries a wash of the colour and the
              active cell fills solid with it. --cell is set inline per cell (see
              buildSegmentedBar) because which three signs appear depends on where the planet
              is, so it can't come from a fixed set of classes the way the seasons do. */
        .cd-signbar .cd-segbar-cell .cd-segbar-tick {
            background: color-mix(in srgb, var(--cell, var(--accent-purple)) 18%, transparent);
        }
        .cd-signbar .cd-segbar-cell.past .cd-segbar-tick {
            background: color-mix(in srgb, var(--cell, var(--accent-purple)) 42%, transparent);
        }
        .cd-signbar .cd-segbar-cell.active .cd-segbar-fill {
            background: var(--cell, var(--accent-purple));
            box-shadow: 0 0 10px var(--cell, var(--accent-purple));
        }
        .cd-signbar .cd-segbar-cell .cd-segbar-name { color: var(--cell, var(--text-dim)); opacity: 0.7; }
        .cd-signbar .cd-segbar-cell.active .cd-segbar-name { opacity: 1; font-weight: 600; }
        .cd-signbar-caption {
            margin-top: 0.4rem;
            font-size: 0.7rem;
            color: var(--text-dim);
            text-align: center;
            font-variant-numeric: tabular-nums;
        }
        /* The sign lens repaints --accent-yours to the chosen sign colour (applySignTheme), and
           every other "about you" mark follows it. This one was pinned to amber, so a Libra
           reader got a Libra-coloured dot in the grid and an amber caption underneath saying
           the same thing. */
        .cd-signbar-caption.yours { color: var(--accent-yours); }

        /* The folds under the bar — meaning, Sun weather, numbers — are read left-to-right, so
           they opt out of the hero's centring. */
        .cd-planet-fold .cd-tel-fold,
        .cd-planet-fold .cd-solarwx { text-align: left; }
        .cd-meaning-fold-body { text-align: left; padding-top: 0.3rem; }
        .cd-meaning-fold-body p { font-size: 0.76rem; line-height: 1.55; color: var(--text-secondary); margin: 0.35rem 0; }
        .cd-meaning-fold-body p:first-child { margin-top: 0; }
        /* ── The report, below the grid it describes ──
              The picker stays above the planets because it is a SETTING and the legend for the
              amber marks underneath. Everything derived from the grid — who's in your sign,
              when each body next visits it, the reminder — used to stack above it too, which
              put a screenful about the reader in front of the card they opened for the planets.
              It reads better as a report after the thing it reports on, and it needs a heading
              down here because it is no longer obviously attached to the picker. */
        /* Spacing and the head come from .cd-fold / .cd-subhead now — this is one of four
           sections on the card and they all wear the same grammar. Only the "you haven't picked
           a sign yet" state is local: a dashed rule under the head rather than the solid one,
           so the lens can demonstrate itself without the page claiming to know whose sign it is. */
        .cd-yoursign.default > .cd-fold-summary { border-bottom-style: dashed; }

        /* ── The sign control block ──
              Two controls for one feature: the picker chooses which sign the page watches, the
              reminder offers to tell you when something reaches it. The picker used to sit
              above the planet grid on the argument that it was the legend for the amber marks
              there — true in Meaning mode, and nonsense in Telemetry, where the grid stops
              mentioning signs at all and the picker is left explaining nothing. Together at the
              foot of the card they are one obvious thing. */
        .cd-signbox {
            margin-top: 0.9rem;
            padding: 0.7rem 0.8rem;
            border: 1px solid rgba(37,180,243,0.28);
            border-radius: 11px;
            background: rgba(37,180,243,0.04);
        }
        /* The divider hangs off the reminder rather than the picker, via the sibling selector,
           so a block with no upcoming visit is just the picker with no stray rule under it. */
        .cd-yoursign-open + .cd-visits-remind {
            margin-top: 0.6rem;
            padding-top: 0.6rem;
            border-top: 1px solid rgba(37,180,243,0.18);
        }

        /* The whole line is the trigger that opens the picker modal. */
        .cd-yoursign-open {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: 0.6rem;
            width: 100%;
            padding: 0;
            font: inherit;
            text-align: left;
            background: transparent;
            border: 0;
            cursor: pointer;
        }
        .cd-yoursign-head { font-size: 0.76rem; color: var(--text-secondary); }
        .cd-yoursign-head strong { color: var(--accent-yours); }
        .cd-yoursign-change {
            font-size: 0.62rem;
            text-transform: uppercase;
            letter-spacing: 0.1em;
            color: var(--accent-yours);
            opacity: 0.8;
            white-space: nowrap;
        }
        .cd-yoursign-open:hover .cd-yoursign-change { opacity: 1; }
        /* Still on the stand-in sign — a "default" tag, so the lens gets to demonstrate itself
           without the page claiming to know whose sign it is.
           (`.cd-yoursign.default { border-style: dashed; }` was here, from when the sign report
            was a bordered card. The card became a fold with no border and the rule stayed — and
            a border-style on nothing is not nothing: width defaults to `medium`, so it drew a
            3px border in the text colour round "✦ Libra in detail" for every visitor who had
            not picked a sign. The dashed state lives on the summary's rule now, near the top of
            this section. test/stylesheet.test.js checks for the pattern.) */
        .cd-yoursign-default-tag {
            font-size: 0.62rem;
            text-transform: uppercase;
            letter-spacing: 0.1em;
            color: var(--text-dim);
            border: 1px solid var(--border);
            border-radius: 20px;
            padding: 0.05rem 0.35rem;
            margin-left: 0.3rem;
            white-space: nowrap;
        }
        .cd-yoursign-note { font-size: 0.7rem; color: var(--text-dim); margin-top: 0.5rem; line-height: 1.5; }
        .sign-modal-content { max-width: 420px; }

        /* A planet currently in your sign — said by lighting the sign cell rather than adding
           a "✦ your sign" chip after it. The chip was a fifth item in the badge column, it
           made that column's width jump between rows, and it repeated on every match what
           one colour says once. */
        /* Amber tint, not purple — "a planet is standing in your sign" is the ABOUT YOU role,
           and it was previously tinted purple while the sign text next to it went amber, so
           one fact was being told in two colours on the same row. */
        .cd-planet-item.in-your-sign > .cd-planet-row { background: rgba(37,180,243,0.07); }
        .cd-planet-sign.yours {
            /* color: var(--accent-yours); */
            font-weight: 600;
        }

        /* Planet accordion — the detail (meaning, or telemetry in nerd mode) opens inline right
           under the tapped row, updated via targeted DOM (no full re-render, so no page flash). */
        /* <details> does the showing and hiding; this just animates the reveal. The old
           display:none / .open pair was the manual accordion and is gone with it. */
        .cd-planet-detail { animation: fadeIn 0.25s ease both; }

        /* ── Sign colour marks ──
           Replaces the zodiac glyphs. A filled dot in the sign's own colour identifies it
           faster than a symbol nobody learned, and it is the same colour the whole ABOUT-YOU
           role turns when that sign is chosen — so the picker is also a preview of the theme. */
        .sign-row-swatch {
            width: 1.15rem;
            height: 1.15rem;
            border-radius: 50%;
            flex-shrink: 0;
            box-shadow: 0 0 10px currentColor;
        }
        .sign-dot {
            display: inline-block;
            width: 0.5rem;
            height: 0.5rem;
            border-radius: 50%;
            margin-right: 0.35rem;
            vertical-align: baseline;
        }

        /* ── The four fold bodies wear one costume ──
              "So what?", "what it means", "the numbers" and "what the Sun is doing" are the
              same gesture — one tap for words you asked for — and were wearing four different
              looks. They all get the so-what treatment: a rounded, tinted card, so opening any
              fold anywhere on the dashboard produces the same shape.
              .cd-sowhat-text used to lead this list. It was the model the others were written
              against, then it was simplified on its own — the left rule, the one-sided corners
              and the gradient all dropped for a flat tint — and the copies were left wearing the
              old costume, so they were merged into one rule. It has now gone entirely: its last
              two users were the zodiac dial's "Why it drifts" and "How the top-down view is
              drawn" folds, and both of those moved to the About modal.

              NOTE the shape of that removal, because getting it wrong has shipped a bug here
              before: a dead selector at the FRONT of a list is safe to delete, a dead one at the
              END takes the rule's opening brace with it and silently unstyles everything left
              behind. Three live selectors remain below. */
        .cd-meaning-fold-body,
        .cd-tel-fold .cd-planet-telemetry,
        .cd-solarwx .cd-solarwx-rows {
            display: block;
            margin-top: 0.45rem;
            padding: 0.65rem 0.8rem;
            border-radius: 9px;
            background: rgba(167,139,250,0.06);
            font-size: 0.74rem;
            line-height: 1.6;
            color: var(--text-secondary);
            text-wrap: pretty;
        }
        /* The telemetry grid keeps its columns inside the card. */
        .cd-tel-fold .cd-planet-telemetry-grid { margin: 0; }
        .cd-solarwx .cd-solarwx-rows { display: flex; flex-direction: column; gap: 0.3rem; }

        /* ── Up there right now, no longer a fold ──
              It sits inside the Earth row, which is already a fold. A fold inside a fold whose
              summary already gave the answer was one gesture too many. */
        .cd-tonight { margin-top: 0.2rem; }
        .cd-tonight-head {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: 0.5rem;
            font-size: 0.62rem;
            letter-spacing: 0.14em;
            text-transform: uppercase;
            color: var(--text-dim);
            margin-bottom: 0.4rem;
        }
        .cd-tonight-count { text-transform: none; letter-spacing: 0.02em; font-size: 0.66rem; }
        .cd-tonight-count.lit { color: var(--accent-cyan); font-weight: 600; }

        /* ── Sky events, inside the Earth row ──
              Was a grey run-on strip below the grid: "Perseids shower — Peak in 14d · Summer
              Solstice — 3d ago". The most interesting sentence on the card, rendered as the
              least interesting thing on it. Rows now, and the imminent ones say so. */
        .cd-skyevents { margin-top: 0.7rem; }
        .cd-skyevents-head {
            font-size: 0.62rem;
            letter-spacing: 0.16em;
            text-transform: uppercase;
            color: var(--text-dim);
            margin-bottom: 0.35rem;
        }
        .cd-skyevent {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            /* Wraps so the observing verdict can take a line of its own — see below. */
            flex-wrap: wrap;
            gap: 0.6rem;
            padding: 0.3rem 0.1rem;
            font-size: 0.74rem;
            border-bottom: 1px solid rgba(255,255,255,0.045);
        }
        .cd-skyevent:last-child { border-bottom: 0; }
        .cd-skyevent-name { color: var(--text-secondary); }
        .cd-skyevent-when { color: var(--text-dim); font-variant-numeric: tabular-nums; }
        /* Within a week — a night out rather than a diary note. */
        .cd-skyevent.soon .cd-skyevent-name { color: var(--accent-cyan); font-weight: 600; }
        .cd-skyevent.soon .cd-skyevent-when { color: var(--accent-cyan); opacity: 0.85; }

        /* ── Is it worth going out for ──
              Full-width so it drops under the name/date pair rather than competing with them
              for the same line: the date answers "when", this answers "and will I see
              anything", which is a different question and deserves its own row. Quiet by
              default and only coloured at the two ends, because "some moonlight" is the
              ordinary case and colouring every row would spend the signal on nothing. */
        .cd-skyevent-moon {
            flex-basis: 100%;
            font-size: 0.7rem;
            letter-spacing: 0.04em;
            color: var(--text-dim);
        }
        .cd-skyevent-moon.good { color: var(--accent-cyan); }
        .cd-skyevent-moon.poor { color: rgba(203, 213, 225, 0.45); }

        /* Earth's summary line is a phrase, not a sign, so it shouldn't wear the sign column's
           weight. */
        .cd-earth-vantage {
            font-style: italic;
            color: var(--text-dim) !important;
            font-size: 0.72rem !important;
        }

        /* ── Your sign, back inside the planets card ──
              There were three rules here for `.cd-sign-card`: a flex heading, an enlarged
              colour dot beside it, and one stripping the control block's border because the
              card around it was already doing that job. The card is gone — the whole thing is
              a fold at the foot of the planets card now — so all three went with it, and the
              third one going is the point rather than a loss: the border was removed because
              "there are no planet rows above it", and now there are, so it earns itself back.

              The dot survives, moved onto the fold's own summary line, which is the only line
              left that names the sign. Smaller than the h2 version it replaces, because it now
              sits in a 0.72rem subhead rather than beside a heading — and sized in `em` so it
              tracks that rather than needing a second number if the subhead ever changes. */
        .cd-yoursign-dot {
            width: 0.62em;
            height: 0.62em;
            margin-right: 0.35em;
            vertical-align: baseline;
            box-shadow: 0 0 8px currentColor;
        }

        /* ── Starfield behind the planet disc ──
           Pure CSS: two layers of box-shadow points twinkling out of phase, so the disc sits in
           something rather than floating on flat card. No image, no canvas, no request. */
        .cd-planet-hero-disc {
            position: relative;
            display: inline-grid;
            place-items: center;
            padding: 0.6rem;
            margin: 0 auto 0.5rem;
        }
        .cd-planet-hero-disc .cd-planet-px-lg {
            position: relative;
            z-index: 1;
            filter: drop-shadow(0 0 12px rgba(0,0,0,0.55));
        }
        .cd-planet-hero-disc::before,
        .cd-planet-hero-disc::after {
            content: '';
            position: absolute;
            inset: 0;
            border-radius: 50%;
            pointer-events: none;
            background-repeat: no-repeat;
        }
        .cd-planet-hero-disc::before {
            background-image:
                radial-gradient(1px 1px at 12% 22%, #fff, transparent),
                radial-gradient(1px 1px at 78% 14%, #cfe6ff, transparent),
                radial-gradient(1px 1px at 88% 62%, #fff, transparent),
                radial-gradient(1px 1px at 22% 82%, #ffe9c9, transparent);
            animation: starTwinkleA 3.2s steps(2, end) infinite;
        }
        .cd-planet-hero-disc::after {
            background-image:
                radial-gradient(1px 1px at 46% 8%, #fff, transparent),
                radial-gradient(1px 1px at 8% 55%, #cfe6ff, transparent),
                radial-gradient(1px 1px at 62% 92%, #fff, transparent),
                radial-gradient(1px 1px at 94% 38%, #ffe9c9, transparent);
            animation: starTwinkleB 4.7s steps(2, end) infinite;
        }
        /* steps() rather than a smooth fade — the discs are pixel art and a soft crossfade
           behind them would be the one un-blocky thing on screen. */
        @keyframes starTwinkleA { 0%, 100% { opacity: 0.85; } 50% { opacity: 0.25; } }
        @keyframes starTwinkleB { 0%, 100% { opacity: 0.3; } 50% { opacity: 0.9; } }
        @media (prefers-reduced-motion: reduce) {
            .cd-planet-hero-disc::before,
            .cd-planet-hero-disc::after { animation: none; }
        }
        .cd-planet-meaning p { font-size: 0.76rem; color: var(--text-secondary); line-height: 1.55; }
        .cd-planet-meaning-yours { color: var(--accent-yours); font-weight: 600; }
        /* The next sign change — quieter than the meaning it follows, since for the outer
           planets it's a fact about years from now rather than about today. */
        .cd-planet-meaning-next {
            margin-top: 0.4rem;
            font-size: 0.7rem !important;
            color: var(--text-dim) !important;
        }
        /* Moving into the reader's own sign — same amber as the badge on the row above, so the
           one line in this panel that's about them isn't the same grey as the almanac facts. */
        .cd-planet-meaning-next.yours {
            color: var(--accent-yours) !important;
            padding: 0.35rem 0.55rem;
            border-radius: 8px;
            /* border: 1px dashed rgba(37,180,243,0.4); */
            background: rgba(37,180,243,0.07);
        }
        .cd-planet-meaning-next.yours strong { color: var(--accent-yours); }

/* ══ THE ONE THING ABOUT TODAY ═════════════════════════════════════════════════════════════
      Tonight, at the foot of the Today card. See buildTodayTonight in core.js and
      api/_lib/headline.js — what it holds is whatever won today's ranking, and tonight's
      sunset whether or not that won, so this has to be one frame that suits a sunset, an
      eclipse, four planets in a row and a meteor shower.

      Which is why the frame carries no meaning of its own. Eyebrow and when-stamp on top,
      glyph and two lines of words in the middle, and the one block only a sunset has — the
      rating — sits outside that and simply does not render for the rest. One shape, four
      contents; not four templates.

      It was the page's lead card until 29 Sept, with a 44px swatch strip of the palette above
      the words. Dan: "less of a highlight around it". The swatches are gone — the picture at
      the top of the Today card is the palette now, drawn as a sky — and the title steps down
      a size, because the word at the top of the card is the headline and this is the verdict
      you leave with. */
/* ── No box ──
      Dan: "it has amber border top and rounded corners, so it looks a bit naff."

      It did, and the cause was that this card was given furniture nothing else on the page
      wears: a full border, a 14px radius, and a 2px opaque bar of accent colour across the top
      that went amber on eclipse days. Three devices to say "this is important", on the one
      element whose position at the top of the page already says it. Cards further down carry a
      1px top-edge glow at 0.15 opacity; a 2px bar at 0.9 is six times the weight of the house
      treatment and it read exactly as loudly as that sounds.

      So the box goes. What is left is a rule, which separates it from the reading without
      drawing a container round it — the same move the Galaxy tab's galactic-centre pill needed
      when it was the one boxed element on a page of plain rows. Above it now, not below: it
      sits under the reading inside the Today card, and the card's own edge closes it. */
        .cd-headline {
            position: relative;
            margin-top: 1rem;
            padding-top: 0.9rem;
            border-top: 1px solid rgba(167,139,250,0.14);
        }
        /* The winner and the sunset, when they are two things. */
        .today-tonight-item + .today-tonight-item { margin-top: 0.9rem; }

        .cd-headline-top {
            display: flex;
            align-items: baseline;
            justify-content: space-between;
            gap: 0.6rem;
            margin-bottom: 0.45rem;
        }
        .cd-headline-eyebrow {
            font-size: 0.62rem;
            letter-spacing: 0.2em;
            text-transform: uppercase;
            color: var(--accent-purple);
            font-weight: 600;
        }
        /* Relative time always carries its real date — house rule. Tabular so a column of
           "in 3 days · 14 Aug" does not jitter between repaints. */
        .cd-headline-when {
            font-size: 0.66rem;
            color: var(--text-dim);
            font-variant-numeric: tabular-nums;
            white-space: nowrap;
        }

        /* (The palette strip that stood here — four 44px swatches, "the palette, as the hero" —
            went on 29 Sept. The hero is the sky picture at the top of the Today card, which is
            the same four colours drawn as tonight's sky; see .today-sky in 50-reading.css.) */

        .cd-headline-body {
            display: flex;
            align-items: flex-start;
            gap: 0.65rem;
        }
        .cd-headline-glyph {
            font-size: 1.15rem;
            line-height: 1.3;
            color: var(--accent-cyan);
            flex: 0 0 auto;
        }
        .cd-headline-text { display: block; min-width: 0; }
        .cd-headline-title {
            display: block;
            font-size: 0.9rem;
            font-weight: 600;
            line-height: 1.35;
            color: var(--text-primary);
            text-wrap: pretty;
        }
        /* The Oracle's own reason, or the event's one useful instruction. Secondary rather than
           dim: this is the sentence the card is for, and it spent long enough being grey. */
        .cd-headline-line {
            display: block;
            margin-top: 0.3rem;
            font-size: 0.8rem;
            line-height: 1.55;
            color: var(--text-secondary);
            text-wrap: pretty;
        }
        /* The safety note. It has to be here — a page that tells somebody a solar eclipse is
           happening and does not tell them not to stare at it has done a bad thing — and it has
           to be small, because it used to be the entire message and read as nagging. Quiet type
           under the sentence it is a footnote to, not a banner over it. */
        .cd-headline-safety {
            display: block;
            margin-top: 0.35rem;
            font-size: 0.68rem;
            letter-spacing: 0.04em;
            color: var(--text-dim);
        }
        /* The engine's own fact under a written line — which planets, and that they can be seen.
           Same quiet register as the safety note, one step brighter: it is an answer, not a
           caveat, and "can I see it" is the question the whole card is there to settle. */
        .cd-headline-note {
            display: block;
            margin-top: 0.35rem;
            font-size: 0.7rem;
            letter-spacing: 0.02em;
            color: var(--text-secondary);
        }

        /* ── The rating ──
              Stars first, the band word second, the raw number last and smallest. A score out
              of a hundred reads as a measurement, and this is an opinion about an evening; the
              order here is the fix for a 1/100 landing on somebody's morning like an omen. */
        /* No rule above it any more: it is one line under the sunset's title, not a band
           of its own, now that the sunset is the foot of a card rather than the whole of one. */
        .cd-headline-rating {
            display: flex;
            align-items: baseline;
            flex-wrap: wrap;
            gap: 0.5rem;
            margin-top: 0.4rem;
        }
        .cd-headline-stars {
            font-size: 0.85rem;
            letter-spacing: 0.08em;
            color: var(--accent-amber);
        }
        .cd-headline-stars.stars-1, .cd-headline-stars.stars-2 { opacity: 0.62; }
        .cd-headline-stars.stars-5 { text-shadow: 0 0 8px rgba(244,162,97,0.5); }
        .cd-headline-band {
            font-size: 0.78rem;
            color: var(--text-primary);
            font-weight: 600;
        }
        /* ── The hedge, on the evenings there is one ──
              This was `.cd-headline-score`, holding "58/100" with the doubt phrase appended,
              and `.cd-headline-score-max` dimming the "/100". Both are gone with the number:
              the stars and the band above carry the verdict, and a raw x/100 on the page's
              lead card reads as a measurement however small it is set. What is left is the
              hedge alone, and only when the Oracle is genuinely unsure — so unlike the number
              it replaced, this span is absent most evenings rather than present every one.
              `tabular-nums` went with the digits; there are none left to align. */
        .cd-headline-doubt {
            margin-left: auto;
            font-size: 0.68rem;
            color: var(--text-dim);
            white-space: nowrap;
        }

        /* ── Everything else that is on ──
              Named, never explained. Two or three chips so a busy night looks busy, without
              this turning into a second timeline. */
        .cd-headline-also {
            display: flex;
            flex-wrap: wrap;
            gap: 0.4rem;
            margin-top: 0.8rem;
        }
        .cd-headline-also-item {
            display: inline-flex;
            align-items: baseline;
            gap: 0.35rem;
            padding: 0.28rem 0.55rem;
            border-radius: 999px;
            border: 1px solid var(--border);
            font-size: 0.68rem;
            color: var(--text-secondary);
            max-width: 100%;
        }
        .cd-headline-also-glyph { color: var(--accent-cyan); }
        .cd-headline-also-when {
            color: var(--text-dim);
            font-variant-numeric: tabular-nums;
            white-space: nowrap;
        }
