/* ============================================================================
   Isometricland — the home page's PLAYBILL  ("pitch.css")

   What sits below the wooden divider: the owner's pitch, set the way a midway
   would have set it in 1899 — a printed bill on cream stock, in a wood frame
   with brass beading, standing on the park's own grass.

   ══ WHY A PRINTED BILL, AND NOT MORE OF THE HERO ═════════════════════════
   The line ON the park (hero.css) is GILDED RYE: an inline wood type, cut in
   gold, lying over moving art. Repeating that voice down here would read as the
   same sign twice — the owner asked for "stylized text that isn't just a copy
   of what's above". So this half of the page is a different OBJECT in a
   different MATERIAL: ink on paper rather than gold on glass, which brings its
   own typography with it rather than borrowing.

     • SANCREEK for the headline — 1890s American wood type, spurred and solid.
       (Rye, the face above, is an INLINE face: white channels down every stem.
       Two wood types, but nobody could mistake one for the other.)
     • PLAYFAIR DISPLAY for the text — the high-contrast roman a bill of this
       period sets its paragraphs in, and the only serif on this site with a
       true italic-free reading colour at 20 px.
     • BUNGEE for the date strip — the one line that is not paper at all but a
       painted enamel band across the foot of the bill, so it gets the signage
       face and the only cream-on-red on the page.

   ⚑ EVERY ONE OF THOSE THREE IS DECLARED HERE. css/pay.css:423 records what
   happens otherwise: `font-family:"Lilita One"` on a page that does not link
   the stylesheet holding its @font-face falls silently through to Trebuchet —
   no console error, nothing visible in review, and the only person who ever
   sees it is the owner. index.html links skeuo.css (Rye) and this file; it does
   NOT link give.css (Alfa Slab, Limelight, Lilita). So the rule is: if this
   file sets a face, this file declares it.

   ⚑ THE TEXT IS INK; THE HEADLINE IS METAL. The owner asked for the headline in
   SILVER with "1999" in GOLD (2026-08-20), so the big line is now leaf laid on
   the sheet rather than a second ink — the way a fairground bill carries a
   gilded top line over a two-colour body. Everything else on the paper stays
   ink: the ornaments, the reading text and its lifted phrases are the same
   oxide red and near-black brown a two-plate job would have printed.

   ⚠ AND METAL ON CREAM NEEDS AN EDGE, WHICH IS WHY THE EXTRUSION IS NOT
   OPTIONAL HERE. A gilded gradient on a light ground is a light shape on a
   light field: silver especially, whose upper half is nearly the colour of the
   stock. What makes these letters read is the dark brown they stand on — a
   solid four-step side plus a hairline at the glyph edge. Take the extrusion
   away to "simplify" and the line does not get cleaner, it goes blind.
   ============================================================================ */

/* ── the faces ────────────────────────────────────────────────────────────── */
@font-face{
  font-family:"Sancreek";
  /* WOFF2 first, TTF kept behind it: same glyph data, ~66% smaller over the
     wire (Sancreek: 91 KB -> 42 KB). A browser takes the first format it
     understands, so the .ttf costs nobody a byte and still covers anything
     that predates WOFF2. Rebuild with `python tools/make_woff2.py` after
     replacing a .ttf -- a stale .woff2 beside a fresh .ttf is a face whose
     metrics silently no longer match the one this stylesheet measured. */
  src:url("../assets/fonts/Sancreek.woff2") format("woff2"),
      url("../assets/fonts/Sancreek.ttf") format("truetype");
  font-weight:400; font-style:normal; font-display:swap;
}
@font-face{
  font-family:"PlayfairDisplay";
  /* WOFF2 first, TTF kept behind it: same glyph data, ~66% smaller over the
     wire (PlayfairDisplay: 294 KB -> 104 KB). A browser takes the first format it
     understands, so the .ttf costs nobody a byte and still covers anything
     that predates WOFF2. Rebuild with `python tools/make_woff2.py` after
     replacing a .ttf -- a stale .woff2 beside a fresh .ttf is a face whose
     metrics silently no longer match the one this stylesheet measured. */
  src:url("../assets/fonts/PlayfairDisplay.woff2") format("woff2"),
      url("../assets/fonts/PlayfairDisplay.ttf") format("truetype");
  font-weight:400; font-style:normal; font-display:swap;
}
@font-face{
  font-family:"PlayfairDisplay";
  /* WOFF2 first, TTF kept behind it: same glyph data, ~66% smaller over the
     wire (PlayfairDisplay-Bold: 190 KB -> 65 KB). A browser takes the first format it
     understands, so the .ttf costs nobody a byte and still covers anything
     that predates WOFF2. Rebuild with `python tools/make_woff2.py` after
     replacing a .ttf -- a stale .woff2 beside a fresh .ttf is a face whose
     metrics silently no longer match the one this stylesheet measured. */
  src:url("../assets/fonts/PlayfairDisplay-Bold.woff2") format("woff2"),
      url("../assets/fonts/PlayfairDisplay-Bold.ttf") format("truetype");
  font-weight:700; font-style:normal; font-display:swap;
}
@font-face{
  font-family:"Bungee";
  /* WOFF2 first, TTF kept behind it: same glyph data, ~66% smaller over the
     wire (Bungee: 116 KB -> 40 KB). A browser takes the first format it
     understands, so the .ttf costs nobody a byte and still covers anything
     that predates WOFF2. Rebuild with `python tools/make_woff2.py` after
     replacing a .ttf -- a stale .woff2 beside a fresh .ttf is a face whose
     metrics silently no longer match the one this stylesheet measured. */
  src:url("../assets/fonts/Bungee.woff2") format("woff2"),
      url("../assets/fonts/Bungee.ttf") format("truetype");
  font-weight:400; font-style:normal; font-display:swap;
}

