/* ==========================================================================
   Bangor RFC P7 Tour 2027
   Design tokens and shared components.

   One accent (gold) used across every page. Dark navy hero band, light
   content sections, locked (no dark mode variant). No external
   fonts, no external images, no icon libraries: the site must work offline
   from a Worker with nothing to fetch.
   ========================================================================== */

/* Palette derived from the Bangor RFC crest: blue, navy blue and yellow.
   Taken down in saturation, because those three at crest strength fight each
   other on a screen. Each colour gets ONE job, which is what stops it looking
   like a bookmakers:

     NAVY   structure. The hero band, body text and headings.
     BLUE   interaction. Buttons, links, focus rings. Nothing else.
     YELLOW accent, small doses only. The prime jersey lot, availability
            figures, the kicker lines, and one hairline rule at the top of
            the page. Never a large fill, never a background panel.

   THEME: locked to light content sections under a dark navy hero band, the
   same shape as the Tigers Challenge site this design follows. The former
   prefers-color-scheme dark variant was removed deliberately; the baseline
   git commit holds it if this experiment gets reverted. */

:root {
  color-scheme: light;
  --page:           #fbfcfe;
  --surface:        #fff;
  --surface-sunk:   #f0f4f9;
  --line:           #d9e1ec;
  --line-strong:    #b9c5d7;
  --text:           #101a35;
  --text-muted:     #4e5c78;
  --text-faint:     #5f6b85; /* 4.5:1+ on both --surface and --surface-sunk */

  /* Blue: interaction. --brand-fill always pairs with --on-brand (5.6:1). */
  --brand:          #17629b;
  --brand-fill:     #17629b;
  --brand-strong:   #0f4d7c;
  --brand-soft:     #eaf2f9;
  --on-brand:       #fff;

  /* Yellow: accent. --accent is the text-safe gold, --accent-fill the badge
     gold which always carries --on-accent on top. */
  --accent:         #8a6008;
  --accent-fill:    #e3ae2f;
  --accent-wash:    #fdf6e6;
  --on-accent:      #211802;

  --radius:         10px;
  --radius-lg:      16px;

  --shadow: 0 1px 2px rgb(16 23 34 / 0.05), 0 8px 24px -12px rgb(16 23 34 / 0.16);

  --measure: 62ch;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --shell: 1240px;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;
}

*, *::before, *::after { box-sizing: border-box; }

/* The -webkit- prefix is the one that actually works on iOS Safari. Do not let
   a linter autofix strip it: without it, iPhone inflates text in landscape. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* The page frame is navy: hero at the top, footer at the bottom, and content
   sections sit on it as white islands. --frame matches the hero gradient's
   tail so hero, body and footer read as one continuous band. */
body {
  margin: 0;
  font-family: var(--font);
  font-size: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
  line-height: 1.6;
  color: var(--text);
  background: #0a1226;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  margin: 0;
  line-height: 1.1;
  letter-spacing: -0.022em;
  font-weight: 640;
  text-wrap: balance;
}

p { margin: 0; }
a { color: inherit; }

img, svg { max-width: 100%; display: block; }

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: var(--gutter);
  top: 0.75rem;
  z-index: 100;
  padding: 0.6rem 1rem;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
}

/* --------------------------------------------------------------- layout -- */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Content sections are the white islands on the navy frame. */
.section { padding-block: clamp(2.75rem, 5.5vw, 4.5rem); background: var(--page); }

.stack { display: grid; gap: 1rem; }
.stack--lg { gap: 1.75rem; }
.stack--sm { gap: 0.5rem; }

.lede {
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.25rem);
  color: var(--text-muted);
  max-width: var(--measure);
  line-height: 1.55;
}

.prose { max-width: var(--measure); color: var(--text-muted); }
.prose > * + * { margin-top: 1rem; }
.prose strong { color: var(--text); font-weight: 620; }

/* ------------------------------------------------------------ site nav -- */

/* Part of the navy frame, like the hero and footer. */
.masthead {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, #0a1226 92%, transparent);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid rgb(255 255 255 / 0.08);
  /* The one structural nod to the crest's gold band. Kept to 3px. */
  border-top: 3px solid var(--accent-fill);
  color: #fff;
}

