/*
 * Theme Name:   5U Worlds
 * Theme URI:    https://fiveandunderworldchampionship.com
 * Description:  Child theme for the Five and Under World Championship website,
 *               based on Twenty Twenty-Four.
 * Author:       Five and Under World Championship
 * Template:     twentytwentyfour
 * Version:      1.0.1
 */


/* ============================================================
   COLOR & TYPOGRAPHY TOKENS
   These custom properties drive every color decision on the site.
   Change a value here and it updates everywhere.
   ============================================================ */

:root {
  /* Brand colors

     SEMANTIC ROLES — the rule of thumb for using these going
     forward, established while building the nav's interaction
     states. Keep new sections consistent with this:

     --5u-red    : primary CTA / actionable buttons only
                   ("click this, it does something" — e.g. the
                   "2026 Event Details" button)
     --5u-gold   : highlighted but NON-interactive — section tags,
                   labels, dividers/accents, and disabled/future
                   states like the Shop "coming soon" button.
                   Reserved meaning: notable, not clickable.
     --5u-slate  : resting state for plain links/nav text, and
                   also used for keyboard focus outlines (so focus
                   stays visually distinct from both hover and
                   from gold's "disabled" meaning)
     --5u-ice-white : hover/active brightening — "this is
                   interactive and you're engaged with it" — also
                   primary body text color on dark backgrounds
  */
  --5u-navy-deepest:  #060E16;  /* footer background */
  --5u-navy-dark:     #0A1520;  /* nav, event strip, champion card headers */
  --5u-navy-base:     #0D1B2A;  /* hero (dark mode), champion section (dark mode) */
  --5u-navy-lift:     #112233;  /* sponsors, mission (dark mode) */
  --5u-navy-mid:      #0F2236;  /* explainer section (dark mode) */
  --5u-red:           #C8102E;  /* primary CTA, accent */
  --5u-red-hover:     #a50d25;
  --5u-gold:          #B8972A;  /* section labels, footer headings, borders */

  /* Medal-tier accents — Champions page only. Deliberately distinct
     from --5u-gold above: --5u-gold is reserved for non-interactive
     "notable" UI (section tags, disabled states) per the semantic
     rule documented above, not for literal medal coloring. These
     three are purely representational (this team won gold/silver/
     bronze), so they get their own tokens rather than overloading
     --5u-gold with a second meaning. */
  --5u-medal-gold:    #D4AF37;
  --5u-medal-silver:  #9DA7B0;
  --5u-medal-bronze:  #B08D57;
  --5u-ice-white:     #F0F4F8;  /* primary text on dark */
  --5u-slate:         #8FA3B1;  /* secondary text on dark */
  --5u-slate-dim:     #6B7C93;  /* muted text, strip labels */
  --5u-slate-dimmer:  #4A5E6D;  /* very muted text */
  --5u-slate-dimmest: #3A4E5C;  /* footer link color */

  /* Light mode surface colors */
  --5u-light-page:       #F7F8FA;
  --5u-light-surface:    #ffffff;
  --5u-light-surface-alt:#F0F4F8;
  --5u-light-border:     #E2E8EF;
  --5u-light-text:       #1A2733;
  --5u-light-text-body:  #3A4E5C;
  --5u-light-text-muted: #4A5E6D;

  /* Typography */
  --5u-font-display: 'Barlow Condensed', sans-serif;
  --5u-font-body:    'Barlow', sans-serif;

  /* Layout
     Full-width sections (nav, colored bands) stay edge-to-edge.
     This caps the INNER content of each section so text and
     elements don't stretch absurdly wide on large monitors —
     same pattern used by Silicon Valley Curling's site, which
     keeps a full-width nav but caps body content at a sane width.

     SINGLE SOURCE OF TRUTH: WordPress automatically generates a
     CSS custom property --wp--style--global--content-size from
     theme.json's settings.layout.contentSize value. Rather than
     hardcoding 1232px a second time here, we reference that
     generated property directly — so theme.json is the only place
     the actual number lives. If you ever change the site's content
     width, update ONLY theme.json's contentSize; this variable (and
     therefore every section on the homepage) follows automatically.
     The hardcoded 1232px below is a fallback only, used if that
     custom property is ever unavailable (e.g. theme.json failing
     to load), and should be kept roughly in sync as a safety net,
     though it is no longer the actively-used value in normal
     operation. */
  --5u-content-max: var(--wp--style--global--content-size, 1232px);

  /* The ACTUAL visible content box width is narrower than
     --5u-content-max once you account for the section padding
     that insets content from the section's own edges (32px each
     side at minimum, per .su-hero/.su-strip/etc's calculated
     padding). Font-size clamps that used raw --5u-content-max as
     their MAX ceiling were calibrated to a wider box than the one
     they actually render inside — the visible content area only
     reaches the FULL --5u-content-max width once the viewport is
     content-max + (padding × 2) wide, creating a "dead zone" where
     the content box is already at full width but text was still
     using a smaller calculated max (confirmed via testing: with
     32px padding each side, this zone spans roughly 1232–1296px
     viewport width). Use THIS variable, not --5u-content-max
     directly, when sizing text that should hold steady exactly
     when the content box itself stops growing. */
  --5u-content-visible: calc(var(--5u-content-max) - 64px);

  /* The rings SVG's hatch pattern and "empty" alternating rings
     (8ft, button) need to paint the SAME color as whatever sits
     directly behind the rings graphic — i.e. .su-hero's own
     background — so the hatch punches genuinely show as "gaps"
     rather than a mismatched color. Defaults to light mode's hero
     background; overridden in body.dark-mode below to match dark
     mode's hero background instead. If .su-hero's background ever
     changes, update this variable to match, in both places. */
  --5u-rings-bg: var(--5u-light-surface);

  /* Rings stroke/line color. Gold reads fine against the dark
     hero background (--5u-navy-base) but has too little contrast
     against light mode's white background to register as a visible
     texture at the rings' low opacity — confirmed via screenshot,
     where gold-on-white was nearly invisible aside from the pin
     dot. --5u-slate-dimmer was chosen over gold-darkened-further
     or plain --5u-slate: darkening gold risked reading as muddy/
     brown, and --5u-slate itself is actually similarly low-contrast
     against white (both sit in a pale midtone band) — slate-dimmer
     is meaningfully darker (roughly 2.4x the contrast ratio against
     white) while staying a cool blue-gray rather than warming
     toward brown. Defaults to light mode's value here; overridden
     in body.dark-mode below back to gold, which already works
     correctly against the dark hero. */
  --5u-rings-line: var(--5u-slate-dimmer);

  /* Hatch pattern line color — deliberately the OPPOSITE of
     --5u-rings-line in each mode (gold here, where the solid ring
     strokes are slate-dimmer). This gives the two hatched rings
     (12ft, 4ft) a visibly different tone from the two solid-stroke
     rings (8ft, button) they alternate with, so the alternating
     pattern reads more clearly as a pattern rather than a flat
     texture — confirmed as an improvement via side-by-side
     screenshot. Both colors stay subdued enough at the rings' low
     opacity that the motif stays recessive either way; this is a
     refinement of the texture, not a contrast fix like
     --5u-rings-line was. Overridden in body.dark-mode below to the
     opposite pairing (slate-dimmer hatch, gold strokes). */
  --5u-rings-hatch: var(--5u-gold);

  /* Spacing */
  --5u-section-pad: 38px 32px;
}



/* ============================================================
   GOOGLE FONTS
   Previously loaded here via @import — moved to a proper
   wp_enqueue_style() call in functions.php instead, since
   @import is unreliable in production (slower, sometimes
   stripped by caching/minification, sometimes blocked by CSP).
   See the comment in functions.php's fiveunder_enqueue_styles()
   for the full explanation. This is the actual likely cause of
   Barlow/Barlow Condensed not rendering on the live site and
   silently falling back to the browser's default sans-serif.
   ============================================================ */


/* ============================================================
   GLOBAL RESETS FOR TWENTYTWENTYFOUR
   TT4 applies some opinionated defaults we need to tame.
   ============================================================ */

/* overflow-x: hidden on BOTH html and body — body alone was tried
   first and confirmed NOT sufficient (still scrolled horizontally
   on iPad/phone after that fix shipped). The root cause: the
   actual viewport-level horizontal scrollbar is governed by the
   ROOT element (<html>), not <body> — per browser behavior, when
   the root element's own overflow isn't constrained, an
   overflowing descendant's box can still create a page-level
   scrollbar regardless of what <body> alone specifies, because
   <body>'s overflow only contains scrolling WITHIN <body>'s own
   box, not the viewport's scroll root. Setting it on <html> is
   what actually stops a full-bleed negative-margin element (see
   .su-champ-grid) from widening the page. */
html {
  overflow-x: hidden;
  width: 100%;
}

body {
  font-family: var(--5u-font-body);
  font-size: 15px;
  line-height: 1.65;
  background: var(--5u-light-page);
  color: var(--5u-light-text);
  /* Safeguard against full-bleed elements with negative margins
     (e.g. .su-champ-grid's intentional bleed past --5u-content-max
     toward the viewport edge) widening the PAGE's own horizontal
     scroll area. A child can legally extend past its parent's edge
     via negative margin; without something in the ancestor chain
     clipping that overflow, it propagates all the way up to the
     document, creating page-level horizontal scroll. See the
     matching rule on <html> above — that's the one actually doing
     the work; this is kept too for defense in depth, since some
     browsers honor either depending on quirks/standards mode. */
  overflow-x: hidden;
  width: 100%;
}

/* STICKY FOOTER — keeps the footer pinned to the bottom of the
   viewport on short pages instead of floating up directly under
   the content, while staying out of view (below the fold) until
   scrolled to on long pages. WordPress block themes wrap the
   header/main-content/footer template parts in a single
   ".wp-site-blocks" div, a direct child of body — confirmed via
   devtools — so that's the flex container that needs to stretch to
   at least the viewport height, with the main content area (not
   header/footer) absorbing any extra space. */
.wp-site-blocks {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.wp-site-blocks > main {
  flex: 1 0 auto;
}

/* Dark mode — applied to <body> by theme.js */
body.dark-mode {
  background: var(--5u-navy-base);
  color: var(--5u-ice-white);
  --5u-rings-bg: var(--5u-navy-base);
  --5u-rings-line: var(--5u-gold);
  --5u-rings-hatch: var(--5u-slate-dimmer);
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--5u-font-display);
}

/* TT4 sets its own explicit heading color via theme.json
   (generated as a :root :where(h1,h2,...) rule), which doesn't
   change with our manual dark-mode toggle — confirmed as the cause
   of headings staying dark-text-colored even on a dark background
   on regular Gutenberg pages. :where() carries zero specificity, so
   a plain element selector here can't outrank it; !important is the
   reliable fix, same approach used elsewhere in this file for
   overriding WP/TT4-generated styles. */
body.dark-mode h1,
body.dark-mode h2,
body.dark-mode h3,
body.dark-mode h4,
body.dark-mode h5,
body.dark-mode h6 {
  color: var(--5u-ice-white) !important;
}

a {
  color: var(--5u-red);
  text-decoration: none;
}

/* Dark mode: plain content links (History, Champions, etc. — not
   homepage-specific classes like .su-link, which already have their
   own treatment) used the same red as primary CTA buttons, which
   reads as harsh against the dark navy background and blurs the
   "red = actionable button" semantic this token is meant to carry
   elsewhere. Matches the resting/hover language already documented
   at the top of this file for nav links (slate resting, ice-white
   brightening on hover) instead of inventing a new pairing. Light
   mode is intentionally left as red — not flagged as a problem. */
body.dark-mode a {
  color: var(--5u-slate);
}

body.dark-mode a:hover {
  color: var(--5u-ice-white);
}


/* ============================================================
   TWENTYTWENTYFOUR LAYOUT OVERRIDES — HOMEPAGE ONLY
   These rules strip WP's native content width cap and inter-block
   spacing so the homepage's Custom HTML block can go full-bleed and
   control its own section padding directly. Scoped to body.home
   (the class WP adds to whichever page is set as the static
   homepage in Settings -> Reading) — without this scoping, these
   rules were applying site-wide, which is why other native-
   Gutenberg pages (History, Champions, etc.) had no content
   max-width and squashed block spacing: theme.json's contentSize
   and WP's default block gap were being stripped from them too,
   not just from the homepage they were actually meant for.
   ============================================================ */

/* Belt-and-suspenders on width — theme.json sets contentSize
   to 100% but some constrained layout wrappers need this too */
body.home .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
  max-width: 100% !important;
}

body.home .wp-site-blocks,
body.home .wp-block-post-content,
body.home .entry-content {
  padding-left: 0 !important;
  padding-right: 0 !important;
  max-width: 100% !important;
}

/* Remove any remaining inter-block margins */
body.home .is-layout-flow > * + *,
body.home .wp-block-post-content > * + * {
  margin-top: 0 !important;
}

/* Hide the Post Title block.
   theme.json sets its color to transparent and font-size to 0,
   but display:none here ensures it takes up no space at all. */
.wp-block-post-title,
h1.wp-block-post-title {
  display: none !important;
}

/* TT4's page template wraps the (hidden) title in two Spacer
   blocks — one above, one below — that reserve vertical space
   regardless of whether the title itself is visible. Hiding the
   title alone left ~144px of dead space at the top of every page.
   These spacers use TT4's preset spacing scale (--wp--preset--
   spacing--50 and --30), so we target the spacer elements
   directly rather than guessing pixel values, since that scale
   can vary by TT4 version. */
.wp-block-post-title + .wp-block-spacer,
.wp-block-spacer:has(+ .wp-block-post-title),
.wp-block-spacer:has(+ h1.wp-block-post-title) {
  display: none !important;
}

/* Belt-and-suspenders: collapse the entire Group wrapping the
   title and its spacers down to zero height, in case the above
   :has() selectors don't catch every spacer (e.g. if TT4 changes
   the exact sibling structure in a future update). */
.wp-block-group:has(> h1.wp-block-post-title) {
  min-height: 0 !important;
  height: 0 !important;
  overflow: hidden;
  margin: 0 !important;
  padding: 0 !important;
}

/* Full width for our Custom HTML block.
   NOTE: theme.json sets contentSize to 1232px, which WordPress
   automatically exposes as the CSS variable
   --wp--style--global--content-size. Our own --5u-content-max
   variable (defined at the top of this file) reads directly from
   that generated property, so theme.json is the single source of
   truth for the site's content width — this homepage's hand-
   written calc()-based section padding and any other page built
   with native Gutenberg blocks both ultimately derive from the
   same one number, even though they apply it through different
   mechanisms (this page can't use theme.json's layout system
   directly since it's a Custom HTML block, not native blocks). */
.wp-block-html {
  max-width: 100% !important;
  width: 100% !important;
  padding: 0 !important;
  margin: 0 !important;
}


/* ============================================================
   NATIVE PAGE CONTENT — SIDE PADDING (non-homepage pages: History,
   Champions, About, etc.)

   theme.json's `styles.spacing.padding` is set to 0 on all sides
   site-wide (needed for the homepage's full-bleed Custom HTML
   block), and theme.json has no mechanism to scope that to the
   homepage only — it isn't a body-class-aware system like the CSS
   overrides above. That 0 padding lands on .wp-block-post-content
   on EVERY page, not just the homepage.

   This is invisible at wide viewports because WP/TT4's native
   "constrained" layout already centers .wp-block-post-content at
   --5u-content-max width with auto side margins — at those widths,
   the empty space outside that centered box reads as if it were
   padding. But once the viewport narrows to roughly --5u-content-max
   or below, that auto-margin collapses to 0 and the content box
   becomes exactly viewport-width with its own padding still 0 — so
   text runs flush to the screen edge. This reproduces identically
   on desktop (narrow/resized browser window) and on every mobile
   breakpoint, which is why it can't be fixed inside a single
   max-width media query — it isn't a breakpoint-specific bug, it's
   a missing inset that's been there at every width all along, just
   masked by the centering at wide viewports.

   Fix: restore side padding directly on .wp-block-post-content,
   scoped to non-homepage pages so the homepage's full-bleed setup
   (handled separately above) is untouched. No !important needed —
   theme.json's generated rule uses :where() (zero specificity), so
   a plain class selector already outranks it. Same max(32px,
   calc(...)) inset formula as every homepage section, so native
   pages end up with the same effective ~1168px inner content width
   as the homepage instead of inventing a different number. */