/* ── the palette of the bill ──────────────────────────────────────────────── */
.pitch{
  --paper-hi:#FDF6E3;      /* the sheet, where the light falls on it */
  --paper:#F6E9C8;
  --paper-lo:#EBDAB0;      /* and where it has aged at the edges */
  --ink:#3A2415;           /* plate one: the near-black brown of the text */
  --ink-red:#8E2718;       /* plate two: oxide red — the same ink the ornaments
                              are cut in (tools/make_pitch_ornaments.py) */
  --ink-red-hi:#A8301C;
  --enamel-a:#8E2313;      /* the painted strip at the foot: not paper */
  --enamel-b:#5E1409;

  /* ONE inset for the printed keyline, and the corner pieces nest a few pixels
     inside it. Written once so the border and its ornaments cannot drift apart
     at some viewport width nobody checked. */
  --key-in:clamp(12px, 1.5vw, 22px);
  --orn-in:calc(var(--key-in) + clamp(3px, .45vw, 7px));

  /* ⭐ THE READING COLUMN IS A NUMBER THIS FILE OWNS, because two other things
     are measured FROM it. The paragraphs take their size and their measure from
     these, and the margin drawings are centred in what is left over — so the
     text and the art cannot disagree about where the column is. Written out
     rather than left as `33em` on the paragraph, because `em` there resolves
     against the paragraph's own font-size and is unreadable from anywhere else
     in the sheet. */
  --lead-size:clamp(16.5px, 1.58vw, 23px);
  --col:calc(33 * var(--lead-size));

  padding:clamp(46px, 6.4vw, 104px) 20px clamp(52px, 7vw, 116px);
  /* the same shading the hero lays over the grass, so the two halves of the
     page sit on ONE ground rather than on two greens that nearly match */
  background:
    radial-gradient(120% 70% at 50% 0%, rgba(0,0,0,.30) 0%, rgba(0,0,0,0) 58%),
    var(--grass-tile);
  background-color:var(--grass-dk);
  background-size:auto, 64px 32px;
}

/* ══ THE FRAME ════════════════════════════════════════════════════════════
   The same construction as the hero's cabinet — wood, a dark outline, brass
   beading, a dark outline again, and a deep drop — because they are the same
   piece of furniture. What is INSIDE them is what differs: up there a window
   into the park, down here a sheet of paper. */
.bill{
  position:relative;
  max-width:1180px; margin:0 auto;
  padding:clamp(12px, 1.3vw, 20px);
  border-radius:14px;
  background:
    linear-gradient(90deg,
      rgba(0,0,0,0) 0%, rgba(0,0,0,.09) 5%, rgba(0,0,0,0) 10%,
      rgba(0,0,0,.09) 20%, rgba(0,0,0,0) 30%, rgba(0,0,0,.083) 40%,
      rgba(0,0,0,0) 50%, rgba(0,0,0,.09) 60%, rgba(0,0,0,0) 70%,
      rgba(0,0,0,.07) 85%, rgba(0,0,0,0) 100%),
    linear-gradient(180deg, var(--wood-highlight) 0%, var(--wood-light) 18%,
                    var(--wood-mid) 55%, var(--wood-dark) 95%, var(--wood-shadow) 100%);
  box-shadow:
    0 0 0 1px var(--wood-line),
    0 0 0 3px var(--brass-mid),
    0 0 0 4px var(--wood-line),
    0 16px 38px rgba(0,0,0,.55);
}

/* ══ THE SHEET ════════════════════════════════════════════════════════════ */
.bill__paper{
  position:relative;
  border-radius:5px;
  overflow:hidden;                 /* the enamel strip runs to the paper's edge */
  box-shadow:
    inset 0 0 0 1px rgba(58,36,21,.28),
    0 2px 0 rgba(255,240,205,.10);
}

/* the printed part: everything above the metal band. It is a separate box from
   .bill__paper so the keyline and the lower corner pieces have a bottom edge to
   sit on — one that is the paper's, not the band's. */
.bill__sheet{
  position:relative;
  background:
    /* the sheet is lit from the top, and has darkened where it was handled */
    radial-gradient(140% 110% at 50% -18%, var(--paper-hi) 0%, var(--paper) 46%, var(--paper-lo) 100%);
  box-shadow:inset 0 2px 14px rgba(90,60,26,.20);
}

/* The stock itself: a fibre speckle, and the SUNBURST a bill of this period
   prints behind its headline. Both are on one layer so the paper carries a
   single background, and both are faint on purpose — this is a printed ground,
   not a graphic. The rays are cut off by a radial mask so they dissolve rather
   than reaching the margins and turning into a pattern. */
