/* Agoramores — "default" theme overrides. Loaded after main.css.
   Every selector here is scoped to body[data-theme-id="default"].

   ---------------------------------------------------------------------------
   THE STRUCK CARD — the site's standing default.

   This is the theme a reader arrives on. The twelve months and the seasonal
   sheets are what they can move TO; none of them is the front door any more.
   That inverts what this sheet has to be: a month may be a mood, but the
   default has to hold up on every page, every day of the year, and still be
   the first thing that says what this place is.

   The brief was "very much like a tarot card, tribal ancient yet modern", and
   the three words pull in different directions on purpose. What resolves them:

     tarot    The page IS the card, not a page with a card on it. main.css
              already built that grammar for the breadcrumb bar — struck corner
              pips, rules that taper out rather than stop, type engraved with a
              single offset lip. This sheet carries the same four devices out to
              the page itself, so <main> is a trump and the bar at its head is
              the trump's own illustration rather than a widget sitting above
              unrelated content.

     ancient  Pigment, not ink-jet. Every colour here is a thing that was
              actually ground and applied before it was a hex code — iron oxide,
              gold leaf, malachite, carnelian, bone. The marks are the ones
              every culture arrived at independently with a straight edge and a
              repeat: the chevron, the tally, the lozenge. No texture overlays,
              no distress filters, no parchment JPEG. Age is in the palette and
              the vocabulary, never in a fake surface.

     modern   Absolute precision in how those marks are drawn. Hairlines that
              are actually one pixel, bands that repeat on an exact interval,
              wide letterspacing on small caps, generous measure, and almost no
              motion at all. The ancient half supplies the vocabulary; the
              modern half supplies the discipline. Take the discipline away and
              this is a fantasy-novel theme, which is the failure mode this
              sheet is written against.

   JEWEL TONES, NO BLUE — the user's palette instruction, and the reason the
   ground is dark. Emerald, magenta, teal, amethyst and topaz are all colours
   that only read as gems against darkness; on pale stock they go chalky and
   the whole conceit collapses. The ground is therefore a deep aubergine-black
   stone rather than the cool near-black July uses, because a warm ground is
   what lets a green and a magenta sit next to each other without either one
   turning grey. Nothing in this sheet is blue: --tt-blue, which main.css spends
   on links and gradient stops, is re-pointed at verdigris so that no rule
   reading it can land on a blue by accident.

   RED IS STILL THE ANCHOR (see .github/agents/style/invariants.md). Ruby is the
   most jewel-toned red there is, it is the same pigment family as the iron
   oxide the tribal half is built on, and it is what a tarot card's own frame
   and pips are struck in. The invariant and the brief want the same colour
   here, which is why red leads every gradient below and reappears three times
   in the long one.
   --------------------------------------------------------------------------- */

body[data-theme-id="default"] {
  /* Ground. Warm, not neutral: #110c14 carries just enough red and violet to
     keep the emerald from reading as sickly and the magenta from reading as
     pink. A true neutral #0f0f0f flattens both. */
  --tt-bg: #130c0b;
  --tt-bg-alt: #231714;
  /* Link-hover paired to THIS block's ground (standing rule 2026-08-14),
     not the mode name. #110c14 is dark: #FF465A clears 5.78:1 here. */
  --link-hover: #FF4947;

  /* --tt-cyan is the body-text and border token in main.css, whatever it is
     named. Here it is bone — aged ivory rather than white, so a long page of
     it reads as a card that has been handled rather than a screen that is on.
     Pure #fff on this ground is the single fastest way to lose "ancient". */
  --tt-cyan: #ecdfc6;
  --tt-cyan-soft: #cbb896;

  /* The gems. Each one is a pigment first and a hex second. */
  --tt-yellow: #e9ba3c;      /* topaz — H1, brand, focus ring */
  --tt-orange: #dd5a28;      /* carnelian — H2, list markers */
  --tt-chartreuse: #93c83f;  /* peridot — H3, bold */
  --tt-green: #569b52;       /* emerald — tags, italics */
  --tt-pink: #e0211e;        /* magenta — code, link hover */
  --tt-purple: #ad4d38;      /* amethyst — accents, visited links */
  --tt-teal: #4b6440;        /* deep malachite — dim borders, scrollbar */
  --tt-gray: #8c8175;        /* warm stone — muted text */
  --tt-gold: #c9a24a;        /* gold leaf — highlights, engraving */
  --tt-red: #cf2321;         /* RUBY — the anchor. Frame, pips, table heads. */

  /* NOT BLUE. main.css spends --tt-blue on links and on two gradient stops, so
     leaving it at July's #3465a4 would put a blue on the page through the back
     door no matter what the rest of this block says. Verdigris — aged bronze —
     is the jewel-tone answer that still reads as "the cool one" in a spectrum,
     and it is bright enough here to carry link text on this ground. */
  --tt-blue: #789e67;

  /* The breadcrumb card letters itself in gold leaf. The glow is real alpha,
     not transparent: this theme wants the lettering to be the thing that
     catches light, which is the whole rule of the card grammar in main.css —
     what glows is the lettering, what is cut stays cut. */
  --tt-breadcrumb-text: #c9a24a;
  --tt-breadcrumb-glow: rgba(201, 162, 74, 0.5);

  /* The zodiac glyph halo, checked against THIS ground rather than inherited.
     Topaz at 0.72 traces a ♌ or an ogham stave legibly on #110c14; the
     breadcrumb gold at 0.5 is a shade too dim to read as a halo on a character
     that small. See .github/agents/style/chips.md — never a border. */
  --zodiac-glow: rgba(233, 186, 60, 0.72);

  /* Engraving direction. This is a dark card, so the lit lip of the cut goes
     BELOW the glyph in black, which is the :root default and is correct here —
     the light-ground months are the ones that have to flip it. Deepened from
     0.55 to 0.62 because this ground is lighter than July's #060507 and the
     cut needs the extra bite to still read as cut. */
  --tt-engrave: 0 1px 0 rgba(0, 0, 0, 0.62);

  /* ---------------------------------------------------------------------
     THE THREE GRADIENTS — NO RAINBOW IN THIS THEME (user instruction, locked).

     These are not decoration. main.css runs every visible border on the site
     through --tt-heading-rainbow as a border-image, so these three
     declarations re-ink every frame, rule, table, card, input, tag, the header
     strip and the section rail at once. That is exactly why the de-rainbowing
     happens HERE and nowhere else: one edit, whole sheet, no hunting.

     The tokens keep their names. They are read by name in ~14 places in
     main.css and renaming or deleting them would strip the borders off the
     page — see the Standing Constraints in
     .github/agents/style/invariants.md. What changes is what they contain: a
     single warm metal ramp — ruby, carnelian, gold, carnelian, ruby — with no
     peridot, emerald, verdigris, amethyst or magenta stop anywhere in it.
     Every hue in the ramp is one pigment family (iron oxide through gold
     leaf), so a border showing 40px of it and a border showing 900px of it are
     recognisably the same border, which is the thing a spectrum could never
     do.

     Red leads all three and returns as the last stop, so the Red Color Bias
     invariant is satisfied by a ramp that is red at both ends rather than by a
     spectrum that merely starts red.

     DO NOT re-introduce a spectrum here. The other thirteen sheets in
     public/themes/ are where a rainbow belongs; the default is not one of
     them. See .github/agents/style/invariants.md — "The Default Theme Has No
     Rainbow".
     --------------------------------------------------------------------- */
  /* THE RAMP'S GOLD IS AN ORNAMENT, NOT AN INK, AND THE TWO PART COMPANY BY
     DAY. --tt-gold is a text colour first — bold, brand, eyebrow, TOC title —
     so on a light ground it has to clear 4.5:1 and the day block takes it down
     to #543d09. But main.css paints THE FRAME's four edges with this ramp, and
     a middle stop that dark turns the head, the foot and both rails to mud
     across the whole of their run: ruby at the corners, near-black through the
     middle, which is what the teeth showed on 2026-08-18. One name doing both
     jobs is the defect; this is the second name.

     It defaults to the ink, so the night face and every consumer that has not
     re-inked its gold are unchanged — only a face that darkens --tt-gold for
     contrast has to re-point it. The text ramp below deliberately keeps
     --tt-gold: clipped to glyphs it is type, and type keeps the ink. */
  --tt-ramp-gold: var(--tt-gold);
  --tt-heading-rainbow: linear-gradient(
    90deg,
    var(--tt-red),
    var(--tt-orange),
    var(--tt-ramp-gold),
    var(--tt-orange),
    var(--tt-red)
  );
  --tt-heading-rainbow-vertical: linear-gradient(
    180deg,
    var(--tt-red),
    var(--tt-orange),
    var(--tt-ramp-gold),
    var(--tt-orange),
    var(--tt-red)
  );
  /* The long one is the same ramp cycled twice. main.css clips it to heading
     text and sizes it at 220%, so a single pass leaves a heading gold in the
     middle and red at both ends regardless of its length; two passes keep the
     ramp reading as a repeat rather than as one wash. */
  --tt-heading-text-rainbow: linear-gradient(
    90deg,
    var(--tt-red),
    var(--tt-orange),
    var(--tt-gold),
    var(--tt-orange),
    var(--tt-red),
    var(--tt-orange),
    var(--tt-gold),
    var(--tt-orange),
    var(--tt-red)
  );

  /* The tribal band, declared once and spent in five places: the header strip,
     the horizon, the rules, the h1's banner and the footer. It is four
     linear-gradients tiling into a continuous row of triangles — a sawtooth,
     the oldest woven border there is, drawn here to an exact 16px repeat with
     hard stops and no anti-aliased fuzz. That exactness is the modern half of
     the brief doing its work: the same motif at a sloppy interval is folk art,
     at a precise one it is a system.

     Consumers set --band-ink to the colour of the teeth and paint it over
     whatever ground they already have. */
  --band-ink: var(--tt-red);
  --tribal-band:
    linear-gradient(135deg, var(--band-ink) 25%, transparent 25%) -8px 0,
    linear-gradient(225deg, var(--band-ink) 25%, transparent 25%) -8px 0,
    linear-gradient(315deg, var(--band-ink) 25%, transparent 25%) 0 0,
    linear-gradient(45deg, var(--band-ink) 25%, transparent 25%) 0 0;

  /* THE FRAME'S NUMBERS ARE IN main.css NOW (2026-08-18). --frame-pitch,
     --frame-tooth-ratio and the four --frame-tooth-* wedges lived here while
     the frame was this sheet's alone; the frame is every sheet's as of today,
     so they live with it in main.css :root and this sheet inherits them like
     any other month. Nothing about them was default-specific — the only part of
     the frame that ever was is the ramp it paints with, and that is
     --tt-heading-rainbow / -vertical above. Do not re-declare them here. */

  --bg: var(--tt-bg);
  --surface: var(--tt-bg-alt);
  --text: var(--tt-cyan);
  --text-soft: var(--tt-cyan-soft);
  --muted: var(--tt-gray);
  /* Ruby frames the card, the way a trump's own border is struck. */
  --border: var(--tt-red);
  --border-dim: rgba(201, 162, 74, 0.28);
  --border-teal: rgba(75, 100, 64, 0.6);

  /* Type. This sheet declares no font token at all any more, and that is the
     change (2026-08-15, user instruction) rather than an omission.

     What stood here was an inscriptional Trajan/Cinzel stack assigned to
     --font-cursive, because July spends that slot on Segoe Script and a
     handwriting face is the single most off-concept thing that could sit at the
     top of a tarot card. The stack was right and the slot was wrong: a Trajan
     column is not a cursive. main.css now carries three category slots, that
     exact stack is the shared --font-stoic default, and the H1 rule below
     spends it directly. Every other sheet reaching for ancient/tribal/tarot
     lettering gets the same stack for free instead of re-deriving it.

     The body face is no longer this sheet's business either: --font-text is
     locked in main.css. The old note here said "Optima stays" — Optima no
     longer sets body copy anywhere, having lost to Lucida Grande on defocus
     behaviour, but it survives inside the --font-stoic fallback chain, which is
     where its Roman-capital skeleton was doing the work all along. */

  background: var(--tt-bg);
  color: var(--tt-cyan);
  color-scheme: dark;
}

/* ---------------------------------------------------------------------------
   THE GROUND

   A card is not a CRT. main.css lays a 1px repeating scanline over the whole
   viewport for July's terminal, and it is the first thing to go — it is the
   one effect on the site that unambiguously says "screen", which is the exact
   opposite of what an object with things cut into it should say.
   --------------------------------------------------------------------------- */
body[data-theme-id="default"]::before {
  display: none;
}

