/* Fonts are linked from index.html <head> instead of @import'ed here — see the note there. */

:root {
  --black: #0a0a0b;
  --charcoal: #131315;
  --gray-950: #18181b;
  --gray-900: #1f1f23;
  --gray-800: #2a2a2f;
  --gray-700: #3d3d43;
  --gray-500: #6f6f78;
  --gray-300: #a8a8b0;
  --gray-100: #e4e4e7;
  --white: #f5f5f7;
  --glow: rgba(255,255,255,0.10);
  --radius: 14px;
  /* Height of the fixed footer. The body's bottom padding and the page skyline both key off this,
     so the three stay in step — see the 560px override below. */
  --footer-h: 92px;
}

@media (max-width: 560px) {
  :root { --footer-h: 104px; }
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--black);
  color: var(--gray-100);
  font-family: 'Space Grotesk', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.wrap {
  max-width: 1160px;
  margin: 0 auto;
  padding: 0 24px;
}

/* film-grain texture over everything */
.noise {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 999;
  opacity: 0.045;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- newsletter signup ----------
   Was a full-screen gate at z-index 1000 that blocked the store until an email was entered. It is
   now an ordinary section near the foot of the page — same card, same form, no overlay, nothing
   gated behind it. */
.signup { padding: 10px 0 70px; }

.signup-card {
  max-width: 420px;
  margin: 0 auto;
  padding: 32px 28px;
  text-align: center;
  background: linear-gradient(160deg, var(--gray-950), var(--charcoal));
  border: 1px solid var(--gray-900);
  border-radius: var(--radius);
}
.signup-card h2 {
  font-size: clamp(28px, 5vw, 36px);
  line-height: 1;
  margin: 12px 0 12px;
}
.signup-note { color: var(--gray-300); font-size: 14px; line-height: 1.6; margin: 0 0 24px; }
.signup-card form { display: flex; flex-direction: column; gap: 14px; text-align: left; }
.signup-card .form-field { margin: 0; }
.signup-msg { color: #ff6b6b; font-size: 13px; margin: 14px 0 0; }
.signup-msg.signup-ok { color: var(--gray-100); }

/* ---------- drifting city backdrop ----------
   The same skyline artwork the intro uses (images/skyline.png), but looping instead of settling, so
   the city the reveal opens on never actually stops moving.

   Each band translates left by exactly one tile width, which is what makes the wrap invisible: the
   art is 672x152, so a band H tall repeats every 4.421H (88.42vh at 20vh, 132.63vh at 30vh). The
   near band covers more ground per second than the far one, which is the parallax. Transform-only,
   so the loop stays on the compositor instead of repainting the page underneath it. */
.city-bg {
  overflow: hidden;
  pointer-events: none;
}

/* Behind the site: pinned to the viewport just above the fixed footer, so the skyline stays put
   and keeps drifting while the page scrolls over it. z-index -1 puts it under the page's content
   but still above the body background — at 0 it would paint over the in-flow text instead. */
.city-bg-page {
  position: fixed;
  left: 0;
  right: 0;
  bottom: var(--footer-h);
  height: 42vh;
  z-index: -1;
}

.city-sky {
  position: absolute;
  bottom: 0;
  left: 0;
  /* Plain url() first so a browser without image-set() still gets the PNG; the image-set()
     line below overrides it where supported, serving a lossless (pixel-identical) WebP at
     44% of the size. Both skyline layers and the intro read this. */
  background-image: url("images/skyline.png?v=1");
  background-image: image-set(url("images/skyline.webp?v=1") type("image/webp"),
                              url("images/skyline.png?v=1") type("image/png"));
  background-repeat: repeat-x;
  background-position: left bottom;
  background-size: auto 100%;
  will-change: transform;
}

/* Each band is one tile wider than the viewport and slides exactly that tile, so at the end of the
   cycle its right edge lands on the viewport's — any narrower and a bare strip opens up there,
   since the tile is sized off viewport *height* while the overhang comes from *width*. The +2px is
   slack against sub-pixel rounding. */
.city-sky-far {
  height: 20vh;
  width: calc(100% + 88.4211vh + 2px);
  opacity: 0.12;
  animation: city-drift-far 60s linear infinite;
}

.city-sky-near {
  height: 30vh;
  width: calc(100% + 132.6316vh + 2px);
  opacity: 0.2;
  animation: city-drift-near 40s linear infinite;
}

/* Faint glow where the city meets the sky — matches the intro's horizon. */
.city-horizon {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 42vh;
  background: radial-gradient(70% 100% at 50% 100%, rgba(120,150,220,0.13) 0%, transparent 70%);
}

@keyframes city-drift-far {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-88.4211vh, 0, 0); }
}

@keyframes city-drift-near {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-132.6316vh, 0, 0); }
}

/* Keep the city, drop the drift — same call the intro makes. */
@media (prefers-reduced-motion: reduce) {
  .city-sky-far,
  .city-sky-near { animation: none; }
}

::selection { background: var(--gray-700); color: var(--white); }

a { color: inherit; text-decoration: none; }

h1, h2, h3 { font-weight: 700; letter-spacing: -0.02em; margin: 0; }

/* ---------- header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(10,10,11,0.75);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--gray-900);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 72px;
  gap: 24px;
}

.logo {
  font-family: 'JetBrains Mono', monospace;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.logo .dot { color: var(--gray-500); }

.nav { display: flex; gap: 8px; margin-right: auto; }

.nav-link {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--gray-300);
  padding: 10px 16px;
  border-radius: 999px;
  display: inline-block;
}

.nav-link:hover { color: var(--white); }

/* ---------- header cart / orders icons ---------- */
.header-actions { display: flex; align-items: center; gap: 8px; }

.header-icon-btn {
  position: relative;
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--gray-950);
  border: 1px solid var(--gray-800);
  color: var(--gray-100);
  cursor: pointer;
}
.header-icon-btn:hover { border-color: var(--gray-500); color: var(--white); }

.cart-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--white);
  color: var(--black);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

/* ---------- social follow pill (hover/tap to reveal Instagram) ---------- */
.social-toggle {
  position: relative;
  display: flex;
  align-items: center;
  height: 40px;
}

