/**
 * The memorial page's colour (Epic 13).
 *
 * PROJECT-AUTHORED, not upstream — like `components.css` and `scale.css`, and
 * unlike `tokens/*.css`, which are verbatim and re-imported by overwriting
 * (design/README.md). Load it LAST, after the token files and `components.css`,
 * for the same reason `scale.css` does: its `:root` block would win from
 * anywhere after the tokens, but any element rule added here would not.
 *
 * WHAT IS IN THIS FILE AND WHAT IS NOT
 * ------------------------------------
 * This block is the **star envelope** only — the constraints a generated
 * contributor colour must satisfy. T13.01 (`gallery.ts`) reads these values and
 * emits the resolved colours per contributor into `gallery.json`; T13.02 adds
 * the rest of the page's colour to this same file.
 *
 * Contributor colours are **generated data, not design tokens**. Tokens are a
 * fixed, named, enumerable set; contributors are unbounded and arrive over
 * time, so there is no `--contributor-7` to write. What is declarable is the
 * envelope, and that is what lives here — read by the builder as plain values
 * so the constraint has exactly one home rather than a copy in each.
 *
 * BOTH ROOMS ARE FIRST-CLASS, AND THEY ARE NOT THE SAME PICTURE
 * -------------------------------------------------------------
 * A theme switcher is coming, so the page has to be right in either room at any
 * moment — this is not one register chosen per deployment. The room follows
 * `tenant/public/tell.html`'s mechanism: `?theme=paper` / `?theme=night` pins
 * it, otherwise `prefers-color-scheme` decides, and the answer lands as
 * `data-theme="night"` on `:root`. `tokens/colors.css` defines `:root` (paper)
 * and `[data-theme="night"]` and nothing else.
 *
 * The two rooms are NOT one picture with the colours swapped:
 *
 *     night   LIGHT      contributor colour, additive glow, emitted against
 *                        a near-black ground. Chroma can be generous.
 *     paper   INK        an engraving. Low chroma, DARKER than the ground,
 *                        no glow.
 *
 * So there are two bands, and **the paper band is ink rather than a lightened
 * version of the night band.** That distinction is the whole reason the paper
 * room reads as an engraving instead of as the same sky printed on white, and
 * it is the part a later reader is most likely to "simplify" away by deriving
 * one band from the other. It cannot be derived: a star at night is brighter
 * than its ground and a mark on paper is darker than its ground, so the two
 * bands sit on opposite sides of their respective surfaces. Only the HUE is
 * shared — that is a contributor's identity across both rooms, and the reason
 * hue is an association cue at all (SPEC).
 *
 * The split is also what makes the numbers good. A single band shared by both
 * rooms was pulled in opposite directions (paper wants darker, night wants
 * lighter), met at a relative luminance of about 0.186, and bottomed out at
 * 3.35:1 — correct against WCAG 2.2 SC 1.4.11 but thin for a ~6px mark on a
 * phone outdoors. Letting each room optimise for its own ground instead:
 *
 *     night   worst case  6.73:1  against --night-0
 *     paper   worst case  7.30:1  against --paper-0
 *
 * measured across the whole envelope in `test/gallery.test.ts` rather than by
 * eye. Widening a band walks its number down, and the night band in particular
 * leaves sRGB if `--star-night-c-max` grows — the test asserts both.
 *
 * Chroma stays low in both rooms, most of all on paper. A sky of ~6px lights
 * should read as starlight, not as categorical chips, and hue here is an
 * ASSOCIATION cue rather than an identification one: hue stops being reliably
 * distinguishable somewhere around 8–10 values, and a contributor's hue must
 * stay stable as the collection grows, which forbids the fix a chart would use
 * (choosing hues to separate neighbours). Local collisions are expected.
 * Identifying *who* is the resting name-labels' job (T13.11).
 *
 * WHY HUE ARCS ARE RESERVED
 * -------------------------
 * `tokens/colors.css` says of amber and moss: "Signals — the only two colors in
 * the system." `--accent-new` IS amber, and it is the freshness signal a
 * recently added piece renders with (T13.05). A contributor assigned amber
 * would render as a system state, on the one page where people are the entire
 * content. So both signals' hues are excluded, with an ~18° guard, measured in
 * OKLCH from the token values themselves:
 *
 *     --amber-day   #B0763F   H 62.4 |  --moss-day   #6E7F58   H 127.3
 *     --amber-night #C9A227   H 89.7 |  --moss-night #7FA06B   H 134.2
 *
 * A day/night pair is ONE signal seen in two rooms and a contributor's hue is
 * shared by both rooms, so an arc spans the pair rather than notching each
 * value, and the arcs are shared rather than per-room. The two touch and the
 * builder merges them; 252° of hue remain.
 *
 * AN ARC IS A PROXY; THE DISTANCE IS THE RULE
 * -------------------------------------------
 * Degrees of hue are not degrees of difference — the separation an angle buys
 * is `C · sin(Δhue)`, so the same guard is worth half as much on a duller
 * signal. An earlier single-band version of this file learned that the hard
 * way: a 15° guard around moss bought only ΔEok 0.016, at or below the
 * just-noticeable difference, so a contributor could sit outside the arc and
 * still be indistinguishable from `--accent-done`.
 *
 * `--star-*-min-signal-distance` is therefore the real constraint and the arcs
 * are a cheap first filter kept in step with it. **Distance is per room, and
 * each room is checked only against the signals a viewer can see in it**: a
 * night colour cannot be confused with `--amber-day`, because they never appear
 * together. As measured across the whole envelope, the nearest allowed colour
 * is:
 *
 *     night   0.0534 from --amber-night   0.0578 from --moss-night
 *     paper   0.2041 from --amber-day     0.1535 from --moss-day
 *
 * against a 0.04 floor in both. Paper's enormous margin is not slack in the
 * arcs — it is the ink band doing it: a signal is a mid-tone and ink is dark,
 * so lightness alone separates them whatever the hue. `test/gallery.test.ts`
 * re-derives each room's signals from `tokens/colors.css` and asserts the
 * distance, not the angle.
 *
 * Values are unitless on purpose: `--star-*-l-*` and `--star-*-c-*` are OKLCH L
 * and C, `--star-hue-reserved-*` are degrees, and all of them are consumed both
 * by `oklch()` in CSS and by the builder.
 */

