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

/* September — a chrome-and-formica diner, late 1950s, seen through a rain-run
   window at midnight.

   The palette is the one September has always shipped: warm autumn rain, red
   anchored, no cold blues. No --tt-* token is altered. The chrome here is warm
   chrome, which is what chrome actually is under a neon sign — it takes the
   colour of whatever is lit around it, and every metallic gradient below is
   mixed from two colours the theme already owns: the cream --tt-cyan
   (244, 217, 184) for a lit edge and the ground's own black (10, 6, 5) for the
   shadow rolling off it.

   The single exception, granted explicitly: the RAIN is blue. Water on glass
   at night is lit by whatever is behind it, and a warm room throws a cold
   reflection — so the drops read as cold blue-white against the maroon. Those
   values live in the --sep-glass-* tokens and are used nowhere except the
   window. The reasoning survived the 2026-08-10 rebuild intact; only the
   execution was replaced. */
body[data-theme-id="september"] {
  --tt-bg: #140c08;
  /* Link-hover paired to THIS block's ground (standing rule 2026-08-14),
     not the mode name — september's unmoded block is night, its own
     canonical lighting. #140c08 is dark: #FF465A clears 5.78:1 here. */
  --link-hover: #FF4947;
  --tt-bg-alt: #2b1810;
  --tt-cyan: #f4d9b8;
  --tt-cyan-soft: #e2bd94;
  --tt-yellow: #eaa63c;
  --tt-orange: #d2571f;
  --tt-chartreuse: #d98a4a;
  --tt-green: #c2a95a;
  --tt-pink: #e78584;
  --tt-purple: #a85757;
  --tt-blue: #b46a3e;
  --tt-teal: #7a3a20;
  --tt-gray: #ab8b70;
  --tt-gold: #f0c987;
  --tt-red: #ef4a34;
  --tt-breadcrumb-text: #ff7a55;
  --tt-breadcrumb-glow: rgba(226, 64, 44, 0.58);
  /* Hover/focus halo for the zodiac glyphs, checked against this month's ground
     (#140c08): a warm filament white with real alpha, so a ♌ or an ogham stave
     traces like a hot tube behind wet glass. Never a border — the rule that
     consumes this token lives once, in main.css. */
  --zodiac-glow: rgba(255, 190, 150, 0.72);
  --tt-heading-rainbow: linear-gradient(
    90deg,
    var(--tt-red),
    var(--tt-orange),
    var(--tt-gold),
    var(--tt-red),
    var(--tt-pink),
    var(--tt-red)
  );
  --tt-heading-rainbow-vertical: linear-gradient(
    180deg,
    var(--tt-red),
    var(--tt-orange),
    var(--tt-gold),
    var(--tt-red),
    var(--tt-pink),
    var(--tt-red)
  );
  --tt-heading-text-rainbow: linear-gradient(
    90deg,
    var(--tt-red),
    var(--tt-orange),
    var(--tt-yellow),
    var(--tt-gold),
    var(--tt-green),
    var(--tt-red),
    var(--tt-pink),
    var(--tt-gold),
    var(--tt-red),
    var(--tt-orange),
    var(--tt-yellow),
    var(--tt-gold),
    var(--tt-green),
    var(--tt-red),
    var(--tt-pink),
    var(--tt-gold),
    var(--tt-red)
  );

  /* ---- Type -------------------------------------------------------------
     The heading face is a system stack. The project loads no webfonts anywhere
     — there is no @font-face, no @import and no fonts.googleapis link in
     main.js or any stylesheet — so this adds zero network requests and the
     first paint is already the finished typography. It is also of the period,
     not merely evocative of it.

     Headings take Copperplate: the engraved gothic that cut American menu
     boards, storefront glass, business cards and matchbooks from the 1920s
     clean through the 1960s. It has no true lowercase — it sets small caps —
     which is precisely why it wants to be centred, tracked wide and short, and
     that is the layout idiom the whole heading block below is built around.
     Filed in the catalogue under stoic; it is spent here through --font-heading
     rather than --font-stoic because the tracking and centring below are cut to
     this face specifically.

     Body is NOT this sheet's decision any more (2026-08-15, user instruction).
     What stood here was Palatino via --font-sans; the text font is now locked
     to --font-text in main.css and is the same on all fourteen themes, so the
     override and its token are both gone. September keeps its period voice in
     the heading, the ground and the sheen kit, which is where a month belongs.

     --font-mono and --font-cursive stay untouched at the token level: the brand
     wordmark is a locked fixture and keeps its own stack. */
  --font-heading: Copperplate, "Copperplate Gothic Bold", "Copperplate Gothic Light", "Big Caslon", "Bookman Old Style", Georgia, serif;

  /* ---- Sheen kit --------------------------------------------------------
     Reusable metal recipes so every polished surface in the theme is lit from
     the same angle. Cream on top, shadow at the foot, exactly as a rolled steel
     edge behaves under a ceiling light. --sep-bullnose is the heavier one: the
     bright chrome nosing that caps a formica counter. */
  --sep-sheen: linear-gradient(
    180deg,
    rgba(244, 217, 184, 0.15) 0%,
    rgba(244, 217, 184, 0.035) 26%,
    rgba(10, 6, 5, 0) 52%,
    rgba(10, 6, 5, 0.2) 86%,
    rgba(10, 6, 5, 0.3) 100%
  );
  --sep-lip: inset 0 1px 0 rgba(244, 217, 184, 0.18), inset 0 -1px 0 rgba(10, 6, 5, 0.55);
  --sep-bullnose:
    inset 0 1px 0 rgba(244, 229, 209, 0.42),
    inset 0 2px 0 rgba(244, 217, 184, 0.16),
    inset 0 -2px 0 rgba(10, 6, 5, 0.72);

  /* ---- Rain ------------------------------------------------------------
     The one sanctioned departure from the warm palette, and the reasoning is
     unchanged: water on glass at night is lit by whatever is behind it, and a
     warm room throws a cold reflection, so the drops read blue-white against
     the maroon.

     Rebuilt 2026-08-11 on three instructions from the user, which turned out to
     be one change: drop the CRT scanline, remove the STATIC water, keep the
     rain and make it better. Most of what was on this window was not rain.

     WHAT WAS REMOVED. .night-sky::before carried a 43-layer motionless paint —
     sixteen hand-placed beads, eight sheeting films, three condensation
     blooms, every one of them no-repeat with `animation: none`. It was built
     with care and it was still the wrong object. A full-viewport wash of water
     that never moves and is identical on every page load does not read as
     weather; it reads as a texture smeared over the site, and with the scanline
     ruled across it at a 4px pitch the two together read as a screen fault. The
     user named it exactly: "a water looking static background". Beads,
     sheeting, condensation and the whole --sep-bead-* / --sep-wet-* kit are
     gone from both modes. Do not reintroduce them as "atmosphere". If this
     month ever wants standing water again it has to be small, local, and off
     the reading column — never a plane.

     WHAT THE RAIN IS NOW: three moving planes at three speeds. That is the
     principle the old build argued for and never actually had, because two of
     its three "motion states" were painted still.

       --far        z-index 1. The veil. Sixteen thin columns across the full
                    width, all at the capped grade, blurred 0.4px, leaning 9.5
                    degrees, one 24rem period every 1.32s (~290px/s).
       __aurora     z-index 2. The wet road. Static, and legitimately so — it is
                    ground, not weather.
       ::before     z-index 3, the glass plane, repurposed from the static water
                    to the NEAR rain. Nine thick columns at full grade, blurred
                    0.9px, leaning 8 degrees, one 24rem period every 0.68s
                    (~565px/s). Twice the far plane's speed, more than twice its
                    head alpha, up to three times its width, and a degree and a
                    half off its angle. That is the parallax, and parallax is the
                    only thing that makes a flat gradient field read as depth
                    rather than as wallpaper.
       --near       z-index 4. Runnels ON the pane. Slow, vertical, eased so the
                    water clings, sheds and clings again.

     THE NEAR PLANE NEVER CROSSES THE READING COLUMN, and that is a measured
     constraint rather than a composition preference. Two capped 0.20-alpha
     heads overlapping composite the local ground to luminance 0.099, where
     --tt-red (luminance 0.235) falls to 1.9:1 — well under the 3:1 floor. One
     capped plane over the centre is safe; two stacked is not. So every near
     column sits outside 18%–82% and only the far veil crosses the middle.
     Brightness for the weather is bought at the shoulders, exactly as it is for
     the ember.

     COST. Ambient loops go from two to three, and the frame budget still
     improves: twenty-five narrow repeat-y columns replace forty-three
     full-viewport radial layers, and the third loop is on an element that was
     already being painted every frame it was composited. All three animations
     are transform-only; both blurs are baked into the rasterization once and
     are not re-run as the rain falls.

     The value tokens that survive:

       --sep-glass-lit    the head of a runnel — the heavy drop at the leading
                          end of a track. Pulled from 0.64 down to 0.50 in the
                          same pass, because the condensation it used to sit
                          against is gone: on bare near-black a 0.64 head is the
                          brightest thing on the page and goes straight back to
                          reading as a meteor. What keeps a runnel from reading
                          as one now is the head PLATEAU — a short bright dash
                          instead of a point — plus the dark bruise under it and
                          the long faint track above it.
       --sep-glass-body   the water itself. Deliberately dim.
       --sep-glass-far    the faint upper end of a track.
       --sep-glass-shade  the bruise on a runnel's leading edge. Near-black on
                          near-black over most of the frame, which is fine: it
                          earns its place where a runnel crosses the ember bank
                          and the lit counter, which is exactly where a bright
                          head would otherwise be loudest. */
  --sep-glass-lit: rgba(239, 231, 210, 0.5);
  --sep-glass-body: rgba(219, 206, 184, 0.26);
  --sep-glass-far: rgba(200, 183, 157, 0.1);
  --sep-glass-shade: rgba(5, 3, 1, 0.8);

  /* Falling rain, NEAR grade: tail / body / head. The shoulders only. The head
     came down from 0.56 to 0.46 in the pass that removed the static water: the
     beads and the condensation used to sit under these columns and gave them
     something to be bright AGAINST, and with that ground gone a 0.56 head on
     #140c08 is a hard white line rather than a drop. 0.46 still reads as water
     at a glance and stops reading as a scratch on the print. */
  --sep-rain-1: rgba(200, 183, 157, 0.04);
  --sep-rain-2: rgba(213, 200, 177, 0.16);
  --sep-rain-3: rgba(239, 231, 210, 0.46);

  /* Falling rain, FAR / reading-column grade. The head alpha is the one number
     in this sheet with a hard ceiling on it. Composited over the ground, a
     0.20-alpha head of this colour lands at luminance 0.032; at 0.26 it lands
     at 0.049 and --tt-red (luminance 0.235) drops under the 3:1 floor against
     it. 0.20 is the value with margin. Do not raise it — brighten the
     shoulders instead, where there is no type. The far plane now runs this
     grade on ALL sixteen of its columns rather than only on the six over the
     centre, so the veil is uniformly under the ceiling wherever the page
     scrolls and the far/near split falls on one clean line. */
  --sep-rain-c1: rgba(200, 183, 157, 0.03);
  --sep-rain-c2: rgba(206, 193, 169, 0.09);
  --sep-rain-c3: rgba(229, 222, 205, 0.2);

  /* ---- Rain bleed --------------------------------------------------------
     How far the two falling planes hang outside the viewport on each side, and
     the reason every column below is positioned in vw off an edge rather than
     in per cent.

     Both planes are rotated — 8 degrees near, 9.5 far — and rotating the layer
     about its own centre pulls its top corners inward. The requirement is that
     each VIEWPORT corner still lands inside the rotated layer:

       bleed >= (vw / 2) x (cos a - 1) + (vh / 2) x sin a

     which at 9.5 degrees and 1440 wide wants 4.0rem on a 900px-tall viewport,
     6.8rem at 1440 tall, and 7.6rem at 1600. 8rem holds to about 1671px tall,
     against roughly 1900px when both planes were at 8 degrees. The steeper far
     plane costs some headroom and there is still plenty: no common viewport is
     that tall, and the requirement FALLS as the window gets narrower, so the
     small-screen case is the safe one rather than the risky one.

     Do not size this against (element height / 2) x sin a. That counts the
     24rem of vertical overhang as area needing cover, which it is not — only the
     viewport has to be covered — and it overstates the requirement by about 3rem
     at desktop heights.

     Nor is raising it free, which is the non-obvious part: every column x is
     written calc(bleed + Nvw) and therefore does not move, but the ROTATION
     PIVOT is the element's centre, and a wider element has a different centre.
     Changing this value rigidly translates the whole rain field. That is
     harmless — one arrangement of scattered drops for another — but it means a
     bleed change is never the no-op the cancelling x values make it look like,
     and it cannot be checked by diffing two renders.

     The trap, and it is a silent one: background-position PERCENTAGES resolve
     against the positioning area, which is now the viewport plus 16rem, not the
     viewport. A column declared at "2%" on this element lands 94px OFF the left
     edge of a 1440px screen, and "97%" lands off the right — three of the near
     plane's nine columns simply never rendered, and the numbers in the source
     said nothing about it. Worse, the skew is width-dependent: at 768px SIX of
     the nine fell off, so the "banked to the shoulders" guarantee that the
     contrast budget rests on quietly stopped holding on small screens.

     So each column is anchored to the near edge and offset by
     calc(var(--sep-rain-bleed) + Nvw): the rem cancels the bleed exactly and
     the vw is then a true viewport position, at every width. Read "left
     calc(bleed + 6vw)" as "6% in from the left edge of the screen", because
     that is precisely what it is. Right-anchored columns are also
     scrollbar-safe, since they measure from .night-sky's own box rather than
     from 100vw.

     The runnel plane deliberately does NOT use this. It is not rotated, so it
     needs no bleed for coverage — its 2rem is only there to keep the 0.7px blur
     from clipping at the edges — and at 2rem the percentage skew is under two
     per cent of the width, which is not worth the noise of converting it. */
  --sep-rain-bleed: 8rem;

  /* ---- Rain column profiles ---------------------------------------------
     Each of these is ONE narrow column of falling water, and the whole reason
     the field has no lattice in it. background-repeat is repeat-Y ONLY: there
     is no horizontal period anywhere in the rain, because every column is
     hand-placed at its own x. The old field tiled in both axes at a 3.5-17rem
     pitch and combed visibly across the viewport; a column that repeats only
     downward cannot comb sideways, and downward it is moving fast enough that
     the vertical period cannot be counted either.

     Every streak fades in from nothing over a long tail and ends on its
     brightest stop about a percent short of its foot, then cuts. Heavy head,
     light tail, stated in the gradient itself rather than assembled out of a
     head layer plus a trail layer. That asymmetry is what a 1/60s exposure of
     a falling drop actually looks like, and it is also what separates rain from
     snow: a spindle that tapers at BOTH ends is a snowflake trail.

     Within a streak the stops sit at 30% / 68% / 94% of its own span, so a long
     drop gets a proportionally long tail rather than a fixed one — which is
     what stops the short streaks looking like clipped versions of the long
     ones.

     THREE PROFILES WERE NOT ENOUGH, and length variance inside them did not fix
     it. The field still read as machined, and the reason was period rather than
     shape: twenty-five columns drawn from three gradients, on tile heights of
     3rem and 4rem, put the SAME 48-64px stamp down the whole height of a column
     and repeated it in the neighbour four columns over. The eye locks a period
     that short in well under a second, and once it has, no amount of variation
     within the stamp reads as random — it reads as a patterned dash.

     So the set is six profiles, and the shortest tile in the sheet is now 8rem:

       a  24rem, 5 streaks   b  24rem, 4 streaks   c  12rem, 3 streaks
       d  12rem, 2 streaks   e   8rem, 2 streaks   f  24rem, 6 streaks

     Every tile height divides the 24rem travel, so each still wraps seamlessly
     (see the septemberRainFall note — travel doubled from 12rem to 24rem for
     exactly this, with both durations doubled alongside it so the water falls at
     the speed it always did).

     The streaks inside each profile sit at deliberately non-uniform intervals —
     the gaps run anywhere from 6% to 30% of the tile — because evenly spaced
     drops of varied LENGTH still read as a rhythm. It is the spacing the eye
     counts, not the marks. d is the sparse one on purpose: a 38% dead stretch,
     so at any moment some columns are simply between drops. Real rain is not
     uniformly populated, and a field where every column always has water in it
     is the single most synthetic thing about a CSS rainstorm.

     Density is held roughly level across the set at 2-3 streaks per 12rem, so
     the profiles differ in rhythm without any column reading as a downpour next
     to a drizzle. */
  /* a — 24rem. Five streaks, spans 14/8/19/11/15% of the tile. */
  --sep-rain-a: linear-gradient(
    180deg,
    transparent 0 3%,
    var(--sep-rain-1) 7.2%,
    var(--sep-rain-2) 12.5%,
    var(--sep-rain-3) 16.2%,
    transparent 17%,
    transparent 26%,
    var(--sep-rain-1) 28.4%,
    var(--sep-rain-2) 31.4%,
    var(--sep-rain-3) 33.5%,
    transparent 34%,
    transparent 41%,
    var(--sep-rain-1) 46.7%,
    var(--sep-rain-2) 53.9%,
    var(--sep-rain-3) 58.9%,
    transparent 60%,
    transparent 67%,
    var(--sep-rain-1) 70.3%,
    var(--sep-rain-2) 74.5%,
    var(--sep-rain-3) 77.3%,
    transparent 78%,
    transparent 84%,
    var(--sep-rain-1) 88.5%,
    var(--sep-rain-2) 94.2%,
    var(--sep-rain-3) 98.1%,
    transparent 99%
  );
  /* b — 24rem. Four streaks, spans 21/9/17/18%. */
  --sep-rain-b: linear-gradient(
    180deg,
    transparent 0 6%,
    var(--sep-rain-1) 12.3%,
    var(--sep-rain-2) 20.3%,
    var(--sep-rain-3) 25.7%,
    transparent 27%,
    transparent 35%,
    var(--sep-rain-1) 37.7%,
    var(--sep-rain-2) 41.1%,
    var(--sep-rain-3) 43.5%,
    transparent 44%,
    transparent 52%,
    var(--sep-rain-1) 57.1%,
    var(--sep-rain-2) 63.6%,
    var(--sep-rain-3) 68%,
    transparent 69%,
    transparent 76%,
    var(--sep-rain-1) 81.4%,
    var(--sep-rain-2) 88.2%,
    var(--sep-rain-3) 92.9%,
    transparent 94%
  );
  /* c — 12rem. Three streaks, spans 18/11/25%. */
  --sep-rain-c: linear-gradient(
    180deg,
    transparent 0 2%,
    var(--sep-rain-1) 7.4%,
    var(--sep-rain-2) 14.2%,
    var(--sep-rain-3) 18.9%,
    transparent 20%,
    transparent 31%,
    var(--sep-rain-1) 34.3%,
    var(--sep-rain-2) 38.5%,
    var(--sep-rain-3) 41.3%,
    transparent 42%,
    transparent 55%,
    var(--sep-rain-1) 62.5%,
    var(--sep-rain-2) 72%,
    var(--sep-rain-3) 78.5%,
    transparent 80%
  );
  /* d — 12rem. The sparse one: two long streaks and a 38% dead stretch. */
  --sep-rain-d: linear-gradient(
    180deg,
    transparent 0 8%,
    var(--sep-rain-1) 16.1%,
    var(--sep-rain-2) 26.4%,
    var(--sep-rain-3) 33.4%,
    transparent 35%,
    transparent 54%,
    var(--sep-rain-1) 58.8%,
    var(--sep-rain-2) 64.9%,
    var(--sep-rain-3) 69%,
    transparent 70%
  );
  /* e — 8rem, the shortest tile in the sheet. Two streaks, spans 22/13%. */
  --sep-rain-e: linear-gradient(
    180deg,
    transparent 0 5%,
    var(--sep-rain-1) 11.6%,
    var(--sep-rain-2) 20%,
    var(--sep-rain-3) 25.7%,
    transparent 27%,
    transparent 48%,
    var(--sep-rain-1) 51.9%,
    var(--sep-rain-2) 56.8%,
    var(--sep-rain-3) 60.2%,
    transparent 61%
  );
  /* f — 24rem. Six short streaks: the busy column, spans 9/13/7/16/10/12%. */
  --sep-rain-f: linear-gradient(
    180deg,
    transparent 0 2%,
    var(--sep-rain-1) 4.7%,
    var(--sep-rain-2) 8.1%,
    var(--sep-rain-3) 10.5%,
    transparent 11%,
    transparent 18%,
    var(--sep-rain-1) 21.9%,
    var(--sep-rain-2) 26.8%,
    var(--sep-rain-3) 30.2%,
    transparent 31%,
    transparent 37%,
    var(--sep-rain-1) 39.1%,
    var(--sep-rain-2) 41.8%,
    var(--sep-rain-3) 43.6%,
    transparent 44%,
    transparent 51%,
    var(--sep-rain-1) 55.8%,
    var(--sep-rain-2) 61.9%,
    var(--sep-rain-3) 66%,
    transparent 67%,
    transparent 73%,
    var(--sep-rain-1) 76%,
    var(--sep-rain-2) 79.8%,
    var(--sep-rain-3) 82.4%,
    transparent 83%,
    transparent 87%,
    var(--sep-rain-1) 90.6%,
    var(--sep-rain-2) 95.2%,
    var(--sep-rain-3) 98.3%,
    transparent 99%
  );
  /* The same six shapes at the capped far/reading-column grade. Identical stop
     positions on purpose: the far plane has to be the SAME rain seen further
     off, not different weather, so only the three colour stops change. */
  --sep-rain-a-dim: linear-gradient(
    180deg,
    transparent 0 3%,
    var(--sep-rain-c1) 7.2%,
    var(--sep-rain-c2) 12.5%,
    var(--sep-rain-c3) 16.2%,
    transparent 17%,
    transparent 26%,
    var(--sep-rain-c1) 28.4%,
    var(--sep-rain-c2) 31.4%,
    var(--sep-rain-c3) 33.5%,
    transparent 34%,
    transparent 41%,
    var(--sep-rain-c1) 46.7%,
    var(--sep-rain-c2) 53.9%,
    var(--sep-rain-c3) 58.9%,
    transparent 60%,
    transparent 67%,
    var(--sep-rain-c1) 70.3%,
    var(--sep-rain-c2) 74.5%,
    var(--sep-rain-c3) 77.3%,
    transparent 78%,
    transparent 84%,
    var(--sep-rain-c1) 88.5%,
    var(--sep-rain-c2) 94.2%,
    var(--sep-rain-c3) 98.1%,
    transparent 99%
  );
  --sep-rain-b-dim: linear-gradient(
    180deg,
    transparent 0 6%,
    var(--sep-rain-c1) 12.3%,
    var(--sep-rain-c2) 20.3%,
    var(--sep-rain-c3) 25.7%,
    transparent 27%,
    transparent 35%,
    var(--sep-rain-c1) 37.7%,
    var(--sep-rain-c2) 41.1%,
    var(--sep-rain-c3) 43.5%,
    transparent 44%,
    transparent 52%,
    var(--sep-rain-c1) 57.1%,
    var(--sep-rain-c2) 63.6%,
    var(--sep-rain-c3) 68%,
    transparent 69%,
    transparent 76%,
    var(--sep-rain-c1) 81.4%,
    var(--sep-rain-c2) 88.2%,
    var(--sep-rain-c3) 92.9%,
    transparent 94%
  );
  --sep-rain-c-dim: linear-gradient(
    180deg,
    transparent 0 2%,
    var(--sep-rain-c1) 7.4%,
    var(--sep-rain-c2) 14.2%,
    var(--sep-rain-c3) 18.9%,
    transparent 20%,
    transparent 31%,
    var(--sep-rain-c1) 34.3%,
    var(--sep-rain-c2) 38.5%,
    var(--sep-rain-c3) 41.3%,
    transparent 42%,
    transparent 55%,
    var(--sep-rain-c1) 62.5%,
    var(--sep-rain-c2) 72%,
    var(--sep-rain-c3) 78.5%,
    transparent 80%
  );
  --sep-rain-d-dim: linear-gradient(
    180deg,
    transparent 0 8%,
    var(--sep-rain-c1) 16.1%,
    var(--sep-rain-c2) 26.4%,
    var(--sep-rain-c3) 33.4%,
    transparent 35%,
    transparent 54%,
    var(--sep-rain-c1) 58.8%,
    var(--sep-rain-c2) 64.9%,
    var(--sep-rain-c3) 69%,
    transparent 70%
  );
  --sep-rain-e-dim: linear-gradient(
    180deg,
    transparent 0 5%,
    var(--sep-rain-c1) 11.6%,
    var(--sep-rain-c2) 20%,
    var(--sep-rain-c3) 25.7%,
    transparent 27%,
    transparent 48%,
    var(--sep-rain-c1) 51.9%,
    var(--sep-rain-c2) 56.8%,
    var(--sep-rain-c3) 60.2%,
    transparent 61%
  );
  --sep-rain-f-dim: linear-gradient(
    180deg,
    transparent 0 2%,
    var(--sep-rain-c1) 4.7%,
    var(--sep-rain-c2) 8.1%,
    var(--sep-rain-c3) 10.5%,
    transparent 11%,
    transparent 18%,
    var(--sep-rain-c1) 21.9%,
    var(--sep-rain-c2) 26.8%,
    var(--sep-rain-c3) 30.2%,
    transparent 31%,
    transparent 37%,
    var(--sep-rain-c1) 39.1%,
    var(--sep-rain-c2) 41.8%,
    var(--sep-rain-c3) 43.6%,
    transparent 44%,
    transparent 51%,
    var(--sep-rain-c1) 55.8%,
    var(--sep-rain-c2) 61.9%,
    var(--sep-rain-c3) 66%,
    transparent 67%,
    transparent 73%,
    var(--sep-rain-c1) 76%,
    var(--sep-rain-c2) 79.8%,
    var(--sep-rain-c3) 82.4%,
    transparent 83%,
    transparent 87%,
    var(--sep-rain-c1) 90.6%,
    var(--sep-rain-c2) 95.2%,
    var(--sep-rain-c3) 98.3%,
    transparent 99%
  );

  /* ---- Runnel profiles ---------------------------------------------------
     A runnel is a long faint track with a heavy head at its foot and a DARK
     bruise immediately below the head. The dark stop is half the trick: a
     bright head at the end of a tapering trail on a black ground is a meteor,
     and that is exactly what an earlier pass rendered. Give the head a shadow
     on its leading edge and it stops being a light in the sky and becomes a
     lump of water pushing down a sheet of glass.

     The other half is new, and it replaces a support the removed beads used to
     provide. The old note argued that what separates a runnel from a shooting
     star is context — vertical, casting, with beading scattered along its
     track — and one of those three has just been deleted. So the shape itself
     has to carry more of it: the head is now a short PLATEAU (76.5%–78.4% of
     the tile, about 9px on a 50vh column) rather than a single stop. A point of
     light is a star; a short bright dash travelling down a long faint track is
     a bead of water with a meniscus, and it reads that way with nothing at all
     behind it. The tail also starts higher (30% instead of 44%) so the track
     above the head is visibly longer than the head is, which no meteor trail
     is. */
  --sep-runnel: linear-gradient(
    180deg,
    transparent 0 30%,
    var(--sep-glass-far) 46%,
    var(--sep-glass-body) 68%,
    var(--sep-glass-lit) 76.5%,
    var(--sep-glass-lit) 78.4%,
    var(--sep-glass-body) 79.6%,
    var(--sep-glass-shade) 82%,
    transparent 85.5%,
    transparent 100%
  );
  --sep-runnel-dim: linear-gradient(
    180deg,
    transparent 0 36%,
    rgba(200, 183, 157, 0.04) 52%,
    rgba(213, 200, 177, 0.09) 70%,
    rgba(234, 227, 211, 0.14) 76.5%,
    rgba(234, 227, 211, 0.14) 78.4%,
    rgba(213, 200, 177, 0.07) 79.6%,
    rgba(5, 3, 1, 0.6) 82%,
    transparent 85.5%,
    transparent 100%
  );

  --bg: #140c08;
  --surface: transparent;
  --text: var(--tt-cyan);
  --text-soft: var(--tt-cyan-soft);
  --muted: var(--tt-gray);
  --border: var(--tt-red);
  --border-dim: rgba(226, 64, 44, 0.26);
  --border-teal: rgba(210, 87, 31, 0.62);
  background: #140c08;
  color: var(--tt-cyan);
  color-scheme: dark;
}

