/* ═══════════════════════════════════════════════════════════════════════
   LBF Theme, assets/css/cancellation.css                      v32.98.0
   2026 cancellation home page + site-wide notice bar.

   Every rule is scoped under .lbf-cx (the page) or .lbf-cx-bar (the bar),
   both of which only exist in cancellation mode. Nothing here can reach a
   normal page, and the whole file goes inert the moment the switch in
   inc/cancellation.php is flipped.

   NO transforms and NO will-change in any reveal or hover that affects
   layout, same reason as 32.96.0 and 32.97.0. Hovers here move colour and
   shadow only.
   ═══════════════════════════════════════════════════════════════════════ */

.lbf-cx,
.lbf-cx-bar {
  --cx-blue:   #0537A4;
  --cx-navy:   #000820;
  --cx-gold:   #F3C303;
  --cx-cream:  #FBF7EE;
  --cx-ink:    #14203a;
  --cx-mute:   #5a6478;
  --cx-line:   rgba(5,55,164,.14);
  --cx-shadow: 0 18px 50px rgba(5,55,164,.10);
}

/* ══ SITE-WIDE NOTICE BAR ═══════════════════════════════════════════
   IN NORMAL FLOW, not fixed.

   32.99.0 made it fixed and grew --header-h by its height so each page's
   nav-clearance rule would grow with it. That reached only the 11
   stylesheets that clear the nav THROUGH that variable. Eight others
   hardcode the number, 70px, 102px, 4.5rem, 6rem, and never moved, so
   some pages had room for the notice and some had it sitting on their
   content. Chasing every page is the wrong shape of fix; there will always
   be one more.

   Flow content cannot be overlapped by anything. The bar now pushes the
   page down by simply existing, on every page, whether that page has a
   clearance rule or not. Worst case becomes a gap instead of a collision.

   It clears the FIXED nav with its own top margin. The nav's height is
   hardcoded here rather than read from --header-h because that variable is
   about to be overridden below, and the bar must not depend on its own
   output. 82px and 68px are the theme's own two values, from :root.
─────────────────────────────────────────────────────────────────── */
.lbf-cx-bar {
  margin: calc(82px + 6px) auto 0;
  max-width: calc(1480px - 2 * clamp(0.75rem, 2vw, 1.5rem));
  border-radius: 14px;
  background: linear-gradient(135deg, #04246e 0%, var(--cx-blue) 55%, #0a49c9 100%);
  color: #fff;
  border: 1px solid rgba(243,195,3,.55);
  border-bottom: 3px solid var(--cx-gold);
  box-shadow: 0 10px 30px rgba(0,8,32,.28);
  position: relative;
  z-index: 5;
}
.admin-bar .lbf-cx-bar { margin-top: calc(82px + 6px); }

/* NEUTRALISE THE DOUBLED CLEARANCE.
   The bar has already carried the page past the nav, so every rule that
   also clears it would now stack a second 82px underneath. --header-h is
   dropped to a breathing gap for the 11 stylesheets that read it. The nav's
   own stylesheet never reads it, so the menu does not move. */
body.lbf-cx-notice { --header-h: 10px; }

/* The eight files that hardcode their clearance instead. Scoped to
   body.lbf-cx-notice so a normal page is untouched, and !important only
   where the original itself used !important. */
body.lbf-cx-notice .post-hero-first        { padding-top: 1.5rem; }
body.lbf-cx-notice .lbf-fa-shell,
body.lbf-cx-notice .rg-shell,
body.lbf-cx-notice #lbf-s3               { padding-top: 12px !important; }
body.lbf-cx-notice .lbf-hs-shell,
body.lbf-cx-notice .lbf-top-shell          { padding-top: 12px; }

.lbf-cx-bar__in {
  padding: .62rem 1.1rem;
  display: flex;
  align-items: center;
  gap: .8rem;
}
.lbf-cx-bar__tag {
  flex: none;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-weight: 900;
  font-size: .78rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  background: var(--cx-gold);
  color: var(--cx-navy);
  padding: .2rem .55rem;
  border-radius: 4px;
  line-height: 1.35;
}
.lbf-cx-bar__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: .12rem;
}
/* Line one carries the reason and the apology, at full size. */
.lbf-cx-bar__txt {
  margin: 0;
  font-size: .95rem;
  font-weight: 700;
  line-height: 1.38;
}
/* Line two, deliberately quieter. Three quarters the size and dropped to
   72% opacity, so the contest deadline stops competing with the festival
   being called off. It used to sit in the same sentence at the same weight,
   which gave the two equal billing. */
.lbf-cx-bar__sub {
  margin: 0;
  font-size: .78rem;
  font-weight: 500;
  line-height: 1.35;
  color: rgba(255,255,255,.72);
}
/* One of the two variants shows at any width. Both are in the markup and
   CSS chooses; swapping the string in JavaScript would flash the wrong one
   on first paint. */