:root {
  /* ---------- night: light, emitted against --night-0 ---------- */

  /* OKLCH lightness band. Well above the ground — this is a star. */
  --star-night-l-min: 0.72;
  --star-night-l-max: 0.8;

  /* Chroma can be generous here; colour is what the night room is for. */
  --star-night-c-min: 0.05;
  --star-night-c-max: 0.1;

  /* ---------- paper: ink, an engraving, DARKER than --paper-0 ---------- */

  /* Far below the ground. Not a lightened night colour — see the note above. */
  --star-paper-l-min: 0.34;
  --star-paper-l-max: 0.42;

  /* Barely chromatic: printed ink with a tint, not a coloured dot. */
  --star-paper-c-min: 0.015;
  --star-paper-c-max: 0.045;

  /* ---------- floors, per room, enforced at build time ----------
     A colour that misses either one refuses the whole artifact. WCAG 2.2 SC
     1.4.11 asks 3:1 of a non-text graphical object, which is what a star is;
     4.5 is the text-grade floor, and the per-room bands clear it with room to
     spare, so there is no reason to declare the weaker number. */
  --star-night-min-contrast: 4.5;
  --star-paper-min-contrast: 4.5;

  /* Minimum ΔEok from the signals THIS room shows — the real "a person must
     never render as a system state" rule. */
  --star-night-min-signal-distance: 0.04;
  --star-paper-min-signal-distance: 0.04;

  /* ---------- shared, because a contributor's hue is shared ----------
     Hue arcs (degrees, `from to`) no contributor may be assigned. The two touch
     and the builder merges them. */
  --star-hue-reserved-amber: 44 108;
  --star-hue-reserved-moss: 108 152;
}

/**
 * ==================================================================
 * The page's own chrome (T13.02)
 * ==================================================================
 *
 * Everything above is the envelope the BUILDER reads. Everything below is
 * rendered colour, and there is deliberately very little of it: the page's
 * type, rules and grounds are already the system's semantic tokens
 * (`--surface-page`, `--text-said`, `--rule`), which means both rooms are
 * correct without a single value being restated here. `design/gallery.css`
 * carries the layout and contains no colour at all.
 *
 * What is left is the part a token cannot express, because it is genuinely
 * different in the two rooms rather than the same idea in two values.
 *
 * WHY THE STAR NEEDS A RULE AT ALL
 * --------------------------------
 * A contributor's two resolved colours arrive per element, inline, from the
 * artifact (`--star-night` / `--star-paper`). The room has to pick one, and it
 * cannot be picked at `:root`: a custom property is substituted where its
 * declaration lives, so `--star: var(--star-night)` written at `:root` would
 * resolve against a `--star-night` that only exists further down the tree, and
 * every element would inherit the empty result. So the choice is made on the
 * element itself, here, in the file that loads last.
 *
 * Never derived from one another. Paper is ink and night is emitted light —
 * the whole argument at the top of this file — and "lighten the paper value
 * for the night room" is the one-line simplification it dies of.
 *
 * THE SUBJECT NEEDS NO RULE OF HIS OWN (T13.14). He is assigned no hue from
 * the contributor palette: `gallery_page.ts` sets the same two properties to
 * `var(--text-said)`, so his star is the colour of the words on the page and
 * every other light is somebody who came to speak about him. Because it rides
 * the same channel, every rule below — the fresh halo, the playing-turn mark —
 * follows him without knowing he exists, which is the whole reason it is a
 * token reference on the element rather than a modifier class here.
 */