/* Rain scene: no CRT scanline.

   Removed 2026-08-11 at the user's request — "remove tv bars from background",
   and they are right that it is a TV artefact rather than a window one. A
   repeating-linear-gradient at a 1px-on-3px-off pitch is the one texture that
   cannot coexist with this month: rain is vertical, the scanline is
   horizontal, and laid over each other at that pitch the two interfere into a
   visible cross-hatch. It was also the last thing on the page still painting
   over the type, since this pseudo-element is fixed at z-index 5 — ABOVE the
   text — which is why the interference was so legible.

   The scanline stays a permanent fixture in main.css. April and december both
   depend on it being there to opt out of or to repaint, so it is switched off
   here on the month's own selector, exactly the way april's daylight scene
   switches it off, rather than being weakened at the source.

   The two corner condensation blooms that used to share this element went with
   it, as part of the same removal of static water. Nothing is left, so the
   element is dropped outright rather than emptied.

   This rule carries no data-mode, so one declaration covers midnight and four
   in the afternoon; the day block below therefore no longer restates it.

   Unlike april's version of this rule, the header neon strip is NOT included.
   April drops the strip because a daylight scene has no neon in it. September's
   diner very much does, and the tube over the door is a fixture of the month. */
body[data-theme-id="september"]::before {
  display: none;
  animation: none;
}

