/* ==========================================================================
   fashionplugrico — shared stylesheet
   --------------------------------------------------------------------------
   One buyer-facing storefront, deliberately its own identity from Trip's HQ's
   internal dark/purple shell. Palette is fixed (a Murakami flower-rug photo:
   cream / tan / cocoa / near-black). Typography is fixed: Archivo does all
   functional work; Unbounded is reserved for the wordmark alone.

   Because the catalog ships with no product photography, the visual system is
   typographic + color-field rather than image-led: the colorway swatch that
   stands in for a photo is treated as a real design material, scaled up on
   the product detail page. The home hero carries a number tag instead of a
   photo — see "Hero number tag" below.

   CASING CONVENTION: the brand layer is lowercase (wordmark, nav links) and
   the functional layer is sentence case (headings, buttons, labels). The store
   name "fashionplugrico" is lowercase everywhere, always.
   ========================================================================== */

:root {
  /* Palette — given, do not reinvent. */
  --bg: #f2e8d8;
  --surface: #fbf6ee;
  --ink: #241a13;
  --ink-muted: #8a7862;
  --border: #ddccb4;
  --accent: #5c3b26;
  --accent-soft: #c9a184;
  --success: #55724b;
  --error: #9c4234;

  /* Derived, not new hues:
     --on-accent  : cream, for text sitting on --accent.
     --ink-soft   : --ink-muted's hue darkened until it clears 4.5:1 on --bg.
                    --ink-muted measures 3.53:1 against the page canvas, which
                    clears the large-text bar but not the one for body copy —
                    and on this site every muted string (colorway, size run,
                    spec rows, fine print) is small. So secondary text uses
                    --ink-soft and --ink-muted stays defined as the palette's
                    own value, available for 24px+ display text.
     --line-quiet : border at low emphasis for inner rules.
     */
  --on-accent: #fbf6ee;
  --ink-soft: #6b5a48;
  --line-quiet: #e6d8c2;

  /* Hero color field — the backdrop the 3D object sits on, same warm family
     as the object's own material rather than tied to live stock. */
  --hero-a: #241a13;
  --hero-b: #c9a184;

  --font: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-wordmark: 'Unbounded', var(--font);

  /* Type scale */
  --t-xs: 12px;
  --t-sm: 13.5px;
  --t-base: 16px;
  --t-md: 18px;
  --t-lg: clamp(20px, 2.2vw, 24px);
  --t-xl: clamp(26px, 3.4vw, 36px);
  --t-2xl: clamp(32px, 5vw, 52px);

  /* Spacing */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 64px;
  --s-9: 96px;

  --radius: 3px;
  --gutter: clamp(20px, 4vw, 48px);
  --measure: 62ch;

  --fast: 0.15s;
  --mid: 0.25s;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  color-scheme: light;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--t-base);
  line-height: 1.55;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  overflow-x: clip;
  -webkit-tap-highlight-color: rgba(36, 26, 19, 0.08);
  touch-action: manipulation;
}

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

p { margin: 0; }

a { color: inherit; }

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

:where(a, button, input, select, [tabindex]):focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-radius: 1px;
}

/* The hidden attribute always wins over a component's display value. */
[hidden] { display: none !important; }

.skip-link {
  position: absolute;
  left: var(--gutter);
  top: -100px;
  z-index: 50;
  background: var(--ink);
  color: var(--on-accent);
  padding: 10px 16px;
  border-radius: var(--radius);
  font-weight: 700;
  font-size: var(--t-sm);
  text-decoration: none;
  transition: top var(--fast) var(--ease);
}

.skip-link:focus { top: 12px; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   Layout shell
   -------------------------------------------------------------------------- */

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

.page-main {
  flex: 1 0 auto;
  padding-bottom: var(--s-9);
}

.section { padding-block: clamp(var(--s-7), 8vw, var(--s-9)); }
.section--tight { padding-block: var(--s-7); }
.section + .section { border-top: 1px solid var(--line-quiet); }

/* --------------------------------------------------------------------------
   Wordmark — Unbounded lives here and nowhere else.
   -------------------------------------------------------------------------- */

.wordmark {
  font-family: var(--font-wordmark);
  font-weight: 800;
  letter-spacing: -0.03em;
  text-transform: lowercase;
  line-height: 1;
}

/* --------------------------------------------------------------------------
   Site header / nav
   -------------------------------------------------------------------------- */

/* Solid, not translucent. A see-through bar would need a backdrop blur to
   stay readable, and blur is the one texture this flat, border-led surface
   does not have anywhere else. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  padding-top: env(safe-area-inset-top);
}

/* Home only. Floats over the opening field. Ink while the rectangle is
   still sitting on the cream page; cream once the field fills the screen. */
.site-header--overlay {
  position: fixed;
  left: 0;
  right: 0;
  background: transparent;
  border-bottom-color: transparent;
}

.site-header--overlay.is-solid {
  background: var(--bg);
  border-bottom-color: var(--border);
}

.site-header--overlay.is-on-field .site-header__mark,
.site-header--overlay.is-on-field .site-nav a {
  color: var(--on-accent);
}

.site-header--plain { position: static; }

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: 60px;
  padding-block: var(--s-3);
}