.social-toggle-btn {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 18px;
  border-radius: 999px;
  background: var(--gray-950);
  border: 1px solid var(--gray-800);
  color: var(--gray-100);
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
  transition: opacity 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.social-toggle-btn:hover { border-color: var(--gray-500); color: var(--white); }

.social-toggle-items {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  height: 40px;
  width: 0;
  overflow: hidden;
  border-radius: 999px;
  background: var(--gray-950);
  border: 1px solid transparent;
  transition: width 0.35s cubic-bezier(0.23,1,0.32,1), border-color 0.2s ease;
  z-index: 1;
}

.social-toggle:hover .social-toggle-items,
.social-toggle.open .social-toggle-items {
  width: 52px;
  border-color: var(--gray-800);
}

.social-toggle:hover .social-toggle-btn,
.social-toggle.open .social-toggle-btn {
  opacity: 0;
  pointer-events: none;
}

.social-toggle-item {
  width: 52px;
  height: 40px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: translateX(-8px);
  transition: opacity 0.25s ease, transform 0.25s ease, background 0.2s ease;
}
.social-toggle-item:hover { background: rgba(255,255,255,0.06); }

.social-toggle:hover .social-toggle-item,
.social-toggle.open .social-toggle-item {
  opacity: 1;
  transform: translateX(0);
  transition-delay: 0.08s;
}

/* ---------- hero ---------- */
.hero { padding: 120px 0 100px; border-bottom: 1px solid var(--gray-900); }

.eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--gray-500);
  margin: 0 0 20px;
}

.hero h1 {
  font-size: clamp(42px, 7vw, 84px);
  line-height: 0.98;
  color: var(--white);
}

.hero-sub {
  max-width: 480px;
  color: var(--gray-300);
  font-size: 17px;
  line-height: 1.6;
  margin: 28px 0 40px;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-block;
  padding: 15px 30px;
  border-radius: 999px;
  border: none;
  background: none;
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  cursor: pointer;
}

.btn-primary {
  background: var(--white);
  color: var(--black);
}

.btn-outline {
  border: 1px solid var(--gray-700);
  color: var(--gray-100);
}
.btn-outline:hover { border-color: var(--gray-500); }
.btn:disabled { opacity: 0.5; cursor: default; }

/* ---------- sections ---------- */
.stock, .how, .contact { padding: 100px 0; border-bottom: 1px solid var(--gray-900); }

.section-head { margin-bottom: 48px; }

.section-head h2 {
  font-size: clamp(28px, 4vw, 42px);
  color: var(--white);
}

.section-note { color: var(--gray-500); font-size: 14px; margin: 10px 0 32px; }

/* ---------- shop by category (tile grid) ---------- */
.category-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px;
  margin-bottom: 56px;
}

.category-tile {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--gray-800);
  background: var(--gray-950);
  padding: 0;
  cursor: pointer;
  text-align: left;
}
.category-tile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.65;
  transition: opacity 0.2s ease;
}
.category-tile:hover img { opacity: 0.85; }

.category-tile-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 2px;
  padding: 12px 14px;
  background: linear-gradient(180deg, transparent 40%, rgba(6,6,7,0.9) 100%);
}
.category-tile-name {
  color: var(--white);
  font-weight: 600;
  font-size: 15px;
}
.category-tile-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gray-300);
}

.category-tile.active { border-color: var(--white); }
.category-tile.active .category-tile-overlay { background: linear-gradient(180deg, transparent 30%, rgba(6,6,7,0.95) 100%); }

/* ---------- catalog head / controls ---------- */
.catalog-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 20px;
  margin-bottom: 20px;
}

.catalog-controls {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.search-field {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--gray-950);
  border: 1px solid var(--gray-800);
  border-radius: 999px;
  padding: 10px 16px;
  color: var(--gray-500);
}

.search-field input {
  background: none;
  border: none;
  outline: none;
  color: var(--gray-100);
  font-family: 'Space Grotesk', sans-serif;
  font-size: 14px;
  width: 160px;
}
.search-field input::placeholder { color: var(--gray-500); }

.select-field {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gray-500);
}

.select-field select {
  background: var(--gray-950);
  border: 1px solid var(--gray-800);
  border-radius: 999px;
  color: var(--gray-100);
  font-family: 'Space Grotesk', sans-serif;
  font-size: 13px;
  padding: 9px 14px;
  outline: none;
}
.select-field select:hover { border-color: var(--gray-500); }

.price-range {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--gray-950);
  border: 1px solid var(--gray-800);
  border-radius: 999px;
  padding: 6px 14px;
}
.price-range input {
  background: none;
  border: none;
  outline: none;
  color: var(--gray-100);
  font-family: 'Space Grotesk', sans-serif;
  font-size: 14px;
  width: 60px;
}
.price-range input::placeholder { color: var(--gray-500); }
.price-range-dash { color: var(--gray-700); }

.checkbox-field {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gray-300);
  cursor: pointer;
}
.checkbox-field input {
  width: 16px;
  height: 16px;
  accent-color: var(--white);
  cursor: pointer;
}

.size-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 20px 0 28px;
}

.size-chip {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--gray-300);
  background: var(--gray-950);
  border: 1px solid var(--gray-800);
  padding: 7px 14px;
  border-radius: 999px;
  cursor: pointer;
}
.size-chip:hover { color: var(--white); border-color: var(--gray-500); }
.size-chip.active {
  background: var(--white);
  color: var(--black);
  border-color: var(--white);
}

.empty-state {
  color: var(--gray-500);
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  text-align: center;
  padding: 60px 0;
}

/* ---------- featured picks (card stack) ---------- */
.featured { padding: 100px 0 60px; border-bottom: 1px solid var(--gray-900); }

.stack-wrap {
  position: relative;
  margin: 0 auto;
  min-height: 480px;
  width: 100%;
  max-width: 1200px;
  cursor: pointer;
  outline: none;
}

.stack-card {
  position: absolute;
  top: 0;
  left: 50%;
  width: 100%;
  max-width: 320px;
  margin-left: -160px;
  padding: 22px;
  border-radius: 18px;
  background: rgba(31,31,35,0.75);
  border: 1px solid rgba(255,255,255,0.08);
  backdrop-filter: blur(18px) saturate(140%);
  box-shadow: 0 8px 30px rgba(0,0,0,0.45);
  transition: transform 480ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 300ms ease, border-color 0.25s ease, box-shadow 0.25s ease;
  transform: translate(var(--sx, 0px), var(--sy, 0px)) rotate(var(--srot, 0deg)) scale(var(--sscale, 1));
  opacity: var(--sopacity, 1);
  will-change: transform;
  outline: none;
}

.stack-card:hover,
.stack-card:focus-visible {
  border-color: rgba(255,255,255,0.16);
  box-shadow: 0 16px 50px rgba(0,0,0,0.6);
}
.stack-card:focus-visible { outline: 2px solid var(--gray-500); outline-offset: 4px; }

.stack-specs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  margin: 0 0 14px;
}