body:not(.home) .wp-block-post-content {
  padding-left: max(32px, calc((100% - var(--5u-content-max)) / 2));
  padding-right: max(32px, calc((100% - var(--5u-content-max)) / 2));
  box-sizing: border-box;
}


/* ============================================================
   NAVIGATION
   TT4's site header block gets a custom class "su-nav" applied
   in the Site Editor (select the Header template part,
   add "su-nav" to the block's Additional CSS class field).
   ============================================================ */

.su-nav,
.wp-block-template-part.su-nav {
  background: var(--5u-light-surface) !important;
  border-bottom: 2px solid var(--5u-gold);
  min-height: 54px;

  /* Sticky header */
  position: sticky;
  top: 0;
  z-index: 100;
}

/* Light mode is the default above — nav was previously a permanent
   dark band regardless of mode (same family as the footer), but
   confirmed direct request to make it toggle-aware: as a thick,
   high-contrast persistent element, it disproportionately dominated
   the page once everything else switched to light. Every other
   color rule in this nav block gets the same dark-mode override
   treatment below, for the same reason. */
body.dark-mode .su-nav,
body.dark-mode .wp-block-template-part.su-nav {
  background: var(--5u-navy-dark) !important;
}

/* The outer "su-nav" group itself carries .alignwide, which TT4's
   own stylesheet caps at a fixed max-width via the --wp--style--
   global--wide-size custom property and a centering margin.
   Override directly on the class WordPress actually renders. */
.su-nav.alignwide {
  max-width: 100% !important;
  width: 100% !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  padding-left: 16px !important;
  padding-right: 28px !important;
  box-sizing: border-box;
}

/* The inner row (logo + nav) is ALSO .alignwide, nested one level
   in. Same fix needed here, plus this is the flex row that should
   actually stretch and space its children apart. */
.su-nav .wp-block-group.alignwide {
  max-width: 100% !important;
  width: 100% !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}

/* CRITICAL: force the logo+nav row to stay on one line.
   TT4's flex group defaults to wrapping, and once the outer
   width grew to 100%, the gap between the two flex children
   exceeded the row's available space calculation and the nav
   dropped to a second line.

   NOTE: WordPress core's own .is-layout-flex base rule sets
   flex-wrap: wrap with no !important, but it was still beating
   our rule due to selector specificity / load order. The extra
   class repetition below (.su-nav.su-nav) artificially boosts
   specificity past core's single-class selector without relying
   on cascade order.

   IMPORTANT: every selector here is scoped with :not() to exclude
   anything inside the mobile responsive container. Earlier broader
   versions of these rules (especially the unscoped is-layout-flex
   rule and a bare div.wp-block-group selector with no .su-nav
   ancestor) were matching elements inside the mobile menu overlay
   too, interfering with TT4's own show/hide breakpoint logic and
   causing the mobile nav list to render inline in the desktop bar. */
.su-nav > .wp-block-group.alignwide.is-content-justification-space-between {
  flex-wrap: nowrap !important;
  align-items: center !important;
  width: 100%;
}

/* The two direct children (logo group, nav group) should not
   shrink to zero or grow unexpectedly — keep them sized to content.
   Scoped to the direct child of the top-level row only. */
.su-nav > .wp-block-group.alignwide.is-content-justification-space-between > .wp-block-group {
  flex: 0 0 auto !important;
}

/* Collapse the empty flow group WordPress inserts after the logo
   (an artifact of the Site Logo block's internal structure) so it
   doesn't add phantom width */
.su-nav .wp-block-site-logo + .wp-block-group.is-layout-flow:empty {
  display: none !important;
}

/* Logo is set to 96x96 in the Site Logo block itself (desktop size),
   which is too large on tablet/phone. Step it down at the same two
   breakpoints as the rest of the site rather than relying on the
   block's own fixed width/height attributes. */
.su-nav .wp-block-site-logo img {
  width: 96px !important;
  height: 96px !important;
}

/* is-layout-constrained adds TT4's default inner padding/margin
   behavior — neutralize ONLY on the top-level desktop nav row's
   own descendants, explicitly excluding anything inside the
   mobile responsive container so we never touch its internal
   layout or interfere with TT4's breakpoint visibility toggle. */
.su-nav > .wp-block-group.is-layout-constrained,
.su-nav > .wp-block-group .is-layout-constrained:not(.wp-block-navigation__responsive-container *),
.su-nav > .wp-block-group .is-layout-flex:not(.wp-block-navigation__responsive-container *) {
  max-width: 100% !important;
}

/* NOTE: TT4 uses a single nav link list for both desktop and
   mobile — there is no separate "desktop horizontal nav" element.
   The same <ul> lives inside .wp-block-navigation__responsive-
   container at all times, and TT4's own JS/CSS toggles it between
   a horizontal row (wide viewports) and the slide-out overlay
   (narrow viewports) by adding/removing .is-menu-open and other
   internal state — NOT by swapping in different markup.

   An earlier version of this stylesheet added a blanket
   "display: none unless .is-menu-open" rule here as a safeguard,
   assuming a separate desktop nav existed elsewhere. It didn't —
   that rule was hiding the only copy of the links that exists,
   which broke desktop entirely. Do not re-add a rule like that;
   let TT4 manage visibility/positioning of the responsive
   container itself, and only style content WITHIN whichever
   state is currently active. */

/* Logo stays left, nav block pushes right via space-between
   (already set as is-content-justification-space-between by your
   block setup) — this just guarantees full available width to work with */
.su-nav .wp-block-navigation {
  margin-left: auto;
  flex-shrink: 0;
}

/* EXPLICIT horizontal layout for the nav link list.
   TT4's own base styles are apparently not reliably resolving to
   a horizontal row at this width once our other width/wrap
   overrides are in play — likely because TT4 leans on container
   queries or JS-driven width detection that our CSS changes
   elsewhere interfere with. Rather than keep depending on TT4's
   own breakpoint logic (which has now broken twice), we take
   explicit control here: the link list is ALWAYS laid out as a
   horizontal row by default. The .responsive-container-content
   rule further down (scoped specifically to the mobile overlay)
   is the only place that switches it to a vertical column. */
.su-nav .wp-block-navigation__container {
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  align-items: center !important;
  gap: 20px;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Each nav item (the <li>) and its inner link both need explicit
   vertical centering. The Shop button has extra padding (border +
   button-like padding) that plain text links don't, so without
   this, items align by their box edges rather than their visual
   centers, causing a slight baseline mismatch across the row.

   ROOT CAUSE (found via inspection): the Shop button's border
   (1.5px) and padding (7px) were being added OUTSIDE the content
   box by default (standard CSS box model), making its total
   rendered height taller than a plain link's by ~17px. Centering
   each item within its OWN box doesn't fix a mismatch between
   boxes of different heights — it just centers each one
   differently. The real fix: box-sizing: border-box so padding/
   border are included in a predictable size, AND a shared
   min-height across every nav item so they all center against
   the same vertical span instead of their own variable heights. */
.su-nav .wp-block-navigation__container > .wp-block-navigation-item {
  display: flex;
  align-items: center;
  box-sizing: border-box;
}

.su-nav .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content {
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  box-sizing: border-box;
  min-height: 36px;
  margin: 0 !important;
}


/* ============================================================
   MOBILE NAVIGATION — hamburger menu + responsive overlay
   TT4's default mobile menu renders as a full-screen white modal
   with no theming. These rules restyle it to match the site.
   ============================================================ */

/* Hamburger button itself */
.su-nav .wp-block-navigation__responsive-container-open {
  color: var(--5u-light-text-muted) !important;
  background: transparent !important;
  border: none !important;
  padding: 8px !important;
}

.su-nav .wp-block-navigation__responsive-container-open svg {
  fill: var(--5u-light-text-muted) !important;
  width: 26px;
  height: 26px;
}

body.dark-mode .su-nav .wp-block-navigation__responsive-container-open {
  color: var(--5u-ice-white) !important;
}

body.dark-mode .su-nav .wp-block-navigation__responsive-container-open svg {
  fill: var(--5u-ice-white) !important;
}

/* The overlay container itself — full height, full width (acting
   as a top-sheet rather than a side drawer per design direction).
   IMPORTANT: every rule touching the overlay must be scoped to
   .is-menu-open, otherwise it renders on desktop too, since the
   underlying markup exists in the DOM at all screen sizes and is
   only hidden/shown via this class being toggled by TT4's JS. */
.su-nav .wp-block-navigation__responsive-container.is-menu-open {
  background: var(--5u-light-surface) !important;
  width: 100%;
  height: 100vh !important;
  min-height: 100vh !important;
  position: fixed !important;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border-left: none;
  border-top: 2px solid var(--5u-gold);
  z-index: 200;
}

.su-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-dialog {
  background: var(--5u-light-surface) !important;
  padding: 24px 28px !important;
  height: 100%;
  min-height: 100vh;
  box-sizing: border-box;
}

body.dark-mode .su-nav .wp-block-navigation__responsive-container.is-menu-open {
  background: var(--5u-navy-dark) !important;
}

body.dark-mode .su-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-dialog {
  background: var(--5u-navy-dark) !important;
}

/* Backdrop scrim behind the menu, dimming the page content.
   Scoped to .is-menu-open ONLY — without this scope the scrim
   was rendering as a permanent full-screen fixed overlay even
   when the menu was closed, which broke the entire desktop site. */
.su-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-close {
  position: fixed;
  inset: 0;
  background: rgba(6, 14, 22, 0.7);
  backdrop-filter: blur(2px);
  z-index: 199;
}

/* Close (×) button */
.su-nav .wp-block-navigation__responsive-container-close {
  color: var(--5u-light-text-muted) !important;
  background: transparent !important;
  border: none !important;
  position: absolute;
  top: 20px;
  right: 24px;
}

.su-nav .wp-block-navigation__responsive-container-close svg {
  fill: var(--5u-light-text-muted) !important;
  width: 22px;
  height: 22px;
}

body.dark-mode .su-nav .wp-block-navigation__responsive-container-close {
  color: var(--5u-ice-white) !important;
}

body.dark-mode .su-nav .wp-block-navigation__responsive-container-close svg {
  fill: var(--5u-ice-white) !important;
}

/* Content wrapper holding the link list — give it breathing room
   below the close button instead of links starting near the edge.
   Gated behind .is-menu-open for the same reason explained below —
   this element exists in the DOM at all widths. */
.su-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
  margin-top: 56px;
  padding: 0 !important;
}

/* The link list itself — centered for visual balance on a
   full-width mobile panel, rather than left-aligned with a
   large empty gap on the right.

   CRITICAL: this selector must include .is-menu-open. The element
   .wp-block-navigation__responsive-container-content exists in the
   DOM unconditionally at ALL screen widths — TT4 only toggles its
   VISIBILITY via the .is-menu-open class on an ancestor, it doesn't
   remove/re-render the element. A version of this rule without
   .is-menu-open in the selector chain was unconditionally winning
   against the desktop row-default rule on every screen size, since
   CSS specificity doesn't care about an element's current display
   state — only about whether the selector matches the DOM at all.
   That's what was forcing the column layout to "win" on desktop
   even though the overlay was never visually open. */
.su-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  gap: 4px;
  width: 100%;
}

/* IMPORTANT: scoped to .is-menu-open, same reasoning as above.
   An earlier version of this rule targeted .wp-block-navigation-item
   directly with no overlay scoping, which risked bleeding into the
   desktop nav's own list items; a later version scoped it to
   .responsive-container-content but without .is-menu-open, which
   still unconditionally matched at all screen widths. */
.su-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item {
  width: 100%;
  max-width: 420px;
  text-align: center;
}

.su-nav .wp-block-navigation__responsive-container.is-menu-open a.wp-block-navigation-item__content {
  color: var(--5u-light-text-muted) !important;
  font-size: 16px !important;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 14px 4px !important;
  display: block;
  width: 100%;
  text-align: center;
  border-bottom: 1px solid var(--5u-light-border);
  text-decoration: none !important;
  outline-offset: -2px;
}

