/* ============================================================
   Fargo Dads — design system
   Refined editorial: warm paper, deep navy, gold used as accent.
   Self-hosted variable fonts; no third-party font requests.
   ============================================================ */

/* ---------- fonts (self-hosted, same-origin, no render-blocking 3rd party) ---------- */
@font-face{
  font-family:"Bricolage Grotesque";
  src:url("/assets/fonts/bricolage-grotesque-latin-var.woff2") format("woff2-variations"),
      url("/assets/fonts/bricolage-grotesque-latin-var.woff2") format("woff2");
  font-weight:200 800; font-style:normal; font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Hanken Grotesk";
  src:url("/assets/fonts/hanken-grotesk-latin-var.woff2") format("woff2-variations"),
      url("/assets/fonts/hanken-grotesk-latin-var.woff2") format("woff2");
  font-weight:100 900; font-style:normal; font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

:root{
  /* --- brand ---------------------------------------------------- */
  --ink:#0f1e2d;            /* deepest navy — footers, utility bar   */
  --sky:#16324e;            /* primary brand navy                    */
  --sky-2:#1e4267;          /* raised navy — hover on dark           */
  --gold:#d29a34;           /* accent (on dark)                      */
  --gold-bright:#e3ad48;    /* accent highlight on dark              */
  --gold-deep:#8a5f10;      /* accent as TEXT on light (AA on cream) */
  --rust:#a4462a;
  --field:#546f49;
  --sage:#4b7157;           /* success surfaces                      */

  /* --- surfaces ------------------------------------------------- */
  --paper:#ffffff;
  --cream:#faf7f0;
  --cream-2:#f2ece0;
  --line:#e6ddcc;
  --line-strong:#d6c9b1;

  /* --- text ----------------------------------------------------- */
  --body:#32404e;           /* long-form body copy                   */
  --slate:#4f5e70;          /* secondary/meta (AA on cream)          */

  /* --- type scale (fluid) --------------------------------------- */
  --fs-2xs:.6875rem; --fs-xs:.75rem;  --fs-sm:.8125rem; --fs-md:.9375rem;
  --fs-base:1rem;    --fs-lg:1.0625rem;
  --fs-h4:1.0625rem;
  --fs-h3:clamp(1.15rem,.95rem + .7vw,1.4rem);
  --fs-h2:clamp(1.6rem,1.2rem + 1.7vw,2.45rem);
  --fs-h1:clamp(1.9rem,1.35rem + 2.4vw,3rem);
  --fs-display:clamp(2.35rem,1.5rem + 3.9vw,4.15rem);

  /* --- spacing -------------------------------------------------- */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px;
  --s6:32px; --s7:48px; --s8:64px; --s9:88px;
  --sec-y:clamp(48px,6vw,80px);

  /* --- shape & depth -------------------------------------------- */
  --r-xs:6px; --r-sm:8px; --r-md:12px; --r-lg:16px; --r-pill:999px;
  --sh-1:0 1px 2px rgba(15,30,45,.05), 0 1px 1px rgba(15,30,45,.04);
  --sh-2:0 2px 4px rgba(15,30,45,.05), 0 4px 12px rgba(15,30,45,.06);
  --sh-3:0 4px 8px rgba(15,30,45,.06), 0 12px 28px rgba(15,30,45,.10);
  --sh-4:0 8px 16px rgba(15,30,45,.08), 0 24px 48px rgba(15,30,45,.13);

  --maxw:1200px;
  --ease:cubic-bezier(.2,.7,.3,1);
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  font-family:"Hanken Grotesk",ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;
  background:var(--cream);color:var(--body);
  font-size:var(--fs-base);line-height:1.6;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
}
h1,h2,h3,h4,.display{
  font-family:"Bricolage Grotesque",ui-sans-serif,system-ui,sans-serif;
  line-height:1.08;letter-spacing:-.021em;color:var(--sky);
  font-weight:700;text-wrap:balance;
}
h1{font-size:var(--fs-h1)}
p{text-wrap:pretty}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
button{font-family:inherit}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px}

/* accessible focus ring, everywhere */
:focus-visible{outline:3px solid var(--gold);outline-offset:2px;border-radius:3px}

/* skip link */
.skip-link{position:absolute;left:-9999px;top:0;z-index:200;background:var(--gold);color:var(--ink);
  padding:12px 20px;font-weight:700;font-size:var(--fs-md);border-radius:0 0 var(--r-sm) 0}
.skip-link:focus{left:0}

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important}
}

/* shared label/eyebrow treatment — uppercase lives HERE, not on headings */
.eyebrow,.crumb,.kicker,.tag,footer h5,.aside-box h4,aside .box h4,.sec-head .more,
.utility a,nav.main>.wrap>ul>li>a,.pill,.btn-inline,.submenu .head,.sponsored-tag{
  text-transform:uppercase;letter-spacing:.09em;
}