/* The wordmark is fifteen wide lowercase letters; at 18px it plus the nav
   overruns a 320px screen, so it steps down on the narrowest phones rather
   than pushing the nav off the edge. */
.site-header__mark {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: clamp(15px, 4.6vw, 18px);
  text-decoration: none;
  color: var(--ink);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

.site-nav a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--s-3);
  font-size: var(--t-sm);
  font-weight: 600;
  text-transform: lowercase;
  text-decoration: none;
  color: var(--ink-soft);
  transition: color var(--fast) var(--ease);
}

.site-nav a::after {
  content: '';
  position: absolute;
  left: var(--s-3);
  right: var(--s-3);
  bottom: 12px;
  height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--mid) var(--ease);
}

.site-nav a:hover { color: var(--ink); }
.site-nav a:hover::after { transform: scaleX(1); }

/* Three links plus the wordmark overrun a phone at full padding, so the
   links tighten up below 480px. Tap height stays 44px. */
@media (max-width: 480px) {
  .site-header__inner { gap: var(--s-2); }
  .site-nav { gap: 0; }
  .site-nav a { padding-inline: var(--s-2); }
}
@media (max-width: 359px) {
  .site-nav a { padding-inline: var(--s-1); }
}

.site-nav a[aria-current='page'] {
  color: var(--ink);
}

.site-nav a[aria-current='page']::after { transform: scaleX(1); }

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 48px;
  padding: 12px 26px;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--on-accent);
  font-family: inherit;
  font-size: var(--t-base);
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
  transition: background-color var(--mid) var(--ease), color var(--mid) var(--ease), border-color var(--mid) var(--ease);
}

.btn > span { position: relative; z-index: 1; }

/* Fill wipe on hover — the interaction, not decoration: the button inverts to
   confirm it is the thing that moves you forward. */
.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--ink);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform var(--mid) var(--ease);
}

.btn:hover { border-color: var(--ink); }
.btn:hover::before { transform: scaleY(1); }

.btn:active { transform: translateY(1px); }

.btn:disabled,
.btn[aria-disabled='true'] {
  opacity: 0.55;
  cursor: default;
  pointer-events: none;
}

.btn--ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--border);
}

.btn--ghost::before { background: var(--ink); }
.btn--ghost:hover { color: var(--on-accent); }

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

@media (prefers-reduced-motion: reduce) {
  .btn::before { display: none; }
  .btn:hover { background: var(--ink); }
  .btn--ghost:hover { background: var(--ink); color: var(--on-accent); }
  .btn:active { transform: none; }
}

/* Quiet text link with a back-arrow glyph drawn in CSS, not typed into copy. */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 44px;
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--ink-soft);
  text-decoration: none;
  transition: color var(--fast) var(--ease);
}

/* The rule slides rather than the gap growing — nudging `gap` would relayout
   the link on every hover frame. */
.back-link::before {
  content: '';
  width: 14px;
  height: 1.5px;
  background: currentColor;
  position: relative;
  transition: transform var(--fast) var(--ease);
}

.back-link:hover { color: var(--ink); }
.back-link:hover::before { transform: translateX(-4px); }

@media (prefers-reduced-motion: reduce) {
  .back-link::before { transition: none; }
}

.text-link {
  position: relative;
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1.5px solid var(--accent-soft);
  padding-bottom: 1px;
  transition: border-color var(--fast) var(--ease);
}

/* The underline has to sit tight against the text, so the tap target is grown
   behind it instead of by padding — full 44px height, no layout change. */
.text-link::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 44px;
  transform: translateY(-50%);
}

.text-link:hover { border-color: var(--ink); }