.masthead__inner {
  height: 68px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.wordmark {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-decoration: none;
  white-space: nowrap;
  color: #fff;
}
.wordmark b { font-weight: 700; }
.wordmark span {
  font-size: 0.8125rem;
  font-weight: 560;
  color: rgb(255 255 255 / 0.6);
  letter-spacing: 0;
}
/* The griffin crest. Centred in the bar while the text keeps its baseline. */
.wordmark__crest {
  align-self: center;
  height: 40px;
  width: auto;
}

.navlinks {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2vw, 1.75rem);
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.9375rem;
}
/* :not(.btn) matters. Without it this rule (specificity 0,1,1) outranks
   .btn--primary (0,1,0) and repaints the nav CTA's label muted blue on a blue
   fill, which fails contrast outright. */
.navlinks a:not(.btn) {
  text-decoration: none;
  color: rgb(255 255 255 / 0.75);
  white-space: nowrap;
  transition: color 0.18s var(--ease);
}
.navlinks a:not(.btn):hover { color: #fff; }
.navlinks a:not(.btn)[aria-current="page"] { color: #fff; font-weight: 580; }

/* Mobile navigation.
   Desktop keeps every link on one line. Below 800px the links move into a
   disclosure panel rather than being hidden, so nothing becomes unreachable
   on a phone. Touch targets are kept at 44px minimum. */

/* A bare kebab (three vertical dots), no pill around it. margin-left: auto is
   load-bearing: the nav element beside it is a zero-width box on mobile (its
   list is absolutely positioned), so space-between alone parks the toggle in
   the middle of the bar instead of at the right edge. */
.navtoggle {
  display: none;
  align-items: center;
  justify-content: center;
  margin-left: auto;
  min-height: 44px;
  min-width: 44px;
  padding: 0;
  color: #fff;
  background: none;
  border: 0;
  cursor: pointer;
}
.navtoggle__dots,
.navtoggle__dots::before,
.navtoggle__dots::after {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
}
.navtoggle__dots { position: relative; }
.navtoggle__dots::before,
.navtoggle__dots::after {
  content: "";
  position: absolute;
  left: 0;
}
.navtoggle__dots::before { top: -8px; }
.navtoggle__dots::after  { top: 8px; }

@media (max-width: 800px) {
  .navtoggle { display: inline-flex; }

  .navlinks {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0.5rem var(--gutter) 1rem;
    background: #0a1226;
    border-bottom: 1px solid rgb(255 255 255 / 0.08);
    box-shadow: var(--shadow);
  }
  .navlinks[hidden] { display: none; }
  .navlinks > li > a {
    display: flex;
    align-items: center;
    min-height: 48px;
    font-size: 1rem;
  }
  .navlinks > li + li > a:not(.btn) {
    border-top: 1px solid rgb(255 255 255 / 0.08);
  }
  .masthead__inner { position: relative; }
}

@media (min-width: 801px) {
  /* Never leave the panel hidden on desktop, whatever state the toggle left. */
  .navlinks[hidden] { display: flex; }
}

/* ------------------------------------------------------------- buttons -- */

/* Pill buttons, cards at 16px. Two radii with a documented rule, per the
   Tigers Challenge design language this site follows. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.72rem 1.4rem;
  min-height: 44px; /* touch target floor */
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border: 1px solid transparent;
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.14s var(--ease), background-color 0.18s var(--ease),
              border-color 0.18s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: 0.55; cursor: not-allowed; }

/* Blue carries every primary action: white on #17629b (5.6:1). */
.btn--primary { background: var(--brand-fill); color: var(--on-brand); }
.btn--primary:hover { background: var(--brand-strong); }

/* Gold is reserved for the one premium thing: the sealed jersey bid. */
.btn--accent { background: var(--accent-fill); color: var(--on-accent); }
.btn--accent:hover { background: color-mix(in srgb, var(--accent-fill) 88%, #000); }

.btn--ghost {
  background: var(--surface);
  color: var(--text);
  border-color: var(--line-strong);
}
.btn--ghost:hover { border-color: var(--text-faint); }

.btn--block { width: 100%; }

/* Hero-scale button. The primary action on the site, so it gets the size. */
.btn--lg {
  padding: 1rem 2rem;
  font-size: clamp(0.875rem, 0.85rem + 0.2vw, 1rem);
  font-weight: 700;
}

/* Outline pill on the hero geometry, where a solid fill would fight the
   background shapes. */
.btn--outline {
  background: transparent;
  color: #fff;
  border: 2px solid rgb(255 255 255 / 0.85);
}
.btn--outline:hover { background: rgb(255 255 255 / 0.12); border-color: #fff; }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; }

/* ============================================================== hero ======
   Design language borrowed from the Tigers Challenge site: the brand colour
   owns the whole canvas, big angular chevrons in lighter tints of it carry the
   movement, a diagonal hatch adds texture, and the type is centred, all-caps
   and stacked in three tiers. Gold stays a small accent on top of it. */

.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(3rem, 8vw, 6rem) 0;
  background: linear-gradient(180deg, #0b1730 0%, #0a1226 55%, #08101f 100%);
}

/* The chevron geometry. Decorative, so it is aria-hidden and never clickable. */
.hero__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  color: #2f7fc0;
  pointer-events: none;
}
.hero__chevron-a { fill: #17629b; opacity: 0.22; }
.hero__chevron-b { fill: #2f7fc0; opacity: 0.16; }
.hero__hatch { fill: url("#heroHatch"); opacity: 0.5; }

.hero__content {
  position: relative;
  display: grid;
  gap: 1.1rem;
  justify-items: center;
  text-align: center;
}

.hero__club {
  font-size: clamp(0.75rem, 0.72rem + 0.15vw, 0.875rem);
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--accent-fill);
}

.hero__title { display: grid; gap: 0.1rem; justify-items: center; }

.hero__title-main {
  font-size: clamp(2.9rem, 1.6rem + 8vw, 6.5rem);
  font-weight: 800;
  line-height: 0.92;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: #fff;
}

.hero__title-sub {
  font-size: clamp(1rem, 0.85rem + 1.2vw, 1.75rem);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgb(255 255 255 / 0.9);
}

.hero__meta {
  display: grid;
  gap: 0.15rem;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgb(255 255 255 / 0.72);
}
.hero__meta strong { font-weight: 700; color: #fff; letter-spacing: 0.1em; }

.hero__count {
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent-fill);
  min-height: 1.4em;
}

/* The players stand on the bottom edge of the hero. */
.hero__players { margin-top: clamp(1.5rem, 4vw, 3rem); }
.hero__players img {
  display: block;
  width: 100%;
  max-width: 1000px;
  height: auto;
  margin-inline: auto;
}

/* ------------------------------------------------- landing entrance ------
   The "thump" sequence, landing hero only. Each line stamps down: starts
   oversized and transparent, accelerates into impact slightly below final
   size, then rebounds to rest. Staggered so P7 FINALE lands first, the tour
   name second, the button pops third and the details fade in around them.

   Pure CSS, transform and opacity only, so it costs nothing and cannot cause
   layout shift. Wrapped in no-preference so reduced-motion users get the
   settled page instantly: the base styles carry no initial state, which means
   the page is complete even if this whole block never runs. */

@media (prefers-reduced-motion: no-preference) {
  @keyframes hero-thump {
    0% {
      opacity: 0;
      transform: scale(2.3);
      animation-timing-function: cubic-bezier(0.5, 0, 0.85, 0.3); /* accelerate into impact */
    }
    55% {
      opacity: 1;
      transform: scale(0.94); /* the thump: squashed past final size */
      animation-timing-function: cubic-bezier(0.2, 0.8, 0.4, 1);
    }
    78% { transform: scale(1.04); } /* rebound */
    100% { opacity: 1; transform: scale(1); }
  }

  @keyframes hero-pop {
    0% { opacity: 0; transform: scale(0.5); }
    70% { opacity: 1; transform: scale(1.08); }
    100% { opacity: 1; transform: scale(1); }
  }

  @keyframes hero-fade {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: none; }
  }

  /* :not(.hero--compact) scopes all of this to the landing page. */
  /* Durations and delays are deliberately unhurried: half speed reads as a
     stamp landing, full speed read as a twitch. */
  .hero:not(.hero--compact) .hero__title-main {
    animation: hero-thump 1.1s 0.3s both;
  }
  .hero:not(.hero--compact) .hero__title-sub {
    animation: hero-thump 1s 1.2s both;
  }
  .hero:not(.hero--compact) .hero__club,
  .hero:not(.hero--compact) .hero__meta {
    animation: hero-fade 0.9s 2.1s var(--ease) both;
  }
  .hero:not(.hero--compact) .btn--outline {
    animation: hero-pop 0.9s 2.5s both;
  }
  .hero:not(.hero--compact) .hero__count {
    animation: hero-fade 0.9s 3.1s var(--ease) both;
  }
}

/* Compact hero band for inner pages. Same geometry (injected by app.js), same
   centred all-caps stack, smaller scale, no players. Every page opens with the
   same brand band; only the landing page gets the full-height version. */
.hero--compact { padding-block: clamp(2.25rem, 5vw, 3.5rem); }
.hero--compact .hero__content { gap: 0.7rem; }
.hero--compact .hero__title-main {
  font-size: clamp(1.9rem, 1.2rem + 3.6vw, 3.4rem);
}
.hero--compact .hero__title-sub {
  font-size: clamp(0.9375rem, 0.85rem + 0.6vw, 1.25rem);
}

.hero__lede {
  max-width: 56ch;
  font-size: clamp(0.9375rem, 0.9rem + 0.3vw, 1.0625rem);
  line-height: 1.55;
  color: rgb(255 255 255 / 0.82);
}

/* Full bleed on a phone, where the players carry the hero. A negative gutter
   margin plus width:100% does NOT work: the width resolves against the padded
   container, so the image sits off-centre and clips on the right. */
@media (max-width: 620px) {
  .hero__players {
    width: 100vw;
    margin-inline: calc(50% - 50vw);
  }
}

.hero h1 {
  font-size: clamp(2.1rem, 1.4rem + 3.2vw, 3.5rem);
  letter-spacing: -0.03em;
}

/* ------------------------------------------------------------ disclose --
   Progressive disclosure. Detail that would clutter the first look lives
   behind a summary the visitor opens if they want it. Used on the
   sponsorship page and for each child's forms in the parent area. */

.disclose {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
}
.disclose > summary {
  cursor: pointer;
  padding: 1rem clamp(1rem, 2.5vw, 1.5rem);
  min-height: 52px;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 600;
  list-style: none;
}
.disclose > summary::-webkit-details-marker { display: none; }
.disclose > summary::after {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  margin-left: auto;
  flex-shrink: 0;
  border-right: 2px solid var(--text-faint);
  border-bottom: 2px solid var(--text-faint);
  transform: rotate(45deg);
  transition: transform 0.18s var(--ease);
}
.disclose[open] > summary::after { transform: rotate(-135deg); }
.disclose > summary:hover { color: var(--brand); }
.disclose__body { padding: 0 clamp(1rem, 2.5vw, 1.5rem) clamp(1rem, 2.5vw, 1.5rem); }

.picked {
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius);
  background: var(--brand-soft);
  border: 1px solid color-mix(in srgb, var(--brand) 35%, transparent);
  font-size: 0.9375rem;
  font-weight: 560;
}
.picked[hidden] { display: none; }

/* --------------------------------------------------------------- offer --
   The only content block below the hero. Four lines on what a sponsor gets. */

/* Wide enough that the longest line fits on one row at desktop. The items
   carry no max-width of their own, so they wrap only when the viewport is
   genuinely too narrow, which is what should happen on a handset. */
.offer { display: grid; gap: 1.1rem; max-width: 48rem; }

/* No bullets and no dividers. Four short sentences do not need either, and the
   emphasis below is what makes them scannable. */
.offer__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.7rem;
}

/* Most of the text is muted with a bright lead phrase carrying the point.
   Four lines of full-brightness white read as a wall. */
.offer__list li {
  font-size: clamp(1rem, 0.97rem + 0.2vw, 1.0625rem);
  line-height: 1.5;
  color: var(--text-muted);
}
.offer__list strong { color: var(--text); font-weight: 620; }

/* --------------------------------------------------------------- stats -- */

.stats {
  display: grid;
  gap: 1px;
  background: var(--line);
  border-block: 1px solid var(--line);
}
@media (min-width: 560px) { .stats { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px) { .stats { grid-template-columns: repeat(4, 1fr); } }

.stat {
  background: var(--page);
  padding: 1.5rem clamp(1rem, 2vw, 1.75rem);
  display: grid;
  gap: 0.3rem;
  align-content: start;
}
.stat__value {
  font-family: var(--font-mono);
  font-size: clamp(1.5rem, 1.2rem + 1.1vw, 2.1rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.stat__label { font-size: 0.875rem; color: var(--text-muted); }

/* --------------------------------------------------------------- tiers -- */

.tier {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  padding: clamp(1.25rem, 2.4vw, 1.85rem);
  display: grid;
  gap: 0.85rem;
  align-content: start;
}

.tier__note { font-size: 0.9375rem; color: var(--text-muted); }

/* ------------------------------------------------------------ kit map --
   Schematic garment diagrams with a clickable hotspot per logo position.
   Hotspots are real buttons layered over the SVG in percentage coordinates,
   so they are focusable and labelled. The position list further down the page
   is the equivalent non-visual route. */

.kitmap {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  padding: clamp(1rem, 2.5vw, 1.5rem);
  display: grid;
  gap: 1rem;
}

.kitmap__garments {
  display: flex;
  gap: 0.35rem;
  overflow-x: auto;
  padding-bottom: 0.25rem;
  scrollbar-width: thin;
}

.kitmap__garment {
  position: relative;
  font: inherit;
  font-size: 0.875rem;
  font-weight: 560;
  white-space: nowrap;
  min-height: 40px;
  padding: 0.45rem 0.8rem;
  color: var(--text-muted);
  background: var(--surface-sunk);
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
}
.kitmap__garment:hover { color: var(--text); }
.kitmap__garment[aria-pressed="true"] {
  color: var(--text);
  background: var(--brand-soft);
  border-color: color-mix(in srgb, var(--brand) 40%, transparent);
}

.kitmap__views { display: flex; gap: 0.35rem; }
.kitmap__view {
  position: relative;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 560;
  min-height: 36px;
  padding: 0.3rem 0.75rem;
  color: var(--text-muted);
  background: none;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  cursor: pointer;
}
.kitmap__view[aria-pressed="true"] {
  color: var(--text);
  border-color: var(--text-faint);
  background: var(--surface-sunk);
}

/* Invisible overlays lift the compact controls to a 44px touch target
   without changing how they draw. Vertical only, so neighbours never overlap. */
.kitmap__garment::after,
.kitmap__view::after,
.kitmap__spot::after {
  content: "";
  position: absolute;
  inset: -4px 0;
}
.kitmap__spot::after { inset: -5px; }

.kitmap__stage { display: grid; place-items: center; }

.kitmap__figure {
  position: relative;
  width: 100%;
  max-width: 400px;
  color: var(--line-strong);
}

.kitmap__svg { width: 100%; height: auto; display: block; }
.kitmap__outline { fill: var(--surface-sunk); stroke: currentColor; stroke-width: 3; }

/* Photograph views (the real jersey) share the schematic's frame, so hotspot
   percentages mean the same thing on both. */
.kitmap__photo { width: 100%; height: auto; display: block; }

.kitmap__spot {
  position: absolute;
  transform: translate(-50%, -50%);
  display: grid;
  gap: 0.1rem;
  justify-items: center;
  min-height: 34px;
  padding: 0.28rem 0.6rem;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 640;
  font-variant-numeric: tabular-nums;
  border-radius: var(--radius);
  cursor: pointer;
  transition: transform 0.14s var(--ease), background-color 0.16s var(--ease);
}
.kitmap__spot:hover:not(:disabled) { transform: translate(-50%, -50%) scale(1.06); }
.kitmap__spot:active:not(:disabled) { transform: translate(-50%, -48%) scale(1.02); }

.kitmap__spot[data-state="open"] {
  color: var(--on-accent);
  background: var(--accent-fill);
  border: 1px solid color-mix(in srgb, var(--accent-fill) 70%, #000);
}
.kitmap__spot[data-state="taken"] {
  color: var(--text-faint);
  background: var(--surface);
  border: 1px dashed var(--line-strong);
  cursor: not-allowed;
}
.kitmap__spot.is-picked {
  color: var(--on-brand);
  background: var(--brand-fill);
  border-color: var(--brand-fill);
}

/* The sealed-bid lot. Bigger and darker so it reads as a different kind of
   thing from the fixed-price positions around it. */
.kitmap__spot[data-tier="prime"][data-state="open"] {
  text-decoration: none;
  padding: 0.4rem 0.9rem;
  font-size: 0.9375rem;
  letter-spacing: 0.06em;
  color: var(--accent-fill);
  background: #16233a;
  border: 2px solid var(--accent-fill);
}
.kitmap__spot[data-tier="prime"][data-state="open"] .kitmap__spotname {
  display: block;
  color: var(--text-muted);
  letter-spacing: 0;
  font-weight: 500;
}

/* Position name appears on hover and on keyboard focus. The button's
   aria-label always carries the full description regardless. */
.kitmap__spotname {
  display: none;
  font-size: 0.6875rem;
  font-weight: 560;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.kitmap__spot:hover .kitmap__spotname,
.kitmap__spot:focus-visible .kitmap__spotname { display: block; }

.kitmap__caption {
  font-size: 0.875rem;
  color: var(--text-muted);
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  .kitmap__spot, .kitmap__spot:hover:not(:disabled) { transition: none; transform: translate(-50%, -50%); }
  .btn, .disclose > summary::after { transition: none; }
  .btn:active { transform: none; }
}

/* ------------------------------------------------------------- bid box -- */

.bidbox {
  border: 1px solid color-mix(in srgb, var(--accent-fill) 40%, var(--line));
  border-radius: var(--radius-lg);
  background: var(--accent-wash);
  padding: clamp(1.25rem, 3vw, 2rem);
  display: grid;
  gap: 0.75rem;
}
.bidbox__count {
  font-family: var(--font-mono);
  font-size: clamp(2rem, 1.5rem + 2.4vw, 3.25rem);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.bidbox__caption { font-size: 0.9375rem; color: var(--text-muted); }

/* ------------------------------------------------------- waterfall list -- */

.waterfall { display: grid; gap: 0; counter-reset: step; }
.waterfall__row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 1rem;
  align-items: baseline;
  padding-block: 1.1rem;
  border-top: 1px solid var(--line);
}
.waterfall__row:last-child { border-bottom: 1px solid var(--line); }
.waterfall__marker {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.waterfall__what { font-weight: 580; }
.waterfall__what small {
  display: block;
  font-weight: 400;
  font-size: 0.9375rem;
  color: var(--text-muted);
  margin-top: 0.2rem;
  max-width: 52ch;
}
.waterfall__amount {
  font-family: var(--font-mono);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --------------------------------------------------------------- forms -- */

.form { display: grid; gap: 1.1rem; }
.field { display: grid; gap: 0.4rem; }
.field > label { font-size: 0.9375rem; font-weight: 580; }
/* Scoped to the form, not the field: intro and footnote help lines sit as
   direct children of .form on the sponsorship and parent pages. */
.form .help, .field .help { font-size: 0.8125rem; color: var(--text-muted); }
.form .err, .field .err { font-size: 0.8125rem; color: #c02626; font-weight: 550; }

input[type="text"], input[type="email"], input[type="tel"],
input[type="number"], select, textarea {
  font: inherit;
  font-size: 1rem;
  width: 100%;
  padding: 0.65rem 0.8rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  transition: border-color 0.16s var(--ease);
}
input::placeholder, textarea::placeholder { color: var(--text-faint); }
input:hover, select:hover, textarea:hover { border-color: var(--text-faint); }
textarea { min-height: 7rem; resize: vertical; }

.check {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.7rem;
  align-items: start;
  font-size: 0.9375rem;
  color: var(--text-muted);
}
.check input { margin-top: 0.25rem; width: 1.05rem; height: 1.05rem; accent-color: var(--accent); }

.form-grid { display: grid; gap: 1.1rem; }
@media (min-width: 620px) { .form-grid--2 { grid-template-columns: 1fr 1fr; } }

/* ------------------------------------------------------------- notices -- */

.notice {
  padding: 0.9rem 1.1rem;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--surface-sunk);
  font-size: 0.9375rem;
}
.notice--ok {
  border-color: color-mix(in srgb, #1f8a4c 40%, var(--line));
  background: color-mix(in srgb, #1f8a4c 9%, var(--surface));
}
.notice--bad {
  border-color: color-mix(in srgb, #c02626 40%, var(--line));
  background: color-mix(in srgb, #c02626 8%, var(--surface));
}
.notice[hidden] { display: none; }

/* ------------------------------------------------------------ skeleton -- */

/* Static placeholder tint; the pulse (opacity only, so it never repaints
   layout) runs solely when the visitor has not asked for reduced motion. */
.skeleton {
  border-radius: var(--radius);
  background: var(--surface-sunk);
  min-height: 1rem;
}
@media (prefers-reduced-motion: no-preference) {
  .skeleton { animation: skeleton-pulse 1.4s ease-in-out infinite; }
  @keyframes skeleton-pulse {
    50% { opacity: 0.45; }
  }
}

.empty {
  padding: 2.5rem 1.5rem;
  text-align: center;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-lg);
  color: var(--text-muted);
  display: grid;
  gap: 0.5rem;
  justify-items: center;
}

/* -------------------------------------------------------------- footer -- */

/* The footer is part of the navy frame, closing the page the way the hero
   opened it. Links stay underlined: colour alone is not enough on navy. */
.footer {
  background: transparent;
  padding-block: 2.25rem 2.75rem;
  font-size: 0.9375rem;
  color: rgb(255 255 255 / 0.72);
}
.footer strong { color: #fff; font-weight: 620; }
.footer__row { display: grid; gap: 1.25rem; }
.footer a { color: rgb(255 255 255 / 0.92); text-decoration: underline; text-underline-offset: 2px; }
.footer a:hover { color: #fff; }

.footer__links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
}
.footer__links a { text-decoration: none; }
.footer__links a:hover { text-decoration: underline; }

.footer__fine { font-size: 0.8125rem; color: rgb(255 255 255 / 0.62); max-width: 78ch; }

/* -------------------------------------------------------------- reveal --
   Entry animation, driven by IntersectionObserver in app.js. Collapses to
   fully visible when reduced motion is requested, and when JS is absent. */

@media (prefers-reduced-motion: no-preference) {
  .js .reveal {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
  }
  .js .reveal.in { opacity: 1; transform: none; }
}

/* ---------------------------------------------------- mobile collapse -- */

/* Every multi-column row declares its own narrow-screen fallback here, so no
   layout relies on "it will probably be fine". */

@media (max-width: 620px) {
  /* Waterfall rows go from three columns to a stacked block with the amount
     sitting under the label, still right-aligned to read as a figure. */
  .waterfall__row {
    grid-template-columns: auto 1fr;
    row-gap: 0.5rem;
  }
  .waterfall__amount {
    grid-column: 2;
    justify-self: start;
    font-size: 0.9375rem;
    color: var(--text-muted);
  }

  .hero h1 { text-wrap: pretty; }

  .btn-row .btn { flex: 1 1 auto; }
}

@media (max-width: 420px) {
  /* Stop long business names and garment labels forcing a sideways scroll. */
  body { overflow-x: hidden; }
  .stat { padding-inline: 1rem; }
}

/* Anything that could contain an unbroken long string. */
.lot__name, .waterfall__what { overflow-wrap: anywhere; }

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.muted { color: var(--text-muted); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
