/* ============================================================
   THE JERSEY HUB — core stylesheet
   Brand: navy ground, cream type, one lime accent
   ============================================================ */

/* ============================================================
   HIDDEN MEANS HIDDEN

   `display` from a class beats the browser's own rule for [hidden], so
   `el.hidden = true` on anything carrying a class that sets display does
   nothing at all — silently. It is only ever found by pressing a button and
   watching nothing happen, which has now happened three times:

     the chat pane sat underneath every other tab on the admin page
     "when i click show the list or hide the list nothing changes"
     and every .btn in the shop, which sets display: inline-flex — so a
     button hidden from script has never once been hidden, anywhere

   Naming the offending classes one at a time was the old fix and it failed
   every time a new one was written. This says it once, for everything.
   ============================================================ */
[hidden] { display: none !important; }

:root {
  /* Grounds. Navy rather than near-black, taken off the logo's own outline,
     so the crest sits on the page as if it were printed there rather than
     pasted onto it. Each step up is the same navy lightened, which keeps the
     whole surface one colour instead of drifting towards grey. */
  --bg-deep: #010c1f;   /* topbar, hero-adjacent bands, footer */
  --bg:      #011532;   /* page — the logo's own navy */
  --surface:   #04203f; /* cards, product tiles, drawer, filter rail */
  --surface-2: #0a2c4f; /* raised: inputs, chips, hover */
  --surface-3: #113a61; /* highest: toast, flags, progress track */
  --line:      #163f66;

  /* The studio sweep the supplier photographs were shot on. Frames holding a
     photograph take this instead of --surface so the shot does not read as a
     grey rectangle pasted onto a navy tile. */
  --photo-bg: #e3e1e2;

  /* Text — the logo's cream, not white. White on this navy is colder than the
     mark it sits under. */
  --text:   #faf6e9;
  --text-2: #c3c9d4;
  --muted:  #8fa0b5;
  --steel:  #93a4b8;   /* the working grey — labels, captions, footer */

  /* Lime — the one accent, sampled off the logo. Loud on navy, which is the
     point: it is spent on CTAs, active state and sale only. The ramp runs
     from a pale tint for text on dark, down to a shade dark enough to carry
     cream type on top of it. */
  --accent-300: #d4fb7d;
  --accent-400: #c6fa4a;
  --accent-500: #b6f823;   /* the logo's lime */
  --accent-600: #8fc80c;
  --accent-700: #6b9707;

  /* Cream type on lime is unreadable; navy on lime is the pairing the logo
     itself uses, so anything filled with the accent takes this on top. */
  --on-accent: #011532;

  --sans: "Helvetica Neue", Helvetica, "Segoe UI", Arial, system-ui, sans-serif;

  --shadow-sm: 0 1px 2px rgba(8, 11, 15, .06), 0 2px 8px rgba(8, 11, 15, .05);
  --shadow-md: 0 8px 30px rgba(8, 11, 15, .10);
  --shadow-lg: 0 24px 60px rgba(8, 11, 15, .16);

  /* Uses a big monitor without running the content into the bezels. Halfway
     between the original 1240 and the full-width 1660 that read as too spread.
     Text blocks set their own narrower max-widths, so this only governs how
     far the product grids and the header reach. */
  --wrap: 1450px;
  --nav-h: 88px;
}

/* ---------- reset ---------- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--sans);
  color: var(--text);
  background: var(--bg);
  line-height: 1.55;
  overflow-x: hidden;
}
img, svg { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }
input, select { font: inherit; }
h1, h2, h3, h4 { margin: 0; line-height: 1.02; letter-spacing: -.02em; }
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }

/* ---------- brand type ---------- */
.tect {
  font-weight: 800;
  font-style: italic;
  letter-spacing: -.03em;
  text-transform: uppercase;
}
.eyebrow {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--accent-500);
}
.eyebrow.on-dark { color: var(--accent-300); }

/* ============================================================
   LOGO
   ============================================================ */
/* The supplied lockup is a single piece of artwork — mark and wordmark
   together — so it is placed as one image rather than rebuilt from parts. */
/* The mark is the wordmark alone, so it is wide and short — roughly 3.4:1
   where the old lockup was 1.2:1. Sizing it by height the way a square-ish
   badge is sized would run it most of the way across the header, so these are
   set to give the same optical weight at the new proportions. */
.logo { display: inline-flex; align-items: center; flex: none; }
/* The lockup is a crest beside a wordmark, roughly two and a half times wider
   than it is tall. Sized by height like the old wordmark it came out barely
   legible, so these are set to give the wordmark the same cap height it had
   before — which means a taller box, and a header tall enough to hold it. */
.logo__img { height: 42px; width: auto; }
.logo:focus-visible { outline: 2px solid var(--accent-400); outline-offset: 4px; border-radius: 2px; }
.foot .logo__img { height: 52px; }
.mmenu .logo__img { height: 34px; }
@media (max-width: 620px) { .logo__img { height: 34px; } }

/* ============================================================
   NAV
   ============================================================ */
.topbar {
  background: var(--bg-deep);
  color: #a8a9b0;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  font-weight: 700;
}
.topbar .wrap {
  min-height: 34px;
  padding-block: 9px;
  /* Deliberately not flex: the accented label is an element, and flex would
     make it its own item, so the line would wrap in three columns instead of
     as one run of text. */
  display: block;
  text-align: center;
  line-height: 1.45;
}
.topbar b { color: var(--accent-300); }
.topbar__p { white-space: nowrap; }
.topbar__dot { font-style: normal; margin: 0 .55em; opacity: .55; }
/* ONE LINE ON A PHONE. Four promises at .16em tracking ran to two lines at
   375px, with "PAYPAL" alone on the second — the first thing on every page,
   and it looked like a mistake. The tracking closes up and the fourth item
   goes: PayPal is on the checkout button, where it matters. */
@media (max-width: 560px) {
  .topbar { font-size: 10.5px; letter-spacing: .06em; }
  .topbar__p[data-n="3"], .topbar__p[data-n="3"] + .topbar__dot,
  .topbar__dot:nth-of-type(3) { display: none; }
}

.nav {
  position: sticky; top: 0; z-index: 60;
  background: rgba(14,14,16,.82);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--line);
}
.nav__in {
  height: var(--nav-h);
  display: flex; align-items: center; gap: 28px;
}
.nav__links { display: flex; align-items: stretch; align-self: stretch; gap: 26px; margin-left: 14px; }
/* Scoped to top-level links so the dropdown's own items don't inherit the
   underline sweep. */
.nav__toplink {
  font-size: 12px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  position: relative; padding: 6px 0; color: var(--text-2);
  display: inline-flex; align-items: center; gap: 6px; align-self: center;
  /* NEVER TWO LINES. On a laptop the row had "26/27 / JERSEYS" and "£10 /
     SATURDAYS" stacked beside "TEAMS" and "REVIEWS" on one line — half the
     tabs a different height from the other half, with no shared baseline.
     A tab is one line; if the row is too full for that, the query below
     tightens it, and below 1160px the burger takes over. */
  white-space: nowrap;
}
/* Seven single-line tabs at 12px with .14em tracking need about 1500px.
   Between the burger breakpoint and that, the letters close up a little and
   the gaps come in, and the row fits without wrapping anything. */
@media (max-width: 1500px) {
  .nav__in { gap: 20px; }
  .nav__links { gap: 18px; margin-left: 8px; }
  .nav__toplink { font-size: 11.5px; letter-spacing: .1em; }
}
/* EIGHT TABS since Flash Sale went in for good. Below 1300px they close up
   further, and hold on one row down to 1160px — below that the burger. */
@media (max-width: 1300px) {
  .nav__in { gap: 14px; }
  .nav__links { gap: 11px; margin-left: 4px; }
  .nav__toplink { font-size: 11px; letter-spacing: .05em; }
}
.nav__toplink::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: 0; height: 2px;
  background: var(--accent-500); transition: right .28s cubic-bezier(.2,.8,.2,1);
}
.nav__toplink:hover::after, .nav__toplink[aria-current="page"]::after { right: 0; }
.nav__toplink[aria-current="page"] { color: var(--text); }
.nav__toplink svg { width: 9px; height: 9px; transition: transform .2s; }

/* The item stretches the full nav height so there is no dead gap between the
   link and the panel for the pointer to fall through. */
.nav__item { position: relative; display: flex; align-items: center; align-self: stretch; }
.nav__panel {
  position: absolute; top: 100%; left: -14px; z-index: 70; min-width: 200px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 4px;
  padding: 6px; box-shadow: 0 20px 44px rgba(0,0,0,.55);
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity .18s, transform .18s, visibility .18s;
}
.nav__item:hover .nav__panel,
.nav__item:focus-within .nav__panel { opacity: 1; visibility: visible; transform: none; }
.nav__item:hover .nav__toplink svg,
.nav__item:focus-within .nav__toplink svg { transform: rotate(180deg); }
.nav__panel a {
  display: block; padding: 10px 12px; border-radius: 3px; color: var(--text-2);
  font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  transition: background .16s, color .16s;
}
.nav__panel a:hover { background: var(--surface-2); color: var(--text); }
.nav__panel a:focus-visible { outline: 2px solid var(--accent-400); outline-offset: -2px; }

.nav__spacer { flex: 1; }
.nav__actions { display: flex; align-items: center; gap: 6px; }
.iconbtn {
  width: 40px; height: 40px; border-radius: 10px;
  display: grid; place-items: center;
  transition: background .18s;
  position: relative;
}
.iconbtn:hover { background: var(--surface-2); }
.iconbtn svg { width: 19px; height: 19px; stroke: var(--text); fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.cart-count {
  position: absolute; top: 3px; right: 2px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 9px; background: var(--accent-500); color: var(--on-accent);
  font-size: 10px; font-weight: 800; line-height: 17px; text-align: center;
  transform: scale(0); transition: transform .22s cubic-bezier(.2,1.5,.4,1);
}
.cart-count.on { transform: scale(1); }

.burger { display: none; }

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  height: 50px; padding: 0 30px;
  font-size: 12px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
  border-radius: 4px;
  transition: transform .16s cubic-bezier(.2,.8,.2,1), box-shadow .2s, background .2s, color .2s;
  clip-path: polygon(11px 0, 100% 0, 100% calc(100% - 11px), calc(100% - 11px) 100%, 0 100%, 0 11px);
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn--primary { background: var(--accent-500); color: var(--on-accent); }
.btn--primary:hover { background: var(--accent-400); box-shadow: 0 10px 26px rgba(182,248,35,.38); }
.btn--drip { background: linear-gradient(135deg, var(--accent-400), var(--accent-600)); color: var(--on-accent); }
.btn--drip:hover { box-shadow: 0 12px 30px rgba(182,248,35,.45); transform: translateY(-2px); }
.btn--ghost { background: transparent; color: #fff; box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.32); }
.btn--ghost:hover { background: var(--text); color: var(--bg); box-shadow: none; }
.btn--outline { background: transparent; color: var(--text); box-shadow: inset 0 0 0 1.5px rgba(242,242,244,.34); }
.btn--outline:hover { background: var(--text); color: var(--bg); box-shadow: none; }
.btn--sm { height: 42px; padding: 0 20px; font-size: 11px; }
.btn--block { width: 100%; }
.btn[disabled] { opacity: .45; pointer-events: none; }

/* ============================================================
   HERO
   ============================================================ */
.hero {
  position: relative;
  background: var(--bg-deep);
  color: #fff;
  overflow: hidden;
  isolation: isolate;
}
.hero__video {
  position: absolute; inset: 0; z-index: -3;
  width: 100%; height: 100%; object-fit: cover;
  /* The clip carries a generator watermark in its bottom-right corner. Scaling
     from the top-left pushes that corner outside the hero, which clips it off
     rather than painting over it. */
  transform: scale(1.16); transform-origin: 0 0;
}

/* Where the phone refused to autoplay. Same frame, same crop, same watermark
   trimmed off — the hero simply stops moving instead of showing a play button
   over itself. */
/* THE STILL, FRAMED EXACTLY AS THE VIDEO IS.

   It was a background sized to 116% of the hero's WIDTH, which is right for
   a wide laptop hero and wrong for a tall phone one: the smoke stopped a
   third of the way down and the rest of the hero was flat navy. Phones now
   always get the still, so it has to fill the box the way the video does —
   cover, then the same 1.16 scale from the top-left that crops the
   watermark off the clip. A layer of its own rather than a background,
   because a background cannot be scaled after it is sized. */
.hero--still::before {
  content: ""; position: absolute; inset: 0; z-index: -3;
  background: url('../img/hero-poster.jpg') 0 0 / cover no-repeat;
  transform: scale(1.16); transform-origin: 0 0;
}
/* Darkest on the left, where the headline sits, easing off towards the panel
   so the footage still reads on the right. */
.hero__scrim {
  position: absolute; inset: 0; z-index: -2;
  background:
    linear-gradient(90deg, rgba(14,14,16,.80) 0%, rgba(14,14,16,.55) 40%,
                           rgba(14,14,16,.22) 72%, rgba(14,14,16,.15) 100%),
    linear-gradient(180deg, rgba(14,14,16,.45) 0%, rgba(14,14,16,0) 30%,
                            rgba(14,14,16,0) 70%, rgba(14,14,16,.60) 100%);
}
.hero__glow {
  position: absolute; inset: -30% -10% auto auto;
  width: 780px; height: 780px;
  background: radial-gradient(circle at 50% 50%, rgba(182,248,35,.42), rgba(182,248,35,0) 62%);
  filter: blur(30px); z-index: -1;
  animation: float 14s ease-in-out infinite;
}
@keyframes float { 0%,100% { transform: translate3d(0,0,0) } 50% { transform: translate3d(-40px,34px,0) } }

.hero__streaks { position: absolute; inset: 0; z-index: -1; opacity: .5; }

.hero__in {
  display: grid; align-items: center;
  min-height: 470px; padding-block: 64px;
}
.hero h1 {
  font-size: clamp(42px, 10.6vw, 104px);
  font-weight: 800; font-style: italic; text-transform: uppercase;
  letter-spacing: -.045em; line-height: .88;
}
.hero h1 em { font-style: italic; color: var(--accent-400); }
.hero__sub {
  margin-top: 22px; max-width: 460px;
  color: #a7b4c1; font-size: 16.5px; line-height: 1.6;
}
.hero__cta { display: flex; gap: 12px; margin-top: 34px; flex-wrap: wrap; }
.hero__stats {
  display: flex; gap: 38px; margin-top: 52px; padding-top: 26px;
  border-top: 1px solid rgba(255,255,255,.1); max-width: 520px;
}
.hero__stats div b {
  display: block; font-size: 26px; font-weight: 800; font-style: italic; letter-spacing: -.03em;
}
.hero__stats div span {
  font-size: 10px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--muted);
}
.hero__art { position: relative; display: grid; place-items: center; min-width: 0; }
/* The hero gives this column around 640px at desktop widths; capping the panel
   at 530 left it floating in its own space with the product small inside it. */
.hero__art > .hot { width: 100%; max-width: min(660px, 100%); min-width: 0; }

/* marquee */
.marquee {
  background: linear-gradient(90deg, var(--accent-600), var(--accent-400), var(--accent-600));
  color: #fff; overflow: hidden; padding: 13px 0;
}
.marquee__track {
  display: flex; gap: 46px; width: max-content;
  animation: slide 34s linear infinite;
  font-size: 12px; font-weight: 800; letter-spacing: .26em; text-transform: uppercase;
}
.marquee__track span { display: flex; align-items: center; gap: 46px; }
@keyframes slide { to { transform: translateX(-50%) } }

/* ============================================================
   SECTIONS
   ============================================================ */
.sec { padding: 86px 0; }
.sec--tight { padding: 60px 0; }
.sec--dark { background: var(--bg-deep); color: var(--text); }
.sec--paper { background: var(--surface); }

.sec__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 34px; }
.sec__head h2 {
  font-size: clamp(28px, 4vw, 46px);
  font-weight: 800; font-style: italic; text-transform: uppercase; letter-spacing: -.04em;
}
.sec__head p { color: var(--muted); margin-top: 10px; max-width: 480px; font-size: 15px; }
.sec--dark .sec__head p { color: var(--text-2); }
.link-arrow {
  font-size: 12px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
  display: inline-flex; align-items: center; gap: 8px; color: var(--accent-500); flex: none;
}
.link-arrow svg { width: 15px; height: 15px; transition: transform .22s; }
.link-arrow:hover svg { transform: translateX(5px); }

/* ============================================================
   CATEGORY TILES
   ============================================================ */
.cats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.cat {
  position: relative; overflow: hidden; border-radius: 6px;
  min-height: 320px; display: flex; align-items: flex-end;
  padding: 26px; color: #fff; isolation: isolate;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 26px), calc(100% - 26px) 100%, 0 100%);
  transition: transform .3s cubic-bezier(.2,.8,.2,1);
}
.cat:hover { transform: translateY(-6px); }
.cat__bg { position: absolute; inset: 0; z-index: -2; }
.cat::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(8,11,15,0) 34%, rgba(8,11,15,.86) 100%);
}
.cat__art { position: absolute; inset: 0; z-index: -1; display: grid; place-items: center; transition: transform .5s cubic-bezier(.2,.8,.2,1); }
.cat:hover .cat__art { transform: scale(1.07) rotate(-2deg); }
.cat__art svg { width: 62%; opacity: .95; }
/* A photograph fills the tile edge to edge. `contain` left it letterboxed with
   a band of panel showing top and bottom — the tile read as unfinished on a
   phone, where it is the full width of the screen. The photographs are square
   and the tile is nearly square, so this crops a few percent and distorts
   nothing. SVG artwork above is unaffected: it is drawn to sit inset. */
