/* ============================================================================
   CetusEd public site — TOKENS (Palette v3)
   Ledger item P0-1 · Spec: docs/Public Redesign/cetused-audit-addendum-c-nautical-celestial.md Part C
   ----------------------------------------------------------------------------
   Addendum C supersedes Addendum A Part B, which superseded the base audit §5.0.
   All hex values are carried forward unchanged from Addendum A; only the naming
   and one new structural token (--waterline) are new. Mapping, so nothing is lost:
     --statute  -> --mira      --policy    -> --phosphor   --student -> --current
     --movement -> --wake      --halt      -> --shoal      --ink-deep-> --sky
     --ink-plate-> --deep      --paper     -> --chart

   ⛔ THE BAN LIST — read this at every review (Addendum C Part A, Part I item 1)
   ----------------------------------------------------------------------------
   BANNED OUTRIGHT, in markup, CSS, asset names and copy alike:
     compass roses · ship's wheels · anchors · rope borders and knots · portholes
     sextants as ornament · treasure-map parchment · scrolls · wave-shaped section
     dividers · lighthouses · sailing-ship silhouettes · serif faces with swashes

   BANNED IN COPY (grep before launch):
     smooth sailing · all hands · charting new waters · navigating the journey
     on course · don't sink · anchor point · north star · uncharted territory · tide
     ⛔ and specifically: "Navigate every student to success" must be OFF the site.

   THE TEST: if a reviewer glances at a screen and thinks "nautical", it has failed.
   The correct reaction is that the page feels like an INSTRUMENT, and only later
   does the reader notice why.

   THE TRADE THAT PAYS FOR IT (Addendum C Part A): the metaphor moves INTO the design
   and comes OUT of the prose entirely. The visual system carries Cetus; the writing
   gets to be flat, specific and plain. Doing both is twice as twee as either alone.
   ========================================================================= */

