/* ============================================================
   BRAND TOKENS — change the vibe here, nothing below
   ============================================================ */
:root {
  --bg:        #000000;   /* page background */
  --text:      #ffffff;   /* main text */
  --text-dim:  #8b8b8b;   /* secondary text */
  --red:       #D70303;   /* brand red, sampled from the logo */
  --line:      rgba(255,255,255,0.35);  /* input underline */
  --error:     #ff5252;

  --font: "Helvetica Neue", Helvetica, Arial, sans-serif;

  --logo-h: 35vh;      /* how tall the 3D logo sits */
  --glow: 0.32;       /* red atmosphere behind the logo, 0 = off */
  --grain: 0.38;       /* film grain strength, 0 = off */
  --grain-fps: 0.32s;   /* one cycle of 4 grain frames — lower = more frantic */
  --grain-scale: 180px; /* speck size — bigger = coarser, softer, more "zoomed in" */
}
@media (min-width: 700px) {
  :root { --logo-h: 42vh; }
}

/* ============================================================ */
*, *::before, *::after { margin:0; padding:0; box-sizing:border-box; }
html, body { height:100%; }
/* page colour lives on <html> so the grain layer (z-index:-1 on body) paints
   above it — if it sat on <body> it would cover the grain */
html { background: var(--bg); }

body {
  background: transparent;
  color: var(--text);
  font-family: var(--font);
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;   /* logo sits high, so the form lands near centre */
  gap: clamp(12px, 2.2vh, 24px);
  padding: 10vh 22px calc(28px + env(safe-area-inset-bottom));
  text-align: center;
  position: relative;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* ---------- film grain over everything ----------
   Four different noise fields cycled on hard steps, so the grain is REGENERATED
   each frame rather than a single texture sliding around — that sliding is what
   makes cheap grain look like a moving sheet you can follow with your eye.
   --grain-fps controls how frantic it is; --grain sets how much shows through. */
body::after {
  --n1: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncR type='linear' slope='0.38'/><feFuncG type='linear' slope='0.38'/><feFuncB type='linear' slope='0.38'/><feFuncA type='linear' slope='8' intercept='-4.9'/></feComponentTransfer></filter><rect width='300' height='300' filter='url(%23n)'/></svg>");
  --n2: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='17' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncR type='linear' slope='0.38'/><feFuncG type='linear' slope='0.38'/><feFuncB type='linear' slope='0.38'/><feFuncA type='linear' slope='8' intercept='-4.9'/></feComponentTransfer></filter><rect width='300' height='300' filter='url(%23n)'/></svg>");
  --n3: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='41' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncR type='linear' slope='0.38'/><feFuncG type='linear' slope='0.38'/><feFuncB type='linear' slope='0.38'/><feFuncA type='linear' slope='8' intercept='-4.9'/></feComponentTransfer></filter><rect width='300' height='300' filter='url(%23n)'/></svg>");
  --n4: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='73' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncR type='linear' slope='0.38'/><feFuncG type='linear' slope='0.38'/><feFuncB type='linear' slope='0.38'/><feFuncA type='linear' slope='8' intercept='-4.9'/></feComponentTransfer></filter><rect width='300' height='300' filter='url(%23n)'/></svg>");
  --n5: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='91' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncR type='linear' slope='0.38'/><feFuncG type='linear' slope='0.38'/><feFuncB type='linear' slope='0.38'/><feFuncA type='linear' slope='8' intercept='-4.9'/></feComponentTransfer></filter><rect width='300' height='300' filter='url(%23n)'/></svg>");
  --n6: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='113' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncR type='linear' slope='0.38'/><feFuncG type='linear' slope='0.38'/><feFuncB type='linear' slope='0.38'/><feFuncA type='linear' slope='8' intercept='-4.9'/></feComponentTransfer></filter><rect width='300' height='300' filter='url(%23n)'/></svg>");
  --n7: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='137' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncR type='linear' slope='0.38'/><feFuncG type='linear' slope='0.38'/><feFuncB type='linear' slope='0.38'/><feFuncA type='linear' slope='8' intercept='-4.9'/></feComponentTransfer></filter><rect width='300' height='300' filter='url(%23n)'/></svg>");
  --n8: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='163' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncR type='linear' slope='0.38'/><feFuncG type='linear' slope='0.38'/><feFuncB type='linear' slope='0.38'/><feFuncA type='linear' slope='8' intercept='-4.9'/></feComponentTransfer></filter><rect width='300' height='300' filter='url(%23n)'/></svg>");

  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  /* behind the logo and text, so grain textures the background only and never
     dirties the artwork or muddies the type */
  z-index: -1;
  opacity: var(--grain);
  background-image: var(--n1);
  background-repeat: repeat;
  /* scales each noise tile up so the specks are bigger and more spread out —
     mimics the softer look of a zoomed-in browser. Raise for chunkier grain. */
  background-size: var(--grain-scale) var(--grain-scale);
  animation: grain var(--grain-fps) steps(1) infinite;
}
@keyframes grain {
  0% { background-image: var(--n1); }
  12.5% { background-image: var(--n2); }
  25% { background-image: var(--n3); }
  37.5% { background-image: var(--n4); }
  50% { background-image: var(--n5); }
  62.5% { background-image: var(--n6); }
  75% { background-image: var(--n7); }
  87.5% { background-image: var(--n8); }
}

/* ---------- 3D logo ---------- */
.stage {
  position: relative;
  height: var(--logo-h);
  width: 100%;
  max-width: 720px;
  flex-shrink: 0;
  /* The glow below is bigger than this box and, being positioned, paints over
     the form underneath — without this it swallows clicks on the name field. */
  pointer-events: none;
}
.stage::before {   /* red atmosphere, drawn behind the canvas */
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 68vmin; height: 68vmin;
  margin: -34vmin 0 0 -34vmin;
  border-radius: 50%;
  /* the outer stop tracks --glow too, so one value dims the whole halo */
  background: radial-gradient(circle, rgba(215,3,3,var(--glow)) 0%, rgba(215,3,3,calc(var(--glow) * 0.33)) 42%, transparent 68%);
  filter: blur(14px);
  animation: pulse 6s ease-in-out infinite;
}
@keyframes pulse {
  0%,100% { opacity: 0.75; transform: scale(0.97); }
  50%     { opacity: 1;    transform: scale(1.05); }
}
.stage canvas, .stage svg {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
}

/* ---------- copy ---------- */
.tagline {
  font-size: clamp(0.7rem, 3vw, 0.82rem);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--text-dim);
  line-height: 1.9;
}
.tagline b { color: var(--text); font-weight: 700; font-size: 1.22em; }