.cat__art img.prod { width: 100%; height: 100%; object-fit: cover; }
.cat h3 { font-size: 25px; font-weight: 800; font-style: italic; text-transform: uppercase; letter-spacing: -.03em; }
.cat p { font-size: 12px; letter-spacing: .16em; text-transform: uppercase; font-weight: 700; color: var(--accent-300); margin-top: 7px; }

/* ============================================================
   PRODUCT GRID
   ============================================================ */
/* Columns follow the width rather than being fixed at four. With a wide
   container a fixed four would just inflate every tile; letting the count grow
   keeps a product card about the size it was and puts the extra room into
   showing more of them. */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 20px; }
/* Shop pages give a column to the filter rail. The minimum is set so the space
   left over still divides into the same card size the home page uses — at 300
   it did not, and the shop dropped to three oversized columns. */
.grid--3 { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }

.card { position: relative; display: flex; flex-direction: column; }
.card__media {
  position: relative; aspect-ratio: 1 / 1; border-radius: 5px; overflow: hidden;
  background: var(--surface);
  display: grid; place-items: center;
}
.card__media svg.prod { width: 74%; transition: transform .45s cubic-bezier(.2,.8,.2,1); }
.card:hover .card__media svg.prod { transform: scale(1.06) translateY(-4px); }
.card__flags { position: absolute; top: 12px; left: 12px; display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.flag {
  font-size: 9.5px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
  padding: 5px 9px; border-radius: 3px; background: var(--surface-3); color: var(--text);
}
.flag--drip { background: var(--text); color: var(--bg); }
.flag--sale { background: var(--accent-500); color: var(--on-accent); }
.flag--gone { background: #000; color: #fff; }
/* Sold out: still browsable, just plainly not for sale right now. The photo
   is left exactly as it is — only the badge and the button say so. */
.card--gone .card__quick .btn { background: var(--surface-3); color: var(--muted); }
.card__quick {
  position: absolute; left: 12px; right: 12px; bottom: 12px;
  opacity: 0; transform: translateY(10px);
  transition: opacity .25s, transform .25s cubic-bezier(.2,.8,.2,1);
}
.card:hover .card__quick { opacity: 1; transform: none; }
.card__body { padding: 14px 2px 0; display: flex; flex-direction: column; gap: 4px; }
.card__cat { font-size: 10px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; color: var(--muted); }
/* Dry Fit is the range's own name rather than a plain section heading, so it
   carries the brand red the way the tag line below the name does. */
.card__cat--dry { color: var(--accent-500); }

/* "Only 2 left in XL" under the add-to-bag row. Deliberately quiet: it is
   there so nobody picks a quantity we cannot fill, not to press anyone. */
.pdp__left { margin-top: 10px; font-size: 12.5px; color: var(--accent-400); }

/* Sizing advice, sat right under the buttons it applies to. Muted, with only
   the word "Recommended" carrying weight — it has to be read before a size is
   picked, but it is guidance, not a warning. */
.sizes__rec { margin-top: 11px; font-size: 12.5px; color: var(--muted); }
.sizes__rec b { color: var(--text); font-weight: 700; }
/* Same treatment as the .eyebrow on the product page, so a line like
   "Player Edition" reads identically wherever the product appears. */
.card__tag { display: block; margin-top: 5px; font-size: 10px; font-weight: 800;
  letter-spacing: .18em; text-transform: uppercase; color: var(--accent-500); }
.card__name { font-size: 15px; font-weight: 700; letter-spacing: -.01em; }
.card__price { font-size: 15px; font-weight: 800; font-style: italic; margin-top: 2px; display: flex; gap: 9px; align-items: baseline; }
.card__price s { color: var(--muted); font-weight: 600; font-style: normal; font-size: 13px; }
.card__swatch { display: flex; gap: 5px; margin-top: 7px; }
.card__swatch i { width: 13px; height: 13px; border-radius: 50%; box-shadow: inset 0 0 0 1px rgba(0,0,0,.14); }

/* ============================================================
   SHOP LAYOUT
   ============================================================ */
.pagehead { background: var(--bg-deep); color: #fff; padding: 54px 0 46px; position: relative; overflow: hidden; }
.pagehead h1 { font-size: clamp(34px, 5.6vw, 62px); font-weight: 800; font-style: italic; text-transform: uppercase; letter-spacing: -.045em; }
.pagehead p { color: var(--text-2); margin-top: 12px; max-width: 540px; }
.crumbs { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; font-weight: 700; color: var(--muted); margin-bottom: 16px; }
.crumbs a:hover { color: var(--accent-300); }

.shop { display: grid; grid-template-columns: 232px 1fr; gap: 40px; align-items: start; padding: 44px 0 90px; }
.filters { position: sticky; top: calc(var(--nav-h) + 20px); }
.fgroup { border-bottom: 1px solid var(--line); padding: 18px 0; }
.fgroup:first-child { padding-top: 0; }
/* The header is a button so it can be operated by keyboard on mobile, but on
   desktop it is styled as the plain label it used to be and never collapses. */
.fgroup__head {
  width: 100%; display: flex; align-items: center; gap: 8px;
  padding: 0; margin-bottom: 13px; text-align: left; cursor: default;
  font-size: 11px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase;
  color: var(--text);
}
.fgroup__n {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--accent-500); color: var(--on-accent);
  font-size: 10px; line-height: 18px; letter-spacing: 0; text-align: center;
}
.fgroup__chev { display: none; }
.fopt { display: flex; align-items: center; gap: 10px; padding: 5px 0; font-size: 14px; color: var(--text-2); cursor: pointer; }
.fopt input { accent-color: var(--accent-500); width: 15px; height: 15px; cursor: pointer; }
.fopt span.n { margin-left: auto; color: var(--muted); font-size: 12px; }
.sizes { display: flex; flex-wrap: wrap; gap: 6px; }
.size-chip {
  min-width: 42px; height: 34px; padding: 0 8px; border-radius: 3px;
  display: grid; place-items: center; font-size: 12.5px; font-weight: 700;
  box-shadow: inset 0 0 0 1px var(--line); transition: .16s;
}
.size-chip:hover { box-shadow: inset 0 0 0 1.5px var(--text); }

/* The "tell me when it's back" row. One field and one button, side by side on
   anything wider than a phone and stacked below that, where a 120px input next
   to a button is neither. */
/* PRE-ORDER, under a sold-out size. A panel rather than a line of text,
   because it is an offer with a button in it, and the quieter "tell me when
   it's back" folds away beneath it for anybody who only wants to hear. */
.preorder { background: var(--surface); box-shadow: inset 0 0 0 1px var(--line);
  border-radius: 6px; padding: 14px 16px; max-width: 460px; }
.preorder--done { box-shadow: inset 0 0 0 1px var(--accent-500); }
.preorder__head { font-size: 14px; }
.preorder__how { font-size: 13px; color: var(--text-2); margin-top: 4px; line-height: 1.55; }
.preorder__how a { color: var(--accent-400); text-decoration: underline; }
.preorder__row { display: flex; gap: 10px; align-items: center; margin-top: 12px; flex-wrap: wrap; }
.qty.qty--sm { height: 38px; }
.qty.qty--sm button { width: 34px; font-size: 16px; }
.qty.qty--sm span { width: 26px; }
.preorder__alt { margin-top: 12px; max-width: 460px; }
.preorder__alt summary { cursor: pointer; font-size: 12.5px; color: var(--muted);
  text-decoration: underline; text-underline-offset: 3px; margin-bottom: 8px; }
.backsoon { display: flex; gap: 8px; margin-top: 4px; max-width: 420px; }
.backsoon input {
  flex: 1; min-width: 0; padding: 12px 13px; border: 0; border-radius: 4px;
  background: var(--surface-2); color: var(--text); font-size: 14.5px; font-family: inherit;
}
.backsoon input:focus-visible { outline: 2px solid var(--accent-400); outline-offset: 1px; }
@media (max-width: 620px) {
  .backsoon { flex-direction: column; }
  .backsoon input { font-size: 16px; }
  .backsoon .btn { width: 100%; }
}
.size-chip.on { background: var(--accent-500); color: var(--on-accent); box-shadow: none; }
.size-chip.off { opacity: .35; text-decoration: line-through; pointer-events: none; }

/* WHERE IT SHIPS FROM — two prices for the same shirt.

   Deliberately not radio buttons: the difference between these two is a price
   and a waiting time, and both have to be readable at a glance from a phone.
   Two wide rows with the figure on the right do that; a radio and a label do
   not. Stacked always, because side by side at 375px gives each one about
   twelve characters to explain itself. */
.ship-pick { display: grid; gap: 8px; }
.ship-pick__opt {
  display: block; width: 100%; text-align: left; padding: 11px 13px; border-radius: 4px;
  box-shadow: inset 0 0 0 1px var(--line); transition: .16s; cursor: pointer;
}
.ship-pick__opt:hover:not([disabled]) { box-shadow: inset 0 0 0 1.5px var(--text); }
.ship-pick__opt.on {
  box-shadow: inset 0 0 0 1.5px var(--accent-500);
  background: color-mix(in srgb, var(--accent-500) 8%, transparent);
}
.ship-pick__top { display: flex; align-items: baseline; gap: 10px; }
.ship-pick__top b { font-size: 14px; }
.ship-pick__top em { margin-left: auto; font-style: normal; font-weight: 800; font-size: 15px; }
.ship-pick__opt small { display: block; margin-top: 3px; font-size: 12px; color: var(--muted); }
/* The UK option closes when the chosen size is off the shelf. Dimmed rather
   than removed: the price it was offering is why someone would wait for it. */
.ship-pick__opt[disabled] { opacity: .45; cursor: default; }
.ship-pick__opt[disabled] .ship-pick__top em { text-decoration: line-through; }

/* "from £19.99" on a tile that has two prices. */
.card__from { font-size: 11px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }

/* Two parcels, said once under the delivery line. */
.co__ship-note { margin: -4px 0 8px; font-size: 11.5px; line-height: 1.45; color: var(--muted); }

/* Filters that cannot apply to this page are removed, not dimmed — a dead
   option still costs a line of phone screen. Hiding is handled once, at the
   top of this file; see the rule beside the reset. */
/* Top padding follows the first *visible* group, not the first in the markup. */
.fgroup--first { padding-top: 0; }

.shopbar { display: flex; align-items: center; gap: 14px; margin-bottom: 22px; flex-wrap: wrap; }
.shopbar .count { font-size: 13px; color: var(--muted); }
.shopbar select {
  margin-left: auto; height: 40px; padding: 0 14px; border-radius: 3px;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--text); font-size: 13px; font-weight: 600;
}
.chips { display: flex; gap: 7px; flex-wrap: wrap; }
.chip {
  font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  padding: 7px 12px; border-radius: 999px; background: var(--surface-2); display: inline-flex; gap: 7px; align-items: center;
}
.chip button { font-size: 14px; line-height: 1; color: var(--muted); }
.empty { padding: 70px 0; text-align: center; color: var(--muted); }

/* ============================================================
   PRODUCT DETAIL
   ============================================================ */
.pdp { display: grid; grid-template-columns: 1.1fr .9fr; gap: 56px; padding: 40px 0 90px; align-items: start; }
/* A shirt from the exclusives pot, opened before it has been revealed. */
.pdp.pdp--locked { display: block; }
.pdp__locked { max-width: 560px; margin: 30px auto 0; text-align: center; background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line); border-radius: 8px; padding: 40px 28px; }
.pdp__lock { font-size: 34px; }
.pdp__locked h1 { font-size: clamp(26px, 3.4vw, 36px); font-weight: 800; font-style: italic;
  text-transform: uppercase; letter-spacing: -.03em; margin: 10px 0 12px; }
.pdp__locked p { color: var(--text-2); line-height: 1.65; margin-bottom: 22px; }
.gallery { display: grid; gap: 12px; }
.gallery__main {
  aspect-ratio: 1/1; background: var(--surface); border-radius: 6px;
  display: grid; place-items: center; overflow: hidden; position: relative;
}
.gallery__main svg.prod { width: 76%; }

/* THE ARROWS ON THE PHOTO. Subtle on purpose: a small dark disc with a thin
   chevron, sitting low-contrast over the photo until it is pointed at. They
   are always there rather than appearing on hover, because a phone has no
   hover and that is where most people will be pressing them. */