.gal-star { background: var(--star-paper, var(--text-faint)); }
[data-theme="night"] .gal-star { background: var(--star-night, var(--text-faint)); }

/**
 * FRESHNESS, IN THE INDEX (T13.05)
 * --------------------------------
 * A telling added inside the freshness window carries `--fresh` on its row and
 * nothing else — no badge, no dot, no date, no count (D15a). What it gets here
 * is MORE OF THE NARRATOR'S OWN COLOUR, which is the same sentence the sky says
 * in its own medium (`web/sky-draw.js`).
 *
 * TWO THINGS THIS DELIBERATELY DOES NOT DO.
 *
 * It does not shift the colour. `--accent-new` is amber and the hue arcs above
 * exist so that no contributor can be assigned amber or moss; brightening by
 * drifting toward the signal would spend that guarantee in the one place it was
 * bought for.
 *
 * And it does not DIM the settled stars to make the fresh ones stand out. Every
 * contributor colour was measured to clear 4.5:1 against its room's ground and
 * the artifact is refused if one does not; an opacity on a settled star would
 * walk that number down silently, and it would also say the collection fades,
 * which is the opposite of what an archive is for. Freshness is an addition.
 *
 * `transform` rather than width/height so a fresh row costs no reflow and the
 * list does not shift as the window moves past a piece. The night room gets a
 * halo as well, because that room is emitted light; the paper room gets weight
 * only, because an engraving has no glow and a soft edge there reads as a
 * printing fault — the same split as the two star bands.
 */

.gal-idx__entry--fresh .gal-star { transform: scale(1.35); }

[data-theme="night"] .gal-idx__entry--fresh .gal-star {
  box-shadow: 0 0 0.45rem var(--star-night, transparent);
}

/* The sentence being said right now (T13.03), marked in the narrator's own
   colour — the same value as their star, picked here for the same reason and
   in the same two lines. The rule sits in the gutter `design/gallery.css`
   reserved for it, so nothing moves when playback reaches a turn; the fallback
   keeps the mark visible if a piece's contributor carries no colour. */
.story-audio__turn[data-playing] { border-left-color: var(--star-paper, var(--text-faint)); }
[data-theme="night"] .story-audio__turn[data-playing] {
  border-left-color: var(--star-night, var(--text-faint));
}

/**
 * THE SECOND TONE — AND WHY PAPER HAS NONE
 * ----------------------------------------
 * Every word on this page is content. There is no disabled state, no status
 * line and no chrome to grey out: a narrator's name, their relation, how long
 * they spoke and the family's own line are all things a visitor came to read.
 * Measured against each room's own ground (`test/gallery_page.test.ts` does the
 * measuring, with `gallery.ts`'s own `contrastRatio`):
 *
 *     paper   --ink-0  12.22:1     --ink-1  3.45:1     --ink-2  2.40:1
 *     night   --bone-0 13.87:1     --bone-1 4.86:1     --bone-2 3.08:1
 *
 * So the system's secondary tones are AA text in the night room and are NOT in
 * the paper one. That is not a flaw in the tokens — they were drawn for the
 * interviewer's chrome, where the quiet tones carry status rather than
 * content — but it decides this page:
 *
 *     night   a second tone, --bone-1, doing what a second tone does.
 *     paper   ONE INK. An engraving has one ink; the hierarchy is cut into it
 *             as size, tracking and case, not printed in a paler one.
 *
 * Which is the same sentence as the star bands, arriving at the page's type:
 * the two rooms are not one picture with the colours swapped. Both sides of
 * this clear 4.5:1, and no new value is introduced — `--gal-secondary` is an
 * alias, so a re-synced token file moves the page with it.
 */

:root { --gal-secondary: var(--ink-0); }
[data-theme="night"] { --gal-secondary: var(--bone-1); }