/* --------------------------------------------------------------------------
   Media: real photo, or the colorway swatch standing in for one.
   Ported from the single-page storefront — tested logic, unchanged behavior.
   -------------------------------------------------------------------------- */

.media {
  position: relative;
  width: 100%;
  overflow: hidden;
  background: var(--bg);
  border-radius: 2px;
}

.media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.media__inner {
  width: 100%;
  height: 100%;
  will-change: transform;
}

.swatch {
  width: 100%;
  height: 100%;
  position: relative;
}

.swatch--speckled::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(255, 255, 255, 0.5) 1px, transparent 1.6px);
  background-size: 9px 9px;
  opacity: 0.5;
}

.photo-soon {
  position: absolute;
  left: 8px;
  bottom: 8px;
  z-index: 2;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--ink-soft);
  font-size: var(--t-xs);
  font-weight: 600;
  padding: 4px 8px;
  border-radius: 2px;
}

/* --------------------------------------------------------------------------
   Opening field — Balatro rectangle that grows to the viewport on scroll.
   --p is 0 at rest and 1 when the box has filled the screen. motion.js
   writes it. The CSS fallback (no JS) is the small rectangle.
   -------------------------------------------------------------------------- */

.expand {
  --p: 0;
  --mark-w: 320px;
  --mark-h: 78px;
  --cx: 50%;
  --cy: 42%;
  height: 220vh;
  position: relative;
}

.expand__sticky {
  position: sticky;
  top: 0;
  height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.expand__panel {
  position: absolute;
  z-index: 0;
  overflow: hidden;
  left: 50%;
  top: 50%;
  width: var(--mark-w);
  height: var(--mark-h);
  transform: translate(-50%, -50%);
  border-radius: calc((1 - var(--p)) * 10px);
  background: var(--hero-a);
  box-shadow: 0 18px 50px rgba(36, 26, 19, calc((1 - var(--p)) * 0.18));
}

.expand__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.expand__stack {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: min(40rem, calc(100% - 32px));
}

.expand__mark {
  margin: 0;
  text-align: center;
  white-space: nowrap;
  color: var(--on-accent);
  font-size: clamp(22px, 6.2vw, 64px);
  text-shadow: 0 2px 28px rgba(36, 26, 19, 0.45);
}

.expand__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 22px;
}

.expand .btn--line {
  min-height: 0;
  padding: 7px 14px;
  background: transparent;
  color: color-mix(in srgb, var(--ink) calc((1 - var(--p)) * 100%), var(--on-accent));
  border: 1px solid color-mix(in srgb, var(--ink) calc((1 - var(--p)) * 100%), var(--on-accent));
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  border-radius: 4px;
}

.expand .btn--line::before { display: none; }
.expand .btn--line:hover { background: transparent; }

/* Primary action. Fills with ink as the field opens so the label stays
   readable on the light parts of the shader. Reviews stays an outline. */
.expand .btn--stock {
  background: color-mix(in srgb, var(--ink) calc(var(--p) * 100%), transparent);
  border-color: var(--ink);
}

.expand .btn--stock:hover {
  background: var(--ink);
  color: var(--on-accent);
}

.expand__notes {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin-top: 16px;
}

.expand__notes .fold-text {
  color: color-mix(in srgb, var(--ink) calc((1 - var(--p)) * 100%), var(--on-accent));
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.expand__fold {
  position: absolute;
  z-index: 1;
  left: 50%;
  bottom: 36px;
  width: min(34rem, calc(100% - 40px));
  transform: translateX(-50%);
  text-align: center;
  color: color-mix(in srgb, var(--ink) calc((1 - var(--p)) * 100%), var(--on-accent));
  font-size: clamp(15px, 2vw, 20px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.15;
}

/* Fold Text, from React Bits. Letters hinge down from the top as the page scrolls. */
.fold-text-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.fold-text-segment {
  display: inline-block;
  perspective: 700px;
  transform-style: preserve-3d;
  vertical-align: baseline;
}

.fold-text-piece {
  position: relative;
  display: inline-block;
  transform-style: preserve-3d;
  backface-visibility: hidden;
  transform-origin: 50% 0%;
}

.fold-text-piece::after {
  content: '';
  position: absolute;
  inset: -0.08em -0.02em;
  pointer-events: none;
  opacity: var(--fold-crease, 0);
  border-radius: 0.08em;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.58) 0%, rgba(0, 0, 0, 0.22) 42%, rgba(255, 255, 255, 0.26) 100%);
}

.expand__mark .ch {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.18em;
  margin-bottom: -0.18em;
}