:root {
  /* ── GROUNDS: a vertical depth/altitude gradient ────────────────────────
     Grounds get darker as the reader descends a page: --zenith through --deep.
     Implement as DISCRETE SECTION BACKGROUNDS, never one giant gradient, so it
     survives lazy loading and does not blow out compositing (Addendum C Part C).
     No single step should be obvious; the effect is cumulative over a full scroll. */
  /* ⭐ COOL CHARCOAL — OPTION B. The chrome is now made of the same light as
     the photography instead of arguing with it. Measured before the change:

       landing photograph (the dominant one)   #2D3236   17% cast   +9.3 B–R
       all five photographs averaged           #1F252D   30% cast   +13.4
       the ground they sat on (--sky)          #0D1436   76% cast   +41

     Four and a half times the saturation of the pictures it was supporting.
     These four keep the photograph's own bias — a slight cool lean rather than
     flat grey — which is why this is #1B1F25 and not #1A1D21.

     ⛔ THE NAMES DID NOT CHANGE, DELIBERATELY. The brief proposed adding
     --ramp-zenith / --ramp-mid / --ramp-base / --ramp-abyss. These four names
     have 47 consumers across the stylesheets and the ramp names had zero, so
     adding them would have left TWO ground vocabularies that can disagree —
     one read by the CSS, one read by nobody — which is this codebase's most
     repeated defect. Same values, one home.

     ⚠ THE VEIL IS MIXED FROM --sky, so this changes how every photograph on
     the site reads, not only the panels. That is the point of the change and
     the thing to look at first. */
  --zenith:      #262B31;  /* upper sky — lightest ground */
  --sky:         #1B1F25;  /* primary above-horizon ground; the site default */
  --surface:     #14171C;  /* just below the line — primary below-horizon ground */
  --deep:        #0A0C0F;  /* diagram plates, deepest sections */
  --chart:       #F6F3EC;  /* daylight chart paper — SUSTAINED READING ONLY */

  /* ⭐ THE DECK'S PANEL HEIGHT, AND IT IS CLAMPED. min() so a short window
     still gets a full screen and a tall one stops at a landscape-ish
     proportion instead of stretching. Read by .canvas-panel and
     .canvas-panel-in, so the outer box and the inner box — which the plate
     fitter's minmax(0,1fr) track resolves against — cannot drift apart.
     Measured on /programs before the clamp: at 1440x810 the beats ran
     48/91/32/91/63% full; at 1235x1300 the same beats ran 22/94/17/94/34%.
     The emptiness was scaling with the display, and every viewport I had
     tested was landscape. */
  --deck-h: min(100svh, 900px);
  --chart-soft:  #ECE7DC;  /* secondary light band */

  /* ── THE WATERLINE ──────────────────────────────────────────────────────
     ⛔ TWO RULES, both absolute:
        1. Only ever a 1px rule (1.5px on UHD). NEVER a fill, a background,
           or a type colour.
        2. Exactly ONE horizon per viewport. It is a singular thing, not a
           repeated decoration.
     It divides meaning: above = law, interpretation, what is fixed and external.
     below = the record, the data, what is held. */
  --waterline-on-dark: #E8C88A;
  --waterline:   var(--waterline-on-dark);

  /* ── SEMANTIC ACCENTS — each means EXACTLY one thing ────────────────────
     ⛔ Colour is never decorative here. This is the structural opposite of
     tinting the second clause of every headline, which is the habit being
     replaced. A reader who spends four minutes on the site learns the code
     without being taught it — but only if it is never broken.
     ⛔ No accent appears on a button unless the button's ACTION is that thing. */
  --mira:        #C4703C;  /* STATUTE. Law being cited. The fixed star.
                              ⛔ Never on a button. Never decorative. */
  --phosphor-on-dark: #4E9A85;
  --phosphor:    var(--phosphor-on-dark);
                           /* DISTRICT POLICY. A bearing the district chose —
                              legitimate, often tighter than the rule, and theirs. */
  --current-on-dark: #7FB6E8;
  --current:     var(--current-on-dark);
                           /* STUDENT DATA IS PRESENT in this component.
                              ⛔ Never decorative. In the privacy plate exactly ONE
                              box carries it, and that is the argument. */
  --wake-on-dark: #E8D98A;
  --wake:        var(--wake-on-dark);  /* DATA IN MOTION — integration flows only. */
  --shoal:       #B04A4A;  /* FAILS CLOSED / BLOCKED / REFUSED. Hazard marking. */

  /* ── TEXT ───────────────────────────────────────────────────────────────── */
  --star-on-dark:     #F2F5F8;
  --star-dim-on-dark: #97A3B0;
  --star:        var(--star-on-dark);      /* primary text on dark grounds */
  --star-dim:    var(--star-dim-on-dark);  /* secondary text on dark; also the NO-FIX badge state */
  --text-ink:    #14181C;  /* primary text on --chart / --chart-soft */
  --text-ink-lo: #5A666E;  /* secondary text on chart paper */

  /* ⛔ THE LIGHT-GROUND HALF OF THE THREE ACCENTS. --star and --star-dim
     already had their chart-paper pair (--text-ink / --text-ink-lo); the three
     accents did not, so a component reaching for var(--waterline) inside a
     light section rendered gold on cream at 1.45:1. Each of these is the same
     hue at a luminance that clears WCAG AA on --chart, measured rather than
     eyeballed — the contrast figures are in the .g-chart block below. */
  --waterline-ink: #8A6618;  /* --waterline on chart paper */
  --wake-ink:      #7D6E14;  /* --wake      on chart paper */
  --current-ink:   #1D5C8F;  /* --current   on chart paper */
  --phosphor-ink:  #2E6B58;  /* --phosphor  on chart paper */

  /* ── RADIUS, SCOPED RATHER THAN GLOBAL ──────────────────────────────────
     Addendum A Part B: a global 8–12px radius applied to diagrams makes
     instruments look like widgets. Soft where the reader TOUCHES, sharp where
     the reader MEASURES. Charts have square corners. */
  --r-interactive: 10px;   /* buttons, inputs, accordions, nav, resource cards */
  --r-surface:      6px;   /* content panels, screenshot frames */
  --r-plate:        0px;   /* ⛔ diagram plates, data tables, matrices, PHOTOGRAPHY */

  /* ── STROKE WEIGHTS ─────────────────────────────────────────────────────
     Hairlines, not cards. Two weights only (base audit §5.0 layout grammar). */
  --hair:        1px;
  --hair-strong: 1.5px;

  /* ── THE THREE STROKE CONVENTIONS, SITE-WIDE ────────────────────────────
     Addendum C Part G. Same three everywhere, on every diagram, and ALWAYS
     accompanied by a text label — stroke pattern alone fails accessibility.
       solid          = established / built / statutory
       dashed         = available / optional / policy
       dotted-ghosted = not yet / unconfirmed  */
  --dash-available: 6 4;
  --dash-notyet:    2 5;
  --ghost-opacity:  0.45;

  /* ── MOTION BUDGET (Addendum A Part D) ──────────────────────────────────
     Nothing animates that is not in this list. Every entry is gated on
     prefers-reduced-motion: no-preference in motion.css. */
  --t-hover:      200ms;
  --t-accordion:  240ms;
  --t-nav:        300ms;
  --t-page:       450ms;
  --t-threshold:  900ms;
  --e-out:        ease-out;
  --e-inout:      ease-in-out;
  --e-threshold:  cubic-bezier(.16, 1, .3, 1);

  /* ── WIDTH TIERS (Addendum A Part E) ────────────────────────────────────
     Three tiers, not one container. On ultrawide the extra space goes to the
     MARGIN COLUMN, not to empty gutters — see layout.css. */
  --w-reading: 70ch;    /* body prose, accordions, Q&A */
  --w-plate:   1600px;  /* diagrams, matrices, tables, screenshots */
  /* ambient = full bleed; no token needed */

  /* ── PHOTOGRAPHY MEASURE (constraint C18) ────────────────────────────────
     A band used to be 100vw of photograph, which on a 3440px display asked a
     1376px frame to stretch 2.50x. Nine of fourteen frames could not fill their
     slot and the manifest recorded it honestly rather than hiding it.

     The fix is GEOMETRY, not new photographs: a band is now a full-bleed GROUND
     with the photograph set into it at a fixed editorial measure. The ground
     runs edge to edge, so the band still reads full-bleed; the image stops at
     --w-band-max and feathers into the ground rather than ending on a seam.

     THE NUMBERS ARE DERIVED FROM THE FRAMES, not chosen for looks. Band natives
     are 1376-1915px. At a 1760px measure the largest upscale demanded anywhere
     on the site is 1.279x (p10, 1376px) and p01 at 1915px is not upscaled at
     all. Headroom under the 1.35 ceiling below is 0.071 — deliberately not a
     value that only just works, because the next photograph swapped in should
     not silently breach it. Re-derive with the arithmetic in build-photos.js;
     do not nudge either number by eye. */
  --w-band-max: 1760px;
  /* Opener plates. Their note claimed 'capped by --w-plate' and NOTHING capped
     them — measured at 3360px on a 3440px display. Opener natives are
     1152-1460px, so 1520 asks at most 1.32x of the smallest. */
  --w-open-max: 1520px;
  /* The most any photograph may be scaled past its native width. A stated
     policy, not a hidden fudge: build-photos.js records the NATIVE shortfall
     unchanged and reports separately whether a frame clears this ceiling. */
  --photo-upscale-max: 1.35;
  /* How far the image dissolves into the ground at each capped edge. */
  --photo-feather: clamp(72px, 7vw, 200px);

  --margin-col:      180px;  /* § numbers, citations, provenance markers */
  --margin-col-wide: 320px;  /* above ~1800px — marginalia moves out into it */
}