.gallery__arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(1, 21, 50, .28); color: #fff; opacity: .72;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .14);
  transition: opacity .18s, background .18s;
}
.gallery__arrow--prev { left: 12px; }
.gallery__arrow--next { right: 12px; }
.gallery__arrow svg { width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.gallery__main:hover .gallery__arrow { opacity: .9; }
.gallery__arrow:hover { opacity: 1; background: rgba(1, 21, 50, .5); }
.gallery__arrow:focus-visible { opacity: 1; outline: 2px solid var(--accent-400); outline-offset: 2px; }
@media (max-width: 620px) {
  .gallery__arrow { width: 34px; height: 34px; }
  .gallery__arrow--prev { left: 8px; }
  .gallery__arrow--next { right: 8px; }
}
.gallery__thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.thumb {
  aspect-ratio: 1/1; background: var(--surface); border-radius: 4px; display: grid; place-items: center;
  box-shadow: inset 0 0 0 1px transparent; transition: .18s; overflow: hidden;
}
.thumb.on { box-shadow: inset 0 0 0 2px var(--accent-500); }
.thumb svg.prod { width: 72%; }

.pdp__info h1 { font-size: clamp(28px, 3.4vw, 40px); font-weight: 800; font-style: italic; text-transform: uppercase; letter-spacing: -.04em; }
.pdp__price { font-size: 26px; font-weight: 800; font-style: italic; margin-top: 14px; display: flex; align-items: baseline; gap: 12px; }
.pdp__price s { font-size: 17px; color: var(--muted); font-weight: 600; font-style: normal; }
.pdp__desc { color: var(--text-2); margin-top: 18px; font-size: 15px; line-height: 1.7; }
/* The star line is a link to the reviews it summarises. */
.pdp__rating { display: inline-flex; align-items: center; gap: 8px; margin-top: 10px;
  font-size: 13px; color: var(--muted); text-decoration: none; }
.pdp__rating:hover span { color: var(--text); text-decoration: underline; }
/* The static version of the page, before the script redraws it. */
.pdp__specs { margin: 16px 0 0; padding-left: 18px; color: var(--text-2); font-size: 14px; line-height: 1.7; }

/* ---- reviews on the product page ---- */
.pdprev .sec__head { align-items: flex-end; }
.pdprev__avg { display: inline-flex; align-items: center; gap: 8px; margin-left: 12px;
  font-size: 15px; font-style: normal; font-weight: 700; letter-spacing: 0;
  text-transform: none; vertical-align: middle; }
.pdprev__avg em { font-style: normal; font-weight: 500; color: var(--muted); font-size: 13px; }
.pdprev__list { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
@media (max-width: 560px) {
  .pdprev__list { grid-template-columns: 1fr; }
  .pdprev__avg { display: flex; margin: 8px 0 0; }
}
.pdp__block { margin-top: 26px; }
.pdp__block h4 { font-size: 11px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; margin-bottom: 11px; display: flex; justify-content: space-between; }
.pdp__block h4 a { color: var(--accent-500); letter-spacing: .1em; }
.colorway { display: flex; gap: 10px; }
.colorway button {
  width: 38px; height: 38px; border-radius: 50%; position: relative;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.12);
}
.colorway button.on::after {
  content: ""; position: absolute; inset: -5px; border-radius: 50%; box-shadow: 0 0 0 2px var(--accent-500);
}
.pdp__buy { display: flex; gap: 10px; margin-top: 28px; }
.qty { display: flex; align-items: center; box-shadow: inset 0 0 0 1.5px var(--line); border-radius: 4px; height: 50px; }
.qty button { width: 42px; height: 100%; font-size: 18px; color: var(--text-2); }
.qty span { width: 34px; text-align: center; font-weight: 800; }
.usp { display: grid; gap: 12px; margin-top: 30px; padding-top: 26px; border-top: 1px solid var(--line); }
.usp li { display: flex; gap: 11px; font-size: 13.5px; color: var(--text-2); align-items: center; }
.usp svg { width: 17px; height: 17px; flex: none; stroke: var(--accent-500); fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

.acc { border-top: 1px solid var(--line); }
.acc__item { border-bottom: 1px solid var(--line); }
.acc__btn { width: 100%; display: flex; justify-content: space-between; align-items: center; padding: 17px 0; font-size: 12px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
.acc__btn i { font-style: normal; font-size: 18px; color: var(--muted); transition: transform .22s; }
.acc__item.on .acc__btn i { transform: rotate(45deg); }
.acc__panel { max-height: 0; overflow: hidden; transition: max-height .3s ease; }
.acc__panel p { padding: 0 0 17px; font-size: 14px; color: var(--text-2); line-height: 1.7; }

/* ============================================================
   CART DRAWER
   ============================================================ */
.scrim { position: fixed; inset: 0; background: rgba(8,11,15,.55); opacity: 0; pointer-events: none; transition: opacity .3s; z-index: 90; backdrop-filter: blur(2px); }
.scrim.on { opacity: 1; pointer-events: auto; }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(430px, 92vw);
  background: var(--surface); z-index: 100; display: flex; flex-direction: column;
  /* Same reasoning as .mmenu: the transform is the animation, not the hiding. */
  transform: translateX(101%); visibility: hidden; pointer-events: none;
  transition: transform .36s cubic-bezier(.2,.85,.25,1);
  box-shadow: var(--shadow-lg);
}
.drawer.on { transform: none; visibility: visible; pointer-events: auto; }
.drawer__head { display: flex; align-items: center; padding: 20px 22px; border-bottom: 1px solid var(--line); }
.drawer__head h3 { font-size: 15px; font-weight: 800; font-style: italic; text-transform: uppercase; letter-spacing: -.01em; }
.drawer__head button { margin-left: auto; font-size: 22px; color: var(--muted); line-height: 1; }
.drawer__body { flex: 1; overflow-y: auto; padding: 8px 22px; }
.drawer__foot { border-top: 1px solid var(--line); padding: 20px 22px; }
.drawer__row { display: flex; justify-content: space-between; font-size: 13.5px; margin-bottom: 8px; color: var(--text-2); }
.drawer__row.total { font-size: 19px; font-weight: 800; font-style: italic; color: var(--text); margin: 14px 0 16px; }

.citem { display: grid; grid-template-columns: 76px 1fr auto; gap: 14px; padding: 16px 0; border-bottom: 1px solid var(--surface-3); }
.citem__img { aspect-ratio: 1/1; background: var(--surface-2); border-radius: 4px; display: grid; place-items: center; }
.citem__img svg.prod { width: 78%; }
.citem b { font-size: 13.5px; font-weight: 700; display: block; }
.citem small { font-size: 11.5px; color: var(--muted); display: block; margin-top: 3px; }
.citem__qty { display: inline-flex; align-items: center; gap: 3px; margin-top: 8px; box-shadow: inset 0 0 0 1px var(--line); border-radius: 3px; }
.citem__qty button { width: 26px; height: 26px; font-size: 14px; color: var(--text-2); }
.citem__qty span { width: 22px; text-align: center; font-size: 12.5px; font-weight: 700; }
.citem__right { text-align: right; font-weight: 800; font-size: 13.5px; font-style: italic; }
.citem__right button { display: block; margin-top: 10px; font-size: 11px; color: var(--muted); text-decoration: underline; margin-left: auto; }
.cart-empty { text-align: center; padding: 60px 10px; color: var(--muted); }
.cart-empty svg { width: 46px; height: 46px; margin: 0 auto 14px; stroke: var(--surface-3); fill: none; stroke-width: 1.5; }

/* toast */
.toast {
  position: fixed; bottom: 26px; left: 50%; z-index: 120;
  /* 130% of its own height was not enough to clear the bottom edge: when empty
     the toast is only 26px tall, so ~18px of it sat visible at the foot of
     every page. Offset by its full height plus the gap, and take it out of the
     rendering entirely, so nothing can peek. */
  transform: translate(-50%, calc(100% + 40px));
  opacity: 0; visibility: hidden; pointer-events: none;
  /* visibility is deliberately NOT transitioned: a transitioned discrete
     property keeps its start value whenever transitions do not run (a
     background tab, reduced motion), which would leave the toast stuck
     hidden. It flips instantly; only movement and fade are animated. */
  transition: transform .38s cubic-bezier(.2,.9,.25,1), opacity .25s;
  background: var(--surface-3); color: var(--text); padding: 13px 22px; border-radius: 4px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .04em; box-shadow: var(--shadow-lg);
  display: flex; align-items: center; gap: 10px;
}
.toast.on { transform: translate(-50%, 0); opacity: 1; visibility: visible; }
.toast svg { width: 17px; height: 17px; stroke: var(--accent-400); fill: none; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }

/* ============================================================
   FEATURE STRIPS
   ============================================================ */
.usps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); border-block: 1px solid var(--line); }
.usps > div, .usps > a { background: var(--surface); padding: 30px 24px; display: flex; gap: 14px; align-items: flex-start; }
.usps > a { transition: background .18s; }
.usps > a:hover { background: var(--surface-2); }
.usps > a:hover b { color: var(--accent-400); }
.usps > a:focus-visible { outline: 2px solid var(--accent-400); outline-offset: -2px; }
.usps svg { width: 24px; height: 24px; flex: none; stroke: var(--accent-500); fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.usps b { display: block; font-size: 12.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.usps p { font-size: 13px; color: var(--muted); margin-top: 5px; line-height: 1.5; }

/* split feature */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 0; align-items: stretch; }
.split__art { background: var(--surface); display: grid; place-items: center; padding: 60px; position: relative; overflow: hidden; min-height: 460px; }
.split__art svg.prod { width: 78%; max-width: 420px; position: relative; }
.split__copy { padding: 70px; display: flex; flex-direction: column; justify-content: center; }
.split__copy h2 { font-size: clamp(28px, 3.6vw, 44px); font-weight: 800; font-style: italic; text-transform: uppercase; letter-spacing: -.04em; }
.split__copy p { color: var(--muted); margin-top: 16px; font-size: 15.5px; line-height: 1.7; max-width: 460px; }
.split__copy .btn { margin-top: 28px; align-self: flex-start; }
.speclist { display: grid; gap: 10px; margin-top: 24px; }
.speclist li { display: flex; gap: 11px; font-size: 14px; align-items: center; color: var(--text-2); }
.speclist i { width: 6px; height: 6px; background: var(--accent-500); transform: rotate(45deg); flex: none; }

/* newsletter */
.news { background: var(--bg-deep); color: #fff; padding: 76px 0; position: relative; overflow: hidden; }
.news__in { display: grid; grid-template-columns: 1fr 1fr; gap: 50px; align-items: center; position: relative; }
.news h2 { font-size: clamp(28px, 3.8vw, 44px); font-weight: 800; font-style: italic; text-transform: uppercase; letter-spacing: -.04em; }
.news p { color: var(--text-2); margin-top: 14px; max-width: 420px; }
.news form { display: flex; gap: 10px; }
.news input {
  flex: 1; height: 52px; padding: 0 18px; border-radius: 4px; border: 0;
  background: rgba(255,255,255,.07); color: #fff; box-shadow: inset 0 0 0 1px rgba(255,255,255,.16);
}
.news input::placeholder { color: var(--muted); }
.news input:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--accent-400); }
.news small { display: block; margin-top: 12px; color: #6f7078; font-size: 12px; }

/* ============================================================
   FOOTER
   ============================================================ */
.foot { background: var(--bg-deep); color: var(--muted); padding: 62px 0 0; border-top: 1px solid rgba(255,255,255,.07); }
.foot__cols { display: grid; grid-template-columns: 1.9fr 1fr 1fr; gap: 40px; padding-bottom: 46px; }
.foot h5 { font-size: 11px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; color: #fff; margin-bottom: 16px; }
.foot li { padding: 6px 0; font-size: 13.5px; }
.foot a:hover { color: var(--accent-300); }
.foot__about p { font-size: 13.5px; margin-top: 16px; max-width: 320px; line-height: 1.65; }
.foot__bar { border-top: 1px solid rgba(255,255,255,.08); padding: 22px 0; display: flex; gap: 18px; align-items: center; font-size: 12px; flex-wrap: wrap; }
.foot__bar .pays { margin-left: auto; display: flex; gap: 8px; }
.pay { width: 42px; height: 27px; border-radius: 3px; background: rgba(255,255,255,.08); display: grid; place-items: center; font-size: 8px; font-weight: 800; letter-spacing: .05em; color: #b6b8bf; }

/* reveal */
.rv { opacity: 0; transform: translateY(22px); transition: opacity .6s ease, transform .6s cubic-bezier(.2,.8,.2,1); }
.rv.in { opacity: 1; transform: none; }

/* Phones do not get the fade at all.

   The reveal hides everything by default and shows it once a browser API
   reports back. That means every way it can fail — an observer that stays
   silent, a redraw that replaces watched elements, a page restored from a
   snapshot — fails to a blank shop. It has done exactly that twice, and on a
   phone a blank shop is the entire shop.

   A design where the failure mode is "no products" is the wrong design for
   the ninety per cent of people arriving on a phone, and a decorative fade is
   not worth one more round of it. Desktop keeps it; it is a bigger screen,
   a scroll that means more, and a place where this has never gone wrong. */
@media (max-width: 900px) {
  .rv { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1080px) {
  .split__copy { padding: 50px 40px; }
}
/* SEVEN TABS NO LONGER FIT AT 900px.

   The header row was six tabs and fitted down to the 900px breakpoint below
   with room to spare. Weekly Exclusives made it seven, and seven runs into
   the search/account/bag icons at anything under about 1080px — which put a
   horizontal scrollbar on every page of the shop at ordinary laptop and
   tablet widths.

   So the nav collapses to the burger earlier. Its own query rather than
   moving the block below, because nothing else in that block was wrong: the
   hero, the category grid and the rest are right where they are, and
   dragging them up to 1100px to fix a header would be a layout change
   nobody asked for. Every tab is still in the menu. */
@media (max-width: 1160px) {
  .nav__links { display: none; }
  .burger { display: grid; }
}
@media (max-width: 900px) {
  .nav__links { display: none; }
  .burger { display: grid; }
  /* Scoped to .hero on purpose: the phone-width `.wrap` rule below sets
     `padding` as a shorthand, which resets padding-block to 0 and left the
     hero flush against both edges. A more specific selector survives it. */
  .hero .hero__in { grid-template-columns: minmax(0, 1fr); min-height: 0;
    padding-block: 48px 56px; }
  .hero__art { width: 100%; max-width: 500px; justify-self: center; margin-top: 26px; }
  /* TWO ACROSS, AND SHORTER.

     One column of 320mm-tall tiles, one per club, came to 6,400px on a phone
     — eight screens, and 44% of the whole home page, spent on a list of team
     names between the shirts at the top and the shirts further down. Nobody
     scrolls eight screens of tiles to find Arsenal; they use the Teams menu.

     Two columns at 150px brings the same eighteen clubs to about 1,400px and
     keeps every one of them on the page. The crest still reads at this size
     — it is the club's own artwork and it is the thing being recognised. */
  .cats { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .cat { min-height: 150px; padding: 14px;
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 16px), calc(100% - 16px) 100%, 0 100%); }
  .cat h3 { font-size: 16px; }
  .cat p { font-size: 10px; letter-spacing: .1em; margin-top: 4px; }
  .cat__art svg { width: 78%; }
  /* Stacked, the 44px lead-in and 40px column gap read as dead space between
     the heading, the filter button and the products. */
  /* The page heading already names the filter, so the run-in to the grid is
     pure spacing — trimmed hard on a phone where it costs a third of a screen. */
  .pagehead { padding: 36px 0 22px; }
  .shop { grid-template-columns: 1fr; padding: 10px 0 70px; gap: 8px; }
  .shopbar { margin-bottom: 6px; gap: 8px; }
  .shopbar select { height: 42px; font-size: 14px; }
  .chip { padding: 5px 10px; font-size: 10.5px; }
  /* Keeps the count and the sort control on one row — wrapped, they cost
     another 45px directly above the grid. */
  .shopbar .count { flex: none; }
  .shopbar select { margin-left: auto; max-width: 58%; }
  .filters { position: static; }
  .pdp { grid-template-columns: 1fr; gap: 34px; }
  .split { grid-template-columns: 1fr; }
  .split__art { min-height: 340px; padding: 40px; }
  .usps { grid-template-columns: repeat(2, 1fr); }
  .news__in { grid-template-columns: 1fr; gap: 26px; }
  .foot__cols { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 620px) {
  .grid, .grid--3 { grid-template-columns: repeat(2, 1fr); gap: 14px; }
  .sec { padding: 58px 0; }
  .wrap { padding: 0 16px; }
  .hero__stats { gap: 22px; }
  .hero__stats div b { font-size: 20px; }
  .usps { grid-template-columns: 1fr; }
  .foot__cols { grid-template-columns: 1fr; gap: 28px; }
  /* THE SHOP COLUMN IS EVERY CLUB, AGAIN.

     Twenty-five links at one per line came to 1,186px — a screen and a half
     of footer listing the same clubs the page has already shown as tiles.
     The links stay, because they are how a search engine finds those pages
     and how somebody deep in the footer gets to their team; they just sit two
     across instead of in a single column. */
  .foot__shop ul { columns: 2; column-gap: 18px; }
  .foot__shop li { break-inside: avoid; }
  .sec__head { flex-direction: column; align-items: flex-start; }
  .gallery__thumbs { grid-template-columns: repeat(4, 1fr); }
  .news form { flex-direction: column; }
  .btn { padding: 0 22px; }

  /* ----------------------------------------------------------------
     PHONES: the rest of this block

     Most of the traffic is on a phone, and the design was drawn on a
     laptop, so the type and the targets came down here rather than up.
     Everything below is that corrected, measured on a 390px screen.
     ---------------------------------------------------------------- */

  /* Form fields are set to 16px on phones so iOS does not zoom the page when
     one is focused — the rule lives beside .fld further down, because these
     selectors are more specific than a bare `input` and would beat it. */

  /* Chrome at the top of the screen. 88px of sticky header plus a topbar
     wrapping onto two lines was 136px — a sixth of the screen — before any
     shop. The variable is used by every sticky sidebar's offset too, so it
     is the one place to change it. */
  :root { --nav-h: 66px; }
  .topbar .wrap { min-height: 0; padding-block: 7px; line-height: 1.35; }

  /* Type. Nothing below is decorative: these are the words that say what a
     thing is, what it costs and what the button does. */
  .btn { font-size: 14px; letter-spacing: .1em; }
  .btn--sm { font-size: 13px; height: 44px; }
  .eyebrow { font-size: 12px; letter-spacing: .2em; }
  .flag { font-size: 11px; padding: 5px 10px; letter-spacing: .1em; }
  .link-arrow { font-size: 13px; letter-spacing: .1em; padding: 6px 0; }
  .hero__stats div span { font-size: 11px; letter-spacing: .12em; }
  .card__cat { font-size: 11px; letter-spacing: .12em; }
  .card__name { font-size: 16px; }
  .card__price { font-size: 16px; }
  .foot li { font-size: 15px; }
  .foot h5 { font-size: 12px; }

  /* Section dividers.

     On a laptop these sections are told apart by their shape — a split runs
     picture beside words, a grid runs three across. Stacked into one column on
     a phone that shape is gone, and several of them share the page's own
     background, so Choose Your Team, The Retro Vault and the Nike panel ran
     together as one wall of navy with no edge between them.

     A rule at the top of each, inset to the same margin the text uses so it
     reads as drawn rather than as a browser default, and carrying the brand's
     lime for its first few millimetres so it belongs to this site rather than
     to any site. */
  .sec, .split, .news { position: relative; }
  .sec::before, .split::before, .news::before {
    content: ""; position: absolute; top: 0; left: 16px; right: 16px; height: 2px;
    background: linear-gradient(to right, var(--accent-500) 0 34px, var(--line) 34px);
    /* A pseudo-element is painted before the element's own children, and a
       split leads with .split__art — a positioned panel with a background of
       its own, starting at exactly the same line. It buried the rule. The
       Retro Vault, which follows Choose Your Team, had no divider at all
       because of it, and the first check missed it by hiding the very panel
       doing the burying. */
    z-index: 1;
  }
  /* The split panels carried 40px of side padding from the desktop layout, so
     their words started 24px further in than every other section's. Invisible
     until a rule was drawn above them, at which point the rule and the heading
     under it plainly did not line up. */
  .split__copy { padding: 46px 16px; }

  /* Targets. A finger is about 9mm across; anything under 44px is a coin
     toss. The size chips are the worst of it — choosing a size is the one
     tap on the page that has to be right, and they were 34px tall. */
  .size-chip { min-width: 48px; height: 44px; font-size: 14px; }
  .foot li { padding: 0; }
  .foot li a { display: block; padding: 11px 0; }
  .link-arrow { min-height: 44px; }
}

/* mobile menu */
.mmenu {
  position: fixed; inset: 0; z-index: 95; background: var(--bg-deep); color: #fff;
  /* Being off-screen must not be the only thing hiding this. Parked on the
     transform alone, the panel bled into the top of the page on Android
     Chrome — its first link, HOME, sat over the content in 26px italic caps.
     visibility takes it out of rendering entirely, whatever the geometry
     resolves to; the 0s delay holds it on screen for the slide-out. */
  transform: translateY(-100%); visibility: hidden; pointer-events: none;
  transition: transform .4s cubic-bezier(.2,.85,.25,1);
  padding: 26px; display: flex; flex-direction: column;
  /* The panel is exactly the height of the screen, and the list inside it is
     not. With twelve clubs under Teams the bottom of the list sat below the
     fold with no way to reach it — the tabs are built from stock, so the menu
     grows every time a club is added and there is no length that stays safe.
     The nav scrolls instead; the logo and the close button stay put. */
  overflow: hidden;
}
.mmenu.on { transform: none; visibility: visible; pointer-events: auto; }
.mmenu > nav {
  flex: 1; min-height: 0;            /* or a flex child refuses to shrink and scroll */
  overflow-y: auto;
  overscroll-behavior: contain;      /* scrolling the menu must not drag the page behind it */
  -webkit-overflow-scrolling: touch;
  /* Clear of the iPhone's home indicator, and a little slack so the last club
     is not flush against the bottom edge. */
  padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px));
}
.mmenu__top { display: flex; align-items: center; margin-bottom: 34px; flex: none; }
.mmenu__top button { margin-left: auto; font-size: 28px; color: #fff; line-height: 1; }
.mmenu nav a {
  display: block; padding: 15px 0; font-size: 26px; font-weight: 800; font-style: italic;
  text-transform: uppercase; letter-spacing: -.03em; border-bottom: 1px solid rgba(255,255,255,.08);
}
.mmenu nav a:hover { color: var(--accent-400); }
/* Same type as a top-level link, with a chevron that turns when it opens. */
.mmenu__toggle {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  padding: 18px 0; text-align: left; color: #fff;
  font-size: 26px; font-weight: 800; font-style: italic;
  text-transform: uppercase; letter-spacing: -.03em;
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.mmenu__toggle i {
  width: 11px; height: 11px; border-right: 2.5px solid currentColor;
  border-bottom: 2.5px solid currentColor; transform: rotate(45deg) translate(-3px, -3px);
  transition: transform .22s; flex: none;
}
.mmenu__toggle[aria-expanded="true"] i { transform: rotate(-135deg) translate(-3px, -3px); }
.mmenu__sub { padding: 10px 0 14px 18px; border-bottom: 1px solid rgba(255,255,255,.08); }
.mmenu nav .mmenu__sub a {
  padding: 9px 0; font-size: 15px; font-style: normal; font-weight: 700;
  letter-spacing: .12em; color: var(--text-2); border-bottom: 0;
}
.mmenu nav .mmenu__sub a:hover { color: var(--accent-400); }

/* droplet idle motion */
@media (prefers-reduced-motion: reduce) {
  .hero__glow, .marquee__track { animation: none !important; }
  .rv { opacity: 1 !important; transform: none !important; }
}

/* ---------- photo slot ----------
   img.prod drops into exactly the same frames as the vector fallback,
   so swapping in photography needs no layout changes. */
img.prod { width: 100%; height: 100%; object-fit: contain; object-position: center; }
.card__media img.prod { transition: transform .45s cubic-bezier(.2,.8,.2,1); }
.card:hover .card__media img.prod { transform: scale(1.06) translateY(-4px); }

/* Photographs go up exactly as the supplier shot them, on their own studio
   sweep, so the frame behind them is that same light grey rather than white —
   on white every shot would read as a grey square floating in a white one.
   Vector-art products keep the dark tile, hence :has() rather than a blanket
   rule. The value matches the sweep the jersey shots were lit on; each image
   is padded to square with its OWN border colour, so the frame only shows
   where a shot is a different grey, and then only as a hairline. */
.card__media:has(img.prod),
.gallery__main:has(img.prod),
.thumb:has(img.prod),
.citem__img:has(img.prod) { background: var(--photo-bg); }

/* WHILE THE PHOTO IS ON ITS WAY.

   A flat grey square with nothing in it reads as a picture that failed. A
   light sweep across the same grey reads as one that is coming. It runs only
   until the photo has arrived — `is-loaded` is set by a load listener in
   site.js — so a grid of seventy tiles is not animating seventy backgrounds
   for as long as the page is open. The photo itself is never hidden to make
   this work: if the script never runs, the pictures still show, and the
   sweep simply sits behind them where nobody can see it. */
.card__media:has(img.prod):not(.is-loaded),
.gallery__main:has(img.prod):not(.is-loaded),
.thumb:has(img.prod):not(.is-loaded),
.citem__img:has(img.prod):not(.is-loaded) {
  background: linear-gradient(100deg, var(--photo-bg) 35%, #eceef0 50%, var(--photo-bg) 65%);
  background-size: 260% 100%;
  animation: photoload 1.35s ease-in-out infinite;
}
@keyframes photoload { from { background-position: 100% 0; } to { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) {
  .card__media:has(img.prod), .gallery__main:has(img.prod),
  .thumb:has(img.prod), .citem__img:has(img.prod) { animation: none; }
}

/* Frames holding a photograph lose their inset padding. It existed to give a
   cut-out room to breathe; a full photograph already has its own margin, and
   the padding only exposes a ring of frame in a slightly different grey. */
.thumb:has(img.prod) { padding: 0; }

/* The two home-page slideshows sit on dark bands with no frame of their own,
   so a photograph there needs one — otherwise it is the same rectangle
   floating on a dark band, just in a different place. */
/* The hot panel is excluded: its shots are transparent cut-outs, so a plate
   behind them would put back the square this was meant to remove. */
.split__art .split__slide:has(img.prod) { background: var(--photo-bg); border-radius: 8px; overflow: hidden; }
.split__art img.prod { width: 78%; max-width: 420px; height: auto; }

/* Inline SVG letterboxes inside an explicit width AND height (preserveAspectRatio),
   so constraining both stops the art overflowing wide/short tiles when the grid
   collapses to a single column. */
.cat__art svg { width: 62%; height: 74%; }
.split__art svg.prod, .split__art img.prod { width: 78%; height: 74%; max-width: 420px; }

/* ---------- back control ---------- */
.backnav { display: flex; }
.backlink {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 9px 15px 9px 12px; border-radius: 3px;
  font-size: 11px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-2); background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: color .18s, background .18s, box-shadow .18s;
}
.backlink:hover { color: var(--text); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--surface-3); }
.backlink:focus-visible { outline: 2px solid var(--accent-400); outline-offset: 2px; }
.backlink svg {
  width: 15px; height: 15px; flex: none;
  stroke: currentColor; fill: none; stroke-width: 2.1; stroke-linecap: round; stroke-linejoin: round;
  transition: transform .18s;
}
.backlink:hover svg { transform: translateX(-3px); }
/* on the dark page head the surface fill would disappear into the band.

   .sat__head is the same band under another name — the £10 Saturdays and
   Weekly Exclusives heads. They were left out when those pages were built,
   so the button there had neither the lighter fill nor the gap under it and
   sat noticeably tighter to the breadcrumb than on every other page. */
.pagehead .backlink,
.sat__head .backlink { background: rgba(255,255,255,.05); box-shadow: inset 0 0 0 1px rgba(255,255,255,.14); }
.pagehead .backlink:hover,
.sat__head .backlink:hover { background: rgba(255,255,255,.11); box-shadow: inset 0 0 0 1px rgba(255,255,255,.24); }
.pagehead .backnav,
.sat__head .backnav { margin-bottom: 18px; }
/* THE BACK BUTTON IS FOR THUMBS. On a phone it is the one reliable way to
   the previous page; on a laptop the breadcrumb directly under it says where
   you are and links where you came from, and the browser has its own back
   button beside the address bar. Three ways back stacked in the head of every
   page reads as clutter, so above the burger breakpoint the button goes and
   the crumb does the job alone. */
@media (min-width: 1161px) {
  .backnav { display: none; }     /* every page that carries one also carries crumbs */
  /* EXCEPT A SHIRT. Jay: "add a back button from a particular jersey, so users
     can return to the previous page." A shirt is where people arrive from a
     grid they were halfway down, and the crumb above it goes to the category,
     not back to the place in the list they left. */
  body[data-page="product"] .backnav { display: flex; }
}

/* ============================================================
   CHAT
   Launcher sits below the cart scrim so it dims with the page;
   the panel sits above it.
   ============================================================ */
/* ------------------------------------------------------------------
   STICKY BUY BAR  (phones, product page)

   On a phone the Add to bag button sits about 1,300px down the product
   page — past the picture, the price, the colours, the sizes and the
   description. That is nearly a screen and a half of scrolling before the
   shop offers to sell you anything, with no price in sight while you read.

   So once the real button scrolls out of sight, this takes its place at
   the bottom of the screen. It does not reimplement buying: its button
   forwards the tap to the real one, so the size check, the stock cap and
   the bag all behave identically and there is only ever one of them.

   Hidden in every direction by default — desktop never sees it, and a
   phone only sees it once the real button has gone off screen.
   ------------------------------------------------------------------ */
.buybar { display: none; }

@media (max-width: 620px) {
  .buybar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 78;
    display: flex; align-items: center; gap: 14px;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
    background: rgba(4, 32, 63, .94);
    -webkit-backdrop-filter: saturate(160%) blur(14px);
    backdrop-filter: saturate(160%) blur(14px);
    border-top: 1px solid var(--line);
    transform: translateY(110%);
    transition: transform .28s cubic-bezier(.2,.85,.25,1);
    pointer-events: none;
  }
  .buybar.on { transform: none; pointer-events: auto; }
  .buybar__what { min-width: 0; }
  .buybar__name {
    display: block; font-size: 13px; color: var(--text-2);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .buybar__price {
    display: block; font-size: 19px; font-weight: 800; font-style: italic;
    letter-spacing: -.02em; color: var(--text);
  }
  .buybar .btn { flex: 1; max-width: 200px; }

  /* The bar and the chat button live in the same corner. The bar wins while
     it is up; chat steps above it rather than being buried under it. */
  body.has-buybar .chat-launcher { bottom: calc(86px + env(safe-area-inset-bottom, 0px)); }
}

.chat-launcher {
  position: fixed; right: 22px; bottom: 22px; z-index: 80;
  display: inline-flex; align-items: center; gap: 9px;
  height: 50px; padding: 0 20px; border-radius: 999px;
  background: linear-gradient(135deg, var(--accent-400), var(--accent-600));
  color: #fff; font-size: 12px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  box-shadow: 0 14px 34px rgba(182,248,35,.38);
  transition: transform .18s cubic-bezier(.2,.8,.2,1), box-shadow .2s;
}
.chat-launcher:hover { transform: translateY(-2px); box-shadow: 0 18px 40px rgba(182,248,35,.5); }
.chat-launcher:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.chat-launcher svg {
  width: 19px; height: 19px; flex: none;
  stroke: currentColor; fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round;
}

.chat-panel {
  position: fixed; right: 22px; bottom: 84px; z-index: 108;
  width: min(370px, calc(100vw - 44px)); max-height: min(560px, calc(100vh - 130px));
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 26px 60px rgba(0,0,0,.62);
  opacity: 0; visibility: hidden; transform: translateY(12px) scale(.98);
  transition: opacity .22s, transform .22s cubic-bezier(.2,.8,.2,1), visibility .22s;
}
.chat-panel.on { opacity: 1; visibility: visible; transform: none; }

.chat__head {
  display: flex; align-items: center; gap: 12px;
  padding: 15px 16px; border-bottom: 1px solid var(--line); background: var(--bg-deep);
}
.chat__head b { display: block; font-size: 14px; font-weight: 800; font-style: italic; text-transform: uppercase; letter-spacing: -.01em; }
.chat__head small { display: block; margin-top: 3px; font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.chat__head button { margin-left: auto; font-size: 22px; line-height: 1; color: var(--muted); }
.chat__head button:hover { color: var(--text); }

.chat__msgs { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.chat__msg { max-width: 86%; }
.chat__msg p {
  padding: 10px 13px; border-radius: 10px; font-size: 13.5px; line-height: 1.55;
  background: var(--surface-2); color: var(--text-2);
}
.chat__msg--you { align-self: flex-end; }
.chat__msg--you p { background: var(--accent-600); color: var(--on-accent); border-bottom-right-radius: 3px; }
.chat__msg--bot p { border-bottom-left-radius: 3px; }
.chat__msg a { color: var(--accent-300); text-decoration: underline; }
/* A pointer to a page is a button, not a sentence telling you to go and look. */
.chat__link {
  display: inline-flex; align-items: center; margin-top: 8px;
  padding: 8px 14px; border-radius: 999px;
  background: var(--accent-500); color: var(--on-accent) !important;
  font-size: 12px; font-weight: 800; letter-spacing: .06em;
  text-decoration: none !important; transition: .16s;
}
.chat__link:hover { background: var(--accent-400); }
.chat__link:focus-visible { outline: 2px solid var(--accent-300); outline-offset: 2px; }
.chat__who {
  display: block; margin-bottom: 5px;
  font-size: 9.5px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: var(--muted);
}

/* A reply from a person has to be unmistakably not the bot — a live label
   and a lit left edge, so nobody mistakes one for the other. */
.chat__who--live { color: var(--accent-300); }
.chat__who--live::before {
  content: ''; display: inline-block; width: 6px; height: 6px; margin-right: 6px;
  border-radius: 50%; background: var(--accent-400); vertical-align: middle;
}
.chat__msg--agent p {
  border-bottom-left-radius: 3px;
  background: var(--surface-3); color: var(--text);
  box-shadow: inset 2px 0 0 var(--accent-500);
}

/* Unread reply marker on the launcher. */
.chat-dot {
  position: absolute; top: 6px; right: 8px; width: 10px; height: 10px;
  border-radius: 50%; background: #fff; box-shadow: 0 0 0 2px var(--accent-600);
}

/* WhatsApp capture, offered once when a question needs a person. */
.chat__wa { padding: 0 16px 12px; }
.chat__wa p { font-size: 12.5px; color: var(--text-2); margin-bottom: 8px; }
.chat__wa-row { display: flex; gap: 8px; margin-bottom: 8px; }
/* The buttons that need no typing, above the boxes that do. */
.chat__ways { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.chat__ways button[hidden] { display: none; }
.chat__wa-row input {
  flex: 1; min-width: 0; height: 38px; padding: 0 12px; border: 0; border-radius: 4px;
  background: var(--surface-2); color: var(--text); font-size: 13.5px;
}
.chat__wa-row input[aria-invalid="true"] { box-shadow: inset 0 0 0 1.5px var(--accent-500); }
.chat__wa-no {
  margin-top: 8px; font-size: 11.5px; color: var(--muted); text-decoration: underline;
}
.chat__wa-no:hover { color: var(--text-2); }

.chat__topics { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 16px 12px; }
.chat__topics button {
  padding: 7px 12px; border-radius: 999px; font-size: 11px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-2);
  box-shadow: inset 0 0 0 1px var(--line); transition: .16s;
}
.chat__topics button:hover { color: var(--text); background: var(--surface-2); }
.chat__topics button:focus-visible { outline: 2px solid var(--accent-400); outline-offset: 1px; }

.chat__form { display: flex; gap: 8px; padding: 12px 16px 16px; border-top: 1px solid var(--line); }
.chat__form input {
  flex: 1; height: 42px; padding: 0 13px; border: 0; border-radius: 4px;
  background: var(--surface-2); color: var(--text);
  box-shadow: inset 0 0 0 1px var(--line);
}
.chat__form input::placeholder { color: var(--muted); }
.chat__form input:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--accent-400); }

@media (max-width: 620px) {
  .chat-launcher { right: 14px; bottom: 14px; height: 46px; padding: 0 16px; }
  .chat-launcher span { display: none; }
  .chat-panel { right: 10px; left: 10px; bottom: 72px; width: auto; max-height: calc(100vh - 110px); }
}
@media (prefers-reduced-motion: reduce) {
  .chat-panel, .chat-launcher { transition: none; }
}

/* Measured, and the old note here was wrong: four labels wrap onto three
   lines on a phone at 10px as readily as at 11px — the strip is long, not the
   type. So the type goes up, because 10px was legible on a laptop pretending
   to be a phone and squinty on an actual one, and the tracking comes off to
   pay for it. Three lines at 11px is 44px against 41px at 10px. */
@media (max-width: 620px) {
  .topbar { font-size: 11px; letter-spacing: .04em; }
}


/* ============================================================
   HOTTEST SELLERS
   No card: it sits straight on the hero. The only container is a
   soft ember glow behind the product, which doubles as the light
   that lifts a dark product off a near-black ground.
   ============================================================ */
.hot { position: relative; isolation: isolate; padding: 4px 0 8px; }
.hot__glow {
  position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(46% 34% at 50% 47%,
    rgba(255,150,20,.36), rgba(182,248,35,.16) 45%, transparent 72%);
  filter: blur(24px);
  animation: ember 3.6s ease-in-out infinite;
}
@keyframes ember {
  0%, 100% { opacity: .74; transform: translateY(0) scale(1); }
  50%      { opacity: 1;   transform: translateY(-6px) scale(1.05); }
}

.hot__head { display: flex; align-items: center; justify-content: center; gap: 14px; }
.hot__flame { font-size: clamp(28px, 3.0vw, 40px); line-height: 1; }
.hot__head h3 {
  font-size: clamp(34px, 3.7vw, 50px);
  font-weight: 800; font-style: italic; text-transform: uppercase; letter-spacing: -.035em;
  background: linear-gradient(94deg, #ffd79a, #ff9314 44%, var(--accent-400));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* Fixed stage height stops the hero jolting as slides swap. */
.hot__stage { margin-top: 20px; min-height: 458px; display: grid; }
.hot__slide {
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 6px;
}
.hot__slide--in { animation: hotIn .45s cubic-bezier(.2,.8,.2,1); }
@keyframes hotIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* No plate behind the product — it floats on the ember light. */
/* Larger than it was, now that there is no plate to sit inside — the cut-out
   carries its own transparent margin, so the garment reads bigger again. */
.hot__media { width: 100%; max-width: 436px; aspect-ratio: 1/1; display: grid; place-items: center; }
.hot__media svg.prod { width: 100%; filter: drop-shadow(0 16px 30px rgba(0,0,0,.55)); }
.hot__media img.prod { width: 100%; height: 100%; object-fit: contain; }
.hot__cat { margin-top: 8px; font-size: 11.5px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; color: #c8a88f; }
.hot__name { font-size: 30px; font-weight: 700; color: var(--text); }
.hot__name:hover { color: #ffd79a; }
.hot__price { font-size: 36px; font-weight: 800; font-style: italic; display: flex; gap: 10px; align-items: baseline; }
.hot__price s { font-size: 14px; font-weight: 600; font-style: normal; color: var(--muted); }
.hot__cta { margin-top: 18px; }

.hot__dots { display: flex; justify-content: center; gap: 8px; margin-top: 18px; }
.hot__dots button {
  width: 8px; height: 8px; padding: 0; border-radius: 50%;
  background: rgba(255,255,255,.24); transition: background .2s, width .2s;
}
.hot__dots button:hover { background: rgba(255,147,20,.75); }
.hot__dots button.on { width: 24px; border-radius: 999px; background: linear-gradient(90deg, #ff9314, var(--accent-500)); }
.hot__dots button:focus-visible { outline: 2px solid #ff9314; outline-offset: 3px; }

@media (max-width: 620px) {
  .hot__stage { min-height: 430px; }
  .hot__media { max-width: 300px; }
  .hot__name { font-size: 24px; }
  .hot__price { font-size: 30px; }
}
@media (prefers-reduced-motion: reduce) {
  .hot__glow { animation: none; }
  .hot__slide--in { animation: none; }
}

/* Anchored sections must clear the sticky header when scrolled to. */
section[id] { scroll-margin-top: 108px; }

/* html carries scroll-behavior: smooth, which would otherwise animate anchor
   jumps even for visitors who have asked for reduced motion. */
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* Secondary note under a split section's body copy. Needs to outrank
   `.split__copy p`, hence the two-class selector. */
.split__copy .split__note {
  margin-top: 10px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--steel);
}

/* ---------- jersey slideshow in the split panel ---------- */
.split__art .split__slides {
  /* flexes inside the arrow row rather than claiming the full panel width */
  flex: 1 1 auto; min-width: 0; max-width: 340px; aspect-ratio: 1 / 1;
  display: grid; place-items: center;
}
.split__art .split__slide { display: grid; place-items: center; width: 100%; height: 100%; }
.split__art .split__slide svg.prod,
.split__art .split__slide img.prod { width: 100%; height: 100%; object-fit: contain; }
.split__slide--in { animation: jerseyIn .5s cubic-bezier(.2,.8,.2,1); }
@keyframes jerseyIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .split__slide--in { animation: none; } }

/* ============================================================
   HELP PAGES
   ============================================================ */
.help { display: grid; grid-template-columns: 232px 1fr; gap: 44px; align-items: start; padding: 44px 0 90px; }
/* Grid items default to min-width:auto and refuse to shrink below their
   content, which stops .prose__scroll from ever scrolling and pushes the
   whole page sideways on a phone. */
.help > * { min-width: 0; }
.help__nav { position: sticky; top: calc(var(--nav-h) + 20px); display: grid; gap: 3px; }
.help__nav a {
  display: block; padding: 11px 13px; border-radius: 4px;
  font-size: 13px; font-weight: 700; color: var(--text-2); transition: background .16s, color .16s;
}
.help__nav a:hover { background: var(--surface); color: var(--text); }
.help__nav a[aria-current="page"] {
  background: var(--surface-2); color: var(--text); box-shadow: inset 0 0 0 1px var(--line);
}
.help__nav a:focus-visible { outline: 2px solid var(--accent-400); outline-offset: 2px; }

.prose { max-width: 68ch; }
.prose h2 {
  font-size: 20px; font-weight: 800; font-style: italic; text-transform: uppercase;
  letter-spacing: -.02em; margin-top: 38px;
}
.prose h2:first-child { margin-top: 0; }
.prose p { color: var(--text-2); font-size: 15px; line-height: 1.75; margin-top: 12px; }
.prose b { color: var(--text); }
.prose ul { margin-top: 14px; display: grid; gap: 10px; }
.prose li { display: flex; gap: 12px; font-size: 14.5px; line-height: 1.65; color: var(--text-2); }
.prose li::before {
  content: ""; width: 6px; height: 6px; margin-top: 8px; flex: none;
  background: var(--accent-500); transform: rotate(45deg);
}
.prose a { color: var(--accent-300); text-decoration: underline; text-underline-offset: 2px; }
.prose a:hover { color: var(--text); }
.prose a.btn { color: #fff; text-decoration: none; margin-top: 18px; }
/* wide tables scroll inside their own box rather than the page */
.prose__scroll { overflow-x: auto; margin-top: 16px; }
.prose table { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 420px; }
.prose th, .prose td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); }
.prose th {
  color: var(--text); font-size: 10.5px; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase; white-space: nowrap;
}
.prose td { color: var(--text-2); font-variant-numeric: tabular-nums; }

@media (max-width: 900px) {
  .help { grid-template-columns: 1fr; gap: 26px; padding-top: 30px; }
  .help__nav { position: static; grid-auto-flow: column; grid-auto-columns: max-content; overflow-x: auto; }
}

/* payments: two named methods rather than a row of card badges */
.pay { width: auto; padding: 0 12px; font-size: 10px; letter-spacing: .08em; }

/* ---------- jersey slideshow controls ---------- */
.split__carousel { display: grid; gap: 20px; justify-items: center; width: 100%; }
.split__stage { display: flex; align-items: center; justify-content: center; gap: 12px; width: 100%; }
.split__arrow {
  width: 42px; height: 42px; flex: none; border-radius: 50%;
  display: grid; place-items: center; color: var(--text-2);
  background: rgba(255,255,255,.05); box-shadow: inset 0 0 0 1px var(--line);
  transition: color .18s, background .18s, box-shadow .18s, transform .18s;
}
.split__arrow:hover {
  color: var(--text); background: var(--surface-2);
  box-shadow: inset 0 0 0 1px var(--surface-3); transform: scale(1.06);
}
.split__arrow:focus-visible { outline: 2px solid var(--accent-400); outline-offset: 2px; }
.split__arrow svg {
  width: 18px; height: 18px; stroke: currentColor; fill: none;
  stroke-width: 2.1; stroke-linecap: round; stroke-linejoin: round;
}
.split__arrow--next svg { transform: rotate(180deg); }

.split__dots { display: flex; gap: 8px; }
.split__dots button {
  width: 8px; height: 8px; padding: 0; border-radius: 50%;
  background: rgba(255,255,255,.24); transition: background .2s, width .2s;
}
.split__dots button:hover { background: var(--accent-400); }
.split__dots button.on {
  width: 24px; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-400), var(--accent-600));
}
.split__dots button:focus-visible { outline: 2px solid var(--accent-400); outline-offset: 3px; }

@media (max-width: 620px) {
  .split__stage { gap: 8px; }
  .split__arrow { width: 38px; height: 38px; }
}

/* ============================================================
   INSTALL PROMPT
   Sits above the chat launcher, clear of it, and respects the
   home-screen safe area on notched phones.
   ============================================================ */
/* The offer itself: a centred card over a dimmed page, shown shortly after
   arriving. A bar along the bottom got ignored, which is the only thing worse
   than being slightly in the way.

   Dismissed, it stays away for a week — the same box on every visit is how a
   shop teaches people to close it without reading it. */
.appmodal {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center; padding: 20px;
  background: rgba(6,6,8,.72); backdrop-filter: blur(3px);
  opacity: 0; transition: opacity .22s ease;
}
.appmodal.on { opacity: 1; }
.appmodal__box {
  position: relative; width: 100%; max-width: 380px;
  padding: 30px 26px 22px; border-radius: 18px; text-align: center;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line), 0 30px 80px rgba(0,0,0,.7);
  transform: translateY(14px) scale(.97); transition: transform .26s cubic-bezier(.2,.8,.2,1);
}
.appmodal.on .appmodal__box { transform: none; }
/* The app tile, shown the size a home screen shows it. It is brand-dark on a
   brand-dark card, so it needs the hairline or it dissolves into the box. */
.appmodal__icon {
  width: 78px; height: 78px; border-radius: 18px; margin: 0 auto 16px;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.12), 0 12px 30px rgba(0,0,0,.55);
}
.appmodal__box h2 {
  font-size: 25px; font-weight: 800; font-style: italic;
  text-transform: uppercase; letter-spacing: -.03em; line-height: 1.05;
}
.appmodal__sub { margin: 12px 0 0; font-size: 13.5px; color: var(--text-2); line-height: 1.6; }

.appmodal__perks { list-style: none; margin: 18px 0 0; padding: 0; text-align: left; }
.appmodal__perks li {
  position: relative; padding: 5px 0 5px 26px;
  font-size: 13.5px; color: var(--text-2);
}
.appmodal__perks li::before {
  content: ''; position: absolute; left: 6px; top: 12px;
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent-500);
}

/* ---- the iPhone, where no site can install anything -------------------
   Two lines, not three, and the Share glyph drawn where the word used to be.
   "Tap the Share button" is a sentence somebody has to turn into a picture
   before they can follow it — so it is the picture. */
.appmodal__ios { position: relative; margin: 18px 0 0; padding: 16px 14px 20px;
  background: var(--bg); border-radius: 10px; text-align: left; }
.ios__line { display: flex; align-items: center; gap: 9px; margin: 0; padding: 7px 0;
  font-size: 14.5px; color: var(--text); line-height: 1.4; }
.ios__line i { flex: none; width: 20px; height: 20px; border-radius: 50%;
  background: var(--accent-500); color: #0d1218; font-style: normal; font-weight: 800;
  font-size: 12px; display: grid; place-items: center; }
.ios__line b { font-weight: 800; }
.ios__glyph { width: 20px; height: 20px; vertical-align: -4px; color: #3b9dff; flex: none; }
/* Pointing at the toolbar the Share button actually sits on, which on an
   iPhone is the bottom of the screen. */
.ios__arrow { position: absolute; left: 50%; bottom: -2px; transform: translateX(-50%);
  color: var(--accent-500); font-size: 15px; animation: iosnudge 1.4s ease-in-out infinite; }
@keyframes iosnudge { 0%, 100% { transform: translate(-50%, 0); opacity: .55; }
                      50% { transform: translate(-50%, 4px); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .ios__arrow { animation: none; } }

/* ---- inside Instagram, TikTok and the rest ----------------------------
   Nothing can be installed from an app's own window. Saying so plainly beats
   three steps that cannot work where they are being read. */
.appmodal__inapp { margin: 18px 0 0; padding: 14px; background: var(--bg);
  border-radius: 10px; text-align: left; font-size: 13.5px; line-height: 1.6;
  color: var(--text-2); }
.appmodal__inapp p { margin: 0 0 9px; }
.appmodal__inapp b { color: var(--text); }
.appmodal__where { color: var(--text); font-weight: 700; }
.appmodal__inapp .btn { margin-top: 4px; }
.appmodal__url { width: 100%; margin-top: 8px; padding: 10px 11px; border: 0;
  border-radius: 8px; background: var(--surface-2); color: var(--text);
  font: inherit; font-size: 13px; }

/* ---- the app reward code ----------------------------------------------
   Shaped like the thing it is. A discount code set as body text is a string
   somebody has to squint at and retype from memory at the checkout two taps
   later, so it gets the lime keyline, the size, and the letter spacing that
   makes O and Q and 8 and B tell themselves apart.

   `user-select: all` is not decoration: the copy button cannot work on every
   browser, and where it fails the fallback is a long-press, which needs the
   whole code to select as one thing rather than word by word. The text-indent
   cancels the trailing letter-space so the code still sits optically centred
   in its box. */
.appmodal__code {
  margin: 18px 0 0; padding: 15px 12px; border-radius: 10px;
  background: var(--bg); box-shadow: inset 0 0 0 1px var(--accent-500);
}
.appmodal__code b {
  display: block; font-size: 30px; line-height: 1.1; font-weight: 800;
  font-style: italic; text-transform: uppercase;
  letter-spacing: .12em; text-indent: .12em; color: var(--accent-500);
  user-select: all; -webkit-user-select: all;
}

/* Numbered, because on any browser that will not install for us these are the
   actual instructions and not decoration. */
.appmodal__steps {
  margin: 18px 0 0; padding: 14px 14px 14px 34px; text-align: left;
  background: var(--bg); border-radius: 10px;
  font-size: 13px; color: var(--text-2); line-height: 1.6;
}
.appmodal__steps li { margin: 3px 0; }

.appmodal .btn { margin-top: 20px; }
.appmodal__later {
  display: block; width: 100%; margin-top: 12px; padding: 8px;
  background: none; border: 0; cursor: pointer;
  font: inherit; font-size: 13px; color: var(--muted);
}
.appmodal__later:hover { color: var(--text-2); }
.appmodal__x {
  position: absolute; top: 8px; right: 10px; width: 34px; height: 34px;
  background: none; border: 0; cursor: pointer;
  font-size: 24px; line-height: 1; color: var(--muted);
}
.appmodal__x:hover { color: var(--text); }

/* Nothing behind a modal should scroll under it. */
body.modal-open { overflow: hidden; }

/* ---------- notched phones ----------
   viewport-fit=cover lets the page paint edge to edge; these insets keep the
   actual content out from under the notch and the home indicator. */
@supports (padding: env(safe-area-inset-left)) {
  .wrap { padding-left: max(24px, env(safe-area-inset-left));
          padding-right: max(24px, env(safe-area-inset-right)); }
  @media (max-width: 620px) {
    .wrap { padding-left: max(16px, env(safe-area-inset-left));
            padding-right: max(16px, env(safe-area-inset-right)); }
  }
  .foot { padding-bottom: env(safe-area-inset-bottom); }
  .chat-launcher { bottom: calc(14px + env(safe-area-inset-bottom)); }
  .chat-panel { bottom: calc(72px + env(safe-area-inset-bottom)); }
}

/* ============================================================
   TOUCH TARGETS
   Small controls that are fine with a mouse are not fine with a
   thumb. On touch devices the dots and icon buttons grow, and the
   dots gain an invisible hit area — kept narrower than the spacing
   between them so neighbouring dots never overlap.
   ============================================================ */
@media (pointer: coarse) {
  .hot__dots, .split__dots { gap: 13px; }
  .hot__dots button, .split__dots button { width: 11px; height: 11px; position: relative; }
  .hot__dots button.on, .split__dots button.on { width: 28px; }
  .hot__dots button::after, .split__dots button::after {
    content: ""; position: absolute; inset: -12px -5px;
  }

  .appmodal__x, .chat__head button, .drawer__head button,
  .mmenu__top button { width: 44px; height: 44px; }
  /* Adjusting the quantity in the bag is done with a thumb, on the move, and
     these were the smallest controls on the busiest screen. */
  .citem__qty button { width: 40px; height: 40px; }
  .citem__qty span { width: 30px; font-size: 14px; }
  /* Remove was an 11px underline 19px tall. Kept visually quiet — it throws
     something away — but made big enough to actually hit. */
  .citem__right button { font-size: 12.5px; padding: 11px 2px; margin-top: 4px; }
  .qty button { width: 48px; }
  .split__arrow { width: 44px; height: 44px; }
  .chat__topics button { padding: 11px 15px; font-size: 13px; }
}

/* ---------- product page on narrow phones ----------
   Grid items default to min-width:auto and refuse to shrink below their
   content, so the Add-to-bag row was forcing the page wider than a 360px
   screen. Let the column shrink, and drop the button onto its own line. */
.pdp > * { min-width: 0; }
@media (max-width: 620px) {
  .pdp__buy { flex-wrap: wrap; }
  .pdp__buy .btn { flex: 1 1 100%; }
  /* ONE ROW ON A PHONE, HOWEVER MANY PHOTOS.

     A grid four across was fine at five photos: two rows. The reversible
     2001 United has ten, which is three rows of thumbnails between the main
     photo and the shirt's own name — the price and the size buttons a whole
     screen down. On a phone the strip now runs sideways instead, the same
     height for five photos or fifty, with a fifth thumbnail cut by the edge
     to say there are more. */
  .gallery__thumbs {
    display: flex; gap: 8px; overflow-x: auto; scroll-snap-type: x mandatory;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
    margin-right: calc(var(--gutter, 16px) * -1); padding-right: var(--gutter, 16px);
  }
  .gallery__thumbs::-webkit-scrollbar { display: none; }
  .gallery__thumbs .thumb { flex: 0 0 22%; scroll-snap-align: start; }
}


/* ============================================================
   COLLAPSIBLE FILTERS (phones and small tablets)
   The rail is hidden behind a Filters button, and each group inside
   is collapsed until tapped, so the product grid starts near the top
   of the screen instead of below a full page of controls.
   ============================================================ */
.filters__toggle { display: none; }

@media (max-width: 900px) {
  .filters__toggle {
    display: inline-flex; align-items: center; gap: 10px; align-self: start;
    height: 46px; padding: 0 18px; border-radius: 4px;
    font-size: 14px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
    color: var(--text); background: var(--surface);
    box-shadow: inset 0 0 0 1px var(--line);
    transition: background .18s, box-shadow .18s;
  }
  .filters__toggle:hover { background: var(--surface-2); }
  .filters__toggle:focus-visible { outline: 2px solid var(--accent-400); outline-offset: 2px; }
  .filters__toggle svg {
    width: 18px; height: 18px; stroke: currentColor; fill: none;
    stroke-width: 2; stroke-linecap: round;
  }
  .filters__toggle[aria-expanded="true"] { background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--surface-3); }
  .filters__n {
    min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px;
    background: var(--accent-500); color: var(--on-accent);
    font-size: 11px; font-weight: 800; line-height: 20px; letter-spacing: 0; text-align: center;
  }

  /* the rail itself */
  .filters { display: none; }
  .filters.on { display: block; margin-top: 6px; }

  /* each group collapses */
  .fgroup { padding: 0; border-bottom: 1px solid var(--line); }
  .fgroup__head {
    min-height: 52px; margin-bottom: 0; padding: 6px 2px; cursor: pointer;
    font-size: 12px;
  }
  .fgroup__head > span:first-child { flex: 1; }
  .fgroup__chev {
    display: block; width: 8px; height: 8px; flex: none; margin-right: 4px;
    border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
    transform: rotate(45deg); transition: transform .2s;
  }
  .fgroup.on .fgroup__chev { transform: rotate(-135deg); }
  .fgroup.has-filter .fgroup__head { color: var(--text); }

  .fgroup__body { display: none; padding: 2px 2px 18px; }
  .fgroup.on .fgroup__body { display: block; }
}

/* ============================================================
   CHECKOUT + MY ORDERS
   Manual payment: the order is recorded here and settled by
   PayPal or bank transfer afterwards, so the job of these two
   pages is to be clear about where a thing has got to.
   ============================================================ */

.co { display: grid; grid-template-columns: 1fr 360px; gap: 34px; align-items: start; padding: 34px 0 70px; }
.co > * { min-width: 0; }
.co__form h2, .co__sum h2 {
  font-size: 12px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase;
  color: var(--text); margin: 26px 0 14px;
}
.co__form h2:first-child, .co__pre + h2 { margin-top: 0; }

.fld { display: block; margin-bottom: 14px; }
.fld > span { display: block; font-size: 12.5px; color: var(--text-2); margin-bottom: 6px; }
.fld > span i { font-style: normal; color: var(--muted); }
.fld input, .fld textarea {
  width: 100%; padding: 12px 13px; border: 0; border-radius: 4px;
  background: var(--surface-2); color: var(--text); font-size: 14.5px;
  font-family: inherit; resize: vertical;
}
.fld input:focus-visible, .fld textarea:focus-visible { outline: 2px solid var(--accent-400); outline-offset: 1px; }

/* iOS Safari zooms the whole page in whenever it focuses a field set under
   16px, and every checkout field was 14.5px. Tapping "Name" lurched the page
   sideways and left the customer pinching back out in the middle of paying.
   16px is the threshold, not a preference, so 16px it is.

   Here rather than up in the phone block on purpose: `.fld input` is more
   specific than a bare `input` and comes later in this file, so the rule has
   to sit beside what it is overriding or it silently loses. It did. */
@media (max-width: 620px) {
  .fld input, .fld textarea, .fld select,
  input, select, textarea { font-size: 16px; }
}
.fld small { display: block; margin-top: 5px; font-size: 11.5px; color: var(--muted); }

.co__note { font-size: 12.5px; color: var(--muted); margin: 4px 0 10px; line-height: 1.6; }
.co__err { color: var(--accent-400); font-size: 13px; min-height: 20px; margin: 6px 0; }
/* The strip at the top of checkout.html?preorder=… saying what this checkout
   is for. */
.co__pre { background: var(--surface); box-shadow: inset 0 0 0 1px var(--accent-500);
  border-radius: 6px; padding: 12px 14px; font-size: 13.5px; line-height: 1.55;
  color: var(--text-2); margin-bottom: 22px; }
.co__pre b { color: var(--text); }
.co__pre a:not(.btn) { color: var(--accent-400); text-decoration: underline; }
.co__test {
  font-size: 11px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: #f0a12b; margin-bottom: 10px;
}

/* PayPal's buttons live in an iframe and cannot be disabled from here, so
   an incomplete form hides them behind a click shield rather than letting
   someone pay before we know where to send it. */
.paypal { position: relative; min-height: 52px; }
.paypal--blocked #paypalButtons { opacity: .35; pointer-events: none; filter: grayscale(1); }
.paypal--busy #paypalButtons { opacity: .5; pointer-events: none; }

/* Says why the buttons are dead, in the colour of something that needs doing
   rather than a grey aside nobody reads. */
.paypal__why {
  font-size: 13px; line-height: 1.5; color: var(--accent-400);
  margin: 0 0 10px; font-weight: 600;
}
/* Invisible, sits over the dead buttons, and exists purely to catch the tap
   so we can say what is wrong. Covers the button area only. */
.paypal__shield {
  position: absolute; left: 0; right: 0; bottom: 0; top: 0;
  background: transparent; border: 0; cursor: pointer;
}
.paypal__shield[hidden] { display: none; }

/* The field that needs fixing, marked while they look at it. */
.fld--bad input, .fld--bad textarea,
input.fld--bad, textarea.fld--bad {
  box-shadow: inset 0 0 0 1.5px var(--accent-500);
}

.co__sum {
  background: var(--surface); border-radius: 6px; padding: 20px;
  box-shadow: inset 0 0 0 1px var(--line); position: sticky; top: calc(var(--nav-h) + 20px);
}
/* Sits at the foot of the details form, divided off so it reads as an aside
   rather than another step of the order. */

/* Payment now lives in the summary panel, under the total. */
.co__payhead { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--line); }

.co__item { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; font-size: 13.5px; color: var(--text-2); }
.co__item small { display: block; color: var(--muted); font-size: 11.5px; margin-top: 2px; }
.co__item b { color: var(--text); white-space: nowrap; }
.co__row { display: flex; justify-content: space-between; padding: 8px 0; font-size: 13.5px; color: var(--text-2); border-top: 1px solid var(--line); }
.co__row b { color: var(--text); }
.co__row--total { font-size: 16px; padding-top: 12px; }

/* The discount code row. Sits under the totals it changes, rather than up with
   the address, because it is part of the money and not part of the delivery. */
.promo { display: flex; gap: 8px; margin-top: 16px; }
.promo input {
  flex: 1; min-width: 0; padding: 11px 12px; border: 0; border-radius: 4px;
  background: var(--surface-2); color: var(--text); font-size: 14px;
  font-family: inherit; text-transform: uppercase; letter-spacing: .08em;
}
.promo input::placeholder { text-transform: none; letter-spacing: 0; }
.promo input:focus-visible { outline: 2px solid var(--accent-400); outline-offset: 1px; }
/* The codes already on this order. They stack — money off and free delivery
   are two different things — so each one sits here with its own way of being
   taken off again. Clearing the box would otherwise take them all. */
.promo__on { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.promo__on:empty { display: none; }
.promo__tag { display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  font-weight: 700; padding: 5px 8px 5px 10px; border-radius: 999px;
  background: var(--surface-2); color: var(--text); }
.promo__tag em { font-style: normal; color: var(--muted); font-weight: 600; }
.promo__tag button { background: none; border: 0; color: var(--muted); font-size: 16px;
  line-height: 1; padding: 0 2px; cursor: pointer; }
.promo__tag button:hover { color: var(--accent-400); }
.promo__msg { font-size: 12.5px; margin-top: 7px; min-height: 1em; color: var(--muted); }
.promo__msg--on { color: var(--accent-400); }
.promo__msg--off { color: #ff8a8a; }
@media (max-width: 620px) {
  .promo input { font-size: 16px; }
}
.co__row--total b { font-size: 19px; }

/* ---- my orders ---- */
.ord__placed {
  background: linear-gradient(135deg, rgba(182,248,35,.16), transparent 60%), var(--surface);
  box-shadow: inset 0 0 0 1px var(--accent-600);
  border-radius: 6px; padding: 22px 24px; margin: 30px 0 26px;
}
.ord__placed h2 { font-size: 20px; margin-bottom: 8px; }
.ord__placed p { font-size: 13.5px; color: var(--text-2); line-height: 1.65; }

.ord { background: var(--surface); border-radius: 6px; box-shadow: inset 0 0 0 1px var(--line); padding: 22px 24px; margin: 30px 0; }
.ord__top { display: flex; justify-content: space-between; gap: 18px; flex-wrap: wrap; align-items: flex-start; }
.ord__top h3 { font-size: 21px; margin-top: 8px; }
.ord__date { font-size: 12.5px; color: var(--muted); margin-top: 5px; }
.ord__total { text-align: right; }
.ord__total span { display: block; font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }
.ord__total b { font-size: 22px; font-style: italic; }

/* Progress trail. The line is drawn behind the markers, so a step is either
   lit or it is not — no half states to misread. */
.trail { list-style: none; display: flex; margin: 24px 0 4px; }
.trail li { flex: 1; position: relative; text-align: center; padding-top: 26px; }
.trail li::before {
  content: ''; position: absolute; top: 8px; left: 0; right: 0; height: 2px; background: var(--line);
}
.trail li:first-child::before { left: 50%; }
.trail li:last-child::before  { right: 50%; }
.trail li.done::before, .trail li.now::before { background: var(--accent-500); }
.trail li.now ~ li::before { background: var(--line); }
.trail li i {
  position: absolute; top: 2px; left: 50%; transform: translateX(-50%);
  width: 14px; height: 14px; border-radius: 50%; background: var(--surface-3);
  box-shadow: inset 0 0 0 2px var(--line);
}
.trail li.done i { background: var(--accent-500); box-shadow: none; }
.trail li.now i  { background: var(--accent-500); box-shadow: 0 0 0 4px rgba(182,248,35,.25); }
.trail li span { font-size: 11px; color: var(--muted); letter-spacing: .04em; }
.trail li.done span, .trail li.now span { color: var(--text); }
.trail--off { padding: 14px 0; }
.trail--off b { display: block; font-size: 15px; color: var(--accent-400); }
.trail--off span { font-size: 12.5px; color: var(--muted); }

.ord__track { margin-top: 16px; font-size: 13.5px; color: var(--text-2); word-break: break-all; }
.ord__items { margin-top: 20px; border-top: 1px solid var(--line); }
.ord__item { display: flex; justify-content: space-between; gap: 12px; padding: 10px 0; font-size: 13.5px; color: var(--text-2); }
.ord__item small { display: block; color: var(--muted); font-size: 11.5px; margin-top: 2px; }
.ord__item b { color: var(--text); white-space: nowrap; }
.ord__foot { border-top: 1px solid var(--line); padding-top: 12px; }
.ord__foot div { display: flex; justify-content: space-between; padding: 4px 0; font-size: 13px; color: var(--muted); }
.ord__foot b { color: var(--text-2); }
.ord__foot-total { font-size: 15px !important; margin-top: 4px; }
.ord__foot-total b { color: var(--text) !important; font-size: 17px; }
.ord__to, .ord__help { margin-top: 14px; font-size: 12.5px; color: var(--muted); line-height: 1.6; }
.ord__help a { color: var(--accent-300); text-decoration: underline; }

.ord__empty, .ord__loading { text-align: center; padding: 50px 20px; color: var(--muted); font-size: 13.5px; }
.ord__empty b { color: var(--text); font-size: 15px; }
.ord__empty p + p { margin-top: 8px; }

.ord__find { background: var(--surface); border-radius: 6px; box-shadow: inset 0 0 0 1px var(--line); padding: 24px; margin-top: 34px; }
.ord__find h2 { font-size: 15px; margin-bottom: 8px; }
.ord__find > p { font-size: 13px; color: var(--muted); line-height: 1.65; margin-bottom: 16px; }
.ord__find-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.ord__find-row > * { min-width: 0; }

@media (max-width: 900px) {
  .co { grid-template-columns: 1fr; gap: 26px; padding-top: 26px; }
  /* The bag panel used to be pulled above the form so a phone showed what was
     being bought first. Now that payment lives in that panel, doing so would
     put the pay buttons before the details they depend on — so the form leads
     and the bag, total and payment follow it, matching the desktop order. */
  .co__sum { position: static; }
  .ord__find-row { grid-template-columns: 1fr; }
  .ord, .ord__find, .ord__placed { padding: 18px 16px; }
  .ord__top h3 { font-size: 18px; }
  /* Five labels will not fit across a phone, so the trail turns vertical. */
  .trail { flex-direction: column; gap: 2px; margin: 20px 0 6px; }
  .trail li { text-align: left; padding: 7px 0 7px 26px; }
  .trail li::before { top: 0; bottom: 0; left: 6px; right: auto; width: 2px; height: auto; }
  .trail li:first-child::before { top: 50%; left: 6px; }
  .trail li:last-child::before { bottom: 50%; top: 0; right: auto; }
  .trail li i { top: 50%; left: 0; transform: translateY(-50%); }
  .trail li span { font-size: 12.5px; }
}

/* ---------- one-photograph split panel ----------
   The photograph runs the full height of the panel, and the panel takes the
   backdrop colour of that photograph — sampled from the image itself in
   index.html, because no fixed value can be right: suppliers shoot on
   different greys, and the jersey sets are far lighter than the Nike ones.
   Get it wrong and the shot reads as a square pasted onto the wrong shade.

   Contain rather than cover. Cover fills the panel with no surround at all,
   which is tidier, but a wide panel cropping a square product shot cuts about
   a ninth off each end — measured against the tee, that takes the collar and
   the hem. A product photograph that clips the product is not worth the
   tidiness.

   This sits at the end of the file, and doubles up the modifier class, because
   the carousel rules further up are more specific than a single class and
   would otherwise win. */
.split__art--fill { padding: 0; background: var(--photo-bg); }
.split__art--fill.split__art .split__slide:has(img.prod) {
  background: none; border-radius: 0;
}
.split__art--fill.split__art .split__slide svg.prod,
.split__art--fill.split__art .split__slide img.prod {
  width: 100%; height: 100%; max-width: none; object-fit: contain;
}

/* Filled panel: the carousel takes the whole tile and the controls sit over
   the shot, so there is no ring of panel colour around a small square. */
.split__art--fill .split__carousel { width: 100%; height: 100%; gap: 0; }
.split__art--fill .split__stage { width: 100%; height: 100%; position: relative; }
.split__art--fill .split__slides {
  max-width: none; width: 100%; height: 100%; aspect-ratio: auto;
}
.split__art--fill .split__arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  background: rgba(12,12,14,.42); color: #fff; box-shadow: none;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.split__art--fill .split__arrow:hover { background: rgba(12,12,14,.68); transform: translateY(-50%); }
.split__art--fill .split__arrow[data-jgo="-1"] { left: 14px; }
.split__art--fill .split__arrow[data-jgo="1"]  { right: 14px; }

/* The hero holds copy only now — the product moved out to its own section, so
   the headline is no longer competing with a carousel for the same space. */
.hero__copy { max-width: 720px; }


/* Brand tiles are ~1000px tall on a phone. Below 900px they move under the
   first product grid so something buyable is reachable sooner. */
@media (max-width: 900px) {
  .homeflow { display: flex; flex-direction: column; }
  .homeflow > #latestDrops { order: 1; }
  .homeflow > .sec:not(#latestDrops) { order: 2; }
}

/* The way out of a payment method the customer has changed their mind about.
   Quiet, but always in the same place under the buttons. */
.paypal__out { font-size: 13px; color: var(--muted); margin: 10px 0 0; }
.paypal__out button {
  color: var(--text); text-decoration: underline; font-size: 13px;
  font-family: inherit; padding: 6px 2px; min-height: 34px;
}
.paypal__out button:hover { color: var(--accent-400); }
.paypal__out[hidden] { display: none; }

/* Sent from a gmail address with no sending history, a first receipt often
   lands in spam. Saying so beats a customer deciding the order failed. */
.ord__spam { font-size: 13px; color: var(--muted); margin-top: 10px; line-height: 1.6; }
.ord__spam b { color: var(--text); }

/* ============================================================
   REVIEWS
   The form a buyer lands on from the review email, and the real
   reviews shown on a product page.
   ============================================================ */
.rv__form { max-width: 640px; margin-top: 34px; }
.rv__intro { color: var(--text-2); margin-bottom: 20px; }
.rv__intro b { color: var(--text); }

/* One button per line of the order. Bigger than a radio because this is the
   first thing a thumb hits on a phone. */
.rv__picks { display: grid; gap: 10px; margin-bottom: 24px; }
.rv__pick {
  text-align: left; padding: 13px 16px; border-radius: 10px; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line); color: var(--text);
  font: inherit; transition: border-color .15s, background .15s;
}
.rv__pick b { display: block; font-size: 14px; }
.rv__pick small { display: block; margin-top: 3px; color: var(--muted); font-size: 12px; }
.rv__pick.on { border-color: var(--accent-500); background: rgba(182,248,35,.08); }

.rv__stars { display: flex; gap: 6px; margin-bottom: 6px; }
.rvstar {
  background: none; border: 0; cursor: pointer; padding: 2px;
  font-size: 34px; line-height: 1; color: #3a3a41; transition: color .12s, transform .12s;
}
.rvstar.on { color: #f0a12b; }
.rvstar:hover { transform: scale(1.12); }

.rv__note { font-size: 12.5px; color: var(--muted); margin: 4px 0 20px; line-height: 1.6; }
.rv__note b { color: var(--text-2); }
.rv__done { max-width: 560px; margin-top: 40px; }
.rv__done h2 { font-size: 26px; font-weight: 800; font-style: italic; text-transform: uppercase; }
.rv__done p { color: var(--text-2); margin: 14px 0 22px; }

/* ---- reviews on a product page ---- */
.revs { margin-top: 34px; }
.revs__head { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin-bottom: 18px; }
.revs__score { font-size: 30px; font-weight: 800; font-style: italic; }
.revs__of { color: var(--muted); font-size: 13px; }
.rev {
  padding: 16px 0; border-top: 1px solid var(--line);
}
.rev__top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.rev__stars { color: #f0a12b; letter-spacing: 1px; font-size: 13px; }
.rev__who { font-size: 12.5px; color: var(--text-2); font-weight: 700; }
.rev__badge {
  font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent-300); border: 1px solid rgba(182,248,35,.4); border-radius: 3px; padding: 2px 6px;
}
/* eBay's mark in eBay's colour, so the source reads at a glance next to the
   lime "Verified buyer" the site's own reviews carry. */
.rev__badge--ebay { color: #f5c542; border-color: rgba(245, 197, 66, .45); }
.rev__item { margin: 10px 0 0; font-size: 12.5px; color: var(--muted); }
.rev__when { font-size: 12px; color: var(--muted); margin-left: auto; }
.rev__title { font-weight: 700; margin: 8px 0 4px; }
.rev__body { color: var(--text-2); font-size: 14px; line-height: 1.65; white-space: pre-line; }
.rev__reply {
  margin-top: 10px; padding: 10px 14px; border-left: 2px solid var(--accent-500);
  background: var(--surface); border-radius: 0 8px 8px 0; font-size: 13.5px; color: var(--text-2);
}
.rev__reply b { color: var(--text); }
.revs__none { color: var(--muted); font-size: 13.5px; }


/* The review button on a shipped order, in "My orders". */
.ord__review { margin-top: 16px; }

/* ============================================================
   REVIEWS PAGE
   ============================================================ */
.revsum {
  display: grid; gap: 26px; align-items: center; margin: 34px 0 26px;
  padding: 24px; border-radius: 14px; background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
}
@media (min-width: 700px) { .revsum { grid-template-columns: 200px 1fr; } }
.revsum__score { text-align: center; }
.revsum__n {
  display: block; font-size: 54px; font-weight: 800; font-style: italic;
  letter-spacing: -.04em; line-height: 1;
}
.revsum__score .rev__stars { font-size: 16px; }
.revsum__of { display: block; margin-top: 6px; font-size: 12.5px; color: var(--muted); }

/* The split across the five stars. An average alone hides whether it is
   everyone saying "fine" or half saying "brilliant" and half "awful". */
.revbar { display: grid; grid-template-columns: 30px 1fr 26px; align-items: center; gap: 10px; margin: 5px 0; }
.revbar span { font-size: 12px; color: var(--muted); }
.revbar i { display: block; height: 7px; border-radius: 4px; background: var(--surface-3); overflow: hidden; }
.revbar i b { display: block; height: 100%; background: #f0a12b; border-radius: 4px; }
.revbar em { font-style: normal; font-size: 12px; color: var(--muted); text-align: right; }

.revchips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 24px; }
.revchip {
  padding: 7px 13px; border-radius: 999px; cursor: pointer; font: inherit; font-size: 12.5px;
  background: var(--surface-2); border: 1px solid transparent; color: var(--text-2);
}
.revchip em { font-style: normal; color: var(--muted); margin-left: 5px; }
.revchip.on { background: var(--accent-500); border-color: var(--accent-500); color: var(--on-accent); }
.revchip.on em { color: rgba(1,21,50,.6); }

.revspage { display: grid; gap: 14px; }
.rev--card {
  padding: 20px; border-top: 0; border-radius: 12px;
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--line);
}

/* The product the review is about, so a good word about something can be
   acted on without going to look for it. */
.rev__prod {
  display: flex; align-items: center; gap: 12px; margin-top: 16px;
  padding-top: 14px; border-top: 1px solid var(--line); text-decoration: none;
}
.rev__prod .prod, .rev__prod svg { width: 52px; height: 52px; border-radius: 8px; flex: none; object-fit: cover; }
.rev__prod b { display: block; font-size: 13.5px; color: var(--text); }
.rev__prod small { display: block; margin-top: 2px; font-size: 12px; color: var(--muted); }
.rev__prod:hover b { color: var(--accent-300); }

/* The hero eyebrow when it is carrying a countdown rather than a season.
   A date is news in a way "Summer / Autumn" is not, so it gets the drip colour
   and a little more weight — enough to read as the headline Jay asked for
   without becoming a second h1 competing with the one underneath it. */
.eyebrow--drop {
  color: var(--accent-300);
  font-weight: 800;
  /* Bigger than the season line it replaces, because it is doing a different
     job. "Summer / Autumn 25.26" is a caption on the h1 underneath; a date is
     the news on the page and has to be read before the h1, not after it.
     Tracking comes in as the size goes up — .28em is set for 11px type and
     falls apart at 17. */
  font-size: clamp(14px, 1.5vw, 17px);
  letter-spacing: .12em;
}
.eyebrow--drop::before {
  content: '';
  display: inline-block;
  width: 7px; height: 7px;
  margin-right: 9px;
  border-radius: 50%;
  background: var(--accent-500);
  vertical-align: middle;
  animation: dropPulse 2.4s ease-in-out infinite;
}
@keyframes dropPulse { 0%, 100% { opacity: 1 } 50% { opacity: .35 } }
@media (prefers-reduced-motion: reduce) {
  .eyebrow--drop::before { animation: none }
}

/* The one blocked-payment reason with a way out. It sits above the shield that
   covers the PayPal buttons, because the shield exists to swallow taps and
   this is the one thing on that panel that is meant to take one. */
#payGetApp {
  position: relative;
  z-index: 3;
  display: block;
  width: 100%;
  margin-top: 12px;
}

/* ============================================================
   MY ACCOUNT — Jersey Points
   ============================================================ */
.acc { max-width: 760px; }
.acc__loading { color: var(--muted); padding: 40px 0; }
.acc__tabs { display: flex; gap: 6px; margin: 30px 0 14px; }
.acc__tabs button {
  flex: 1; padding: 12px; border: 0; border-radius: 4px; cursor: pointer;
  background: var(--surface); color: var(--text-2); font: inherit; font-size: 12px;
  font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  box-shadow: inset 0 0 0 1px var(--line);
}
.acc__tabs button.on { background: var(--surface-2); color: var(--text); box-shadow: inset 0 -2px 0 var(--accent-500); }
.acc__card { background: var(--surface); border-radius: 6px; box-shadow: inset 0 0 0 1px var(--line); padding: 22px 24px; margin-bottom: 18px; }
.acc__card h2 { font-size: 18px; margin-bottom: 8px; }
.acc__card h3 { font-size: 15px; margin-bottom: 6px; }
.acc__lead { font-size: 13.5px; color: var(--text-2); line-height: 1.65; margin-bottom: 18px; }
.acc__small { font-size: 12.5px; color: var(--muted); line-height: 1.6; }
/* One pre-order on the account page. */
.acc__pre { padding: 12px 0; border-bottom: 1px solid var(--line); display: grid; gap: 6px; justify-items: start; }
.acc__pre:first-child { padding-top: 0; }
.acc__pre:last-child { border-bottom: 0; padding-bottom: 0; }
.acc__pre__top { display: flex; justify-content: space-between; gap: 12px; width: 100%; flex-wrap: wrap; }
.acc__pre__top small { color: var(--muted); font-size: 12px; }
.acc__pre__top em { font-style: normal; font-size: 11px; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); }
.acc__pre--confirmed .acc__pre__top em { color: var(--accent-400); }
.acc__pre--paid .acc__pre__top em { color: var(--text-2); }
.acc__pre__x { font-size: 12px; color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.acc__small a, .acc__lead a { color: var(--accent-400); }
.acc__h { font-size: 12px; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; margin: 34px 0 12px; }
.acc__row { display: flex; gap: 10px; flex-wrap: wrap; }

.acc__hero {
  display: grid; grid-template-columns: 1fr auto; gap: 24px; align-items: center;
  margin: 30px 0 0; padding: 26px 28px; border-radius: 6px;
  background: linear-gradient(135deg, rgba(182,248,35,.18), transparent 65%), var(--surface);
  box-shadow: inset 0 0 0 1px var(--accent-600);
}
.acc__pts { display: flex; align-items: baseline; gap: 10px; margin: 6px 0 4px; }
.acc__pts b { font-size: 54px; line-height: 1; font-weight: 900; color: var(--accent-400); letter-spacing: -.02em; }
.acc__pts span { font-size: 13px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--text); }
.acc__worth { font-size: 14px; color: var(--text-2); }
.acc__worth b { color: var(--text); }
.acc__how { font-size: 13px; color: var(--text-2); line-height: 1.8; text-align: right; }
.acc__how b { color: var(--text); }
.acc__how .btn { margin-top: 10px; }

.acc__tasks { display: grid; gap: 10px; }
.acc__task {
  display: grid; grid-template-columns: 64px 1fr auto; gap: 16px; align-items: center;
  background: var(--surface); border-radius: 6px; box-shadow: inset 0 0 0 1px var(--line); padding: 16px 18px;
}
.acc__task-pts { font-size: 20px; font-weight: 900; color: var(--accent-400); text-align: center; }
.acc__task-body b { display: block; font-size: 14.5px; }
.acc__task-body small { display: block; font-size: 12.5px; color: var(--muted); line-height: 1.55; margin-top: 3px; }
.acc__task.is-done { opacity: .6; }
.acc__task.is-done .acc__task-pts { color: var(--muted); }
.acc__done { font-size: 12px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--accent-400); }

.acc__ref { margin-top: 18px; }
.acc__link { display: flex; gap: 8px; margin-top: 12px; }
.acc__link input {
  flex: 1; min-width: 0; padding: 11px 12px; border: 0; border-radius: 4px;
  background: var(--surface-2); color: var(--text); font: inherit; font-size: 13.5px;
}

.acc__led, .acc__order { display: flex; justify-content: space-between; gap: 14px; padding: 11px 0; border-top: 1px solid var(--line); font-size: 13.5px; }
.acc__led:first-child, .acc__order:first-child { border-top: 0; padding-top: 0; }
.acc__led small, .acc__order small { display: block; font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.acc__led b { color: var(--accent-400); white-space: nowrap; }
.acc__led b.neg { color: var(--text-2); }
.acc__order-r { text-align: right; white-space: nowrap; }
.acc__order-r a { display: block; font-size: 12px; color: var(--accent-400); margin-top: 3px; }

@media (max-width: 620px) {
  .acc__hero { grid-template-columns: 1fr; padding: 22px 20px; }
  .acc__how { text-align: left; }
  .acc__pts b { font-size: 46px; }
  .acc__task { grid-template-columns: 48px 1fr; gap: 12px; padding: 14px; }
  .acc__task-go { grid-column: 2; }
  .acc__card { padding: 18px; }
}

/* ---- Jersey Points at checkout and after it ---- */
.pts { margin: 22px 0 6px; padding: 16px 18px; border-radius: 6px;
  background: linear-gradient(135deg, rgba(182,248,35,.12), transparent 70%), var(--surface);
  box-shadow: inset 0 0 0 1px var(--line); }
.pts__head { font-size: 14px; line-height: 1.55; color: var(--text-2); }
.pts__head b { color: var(--accent-400); }
.pts__row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.pts .fld { margin: 12px 0 0; }
.pts .co__err { min-height: 0; }
.pts__use { display: flex; align-items: center; gap: 10px; margin-top: 10px; font-size: 14px; color: var(--text); cursor: pointer; }
.pts__use input { accent-color: var(--accent-500); width: 17px; height: 17px; }
.pts__use small { color: var(--muted); font-size: 12px; }
.ord__placed .ord__pts { margin-top: 14px; padding: 12px 14px; border-radius: 4px; background: var(--surface-2); color: var(--text-2); }

/* ---- the app, asked for after the order ------------------------------
   A row rather than a box with a heading: it sits under a confirmation that
   is already the loudest thing on the page, and it is an offer, not news. */
.ord__app {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin: 16px 0 0; padding: 14px 16px; border-radius: 14px;
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--line);
}
.ord__appicon { width: 46px; height: 46px; border-radius: 11px; flex: none;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.12); }
.ord__appsay { flex: 1 1 190px; min-width: 0; }
.ord__appsay b { display: block; font-size: 14.5px; }
.ord__appsay span { display: block; margin-top: 3px; font-size: 12.5px;
  color: var(--text-2); line-height: 1.5; }
.ord__app .btn { flex: none; }
@media (max-width: 420px) { .ord__app .btn { width: 100%; } }
.ord__placed .ord__pts b { color: var(--accent-400); }
.ord__placed .ord__pts a { color: var(--accent-400); font-weight: 700; white-space: nowrap; }
.rv__pts { margin: 12px 0 16px; font-size: 14px; color: var(--text-2); }
.rv__pts b { color: var(--accent-400); }
.rv__pts a { color: var(--accent-400); font-weight: 700; }

/* ---- Members price ---- */
.acc__mem { margin-top: 8px; font-size: 13px; color: var(--text-2); }
.acc__mem b { color: var(--accent-400); }
.mem { margin: 16px 0 6px; padding: 16px 18px; border-radius: 6px;
  background: linear-gradient(135deg, rgba(182,248,35,.14), transparent 70%), var(--surface-2);
  box-shadow: inset 0 0 0 1px var(--accent-600); }
.mem__row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  font-size: 14px; color: var(--text-2); padding: 3px 0; }
.mem__row b { font-size: 15px; color: var(--text); }
.mem__row--lock span { color: var(--text); font-weight: 700; }
.mem__row--lock b { font-size: 22px; font-weight: 900; color: var(--accent-400); }
.mem__row--lock i { font-style: normal; margin-right: 4px; }
.mem__save { margin: 4px 0 0; font-size: 12.5px; color: var(--muted); }
/* Under the button, not above it: the reassurance is for somebody whose
   thumb is already over the button and who is wondering what it costs them. */
.mem__small { margin: 8px 0 0; font-size: 12px; color: var(--muted); text-align: center; }
.mem .btn { margin-top: 12px; }
.mem--on { padding: 12px 16px; }
.mem__on { margin: 0; font-size: 13.5px; color: var(--text-2); }
.mem__on b { color: var(--accent-400); }
.mem__perks li { padding-left: 2px; font-size: 14px; color: var(--text); }
.mem__perks li::before { display: none; }
.mem__step { margin: 18px 0 0; font-size: 12.5px; color: var(--muted); text-align: left; }
.mem__step b { color: var(--accent-400); }
.mem__form { margin-top: 12px; text-align: left; }
.mem__form .fld { margin-bottom: 10px; }
.mem__form .co__err { min-height: 0; }
#unlock .appmodal__box { max-height: calc(100vh - 40px); overflow-y: auto; }
#unlock .ios__line span b, #unlock .appmodal__steps b { color: var(--text); }
#unlock .appmodal__box h2 { font-size: 22px; padding: 0 22px; }
.mem__head { margin: 0; font-size: 14.5px; color: var(--text); line-height: 1.5; }
.mem__head b { color: var(--accent-400); }
.mem__list { list-style: none; margin: 10px 0 0; padding: 0; font-size: 13.5px; color: var(--text-2); line-height: 1.9; }
.mem .mem__on + .mem__head { margin-top: 12px; }
.mem .appmodal__later { margin-top: 6px; }

/* ============================================================
   £10 SATURDAYS
   The bolt is the mark from the business card. It carries the lime, so
   nothing else in these blocks needs to shout.
   ============================================================ */

/* ---- the home hero ---- */
.hero__copy--sat .hero__sub { max-width: 30ch; }
/* The vote's hero, which is the Saturday one with a different mark. The team
   name in the headline can be long — "Manchester United Won It" — so it is
   allowed to wrap where the £10 one never has to. */
.hero__copy--wk .hero__sub { max-width: 34ch; }
.hero__copy--wk .hero__bolt { color: var(--accent-500); }
.hero__copy--wk .hero__sat { word-break: normal; overflow-wrap: anywhere; }
/* The flame, sized down and lifted off the baseline.

   A colour emoji ignores font-weight, italics and colour — it renders at its
   own size in its own palette — so at the headline's 62px it arrives larger
   and heavier than the word it is decorating. Two thirds of an em puts it at
   the weight of a mark beside the text rather than a third line of it. */
.hero__fire {
  display: inline-block; margin-left: .18em; font-size: .62em;
  line-height: 1; vertical-align: .34em; font-style: normal;
}

/* The vote's band under the hero. The £10 rail's spacing, without the rail:
   a ballot is a stack, not a row that runs off the edge. */
.wkband .wk__ballot { margin-top: 14px; }
.wkband .wk__tally { margin-top: 12px; }
/* The £10 band's heading is three words and is told never to wrap. This one
   is a sentence — "Vote for the team whose shirt drops Thursday" — because
   naming the thing was not enough; it has to say what to do with it. So the
   nowrap comes off here, and the head lays out as a wrapping row. */
.wkband .satband__head { align-items: center; }
.wkband .satband__tag { flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.wkband .satband__tag b { white-space: normal; font-size: 15px; line-height: 1.25; }
@media (max-width: 520px) {
  /* At phone width the sentence fills the row and pushes "See all" onto a
     line of its own, floating right of nothing. It goes under, left-aligned
     with everything else. The margin-left has to beat `.satband .link-arrow`,
     which sets it to auto — hence the longer selector. */
  .wkband .satband__head { flex-direction: column; align-items: flex-start; gap: 8px; }
  .wkband .satband__head .link-arrow { margin-left: 0; align-self: flex-start; }
}
.hero__bolt {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 13px; border-radius: 999px; text-decoration: none;
  background: rgba(182,248,35,.14); color: var(--accent-500);
  box-shadow: inset 0 0 0 1px rgba(182,248,35,.4);
  font-size: 12px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
}
.hero__bolt span { font-size: 15px; line-height: 1; }
.hero__bolt:hover { background: rgba(182,248,35,.22); }
/* The number is the headline, so it is set as big as the column allows and
   trimmed by the viewport rather than by a fixed size. */
.hero__sat {
  margin-top: 16px; font-size: clamp(54px, 13vw, 118px); line-height: .88;
  letter-spacing: -.045em;
}
.hero__sat em { color: var(--accent-500); font-style: italic; }

.hero__count {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin: 16px 0 0; padding: 11px 15px; border-radius: 14px;
  background: rgba(2,12,30,.55); backdrop-filter: blur(4px);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.14); width: fit-content;
}
.hc__lab { font-size: 11px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); }
.hc__clock { display: flex; gap: 10px; }
.hc__u { display: flex; flex-direction: column; align-items: center; min-width: 40px; }
/* Tabular figures: without them the whole row jiggles sideways every second
   as the digits change width, which is the sort of thing that reads as a
   page still loading. */