.expand__mark .ch > i {
  display: inline-block;
  font-style: normal;
}

@media (prefers-reduced-motion: reduce) {
  .expand { height: auto; }
  .expand__sticky { position: relative; height: 100dvh; }
  .expand__panel { --p: 1; box-shadow: none; }
}

/* --------------------------------------------------------------------------
   Home intro, under the opening field
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  padding-top: clamp(var(--s-7), 8vw, var(--s-9));
  padding-bottom: clamp(var(--s-6), 5vw, var(--s-7));
}

/* Unbounded's lowercase runs about 0.65em per character, so the fifteen
   letters of the wordmark measure roughly 9.8em. This is the mobile rule,
   where .hero__body is still a single column and the mark has the full
   content width to itself: the ceiling fills about 90% of that width — big
   enough to be the hero object, never close enough to the edge to risk
   clipping if the face metrics shift. Below 860px .hero__tag stacks
   underneath rather than sharing a row, so there is nothing to overlap.
   Light rather than --ink now that the mark sits on the color field
   instead of the page's own cream background. */
.hero__mark {
  font-size: clamp(26px, 8.6vw, 100px);
  margin-bottom: clamp(var(--s-4), 3vw, var(--s-6));
  white-space: nowrap;
  color: var(--on-accent);
}

/* Per-character mask for the entrance reveal. Padding + negative margin keep
   the descenders on p and g inside the clip box. */
.hero__mark .ch {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.18em;
  margin-bottom: -0.18em;
}

.hero__mark .ch > i {
  display: inline-block;
  font-style: normal;
}

/* Copy sits at the top of the row, hard under the wordmark, aligned with
   the tag grid rather than centred against it — centring it would open a
   dead band across the middle now that both sit on the same full field. */
.hero__body {
  display: grid;
  gap: clamp(var(--s-5), 4vw, var(--s-7));
  align-items: start;
}

.hero__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-5);
  max-width: 34ch;
}

.hero__line {
  font-size: var(--t-lg);
  line-height: 1.35;
  font-weight: 500;
  letter-spacing: -0.015em;
  text-wrap: balance;
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Hero number tag
   --------------------------------------------------------------------------
   A plain count from 0 to 23, laid out 10/7/7 the way a size-run tag reads,
   sitting in its own column of .hero__body rather than a boxed field of its
   own -- the whole section is the color field now, so this is just content
   on it, not an object with a stage. motion.js measures each .num's center
   once fonts are ready and drives .hero__tag-circle's transform straight
   off scroll position -- 1:1, no easing of its own, the same "no lag" rule
   the old scroll-bound dial used. The circle starts hidden and motion.js
   reveals it only once it has real coordinates to place it at, so a JS
   failure leaves a clean static number grid rather than a circle stranded
   at the origin. */

.hero__tag {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: clamp(180px, 24vw, 300px);
}

.hero__tag-grid {
  position: relative;
  font-size: clamp(16px, 2vw, 25px);
}

.hero__tag-row {
  display: flex;
  gap: 0.5em;
  margin: 0 0 0.16em;
}

.hero__tag-row:last-child {
  margin-bottom: 0;
}

.hero__tag .num {
  display: inline-block;
  min-width: 1.05em;
  text-align: center;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--on-accent);
}

.hero__tag-circle {
  position: absolute;
  left: 0;
  top: 0;
  width: 1.7em;
  height: 1.7em;
  border-radius: 50%;
  border: 2px solid var(--on-accent);
  pointer-events: none;
  opacity: 0;
}

.hero__tag-circle.is-placed {
  opacity: 1;
}

@media (min-width: 860px) {
  .hero__body {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  }

  /* The mobile rule above sizes the mark against the full content width, but
     from here down .hero__mark shares its row with .hero__tag and only
     owns the narrower of the two columns (1 part of 2.05, minus the row
     gap) — left uncorrected the mark's natural width blew straight past its
     column and ran under the field, which painted over "grico". Same 9.8em/
     90%-of-column logic as the mobile rule, just measured against the actual
     column instead of the whole shell. */
  .hero__mark {
    font-size: clamp(26px, 3.9vw, 46px);
  }
}

/* --------------------------------------------------------------------------
   Stock strip on home
   -------------------------------------------------------------------------- */

.strip-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  margin-bottom: var(--s-5);
}

.strip-head h2,
.section-title { font-size: var(--t-xl); }

.section-title { margin-bottom: var(--s-4); }

.stock-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--border);
}