/* ── UHD: the waterline thickens; the margin column earns the extra space ── */
@media (min-width: 1800px) {
  :root { --hair: 1.5px; --margin-col: var(--margin-col-wide); }
}

/* ── GROUND UTILITIES ───────────────────────────────────────────────────────
   Dark means LOOK. Light means READ. The switch is the signal, and the reader
   learns it in one page (Addendum C Part B). --chart appears ONLY where there is
   sustained reading: /about, long-form Q&A, white-paper preview pages. */
.g-zenith  { background: var(--zenith);  color: var(--star); }
.g-sky     { background: var(--sky);     color: var(--star); }
.g-surface { background: var(--surface); color: var(--star); }
.g-deep    { background: var(--deep);    color: var(--star); }
/* ⛔ A LIGHT GROUND MUST REMAP THE TOKENS, NOT JUST SET A COLOUR.
   These two rules used to set `color` alone. Inherited text was therefore
   correct, and every component that names a colour token directly was not —
   it kept the value tuned for a navy ground and rendered it on cream.

   Measured across the seven pages that use these grounds, before the fix:
   58 distinct selectors below WCAG AA, collapsing to FIVE source tokens.

     --star      #F2F5F8   1.01:1   18 selectors
     --star-dim  #97A3B0   2.32:1   33 selectors
     --waterline #E8C88A   1.45:1    3 selectors
     --wake      #E8D98A   1.29:1    3 selectors
     --current   #7FB6E8   1.94:1    1 selector

   Fixing 58 components would have been fixing instances of one defect. The
   token is where the fact lives, so the token is what gets remapped — which
   also means a component written tomorrow is correct on both grounds without
   its author knowing this block exists.

   Contrast on --chart #F6F3EC after the remap: ink 16.6:1 · ink-lo 5.3:1 ·
   waterline-ink 4.7:1 · wake-ink 4.6:1 · current-ink 6.4:1. _test-a11y walks
   all seven pages and re-derives these on every run. */