body.dark-mode .su-nav .wp-block-navigation__responsive-container.is-menu-open a.wp-block-navigation-item__content {
  color: var(--5u-slate) !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

/* The divider line exists to separate plain text rows from each
   other. The Shop button is its own self-contained bordered
   element, not a plain text row, so it doesn't need a divider
   above it — and having one creates an awkward doubled-line
   effect right against the button's own top border. This removes
   the divider specifically from whichever item sits directly
   before the Shop link in the list (structurally: the <li>
   immediately preceding .su-nav-shop). */
.su-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item:has(+ .su-nav-shop) a.wp-block-navigation-item__content {
  border-bottom: none;
}

/* UNIFIED INTERACTION LANGUAGE — same on desktop and mobile:
   - default: slate gray (recedes)
   - hover:   ice white (brightens — "this is interactive")
   - focus:   ice white text + a visible gold outline box
              (distinct from hover by HAVING an outline, not just
              a color, so keyboard focus is never confusable with
              mouse hover, and never reads as the Shop button's
              permanent gold border) */
.su-nav .wp-block-navigation__responsive-container.is-menu-open a.wp-block-navigation-item__content:hover {
  color: var(--5u-light-text) !important;
}

.su-nav .wp-block-navigation__responsive-container.is-menu-open a.wp-block-navigation-item__content:focus {
  color: var(--5u-light-text) !important;
  outline: 2px solid var(--5u-light-text-muted) !important;
}

body.dark-mode .su-nav .wp-block-navigation__responsive-container.is-menu-open a.wp-block-navigation-item__content:hover {
  color: var(--5u-ice-white) !important;
}

body.dark-mode .su-nav .wp-block-navigation__responsive-container.is-menu-open a.wp-block-navigation-item__content:focus {
  color: var(--5u-ice-white) !important;
  outline: 2px solid var(--5u-slate) !important;
}

/* The Shop item (MOBILE OVERLAY ONLY) — styled as a clearly
   "coming soon" / disabled state rather than a loud actionable
   CTA, since there's nothing to click through to yet. Gold
   outline instead of solid red, with "Coming Soon" treated as a
   smaller secondary label. The margin-top here is intentional —
   it's spacing above the button when stacked under five other
   links in the vertical mobile list.

   CRITICAL: this MUST be scoped to .is-menu-open. An earlier
   version of this selector was a bare descendant selector with
   no overlay scoping at all, so it matched the Shop link on
   desktop too, where its margin-top: 12px (meant only to space
   it from the link above it in the vertical mobile stack) was
   silently shifting the desktop button's vertical position and
   breaking row alignment — a completely different rule than the
   one we spent the last several rounds investigating and fixing,
   despite producing a visually similar symptom. */
.su-nav .wp-block-navigation__responsive-container.is-menu-open .su-nav-shop a.wp-block-navigation-item__content {
  background: transparent !important;
  border: 1.5px solid var(--5u-gold) !important;
  color: var(--5u-gold) !important;
  border-radius: 4px;
  border-bottom: 1.5px solid var(--5u-gold) !important;
  text-align: center;
  margin-top: 20px;
  cursor: default;
}

.su-nav .wp-block-navigation__responsive-container.is-menu-open .su-nav-shop a.wp-block-navigation-item__content:hover {
  background: rgba(184, 151, 42, 0.08) !important;
  color: var(--5u-gold) !important;
}

/* Nav links (desktop).
   UNIFIED INTERACTION LANGUAGE — matches mobile exactly:
   - default: slate gray (recedes)
   - hover:   ice white (brightens)
   - focus:   ice white text + visible gold outline box
   See the matching comment in the mobile overlay section above
   for the full rationale. Both breakpoints now share one set of
   state colors instead of two independently-evolved systems. */
.su-nav .wp-block-navigation a,
.su-nav .wp-block-navigation-item__content {
  color: var(--5u-light-text-muted) !important;
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-decoration: none;
}

.su-nav .wp-block-navigation a:hover {
  color: var(--5u-light-text) !important;
}

.su-nav .wp-block-navigation a:focus {
  color: var(--5u-light-text) !important;
  outline: 2px solid var(--5u-light-text-muted) !important;
  outline-offset: 2px;
}

body.dark-mode .su-nav .wp-block-navigation a,
body.dark-mode .su-nav .wp-block-navigation-item__content {
  color: var(--5u-slate) !important;
}

body.dark-mode .su-nav .wp-block-navigation a:hover {
  color: var(--5u-ice-white) !important;
}

body.dark-mode .su-nav .wp-block-navigation a:focus {
  color: var(--5u-ice-white) !important;
  outline: 2px solid var(--5u-slate) !important;
  outline-offset: 2px;
}

/* Shop button (desktop) — add class "su-nav-shop" to that nav item.
   Styled as a clearly disabled/coming-soon state: gold outline
   rather than a solid, fully-actionable-looking red CTA, since
   there's nothing live to click through to yet. Swap this back to
   the solid red treatment once WooCommerce is live — search
   "su-nav-shop" in this file, both this rule and the mobile
   equivalent above will need updating together. */
.su-nav .su-nav-shop > .wp-block-navigation-item__content {
  background: transparent;
  border: 1.5px solid var(--5u-gold);
  color: var(--5u-gold) !important;
  padding: 7px 16px !important;
  margin: 0 !important;
  border-radius: 3px;
  cursor: default;
  box-sizing: border-box;
}

.su-nav .su-nav-shop > .wp-block-navigation-item__content:hover {
  background: rgba(184, 151, 42, 0.08);
}

/* Optional: if the nav link label is edited in the block editor to
   wrap "(Coming Soon)" in its own <span class="su-shop-subtext">,
   it will render smaller and lighter than "Shop" for a cleaner
   two-tier label. Not required — the button reads fine as plain
   text too — but available if you want the extra polish. To use:
   in the Navigation Link's text field switch to a tag where
   supported, or use a Custom Link with this HTML in the label. */
.su-nav .su-shop-subtext {
  font-size: 0.8em;
  opacity: 0.75;
  font-weight: 400;
  margin-left: 4px;
}


/* ============================================================
   CONTENT WIDTH WRAPPER
   Reusable class for capping inner content width while letting
   section backgrounds stay full-bleed. Apply "su-content" to an
   inner Group block wrapping the actual text/elements within any
   full-width section (hero text, event strip items, sponsor row,
   etc). The section's own background color block stays untouched
   at 100% width; only this inner wrapper gets centered and capped.
   ============================================================ */
.su-content {
  max-width: var(--5u-content-max);
  margin-left: auto !important;
  margin-right: auto !important;
  width: 100%;
  box-sizing: border-box;
}


/* ============================================================
   HERO SECTION
   Apply class "su-hero" to the outermost Group block
   wrapping the hero content in the page editor.
   ============================================================ */

/* Light mode.
   This section's background stays full-bleed (100% width) so the
   color band spans edge to edge — matching the reference pattern
   from Silicon Valley Curling's site (full-width nav/bands, with
   only the CONTENT inside capped to a max-width). The inner flex
   row (.su-hero-text + .su-rings-wrap) is what actually gets
   centered and capped, via padding calculated from the content
   max-width below — NOT by capping .su-hero itself, which would
   shrink the background band too. */
.su-hero {
  background: var(--5u-light-surface);
  border-bottom: 1px solid var(--5u-light-border);
  position: relative;
  overflow: hidden;
  min-height: 420px;

  /* Center the content by using auto-calculated side padding:
     whatever space exists beyond --5u-content-max is split evenly
     left/right, with a 32px minimum so content never touches the
     viewport edge on smaller screens.

     REVERTED from a larger exploratory pass (140/128, min-height
     540) back to these values — the bigger version made the
     section feel like padding for its own sake rather than content
     with room to breathe; these proportions were confirmed as the
     right balance. */
  padding-top: 96px;
  padding-bottom: 88px;
  padding-left: max(32px, calc((100% - var(--5u-content-max)) / 2));
  padding-right: max(32px, calc((100% - var(--5u-content-max)) / 2));
  box-sizing: border-box;
}


/* Dark mode */
body.dark-mode .su-hero {
  background: var(--5u-navy-base);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

/* ─────────────────────────────────────────────────────────
   HERO INNER LAYOUT — two columns
   Left: org name (dominant) + CTAs. Right: headline + flavor
   text, separated by a thin vertical divider. This replaced
   an earlier single-column version where the org name was a
   small eyebrow label above a large headline — user feedback
   was that the org name needed to read as the primary
   "announcement" element, not a minor label, while the
   headline should support rather than compete with it.
   ───────────────────────────────────────────────────────── */
.su-hero-inner {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 48px;
}

.su-hero-name-col {
  flex: 1.15;
}

.su-hero-flavor-col {
  flex: 1;
  /* Bumped from 0.12 to 0.25 — at 0.12 the divider was nearly
     invisible against the hero background, especially once the
     rings graphic (also very low opacity) sat nearby; the two
     were competing for the same faint visual register rather than
     one clearly reading as a structural line and the other as
     atmospheric texture. */
  border-left: 1px solid rgba(255, 255, 255, 0.25);
  padding-left: 40px;
}

body:not(.dark-mode) .su-hero-flavor-col {
  border-left-color: rgba(20, 30, 40, 0.25);
}

/* Small "Est. 2025" accent above the name */
.su-hero-est {
  font-size: 11px !important;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--5u-gold) !important;
  margin: 0 0 12px;
}

/* ORG NAME — two locked lines, same color throughout.
   "Five and Under" / "World Championship" are two SEPARATE
   elements in the HTML (not one wrapped line of text), so the
   break point is fixed and can never shift due to container
   width, font size changes, or responsive reflow. Do not
   combine these into a single element or rely on natural text
   wrapping — the break must always fall exactly here. Size and
   weight differ between the two lines to create emphasis, but
   color is identical on both, per design feedback: the name
   should read as one cohesive unit, with hierarchy expressed
   only through scale/weight, never through color changes. */
.su-hero-name-main {
  font-family: var(--5u-font-display);
  /* SELF-LOCKING FORMULA — codifies the gap-prevention math
     directly in CSS so PREFERRED and MAX can never drift apart
     again, instead of relying on two independently-typed numbers
     staying in sync by careful arithmetic.

     Background: clamp() picks whichever of its three values is
     literally in the middle at any given viewport. PREFERRED here
     is vw-based (a straight line through the origin); MAX is based
     on --5u-content-visible, which is FLAT until viewport reaches
     content-max + 64px (1296px), then grows 1:1 with viewport
     above that. Two different lines only cross at one point, and
     that crossing only lands exactly at 1296px (where the
     section's padding system also transitions) if MAX's multiplier
     is tuned to match PREFERRED's vw fraction via:
       multiplier = (1296 * vw_fraction) / 1168
     --5u-name-main-vw stores that vw fraction as a UNITLESS NUMBER
     (not a vw length) specifically so it can be used in arithmetic
     on both sides: PREFERRED builds the actual vw length from it
     via calc(var(...) * 1vw), and MAX derives its multiplier from
     the SAME number using the formula above. calc() does not
     support multiplying two length values together (px * vw is
     invalid), which is why the fraction has to stay a plain number
     and get multiplied by "1vw" / "1" separately in each branch,
     rather than storing a pre-built vw length and trying to reuse
     it directly inside the MAX arithmetic. Change
     --5u-name-main-vw and both ends of the clamp move together
     automatically — there's no second number to remember to
     update by hand. */
  --5u-name-main-vw: 7.6;
  font-size: clamp(
    56px,
    calc(var(--5u-name-main-vw) * 1vw),
    calc(var(--5u-content-visible) * var(--5u-name-main-vw) * 1296 / 1168 / 100)
  );
  font-weight: 700;
  line-height: 0.96;
  letter-spacing: 0.005em;
  color: var(--5u-light-text);
  margin: 0;
}

.su-hero-name-sub {
  font-family: var(--5u-font-display);
  /* Same self-locking formula as .su-hero-name-main above. */
  --5u-name-sub-vw: 4;
  font-size: clamp(
    30px,
    calc(var(--5u-name-sub-vw) * 1vw),
    calc(var(--5u-content-visible) * var(--5u-name-sub-vw) * 1296 / 1168 / 100)
  );
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--5u-light-text);
  margin: 8px 0 0;
}

body.dark-mode .su-hero-name-main,
body.dark-mode .su-hero-name-sub {
  color: var(--5u-ice-white);
}

.su-hero-ctas {
  margin-top: 34px;
}

/* Headline — same clamp restructuring as the name above:
   Uses the same self-locking formula as .su-hero-name-main —
   --5u-headline-vw is defined once and used to derive both the
   PREFERRED and MAX values, so they can't drift out of sync. */
.su-hero h1,
.su-hero .wp-block-heading {
  font-family: var(--5u-font-display);
  --5u-headline-vw: 2.6;
  font-size: clamp(
    18px,
    calc(var(--5u-headline-vw) * 1vw),
    calc(var(--5u-content-visible) * var(--5u-headline-vw) * 1296 / 1168 / 100)
  );
  font-weight: 600;
  line-height: 1.2;
  color: var(--5u-light-text);
  letter-spacing: 0.01em;
  margin: 0 0 14px;
}

body.dark-mode .su-hero h1,
body.dark-mode .su-hero .wp-block-heading {
  color: var(--5u-ice-white);
}

/* Hero subheading (flavor text) — apply class "su-hero-sub" to
   a Paragraph block. No longer needs its own max-width cap since
   the column itself now constrains line length. */
.su-hero-sub {
  font-size: 14px !important;
  color: var(--5u-light-text-muted) !important;
  font-style: italic;
  line-height: 1.7;
  margin: 0;
}

body.dark-mode .su-hero-sub {
  color: var(--5u-slate) !important;
}

/* Primary CTA button — apply class "su-btn-primary" to a Button block */
.su-btn-primary,
.su-btn-primary.wp-block-button__link {
  background: var(--5u-red) !important;
  color: #fff !important;
  border: none !important;
  border-radius: 4px !important;
  font-family: var(--5u-font-body);
  font-size: 13px !important;
  font-weight: 600;
  padding: 10px 20px !important;
  display: inline-block;
}

.su-btn-primary:hover,
.su-btn-primary.wp-block-button__link:hover {
  background: var(--5u-red-hover) !important;
}

/* Outline CTA button — apply class "su-btn-outline" to a Button block */
.su-btn-outline,
.su-btn-outline.wp-block-button__link {
  background: transparent !important;
  border: 1.5px solid var(--5u-light-text) !important;
  color: var(--5u-light-text) !important;
  border-radius: 4px !important;
  font-family: var(--5u-font-body);
  font-size: 13px !important;
  font-weight: 500;
  padding: 9px 20px !important;
  display: inline-block;
  margin-left: 10px;
}

body.dark-mode .su-btn-outline,
body.dark-mode .su-btn-outline.wp-block-button__link {
  border-color: rgba(240, 244, 248, 0.3) !important;
  color: var(--5u-ice-white) !important;
}

/* House rings SVG — inserted as an HTML block inside the hero Group,
   positioned absolutely via these styles.

   REBUILT around an explicit CENTER POINT rather than a right-edge
   anchor, per design direction: the rings should be substantially
   larger and more present than before — radius ≈ half the content
   width (diameter ≈ full content width), centered at roughly 80%
   of the content width across from the left edge. This is a much
   bigger, more deliberate background motif than the earlier
   small-corner-accent version.

   Both the position and size are expressed as percentages of
   --5u-content-visible (the actual RENDERED content box width,
   not the raw --5u-content-max constant) — using the wrong one
   here would reintroduce the same "dead zone" bug already found
   and fixed on the hero text sizing, where a value calculated
   against the nominal cap doesn't actually match the real content
   box once section padding is accounted for.

   CSS has no native "position an element by its center" — only by
   an edge — so we position the wrapper's TOP-LEFT at the desired
   center point, then use transform: translate(-50%, -50%) to pull
   it back by exactly half its own rendered size in both directions.
   This keeps the math correct regardless of how large the SVG
   itself ends up being at any given screen width. */
.su-rings-wrap {
  position: absolute;
  /* POSITION BUG FOUND during testing: this used a flat
     --5u-content-visible-based offset with NO viewport-responsive
     term, unlike the width/height rules below (which already use
     the self-locking vw formula). Below the content cap,
     --5u-content-visible stays a constant 1168px regardless of
     actual viewport width, so the rings' center was always placed
     934px (1168 * 0.80) from the padding edge — on an iPad at
     768px wide, that pushes the center point off the right edge of
     the screen entirely, which is exactly the "rings are way off
     screen, only outer edge visible" bug found in testing.

     Fix: same self-locking vw/content-visible formula as the size
     rules below — --5u-rings-left-vw stores the fraction as a
     unitless number, PREFERRED builds an actual vw length from it
     (so the position genuinely shrinks/moves with a narrowing
     viewport), MAX derives its multiplier from the same number via
     (1296 * vw_fraction) / 1168 so the position holds steady once
     at/above the content cap, with no dead zone between the two
     behaviors — identical reasoning to .su-hero-name-main's
     formula, just applied to a position value instead of a
     font-size. */
  --5u-rings-left-vw: 72.0988;
  left: calc(
    max(32px, (100% - var(--5u-content-max)) / 2)
    + clamp(
      120px,
      calc(var(--5u-rings-left-vw) * 1vw),
      calc(var(--5u-content-visible) * var(--5u-rings-left-vw) * 1296 / 1168 / 100)
    )
  );
  top: 70%;
  /* translate(-50%, -50%) centers the SVG on the calculated point
     above; rotate(18deg) is applied AFTER centering (transforms
     apply right-to-left in this notation, so translate happens
     first) so the rotation pivots around the rings' own center
     rather than some other point. The rotation exists specifically
     to break the crosshair lines out of parallel alignment with
     the vertical divider between the hero's two columns — without
     it, the lines visually merged with the divider (confirmed via
     side-by-side comparison during design review). */
  transform: translate(-50%, -50%) rotate(18deg);
  pointer-events: none;
  z-index: 1;
  /* Opacity confirmed via direct side-by-side comparison against
     several fill/pattern treatments — 0.09 was the value where the
     hatch pattern read as a soft tonal texture rather than a
     visible/distracting pattern, while still being distinct enough
     from a flat fill to convey the alternating ring colors. */
  opacity: 0.09;
}

.su-rings-wrap svg {
  /* SELF-LOCKING FORMULA — same pattern used for the hero text
     sizing (see .su-hero-name-main for the full explanation).

     BUG FOUND: the previous version used calc(--5u-content-visible
     * 1.0) as the clamp's PREFERRED value. --5u-content-visible is
     calculated from --5u-content-max, which is a FLAT CONSTANT
     (1232px, from theme.json) — it never tracks the actual
     viewport at all, at any width. That meant the rings had ZERO
     viewport-responsiveness below the content cap: the "preferred"
     size was always a flat 1168px target, clamped down only by
     the section's own overflow:hidden, which is why the rings
     rendered far oversized and badly off-center on iPad/phone
     widths — there was nothing in the formula to shrink them.

     Fix: same self-locking vw/content-visible pattern as the text.
     --5u-rings-vw stores the preferred scaling rate as a unitless
     number, used to build an actual vw length for PREFERRED, and
     to derive MAX's multiplier via the same (1296 * vw_fraction)
     / 1168 formula — so PREFERRED actually shrinks with the
     viewport below the cap, and MAX holds the rings at a steady
     size once at/above the cap, with no dead zone between the two
     behaviors. */
  --5u-rings-vw: 90.12;
  width: clamp(
    180px,
    calc(var(--5u-rings-vw) * 1vw),
    calc(var(--5u-content-visible) * var(--5u-rings-vw) * 1296 / 1168 / 100)
  ) !important;
  height: clamp(
    180px,
    calc(var(--5u-rings-vw) * 1vw),
    calc(var(--5u-content-visible) * var(--5u-rings-vw) * 1296 / 1168 / 100)
  ) !important;
}

/* NOTE: .su-hero-text (old single-column wrapper) has been
   replaced by .su-hero-inner (two-column layout, defined above).
   This selector is intentionally removed — if you see references
   to .su-hero-text elsewhere, they're stale and should be updated
   to the new structure. */


/* ============================================================
   EVENT STRIP
   Apply class "su-strip" to a Group block.
   Each item inside gets class "su-strip-item".
   ============================================================ */