.bill__stock{
  position:absolute; inset:0; pointer-events:none;
  background:
    /* the burst is centred on the HEADLINE, not on the middle of the sheet:
       a fan whose focus sits in the gap under the type reads as a smudge across
       the fold rather than as rays behind the words */
    repeating-conic-gradient(from 0deg at 50% 19%,
      rgba(142,39,24,.042) 0deg 3.2deg, rgba(142,39,24,0) 3.2deg 11deg),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='170' height='170'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='170' height='170' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
  background-size:auto, 170px 170px;
  -webkit-mask-image:radial-gradient(76% 62% at 50% 19%, #000 0%, rgba(0,0,0,.50) 44%, rgba(0,0,0,0) 76%);
          mask-image:radial-gradient(76% 62% at 50% 19%, #000 0%, rgba(0,0,0,.50) 44%, rgba(0,0,0,0) 76%);
  mix-blend-mode:multiply;
  opacity:.62;
}

/* The double keyline every printed bill carries: a red rule set in from the
   trim with a dark hairline just inside it, drawn on ONE element so the pair
   cannot drift apart at a corner.

   ⚑ THE TRANSPARENT SHADOW IS NOT DEAD CODE. An inset shadow fills a band
   inward from the edge, and EARLIER shadows paint over later ones — so the 3 px
   transparent band is what lets the paper show through the outer part of the
   4 px dark one, leaving a 1 px hairline at its inner edge. Deleting it as a
   no-op turns the hairline into a 4 px slab. */
.bill__keyline{
  position:absolute; inset:var(--key-in); pointer-events:none;
  border:2px solid rgba(142,39,24,.55);
  border-radius:3px;
  box-shadow:inset 0 0 0 3px rgba(246,233,200,0), inset 0 0 0 4px rgba(58,36,21,.30);
}

/* The four corner pieces. ONE file, and the other three are its REFLECTIONS —
   the ornament is symmetric about its own 45° diagonal (the two arms are one
   arm mirrored), so scaleX / scaleY / both give the four corners with no
   rotation anywhere and nothing to keep in step by hand.
   (tools/make_pitch_ornaments.py) */
.bill__corner{
  position:absolute; width:clamp(52px, 6vw, 98px); aspect-ratio:1;
  background:url("../assets/logo/pitch_scroll.svg?v=12829570") no-repeat center/contain;
  pointer-events:none; opacity:.94;
}
.bill__corner--tl{ left:var(--orn-in); top:var(--orn-in); }
.bill__corner--tr{ right:var(--orn-in); top:var(--orn-in); transform:scaleX(-1); }
.bill__corner--bl{ left:var(--orn-in); bottom:var(--orn-in); transform:scaleY(-1); }
.bill__corner--br{ right:var(--orn-in); bottom:var(--orn-in); transform:scale(-1,-1); }

/* ══ THE RIDES IN THE MARGINS ═════════════════════════════════════════════
   A wheel on the left, a coaster with a loop on the right, in the margins the
   centred text leaves either side (owner, 2026-08-20). Stroke-only, in the
   ornaments' oxide red, so they read as the same hand that cut the corner
   scrolls — see tools/make_pitch_rides.py for the drawings themselves.

   ⚑ SIZED BY HEIGHT, NOT BY WIDTH, and that is what makes them a PAIR. The two
   boxes are 200x252 and 232x252 — the same height, different widths, because a
   coaster is a wider object than a wheel. Give them equal WIDTHS and the wheel
   comes out taller than the coaster and the two stop looking like two plates
   from one set. Equal heights + `aspect-ratio` and the scale is shared.

   ⚑ THEY ARE BEHIND THE WORDS IN THE STACK. z-index 1 against .bill__body's 2:
   if a margin ever does run out, the sentence wins and the drawing goes under
   it rather than a line of type landing on a rail. */
.bill__ride{
  position:absolute; top:50%; transform:translateY(-50%);
  z-index:1; pointer-events:none;
  /* ⭐⭐ EACH RIDE'S BOX IS THE WHOLE GUTTER, AND THE DRAWING CENTRES ITSELF IN
     IT. (Owner, 2026-08-20: "make sure the rides are centered between the text
     and edge of the box on both sides.")

     v1 pinned each drawing at a fixed inset from the paper's edge, which is not
     centring — it is one of the two gaps being chosen and the other being
     whatever is left. With two drawings of DIFFERENT widths (a coaster is wider
     than a wheel) the two sides then disagree by the difference, and no single
     inset can fix both.

     So the element spans keyline → column edge and `background-position:center`
     does the arithmetic: the gutter is `(sheet − column) / 2 − keyline inset`,
     both halves of which this file now owns (--col above). `contain` then sizes
     the art by the box's HEIGHT, so the pair still shares one scale — and if a
     gutter ever narrows below the drawing's width, `contain` shrinks it to fit
     instead of letting it cross into the type. */
  /* ⚠ AND THE HEIGHT IS CAPPED BELOW WHAT THE GUTTER WOULD ALLOW. Centred is not
     the same as comfortable: at 192 px the art filled its 170 px gutter to
     within 7 px a side, which reads as two drawings wedged in rather than two
     standing in a margin. 172 px leaves ~15 px of air either side at 1440. */
  height:clamp(126px, 12.2vw, 172px);
  width:calc((100% - var(--col)) / 2 - var(--key-in));
  background-repeat:no-repeat;
  background-position:center;
  background-size:contain;
}
.bill__ride--wheel{
  left:var(--key-in);
  background-image:url("../assets/logo/pitch_ferris.svg?v=30be3d38");
}
.bill__ride--coaster{
  right:var(--key-in);
  background-image:url("../assets/logo/pitch_coaster.svg?v=2468d643");
}
/* ⚠ THE MARGIN IS WHAT THEY LIVE IN, SO THEY GO WHEN IT DOES. Below ~1080 px
   the centred measure has eaten the sides and there is no white space left for
   a drawing to stand in — at which point the honest thing is to remove them,
   not to shrink them into two smudges. */
@media (max-width:1080px){ .bill__ride{ display:none; } }

.bill__body{
  position:relative; z-index:2;
  padding:clamp(40px, 4.8vw, 78px) clamp(26px, 5vw, 92px) clamp(38px, 4.4vw, 70px);
  text-align:center;
}

/* ══ THE HEADLINE ═════════════════════════════════════════════════════════
   Sancreek, in leaf: a silver line with the year struck in gold.

   ⛔⛔⛔ THE SHADOW HAS TO BE A `filter`, NOT A `text-shadow`, AND THAT IS FORCED
   BY THE METAL. The face is a gradient clipped to the glyphs
   (`background-clip:text` + a transparent fill), which paints in the element's
   BACKGROUND layer — and a text-shadow paints ABOVE an element's own background.
   So the two together put the shadow colour ON TOP of the letters as smears:
   the source reads perfectly and the render is mud. css/pay.css:536 records the
   same collision from the other side (it chose a flat face so it could keep
   text-shadow). `drop-shadow()` applies to the composited element, gradient and
   all, so it goes behind. The hero's gilded line is built the same way
   (css/hero.css .tagline__c) — it is the only construction that works.

   ⚑ IT IS A HARD SHADOW, NOT A BLUR — that is the whole difference between a
   printed showbill and a web page with a shadow on it. A blurred shadow says
   "this letter is floating above something"; a solid offset copy says "this
   letter was struck onto the sheet".

   ⚑ AND CHAINING IS FREE HERE, WHERE IT WAS WORK BEFORE. Each drop-shadow in a
   filter list takes the RESULT of the previous one as its input, so four steps
   of .022em build ONE solid .088em side whose bands run nearest-the-face first.
   (With text-shadow the same four offsets have to be written cumulatively —
   .022 / .044 / .066 / .088 — or they come out as four separate ghosts.)
   ⚠ The steps are therefore OPAQUE: a translucent step would let the step
   behind it show through the one in front, and the side would band. */
.bill__head{
  margin:0;
  font-family:"Sancreek", "Rye", Georgia, serif;
  font-weight:400;
  font-size:clamp(29px, 5.35vw, 74px);
  line-height:1.06;
  letter-spacing:.008em;
  text-wrap:balance;
  /* ⛔⛔⛔ THIS LINE IS LOAD-BEARING AND IT LOOKS LIKE TIDINESS.
     .bill__head is an <h2>, and skeuo.css's `h1,h2,h3` rule carries
     `text-shadow:0 2px 0 ..., 0 3px 6px ...` — which INHERITS into every letter
     span inside it. Against the old flat ink face that shadow was merely
     redundant (each letter set its own). Against a CLIPPED GRADIENT it is
     fatal: the gradient paints in the background layer and the text-shadow
     paints above it, so the inherited shadow lands ON TOP of the metal and the
     whole line renders as flat dark brown — which is precisely what shipped for
     one render when this declaration was dropped in the rewrite.
     ⭐ A shadow you never wrote can still be on your element. Nothing in this
     file mentioned it; it arrives from a site-wide heading rule two stylesheets
     away, and its symptom is a COLOUR bug, not a shadow bug. */
  text-shadow:none;
}
.bill__head .bw{ display:inline-block; white-space:nowrap; }
.bill__head .bw + .bw{ margin-left:.30em; }

/* SILVER. The stops are a real reflection, not a grey ramp: white where the sky
   falls on the top bevel, a hard step at the HORIZON just above the middle
   (#96A3AF -> #C6D0D9 in one stop, which is the line your eye reads as polish),
   then the ground reflected back up the lower half and a dark lip at the foot.
   A smooth light-to-dark grey has no horizon and reads as unpainted plastic. */
.bill__head .bc{
  display:inline-block;
  background:linear-gradient(180deg,
    #FFFFFF 0%, #F2F5F8 12%, #D3DAE1 30%,
    #96A3AF 49%, #C6D0D9 51%,
    #EDF1F5 68%, #C3CCD5 86%, #7C8894 100%);
  -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent;
  color:transparent;              /* the fallback if text-fill-color is missing */
  filter:
    drop-shadow(0 0 .014em rgba(36,22,12,.85))        /* the edge on cream */
    drop-shadow(.022em .022em 0 #3A2415)
    drop-shadow(.022em .022em 0 #3A2415)
    drop-shadow(.022em .022em 0 #33200E)
    drop-shadow(.022em .022em 0 #2A1A0E)
    drop-shadow(.02em .04em .12em rgba(42,26,14,.34)); /* the sheet under it */
}

/* ⭐ HAND-SET TYPE IS NEVER PERFECTLY LEVEL, and that is the tell that separates
   wood type from a web font at 70 px. Each letter is a separate sort of wood
   standing in a chase, so it sits a fraction proud or shy of its neighbours.

   ⚑ THE CYCLE IS CARRIED BY A CLASS, NOT BY :nth-child. The letters are nested
   inside WORD spans (they have to be — a word must wrap as a unit), so
   :nth-child counts from 1 again at every word and every word would open on the
   same tilt. Seven classes dealt out across the whole line instead: seven is
   coprime with every word length here, so the pattern never lands with the
   words and never reads as a pattern.

   It is deliberately smaller than it wants to be: at ±0.8° the line reads as
   hand-set; at ±2° it reads as broken. */
.bill__head .j1{ transform:rotate(-0.7deg) translateY(.010em); }
.bill__head .j2{ transform:rotate( 0.5deg) translateY(-.014em); }
.bill__head .j3{ transform:rotate(-0.3deg) translateY(.006em); }
.bill__head .j4{ transform:rotate( 0.8deg) translateY(.012em); }
.bill__head .j5{ transform:rotate(-0.5deg) translateY(-.008em); }
.bill__head .j6{ transform:rotate( 0.2deg) translateY(.014em); }
.bill__head .j7{ transform:rotate(-0.8deg) translateY(-.006em); }

/* GOLD, on the same construction, so the year is picked out of the line by
   METAL rather than by a second face, a box, or a size change. Same horizon
   step as the silver at 49/51 % — the two have to be lit from the same place or
   they read as two different objects that happen to share a line.

   ⚠ The side under the gold is warmed (a red-brown rather than the silver's
   cold brown): a neutral shadow against gold reads as dirt in the crook of the
   letter, which at this size is the only place the two are ever seen touching. */
.bill__head .bc--year{
  background:linear-gradient(180deg,
    #FFF8DF 0%, #FCEBB4 12%, #F0C868 30%,
    #C08A22 49%, #F6D77F 51%,
    #FFEFBE 68%, #E6BB59 86%, #9B6C14 100%);
  -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent;
  color:transparent;
  filter:
    drop-shadow(0 0 .014em rgba(58,26,8,.85))
    drop-shadow(.022em .022em 0 #4A2410)
    drop-shadow(.022em .022em 0 #4A2410)
    drop-shadow(.022em .022em 0 #3E1D0C)
    drop-shadow(.022em .022em 0 #33170A)
    drop-shadow(.02em .04em .12em rgba(52,26,10,.34));
}

/* ── the divider under the headline ──────────────────────────────────────── */
.bill__fleuron{
  width:min(560px, 74%); height:clamp(30px, 3.4vw, 50px);
  margin:clamp(16px,1.8vw,26px) auto clamp(18px,2vw,30px);
  background:url("../assets/logo/pitch_fleuron.svg?v=a212929b") no-repeat center/contain;
}

/* ══ THE TEXT ═════════════════════════════════════════════════════════════
   Playfair at reading size, in the brown plate, on a measure a bill would
   actually have used. `text-wrap:balance` is what keeps a centred paragraph
   from ending on one orphaned word — the one thing centred setting cannot
   survive. */
.bill__lead{
  margin:0 auto;
  /* 33 em, not 35: the two margin drawings need ~190 px a side at 1440 and the
     wider measure left them 167. A centred column is the one place where taking
     the measure IN costs nothing — it is still 66 characters, which is inside
     the comfortable band, and the block gets taller in step with the art. */
  max-width:var(--col);
  font-family:"PlayfairDisplay", Georgia, "Times New Roman", serif;
  font-size:var(--lead-size);
  line-height:1.66;
  color:var(--ink);
  text-wrap:balance;
  text-shadow:0 1px 0 rgba(255,247,222,.55);   /* the paper under the ink */
}
.bill__lead + .bill__lead{ margin-top:clamp(14px,1.5vw,22px); }

/* The show's own name, set the way a bill sets it: the display face, the loud
   ink, and enough letter-spacing to stand out of a line of roman without
   needing a bigger size. */
.bill__name{
  font-family:"Sancreek", Georgia, serif;
  font-size:1.30em; line-height:1;
  letter-spacing:.012em;
  color:var(--ink-red);
  text-shadow:.018em .018em 0 rgba(58,36,21,.55);
}

/* The lifted clauses. Bold, in the red plate, tracked a hair — a bill lifts a
   phrase by INK, not by size, so the paragraph keeps one baseline grid. */
.bill__lift{
  font-weight:700; color:var(--ink-red-hi);
  letter-spacing:.006em;
}

/* ══ THE ENAMEL STRIP — A BULB MARQUEE, AND THE ONE LINK ON THIS BILL ════
   The date is the one line that is not printed on the paper: a painted metal
   band bolted across the foot, which is why it is the only cream-on-red here
   and the only place the signage face appears. It is now ringed in COLOURED
   bulbs and it goes to the buy page (owner, 2026-08-20).

   Bungee has no lowercase — its lowercase codepoints ARE capitals — so the
   sentence is written exactly as the owner wrote it and the FACE does the
   shouting. Nothing here re-types his words in caps.

   ⭐ IT IS AN <a>, NOT A DIV THAT LISTENS FOR CLICKS. A real link is
   middle-clickable, Cmd-clickable, focusable, announced as a link, shown in the
   status bar on hover and followed by Enter — every one of which has to be
   re-implemented, badly, the moment it becomes a handler on a box.

   ⛔ AND THE BULBS ARE THE HOUSE RECIPE, NOT A SECOND ONE. Ported from the buy
   page's Luna Park marquee (css/pay.css:923 records why it looks the way it
   does, in four points that are worth re-reading before touching this):
     1. a bulb is an ELEMENT WITH A SOCKET — a brass collar with glass inside it,
        the glass highlight OFF-CENTRE at 42%/34%, which is what makes a circle
        read as a sphere rather than as a dot;
     2. the lit filament is a SEPARATE LAYER with real bloom — three stacked
        box-shadows, because bloom cannot be baked into a background gradient;
     3. a chase reads as MOVEMENT only if the bright band is NARROW — a short
        hard crest with a soft tail, never a slow sine over the whole cycle;
     4. an unlit bulb is NOT off — it idles warm, so the run stays continuous
        where the light is not.
   ONLY OPACITY ANIMATES. A keyframed box-shadow re-rasterises the bloom on every
   bulb every frame, and this band is on screen the whole time the page is. */
.bill__buy{
  --pl-cycle:2.8s;          /* one lap of the chase                          */
  --pl-pitch:34px;          /* bulb spacing, uniform on every side           */
  --pl-inset:15px;          /* how far inside the band's rim the string runs */
  --pl-lag:-0.03s;          /* per-bulb delay; js/pitch.js measures the real one */

  display:block;
  position:relative; z-index:2;
  margin:0;
  /* ⚠ THE BAND HAD TO GROW WHEN THE BULBS ARRIVED. At its printed height the two
     rails sat 37 px apart with the caption between them and the sign read as a
     wall of lamps rather than as a lit board with something written on it. A
     marquee needs AIR between the string and the words — that gap is what makes
     the bulbs read as a frame. */
  padding:clamp(19px,2.5vw,34px) 18px clamp(20px,2.6vw,35px);
  text-align:center;
  text-decoration:none;
  isolation:isolate;
  background:
    linear-gradient(180deg, rgba(255,255,255,.14) 0%, rgba(255,255,255,0) 42%),
    linear-gradient(180deg, var(--enamel-a) 0%, var(--enamel-b) 100%);
  border-top:2px solid rgba(58,36,21,.85);
  box-shadow:
    /* ⭐ THE RIM IS DARKENED, AND THAT IS WHAT MAKES COLOURED BULBS WORK ON A RED
       BOARD. A red lamp on maroon enamel is the one hue in the paintbox with
       nowhere to go: measured against the others it was the least distinct by a
       wide margin. Every real marquee solves this the same way — the lamps are
       mounted on the dark rim, not on the painted face — so the board is shaded
       inward from all four edges and every hue gets its own ground back. */
    inset 0 0 34px 4px rgba(26,3,0,.55),
    inset 0 2px 0 rgba(255,214,150,.30),
    inset 0 -2px 0 rgba(0,0,0,.35),
    0 -3px 10px rgba(58,36,21,.22);
  font-family:"Bungee", "Trebuchet MS", sans-serif;
  /* ⚑ SIZED BY THE VIEWPORT, NOT BY A FLOOR. clamp(13px, 1.62vw, 23px) pinned
     the band at its 13 px FLOOR for every width under 800 — and 13 px of Bungee
     plus its tracking plus two lozenges is 283 px against the 281 px a 375 px
     phone has, so the second lozenge wrapped to a line of its own. A line that
     must not break has to shrink with the sheet it is printed on. */
  font-size:clamp(10.5px, 3.05vw, 23px);
  letter-spacing:.055em;
  line-height:1.15;
  color:#FFF3DA;
  text-shadow:0 2px 0 rgba(64,10,4,.85), 0 3px 6px rgba(0,0,0,.35);
  transition:filter .16s ease, box-shadow .16s ease;
}
/* a brass hairline where the band meets the sheet, so the metal has an edge */
.bill__buy::before{
  content:""; position:absolute; left:0; right:0; top:0; height:2px;
  background:linear-gradient(180deg, var(--brass-light), var(--brass-dark));
  opacity:.85; z-index:3;
}
/* the two lozenges that flank the date — the same lozenge as the wooden
   divider's boss and the fleuron's centre, in enamel this time */
.bill__buy .bd{
  display:inline-block; width:.46em; height:.46em; margin:0 .85em .12em;
  transform:rotate(45deg);
  background:linear-gradient(135deg, var(--brass-highlight), var(--brass-dark));
  box-shadow:0 0 0 1px rgba(58,14,4,.7);
}
/* the caption has to sit ABOVE the bulbs' bloom, or the glow washes the words */
.bill__buy .bill__date{ position:relative; z-index:2; display:block; }

/* —— hover / focus: the sign is a door, so it has to say so ———————————
   The affordance is the sign getting BRIGHTER — which is what a marquee does
   when you walk up to it — rather than an underline, which would be the one
   piece of web furniture on a page made entirely of painted objects. */
.bill__buy:hover{ filter:brightness(1.10) saturate(1.04); }
.bill__buy:active{ filter:brightness(.97); }
.bill__buy:focus-visible{
  outline:none;
  box-shadow:
    inset 0 0 0 3px var(--brass-highlight),
    inset 0 0 34px 4px rgba(26,3,0,.55),
    inset 0 2px 0 rgba(255,214,150,.30),
    inset 0 -2px 0 rgba(0,0,0,.35),
    0 0 0 3px rgba(255,233,168,.55),
    0 -3px 10px rgba(58,36,21,.22);
}

/* —— the bulbs ————————————————————————————————————————
   Positions come from js/pitch.js, which walks the band's perimeter at a
   uniform pitch. Uniform is the whole point: a `space-between` rail puts them
   30 px apart across the top and 60 px down the side, and the eye catches that
   instantly on a string it is supposed to read as one. */
.bill__buy .pl-bulbs{ position:absolute; inset:0; pointer-events:none; z-index:1; }

.pl-bulb{
  position:absolute;                       /* left/top are the bulb's CENTRE */
  width:13px; height:13px; margin:-6.5px 0 0 -6.5px;
  border-radius:50%;
  background:
    radial-gradient(circle at 42% 34%, var(--pl-glass-hi) 0%, var(--pl-glass) 36%,
                    var(--pl-glass-lo) 54%, rgba(0,0,0,0) 55%),
    linear-gradient(180deg,#F5C25A 0%,#C99230 44%,#5C4210 100%);
  box-shadow:0 1px 2px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,247,221,.5);
}
.pl-bulb::after{
  content:"";
  position:absolute; left:50%; top:50%;
  width:9.5px; height:9.5px; margin:-4.75px 0 0 -4.75px;
  border-radius:50%;
  background:radial-gradient(circle at 45% 38%,
    #FFFFFF 0%, var(--pl-hot) 42%, var(--pl-lit) 78%, rgba(255,255,255,0) 100%);
  box-shadow:
    0 0 8px 2px var(--pl-g1),
    0 0 19px 6px var(--pl-g2),
    0 0 38px 14px var(--pl-g3);
  /* ⚠ .26, WHERE THE BUY PAGE'S MARQUEE USES .13 — AND THE BOARD IS THE REASON.
     That number is not a taste setting, it is "how much light does an unlit bulb
     still throw", and the answer depends on what it is throwing it against. On
     the countdown's NAVY night sky a bulb at .13 still reads as a bright dot; on
     this MAROON enamel the same bulb sinks into the board and 80 % of the string
     reads as dead lamps between chase crests. Rendered both: .16 gave a sharper
     crest on a sign that looked switched off, .30 a live sign with no crest.
     Raise the floor, keep the crest narrow. */
  opacity:.26;                              /* the always-warm filament */
  animation-duration:var(--pl-cycle);
  animation-timing-function:linear;
  animation-iteration-count:infinite;
}

/* ⚑ THE PAINTBOX IS THE COUNTDOWN'S, NOT A NEW ONE. Signal red, amber, park
   green, royal blue — the four hues of the buy page's countdown cells and the
   donate midway's chips, in the same order. A fifth hue invented here would
   make this the only page in the site with its own fairground palette. */
.pl-bulb--0{ --pl-lit:#FF6A55; --pl-hot:#FFD2C7;
             --pl-g1:rgba(255,120,92,.85); --pl-g2:rgba(255,86,58,.46); --pl-g3:rgba(255,70,44,.20);
             --pl-glass-hi:#E9C6BE; --pl-glass:#A4756B; --pl-glass-lo:#7C4E45; }
.pl-bulb--1{ --pl-lit:#FFC24A; --pl-hot:#FFEEC4;
             --pl-g1:rgba(255,206,110,.88); --pl-g2:rgba(255,184,58,.48); --pl-g3:rgba(255,176,40,.21);
             --pl-glass-hi:#EFDCB4; --pl-glass:#A99062; --pl-glass-lo:#7C6432; }
.pl-bulb--2{ --pl-lit:#63E6A3; --pl-hot:#D3F9E4;
             --pl-g1:rgba(110,240,170,.82); --pl-g2:rgba(50,214,132,.44); --pl-g3:rgba(30,200,120,.19);
             --pl-glass-hi:#C9E4D4; --pl-glass:#77A78C; --pl-glass-lo:#4A7360; }
.pl-bulb--3{ --pl-lit:#8CBEF5; --pl-hot:#DDEEFF;
             --pl-g1:rgba(140,196,255,.84); --pl-g2:rgba(78,150,240,.46); --pl-g3:rgba(56,128,232,.20);
             --pl-glass-hi:#CBDCEE; --pl-glass:#7B93AC; --pl-glass-lo:#4E657E; }

/* —— the patterns ———————————————————————————————————
   The owner asked for "chasing and doing various patterns", so js/pitch.js
   swaps ONE class on the band every few laps. Every pattern is built out of the
   same three static per-bulb numbers, set once when the string is laid out:
   `--i` (how far along the string), `--m2` / `--m4` (its parity and its colour
   group) and `--r` (a fixed random). Nothing is recomputed when the pattern
   changes — the animation-delay is just read from a different one of them.

   ⚠ EVERY PATTERN ENDS FULLY LIT SOMEWHERE IN ITS CYCLE. A pattern that leaves
   a third of the bulbs dark for its whole lap does not read as a pattern, it
   reads as a sign with dead lamps in it — which is the one thing a marquee must
   never look like. */

/* 1. THE CHASE — a short hard crest with a soft tail, running along the string */
@keyframes pl-chase{
  0%  { opacity:1; }
  8%  { opacity:.66; }
  19% { opacity:.26; }
  100%{ opacity:.26; }
}
.pl--chase .pl-bulb::after{
  animation-name:pl-chase;
  animation-delay:calc(var(--i) * var(--pl-lag));
}
/* 2. and the same crest walking the other way — the sign a fairground runs
      when the ride is unloading. Positive lag reverses it; nothing else moves. */
.pl--chase-rev .pl-bulb::after{
  animation-name:pl-chase;
  animation-delay:calc(var(--i) * var(--pl-lag) * -1);
}
/* 3. ALTERNATE — odds and evens trading places, the oldest marquee trick there
      is. Long dwells at each end, quick cross-fade between: a slow blink reads
      as a fault, a hard cut reads as a switch. */
@keyframes pl-alt{
  0%   { opacity:1; }
  40%  { opacity:1; }
  50%  { opacity:.26; }
  90%  { opacity:.26; }
  100% { opacity:1; }
}
.pl--alt .pl-bulb::after{
  animation-name:pl-alt;
  animation-duration:calc(var(--pl-cycle) * .72);
  animation-delay:calc(var(--m2) * var(--pl-cycle) * -.36);
}
/* 4. COLOUR RUN — one hue at a time, red → amber → green → blue. This is the
      pattern the coloured glass exists for: on the others the colour is texture,
      on this one it IS the movement. */
@keyframes pl-hue{
  0%  { opacity:1; }
  16% { opacity:.86; }
  30% { opacity:.26; }
  100%{ opacity:.26; }
}
.pl--hue .pl-bulb::after{
  animation-name:pl-hue;
  animation-duration:calc(var(--pl-cycle) * 1.5);
  animation-delay:calc(var(--m4) * var(--pl-cycle) * -.375);
}
/* 5. TWINKLE — no order at all: each bulb keeps its own fixed random phase, so
      the string shimmers without ever repeating a visible figure. */
@keyframes pl-twinkle{
  0%  { opacity:1; }
  12% { opacity:.30; }
  26% { opacity:.26; }
  62% { opacity:.26; }
  74% { opacity:.55; }
  100%{ opacity:1; }
}
.pl--twinkle .pl-bulb::after{
  animation-name:pl-twinkle;
  animation-duration:calc(var(--pl-cycle) * 1.35);
  animation-delay:calc(var(--r) * var(--pl-cycle) * -1.35);
}

/* ⚠ THE STRING ONLY RUNS WHILE IT IS ON SCREEN. js/pitch.js adds .pl--on when
   the band enters the viewport and removes it when it leaves — there are ~80
   bulbs here and the hero above them is a compositing canvas that wants the
   frame budget. With the class off every bulb sits at its lit value, so the
   sign is never caught dark. */
.bill__buy:not(.pl--on) .pl-bulb::after{ animation:none; opacity:1; }

@media (prefers-reduced-motion:reduce){
  /* Stop the chase and leave every bulb LIT, rather than leaving whichever ones
     the pattern happened to have dark. */
  .bill__buy .pl-bulb::after{ animation:none !important; opacity:1; }
}
@media (forced-colors:active){
  /* the bulbs and the enamel are both gone by definition here; give the band an
     edge back so it still reads as a control */
  .bill__buy{ border:1px solid LinkText; }
  .bill__buy .pl-bulbs{ display:none; }
}

/* ══ PHONE ════════════════════════════════════════════════════════════════
   The corner scrolls come off first: at 380 px they are 15 % of the sheet and
   the text has to set inside what is left of it. The keyline stays — it is what
   makes the sheet read as a printed bill rather than as a cream box. */
@media (max-width:700px){
  .bill{ padding:9px; border-radius:11px; }
  .bill__body{ padding:30px 18px 24px; }
  .bill__corner{ display:none; }
  .bill__keyline{ inset:9px; }
  .bill__fleuron{ width:86%; }
  .bill__lead{ max-width:none; }
  .bill__buy .bd{ margin:0 .5em .12em; }
  /* the string scales with the board: at the desktop pitch a 300 px band holds
     two rails 24 px apart and the caption has nowhere to sit */
  .bill__buy{ --pl-pitch:23px; --pl-inset:10px; }

  /* ⚑ ON A PHONE THE HEADLINE IS MEANT TO WRAP. The desktop clamp bottoms out
     at 29 px, which at 480 px is the one size that neither wraps NOR clears the
     keyline — it lands within a few pixels of the margin on a single line and
     reads as type that only just escaped. Two big balanced lines are better
     than one cramped one, so on a narrow sheet it is sized to be too wide for
     one line ON PURPOSE and `text-wrap:balance` splits it. */
  .bill__head{ font-size:clamp(30px, 8.4vw, 40px); }
  /* the 40 px cap is not a taste call: it is what makes the step across the
     700 px breakpoint almost invisible (40 px at 700, 37.5 px at 701). Raising
     the DESKTOP arm to meet the phone instead would crowd the 768-900 band,
     where the line is already within 40 px of the corner pieces. */
}

/* Nothing on this bill moves: the hand-set jitter is a STATIC offset, not an
   animation, so there is no prefers-reduced-motion arm to write. Anything added
   here later that does move needs one. */