/* sits below the fields — no longer inherits from .tagline, so it's styled here */
.sub {
  /* claws back the invisible error slot inside the form, so the gap here
     matches the 18px rhythm between the logo, tagline and fields */
  margin-top: -28px;
  font-size: clamp(0.59rem, 2.5vw, 0.69rem);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--text-dim);
  line-height: 1.9;
}

/* the real wordmark, drawn inline in the sentence instead of typed letters */
.wordmark {
  display: inline-block;
  height: 2.5em;          /* sized against the surrounding text */
  vertical-align: -0.92em;
  color: var(--red);
  margin-right: 0.12em;
}
.wordmark svg { height: 100%; width: auto; display: block; overflow: visible; }

/* ---------- form ---------- */
form {
  width: 100%;
  max-width: 400px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* name and contact share one row: a short line, then the long one */
.row {
  display: flex;
  align-items: stretch;
  gap: 12px;
}
.field {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--line);
  transition: border-color 0.2s ease;
  /* without this a flex item refuses to shrink below the input's default
     intrinsic width (~175px), which blows the row apart */
  min-width: 0;
}
.field:focus-within { border-bottom-color: var(--text); }
.field-name    { flex: 0 0 29%; }
.field-contact { flex: 1 1 auto; }

.field input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: 0;
  outline: 0;
  color: var(--text);
  font-family: var(--font);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 14px 2px;
  text-align: left;    /* two fields side by side read better left-aligned */
}
input::placeholder {
  color: var(--text-dim);
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  font-size: 0.72rem;
}