/* ---------- utility bar ---------- */
.utility{background:var(--ink);color:#a9b6c6;font-size:var(--fs-xs)}
.utility .wrap{display:flex;justify-content:space-between;align-items:center;min-height:38px;gap:var(--s4)}
.utility a{color:#a9b6c6;font-weight:600;margin-right:var(--s5);transition:color .18s var(--ease)}
.utility a:hover{color:var(--gold-bright)}
/* RING OPACITY .34, NOT .16, AND IT IS A DESIGN FIX RATHER THAN A COMPLIANCE ONE. The
   reported symptom was "the header icons look undersized and weak". The obvious hypothesis --
   the icons are too dim -- measures 8.19:1 for the glyph, five times over the 3:1 floor, so
   measuring the thing the complaint NAMED would have cleared it and left the symptom in place.
   What is dim is the RING: rgba(255,255,255,.16) composites to rgb(53,66,79) over the navy bar
   for 1.64:1, and the ring is the shape the eye reads as "the button". A bright mark inside a
   near-invisible frame reads as small and cheap.
   NOT a WCAG 1.4.11 failure, and do not record it as one: that criterion covers boundaries that
   IDENTIFY a component, the glyph does that at 8.19:1, so the ring is decorative and out of
   scope. The design reason is sufficient on its own.
   HIT AREA 44x44 via a centred ::after overlay, so the VISIBLE ring stays 28px and the bar does
   not grow. Recorded honestly: 28x28 already PASSES WCAG 2.2 SC 2.5.8 (AA, 24x24). 44x44 is
   SC 2.5.5 (AAA) and the Apple HIG figure -- a comfortable target, not a violation being fixed.
   THE GAP HAD TO MOVE WITH IT. At the old margin the centres sat 36px apart, so two 44px
   targets would have OVERLAPPED by 8px and the click would land on whichever painted last
   rather than on what the reader aimed at -- a bigger target that is wrong more often. 16px
   puts the centres 44px apart, exactly edge to edge. */
.utility .right a{margin:0 0 0 var(--s4);display:inline-grid;place-items:center;width:28px;height:28px;
  position:relative;
  border:1px solid rgba(255,255,255,.34);border-radius:50%;font-size:var(--fs-2xs);letter-spacing:.02em}
.utility .right a::after{content:"";position:absolute;top:50%;left:50%;width:44px;height:44px;
  transform:translate(-50%,-50%)}
.utility .right a:hover{border-color:var(--gold);background:var(--gold);color:var(--ink)}
.utility .right a svg{display:block}

/* ---------- brand band ---------- */
/* #f8f3ed matches the logo PNG background exactly. --cream (#faf7f0) is three points
   lighter, which was invisible at 44px but reads as a distinct rounded tile behind the
   mark at 88px. Revert this to var(--cream) once a transparent-background logo lands.
   Do NOT change --cream itself; other surfaces use it. */
/* THE HEADER ICON TARGETS OVERFLOW 3px INTO THIS BAND. `.utility .right a::after` is a 44x44
   hit area centred on a 28px ring inside a 38px bar, so it extends ~3px above and below. A
   focusable element in the TOP 3px of this band would lose clicks to an icon sitting above it,
   and nobody would connect that back to a change in the utility bar.
   WHAT PROTECTS IT IS THIS RULE'S `padding-top`, NOT DISTANCE. Measured on the live page: the
   icon targets stop at y=41, and `padding:var(--s5)` puts the first focusable here (the logo,
   then the CTA pills) at y=62. That is a 21px margin held by one token. Note the pills ALREADY
   overlap the icons horizontally -- `.pill.solid` spans x1031-1209 against icon targets at
   x~1129-1217 -- so the separation is purely vertical and purely this padding.
   So: do not reduce the top padding here, and do not add a focusable element that reaches into
   the first few pixels, without re-checking the overlap. This warning lives at the rule rather
   than in CLAUDE.md because whoever breaks it will be editing CSS, not reading a register. */
.brandband{background:#f8f3ed;border-bottom:1px solid var(--line);padding:var(--s5) 0}
.brandband .wrap{display:flex;align-items:center;justify-content:space-between;gap:var(--s5)}
.logo{display:inline-flex;align-items:center;gap:var(--s3)}
.logo .mark-img{width:88px;height:88px;border-radius:14px;display:block;flex:none}
/* Cap the mark on small screens: at 88px it crowds the wordmark once the tagline wraps
   to two lines. (Not the CTA pills — .brandband .cta is display:none below 820px.) */
@media(max-width:520px){.logo .mark-img{width:56px;height:56px;border-radius:11px}}
.logo .mark{width:48px;height:48px;border-radius:12px;background:var(--sky);display:grid;place-items:center;
  color:var(--gold);font-family:"Bricolage Grotesque";font-weight:800;font-size:24px;box-shadow:var(--sh-2)}
.logo .word{font-family:"Bricolage Grotesque";font-weight:800;font-size:clamp(24px,3.2vw,31px);
  color:var(--sky);line-height:.95;letter-spacing:-.025em}
.logo .word small{display:block;font-family:"Hanken Grotesk";font-weight:600;font-size:var(--fs-2xs);
  letter-spacing:.22em;color:var(--gold-deep);text-transform:uppercase;margin-top:6px}
.brandband .cta{display:flex;gap:var(--s2);align-items:center}
.pill{font-size:var(--fs-xs);font-weight:700;padding:11px 19px;border-radius:var(--r-pill);
  border:1.5px solid var(--line-strong);color:var(--sky);transition:all .18s var(--ease);white-space:nowrap}
.pill:hover{border-color:var(--sky);background:var(--sky);color:#fff}
.pill.solid{background:var(--sky);border-color:var(--sky);color:#fff}
.pill.solid:hover{background:var(--ink);border-color:var(--ink)}
@media(max-width:820px){.brandband .cta{display:none}}

/* ---------- nav ---------- */
nav.main{background:var(--sky);position:sticky;top:0;z-index:60;box-shadow:var(--sh-2)}
nav.main .wrap{display:flex;align-items:stretch;justify-content:center;flex-wrap:wrap}
nav.main ul{list-style:none;display:flex;align-items:stretch}
nav.main>.wrap>ul>li{position:relative}
nav.main>.wrap>ul>li>a{display:flex;align-items:center;gap:6px;height:52px;padding:0 18px;
  color:#dbe5ef;font-weight:600;font-size:var(--fs-xs);transition:color .16s var(--ease),background .16s var(--ease);
  position:relative}
nav.main>.wrap>ul>li>a::after{content:"";position:absolute;left:18px;right:18px;bottom:0;height:2px;
  background:var(--gold);transform:scaleX(0);transform-origin:left;transition:transform .2s var(--ease)}
nav.main>.wrap>ul>li:hover>a,nav.main>.wrap>ul>li>a:focus-visible{color:#fff;background:var(--sky-2)}
nav.main>.wrap>ul>li:hover>a::after{transform:scaleX(1)}
.caret{font-size:7px;opacity:.6;transform:translateY(1px)}
.submenu{position:absolute;top:100%;left:0;flex-direction:column;min-width:272px;background:var(--paper);
  border:1px solid var(--line);border-top:2px solid var(--gold);border-radius:0 0 var(--r-md) var(--r-md);
  box-shadow:var(--sh-4);padding:var(--s2) 0;opacity:0;visibility:hidden;transform:translateY(6px);
  transition:opacity .18s var(--ease),transform .18s var(--ease),visibility .18s}
nav.main li:hover>.submenu,nav.main li:focus-within>.submenu{opacity:1;visibility:visible;transform:translateY(0)}
nav.main>.wrap>ul>li:nth-last-child(-n+2)>.submenu{left:auto;right:0}
.submenu li a{display:block;padding:9px 20px;font-size:var(--fs-md);font-weight:500;color:var(--body);
  border-left:2px solid transparent;transition:all .14s var(--ease)}
.submenu li a:hover{background:var(--cream);border-left-color:var(--gold);color:var(--sky)}
.submenu .head{padding:8px 20px 4px;font-size:var(--fs-2xs);color:var(--slate);font-weight:700}
.search-btn{display:flex;align-items:center;height:52px;padding:0 18px;color:#dbe5ef;font-size:16px;
  border-left:1px solid rgba(255,255,255,.09);transition:color .16s var(--ease)}
.search-btn:hover{color:var(--gold-bright)}
.menu-toggle{display:none}

/* ---------- hero ---------- */
.hero{position:relative;min-height:clamp(420px,52vw,510px);display:flex;align-items:flex-end;
  color:#fff;overflow:hidden;background:var(--sky)}
.hero .bg{position:absolute;inset:0;z-index:0}
/* COLOUR GRADE, .45 soft-light. The first pass ran grayscale(1) + mix-blend-mode:color
   at .62 and came out murky, for two compounding reasons worth writing down: grayscale(1)
   strips the sunset BEFORE the gradient can put anything back, and a gold stop at 100% on
   a 155deg ramp lands in the bottom-right CORNER, so the visible field only ever received
   the navy end. All of the cool, none of the warm.
   So: partial desaturation (.45) unifies the photograph with the palette without erasing
   it; the gold moves in to 82% with a lighter stop past it so warmth reaches the frame;
   and soft-light preserves the photograph own luminance variation, which the color blend
   mode flattened to the gradient. */
.hero .bg::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(155deg,#0c1a28 0%,#16324e 48%,#c99a3f 82%,#e0b25c 100%);
  mix-blend-mode:soft-light;opacity:.45}
.hero .bg img{filter:grayscale(.45) contrast(1.08) brightness(1.06) saturate(1.05)}
/* CROP. Measured across 20/25/28/35/42% rather than picked by eye, because the crop is
   also a contrast decision: pushing the value UP reveals more of the photograph BOTTOM,
   which is sunlit grass, which is the brightest thing behind the type. The ordered 42%
   therefore moved opposite to its own stated goal -- less sky, not more -- and took gold
   to 3.93 (see the floor note below -- that is a pass under AA-large, and 20% still wins).
   20% gives the most sky, the best h1 (5.56) and gold
   tied-best (4.58); it strictly dominates the alternatives.
   Note the type never sits ON sky at any crop: .hero is align-items:flex-end, so the
   headline is always in the lower third. Only the alignment could change that.
   AND THIS IS A DESKTOP-ONLY DECISION. At 375px the box is 375x425 against a 1.90 image,
   so cover is height-constrained and the vertical slack is exactly 0 -- object-position Y
   has no travel on mobile. Four crops measured byte-identical there, which read as a
   stable result and was a stuck instrument until the slack was checked. */
.hero .bg svg,.hero .bg img{width:100%;height:100%;object-fit:cover;object-position:50% 20%;display:block}
/* TOP STOP, .12 on desktop. The vertical ramp top stop was protecting nothing there:
   .hero is align-items:flex-end, so no type sits in the top third. Lifting it brightens the
   sky -- the brightest thing in frame and the part carrying no text. Measured by compositing
   the shipping stack (photo -> filter -> grade -> scrim -> grain) in a canvas at live page
   geometry, sampling the real element rects, reading median L* (perceptually uniform, 0-100,
   ~1 unit being the threshold of visible) for fields and worst-pixel contrast for type.
   Desktop 1280, .30 -> .12:
     top third   26.6 -> 28.5 L*      gold      4.31 -> 4.31  (unchanged)
     whole hero  16.7 -> 16.9 L*      dek       7.63 -> 7.63  (unchanged)
     h1 white    5.26 -> 5.04         kicker    6.20 -> 5.92
   NOT FREE, THOUGH IT WAS PREDICTED TO BE. An earlier pass measured h1/gold/dek "unchanged
   to 2 d.p." and that held only for gold and the dek; h1 gives up 0.22 and the kicker 0.28.
   Both still clear their floors with room. The prediction was taken at a different srcset
   rendition from the one that ships -- measure the composite the reader actually gets.

   MOBILE, .42 -> .30, is the bigger win and it was BLOCKED FOR ONE ROUND on a defect that
   predated it: .kicker measured 4.00 against its 4.5 floor before any change here, and the
   lift took it to 3.42. Deepening an existing failure is still shipping a failure, so the
   lift was held until the pill was fixed (see .kicker below). With that done:
     top third   33.5 -> 37.6 L*      gold      5.10 -> 5.04
     whole hero  14.8 -> 14.8 L*      dek       8.85 -> 8.85  (unchanged)
     h1 white    8.93 -> 8.63         kicker    4.00 -> 6.89  (the fix, not the lift)
   +4.1 L* on the top third is the largest single number in this whole exercise, and it was
   sitting behind an 11px pill nothing had ever measured.

   AND THE LEVER THAT IS NOT THERE. Grade opacity .45 -> .35 measures +0.3 L*, under the
   perceptual threshold, while spending contrast: it is not a brightness control and should
   not be reached for as one. The darkness is structural. The scrim is 13 of the ~16 L* of
   darkening and cannot come off -- without it mobile gold falls 4.09 -> 1.13, so it is not
   holding the floor with margin, it IS the floor. The photograph post-filter is L* 32.5 and
   ships at 16.7, so most of the mood is the treatment rather than the light that was there;
   "it is just a dusk photo" is half wrong. The only remaining move that does not spend
   contrast is reducing how much of the viewport the hero occupies -- a layout decision.
   .phero-scrim (subpage heroes) still carries the old .42 top stop and was not touched. */
.hero .scrim{position:absolute;inset:0;
  background:
    linear-gradient(90deg,rgba(12,26,40,.88) 0%,rgba(12,26,40,.62) 38%,rgba(12,26,40,.18) 66%,rgba(12,26,40,.05) 100%),
    linear-gradient(180deg,rgba(12,26,40,.12) 0%,rgba(12,26,40,0) 38%,rgba(12,26,40,.72) 100%)}
/* One column under 800px: the type spans the full width, so a horizontal ramp would
   put the headline's right half on bare photograph. Vertical only. */
@media (max-width:800px){
  .hero .scrim{background:linear-gradient(180deg,rgba(12,26,40,.30) 0%,rgba(12,26,40,.66) 45%,rgba(12,26,40,.90) 100%)}
}
/* GRAIN, 4.5%, 160x160 tile. Above the scrim and below the text: it exists to break up
   gradient banding in the scrim ramp, so painting it under the scrim would defeat it and
   painting it over the type would soften the type. */
.hero::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:2;opacity:.045;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>")}
.hero-inner{position:relative;z-index:3;width:100%;max-width:var(--maxw);margin:0 auto;padding:var(--s8) 24px var(--s7)}
.hero h1{line-height:.96;letter-spacing:-.022em;text-wrap:balance}
/* THE WASH IS DARK BECAUSE THE TEXT IS WHITE. This was rgba(255,255,255,.10) -- a legibility
   affordance running backwards, lightening the ground beneath light type and COSTING 0.6.
   .kicker is 11px/700, which is NORMAL text under WCAG (bold counts as large only from
   18.66px), so its floor is 4.5 and it was shipping at 4.00 on mobile. A live AA failure,
   found the same way gold was and one element over -- the composite pass that fixed gold
   measured the h1 and the gold and never looked at the pill on the same pixels.
   Both candidate fixes measured, mobile at the lifted .30 top stop:
     remove the wash   4.06   STILL FAILS -- and so would not have unblocked the lift
     dark rgba(12,26,40,.35)   6.89   ships
   Removing it was not merely the weaker option, it was not a fix: the whole point of the
   change was to unblock the mobile top stop, and only the dark wash does. Desktop goes
   5.92 -> 10.63. NOT fixed by bumping the font past 18.66px to reclassify it as large text
   -- that changes which standard applies instead of changing legibility.
   The .22 white border stays: it is a hairline, not a backdrop, and carries no text. */
.kicker{display:inline-flex;align-items:center;gap:8px;background:rgba(12,26,40,.35);color:#fff;
  border:1px solid rgba(255,255,255,.22);backdrop-filter:blur(6px);
  font-weight:700;font-size:var(--fs-2xs);padding:7px 14px;border-radius:var(--r-pill);margin-bottom:var(--s4)}
/* a.kicker: the homepage pill links to /this-weekend/, because "updated daily" is true of that
   page and not of the standing copy under the hero. Colour and wash are untouched, so the 6.89
   mobile / 10.63 desktop figures above still describe it; hover moves only the hairline, and
   focus gets a visible ring rather than relying on the pill looking clickable. */
a.kicker{transition:border-color .18s var(--ease)}
a.kicker:hover{border-color:rgba(255,255,255,.6)}
a.kicker:focus-visible{outline:2px solid var(--gold-bright);outline-offset:3px}
.kicker .dot{width:7px;height:7px;border-radius:50%;background:var(--gold-bright);animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}
.hero h1{font-size:var(--fs-display);font-weight:800;max-width:15ch;color:#fff;letter-spacing:-.028em;
  text-shadow:0 2px 24px rgba(0,0,0,.35)}
/* GOLD HOLDS TO 3.0 (AA-large), NOT 4.5. Stated because the two floors disagree about the
   shipping build: gold measures 4.31 desktop and, on mobile, EITHER 5.04 OR 3.42 -- see the
   dispute below. All three pass 3.0. Under 4.5 the desktop figure and one of the two mobile
   figures fail, which is why the floor has to be declared rather than left to whoever reads
   the number next.

   THE MOBILE GOLD FIGURE IS DISPUTED AND MUST NOT BE USED AS A BASELINE UNTIL RECONCILED.
   Two independently written instruments measured this hero on 2026-09-08 and agreed EXACTLY
   on the kicker (4.00/3.99 before, 4.06 with no wash), on both top-third L* values, and on
   the desktop kicker -- then disagreed on the mobile type:
                    instrument A        instrument B
     h1             8.93 -> 8.63        6.51 -> 6.13
     gold           5.10 -> 5.04        3.51 -> 3.42
     dek            8.85                7.07
   Neither models the h1 text-shadow, so that is not the difference; the likeliest cause is
   srcset rendition, which was independently worth ~0.4 on desktop in the same session (the
   600 file and the 1200 file give different worst pixels). It is not a rounding difference
   and the two readings say opposite things: 5.04 is two points of margin, 3.42 is four
   tenths. B calls gold "the thinnest margin in the hero and the thing to re-measure first if
   the photograph ever changes" -- correct under B, misleading under A. That judgement, not
   the pass/fail, is what the disagreement actually decides.
   Reconcile by fixing the rendition and the sample region before either number is trusted.
   3.0 is the actual WCAG figure for display-size text, and this is display-size text.
   4.5 is AAA-large. Reaching it means deepening the scrim, which is the one direction this
   hero has spent a whole pass moving away from -- so holding a display accent to AAA would
   trade visible brightness for a standard WCAG does not ask for at this size, and would
   manufacture a failure whose only fix makes the page darker.
   The crop note above rejects the 42% crop for taking gold "under the 4.5 floor". That
   rejection stands on its own: 20% gives the most sky, the best h1 AND the best gold, so it
   dominates on every axis and does not depend on which floor is declared.
   .kicker gets no such latitude and is not a precedent for any: it is 11px, genuinely small
   text, 4.5 is genuinely its floor, and it was genuinely below it. */
.hero h1 .u{color:var(--gold-bright)}
.hero p{font-size:clamp(1rem,.9rem + .45vw,1.175rem);max-width:54ch;margin:var(--s4) 0 var(--s6);
  color:#dbe4ee;font-weight:400;line-height:1.55}

/* ---------- hero buttons ---------- */
.hero .btns{display:flex;gap:var(--s3);flex-wrap:wrap;align-items:center}
/* The seasonal CTA de-weighted from a second button to a text link. One primary action
   plus an underlined secondary is still one clear action; two equal-weight buttons was
   the actual problem. Deliberately NOT .btn-inline, which carries the shared uppercase
   label rule -- this is body-sized sentence text.
   WHITE, NOT --gold-bright: dropping to body size moves it from the 3.0 AA floor for
   large text to 4.5 for normal text, and mobile gold sits at 4.26. */
.hero .tlink{color:#fff;font-size:var(--fs-base);font-weight:600;line-height:1.3;
  text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px;
  text-decoration-color:rgba(255,255,255,.5);padding:2px 0}
.hero .tlink:hover{text-decoration-color:#fff}
.btn{display:inline-flex;align-items:center;gap:var(--s2);background:var(--gold);color:var(--ink);
  font-weight:700;font-size:var(--fs-xs);letter-spacing:.09em;text-transform:uppercase;
  padding:15px 26px;border-radius:var(--r-sm);box-shadow:var(--sh-2);
  transition:transform .18s var(--ease),box-shadow .18s var(--ease),background .18s var(--ease)}
.btn:hover{background:var(--gold-bright);transform:translateY(-2px);box-shadow:var(--sh-3)}
.btn.ghost{background:rgba(255,255,255,.09);color:#fff;border:1px solid rgba(255,255,255,.38);
  box-shadow:none;backdrop-filter:blur(6px)}
.btn.ghost:hover{background:rgba(255,255,255,.16);border-color:#fff;color:#fff;transform:translateY(-2px);box-shadow:none}

/* ---------- stat bar ---------- */
/* FLOATING STATS BAR. The band was DARK (--ink) and its three text colours were all
   dark-surface values. Repainting the background cream without flipping them is the
   documented .cats trap one shelf over: --gold-bright fails AA on cream, and #9dabbc /
   #c2cedd are light-on-dark greys. So the colours move with the surface --
   --gold-deep is the only gold that passes AA on light, --slate is the documented
   AA-on-cream secondary. */
.statbar{background:transparent;color:var(--body);border-top:0}
.statbar .wrap{display:flex;justify-content:space-around;flex-wrap:wrap;padding:var(--s5) 24px;gap:var(--s4)}
.stat{text-align:center;padding:2px var(--s3)}
.stat b{display:block;font-family:"Bricolage Grotesque";font-weight:700;font-size:clamp(24px,3vw,30px);
  color:var(--gold-deep);line-height:1.1;letter-spacing:-.02em}
.stat span{font-size:var(--fs-2xs);letter-spacing:.13em;text-transform:uppercase;font-weight:600;
  display:block;margin-top:5px;color:var(--slate)}
/* Desktop only: lift the card over the hero's bottom edge. z-index:4 clears the grain (2)
   and the hero text (3). Mobile keeps the normal stack -- the hero is already tight there
   and a negative margin costs more than the seam does. */
@media (min-width:768px){
  .statbar{position:relative;z-index:4;padding:0 24px}
  .statbar .wrap{margin-top:-28px;background:rgba(250,247,240,.94);border:1px solid var(--line);
    border-radius:14px;box-shadow:0 6px 24px rgba(12,26,40,.18);padding:var(--s5) var(--s4)}
}

/* ---------- sections ---------- */
section{padding:var(--sec-y) 0}
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--s5);flex-wrap:wrap;margin-bottom:var(--s3)}
.sec-head .eyebrow{font-size:var(--fs-2xs);font-weight:700;color:var(--gold-deep);margin-bottom:var(--s2)}
.sec-head h2{font-size:var(--fs-h2);font-weight:700;color:var(--sky)}
.sec-head h2 .u{color:var(--gold-deep)}
.sec-head .more{font-weight:700;font-size:var(--fs-xs);color:var(--sky);padding-bottom:3px;white-space:nowrap;
  border-bottom:2px solid var(--gold);transition:color .16s var(--ease)}
.sec-head .more:hover{color:var(--gold-deep)}
.sec-sub{color:var(--slate);max-width:64ch;margin-bottom:var(--s6);font-size:var(--fs-lg)}

/* ---------- feature cards ---------- */
.mag{display:grid;grid-template-columns:1.5fr 1fr;gap:var(--s5)}
.mag .col{display:grid;gap:var(--s5)}
.card{position:relative;border-radius:var(--r-lg);overflow:hidden;display:block;min-height:230px;color:#fff;
  transition:transform .28s var(--ease),box-shadow .28s var(--ease)}
.card:hover{transform:translateY(-4px);box-shadow:var(--sh-4)}
.card .ph{position:absolute;inset:0}
.card .ph::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(12,26,40,0) 30%,rgba(12,26,40,.55) 62%,rgba(12,26,40,.90) 100%)}
.bg-sky{background:linear-gradient(150deg,#16324e,#2a5074)}
.bg-gold{background:linear-gradient(150deg,#9c6a12,#d29a34)}
.bg-rust{background:linear-gradient(150deg,#7f3520,#b05430)}
.bg-field{background:linear-gradient(150deg,#374b31,#617f52)}
.bg-dusk{background:linear-gradient(160deg,#16324e 0%,#54614f 68%,#c08c2c 100%)}
.card .tag{position:absolute;top:14px;left:14px;z-index:3;background:var(--gold);color:var(--ink);
  font-size:var(--fs-2xs);font-weight:700;padding:5px 11px;border-radius:var(--r-xs)}
.card .ic{position:absolute;top:16px;right:18px;z-index:3;font-size:30px;opacity:.4}
.card .meta-wrap{position:absolute;left:0;bottom:0;z-index:3;padding:var(--s5)}
.card h3{font-size:var(--fs-h3);font-weight:700;color:#fff;letter-spacing:-.018em}
.card .m{font-size:var(--fs-sm);font-weight:500;color:#cdd7e3;margin-top:var(--s2)}
.card .m b{color:var(--gold-bright);font-weight:700}
.mag .lead{min-height:460px}
.mag .lead .ph{background:var(--sky)}
.mag .lead h3{font-size:clamp(1.4rem,1.05rem + 1.3vw,1.95rem);max-width:17ch}
.tri{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s5);margin-top:var(--s5)}
.tri .card{min-height:262px}

/* ---------- categories (dark band) ---------- */
.cats{background:var(--sky);color:#fff;position:relative;overflow:hidden}
.cats::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(1100px 420px at 78% -10%,rgba(210,154,52,.13),transparent 62%)}
.cats .sec-head h2{color:#fff}
.cats .sec-head h2 .u{color:var(--gold-bright)}   /* gold-deep is for light surfaces only */
.cats .sec-head .eyebrow{color:var(--gold-bright)}
.cats .sec-head .more{color:#fff}
.cats .sec-head .more:hover{color:var(--gold-bright)}
.cats .sec-sub{color:#b9c6d5}
/* light alternate band — same rhythm as .cats, but on paper (no dark-context overrides) */
.sec-alt{background:var(--cream-2)}

.cat-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s5);position:relative;z-index:2}
.cat{position:relative;aspect-ratio:4/3;border-radius:var(--r-lg);overflow:hidden;display:flex;align-items:flex-end;
  padding:var(--s5);transition:transform .28s var(--ease),box-shadow .28s var(--ease)}
.cat:hover{transform:translateY(-4px);box-shadow:var(--sh-4)}
.cat .ph{position:absolute;inset:0}
.cat .ph::after{content:"";position:absolute;inset:0;
  background:linear-gradient(0deg,rgba(12,26,40,.88) 6%,rgba(12,26,40,.12) 72%)}
.cat .label{position:relative;z-index:2}
.cat small{display:block;font-weight:700;font-size:var(--fs-2xs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--gold-bright);margin-bottom:6px}
.cat span{font-family:"Bricolage Grotesque";font-weight:700;font-size:var(--fs-h3);line-height:1.1;color:#fff}
.cat .arrow{position:absolute;top:16px;right:16px;z-index:2;width:34px;height:34px;border-radius:50%;
  background:rgba(255,255,255,.13);display:grid;place-items:center;color:#fff;
  border:1px solid rgba(255,255,255,.24);transition:all .2s var(--ease)}
.cat:hover .arrow{background:var(--gold);color:var(--ink);border-color:var(--gold)}

/* ---------- topic tiles ---------- */
.topics{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s4);margin-top:var(--s5)}
.topic{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-md);padding:var(--s5) var(--s5) var(--s5);
  transition:transform .2s var(--ease),box-shadow .2s var(--ease),border-color .2s var(--ease);
  position:relative;overflow:hidden}
.topic::before{content:"";position:absolute;left:0;right:0;bottom:0;height:3px;background:var(--gold);
  transform:scaleX(0);transform-origin:left;transition:transform .24s var(--ease)}
.topic:hover{transform:translateY(-3px);box-shadow:var(--sh-3);border-color:var(--line-strong)}
.topic:hover::before{transform:scaleX(1)}
.topic .ic{font-size:24px;margin-bottom:var(--s3)}
.topic h4{font-size:var(--fs-h4);color:var(--sky);font-weight:700;margin-bottom:var(--s1)}
.topic p{font-size:var(--fs-md);color:var(--slate);line-height:1.5}

/* ---------- split: latest + sidebar ---------- */
.split{display:grid;grid-template-columns:1fr 340px;gap:var(--s7);position:relative;z-index:2}
.latest .item{display:grid;grid-template-columns:158px 1fr;gap:var(--s5);padding:var(--s5) 0;border-bottom:1px solid var(--line);
  transition:background .18s var(--ease)}
.latest .item:first-child{padding-top:0}
.latest .item:last-child{border-bottom:none}
.latest .thumb{aspect-ratio:4/3;border-radius:var(--r-sm);overflow:hidden;position:relative;background:var(--sky)}
.latest h3{font-size:var(--fs-h4);color:var(--sky);font-weight:700;margin-bottom:5px;line-height:1.25;transition:color .16s var(--ease)}
.latest .item:hover h3{color:var(--gold-deep)}
.latest .meta{font-size:var(--fs-sm);color:var(--slate);font-weight:500}
.latest .meta b{color:var(--gold-deep);font-weight:700}
.latest p{font-size:var(--fs-md);color:var(--body);margin-top:6px;line-height:1.55}

aside .box,.aside-box{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-md);
  padding:var(--s5);margin-bottom:var(--s5);box-shadow:var(--sh-1)}
aside .box h4,.aside-box h4{display:flex;align-items:center;justify-content:space-between;gap:var(--s2);
  font-size:var(--fs-2xs);color:var(--sky);font-weight:700;padding-bottom:var(--s3);margin-bottom:var(--s3);
  border-bottom:1px solid var(--line);position:relative}
aside .box h4::after,.aside-box h4::after{content:"";position:absolute;left:0;bottom:-1px;width:34px;height:2px;background:var(--gold)}
.live{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-2xs);color:var(--gold-deep);font-weight:700}
.live .dot{width:7px;height:7px;border-radius:50%;background:#1f9e6f;animation:pulse 2s infinite}
.evt{display:flex;gap:var(--s3);padding:var(--s3) 0;border-bottom:1px solid var(--line)}
.evt:last-child{border-bottom:none}
.evt .date{flex:0 0 50px;text-align:center;background:var(--cream);border:1px solid var(--line);
  border-radius:var(--r-xs);padding:7px 0;line-height:1}
.evt .date .mo{font-size:var(--fs-2xs);font-weight:700;color:var(--gold-deep);text-transform:uppercase;letter-spacing:.06em}
.evt .date .d{font-size:20px;font-weight:700;color:var(--sky);font-family:"Bricolage Grotesque"}
.evt .info{font-size:var(--fs-md);min-width:0}
.evt .info a{font-weight:700;color:var(--sky)}
.evt .info a:hover{color:var(--gold-deep)}
.evt .info .v{display:block;font-size:var(--fs-sm);color:var(--slate);margin-top:2px}
.evt .info .t{font-size:var(--fs-sm);color:var(--gold-deep);font-weight:600}
.evt-empty{font-size:var(--fs-md);color:var(--slate);padding:var(--s2) 0}
.weather{display:flex;align-items:center;gap:var(--s4)}
.weather .temp{font-family:"Bricolage Grotesque";font-weight:700;font-size:44px;color:var(--sky);line-height:1}
.weather .cond{font-size:var(--fs-md);color:var(--slate);text-transform:capitalize}
.socials{display:flex;flex-direction:column;gap:var(--s2)}
.soc{display:flex;justify-content:space-between;align-items:center;padding:12px 15px;border-radius:var(--r-sm);
  color:#fff;font-weight:600;font-size:var(--fs-md);transition:transform .16s var(--ease),filter .16s var(--ease)}
.soc:hover{filter:brightness(1.07);transform:translateX(2px)}
.soc.fb{background:#2b4a86}.soc.ig{background:#8e4079}.soc.yt{background:#a83029}
.soc .n{font-size:var(--fs-sm);opacity:.85}

/* ---------- newsletter band ---------- */
.news{position:relative;color:#fff;overflow:hidden;background:var(--sky)}
.news .bg{position:absolute;inset:0;opacity:.26}
.news .bg svg{width:100%;height:100%;object-fit:cover}
.news .scrim{position:absolute;inset:0;background:linear-gradient(180deg,rgba(22,50,78,.78),rgba(15,30,45,.93))}
.news .wrap{position:relative;z-index:2;padding:var(--s9) 24px;text-align:center}
.news h2{font-size:var(--fs-h2);font-weight:700;color:#fff}
.news h2 .u{color:var(--gold-bright)}
.news p{color:#c2cfdd;max-width:52ch;margin:var(--s3) auto var(--s6);font-size:var(--fs-lg)}
.news form{display:flex;gap:var(--s2);max-width:480px;margin:0 auto;flex-wrap:wrap;justify-content:center}
.news input{flex:1;min-width:230px;padding:15px 17px;border:1px solid transparent;border-radius:var(--r-sm);
  font-size:var(--fs-base);font-family:inherit}
.news input:focus{outline:none;border-color:var(--gold);box-shadow:0 0 0 3px rgba(210,154,52,.3)}

/* ---------- footer ---------- */
footer{background:var(--ink);color:#9dabbc;padding:var(--s8) 0 0}
.foot-grid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:var(--s6);padding-bottom:var(--s7)}
footer .word{font-family:"Bricolage Grotesque";font-weight:800;font-size:26px;color:#fff;letter-spacing:-.02em}
footer .word .u{color:var(--gold-bright)}
footer p{font-size:var(--fs-md);margin-top:var(--s3);max-width:38ch;line-height:1.6}
footer h5{color:#fff;font-size:var(--fs-2xs);margin-bottom:var(--s3);font-weight:700}
footer ul{list-style:none}
footer ul li{margin-bottom:var(--s2)}
footer ul a{font-size:var(--fs-md);transition:color .16s var(--ease)}
footer ul a:hover{color:var(--gold-bright)}
.subfoot{border-top:1px solid rgba(255,255,255,.09);padding:var(--s4) 0;font-size:var(--fs-sm)}
.subfoot .wrap{display:flex;justify-content:space-between;flex-wrap:wrap;gap:var(--s2)}

/* ---------- responsive: layout ---------- */
@media(max-width:980px){
  .mag{grid-template-columns:1fr}.mag .lead{min-height:330px}
  .tri,.cat-grid{grid-template-columns:1fr 1fr}
  .topics{grid-template-columns:1fr 1fr}
  .split{grid-template-columns:1fr}
  .foot-grid{grid-template-columns:1fr 1fr}
  /* collapse nav to a stacked hamburger so it never overflows */
  nav.main>.wrap{justify-content:space-between}
  nav.main ul.menu{display:none;flex-direction:column;width:100%}
  nav.main ul.menu.open{display:flex;max-height:calc(100vh - 56px);overflow-y:auto;
    overscroll-behavior:contain;-webkit-overflow-scrolling:touch;padding-bottom:var(--s2)}
  nav.main>.wrap>ul>li{width:100%;border-top:1px solid rgba(255,255,255,.09)}
  nav.main>.wrap>ul>li>a{height:auto;padding:14px 4px;justify-content:space-between}
  nav.main>.wrap>ul>li>a::after{display:none}
  .submenu{position:static;opacity:1;visibility:visible;transform:none;box-shadow:none;border:none;
    border-radius:0;min-width:0;padding:0 0 var(--s2) var(--s4);background:transparent}
  .submenu li a{color:#c3d0dd;padding:8px 0}
  .submenu li a:hover{background:transparent;color:var(--gold-bright);border-left-color:transparent}
  .submenu .head{color:#8496a8;padding:8px 0 2px}
  .menu-toggle{display:flex;align-items:center;height:52px;color:#fff;font-weight:600;background:none;
    border:none;font-size:var(--fs-base);cursor:pointer;gap:var(--s2)}
}
@media(max-width:680px){
  .tri,.cat-grid,.topics{grid-template-columns:1fr}
  .utility .left{display:none}
  /* .left is removed as a flex child above, so space-between would strand the social
     icons at flex-start. Push the surviving child to the right edge. */
  .utility .wrap{justify-content:flex-end}
  .latest .item{grid-template-columns:1fr}
  .latest .thumb{max-width:280px}
  .foot-grid{grid-template-columns:1fr}
  .hero-inner{padding:var(--s7) 24px var(--s6)}
}

/* ============ SUBPAGE ============ */
.ph svg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.phero{position:relative;min-height:290px;display:flex;align-items:flex-end;color:#fff;overflow:hidden;background:var(--sky)}
.phero-bg{position:absolute;inset:0}
.phero-bg svg{width:100%;height:100%;object-fit:cover}
.phero-scrim{position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(12,26,40,.42) 0%,rgba(12,26,40,.66) 52%,rgba(12,26,40,.90) 100%)}
.phero-in{position:relative;z-index:2;width:100%;max-width:var(--maxw);margin:0 auto;padding:var(--s7) 24px var(--s6)}
.crumb{font-size:var(--fs-2xs);font-weight:700;color:var(--gold-bright);margin-bottom:var(--s3)}
.crumb a{color:var(--gold-bright);transition:color .16s var(--ease)}
.crumb a:hover{color:#fff}
.crumb b{opacity:.72;color:#fff;font-weight:500}
.phero h1{font-size:var(--fs-h1);font-weight:800;max-width:22ch;color:#fff;letter-spacing:-.026em;
  text-shadow:0 2px 18px rgba(0,0,0,.32)}
.phero .dek{font-size:clamp(1rem,.92rem + .4vw,1.15rem);max-width:60ch;margin-top:var(--s3);color:#d8e1ea;line-height:1.55}
.phero .dek a{text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px;text-decoration-color:rgba(216,225,234,.45)}
.phero .dek a:hover{text-decoration-color:var(--gold-bright)}

.article{padding:var(--sec-y) 0}
.article-grid{display:grid;grid-template-columns:minmax(0,1fr) 330px;gap:var(--s7)}
.prose p{font-size:var(--fs-lg);color:var(--body);margin-bottom:var(--s4);max-width:70ch;line-height:1.7}
.prose h3{font-size:var(--fs-h3);color:var(--sky);font-weight:700;margin:var(--s6) 0 var(--s3);letter-spacing:-.018em}

/* listing cards — each line on its own row (fixes run-together description + CTA) */
.list-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--s3);margin:var(--s2) 0 var(--s3)}
.lcard{background:var(--paper);border:1px solid var(--line);border-left:3px solid var(--gold);
  border-radius:var(--r-sm);padding:var(--s4) var(--s4)}
.lcard b{display:block;color:var(--sky);font-size:var(--fs-base);font-weight:700;margin-bottom:3px;line-height:1.3}
.lcard span{display:block;font-size:var(--fs-md);color:var(--slate);line-height:1.5}
a.lcard.linked{display:block;text-decoration:none;position:relative;
  transition:transform .18s var(--ease),box-shadow .18s var(--ease),border-color .18s var(--ease)}
a.lcard.linked:hover{border-left-color:var(--rust);transform:translateY(-2px);box-shadow:var(--sh-2)}
a.lcard.linked .lcard-go{display:block;margin-top:var(--s2);font-size:var(--fs-2xs);font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;color:var(--gold-deep)}
a.lcard.linked:hover .lcard-go{color:var(--rust)}

/* PAID DISCLOSURE. Behaviour 1 of the sponsored field: unmissable, never a small grey word.
   So it is a filled chip on the ROW ABOVE the description rather than a suffix -- a reader
   scanning the card meets it before the copy, not after it. --rust on white measures 5.9:1,
   well past the 4.5 normal-text floor, and it is the one palette colour used nowhere else as
   a fill, so it cannot be mistaken for the gold accent that decorates every other card.
   The card keeps a rust left border for the same reason: the label must survive being read
   at a glance on a phone, where a 10px chip is easy to slide past. */
.sponsored-tag{display:table;margin:0 0 6px;background:var(--rust);color:#fff;font-weight:700;
  font-size:var(--fs-2xs);padding:4px 9px;border-radius:var(--r-xs)}
.lcard.sponsored,.prose .spot.sponsored{border-left-color:var(--rust)}
a.lcard.linked.sponsored:hover{border-left-color:var(--rust)}

.tipbox{background:var(--sky);color:#fff;border-radius:var(--r-md);padding:var(--s5);margin:var(--s6) 0;
  display:flex;gap:var(--s4);align-items:flex-start;box-shadow:var(--sh-2)}
.tipbox .k{flex:0 0 auto;background:var(--gold);color:var(--ink);font-weight:700;font-size:var(--fs-2xs);
  letter-spacing:.09em;text-transform:uppercase;padding:6px 10px;border-radius:var(--r-xs)}
.tipbox p{font-size:var(--fs-base);color:#e3ebf3;margin:0;line-height:1.6}
.btn-inline{display:inline-flex;align-items:center;gap:var(--s2);background:var(--sky);color:#fff;
  font-weight:700;font-size:var(--fs-xs);padding:13px 22px;border-radius:var(--r-sm);margin-top:var(--s1);
  border:none;cursor:pointer;transition:background .18s var(--ease),transform .18s var(--ease),box-shadow .18s var(--ease)}
.btn-inline:hover{background:var(--ink);color:#fff;transform:translateY(-1px);box-shadow:var(--sh-2)}
.related a{display:block;padding:10px 0;border-bottom:1px solid var(--line);font-weight:600;
  color:var(--sky);font-size:var(--fs-md);line-height:1.4;transition:color .16s var(--ease)}
.related a:last-child{border:none}
.related a:hover{color:var(--gold-deep)}

.hubgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s5)}
/* THE HUB CARD GREW A DEK, AND THE SCRIM HAD TO BE RE-MEASURED RATHER THAN ASSUMED. Measured on the
   composite: each photo drawn at its rendered crop, this gradient applied, luminance sampled on the
   text's own line boxes (Range.getClientRects -- NOT the block, which is full-width and averages in
   photo the glyphs never touch; the block method called 14 labels failing when 12 were), p95 rather
   than max so one specular pixel cannot decide it.

   THE OLD SCRIM WAS ALREADY FAILING, before any dek. 0.90 at 8% fading to 0.16 at 72%, 200px tile,
   /things-to-do/ at 1280px: the gold category label (11px/700, normal text, floor 4.5) failed on
   12 of 15 cards, worst 1.65. Titles passed. Adding the dek on those values pushed the label to 88%
   of the tile and failed titles as well (label 14/15, title 5/15), so the dek could not ship on them.

   A near-uniform scrim passed at 200px and buried the photograph, so the fix is the tile as well as
   the ramp. 280px with the dark stop at 62% passed every card AT 1280px -- and then failed 6 at the
   narrowest tiles, 981px (3 columns, 295px wide) and 681px (2 columns), where the two longest titles
   wrap further and lift their label to 80% of the height. A measurement carries a viewport.

   Shipped: 300px, 0.88 held to 78%. Swept at 1280 / 981 / 681 / 375px across /guides/,
   /things-to-do/, /travel/, /dad-life/, /ages/ and /ages/big-kids/ -- figures in the commit. The
   worst label sits below the 78% stop rather than on it, which is the margin a slightly longer dek
   needs. A swapped photo or a new dek is a new composite: re-measure, do not adjust. */
.hcard{position:relative;border-radius:var(--r-lg);overflow:hidden;min-height:300px;color:#fff;display:flex;
  align-items:flex-end;transition:transform .26s var(--ease),box-shadow .26s var(--ease)}
.hcard:hover{transform:translateY(-4px);box-shadow:var(--sh-4)}
.hcard .sc{position:absolute;inset:0}
.hcard .sc::after{content:"";position:absolute;inset:0;
  background:linear-gradient(0deg,rgba(12,26,40,.94) 0%,rgba(12,26,40,.88) 78%,rgba(12,26,40,.30) 100%)}
.hcard .lab{position:relative;z-index:2;padding:var(--s5)}
.hcard small{display:block;font-weight:700;font-size:var(--fs-2xs);letter-spacing:.13em;text-transform:uppercase;
  color:var(--gold-bright);margin-bottom:5px}
.hcard h3{font-size:var(--fs-h3);font-weight:700;color:#fff}
.hcard .lab p{margin-top:6px;font-size:var(--fs-sm);line-height:1.45;color:#fff}

.cal{display:flex;flex-direction:column;gap:var(--s2)}
.calrow{display:grid;grid-template-columns:60px minmax(0,1fr) auto;gap:var(--s4);align-items:center;
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-sm);padding:var(--s3) var(--s4);
  transition:border-color .16s var(--ease),box-shadow .16s var(--ease),transform .16s var(--ease)}
.calrow:hover{border-color:var(--gold);box-shadow:var(--sh-2);transform:translateY(-1px)}
.calrow .cd{text-align:center;line-height:1;background:var(--cream);border-radius:var(--r-xs);padding:8px 0}
.calrow .cd .mo{font-size:var(--fs-2xs);font-weight:700;color:var(--gold-deep);text-transform:uppercase;letter-spacing:.06em}
.calrow .cd .d{font-size:21px;font-weight:700;color:var(--sky);font-family:"Bricolage Grotesque"}
.calrow .cn b{display:block;color:var(--sky);font-size:var(--fs-base);font-weight:700;line-height:1.3}
.calrow .cn span{font-size:var(--fs-md);color:var(--slate)}
.calrow .ct{font-size:var(--fs-md);color:var(--gold-deep);font-weight:600;white-space:nowrap}
/* day divider inside a grouped calendar (/this-weekend/) — a heading, so no uppercase */
.cal-day{font-family:"Bricolage Grotesque";font-size:var(--fs-h3);font-weight:700;color:var(--sky);
  line-height:1.2;margin:var(--s5) 0 var(--s1);padding-bottom:var(--s2);border-bottom:1px solid var(--line)}
.cal-day:first-child{margin-top:0}
.cal-day span{font-family:"Hanken Grotesk";font-size:var(--fs-md);font-weight:600;color:var(--slate)}

/* Band divider inside a day: "During the day", "Further out". A label, so it takes the
   shared uppercase treatment rather than setting text-transform on a heading. */
.cal-band{font-family:"Hanken Grotesk";font-size:var(--fs-2xs);font-weight:700;
  color:var(--gold-deep);letter-spacing:.08em;margin:var(--s4) 0 var(--s1)}
/* Age chip on a calendar row — rendered ONLY where the venue publishes an age, so its
   absence is information too and it must never look like a missing value. */
.cage{display:inline-block;margin-top:4px;padding:2px 8px;border-radius:999px;
  background:var(--cream-2);border:1px solid var(--line);
  font-size:var(--fs-2xs);font-weight:700;color:var(--gold-deep);letter-spacing:.03em}
/* The derived summary sentence at the top of /events/today/ and /this-weekend/. */
.cal-summary{font-size:var(--fs-lg);line-height:1.5;color:var(--sky);font-weight:600;
  margin:0 0 var(--s4);padding-bottom:var(--s3);border-bottom:2px solid var(--gold)}
.cal-note{font-size:var(--fs-md);color:var(--slate);margin:0 0 var(--s4)}

/* Guide footer: the verification line and the link back up to the hub. */
.guide-check{margin:var(--s5) 0 0;padding:var(--s3) var(--s4);background:var(--cream-2);
  border-left:3px solid var(--gold);border-radius:var(--r-xs);
  font-size:var(--fs-md);color:var(--slate);line-height:1.55}
.guide-check a{color:var(--gold-deep);font-weight:600}
.guide-up{margin:var(--s4) 0 0;font-size:var(--fs-md);color:var(--slate)}
.guide-up a{color:var(--gold-deep);font-weight:700}
.guide-posts{margin:var(--s4) 0 0;font-size:var(--fs-md);color:var(--slate)}
.guide-posts a{color:var(--gold-deep);font-weight:600}
.post-guide{margin:var(--s5) 0 0;padding:var(--s3) var(--s4);background:var(--cream-2);
  border-left:3px solid var(--gold);border-radius:var(--r-xs);
  font-size:var(--fs-md);color:var(--slate);line-height:1.55}
.post-guide a{color:var(--gold-deep);font-weight:700}

/* ---------- forms ---------- */
.form{max-width:600px}
.form label{display:block;font-weight:600;font-size:var(--fs-md);color:var(--sky);margin:var(--s4) 0 6px}
.form input,.form textarea,.form select{width:100%;padding:13px 14px;border:1px solid var(--line-strong);
  border-radius:var(--r-sm);font-family:inherit;font-size:var(--fs-base);background:var(--paper);color:var(--body);
  transition:border-color .16s var(--ease),box-shadow .16s var(--ease)}
.form input:focus,.form textarea:focus,.form select:focus{outline:none;border-color:var(--gold);
  box-shadow:0 0 0 3px rgba(210,154,52,.22)}
.form textarea{min-height:130px;resize:vertical}
.concept-note{background:#fdf6e6;border:1px solid #e6cd96;color:#7a5a12;font-size:var(--fs-md);font-weight:500;
  border-radius:var(--r-sm);padding:11px 14px;margin-bottom:var(--s5)}
.news-form input{border:1px solid var(--line-strong)}
/* Signup fine print. flex-basis:100% is load-bearing: the homepage band's form is
   display:flex with the input and button side by side, so without it this becomes a
   third flex item on the same row. It sits AFTER the button in the DOM for the same
   reason -- between input and button it would force the button onto its own line and
   push it down the viewport, which is what it must not do at 375px. */
.news-fine{flex-basis:100%;width:100%;margin:var(--s2) 0 0;font-size:var(--fs-xs);
  line-height:1.45;color:var(--slate)}
/* Same string, two surfaces -- the "gold depends on the surface" problem in miniature.
   --slate is AA on the light aside card and near-invisible on the .news navy scrim, so
   the dark context reuses the colour that band's own paragraph already uses.

   It must also restate font-size and margin, which is not belt-and-braces: `.news p` is
   (0,1,1) and `.news-fine` is (0,1,0), so on the homepage band the more specific rule
   won and this line rendered at var(--fs-lg) -- 17px, the same size as the body copy
   above it -- with that rule's var(--s6) bottom margin. The markup was correct and the
   built HTML looked right; only measuring the rendered box showed it. */
.news .news-fine{font-size:var(--fs-xs);color:#c2cfdd;margin:var(--s2) auto 0;max-width:none}

/* minmax(0,1fr), NOT 1fr, and the difference was a live bug. The desktop rule above already says
   minmax(0,1fr); this override said 1fr, which restores the grid item's automatic minimum, so .prose
   grew to its widest child instead of the column. A table's overflow-x:auto wrapper then had no width
   to constrain, and the WHOLE PAGE scrolled sideways.
   Census of all 65 pages on 2026-09-14, on the tree before this change, at 375/681/981/1280px:
     375px  /youth-sports/ 606px, /things-to-do/rainy-day/ 606px, /travel/fishing-lakes/ 733px
     681px  /travel/fishing-lakes/ 733px
   After: 0 at every width. Found only because a new table was checked at the width it would be read
   at, rather than at the desktop width where every one of these looked fine. */
@media(max-width:980px){.article-grid{grid-template-columns:minmax(0,1fr)}.hubgrid{grid-template-columns:1fr 1fr}}
@media(max-width:680px){
  .list-grid,.hubgrid{grid-template-columns:1fr}
  .calrow{grid-template-columns:52px minmax(0,1fr)}
  .calrow .ct{grid-column:2;text-align:left}
}

/* photo layer over SVG scenes */
.photo-layer{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;
  transition:opacity .5s var(--ease);z-index:0}
.photo-layer.on{opacity:1}

/* ============ BLOG / SEARCH / STATES ============ */
.muted{font-size:var(--fs-md);color:var(--slate)}
.lead-p{font-size:clamp(1.075rem,1rem + .45vw,1.25rem);line-height:1.6;color:var(--sky);font-weight:500;
  max-width:64ch;margin-bottom:var(--s5)}
.aside-links{display:flex;flex-wrap:wrap;gap:var(--s2) var(--s4)}
.related-more{display:inline-block;margin-top:var(--s3);font-weight:700;font-size:var(--fs-sm);color:var(--gold-deep)}
.related-more:hover{color:var(--rust)}

.bloggrid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s5)}
.pcard{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;
  display:flex;flex-direction:column;box-shadow:var(--sh-1);
  transition:transform .24s var(--ease),box-shadow .24s var(--ease),border-color .24s var(--ease)}
.pcard:hover{transform:translateY(-4px);box-shadow:var(--sh-3);border-color:var(--line-strong)}
.pcard-img{position:relative;aspect-ratio:16/10;overflow:hidden;background:var(--sky)}
.pcard-img .ph{position:absolute;inset:0}
.pcard-img .tag{position:absolute;top:12px;left:12px;z-index:3;background:var(--gold);color:var(--ink);
  font-weight:700;font-size:var(--fs-2xs);letter-spacing:.09em;text-transform:uppercase;padding:5px 10px;border-radius:var(--r-xs)}
.pcard-body{padding:var(--s5)}
.pcard-body h3{font-size:var(--fs-h4);font-weight:700;color:var(--sky);line-height:1.3;margin-bottom:var(--s2);
  transition:color .16s var(--ease)}
.pcard:hover .pcard-body h3{color:var(--gold-deep)}
.pcard-body .meta{font-size:var(--fs-sm);color:var(--slate);margin-bottom:var(--s2)}
.pcard-body .meta b{color:var(--rust);font-weight:600}
.pcard-body p{font-size:var(--fs-md);color:var(--body);line-height:1.55}

.searchbox{width:100%;padding:17px 20px;border:1px solid var(--line-strong);border-radius:var(--r-md);
  font-family:inherit;font-size:var(--fs-lg);background:var(--paper);color:var(--body);
  transition:border-color .16s var(--ease),box-shadow .16s var(--ease)}
.searchbox:focus{outline:none;border-color:var(--gold);box-shadow:0 0 0 3px rgba(210,154,52,.22)}
.result-item{display:block;padding:var(--s4) var(--s5);margin-top:var(--s3);background:var(--paper);
  border:1px solid var(--line);border-left:3px solid var(--gold);border-radius:var(--r-sm);
  transition:transform .16s var(--ease),box-shadow .16s var(--ease)}
.result-item:hover{transform:translateX(3px);box-shadow:var(--sh-2)}
.result-item b{display:block;font-size:var(--fs-h4);color:var(--sky);font-weight:700;line-height:1.3}
.result-item .rs{display:block;font-size:var(--fs-2xs);letter-spacing:.09em;text-transform:uppercase;
  color:var(--gold-deep);font-weight:700;margin:4px 0 6px}
.result-item .rd{display:block;font-size:var(--fs-md);color:var(--slate);line-height:1.5}

.form-ok{background:var(--sage);color:#fff;border-radius:var(--r-md);padding:var(--s5);font-size:var(--fs-lg);font-weight:600}
.form-err{margin-top:var(--s3);background:#fbeaea;color:#8a1c1c;border:1px solid #e3b7b7;border-radius:var(--r-sm);
  padding:var(--s3) var(--s4);font-size:var(--fs-md);font-weight:500}
.form-err a{color:#8a1c1c;text-decoration:underline}

@media(max-width:980px){.bloggrid{grid-template-columns:1fr 1fr}}
@media(max-width:680px){.bloggrid{grid-template-columns:1fr}}

/* clickable event rows */
a.evt{cursor:pointer;text-decoration:none;border-radius:var(--r-xs);transition:background .16s var(--ease)}
a.evt:hover{background:rgba(210,154,52,.07)}
a.evt:hover .en{color:var(--gold-deep)}
.evt .en{display:block;font-weight:700;color:var(--sky);font-size:var(--fs-md);line-height:1.35}
.evt .v,.evt .t{pointer-events:none}

/* ---------- rich guide content ---------- */
.prose .spot{border-left:2px solid var(--gold);padding:2px 0 2px var(--s4);margin:var(--s5) 0}
.prose .spot h4{font-family:"Bricolage Grotesque";font-size:var(--fs-h3);color:var(--sky);margin:0 0 6px;
  line-height:1.2;font-weight:700}
.prose .spot .spot-loc{display:inline-block;margin-left:var(--s2);font-family:"Hanken Grotesk";
  font-size:var(--fs-xs);font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--gold-deep);
  vertical-align:middle}
.prose .spot p{margin:0 0 var(--s2)}
.prose ul.facts{list-style:none;margin:0 0 var(--s2);padding:0;display:flex;flex-wrap:wrap;gap:5px var(--s5)}
.prose ul.facts li{font-size:var(--fs-md);color:var(--slate)}
.prose ul.facts li b{color:var(--sky);font-weight:700}
/* Youth sports directory: a confirmed signup window is the whole point of the page,
   so it must not look identical to an admitted gap. Gold-deep = confirmed (light
   surface, so deep not bright); muted italic = we did not verify it. */
.prose ul.facts li.reg{flex-basis:100%;color:var(--gold-deep);font-weight:600}
.lcard .lcard-drive{display:block;margin-top:.3rem;font-size:var(--fs-xs);color:var(--sky);font-weight:600}
.lcard .lcard-v{display:block;margin-top:.3rem;font-size:var(--fs-xs);color:var(--slate);opacity:.75}
.spot .drive{margin:0 0 var(--s2);font-size:var(--fs-md);color:var(--slate)}
.spot .drive b{color:var(--sky);font-weight:700;margin-right:.35em}
.spot .drive small{font-size:var(--fs-xs);opacity:.85}
.spot .checked{margin:.5rem 0 0;font-size:var(--fs-xs);color:var(--slate);opacity:.85}
.spot .checked a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.spot .checked a:hover{color:var(--gold-deep)}
.prose ul.facts li.unk{flex-basis:100%;color:var(--slate);font-style:italic;opacity:.85}
.spot-go{display:inline-block;font-size:var(--fs-2xs);font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--gold-deep)}
.spot-go:hover{color:var(--rust)}
.ftable-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:var(--s4) 0 var(--s1);
  border:1px solid var(--line);border-radius:var(--r-sm)}
table.ftable{border-collapse:collapse;width:100%;min-width:580px;font-size:var(--fs-md)}
table.ftable th{background:var(--sky);color:#e3ebf3;text-align:left;padding:11px 13px;font-size:var(--fs-2xs);
  letter-spacing:.07em;text-transform:uppercase;font-weight:700;white-space:nowrap}
table.ftable td{padding:11px 13px;border-bottom:1px solid var(--line);color:var(--body)}
table.ftable tbody tr:last-child td{border-bottom:none}
table.ftable td.rowh{font-weight:700;color:var(--sky);white-space:nowrap}
/* Derived comparison cells: an admitted gap and a pointer elsewhere must never read as a value, and
   must not read as each other either. "Not published" takes the muted italic of .facts li.unk; "See
   entry" stays upright, so the two are told apart by more than colour. */
table.ftable td.unk{color:var(--slate);font-style:italic}
table.ftable td.see{color:var(--slate)}
table.ftable tbody tr:nth-child(even){background:var(--cream)}
.ftable-note{font-size:var(--fs-sm);color:var(--slate);margin:7px 0 0;font-style:italic}
.faq{margin-top:var(--s6);border-top:1px solid var(--line);padding-top:var(--s5)}
.faq h2{font-size:var(--fs-h3);color:var(--sky);margin:0 0 var(--s3);font-weight:700}
.faq .faq-q{margin:0 0 var(--s4)}
.faq .faq-q h3{font-size:var(--fs-h4);color:var(--sky);margin:0 0 4px;font-weight:700}
.faq .faq-q p{margin:0}
.weather + .weather{margin-top:var(--s2);border-top:1px solid var(--line);padding-top:var(--s2)}

/* ---------- packing list tool ---------- */
.pack-controls{display:flex;flex-wrap:wrap;gap:var(--s2);margin:6px 0 var(--s3)}
.pack-pick{font-family:inherit;font-weight:600;font-size:var(--fs-md);padding:10px 17px;
  border:1px solid var(--line-strong);background:var(--paper);border-radius:var(--r-pill);cursor:pointer;
  color:var(--sky);transition:all .16s var(--ease)}
.pack-pick:hover{border-color:var(--gold);background:var(--cream)}
.pack-pick.active{background:var(--sky);color:#fff;border-color:var(--sky)}
.pack-ages{margin:0 0 var(--s5);font-size:var(--fs-md);color:var(--slate)}
.pack-ages label{cursor:pointer;display:inline-flex;align-items:center;gap:var(--s2)}
/* Every list ships in the html and site.js hides all but one, so with JavaScript off the page is a
   stack of five. The separator is scoped to VISIBLE siblings: a plain `+` would draw a rule above
   whichever list the picker reveals, because hidden blocks still count as siblings. */
.pack-block:not([hidden]) + .pack-block:not([hidden]){margin-top:var(--s6);padding-top:var(--s6);border-top:1px solid var(--line-strong)}
.pack-head{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);flex-wrap:wrap;margin:0 0 var(--s3)}
.pack-head h2{font-size:var(--fs-h3);color:var(--sky);margin:0;font-weight:700}
.pack-tip{background:var(--cream-2);border-left:3px solid var(--gold);padding:var(--s3) var(--s4);
  border-radius:var(--r-sm);margin:0 0 var(--s5);font-size:var(--fs-md)}
.pack-group{margin:0 0 var(--s5)}
.pack-group h3{font-size:var(--fs-h4);color:var(--sky);margin:0 0 6px;font-weight:700}
.pack-list{list-style:none;margin:0;padding:0}
.pack-list li{display:flex;align-items:flex-start;gap:11px;padding:9px 2px;border-bottom:1px solid var(--line);
  font-size:var(--fs-base);cursor:pointer;transition:color .14s var(--ease)}
.pack-list li::before{content:"";flex:none;width:18px;height:18px;border:2px solid var(--gold-deep);
  border-radius:var(--r-xs);margin-top:2px;transition:background .14s var(--ease)}
.pack-list li.done::before{background:var(--gold-deep)}
.pack-list li.done{color:var(--slate);text-decoration:line-through}

/* ---------- print ---------- */
@media print{
  .utility,.brandband,nav.main,footer,.news,.statbar,aside,.search-btn,.pack-controls,.pack-ages,
  .pack-print,.phero-bg,.phero-scrim,.skip-link,.wx-alert{display:none !important}
  body{background:#fff;color:#000}
  .phero{min-height:0;padding:0;background:#fff}
  .phero-in{position:static;color:#000;padding:0 0 10px}
  .phero-in h1,.phero-in .dek{color:#000;text-shadow:none}
  .article-grid{display:block}
  a{color:#000;text-decoration:none}
  .pack-list li::before{border-color:#000}
}

/* ---------- weather widget ---------- */
.wx-loc{padding:1px 0}
.wx-loc + .wx-loc{margin-top:var(--s3);border-top:1px solid var(--line);padding-top:var(--s3)}
.wx-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s2)}
.wx-city{font-weight:600;font-size:var(--fs-md);color:var(--sky)}
.wx-temp{font-family:"Bricolage Grotesque";font-weight:700;font-size:28px;color:var(--sky);line-height:1}
.wx-cond{font-size:var(--fs-sm);color:var(--slate);text-transform:capitalize;margin:2px 0 var(--s2)}
.wx-days{display:flex;gap:5px}
.wx-day{flex:1;text-align:center;background:var(--cream);border:1px solid var(--line);border-radius:var(--r-xs);padding:6px 3px}
.wx-day b{display:block;font-size:var(--fs-2xs);letter-spacing:.05em;text-transform:uppercase;color:var(--gold-deep);font-weight:700}
.wx-day i{display:block;font-style:normal;font-size:var(--fs-sm);color:var(--sky);font-weight:700;margin-top:3px}
.wx-day span{display:block;font-size:10px;line-height:1.25;color:var(--slate);text-transform:capitalize;margin-top:2px}

/* ---------- NWS alert banner ---------- */
.wx-alert{background:#7a1420;color:#fff}
.wx-alert[hidden]{display:none}
.wx-alert-in{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;padding:10px 0;color:#fff;
  text-decoration:none;font-size:var(--fs-md)}
.wx-alert-ev{font-weight:700}
.wx-alert-area{opacity:.86;font-size:var(--fs-sm)}
.wx-alert-more{margin-left:auto;background:rgba(255,255,255,.18);padding:2px 9px;border-radius:var(--r-pill);
  font-size:var(--fs-xs);font-weight:600}
.wx-alert-in:hover{text-decoration:underline}

/* ---------- air-quality badge ---------- */
.wx-aqi{display:inline-block;font-size:var(--fs-2xs);font-weight:700;padding:1px 8px;border-radius:var(--r-pill);
  vertical-align:middle;white-space:nowrap}
.aqi-good{background:#e0f2de;color:#1d6129}
.aqi-mod{background:#fbf0cf;color:#7d5f0f}
.aqi-usg{background:#fbe2c8;color:#984c13}
.aqi-unh{background:#f9d6d6;color:#992020}
.aqi-vunh{background:#ecd9f0;color:#63237a}
.aqi-haz{background:#eccfd2;color:#66111d}

/* OUT-OF-SEASON NOTICE. Deliberately a warning colour rather than a muted aside: the failure it
   prevents is a family driving to a closed splash pad, and a grey box reads as chrome. Sits above
   the lead paragraph because a reader who has started reading has already decided to trust the
   page -- the notice has to arrive before the dek does its work. */
.oos{background:#fdf3e3;border:1px solid #e0b25c;border-left:4px solid var(--gold-deep);
  border-radius:var(--r-sm);padding:14px 16px;margin:0 0 var(--s4);font-size:var(--fs-sm);
  line-height:1.5;color:var(--ink)}
.oos b{color:var(--gold-deep)}