.stock-row {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-4);
  padding-block: var(--s-4);
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  color: inherit;
  transition: background-color var(--fast) var(--ease), transform var(--mid) var(--ease);
}

/* Transform, not padding: a padding shift on hover relayouts the whole row. */
.stock-row:hover {
  background: var(--surface);
  transform: translateX(6px);
}

@media (prefers-reduced-motion: reduce) {
  .stock-row { transition: background-color var(--fast) var(--ease); }
  .stock-row:hover { transform: none; }
}

.stock-row .media {
  aspect-ratio: 1;
  border: 1px solid var(--border);
}

.stock-row__name {
  font-weight: 700;
  letter-spacing: -0.015em;
}

.stock-row__meta {
  font-size: var(--t-sm);
  color: var(--ink-soft);
}

.stock-row__price {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   How it works — three facts, no numbering (it is not a sequence)
   -------------------------------------------------------------------------- */

.facts {
  display: grid;
  gap: var(--s-5);
  margin-top: var(--s-6);
}

@media (min-width: 720px) {
  .facts { grid-template-columns: minmax(0, 42rem); gap: var(--s-6); }
}

.fact {
  position: relative;
  border-top: 2px solid var(--ink);
  padding-top: var(--s-4);
}

.fact::before {
  content: '';
  position: absolute;
  left: -16px;
  right: -16px;
  top: 0;
  bottom: -8px;
  background: radial-gradient(280px circle at var(--mx, 50%) var(--my, 0%), rgba(201, 161, 132, 0.45), transparent 60%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s var(--ease);
}

.fact.is-lit::before { opacity: 1; }

.fact h3 {
  font-size: var(--t-md);
  margin-bottom: var(--s-2);
}

.fact p {
  font-size: var(--t-sm);
  color: var(--ink-soft);
  max-width: 34ch;
}

.ship-list {
  list-style: none;
  margin: var(--s-6) 0 0;
  padding: 0;
  max-width: 42rem;
}

.ship-list li {
  padding-block: var(--s-3);
  border-top: 1px solid var(--line-quiet);
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: -0.015em;
}

.ship-list li:last-child { border-bottom: 1px solid var(--line-quiet); }

.delivery {
  margin: var(--s-5) 0 0;
  font-size: var(--t-md);
  font-weight: 700;
}

/* --------------------------------------------------------------------------
   Page heading block
   -------------------------------------------------------------------------- */

.page-head {
  padding-block: clamp(var(--s-6), 6vw, var(--s-8)) var(--s-6);
}

.page-head h1 { font-size: var(--t-2xl); }

.page-head p {
  margin-top: var(--s-3);
  color: var(--ink-soft);
  max-width: var(--measure);
}

/* --------------------------------------------------------------------------
   Shop: model sections + product grid
   -------------------------------------------------------------------------- */

.model-filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-bottom: var(--s-6);
  padding-bottom: var(--s-5);
  border-bottom: 1px solid var(--border);
}

.model-filter a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--s-4);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: var(--t-sm);
  font-weight: 600;
  text-decoration: none;
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}

.model-filter a:hover {
  border-color: var(--ink);
}

.model-filter a[aria-current='true'] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--on-accent);
}

.model-section + .model-section { margin-top: var(--s-8); }

.model-section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-5);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--border);
}

.model-section__head h2 {
  font-size: var(--t-lg);
}

.model-section__count {
  font-size: var(--t-sm);
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
  gap: clamp(var(--s-4), 2.5vw, var(--s-6));
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color var(--mid) var(--ease);
}

.card:hover { border-color: var(--accent); }
.card:focus-within { border-color: var(--ink); }

.card .media { aspect-ratio: 1; }

.card__body {
  padding: var(--s-4);
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}

.card__name {
  font-size: var(--t-md);
  font-weight: 700;
  letter-spacing: -0.015em;
}

/* Stretched link: the whole card is clickable, but the size links below sit
   above it so they stay individually reachable — no nested <a> elements. */
.card__link {
  text-decoration: none;
  color: inherit;
}

.card__link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
}

.card__colorway {
  font-size: var(--t-sm);
  color: var(--ink-soft);
}

.card__price {
  margin-top: var(--s-2);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.size-row {
  position: relative;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  padding: 0 var(--s-4) var(--s-4);
  margin-top: auto;
}

.size-link,
.size-option {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 48px;
  min-height: 44px;
  padding-inline: var(--s-3);
  border: 1px solid var(--border);
  border-radius: 2px;
  background: var(--bg);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--t-sm);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}