.stack-spec { display: flex; flex-direction: column; min-width: 0; margin: 0; }
.stack-spec-value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--gray-500);
  overflow-wrap: break-word;
  margin: 0;
}
.stack-spec-label {
  font-size: 11px;
  color: var(--gray-100);
  margin: 2px 0 0;
  overflow-wrap: break-word;
}

.stack-image {
  aspect-ratio: 16 / 11;
  border-radius: 10px;
  background: repeating-linear-gradient(135deg, var(--gray-900) 0px, var(--gray-900) 2px, var(--charcoal) 2px, var(--charcoal) 14px);
  border: 1px solid var(--gray-800);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.stack-image span {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--gray-500);
}

.stack-title {
  display: block;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--white);
  margin-top: 16px;
}
.stack-subtitle {
  display: block;
  font-size: 15px;
  font-weight: 600;
  color: var(--gray-500);
}
.stack-desc { font-size: 13px; color: var(--gray-300); line-height: 1.5; margin: 8px 0 0; }

@media (prefers-reduced-motion: reduce) {
  .stack-card { transition: transform 200ms ease-out; }
}

/* ---------- product grid ---------- */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 18px;
}

/* Column flex so the price row can be pinned to the bottom. Grid rows stretch every card to the
   tallest in the row, and once shirts carry a bulk strip their neighbours gain ~86px of slack —
   without this the shorter card's price and Details button float mid-card above a dead gap. */
.card {
  position: relative;
  background: linear-gradient(160deg, var(--gray-950), var(--charcoal));
  border: 1px solid var(--gray-900);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.card-media {
  flex: none;                /* keep the 4:5 photo box exact when the card is stretched */
  aspect-ratio: 4 / 5;
  background: repeating-linear-gradient(135deg, var(--gray-900) 0px, var(--gray-900) 2px, var(--gray-950) 2px, var(--gray-950) 14px);
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.card-media span {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--gray-500);
}

.card-media img,
.stack-image img,
.modal-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.tag {
  position: absolute;
  top: 12px;
  left: 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 5px 10px;
  border-radius: 999px;
  background: rgba(10,10,11,0.7);
  border: 1px solid var(--gray-800);
  color: var(--gray-300);
}

.tag.sold { color: var(--gray-500); }
.tag.available { color: var(--white); border-color: var(--gray-700); }

.card-body { padding: 16px 18px 18px; flex: 1; display: flex; flex-direction: column; }

.card-title {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 1.35;
  color: var(--white);
  margin: 0 0 8px;
}
.card-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--gray-500);
  margin: 0 0 14px;
}

/* margin-top:auto pins the price row (and the bulk strip under it) to the bottom of the card, so
   every card in a stretched row lines its pricing up on the same baseline. */
.card-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: auto; }
.price { font-family: 'JetBrains Mono', monospace; font-size: 15px; font-weight: 500; color: var(--white); }

.price-block { display: flex; flex-direction: column; gap: 2px; }
.stock-note {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gray-500);
}

/* ---------- bulk pricing ----------
   Rendered only for products whose tiers actually beat the single price, so today this appears on
   shirts and nowhere else — no category check in the CSS or the markup.

   The card strip is deliberately quiet: mono type at the stock-note size, one hairline rule to
   separate it from the price row. It has to read as a footnote to the price, not compete with it. */
.bulk-strip {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--gray-900);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.bulk-strip-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--gray-500);
}

/* Wraps rather than overflowing — at the 200px minimum card width three tiers won't fit on one
   line, and a card must never push its own content sideways. */
.bulk-strip-tiers {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.bulk-tier {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  line-height: 1;
  color: var(--gray-300);
  background: var(--gray-900);
  border: 1px solid var(--gray-800);
  border-radius: 999px;
  padding: 4px 7px;
  white-space: nowrap;
}

.bulk-tier b {
  color: var(--white);
  font-weight: 500;
  margin-right: 4px;
}

/* Modal version: the full ladder including the retail row, so the saving is legible as a ladder. */
.bulk-table {
  margin: 0 0 18px;
  padding: 14px 16px;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--gray-900);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.bulk-table-head {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--gray-500);
  margin-bottom: 2px;
}

.bulk-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--white);
}

/* The retail band is the reference point, not an offer — kept a step back from the discounts. */
.bulk-row.is-retail { color: var(--gray-300); }

.bulk-row-qty { color: var(--gray-300); }
.bulk-row.is-retail .bulk-row-qty { color: var(--gray-500); }

.bulk-row-price { font-weight: 500; white-space: nowrap; }
.bulk-row-price i { font-style: normal; font-size: 10px; color: var(--gray-500); }

.bulk-note {
  margin-top: 4px;
  padding-top: 9px;
  border-top: 1px solid var(--gray-900);
  font-size: 11px;
  line-height: 1.5;
  color: var(--gray-500);
}

.card-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--gray-300);
  border: 1px solid var(--gray-700);
  padding: 8px 14px;
  border-radius: 999px;
  background: none;
  cursor: pointer;
}
.card-cta:hover { color: var(--white); border-color: var(--gray-500); }
.card-cta svg { flex-shrink: 0; }

/* ---------- how it works ---------- */
.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
}

.step {
  background: var(--gray-950);
  border: 1px solid var(--gray-900);
  border-radius: var(--radius);
  padding: 28px 24px;
}

.step-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--gray-500);
}

.step h3 { color: var(--white); font-size: 18px; margin: 14px 0 8px; }
.step p { color: var(--gray-300); font-size: 14px; line-height: 1.6; margin: 0; }

/* ---------- bid of the week ---------- */
.bid-week { padding: 100px 0; border-bottom: 1px solid var(--gray-900); }

.bid-card {
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--gray-950);
  border: 1px solid var(--gray-900);
  border-radius: var(--radius);
  overflow: hidden;
}
@media (max-width: 560px) {
  .bid-card { grid-template-columns: 1fr; }
}

.bid-card-media {
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: repeating-linear-gradient(135deg, var(--gray-900) 0px, var(--gray-900) 2px, var(--gray-950) 2px, var(--gray-950) 14px);
}
.bid-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }

.bid-card-info { padding: 30px 28px; display: flex; flex-direction: column; }
.bid-card-info h3 { font-size: 22px; color: var(--white); margin: 10px 0 6px; text-transform: uppercase; }
.bid-card-info .card-meta { margin: 0 0 6px; }
.bid-card-desc { color: var(--gray-300); font-size: 14px; line-height: 1.6; margin: 0; }

.bid-current {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  margin: 20px 0;
  padding: 14px 16px;
  border: 1px solid var(--gray-800);
  border-radius: 12px;
}
.bid-current-label {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gray-500);
  margin-bottom: 4px;
}
.bid-current-amount { font-size: 28px; font-weight: 700; color: var(--white); }
.bid-current-name {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--gray-500);
}