/* Event strip — CSS Grid rather than flex-row/flex-column.
   Previously this was flex-direction: row on desktop, switching to
   flex-direction: column at the 768px breakpoint. That meant any
   viewport at or below 768px (including iPad Mini, which sits
   exactly on that boundary) got the fully-stacked single-column
   layout despite having ample width for all 3 items side by side
   — confirmed via screenshot: iPad Mini showed 3 items stacked
   vertically with large unused horizontal space on either side.

   Grid lets us declare actual column counts per breakpoint instead
   of an all-or-nothing row/column switch: 3 columns at tablet+
   widths (where it's always rendered correctly), 2 columns below
   that. See the responsive overrides further down for the 2-column
   mobile grid and its divider handling.

   .su-strip is the outer card; .su-strip-grid is the grid of data
   items inside it. Split into two elements because .su-strip-note
   (the broadcast caveat) needed to sit OUTSIDE the grid but INSIDE
   the card — see the markup comment and .su-strip-note rule below.

   --- Card treatment (added after second round of feedback) ---
   Originally .su-strip had no defined right edge: grid columns
   were 1fr/1fr/1fr, stretching to fill the FULL --5u-content-max
   width (1232px) regardless of how much space the 3 short data
   points actually needed. That left a large empty void trailing
   off to the right of "Location" — confirmed via screenshot, where
   the open right edge made the row feel unanchored. Centering the
   item text was considered and rejected: it would make individual
   cells feel more self-contained, but wouldn't fix the real
   problem, which is the ROW not filling its allotted space, not
   the alignment within each item.

   Fix: .su-strip stays full-bleed (a horizontal band across the
   page, matching the visual rhythm of the hero/sponsors sections
   above and below it) — but the actual DATA — .su-strip-grid plus
   .su-strip-note together — is now wrapped in a bordered card sized
   to fit its own content (width: fit-content) rather than stretched
   edge to edge. That gives the content a real right edge and a
   bottom edge to anchor against, without losing the full-width
   background band that ties this section to the rest of the page.
   The broadcast note sits inside that same card with its own top
   border, so it reads as a footer row of the card — this addresses
   the "feels like an afterthought" feedback directly. */
.su-strip,
.su-strip.wp-block-group {
  background: var(--5u-light-surface-alt) !important;
  box-sizing: border-box;

  /* Same content-width capping pattern as .su-hero — background
     stays full-bleed, content padding is calculated to center the
     row within --5u-content-max on large screens. */
  padding-top: 24px;
  padding-bottom: 24px;
  padding-left: max(28px, calc((100% - var(--5u-content-max)) / 2));
  padding-right: max(28px, calc((100% - var(--5u-content-max)) / 2));
}

/* Light mode is the default above — .su-strip was previously a
   permanent dark band regardless of mode, like .su-champ-hdr and
   .su-aside-card below. Confirmed direct request to soften all
   three: as large, high-contrast blocks they were distracting from
   the page's more subtle light-mode color differences. The child
   rules below (.su-strip-item border, .su-strip-label,
   .su-strip-value, .su-strip-note border) all get matching
   dark-mode overrides since they were tuned for light text/dividers
   on a dark background and would otherwise have poor contrast or
   vanish entirely against the new light background. */
body.dark-mode .su-strip,
body.dark-mode .su-strip.wp-block-group {
  background: var(--5u-navy-dark) !important;
}

/* .su-strip-card removed — the bordered, fit-content card layer was
   the source of repeated layout bugs (centering relying on
   margin: auto in normal flow, width mismatches against the
   surrounding band, an extra abstraction every other fix had to
   account for) and was never something explicitly requested in the
   first place — it was added as a side effect of fixing the
   broadcast note's spacing. Removed per direct confirmation: the
   strip's content now fills the full content width directly again,
   matching the original pre-card design. .su-strip-grid and
   .su-strip-note are direct children of .su-strip now (see markup),
   no wrapper between them. */
.su-strip-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 36px;
}

.su-strip-item {
  padding-right: 36px;
  border-right: 1px solid var(--5u-light-border);
  display: flex;
  flex-direction: column;
}

body.dark-mode .su-strip-item {
  border-right-color: rgba(255, 255, 255, 0.09);
}

/* Grid version of the old flex ":last-child" divider removal —
   "last child" alone isn't enough once layout can wrap items onto
   multiple rows (item 3 of 3 is the LAST item in the row at both
   3-column and 1-column widths, so the existing :last-child rule
   below still correctly drops its divider in both of those cases).
   The 2-column mobile case is handled separately in the responsive
   override, since there item 3 sits ALONE on its own row and needs
   different divider treatment (bottom border instead of right). */
.su-strip-item:last-child {
  border-right: none;
  padding-right: 0;
}

/* Apply "su-strip-label" to a Paragraph block */
.su-strip-label {
  font-size: 10px !important;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--5u-light-text-muted) !important;
  margin-bottom: 3px;
}

body.dark-mode .su-strip-label {
  color: var(--5u-slate-dim) !important;
}

/* Apply "su-strip-value" to a Paragraph block */
.su-strip-value {
  font-family: var(--5u-font-display);
  font-size: 17px !important;
  font-weight: 700;
  color: var(--5u-light-text) !important;
}

body.dark-mode .su-strip-value {
  color: var(--5u-ice-white) !important;
}

/* Apply "su-strip-note" to a Paragraph block.
   Direct child of .su-strip now (card wrapper removed — see
   .su-strip-grid comment for why). .su-strip itself already
   provides the content-width side padding, so this no longer needs
   its own horizontal padding — adding any here would double-indent
   the note relative to .su-strip-grid above it, which gets its
   alignment the same way (from .su-strip's padding, not its own). */
.su-strip-note {
  display: block;
  font-size: 11px !important;
  color: #3A4E5C !important;
  font-style: italic;
  border-top: 1px solid var(--5u-light-border);
  padding: 10px 0 0;
  margin: 14px 0 0;
}

body.dark-mode .su-strip-note {
  border-top-color: rgba(255, 255, 255, 0.09);
}


/* ============================================================
   SPONSOR STRIP
   Apply class "su-sponsors" to a Group block.
   ============================================================ */

.su-sponsors,
.su-sponsors.wp-block-group {
  border-bottom: 1px solid var(--5u-light-border);
  padding-top: 20px;
  padding-bottom: 20px;
  padding-left: max(28px, calc((100% - var(--5u-content-max)) / 2));
  padding-right: max(28px, calc((100% - var(--5u-content-max)) / 2));
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  /* Was gap: 0 — meant the row only looked correct as long as it
     never actually wrapped. Below ~498px (between this rule and
     the explicit mobile wrap styling at the 768px breakpoint) it
     would wrap with no spacing between rows, producing a cramped,
     accidental-looking break. A real gap here means wrapping looks
     like a deliberate layout at ANY width, not just the widths
     someone happened to test. The 768px breakpoint below sets its
     own gap (12px) for the fully-stacked mobile case; this is just
     for the in-between range it doesn't cover. */
  gap: 12px 0;
  background: var(--5u-light-surface);
  box-sizing: border-box;
}

body.dark-mode .su-sponsors {
  background: var(--5u-navy-lift) !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

/* Apply "su-sponsor-label" to a Paragraph block */
.su-sponsor-label {
  font-size: 12px !important;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--5u-gold) !important;
  margin-right: 22px;
  white-space: nowrap;
}

/* Wraps the individual .su-sponsor-logo items so the phone
   breakpoint can treat them as one wrapping row separate from the
   label/CTA (see the 600px breakpoint below). At desktop/tablet
   widths this wrapper should be invisible — display: contents drops
   it out of the box tree entirely so .su-sponsor-label, each
   .su-sponsor-logo, and .su-sponsor-cta stay direct flex items of
   .su-sponsors exactly as before this wrapper existed. */
.su-sponsor-logos {
  display: contents;
}

/* Wrap each sponsor logo Image block in a Group with class "su-sponsor-logo" */
.su-sponsor-logo,
.su-sponsor-logo.wp-block-group {
  height: 64px;
  display: flex !important;
  align-items: center;
  justify-content: center;
  padding: 0 20px;
  border-left: 1px solid var(--5u-light-border);
  background: transparent !important;
}

body.dark-mode .su-sponsor-logo {
  border-left-color: rgba(255, 255, 255, 0.08);
}

/* Logo height bumped 26px -> 56px for legibility. max-width raised to
   228px to fit Milwaukee Window Guys — the widest current sponsor
   mark — at that height without object-fit clipping it; narrower
   logos (e.g. the Curlytics squircle) just render smaller within
   that ceiling since object-fit: contain preserves their own
   aspect ratio. */
.su-sponsor-logo img,
.su-sponsor-logo .wp-block-image img {
  max-height: 56px;
  max-width: 228px;
  object-fit: contain;
  opacity: 0.6;
}

/* NOTE: previously had a body.dark-mode override here that applied
   filter: brightness(0) invert(1) to force every sponsor logo to a
   flat white silhouette. Removed — it destroyed actual logo color
   for any sponsor with a multi-color mark (confirmed via
   screenshot: Curlytics' logo became an unrecognizable white blob),
   and only happened to look fine for Milwaukee Window Guys because
   that mark is desaturated enough to read as a clean shape even
   flattened. Sponsor logos should render in their real brand colors
   in both modes — the opacity above already mutes them
   appropriately against the section background without erasing
   color. If a future sponsor logo is pure black (or otherwise
   illegible on navy), handle that as a one-off override on that
   specific .su-sponsor-logo img rather than reintroducing a
   blanket filter for all logos. */
body.dark-mode .su-sponsor-logo img,
body.dark-mode .su-sponsor-logo .wp-block-image img {
  opacity: 0.75;
}

/* "Become a sponsor" link — apply class "su-sponsor-cta" to the
   wrapper div, with the actual <a> nested inside it. The divider
   border and left padding live on the wrapper, not the <a>, so the
   link's focus outline isn't pushed lopsided by that padding —
   the <a> gets its own small, even padding below instead. */
.su-sponsor-cta {
  border-left: 1px solid var(--5u-light-border);
  padding-left: 20px;
  white-space: nowrap;
}

body.dark-mode .su-sponsor-cta {
  border-left-color: rgba(255, 255, 255, 0.08);
}

.su-sponsor-cta a {
  display: inline-block;
  font-size: 12px !important;
  color: var(--5u-gold) !important;
  font-style: italic;
  padding: 4px;
}

/* Click-to-copy email links — apply class "su-copy-email" to any
   <a href="mailto:...">. Behavior lives in theme.js; this class
   carries no real visual styling of its own so it layers onto
   existing link styles (e.g. .su-sponsor-cta) without fighting
   them. */
.su-copy-email {
  cursor: pointer;
}

/* Copy confirmation toast — single sitewide instance, created once
   by theme.js and appended to <body>. Fixed bottom-center rather
   than positioned relative to whichever link was clicked: the
   sponsor row wraps responsively, and the footer link's markup
   isn't controlled by this repo at all. z-index 160 sits above
   .su-dark-toggle (150) and below the mobile nav overlay (200),
   matching the existing layering order. Message text is kept short
   ("Copied to clipboard", not the raw address) so the toast stays
   narrow enough to never overlap .su-dark-toggle's fixed bottom-
   right footprint even at the narrowest tested viewport (360px). */
.su-copy-toast {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%) translateY(8px);
  z-index: 160;
  background: var(--5u-navy-dark);
  color: var(--5u-ice-white);
  font-size: 13px;
  padding: 10px 18px;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  opacity: 0;
  pointer-events: none;
  white-space: nowrap;
  transition: opacity 0.2s ease, transform 0.2s ease;
  /* Intentionally mode-invariant — floats above the page as system
     chrome, like an OS toast, so it doesn't need a body.dark-mode
     override the way in-page elements do. */
}

.su-copy-toast.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}


/* ============================================================
   WHAT IS 5U — EXPLAINER SECTION
   Apply class "su-explainer" to the outer Group block.
   Use a two-column Columns block inside.
   ============================================================ */

.su-explainer,
.su-explainer.wp-block-group {
  background: var(--5u-light-surface-alt) !important;
  border-bottom: 1px solid var(--5u-light-border);
  padding-top: 38px;
  padding-bottom: 38px;
  padding-left: max(32px, calc((100% - var(--5u-content-max)) / 2));
  padding-right: max(32px, calc((100% - var(--5u-content-max)) / 2));
  box-sizing: border-box;
}

body.dark-mode .su-explainer {
  background: var(--5u-navy-mid) !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.su-explainer-main p:not(.su-section-tag),
.su-explainer-main .wp-block-paragraph:not(.su-section-tag) {
  font-size: 14px;
  color: var(--5u-light-text-body);
  line-height: 1.8;
  /* Was relying on the browser's default <p> margin (~1em top and
     bottom, since this section is plain HTML inside a Custom HTML
     block, not native Gutenberg blocks with their own spacing
     resets) — confirmed via screenshot: the gap above "WHAT IS '5
     AND UNDER'?" (a <p class="su-section-tag">) was section padding
     PLUS that unreset default margin stacking on top, and the body
     paragraph below the heading had its own default bottom margin
     adding extra space before "Read the full history" beyond the
     .su-link's own margin-top. Resetting to 0 here and letting only
     the explicit margin-bottom/margin-top values below (on
     .su-section-tag, .su-section-h, .su-link) control spacing means
     every gap in this section is a deliberate, single value instead
     of an unintended sum of two.

     :not(.su-section-tag) added after checking specificity: that
     class is ALSO a <p> tag (see homepage.html), and without this
     exclusion this selector (class+element, specificity 0,0,1,1)
     would outrank .su-section-tag (class only, 0,0,1,0) and apply
     this rule's 18px margin instead of .su-section-tag's own
     intended 7px — same bug pattern caught and fixed in the aside
     card's paragraph rule below.

     Scoped to .su-explainer-main specifically (not the broader
     .su-explainer) — the aside card's "Who competes?" text is also
     a <p> tag nested inside .su-explainer, and a broader selector
     here would have outranked .su-aside-h's own margin via higher
     specificity too. Keeping these scoped separately avoids relying
     on source order or specificity tie-breaking to sort that out. */
  margin: 0 0 18px;
}

.su-explainer-main p:not(.su-section-tag):last-of-type {
  margin-bottom: 0;
}

body.dark-mode .su-explainer p,
body.dark-mode .su-explainer .wp-block-paragraph {
  color: var(--5u-slate);
}

/* Aside card — apply class "su-aside-card" to a Group block
   in the right column */
.su-aside-card,
.su-aside-card.wp-block-group {
  background: var(--5u-light-surface) !important;
  /* Light mode card definition: the section behind it
     (.su-explainer) is --5u-light-surface-alt, only a few percent
     darker than this card's white — visible but subtle, so a border
     gives it the same crisp "card" definition .su-champ-card already
     relies on rather than just background contrast. Not needed in
     dark mode: navy-dark vs the section's navy-mid background is
     already a clearly distinct shade without one. */
  border: 1px solid var(--5u-light-border);
  border-radius: 6px;
  padding: 20px 22px !important;
  /* Confirmed via screenshot: "Read the full history" (in the LEFT
     column) sat almost flush against the top of this card (in the
     RIGHT column) with no visible gap, even though they're
     unrelated topics. This card had no margin-top of its own to
     create separation from whatever happens to be vertically
     adjacent to it in the other column — at narrower/stacked
     layouts in particular, this card and the end of the main
     column's content become direct vertical neighbors. */
  margin-top: 24px;
}

body.dark-mode .su-aside-card,
body.dark-mode .su-aside-card.wp-block-group {
  background: var(--5u-navy-dark) !important;
  border: none;
}

/* Apply "su-aside-h" to a Heading block inside the aside */
.su-aside-h {
  font-family: var(--5u-font-display);
  font-size: 15px !important;
  font-weight: 700;
  color: var(--5u-gold) !important;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0 0 9px;
}

.su-aside-card p:not(.su-aside-h),
.su-aside-card .wp-block-paragraph:not(.su-aside-h) {
  font-size: 13px !important;
  color: var(--5u-light-text-body) !important;
  line-height: 1.65;
  /* Same unreset-default-margin issue as .su-explainer-main p above
     — confirmed via screenshot: the gap above "WHO COMPETES?" was
     visibly larger than the gap below "How to qualify", which
     shouldn't have been true given the divider's own explicit
     margin (13px 0 11px) is symmetric-ish. The asymmetry was this
     paragraph's unreset default bottom margin adding extra space
     the divider's own margin-top then stacked on top of.

     :not(.su-aside-h) added after checking specificity directly:
     .su-aside-h ("Who competes?") is ALSO a <p> tag, so without
     this exclusion, .su-aside-card p (class+element, specificity
     0,0,1,1) would outrank .su-aside-h (class only, 0,0,1,0) and
     silently override its margin: 0 0 9px back to 0 — collapsing
     the gap below the heading instead of fixing it. */
  margin: 0;
}

body.dark-mode .su-aside-card p:not(.su-aside-h),
body.dark-mode .su-aside-card .wp-block-paragraph:not(.su-aside-h) {
  color: var(--5u-slate) !important;
}

/* Separator block inside aside — add class "su-aside-divider" */
.su-aside-divider,
.su-aside-card .wp-block-separator.su-aside-divider {
  border-color: var(--5u-light-border) !important;
  margin: 13px 0 11px;
}

body.dark-mode .su-aside-divider,
body.dark-mode .su-aside-card .wp-block-separator.su-aside-divider {
  border-color: rgba(255, 255, 255, 0.08) !important;
}

.su-aside-link {
  display: inline-block;
  color: var(--5u-gold) !important;
  font-size: 13px;
  font-weight: 600;
  margin: 0;
}


/* ============================================================
   SECTION SHARED STYLES
   Reusable classes for section tags and headings.
   ============================================================ */

.su-section-tag {
  font-size: 11px !important;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--5u-gold) !important;
  /* margin-top: 0 added alongside the existing margin-bottom — this
     class is a <p> tag (see homepage.html), and without resetting
     margin-top, the browser's default <p> top margin (~1em) was
     adding extra unintended space above this element wherever it's
     used (explainer, champions, mission sections), independent of
     and on top of each section's own deliberate padding-top. */
  margin: 0 0 7px;
}