.hc__u b { font-size: 25px; line-height: 1; font-weight: 800; color: #fff;
  font-variant-numeric: tabular-nums; }
.hc__u em { margin-top: 4px; font-style: normal; font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); }

/* ---- the page ---- */
.sat__head { position: relative; padding: 34px 0 30px; overflow: hidden;
  background: linear-gradient(160deg, #06224a, var(--bg) 62%); }
.sat__h1 { margin-top: 14px; font-size: clamp(34px, 9vw, 62px); line-height: .95;
  letter-spacing: -.035em; }
.sat__bolt { color: var(--accent-500); }
.sat__sub { margin-top: 12px; max-width: 52ch; color: var(--text-2); line-height: 1.6; }

.sat__count { margin-top: 22px; padding: 16px 18px; border-radius: 16px;
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); width: fit-content; }
.sat__countlab { margin: 0; font-size: 11px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); }
.sat__clock { display: flex; gap: 14px; margin-top: 10px; }
.sat__unit { display: flex; flex-direction: column; align-items: center; min-width: 48px; }
.sat__unit b { font-size: 32px; line-height: 1; font-weight: 800; color: var(--accent-500);
  font-variant-numeric: tabular-nums; }
.sat__unit em { margin-top: 5px; font-style: normal; font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); }
.sat__when { margin: 10px 0 0; font-size: 12.5px; color: var(--text-2); }