.bid-form { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.bid-form input {
  background: var(--gray-950);
  border: 1px solid var(--gray-800);
  border-radius: 10px;
  padding: 10px 14px;
  color: var(--gray-100);
  font-family: 'Space Grotesk', sans-serif;
  font-size: 14px;
  outline: none;
  flex: 1;
  min-width: 110px;
}
.bid-form input::placeholder { color: var(--gray-700); }
.bid-form input:focus { border-color: var(--gray-500); }
.bid-form button { flex-shrink: 0; }

.bid-error { color: #ff6b6b; font-size: 13px; margin: 8px 0 0; }
.bid-note { color: var(--gray-500); font-size: 12px; line-height: 1.5; margin: 10px 0 0; }

/* ---------- item detail modal ---------- */
.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(6,6,7,0.8);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.modal-overlay[hidden] { display: none; }

.modal {
  position: relative;
  width: 100%;
  max-width: 640px;
  max-height: 88vh;
  overflow-y: auto;
  background: var(--gray-950);
  border: 1px solid var(--gray-800);
  border-radius: var(--radius);
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 2;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: rgba(10,10,11,0.6);
  border: 1px solid var(--gray-800);
  color: var(--gray-100);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
.modal-close:hover { color: var(--white); border-color: var(--gray-500); }

.modal-media {
  aspect-ratio: 4 / 5;
  background: repeating-linear-gradient(135deg, var(--gray-900) 0px, var(--gray-900) 2px, var(--gray-950) 2px, var(--gray-950) 14px);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.modal-media span {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--gray-500);
}

.modal-body { padding: 28px 26px; display: flex; flex-direction: column; }
.modal-body h3 { font-size: 22px; color: var(--white); margin: 10px 0 6px; text-transform: uppercase; }
.modal-body .card-meta { margin-bottom: 16px; }
.modal-desc { color: var(--gray-300); font-size: 14px; line-height: 1.6; margin: 0 0 24px; }
.modal-foot { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.modal-foot .price { font-size: 20px; }
.modal-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---------- checkout modal (front-end mock, no processor wired up) ---------- */
.checkout-modal { grid-template-columns: 1fr; max-width: 480px; max-height: 94vh; }

.checkout-body { padding: 24px 28px 26px; }
.checkout-body h3 { font-size: 20px; color: var(--white); margin: 4px 0 16px; }

.checkout-items {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
}

.checkout-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--gray-800);
  border-radius: 12px;
}

.checkout-total-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 4px 16px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gray-500);
}
.checkout-total-row .price { font-size: 18px; color: var(--white); }

.cart-empty-note {
  color: var(--gray-500);
  font-size: 13px;
  text-align: center;
  padding: 24px 0;
}

.checkout-item-remove {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: none;
  border: 1px solid var(--gray-800);
  color: var(--gray-500);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.checkout-item-remove:hover { color: var(--white); border-color: var(--gray-500); }

/* ---------- my orders (collapsible order cards) ---------- */
.order-card { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }

.order-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 2px;
}
.order-card-head h4 { font-size: 14px; font-weight: 600; color: var(--white); margin: 0; }

.order-toggle-btn {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: none;
  border: 1px solid var(--gray-800);
  color: var(--gray-300);
  cursor: pointer;
}
.order-toggle-btn:hover { color: var(--white); border-color: var(--gray-500); }
.order-toggle-btn.open { color: var(--white); border-color: var(--gray-500); }

.order-field-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border: 1px solid var(--gray-800);
  border-radius: 10px;
  font-size: 13px;
}
.order-field-row .order-field-label { color: var(--gray-500); }
.order-field-row .order-field-value { color: var(--gray-100); font-weight: 500; text-align: right; }

.order-details { display: flex; flex-direction: column; gap: 8px; }
.order-details[hidden] { display: none; }
.order-field-block {
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}
.order-field-block .order-field-label { margin: 0; font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; font-family: 'JetBrains Mono', monospace; }
.order-field-block .order-field-value { margin: 0; text-align: left; font-weight: 400; color: var(--gray-300); }

.apple-pay-btn {
  width: 100%;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  background: #fff;
  color: #000;
  border: none;
  border-radius: 10px;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}
.apple-pay-btn:disabled { opacity: 0.6; cursor: default; }

.checkout-trust {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
  margin: 0 0 16px;
  padding: 0;
  list-style: none;
}
.checkout-trust li {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gray-500);
}
.checkout-trust li:not(:last-child)::after {
  content: "·";
  margin-left: 10px;
  color: var(--gray-800);
}

.checkout-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 16px 0;
}
.checkout-divider::before,
.checkout-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--gray-800);
}
.checkout-divider span {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--gray-500);
  white-space: nowrap;
}
.checkout-item-media {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: 8px;
  overflow: hidden;
  background: repeating-linear-gradient(135deg, var(--gray-900) 0px, var(--gray-900) 2px, var(--gray-950) 2px, var(--gray-950) 10px);
}
.checkout-item-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.checkout-item-info { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.checkout-item-info .checkout-item-name { font-size: 14px; font-weight: 600; color: var(--white); }
.checkout-item-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--gray-500);
}
.checkout-item .price { font-size: 15px; }

.form-field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 12px; min-width: 0; }
.form-field label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gray-500);
}
.form-field input {
  background: var(--gray-950);
  border: 1px solid var(--gray-800);
  border-radius: 10px;
  padding: 10px 14px;
  color: var(--gray-100);
  font-family: 'Space Grotesk', sans-serif;
  font-size: 14px;
  outline: none;
  transition: border-color 0.15s ease;
  width: 100%;
}
.form-field input::placeholder { color: var(--gray-700); }
.form-field input:focus { border-color: var(--gray-500); }

.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 0; }
.form-row .form-field { margin-bottom: 12px; }

.checkout-pay-btn {
  width: 100%;
  text-align: center;
  padding: 13px 0;
  margin-top: 4px;
  font-size: 13px;
}
.checkout-pay-btn:disabled { opacity: 0.6; cursor: default; }

.checkout-disclaimer {
  text-align: center;
  font-size: 11px;
  color: var(--gray-500);
  margin: 10px 0 0;
}

.checkout-success { padding: 30px 28px; }
.checkout-success #checkout-done-btn { width: 100%; text-align: center; }