.su-section-h {
  font-family: var(--5u-font-display) !important;
  font-size: 29px !important;
  font-weight: 700;
  color: var(--5u-light-text) !important;
  /* Same fix as .su-section-tag above — this is an <h2>, whose
     browser default top margin (~0.83em, larger than the <p>
     default since it scales with the heading's own larger
     font-size) was the bigger contributor to the oversized gap
     seen above "A competitive home for newer curlers" in the
     explainer section. */
  margin: 0 0 14px;
}

body.dark-mode .su-section-h {
  color: var(--5u-ice-white) !important;
}

.su-link {
  display: inline-block;
  margin-top: 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--5u-red) !important;
  text-decoration: none;
}


/* ============================================================
   CHAMPIONS SECTION
   Apply class "su-champs" to outer Group.
   Each event uses a Group with class "su-champ-card".
   ============================================================ */

.su-champs,
.su-champs.wp-block-group {
  background: var(--5u-light-surface) !important;
  border-bottom: 1px solid var(--5u-light-border);
  padding-top: 38px;
  padding-bottom: 38px;
  box-sizing: border-box;
  /* Local containment boundary, in addition to the html/body level
     fix — .su-champ-grid's negative margin-right (its intentional
     full-bleed peek effect) should be clipped here, at the section
     it actually belongs to, rather than relying solely on the
     document root to catch it. Belt-and-suspenders after the
     html/body-only fix was confirmed insufficient on its own. */
  overflow-x: hidden;
}

body.dark-mode .su-champs {
  background: var(--5u-navy-base) !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

/* Section tag/heading still need the content-max side padding (the
   scrolling card row below intentionally does NOT — see
   .su-champ-grid comment), so it's applied directly to them instead
   of to .su-champs as a whole now. Includes .su-link ("View all
   medalists") since that's also a direct child of .su-champs,
   outside the scrolling grid, that needs the same alignment. */
.su-champs .su-section-tag,
.su-champs .su-section-h,
.su-champs > .su-link {
  padding-left: max(32px, calc((100% - var(--5u-content-max)) / 2));
  padding-right: max(32px, calc((100% - var(--5u-content-max)) / 2));
}

/* .su-link normally has display: inline-block with no padding
   support beyond text flow — adding padding-left here works
   because inline-block respects padding, but margin-top (its
   normal top-spacing mechanism) needs to still apply too. Confirmed
   no conflict: .su-link's own margin-top: 12px is untouched by
   this rule, just supplemented with horizontal padding. */

/* Card row — was a plain stacked block with no layout CSS at all
   (relying entirely on default element stacking, the same gap that
   caused the explainer section's spacing issues), which is why the
   cards had zero space between them and consumed a large, fully
   vertical chunk of the page for very little actual content density
   — confirmed via screenshot, where 2 cards took up nearly a full
   screen height on desktop with huge unused width on either side.

   Switched to a horizontally-scrolling row of fixed-width cards
   instead of a responsive grid. Reasoning: this section's content
   grows by ONE card per year indefinitely (see markup comment —
   "add the new event... shifting the previous card to second
   position"). A column-count-based grid would need its breakpoints
   revisited every time the dataset grows past whatever count it was
   tuned for; a horizontal scroll lane just keeps appending cards to
   the same lane forever without ever needing layout changes again.

   Card width (330px, see .su-champ-card) was sized so 3 cards sit
   fully visible in the desktop content area with roughly a third of
   a 4th card peeking past the edge — confirmed via calculation
   against the actual content width (1168px) — which reads as "this
   scrolls" even before a person tries to interact with it, rather
   than looking like an arbitrary cutoff.

   LEFT side: a dedicated spacer flex item (.su-champ-grid-spacer,
   see markup) provides the start-edge inset instead of padding-left
   — padding-left on a horizontally scrollable flex container is not
   reliably rendered before the first child across browsers (a real,
   documented CSS quirk, confirmed via dev tools computed styles:
   padding-left showed 20px in the box model, but the first card
   still rendered with zero visible gap at rest). A real flex item's
   width doesn't have this ambiguity. RIGHT side still uses
   padding-right (the END side, which IS reliably honored) plus a
   negative margin-right that bleeds past --5u-content-max to the
   true viewport edge — this is what makes the partial-card peek and
   scroll affordance visible all the way to the browser edge on wide
   screens, rather than stopping at the centered content column.
   This LEFT/RIGHT asymmetry (spacer item vs. padding+negative
   margin) is intentional and necessary — they're different
   mechanisms because the two sides have different browser
   reliability characteristics, not an oversight. */
.su-champ-grid {
  display: flex;
  gap: 20px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding: 4px max(32px, calc((100% - var(--5u-content-max)) / 2)) 4px 0;
  margin-right: calc(-1 * max(32px, calc((100% - var(--5u-content-max)) / 2)));
  /* Thin, theme-colored scrollbar instead of the bulky OS default,
     where supported (Firefox + Chromium). Safari falls back to its
     own default overlay scrollbar; harmless, just not themed. */
  scrollbar-width: thin;
  scrollbar-color: var(--5u-slate-dim) transparent;
}

/* Spacer flex item — provides the grid's start-edge inset reliably,
   working around the padding-left scroll-container quirk described
   above. Width is the intended inset MINUS the 20px flex gap —
   .su-champ-grid's `gap` applies between EVERY flex child, including
   this spacer and the first real card, so without subtracting it
   the visual inset would be (intended width + 20px), overshooting.
   Kept as the same max(32px, calc(...)) expression as the section
   heading's own left inset, minus the gap, so it stays in sync if
   --5u-content-max or the breakpoint values ever change.
   flex-shrink: 0 so it can't be squeezed by overflow, exactly like
   the real cards. aria-hidden in the markup since it carries no
   content.

   scroll-snap-align: start — without this, the spacer's correct
   width was rendering (confirmed via computed styles) but had no
   visible effect, because .su-champ-card has scroll-snap-align:
   start and the grid uses scroll-snap-type: x proximity. With only
   the cards registered as snap points, position 0 (spacer visible)
   wasn't a valid resting point, so proximity snapping pulled the
   scroll forward to the first card's edge — confirmed via testing:
   scrolling to the start briefly showed the inset before snapping
   back flush. Giving the spacer its own start snap point makes
   position 0 itself a valid place to rest. */
.su-champ-grid-spacer {
  width: calc(max(32px, calc((100% - var(--5u-content-max)) / 2)) - 20px);
  flex-shrink: 0;
  scroll-snap-align: start;
}

body.dark-mode .su-champ-grid {
  scrollbar-color: var(--5u-slate-dimmer) transparent;
}

.su-champ-card,
.su-champ-card.wp-block-group {
  border: 1px solid var(--5u-light-border) !important;
  border-radius: 6px;
  overflow: hidden;
  padding: 0 !important;
  /* Fixed width + flex-shrink: 0 — cards keep their real size
     rather than being squeezed to fit, which is what makes this a
     genuine horizontal scroll lane instead of a flex-wrap row that
     happens to overflow. See .su-champ-grid comment for how 330px
     was chosen. */
  width: 330px;
  flex-shrink: 0;
  scroll-snap-align: start;
}

body.dark-mode .su-champ-card {
  border-color: rgba(255, 255, 255, 0.08) !important;
}

/* Apply "su-champ-hdr" to a Group block at the top of each card */
.su-champ-hdr,
.su-champ-hdr.wp-block-group {
  background: var(--5u-light-surface-alt) !important;
  padding: 11px 16px !important;
  border-radius: 0 !important;
  /* Light mode only — without this, the header and .su-champ-body
     below it (light-surface, i.e. white) are too close in tone to
     read as separate regions on their own. Not needed in dark mode:
     navy-dark vs the body's navy-lift background is already clearly
     distinct. */
  border-bottom: 1px solid var(--5u-light-border);
}

body.dark-mode .su-champ-hdr,
body.dark-mode .su-champ-hdr.wp-block-group {
  background: var(--5u-navy-dark) !important;
  border-bottom: none;
}

.su-champ-event-name {
  font-family: var(--5u-font-display);
  font-size: 17px !important;
  font-weight: 700;
  color: var(--5u-light-text) !important;
  margin: 0 !important;
}

body.dark-mode .su-champ-event-name {
  color: var(--5u-ice-white) !important;
}

.su-champ-event-meta {
  font-size: 11px !important;
  color: var(--5u-light-text-muted) !important;
  margin-top: 2px;
}

body.dark-mode .su-champ-event-meta {
  color: var(--5u-slate-dim) !important;
}

/* Apply "su-champ-body" to the content Group block below the header */
.su-champ-body,
.su-champ-body.wp-block-group {
  background: var(--5u-light-surface) !important;
  padding: 16px 18px !important;
}

body.dark-mode .su-champ-body {
  background: var(--5u-navy-lift) !important;
}

/* Medal icon + team name on one row, rather than separate rows with
   the icon floated to its own line above — confirmed via feedback
   that giving them separate rows wasted vertical space for two
   pieces of info that read naturally as a single unit ("here's who
   won"). */
.su-champ-winner-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}

.su-gold-icon {
  font-size: 20px;
  line-height: 1;
}

.su-team-name {
  font-size: 15px !important;
  font-weight: 600;
  color: var(--5u-light-text) !important;
  margin: 0 !important;
}

body.dark-mode .su-team-name {
  color: var(--5u-ice-white) !important;
}

.su-team-club {
  font-size: 12px !important;
  color: var(--5u-slate-dim) !important;
  /* Tightened from 8px — confirmed via feedback this should read as
     a small note directly under the winner row, not a separately-
     spaced block. */
  margin: 0 0 6px;
}

/* Each player row — apply "su-player-row" to a Group or Columns block */
.su-player-row,
.su-player-row.wp-block-group {
  display: flex !important;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 3px;
  background: transparent !important;
  padding: 0 !important;
}

.su-pos {
  font-size: 10px !important;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--5u-slate-dim) !important;
  width: 32px;
  flex-shrink: 0;
}

body.dark-mode .su-pos {
  color: var(--5u-slate-dimmer) !important;
}

.su-player-name {
  font-size: 13px !important;
  color: var(--5u-light-text-muted) !important;
}

body.dark-mode .su-player-name {
  color: var(--5u-slate) !important;
}


/* ============================================================
   CHAMPIONS PAGE — full roster layout (dedicated Our Champions
   page, native Gutenberg blocks — NOT the homepage mini-feed
   above, though it reuses .su-team-name/.su-team-club/
   .su-player-row/.su-pos/.su-player-name from that section
   since those classes aren't scoped to .su-champ-card).

   Structure:
   - Group, class "su-champ-page-event" — one per event, repeats
     down the page (most recent first).
     - header content: h2.su-section-h (event name), p with
       class "su-champ-page-meta" (dates), p with class
       "su-champ-page-host" (host club).
     - Group/Columns, class "su-medal-row" — three medal cards.
       - Group, class "su-medal-card" PLUS exactly one of
         "su-medal-card--gold" / "su-medal-card--silver" /
         "su-medal-card--bronze".
         - Group, class "su-medal-hdr" — set this Group's block
           orientation to HORIZONTAL in the editor (the CSS also
           forces flex-direction via !important, but match it in
           the editor too so it's not fighting the CSS). Contains
           three separate text elements, each its own
           paragraph/text block with one of these classes:
             - "su-medal-tier" — "🥇 Gold" / "🥈 Silver" / "🥉 Bronze"
             - "su-medal-team-name" — e.g. "Team Purves"
             - "su-medal-team-club" — e.g. "St. Paul Curling Club ·
               MN, USA" (the "·" here is the one BETWEEN club and
               state/province — keep typing that one. Don't add a
               leading "·" before the club name itself; CSS forces
               this onto its own line via flex-basis, deliberately
               with no leading separator, so the line is always
               club-name-first, not dot-first.)
           CSS adds a "·" before su-medal-team-name automatically
           (::before) — don't type that one manually. su-medal-team-
           club gets no automatic leading dot (see above).
         - Image block, class "su-medal-photo" — team photo.
         - Group, class "su-medal-body" — roster ONLY now (no team
           name/club here anymore). Same .su-player-row/.su-pos/
           .su-player-name pattern as homepage .su-champ-card.
   ============================================================ */

/* Outer wrapper Group around ALL events — owns the page's top inset
   from the nav and bottom inset before the footer. Horizontal side
   padding and width centering used to live here too, but that's now
   handled universally for every native page (this one included) by
   the ".wp-block-post-content" rule under "NATIVE PAGE CONTENT —
   SIDE PADDING" near the top of this file — keeping it here too
   would have doubled the inset (this Group nested inside an
   already-padded post-content box). Only vertical spacing remains
   page-specific to Champions. */
.su-champ-page {
  padding-top: 40px;
  padding-bottom: 56px;
}

.su-champ-page-event {
  padding-bottom: 36px;
  margin-bottom: 36px;
  border-bottom: 1px solid var(--5u-light-border);
}

body.dark-mode .su-champ-page-event {
  border-bottom-color: rgba(255, 255, 255, 0.08);
}

/* Last event shouldn't carry a trailing divider/space before
   whatever follows (sponsors, footer, etc). :last-of-type rather
   than :last-child since WP may wrap these Groups inside other
   block-level siblings (e.g. a Page block's root appender). */
.su-champ-page-event:last-of-type {
  padding-bottom: 0;
  margin-bottom: 0;
  border-bottom: none;
}

.su-champ-page-meta {
  font-size: 13px !important;
  color: var(--5u-light-text-muted) !important;
  margin: 0 0 2px;
}

body.dark-mode .su-champ-page-meta {
  color: var(--5u-slate-dim) !important;
}

.su-champ-page-host {
  font-size: 13px !important;
  color: var(--5u-light-text-muted) !important;
  margin: 0 0 20px;
}

body.dark-mode .su-champ-page-host {
  color: var(--5u-slate-dim) !important;
}

/* Event name + date + host club on one line, tablet and up. This is
   the BASE (desktop+tablet) rule, following this codebase's
   desktop-first convention — the phone override that restores
   vertical stacking lives in the 600px breakpoint block below, not
   here. Markup: wrap the existing h2.su-section-h +
   p.su-champ-page-meta + p.su-champ-page-host in a new Group with
   class "su-champ-page-hdr" (this didn't exist before — those three
   were previously plain siblings of .su-champ-page-event with no
   shared container, which is why they had no way to lay out in a
   row together).

   flex-direction/align-items are !important for the same recurring
   reason as .su-medal-card/.su-medal-hdr above: WP's auto-generated
   per-instance layout class on this Group would otherwise win at
   equal specificity and override a non-important value.

   No flex-basis: 100% trick here (unlike .su-medal-team-club) —
   there's no sibling card whose header height this needs to match,
   so a plain wrap if the combined text doesn't fit is an acceptable
   fallback, not a height-consistency bug. */
.su-champ-page-hdr {
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: wrap;
  align-items: baseline !important;
  gap: 4px 10px;
  margin-bottom: 20px;
}

.su-champ-page-hdr > * {
  margin: 0 !important;
}