.g-chart, .g-chart-soft {
  --star:      var(--text-ink);
  --star-dim:  var(--text-ink-lo);
  --waterline: var(--waterline-ink);
  --wake:      var(--wake-ink);
  --current:   var(--current-ink);
  --phosphor:  var(--phosphor-ink);
}

/* ⛔ AND A DARK INSTRUMENT INSIDE A LIGHT SECTION RESTORES THEM.
   Custom properties inherit, so the remap above reaches everything in the
   section — including the plates, which paint their OWN near-black ground
   (--ink-plate) and are meant to. A reference paper is cream for sustained
   reading with dark instruments set into it; that contrast is the design, not
   an accident. Without this rule the remap put #14181C ink on a #05080F plate:
   1.12:1, and I introduced it while fixing the opposite fault one level up.

   THE INVARIANT, which is the general form of both rules: ANYTHING THAT PAINTS
   ITS OWN GROUND MUST ALSO CARRY THE TOKEN SET FOR THAT GROUND. Setting a
   background without setting the tokens leaves every descendant coloured for
   whatever the ancestor happened to be.

   Each dark value has ONE home — the --*-on-dark token above. :root aliases it
   and this block restores it, so there is no second copy to drift. */
.g-chart .plate, .g-chart-soft .plate {
  --star:      var(--star-on-dark);
  --star-dim:  var(--star-dim-on-dark);
  --waterline: var(--waterline-on-dark);
  --wake:      var(--wake-on-dark);
  --current:   var(--current-on-dark);
  --phosphor:  var(--phosphor-on-dark);
  color: var(--star-on-dark);
}
.g-chart   { background: var(--chart);   color: var(--text-ink); }
.g-chart-soft { background: var(--chart-soft); color: var(--text-ink); }

/* ⛔ NO GRADIENT ORBS. NO NOISE OVERLAYS. The base audit Part Seven deletes all
   eight of them. The only ambient element permitted anywhere on this site is the
   record hairline (Addendum A Part B). */