/**
 * THE PARTS THE BROWSER DRAWS ARE IN THE ROOM AS WELL
 * ---------------------------------------------------
 * `<audio controls>` is painted by the UA, not by this file, and in the night
 * room it arrives as a light pill on a near-black ground — the one element on
 * the page that did not get the memo. `color-scheme` is the only way to tell
 * the UA which room it is standing in; it also darkens the scrollbar these two
 * pages get, which is the same sentence rather than a side effect.
 *
 * SCOPED BY THIS STYLESHEET, ON PURPOSE. Only `index.html` and `piece.html`
 * link `gallery-color.css`. `/tell` and `/interview` carry their own inline CSS
 * and their own controls, drawn against grounds this epic never looked at, so
 * the same declaration in `tokens/colors.css` — where it would otherwise
 * belong — would reach two surfaces nobody reviewed for it.
 */
[data-theme="night"] { color-scheme: dark; }

/**
 * THE ENTRANCE GROUND
 * -------------------
 * The one place the two rooms are not the same picture recoloured.
 *
 * Night is a light source above a near-black ground, so the entrance opens
 * with the faintest possible lift behind the name — the same move the sky
 * makes (T13.04), arriving before it. Built from `--surface-raised`, the
 * system's own third tone, so it is a tone of the room rather than a colour
 * introduced on top of it.
 *
 * Paper is an engraving: ink on stock, no glow, nothing behind the name. A
 * wash there would read as a printing fault. The paper rule is written out
 * rather than left to the absence of a rule, because "the paper room has no
 * wash" is a decision and should look like one.
 */

.gal-entrance { background: none; }

[data-theme="night"] .gal-entrance {
  background: radial-gradient(ellipse 120% 70% at 50% 0%, var(--surface-raised), transparent 70%);
}

/**
 * HOW FAR THE BACKDROP RECEDES, AND IT IS NOT THE SAME NUMBER IN BOTH ROOMS
 * -------------------------------------------------------------------------
 * The stage's default state is a sentence and two doors over a sky that is
 * scenery — dimmed so the words are the only thing asking to be read. How much
 * dimming that takes is a property of the room, not of the layout, which is why
 * `gallery.css` only names the custom property and this file fills it.
 *
 * Night recedes by being darker, and the sky is emitted light on a near-black
 * ground: it already sits below the text without much help, so it keeps more of
 * itself. Paper recedes the other way (the argument `gallery.css` records for
 * the gutters) — ink on stock competes with ink on stock, and a constellation
 * at the same weight as the sentence over it makes both hard to read. So the
 * plate is pulled further back.
 *
 * These are the BACKDROP numbers only. Pressing "explore the stories" takes the
 * sky to full strength in either room, because at that point it is the subject
 * and there is nothing on top of it to compete with.
 */
:root { --gal-backdrop: 0.38; }
[data-theme="night"] { --gal-backdrop: 0.55; }

/**
 * THE SKY'S TWO COLOURS (T13.04, T13.11)
 * --------------------------------------
 * A star is a contributor's colour and arrives from the artifact, resolved for
 * each room and contrast-checked at build time. An EDGE is not: it belongs to
 * two pieces and therefore to neither contributor, so drawing it in one of
 * their colours would say something about the pair that the pair does not say.
 * It is the room's own line — bone in the night room, ink in the paper one —
 * and it is the only colour the sky needs that the artifact cannot carry.
 *
 * A LITERAL HEX, WHICH THIS FILE OTHERWISE AVOIDS. `web/sky.js` reads this
 * property with `getComputedStyle` and hands it to a canvas, and a canvas
 * parses `#rrggbb` and not `var(--bone-1)`. A computed `var()` chain resolves
 * to its final value, so an alias would in fact work today — but only while
 * every step of the chain stays a hex, and `tokens/colors.css` is re-synced by
 * overwriting. Read once per room change, never per frame.
 *
 * Both values are the token they name (`--bone-1`, `--ink-0`), and
 * `test/gallery_sky.test.ts` asserts they still are, so a re-synced token file
 * fails a test here instead of drifting quietly into the canvas.
 *
 * THE SECOND IS THE RESTING LABEL (T13.11), and it is the room's TEXT colour
 * rather than a dimmer relative of the edge. The labels are the sky's
 * identification mechanism — hue is stable-per-contributor by construction and
 * therefore cannot be chosen to separate neighbours, so the name is what says
 * who is speaking — and they have to survive a phone held at arm's length
 * outdoors. That is a contrast requirement, not a taste one, so a label gets
 * `--text-said`'s own value in each room and never the line's.
 */

:root { --sky-edge: #332C24; }        /* --ink-0 */
[data-theme="night"] { --sky-edge: #8C867B; }  /* --bone-1 */

:root { --sky-label: #332C24; }        /* --ink-0, = --text-said */
[data-theme="night"] { --sky-label: #E9E4DA; }  /* --bone-0, = --text-said */