/* Separator dots — only meaningful in the one-line layout above;
   the phone override below removes these (content: none) since a
   dot at the start of a stacked line is the exact orphan-separator
   problem already solved for .su-medal-team-club. */
.su-champ-page-hdr .su-champ-page-meta::before,
.su-champ-page-hdr .su-champ-page-host::before {
  content: "·";
  margin-right: 8px;
  color: var(--5u-slate-dim);
}

/* Three medal cards across. display:grid + grid-template-columns
   are !important because WordPress generates its own layout CSS for
   whatever block type holds the cards (a Group's flex/flow layout,
   etc.) and that generated rule was winning over a non-important
   grid here — which is why the cards were NOT actually in this grid
   (confirmed by the symptoms: they neither stacked at the mobile
   breakpoint nor took equal heights, both of which a real grid does
   for free). align-items: stretch (the grid default, stated
   explicitly) is what makes every card in a row match the tallest
   sibling's height regardless of roster length. The card's DIRECT
   children must be the three .su-medal-card Groups — use a plain
   Group block here, NOT a Columns block (Columns wraps each child
   in an extra .wp-block-column, which would become the grid item
   instead of the card). */
.su-medal-row {
  display: grid !important;
  grid-template-columns: repeat(3, 1fr) !important;
  gap: 20px !important;
  align-items: stretch;
}

/* Card itself is a flex column so the body can grow to fill the
   extra height a shorter-roster card gets from grid stretch —
   without this, an equal-height card with fewer players would show
   a gap of bare card background below its body. gap:0 + the child
   margin reset below keep header/photo/body flush (no WP blockGap
   spacing between them). Border is on the single class (NOT a
   .wp-block-group compound) deliberately: the previous compound
   selector's `border` shorthand set border-top to transparent at a
   HIGHER specificity (0,0,2,0) than the --gold/--silver/--bronze
   modifiers (0,0,1,0), so the accent color never showed. Keeping
   the base border at single-class specificity lets the modifiers
   win on source order. */
.su-medal-card {
  display: flex !important;
  flex-direction: column;
  /* WP generates a per-instance layout class (e.g.
     .wp-container-core-group-is-layout-xxxxxxxx) on every vertical
     Group block that explicitly sets align-items: flex-start — at
     the same specificity as this rule, so omitting align-items here
     let that win by default instead of the browser's normal
     stretch. flex-start is what was actually causing the header/
     body width bug: each child (hdr, photo, body) sized to its own
     content's natural width along the cross-axis instead of
     filling the card — confirmed via Computed tab, where .su-medal-
     hdr measured 75px (sized to "Gold" text) while .su-medal-body
     measured 207px (sized to its longest line of text) on the same
     card. stretch forces every child to span the card's full
     width regardless of its own content length. */
  align-items: stretch !important;
  gap: 0 !important;
  border: 1px solid var(--5u-light-border) !important;
  border-top: 4px solid transparent !important;
  border-radius: 6px;
  overflow: hidden;
  padding: 0 !important;
}

/* border-right/bottom/left-color only — NOT the border-color
   shorthand. The shorthand sets all four sides including
   border-top-color, which at this rule's higher specificity
   (0,0,2,0) silently overrode the --gold/--silver/--bronze
   modifiers' border-top-color (0,0,1,0) any time dark mode was
   active — confirmed as the actual cause of the "no accent stripe"
   symptom, not a missing/unapplied modifier class. */
body.dark-mode .su-medal-card {
  border-right-color: rgba(255, 255, 255, 0.08) !important;
  border-bottom-color: rgba(255, 255, 255, 0.08) !important;
  border-left-color: rgba(255, 255, 255, 0.08) !important;
}

/* Neutralize WP block layout interference on the card's children:
   blockGap margins (the unintended spacing between header/photo/
   body) AND constrained-layout max-width + auto side margins (which
   left the header/body backgrounds narrower than the card, the
   "partially-filled background" symptom). max-width:none + margin:0
   force every child to span the card edge-to-edge and sit flush. */
.su-medal-card > * {
  max-width: none !important;
  margin: 0 !important;
}

.su-medal-card--gold {
  border-top-color: var(--5u-medal-gold) !important;
}

.su-medal-card--silver {
  border-top-color: var(--5u-medal-silver) !important;
}

.su-medal-card--bronze {
  border-top-color: var(--5u-medal-bronze) !important;
}

/* Holds tier + team name + team club on one line (falls back to
   wrapping onto a second line if a long club name doesn't fit —
   flex-wrap: wrap rather than nowrap/ellipsis, so the full club name
   stays readable instead of being truncated). flex-direction: row
   and align-items: baseline are !important for the same reason
   .su-medal-card needed align-items: stretch !important — WP's
   auto-generated per-instance layout class on this Group (if its
   orientation is set to Vertical in the editor) sets
   flex-direction: column / align-items: flex-start at equal
   specificity and would otherwise win by default over a
   non-important rule here. */
.su-medal-hdr,
.su-medal-hdr.wp-block-group {
  flex: 0 0 auto;
  background: var(--5u-light-surface-alt) !important;
  padding: 10px 16px !important;
  border-radius: 0 !important;
  border-bottom: 1px solid var(--5u-light-border);
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: wrap;
  align-items: baseline !important;
  gap: 4px 6px;
}

body.dark-mode .su-medal-hdr,
body.dark-mode .su-medal-hdr.wp-block-group {
  background: var(--5u-navy-dark) !important;
  border-bottom-color: rgba(255, 255, 255, 0.05);
}

/* Margin reset for the hdr's own children — same reasoning as
   .su-medal-card > * below: these are separate Paragraph blocks
   inside the Group, and a Paragraph's default margin would add
   unwanted vertical space and break the single-line baseline
   alignment. Scoped to .su-medal-hdr specifically rather than
   relying on the broader .su-medal-card > * rule, since these are
   grandchildren (.su-medal-hdr's children), not direct children of
   .su-medal-card. */
.su-medal-hdr > * {
  margin: 0 !important;
}

.su-medal-tier {
  font-family: var(--5u-font-display);
  font-size: 14px !important;
  font-weight: 700;
  color: var(--5u-light-text) !important;
}

body.dark-mode .su-medal-tier {
  color: var(--5u-ice-white) !important;
}

.su-medal-card--gold .su-medal-tier {
  color: var(--5u-medal-gold) !important;
}

.su-medal-card--silver .su-medal-tier {
  color: var(--5u-medal-silver) !important;
}

.su-medal-card--bronze .su-medal-tier {
  color: var(--5u-medal-bronze) !important;
}

.su-medal-team-name {
  font-family: var(--5u-font-display);
  font-size: 15px !important;
  font-weight: 700;
  color: var(--5u-light-text) !important;
}

body.dark-mode .su-medal-team-name {
  color: var(--5u-ice-white) !important;
}

/* "·" separator before team name/club — added here via ::before
   rather than typed into the editor content, so the dot's spacing
   and muted color are consistent and can't be fat-fingered into the
   wrong style by accident when someone edits roster text later. */
.su-medal-team-name::before {
  content: "·";
  margin-right: 6px;
  color: var(--5u-slate-dim);
  font-weight: 400;
}

/* flex-basis: 100% on a flex item in a wrapping flex container
   forces it onto its own new line UNCONDITIONALLY, regardless of
   whether tier+name+club would have technically fit together —
   this is what makes the header's line count fixed at exactly 2
   (tier+name on line 1, club on line 2) instead of varying with
   club-name length. Without this, whether club wrapped onto its own
   line depended on each team's specific name/club length relative
   to the card's width, which is why header height differed card to
   card in the same row (confirmed via screenshot: Gold's shorter
   combined text fit on one line while Silver/Bronze's didn't, at
   the same card width) — a real card-width range was checked
   (220–726px across breakpoints) and even the longest realistic
   club name reliably fits when given a guaranteed full line to
   itself, so this isn't a partial fix that could still wrap awkwardly
   mid-string at typical lengths. No ::before dot here (unlike
   .su-medal-team-name above) — since the line break is now
   deliberate rather than wrap-induced, a leading dot would just be
   an orphaned character with nothing to its left, the exact problem
   this rule exists to avoid; matches the homepage .su-team-club,
   which also has no leading dot of its own. */
.su-medal-team-club {
  flex-basis: 100%;
  font-size: 12px !important;
  color: var(--5u-light-text-muted) !important;
}

body.dark-mode .su-medal-team-club {
  color: var(--5u-slate-dim) !important;
}

/* Fixed-aspect frame so cards stay the same height regardless of
   each source photo's native dimensions — object-fit: cover crops
   to fill rather than letterboxing or stretching. Apply this class
   to the Image block's wrapping figure; WP's Image block renders
   <figure class="wp-block-image"><img>, so the rule below targets
   the img directly via descendant selector rather than assuming
   the class lands on <img> itself. flex:0 0 auto so the fixed 4:3
   height is honored and the photo isn't stretched by the flex
   column when the card grows. */
.su-medal-photo {
  flex: 0 0 auto;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--5u-light-surface-alt);
  margin: 0 !important;
}

body.dark-mode .su-medal-photo {
  background: var(--5u-navy-lift);
}

.su-medal-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* flex:1 1 auto — the body absorbs the leftover height when grid
   stretch makes this card taller than its own content needs, so the
   surface-colored background fills to the card's bottom edge rather
   than stopping under the last player row. */
.su-medal-body,
.su-medal-body.wp-block-group {
  flex: 1 1 auto;
  background: var(--5u-light-surface) !important;
  padding: 16px 18px !important;
}

body.dark-mode .su-medal-body {
  background: var(--5u-navy-lift) !important;
}

/* Position label column — wider than the homepage card's 32px
   because this page's rosters include longer position words the
   homepage never shows ("Second", "Alternate", "Coach"), which were
   overflowing the 32px box and colliding with the player name. 64px
   still read as cramped for "Alternate" per user feedback; bumped
   to 72px. Scoped to .su-medal-body so the homepage .su-champ-card's
   own .su-pos stays at its tuned 32px. */
.su-medal-body .su-pos {
  width: 72px;
}


/* ============================================================
   TEAM / BOARD PAGE
   Native Gutenberg page (NOT the homepage Custom HTML block).
   Classes added via each block's "Additional CSS class(es)".
   Mirrors the Champions .su-medal-* card system — same grid /
   stretch / WP-layout-neutralizing tricks; see those comments.
   Deliberately simpler shell than a medal card: no header bar and
   no colored top accent — the photo is the card's FIRST child, so
   it bleeds to top + left + right (only the card's exterior corners
   round it), then the body follows.
   ============================================================ */

.su-team-page {
  padding-top: 40px;
  padding-bottom: 56px;
}

/* Page intro — reuses .su-section-tag (eyebrow) + .su-section-h
   (heading); .su-team-lead is an optional one-line intro. */
.su-team-intro {
  margin-bottom: 32px;
}
.su-team-lead {
  font-size: 15px !important;
  color: var(--5u-light-text-body) !important;
  max-width: 640px;
  margin: 8px 0 0 !important;
}
body.dark-mode .su-team-lead {
  color: var(--5u-slate) !important;
}

/* Two members across. display:grid + columns !important for the same
   reason as .su-medal-row (WP's per-instance layout class on the
   holding Group otherwise wins over a non-important grid). Use a
   PLAIN Group block, NOT Columns, so the four .su-team-card Groups
   are the direct grid items. align-items: stretch equalizes card
   heights per row so different bio lengths still line up. */
.su-team-grid {
  display: grid !important;
  grid-template-columns: repeat(2, 1fr) !important;
  gap: 24px !important;
  align-items: stretch;
}

.su-team-card,
.su-team-card.wp-block-group {
  display: flex !important;
  flex-direction: column;
  align-items: stretch !important;
  gap: 0 !important;
  border: 1px solid var(--5u-light-border) !important;
  border-radius: 8px;
  overflow: hidden;
  padding: 0 !important;
  background: var(--5u-light-surface) !important;
}
body.dark-mode .su-team-card {
  border-color: rgba(255, 255, 255, 0.08) !important;
  background: var(--5u-navy-lift) !important;
}

/* Neutralize WP constrained-layout max-width/auto-margins so photo
   and body span the full card width (full-bleed left/right; exterior
   corners rounded by the card's own overflow:hidden + radius). Same
   trick as .su-medal-card > *. */
.su-team-card > * {
  max-width: none !important;
  margin: 0 !important;
}

/* Full-bleed photo, flush to top/left/right. 4:3 matches the site's
   established card-photo ratio (.su-medal-photo); adjustable here if
   head-and-shoulders crops want something taller — photos are
   placeholders, so dial in during visual QA. flex:0 0 auto keeps the
   photo height fixed when grid-stretch makes a card taller than its
   content.

   The img rules are !important AND use the compound
   ".su-team-photo.wp-block-image img" selector (specificity 0,2,1) so
   they beat WordPress core's ".wp-block-image img { height:auto }"
   REGARDLESS of stylesheet print order. WP prints block-library /
   global styles AFTER the enqueued theme stylesheet, so a plain
   ".su-team-photo img" (0,1,1) loses the specificity tie on source
   order — WP's height:auto then wins, object-fit:cover silently stops
   working, and each image sizes to its own source ratio instead of
   the fixed box (confirmed: a source at/near the card's own width
   rendered at the wrong height). width:100% on the figure likewise
   guards against WP's fit-content sizing of .wp-block-image. This is
   why .su-medal-photo never hit it — those photos are all larger than
   their card, so cover always crops and the failure never surfaces;
   here a member could submit a small/near-card-width headshot. */
.su-team-photo,
.su-team-photo.wp-block-image {
  display: block;
  width: 100%;
  flex: 0 0 auto;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--5u-light-surface-alt);
}
body.dark-mode .su-team-photo {
  background: var(--5u-navy-base);
}
.su-team-photo img,
.su-team-photo.wp-block-image img {
  width: 100% !important;
  height: 100% !important;
  object-fit: cover;
  display: block;
}

/* Body absorbs leftover height (flex:1 1 auto) so the card surface
   fills to the bottom edge when a shorter bio would otherwise leave a
   gap under a grid-stretched card. */
.su-team-body,
.su-team-body.wp-block-group {
  flex: 1 1 auto;
  padding: 20px 22px 24px !important;
}
.su-team-body > * {
  max-width: none !important;
  margin: 0 !important;
}

.su-team-name {
  font-family: var(--5u-font-display) !important;
  font-size: 22px !important;
  font-weight: 700;
  line-height: 1.15;
  color: var(--5u-light-text) !important;
  margin: 0 0 4px !important;
}
body.dark-mode .su-team-name {
  color: var(--5u-ice-white) !important;
}

/* Role — gold uppercase label (consistent with gold's "section
   label" role; reads on both modes). */
.su-team-role {
  font-size: 11px !important;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--5u-gold) !important;
  margin: 0 0 12px !important;
}

/* Location + club(s): muted, tight-stacked. */
.su-team-location,
.su-team-clubs {
  font-size: 13px !important;
  color: var(--5u-light-text-muted) !important;
  margin: 0 0 2px !important;
}
body.dark-mode .su-team-location,
body.dark-mode .su-team-clubs {
  color: var(--5u-slate-dim) !important;
}

/* Bio — separated from the meta block by a hairline rule. */
.su-team-bio {
  font-size: 14px !important;
  line-height: 1.65;
  color: var(--5u-light-text-body) !important;
  margin: 14px 0 0 !important;
  padding-top: 14px;
  border-top: 1px solid var(--5u-light-border);
}
body.dark-mode .su-team-bio {
  color: var(--5u-slate) !important;
  border-top-color: rgba(255, 255, 255, 0.08);
}


/* ============================================================
   EVENT PAGE (/2026-glenmore-curling-club/)
   Native Gutenberg page. Centered content within the universal
   .wp-block-post-content inset (same model as Champions/Team) —
   deliberately NOT the homepage's full-viewport bands, which would
   need a 100vw + negative-margin bleed to escape the native page's
   side padding + WP's constrained max-width cap (a viewport-math
   technique this codebase avoids). Intentionally lean to avoid
   repeating what the homepage/history pages already say: a title +
   one-line facts sub, then plain section headings (no eyebrow tags),
   with a single venue card as the one visual anchor. Reuses
   .su-sponsors, .su-section-h, .su-link.
   ============================================================ */