.lbf-cx-bar__sub-sm { display: none; }
@media (max-width: 700px) {
  .lbf-cx-bar__sub-lg { display: none; }
  .lbf-cx-bar__sub-sm { display: inline; }
}
.lbf-cx-bar__cta {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  background: #fff;
  color: var(--cx-blue);
  font-weight: 800;
  font-size: .84rem;
  padding: .42rem .85rem;
  border-radius: 999px;
  text-decoration: none;
  white-space: nowrap;
  transition: background .18s ease, color .18s ease, box-shadow .18s ease;
}
.lbf-cx-bar__cta:hover,
.lbf-cx-bar__cta:focus-visible {
  background: var(--cx-gold);
  color: var(--cx-navy);
  box-shadow: 0 4px 14px rgba(0,0,0,.25);
}
.lbf-cx-bar__cta:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }

/* The nav drops to 68px below its own breakpoint; the bar follows it up. */
@media (max-width: 900px) {
  .lbf-cx-bar { margin: calc(68px + 6px) .6rem 0; }
  .admin-bar .lbf-cx-bar { margin-top: calc(68px + 6px); }
}
@media (max-width: 700px) {
  .lbf-cx-bar__in   { padding: .55rem .8rem; gap: .45rem; flex-wrap: wrap; }
  .lbf-cx-bar__tag  { order: 1; }
  .lbf-cx-bar__body { order: 2; flex-basis: 100%; }
  .lbf-cx-bar__txt  { font-size: .84rem; }
  .lbf-cx-bar__sub  { font-size: .74rem; }
  .lbf-cx-bar__cta  { order: 3; font-size: .8rem; padding: .35rem .7rem; }
}

/* ══ PAGE SHELL: CANVAS + ONE BIG ROUNDED CARD ══════════════════════
   Same pattern as the real home page (v3-canvas wrapping v3-outer-card):
   a full-bleed background, then a single large rounded card holding every
   section, with each section its own rounded rectangle inside it.

   WIDTH IS THE NAV CARD'S OWN FORMULA, not a number copied out of it. The
   menu, the notice bar, the outer card and the banner therefore all share
   one left and right edge, and if the nav ever changes width they all
   follow together.
─────────────────────────────────────────────────────────────────── */
.lbf-cx {
  color: var(--cx-ink);
  font-family: 'Outfit', system-ui, -apple-system, sans-serif;
  overflow-anchor: none;
}

.cx-canvas {
  background:
    radial-gradient(1200px 500px at 50% -8%, rgba(5,55,164,.10), transparent 65%),
    var(--cx-cream);
  /* CLEARS THE FIXED NAV. This was missing entirely in 32.99.0, so the
     banner started at y=0 and the floating menu sat straight on top of the
     announcement artwork. The home page carries no notice bar (it IS the
     notice), so --header-h is still its normal 82px here. */
  padding: calc(var(--header-h, 82px) + 0.75rem) clamp(0.75rem, 2vw, 1.5rem) clamp(2rem, 5vw, 3.5rem);
}
.admin-bar .cx-canvas { padding-top: calc(var(--header-h, 82px) + 0.75rem + 32px); }
@media (max-width: 900px) {
  .cx-canvas { padding-top: calc(68px + 0.75rem); }
  .admin-bar .cx-canvas { padding-top: calc(68px + 0.75rem + 46px); }
}

.cx-outer {
  max-width: calc(1480px - 2 * clamp(0.75rem, 2vw, 1.5rem));
  margin: 0 auto;
  background: #fff;
  border: 1px solid var(--cx-line);
  border-radius: 26px;
  /* Clips the banner to the card's own corners so the art does not poke
     square edges out of a rounded container. */
  overflow: hidden;
  box-shadow: 0 30px 90px rgba(5,55,164,.13);
}

/* Every section inside the outer card is its own rounded rectangle, inset
   from the card edge. The banner is the exception: it is flush to the top
   so the card reads as being *made of* the announcement rather than
   containing a picture of it. */
.cx-outer > section {
  margin: clamp(0.85rem, 1.6vw, 1.25rem);
  border-radius: 18px;
  overflow: hidden;
}
.cx-outer > .cx-hero { margin: 0; border-radius: 0; }

@media (max-width: 700px) {
  .cx-canvas { padding-inline: .6rem; }
  .cx-outer  { border-radius: 18px; }
  .cx-outer > section { margin: .6rem; border-radius: 14px; }
}

