/* ============================================================================
   NIGHT
   ----------------------------------------------------------------------------
   His night is a REPAINT, not a dimming. The thing that makes it read is what
   does NOT change: the guide signs stay full green, the banner full yellow,
   the shield, the warning triangles, the copy and the lane markings all stay
   exactly as bright as they are at noon. What goes dark is the world around
   them - the sky to almost black, the ocean to deep navy, the tarmac to
   nearly nothing - so the signage is the only lit thing left.

   That is why there is no filter over the page. A filter cannot tell a lane
   marking from the tarmac it is painted on; it takes both down together and
   the road stops reading. The two have to move in opposite directions, so
   they are two variables and his road tiles are inline to receive them.

   ONE TRIGGER, THREE STATES. An explicit theme choice stamps data-theme on the
   root, and the default "system" setting stamps nothing at all - so the media
   query carries the unstamped case and the stamps win in both directions.

   WHAT DRIVES IT is the one thing still open. It follows the reader's theme
   for now because that is the only switch there is; a toggle, the hour, or
   scroll depth all set the same variables and nothing downstream changes.
   ========================================================================= */

:root{
  /* how lit the vehicle beams are: zero through the day, not faint - a beam at
     noon reads as a mistake - and full at night */
  --night: 0;

  /* his road, the one place a filter could never go */
  --tarmac:  #575757;
  --marking: #fff;
  /* AND HIS SHOULDER LINES, WHICH ARE NOW THEIR OWN COLOUR. The drive already
     reads this way - a solid gold line down each shoulder, a broken white one
     down the middle - and the top-down sections did not: every marking in them
     was one white. tools/gold_edges.js tells the two apart by length and gives
     the edges this variable, so the two roads are the same road and each kind
     of line can be taken down after dark on its own terms. Same gold as the
     drive, to the digit. */
  --edge: #ffda00;

  /* how far the scenery ART is taken down. His painted layers - waves, rocks,
     trees, the canopy, the clouds - carry thousands of baked fills between
     them, so they are darkened as layers rather than stop by stop. They are
     static, so this is composited once and then left alone; it is the moving
     traffic a filter must never be put over. */
  --scene: 1;
  --scene-sat: 1;
  --cloud-filter: none;

  /* his signs, and his cards, at full daylight */
  --card-bg: #fff;
  --card-line: #1a1a1a;
  --card-ink: #1a1a1a;
  --card-sub: #333;
}