.sat__lock { margin: 22px 0 6px; padding: 16px 18px; border-radius: 14px;
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--accent-500); }
.sat__lock p { margin: 0 0 12px; font-size: 13.5px; line-height: 1.6; color: var(--text-2); }
.sat__lock b { color: var(--text); }
.sat__none { margin: 34px 0 0; text-align: center; color: var(--text-2); line-height: 1.7; }

/* The bolt on the locked sheet, sized to carry the box on its own. */
.drop__bolt { margin: 0 0 6px; font-size: 44px; line-height: 1; text-align: center; }

/* ---- the picker on the admin page ---- */
/* Taller, and made to look like a thing that scrolls.

   At 340px this showed seven rows of seventy-five with no visible scrollbar,
   which on a phone is indistinguishable from a list that ends. The height is
   up, the box has a border so its bottom edge reads as a cut rather than an
   end, and the scrollbar is asked for explicitly instead of being left to the
   platform to hide. */
.sat__pick { display: grid; gap: 8px; margin-top: 8px;
  max-height: 60vh; min-height: 260px; overflow-y: auto; overscroll-behavior: contain;
  padding: 8px; border: 1px solid var(--line); border-radius: 12px;
  scrollbar-width: thin; scrollbar-color: var(--accent-500) transparent; }