.size-link:hover,
.size-option:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--on-accent);
}

/* --------------------------------------------------------------------------
   Product detail
   -------------------------------------------------------------------------- */

.product {
  display: grid;
  gap: clamp(var(--s-5), 4vw, var(--s-8));
  align-items: start;
}

@media (min-width: 900px) {
  .product { grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr); }
}

.product__media {
  aspect-ratio: 4 / 3;
  border: 1px solid var(--border);
}

@media (min-width: 900px) {
  .product__media {
    position: sticky;
    top: 92px;
  }
}

.product__info {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}

.product__title { font-size: var(--t-xl); }

.product__colorway {
  margin-top: var(--s-2);
  color: var(--ink-soft);
}

.product__price {
  font-size: var(--t-lg);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.product__desc {
  font-size: var(--t-base);
  color: var(--ink);
  max-width: 46ch;
}

.product__desc + .product__desc { margin-top: var(--s-3); }

.field-group {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.field-group legend,
.field-label {
  padding: 0;
  font-size: var(--t-sm);
  font-weight: 700;
  color: var(--ink);
}

.size-picker {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}

/* Native radios kept in the DOM for keyboard + screen reader support; the
   visible chip is the label. */
.size-picker input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 1px;
  height: 1px;
}

.size-picker input:checked + .size-option {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

.size-picker input:focus-visible + .size-option {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.spec {
  margin: 0;
  border-top: 1px solid var(--border);
}

.spec__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding-block: var(--s-3);
  border-bottom: 1px solid var(--line-quiet);
}

.spec dt {
  font-size: var(--t-sm);
  color: var(--ink-soft);
}

.spec dd {
  margin: 0;
  font-size: var(--t-sm);
  font-weight: 600;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Checkout — deliberately motionless. No transitions, no reveals, nothing
   that could read as instability while someone is handing over money.
   -------------------------------------------------------------------------- */

.checkout-layout {
  width: 100%;
  max-width: 560px;
  margin-inline: auto;
}

.summary {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--s-3);
}

.summary .media {
  width: 64px;
  height: 64px;
  flex-shrink: 0;
  border: 1px solid var(--border);
}

.summary__info { flex: 1; min-width: 0; }

.summary__name {
  font-weight: 700;
  letter-spacing: -0.015em;
  overflow-wrap: break-word;
}

.summary__meta {
  font-size: var(--t-sm);
  color: var(--ink-soft);
}

.summary__price {
  font-weight: 700;
  font-size: var(--t-md);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.form-stack {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  margin-top: var(--s-6);
}

.form-section-title {
  font-size: var(--t-sm);
  font-weight: 700;
  margin-top: var(--s-3);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--border);
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.field label {
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--ink);
}

.field label .optional {
  font-weight: 400;
  color: var(--ink-soft);
}

.field input {
  min-height: 48px;
  width: 100%;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 10px 12px;
  font-family: inherit;
  font-size: var(--t-base);
}

.field input::placeholder { color: var(--ink-soft); }

.field input:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
  border-color: var(--ink);
}

.field input[aria-invalid='true'] { border-color: var(--error); }

.field-error {
  font-size: var(--t-sm);
  color: var(--error);
  font-weight: 600;
}

.field-row {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

/* On the narrowest phones a split row leaves each field too cramped to read
   what has been typed into it. */
@media (max-width: 380px) {
  .field-row { grid-template-columns: minmax(0, 1fr); }
}

.note {
  font-size: var(--t-sm);
  color: var(--ink-soft);
  max-width: var(--measure);
}

.alert {
  border: 1px solid var(--error);
  border-left-width: 3px;
  border-radius: 2px;
  background: var(--surface);
  color: var(--error);
  font-size: var(--t-sm);
  font-weight: 600;
  padding: var(--s-3) var(--s-4);
}

.confirm {
  max-width: 520px;
  margin-inline: auto;
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: clamp(var(--s-6), 6vw, var(--s-8)) var(--s-5);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-4);
}

.confirm__icon { color: var(--success); }

.confirm h1 { font-size: var(--t-xl); }

.confirm p {
  color: var(--ink-soft);
  max-width: 44ch;
}

/* --------------------------------------------------------------------------
   About
   -------------------------------------------------------------------------- */

.prose {
  max-width: var(--measure);
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}

.prose p { font-size: var(--t-md); }

.prose p.lede {
  font-size: var(--t-lg);
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.4;
}

/* --------------------------------------------------------------------------
   Reviews
   -------------------------------------------------------------------------- */

.review-stars {
  color: var(--accent);
  letter-spacing: 0.08em;
  font-size: var(--t-md);
  line-height: 1;
}

.review-summary {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding-bottom: var(--s-5);
  border-bottom: 1px solid var(--border);
}

.review-summary__score {
  font-size: var(--t-2xl);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.review-summary__count {
  margin-top: 6px;
  font-size: var(--t-sm);
  color: var(--ink-soft);
}

.review-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: var(--measure);
}

.review {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding-block: var(--s-5);
  border-bottom: 1px solid var(--border);
}

.review__text {
  font-size: var(--t-md);
  overflow-wrap: anywhere;
}

.review__meta {
  font-size: var(--t-sm);
  color: var(--ink-soft);
}

.review-form {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  max-width: 560px;
  margin-bottom: var(--s-6);
  padding: var(--s-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.review-form__title { font-size: var(--t-lg); }

.review-form .btn { align-self: flex-start; }

.review-form .field input { background: var(--bg); }

#review-write .confirm { margin: 0 0 var(--s-6); }

.star-picker {
  display: flex;
  gap: var(--s-1);
}

.star-picker__star {
  min-width: 44px;
  min-height: 44px;
  font-size: 30px;
  line-height: 1;
  color: var(--accent);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

.star-picker__star:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.field textarea {
  width: 100%;
  min-height: 112px;
  resize: vertical;
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 10px 12px;
  font-family: inherit;
  font-size: var(--t-base);
}

.field textarea:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
  border-color: var(--ink);
}

/* Bundle deal — a real, dated offer (api/_deals.js). */
.deal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  padding: 14px 16px;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
  animation: deal-in 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.deal--banner { margin-bottom: var(--s-5); }

.deal__tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.deal__tag::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  animation: deal-pulse 1.6s ease-in-out infinite;
}

.deal__line {
  flex: 1 1 16rem;
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--ink);
}

.deal__link {
  font-size: var(--t-sm);
  font-weight: 800;
  color: var(--accent);
  text-underline-offset: 3px;
  transition: letter-spacing 0.25s ease;
}

.deal__link:hover { letter-spacing: 0.02em; }

.price-was {
  color: var(--ink-soft);
  font-weight: 500;
  margin-right: 2px;
}

.summary__totals { margin-top: var(--s-3); }
.summary__totals .spec__row:last-child dd { font-size: var(--t-md); }

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

@keyframes deal-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

/* Make an offer — under Buy on product pages. */
.offer { display: flex; flex-direction: column; gap: var(--s-3); }
.offer__toggle {
  align-self: flex-start;
  background: none;
  border: 0;
  padding: 6px 0;
  cursor: pointer;
  font-family: inherit;
  text-decoration: underline;
}
.offer__form {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: var(--s-4);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  animation: deal-in 0.35s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.offer__form .field input { background: var(--bg); }
.offer__form .btn { align-self: flex-start; }

/* Admin */
.admin { max-width: 720px; }
.admin-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  margin-bottom: var(--s-6);
  padding: var(--s-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.admin-card h2 { font-size: var(--t-lg); }
.admin-pairs { display: flex; flex-direction: column; gap: 6px; }
.admin-pair {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: var(--bg);
  cursor: pointer;
}
.admin-pair__name { flex: 1; font-weight: 600; }
.admin-pair__price { font-variant-numeric: tabular-nums; }
.admin-select {
  min-height: 48px;
  width: 100%;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 10px 12px;
  font: inherit;
}
.admin-link { overflow-wrap: anywhere; font-weight: 600; }
.admin-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.admin-copy { min-height: 36px; padding: 6px 12px; font-size: var(--t-sm); }
.admin-signout {
  background: none;
  border: 0;
  font: inherit;
  color: var(--ink-soft);
  cursor: pointer;
  min-height: 44px;
}

/* Product gallery thumbnails */
.gallery-thumbs {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: 2px;
}

.gallery-thumb {
  flex: 0 0 64px;
  height: 64px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
  background: var(--surface);
  cursor: pointer;
  scroll-snap-align: start;
  opacity: 0.6;
  transition: opacity 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.gallery-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gallery-thumb:hover { opacity: 1; transform: translateY(-1px); }
.gallery-thumb[aria-pressed='true'] { opacity: 1; border-color: var(--ink); }
.gallery-thumb:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

@media (min-width: 900px) {
  .product__gallery {
    position: sticky;
    top: 92px;
    align-self: start;
  }
  .product__gallery .product__media { position: static; }
}

.product__media { background: var(--surface); }
.product__media img { object-fit: contain; transition: opacity 0.16s ease; }
.product__media img.is-swapping { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .deal, .deal__tag::before { animation: none; }
}

/* Depop proof — the earlier shop's reviews, clearly marked as from there. */
.depop-proof {
  margin-top: clamp(var(--s-6), 8vw, 72px);
  padding-top: var(--s-6);
  border-top: 2px solid var(--ink);
}

.depop-proof__head { margin-bottom: var(--s-5); }
.depop-proof__head h2 { font-size: var(--t-xl); }
.depop-proof__head p {
  margin-top: var(--s-2);
  color: var(--ink-soft);
  max-width: var(--measure);
}

.depop-proof .review-summary { flex-wrap: wrap; }

.depop-proof__link {
  margin-left: auto;
  font-size: var(--t-sm);
  font-weight: 700;
  color: var(--ink);
}

/* DM screenshots — phone-shaped, two up on wide screens. */
.dm-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 340px));
  gap: var(--s-5);
}

.dm-shot {
  margin: 0;
  border-radius: 22px;
  overflow: hidden;
  border: 1px solid var(--border);
  background: #0f1116;
  box-shadow: 0 18px 40px -24px rgba(36, 26, 19, 0.55);
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.35s ease;
}

.dm-shot:hover {
  transform: translateY(-4px) rotate(-0.4deg);
  box-shadow: 0 26px 50px -24px rgba(36, 26, 19, 0.6);
}

.dm-shot img {
  display: block;
  width: 100%;
  height: auto;
}

@media (prefers-reduced-motion: reduce) {
  .dm-shot, .dm-shot:hover { transition: none; transform: none; }
}

/* Hero proof badges under the two buttons; same ink-to-cream shift as
   the buttons while the field grows. */
.expand__badges {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}

.proof-badge {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-decoration: none;
  color: color-mix(in srgb, var(--ink) calc((1 - var(--p)) * 100%), var(--on-accent));
  background: color-mix(in srgb, var(--ink) calc(var(--p) * 35%), transparent);
  border: 1px solid color-mix(in srgb, var(--ink) calc((1 - var(--p)) * 40%), rgba(255, 255, 255, 0.45));
  transition: transform 0.2s ease;
}

.proof-badge:hover { transform: translateY(-1px); }

/* --------------------------------------------------------------------------
   Empty / error states
   -------------------------------------------------------------------------- */

.state {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-4);
  padding: var(--s-6);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.state p {
  color: var(--ink-soft);
  max-width: 44ch;
}

.skeleton {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  min-height: 320px;
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer {
  flex-shrink: 0;
  border-top: 1px solid var(--border);
  padding-bottom: max(var(--s-5), env(safe-area-inset-bottom));
  padding-top: var(--s-5);
}

.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
}

.site-footer__mark {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 15px;
  color: var(--ink);
  text-decoration: none;
}

.site-footer nav {
  display: flex;
  gap: var(--s-4);
}

.site-footer nav a {
  font-size: var(--t-sm);
  font-weight: 600;
  text-transform: lowercase;
  color: var(--ink-soft);
  text-decoration: none;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  /* Widens the hit area past the word without moving it. */
  padding-inline: var(--s-2);
  margin-inline: calc(var(--s-2) * -1);
}

.site-footer nav a:hover { color: var(--ink); }

.site-footer__fine {
  width: 100%;
  font-size: var(--t-xs);
  color: var(--ink-soft);
}

/* --------------------------------------------------------------------------
   Motion pre-state
   --------------------------------------------------------------------------
   Elements are only hidden ahead of an entrance when the inline head script
   has confirmed JS is running AND reduced motion is off. Without that class
   everything renders in its final state, so a failed CDN or a disabled script
   never leaves the page blank.
   -------------------------------------------------------------------------- */

html.anim [data-anim] { opacity: 0; }
html.anim [data-anim='mask'] { opacity: 1; }
html.anim .expand__mark .ch > i { transform: translateY(115%); }

/* Cross-document page transitions live in transitions.css, which checkout and
   the confirmation page deliberately do not load. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.28s;
  animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

/* Backstop. The individual reduced-motion rules above say what each effect
   should fall back to; this catches anything they miss, including transitions
   added later. GSAP is stood down separately, in motion.js. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