/* ══ 1 · HEADER BANNER + HOT ZONES ══════════════════════════════════ */
.cx-hero { background: #fff; }
.cx-hero__frame { position: relative; display: block; }
.cx-hero__pic { display: block; }
.cx-hero__pic img { display: block; width: 100%; height: auto; }

/* The art is 1480 wide, which is exactly the outer card's own maximum, so
   at full size it lands pixel for pixel with no upscaling.

   Below 700px the frame is ~3:1 and would render about 128px tall, putting
   the body copy baked into the graphic at roughly five pixels. It is
   cropped to a taller ratio and anchored LEFT, keeping the logo and the
   headline, which are the only parts legible at that size. Nothing is
   lost: every word inside the graphic is repeated as real text below, and
   the events panel that gets cropped away is reachable through the chips. */
/* No CSS crop below 700px any more. The <picture> element now serves a
   purpose-made mobile file that is already composed and already small, so
   there is nothing left to crop and nothing wasted downloading it. The
   aspect-ratio and object-fit rules that used to force the crop are gone;
   leaving them would squeeze the mobile artwork a second time. */
@media (max-width: 700px) {
  .cx-hero__pic img { aspect-ratio: auto; object-fit: fill; }
}

/* Hot zones over the three panel rows. Percentages, measured off the
   1480x500 source, so they stay locked to their rows at any width, which
   is the whole reason this is not an <area> map. */
.cx-hero__hot {
  position: absolute;
  display: block;
  border-radius: 10px;
  text-decoration: none;
  /* Invisible at rest. A visible box over artwork that already reads as a
     list would look like a rendering fault. */
  background: transparent;
  transition: background .18s ease, box-shadow .18s ease;
}
.cx-hero__hot:hover {
  background: rgba(5,55,164,.10);
  box-shadow: inset 0 0 0 2px rgba(5,55,164,.45);
}
/* Keyboard users need to SEE where they are; an invisible target with no
   focus ring is unusable by tab. Gold, because it has to read against both
   the cream panel and the blue page. */
.cx-hero__hot:focus-visible {
  background: rgba(243,195,3,.16);
  box-shadow: 0 0 0 3px var(--cx-gold), inset 0 0 0 2px rgba(5,55,164,.5);
  outline: none;
}
/* Gone below 900px: the panel is cropped out of frame, and even uncropped
   each row would be ~16px tall against the 44px minimum tap target. */
@media (max-width: 900px) {
  .cx-hero__hot { display: none; }
}

/* ── Jump chips ─────────────────────────────────────────────────────
   Shown at every width. On a phone they are the only route from the top
   of the page to the three sections; on desktop they give keyboard and
   screen-reader users a target that is not an invisible box over a
   picture. */
.cx-jump {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  justify-content: center;
  padding: .9rem clamp(0.75rem, 2vw, 1.25rem);
  background: linear-gradient(180deg, #fff, var(--cx-cream));
  border-top: 1px solid var(--cx-line);
}
.cx-jump__c {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  /* 44px minimum, which is the point of these on a phone. */
  min-height: 44px;
  padding: .5rem 1rem;
  border-radius: 999px;
  background: #fff;
  border: 1px solid var(--cx-line);
  color: var(--cx-blue);
  font-weight: 800;
  font-size: .92rem;
  text-decoration: none;
  transition: background .18s ease, color .18s ease, border-color .18s ease;
}
.cx-jump__c:hover,
.cx-jump__c:focus-visible {
  background: var(--cx-blue);
  border-color: var(--cx-blue);
  color: #fff;
}
.cx-jump__c:hover .cx-jump__d,
.cx-jump__c:focus-visible .cx-jump__d { background: var(--cx-gold); color: var(--cx-navy); }
.cx-jump__c:focus-visible { outline: 3px solid var(--cx-gold); outline-offset: 2px; }
.cx-jump__d {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: .7rem;
  font-weight: 900;
  letter-spacing: .1em;
  text-transform: uppercase;
  background: rgba(5,55,164,.1);
  color: var(--cx-blue);
  padding: .12rem .4rem;
  border-radius: 4px;
  transition: background .18s ease, color .18s ease;
}
/* The Questions chip is not an event. Lighter fill and a dashed edge so it
   reads as a way to somewhere on the page rather than a fourth thing
   happening this weekend, which is the exact confusion this page exists to
   clear up. Hover still resolves to the same solid blue as the others, so
   it does not feel disabled. */
.cx-jump__c--alt {
  background: transparent;
  border-style: dashed;
  border-color: rgba(5,55,164,.32);
}
.cx-jump__c--alt .cx-jump__d {
  background: rgba(5,55,164,.14);
  min-width: 1.15rem;
  text-align: center;
}

@media (max-width: 520px) {
  .cx-jump   { gap: .4rem; }
  /* The three events stack full width; they are the reason people are
     here. The Questions chip stays compact on its own row underneath, so
     four chips do not turn into four full rows of navigation before any
     content on a phone. */
  .cx-jump__c        { font-size: .85rem; padding: .5rem .8rem; flex: 1 1 100%; justify-content: center; }
  .cx-jump__c--alt   { flex: 0 1 auto; }
}

/* WHERE A JUMP LANDS.
   The nav is position:fixed, so an anchor target scrolls to the very top
   of the viewport and sits UNDERNEATH the menu. scroll-margin-top holds it
   clear. The value is the nav height plus a gap; on pages carrying the
   notice bar --header-h is only 10px, but the home page never carries it,
   so the full 82px applies here. */
.lbf-cx [id^="cx-"] { scroll-margin-top: calc(82px + 1.25rem); }
@media (max-width: 900px) {
  .lbf-cx [id^="cx-"] { scroll-margin-top: calc(68px + 1rem); }
}
/* Scoped with :has so smooth scrolling is confined to this page and does
   not change how every other page in the site behaves. Where :has is not
   supported the jump simply happens instantly, which is the old behaviour
   and perfectly fine. */
html:has(body.lbf-cx-page) { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html:has(body.lbf-cx-page) { scroll-behavior: auto; }
}

/* ══ 2 · PHOTO CONTEST STRIP ════════════════════════════════════════ */
.cx-contest {
  background: linear-gradient(135deg, #1b1046 0%, #2a1a63 50%, #3b2585 100%);
  border: 2px solid var(--cx-gold);
  color: #fff;
}
.cx-contest__in {
  margin: 0 auto;
  padding: clamp(1.5rem, 3.5vw, 2.2rem) clamp(1.15rem, 3vw, 2.4rem);
  display: grid;
  grid-template-columns: 190px 1fr;
  gap: 1.8rem;
  align-items: center;
}
.cx-contest__mark img { display: block; width: 100%; height: auto; }
.cx-contest__eyebrow {
  display: inline-block;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-weight: 900;
  font-size: .84rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--cx-gold);
  margin-bottom: .35rem;
}
.cx-contest__h {
  font-size: clamp(1.35rem, 3vw, 1.9rem);
  font-weight: 800;
  line-height: 1.2;
  margin: 0 0 .6rem;
  color: #fff;
}
.cx-contest__p {
  margin: 0 0 1rem;
  font-size: 1rem;
  line-height: 1.65;
  max-width: 62ch;
  color: rgba(255,255,255,.9);
}
.cx-contest__p strong { color: var(--cx-gold); }

/* The clock. Four units, ticking every second.

   Colour only on the urgent state, nothing pulses, nothing moves. A page
   carrying bad news should not also be flashing at people.

   tabular-nums is doing real work here: without it the seconds digit
   changes width as it counts and the whole row jitters sideways once a
   second, which is far more distracting than the number itself. */
.cx-clock {
  display: inline-flex;
  align-items: center;
  gap: .85rem;
  flex-wrap: wrap;
  background: rgba(0,0,0,.28);
  border: 1px solid rgba(243,195,3,.35);
  border-radius: 12px;
  padding: .6rem 1rem;
  margin-bottom: 1rem;
}
.cx-clock__say {
  font-size: .78rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: rgba(255,255,255,.72);
  font-weight: 700;
}
.cx-clock__val { display: inline-flex; gap: .5rem; }

.cx-u {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  min-width: 2.9rem;
  background: rgba(255,255,255,.07);
  border-radius: 8px;
  padding: .25rem .35rem;
}
.cx-u__n {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-weight: 900;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--cx-gold);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}
.cx-u__l {
  font-size: .64rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(255,255,255,.6);
  font-weight: 700;
  margin-top: .12rem;
}

.cx-clock.is-urgent {
  border-color: #ff8a3d;
  background: rgba(255,90,20,.18);
}
.cx-clock.is-urgent .cx-u__n { color: #ffb066; }

.cx-clock.is-closed .cx-clock__val { display: block; }
.cx-clock__closed {
  font-family: 'Outfit', system-ui, sans-serif;
  font-weight: 700;
  font-size: .95rem;
  color: var(--cx-gold);
}

@media (max-width: 780px) {
  .cx-clock     { justify-content: center; gap: .6rem; }
  .cx-u         { min-width: 2.6rem; }
  .cx-u__n      { font-size: 1.4rem; }
}

.cx-contest__acts { display: flex; gap: .7rem; flex-wrap: wrap; }

@media (max-width: 780px) {
  .cx-contest__in { grid-template-columns: 1fr; gap: 1.1rem; padding: 1.7rem 1.15rem; text-align: center; }
  .cx-contest__mark { max-width: 170px; margin: 0 auto; }
  .cx-contest__p  { margin-inline: auto; }
  .cx-contest__acts { justify-content: center; }
}

/* ══ BUTTONS ════════════════════════════════════════════════════════ */
.cx-btn {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  background: var(--cx-blue);
  color: #fff;
  font-weight: 800;
  font-size: .95rem;
  padding: .7rem 1.3rem;
  border-radius: 999px;
  text-decoration: none;
  transition: background .18s ease, box-shadow .18s ease, color .18s ease;
}
.cx-btn:hover, .cx-btn:focus-visible {
  background: #0447cf;
  box-shadow: 0 8px 22px rgba(5,55,164,.3);
  color: #fff;
}
.cx-btn--gold { background: var(--cx-gold); color: var(--cx-navy); }
.cx-btn--gold:hover, .cx-btn--gold:focus-visible {
  background: #ffd52b; color: var(--cx-navy);
  box-shadow: 0 8px 24px rgba(243,195,3,.4);
}
.cx-btn--ghost {
  background: transparent;
  color: var(--cx-blue);
  border: 2px solid var(--cx-line);
}
.cx-btn--ghost:hover, .cx-btn--ghost:focus-visible {
  background: var(--cx-blue); color: #fff; border-color: var(--cx-blue);
}
.cx-btn:focus-visible { outline: 3px solid var(--cx-gold); outline-offset: 3px; }

/* ══ 3 · PRESS RELEASE ══════════════════════════════════════════════ */
.cx-release { background: #fff; border: 1px solid var(--cx-line); }
.cx-release__in {
  max-width: 820px;
  margin: 0 auto;
  padding: clamp(1.8rem, 4vw, 3rem) clamp(1.15rem, 3vw, 2.4rem);
}
.cx-release__tag {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-weight: 900;
  font-size: .8rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--cx-blue);
  padding-bottom: .5rem;
  border-bottom: 2px solid var(--cx-line);
  margin-bottom: 1.2rem;
}
.cx-release__h {
  font-size: clamp(1.5rem, 3.4vw, 2.1rem);
  font-weight: 800;
  line-height: 1.22;
  color: var(--cx-navy);
  margin: 0 0 .5rem;
}
.cx-release__sub {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--cx-blue);
  margin: 0 0 1.8rem;
}
/* Measure capped and left-aligned. The column is 780px; at 1rem that runs
   to roughly 95 characters a line against a comfortable 60–75, and this is
   400 words of copy people have to actually read. */
.cx-release__body p {
  max-width: 66ch;
  margin: 0 0 1.15rem;
  font-size: 1.02rem;
  line-height: 1.72;
  color: #2b3550;
  text-wrap: pretty;
}
.cx-release__dateline { font-weight: 800; color: var(--cx-navy); }
.cx-release__h3 {
  font-size: 1.14rem;
  font-weight: 800;
  color: var(--cx-blue);
  margin: 1.9rem 0 .55rem;
  line-height: 1.35;
}
.cx-release__sig {
  margin-top: 2.2rem;
  padding-top: 1.2rem;
  border-top: 2px solid var(--cx-line);
  display: flex;
  flex-direction: column;
  gap: .12rem;
  font-size: .95rem;
  color: var(--cx-mute);
}
.cx-release__sig strong { color: var(--cx-navy); font-size: 1rem; }
.cx-release__sig a { color: var(--cx-blue); font-weight: 700; }

@media (max-width: 640px) {
  .cx-release__in   { padding: 2.2rem 1.15rem; }
  .cx-release__body p { max-width: none; font-size: .98rem; }
}

/* ══ 4 · THE THREE SECTIONS ═════════════════════════════════════════ */
.cx-still { background: var(--cx-cream); border: 1px solid var(--cx-line); }
.cx-still__in {
  margin: 0 auto;
  padding: clamp(1.8rem, 4vw, 3rem) clamp(1.15rem, 3vw, 2.4rem);
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
}
.cx-still__hd { text-align: center; margin-bottom: .4rem; }
.cx-still__eyebrow {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-weight: 900;
  font-size: .86rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--cx-blue);
}
.cx-still__h {
  font-size: clamp(1.7rem, 4vw, 2.4rem);
  font-weight: 800;
  color: var(--cx-navy);
  margin: .3rem 0 0;
}