/* ---------- alert (shadcn-style: icon + title + description, adapted to our tokens) ---------- */
.alert {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 12px;
  padding: 16px;
  border: 1px solid var(--gray-800);
  border-radius: 12px;
  background: var(--gray-900);
  margin-bottom: 22px;
}
.alert-icon { grid-row: span 2; width: 18px; height: 18px; margin-top: 2px; color: var(--white); }
.alert-title { grid-column: 2; font-size: 14px; font-weight: 600; color: var(--white); margin: 0; }
.alert-description { grid-column: 2; font-size: 13px; color: var(--gray-400); line-height: 1.5; margin: 4px 0 0; }
.alert.destructive { border-color: rgba(255,107,107,0.35); }
.alert.destructive .alert-icon,
.alert.destructive .alert-title { color: #ff6b6b; }

/* ---------- image lightbox ---------- */
.modal-media img { cursor: zoom-in; }

.lightbox-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(8,8,9,0.92);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px;
  cursor: zoom-out;
}
.lightbox-overlay[hidden] { display: none; }
.lightbox-overlay img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 14px;
  box-shadow: 0 24px 70px rgba(0,0,0,0.6);
  cursor: default;
}
.lightbox-close {
  position: absolute;
  top: 22px;
  right: 26px;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  border: 1px solid var(--gray-700);
  background: rgba(10,10,11,0.7);
  color: var(--gray-100);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
.lightbox-close:hover { color: var(--white); border-color: var(--gray-500); }

/* ---------- 3D tilt effect (shared across all .tilt elements) ---------- */
.tilt {
  position: relative;
  --rx: 0deg;
  --ry: 0deg;
  --spot-x: 50%;
  --spot-y: 50%;
  --spot-o: 0;
  --scale: 1;
  transform: perspective(900px) rotateX(var(--rx)) rotateY(var(--ry)) scale(var(--scale));
  transform-style: preserve-3d;
  transition: transform 200ms ease-out;
  will-change: transform;
}

.tilt-glow {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  pointer-events: none;
  z-index: 5;
  opacity: var(--spot-o, 0);
  transition: opacity 300ms ease-out;
  background: radial-gradient(180px circle at var(--spot-x) var(--spot-y), var(--glow) 0%, transparent 65%);
}

@media (prefers-reduced-motion: reduce) {
  .tilt { transition: none; transform: none !important; }
}

/* ---------- brand line (designer name, shown above every product title) ---------- */
.card-brand,
.stack-brand {
  display: block;
  margin: 0 0 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--white);
}

.stack-brand { margin-bottom: 2px; }

#modal-brand {
  margin: 10px 0 2px;
  font-size: 0.72rem;
}

/* Unfilled brand — deliberately loud so an unlabelled piece can't pass as finished. */
.card-brand-missing {
  color: #f0a84a;
  text-transform: none;
  letter-spacing: 0.04em;
}

/* ---------- per-size availability pills (item modal) ---------- */
.modal-sizes {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 10px 0 2px;
}

.size-pill {
  padding: 6px 11px;
  border: 1px solid var(--gray-800);
  border-radius: 999px;
  background: var(--gray-950);
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.68rem;
  color: var(--gray-300);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}

.size-pill:hover { border-color: var(--gray-500); }

.size-pill:focus-visible {
  outline: 2px solid var(--white);
  outline-offset: 2px;
}

.size-pill.selected {
  background: var(--white);
  border-color: var(--white);
  color: var(--black);
}

.size-pill b {
  color: var(--white);
  font-weight: 500;
}

.size-pill.selected b { color: var(--black); }

@media (prefers-reduced-motion: reduce) {
  .size-pill { transition: none; }
}

/* ---------- quantity stepper (item modal + cart rows) ---------- */
.qty-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 14px 0 2px;
}

.qty-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gray-500);
}

.qty-max {
  font-size: 0.78rem;
  color: var(--gray-500);
}

.qty-stepper {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--gray-800);
  border-radius: 999px;
  background: var(--gray-950);
  overflow: hidden;
}

.qty-stepper button {
  width: 30px;
  height: 30px;
  border: 0;
  background: transparent;
  color: var(--white);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease;
}

.qty-stepper button:hover:not(:disabled) { background: var(--gray-800); }

.qty-stepper button:disabled {
  color: var(--gray-700);
  cursor: not-allowed;
}

.qty-stepper span {
  min-width: 28px;
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.8rem;
  color: var(--white);
}

.qty-stepper-sm { flex: 0 0 auto; }
.qty-stepper-sm button { width: 24px; height: 24px; font-size: 0.85rem; }
.qty-stepper-sm span { min-width: 22px; font-size: 0.72rem; }

.checkout-item-qty {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.75rem;
  color: var(--gray-300);
}

@media (prefers-reduced-motion: reduce) {
  .qty-stepper button { transition: none; }
}

/* ---------- subtotal / shipping rows above the order total ---------- */
.checkout-subtotal-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 5px 0;
  font-size: 0.85rem;
  color: var(--gray-300);
}

.checkout-subtotal-row em {
  font-style: normal;
  font-size: 0.75rem;
  color: var(--gray-500);
}

.form-row-3 { grid-template-columns: 2fr 1fr 1fr; }

.optional {
  font-size: 0.7rem;
  color: var(--gray-500);
  text-transform: none;
  letter-spacing: 0;
}

@media (max-width: 560px) {
  .form-row-3 { grid-template-columns: 1fr; }
}

/* ---------- responsive header ----------
   The header is one flex row of logo + nav + cart/orders + follow, which needs ~676px. Below that
   it used to overflow the viewport and push the cart and orders buttons off-screen entirely, so on
   a phone they were unreachable. Under 820px it becomes two rows: identity and actions on top, the
   section nav on its own scrollable strip beneath. */