/* ---------------------------------------------------------------------------
   THE COUNTER — the breadcrumb bar is the single element allowed its own
   background, so it is where the diner is actually built: a speckled formica
   top, a checker-tile trim along its foot, and the bright chrome bullnose
   nosing that caps every counter of the period. The rivet studs on the
   ::after keyline in main.css were already the right idea; they stay.
   All static. Nothing here animates.
   --------------------------------------------------------------------------- */
body[data-theme-id="september"] .breadcrumb-nav {
  background:
    /* Checker trim: two offset rows along the bottom edge. Widened from 6px to
       9px — at 6px the squares were smaller than the gap they sat in and the
       whole trim read as a dashed rule under the bar rather than as checker. */
    repeating-linear-gradient(90deg, rgba(244, 217, 184, 0.13) 0 9px, transparent 9px 18px)
      left bottom / 100% 4px repeat-x,
    repeating-linear-gradient(90deg, transparent 0 9px, rgba(244, 217, 184, 0.13) 9px 18px)
      left bottom 4px / 100% 4px repeat-x,
    /* Formica confetti: the flecks that ran through every counter laminate of
       the era, in the theme's own cream, ember and gold.

       Retuned 2026-08-10 for the same reason the rain was. At 17x13 / 23x19 /
       29x23px with hard-edged 2px flecks this was not confetti, it was a
       perforated grid — the counter read as pegboard, and once the sky behind
       it went quiet the grid was the first thing the eye landed on. Periods are
       now coarse and mutually prime, and each fleck carries a soft outer stop
       instead of a hard edge, which is what turns a dot into a speck suspended
       in laminate. One broad non-repeating mottle underneath keeps the surface
       from being flat between them.

       The fleck radius is stated explicitly and kept far smaller than its tile.
       Letting a radial fade across the whole tile instead — which is what the
       first attempt at this did — makes every cell paint a soft blob edge to
       edge, and the counter quilts into a grid of blurry squares. A speck must
       be small relative to its cell or it is not a speck, it is a tile. */
    radial-gradient(circle at 34% 44%, rgba(244, 217, 184, 0.12) 0 0.7px, rgba(244, 217, 184, 0.05) 1.4px, transparent 2.2px)
      0 0 / 59px 47px repeat,
    radial-gradient(circle at 68% 61%, rgba(239, 74, 52, 0.11) 0 0.8px, rgba(239, 74, 52, 0.045) 1.5px, transparent 2.4px)
      13px 9px / 83px 67px repeat,
    radial-gradient(circle at 47% 24%, rgba(240, 201, 135, 0.1) 0 0.6px, rgba(240, 201, 135, 0.04) 1.2px, transparent 2px)
      29px 17px / 107px 89px repeat,
    radial-gradient(ellipse 70% 120% at 22% 30%, rgba(244, 217, 184, 0.05), transparent 70%)
      0 0 / 100% 100% no-repeat,
    radial-gradient(ellipse 60% 110% at 78% 74%, rgba(239, 74, 52, 0.05), transparent 68%)
      0 0 / 100% 100% no-repeat,
    var(--sep-sheen) 0 0 / 100% 100% no-repeat,
    linear-gradient(180deg, #33200f 0%, #2b1810 44%, #1c100a 100%) 0 0 / 100% 100% no-repeat;
  box-shadow:
    var(--sep-bullnose),
    0 0 18px rgba(226, 64, 44, 0.14);
}

/* The existing sweep becomes the specular highlight travelling along the
   nosing. Same element, same animation, same duration — only the colours move
   from July's cyan/hotpink to this month's cream and ember. */
body[data-theme-id="september"] .breadcrumb-nav::before {
  background: linear-gradient(
    90deg,
    transparent,
    rgba(244, 229, 209, 0.26),
    rgba(255, 122, 85, 0.15),
    transparent
  );
}

/* THE SCENE — midnight, overcast, the street outside the window.

   Diagnosis of what was here before: the base linear-gradient climbed from
   #0a0605 all the way to #2f1810, so by the time it reached the bottom of the
   viewport it had already lifted the whole lower half to a flat mid-brown. The
   three ember radials were then centred at 105-108% of a POSITION:FIXED element
   — i.e. off the bottom of the screen — with `transparent 27-36%` falloffs, so
   only their dimmest tails were ever on screen, and those tails were painted
   onto a ground the base gradient had already raised to the same value. Net
   result: no ember, no horizon, no shape. Just a brown wash, which is exactly
   what it looked like.

   The fix is a reversal of which layer does the work. The base gradient now
   stays genuinely dark to the bottom edge (#130b08, marginally darker than the
   page ground) so there is something for a glow to be a glow AGAINST, and the
   embers are pulled up on screen with explicit ellipse sizing so they land as
   deliberate, soft-topped banks of light rather than clipped tails.

   They are also banked to the SHOULDERS. The sign is off to one side and the
   wet street catches it to the other; the centre of the frame — which is where
   the max-width reading column sits — stays the darkest part of the picture.
   That is both the more interesting composition and the reason red type keeps
   its contrast over the scenery, since this palette's --tt-red has almost no
   luminance headroom to give away.

   Every ellipse is explicitly sized. A radial-gradient with no size resolves to
   farthest-corner, which on a viewport-shaped box overshoots badly and paints
   soft rectangles into the corners. Nothing here is left to default. */
body[data-theme-id="september"] .night-sky {
  background:
    /* The sign, low and left. */
    radial-gradient(ellipse 58% 30% at 15% 100%, rgba(226, 64, 44, 0.3), transparent 68%),
    /* Warm spill off the wet road, low and right. */
    radial-gradient(ellipse 46% 24% at 87% 103%, rgba(234, 166, 60, 0.19), transparent 66%),
    /* The two joined by one wide dim bank so the horizon is continuous. */
    radial-gradient(ellipse 96% 15% at 50% 105%, rgba(210, 87, 31, 0.21), transparent 70%),
    /* Cloud deck: overcast, lit faintly from beneath by the town. No stars —
       it is raining, and a clear star field under rain was always a contradiction. */
    radial-gradient(ellipse 130% 34% at 50% 100%, rgba(43, 24, 16, 0.4), transparent 74%),
    linear-gradient(180deg, #090504 0%, #0b0703 38%, #100a08 70%, #130b08 100%);
}

/* ---------------------------------------------------------------------------
   THE RAIN.

   Three moving planes at three speeds, plus the road. The whole point is that
   they MOVE at different rates: a single field at a single rate is snow no
   matter what colour it is, and a field that does not move at all is not
   weather, it is a texture. The previous build named three "motion states" and
   two of them were painted still — that is what got removed on 2026-08-11.

     --far        z-index 1. The veil, falling behind the pane. Sixteen thin
                  columns, capped grade, ~290px/s, blur 0.4px, 8 degrees off
                  vertical. Crosses the full width including the reading column.
     __aurora     z-index 2. The wet road. Static, and legitimately so: it is
                  ground rather than weather, and ground does not move.
     ::before     z-index 3, the front plane of the scenery. Repurposed from the
                  static glass to the NEAR rain: nine thick columns, full grade,
                  ~565px/s, blur 0.9px, the same 8 degrees. Shoulders only.
     --near       z-index 4. Runnels ON the pane. Slow, vertical, eased so the
                  water clings, sheds and clings again.

   Ambient loops go from two to three, and the frame cost still goes DOWN:
   twenty-five narrow repeat-y columns replace forty-three full-viewport radial
   layers, and the new loop sits on an element that was already being painted.
   All three animations are transform-only on composited layers — no filter
   animation, no box-shadow, no background-position animation — and both blurs
   are baked into the rasterization once rather than re-run per frame.

   Five things are load-bearing across all the planes:

   * NO HORIZONTAL PERIOD ANYWHERE. Every falling column and every runnel is
     background-repeat: repeat-y, hand-placed at its own x. The old field tiled
     in both axes and combed visibly; a column that only repeats downward
     cannot comb sideways.
   * NO SEAM. Every plane travels exactly one background period per iteration,
     and every tile height divides that travel — 12rem / 6rem / 4rem / 3rem
     against a 12rem travel, 50vh / 25vh against a 50vh travel. Phase is varied
     through each column's y offset instead, so columns that share a period
     still never line up. A tile height that does not divide the travel is the
     one way to make the wrap visible, and there is not one in this sheet.
   * HEAVY HEAD, LIGHT TAIL, plus LENGTH VARIANCE, both stated inside each
     gradient rather than assembled from a head layer plus a trail layer.
   * DEPTH BY PARALLAX. Far is thin, dim, slow. Near is thick, bright, fast, and
     more heavily blurred because it is closer to the eye. Nothing else in CSS
     buys depth on a flat gradient field.
   * BANKED TO THE SHOULDERS, exactly like the ember. The near plane never
     enters 18%–82%; only the capped far veil crosses the reading column, and
     never two capped planes at once. See the contrast arithmetic in the token
     block above — this is a measured limit, not a preference.
   --------------------------------------------------------------------------- */

/* THE NEAR RAIN — the front plane of the weather, on the shoulders only.

   This element used to be THE GLASS: sixteen hand-placed beads, eight sheeting
   films and three condensation blooms, no-repeat, `animation: none`. All of it
   is gone. It was the "water looking static background" the user asked to have
   removed, and the diagnosis is worth keeping because the same instinct will
   come back: a static full-viewport water layer is indistinguishable from dirt
   on the reader's screen. Real rain on a window is never still — even the beads
   that appear to hang are wobbling and being struck. If it cannot move, it
   cannot be water, and it should not be a plane covering the page.

   What replaces it is the near half of the parallax. Nine columns, all outside
   18%–82%, at full --sep-rain-* grade. Every distinction from the far plane is
   a depth cue, and the first four run the same direction:

     width   2.2–3.6px against the far plane's 0.9–1.8px
     speed   0.68s per 24rem (~565px/s) against 1.32s (~290px/s)
     alpha   head 0.46 against the capped 0.20
     blur    0.9px against 0.4px — nearer water is more motion-blurred, and the
             extra softness is also what keeps a 3.6px column at 0.46 alpha from
             reading as a hard white rule.
     angle   8 degrees against 9.5 — not a depth cue but a shear cue, and the
             one distinction between the planes that is about the air rather
             than about the distance. See the septemberRainFall keyframes.

   z-index: 3 is kept from the old glass rule and still matters: main.css leaves
   this pseudo-element at auto, which would put it under .night-sky__stars
   (z-index 1) and under the road (z-index 2), so the nearest plane would paint
   behind the weather. It stays inside .night-sky's own stacking context and
   therefore still behind every word on the page.

   The inset overhang is sized for the rotation — main.css gives this element
   inset: -2rem, which at 8 degrees leaves bare wedges in the top corners once
   the layer is turned — and the horizontal half of it is cancelled back out of
   every background-position. See the --sep-rain-bleed note. .night-sky is
   overflow: hidden, so the extra area is clipped and costs nothing beyond the
   columns themselves, which are at most 3.6px wide.

   Every x below is a real viewport position: five columns in the left 17% and
   four in the right 16%, nothing between.

   Those x values are now IRREGULAR, and that is a fix rather than a flourish.
   The previous five ran 2 / 6 / 10 / 14 / 17vw — a 4vw pitch, four times over —
   and the four on the right were its mirror image at 2 / 6 / 10 / 15. Evenly
   spaced columns are a comb whatever is drawn in them, and a mirrored comb is
   worse, because the symmetry gives the eye a second pattern to find after it
   has found the first. The new spacing runs in clumps with voids between, the
   two shoulders share no interval, and neither is the other reflected.

   No profile is used twice at the same width or the same phase, so the two
   reappearances of a, c and e cannot pair up visually. */
body[data-theme-id="september"] .night-sky::before {
  inset: -18rem calc(-1 * var(--sep-rain-bleed)) -6rem;
  z-index: 3;
  opacity: 1;
  background-image:
    /* left shoulder — five */
    var(--sep-rain-a), var(--sep-rain-e), var(--sep-rain-c),
    var(--sep-rain-f), var(--sep-rain-b),
    /* right shoulder — four */
    var(--sep-rain-d), var(--sep-rain-a), var(--sep-rain-c), var(--sep-rain-e);
  background-size:
    3.2px 24rem, 2.2px 8rem, 2.8px 12rem, 3.6px 24rem, 2.5px 24rem,
    3px 12rem, 2.3px 24rem, 3.4px 12rem, 2.7px 8rem;
  background-position:
    left calc(var(--sep-rain-bleed) + 1.5vw) top 0,
    left calc(var(--sep-rain-bleed) + 4vw) top 5.3rem,
    left calc(var(--sep-rain-bleed) + 5.2vw) top 9.4rem,
    left calc(var(--sep-rain-bleed) + 11vw) top 13.7rem,
    left calc(var(--sep-rain-bleed) + 16.4vw) top 20.2rem,
    right calc(var(--sep-rain-bleed) + 15.2vw) top 2.6rem,
    right calc(var(--sep-rain-bleed) + 12.4vw) top 8.1rem,
    right calc(var(--sep-rain-bleed) + 6.1vw) top 6.8rem,
    right calc(var(--sep-rain-bleed) + 1.8vw) top 1.9rem;
  background-repeat: repeat-y;
  /* Nearer water, so more motion blur than the far veil — and at 3.6px wide a
     column needs it, because a hard-edged bright vertical bar is a scratch on
     the film rather than a drop. Free per frame: the animation is
     transform-only, so the layer rasterizes once with the blur already in it
     and the compositor slides the finished texture. */
  filter: blur(0.9px);
  /* 24rem per 0.68s, which is the 12rem-per-0.34s this plane has always fallen
     at. The travel doubled to lengthen the loop, not to change the weather. */
  animation: septemberRainFall 0.68s linear infinite;
}

/* THE FAR RAIN — the veil, well behind the pane. Sixteen columns, repeat-y.

   Every column is now the capped -dim grade, where the previous version ran
   fourteen of twenty at full strength. That is the far/near split doing its
   job: distant rain in any photograph is a faint uniform veil and near rain is
   a handful of distinct streaks, and if the far plane runs bright too there is
   no depth, just two identical fields at different speeds. It also makes the
   contrast budget trivial — this is the only plane that crosses the reading
   column and it is under the 0.20 ceiling everywhere, at every scroll position,
   by construction rather than by hand-placement.

   Slowed from 0.42s to 0.66s per 12rem, ~450px/s down to ~290px/s — now stated
   as 1.32s per 24rem, which is the same speed over the longer travel. Apparent
   speed falls with distance, so the far plane has to be the slow one; running
   the veil faster than the near streaks reverses the parallax and the picture
   turns inside out.

   The rotation is in the keyframes rather than on the element, because the
   animation sets `transform` and would otherwise cancel it. The translate runs
   along the element's own rotated y-axis, so the loop is still exactly one
   background period and still seamless.

   This plane leans 9.5 degrees where the near plane leans 8, and it has its own
   keyframe to do it. Both used to run the same 8, and two fields sharing an
   angle to the degree is a tell no photograph has: rain a hundred feet out is
   not in the same air as rain on the glass, and wind shear across that distance
   is exactly what makes a real downpour look unruled. A degree and a half is
   enough for the two planes to read as separate weather and small enough that
   neither looks blown sideways. The steeper angle does eat into the corner
   coverage --sep-rain-bleed provides — see that note — but 8rem still holds well
   past any viewport height a reader is going to have.

   Travel is 24rem and every column period divides it (24 / 12 / 8rem), which is
   what makes the wrap invisible; phase is varied per column through the y offset
   instead, and every offset is now spread across its own tile's full height
   rather than bunched into the first 3.4rem — a 3.3rem offset on a 4rem tile was
   very nearly no offset at all. The inset overhang is sized for the rotation and
   cancelled back out of every x, so the sixteen offsets below read as true
   viewport positions. See --sep-rain-bleed.

   The x values are clumped rather than combed, for the reason given on the near
   plane, and the profile order is a permutation with no run and no cycle — the
   old sequence was literally a-b-c repeated five times across the screen. */
body[data-theme-id="september"] .night-sky__stars--far {
  display: block;
  inset: -18rem calc(-1 * var(--sep-rain-bleed)) -6rem;
  opacity: 1;
  background-image:
    var(--sep-rain-a-dim), var(--sep-rain-e-dim), var(--sep-rain-c-dim),
    var(--sep-rain-f-dim), var(--sep-rain-b-dim), var(--sep-rain-d-dim),
    var(--sep-rain-c-dim), var(--sep-rain-a-dim), var(--sep-rain-f-dim),
    var(--sep-rain-e-dim), var(--sep-rain-b-dim), var(--sep-rain-a-dim),
    var(--sep-rain-d-dim), var(--sep-rain-c-dim), var(--sep-rain-f-dim),
    var(--sep-rain-b-dim);
  background-size:
    1.4px 24rem, 0.9px 8rem, 1.6px 12rem, 1.1px 24rem,
    1.8px 24rem, 1px 12rem, 1.2px 12rem, 1.5px 24rem,
    0.9px 24rem, 1.7px 8rem, 1.1px 24rem, 1.3px 24rem,
    1.6px 12rem, 1px 12rem, 1.8px 24rem, 1.2px 24rem;
  background-position:
    left calc(var(--sep-rain-bleed) + 1.8vw) top 0,
    left calc(var(--sep-rain-bleed) + 3.4vw) top 3.1rem,
    left calc(var(--sep-rain-bleed) + 9.7vw) top 7.4rem,
    left calc(var(--sep-rain-bleed) + 16.2vw) top 18.6rem,
    left calc(var(--sep-rain-bleed) + 17.5vw) top 5.2rem,
    left calc(var(--sep-rain-bleed) + 25.8vw) top 10.3rem,
    left calc(var(--sep-rain-bleed) + 33.1vw) top 2.8rem,
    left calc(var(--sep-rain-bleed) + 42.9vw) top 14.7rem,
    left calc(var(--sep-rain-bleed) + 48.3vw) top 21.4rem,
    right calc(var(--sep-rain-bleed) + 43.3vw) top 6.2rem,
    right calc(var(--sep-rain-bleed) + 41.8vw) top 9.9rem,
    right calc(var(--sep-rain-bleed) + 33.6vw) top 3.6rem,
    right calc(var(--sep-rain-bleed) + 25.1vw) top 5.7rem,
    right calc(var(--sep-rain-bleed) + 16.4vw) top 11.1rem,
    right calc(var(--sep-rain-bleed) + 8.2vw) top 8.3rem,
    right calc(var(--sep-rain-bleed) + 2.7vw) top 16.8rem;
  background-repeat: repeat-y;
  /* A background column has dead-hard vertical sides; at 1-2px on a near-black
     ground that is a scratch on the film, which is precisely what this layer
     kept rendering as before any blur was applied. Under half a pixel rounds
     the sides off and the column becomes a motion-blurred thread of water,
     which is what a falling drop is at a 1/60s exposure. Less than the near
     plane's 0.9px, because a distant drop crosses fewer pixels per frame and
     therefore smears less — the blur is a depth cue as much as a softener.

     It costs nothing per frame: the animation is transform-only, so the layer
     rasterizes once with the blur baked in and the compositor slides that
     finished texture. A blur that stays under a pixel also cannot pull a bright
     stop across the reading column, so the ceiling on --sep-rain-c3 holds. */
  filter: blur(0.4px);
  animation: septemberRainFallFar 1.32s linear infinite;
}

/* RUNNELS ON THE GLASS — the water that is actually running down the pane, and
   the plane that makes the window read as a window rather than as a sky. With
   the beading gone this is now the ONLY thing on the near surface, so it carries
   the whole "there is a pane here" reading and was retuned accordingly.

   Repurposed from the near star layer, raised to z-index 4 so it sits on the
   glass rather than behind it. Twelve columns, repeat-y, hand-placed x, dead
   vertical — a runnel is pulled by gravity down a stationary sheet of glass and
   takes no part in the 8-degree slant the falling planes have.

   The easing is the point. A cubic-bezier that starts and ends each iteration
   at zero velocity makes the pane hang, shed, and hang again — which is what
   water on glass does, and what no amount of linear drift can imitate. Because
   the travel is exactly one 50vh background period, position is continuous
   across the loop AND velocity is zero on both sides of the seam, so the wrap
   is invisible in both senses. This is the one place in the theme where a
   non-linear timing function is correct rather than a mistake.

   Eased back from cubic-bezier(0.85, 0, 0.15, 1) to (0.62, 0, 0.38, 1), and
   shortened from 9s to 8s. Both ends still hit zero velocity, so the seam
   argument above is untouched — but the old curve spent so much of its nine
   seconds near-stationary that the runnels read as part of the static water
   rather than as the thing moving through it. That was a real contributor to
   the layer the user asked to have removed: when three of four planes are
   motionless, the fourth stops being read as motion. Less dwell, same physics.

   The head of each runnel carries a dark bruise on its leading edge plus a short
   bright PLATEAU rather than a single stop — see the --sep-runnel note. Between
   them they are what stops twelve bright heads on tapering tracks from reading
   as a meteor shower. A meteor is a point with nothing under it; a drop pushing
   down a wet pane is a short dash with a shadow. */
body[data-theme-id="september"] .night-sky__stars--near {
  inset: -56vh -2rem 0;
  z-index: 4;
  opacity: 1;
  background-image:
    var(--sep-runnel), var(--sep-runnel), var(--sep-runnel), var(--sep-runnel),
    var(--sep-runnel-dim), var(--sep-runnel-dim),
    var(--sep-runnel-dim), var(--sep-runnel-dim),
    var(--sep-runnel), var(--sep-runnel), var(--sep-runnel), var(--sep-runnel);
  background-size:
    2.6px 50vh, 1.8px 25vh, 3px 50vh, 2px 25vh,
    1.8px 50vh, 1.5px 25vh, 1.9px 50vh, 1.6px 25vh,
    2px 25vh, 3.2px 50vh, 2.1px 25vh, 2.8px 50vh;
  background-position:
    1.5% 0, 5% 9vh, 9% 21vh, 13.5% 4vh,
    22% 14vh, 34% 2vh, 64% 18vh, 79% 7vh,
    87% 11vh, 91% 24vh, 95% 3vh, 98.5% 16vh;
  background-repeat: repeat-y;
  /* Same reasoning as the falling planes: a runnel is wider than a falling
     thread and sits closer to the eye, so its edges want more rounding, and the
     same transform-only rule keeps it free per frame. */
  filter: blur(0.7px);
  animation: septemberRunnelSlide 8s cubic-bezier(0.62, 0, 0.38, 1) infinite;
}

/* THE GROUND. No skyline — the city silhouette is July's Fourth-of-July
   scenery and is never borrowed. This is the wet road under the window: a low
   plane with a soft top edge, filled DARKER than the ember banked above it,
   because wet asphalt at night is the darkest thing in the frame and the
   horizon only exists if something sits below it. Three broad warm smears rise
   off the bottom edge — the sign reflected in standing water. They are
   deliberately few, very wide and very soft; a row of narrow bright verticals
   here would restage the bar-code problem the rain just had.

   Also the reason the bottom of the page stopped being a flat brown field:
   the old horizon had no plane, so the lower half of every screenshot was one
   featureless wash. */
body[data-theme-id="september"] .night-sky__aurora {
  display: block;
  left: 0;
  right: 0;
  bottom: 0;
  height: clamp(5rem, 17vh, 12rem);
  clip-path: none;
  box-shadow: none;
  background:
    radial-gradient(ellipse 26% 76% at 16% 100%, rgba(239, 74, 52, 0.2), transparent 72%),
    radial-gradient(ellipse 19% 62% at 47% 100%, rgba(234, 166, 60, 0.13), transparent 70%),
    radial-gradient(ellipse 31% 84% at 83% 100%, rgba(210, 87, 31, 0.15), transparent 74%),
    linear-gradient(180deg, rgba(8, 5, 2, 0) 0%, rgba(8, 5, 2, 0.5) 42%, rgba(6, 4, 2, 0.86) 100%);
}

body[data-theme-id="september"] .brand a {
  text-shadow:
    0 0 10px rgba(234, 166, 60, 0.6),
    0 0 26px rgba(226, 64, 44, 0.34),
    0 0 46px rgba(126, 60, 60, 0.2);
}

/* ---------------------------------------------------------------------------
   HEADINGS — the menu board.
   --------------------------------------------------------------------------- */

/* H1 is the sign in the window, and on a resting page it is very often the ONLY
   type on screen — every heading body below it is collapsed until hovered — so
   it has to carry the theme on its own.

   SignPainter, NOT Brush Script MT. This is a correction: the shared
   --font-cursive stack is "Segoe Script", "Lucida Handwriting", "Brush Script
   MT", cursive, and the first two ship on Windows only. On macOS that stack has
   always resolved to Brush Script MT — so naming Brush Script MT here changed
   nothing whatsoever, and the largest element on the page silently kept the
   face it already had. SignPainter is a genuine sign-painter's brush, closer to
   what was actually lettered onto diner glass in the fifties than the 1942
   typeface is, and it is unmistakably a different face. Roundhand and Brush
   Script follow for machines without it, cursive last.

   All three are already slanted, so the synthesised italic main.css applies is
   cancelled — doubling the slant smears it at display size. Only markdown H1 is
   touched; the brand wordmark keeps its locked stack. */
body[data-theme-id="september"] main h1,
body[data-theme-id="september"] .page-title {
  font-family: SignPainter, "SignPainter-HouseScript", "Snell Roundhand", "Brush Script MT", cursive;
  font-style: normal;
  letter-spacing: 0.02em;
}

/* Because H1 is usually alone on the resting page, it gets the full tube rather
   than the shared heading haze: a tight hot core, a mid bloom and a wide throw.
   Still all blurred — a hard-edged shadow would render through the transparent
   glyph and bury the clipped gradient. */
body[data-theme-id="september"] main h1,
body[data-theme-id="september"] .page-title,
body[data-theme-id="september"] .heading-section--level-1 > .heading-section__summary > .heading-section__trigger {
  text-shadow:
    0 0 6px rgba(255, 176, 132, 0.5),
    0 0 18px rgba(239, 74, 52, 0.42),
    0 0 44px rgba(226, 64, 44, 0.26),
    0 0 78px rgba(240, 201, 135, 0.14);
}

/* Every heading's glow goes warm. main.css casts a cyan bloom here, which is
   July's colour and has been leaking onto this month; ember and gold put the
   headings back behind September's own glass. It has to stay a blurred shadow:
   these letters are painted with background-clip:text, so a hard-edged shadow
   would render through the transparent glyph and bury the gradient. */
/* H1 is deliberately absent from this list — it carries the heavier tube above,
   and listing it here again at equal specificity would let the later rule win
   and quietly cancel it. */
body[data-theme-id="september"] main h2,
body[data-theme-id="september"] main h3,
body[data-theme-id="september"] main h4,
body[data-theme-id="september"] main h5,
body[data-theme-id="september"] main h6 {
  text-shadow:
    0 0 14px rgba(226, 64, 44, 0.26),
    0 0 34px rgba(240, 201, 135, 0.12);
}

body[data-theme-id="september"] .markdown-page .heading-section--level-2 > .heading-section__summary > .heading-section__trigger,
body[data-theme-id="september"] .markdown-page .heading-section--level-3 > .heading-section__summary > .heading-section__trigger {
  text-shadow:
    0 0 14px rgba(226, 64, 44, 0.26),
    0 0 34px rgba(240, 201, 135, 0.12);
}

/* H2 and H3 are set the way a board over a counter is set: engraved caps,
   centred, tracked wide, and small. Copperplate has no true lowercase, so the
   uppercase is stated rather than left to chance. Body copy underneath stays
   left-aligned. */
body[data-theme-id="september"] main h2,
body[data-theme-id="september"] main h3 {
  text-align: center;
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: 0.14em;
}

body[data-theme-id="september"] main h3 {
  letter-spacing: 0.18em;
}

/* Engraved caps at 0.14em set far wider than the humanist sans they replace, so
   the display sizes come down to keep a section title on one line. The trigger
   selectors are stated explicitly because main.css sizes those at (0,3,0) and
   would otherwise outrank a bare `main h2`. */
body[data-theme-id="september"] main h2,
body[data-theme-id="september"] .heading-section--level-2 > .heading-section__summary > .heading-section__trigger {
  font-size: clamp(1.2rem, 2.7vw, 1.8rem);
}

body[data-theme-id="september"] main h3,
body[data-theme-id="september"] .heading-section--level-3 > .heading-section__summary > .heading-section__trigger {
  font-size: clamp(0.98rem, 1.8vw, 1.2rem);
}

/* No rule under a board heading. The short centred --tt-heading-rainbow bar
   that used to sit beneath every H2 read as an underline on the rendered page
   and was the only thing drawing a line under a title in this month, so it is
   gone. The engraved caps, the centring and the ember glow carry the menu-board
   reading entirely on their own now — the section rail (.heading-section::before)
   remains the structural marker. Do not reinstate a ::after bar, a border-bottom
   or a text-decoration here. */

/* The collapsible heading trigger carries an asymmetric 2rem right gutter, and
   main.css indents it further on hover — both would pull a centred line off
   centre and make it twitch as the pointer crossed it. Symmetric padding on
   both levels fixes the geometry; this selector outranks the hover/active rule
   in main.css, so the indent is neutralised at rest and while open. The
   collapse behaviour, the rail and the body reveal are all untouched. */
body[data-theme-id="september"] .heading-section--level-2 > .heading-section__summary > .heading-section__trigger,
body[data-theme-id="september"] .heading-section--level-3 > .heading-section__summary > .heading-section__trigger {
  padding-inline: clamp(0.5rem, 2vw, 2rem);
}

/* The section rails are wet neon tubing, not July's cyan filament. */
body[data-theme-id="september"] .heading-section::before {
  box-shadow: 0 0 10px rgba(226, 64, 44, 0.3);
}

/* ---------------------------------------------------------------------------
   Links — the tubing itself. main.css hovers --link-hover (#FF465A, standing
   user rule 2026-08-14, replacing the old sitewide hotpink); this month keeps
   its own ember pulse on the shadow, matching the one the Obsidian september
   theme already ships, so both surfaces light the same way. Only the flat
   colour moved off --tt-red — the ember glow was never colour-matched to it
   1:1 and is left as it was.
   --------------------------------------------------------------------------- */
body[data-theme-id="september"] a:hover,
body[data-theme-id="september"] a:focus-visible {
  color: var(--link-hover);
  text-shadow:
    0 0 8px rgba(239, 74, 52, 0.86),
    0 0 16px rgba(239, 74, 52, 0.6),
    0 0 28px rgba(210, 87, 31, 0.34);
  animation: septemberLinkEmberGlow 1.05s ease-in-out infinite alternate;
}

body[data-theme-id="september"] a:visited {
  text-shadow:
    0 0 3px rgba(20, 12, 8, 0.95),
    0 0 10px rgba(168, 87, 87, 0.72),
    0 0 18px rgba(20, 12, 8, 0.86);
}

/* The eyebrow is the little lit strip over the counter — OPEN ALL NITE set in
   spaced caps, which is exactly what the class already is. It just gains the
   period's tracking and a tube glow. */
body[data-theme-id="september"] .eyebrow {
  letter-spacing: 0.34em;
  text-shadow: 0 0 10px rgba(210, 87, 31, 0.44);
}

/* ---------------------------------------------------------------------------
   Surfaces — everything below already had a fill or a frame in main.css. Each
   one gains gloss, a lit edge or both. Nothing gains a background it did not
   already have.
   --------------------------------------------------------------------------- */

/* Wet glass over the existing tint: the gloss runs light at the top and pools
   dark at the foot, the way a rained-on pane does. Inline code is left without
   the lit edge on purpose — an inline box fragments across line breaks and the
   hairline would break with it. */
body[data-theme-id="september"] input,
body[data-theme-id="september"] textarea,
body[data-theme-id="september"] select,
body[data-theme-id="september"] code,
body[data-theme-id="september"] pre {
  background-color: rgba(43, 24, 16, 0.5);
  background-image: var(--sep-sheen);
  color: var(--tt-cyan);
}

body[data-theme-id="september"] input,
body[data-theme-id="september"] textarea,
body[data-theme-id="september"] select,
body[data-theme-id="september"] pre {
  box-shadow: var(--sep-lip);
}

/* A code block is one pane of glass, not one per line: the gloss and the tint
   belong to the <pre>, and the <code> inside it stays clear. Needed explicitly
   because the tinted-surface rule above outranks main.css's `pre code`. */
body[data-theme-id="september"] pre code {
  background-color: transparent;
  background-image: none;
  box-shadow: none;
}

/* The table header is the board itself: engraved caps on anodised steel. The
   gloss is an overlay on the red token rather than a second hex, so the bar
   can never drift off the anchor colour if the palette is ever retuned. */
body[data-theme-id="september"] th {
  background-color: var(--tt-red);
  background-image: linear-gradient(
    180deg,
    rgba(242, 230, 210, 0.24) 0%,
    rgba(242, 230, 210, 0.06) 46%,
    rgba(10, 6, 5, 0.16) 54%,
    rgba(10, 6, 5, 0.32) 100%
  );
  color: #170d08;
  font-family: var(--font-heading);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Chrome trim: the bright nosing along the top edge and the shadow under it,
   no fill. Selected by class rather than by element so the rule cannot reach
   the zodiac chips, which share the <button>/<a> ground with these — a
   box-shadow on a chip is a border, and this theme is not going to grow one. */
body[data-theme-id="september"] .time-bar,
body[data-theme-id="september"] .sitemap-link,
body[data-theme-id="september"] .calendar-app__nav,
body[data-theme-id="september"] .calendar-app__today {
  box-shadow: var(--sep-lip);
}

/* The time bar is the chrome-framed title strip off a wallbox: heavier nosing,
   wider caps. */
body[data-theme-id="september"] .time-bar {
  box-shadow: var(--sep-bullnose);
  letter-spacing: 0.18em;
}

body[data-theme-id="september"] .sitemap-link:hover,
body[data-theme-id="september"] .calendar-app__nav:hover,
body[data-theme-id="september"] .calendar-app__today:hover,
body[data-theme-id="september"] .sitemap-link:focus-visible,
body[data-theme-id="september"] .calendar-app__nav:focus-visible,
body[data-theme-id="september"] .calendar-app__today:focus-visible {
  box-shadow:
    inset 0 1px 0 rgba(244, 229, 209, 0.4),
    inset 0 -1px 0 rgba(10, 6, 5, 0.6),
    0 0 16px rgba(226, 64, 44, 0.2);
}

/* Belt-and-braces, per the permanent note on .celestial-chip in main.css: the
   chips carry no border, no ring and no box halo under any theme. Their
   hover/focus affordance is the glyph halo cast from --zodiac-glow above. This
   pin exists so no future rule in this sheet can reach them by accident. */
body[data-theme-id="september"] .celestial-chip,
body[data-theme-id="september"] .celestial-chip:hover,
body[data-theme-id="september"] .celestial-chip:focus-visible {
  border: 0;
  box-shadow: none;
  outline: none;
}

/* Cards keep their rainbow frame and gain the same lit top edge as the trim,
   with the ambient bloom moved from July's purple to this month's ember. */
body[data-theme-id="september"] .hero-card,
body[data-theme-id="september"] .folder-section {
  box-shadow:
    inset 0 1px 0 rgba(244, 217, 184, 0.14),
    0 0 20px rgba(226, 64, 44, 0.09);
}

body[data-theme-id="september"] .hero-card:hover,
body[data-theme-id="september"] .folder-section:hover {
  box-shadow:
    inset 0 1px 0 rgba(244, 229, 209, 0.3),
    0 0 26px rgba(226, 64, 44, 0.16);
}

/* No left rule on quotes — left borders are reserved for list anchors. The
   inset wash just moves from July's green to gold. */
body[data-theme-id="september"] blockquote {
  color: var(--tt-cyan-soft);
  box-shadow: inset 1rem 0 1.4rem -1.2rem rgba(240, 201, 135, 0.5);
}

/* Tags are the little spaced-caps chips off a check pad. */
body[data-theme-id="september"] .tag {
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* The footer is the bottom of the check. */
body[data-theme-id="september"] footer {
  letter-spacing: 0.16em;
}

/* The scrollbar is the last piece of trim: a brushed rail, lit down one side. */
body[data-theme-id="september"]::-webkit-scrollbar-thumb,
body[data-theme-id="september"] ::-webkit-scrollbar-thumb {
  background-image: linear-gradient(
    90deg,
    rgba(244, 217, 184, 0.34) 0%,
    rgba(244, 217, 184, 0.05) 42%,
    rgba(10, 6, 5, 0.34) 100%
  );
}

/* Fireworks are Independence Day furniture: July theme only. The JS also refuses to
   spawn them off-July, so this is belt-and-braces for any burst already on screen. */
body[data-theme-id="september"] .night-sky__fireworks {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  /* Month blocks set their ambient motion on higher-specificity selectors, so
     they need their own entry. The scene is unchanged and complete: every
     falling column, every runnel, the ember horizon and the wet road are all
     painted in the first frame regardless, and the three moving layers simply
     stop where they stand rather than disappearing. Reduced motion here loses
     the travel and nothing else.

     BOTH falling planes keep their rotation, because the slant is part of the
     picture rather than part of the motion; `transform: none` would stand the
     rain upright and leave uncovered wedges in the corners of a layer whose
     overhang is sized for a rotated box. .night-sky::before is now one of them —
     it was in the `transform: none` group when it was the static glass, and
     moving it here is required, not cosmetic.

     They no longer share an angle, so they no longer share a rule: the near
     plane holds 8 degrees and the far veil holds 9.5, matching the keyframe each
     one is having taken away from it. A single grouped `rotate(8deg)` here would
     stand the far plane up by a degree and a half the moment a reader turns
     motion off, which is a still frame that does not match the moving one.

     The runnels are the one plane that does take `transform: none`: they are
     vertical, so there is nothing to preserve. */
  body[data-theme-id="september"] .night-sky::before {
    animation: none !important;
    transform: rotate(8deg) !important;
  }

  body[data-theme-id="september"] .night-sky__stars--far {
    animation: none !important;
    transform: rotate(9.5deg) !important;
  }

  body[data-theme-id="september"] .night-sky__stars--near {
    animation: none !important;
    transform: none !important;
  }

  body[data-theme-id="september"] a:hover,
  body[data-theme-id="september"] a:focus-visible {
    animation: none;
  }
}

@media (prefers-reduced-data: reduce) {
  /* Month themes set ambient motion on higher-specificity selectors; stop those
     too. On a metered connection the scene keeps its shape and loses its
     population: four near columns of nine, seven far columns of sixteen, five
     runnels of twelve. The ember horizon and the wet road survive intact,
     because they are the picture, and the survivors are chosen to keep the
     composition — near water still banked to the shoulders, only the capped
     veil across the middle, so the frame still reads as rained on rather than
     as a thinned-out version of one thing.

     Nothing here was ever a network cost; this is purely a fill-rate budget,
     which is why the reduction is in LAYER COUNT and nothing else. In
     particular every surviving column still repeats only downward and is still
     hand-placed at its own x. An earlier version of this block "reduced" the
     old bead field to a single tiled 149x191px pattern, which is cheaper to
     declare and reintroduces the exact lattice the theme exists to avoid. A
     cheap render is still not allowed to be a grid.

     The bead and sheeting thinning that used to live here went with the layers
     it thinned; there is no static water left to reduce. */
  body[data-theme-id="september"] .night-sky::before {
    animation: none;
    transform: rotate(8deg);
  }

  /* 9.5, not 8 — same reason as the reduced-motion block: each plane holds the
     angle its own keyframe was running. */
  body[data-theme-id="september"] .night-sky__stars--far {
    animation: none;
    transform: rotate(9.5deg);
  }

  body[data-theme-id="september"] .night-sky__stars--near {
    animation: none;
    transform: none;
  }

  /* Same bleed-cancelled vw anchoring as the full rules — a thinned field that
     silently drops its outermost columns off the edge of the screen is not a
     thinned field, it is a differently broken one.

     A thinned field is also the one that can least afford a repeat: with four
     columns instead of nine, any two of them sharing a profile is a quarter of
     the picture doubled. So the survivors take four different profiles, four
     different tile heights and four irregular x values, exactly as the full rule
     does — the reduction is in column count and nothing else. */
  body[data-theme-id="september"] .night-sky::before {
    background-image:
      var(--sep-rain-a), var(--sep-rain-f),
      var(--sep-rain-c), var(--sep-rain-b);
    background-size:
      3.2px 24rem, 2.6px 24rem, 3.4px 12rem, 2.8px 24rem;
    background-position:
      left calc(var(--sep-rain-bleed) + 3.2vw) top 0,
      left calc(var(--sep-rain-bleed) + 13.6vw) top 13.5rem,
      right calc(var(--sep-rain-bleed) + 10.4vw) top 4.8rem,
      right calc(var(--sep-rain-bleed) + 2.9vw) top 19.1rem;
  }

  body[data-theme-id="september"] .night-sky__stars--far {
    background-image:
      var(--sep-rain-c-dim), var(--sep-rain-a-dim), var(--sep-rain-e-dim),
      var(--sep-rain-f-dim), var(--sep-rain-b-dim),
      var(--sep-rain-d-dim), var(--sep-rain-a-dim);
    background-size:
      1.4px 12rem, 1.6px 24rem, 1.1px 8rem,
      1.5px 24rem, 1.2px 24rem,
      1.8px 12rem, 1.3px 24rem;
    background-position:
      left calc(var(--sep-rain-bleed) + 4.1vw) top 0,
      left calc(var(--sep-rain-bleed) + 17.3vw) top 9.2rem,
      left calc(var(--sep-rain-bleed) + 28.6vw) top 3.7rem,
      left calc(var(--sep-rain-bleed) + 45.2vw) top 15.8rem,
      right calc(var(--sep-rain-bleed) + 33.8vw) top 6.4rem,
      right calc(var(--sep-rain-bleed) + 16.1vw) top 2.1rem,
      right calc(var(--sep-rain-bleed) + 4.7vw) top 20.6rem;
  }

  body[data-theme-id="september"] .night-sky__stars--near {
    background-image:
      var(--sep-runnel), var(--sep-runnel), var(--sep-runnel-dim),
      var(--sep-runnel), var(--sep-runnel);
    background-size:
      3.4px 50vh, 4px 50vh, 2.4px 50vh, 4.2px 50vh, 3.6px 50vh;
    background-position:
      2% 0, 9% 21vh, 30% 14vh, 91% 24vh, 97% 3vh;
  }

  body[data-theme-id="september"] a:hover,
  body[data-theme-id="september"] a:focus-visible {
    animation: none;
  }
}

/* ---------------------------------------------------------------------------
   SEPTEMBER BY DAY — the same rain, at four in the afternoon.

   Base plus counterpart. Everything above is September's canonical lighting
   and is untouched: a body with no data-mode is the diner window at midnight,
   which is what the server sends and what a reader with JS off keeps for good.
   Every selector here carries both attributes, landing at (0,2,1)/(0,2,2) over
   the base's (0,1,1)/(0,1,2), so it wins on specificity rather than on order —
   which matters, because every theme sheet is loaded on every page.

   The month does not become a different month. It is the same diner, the same
   window, the same weather, four hours earlier: a low grey-warm ceiling down
   on the street, everything soaked, and light coming through the pane instead
   of the room throwing light out at it. Ember red is still the anchor.

   ONE INVERSION DOES ALMOST ALL THE WORK, and it is the same physics the base
   block already argued for, applied to a different sky.

     At night the brightest thing in frame is the room, so water lit from
     behind reads as a BRIGHT mark and the rain reads cold, because a warm room
     throws a cold reflection off glass. That was the sheet's one sanctioned
     departure from the warm palette.

     By day the brightest thing in frame is the overcast, so the same water is
     a DARK lens against it, and it takes the sky's colour — which today is a
     grey-warm ceiling, not a cold one. So the day rain is warm-neutral and
     mostly below the ground value. The exception dissolves rather than being
     overridden: the rain is still exactly the colour of whatever is behind it.

   Which is why almost none of the scenery is restated below. The rain, runnel
   and chrome recipes are all built out of --sep-* value tokens, and
   re-declaring those tokens re-lights every layer that reads them.
   .night-sky::before, .night-sky__stars--far and .night-sky__stars--near are
   NOT overridden here at all — they re-light for free, they keep their three
   loops and their geometry, and, critically, the sheet's existing
   prefers-reduced-data block still reaches them, because nothing at (0,2,2)
   is competing with its (0,1,2) declarations for the same properties. Writing
   day copies of those three rules would silently restore the full column count
   on a metered connection.

   The rain STAYS in day mode. --far and --near are weather, not stars; the
   "stars are the night" rule does not apply to a month whose star layers carry
   rain. Fireworks and the city skyline remain July's alone in both modes.
   --------------------------------------------------------------------------- */
body[data-theme-id="september"][data-mode="day"] {
  /* Damp warm grey — wet concrete under an overcast, deliberately a step below
     a dry-day light theme so the page reads as soaked rather than as sunny. */
  --tt-bg: #ded5ca;
  /* Link-hover re-paired to THIS block's ground (standing rule 2026-08-14).
     #ded5ca is light: #FF465A only measures 2.31:1 here, so day takes the
     same-hue dark variant, #BD0014 — 4.56:1. */
  --link-hover: #BC0900;
  --tt-bg-alt: #cabeb0;
  /* Body ink is wet wood: the same warm brown the night theme lights its
     chrome with, taken to full density. 11:1 on the ground. */
  --tt-cyan: #241611;
  --tt-cyan-soft: #4d382c;
  /* The ramp stays warm-only, because warm-only IS September — no cold blues
     were introduced at night and none are introduced here. Every accent is its
     night hue pulled to ink weight, and every one was checked against the
     darkest ground a glyph can land on in day mode (the cloud deck at the top
     of the frame, luminance 0.61 after the deck composites). All clear 4.5:1
     there, so any of them can carry body copy, a border or a gradient stop.
     Separation in this ramp is carried by hue rather than by value — red,
     ember, amber, gold, olive and rose — exactly as it is at night; what is
     forbidden is a ramp with no hue in it at all, which was the August defect,
     not a ramp that is deliberately one temperature. */
  --tt-yellow: #734a04;
  --tt-orange: #7f2b06;
  --tt-chartreuse: #7e4114;
  --tt-green: #5f5216;
  --tt-pink: #922d2c;
  --tt-purple: #6c2b2b;
  --tt-blue: #73401f;
  --tt-teal: #5a2610;
  --tt-gray: #5f5148;
  --tt-gold: #71501a;
  /* Red stays the anchor and stays saturated. It is pitched slightly darker
     than a straight value-flip of #ef4a34 would give, and the margin is
     deliberate: red is the one token that has to survive being read THROUGH
     weather. A dark sheeting film over the reading column drops the local
     ground to about 0.63, and at luminance 0.075 this red still clears 4.8:1
     there. That is the same discipline as the base block's capped rain alpha,
     solved from the other end. */
  --tt-red: #9c1409;
  --tt-breadcrumb-text: #96280f;
  /* Glows do not read on a bright ground. This drops to a tint. */
  --tt-breadcrumb-glow: rgba(156, 20, 9, 0.22);
  /* And so the zodiac chips need their own, DARK, or the halo that traces a
     glyph on hover and focus vanishes and the chips lose their only
     affordance. Ember, so the strip stays on the month's anchor. Still a halo
     on the character — never a border, never a ring, never a box shadow. */
  --zodiac-glow: rgba(150, 40, 15, 0.6);
  /* Cut the other way: on a pale card the lit lip of an engraved stroke is
     white below the glyph, not black. */
  --tt-engrave: 0 1px 0 rgba(242, 230, 210, 0.75);

  /* ---- Type -------------------------------------------------------------
     Copperplate and Palatino are the month's identity, not its lighting, and
     both are as much a 1950s daylight menu board as a 1950s night one. Left
     alone on purpose. */

  /* ---- Sheen kit, daylight ----------------------------------------------
     Chrome does not lose contrast in daylight, it gains it: the specular goes
     to near-white and the shadow rolling off the foot is a warm brown rather
     than the room's black. Same angle, same three recipes, so every polished
     surface in the theme re-lights at once — the counter, the time bar, the
     input surfaces and the sitemap trim all read these. */
  --sep-sheen: linear-gradient(
    180deg,
    rgba(242, 230, 210, 0.5) 0%,
    rgba(242, 230, 210, 0.17) 26%,
    rgba(60, 44, 34, 0) 52%,
    rgba(60, 44, 34, 0.1) 86%,
    rgba(60, 44, 34, 0.17) 100%
  );
  --sep-lip: inset 0 1px 0 rgba(242, 230, 210, 0.72), inset 0 -1px 0 rgba(60, 44, 34, 0.3);
  --sep-bullnose:
    inset 0 1px 0 rgba(242, 230, 210, 0.88),
    inset 0 2px 0 rgba(242, 230, 210, 0.4),
    inset 0 -2px 0 rgba(60, 44, 34, 0.38);

  /* ---- Glass, daylight ---------------------------------------------------
     The four value tokens keep their roles exactly — "lit" is still the
     brightest point on a runnel and "shade" is still its darkest — but the
     BALANCE between them reverses, and that is the whole day/night difference
     in the water.

     At night a runnel is mostly bright with a dark cast under it. By day it is
     mostly dark with one small bright pip on it, because water is a lens and
     the thing it is inverting is now a bright sky rather than a dark one. So
     --sep-glass-body and --sep-glass-far, the water itself, cross the ground
     and go warm-dark; --sep-glass-lit stays near-white but is now a specular
     the size of a pinhead rather than a lamp.

     The construction underneath is untouched: a runnel still runs faint → body
     → head plateau → bruise in both modes. Only which part of that reads loud
     changes, which is exactly what changes on a real window between midnight
     and four in the afternoon.

     --sep-glass-lens went with the beads it was the only consumer of. */
  --sep-glass-lit: rgba(238, 232, 210, 0.85);
  --sep-glass-body: rgba(58, 44, 36, 0.3);
  --sep-glass-far: rgba(72, 58, 48, 0.11);
  --sep-glass-shade: rgba(38, 26, 20, 0.42);

  /* Falling rain, NEAR grade: tail / body / head, all now below the ground
     value. Head is the heaviest stop in both modes; it has simply changed
     which side of the ground it is heavy on. Used by the near plane at the
     shoulders only, exactly as at night. */
  --sep-rain-1: rgba(78, 64, 54, 0.05);
  --sep-rain-2: rgba(64, 50, 40, 0.16);
  --sep-rain-3: rgba(44, 32, 24, 0.4);

  /* Falling rain, FAR / reading-column grade, and the cap inverts with
     everything else. At night the ceiling was on how BRIGHT the head could get
     before it lifted the ground under red type; by day it is on how DARK it can
     get before it drops the ground under red type. Composited over #ded5ca, a
     0.09-alpha head of this colour lands the local ground near 0.63, where
     --tt-red (luminance 0.075) holds 4.8:1. At 0.14 it lands near 0.60 and the
     margin is gone. Do not raise it — darken the shoulders instead, where
     there is no type. As at night, the far veil runs this grade on all sixteen
     of its columns and is the only plane over the centre. */
  --sep-rain-c1: rgba(78, 64, 54, 0.03);
  --sep-rain-c2: rgba(64, 50, 40, 0.06);
  --sep-rain-c3: rgba(44, 32, 24, 0.09);

  /* The bead recipes and the wet-film tokens that used to be restated here went
     with the static water they described; see the base block's rain note. Both
     falling planes and the runnels are built entirely out of --sep-rain-* and
     --sep-glass-* references, so they re-light from the tokens above for free
     and none of the three scenery rules needs a day copy. That is also what
     keeps the prefers-reduced-data block reaching them: nothing at (0,2,2) is
     competing with its (0,1,2) declarations. */

  /* The dim runnel is the sheet's one all-literal recipe, so it is restated
     too, on the base's stop positions exactly. --sep-runnel itself is
     var-built and re-lights for free. The head stays the one bright stop —
     the lens at the leading end catching the sky — and the bruise below it
     stays dark, because a drop pushing down a wet pane displaces what is
     behind it in any light. That dark stop is what stops six bright heads on
     tapering tracks from reading as a meteor shower; by day it is what stops
     them reading as scratches. */
  --sep-runnel-dim: linear-gradient(
    180deg,
    transparent 0 36%,
    rgba(78, 64, 54, 0.05) 52%,
    rgba(64, 50, 40, 0.11) 70%,
    rgba(238, 232, 210, 0.4) 76.5%,
    rgba(238, 232, 210, 0.4) 78.4%,
    rgba(64, 50, 40, 0.09) 79.6%,
    rgba(38, 26, 20, 0.28) 82%,
    transparent 85.5%,
    transparent 100%
  );

  /* The three heading gradients are declared in the base block entirely out of
     var(--tt-*), so they re-resolve from the tokens above at no cost and are
     deliberately not restated. --text / --text-soft / --muted / --border are
     var-based for the same reason. */
  --bg: #ded5ca;
  --border-dim: rgba(156, 20, 9, 0.3);
  --border-teal: rgba(127, 43, 6, 0.55);
  background: #ded5ca;
  color: var(--tt-cyan);
  color-scheme: light;
}

/* The day counterpart of the CRT scanline used to live here, restated in
   warm-brown over wet concrete instead of cream over black. It is gone with the
   night one: the opt-out above carries no data-mode, so a single
   `display: none` covers both lightings, and a day rule setting `background` on
   a hidden element would be dead weight that reads like an active declaration.
   If the scanline is ever wanted back for this month it has to come back in
   both modes at once, from that one rule. */

/* THE COUNTER, under the window. Cream-and-red formica, which is what the
   laminate actually was before a night interior turned it to a dark bar: the
   same checker trim, the same three coarse mutually-prime fleck periods with
   the same soft outer stop on each speck, the same broad mottle underneath,
   the same chrome bullnose. Only the ground under the flecks crosses over, so
   the flecks cross with it — cream specks on brown become brown specks on
   cream, and the ember and gold ones stay their own colour at ink weight.
   Nothing here repeats at a period the eye can count, for the reason the base
   block sets out at length: a counter that quilts into a grid is pegboard. */
body[data-theme-id="september"][data-mode="day"] .breadcrumb-nav {
  background:
    repeating-linear-gradient(90deg, rgba(58, 40, 30, 0.15) 0 9px, transparent 9px 18px)
      left bottom / 100% 4px repeat-x,
    repeating-linear-gradient(90deg, transparent 0 9px, rgba(58, 40, 30, 0.15) 9px 18px)
      left bottom 4px / 100% 4px repeat-x,
    radial-gradient(circle at 34% 44%, rgba(58, 40, 30, 0.14) 0 0.7px, rgba(58, 40, 30, 0.06) 1.4px, transparent 2.2px)
      0 0 / 59px 47px repeat,
    radial-gradient(circle at 68% 61%, rgba(156, 20, 9, 0.16) 0 0.8px, rgba(156, 20, 9, 0.06) 1.5px, transparent 2.4px)
      13px 9px / 83px 67px repeat,
    radial-gradient(circle at 47% 24%, rgba(113, 80, 26, 0.15) 0 0.6px, rgba(113, 80, 26, 0.055) 1.2px, transparent 2px)
      29px 17px / 107px 89px repeat,
    radial-gradient(ellipse 70% 120% at 22% 30%, rgba(242, 230, 210, 0.42), transparent 70%)
      0 0 / 100% 100% no-repeat,
    radial-gradient(ellipse 60% 110% at 78% 74%, rgba(156, 20, 9, 0.06), transparent 68%)
      0 0 / 100% 100% no-repeat,
    var(--sep-sheen) 0 0 / 100% 100% no-repeat,
    linear-gradient(180deg, #f3e6d2 0%, #ebe1d4 44%, #dcd0c0 100%) 0 0 / 100% 100% no-repeat;
  box-shadow:
    var(--sep-bullnose),
    0 2px 10px rgba(58, 40, 30, 0.13);
}

/* The specular travelling along the nosing stays bright — a highlight on
   chrome is brighter than the laminate in any light. The ember behind it comes
   down, because the sign it is picking up is losing to the sky. */
body[data-theme-id="september"][data-mode="day"] .breadcrumb-nav::before {
  background: linear-gradient(
    90deg,
    transparent,
    rgba(242, 230, 210, 0.6),
    rgba(156, 20, 9, 0.12),
    transparent
  );
}

/* THE SCENE at four o'clock. The base block's composition survives intact and
   only its sign flips: the shoulders carry the weather and the reading column
   stays the cleanest part of the frame. At night that meant the centre was the
   DARKEST part so red type kept its contrast against a lit surround; by day it
   means the centre is the LIGHTEST part, for the identical reason.

   The ember is still there and still low and left, because the sign is still
   on — it is the same diner — but daylight nearly cancels it, so it reads as
   a warm stain on wet brick rather than as a light source. What replaces it as
   the strongest gradient is the ceiling: a low grey-warm deck pulled down over
   the top of the frame, which is the single thing that says four in the
   afternoon rather than noon.

   Every ellipse is explicitly sized, as above; a radial-gradient left at
   farthest-corner overshoots a viewport-shaped box and paints soft rectangles
   into the corners. The deck alpha is held at 0.10 for a measured reason: it
   lands the top-centre ground at luminance 0.61, which is the darkest place a
   glyph sits in this mode and where every accent token above was checked. */
body[data-theme-id="september"][data-mode="day"] .night-sky {
  background:
    /* The sign, low and left, losing to the sky. */
    radial-gradient(ellipse 58% 30% at 15% 100%, rgba(156, 20, 9, 0.11), transparent 68%),
    /* Warm spill off the wet road, low and right. */
    radial-gradient(ellipse 46% 24% at 87% 103%, rgba(127, 43, 6, 0.09), transparent 66%),
    /* Rain-dark shoulders. These bank the weather off the reading column, and
       they sit hard against the outer edges where no type ever lands. */
    radial-gradient(ellipse 34% 78% at 0% 46%, rgba(96, 84, 72, 0.18), transparent 72%),
    radial-gradient(ellipse 32% 74% at 100% 52%, rgba(96, 84, 72, 0.16), transparent 72%),
    /* The ceiling, down on the street. */
    radial-gradient(ellipse 130% 34% at 50% 0%, rgba(112, 100, 88, 0.1), transparent 76%),
    linear-gradient(180deg, #dcd3c8 0%, #ded5ca 34%, #e2d9cf 62%, #d8cdc0 100%);
}

/* THE WET ROAD, and the last inversion. At night wet asphalt is the darkest
   thing in the frame with the sign's reflection smeared bright across it. By
   day it is the BRIGHTEST thing in the frame, because standing water is a
   mirror and the thing it is mirroring is the overcast — which is why a wet
   street photographs as a sheet of light with dark asphalt showing through in
   patches, and a dry one does not.

   That is also what keeps the footer readable. This plane is pinned to the
   foot of the fixed viewport and the footer scrolls across it, so a dark road
   would have put dark ink on dark ground at the end of every page; the
   daylight reading is both the honest one and the one that leaves the muted
   footer text above 5:1. Still no skyline: the city silhouette is July's
   Fourth-of-July scenery and is never borrowed, in either mode. */
body[data-theme-id="september"][data-mode="day"] .night-sky__aurora {
  background:
    radial-gradient(ellipse 26% 76% at 16% 100%, rgba(156, 20, 9, 0.1), transparent 72%),
    radial-gradient(ellipse 19% 62% at 47% 100%, rgba(122, 110, 98, 0.22), transparent 70%),
    radial-gradient(ellipse 31% 84% at 83% 100%, rgba(122, 110, 98, 0.18), transparent 74%),
    linear-gradient(180deg, rgba(241, 230, 210, 0) 0%, rgba(241, 230, 210, 0.46) 42%, rgba(241, 230, 210, 0.7) 100%);
}

/* The wordmark loses its neon for the same reason: three stacked ember blurs
   on wet concrete read as a printing fault. It becomes painted glass instead —
   the sign as it looks with the tubes cold — lifted off the ground by the same
   one-pixel white engraving every other light surface uses. */
body[data-theme-id="september"][data-mode="day"] .brand a {
  color: var(--tt-red);
  text-shadow: 0 1px 0 rgba(242, 230, 210, 0.7);
}

body[data-theme-id="september"][data-mode="day"] .brand a:hover {
  color: var(--tt-red);
  text-shadow: 0 1px 0 rgba(242, 230, 210, 0.85), 0 0 14px rgba(156, 20, 9, 0.2);
}

/* HEADINGS. The menu board keeps its Copperplate, its centring, its tracking
   and its sizes — those are the board, not the hour. What changes is the glow.
   A bloom is an emission and daylight cancels it, so H1's four-stop tube
   becomes a soft warm cast that gives the letters weight on a bright ground.
   It stays a BLURRED shadow: these glyphs are painted with background-clip:
   text, so a hard-edged shadow renders through the transparent letterform and
   buries the clipped gradient. That constraint holds in both modes. */
body[data-theme-id="september"][data-mode="day"] main h1,
body[data-theme-id="september"][data-mode="day"] .page-title,
body[data-theme-id="september"][data-mode="day"] .heading-section--level-1 > .heading-section__summary > .heading-section__trigger {
  text-shadow:
    0 1px 2px rgba(60, 34, 22, 0.26),
    0 0 20px rgba(156, 20, 9, 0.12);
}

body[data-theme-id="september"][data-mode="day"] main h2,
body[data-theme-id="september"][data-mode="day"] main h3,
body[data-theme-id="september"][data-mode="day"] main h4,
body[data-theme-id="september"][data-mode="day"] main h5,
body[data-theme-id="september"][data-mode="day"] main h6 {
  text-shadow: 0 1px 2px rgba(60, 34, 22, 0.2);
}

body[data-theme-id="september"][data-mode="day"] .markdown-page .heading-section--level-2 > .heading-section__summary > .heading-section__trigger,
body[data-theme-id="september"][data-mode="day"] .markdown-page .heading-section--level-3 > .heading-section__summary > .heading-section__trigger {
  text-shadow: 0 1px 2px rgba(60, 34, 22, 0.2);
}

/* The section rails stop being wet neon tubing and become painted rules. */
body[data-theme-id="september"][data-mode="day"] .heading-section::before {
  box-shadow: none;
}

/* LINKS. The ember pulse is switched off rather than re-lit, and that is a
   deliberate reduction, not an omission: a neon tube breathing is a night
   affordance, and by day the sign is cold. `animation: none` here also keeps
   the theme honest under prefers-reduced-motion — the base's cancellation of
   that keyframe is written without !important at (0,1,2), so a day rule at
   (0,2,2) that re-declared an animation would have quietly outranked it and
   run a loop for a reader who asked for none.

   :not(.celestial-chip) is load-bearing and is the reason this reads oddly.
   The zodiac chips are anchors now, and a selector at (0,2,2) outranks the
   .celestial-chip.celestial-chip carve-out in main.css at (0,2,0) — text-shadow
   inherits, so an unguarded `a:hover` here would bloom behind the WEST/CELTIC
   labels and the moon's phase text, and the colour change would fight the
   chip's own. Excluding the class keeps the strip out of reach by construction
   rather than by another pin. */
body[data-theme-id="september"][data-mode="day"] a:hover:not(.celestial-chip),
body[data-theme-id="september"][data-mode="day"] a:focus-visible:not(.celestial-chip) {
  color: var(--tt-red);
  text-shadow: 0 1px 0 rgba(242, 230, 210, 0.75);
  animation: none;
}

/* A read link at night is ringed in near-black so its colour survives the dark
   ground; on wet concrete that ring is a dark fringe around every visited
   word, so it becomes the same white engraving as the rest of the light
   surfaces. */
body[data-theme-id="september"][data-mode="day"] a:visited:not(.celestial-chip) {
  text-shadow: 0 1px 0 rgba(242, 230, 210, 0.6);
}

/* The lit strip over the counter keeps its tracking and loses its tube. */
body[data-theme-id="september"][data-mode="day"] .eyebrow {
  text-shadow: 0 1px 0 rgba(242, 230, 210, 0.6);
}

/* SURFACES. Every one of these already reads --sep-sheen, --sep-lip or
   --sep-bullnose, so the chrome re-lit itself the moment those tokens did.
   What is left is the tint underneath: a rained-on pane by day is bright glass
   with the gloss still pooling dark at its foot. */
body[data-theme-id="september"][data-mode="day"] input,
body[data-theme-id="september"][data-mode="day"] textarea,
body[data-theme-id="september"][data-mode="day"] select,
body[data-theme-id="september"][data-mode="day"] code,
body[data-theme-id="september"][data-mode="day"] pre {
  background-color: rgba(242, 230, 210, 0.62);
  color: var(--tt-cyan);
}

/* The board is the same anodised steel and still takes its fill from the red
   token, so the bar can never drift off the anchor colour. Two things change,
   and the second is the reason the first is not enough on its own.

   The ink crosses over: the day red is a dark ink and no longer carries
   near-black engraved caps.

   And the gloss comes right down. The night overlay runs a 0.24 white top stop
   over a bright red, which spans the bar from luminance 0.42 to 0.05 — a wide,
   convincing roll of light, and dark caps clear 8:1 across all of it. Laid
   over the day red the same overlay spans 0.30 to 0.05, and there is no ink
   that works: pale caps fail at 2.7:1 on the lit top, dark caps fail at 1.8:1
   in the shadow at the foot. Narrowing the roll to 0.07 white and 0.20 black
   holds the whole bar between 0.14 and 0.06, where the pale caps clear 5:1 at
   the top and 8.6:1 at the bottom. It reads as a lower sheen, which is what a
   dark steel bar in a bright room actually has. */
body[data-theme-id="september"][data-mode="day"] th {
  background-image: linear-gradient(
    180deg,
    rgba(242, 230, 210, 0.07) 0%,
    rgba(242, 230, 210, 0.02) 46%,
    rgba(10, 6, 5, 0.06) 54%,
    rgba(10, 6, 5, 0.2) 100%
  );
  color: #fae2d9;
}

body[data-theme-id="september"][data-mode="day"] .sitemap-link:hover,
body[data-theme-id="september"][data-mode="day"] .calendar-app__nav:hover,
body[data-theme-id="september"][data-mode="day"] .calendar-app__today:hover,
body[data-theme-id="september"][data-mode="day"] .sitemap-link:focus-visible,
body[data-theme-id="september"][data-mode="day"] .calendar-app__nav:focus-visible,
body[data-theme-id="september"][data-mode="day"] .calendar-app__today:focus-visible {
  box-shadow:
    inset 0 1px 0 rgba(242, 230, 210, 0.85),
    inset 0 -1px 0 rgba(60, 44, 34, 0.34),
    0 2px 10px rgba(60, 44, 34, 0.14);
}

/* Cards keep their rainbow frame. The lit top edge stays lit and the ambient
   ember bloom becomes the small drop shadow a card actually casts in a room
   with the lights on. */
body[data-theme-id="september"][data-mode="day"] .hero-card,
body[data-theme-id="september"][data-mode="day"] .folder-section {
  box-shadow:
    inset 0 1px 0 rgba(242, 230, 210, 0.7),
    0 2px 12px rgba(60, 44, 34, 0.1);
}

body[data-theme-id="september"][data-mode="day"] .hero-card:hover,
body[data-theme-id="september"][data-mode="day"] .folder-section:hover {
  box-shadow:
    inset 0 1px 0 rgba(242, 230, 210, 0.9),
    0 4px 18px rgba(60, 44, 34, 0.16);
}

/* Still no left rule on quotes — left borders are reserved for list anchors.
   The inset wash only changes sign, from a gold glow to a warm shade. */
body[data-theme-id="september"][data-mode="day"] blockquote {
  color: var(--tt-cyan-soft);
  box-shadow: inset 1rem 0 1.4rem -1.2rem rgba(96, 68, 30, 0.45);
}

/* The brushed rail, lit down the other side of the room. */
body[data-theme-id="september"][data-mode="day"]::-webkit-scrollbar-thumb,
body[data-theme-id="september"][data-mode="day"] ::-webkit-scrollbar-thumb {
  background-image: linear-gradient(
    90deg,
    rgba(242, 230, 210, 0.7) 0%,
    rgba(242, 230, 210, 0.1) 42%,
    rgba(60, 44, 34, 0.28) 100%
  );
}

/* The tooltip is a --bg-filled card lifting off the page. The 0.45 black that
   reads as depth over #140c08 reads as soot over wet concrete, so it comes
   down to the weight a light card actually casts. */
body[data-theme-id="september"][data-mode="day"] .celestial-tooltip {
  box-shadow: 0 4px 18px rgba(60, 44, 34, 0.22);
}

/* Ambient loops 1 AND 2 of 3 — one per falling plane.

   These were a single shared keyframe, on the reasoning that rain in a given
   frame falls at one angle and the two planes must therefore agree on it. That
   is true of two drops beside each other and false of two drops a hundred feet
   apart: wind shear over that distance is real, and it is a good part of why a
   photographed downpour looks unruled where a CSS one looks drafted. So the
   near plane keeps 8 degrees, the far veil leans 9.5, and each owns the value
   it uses. See the far-plane note for why the bleed still covers the steeper
   sweep.

   Each layer travels exactly one 24rem background period — doubled from 12rem,
   with both durations doubled alongside so neither plane changed speed. The
   point is the wrap: at 12rem, a column on a 4rem tile put the same three drops
   down three times per loop and the loop itself came round twice a second. Every
   tile height still divides the travel, so every column restarts with no seam.

   The rotation lives here rather than on the element because `animation` sets
   `transform` outright and would cancel a static rotate; keeping it inside the
   keyframes also means the translate runs along the element's own tilted y-axis,
   which is what makes a slanted field loop as cleanly as a vertical one.
   Transform only: no filter, no background-position animation, nothing that
   repaints. */
@keyframes septemberRainFall {
  from { transform: rotate(8deg) translate3d(0, 0, 0); }
  to { transform: rotate(8deg) translate3d(0, 24rem, 0); }
}

@keyframes septemberRainFallFar {
  from { transform: rotate(9.5deg) translate3d(0, 0, 0); }
  to { transform: rotate(9.5deg) translate3d(0, 24rem, 0); }
}

/* Ambient loop 3 of 3. One 50vh background period, eased so the pane hangs,
   sheds and hangs again. Velocity is zero at both ends of the iteration, so the
   seam is invisible in rhythm as well as in position. Vertical, unlike the two
   falling planes: glass does not tilt. */
@keyframes septemberRunnelSlide {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(0, 50vh, 0); }
}

/* Hover-only, one element at a time, text-shadow alone — the same pulse the
   Obsidian september theme runs, so a link breathes identically on both
   surfaces. Replaces July's hotpink keyframe rather than adding to it. */
@keyframes septemberLinkEmberGlow {
  from {
    text-shadow:
      0 0 6px rgba(239, 74, 52, 0.72),
      0 0 12px rgba(210, 87, 31, 0.5),
      0 0 22px rgba(239, 74, 52, 0.26);
  }
  to {
    text-shadow:
      0 0 9px rgba(239, 74, 52, 0.96),
      0 0 20px rgba(210, 87, 31, 0.8),
      0 0 32px rgba(239, 74, 52, 0.44);
  }
}