.cx-card {
  display: grid;
  grid-template-columns: 210px 1fr;
  gap: 1.6rem;
  align-items: center;
  background: #fff;
  border: 1px solid var(--cx-line);
  border-radius: 18px;
  padding: 1.7rem;
  box-shadow: 0 6px 20px rgba(5,55,164,.07);
}
/* Art panel. Deliberately an icon plate rather than a photograph: there are
   no photographs of these three as they will happen this year, and a stock
   crowd shot on a cancellation page reads as a stock crowd shot. */
/* LIGHT PLATES. These were navy, purple and green gradients holding white
   line icons. All three real logos are navy-and-gold artwork on transparent
   backgrounds, drawn for white, the Crownings mark in particular is navy
   on navy and would have all but vanished on the old plate. So the plate
   becomes the paper the logo was designed for, which also matches how the
   same three marks are presented inside the banner panel. */
.cx-card__art {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  border-radius: 14px;
  background: linear-gradient(160deg, #ffffff 0%, var(--cx-cream) 100%);
  border: 1px solid var(--cx-line);
  padding: 1.1rem;
}
/* contain, never cover: these are logos, and cropping one is worse than
   leaving space around it. The crownings mark is 600x558 rather than
   square, so it letterboxes slightly and that is correct. */
.cx-card__art picture,
.cx-card__art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* A faint wash per event so the three still read as distinct at a glance,
   without putting anything behind the artwork that could fight it. */
.cx-card__art--crown  { background: linear-gradient(160deg, #ffffff 0%, #f2f6ff 100%); }
.cx-card__art--plate  { background: linear-gradient(160deg, #ffffff 0%, #f7f4ff 100%); }
.cx-card__art--parade { background: linear-gradient(160deg, #ffffff 0%, #f1fbf7 100%); }

.cx-card__day {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-weight: 900;
  font-size: .82rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--cx-blue);
}
.cx-card__h {
  font-size: clamp(1.25rem, 2.6vw, 1.6rem);
  font-weight: 800;
  color: var(--cx-navy);
  margin: .25rem 0 .6rem;
  line-height: 1.25;
}
.cx-card__p {
  margin: 0 0 .8rem;
  font-size: 1rem;
  line-height: 1.65;
  color: #45506b;
  max-width: 60ch;
}
.cx-card__open,
.cx-card__closed {
  margin: 0 0 .9rem;
  padding: .6rem .85rem;
  border-radius: 9px;
  font-size: .93rem;
  line-height: 1.5;
  max-width: 60ch;
}
.cx-card__open   { background: rgba(18,160,116,.1); border-left: 4px solid #12a074; color: #0a5b43; }
.cx-card__closed { background: rgba(243,195,3,.14); border-left: 4px solid var(--cx-gold); color: #6b5300; }
.cx-card__facts { list-style: none; margin: 0 0 1rem; padding: 0; display: flex; flex-direction: column; gap: .35rem; }
.cx-card__facts li {
  display: flex; align-items: center; gap: .5rem;
  font-size: .95rem; font-weight: 600; color: var(--cx-ink);
}
.cx-i { font-size: .95rem; line-height: 1; }
.cx-card__done { margin: 0; font-weight: 700; color: var(--cx-blue); font-size: .95rem; }

/* Image right, copy left on the middle card, so the three do not read as a
   column of identical blocks. */
.cx-card--flip { grid-template-columns: 1fr 210px; }
.cx-card--flip .cx-card__art { order: 2; }

/* Finished events fade rather than disappear. A section that vanishes
   mid-weekend makes the page look broken to somebody who was reading it an
   hour before. */
.cx-card.is-past { opacity: .62; }
.cx-card.is-past .cx-card__art { filter: grayscale(.7); }

@media (max-width: 820px) {
  .cx-card,
  .cx-card--flip { grid-template-columns: 1fr; gap: 1.1rem; padding: 1.3rem; }
  .cx-card--flip .cx-card__art { order: 0; }
  .cx-card__art { aspect-ratio: 5 / 2; padding: .7rem; }
  .cx-card__art img { max-height: 110px; }
  .cx-still__in { padding: 2.4rem 1.15rem; }
}

/* ══ 5 · FAQ ════════════════════════════════════════════════════════ */
.cx-faq { background: #fff; border: 1px solid var(--cx-line); }
.cx-faq__in { max-width: 900px; margin: 0 auto; padding: clamp(1.8rem, 4vw, 3rem) clamp(1.15rem, 3vw, 2.4rem); }
.cx-faq__hd { text-align: center; margin-bottom: 1.6rem; }
.cx-faq__eyebrow {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-weight: 900; font-size: .86rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--cx-blue);
}
.cx-faq__h {
  font-size: clamp(1.6rem, 3.6vw, 2.1rem);
  font-weight: 800; color: var(--cx-navy); margin: .3rem 0 0;
}

.cx-q {
  border: 1px solid var(--cx-line);
  border-radius: 12px;
  margin-bottom: .6rem;
  background: #fff;
  overflow: hidden;
}
.cx-q[open] { border-color: rgba(5,55,164,.3); box-shadow: 0 6px 20px rgba(5,55,164,.07); }
.cx-q__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.15rem;
  cursor: pointer;
  font-weight: 700;
  font-size: 1.02rem;
  color: var(--cx-navy);
  line-height: 1.4;
  list-style: none;
  transition: background .15s ease, color .15s ease;
}
.cx-q__q::-webkit-details-marker { display: none; }
.cx-q__q:hover { background: rgba(5,55,164,.04); color: var(--cx-blue); }
.cx-q__q:focus-visible { outline: 3px solid var(--cx-gold); outline-offset: -3px; }

/* Plus / minus drawn in CSS. A rotating chevron would be a transform on an
   element inside a block that changes height as it opens, the exact pair
   that caused the scroll jerk fixed in 32.96.0. Swapping which bar is
   visible costs nothing and cannot reach layout. */
.cx-q__mark { position: relative; flex: none; width: 18px; height: 18px; }
.cx-q__mark::before,
.cx-q__mark::after {
  content: '';
  position: absolute;
  background: var(--cx-blue);
  border-radius: 2px;
}
.cx-q__mark::before { inset: 8px 0 8px 0; height: 2px; }
.cx-q__mark::after  { inset: 0 8px 0 8px; width: 2px; }
.cx-q[open] .cx-q__mark::after { opacity: 0; }

.cx-q__a { padding: 0 1.15rem 1.15rem; }
.cx-q__a p {
  margin: 0 0 .75rem;
  font-size: .98rem;
  line-height: 1.68;
  color: #45506b;
  max-width: 64ch;
}
.cx-q__a p:last-child { margin-bottom: 0; }
.cx-q__a a { color: var(--cx-blue); font-weight: 700; }

@media (max-width: 640px) {
  .cx-faq__in { padding: 2.2rem 1.15rem; }
  .cx-q__q    { font-size: .96rem; padding: .85rem 1rem; }
  .cx-q__a    { padding: 0 1rem 1rem; }
}

/* ══ 6 · CLOSE ══════════════════════════════════════════════════════ */
.cx-close {
  background: linear-gradient(135deg, var(--cx-navy) 0%, #05123a 60%, var(--cx-blue) 100%);
  color: #fff;
}
.cx-close__in {
  max-width: 720px;
  margin: 0 auto;
  padding: clamp(1.8rem, 4vw, 2.8rem) 1.5rem;
  text-align: center;
}
.cx-close__p {
  margin: 0 0 1.3rem;
  font-size: 1.08rem;
  line-height: 1.7;
  color: rgba(255,255,255,.92);
}
.cx-close .cx-btn--ghost { color: #fff; border-color: rgba(255,255,255,.4); }
.cx-close .cx-btn--ghost:hover,
.cx-close .cx-btn--ghost:focus-visible {
  background: var(--cx-gold); color: var(--cx-navy); border-color: var(--cx-gold);
}

/* ══ REDUCED MOTION ═════════════════════════════════════════════════
   Nothing here animates position, so there is little to switch off, but
   the colour transitions on buttons and rows still go. */
@media (prefers-reduced-motion: reduce) {
  .lbf-cx *,
  .lbf-cx-bar * { transition: none !important; animation: none !important; }
}

/* ══ PRINT ══════════════════════════════════════════════════════════
   People will print the release and pin it up. */
@media print {
  .lbf-cx-bar,
  .cx-contest__acts,
  .cx-close,
  .cx-clock { display: none !important; }
  .lbf-cx { background: #fff !important; }
  .cx-q { break-inside: avoid; }
  .cx-q__a { display: block !important; }
  .cx-card { break-inside: avoid; box-shadow: none; border: 1px solid #ccc; }
}

/* ══ READ MORE (press release fold) ═════════════════════════════════
   Native details/summary. The hidden half is real HTML, not something
   fetched on click, so search engines and screen readers get the whole
   release either way and it expands with no page jump.

   No transform on the arrow. A rotating chevron inside a block that grows
   as it opens is the exact pair that caused the scroll jerk fixed in
   32.96.0; the arrow simply flips which way it points via the two label
   spans instead.
─────────────────────────────────────────────────────────────────── */
.cx-more { margin: .4rem 0 0; }
.cx-more__btn {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  cursor: pointer;
  list-style: none;
  font-weight: 800;
  font-size: .95rem;
  color: var(--cx-blue);
  background: rgba(5,55,164,.06);
  border: 1px solid var(--cx-line);
  border-radius: 999px;
  padding: .6rem 1.15rem;
  transition: background .18s ease, color .18s ease;
}
.cx-more__btn::-webkit-details-marker { display: none; }
.cx-more__btn:hover { background: var(--cx-blue); color: #fff; }
.cx-more__btn:focus-visible { outline: 3px solid var(--cx-gold); outline-offset: 2px; }
.cx-more__hide { display: none; }
.cx-more[open] .cx-more__show { display: none; }
.cx-more[open] .cx-more__hide { display: inline; }
.cx-more[open] .cx-more__btn svg { rotate: 180deg; }
.cx-more__body { padding-top: 1.2rem; }

/* The fold is softened while closed so the text visibly continues rather
   than stopping mid-thought at a hard edge. Removed once open. */
.cx-release__body > p:last-of-type { position: relative; }
.cx-more:not([open]) { position: relative; }
.cx-more:not([open])::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: -3.2rem;
  height: 3.2rem;
  background: linear-gradient(180deg, rgba(255,255,255,0), #fff 92%);
  pointer-events: none;
}

@media print {
  .cx-more__btn { display: none !important; }
  .cx-more__body { display: block !important; padding-top: 0; }
  .cx-more:not([open])::before { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   MOTION                                                    v33.1.0
   ───────────────────────────────────────────────────────────────────
   THE ONE RULE HERE: nothing that moves may affect layout, and nothing
   at all moves during a scroll.

   32.96.0 and 32.97.0 were both spent removing scroll-driven transforms
   from this theme. The cause each time was the same pair, will-change
   promoting elements to their own compositing layers as they scrolled
   into view, and translateY animating under the browser's scroll
   anchoring, which makes it re-pick an anchor and correct the scroll
   position. That is the flashing and the jerk.

   So the reveal is a PLAIN OPACITY FADE. No transform, no will-change.
   A fade touches no layout, creates no compositing layer and gives
   scroll anchoring nothing to chase.

   The micro-motion is all either (a) hover, which is user-initiated and
   never happens mid-scroll, or (b) on a pseudo-element or an absolutely
   positioned child, which is out of flow and cannot reach layout.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Scroll reveal: opacity only ────────────────────────────────── */
.lbf-cx [data-cx-rv] {
  opacity: 0;
  transition: opacity .72s cubic-bezier(.22,.61,.36,1);
}
.lbf-cx [data-cx-rv].is-in { opacity: 1; }

/* Children stagger behind their parent so a card's contents arrive in
   reading order instead of all at once. Delay only, no movement. */
.lbf-cx [data-cx-rv][data-cx-d="1"] { transition-delay: .07s; }
.lbf-cx [data-cx-rv][data-cx-d="2"] { transition-delay: .14s; }
.lbf-cx [data-cx-rv][data-cx-d="3"] { transition-delay: .21s; }
.lbf-cx [data-cx-rv][data-cx-d="4"] { transition-delay: .28s; }

/* ── Card hover: lift and warm ──────────────────────────────────── */
.cx-card {
  transition: box-shadow .26s ease, border-color .26s ease;
}
.cx-card:hover {
  border-color: rgba(5,55,164,.34);
  box-shadow: 0 16px 44px rgba(5,55,164,.16);
}
.cx-card.is-past:hover { box-shadow: 0 6px 20px rgba(5,55,164,.07); }

/* The art plate breathes on hover. Scale on an element inside a card that
   clips its own overflow, it cannot push anything or reach the scroll
   region, and it only runs while the pointer is on it. */
.cx-card__art {
  /* position + overflow together, deliberately: the ::after sheen is
     absolutely positioned against this box and clipped by it. Split across
     two rules they are one careless edit away from the sheen escaping
     across the whole card. */
  position: relative;
  overflow: hidden;
  transition: box-shadow .3s ease;
}
.cx-card__art img {
  transition: scale .45s cubic-bezier(.22,.61,.36,1);
}
.cx-card:hover .cx-card__art img { scale: 1.05; }

/* A slow gold sweep across the plate on hover. Painted only while
   hovered, so it costs nothing at rest, and it runs ONCE per hover
   rather than looping, a repeating shine reads as a button demanding
   to be pressed. Clipped by the plate's own overflow. */
.cx-card__art::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.22) 50%, transparent 62%);
  translate: -110% 0;
  opacity: 0;
  pointer-events: none;
}
.cx-card:hover .cx-card__art::after {
  opacity: 1;
  animation: cx-sweep .85s ease-out 1;
}
@keyframes cx-sweep {
  from { translate: -110% 0; }
  to   { translate: 110% 0; }
}

/* ── The contest logo drifts, very slightly ─────────────────────── */
.cx-contest__mark img {
  animation: cx-drift 7s ease-in-out infinite;
}
@keyframes cx-drift {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -5px; }
}

/* ── Buttons ────────────────────────────────────────────────────── */
.cx-btn { position: relative; overflow: hidden; }
.cx-btn > svg { transition: translate .22s ease; }
.cx-btn:hover > svg { translate: 3px 0; }

/* ── FAQ rows warm and indent on hover ──────────────────────────── */
.cx-q { transition: border-color .2s ease, box-shadow .2s ease; }
.cx-q__q { transition: background .18s ease, color .18s ease, padding-left .2s ease; }
.cx-q__q:hover { padding-left: 1.45rem; }

/* ── Notice bar arrow ───────────────────────────────────────────── */
.lbf-cx-bar__cta svg { transition: translate .2s ease; }
.lbf-cx-bar__cta:hover svg { translate: 3px 0; }

/* ── REDUCED MOTION ─────────────────────────────────────────────
   Everything off, and, the part that matters, the reveal is pinned
   VISIBLE. A reveal that is switched off while its hidden state stays
   applied is a blank page, which is how this pattern usually fails. */
@media (prefers-reduced-motion: reduce) {
  .lbf-cx [data-cx-rv],
  .lbf-cx [data-cx-rv].is-in {
    opacity: 1 !important;
    transition: none !important;
  }
  .cx-contest__mark img,
  .cx-card__art::after { animation: none !important; }
  .cx-card:hover .cx-card__art img,
  .cx-btn:hover > svg,
  .lbf-cx-bar__cta:hover svg { scale: 1; translate: 0 0; }
  .cx-q__q:hover { padding-left: 1.15rem; }
}