@media (max-width: 820px) {
  .header-inner {
    flex-wrap: wrap;
    height: auto;
    padding-top: 12px;
    padding-bottom: 8px;
    gap: 10px 12px;
  }

  .logo { order: 1; margin-right: auto; font-size: 14px; }
  .header-actions { order: 2; }
  .social-toggle { order: 3; }

  /* Second row: full width, scrolls sideways instead of wrapping into a stack. */
  .nav {
    order: 4;
    flex: 1 0 100%;
    margin-right: 0;
    gap: 4px;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .nav::-webkit-scrollbar { display: none; }

  .nav-link {
    padding: 8px 12px;
    font-size: 12px;
    white-space: nowrap;
  }
}

/* The featured stack positions its cards with fixed 320px pose math, which overhangs a phone
   viewport. Clip at the wrap so the spread can't widen the document; `clip` rather than `hidden`
   so no scroll container is created around the absolutely-positioned cards. */
@media (max-width: 820px) {
  .stack-wrap {
    overflow-x: hidden;
    overflow-x: clip;
  }
}

/* ---------- reduced vertical rhythm on phones ----------
   Every section carries 100-120px of top/bottom padding sized for a desktop-length scroll. On a
   390-430px phone that reads as dead space between sections — close to a full screen of empty
   black between the hero and Featured Picks, and again between Bid of the Week and Shop by
   Category. Trimmed here so five stacked sections don't compound into several viewport-heights of
   nothing; desktop keeps the original spacing untouched. */
@media (max-width: 640px) {
  .hero { padding: 64px 0 48px; }
  .featured { padding: 56px 0 40px; }
  .bid-week,
  .stock,
  .how,
  .contact { padding: 56px 0; }
  .section-head { margin-bottom: 32px; }
}

/* Narrowest phones: drop the "Follow" wordmark to its icon so the top row still fits. */
@media (max-width: 420px) {
  .social-toggle-btn { padding: 0 12px; }
  .social-toggle-btn span { display: none; }
  .header-icon-btn { width: 34px; height: 34px; }
}

/* Scroll stays locked behind the intro so the page can't be moved before it clears. */
body.intro-playing { overflow: hidden; }

/* ---------- footer: rotating buyer vouches ----------
   The site's only footer, pinned to the bottom of the viewport. Every quote sits stacked in the
   same box and only `.is-active` shows, so swapping is a transition rather than a reflow. */
.site-footer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 95;               /* under the header (100) and the intro (2000) */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  height: var(--footer-h);
  padding: 0 24px;
  overflow: hidden;
  background: rgba(10,10,11,0.92);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--gray-900);
}

/* Keeps page content clear of the fixed footer instead of running underneath it. */
body { padding-bottom: var(--footer-h); }

.vouch-rotator {
  position: relative;
  width: 100%;
  height: 40px;
}

.vouch-item {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
  opacity: 0;
  transform: translateY(9px);
  transition: opacity 520ms ease, transform 520ms cubic-bezier(0.16, 1, 0.3, 1);
  pointer-events: none;
}

.vouch-item.is-active {
  opacity: 1;
  transform: translateY(0);
}

.vouch-quote {
  font-size: clamp(1rem, 2.1vw, 1.35rem);
  line-height: 1.25;
  color: var(--white);
}

.vouch-handle {
  flex: 0 0 auto;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.76rem;
  letter-spacing: 0.06em;
  color: var(--gray-500);
}

.site-footer-line {
  margin: 0;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.64rem;
  letter-spacing: 0.08em;
  color: var(--gray-700);
  text-align: center;
}

@media (max-width: 560px) {
  /* height/padding follow --footer-h, overridden for this breakpoint up in :root */
  .vouch-rotator { height: 52px; }
  .vouch-item { flex-direction: column; gap: 3px; }
  .vouch-quote { font-size: 0.98rem; }
}

@media (prefers-reduced-motion: reduce) {
  .vouch-item { transition: opacity 120ms linear; transform: none; }
  .vouch-item.is-active { transform: none; }
}

/* ---------- opening logo reveal ----------
   Sits above every other layer so it plays before anything else is reachable.
   Everything animates transform/opacity only — no blur or filter — so the whole sequence stays on
   the compositor and doesn't hitch mid-spin. */
.intro {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  /* Night sky rather than flat black: a touch of blue lifting toward the horizon. */
  background:
    radial-gradient(120% 62% at 50% 100%, #14161f 0%, #0b0c11 45%, #000 100%),
    #000;
  perspective: 1600px;
  animation: intro-out 350ms cubic-bezier(0.4, 0, 0.2, 1) 650ms both;
}

.intro[hidden] { display: none; }

/* ---- city backdrop ----
   Both bands are the skyline lifted out of the logo itself (images/skyline.png), tiled across the
   viewport at two scales and drifting at two speeds so the horizon reads with depth instead of as
   one flat cut-out. Kept dim so the spinning mark stays the subject. */
.intro-bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.intro-sky {
  position: absolute;
  bottom: 0;
  left: -20%;
  width: 160%;
  /* Plain url() first so a browser without image-set() still gets the PNG; the image-set()
     line below overrides it where supported, serving a lossless (pixel-identical) WebP at
     44% of the size. Both skyline layers and the intro read this. */
  background-image: url("images/skyline.png?v=1");
  background-image: image-set(url("images/skyline.webp?v=1") type("image/webp"),
                              url("images/skyline.png?v=1") type("image/png"));
  background-repeat: repeat-x;
  background-position: left bottom;
  will-change: transform;
}

.intro-sky-far {
  height: 20vh;
  background-size: auto 100%;
  opacity: 0.12;
  animation: intro-drift-far 9s linear both;
}

.intro-sky-near {
  height: 30vh;
  background-size: auto 100%;
  opacity: 0.2;
  animation: intro-drift-near 9s linear both;
}

/* Faint glow where the city meets the sky. */
.intro-horizon {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 42vh;
  background: radial-gradient(70% 100% at 50% 100%, rgba(120,150,220,0.13) 0%, transparent 70%);
  animation: intro-skip-in 1400ms ease-out both;
}

.intro-stage {
  position: relative;
  z-index: 1;
  width: min(74vw, 620px);
  transform-style: preserve-3d;
  /* No backface-visibility here: the mark turns through two full revolutions, so hiding the back
     face would blank it for half of every turn. Letting the back show reads as a coin flip, and
     the ease-out means the mirrored moments are the fast ones while it lands facing forward. */
  will-change: transform, opacity;
  animation: intro-spin 2100ms cubic-bezier(0.16, 0.84, 0.24, 1) both;
}

.intro-logo {
  display: block;
  width: 100%;
  height: auto;
}

/* Viewport-wide light sweep — a skewed band wider than the screen, translated clear across it, so
   the shine passes over the skyline and the logo alike. */
.intro-sheen {
  position: absolute;
  z-index: 2;
  top: -20%;
  left: 0;
  width: 60%;
  height: 140%;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(255,255,255,0.05) 30%,
    rgba(255,255,255,0.20) 50%,
    rgba(255,255,255,0.05) 70%,
    transparent 100%
  );
  transform: translate3d(-100%, 0, 0) skewX(-14deg);
  will-change: transform;
  animation: intro-sheen 1700ms cubic-bezier(0.35, 0, 0.25, 1) 950ms both;
}

.intro-skip {
  position: absolute;
  z-index: 3;
  bottom: 28px;
  right: 28px;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid var(--gray-800);
  background: transparent;
  color: var(--gray-500);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  cursor: pointer;
  animation: intro-skip-in 500ms ease-out 1200ms both;
}
.intro-skip:hover { color: var(--white); border-color: var(--gray-500); }