.sat__pick::-webkit-scrollbar { width: 8px; }
.sat__pick::-webkit-scrollbar-thumb { background: var(--accent-500); border-radius: 999px; }
.sat__pick::-webkit-scrollbar-track { background: transparent; }
.sat__row { display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border-radius: 10px; background: var(--bg); font-size: 13px; }
.sat__row input { width: 18px; height: 18px; flex: none; accent-color: var(--accent-500); }
.sat__row span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.sat__row em { font-style: normal; color: var(--muted); font-size: 12px; }
.sat__row--on { box-shadow: inset 0 0 0 1px var(--accent-500); }
/* Only ever a shirt already in the drop that has sold out since. It is here
   to be unticked, so it is dimmed rather than removed — and its price is
   replaced by the reason, since what it costs has stopped mattering. */
.sat__row--gone { opacity: .55; }
.sat__row--gone em { font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; font-size: 10.5px; }

/* The bolt itself. One shape, used in the nav, on the hero, on the page and
   on the locked sheet, taking its colour from whatever it sits in. */
.bolt { width: 1em; height: 1em; flex: none; vertical-align: -.12em; }
.nav__toplink--bolt, .mmenu__bolt { color: var(--accent-500); }
.nav__toplink--bolt .bolt, .mmenu__bolt .bolt { margin-right: 5px; }
/* The flame in the nav. A colour emoji, so it takes no colour from the link
   and needs its own spacing — `.bolt` is the SVG's class and does not apply. */