.su-event-page {            /* vertical padding only; horizontal inset
                               comes from .wp-block-post-content */
  padding-top: 40px;
  padding-bottom: 56px;
}

/* Title — the page's only hero element (no eyebrow, no CTA cluster).
   Self-locking clamp, SAME formula as .su-hero-name-main (one knob
   drives PREFERRED and MAX so they can't drift). Compound with
   .wp-block-heading to beat core heading sizing on the native H1. */
.su-event-title,
.wp-block-heading.su-event-title {
  font-family: var(--5u-font-display) !important;
  --5u-event-title-vw: 5.2;
  font-size: clamp(
    38px,
    calc(var(--5u-event-title-vw) * 1vw),
    calc(var(--5u-content-visible) * var(--5u-event-title-vw) * 1296 / 1168 / 100)
  ) !important;
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: 0.005em;
  color: var(--5u-light-text) !important;
  max-width: 20ch;
  margin: 0 0 14px !important;
}
body.dark-mode .su-event-title { color: var(--5u-ice-white) !important; }

/* One-line facts sub (dates · venue · location) — replaces the
   separate homepage-style strip, which carried the exact same info in
   more space. margin:0; the following section's margin-top spaces it. */
.su-event-hero-sub {
  font-size: 16px !important;
  color: var(--5u-light-text-body) !important;
  line-height: 1.5;
  margin: 0 !important;
}
body.dark-mode .su-event-hero-sub { color: var(--5u-slate) !important; }

.su-event-section { margin-top: 40px; }

/* Body copy — class sits directly on the paragraph (no wrapper Group). */
.su-event-body {
  font-size: 15px !important;
  color: var(--5u-light-text-body) !important;
  line-height: 1.8;
  max-width: 680px;
  margin: 0 !important;
}
body.dark-mode .su-event-body { color: var(--5u-slate) !important; }

/* Venue — the page's single card (bordered panel). Logo | info via a
   CSS GRID on a plain Group (not a Columns block: WP Columns can't
   have their ratio edited after creation, and grid matches the
   .su-medal-row/.su-team-grid pattern already used here). grid +
   align-items are !important to beat WP's per-instance .wp-container-*
   layout class (same gotcha as those grids). */
.su-venue {
  margin-top: 16px;
  border: 1px solid var(--5u-light-border);
  border-radius: 10px;
  background: var(--5u-light-surface);
  padding: 28px;
  box-sizing: border-box;
}
body.dark-mode .su-venue {
  border-color: rgba(255, 255, 255, 0.08);
  background: var(--5u-navy-lift);
}
.su-venue-grid {
  display: grid !important;
  grid-template-columns: 220px 1fr !important;
  gap: 32px !important;
  align-items: center !important;
}
.su-venue-grid > * {         /* neutralize WP constrained-child width */
  min-width: 0;
  max-width: none !important;
  margin: 0 !important;
}

/* Club mark on a persistent white chip so a dark logo stays legible
   in dark mode. */
.su-venue-logo,
.su-venue-logo.wp-block-image {
  display: block;
  width: 100%;
  margin: 0;
  box-sizing: border-box;
  background: #fff;
  border: 1px solid var(--5u-light-border);
  border-radius: 8px;
  padding: 20px;
}
body.dark-mode .su-venue-logo { border-color: rgba(255, 255, 255, 0.09); }

/* Logo containment fix — same cascade-order reasoning as
   .su-team-photo: compound selector (0,2,1) + !important beats core's
   .wp-block-image img { height:auto } regardless of print order.
   object-fit:contain so the mark scales whole and is NEVER cropped
   (this is the fix for the oversized full-res logo). */
.su-venue-logo img,
.su-venue-logo.wp-block-image img {
  width: 100% !important;
  height: 140px !important;
  max-width: 100% !important;
  object-fit: contain;
  display: block;
}

.su-venue-name {
  font-family: var(--5u-font-display) !important;
  font-size: 22px !important;
  font-weight: 700;
  color: var(--5u-light-text) !important;
  margin: 0 0 6px !important;
}
body.dark-mode .su-venue-name { color: var(--5u-ice-white) !important; }

/* Address line carries the "Get Directions →" link inline (an inline
   link on the paragraph — no separate block, no Custom HTML). */