/* >>> palette */
  /* GENERATED by tools/make_night.js from his own day colours. Each stop
     pulled toward black and given a night sky's blue cast. His day
     gradients stay in their own section files - they are the fallback in
     var(--secN-bg, ...) - so nothing here is kept in step by hand. */
  @media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]):not([data-mode="day"]){
    --night: 1;
    --tarmac: #111623;
    /* MUTED, NOT WHITE. Fresh paint at midnight is what a headlamp sees, not
       what the sky does: away from the beams his lines go the colour of the
       night they are lying in, a blue-grey rather than a glare. */
    --marking: #8ea3c4;
    --edge: #8a6a26;
    --truss-night: url(#truss-night);
    --boat-night: brightness(.68) saturate(.85);
    --cta-plate: #530000;
    --cta-glow: drop-shadow(0 0 0.35cqw rgba(255,60,60,.95)) drop-shadow(0 0 1.4cqw rgba(230,20,30,.65));
    --sign-green: #0a3d1f;
    --sign-gold: #e7aa28;
    --scene: 0.50;
    --scene-sat: 0.95;
    --cloud-filter: url(#cloud-night);
    --scene-tree: brightness(.30) saturate(.95) hue-rotate(70deg);
    --sec2-ink: #dfe7f2;
    --sec6-ink: #eef2f7;
    --card-bg: transparent;
    --card-hover-bg: #05070c;
    --card-line: #7d8ea3;
    --card-ink: #f2f6fa;
    --card-sub: #f2f6fa;
    --sea-surf-hi: #0c2843;
    --sea-surf-lo: #07223f;
    --sea-mid: #011f51;
    --sea-swell: #022152;
    --sea-far-a: #000619;
    --sea-far-b: #001136;
    --sea-foam: #8ea0bd;
    --sea-foam-a: #6c7b99;
    --sea-foam-b: #8ea0bd;
    --sea-far-shade: #233e77;
    --sea-far-foam: 0;
    --sign-red: #b5000d;
    --sign-gold-2: #dda517;
    --sign-gold-line: #fcee21;
    --cta-line: red;
    --cta-tri: #b5000d;
    --sec1-bg:
      linear-gradient(180deg, rgba(0,5,18,1) 0%, rgba(0,5,18,1) 6.460%, rgba(0,6,18,.98) 28.736%, rgba(0,6,18,.9) 45.443%, rgba(0,7,19,.78) 59.366%, rgba(0,8,20,.6) 72.360%, rgba(0,9,22,.37) 84.426%, rgba(0,10,24,.1) 95.564%, rgba(0,11,25,0) 99.277%), linear-gradient(90deg, #000915 0%, #000b19 100%);
    --sec1-fade:
      linear-gradient(90deg,#000c1b 0%,#010e1f 100%);
    --sec2-bg:
      linear-gradient(180deg, #0f172c 0.03%, #0f172c 12.41%, #252633 12.54%, #322f36 12.67%, #322f36 12.80%, #232431 12.93%, #0e162a 13.07%, #0e162a 13.59%, #0f1931 13.85%, #0f1931 17.37%, #0e1e34 17.63%, #0e1e34 26.76%, #152135 26.89%, #322f36 27.02%, #322f36 27.54%, #161f2e 27.67%, #0e1a2c 27.80%, #0e1a2c 28.19%, #0e2033 28.32%, #0f2135 28.45%, #0f2135 33.80%, #1a2332 34.06%, #1a2332 42.66%, #262935 42.79%, #302d36 42.92%, #302d36 45.40%), linear-gradient(90deg,#0e162a 0%,#0f182e 100%);
    --sec3-bg:
      linear-gradient(180deg, transparent 0%,  transparent 18%, #1e213c 21%,     #1e1f37 45.78%,  #1e1f36 47.72%, #1c1c34 47.86%,  #1b1b33 48.00%,  #1a1b36 48.13%,  #191a36 48.83%, #1c1c38 50.76%,  #181a35 50.90%,  #171934 51.87%,  #1c1c36 52.01%, #1e1f36 61.70%,  #1b1b33 61.97%,  #1b1b33 69.72%,  #161833 69.86%, #161833 72.21%,  #191a36 72.35%,  #1b1c37 78.58%,  #171834 78.72%, #161834 80.66%,  #1c1c37 80.80%,  #1c1d38 96.43%,  #1d1d39 96.57%, #1a1b36 96.71%,  #1a1b36 97.96%,  #1b1b33 98.09%,  #1b1b33 100%);
    --sec4-ground:
      linear-gradient(180deg, #021b22 0%, #021b22 1.59%, #052023 93.90%, #052023 100%);
    --sec6-bg:
      linear-gradient(180deg, transparent 0, transparent 3.67%, #0a0e1f 3.85%, #0a0e1f 100%);
  }}
  :root[data-theme="dark"]:not([data-mode="day"]),
  :root[data-mode="night"]{
    --night: 1;
    --tarmac: #111623;
    /* MUTED, NOT WHITE. Fresh paint at midnight is what a headlamp sees, not
       what the sky does: away from the beams his lines go the colour of the
       night they are lying in, a blue-grey rather than a glare. */
    --marking: #8ea3c4;
    --edge: #8a6a26;
    --truss-night: url(#truss-night);
    --boat-night: brightness(.68) saturate(.85);
    --cta-plate: #530000;
    --cta-glow: drop-shadow(0 0 0.35cqw rgba(255,60,60,.95)) drop-shadow(0 0 1.4cqw rgba(230,20,30,.65));
    --sign-green: #0a3d1f;
    --sign-gold: #e7aa28;
    --scene: 0.50;
    --scene-sat: 0.95;
    --cloud-filter: url(#cloud-night);
    --scene-tree: brightness(.30) saturate(.95) hue-rotate(70deg);
    --sec2-ink: #dfe7f2;
    --sec6-ink: #eef2f7;
    --card-bg: transparent;
    --card-hover-bg: #05070c;
    --card-line: #7d8ea3;
    --card-ink: #f2f6fa;
    --card-sub: #f2f6fa;
    --sea-surf-hi: #0c2843;
    --sea-surf-lo: #07223f;
    --sea-mid: #011f51;
    --sea-swell: #022152;
    --sea-far-a: #000619;
    --sea-far-b: #001136;
    --sea-foam: #8ea0bd;
    --sea-foam-a: #6c7b99;
    --sea-foam-b: #8ea0bd;
    --sea-far-shade: #233e77;
    --sea-far-foam: 0;
    --sign-red: #b5000d;
    --sign-gold-2: #dda517;
    --sign-gold-line: #fcee21;
    --cta-line: red;
    --cta-tri: #b5000d;
    --sec1-bg:
      linear-gradient(180deg, rgba(0,5,18,1) 0%, rgba(0,5,18,1) 6.460%, rgba(0,6,18,.98) 28.736%, rgba(0,6,18,.9) 45.443%, rgba(0,7,19,.78) 59.366%, rgba(0,8,20,.6) 72.360%, rgba(0,9,22,.37) 84.426%, rgba(0,10,24,.1) 95.564%, rgba(0,11,25,0) 99.277%), linear-gradient(90deg, #000915 0%, #000b19 100%);
    --sec1-fade:
      linear-gradient(90deg,#000c1b 0%,#010e1f 100%);
    --sec2-bg:
      linear-gradient(180deg, #0f172c 0.03%, #0f172c 12.41%, #252633 12.54%, #322f36 12.67%, #322f36 12.80%, #232431 12.93%, #0e162a 13.07%, #0e162a 13.59%, #0f1931 13.85%, #0f1931 17.37%, #0e1e34 17.63%, #0e1e34 26.76%, #152135 26.89%, #322f36 27.02%, #322f36 27.54%, #161f2e 27.67%, #0e1a2c 27.80%, #0e1a2c 28.19%, #0e2033 28.32%, #0f2135 28.45%, #0f2135 33.80%, #1a2332 34.06%, #1a2332 42.66%, #262935 42.79%, #302d36 42.92%, #302d36 45.40%), linear-gradient(90deg,#0e162a 0%,#0f182e 100%);
    --sec3-bg:
      linear-gradient(180deg, transparent 0%,  transparent 18%, #1e213c 21%,     #1e1f37 45.78%,  #1e1f36 47.72%, #1c1c34 47.86%,  #1b1b33 48.00%,  #1a1b36 48.13%,  #191a36 48.83%, #1c1c38 50.76%,  #181a35 50.90%,  #171934 51.87%,  #1c1c36 52.01%, #1e1f36 61.70%,  #1b1b33 61.97%,  #1b1b33 69.72%,  #161833 69.86%, #161833 72.21%,  #191a36 72.35%,  #1b1c37 78.58%,  #171834 78.72%, #161834 80.66%,  #1c1c37 80.80%,  #1c1d38 96.43%,  #1d1d39 96.57%, #1a1b36 96.71%,  #1a1b36 97.96%,  #1b1b33 98.09%,  #1b1b33 100%);
    --sec4-ground:
      linear-gradient(180deg, #021b22 0%, #021b22 1.59%, #052023 93.90%, #052023 100%);
    --sec6-bg:
      linear-gradient(180deg, transparent 0, transparent 3.67%, #0a0e1f 3.85%, #0a0e1f 100%);
  }
  /* <<< palette */

/* --- THE CARD PAGE AT NIGHT, REWRITTEN OVER THE GENERATED ONE --------------
   Sampled off his night artboard this section came back one flat near-black,
   which was fine while a snow range carried the eye off the bottom of it. The
   drive is what carries it now, and the drive opens on a night sky - so this
   page has to arrive there rather than cut to it. Dark blue at the top of the
   cards going to the same #05080f the drive's sky washes in from at the
   bottom, which puts the two on one colour at the seam and gives the section's
   own lower half something for the starfield to sit against.

   AT NIGHT THE JOIN IS EASIER, because his night sky is a straight 180deg ramp
   - so its top row IS one flat colour, #02060f, and this page only has to
   arrive at that. No mirrored ramp is needed; the two sky layers are turned
   off and the page's own gradient ends on the drive's first row.

   The first 3.85% stays transparent for the reason it always did: section four
   paints through there, so the two overlap and no hairline can open. */
:root[data-theme="dark"]:not([data-mode="day"]),
:root[data-mode="night"]{
  --sec6-bg:
    linear-gradient(180deg, transparent 0, transparent 3.67%,
      #101b33 3.67%, #0b1226 44%, #0b1226 calc(59.28% + 100px), #02060f 100%);
  --sec6-sky-glow: none; --sec6-sky: none;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]):not([data-mode="day"]){
    --sec6-bg:
      linear-gradient(180deg, transparent 0, transparent 3.67%,
        #101b33 3.67%, #0b1226 44%, #0b1226 calc(59.28% + 100px), #02060f 100%);
    --sec6-sky-glow: none; --sec6-sky: none;
  }}

/* --- HIS CLOSE AND HIS FOOTER AFTER DARK ----------------------------------
   His first site had no night, so this is the only part of these two sections
   that is not his: the same layout with the ground taken down. His interstate
   blue band deepens, his form card turns to the dark blue the cards page uses
   and his footer goes the rest of the way to black. What does NOT change is
   what makes his night read everywhere else on this page - the yellow button,
   the yellow column heads, the guide sign's green and the white shield stay
   exactly as bright as they are at noon.

   The join needs nothing here: the top of the band is transparent in both
   modes, so whatever the road leaves behind shows through it. */
:root[data-theme="dark"]:not([data-mode="day"]),
:root[data-mode="night"]{
  --sec8-band:linear-gradient(180deg, rgba(7,20,38,0) 0, rgba(7,20,38,0) calc(var(--sec8-fade,180px) - 150px), #071426 var(--sec8-fade,180px), #071426 100%);
  --sec8-paper:#0d1a2f; --sec8-ink:#eef3fb; --sec8-label:#9fb2cf;
  --sec8-field:#1c2b46; --sec8-rule:#3c4d6e; --sec8-ring:rgba(24,98,180,.35);
  --sec8-link:#63a6ff; --sec8-edge:rgba(255,255,255,.09);
  --sec8-ok:#5fd08a; --sec8-err:#ff8086;
  --sec9-bg:#050c1a; --sec9-sign:#0c5f26;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]):not([data-mode="day"]){
    --sec8-band:linear-gradient(180deg, rgba(7,20,38,0) 0, rgba(7,20,38,0) calc(var(--sec8-fade,180px) - 150px), #071426 var(--sec8-fade,180px), #071426 100%);
    --sec8-paper:#0d1a2f; --sec8-ink:#eef3fb; --sec8-label:#9fb2cf;
    --sec8-field:#1c2b46; --sec8-rule:#3c4d6e; --sec8-ring:rgba(24,98,180,.35);
    --sec8-link:#63a6ff; --sec8-edge:rgba(255,255,255,.09);
  --sec8-ok:#5fd08a; --sec8-err:#ff8086;
    --sec9-bg:#050c1a; --sec9-sign:#0c5f26;
  }}

/* --- FIRST LIGHT ----------------------------------------------------------
   The page opens black and comes up into daylight, and it does it in CSS
   rather than in script so it happens whether or not anything else has
   loaded: one fixed sheet of black over everything, held for a fifth of a
   half-second so the arrival registers, then a second and a half of ease out.

   IT IS A VEIL, NOT A PALETTE CHANGE, and it has to be. The night palette
   lives in custom properties inside `background`, and a gradient behind a
   changed variable does not transition - it snaps. So the swap from night to
   day is made UNDER the black, at four tenths of a second, while the sheet is
   still three quarters opaque. What the eye sees is a room being lit; what
   actually happened is a cut, hidden.

   forwards, so it stays clear afterwards; pointer-events off, so it is never
   in the way even for the second and a half it is visible. */
.dawn{
  position:fixed; inset:0; z-index:9998;
  background:#000; pointer-events:none;
  animation:h19-dawn 1.9s ease-out forwards;
}
@keyframes h19-dawn{ 0%,26%{ opacity:1 } 100%{ opacity:0 } }
@media (prefers-reduced-motion:reduce){
  .dawn{ animation:none; opacity:0 }
}

/* DAYLIGHT IS THE DEFAULT ABOVE. An explicit light choice has to beat a dark
   system setting, so it restates the day values rather than relying on order. */
:root[data-theme="light"]{
  --night: 0;
  --tarmac: #575757;
  --marking: #fff;
  --edge: #ffda00;
  --scene: 1; --scene-sat: 1; --cloud-filter: none;
  --sec2-ink: #333; --sec6-ink: #1a1a1a;
  --card-bg: #fff; --card-line: #1a1a1a; --card-ink: #1a1a1a; --card-sub: #333;
  --sec1-bg: initial; --sec1-fade: initial; --sec2-bg: initial;
  --sec2-sand: initial; --sec3-bg: initial; --sec4-ground: initial;
  --sec6-bg: initial;
  --sec8-band: initial;
  --sec8-paper: initial; --sec8-ink: initial; --sec8-label: initial;
  --sec8-field: initial; --sec8-rule: initial; --sec8-ring: initial;
  --sec8-link: initial; --sec9-bg: initial; --sec9-sign: initial;
}

/* THE SCENERY, AND ONLY THE SCENERY. Named layer by layer rather than by
   section, so his signs, his copy, his buttons, the cars and the boats are
   never in it - they are what the night is for. */
/* HIS GANTRY STAYS LIT. It is the one built thing in the scene and in his own
   night it reads pale against the black - a lit steel truss, not a dark one -
   so it is deliberately NOT in this list. */
section .z-back,
section .z-ground,
section .rock-layer,
section .rock-cross{
  filter: brightness(var(--scene)) saturate(var(--scene-sat));
  transition: filter 1s linear;
}

/* HIS SURF IS NOT IN IT EITHER, AND FOR THE OPPOSITE REASON TO THE GANTRY.
   He sent waves_Night.svg - the same eleven shapes, recoloured by hand - so
   the ocean has his own night values on his own gradient stops, written in
   section-02.css. A brightness on top of those would be a second opinion
   over his. The wrapper carries .z-ground and each band carries .wave, so
   both are taken out of the filter here rather than left off the list, and
   in daylight this rule changes nothing: there is no filter to remove. */
.sec2 .waves,
.sec2 .waves .wave{ filter:none }

/* AND HIS BEACH IS OUT OF IT TOO. Same reason again: --sec2-sand is now his
   own night violet rather than his day tan taken down, so there is nothing
   left for a brightness to do to it but make it wrong. */
.sec2 .sand{ filter:none }

/* HIS DESERT IS OUT OF THE FILTER ALTOGETHER NOW. It had a hue chain, and a
   hue chain still could not do it: in his day art the sand is the bright
   thing and the rocks are dark, and in his night artboard it is the other
   way round - his dunes go to a deep navy and his rocks stay a warm brown,
   catching the moon. Nothing that maps one lightness onto another can swap
   two families over. Each of his paints has its own switch instead, written
   into section-03.css by tools/make_desert_night.js, and this takes the
   blanket off so those colours are what you see.

   It is also what closed the join with the beach: the chain lifted the whole
   desert to #26294b while section two's sand sat at #1a1829, and a step like
   that between two sections reads as a seam. */
.sec3 .z-ground{ filter:none }

/* HIS FOREST CANOPY, AND WHY IT NEEDED NO FILE. It is the one raster on the
   page, so there is no fill to recolour - but his night canopy is already in
   his artboard four, and reading it there gives the target directly: his night
   trees are #042422, a dark TEAL, where mine were #1f3811, a green with no
   blue in it at all. Sweeping the hue against his own number found 70 degrees,
   which lands 8 of 441 away. Rotating the other way - which is what I tried
   first - takes green toward yellow and made it worse. */
.sec4 .z-back{
  filter: var(--scene-tree, brightness(var(--scene)) saturate(var(--scene-sat)));
}

/* HIS CLOUDS GO DEEP BLUE, not grey. Sampled off his painting they are
   #001a43 at full saturation, and no amount of brightness reaches a hue - see
   the chain in tools/make_night.js. */
section .z-cloud{
  filter: var(--cloud-filter, none);
  transition: filter 1s linear;
}

@media (prefers-reduced-motion: reduce){
  section .z-back, section .z-ground, section .wave, section .sand,
  section .rock-layer, section .rock-cross, section .z-cloud{ transition: none }
}


/* HIS SIGNS, MUTED RATHER THAN DIMMED. Only the sign ART is named - the svg he
   drew the gantry sign in, and the small sign images - never the copy beside
   them, which is HTML and would go grey with it. */
/* NOTHING IS FILTERED ANY MORE. Every sign on the page is inline and takes
   his own colours a fill at a time; the brightness that used to stand in for
   this is what was dimming his white type. */
@media (prefers-reduced-motion: reduce){
  section img.z-copy{ transition: none }
}

/* --- THE TEMPORARY SWITCH ------------------------------------------------
   His sun and his moon, top right, so the two modes can be put side by side.
   It writes data-mode on the root, which is the third way into the palette
   above - alongside the system setting and an explicit theme - and remembers
   the choice. Temporary by agreement: when he decides what really drives
   night, this comes out and nothing else changes. */
.mode-switch{
  position:fixed; top:14px; right:14px; z-index:10000;
  width:52px; height:52px; padding:0; border:0; border-radius:50%;
  background:rgba(0,0,0,.30); backdrop-filter:blur(2px);
  cursor:pointer; display:grid; place-items:center;
  box-shadow:0 2px 10px rgba(0,0,0,.35);
  transition:background .25s ease, transform .25s ease;
}
.mode-switch:hover{ transform:scale(1.06) }
.mode-switch:focus-visible{ outline:3px solid #fcee21; outline-offset:3px }
.mode-switch img,.mode-switch svg{ width:38px; height:38px; display:block }
/* THE ICON IS THE HOUR YOU ARE IN, NOT THE ONE YOU WOULD GO TO. It used to
   show the destination - a moon in daylight, meaning "press for night" - which
   is how a button label works and not how a sky works. His own drawing has the
   sun on the blue bar and the moon on the black one, so the switch now reads
   as the time of day and the press is what changes it. The class names say
   which HOUR each belongs to, so nothing here has to be read twice. */
.mode-switch .is-day{ display:block }
.mode-switch .is-night{ display:none }
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]):not([data-mode="day"]) .mode-switch .is-day{ display:none }
  :root:not([data-theme="light"]):not([data-mode="day"]) .mode-switch .is-night{ display:block }
}
:root[data-theme="dark"]:not([data-mode="day"]) .mode-switch .is-day,
:root[data-mode="night"] .mode-switch .is-day{ display:none }
:root[data-theme="dark"]:not([data-mode="day"]) .mode-switch .is-night,
:root[data-mode="night"] .mode-switch .is-night{ display:block }


/* HIS CARDS TAKE THEIR OWN COLOUR AT NIGHT. In daylight the outline is his
   near-black; against a black card that outline is invisible, so the lane's
   own colour draws it instead - the same colour as its pill and its button,
   which is what makes the four read as four lanes rather than four boxes. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]):not([data-mode="day"]) .sec6 .card{
    border-color:var(--c);
  }
}
:root[data-theme="dark"]:not([data-mode="day"]) .sec6 .card,
:root[data-mode="night"] .sec6 .card{ border-color:var(--c) }


/* --- AND THE LANE'S OWN GLOW ---------------------------------------------
   Written against the CARD and not against :root, which is the whole of why
   the first attempt showed nothing: a var() inside a custom property is
   substituted where the property is declared, so a --card-glow set on :root
   went looking for a --c that only ever exists on a card, came out invalid,
   and the four of them inherited an empty value. Here --c is in scope and
   one rule gives four different glows.

   Soft at rest, twice as far and twice as strong under the pointer, with a
   tight second shadow inside it - which is what makes a glow read as light
   coming off an edge rather than as a blur. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]):not([data-mode="day"]) .sec6 .page .card{
    box-shadow: 0 0 1.1cqw color-mix(in srgb, var(--c) 42%, transparent);
  }
  :root:not([data-theme="light"]):not([data-mode="day"]) .sec6 .page .card:hover,
  :root:not([data-theme="light"]):not([data-mode="day"]) .sec6 .page .card:focus-within{
    box-shadow: 0 0 2.6cqw color-mix(in srgb, var(--c) 78%, transparent),
                0 0 0.7cqw color-mix(in srgb, var(--c) 60%, transparent);
  }
}
:root[data-theme="dark"]:not([data-mode="day"]) .sec6 .page .card,
:root[data-mode="night"] .sec6 .page .card{
  box-shadow: 0 0 1.1cqw color-mix(in srgb, var(--c) 42%, transparent);
}
:root[data-theme="dark"]:not([data-mode="day"]) .sec6 .page .card:hover,
:root[data-theme="dark"]:not([data-mode="day"]) .sec6 .page .card:focus-within,
:root[data-mode="night"] .sec6 .page .card:hover,
:root[data-mode="night"] .sec6 .page .card:focus-within{
  box-shadow: 0 0 2.6cqw color-mix(in srgb, var(--c) 78%, transparent),
              0 0 0.7cqw color-mix(in srgb, var(--c) 60%, transparent);
}


/* --- HIS GANTRY, IN HIS OWN NIGHT ----------------------------------------
   It used to be left out of the night on purpose - a lit steel truss reads
   pale against the black - and that was my call, not his. His night gantry
   is one gradient, #b3b3b3 down to #1a1a1a. The tile is a raster so there is
   no fill to set, but it is pure greyscale running 127 to 255, and a
   greyscale range maps onto another with two numbers: brightness then
   contrast, solved for his two ends - except that he wants BLUE in it, and a
   tint needs the three channels moved by different amounts, which brightness
   and contrast cannot do: they move all three by one shared offset. A linear
   transfer per channel does it in one pass. Both gantries take it; section
   four's was still lit like daylight because this rule only named section
   one's. His own light-to-dark direction is whatever his day tile has, and
   it is kept. */
.sec1 .truss,
.sec4 .truss{
  filter: var(--truss-night, none);
  transition: filter 1s linear;
}

/* his boats, taken down to the greys and the dark red he painted them */
.sec1 .boat .art,
.sec1 .fast-boat .art{
  filter: var(--boat-night, none);
  transition: filter 1s linear;
}

/* --- HIS SIGN, COLOUR BY COLOUR ------------------------------------------
   The hero sign is inline, so its fills can be set rather than filtered -
   which is the whole point. A brightness over the sign took his white
   arrows and white type down with the board; in his own artboard they are a
   pure 255 and only the paint behind them goes dark. That is the contrast
   he was missing, and no filter can give it: a filter cannot tell his paint
   from his letters.

   Matched by the day colour itself, so his art needs no classes added to
   it and re-exports keep working. The day value is the fallback in both, so
   with no night set this resolves to the sign he drew. */
.sec1 .z-sign [fill="#1c9022"]{ fill: var(--sign-green, #1c9022) }
.sec1 .z-sign [fill="#ffda00"]{ fill: var(--sign-gold,  #ffda00) }

/* AND THE FIVE SMALLER SIGNS, from the five files he sent. All inline now,
   for the same reason the hero sign is: an image can only be filtered, and a
   filter takes his white type down with his paint. His whites stay 255 in
   every one of these; what turns is the board behind them.

   Two of them gain a stroke at night that they do not have by day - his
   banner picks up a #fcee21 edge and his button a red one - so the stroke
   is a variable too, and `none` in daylight. */
section svg.z-copy [fill="#059236"]{ fill: var(--sign-green, #059236) }
section svg.z-copy [fill="#1c9022"]{ fill: var(--sign-green, #1c9022) }
section svg.z-copy [fill="#ea2127"]{ fill: var(--sign-red,   #ea2127) }
section svg.z-copy [fill="#ffda00"]{
  fill: var(--sign-gold-2, #ffda00);
  stroke: var(--sign-gold-line, none);
  stroke-miterlimit:10;
}
/* his second sign's banner is the HERO's gold ramp, not the button's - same
   #cc9300 / #fbc93b / #fbb03b he drew on the gantry. It has to come after the
   general rule above, which is written for the button. */
.sec4 svg.our-sign [fill="#ffda00"]{ fill: var(--sign-gold, #ffda00) }

/* his button: a dark red plate inside a bright red edge, which is where the
   neon comes from - the glow on .cta only carries it off the plate */
.sec1 .cta svg.plate [fill="#ea2127"]{ fill: var(--cta-tri, #ea2127) }

.sec1 .z-sign [fill="#1c9022"],
.sec1 .z-sign [fill="#ffda00"],
section svg.z-copy [fill^="#"],
.sec1 .cta svg.plate [fill^="#"]{ transition: fill 1s linear, stroke 1s linear }

/* --- HIS LIGHT ON THE SIGN GANTRIES --------------------------------------
   His own file, GreenSIgn_Lights.svg: the beams themselves - the light that
   lands on the board - and not a glow around a bulb. Four fittings under the
   four panels throwing up, two over the outside panels throwing down, two
   small ones on the banner. What was here before was mine: soft warm blobs
   sitting where a lamp would be, which is the light SOURCE, and he asked for
   the opposite.

   IT SITS ON TOP OF THE SIGN, not behind it. The span follows the sign
   element in the markup at the same z-index, so it paints over the board and
   under his clouds without a stacking rule of its own.

   THE BOX IS TALLER THAN HIS ART NOW. His fittings are moved out past the
   board's edges - see tools/make_sign_lights.js - so both files carry a
   viewBox eight units above his and twenty-one below, and these numbers place
   that larger box instead. The board's own edges have not moved.

   ALIGNED TO THE BOTTOM EDGE, as he asked. His fittings land on the four
   panel centres - their spacings are his sign's, the short last gap included
   - so the art is the panel's width less its rounded corners, CENTRED on the
   board and PINNED to its bottom: 97.09% wide, and the top offset is
   whatever falls out of that. Every number below is those two facts and
   nothing else.

   NO BLEND MODE. His beams are already a quarter-opacity gradient painted to
   sit over green, so ordinary compositing gives back his own render exactly -
   and it keeps a blend off the daylight page, which is where the last one
   cost 8,000 pixels of body copy. */
.signlamps{
  position:absolute; display:block; pointer-events:none; z-index:3;
  aspect-ratio:938.5 / 349.56;
  background: url("../../assets/v2/ui-sign-fixtures.svg")
              left 1.429% top 0.411% / 97.091% 102.986% no-repeat;
}
/* THE FITTINGS ARE BOLTED ON, so they stay in daylight; the light they throw
   is the night only part. Two backgrounds on one box rather than two elements,
   so the metal and its beam cannot drift apart - they are the same offsets,
   split out of the same file by tools/make_sign_lights.js. */
.signlamps::after{
  content:''; position:absolute; inset:0;
  background: url("../../assets/v2/ui-sign-lights.svg")
              left 1.429% top 0.411% / 97.091% 102.986% no-repeat;
  opacity:var(--night, 0);
  transition:opacity 1s linear;
}
/* SECTION FOUR'S BOARD HAS NO BANNER over it, so it takes the variant with
   the two banner fittings dropped (tools/make_sign_lights.js) - and that
   board is a little taller for its width than the hero's, so his beams are
   stretched to reach the same two edges rather than stopping short. */
/* SECTION FOUR HAS ITS OWN RIG, and no offsets at all. The gantry's pattern
   does not fit this sign - he puts two of the six board fittings at its
   right-hand end rather than at its corners, and hangs two more on the REST
   AREA banner - so the fittings and beams come out of HIS OWN file for this
   sign, in his own coordinates. Same box as the sign, 100% by 100%: there is
   nothing to align, because the two were drawn together. */
.sec4 .signlamps{
  aspect-ratio:858.12 / 371.25;
  background-image: url("../../assets/v2/section-04/our-sign-fixtures.svg");
  background-position: 0 0;
  /* his fittings are moved out past the board's edges, so both files carry a
     box six units taller than the sign's; the width is untouched. */
  background-size: 100% 101.549%;
}
.sec4 .signlamps::after{
  background-image: url("../../assets/v2/section-04/our-sign-beams.svg");
  background-position: 0 0;
  background-size: 100% 101.549%;
}
@media (prefers-reduced-motion: reduce){ .signlamps::after{ transition:none } }


/* NO BLEND MODES ANYWHERE ON THIS PAGE, AND THAT IS DELIBERATE. An element
   carrying mix-blend-mode changes how its whole section composites even at
   opacity zero - text in that section loses its subpixel antialiasing, and
   the daylight page once shifted by 8,000 pixels of body copy for a moon
   reflection nobody could see. The reflection is gone and his sign lights
   need no blend, so the last one has gone with it. Anything added here
   later should be checked the same way: switch it off in daylight and
   diff the page. */


/* the desert's night paints, one per colour he used.
   GENERATED by tools/make_desert_night.js. */
/* >>> desert */
  @media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]):not([data-mode="day"]){
    --dffdb96: #16233a;
    --dffd486: #152032;
    --dfac67e: #172236;
    --d754c24: #110f13;
    --dc89a70: #4e3633;
    --dbb9067: #46312e;
    --d83643d: #21191b;
    --daf845b: #3d2b29;
    --dc3976b: #4b3431;
    --dbb9066: #46312e;
    --dd8a77c: #593d38;
    --d735632: #161216;
    --da67f56: #382827;
    --db48a5f: #412e2c;
    --db4895f: #402d2b;
    --dc7996e: #4d3632;
    --daf865c: #3e2c2a;
    --d9a754e: #302323;
    --da17b53: #352625;
    --db68c61: #422f2c;
    --d80623c: #20181b;
    --d93704a: #2c2021;
    --d9b6b22: #281e1f;
    --d376e00: #0b1410;
    --d4f9705: #162616;
    --d458500: #111e13;
    --d51ab00: #1a2c18;
    --d67ba14: #20361c;
    --d83c438: #26401f;
    --d3f7a00: #0e1912;
  }}
  :root[data-theme="dark"]:not([data-mode="day"]),
  :root[data-mode="night"]{
    --dffdb96: #16233a;
    --dffd486: #152032;
    --dfac67e: #172236;
    --d754c24: #110f13;
    --dc89a70: #4e3633;
    --dbb9067: #46312e;
    --d83643d: #21191b;
    --daf845b: #3d2b29;
    --dc3976b: #4b3431;
    --dbb9066: #46312e;
    --dd8a77c: #593d38;
    --d735632: #161216;
    --da67f56: #382827;
    --db48a5f: #412e2c;
    --db4895f: #402d2b;
    --dc7996e: #4d3632;
    --daf865c: #3e2c2a;
    --d9a754e: #302323;
    --da17b53: #352625;
    --db68c61: #422f2c;
    --d80623c: #20181b;
    --d93704a: #2c2021;
    --d9b6b22: #281e1f;
    --d376e00: #0b1410;
    --d4f9705: #162616;
    --d458500: #111e13;
    --d51ab00: #1a2c18;
    --d67ba14: #20361c;
    --d83c438: #26401f;
    --d3f7a00: #0e1912;
  }
/* <<< desert */

/* --- HIS HEADER AFTER DARK -------------------------------------------------
   The bar was the one thing on this page that stayed at noon while everything
   under it went dark: an interstate-blue band across the top of a black sky,
   which is the join you cannot not see.

   THE BAR GOES DOWN WITH THE SKY. Same ramp, same shape, four fifths of the
   way to black - the centre keeps just enough blue to read as his gradient
   rather than as a flat black strip.

   AND CONTACT US GOES RED, which is the one place this departs from the rule
   the rest of the night follows. Everywhere else the yellow stays exactly as
   bright as it is at noon, because it is the thing the eye is meant to find.
   On a bar this dark the yellow stops being a button and starts being a lamp;
   his own night mock has it in the interstate red off the shield, which is on
   the badge six inches to its left and carries at that size without shouting.

   The lockup, the tagline, the rule and the nav do not change: they are white
   and #29abe2 on dark either way. */
:root[data-theme="dark"]:not([data-mode="day"]),
:root[data-mode="night"]{
  --hdr-bg:linear-gradient(90deg,#010817 0%,#06214e 42%,#062253 48%,
    #04173a 62%,#031029 75%,#020b1d 88%,#01060f 100%);
  --hdr-edge:rgba(0,0,0,.72);
  --hdr-cast:0 3px 5px rgba(0,0,0,.55), 0 14px 30px rgba(0,0,0,.45);
  --hdr-bar-bg:linear-gradient(90deg,#020c1d 0%,#0a2b4d 46%,#0a2b4d 54%,#020c1d 100%);
  --hdr-menu-bg:#000;
  --hdr-menu-ink:#fff;
  --hdr-menu-rule:rgba(255,255,255,.15);
  --hdr-cta-bg:#c8161d;
  --hdr-cta-ink:#fff;
  --hdr-cta-cast:0 3px 10px rgba(0,0,0,.55);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]):not([data-mode="day"]){
    --hdr-bg:linear-gradient(90deg,#010817 0%,#06214e 42%,#062253 48%,
      #04173a 62%,#031029 75%,#020b1d 88%,#01060f 100%);
    --hdr-edge:rgba(0,0,0,.72);
    --hdr-cast:0 3px 5px rgba(0,0,0,.55), 0 14px 30px rgba(0,0,0,.45);
    --hdr-bar-bg:linear-gradient(90deg,#020c1d 0%,#0a2b4d 46%,#0a2b4d 54%,#020c1d 100%);
  --hdr-menu-bg:#000;
  --hdr-menu-ink:#fff;
  --hdr-menu-rule:rgba(255,255,255,.15);
    --hdr-cta-bg:#c8161d;
    --hdr-cta-ink:#fff;
    --hdr-cta-cast:0 3px 10px rgba(0,0,0,.55);
  }}