.nav__fire { margin-right: 5px; font-size: .95em; }
.sat__bolt { display: inline-block; width: .82em; margin-right: .22em; color: var(--accent-500); }
.sat__bolt .bolt { width: 100%; height: auto; }
.hero__bolt .bolt { width: 13px; height: 15px; }
.drop__bolt { color: var(--accent-500); }
.drop__bolt .bolt { width: 42px; height: 46px; }

/* ---- £10 Saturdays: the live state ------------------------------------
   Lime, and a dot that pulses, because "now live" has to look different
   from a countdown at a glance rather than on a second read. */
.hero__count--live { box-shadow: inset 0 0 0 1px rgba(182,248,35,.5); }
.hc__now { display: inline-flex; align-items: center; gap: 8px;
  font-size: 19px; font-weight: 800; font-style: italic; text-transform: uppercase;
  letter-spacing: -.02em; color: var(--accent-500); }
.hc__now i { width: 9px; height: 9px; border-radius: 50%; background: var(--accent-500);
  animation: satpulse 1.6s ease-in-out infinite; }
.hc__until { font-size: 12px; color: var(--muted); }

.sat__count--live { box-shadow: inset 0 0 0 1px var(--accent-500); }
.sat__count--live .sat__countlab { display: flex; align-items: center; gap: 8px;
  color: var(--accent-500); }