.su-venue-address {
  font-size: 15px !important;
  color: var(--5u-light-text-body) !important;
  line-height: 1.6;
  margin: 0 0 14px !important;
}
body.dark-mode .su-venue-address { color: var(--5u-slate) !important; }
.su-venue-address a {
  color: var(--5u-red) !important;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

/* History — one paragraph, class directly on it (no wrapper Group). */
.su-venue-history {
  font-size: 14px !important;
  color: var(--5u-light-text-body) !important;
  line-height: 1.75;
  margin: 0 !important;
}
body.dark-mode .su-venue-history { color: var(--5u-slate) !important; }

/* Schedule / Teams placeholders */
.su-event-placeholder {
  font-size: 15px !important;
  color: var(--5u-light-text-muted) !important;
  font-style: italic;
  line-height: 1.7;
  margin: 0 !important;
}
body.dark-mode .su-event-placeholder { color: var(--5u-slate-dim) !important; }

/* Sponsors reused; contain (zero the homepage band's full-bleed side
   padding + bottom border so it sits flush as page content). */
.su-event-page .su-sponsors {
  padding-left: 0 !important;
  padding-right: 0 !important;
  border-bottom: none !important;
  border-radius: 8px;
  margin-top: 40px;
}


/* ============================================================
   MISSION SECTION
   Apply class "su-mission" to outer Group block.
   ============================================================ */

.su-mission,
.su-mission.wp-block-group {
  background: var(--5u-light-surface-alt) !important;
  border-bottom: 1px solid var(--5u-light-border);
  padding-top: 38px;
  padding-bottom: 38px;
  padding-left: max(32px, calc((100% - var(--5u-content-max)) / 2));
  padding-right: max(32px, calc((100% - var(--5u-content-max)) / 2));
  box-sizing: border-box;
}

body.dark-mode .su-mission {
  background: var(--5u-navy-lift) !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.su-mission p,
.su-mission .wp-block-paragraph {
  font-size: 14px;
  color: var(--5u-light-text-body);
  line-height: 1.8;
  max-width: 660px;
}

body.dark-mode .su-mission p,
body.dark-mode .su-mission .wp-block-paragraph {
  color: var(--5u-slate);
}


/* ============================================================
   FOOTER
   Apply class "su-footer" to the Footer template part.
   ============================================================ */

.su-footer,
.wp-block-template-part.su-footer {
  background: var(--5u-light-surface) !important;
  border-top: 2px solid var(--5u-gold);
  padding-top: 32px;
  padding-bottom: 18px;
  padding-left: max(28px, calc((100% - var(--5u-content-max)) / 2));
  padding-right: max(28px, calc((100% - var(--5u-content-max)) / 2));
  box-sizing: border-box;
}

/* Light mode is the default above — same family of fix as .su-nav:
   the footer was a permanent dark band regardless of mode. Link
   hover and the bottom bar below get matching overrides for the
   same reason; headings and link rest-state colors (gold and
   slate-dimmest) already have enough contrast on both backgrounds
   and don't need mode-specific variants. */
body.dark-mode .su-footer,
body.dark-mode .wp-block-template-part.su-footer {
  background: var(--5u-navy-deepest) !important;
}

.su-footer img,
.su-footer .wp-block-image img {
  max-height: 32px;
  opacity: 0.65;
}

.su-footer-tagline {
  font-size: 13px !important;
  color: var(--5u-slate-dimmest) !important;
  line-height: 1.65;
}

.su-footer h4,
.su-footer .wp-block-heading {
  font-family: var(--5u-font-body) !important;
  font-size: 11px !important;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--5u-gold) !important;
  margin-bottom: 11px;
  text-align: center;
}

/* Centering experiment, all screen sizes — both ".wp-block-group.
   is-vertical" levels confirmed in the rendered markup (the per-
   column outer wrapper AND the inner group wrapping each nav block)
   need align-items: center, since by default WP's flex column
   layout left-aligns children to the container's cross-axis start;
   text-align on the heading/links alone wouldn't move their boxes,
   only the text within them. */
.su-footer .wp-block-group.is-vertical,
.su-footer .wp-block-navigation__container {
  align-items: center;
}

.su-footer a {
  font-size: 13px;
  color: var(--5u-slate-dimmest) !important;
  text-decoration: none;
  text-align: center;
}

.su-footer a:hover {
  /* --5u-slate is "brightening on dark backgrounds" per its
     documented role — same wrong-direction issue as the dark mode
     toggle button's hover before that fix. var(--5u-light-text) is
     the light-mode equivalent "brightens on hover" direction. */
  color: var(--5u-light-text) !important;
}

body.dark-mode .su-footer a:hover {
  color: var(--5u-slate) !important;
}

/* Footer bottom bar — apply class "su-footer-bottom" to a Group block */
.su-footer-bottom,
.su-footer-bottom.wp-block-group {
  background: var(--5u-light-surface-alt) !important;
  border-top: 1px solid var(--5u-light-border);
  padding: 11px 28px !important;
}

body.dark-mode .su-footer-bottom,
body.dark-mode .su-footer-bottom.wp-block-group {
  background: var(--5u-navy-deepest) !important;
  border-top: 1px solid rgba(255, 255, 255, 0.04);
}

.su-footer-bottom p,
.su-footer-bottom .wp-block-paragraph {
  font-size: 12px !important;
  color: var(--5u-light-text-muted) !important;
}

body.dark-mode .su-footer-bottom p,
body.dark-mode .su-footer-bottom .wp-block-paragraph {
  color: #243040 !important;
}


/* ============================================================
   DARK MODE TOGGLE BUTTON
   Floating icon button, fixed to the viewport's bottom-right
   corner — taken out of the page content flow entirely (it used to
   sit in its own full-width row between sections, which read as an
   awkward leftover strip rather than a real piece of content).
   Markup is injected automatically on every front-end page by
   fiveunder_dark_mode_toggle() in functions.php (hooked to
   wp_footer) — not pasted into page content or a template part, so
   it can't be lost or forgotten on pages other than the homepage.
   Both icons ship in the markup always; which one is visible is
   controlled entirely by CSS below based on body.dark-mode, so
   theme.js never has to touch the button's child content (it used
   to set textContent on every toggle, which would now destroy the
   icon markup — updated to set aria-label instead). The icon shown
   is always the mode you'd switch TO: a moon in light mode (tap for
   dark), a sun in dark mode (tap for light). */

.su-dark-toggle {
  position: fixed;
  bottom: 20px;
  right: 20px;
  /* Above page content/footer, below the open mobile nav overlay
     (z-index 200) so the overlay can still cover it while open. */
  z-index: 150;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-radius: 50%;
  cursor: pointer;
  /* Solid background rather than transparent — this button now
     floats over whatever happens to be scrolled beneath it (footer,
     page content, etc.) rather than sitting in a known, fixed
     section background like before, so it needs its own contrast
     independent of what's behind it. */
  background: var(--5u-light-surface);
  border: 1px solid var(--5u-light-border);
  color: var(--5u-light-text-muted);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}

body.dark-mode .su-dark-toggle {
  background: var(--5u-navy-dark);
  border-color: rgba(255, 255, 255, 0.12);
  color: var(--5u-slate);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

.su-dark-toggle:hover {
  color: var(--5u-light-text);
  border-color: var(--5u-light-text-muted);
}

body.dark-mode .su-dark-toggle:hover {
  color: var(--5u-ice-white);
  border-color: var(--5u-slate);
}

.su-dark-toggle svg {
  width: 20px;
  height: 20px;
}

/* Default (light mode): show the moon, hide the sun. */
.su-dark-toggle .su-icon-sun {
  display: none;
}

.su-dark-toggle .su-icon-moon {
  display: block;
}

body.dark-mode .su-dark-toggle .su-icon-sun {
  display: block;
}

body.dark-mode .su-dark-toggle .su-icon-moon {
  display: none;
}


/* ============================================================
   RESPONSIVE — mobile breakpoint
   ============================================================ */

@media (max-width: 768px) {
  /* NOTE: these flat padding overrides replace the calc()-based
     centering padding used at desktop widths. This is intentional
     and safe — mobile viewports are always narrower than
     --5u-content-max (1232px), so the calc() would resolve to its
     own minimum-padding floor anyway at these sizes. Flat values
     here are just simpler to read/maintain for the mobile case. */
  .su-hero {
    padding: 32px 20px 28px;
  }

  /* Header logo steps down from its 96px desktop size — tablet tier. */
  .su-nav .wp-block-site-logo img {
    width: 80px !important;
    height: 80px !important;
  }

  /* Native page content (History, Champions, etc.) — same flat-20px
     step-down as every other section at this breakpoint, applied to
     the base rule above instead of recalculating the same max()
     expression (which would resolve to this same floor anyway). */
  body:not(.home) .wp-block-post-content {
    padding-left: 20px;
    padding-right: 20px;
  }

  /* Two-column hero stacks to one column on mobile — name/CTAs
     first, then the divider becomes a horizontal rule, then the
     headline/flavor text below.

     IMPORTANT: .su-hero-name-col and .su-hero-flavor-col both use
     "flex: 1.15" / "flex: 1" at desktop widths, which controls
     WIDTH distribution when .su-hero-inner is flex-direction: row.
     Once we switch to flex-direction: column here, those same
     flex-basis values control HEIGHT distribution instead — width
     reverts to "size to content," which is why the name column
     (and therefore the CTA buttons inside it) were only as wide as
     the text "Five and Under" itself, not the full viewport.
     Setting width: 100% explicitly on both columns fixes this
     regardless of how flex-basis behaves in the column direction. */
  .su-hero-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 28px;
  }

  .su-hero-name-col,
  .su-hero-flavor-col {
    width: 100%;
  }

  .su-hero-flavor-col {
    border-left: none;
    border-top: 1px solid rgba(255, 255, 255, 0.25);
    padding-left: 0;
    padding-top: 24px;
  }

  body:not(.dark-mode) .su-hero-flavor-col {
    border-top-color: rgba(20, 30, 40, 0.25);
  }

  /* RINGS — mobile-specific floor.
     Below 768px the hero switches from a two-column row to a
     stacked column (see .su-hero-inner above), and the section's
     height stops being driven by viewport width entirely — it's
     just padding + however tall the stacked content happens to
     render, which varies with line-wrapping and has no fixed
     relationship to vw. The existing clamp() on .su-rings-wrap svg
     is correctly width-responsive, but width and the stacked
     hero's height are decoupled at this layout, so a width-only
     formula can't track "most of the hero" once stacking kicks in
     — confirmed via testing: at narrow phone widths the existing
     90.12vw rate produces a ring noticeably smaller than the
     stacked content block, reading as a token accent rather than
     the intended texture-across-the-hero effect.

     Fix: explicitly raise the floor for this breakpoint only. This
     doesn't touch the underlying clamp's vw rate or its desktop/
     tablet behavior (iPad and up render exactly as before) — it
     only raises what the MIN side of that clamp can settle on once
     we're inside the stacked mobile layout. 600px confirmed via
     side-by-side screenshot comparison against 440px — at 600px the
     rings visibly extend through the divider/headline area instead
     of topping out partway down, making better use of the stacked
     layout's vertical space without overpowering it. */
  .su-rings-wrap svg {
    width: max(600px, clamp(
      180px,
      calc(var(--5u-rings-vw) * 1vw),
      calc(var(--5u-content-visible) * var(--5u-rings-vw) * 1296 / 1168 / 100)
    )) !important;
    height: max(600px, clamp(
      180px,
      calc(var(--5u-rings-vw) * 1vw),
      calc(var(--5u-content-visible) * var(--5u-rings-vw) * 1296 / 1168 / 100)
    )) !important;
  }

  /* MOBILE NAME SIZING — values tested across Galaxy S8+ (360px)
     through iPad Mini, confirmed by hand rather than estimated. */
  .su-hero-name-main {
    font-size: clamp(40px, 16vw, 120px);
  }

  .su-hero-name-sub {
    font-size: clamp(18px, 8vw, 64px);
  }

  .su-hero h1,
  .su-hero .wp-block-heading {
    font-size: clamp(28px, 4vw, 32px);
  }

  /* CTA EXPERIMENT: full-width, equal-split buttons on mobile
     instead of left-aligned inline buttons sized to their text.
     Easy to revert — remove this block to go back to the default
     inline button sizing/spacing defined for desktop. */
  .su-hero-ctas {
    display: flex;
    gap: 10px;
    width: 100%;
  }

  .su-hero-ctas .su-btn-primary,
  .su-hero-ctas .su-btn-outline {
    flex: 1;
    text-align: center;
    margin-left: 0;
  }

  /* NOTE: .su-hero h1 sizing is now set once, earlier in this same
     media query (clamp(28px, 4vw, 32px)) — a duplicate flat 22px
     rule used to live here, which would have silently overridden
     the clamp() version since both have identical specificity and
     this one came later in source order. Removed. */

  /* Event strip: still 3 columns through this breakpoint (768px,
     tablet width) — this is the fix for the iPad Mini issue. Only
     the outer wrapper's SIDE padding changes here; column count
     doesn't drop until the narrower phone-only breakpoint below.
     Left/right only (not the `padding` shorthand) — a prior version
     used `padding: 0 20px`, which also zeroed top/bottom and wiped
     out the base rule's 24px vertical padding, leaving content
     cramped against the section's top/bottom edges at this
     breakpoint. */
  .su-strip,
  .su-strip.wp-block-group {
    padding-left: 20px;
    padding-right: 20px;
  }

  .su-sponsors {
    flex-wrap: wrap;
    gap: 12px;
    padding: 20px 20px;
  }

  /* Logos step down from the 56px desktop size starting at tablet —
     confirmed via screenshot that the row only wraps to a second
     line at this breakpoint (the smallest desktop width was fine),
     so tablet needs the same smaller size the phone breakpoint
     below also uses. 164px width keeps the same ratio as the
     desktop rule's 228px so Milwaukee Window Guys, the widest mark,
     still renders unclipped. */
  .su-sponsor-logo,
  .su-sponsor-logo.wp-block-group {
    height: 48px;
  }

  .su-sponsor-logo img,
  .su-sponsor-logo .wp-block-image img {
    max-height: 40px;
    max-width: 164px;
  }

  .su-explainer,
  .su-explainer.wp-block-group {
    flex-direction: column;
    padding: 28px 20px;
  }

  /* Mission and champions section heading/tag/link: these still
     used the desktop max(32px, calc(...)) side padding at this
     breakpoint and below — unlike every other section here, they
     never had a narrower-viewport override, so they stayed flush
     at 32px from the content edge while everything else around
     them had already stepped down to 20px. (.su-champ-grid itself
     is unaffected — its own responsive spacing is handled
     separately, see its breakpoint rule further down.) */
  .su-mission,
  .su-mission.wp-block-group {
    padding-left: 20px;
    padding-right: 20px;
  }

  .su-champs .su-section-tag,
  .su-champs .su-section-h,
  .su-champs > .su-link {
    padding-left: 20px;
    padding-right: 20px;
  }

  /* Champions page: smaller top/bottom insets than desktop's 40/56.
     Horizontal padding is no longer set here — the universal
     ".wp-block-post-content" rule already steps that down to 20px
     at this same breakpoint (see its own 768px override), and
     setting it here too would double it. */
  .su-champ-page {
    padding-top: 28px;
    padding-bottom: 40px;
  }

  /* 3-across medal grid -> single column. !important for the same
     reason as the base rule: it has to outrank WP's generated block
     layout CSS, which otherwise kept the cards in a 3-wide row that
     overflowed the screen instead of stacking. At tablet width each
     card's photo + full roster doesn't fit legibly 2 or 3 up, so
     this drops straight to 1 column rather than an intermediate
     2-column step. */
  .su-medal-row {
    grid-template-columns: 1fr !important;
  }

  /* 2-across team grid -> single column, same rationale/!important
     as .su-medal-row above. */
  .su-team-grid {
    grid-template-columns: 1fr !important;
  }

  /* Event page: smaller vertical insets (horizontal handled by the
     universal post-content 768px override, like .su-champ-page). */
  .su-event-page {
    padding-top: 28px;
    padding-bottom: 40px;
  }
  .su-venue {
    padding: 20px;
  }
  /* Venue grid stacks to one column. Cap the logo chip's width (else
     it spans the full card with a small centered logo and too much
     surrounding whitespace) and left-align it with the text below;
     drop the height a touch to save vertical space. */
  .su-venue-grid {
    grid-template-columns: 1fr !important;
    gap: 20px !important;
  }
  /* !important + the > child selector (0,2,0) is needed to beat the
     ".su-venue-grid > * { max-width:none !important }" neutralizer
     above, which otherwise forces the chip back to full width. */
  .su-venue-grid > .su-venue-logo {
    max-width: 260px !important;
  }
  .su-venue-logo img,
  .su-venue-logo.wp-block-image img {
    height: 130px !important;
  }

  /* Columns block stacks automatically on mobile in Gutenberg,
     so the two-column explainer and champion grid handle themselves */

  .su-section-h {
    font-size: 24px !important;
  }
}

/* ============================================================
   PHONE-ONLY BREAKPOINT
   Narrower than the 768px tablet breakpoint above. Currently only
   used by the event strip: 3 columns remain reasonable for the
   strip's longest value text ("Dollard-des-Ormeaux, QC") down
   through tablet widths, but get visibly cramped below ~600px,
   where the location text would start wrapping inside its column.
   600px was chosen as a value clearly in phone territory (below
   any standard tablet width) rather than tuned to a specific
   device — confirm against your usual breakpoint set (Galaxy S8+,
   etc.) and adjust if the wrap point doesn't match what you see.
   ============================================================ */
@media (max-width: 600px) {
  /* Header logo steps down again — phone tier. */
  .su-nav .wp-block-site-logo img {
    width: 64px !important;
    height: 64px !important;
  }

  /* Revert .su-champ-page-hdr's tablet+ one-line layout back to the
     original vertical stack on phones — explicit per-child margins
     restore the same spacing the un-wrapped elements had before
     .su-champ-page-hdr existed. The base rule's ".su-champ-page-hdr
     > * { margin: 0 !important }" zeroes EVERY child's margin
     including the heading's, at every breakpoint (it's never scoped
     to tablet+ only) — so the h2 needs its 14px bottom margin
     restored here too, not just meta/host, or it'd stay flush
     against the date line even in the stacked mobile layout.
     content: none removes the separator dots, which only make sense
     between items sitting on the same line. */
  .su-champ-page-hdr {
    flex-direction: column !important;
  }

  .su-champ-page-hdr h2.su-section-h {
    margin: 0 0 14px !important;
  }

  .su-champ-page-hdr .su-champ-page-meta {
    margin: 0 0 2px !important;
  }

  .su-champ-page-hdr .su-champ-page-host {
    margin: 0 0 20px !important;
  }

  .su-champ-page-hdr .su-champ-page-meta::before,
  .su-champ-page-hdr .su-champ-page-host::before {
    content: none;
  }

  /* .su-strip-card removed (see base rule comment) — .su-strip
     itself already provides side padding via the 768px breakpoint
     rule above (padding-left/padding-right: 20px), which cascades
     down to this breakpoint too, so .su-strip-grid and .su-strip-note
     no longer need their own horizontal padding logic to stay
     aligned with it.

     No padding-top here either — a prior version added 18px to
     compensate for .su-strip's vertical padding being wiped out by
     the old `padding: 0 20px` shorthand at the 768px breakpoint.
     Now that bug is fixed and .su-strip keeps its own 24px top/
     bottom padding at this breakpoint too, so this would just stack
     on top of that and make the top spacing read as too generous
     relative to the bottom. */
  .su-strip-grid {
    grid-template-columns: repeat(2, 1fr);
    row-gap: 0;
  }

  /* No phone-specific item padding here — a prior version set
     padding: 14px 14px 14px 0, but that gave items their own
     reduced spacing scheme instead of just inheriting the base
     rule's padding-right: 36px (see line ~1216). Removed per direct
     confirmation (toggled off in devtools and compared): without
     it, item spacing at this breakpoint matches the same
     padding-right/border-right pattern used at every other screen
     size instead of a one-off phone value. */

  /* Divider logic for a 2-column grid of 3 items, reworked after
     testing surfaced a real issue with the previous per-item
     border-bottom approach: when one item's value wraps to more
     lines than its row neighbor (confirmed via screenshot —
     "Glenmore Curling Club" wraps to 2 lines, "Dec 2-6, 2026"
     doesn't), a border-bottom drawn on the SHORTER item still sits
     at the correct row boundary (grid items stretch to fill their
     row height by default), but the empty space between the
     short item's content and that line reads as visually
     disconnected — the divider looks like it belongs to nothing.

     Fix: row 1 gets ONE shared divider, drawn as a border-top on
     item 3 (which spans the full card width via grid-column: 1/-1
     below) rather than as border-bottom on items 1+2 individually.
     A single full-width line reads as "this is where row 1 ends"
     regardless of any individual item's content height — it's
     structurally tied to the row, not to whichever item happens to
     be shortest. */
  .su-strip-item:nth-child(1) {
    border-right: 1px solid var(--5u-light-border);
    border-bottom: none;
  }

  body.dark-mode .su-strip-item:nth-child(1) {
    border-right-color: rgba(255, 255, 255, 0.09);
  }

  .su-strip-item:nth-child(2) {
    border-right: none;
    border-bottom: none;
  }

  .su-strip-item:nth-child(3) {
    grid-column: 1 / -1;
    border-right: none;
    border-bottom: none;
    border-top: 1px solid var(--5u-light-border);
    margin-top: 14px;
    padding-top: 14px;
  }

  body.dark-mode .su-strip-item:nth-child(3) {
    border-top-color: rgba(255, 255, 255, 0.09);
  }

  /* Sponsor logo dividers: border-left on each item orphans a leading
     divider on whichever logo lands first on a wrapped row, since
     CSS alone can't target "first item in a flex line" — that's a
     runtime box position, not something a selector can see (and a
     fixed nth-child rule, like the event strip uses, doesn't work
     either, since the sponsor list is intentionally open-ended — see
     homepage.html's "to add a sponsor" comment).

     A JS-based fix (tagging each row's true leader at runtime via
     offsetTop comparison, then suppressing the divider only on that
     item) was tried and reverted — technically correct, but each
     sponsor's source image has a different amount of transparent
     padding baked in, so the divider's visual gap from one logo to
     the next was inconsistent logo-to-logo even where the CSS box
     boundary was right. Not worth fixing with per-logo crop
     adjustments for a purely decorative rule. Simplest robust fix:
     drop the divider borders at this breakpoint entirely and rely on
     gap spacing (plus centering, below) to separate items instead —
     holds up regardless of sponsor count, wrap point, or a given
     logo's internal padding. */
  .su-sponsor-label {
    margin-right: 0;
  }

  /* Phone layout is a 3-row stack — label, then logos, then CTA —
     rather than the single wrapping row used at wider widths. A
     single row stopped working once logos grew to a legible size
     (see the 768px breakpoint above) and a third sponsor was added:
     with 3+ logos plus a label and a CTA link all competing for one
     row's width, wherever the wrap happened to fall would orphan
     whichever piece landed alone on its own line. Stacking the three
     pieces explicitly sidesteps that — and unlike the single-row
     approach, the middle "row" (.su-sponsor-logos) is itself allowed
     to wrap onto multiple lines as more sponsors are added later,
     which reads as an intentional grid rather than an accidental
     line break, however many logos end up in it. */
  .su-sponsors {
    flex-direction: column;
    align-items: flex-start;
    padding-top: 16px;
    padding-bottom: 16px;
    gap: 12px;
  }

  /* justify-content: center (rather than the row's default flex-start,
     or space-around/space-between) keeps an odd number of logos from
     reading as lopsided or oddly spaced — confirmed via screenshot
     that space-around produced uneven-looking gaps between logos of
     different widths. Centering holds up regardless of sponsor count
     or how a row happens to wrap. */
  .su-sponsor-logos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    width: 100%;
    gap: 10px 4px;
  }

  .su-sponsor-logo,
  .su-sponsor-logo.wp-block-group {
    border-left: none;
    padding: 0 8px;
  }

  .su-sponsor-cta {
    border-left: none;
    padding-left: 0;
  }

  /* Champions cards: same family of issue as .su-strip-card above
     — confirmed via screenshot, at this breakpoint .su-champ-grid
     was using the desktop max(32px, calc(...)) side padding, and
     more importantly the card itself was sized at the desktop-
     tuned 330px, which ate nearly the full phone screen width
     while still leaving visible empty space within the card's own
     content, plus no right-edge breathing room on the last card.
     330px was explicitly flagged as "not deliberately tuned for
     phone" when first built — this is that follow-up.

     padding-left is 0 here, not 20px — the actual start-edge inset
     comes from .su-champ-grid-spacer instead (see base rule comment
     for why padding-left isn't reliable on a scroll container's
     start side; confirmed via dev tools at THIS breakpoint too —
     computed padding-left showed 20px but the first card still
     rendered flush with zero visible gap). */
  .su-champ-grid {
    /* Match the 20px side padding already established for other
       sections at this breakpoint (strip, sponsors, explainer),
       instead of the desktop content-max-based padding which is
       needlessly large below the content-max breakpoint anyway. */
    padding: 4px 20px 4px 0;
    margin-right: 0;
    gap: 14px;
  }

  /* Spacer width re-specified for this breakpoint's own intended
     inset (20px) minus this breakpoint's own gap (14px, not the
     desktop rule's 20px) — these must stay in sync with the
     .su-champ-grid padding-right and gap values directly above. */
  .su-champ-grid-spacer {
    width: 6px; /* 20px intended inset − 14px gap */
  }

  .su-champ-card,
  .su-champ-card.wp-block-group {
    /* Narrower than the desktop-tuned 330px — at 330px on a 360px
       phone the card was consuming nearly the entire screen width
       (confirmed via screenshot) while its own content didn't need
       that much room, reading as mostly empty space rather than a
       deliberately-sized card. 280px leaves a clearer, more
       legible peek of the next card (confirmed via calculation:
       roughly 21-41% of the next card visible across common phone
       widths 360-414px) without being so narrow the roster text
       feels cramped. */
    width: 280px;
  }

  /* Footer grid: 3 columns -> 1 at phone width. Targets .is-layout-
     grid directly (a stable WP core class) rather than the auto-
     generated per-block-instance class WordPress also adds (e.g.
     wp-container-core-group-is-layout-xxxxxxxx) — that class is a
     content hash that changes if the block is ever rebuilt in the
     editor, so relying on it here would silently stop working after
     an unrelated edit. !important to reliably outrank WP's own
     generated grid-template-columns rule regardless of its source
     order in the page <head>. */
  .su-footer.is-layout-grid {
    grid-template-columns: 1fr !important;
    row-gap: 28px;
  }

  /* Single-column phone layout looked lopsided/empty with each
     column's 3 links still stacked in a tall, narrow vertical list
     under a centered heading — lots of unused horizontal width.
     Switching the link list to a horizontal row with dividers uses
     that width instead and reads as a deliberate compact layout
     rather than a leftover desktop pattern. flex-wrap: wrap is a
     safety net for the longer labels ("Terms and Conditions") on
     the narrowest phones — confirm this on Galaxy S8+ specifically,
     since a wrapped second line would show a stray leading divider
     on whichever item wraps first (same family of issue as the
     sponsor row's wrap handling above). */
  .su-footer .wp-block-navigation__container {
    flex-direction: row !important;
    justify-content: center;
    flex-wrap: wrap;
    gap: 10px;
  }

  .su-footer .wp-block-navigation-item:not(:first-child) {
    border-left: 1px solid var(--5u-light-border);
    padding-left: 10px;
  }

  body.dark-mode .su-footer .wp-block-navigation-item:not(:first-child) {
    border-left-color: rgba(255, 255, 255, 0.08);
  }

  /* Reserve room for the fixed dark mode toggle (44px button + 20px
     offset from the viewport edge) so it doesn't sit directly on
     top of the last bit of real footer content once the page is
     scrolled all the way down — on a narrow phone the toggle's
     footprint takes up proportionally more of the corner than on
     desktop, where there's already enough surrounding padding for
     it to read as floating rather than colliding. Only the actual
     LAST element in the footer needs this — :not(:has(+ ...))
     skips it on .su-footer specifically when a .su-footer-bottom
     bar follows, so the buffer never gets reserved twice. */
  .su-footer.is-layout-grid:not(:has(+ .su-footer-bottom)) {
    padding-bottom: 76px;
  }

  .su-footer-bottom {
    padding-bottom: calc(11px + 76px);
  }
}