/* Two full turns, decelerating into place. Opacity lands early so the spin itself is fully visible
   rather than fading in over the top of it. */
@keyframes intro-spin {
  0%   { opacity: 0; transform: rotateY(-720deg) scale(0.68); }
  15%  { opacity: 1; }
  100% { opacity: 1; transform: rotateY(0deg) scale(1); }
}

@keyframes intro-drift-far {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-4%, 0, 0); }
}

@keyframes intro-drift-near {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-9%, 0, 0); }
}

@keyframes intro-sheen {
  0%   { transform: translate3d(-100%, 0, 0) skewX(-14deg); }
  100% { transform: translate3d(266%, 0, 0) skewX(-14deg); }
}

@keyframes intro-skip-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes intro-out {
  0%   { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.05); visibility: hidden; }
}

/* Reduced motion: keep the city, drop the spin, sweep and drift. */
@media (prefers-reduced-motion: reduce) {
  .intro { animation: intro-out 200ms linear 900ms both; }
  .intro-stage { animation: intro-skip-in 200ms linear both; }
  .intro-sheen { display: none; }
  .intro-sky-far,
  .intro-sky-near,
  .intro-horizon { animation: none; }
  .intro-skip { animation: none; }
}

/* ---------- product modal on phones ----------
   Desktop is untouched: everything here is inside the same 560px breakpoint that already stacks the
   modal into one column.

   The image was eating the screen. Two separate problems:

   1. `.modal-media` sized itself with `aspect-ratio: 4/5` and no height. Inside the modal's
      max-height scroll container that row resolved to 0px while the element still painted ~438px
      tall, so the title, sizes, price and bulk table were drawn ON TOP of the photo. Giving the
      media a definite height puts it back in its own row.
   2. Even laid out correctly, 4:5 of a 350px column is 438px — over half a 824px screen before any
      purchasing information appears.

   A definite height fixes both. `object-fit: contain` then shows the whole product rather than the
   centre crop `cover` was taking, which is what keeps the full image visible at the smaller size. */
@media (max-width: 560px) {
  /* Use nearly the whole screen. At 92vh the modal's scroll box cut off Add to Cart on a 812px
     phone even though the button had rendered — the extra ~40px here is what un-clips it without
     taking anything back off the image.

     dvh, not vh: on iOS Safari `vh` is the LARGE viewport — the height the page would have if the
     URL bar were hidden. With the bars actually showing, a 100vh modal is taller than the screen
     really is, and the bottom of it (Add to Cart) sits under the toolbar. `dvh` tracks the visible
     viewport as the bars come and go. The vh line stays first as the fallback for browsers without
     dvh, where the two are equivalent anyway. */
  .modal {
    grid-template-columns: 1fr;
    max-height: calc(100vh - 16px);
    max-height: calc(100dvh - 16px);
  }

  /* Reclaim the screen edges — 8px instead of 24px gives the modal 32px more width and height.
     The bottom pad also clears the home indicator on notched iPhones, which overlays the last
     ~34px; without it the buy buttons can end up underneath it. */
  .modal-overlay {
    padding: 8px;
    padding-bottom: max(8px, env(safe-area-inset-bottom));
  }

  .modal-media {
    aspect-ratio: auto;              /* the 4:5 box is what collapsed the grid row */
    /* dvh for the same reason as the modal: this stays 33% of the height actually on screen, so
       the image keeps its proportion instead of quietly eating the buy buttons' room when Safari's
       toolbars are up. Identical to 33vh wherever there are no dynamic toolbars.

       The `min()` is what makes Add to Cart survive a short screen. Everything below the image —
       title through buy buttons — needs about 518px, so on a viewport with room to spare the image
       is simply 33% of it, and only when the screen is too short does it give way rather than
       pushing the buttons out of the modal's scroll box. On a 812px iPhone with the toolbars
       hidden nothing changes; with them showing, the image yields ~50px instead of the buttons. */
    height: 33vh;                    /* fallback: browsers without dvh get the flat 33% */
    height: min(33dvh, calc(100dvh - 549px));
    min-height: 165px;               /* never collapse — a short screen still shows the product */
    max-height: 320px;
  }

  /* contain, not cover: the whole piece stays visible and undistorted in the shorter box. The
     striped placeholder background fills the letterbox, so it reads as intentional. */
  .modal-media img { object-fit: contain; }

  /* 26px of bottom padding keeps the last block clear of the modal's rounded bottom edge. */
  .modal-body { padding: 16px 18px 26px; }
  .modal-body h3 { font-size: 19px; margin: 6px 0 3px; }
  .modal-body .card-meta { margin-bottom: 8px; }
  .modal-desc { font-size: 13px; margin: 0 0 12px; }

  .modal-sizes { gap: 7px; margin: 6px 0 2px; }

  /* Sizes and quantity are the two things a thumb has to hit, so they get BIGGER here, not
     smaller — 36px tall clears the comfortable-target floor. The space comes from the image. */
  .size-pill { min-height: 36px; padding: 7px 13px; font-size: 0.74rem; }
  .qty-row { margin: 8px 0 2px; }
  .qty-stepper button { width: 34px; height: 34px; }

  /* Reorder so the buy controls come before the description. The body is already a flex column, so
     this is pure CSS — no markup or script change, and desktop keeps the original order. The
     description is the one block a shopper doesn't need before deciding to add to cart. */
  .modal-body > #modal-bulk { order: 1; }
  .modal-body > .modal-foot { order: 2; margin-top: 0; }
  .modal-body > .modal-desc { order: 3; margin: 14px 0 0; }

  /* The foot wraps on a phone, so this gap is the breathing room *below the price* before the
     buttons start. 16px reads as a deliberate break rather than a crowded stack. */
  .modal-foot { gap: 16px; }
  .modal-actions { gap: 10px; width: 100%; }
  /* Add to Cart and Buy Now share a row and stretch; "Ask on IG" drops to its own full-width line
     underneath. The default .btn padding renders these 66px tall — trimming to a 44px target keeps
     them comfortably tappable while giving ~60px back across the two rows. */
  /* The basis must be half the row MINUS half the gap, or the pair no longer fits on one line and
     silently stacks — which is exactly what a 10px gap against a `50% - 4px` basis did. */
  .modal-actions .btn {
    flex: 1 1 calc(50% - 5px);
    min-height: 44px;
    padding: 11px 14px;
    font-size: 12px;
  }
  /* order:3 puts "Ask on IG" *under* the two buy buttons. It's the secondary path, and having it
     take the first full-width row was pushing Add to Cart just past the fold. */
  .modal-actions .btn-outline[href] { flex: 1 1 100%; order: 3; }

  /* Bulk block: the compacting is all box — padding, row gaps, the rule above the note. Every font
     size here is untouched, so the ladder reads exactly as before in a shorter box. This is where
     the extra image height comes from. */
  .bulk-table { padding: 9px 13px 10px; gap: 3px; margin-bottom: 12px; }
  .bulk-table-head { font-size: 11px; margin-bottom: 0; }
  .bulk-row { font-size: 13px; line-height: 1.35; }
  .bulk-row-price i { font-size: 11px; }
  .bulk-note { font-size: 11.5px; line-height: 1.45; padding-top: 7px; margin-top: 3px; }

  /* Card pills too — 10px mono was tight on a phone. */
  .bulk-tier { font-size: 11px; padding: 5px 9px; }
  .bulk-strip-label { font-size: 10px; }
}