.enter {
  background: var(--text);
  color: #000;
  border: 0;
  font-family: var(--font);
  font-weight: 800;
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  padding: 0 16px;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, opacity 0.2s ease;
  -webkit-tap-highlight-color: transparent;
  flex-shrink: 0;
}
.enter:hover  { background: var(--red); color: #fff; }
.enter:active { transform: translateY(1px); }
.enter:disabled { opacity: 0.5; cursor: wait; }

.msg {
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  min-height: 1.2em;
  color: var(--error);
}

/* ---------- success ---------- */
.success {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  max-width: 400px;
}
.success.show { display: flex; animation: rise 0.5s cubic-bezier(.2,.7,.3,1); }
@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
.success h2 {
  font-size: clamp(1.1rem, 5vw, 1.4rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 800;
}
.success h2 span { color: var(--red); }
.success p {
  font-size: 0.76rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-dim);
  line-height: 1.9;
}
.share {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--text);
  font-family: var(--font);
  font-weight: 800;
  font-size: 0.74rem;
  letter-spacing: 0.18em;
  padding: 13px 26px;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.share:hover { background: var(--text); color: #000; border-color: var(--text); }

.hidden { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  body::after, .stage::before { animation: none; }
  .success.show { animation: none; }
}
/* ============================================================
   SITE ADDITIONS — everything above this line is the waitlist
   page's design system, untouched. Below: nav, shop grid,
   product page, about, footer.
   ============================================================ */

/* ---------- layout modes ----------
   The base body rules center a single hero (the waitlist look).
   body.home keeps that inside .hero and stacks sections after it;
   body.page is a normal scrolling page (shop / product / about). */
body.home { padding: 0; gap: 0; justify-content: flex-start; }
.hero {
  min-height: 100dvh;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: clamp(12px, 2.2vh, 24px);
  padding: 10vh 22px calc(56px + env(safe-area-inset-bottom));
}
body.page {
  display: block;
  text-align: left;
  padding: 0;
}
.wrap { width: 100%; max-width: 1060px; margin: 0 auto; padding: 0 22px; }

/* ---------- nav ---------- */
/* no bar — just the logo and the links sitting on the page, scrolling with it */
.nav {
  position: relative;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 22px 0;
}
.nav a { text-decoration: none; -webkit-tap-highlight-color: transparent; }
/* the 3D logo's stage — square, top-left. --nav-logo sets its size. */
.nav-mark {
  --nav-logo: 46px;
  position: relative;
  display: block;
  width: var(--nav-logo);
  height: var(--nav-logo);
  color: var(--red);
}
.nav-mark::before {   /* a whisper of the hero's red atmosphere behind the mark */
  content: "";
  position: absolute;
  inset: -45%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(215,3,3,0.42) 0%, rgba(215,3,3,0.12) 45%, transparent 70%);
  filter: blur(6px);
  z-index: -1;
}
.nav-mark canvas, .nav-mark svg { display: block; width: 100%; height: 100%; overflow: visible; }
@media (min-width: 700px) { .nav-mark { --nav-logo: 54px; } }
.nav-links { display: flex; gap: 22px; }
.nav-links a {
  color: var(--text-dim);
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  transition: color 0.2s ease;
}
.nav-links a:hover, .nav-links a.on { color: var(--text); }

/* ---------- section headers ---------- */
.kicker {
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.kicker .live { color: var(--red); }
.page-head {
  padding: 30px 0 26px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.page-head h1 {
  font-size: clamp(1.5rem, 6vw, 2.2rem);
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.15;
}
.page-head h1 .mark { display: inline-block; height: 1.4em; vertical-align: -0.34em; color: var(--red); }
.page-head h1 .mark svg { height: 100%; width: auto; }
.page-head .statement {
  color: var(--red);       /* the same red the LIVE NOW tag used */
  font-size: 0.8rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  line-height: 1.9;
}

/* ---------- pre-order banner ---------- */
.presale {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 14px 16px;
  border: 1px solid rgba(215, 3, 3, 0.35);
  background: rgba(215, 3, 3, 0.06);
  max-width: 46ch;
}
.presale-tag {
  align-self: flex-start;
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--red);
}
.presale p {
  color: var(--text);
  font-size: 0.78rem;
  line-height: 1.75;
  letter-spacing: 0.02em;
}
.presale p b { color: var(--text); font-weight: 800; }
.presale .presale-fine { color: var(--text-dim); font-size: 0.72rem; }
.presale a { color: var(--text-dim); text-decoration: underline; }
.presale a:hover { color: var(--text); }

/* ---------- waitlist popup ----------
   The standalone waitlist card, over the site. It reuses that page's own
   classes (.tagline, .field, .enter, .success), so the look comes from the
   original rather than a copy of it. The card's edges dissolve the same way
   the drop line's do, so it sits in the dark rather than being a box on it. */
body.pop-open { overflow: hidden; }

.pop {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 22px;
  opacity: 0;
  transition: opacity 0.22s ease;
}
/* a class selector outranks the UA's [hidden] rule, so display must be turned
   off explicitly — without this the invisible dialog still covers the page and
   swallows every click meant for the products underneath */
.pop[hidden] { display: none; }
.pop.on { opacity: 1; }
.pop-veil {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.82);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.pop-card {
  position: relative;
  width: 100%;
  max-width: 460px;
  padding: 54px 30px 46px;
  text-align: center;
  transform: translateY(8px) scale(0.99);
  transition: transform 0.28s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.pop.on .pop-card { transform: none; }
/* the red atmosphere from the waitlist page, behind the card */
.pop-card::before {
  content: "";
  position: absolute;
  left: 50%; top: 46%;
  width: 108%; height: 108%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle,
    rgba(215, 3, 3, calc(var(--glow) * 0.62)) 0%,
    rgba(215, 3, 3, calc(var(--glow) * 0.18)) 44%,
    transparent 70%);
  filter: blur(22px);
  pointer-events: none;
}
/* edges dissolve, like the ends of the drop line */
.pop-inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(12px, 2.2vh, 22px);
  -webkit-mask-image: radial-gradient(120% 118% at 50% 50%, #000 62%, transparent 100%);
  mask-image: radial-gradient(120% 118% at 50% 50%, #000 62%, transparent 100%);
}
.pop-inner form { max-width: 360px; }
/* On a phone the card's own padding was squeezing the row narrower than the
   waitlist page ever is, so ENTER overlapped the field. Give the form its
   width back. */
@media (max-width: 480px) {
  .pop { padding: 12px; }
  .pop-card { padding: 46px 14px 38px; }
}
.pop-x {
  position: absolute;
  top: 10px; right: 6px;
  width: 40px; height: 40px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-dim);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  transition: color 0.2s ease;
  -webkit-tap-highlight-color: transparent;
}
.pop-x:hover { color: var(--text); }
.pop-x:focus-visible { outline: 1px solid var(--line); outline-offset: 2px; }

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

/* ---------- home drop line ----------
   The tops slide along in a row that never stops, the bottom sits under them.
   These are the same .card blocks the grid uses, so names and prices come with
   them. The slide is a CSS keyframe animation — it runs on the compositor, so
   it stays smooth; dragging goes on .reel-drag so the two never fight. */
.dropline {
  /* wide enough on a phone that a title like FULL-ZIP 001 (LAVENDER) $110
     doesn't shred into three lines */
  --card-w: 62vw;
  --card-gap: 14px;
  --pitch: calc(var(--card-w) + var(--card-gap));
  --reel-count: 4;                 /* set from JS: how many tops */
  --loop-w: calc(var(--pitch) * var(--reel-count));
  --reel-secs: 6s;                 /* seconds per product */
  padding-bottom: 10px;
}
@media (min-width: 560px) { .dropline { --card-w: 44vw; } }
@media (min-width: 760px) { .dropline { --card-w: 330px; --card-gap: 18px; } }

/* the arrows sit outside .reel so the edge fade doesn't dissolve them too */
.reel-wrap { position: relative; }
.reel-arrow {
  position: absolute;
  /* centred on the garment, not the card — the card is taller by its label */
  top: calc(var(--card-w) / 2);
  transform: translateY(-50%);
  z-index: 5;
  width: 34px; height: 34px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: none;
  /* brand red, see-through, with a violet halo just off the red so the edge
     shifts hue slightly — reads iridescent at this size, where a gradient
     across a 20px stroke would be invisible */
  color: var(--red);
  opacity: 0.6;
  filter: drop-shadow(0 0 3px rgba(215, 3, 3, 0.5))
          drop-shadow(0 0 8px rgba(170, 60, 230, 0.35));
  cursor: pointer;
  transition: opacity 0.2s ease, transform 0.2s ease, filter 0.2s ease;
  -webkit-tap-highlight-color: transparent;
}
.reel-arrow svg { width: 20px; height: 20px; display: block; }
.reel-arrow.prev { left: -2px; }
.reel-arrow.next { right: -2px; }
.reel-arrow:hover {
  opacity: 1;
  filter: drop-shadow(0 0 4px rgba(215, 3, 3, 0.65))
          drop-shadow(0 0 11px rgba(170, 60, 230, 0.5));
}
.reel-arrow.prev:hover { transform: translateY(-50%) translateX(-2px); }
.reel-arrow.next:hover { transform: translateY(-50%) translateX(2px); }
.reel-arrow:focus-visible { outline: 1px solid var(--line); outline-offset: 2px; }
@media (min-width: 760px) {
  .reel-arrow { width: 40px; height: 40px; }
  .reel-arrow svg { width: 24px; height: 24px; }
}
@media (prefers-reduced-motion: reduce) {
  .reel-arrow.prev:hover, .reel-arrow.next:hover { transform: translateY(-50%); }
}

.reel {
  /* wider on a phone: the cards are big there, so a narrow fade still leaves a
     half-cut title legible at the edge */
  --edge-fade: 17%;
  width: 100%;
  overflow: hidden;
  cursor: grab;
  touch-action: pan-y;             /* horizontal is ours, vertical still scrolls */
  -webkit-tap-highlight-color: transparent;
  /* fade the row out at both ends so pieces aren't sliced off mid-slide —
     they arrive and leave instead of being cut by the container edge */
  -webkit-mask-image: linear-gradient(to right, transparent 0,
    #000 var(--edge-fade), #000 calc(100% - var(--edge-fade)), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0,
    #000 var(--edge-fade), #000 calc(100% - var(--edge-fade)), transparent 100%);
}
/* these must come after the block above — same specificity, so source order
   decides which value applies */
@media (min-width: 560px) { .reel { --edge-fade: 12%; } }
@media (min-width: 760px) { .reel { --edge-fade: 9%; } }
.reel.dragging { cursor: grabbing; }
/* the cards are links wrapping images — both are natively draggable, and that
   native drag steals the pointer so our own release never arrives. Kill it. */
.reel, .reel a, .reel img {
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
}

.reel-drag { will-change: transform; }
/* only while springing back — mid-drag it must track the pointer exactly */
.reel-drag.springing { transition: transform 0.55s cubic-bezier(0.22, 0.61, 0.36, 1); }

.reel-track {
  display: flex;
  width: max-content;
  will-change: transform;
  animation: reel-slide calc(var(--reel-count) * var(--reel-secs)) linear infinite;
}
/* sits on the middle copy, leaving a spare loop each side for dragging */
@keyframes reel-slide {
  from { transform: translate3d(calc(var(--loop-w) * -2), 0, 0); }
  to   { transform: translate3d(calc(var(--loop-w) * -1), 0, 0); }
}
.reel-track .card {
  flex: 0 0 var(--card-w);
  width: var(--card-w);
  margin-right: var(--card-gap);
}

/* the bottom piece, on its own under the row */
.solo { width: var(--card-w); margin: 26px auto 0; }

@media (prefers-reduced-motion: reduce) {
  .reel-track { animation: none; }
  .reel-drag.springing { transition: none; }
}

/* ---------- product grid ---------- */
.grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px 12px;
  padding-bottom: 20px;
}
@media (min-width: 760px) { .grid { grid-template-columns: repeat(3, 1fr); gap: 22px 18px; } }
.card { display: block; text-decoration: none; color: var(--text); -webkit-tap-highlight-color: transparent; }
/* no panel, no border — the pieces are cut out and sit straight on the page */
.card-img {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
}
.card-img img {
  width: 100%; height: 100%;
  object-fit: contain;
  display: block;
  transition: transform 0.4s ease, opacity 0.35s ease;
}
/* the detail shot sits on top, hidden, and fades in on hover */
.card-img .alt {
  position: absolute;
  inset: 0;
  opacity: 0;
}
.card:hover .card-img img,
.card:focus-visible .card-img img { transform: scale(1.04); }
.card:hover .card-img .alt,
.card:focus-visible .card-img .alt { opacity: 1; }
/* Both shots are cut out, so the one underneath shows through the transparent
   parts of the one on top — the front image has to fade out as the detail
   fades in. Only images marked .base have a detail shot to swap to. */
.card:hover .card-img .base,
.card:focus-visible .card-img .base { opacity: 0; }
/* on touch there is no hover, so never leave a card stuck on the detail shot */
@media (hover: none) {
  .card-img .alt { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .card-img img { transition: opacity 0.35s ease; }
  .card:hover .card-img img { transform: none; }
}
.card-row { padding-top: 10px; }
.card-name {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.card-price { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.12em; color: var(--text-dim); }
.chip {
  display: inline-block;
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 4px 8px;
  border: 1px solid var(--red);
  color: var(--red);
}
.chip.dim { border-color: var(--line); color: var(--text-dim); }
.card .chip { margin-top: 8px; }

/* ---------- product page ---------- */
.pd { display: grid; gap: 26px; padding-bottom: 30px; }
@media (min-width: 900px) {
  .pd { grid-template-columns: 1.15fr 1fr; gap: 44px; align-items: start; }
  .pd-info { position: sticky; top: 90px; }
}
.pd-main { aspect-ratio: 1 / 1; }
.pd-main img { width: 100%; height: 100%; object-fit: contain; display: block; }
.pd-thumbs { display: flex; gap: 8px; margin-top: 8px; }
.pd-thumbs button {
  width: 76px; height: 76px;
  padding: 0; border: 1px solid transparent;
  background: none; cursor: pointer; opacity: 0.45;
  transition: opacity 0.2s ease, border-color 0.2s ease;
}
.pd-thumbs button.on { opacity: 1; border-color: rgba(255,255,255,0.22); }
.pd-thumbs img { width: 100%; height: 100%; object-fit: contain; display: block; }
.pd-info { display: flex; flex-direction: column; gap: 16px; }
.pd-info h1 {
  font-size: clamp(1.3rem, 5vw, 1.8rem);
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.2;
}
.pd-price { font-size: 1rem; font-weight: 700; letter-spacing: 0.12em; color: var(--text); }
.pd-desc { color: var(--text-dim); font-size: 0.86rem; line-height: 1.9; letter-spacing: 0.04em; max-width: 46ch; }
.pd-label { font-size: 0.62rem; font-weight: 800; letter-spacing: 0.24em; text-transform: uppercase; color: var(--text-dim); }
.sizes { display: flex; flex-wrap: wrap; gap: 8px; }
.size {
  min-width: 46px;
  padding: 11px 12px;
  background: transparent;
  border: 1px solid var(--line);
  color: var(--text-dim);
  font-family: var(--font);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
  -webkit-tap-highlight-color: transparent;
}
.size:hover { color: var(--text); border-color: var(--text-dim); }
.size.on { background: var(--text); color: #000; border-color: var(--text); }
.buy {
  width: 100%;
  padding: 16px;
  background: var(--text);
  color: #000;
  border: 0;
  font-family: var(--font);
  font-weight: 800;
  font-size: 0.85rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, opacity 0.2s ease;
  -webkit-tap-highlight-color: transparent;
}
.buy:hover { background: var(--red); color: #fff; }
.buy:disabled { opacity: 0.45; cursor: not-allowed; }
.buy.ghost { background: transparent; border: 1px solid var(--line); color: var(--text-dim); cursor: default; }
.pd-note { font-size: 0.68rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-dim); line-height: 2; }

/* ---------- home featured strip ---------- */
.featured { width: 100%; max-width: 1060px; margin: 0 auto; padding: 8px 22px 12px; text-align: left; }
.featured .kicker { display: block; text-align: center; margin-bottom: 18px; }
.view-all {
  display: block;
  text-align: center;
  margin: 6px 0 10px;
  color: var(--text-dim);
  text-decoration: none;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  transition: color 0.2s ease;
}
.view-all:hover { color: var(--text); }

/* ---------- about ---------- */
.prose { max-width: 54ch; display: flex; flex-direction: column; gap: 18px; padding-bottom: 30px; }
.prose p { color: var(--text-dim); font-size: 0.92rem; line-height: 2; letter-spacing: 0.04em; }
.prose p b { color: var(--text); font-weight: 700; }
.prose-terms { max-width: 62ch; gap: 8px; }
.prose-terms h2 {
  margin-top: 22px;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--red);
}
.prose-terms h2:first-child { margin-top: 0; }
.prose-terms p { font-size: 0.86rem; line-height: 1.95; }
.prose-terms a { color: var(--text); }

/* ---------- footer ---------- */
.footer {
  margin-top: 40px;
  padding: 44px 22px calc(40px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-align: center;
}
.footer .cap { width: 100%; max-width: 400px; display: flex; flex-direction: column; gap: 12px; }
.footer .cap .msg { min-height: 0; }
.footer-done {
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text);
  line-height: 2;
}
.footer-done span { color: var(--red); }
.socials { display: flex; gap: 24px; margin-top: 6px; }
.socials a {
  color: var(--text-dim);
  text-decoration: none;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  transition: color 0.2s ease;
}
.socials a:hover { color: var(--text); }
.legal {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  color: rgba(255,255,255,0.28);
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1.8;
}
.legal a { color: inherit; text-decoration: none; }
.legal a:hover { color: var(--text-dim); }