/* Stone, lit from above. Three pigment washes that never resolve into a
   picture — this is the table the card lies on, and it has to stay quiet
   enough that a page of text sits on it for twenty minutes without fatigue.
   The washes are placed off-centre and at low alpha on purpose: a symmetric
   vignette reads as a photo filter, an asymmetric one reads as a surface. */
body[data-theme-id="default"] .night-sky {
  background:
    radial-gradient(ellipse at 26% 8%, rgba(201, 162, 74, 0.07), transparent 46%),
    radial-gradient(ellipse at 78% 22%, rgba(173, 77, 56, 0.06), transparent 42%),
    radial-gradient(ellipse at 50% 104%, rgba(207, 35, 33, 0.07), transparent 38%),
    linear-gradient(180deg, #1e1310 0%, #18100e 34%, var(--tt-bg) 72%, #0e0807 100%);
}

/* Gold dust rather than starlight. The drift and twinkle are kept — they are
   the sanctioned ambient exception in .github/agents/style/motion.md, they cost
   two small pseudo-elements, and a scatter of gold points on a dark ground is
   The Star, which is a trump. What changes is the ink: July's white and cyan
   points read as a night sky, warm gold and bone points read as leaf flaked off
   the card. Opacity is pulled back to 0.55 so it stays a texture and never
   competes with the type. */
body[data-theme-id="default"] .night-sky::before {
  opacity: 0.55;
  background-image:
    radial-gradient(circle at 18% 26%, rgba(233, 186, 60, 0.85) 0 1.1px, transparent 1.7px),
    radial-gradient(circle at 74% 16%, rgba(236, 223, 198, 0.72) 0 1px, transparent 1.55px),
    radial-gradient(circle at 42% 78%, rgba(201, 162, 74, 0.66) 0 0.9px, transparent 1.4px),
    radial-gradient(circle at 84% 58%, rgba(224, 33, 30, 0.42) 0 0.9px, transparent 1.4px),
    radial-gradient(circle at 57% 35%, rgba(236, 223, 198, 0.55) 0 0.7px, transparent 1.25px);
}

/* The dust is THREE layers, not one. .night-sky::before is the fine scatter,
   and .night-sky__stars--far / --near are two further parallax layers that
   drift and twinkle on their own clocks. Restyling only the pseudo-element
   leaves July's white and cyan starlight showing through on two thirds of the
   points — which is what it did, and what the screenshot caught. All three take
   the same warm ink. */
body[data-theme-id="default"] .night-sky__stars--far {
  opacity: 0.4;
  background-image:
    radial-gradient(circle, rgba(233, 186, 60, 0.8) 0 0.8px, transparent 1.1px),
    radial-gradient(circle, rgba(236, 223, 198, 0.62) 0 0.7px, transparent 1.05px),
    radial-gradient(circle, rgba(201, 162, 74, 0.5) 0 0.55px, transparent 0.95px);
}

body[data-theme-id="default"] .night-sky__stars--near {
  opacity: 0.5;
  background-image:
    radial-gradient(circle, rgba(233, 186, 60, 0.9) 0 1.2px, transparent 1.7px),
    radial-gradient(circle, rgba(201, 162, 74, 0.72) 0 0.95px, transparent 1.45px),
    radial-gradient(circle, rgba(236, 223, 198, 0.66) 0 1px, transparent 1.5px),
    radial-gradient(circle, rgba(224, 33, 30, 0.34) 0 0.75px, transparent 1.25px);
}

/* THE HORIZON — this theme's ground element.
   .night-sky__aurora is the shared ground slot, and it is July's city skyline;
   the invariant is that every other theme either hides it or repurposes it into
   its own scenery. Here it becomes the card's foot ornament: the tribal band
   run the full width, sitting on a band of deeper stone.

   The skyline clip-path has to be cleared explicitly — it is a fifty-stop
   polygon and any of it left behind would chew the band into towers. */
body[data-theme-id="default"] .night-sky__aurora {
  height: clamp(2.2rem, 5vh, 3.4rem);
  clip-path: none;
  background:
    linear-gradient(180deg, transparent 0 45%, rgba(207, 35, 33, 0.5) 45% calc(45% + 1px), transparent calc(45% + 1px)),
    linear-gradient(180deg, transparent 0 62%, #0d0706 62%);
  box-shadow: none;
}

/* The horizon's own 16px band is OFF, and it is superseded rather than dropped
   (2026-08-16). It was the card's foot ornament — the tribal band in gold at
   0.34, sitting at the bottom of the viewport behind the content — and THE
   FRAME now puts the real thing in the same place: the header's own teeth, in
   the jewel ramp, opaque, over the content, 7px deep against this band's 16px.
   Run together they are a scalloped gold texture with a sawtooth on top of it,
   and the eye reads a smudge rather than either mark. The stone band and the
   ruby hairline above it stay — those are the horizon, they sit clear of the
   frame, and they are not what this rule was. Do not restore it as a fix for a
   foot that looks bare; the foot is the frame now. */
body[data-theme-id="default"] .night-sky__aurora::before {
  content: none;
}

/* ---------------------------------------------------------------------------
   THE HEADER STRIP: NOTHING TO SWITCH OFF HERE ANY MORE (2026-08-18).

   This sheet used to carry `header::before { content: none }`, because main.css
   generated a 2px animated neon strip across the top of <header> and this was
   the one sheet that had replaced it with a frame. Both halves of that are now
   the site's: main.css retired the strip at the source and installed the frame
   for every sheet, so a rule cancelling it here would name a pseudo-element
   nothing generates. The argument for the move — locked, matched, no overlap —
   is written where the strip used to be, in main.css.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   THE FRAME IS IN main.css NOW (2026-08-18, user instruction: "borders always
   need to be perfect like this", answered on scope: all fourteen sheets).

   What stood here was the whole of it — `body[data-theme-id="default"]::after`
   at inset:0 with its four background layers, its four conic masks, the
   per-axis snap in an @supports block and the @media print switch-off. It was
   scoped to this sheet because the instruction it was built for was about this
   sheet's card. Nothing in it was ever about the card: the geometry is the
   same mark in any palette, and the only thing it takes from a sheet is
   --tt-heading-rainbow / --tt-heading-rainbow-vertical, which all fourteen
   declare. So it moved to main.css as body[data-theme-id]::after, and this
   sheet gets it by inheritance, in this sheet's ramp.

   Read the argument there, not here: one element for four edges, the conic
   mask, the 45deg corner proof, the count-from-vw / tile-in-percent split, and
   why there is no glow on it. What stays this sheet's business is the ramp —
   ruby, carnelian, gold, carnelian, ruby, with no spectrum in it. See "The
   Default Theme Has No Rainbow" above.

   Do not re-add a frame rule here. A second frame element is a second tooth
   phase, which is the exact defect the one-element rule exists to prevent.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   THE BRAND — LETTERING LOCKED, COLOUR LOCAL (user instruction, 2026-08-13).

   This sheet used to re-letter the wordmark as a Roman inscription: caps, wide
   tracking, the inscriptional --font-cursive stack, and the blinking underscore
   swapped for a still ruby lozenge. It read well as a tarot card and it was
   wrong for the reason a card argument cannot reach — the wordmark is not part
   of the theme. It is the one string on the site that says what this place is,
   and a reader who changes the theme has not asked to be taken somewhere else.

   So the split is now explicit:

     LOCKED, from main.css   the classic script face (--font-brand-cursive),
                             italic, mixed case, negative tracking, the versal
                             capital, and the blinking terminal underscore.
                             This sheet declares NONE of it. Neither may any
                             other sheet in public/themes/.

     LOCAL, declared here    colour and lighting only — gold leaf with the
                             engraved lip instead of July's yellow neon — plus
                             the float, which stays off because near-zero
                             ambient motion is this sheet's whole thesis and
                             the blink is now the one moving thing in the
                             header.

   Note what is NOT here any more: font-family, font-style, font-size,
   letter-spacing, text-transform, and the whole ::after override. Adding any
   of them back re-breaks the wordmark. See
   .github/agents/style/invariants.md — "The Wordmark Is Locked".
   --------------------------------------------------------------------------- */
body[data-theme-id="default"] .brand a {
  color: var(--tt-gold);
  text-shadow: 0 0 18px rgba(201, 162, 74, 0.34), var(--tt-engrave);
  animation: none;
}

body[data-theme-id="default"] .brand a:hover {
  color: var(--tt-yellow);
  transform: none;
  text-shadow: 0 0 22px rgba(233, 186, 60, 0.5), var(--tt-engrave);
}

/* The cursor keeps main.css's glyph, size, blink and cadence untouched — only
   its ink is re-pointed, because magenta is the one hue the de-rainbowed
   palette no longer puts anywhere else on the page and a lone magenta mark in
   a gold header reads as a leftover. Ruby is the anchor and the colour this
   sheet already strikes every pip and frame in. The blink itself is locked. */
body[data-theme-id="default"] .brand a::after {
  color: var(--tt-red);
  text-shadow: 0 0 12px rgba(207, 35, 33, 0.55);
}

/* ---------------------------------------------------------------------------
   HEADINGS

   Still gradients, not flowing ones. main.css animates every heading's
   background-position on a 5.4s loop; on a page with fifteen headings that is
   fifteen simultaneous continuous animations, and every one of them is a
   full-width gradient repaint. It is right for a neon theme and wrong for this
   one on both counts — concept and cost. The gradient stays, the flow stops,
   and the first frame is the finished frame.

   The h1 is the card's title: inscriptional caps, tracked wide, with a tapered
   rule struck beneath it. On a markdown page the h1 IS .heading-section__trigger
   (main.js emits the heading as the summary's trigger), so both selectors have
   to be carried or the styling lands on exactly half the site's pages.

   EVERY HEADING IS WHITE (2026-08-14, user instruction). h1 through h6, at
   every level, on every page, in the prose and in the components that embed a
   heading — the calendar agenda's h3, the hero card's h2, the folder section's
   h3, the Related block's h1 and its tag h2s. No gradient in a heading's
   letters any more, at any level.

   THREE DECLARATIONS, NOT ONE. `color` alone does nothing here and is the way
   this gets reported as not fixed: main.css paints every heading by clipping
   --tt-heading-text-rainbow to the glyphs and setting
   -webkit-text-fill-color: transparent, and that fill beats `color` on the
   element it lands on. The background has to be cleared, the clip returned to
   border-box, and the fill handed back — all of it, or the letters stay the
   ramp.

   WHAT DID NOT CHANGE: the three gradient tokens. They still ink every border,
   rule, frame, table, card, input, tag, the header strip and the section rail,
   and "The Default Theme Has No Rainbow" still governs all of them. Only the
   letterforms are repainted. The h1's tapered rule below is a mark, not type,
   and keeps its ruby-and-gold ramp.

   By day the same instruction is struck in ink instead — white on vellum is
   1.09:1 and simply is not there. See the day block at the foot of this file.
   --------------------------------------------------------------------------- */
body[data-theme-id="default"] main h1,
body[data-theme-id="default"] .page-title,
body[data-theme-id="default"] main h2,
body[data-theme-id="default"] main h3,
body[data-theme-id="default"] main h4,
body[data-theme-id="default"] main h5,
body[data-theme-id="default"] main h6,
body[data-theme-id="default"] .markdown-page .heading-section__trigger {
  background: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: #f2e6d2;
  -webkit-text-fill-color: #f2e6d2;
  text-shadow: none;
  animation: none;
  letter-spacing: 0.02em;
}

body[data-theme-id="default"] main h1,
body[data-theme-id="default"] .page-title,
body[data-theme-id="default"] .heading-section--level-1 > .heading-section__summary > .heading-section__trigger {
  font-family: var(--font-stoic);
  font-style: normal;
  font-weight: 600;
  font-size: clamp(1.9rem, 5vw, 3.3rem);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* NO RULE UNDER A HEADING (2026-08-14, user instruction).

   What stood here was the title banner: a 1px ruby-and-gold stroke struck under
   the h1 and under the level-1 section trigger, tapered to nothing at both ends.
   It is gone rather than restyled. A heading in this theme is separated from its
   content by size, tracking and face — nothing is drawn beneath it at any level.

   Do not re-add an `::after` rule, a `border-bottom`, or a `text-decoration` to
   a heading here. The card still reads as a card: it keeps its four struck
   corner pips, its frame and the tribal band at head and foot. */

/* h2 and h3 used to carry the warm ramp at two different phases of it, so that
   hierarchy read as colour as well as size, and each was restated on its
   .heading-section--level-N trigger at (0,4,0). Both blocks are gone rather
   than recoloured: they outranked the white rule above on order and on
   specificity respectively, so leaving either one in place would have left the
   two most common headings on the site still gradient. Hierarchy is now size,
   tracking and face alone, which is what the instruction costs and what it
   buys — a heading no longer competes with the frame it sits inside.

   Do not re-add a per-level heading colour here. If a level needs separating,
   separate it by size. */

/* The Related block's own headings. main.css carries them at (0,3,1) and
   (0,4,1) on purpose — high enough that a month sheet's `main h1` / `main h2`
   rules, written for the page's title, cannot reach a component label — so the
   white rule above does not reach them either and they need saying again one
   step higher. The h1 comes off the same clipped token as the prose headings;
   the tag h2 was already solid and only wants the bone taken to white. The mono
   face and the tracking are main.css's and stay.

   The ruled underline does NOT stay. main.css gives this heading a 1px
   `border-image: var(--tt-heading-rainbow)` along its foot at (0,3,1); it is
   cleared here at (0,4,1) along with the padding that was holding the type off
   it, because no heading in this theme carries a rule beneath it. */
body[data-theme-id="default"] .markdown-page .related h1.related__heading {
  padding-bottom: 0;
  border-bottom-width: 0;
  border-image: none;
  background: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: #f2e6d2;
  -webkit-text-fill-color: #f2e6d2;
}

body[data-theme-id="default"] .markdown-page .related .related__group h2.related__tag {
  color: #f2e6d2;
  -webkit-text-fill-color: #f2e6d2;
}

/* ---------------------------------------------------------------------------
   THE PAGE BODY CARRIES NO CORNER MARKS (2026-08-15, user instruction)

   `main::before` used to carry the breadcrumb card's grammar out to the page
   body — a ruby pip at each corner of <main> with a gold quarter-arc swung
   around it — so the content column read as the card's face. It is removed.
   DO NOT PUT IT BACK: at page width the four arcs are the only marks in a
   thousand pixels of empty gutter, so they stop reading as an engraver's
   compass mark and start reading as a frame the page does not have.

   THE CARD ITSELF KEEPS ITS PIPS. `.breadcrumb-nav::after` in main.css is a
   different element and is untouched — four struck corners on an object the
   size of a card is the mark working as intended. What was removed is the copy
   of it on <main>, and only that.
   --------------------------------------------------------------------------- */

/* The breadcrumb card sits INSIDE the page card now, so it drops the cyan
   bloom July gives it — one lit object inside another lit object is two cards,
   and the point of the nesting is that there is only one. What is left is a
   slightly raised stone panel with the pips still struck into it. */
body[data-theme-id="default"] .breadcrumb-nav {
  background: rgba(35, 23, 20, 0.72);
  box-shadow: none;
}

/* The terminal sweep that runs across the bar. Same call as the scanline and
   the heading flow: it is a screen effect on an object that is not a screen. */
body[data-theme-id="default"] .breadcrumb-nav::before {
  display: none;
  animation: none;
}

/* ---------------------------------------------------------------------------
   TEXT
   --------------------------------------------------------------------------- */

body[data-theme-id="default"] p { color: var(--tt-cyan); }

body[data-theme-id="default"] strong,
body[data-theme-id="default"] b {
  color: var(--tt-gold);
  font-weight: 700;
}

body[data-theme-id="default"] em,
body[data-theme-id="default"] i { color: var(--tt-green); }

body[data-theme-id="default"] mark {
  color: var(--tt-yellow);
  text-shadow: none;
}

/* Links. main.css gives a link a hotpink bloom on hover AND starts an infinite
   glow loop that runs for as long as the pointer rests on it — a continuous
   animation per hovered link, which the motion rules would not sanction for a
   new effect and which this theme has no use for. Replaced with a gold-leaf
   colour change: instant, one repaint, and it reads as the mark an engraver
   makes rather than as a neon sign warming up.

   No underline, standing user rule (2026-08-14): a hyperlink never carries one,
   in any state. The struck rule this used to draw under the word is gone.

   Hover colour is --link-hover, standing user rule 2026-08-14: #FF465A on
   every theme, not gold-leaf here any more. The token is set once in
   main.css's :root and locked — no sheet re-points it. */
body[data-theme-id="default"] a:hover,
body[data-theme-id="default"] a:focus-visible {
  color: var(--link-hover);
  text-shadow: none;
  text-decoration: none;
  animation: none;
}

body[data-theme-id="default"] a:visited {
  color: var(--tt-purple);
  text-shadow: none;
}

/* The focus ring is topaz on a dark ground at 3px offset — the contrast is
   well clear of the 3:1 the success criterion asks of a focus indicator, and
   it is the one ring in this sheet, because a focus indicator is not
   decoration and the no-borders rule was never about accessibility. */
body[data-theme-id="default"] a:focus-visible,
body[data-theme-id="default"] button:focus-visible,
body[data-theme-id="default"] input:focus-visible,
body[data-theme-id="default"] textarea:focus-visible,
body[data-theme-id="default"] select:focus-visible {
  outline: 1px solid var(--tt-yellow);
  outline-offset: 3px;
}

/* Small-caps labels. The eyebrow is already tracked and uppercased in main.css;
   here it is re-inked to gold so it reads as the card's classification line —
   the small lettering above a trump's illustration — rather than as an alert. */
body[data-theme-id="default"] .eyebrow {
  color: var(--tt-gold);
  letter-spacing: 0.3em;
}

/* ---------------------------------------------------------------------------
   MARKS AND RULES
   --------------------------------------------------------------------------- */

/* The rule between sections is the tribal band, at its true 16px repeat and
   tapered at both ends by a mask. main.css draws it as a 1px rainbow
   border-image; this is the one place in the sheet where a hairline is traded
   for an ornament, because an <hr> is the only element on the page whose entire
   job is to be a mark. Everything else keeps its hairline. */
body[data-theme-id="default"] hr {
  height: 9px;
  border: 0;
  border-image: none;
  margin: 2.4rem 0;
  --band-ink: var(--tt-red);
  background-image: var(--tribal-band);
  background-size: 16px 18px;
  background-repeat: repeat-x;
  background-position: -8px 0, -8px 0, 0 0, 0 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 22%, #000 78%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 22%, #000 78%, transparent);
  opacity: 0.85;
}

/* No list bullet. This sheet used to cut July's eight-pointed star down to a
   ruby lozenge with a gold core; unordered lists now carry no marker at all, in
   any state, and the rule is gone rather than restyled. Do not add one back. */

/* Numerals in gold leaf, not ruby. Two reasons pointing the same way: ruby is
   3.59:1 on this ground, which is fine for the pips and the frame but under the
   4.5 a numeral needs as text; and a trump numbers itself in gold at the head of
   the card, so the convention and the contrast agree. Red stays bound to the
   structural things the Red Color Bias invariant names — the border, the table
   heads, the frame and the pips — none of which is body-size text. */
body[data-theme-id="default"] ol > li::marker {
  color: var(--tt-gold);
  font-weight: 700;
}

/* Quotes carry gold at the inset edge rather than emerald. Still no left rule —
   border-left is reserved for list anchors and nothing else. */
body[data-theme-id="default"] blockquote {
  color: var(--tt-cyan-soft);
  font-style: italic;
  box-shadow: inset 1rem 0 1.4rem -1.2rem rgba(201, 162, 74, 0.55);
}

/* ---------------------------------------------------------------------------
   CODE, TABLES, PANELS
   --------------------------------------------------------------------------- */

/* Code is magenta, but NOT --tt-pink directly. The token is tuned to sit in a
   gradient and to ink a bullet; against the code block's own darker ground it
   measures 3.83:1, which is under the 4.5 that body-size text has to clear.
   This is the lighter cut of the same magenta, at 5.7:1, and it is stated as a
   literal so the gradients keep the token they were balanced against. The day
   lighting re-points this at its own --tt-pink, which is already dark enough on
   stock to clear the bar without help. */
body[data-theme-id="default"] code {
  color: #f85857;
  background: rgba(35, 23, 20, 0.66);
}

body[data-theme-id="default"] pre {
  background: rgba(13, 7, 6, 0.62);
}

body[data-theme-id="default"] pre code {
  color: var(--tt-cyan-soft);
  background: transparent;
}

/* Table heads are struck in the anchor. July puts peridot behind them with the
   page ground as the text, which is a bright bar across the page; ruby with
   bone lettering on it is the card's own frame colour doing the same job, and
   it holds the red bias in the one component that repeats down a long page. */
body[data-theme-id="default"] th {
  color: var(--tt-cyan);
  background: var(--tt-red);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: 0.86em;
}

body[data-theme-id="default"] td { color: var(--tt-cyan-soft); }

/* Cards. The purple bloom and the cyan hover bloom both go — a card in this
   theme is a panel cut into stone, and what marks it is the frame and the lift,
   not a glow around it. The lift is kept because it is a 180ms transform, which
   is the kind of motion the rules actively prefer. */
body[data-theme-id="default"] .hero-card,
body[data-theme-id="default"] .folder-section {
  background: rgba(35, 23, 20, 0.42);
  box-shadow: none;
}

body[data-theme-id="default"] .hero-card:hover,
body[data-theme-id="default"] .folder-section:hover {
  border-color: rgba(207, 35, 33, 0.5);
  box-shadow: none;
}

body[data-theme-id="default"] .tag {
  color: var(--tt-green);
  letter-spacing: 0.04em;
}

/* ---------------------------------------------------------------------------
   NO RAILS (2026-08-14, user instruction).

   main.css draws two 3px vertical bars out of --tt-heading-rainbow-vertical:
   `.heading-section::before`, the section rail that fades in on the active
   heading path, and `.page-toc::before` down the left edge of the index. Both
   are switched off for this theme and this theme only — `content: none` rather
   than `display: none`, so the pseudo-element is never generated instead of
   being generated and hidden.

   THIS IS A SCOPED EXCEPTION, NOT A REPEAL. `.github/agents/style/invariants.md`
   locks the section rail site-wide, and it stays locked: main.css still declares
   it, the eleven month sheets still restyle it, and it still marks the active
   heading path everywhere except here. Do not carry this override into another
   sheet and do not delete the rail from main.css.

   WHAT THE THEME LOSES. The rail was the only visible mark of which heading path
   is active. The collapse behaviour itself is untouched — hover and focus still
   open a section, JS still marks `.heading-section--active`, and the saved place
   still restores — but in this theme that state now reads from the section
   opening alone.

   The index gets its 0.55rem of rail clearance back as well; main.css pads its
   left edge to stand clear of a bar that is no longer there.
   --------------------------------------------------------------------------- */
body[data-theme-id="default"] .heading-section::before,
body[data-theme-id="default"] .page-toc::before {
  content: none;
}

/* The table of contents is the card's index. Gold rules, bone entries.

   NO PANEL BEHIND IT (2026-08-18, user instruction). This carried a 36% wash of
   the card ink, and the day sheet below carried an 86% bone one. Both are gone:
   the index is set on the page, not on a plate laid over it. Nothing replaces
   them — the reader tells the index from the prose by its mono face, its caps
   title and the gutter the float leaves, which is the same set of marks every
   other element on this site is told apart by. */
body[data-theme-id="default"] .page-toc {
  padding-left: var(--toc-pad);
  background: transparent;
}

/* CARRIED AT (0,4,2), not the (0,3,1) this was written at. main.css now guards
   the index title against the month sheets' `main h2` rules by restating its
   type at (0,3,1) — see THE TITLE IS AN H2 AND MUST NOT LOOK LIKE ONE there —
   and that rule sets `letter-spacing` among the rest. At equal weight this
   sheet would still win on load order alone, because every theme sheet is
   linked after main.css, but a tie is not a guard: one more class in main.css
   and the gold would go out with no rule changed here. The extra `.markdown-page`
   and `h2` put it beyond reach.

   main.css carries `color: var(--tt-cyan)` at that same (0,3,1) to keep the
   month sheets off the title, so gold is only gold from here up. */
body[data-theme-id="default"] .markdown-page .page-toc h2.page-toc__title {
  color: var(--tt-gold);
  letter-spacing: 0.22em;
}

/* The footer is the card's foot: the band again, at low alpha, above the text.
   Same motif at the top of the page and the bottom of it is what closes the
   object — a card is bordered on all four sides or it is a poster. */
body[data-theme-id="default"] footer {
  position: relative;
  padding-top: 2rem;
  color: var(--tt-gray);
  letter-spacing: 0.14em;
}

body[data-theme-id="default"] footer::before {
  content: "";
  position: absolute;
  top: 0.6rem;
  left: 12%;
  right: 12%;
  height: 8px;
  --band-ink: rgba(201, 162, 74, 0.4);
  background-image: var(--tribal-band);
  background-size: 16px 16px;
  background-repeat: repeat-x;
  background-position: -8px 0, -8px 0, 0 0, 0 0;
}

/* ---------------------------------------------------------------------------
   FORMS AND CONTROLS
   --------------------------------------------------------------------------- */

body[data-theme-id="default"] input,
body[data-theme-id="default"] textarea,
body[data-theme-id="default"] select {
  background: rgba(13, 7, 6, 0.62);
  color: var(--tt-cyan);
}

body[data-theme-id="default"] .site-search__input { color: var(--tt-cyan); }

body[data-theme-id="default"] .site-search__panel {
  background: rgba(19, 12, 11, 0.97);
}

body[data-theme-id="default"] .site-search__option.is-active {
  background: rgba(207, 35, 33, 0.16);
}

/* ---------------------------------------------------------------------------
   THE ZODIAC STRIP

   The chips take their colour from the tokens above and need nothing here
   beyond the glow, which is already set on --zodiac-glow at the top of this
   block. Restated only to be explicit about what this sheet must never do:
   no border, no ring outline, no ring box-shadow, no ::before ring on a chip,
   under any circumstance. See .github/agents/style/chips.md — this has
   regressed before, and it regressed by a month sheet re-framing a chip that
   main.css had already unframed.

   This sheet styles no bare `a`, `button` or `input` element selector, which
   is the other half of that trap: those reach the chips at a higher weight
   than the chips' own class. Every rule above is scoped to a class or to a
   descendant of one.
   --------------------------------------------------------------------------- */
body[data-theme-id="default"] .celestial-chip {
  border: 0;
  box-shadow: none;
  outline: none;
}

/* ---------------------------------------------------------------------------
   THE STORM (2026-08-14, user instruction: "very realistic lightning")

   The table the card lies on is now lit, from time to time, by a storm outside
   the frame. This is the one place the sheet spends real motion, and it earns
   it the way lightning earns attention in life: by being absent for most of a
   minute and then, for four hundred milliseconds, being the only thing there
   is. Nothing here runs continuously — the layers sit at opacity 0 and stay
   there, which is why this does not violate the "almost no motion at all"
   half of the brief. The static first frame is a dark sky, and a dark sky is
   also the honest final frame: lightning that has finished is not dimmer, it
   is gone. That is why the reduced-motion answer below is `display: none`
   rather than a frozen bolt.

   WHAT MAKES A BOLT READ AS REAL. Four things, and CSS can do all four:

     1  Flicker, not a flash. A cloud-to-ground stroke is not one event. A dim
        stepped leader feels its way down, the return stroke fires and is the
        bright one, and then two or three restrikes follow down the ionised
        channel at 40-70ms intervals, each weaker than the last. The eye knows
        this cadence even when it cannot name it, and a single fade-in/fade-out
        is the tell that gives away every fake lightning effect. Every keyframe
        block below is that envelope, written out stroke by stroke.

     2  Forks that die in the air. Real channels branch downward and outward,
        the branches are thinner than the trunk, and most of them terminate
        mid-descent without reaching anything. The clip-paths below are traced
        by hand for this: down one edge of the trunk, out and back along each
        branch as an excursion, then up the other edge — one closed,
        non-self-intersecting polygon per bolt, the same technique main.css
        uses for July's fifty-vertex skyline.

     3  A taper. The channel is widest at the cloud base and comes to an actual
        point at the end. Both trunks run from roughly a 9px width at the cloud
        down to about 2px, and both close on a single shared tip vertex rather
        than on a flat end.

     4  The sky lights up, not just the channel. A strike is a light source: it
        washes the cloud base far wider than the bolt is, and the wash outlasts
        the channel by a beat. That is `.night-sky::after`, keyed to the same
        cycle so the flash and the bolt are the same event.

   NO BLUE, WHICH IS THE ONE PLACE PHYSICS AND THE PALETTE DISAGREE. Lightning
   photographs blue-white because ionised nitrogen emits there, and the theme's
   locked instruction is that nothing on this sheet is blue. The resolution is
   the one every landscape photographer already knows: at distance, through
   haze and dust, a channel warms — near strikes shot through summer air come
   back white-hot cored in violet and gold, which is exactly this palette's
   amethyst and gold leaf. So the channel is white (a real bolt's core is
   genuinely blown out to white on any surface) and every glow around it is
   topaz, bone and amethyst. Nothing borrows --tt-blue, even at low alpha.

   ONE CLOCK, SEVEN EVENTS. Every layer runs the same --storm-cycle, and the
   strikes are placed at percentages of it rather than each layer keeping its
   own timer. That is not a tidiness point, it is the whole illusion: if the
   flash and the channel drifted apart by even 30ms the effect would read as
   two unrelated animations. The offsets are irregular on purpose — 8.2s,
   8.7s, 1.7s, 11.5s, 7.4s, 8.2s between events — so the storm never settles
   into a countable rhythm inside one pass.

     6.0%   near strike, three return strokes          (bolt A + sky flash)
     21.5%  distant sheet lightning, no channel        (horizon glow)
     38.0%  far strike, single stroke                  (bolt B + sky flash)
     41.2%  the same cell restrikes, weakly            (bolt B + sky flash)
     63.0%  distant sheet lightning, dimmer            (horizon glow)
     77.0%  near strike again, two strokes, mirrored   (bolt A + sky flash)
     92.5%  distant sheet lightning, faint             (horizon glow)

   WHY THESE FOUR HOOKS AND NO NEW MARKUP. `.night-sky::after` is already
   anticipated by main.css's flyway rule and is otherwise unspent; the two
   `.night-sky__fireworks` pseudo-elements are unused, the element is fixed at
   inset 0 with z-index 3, and it is already display:none under both reduced
   preferences, which the bolts inherit for free; `.night-sky__aurora::after`
   is free and sits at the horizon, where distant lightning belongs. Every one
   of them is inside `.night-sky`, which is z-index 0 — so no flash ever paints
   over a word of text, and the storm cannot cost the page any legibility.
   Nothing was added to main.js and no other theme is touched.

   COST. Each layer animates `opacity` alone (bolt A also snaps `transform`
   once, in the dark, between its two strikes), so each gets its own compositor
   layer and the paint is done once. The glows are static `drop-shadow` filters
   — rasterised into the layer at promotion, not re-evaluated per frame, which
   is why the glow is a filter here and the motion is not.
   --------------------------------------------------------------------------- */
body[data-theme-id="default"] {
  --storm-cycle: 53s;
}

/* THE SKY FLASH. The cloud base lit from above and behind, wide and soft, with
   the hot core placed left of centre and high — a strike overhead lights the
   whole ceiling, so this layer is deliberately not aligned to either bolt and
   reads correctly for both. Sits at z-index 0, under the gold dust, so a flash
   brightens the sky the dust hangs in rather than washing over it. */
body[data-theme-id="default"] .night-sky::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  transform: translate3d(0, 0, 0);
  background:
    radial-gradient(ellipse 78% 52% at 32% -8%, rgba(242, 230, 210, 0.6), rgba(236, 223, 198, 0.28) 36%, transparent 68%),
    radial-gradient(ellipse 100% 66% at 62% -20%, rgba(233, 186, 60, 0.24), transparent 60%),
    linear-gradient(180deg, rgba(233, 186, 60, 0.15), rgba(173, 77, 56, 0.065) 44%, transparent 74%);
  animation: defaultSkyFlash var(--storm-cycle) linear infinite;
}

/* Both bolts share their channel paint and their glow stack.

   THE CHANNEL FADES AS IT FALLS, and this is the one decision here that is
   equally a physics decision and a legibility decision.

   <main> in this theme has no fill. The card is a frame of marks — four struck
   pips and their arcs — laid straight over the stone, which means there is no
   panel between the sky and the body copy and a bolt is behind the text rather
   than behind a page. A 5px opaque white channel crossing a line of bone type
   takes that line to about 1.3:1 for as long as it is lit. Brief, but this
   sheet does not get to trade contrast for an effect.

   What fixes it is also what a bolt actually looks like. A return stroke is
   brightest at the cloud base and the lower channel is nearly always veiled —
   by the rain shaft it is falling through, by the murk under the cell, by its
   own smoke. So the fill is blown-out white for the top third, where the bolt
   is in open sky above the reading column, and ramps down through bone to a
   0.14-alpha gold by the tip. The hard white core therefore lives where there
   is nothing to obscure, and what crosses the paragraphs is a warm translucent
   veil that reads as a channel receding into rain.

   The bolts also stop short of the horizon rather than striking it, which is
   the same call again: most discharges never reach the ground, and one that
   dissolves into the murk is both the commoner event and the quieter mark.

   The colour is in the drop-shadows, which spread white → bone → gold →
   amethyst, tight to wide. Four on the near bolt, three on the far one — the
   fourth is the wide amethyst bloom, and a distant channel has too much air in
   front of it to throw one. */
body[data-theme-id="default"] .night-sky__fireworks::before,
body[data-theme-id="default"] .night-sky__fireworks::after {
  content: "";
  position: absolute;
  opacity: 0;
  pointer-events: none;
  transform-origin: 50% 100%;
  background: linear-gradient(
    180deg,
    rgba(242, 230, 210, 0.9) 0%,
    #f2e6d2 9%,
    #f2e6d2 34%,
    rgba(241, 230, 210, 0.78) 52%,
    rgba(247, 226, 186, 0.5) 70%,
    rgba(233, 186, 60, 0.3) 86%,
    rgba(201, 162, 74, 0.14) 100%
  );
}

/* BOLT A — the near strike, left of the page.

   THE BOX IS WIDE ON PURPOSE, and the first cut of this got it wrong. A
   clip-path's coordinates are percentages of its own element, so the box's
   aspect ratio IS the bolt's character: run the same polygon in a 190px box
   over 98vh and every bend flattens to nothing and the channel reads as a
   crack in the screen rather than as lightning. The trunk here wanders across
   82% of a box that is itself 31vw wide — about 160px of lateral travel per
   830px of drop, which is roughly what a real channel does — and only then do
   the bends read as the stepped, angular descent they are.

   The half-widths are correspondingly tiny — under 1% of the box — which puts
   the trunk at roughly 8.6px at the cloud base and 2.3px at the tip. It was
   thinner than that on the first pass and had to come back up: a drop-shadow
   spreads a shape's own alpha, so a 2px channel had nothing to give its glow
   and the bolt rendered as a bare scratch. Below about 6px the fill stops
   being able to light anything around it.

   THE POLYGON IS NOT HAND-TRACED and should not be hand-edited. It came off a
   generator that walks a centreline — flipping lateral direction most steps and
   holding it for a second step now and then, so the trunk gets the occasional
   long sweep one way — then offsets that centreline along its own perpendicular
   to get the two edges. The perpendicular matters: offsetting in x instead, the
   obvious way to do it by hand, makes steep segments thin and shallow ones fat,
   and the channel visibly changes weight as it turns.

   Three branches, all dying in the air, all leaving at 25-55° off the trunk and
   descending — a branch drawn near-horizontal is the other tell that gives a
   fake bolt away. Read the polygon as one closed loop: down the left edge, out
   and back along each left branch, round the tip, then up the right edge taking
   the right-hand branch on the way. Each branch departs and rejoins the trunk
   edge within its own root width, so the mouth closes on itself instead of
   filling as a triangle.

   To recut it: the generator is in the session scratchpad, not the repo. It is
   cheaper to rewrite than to keep — the output is the artefact, and any tool
   that walks a centreline and offsets it perpendicular will do. */
body[data-theme-id="default"] .night-sky__fireworks::before {
  left: -1%;
  top: -6vh;
  width: clamp(210px, 31vw, 470px);
  height: 84vh;
  clip-path: polygon(
    54.13% 0.17%,
    57.26% 5.92%,
    47.90% 11.40%,
    55.34% 15.30%,
    46.15% 18.27%,
    50.46% 22.58%,
    45.90% 25.65%,
    50.22% 29.11%,
    44.72% 32.30%,
    40.43% 39.45%,
    31.52% 46.90%,
    13.82% 56.69%,
    2.00% 64.37%,
    14.00% 56.81%,
    31.83% 47.09%,
    40.74% 39.76%,
    46.77% 45.72%,
    26.70% 51.95%,
    33.63% 57.47%,
    28.69% 60.23%,
    6.25% 66.88%,
    23.13% 71.22%,
    19.90% 77.13%,
    24.35% 80.56%,
    33.83% 87.16%,
    24.94% 91.26%,
    31.47% 96.70%,
    35.30% 100.00%,
    31.91% 96.51%,
    25.51% 91.32%,
    34.45% 87.14%,
    24.85% 80.29%,
    20.60% 77.09%,
    23.71% 70.93%,
    7.43% 67.13%,
    12.43% 71.49%,
    18.31% 75.59%,
    21.06% 81.12%,
    18.49% 75.53%,
    12.68% 71.36%,
    7.01% 67.04%,
    29.11% 60.69%,
    34.52% 57.39%,
    27.48% 52.29%,
    47.60% 46.07%,
    41.48% 39.39%,
    45.67% 32.66%,
    51.39% 29.20%,
    47.14% 25.67%,
    51.77% 22.59%,
    47.84% 19.00%,
    49.35% 29.51%,
    64.72% 37.13%,
    49.74% 29.36%,
    47.41% 18.60%,
    56.77% 15.45%,
    49.42% 11.52%,
    58.82% 6.26%,
    55.87% -0.17%
  );
  /* THE BLUR RADII ARE SMALL BECAUSE THE CHANNEL IS THIN. A drop-shadow
     spreads a shape's own alpha over its radius, so a 90px blur of a 5px line
     — which is what the first cut asked for — lands at an alpha too low to see
     and the bolt renders with no glow at all. The wide bloom is the sky flash's
     job; these four stay tight and bright, white → bone → gold → amethyst. */
  filter:
    drop-shadow(0 0 3px rgba(242, 230, 210, 1))
    drop-shadow(0 0 9px rgba(241, 230, 210, 0.95))
    drop-shadow(0 0 22px rgba(233, 186, 60, 0.75))
    drop-shadow(0 0 52px rgba(173, 77, 56, 0.6));
  animation: defaultBoltNear var(--storm-cycle) linear infinite;
}

/* BOLT B — the far strike, right of the page. Two thirds the box, two thirds
   the throw of light, one branch instead of three, and a peak opacity of 0.8
   rather than 1: distance costs a channel its brightness before it costs it
   anything else, and it costs it its branches next. */
body[data-theme-id="default"] .night-sky__fireworks::after {
  left: 70%;
  top: 2vh;
  width: clamp(150px, 21vw, 320px);
  height: 70vh;
  clip-path: polygon(
    57.71% -0.44%,
    36.16% 3.38%,
    40.95% 9.37%,
    61.95% 15.00%,
    57.14% 20.23%,
    63.96% 26.29%,
    41.63% 33.11%,
    47.48% 38.18%,
    33.68% 48.87%,
    10.43% 58.98%,
    8.09% 64.73%,
    10.65% 59.07%,
    34.03% 49.03%,
    47.83% 38.45%,
    55.73% 44.56%,
    64.74% 47.93%,
    58.18% 53.69%,
    51.89% 59.63%,
    58.42% 66.48%,
    51.19% 72.26%,
    57.40% 77.25%,
    50.15% 84.71%,
    64.20% 92.03%,
    57.88% 97.64%,
    65.09% 100.00%,
    58.46% 97.63%,
    64.80% 91.94%,
    50.81% 84.63%,
    58.13% 77.27%,
    51.96% 72.28%,
    59.24% 66.49%,
    52.78% 59.63%,
    59.00% 53.92%,
    65.73% 47.86%,
    56.52% 44.21%,
    48.43% 37.87%,
    42.59% 33.46%,
    65.03% 26.62%,
    58.46% 20.17%,
    63.08% 14.57%,
    41.93% 8.79%,
    37.34% 3.93%,
    58.29% 0.44%
  );
  filter:
    drop-shadow(0 0 3px rgba(242, 230, 210, 0.9))
    drop-shadow(0 0 8px rgba(241, 230, 210, 0.7))
    drop-shadow(0 0 24px rgba(233, 186, 60, 0.5));
  animation: defaultBoltFar var(--storm-cycle) linear infinite;
}

/* DISTANT SHEET LIGHTNING. The commonest thing you actually see in a storm: a
   cell far enough off that the channel is entirely hidden and only the cloud
   it is inside lights up. No geometry, no fork, no hard edge — a soft dome of
   light sitting on the horizon and diffusing upward, with a slower rise and a
   longer decay than a near stroke because that is what several kilometres of
   air does to an impulse.

   Placed at `bottom: 100%` so it lives entirely ABOVE the horizon band and
   never paints across it: the band is what the light is happening behind. It
   inherits the aurora's z-index 2, which puts it under both bolts — correct,
   since everything at this layer is further away than they are. */
body[data-theme-id="default"] .night-sky__aurora::after {
  content: "";
  position: absolute;
  left: 6%;
  right: 26%;
  bottom: 100%;
  height: clamp(4.5rem, 14vh, 10rem);
  opacity: 0;
  pointer-events: none;
  transform: translate3d(0, 0, 0);
  background: radial-gradient(
    ellipse 62% 100% at 40% 100%,
    rgba(240, 231, 210, 0.36),
    rgba(233, 186, 60, 0.17) 34%,
    rgba(173, 77, 56, 0.075) 60%,
    transparent 80%
  );
  animation: defaultSheetFlash var(--storm-cycle) linear infinite;
}

/* The envelopes. Every stop is a real millisecond count against a 53s cycle —
   1ms is 0.0019% here — so the numbers look arbitrary and are not: the gap
   between a leader and its return stroke is ~20ms, between restrikes ~50ms,
   and the whole cloud-to-ground event is under half a second. */
@keyframes defaultBoltNear {
  /* Strike one, 6.0%: leader, return stroke, and two restrikes down the same
     channel, each weaker. 450ms end to end. */
  0%, 5.98% { opacity: 0; transform: translate3d(0, 0, 0); }
  6.02% { opacity: 0.24; }
  6.05% { opacity: 1; }
  6.11% { opacity: 0.34; }
  6.16% { opacity: 0.96; }
  6.22% { opacity: 0.18; }
  6.29% { opacity: 0.66; }
  6.36% { opacity: 0.1; }
  6.85% { opacity: 0; }
  /* Between the two strikes the bolt is mirrored and shortened a twelfth, so
     the cell's second discharge is not a pixel rerun of its first. The swap is
     a 26ms snap at 76.9% — invisible, because opacity has been 0 for seventy
     percent of the cycle by then. The origin is the bottom edge, so shortening
     lifts the cloud base and leaves the tip where it belongs.

     THE TRANSLATE IS NEGATIVE, AND IT HAS TO BE. Mirroring swings the trunk
     from the left of its own box to the right of it, which walked the second
     strike straight into the reading column — the whole reason the bolt is
     parked off the left edge in the first place. The box moves left by roughly
     the trunk's own offset to put it back in the gutter. Retune this and the
     translate together, never one alone. */
  76.9% { opacity: 0; transform: translate3d(0, 0, 0); }
  76.95% { opacity: 0; transform: translate3d(-13vw, 0, 0) scale(-0.92, 0.96); }
  77.03% { opacity: 0.2; }
  77.07% { opacity: 0.9; }
  77.13% { opacity: 0.22; }
  77.18% { opacity: 0.62; }
  77.25% { opacity: 0.08; }
  77.62% { opacity: 0; }
  100% { opacity: 0; transform: translate3d(-13vw, 0, 0) scale(-0.92, 0.96); }
}

@keyframes defaultBoltFar {
  /* One clean stroke and one faint restrike, 38.0%. */
  0%, 37.98% { opacity: 0; }
  38.02% { opacity: 0.16; }
  38.05% { opacity: 0.8; }
  38.11% { opacity: 0.2; }
  38.16% { opacity: 0.5; }
  38.44% { opacity: 0; }
  /* The same cell going again 1.7s later, which is what cells do. */
  41.16% { opacity: 0; }
  41.2% { opacity: 0.46; }
  41.25% { opacity: 0.12; }
  41.29% { opacity: 0.3; }
  41.55% { opacity: 0; }
  100% { opacity: 0; }
}

@keyframes defaultSkyFlash {
  /* Tracks each bolt's flicker stop for stop, then outlasts it: the channel is
     gone by 6.85% and the ceiling is still cooling at 7.3%. That trailing beat
     is most of what sells the flash as light rather than as a fade. */
  0%, 5.98% { opacity: 0; }
  6.02% { opacity: 0.2; }
  6.05% { opacity: 1; }
  6.12% { opacity: 0.42; }
  6.16% { opacity: 0.92; }
  6.23% { opacity: 0.26; }
  6.29% { opacity: 0.6; }
  6.4% { opacity: 0.14; }
  7.3% { opacity: 0; }
  37.98% { opacity: 0; }
  38.05% { opacity: 0.5; }
  38.12% { opacity: 0.14; }
  38.16% { opacity: 0.32; }
  38.9% { opacity: 0; }
  41.16% { opacity: 0; }
  41.2% { opacity: 0.28; }
  41.7% { opacity: 0; }
  76.95% { opacity: 0; }
  77.07% { opacity: 0.86; }
  77.13% { opacity: 0.24; }
  77.18% { opacity: 0.56; }
  78.1% { opacity: 0; }
  100% { opacity: 0; }
}

@keyframes defaultSheetFlash {
  /* Distance smooths an impulse. No stop here is instantaneous, the peak sits
     100ms in rather than 20ms in, and the decay runs three times as long as a
     near stroke's — the pulse arrives already blurred by the air it crossed. */
  0%, 21.4% { opacity: 0; }
  21.52% { opacity: 0.55; }
  21.62% { opacity: 0.92; }
  21.72% { opacity: 0.46; }
  21.8% { opacity: 0.74; }
  22.35% { opacity: 0; }
  62.88% { opacity: 0; }
  63.02% { opacity: 0.4; }
  63.14% { opacity: 0.62; }
  63.62% { opacity: 0; }
  92.38% { opacity: 0; }
  92.52% { opacity: 0.26; }
  92.64% { opacity: 0.38; }
  93.1% { opacity: 0; }
  100% { opacity: 0; }
}

/* THE STORM IS A NIGHT EVENT. The day face has weather of its own — see THE
   CARD AT THE WINDOW at the foot of this file — but it is steady rain, not a
   cloud-to-ground discharge, and a bolt struck across a page lit by daylight
   is not a weather effect, it is a bug. The two bolts and the horizon's sheet
   lightning are generated away rather than hidden, at (0,2,1) and (0,2,2),
   which clears the night rules above at (0,1,1) and (0,1,2).

   `.night-sky::after` is NOT in this list any more and must not be put back:
   by day that pseudo-element is the window pane the rain is running down, and
   the day rule for it is a full override of the sky-flash rule above. */
body[data-theme-id="default"][data-mode="day"] .night-sky__aurora::after,
body[data-theme-id="default"][data-mode="day"] .night-sky__fireworks::before,
body[data-theme-id="default"][data-mode="day"] .night-sky__fireworks::after {
  content: none;
  animation: none;
}

/* While the flyway lamp is on, the map is the ground and the month steps back.
   main.css already quiets `.night-sky::after` there, but it never had a reason
   to name the fireworks pseudo-elements, so a bolt would go on striking across
   a chart someone is reading. The attribute is repeated to (0,4,x) for the
   same reason main.css repeats it — theme sheets load last. */
body[data-flyways="on"][data-flyways="on"][data-flyways="on"][data-theme-id="default"] .night-sky::after,
body[data-flyways="on"][data-flyways="on"][data-flyways="on"][data-theme-id="default"] .night-sky__aurora::after,
body[data-flyways="on"][data-flyways="on"][data-flyways="on"][data-theme-id="default"] .night-sky__fireworks::before,
body[data-flyways="on"][data-flyways="on"][data-flyways="on"][data-theme-id="default"] .night-sky__fireworks::after {
  opacity: 0;
  animation: none;
}

/* ---------------------------------------------------------------------------
   REDUCED MOTION

   A month block outranks the shared rules on specificity, so this theme needs
   its own entries here rather than relying on main.css's block — which is the
   documented trap in .github/agents/style/motion.md.

   Very little is left to remove: this sheet already stopped the header strip,
   the heading flow, the brand float, the link glow loop and the bullet pulse
   for every reader, not just this one. What remains is the gold-dust drift,
   the storm, the hover transitions, and the wordmark's blinking cursor.

   THE STORM IS REMOVED, NOT FROZEN. Every other effect on this page has a
   final visual state worth preserving; lightning's final state is an unlit
   sky, so the four layers are generated away rather than stopped. A bolt held
   at its brightest frame would be a stripe of white across the page for the
   one reader who asked for less. Two of the four are already covered by
   main.css hiding `.night-sky__fireworks`, and they are restated here anyway
   — this sheet does not want its storm depending on a rule in another file
   that exists for pointer sparks.

   The cursor is deliberately NOT re-stopped here. This sheet no longer
   overrides `.brand a::after`'s animation at all, so main.css's own
   reduced-motion rule — which already lists `.brand a::after` — is the one
   that applies, and it applies at lower specificity precisely because nothing
   here outranks it any more. Adding a `body[data-theme-id="default"]
   .brand a::after { animation: none }` rule to this sheet would stop the blink
   for every reader, not only the ones who asked for less motion, which is the
   locked behaviour it must not touch.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  body[data-theme-id="default"] .night-sky::before,
  body[data-theme-id="default"] .night-sky__stars {
    animation: none;
  }

  body[data-theme-id="default"] .night-sky::after,
  body[data-theme-id="default"] .night-sky__aurora::after,
  body[data-theme-id="default"] .night-sky__fireworks::before,
  body[data-theme-id="default"] .night-sky__fireworks::after {
    content: none;
    animation: none;
  }

  body[data-theme-id="default"] .hero-card,
  body[data-theme-id="default"] .folder-section {
    transition: none;
  }

  body[data-theme-id="default"] .hero-card:hover,
  body[data-theme-id="default"] .folder-section:hover {
    transform: none;
  }

}

/* Reduced data drops the decorative paints that buy nothing at small sizes or
   on a metered connection: the dust layer and the storm. (It used to drop the
   page body's corner arcs too; there are no page body corner marks any more —
   see THE PAGE BODY CARRIES NO CORNER MARKS. It also used to drop the horizon
   band's teeth, which are gone in every state now — see THE FRAME.)

   The storm is here for painting cost rather than for bytes — it adds no
   request and about a kilobyte of stylesheet — but four drop-shadows and a
   full-viewport wash are exactly the kind of work a machine asking for less
   of it is asking about.

   THE FRAME STAYS, and that is a decision rather than an omission. It is three
   gradients and three conic masks on one element, painted once and never
   repainted, with no request behind it — cheaper than most of what this block
   keeps. It is also the card's border, and a card asking for less data has not
   asked to stop being a card. */
@media (prefers-reduced-data: reduce) {
  body[data-theme-id="default"] .night-sky::before,
  body[data-theme-id="default"] .night-sky__stars {
    display: none;
  }

  body[data-theme-id="default"] .night-sky::after,
  body[data-theme-id="default"] .night-sky__aurora::after,
  body[data-theme-id="default"] .night-sky__fireworks::before,
  body[data-theme-id="default"] .night-sky__fireworks::after {
    content: none;
    animation: none;
  }
}

/* ---------------------------------------------------------------------------
   THE CARD AT THE WINDOW — a wet day (2026-08-15, user instruction).

   Every theme is struck twice: once in its own lighting and once in the other,
   and /settings says so in as many words. The unmoded body above is this
   theme's canonical lighting — stone, by candle — and this block is the other
   one.

   The day face used to be vellum: the same card held up to a window, warm
   light coming through warm stock, and every surface on the page a shade of
   cream. The instruction that replaced it is "make it a rainy day", and that
   is a weather change rather than a palette change: the card has not moved and
   is not made of anything different. What changed is what is outside the
   window. The pigments are still iron oxide, gold leaf, malachite and
   carnelian on bone stock; they are simply being read by the light of an
   overcast afternoon with rain running down the glass.

   That split is the whole design, and it is doing two jobs at once:

     THE CARD IS WARM.    Every surface that belongs to the object — the panels,
                          the breadcrumb bar, the code wells, the stock behind
                          the search results, the gold and the ruby — stays on
                          the warm side of neutral, hue 40°–56°.

     THE WEATHER IS COOL. Every surface that belongs to the world — the sky,
                          the rain, the shaft, the glass, the far horizon — sits
                          at hue 130°–160°, a green-cyan grey with the red
                          channel pulled down.

   ---------------------------------------------------------------------------
   AS BLUE AS POSSIBLE, WITHOUT BLUE (the second half of the instruction, and
   the reason the numbers below are not free to be re-picked by eye).

   The reader asked for a sky that reads blue while emitting no blue light. On
   an sRGB display "blue light" is not a metaphor: short-wavelength output IS
   the blue primary, so any honest answer has to hold the B channel down and
   find the blueness somewhere else. Three rules do that, and all three are
   checked rather than judged:

     1  NO HUE IN THE BLUE SECTOR. Every colour that covers area on this face —
        every sky stop, wash, rain ink, bead, panel and band — satisfies B <= G.
        A colour with B <= G cannot be blue; the coolest anything here gets is
        180° cyan, and in practice the sky sits at 162°–171°, which is a teal.
        Nothing on the page is in 200°–260° at all. (The card's own small
        pigments — ruby, magenta, amethyst — are type, not area, and keep the
        palette they have always had.)

     2  A BLUE-CHANNEL CEILING OF 209. No composited pixel of this face — sky
        plus wash plus rain plus glass plus panel — carries a blue channel above
        209. The vellum face this replaces peaked at 222 in the search panel and
        213 in the cards; a white page is 255. So the rainy face emits strictly
        LESS short-wavelength light than the day face it replaces, which is the
        only comparison that means anything.

     3  THE VIBRANCE COMES OUT OF THE RED CHANNEL, NOT OUT OF THE BLUE ONE, and
        this is the single most useful fact in the whole block. The sky was a
        near-neutral grey on the first cut and the instruction that followed was
        "more vibrant, like a light teal" — which sounds like it needs blue and
        does not. Chroma is the SPREAD between the channels, so with B pinned at
        the ceiling the only way to open that spread is to take red away: the
        ramp's top stop runs R=99 against G=210, a 111-point gap, where the grey
        it replaced ran a 10-point one. Eleven times the chroma — and the blue
        channel went DOWN on the way, 196 to 180, because a deeper teal needs
        less of it. That is counter-intuitive enough to say plainly: on this
        face, MORE VIVID IS LESS BLUE. Every cool value here is built that way.
        If a colour needs more life, LOWER ITS RED — never raise its blue.

     4  AND THE WARM HALF STILL ADDS TO IT. Simultaneous contrast has not been
        spent: a teal surrounded by strong warm hues reads cooler and deeper
        than the same teal on its own. That is why the card stays cream and
        gold, why the sky ramp turns warm over its last quarter rather than
        staying teal all the way down, and why the one bright wash in the sky is
        ochre. The value ramp does the rest — deeper and cooler at the ceiling,
        lighter and warmer at the horizon, which is the aerial-perspective cue
        the eye reads as sky before it reads any hue at all.

   DO NOT "FIX" THE SKY BY ADDING BLUE TO IT. It will look better in a swatch
   and worse on the page, and it breaks the instruction this face exists for.

   ---------------------------------------------------------------------------
   THE PIGMENTS DEEPEN AGAIN. A jewel tone is a light colour seen against dark;
   on a light ground it goes chalky and stops carrying text. The vellum face
   already took each one down 20–35% from its night value; the overcast ground
   is darker than vellum was (the darkest pixel body text can cross is #a8b3af,
   against #e7dcc2 before), so each is taken down again until it clears 4.5:1
   there. Nothing below is a placeholder and the hues stay separated, so the
   ramp still reads as a ramp on this ground rather than as a band of mud.

   EVERY NUMBER IN THIS BLOCK IS MEASURED. The worst case is the sky's own top
   stop under the cool cell wash and NOTHING ELSE — #5bceaf. The rain used to
   belong in that stack and no longer does: it lightens now, so a streak can
   only lift the ground under a word. Body ink reads 8.68:1 on that floor, bold
   gold 5.32:1, the muted footer 5.06:1, and the frame's ruby 3.80:1 against the
   3:1 a boundary has to clear; under three stacked curtains every one of those
   improves by about a fifth. Re-tune one value and re-measure against #5bceaf.

   Selectors carry both attributes — body[data-theme-id="default"][data-mode="day"]
   at (0,2,0) — so they outrank the theme's own block at (0,1,0) and the whole
   re-lighting happens in the cascade with no JS beyond the attribute flip.
   --------------------------------------------------------------------------- */
body[data-theme-id="default"][data-mode="day"] {
  /* The overcast ceiling. This was a light teal (#9ed2c8) on 2026-08-15, from
     the user instruction "more vibrant, like a light teal" — and teal is named
     in the no-blue-light rule of 2026-08-16 as barred outright, so it could
     not stay. What survives of that instruction is the part that was not about
     the hue: VIBRANT, not a grey sky. The value moved the short way along the
     wheel to a light spring green at the same lightness (L 0.824), and then
     had its chroma pushed back up to 0.045 — the mechanical conversion landed
     on a sage that was compliant and dull, which honours the letter of one
     instruction and the point of neither.

     It is also deliberately the sky ramp's own top stop: the header strip's
     teeth are cut in --band-ink: var(--tt-bg) over the jewel gradient, so this
     value has to be exactly the colour painted behind the header or the teeth
     show as ghosts. That is why the sky's cell wash is placed at 46% height
     and not at the top — it must not reach y=0. */
  --tt-bg: #63d2b4;
  /* --surface, and the one ground token that stays warm: it is the stock, not
     the weather. */
  --tt-bg-alt: #cfc4a6;
  /* Link-hover paired to THIS block's ground (standing rule 2026-08-14), not
     the mode name. The vellum face used #BD0014; on the overcast ground that
     falls to 3.9:1 under rain, so the day value deepens with everything else —
     #88000b measures 4.74:1 on the worst pixel. */
  --link-hover: #870500;

  /* Ink, not black, and still warm. Warm charcoal-brown is what a carbon ink
     dries to on bone stock, it is easier to read at length than #000, and on
     this face it is also load-bearing for rule 3 above: a page of warm ink is
     part of what makes the grey behind it read as blue. */
  --tt-cyan: #241c18;
  --tt-cyan-soft: #443830;

  --tt-yellow: #553c08;
  --tt-orange: #a63a15;
  --tt-chartreuse: #4b6511;
  --tt-green: #244c24;
  --tt-pink: #9b1311;
  --tt-purple: #722d1d;
  --tt-teal: #2e3e26;
  --tt-gray: #4b4335;
  --tt-gold: #543d09;
  /* THE ORNAMENT GOLD — the one token on this face deliberately LIGHTER than
     the ink beside it. See --tt-ramp-gold in the theme block for why the two
     names exist. #543d09 is measured for glyphs (5.57:1 on the sky); spent as
     the middle of the frame's ramp it reads as a dark hole strung between two
     ruby corners rather than as gold leaf.

     This value is measured the way a boundary is, not the way type is: 3.35:1
     on the top stop #63d2b4 and 3.20:1 on the cool cell #5bceaf — the contrast
     floor for this face, since the rain can only lift the ground — both clear
     of the 3:1 a non-text mark has to hold. Its luminance, 0.120, also sits
     just ABOVE carnelian's 0.112, so the ramp brightens toward its middle the
     way the night face's #c9a24a does; a ramp that darkens at the centre is
     not gold leaf, it is a shadow. Blue is the smallest channel at 12, so the
     ceiling of 209 is nowhere near in play. Move it and re-measure on #5bceaf,
     not on the top stop. */
  --tt-ramp-gold: #815a0c;
  --tt-red: #a91c1b;
  --tt-blue: #34472c;

  --tt-breadcrumb-text: #543d09;
  --tt-breadcrumb-glow: rgba(84, 61, 9, 0.28);

  /* A halo on a light ground has to be DARK to trace a glyph — a pale glow on
     pale stock is nothing at all. This is the same trap April documents, and
     it has to be re-answered per lighting, not just per theme. */
  --zodiac-glow: rgba(169, 28, 27, 0.5);

  /* The engraving flips. On a dark card the lit lip of the cut goes below the
     glyph in black; on a light ground that same black lip is a drop shadow,
     not a cut. White below, and the numeral reads as pressed INTO the stock. */
  --tt-engrave: 0 1px 0 rgba(242, 230, 210, 0.7);

  --bg: var(--tt-bg);
  --surface: var(--tt-bg-alt);
  --text: var(--tt-cyan);
  --text-soft: var(--tt-cyan-soft);
  --muted: var(--tt-gray);
  --border: var(--tt-red);
  --border-dim: rgba(84, 61, 9, 0.4);
  --border-teal: rgba(52, 71, 44, 0.5);

  /* The rain's own ink, declared once and spent by all three curtains.

     IT IS LIGHTER THAN THE SKY, AND SIGNIFICANTLY SO (2026-08-16, user
     instruction). The first cut drew it darker on the physical argument that a
     drop in front of a bright overcast is a lens full of the dark ground behind
     it — true of a photograph, and wrong for this page. Against a ground this
     saturated a darkening streak reads as a smudge in the paint rather than as
     water, and the whole point of the layer is that a reader should see rain
     without having to look for it. Lighter wins, and it is not un-physical
     either: rain lit from within a bright cell scatters forward and comes back
     white. +0.33 in relative luminance over the top stop, which is what
     "significantly" was measured as.

     TWO CONSEQUENCES, BOTH ALREADY PAID FOR BELOW. Lighter rain lifts the
     ground under the text instead of dropping it, so the contrast floor is now
     the cool cell with NO rain on it (#5bceaf) rather than the cell with three
     curtains stacked on it — the rain can only help. And it pushes on the
     blue-channel ceiling from the other side, so the worst pixel on the face is
     now the brightest one: a glass bead sitting on top of all three curtains,
     which lands at B=207 against the ceiling of 209. Raise a rain or bead alpha
     and that is the number to re-check. */
  --rain-ink: 217, 247, 220;

  background: var(--tt-bg);
  color: var(--tt-cyan);
  color-scheme: light;
}

/* THE CEILING.

   Four layers, none of them animated, and the first painted frame is already
   the finished weather — the rain below is the only thing that moves.

   THE RAMP IS THE PICTURE. It holds a light teal for the top three quarters
   and then turns warm over the last one, which is both what a rain cell
   actually looks like from underneath (the cloud thins toward the horizon and
   the light gets in under it) and rule 4 in the block comment: the warm foot is
   what the cool ceiling is seen AGAINST.

   THE TEAL IS MADE BY SUBTRACTING RED. Stop 0 is #63d2b4 — R=99, G=210, B=180 —
   so the spread carrying the chroma is 111 points wide and every one of them
   came off the red side. Note where the blue went while the sky got twice as
   vivid: DOWN, 196 to 180, and 29 clear of the ceiling. Saturating this sky
   makes the page emit LESS short-wavelength light, not more.

   BLUE IS NEVER THE BRIGHTEST CHANNEL, here or anywhere else in the workspace,
   and this ramp holds that: green leads at 210 with blue second at 180. What
   this ramp does NOT do is hold blue at or below RED as well — it cannot, and
   neither can any teal. A colour with blue below red has its hue at 120° or
   under, which is a green; the user asked for teal twice, so blue sits between
   the two channels and the stated rule is met rather than exceeded. If the
   workspace rule is ever meant as B <= min(R, G), it is a decision to drop teal
   from this sky, and it needs the user rather than a sweep.

   Greying the ramp back toward neutral is the change to avoid; raising its blue
   is the change that is forbidden outright.

   THE TOP STOP IS --tt-bg AND MUST STAY THAT WAY. The header strip's teeth are
   cut in the page ground; if the ramp starts anywhere else the teeth stop
   matching what is behind them. That constraint is also why the cool cell sits
   at 46% height with a 40% vertical radius — it fades out well before y=0. */
body[data-theme-id="default"][data-mode="day"] .night-sky {
  background:
    /* The light getting in, low and to the right. The single strongest warm
       anchor on the page and the reason the grey above it reads blue. */
    radial-gradient(ellipse 88% 42% at 72% 104%, rgba(236, 211, 152, 0.34), transparent 72%),
    /* The thick middle of the cell — the coolest, darkest thing here. */
    radial-gradient(ellipse 64% 40% at 20% 46%, rgba(63, 191, 158, 0.22), transparent 74%),
    /* The shaft: it is coming down harder over there. A soft diagonal band
       rather than a hard edge, because a rain shaft has no outline. */
    linear-gradient(101deg, transparent 0 34%, rgba(92, 201, 171, 0.18) 52%, transparent 72%),
    /* The ceiling itself. */
    linear-gradient(180deg, var(--tt-bg) 0%, #6ed4b8 30%, #86d8bf 62%, #b3dbbf 82%, #ded9be 100%);
}

/* ---------------------------------------------------------------------------
   THE RAIN — three curtains on the three star layers.

   By night these are the gold-dust scatter and its two parallax depths, and
   they carry the site's one sanctioned ambient effect (star drift and twinkle,
   see .github/agents/style/motion.md). By day the vellum face switched all
   three off, so the day face has been running with no ambient motion at all.
   The rain takes that budget back rather than adding to it — same three
   elements, and FEWER animations than the night face, which runs a drift and a
   twinkle on each. Each layer here animates `transform` alone: one promoted
   compositor layer per curtain, no filter, no background-position, nothing
   repainted per frame. A 0.8s loop and a 36s loop cost exactly the same per
   frame; only the distance travelled differs.

   PARALLAX IS THE WHOLE ILLUSION, and it is three properties moving together:
   the far curtain has the smallest drops, the lowest alpha and the slowest
   fall; the near one has the longest drops, the highest alpha and the fastest.
   Get one of the three backwards and the depth collapses.

   THE STREAKS ARE ELLIPSES, NOT STRIPES. A linear-gradient can only draw a
   band that runs the full length of its tile, which tiles into an unbroken
   line — hatching, not rain. A radial-gradient with two different radii is a
   real drop with soft ends, and the soft end is what makes it read as motion
   blur rather than as a drawn mark.

   ONE TILE SIZE PER CURTAIN, AND THE LOOP IS EXACTLY ONE TILE. background-size
   is per-element, so every drop in a curtain shares its tile and the whole
   layer can be translated by exactly one tile height to land on an identical
   frame. Give the drops different tile sizes and there is no common distance
   to loop on, and the seam becomes visible. Variety comes from the drop
   positions inside the tile instead — deliberately not on a grid.

   THE SLANT IS A ROTATION ON THE ELEMENT. An ellipse cannot be rotated, so the
   curtain is, and the translate is written INSIDE the rotate in every keyframe
   so each drop travels along its own axis — which is what rain does and what a
   vertical fall behind a slanted streak would visibly not do. All three share
   one 4° angle because one wind is blowing.

   THAT ROTATION IS WHY THE BOXES OVERHANG. A rotated box exposes its own
   corners, and a box translated down by one tile exposes a strip at the top.
   `inset: -280px -9vw -8vw` covers both: 280px of top overhang clears the
   largest tile (208px) plus the rotation margin, and the side and foot values
   scale with the viewport. Shrink these and the rain acquires a diagonal edge
   across the page. */
body[data-theme-id="default"][data-mode="day"] .night-sky::before,
body[data-theme-id="default"][data-mode="day"] .night-sky__stars {
  display: block;
  inset: -280px -9vw -8vw;
  background-repeat: repeat;
  background-position: 0 0;
  transform: rotate(4deg);
}

/* THE FAR CURTAIN — drizzle at the back of the shaft. Sub-pixel drop widths on
   purpose: antialiasing renders them fainter than any alpha would, which is
   exactly what distance does to rain. */
body[data-theme-id="default"][data-mode="day"] .night-sky::before {
  opacity: 1;
  background-image:
    radial-gradient(0.7px 5px at 11% 14%, rgba(var(--rain-ink), 0.13) 0 56%, transparent 100%),
    radial-gradient(0.7px 4px at 34% 63%, rgba(var(--rain-ink), 0.13) 0 56%, transparent 100%),
    radial-gradient(0.6px 5px at 52% 27%, rgba(var(--rain-ink), 0.13) 0 56%, transparent 100%),
    radial-gradient(0.6px 4px at 71% 81%, rgba(var(--rain-ink), 0.12) 0 56%, transparent 100%),
    radial-gradient(0.7px 5px at 88% 44%, rgba(var(--rain-ink), 0.13) 0 56%, transparent 100%),
    radial-gradient(0.6px 4px at 23% 92%, rgba(var(--rain-ink), 0.13) 0 56%, transparent 100%),
    radial-gradient(0.7px 5px at 64% 7%, rgba(var(--rain-ink), 0.13) 0 56%, transparent 100%);
  background-size: 168px 118px;
  animation: defaultRainFar 1.8s linear infinite;
}

/* THE MIDDLE CURTAIN. */
body[data-theme-id="default"][data-mode="day"] .night-sky__stars--far {
  opacity: 1;
  background-image:
    radial-gradient(1px 8px at 8% 21%, rgba(var(--rain-ink), 0.18) 0 58%, transparent 100%),
    radial-gradient(1px 7px at 29% 74%, rgba(var(--rain-ink), 0.165) 0 58%, transparent 100%),
    radial-gradient(1px 9px at 47% 12%, rgba(var(--rain-ink), 0.18) 0 58%, transparent 100%),
    radial-gradient(1px 7px at 62% 55%, rgba(var(--rain-ink), 0.155) 0 58%, transparent 100%),
    radial-gradient(1px 8px at 81% 33%, rgba(var(--rain-ink), 0.18) 0 58%, transparent 100%),
    radial-gradient(1px 7px at 93% 87%, rgba(var(--rain-ink), 0.165) 0 58%, transparent 100%);
  background-size: 214px 152px;
  animation: defaultRainMid 1.2s linear infinite;
}

/* THE NEAR CURTAIN — the drops just outside the glass. Longest, fastest,
   heaviest, and the fewest of them: at this distance you only ever see a
   handful at once. 0.16 is the peak alpha anywhere in the storm, and it is the
   number the contrast floor was measured against. */
body[data-theme-id="default"][data-mode="day"] .night-sky__stars--near {
  opacity: 1;
  background-image:
    radial-gradient(1.3px 15px at 17% 26%, rgba(var(--rain-ink), 0.24) 0 60%, transparent 100%),
    radial-gradient(1.2px 12px at 44% 71%, rgba(var(--rain-ink), 0.21) 0 60%, transparent 100%),
    radial-gradient(1.3px 16px at 68% 9%, rgba(var(--rain-ink), 0.24) 0 60%, transparent 100%),
    radial-gradient(1.2px 13px at 89% 48%, rgba(var(--rain-ink), 0.225) 0 60%, transparent 100%);
  background-size: 286px 208px;
  animation: defaultRainNear 0.8s linear infinite;
}

/* THE GLASS — the pane the whole page is being read through.

   This is `.night-sky::after`, which by night is the storm's cloud-base flash
   and by day is unspent. It is the nearest layer in the scene, so it takes
   z-index 2 to sit in front of the falling curtains (they are z-index 1); the
   sky's own stacking context keeps all of it behind header, main and footer
   regardless. It does not move, and that is the point of it: the honest still
   frame of weather on a window is the water already standing on it.

   A bead is a lens: bright where it gathers the ceiling, faintly dark at its
   underside where it bends the ground up into view. Both halves are drawn, and
   both are drawn SOFT — a tight dark ring around a tight light core renders as
   a soap bubble, which is what the first cut of this looked like. The rim is
   spread over a third of the radius at a twentieth of the alpha, so it reads as
   a thickening rather than as an outline.

   The field is mostly small. Beads on a pane cluster and most of them are
   barely more than a speck; four large ones in a 470px tile is already at the
   limit before the repeat starts to show as a grid. */
body[data-theme-id="default"][data-mode="day"] .night-sky::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  opacity: 1;
  pointer-events: none;
  transform: translate3d(0, 0, 0);
  animation: none;
  background-image:
    radial-gradient(circle 9px at 14% 17%, rgba(220, 243, 224, 0.09) 0 34%, rgba(72, 150, 128, 0.035) 62% 84%, transparent 100%),
    radial-gradient(circle 11px at 74% 73%, rgba(220, 243, 224, 0.08) 0 32%, rgba(72, 150, 128, 0.03) 60% 84%, transparent 100%),
    radial-gradient(circle 5px at 37% 61%, rgba(220, 243, 224, 0.115) 0 40%, transparent 100%),
    radial-gradient(circle 6px at 22% 88%, rgba(220, 243, 224, 0.10) 0 38%, transparent 100%),
    radial-gradient(circle 3px at 58% 29%, rgba(220, 243, 224, 0.115) 0 48%, transparent 100%),
    radial-gradient(circle 4px at 89% 11%, rgba(220, 243, 224, 0.10) 0 44%, transparent 100%),
    radial-gradient(circle 2px at 46% 41%, rgba(220, 243, 224, 0.155) 0 52%, transparent 100%),
    radial-gradient(circle 2px at 66% 96%, rgba(220, 243, 224, 0.145) 0 52%, transparent 100%),
    radial-gradient(circle 1.5px at 31% 33%, rgba(220, 243, 224, 0.16) 0 55%, transparent 100%),
    radial-gradient(circle 1.5px at 83% 52%, rgba(220, 243, 224, 0.155) 0 55%, transparent 100%),
    radial-gradient(circle 2px at 7% 68%, rgba(220, 243, 224, 0.145) 0 52%, transparent 100%),
    radial-gradient(circle 1.5px at 54% 80%, rgba(220, 243, 224, 0.16) 0 55%, transparent 100%);
  background-size: 470px 410px;
  background-repeat: repeat;
  background-position: 0 0;
}

/* THE HORIZON — the wet sill.

   The card's foot ornament stays exactly where it was: the ruby keyline and
   the gold teeth are the object, not the weather, and they are re-inked rather
   than replaced. What is new is the band under them, which was warm tan on the
   vellum face and is now wet slate with a bright specular line along its top
   edge — a horizontal surface with water on it, lit from a low warm sky. That
   sheen line is listed BEFORE the band so it paints over the band's own edge. */
body[data-theme-id="default"][data-mode="day"] .night-sky__aurora {
  background:
    linear-gradient(180deg, transparent 0 45%, rgba(169, 28, 27, 0.42) 45% calc(45% + 1px), transparent calc(45% + 1px)),
    linear-gradient(180deg, transparent 0 62%, rgba(241, 231, 203, 0.55) 62% calc(62% + 1px), transparent calc(62% + 1px)),
    linear-gradient(180deg, transparent 0 62%, #63a891 62%);
}

body[data-theme-id="default"][data-mode="day"] .night-sky__aurora::before {
  --band-ink: rgba(84, 61, 9, 0.4);
}

/* PANELS — and this is where the sky gets its colour from.

   Every panel on this face is warm cream. That is rule 4 of the block comment
   cashed in: these are the surfaces sitting directly against the teal, and the
   warmer they read the deeper the teal reads. They are also the reason the card
   still holds as an object rather than as a tinted page — the stock is dry, the
   weather is not.

   THE ALPHAS ARE SET BY ARITHMETIC, NOT BY TASTE, AND THEY GO UP EVERY TIME THE
   SKY GAINS CHROMA. A panel only reads warm while its COMPOSITE has R > G, and
   the ground it mixes with now runs R=134 against G=216 — an 82-point deficit
   the cream has to overcome with 17 points of its own warmth. That puts the
   crossover at 82/99 = 0.828: below it the panel composites to a pale green and
   the warm anchor — half of what makes the sky read as saturated at all —
   quietly stops existing. The cards sit at 0.86 and the breadcrumb card at
   0.90. Work the crossover out again after any change to the sky; never guess
   it, and never lower these to "let more of the weather through".

   That the card is now all but opaque is a gain rather than a cost: it is an
   object on a sill, and the weather belongs behind it rather than through it.

   The blue ceiling still binds and has more room than before — the cards land
   at B=189 and the breadcrumb at B=191, both well under 209. */
body[data-theme-id="default"][data-mode="day"] .breadcrumb-nav {
  background: rgba(244, 229, 192, 0.9);
}

/* `.page-toc` is deliberately NOT in this list any more — see the note on the
   index above. Day mode gave it an 86% bone plate; the index is set on the page
   in both modes now, so putting it back here would restore half the layer. */
body[data-theme-id="default"][data-mode="day"] .hero-card,
body[data-theme-id="default"][data-mode="day"] .folder-section {
  background: rgba(245, 228, 189, 0.86);
}

body[data-theme-id="default"][data-mode="day"] .hero-card:hover,
body[data-theme-id="default"][data-mode="day"] .folder-section:hover {
  border-color: rgba(169, 28, 27, 0.5);
}

/* TABLE HEADS TAKE BONE, NOT INK — a legibility fix carried in with this face
   rather than a design change. `th` is painted at (0,1,1) above as
   `color: var(--tt-cyan); background: var(--tt-red)`, and by night that is bone
   lettering on ruby at 9.6:1. By day --tt-cyan resolves to the dark carbon ink,
   so the same rule produced ink on ruby: 2.28:1 on the vellum face and 2.21:1
   here — a table head nobody could read, on both day faces. The lettering takes
   the bone the night face uses, which is what the rule always meant, and reads
   6.41:1. Do not "simplify" this back to var(--tt-cyan). */
body[data-theme-id="default"][data-mode="day"] th {
  color: #f2e6d2;
}

body[data-theme-id="default"][data-mode="day"] code {
  color: var(--tt-pink);
}

body[data-theme-id="default"][data-mode="day"] code,
body[data-theme-id="default"][data-mode="day"] pre,
body[data-theme-id="default"][data-mode="day"] input,
body[data-theme-id="default"][data-mode="day"] textarea,
body[data-theme-id="default"][data-mode="day"] select {
  background: rgba(245, 228, 189, 0.86);
}

/* The search panel is the one opaque surface on the face and therefore the one
   place a stray bright value would sit unmixed against anything. #e7e0c9 is
   B=201, comfortably under the ceiling, and warm enough that the results list
   reads as a page of the card rather than as a system dialog. */
body[data-theme-id="default"][data-mode="day"] .site-search__panel {
  background: rgba(231, 224, 201, 0.98);
}

body[data-theme-id="default"][data-mode="day"] .site-search__option.is-active {
  background: rgba(169, 28, 27, 0.14);
}

body[data-theme-id="default"][data-mode="day"] .site-search__input {
  color: var(--tt-cyan);
}

/* The brand's own glow is light coming off gold leaf. On stock there is no
   light to come off, so what is left is the engraving. */
body[data-theme-id="default"][data-mode="day"] .brand a {
  color: var(--tt-gold);
  text-shadow: var(--tt-engrave);
}

body[data-theme-id="default"][data-mode="day"] .brand a:hover {
  color: var(--tt-red);
  text-shadow: var(--tt-engrave);
}

/* The day face used to kill the header strip's glow here. The strip itself is
   gone — THE FRAME carries the top edge now and carries no glow in either
   lighting — so there is nothing left to unlight. */

/* HEADINGS BY DAY — the white instruction, struck on stock.

   White is the night face's answer to "no colour in a heading": on #110c14 it
   is the brightest thing the card can be lettered in and it reads at 18.4:1.
   Painted onto the overcast ground the same #fff measures 1.3:1 — not a dim
   heading, an absent one — so this lighting takes the ink every other line of
   type on it is set in. Same decision, same absence of colour, the other end
   of the ramp.

   The selectors mirror the night block one for one, at (0,2,2) / (0,4,0) /
   (0,5,1) / (0,6,1) so each clears its own counterpart. If a heading selector
   is ever added above, add it here too — a heading that gets white and no day
   entry disappears on stock. */
body[data-theme-id="default"][data-mode="day"] main h1,
body[data-theme-id="default"][data-mode="day"] .page-title,
body[data-theme-id="default"][data-mode="day"] main h2,
body[data-theme-id="default"][data-mode="day"] main h3,
body[data-theme-id="default"][data-mode="day"] main h4,
body[data-theme-id="default"][data-mode="day"] main h5,
body[data-theme-id="default"][data-mode="day"] main h6,
body[data-theme-id="default"][data-mode="day"] .markdown-page .heading-section__trigger,
body[data-theme-id="default"][data-mode="day"] .markdown-page .related h1.related__heading,
body[data-theme-id="default"][data-mode="day"] .markdown-page .related .related__group h2.related__tag {
  color: var(--tt-cyan);
  -webkit-text-fill-color: var(--tt-cyan);
}

body[data-theme-id="default"][data-mode="day"] blockquote {
  box-shadow: inset 1rem 0 1.4rem -1.2rem rgba(84, 61, 9, 0.6);
}

/* The three curtains. Each translates by exactly one of its own tile heights,
   written INSIDE the shared 4° rotation so the drops travel along their own
   axis rather than straight down behind a slanted streak. Change a tile height
   above and change its distance here, or the loop acquires a seam. */
@keyframes defaultRainFar {
  from { transform: rotate(4deg) translate3d(0, 0, 0); }
  to { transform: rotate(4deg) translate3d(0, 118px, 0); }
}

@keyframes defaultRainMid {
  from { transform: rotate(4deg) translate3d(0, 0, 0); }
  to { transform: rotate(4deg) translate3d(0, 152px, 0); }
}

@keyframes defaultRainNear {
  from { transform: rotate(4deg) translate3d(0, 0, 0); }
  to { transform: rotate(4deg) translate3d(0, 208px, 0); }
}

/* ---------------------------------------------------------------------------
   THE WET DAY UNDER THE TWO PREFERENCES

   These blocks have to live here, AFTER the day face, and not up in the shared
   reduced-motion block further above. Both sets of selectors land at (0,3,1) —
   the same weight as the day rules they are overriding — so the cascade
   settles them on source order alone, and the copies above at (0,1,1) never
   reach this face at all. That is the documented trap in
   .github/agents/style/motion.md, and it is why a new ambient effect on a
   themed sheet always needs its own pair.

   REDUCED MOTION FREEZES THE RAIN; IT DOES NOT REMOVE IT. This is the opposite
   call to the storm above, and deliberately so. The rule in motion.md is to ask
   what the effect looks like when it is over: a lightning bolt held at its
   brightest frame is a white stripe across the page, so the night face deletes
   it. Rain held still is a photograph of rain — the oldest and most legible
   still image of weather there is, and everybody reads it correctly. The three
   curtains keep their 4° rotation from the day rule the moment the animation is
   dropped, the glass and the sky never moved, and the reader who asked for less
   motion gets the same wet afternoon with the shutter closed. */
@media (prefers-reduced-motion: reduce) {
  body[data-theme-id="default"][data-mode="day"] .night-sky::before,
  body[data-theme-id="default"][data-mode="day"] .night-sky__stars {
    animation: none;
  }
}

/* Reduced data drops the paint instead. What is left — the ramp, the cool
   cell, the shaft and the wet horizon — is still unmistakably an overcast
   afternoon, still carries the whole cool/warm split the blue percept depends
   on, and costs four static gradients on one element. What goes is everything
   that is drawn per-drop: three tiled curtains and a tiled bead field, which
   are the only layers on this face a machine asking for less would feel. */
@media (prefers-reduced-data: reduce) {
  body[data-theme-id="default"][data-mode="day"] .night-sky::before,
  body[data-theme-id="default"][data-mode="day"] .night-sky__stars {
    display: none;
    animation: none;
  }

  body[data-theme-id="default"][data-mode="day"] .night-sky::after {
    content: none;
  }
}

/* ---------------------------------------------------------------------------
   NARROW SCREENS

   This block used to shrink the page body's corner marks, which were
   proportional marks rather than fixed ones. There are no page body corner
   marks any more — see THE PAGE BODY CARRIES NO CORNER MARKS — and the
   breadcrumb card's own pips are shrunk by main.css at its own breakpoint.

   The brand needs nothing here any more. It used to take a narrow-width
   letter-spacing correction to keep the wide inscriptional tracking on one
   line; the wordmark is back on main.css's own clamp and negative tracking,
   which is the sizing every other theme already wraps correctly at, so the
   override is gone rather than retuned. Do not add a .brand a rule back into
   this block — see "The Wordmark Is Locked".
   --------------------------------------------------------------------------- */
@media (max-width: 700px) {
  body[data-theme-id="default"] footer::before {
    left: 22%;
    right: 22%;
  }

  /* THE CHANNELS GO BELOW 700px, and this is a scope decision rather than a
     tuning one.

     Everything above is built on the page having gutters. The near bolt is
     parked off the left edge and the far one over in the right margin
     precisely so that neither trunk crosses the reading column, and the fade
     down the channel covers the little that still clips it. At 390px there is
     no margin to park in: <main> is the viewport, the card is full-bleed, and
     a channel anywhere on screen is a channel through a paragraph. Shrinking
     the bolts does not fix that — it makes a thinner line through the same
     paragraph.

     So on a phone the storm keeps the two layers that were never in the way:
     the cloud-base flash and the distant sheet lightning at the horizon. That
     is also, as it happens, the storm most people actually watch — you see the
     sky go white far more often than you see the channel that did it.

     It costs the weakest device the most expensive layer in the sheet. Four
     drop-shadows rasterised over a 470px box is the one thing here a low-end
     phone would have felt, and it is now the one thing a low-end phone never
     paints. */
  body[data-theme-id="default"] .night-sky__fireworks::before,
  body[data-theme-id="default"] .night-sky__fireworks::after {
    content: none;
    animation: none;
  }

  /* The horizon glow spans a wider share of a narrow viewport, or it reads as
     a smudge parked off to one side rather than as a cell beyond the skyline. */
  body[data-theme-id="default"] .night-sky__aurora::after {
    left: 0;
    right: 8%;
    height: clamp(3.5rem, 11vh, 7rem);
  }

  /* THE NEAR CURTAIN GOES BELOW 700px, and unlike the storm's channels this is
     a cost decision rather than a layout one — faint rain crosses a paragraph
     harmlessly at any width. The near curtain is simply the most expensive
     thing on the day face: the largest tile, the highest alpha, and a loop
     three times faster than the far one, on the device least able to composite
     it. Two curtains still parallax against each other, which is all the depth
     cue needs; a phone held at arm's length was never going to resolve the
     third. (0,3,1), same as the day rule it clears, so it wins on source order
     — this block is last in the file and must stay last. */
  body[data-theme-id="default"][data-mode="day"] .night-sky__stars--near {
    display: none;
  }
}