.sat__dot { width: 9px; height: 9px; border-radius: 50%; background: var(--accent-500);
  animation: satpulse 1.6s ease-in-out infinite; }
@keyframes satpulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) {
  .hc__now i, .sat__dot { animation: none; }
}

/* What the shirts below are: this week's, or last week's still at £10. */
.sat__state { margin: 20px 0 14px; padding: 11px 14px; border-radius: 10px;
  background: var(--surface); font-size: 13px; color: var(--text-2); line-height: 1.55; }
.sat__state b { color: var(--text); }
.sat__state--live { box-shadow: inset 0 0 0 1px rgba(182,248,35,.45); }
.sat__state--live b { color: var(--accent-500); }

/* ============================================================
   WEEKLY EXCLUSIVES — the ballot and the reveal.

   Built out of the £10 Saturdays page's parts on purpose: the same head, the
   same countdown, the same state line. They are two halves of one weekly
   rhythm and a customer moving between them on a Thursday should feel one
   shop, not two microsites.

   What is new is the ballot. Everything else here is a variation.
   ============================================================ */

/* The head is the Saturday page's, turned the other way round the colour
   wheel so the two are told apart at a glance without a second palette. */
.wk__head { background: linear-gradient(160deg, #123a2a, var(--bg) 62%); }
/* And the flash sale's, warm where the other two are cool — it is the one of
   the three that is about a price rather than a date. */
.fl__head { background: linear-gradient(160deg, #4a1e12, var(--bg) 64%); }
.fl__fire { display: inline-block; margin-right: .22em; font-size: .82em;
  vertical-align: .04em; }
.fl__count { margin-top: 18px; padding: 11px 16px; border-radius: 999px;
  width: fit-content; background: var(--surface);
  box-shadow: inset 0 0 0 1px rgba(255, 120, 60, .45);
  font-size: 13px; color: var(--text-2); }
.fl__count b { color: var(--text); font-weight: 800; }

/* ---- how it works, in three ----

   Jay: "i need it made explicitly clear on the homepage what theyre voting
   for." Three steps sitting directly on top of the ballot, because an
   explanation two screens up in the hero is read once and forgotten before
   the reader reaches the thing it explained.

   A row on a phone, not a stack: three short steps down the page take the
   ballot below the fold, and the whole point is that both are seen at once. */
.wkhow {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
  margin: 16px 0 0; padding: 0; list-style: none; counter-reset: none;
}
.wkhow li {
  display: flex; flex-direction: column; gap: 7px; padding: 12px 12px 13px;
  border-radius: 12px; background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
}
.wkhow b {
  display: grid; place-items: center; width: 21px; height: 21px; border-radius: 50%;
  background: var(--accent-500); color: var(--on-accent);
  font-size: 11.5px; font-weight: 800;
}
.wkhow span { font-size: 12.5px; line-height: 1.35; color: var(--text-2); }
.wkhow em { font-style: normal; font-weight: 800; color: var(--accent-500); }
@media (max-width: 420px) {
  /* Three across at 375px gives each step about 105px, which is enough for
     "Most votes wins" on two lines and not for the third. The third is the
     one carrying the price, so it takes the full width underneath rather
     than being squeezed. */
  .wkhow { grid-template-columns: 1fr 1fr; }
  .wkhow li:last-child { grid-column: 1 / -1; flex-direction: row; align-items: center; gap: 10px; }
}

/* "Voting live", with the same pulsing dot the £10 band wears on a Saturday.
   One mark for "this is happening now", used in both places. */
.wkband__live {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  padding: 4px 10px; border-radius: 999px;
  background: rgba(182, 248, 35, .14); box-shadow: inset 0 0 0 1px rgba(182, 248, 35, .45);
  color: var(--accent-500);
  font-size: 10.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
}
.wkband__live i {
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent-500);
  animation: satpulse 1.6s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) { .wkband__live i { animation: none; } }

.wk__ballot { display: grid; gap: 10px; margin-top: 18px; }

/* ONE ROW IS THREE THINGS AT ONCE: a button, a bar chart and a result.

   The bar is a sibling behind the text rather than a background on the
   button, because a background cannot be a percentage of the row's width
   and animate to a new one while the text stays put. */
.wk__opt {
  position: relative; display: block; width: 100%; padding: 0; overflow: hidden;
  border: 0; border-radius: 14px; background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
  font: inherit; text-align: left; cursor: pointer;
  transition: box-shadow .18s ease, transform .12s ease;
}
.wk__opt:hover:not(:disabled) { box-shadow: inset 0 0 0 1px var(--accent-500); }
.wk__opt:active:not(:disabled) { transform: scale(.995); }
.wk__opt:focus-visible { outline: 2px solid var(--accent-400); outline-offset: 2px; }
/* Voted already: the rows stop being buttons but stay perfectly readable.
   Dimming them would hide the result, which is the thing people come back
   to look at. */
.wk__opt:disabled { cursor: default; }

/* THE BAR NEEDS AN END, NOT JUST A FILL.

   A lime wash fading out over navy reads as olive and its right-hand edge is
   guesswork — which defeats the point, because the length IS the result. A
   solid two-pixel edge in the accent colour gives it a definite stop, and the
   fill behind it can then be quiet enough to keep the team name readable. */
.wk__opt__bar {
  position: absolute; inset: 0 auto 0 0; z-index: 0;
  background: linear-gradient(90deg, rgba(182, 248, 35, .20), rgba(182, 248, 35, .09));
  border-right: 2px solid var(--accent-500);
  transition: width .45s cubic-bezier(.22, .61, .36, 1);
}
/* Nothing to draw an edge on at zero votes — a 2px lime line down the left of
   every row would read as four teams tied at nothing rather than none. */
.wk__opt__bar[style*="width:0%"] { border-right: 0; }
.wk__opt--mine { box-shadow: inset 0 0 0 2px var(--accent-500); }
.wk__opt--mine .wk__opt__bar {
  background: linear-gradient(90deg, rgba(182, 248, 35, .42), rgba(182, 248, 35, .18));
}

/* One row now the raw count has gone. The count used to sit under the team
   name in a second row, which is why this was a two-row grid — see
   weeklyShare in site.js for why it is not published any more. */
.wk__opt__face {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: 12px; padding: 17px 16px;
}
.wk__opt__dot { width: 13px; height: 13px; border-radius: 50%;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, .18); }
.wk__opt__face b { font-size: 16px; font-weight: 800; letter-spacing: -.01em; }
.wk__opt__face em { font-style: normal; font-size: 19px; font-weight: 800;
  color: var(--accent-500); font-variant-numeric: tabular-nums; }

.wk__tally { margin: 16px 0 0; font-size: 13px; color: var(--text-2); }
.wk__tally b { color: var(--text); }
.wk__done { display: inline-block; margin-left: 8px; padding: 3px 10px; border-radius: 999px;
  background: var(--accent-500); color: var(--on-accent);
  font-size: 11px; font-weight: 800; letter-spacing: .04em; }

/* ---- the shirt that won ---- */

.wk__won { margin-top: 20px; padding: 22px 20px; border-radius: 18px; text-align: center;
  background: linear-gradient(150deg, rgba(182,248,35,.16), var(--surface) 70%);
  box-shadow: inset 0 0 0 1px rgba(182,248,35,.4); }
.wk__won__tag { display: inline-block; padding: 5px 12px; border-radius: 999px;
  background: var(--accent-500); color: var(--on-accent);
  font-size: 11px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.wk__won__team { margin: 14px 0 0; font-size: clamp(30px, 8vw, 50px); line-height: 1;
  letter-spacing: -.03em; }
.wk__won__sub { margin: 12px auto 0; max-width: 46ch; font-size: 13.5px; line-height: 1.6;
  color: var(--text-2); }
.wk__won__sub b { color: var(--accent-500); }

/* One shirt in a three-column grid would sit in the left third looking like
   two had failed to load, so the winner's tile is centred and held to a
   sensible width instead of stretching across the page. */
/* One column, centred, rather than the auto-fill the grid normally uses —
   with auto-fill a single tile sits in the left third of the page looking
   like two more had failed to load. */
.wk__wongrid { margin-top: 20px; grid-template-columns: minmax(0, 340px);
  justify-content: center; }

@media (prefers-reduced-motion: reduce) {
  .wk__opt, .wk__opt__bar { transition: none; }
}

/* ============================================================
   THIS WEEK'S £10 SHIRTS, DIRECTLY UNDER THE HERO
   ============================================================ */
.satband {
  padding: 22px 0 26px;
  background: linear-gradient(180deg, rgba(182,248,35,.07), transparent 70%), var(--bg);
  border-bottom: 1px solid var(--line);
}
.satband__head { display: flex; align-items: baseline; flex-wrap: wrap;
  gap: 4px 12px; margin-bottom: 14px; }
.satband__tag { display: inline-flex; align-items: baseline; gap: 8px; min-width: 0;
  font-size: 14px; }
.satband__tag .bolt { width: 15px; height: 15px; flex: none; color: var(--accent-500);
  align-self: center; }
.satband__tag b { color: var(--accent-500); font-weight: 800; letter-spacing: -.01em;
  white-space: nowrap; }
/* The clock, quieter than the claim and free to wrap under it on a narrow
   screen rather than dragging the whole line into three. */
.satband__tag em { font-style: normal; font-size: 13px; color: var(--muted);
  white-space: nowrap; }
.satband .link-arrow { margin-left: auto; flex: none; }

/* A rail, not a grid. Three tiles across is a wall on a phone; a row that
   runs off the edge says there is more without a heading having to say so.
   Scroll-snap so it stops on a shirt rather than halfway between two. */
.rail {
  display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory;
  /* The negative margin lets the rail bleed to the screen edges while its own
     padding keeps the first tile lined up with everything else on the page.
     The gutter is inherited from .wrap rather than repeated, so the rail
     cannot drift out of line with the page when that changes — which it does
     at 16px on a narrow phone.

     scroll-padding is not optional here. Without it the snap point sits at
     the rail's content edge and the browser scrolls the padding away on
     load, which puts the first shirt half off the screen before anybody has
     touched it. */
  --rail-gutter: 24px;
  margin: 0 calc(var(--rail-gutter) * -1);
  padding: 2px var(--rail-gutter) 6px;
  scroll-padding-inline: var(--rail-gutter);
  scrollbar-width: none;
}
@media (max-width: 720px) { .rail { --rail-gutter: 16px; } }
.rail::-webkit-scrollbar { display: none; }
.rail__item { position: relative; flex: 0 0 63%; max-width: 250px; scroll-snap-align: start; }
@media (min-width: 640px) { .rail__item { flex-basis: 30%; } }
@media (min-width: 900px) { .rail__item { flex-basis: 23%; } }
.rail__item .card { height: 100%; }

/* ---- telling people the rail scrolls ----

   The scrollbar is hidden on purpose a few rules up, which is right on a
   desktop and wrong on a phone: there is then no indication at all that the
   row continues past the edge, and people stop at what they can see.

   The bar is the positional half. Its thumb is as wide a share of the track
   as the visible rail is of the whole rail, so a drop of three barely moves
   and a drop of eight has a short thumb with a long way to travel — the
   length itself says how much more there is.

   The word is the instructional half, and it is deliberately the one that
   leaves. It is there for somebody who has not worked out that the row
   moves; once they have, repeating it is clutter, so the first real swipe
   fades it and the bar carries on alone. */
.rail__nav { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.rail__bar {
  flex: 1 1 auto; min-width: 0; height: 3px; border-radius: 999px;
  background: rgba(255, 255, 255, .15);
}
.rail__bar i {
  display: block; height: 100%; width: 30%; margin-left: 0;
  border-radius: inherit; background: var(--accent-500);
  transition: margin-left .1s linear, width .1s linear;
}
.rail__hint {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--accent-500); transition: opacity .3s ease;
}
.rail__hint svg { width: 14px; height: 14px; flex: none; }
/* Gone, but still holding its width — the bar must not lurch sideways at the
   exact moment somebody is dragging it. */
.rail__hint--gone { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .rail__bar i, .rail__hint { transition: none; }
}

/* What it will be on Saturday, on the tile, while the real price is still the
   one being charged underneath. */
/* On the shirt, top right, opposite the NEW flag. It sat under the price at
   first, where it crowded the colour swatch and read as part of the price
   rather than as a thing about Saturday. */
.rail__soon {
  position: absolute; right: 10px; top: 12px; z-index: 2;
  padding: 5px 9px; border-radius: 999px;
  background: var(--accent-500); color: #06131f;
  font-size: 10.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
  box-shadow: 0 4px 14px rgba(0,0,0,.35);
  pointer-events: none;
}

/* ---- the hero's trust line ---- */
/* On a phone the returns promise is already in the strip at the very top of
   the screen, and saying it twice cost the line a wrap that left "returns"
   on its own. */
@media (max-width: 480px) { .hero__trust-ret { display: none; } }
.hero__trust {
  margin: 18px 0 0; padding-top: 14px; border-top: 1px solid rgba(255,255,255,.14);
  font-size: 13px; color: var(--muted); letter-spacing: .01em;
}
.hero__trust b { color: #fff; font-weight: 800; }
.hero__trust i { margin: 0 8px; font-style: normal; opacity: .5; }
.hero__star { color: var(--accent-500); }