/* ================= TOUCH DEVICES ONLY — performance =================
   Everything below is gated on `(hover: none)`, which is true on phones and tablets and false on
   any machine with a mouse, so the desktop build never sees a single one of these rules.

   These are the four things measured as the dominant GPU cost on iPhone. Colours, layout, fonts,
   card design, pricing and the brand look are all untouched — what goes away is per-frame
   compositing work, not the design. */
/* ---------- cart tier feedback ---------- */
/* The saved row and the nudge answer two different questions — "did the discount land?" and
   "am I one piece short of a better one?" — so they read as separate objects, not one panel. */
.bulk-saved {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 14px 0 0;
  padding: 10px 14px;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--gray-900);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--gray-300);
}

.bulk-saved-amount {
  color: var(--white);
  font-size: 13px;
  letter-spacing: 0.04em;
}

.bulk-nudge {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 10px 0 0;
  padding: 11px 14px;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.02);
  border: 1px dashed var(--gray-800);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--gray-300);
}

/* The cliff case — where buying more costs less — is the one worth actually interrupting for. */
.bulk-nudge.is-cliff {
  border-style: solid;
  border-color: var(--gray-700);
  background: rgba(255, 255, 255, 0.05);
  color: var(--gray-100);
}

.bulk-nudge-icon {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  line-height: 1.5;
  color: var(--gray-500);
  flex-shrink: 0;
}

.bulk-nudge.is-cliff .bulk-nudge-icon { color: var(--white); }

.bulk-nudge-text b {
  color: var(--white);
  font-weight: 600;
}

.bulk-nudge-text em {
  display: block;
  margin-top: 3px;
  font-style: normal;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--white);
}

/* Per-line: the retail figure struck through, with the tier that replaced it named underneath. */
.checkout-item-tier {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--gray-300);
}

/* Stacked, not inline: side by side the two figures nearly double the price cell's width, and the
   cart row pays for it out of the product name — which then wraps to five or six lines. */
.checkout-item .price {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.25;
  white-space: nowrap;
  flex-shrink: 0;
}

.price-was {
  color: var(--gray-500);
  text-decoration-thickness: 1px;
  font-size: 0.72em;
}

/* Cart rows on a phone. Thumbnail, name, stepper, price and remove all sat on one flex line, which
   left the product name about 52px — one word per line, and a row nearly 250px tall before the tier
   line was ever added. Wrapping gives the name the full width and drops the controls to a second
   line, indented past the thumbnail so they read as belonging to it. */
@media (max-width: 560px) {
  .checkout-item {
    flex-wrap: wrap;
    row-gap: 10px;
    align-items: flex-start;
  }

  /* Basis is the full row minus the thumbnail and its gap, so the controls are pushed to line two. */
  .checkout-item-info { flex: 1 1 calc(100% - 56px); }

  .checkout-item .qty-stepper-sm { margin-left: 56px; }

  .checkout-item .price {
    margin-left: auto;
    align-self: center;
  }

  .checkout-item-remove { align-self: center; }
}

/* Shown when the server refuses an order — out of stock, or a price that no longer matches. */
.checkout-error{background:#2a1414;border:1px solid #5c2b2b;color:#fca5a5;border-radius:10px;
  padding:11px 13px;margin-bottom:14px;font-size:13px;line-height:1.55}

/* Shown in place of the card fields until a real payment processor is connected. */
.checkout-notice{background:var(--g950);border:1px solid var(--g800);border-radius:12px;
  padding:14px 16px;margin-bottom:18px;font-size:13px;line-height:1.6;color:var(--g300)}
.checkout-notice strong{color:var(--white);display:block;margin-bottom:4px}
.checkout-notice a{color:var(--white)}

@media (hover: none) {

  /* 1. Film grain. A viewport-sized `mix-blend-mode: overlay` layer forces Safari to re-composite
        the ENTIRE page through a blend on every single frame, which is what made scrolling drag.
        It was only 4.5% opacity, so its absence reads as a very slightly cleaner surface. */
  .noise { display: none; }

  /* 2. Backdrop blurs. Each one re-blurs whatever sits behind it every frame, and the header and
        footer are pinned on screen for the whole scroll. Dropping the blur alone would leave sharp
        page content showing through translucent bars, so each background steps up in opacity —
        same colour, same hue, just more of it — to keep the separation the blur was providing. */
  .site-header { backdrop-filter: none; background: rgba(10,10,11,0.94); }
  .site-footer { backdrop-filter: none; background: rgba(10,10,11,0.97); }
  .stack-card  { backdrop-filter: none; background: rgba(31,31,35,0.93); }
  /* one class covers the item, checkout, cart and orders overlays */
  .modal-overlay { backdrop-filter: none; background: rgba(6,6,7,0.94); }
  .lightbox-overlay { backdrop-filter: none; background: rgba(8,8,9,0.97); }

  /* 3. Skyline motion. The two bands are 192k and 383k pixels of permanently animating composited
        layer, so the GPU never goes idle even while the page sits still. The city itself stays
        exactly where it is and at the same opacity — only the drift stops. */
  .city-sky-far,
  .city-sky-near {
    animation: none;
    will-change: auto;
  }

  /* 4. The 3D tilt. It is driven entirely by `mousemove`, which a touch screen never fires, so on a
        phone it renders nothing while `will-change` pins all 45 `.tilt` elements — 20 product cards
        among them — onto permanent GPU layers. At rest the transform is identity and the glow is
        transparent, so removing it is pixel-identical to what the phone already displays. */
  .tilt {
    transform: none;
    transform-style: flat;
    transition: none;
    will-change: auto;
  }
  .tilt-glow { display: none; }
}


@media (max-width: 768px) {
  .intro {
    display: none !important;
  }

  body.intro-playing {
    overflow: auto !important;
  }
}
