/* ══════════════════════════════════════════════════════════════════════════
   Kessler storefront — site layer.
   Everything here is built on the Modernist tokens in
   _ds/modernist-.../styles.css. No hard-coded hex, font or spacing value
   that a token already carries. Zero radius, 2px section rules, flush left.
   ══════════════════════════════════════════════════════════════════════ */

:root {
  --hairline: var(--color-neutral-300);
  --rule: 2px solid var(--color-text);
  --hair: 1px solid var(--hairline);
  --gut: var(--space-6);
  --maxw: 1340px;
  --nav-h: 62px;
}

html { -webkit-text-size-adjust: 100%; }
body { font-size: 15px; }

/* ── layout ─────────────────────────────────────────────────────────── */
.wrap { max-width: var(--maxw); margin: 0 auto; padding-inline: var(--gut); }
.bleed { border-top: var(--rule); }
.stack { display: flex; flex-direction: column; }
.row { display: flex; align-items: center; }
.spread { display: flex; align-items: center; justify-content: space-between; }
.grow { flex: 1; }
main { display: block; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 99;
  background: var(--color-bg); border: 2px solid var(--color-text);
}
.skip:focus { left: var(--space-2); top: var(--space-2); }

.eyebrow {
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  font-weight: 600; color: var(--color-neutral-700);
}
.kicker {
  font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
  font-weight: 600; color: var(--color-accent-700);
}
.sec-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-4); padding: var(--space-6) 0 var(--space-3);
}
.sec-head h2 { font-size: 15px; letter-spacing: 0.1em; text-transform: uppercase; margin: 0; }
/* Filter chips beside a section head: smaller than a button proper, so they
   read as a control strip rather than as calls to action. */
.chiprow .btn { padding: 4px 10px; font-size: 12px; }
.muted { color: var(--color-neutral-600); }
.price { font-variant-numeric: tabular-nums; }
.mono { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }

/* ── announcement + header ──────────────────────────────────────────── */
.topbar {
  display: flex; justify-content: space-between; gap: var(--space-4);
  font-size: 11.5px; letter-spacing: 0.02em; color: var(--color-neutral-700);
  padding: 7px 0; border-bottom: var(--hair);
}
.topbar a { color: inherit; text-decoration: none; }
.topbar a:hover { color: var(--color-accent); }

.site-head { position: sticky; top: 0; z-index: 40; background: var(--color-bg); }
.site-nav {
  display: flex; align-items: center; gap: var(--space-6);
  height: var(--nav-h); border-bottom: var(--rule);
}
.brand {
  font-family: var(--font-heading); font-weight: 800; font-size: 21px;
  letter-spacing: 0.02em; text-decoration: none; color: var(--color-text);
  margin-right: auto;
}
.mainnav { display: flex; gap: var(--space-6); }
.mainnav a {
  font-size: 13.5px; letter-spacing: 0.04em; text-transform: uppercase;
  font-weight: 600; text-decoration: none; color: var(--color-text);
  padding-bottom: 2px; border-bottom: 2px solid transparent;
}
.mainnav a:hover { color: var(--color-accent); }
.mainnav a[aria-current="page"] { border-bottom-color: var(--color-text); }
.navtools { display: flex; align-items: center; gap: var(--space-1); margin-left: auto; }
.iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0; position: relative;
  background: transparent; border: 1px solid transparent; color: var(--color-text);
  cursor: pointer; text-decoration: none;
}
.iconbtn:hover { background: color-mix(in srgb, var(--color-text) 8%, transparent); }
.bagcount {
  position: absolute; top: 1px; right: 0;
  min-width: 15px; height: 15px; padding: 0 3px;
  display: flex; align-items: center; justify-content: center;
  font-size: 9px; font-weight: 800; font-family: var(--font-heading);
  background: var(--color-accent); color: var(--color-bg);
}
.bagcount[hidden] { display: none; }
.navtoggle { display: none; }

.ic { width: 18px; height: 18px; stroke-width: 1.75; }
.ic-sm { width: 14px; height: 14px; }

/* ── breadcrumb ─────────────────────────────────────────────────────── */
.crumb {
  display: flex; gap: 7px; font-size: 11.5px; color: var(--color-neutral-600);
  padding: var(--space-3) 0;
}
.crumb a { color: inherit; text-decoration: none; }
.crumb a:hover { color: var(--color-accent); }
.crumb [aria-current] { color: var(--color-text); }

/* ── image slots ────────────────────────────────────────────────────────
   A slot renders its placeholder until a real photograph is dropped into
   assets/img/. The <img> covers the placeholder; if the file is missing it
   removes itself and the labelled placeholder stays. Every photograph is
   grayscale per the system.                                              */
.ph {
  position: relative; overflow: hidden; background: var(--color-neutral-200);
  background-image:
    linear-gradient(to top right, transparent calc(50% - 0.5px), var(--color-neutral-300) calc(50% - 0.5px), var(--color-neutral-300) calc(50% + 0.5px), transparent calc(50% + 0.5px)),
    linear-gradient(to top left,  transparent calc(50% - 0.5px), var(--color-neutral-300) calc(50% - 0.5px), var(--color-neutral-300) calc(50% + 0.5px), transparent calc(50% + 0.5px));
  display: flex; align-items: flex-end;
}
.ph > img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; filter: grayscale(1) contrast(1.08);
}
.ph-label {
  position: relative; margin: var(--space-2);
  font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--color-neutral-700); background: var(--color-bg);
  padding: 2px 6px; border: var(--hair);
}
/* Once a real photograph is in the slot the caption is redundant — the <img>
   only survives in the DOM when the file loaded, so this hides it exactly
   when there is something to see. */
.ph:has(> img) .ph-label { display: none; }

.ph-1-1 { aspect-ratio: 1 / 1; }
.ph-3-2 { aspect-ratio: 3 / 2; }
.ph-4-5 { aspect-ratio: 4 / 5; }
.ph-fill { height: 100%; }

/* ── homepage hero ──────────────────────────────────────────────────── */
/* The hero holds most of the viewport: it gives the scrubbed film room to run
   while it is still the thing you are looking at, rather than racing through
   its last frames on the way off screen. */
.hero { display: grid; grid-template-columns: 1fr 1fr; border-bottom: var(--rule); }
/* 84vh made the media cell strongly portrait, and object-fit: cover then cut
   ~40% off the sides of a landscape clip — the bag lost its own edges. At 70vh
   the cell sits near the clip's own proportion and the crop drops to ~29%. */
@media (min-width: 861px) { .hero { min-height: min(70vh, 660px); } }
.hero-copy {
  display: flex; flex-direction: column; align-items: flex-start;
  justify-content: center;
  gap: var(--space-4); padding: var(--space-8) var(--space-8) var(--space-8) 0;
  border-right: var(--rule);
}
.hero-copy h1 {
  font-size: clamp(34px, 4.4vw, 58px); line-height: 0.98;
  letter-spacing: -0.025em; margin: 0; max-width: 12ch;
}
.hero-copy p { max-width: 40ch; margin: 0; color: var(--color-neutral-800); }
.hero-media { position: relative; min-height: 420px; }
/* The cell is squarer than the clip, so cover has to crop the sides. The bag
   sits right of centre when the shot is wide and drifts to centre as the camera
   pushes in — biasing the crop to 66% keeps the whole piece in frame at both
   ends instead of shaving its edge off. */
.hero-media .ph > img,
.hero-media .ph > video { object-position: 66% center; }

.btnrow { display: flex; gap: var(--space-2); flex-wrap: wrap; }
/* Labels flush left inside any button wider than its text. */
.btn { justify-content: flex-start; text-align: left; }
.btn-lg { padding: var(--space-3) var(--space-4); font-size: 14px; }
.btn-disabled { opacity: .45; pointer-events: none; }

/* ── modular cell grids ─────────────────────────────────────────────── */
.cells { display: grid; border-top: var(--hair); }
.cells > * { border-right: var(--hair); border-bottom: var(--hair); padding: var(--space-4); }
.cells-5 { grid-template-columns: repeat(5, 1fr); }
.cells-4 { grid-template-columns: repeat(4, 1fr); }
.cells-3 { grid-template-columns: repeat(3, 1fr); }
.cells-5 > *:nth-child(5n), .cells-4 > *:nth-child(4n), .cells-3 > *:nth-child(3n) { border-right: 0; }

.cat {
  display: flex; flex-direction: column; gap: var(--space-2);
  text-decoration: none; color: inherit;
}
.cat:hover .ph > img { filter: grayscale(1) contrast(1.2); }
.cat:hover .cat-name { color: var(--color-accent); }
.cat-name { font-family: var(--font-heading); font-weight: 800; font-size: 14px; }

/* ── product card ───────────────────────────────────────────────────── */
.prod {
  display: flex; flex-direction: column; gap: var(--space-2);
  text-decoration: none; color: inherit; position: relative;
}
.prod-media { position: relative; }
.prod-flag {
  position: absolute; top: var(--space-2); left: var(--space-2); z-index: 2;
  font-size: 9.5px; letter-spacing: 0.1em; font-weight: 800;
  font-family: var(--font-heading);
  background: var(--color-accent); color: var(--color-bg); padding: 2px 6px;
}
.prod-name { font-family: var(--font-heading); font-weight: 800; font-size: 14px; line-height: 1.25; }
.prod-meta { font-size: 11.5px; color: var(--color-neutral-600); }
.prod-price { font-size: 13.5px; }
.prod:hover .prod-name { color: var(--color-accent); }

/* The whole card is the target. The name stays the real <a>, so the tab stop
   and the accessible name are still the product; its ::after is stretched over
   the card to catch the click. Wrapping the card in an anchor instead would
   nest the Quick view button inside a link — invalid, and it breaks both.
   Quick view sits above the stretched link so it stays independently
   clickable. */
.prod { cursor: pointer; }
.prod-name::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.quickview { z-index: 3; }
/* The cell clips, so the focus ring is drawn just inside the card rather than
   outside it, where overflow would eat it. */
.prod-name:focus-visible { outline: none; }
.prod-name:focus-visible::after { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.cat:focus-visible { outline-offset: -2px; }
.quickview {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  padding: var(--space-2); font-size: 12px; font-weight: 800;
  font-family: var(--font-heading); text-align: left;
  background: var(--color-text); color: var(--color-bg);
  border: 0; cursor: pointer; opacity: 0; translate: 0 6px;
  transition: opacity .12s linear, translate .12s linear;
}
.prod-media:hover .quickview, .quickview:focus-visible { opacity: 1; translate: 0 0; }
@media (hover: none) { .quickview { opacity: 1; translate: 0 0; } }

/* ── the one red field ──────────────────────────────────────────────── */
.poster {
  background: var(--color-accent); color: var(--color-bg);
  padding: var(--space-8) 0;
}
.poster h2 {
  font-size: clamp(28px, 4vw, 48px); line-height: 1; letter-spacing: -0.025em;
  margin: 0 0 var(--space-4); max-width: 16ch;
}
.poster p { max-width: 46ch; margin: 0 0 var(--space-4); opacity: .92; }
.signup { display: flex; max-width: 460px; }
.signup .input {
  flex: 1; background: transparent; border: 2px solid var(--color-bg);
  color: var(--color-bg); min-height: 44px;
}
.signup .input::placeholder { color: color-mix(in srgb, #fff 65%, transparent); }
.signup .input:hover, .signup .input:focus-visible { border-color: var(--color-bg); }
.signup button {
  border: 2px solid var(--color-bg); border-left: 0; background: var(--color-bg);
  color: var(--color-accent); font-family: var(--font-heading); font-weight: 800;
  font-size: 14px; padding-inline: var(--space-4); cursor: pointer;
}
.signup button:hover { background: var(--color-accent-100); }
.poster :focus-visible { outline-color: var(--color-bg); }

/* ── full-bleed plate ────────────────────────────────────────────────
   One wide film held edge to edge between two rules. No type over it — the
   frame changes brightness as the figure crosses, so a caption underneath is
   the honest place for it. */
.plate { border-top: var(--rule); border-bottom: var(--rule); margin-top: var(--space-8); }
.plate-media { aspect-ratio: 16 / 9; max-height: 86vh; width: 100%; }
/* When the viewport is too short for a full 16:9 the frame has to crop. Bias
   it upward so the crop eats floor rather than the walker's head. */
.plate-media > img, .plate-media > video { object-position: center 30%; }
/* Copy sits over the empty left half of the frame. That region never darkens
   past Y 150, so ink on it already clears AA — but the scrub changes the field
   under the type as the figure crosses, and type whose ground moves reads as
   unanchored. So the block is set on a paper panel: the ground stays fixed,
   contrast stops depending on the frame, and the plate gets a masthead rather
   than a caption. The panel is held well clear of the walker's path. */
/* Media and copy share one grid cell rather than the copy being absolutely
   positioned over the frame. Stacking this way, the row takes the height of
   whichever is taller, so the panel can never outgrow the frame and spill —
   which is what forced the copy underneath on small screens before. */
.plate { position: relative; display: grid; }
.plate-media, .plate-copy { grid-area: 1 / 1; }
.plate-copy {
  position: relative; z-index: 2;
  /* .wrap's auto margins would shrink-wrap a grid item to its content and
     centre it, so the width is asserted; the max-width still holds the copy to
     the content column on wide screens. */
  width: 100%;
  display: flex; align-items: center;
  pointer-events: none;
}
.plate-copy > div {
  pointer-events: auto;
  max-width: min(46%, 34rem);
  display: flex; flex-direction: column; align-items: flex-start;
  gap: var(--space-4);
  padding: clamp(24px, 2.6vw, 40px);
  /* 94% paper: the frame reads faintly through the panel so it still belongs to
     the photograph, while ink on it holds ~15:1 against every frame. */
  background: color-mix(in srgb, var(--color-bg) 94%, transparent);
  border-top: var(--rule);
  border-bottom: var(--hair);
}
/* Where the browser can blur, the panel can be thinner and the frame carries
   further through it without costing contrast. */
@supports (backdrop-filter: blur(1px)) {
  .plate-copy > div {
    background: color-mix(in srgb, var(--color-bg) 86%, transparent);
    backdrop-filter: blur(10px) saturate(1.1);
  }
}
/* Honour a stated preference for solid surfaces. */
@media (prefers-reduced-transparency: reduce) {
  .plate-copy > div {
    background: var(--color-bg); backdrop-filter: none;
  }
}
/* The kicker carries a short rule so the panel opens on a mark, not on text. */
.plate-copy .kicker {
  display: flex; align-items: center; gap: var(--space-2);
}
.plate-copy .kicker::after {
  content: ""; width: clamp(24px, 4vw, 56px); height: 2px;
  background: currentColor;
}
/* Display size: this is the loudest heading on the page after the hero, so it
   is set larger, tighter and on a shorter measure than a section head. */
.plate-copy h2 {
  font-size: clamp(30px, 4.4vw, 64px); line-height: 0.98;
  letter-spacing: -0.03em; margin: 0; max-width: 12ch;
  text-wrap: balance;
}
.plate-copy p {
  margin: 0; font-size: clamp(14px, 1.05vw, 16px); line-height: 1.55;
  max-width: 34ch; color: var(--color-neutral-800); text-wrap: pretty;
}

/* Small screens keep the same composition — copy left, figure right — rather
   than dropping the copy underneath. Two things make that work: the frame turns
   portrait so there is room to stack, and the crop is biased right so the walker
   stays in frame while the left of the wall clears for type. The paper panel is
   dropped: at this size a box that wide reads as a card sitting on the picture
   rather than type in it, so the copy is set straight on the photograph and the
   contrast is carried by the crop plus the scrim below. */
@media (max-width: 860px) {
  .plate-media { aspect-ratio: 1 / 1; max-height: none; }
  .plate-media > img, .plate-media > video { object-position: 74% 30%; }
  .plate-copy > div {
    max-width: min(86%, 30rem);
    padding: 0;
    gap: var(--space-3);
    background: none; backdrop-filter: none;
    border-top: 0; border-bottom: 0;
  }
  .plate-copy h2 { font-size: clamp(28px, 7vw, 40px); max-width: 13ch; }
  /* Ink, not the softer grey, since this now sits on a photograph. */
  .plate-copy p { font-size: 15px; max-width: 30ch; color: var(--color-text); }
}
/* Without a panel the type depends on the frame under it, and the frame moves
   as the figure crosses. This lifts the bottom corner the copy occupies toward
   paper — no edge, no box, it reads as light falling off — so ink holds well
   past AA on every frame of the scrub. */
@media (max-width: 860px) {
  .plate-media::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background:
      linear-gradient(to top, color-mix(in srgb, var(--color-bg) 82%, transparent) 0%,
                              color-mix(in srgb, var(--color-bg) 30%, transparent) 38%,
                              transparent 62%);
  }
}
/* Phone: taller frame, since the copy takes a larger share of a narrow one and
   the figure needs height to stay legible above it. */
@media (max-width: 560px) {
  /* The ratio suits a phone; the cap stops it turning into a 900px column on a
     wider small-screen device or a short window. */
  .plate-media { aspect-ratio: 4 / 5; max-height: min(72vh, 560px); }
  /* With no panel to sit on, the type needs the figure and the bag out of its
     column; 85% is the crop that clears them without walking him off frame. */
  .plate-media > img, .plate-media > video { object-position: 85% 30%; }
  /* Set at the foot of the frame: centred, the copy would cut the figure in
     half; here it leaves the whole standing figure above it. */
  .plate-copy { align-items: flex-end; padding-block: var(--space-6); }
  .plate-copy > div { max-width: 100%; }
}

/* ── editorial split ────────────────────────────────────────────────── */
.split { display: grid; grid-template-columns: 1.15fr 1fr; border-top: var(--rule); }
.split-copy {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-8); border-left: var(--rule); justify-content: center;
}
.split-copy h2 { font-size: clamp(24px, 2.6vw, 34px); line-height: 1.04; letter-spacing: -0.02em; margin: 0; max-width: 14ch; }
.split-copy p { max-width: 42ch; margin: 0; color: var(--color-neutral-800); }

/* ── section lead ────────────────────────────────────────────────────
   A kicker over display type. Sections that carry only the small uppercase
   label read as captions next to the ones that have a headline, which is why
   the rules and the questions felt like footnotes. */
.band { padding-block: clamp(48px, 6vw, 88px); }
.section-lead { margin-bottom: var(--space-6); }
.section-lead h2 {
  font-size: clamp(28px, 3.2vw, 44px); line-height: 1.02;
  letter-spacing: -0.02em; margin: var(--space-2) 0 0; max-width: 18ch;
}
.section-lead p { margin: var(--space-3) 0 0; max-width: 52ch; font-size: 14.5px; }

/* ── dealt cells ─────────────────────────────────────────────────────
   The grid cell becomes the mask, so the padding has to move inside it —
   otherwise a card translated its own height down still shows through the
   cell's own padding, which overflow clips to. */
.cells > .deal, .results > .deal { padding: 0; overflow: hidden; }
.deal > .cat, .deal > .prod { padding: var(--space-4); height: 100%; }

/* ── drawn grids ─────────────────────────────────────────────────────
   A cell carries its own top rule as an element rather than a border, so the
   motion layer can draw it left to right. The line is structure, so it lives
   here and is present and correct with no JS at all. */
.cells-drawn { border-top: 0; }
.cells-drawn > * { position: relative; }
.cells-drawn > *::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: var(--hairline);
}

/* ── house rules ────────────────────────────────────────────────────── */
.rules-cells { border-top: 0; }
/* Every cell is padded on both sides so nothing sits against a divider; only
   the outer edges are trimmed, so the row still aligns flush with the page
   gutter at both ends. */
.rules-cells > * { padding: var(--space-6) var(--space-6) var(--space-8); }
.rules-cells > *:first-child { padding-left: 0; }
.rules-cells > *:last-child { padding-right: 0; }
.rule-cell { display: flex; flex-direction: column; gap: var(--space-3); align-items: flex-start; }
.rule-cell .ic { width: 28px; height: 28px; stroke-width: 1.4; color: var(--color-accent); }
.rule-num {
  font-family: var(--font-heading); font-weight: 800; font-size: 11px;
  letter-spacing: 0.12em; color: var(--color-accent);
}
.rule-cell h3 { font-size: 18px; line-height: 1.12; margin: 0; max-width: 14ch; }
.rule-cell p { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--color-neutral-700); }

/* ── questions ───────────────────────────────────────────────────────
   The heading holds the left column and the answers run down the right, the
   same split the workshop story uses. */
.faq { display: grid; grid-template-columns: 1fr 1.5fr; gap: clamp(32px, 5vw, 88px); }
.faq-head { align-self: start; position: sticky; top: calc(var(--nav-h) + var(--space-4)); }
.faq-head h2 {
  font-size: clamp(28px, 3.2vw, 44px); line-height: 1.02;
  letter-spacing: -0.02em; margin: var(--space-2) 0 var(--space-3); max-width: 14ch;
}
.faq-head p { margin: 0; font-size: 14.5px; max-width: 34ch; }

/* Rows sized to be read, not skimmed past. */
.faq .acc details { position: relative; border-bottom: 0; }
.faq .acc details::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--hairline);
}
.faq .acc summary { font-size: 17px; padding: var(--space-4) 0; }
.faq .acc .acc-body { font-size: 14.5px; padding-bottom: var(--space-4); }
.faq .acc .acc-body p { margin: 0; max-width: 62ch; }
.faq .acc { border-top: 0; }
@media (max-width: 860px) {
  .faq { grid-template-columns: 1fr; gap: var(--space-4); }
  .faq-head { position: static; }
}

/* ── footer ─────────────────────────────────────────────────────────── */
.site-foot { border-top: var(--rule); margin-top: var(--space-8); }
.foot-grid {
  display: grid; grid-template-columns: 1.4fr repeat(3, 1fr);
  gap: var(--space-6); padding: var(--space-8) 0 var(--space-6);
}
.foot-grid h3 { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--color-neutral-600); margin: 0 0 var(--space-3); font-weight: 600; font-family: var(--font-body); }
.foot-grid ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.foot-grid a { font-size: 13.5px; color: var(--color-text); text-decoration: none; }
.foot-grid a:hover { color: var(--color-accent); }
.foot-legal {
  display: flex; justify-content: space-between; gap: var(--space-4);
  flex-wrap: wrap; font-size: 11.5px; color: var(--color-neutral-600);
  border-top: var(--hair); padding: var(--space-4) 0;
}

/* ── listing page ───────────────────────────────────────────────────── */
.listing-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--space-4); padding-bottom: var(--space-4); border-bottom: var(--rule);
}
.listing-head h1 { font-size: clamp(28px, 3.4vw, 42px); letter-spacing: -0.02em; margin: 0; }
/* The rail is sticky, so it cannot carry the column rule — a short border
   would stop where the rail ends. The rule is painted on the grid itself. */
.listing-body {
  display: grid; grid-template-columns: 232px 1fr;
  background: linear-gradient(var(--color-text) 0 0) 230px 0 / 2px 100% no-repeat;
}
.rail {
  padding: var(--space-4) var(--space-6) var(--space-8) 0;
  display: flex; flex-direction: column; gap: var(--space-4);
  align-self: start; position: sticky; top: calc(var(--nav-h) + var(--space-2));
}
.rail h3 {
  font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--color-neutral-600); margin: 0 0 var(--space-3);
  font-weight: 600; font-family: var(--font-body);
}
.rail-group + .rail-group { border-top: var(--hair); padding-top: var(--space-4); }
.check {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: 13.5px; cursor: pointer; padding: 2px 0;
}
.check input { position: absolute; opacity: 0; width: 0; height: 0; }
.check .box {
  width: 14px; height: 14px; flex: none; border: 1.5px solid var(--color-text);
  display: grid; place-items: center; color: var(--color-bg);
}
.check .box svg { opacity: 0; width: 10px; height: 10px; }
.check input:checked + .box { background: var(--color-text); }
.check input:checked + .box svg { opacity: 1; }
.check input:focus-visible + .box { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.check:hover .box { border-color: var(--color-accent); }
.check .count { margin-left: auto; font-size: 11.5px; color: var(--color-neutral-500); }
.swatches { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.swatch {
  width: 24px; height: 24px; padding: 0; border: 1px solid var(--color-divider);
  cursor: pointer; background-clip: padding-box;
}
.swatch[aria-pressed="true"] { outline: 1.5px solid var(--color-accent); outline-offset: 2px; }
.pricerail { display: flex; flex-direction: column; gap: var(--space-2); }
.pricerail input[type="range"] { width: 100%; accent-color: var(--color-accent); }
.activefilters { display: flex; flex-wrap: wrap; gap: 5px; }
.pill {
  display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px;
  padding: 3px 8px; border: 1px solid var(--color-accent); color: var(--color-accent);
  background: transparent; cursor: pointer;
}
.pill:hover { background: var(--color-accent-100); }
.toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); padding: var(--space-3) 0 var(--space-3) var(--space-6);
  border-bottom: var(--hair); font-size: 12.5px;
}
.select {
  font: inherit; font-size: 12.5px; padding: 5px 8px; background: transparent;
  border: 1px solid var(--color-divider); color: var(--color-text); cursor: pointer;
  border-radius: 0;
}
.grid-pad { padding-left: var(--space-6); }
.results { display: grid; grid-template-columns: repeat(3, 1fr); }
.results > * { padding: var(--space-4); border-right: var(--hair); border-bottom: var(--hair); }
.results > *:nth-child(3n) { border-right: 0; }
.empty { padding: var(--space-8) var(--space-4); grid-column: 1 / -1; border: 0; }
.loadmore { display: flex; justify-content: center; padding: var(--space-6); }
.filterbtn { display: none; }

/* ── product detail ─────────────────────────────────────────────────── */
.pdp { display: grid; grid-template-columns: 1.12fr 1fr; border-top: var(--rule); }
.gallery { display: grid; grid-template-columns: 66px 1fr; gap: var(--space-3); padding: var(--space-4) var(--space-6) var(--space-8) 0; border-right: var(--rule); }
/* A piece with a single frame drops the rail — and its column with it. */
.gallery:has(.thumbs:empty) { grid-template-columns: 1fr; }
.thumbs:empty { display: none; }
.thumbs { display: flex; flex-direction: column; gap: var(--space-2); }
.thumb { padding: 0; border: 1px solid var(--hairline); background: none; cursor: pointer; }
.thumb[aria-current="true"] { border: 2px solid var(--color-text); }
.thumb:hover { border-color: var(--color-accent); }
.stage { position: relative; }
.stage .ph { aspect-ratio: 1 / 1; }
.gallery-note { font-size: 11.5px; color: var(--color-neutral-600); margin-top: var(--space-2); }

.pdp-info { padding: var(--space-4) 0 var(--space-8) var(--space-8); display: flex; flex-direction: column; gap: var(--space-3); align-items: flex-start; }
.pdp-info h1 { font-size: clamp(26px, 3vw, 38px); letter-spacing: -0.02em; margin: 0; }
.pdp-price { font-size: 20px; font-family: var(--font-heading); font-weight: 800; }
.optgroup { width: 100%; display: flex; flex-direction: column; gap: var(--space-2); }
.optgroup > .spread { font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--color-neutral-600); font-weight: 600; }
.sizes { display: flex; }
.size {
  padding: 8px 14px; font-size: 13px; font-family: var(--font-heading); font-weight: 800;
  border: 1px solid var(--color-divider); background: transparent; color: var(--color-text);
  cursor: pointer; margin-left: -1px;
}
.size:first-child { margin-left: 0; }
.size[aria-pressed="true"] { background: var(--color-text); color: var(--color-bg); border-color: var(--color-text); }
.size:disabled { color: var(--color-neutral-400); text-decoration: line-through; cursor: not-allowed; }
.size:not(:disabled):not([aria-pressed="true"]):hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
.swatch-lg { width: 30px; height: 30px; }
.buyrow { display: flex; gap: var(--space-2); width: 100%; align-items: stretch; }
.stepper { display: inline-flex; align-items: center; border: 1px solid var(--color-divider); }
.stepper button {
  width: 32px; height: 100%; min-height: 38px; border: 0; background: transparent;
  color: var(--color-text); cursor: pointer; display: grid; place-items: center;
}
.stepper button:hover { background: color-mix(in srgb, var(--color-text) 8%, transparent); }
.stepper output { min-width: 26px; text-align: center; font-size: 13px; font-variant-numeric: tabular-nums; }
.buyrow .btn-primary { flex: 1; }
.acc { width: 100%; border-top: var(--hair); }
.acc details { border-bottom: var(--hair); }
.acc summary {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-3) 0; font-size: 13.5px; font-family: var(--font-heading);
  font-weight: 800; cursor: pointer; list-style: none;
}
.acc summary::-webkit-details-marker { display: none; }
.acc summary::after { content: "+"; font-size: 15px; color: var(--color-neutral-600); }
.acc details[open] summary::after { content: "–"; }
.acc .acc-body { padding: 0 0 var(--space-3); font-size: 13.5px; color: var(--color-neutral-800); }
.acc .acc-body p { margin: 0 0 var(--space-2); }
.acc dl { display: grid; grid-template-columns: auto 1fr; gap: 4px var(--space-4); margin: 0; font-size: 13px; }
.acc dt { color: var(--color-neutral-600); }
.acc dd { margin: 0; }

/* ── cart ───────────────────────────────────────────────────────────── */
.cart-body { display: grid; grid-template-columns: 1.6fr 1fr; border-top: var(--rule); }
.cart-lines { border-right: var(--rule); padding-right: var(--space-6); }
.line { display: grid; grid-template-columns: 84px 1fr; gap: var(--space-4); padding: var(--space-4) 0; border-bottom: var(--hair); }
.line-name { font-family: var(--font-heading); font-weight: 800; font-size: 15px; }
.line-name a { color: inherit; text-decoration: none; }
.line-name a:hover { color: var(--color-accent); }
.linkbtn {
  background: none; border: 0; padding: 0; font: inherit; font-size: 12px;
  color: var(--color-neutral-600); text-decoration: underline;
  text-underline-offset: 3px; cursor: pointer;
}
.linkbtn:hover { color: var(--color-accent); }
.summary { padding: var(--space-4) 0 var(--space-8) var(--space-6); display: flex; flex-direction: column; gap: var(--space-2); align-self: start; position: sticky; top: calc(var(--nav-h) + var(--space-2)); }
.sumrow { display: flex; justify-content: space-between; font-size: 13.5px; }
.sumtotal { display: flex; justify-content: space-between; font-size: 18px; font-family: var(--font-heading); font-weight: 800; }
.promo { display: flex; margin-top: var(--space-2); }
.promo .input { border-right: 0; }
.promo button { border: 1px solid var(--color-text); background: var(--color-text); color: var(--color-bg); font-family: var(--font-heading); font-weight: 800; font-size: 13px; padding-inline: var(--space-3); cursor: pointer; }
.promo button:hover { background: var(--color-neutral-800); }

.undo {
  position: fixed; left: 50%; translate: -50% 0; bottom: var(--space-6); z-index: 60;
  display: flex; align-items: center; gap: var(--space-4);
  background: var(--color-text); color: var(--color-bg);
  padding: var(--space-3) var(--space-4); box-shadow: var(--shadow-lg); font-size: 13px;
}
.undo button { background: none; border: 0; color: var(--color-accent-400); font: inherit; font-weight: 800; font-family: var(--font-heading); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.undo[hidden] { display: none; }

/* ── checkout ───────────────────────────────────────────────────────── */
.checkout-head { display: flex; align-items: center; justify-content: space-between; height: var(--nav-h); border-bottom: var(--rule); }
.checkout-body { display: grid; grid-template-columns: 1.45fr 1fr; border-top: 0; }
.checkout-form { border-right: var(--rule); padding: var(--space-6) var(--space-6) var(--space-8) 0; display: flex; flex-direction: column; gap: var(--space-6); }
.step { display: flex; flex-direction: column; gap: var(--space-3); }
.step + .step { border-top: var(--hair); padding-top: var(--space-6); }
.step-head { display: flex; align-items: baseline; gap: var(--space-3); }
.step-num { font-size: 12px; font-family: var(--font-heading); font-weight: 800; color: var(--color-accent); }
.step-head h2 { font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase; margin: 0; }
.fieldgrid { display: grid; gap: var(--space-3); }
.g2 { grid-template-columns: 1fr 1fr; }
.g3 { grid-template-columns: 1fr 1fr 1fr; }
.ship-opt {
  display: flex; align-items: center; gap: var(--space-3); width: 100%;
  padding: var(--space-3); border: 1px solid var(--color-divider); cursor: pointer; font-size: 13.5px;
}
.ship-opt:has(input:checked) { border: 2px solid var(--color-text); padding: calc(var(--space-3) - 1px); }
.ship-opt:hover { border-color: var(--color-accent); }
.ship-opt .ship-price { margin-left: auto; font-variant-numeric: tabular-nums; }
.ship-opt:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.ship-opt input { position: absolute; opacity: 0; width: 0; height: 0; }
.ship-opt .dot {
  width: 15px; height: 15px; flex: none; border-radius: 50%;
  border: 1.5px solid var(--color-divider);
}
.ship-opt input:checked + .dot {
  border-color: var(--color-accent); background: var(--color-accent);
  box-shadow: inset 0 0 0 3.5px var(--color-bg);
}
.osummary { padding: var(--space-6) 0 var(--space-8) var(--space-6); display: flex; flex-direction: column; gap: var(--space-3); align-self: start; position: sticky; top: var(--space-4); }
.oline { display: grid; grid-template-columns: 52px 1fr auto; gap: var(--space-3); align-items: start; font-size: 13px; }

/* ── account ────────────────────────────────────────────────────────── */
.account-body {
  display: grid; grid-template-columns: 200px 1fr; border-top: var(--rule);
  background: linear-gradient(var(--color-text) 0 0) 198px 0 / 2px 100% no-repeat;
}
.side { padding: var(--space-6) var(--space-6) var(--space-8) 0; display: flex; flex-direction: column; gap: var(--space-2); align-self: start; }
.side a { font-size: 13.5px; text-decoration: none; color: var(--color-neutral-700); padding: 4px 0 4px var(--space-3); border-left: 2px solid transparent; }
.side a:hover { color: var(--color-accent); }
.side a[aria-current="page"] { color: var(--color-text); font-weight: 800; font-family: var(--font-heading); border-left-color: var(--color-accent); }
.orders { padding-left: var(--space-6); }
.order { padding: var(--space-4) 0; border-bottom: var(--hair); display: flex; flex-direction: column; gap: var(--space-3); }
.order-top { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); font-size: 12px; color: var(--color-neutral-600); }
.order-items { display: flex; gap: var(--space-3); align-items: center; }
.order-thumbs { display: flex; gap: var(--space-2); }
.order-thumbs .ph { width: 54px; aspect-ratio: 1 / 1; }
.status { font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 800; font-family: var(--font-heading); padding: 3px 8px; }
.status-live { border: 1px solid var(--color-accent); color: var(--color-accent); }
.status-done { border: 1px solid var(--color-divider); color: var(--color-neutral-700); }

/* ── overlays: quick view + search ──────────────────────────────────── */
.backdrop {
  position: fixed; inset: 0; z-index: 80;
  background: color-mix(in srgb, var(--color-neutral-900) 45%, transparent);
  display: flex; justify-content: center; padding: var(--space-4);
}
.backdrop[hidden] { display: none; }
.qv-panel {
  align-self: center; width: min(760px, 100%); max-height: 90vh; overflow: auto;
  background: var(--color-bg); border: 2px solid var(--color-text);
  display: grid; grid-template-columns: 1fr 1fr;
}
.qv-media { border-right: 2px solid var(--color-text); }
.qv-body { padding: var(--space-6); display: flex; flex-direction: column; gap: var(--space-3); align-items: flex-start; position: relative; }
.qv-title { font-size: 26px; letter-spacing: -0.02em; margin: 0; }
.closebtn {
  position: absolute; top: var(--space-2); right: var(--space-2);
  width: 32px; height: 32px; display: grid; place-items: center;
  background: transparent; border: 0; cursor: pointer; color: var(--color-text);
}
.closebtn:hover { background: color-mix(in srgb, var(--color-text) 8%, transparent); }

.search-panel {
  align-self: flex-start; width: min(720px, 100%); margin-top: 8vh;
  background: var(--color-bg); border: 2px solid var(--color-text);
}
.search-field { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4); border-bottom: 2px solid var(--color-text); }
.search-field input {
  flex: 1; font: inherit; font-size: 18px; font-family: var(--font-heading); font-weight: 800;
  background: transparent; border: 0; color: var(--color-text); caret-color: var(--color-accent);
}
.search-field input::placeholder { color: var(--color-neutral-500); }
.esc { font-size: 10.5px; letter-spacing: 0.08em; border: 1px solid var(--color-divider); padding: 3px 7px; color: var(--color-neutral-600); }
.search-cols { display: grid; grid-template-columns: 1fr 1.25fr; min-height: 240px; }
.search-sugg { border-right: var(--hair); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.search-res { padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); }
.search-sugg h3, .search-res h3 { font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--color-neutral-600); margin: 0 0 var(--space-1); font-weight: 600; font-family: var(--font-body); }
.sugg {
  text-align: left; background: none; border: 0; padding: 3px 0; font: inherit;
  font-size: 13.5px; cursor: pointer; color: var(--color-text);
}
.sugg:hover, .sugg:focus-visible { color: var(--color-accent); }
.sugg b { font-weight: 800; font-family: var(--font-heading); }
.hitrow { display: flex; gap: var(--space-3); align-items: center; text-decoration: none; color: inherit; }
.hitrow .ph { width: 46px; aspect-ratio: 1 / 1; flex: none; }
.hitrow:hover .hit-name { color: var(--color-accent); }
.hit-name { font-family: var(--font-heading); font-weight: 800; font-size: 13.5px; }

/* ── responsive ─────────────────────────────────────────────────────── */
@media (max-width: 1040px) {
  .foot-grid { grid-template-columns: 1fr 1fr; }
  .results, .cells-4 { grid-template-columns: repeat(2, 1fr); }
  .results > *:nth-child(3n), .cells-4 > *:nth-child(4n) { border-right: var(--hair); }
  .results > *:nth-child(2n), .cells-4 > *:nth-child(2n) { border-right: 0; }
  .cells-5 { grid-template-columns: repeat(3, 1fr); }
  .cells-5 > *:nth-child(5n) { border-right: var(--hair); }
  .cells-5 > *:nth-child(3n) { border-right: 0; }
  /* Two up, the gutter-trimming has to follow the row, not the first and last
     cell of the set — otherwise rule 03 sits indented under rule 01. */
  .rules-cells > *:nth-child(2n+1) { padding-left: 0; }
  .rules-cells > *:nth-child(2n) { padding-right: 0; }
}

@media (max-width: 860px) {
  :root { --gut: var(--space-4); }
  .navtoggle { display: inline-flex; }
  .mainnav {
    position: absolute; top: 100%; left: 0; right: 0; flex-direction: column;
    gap: 0; background: var(--color-bg); border-bottom: var(--rule); padding: var(--space-2) var(--gut);
  }
  .mainnav[hidden] { display: none; }
  .mainnav a { padding: var(--space-3) 0; border-bottom: var(--hair); border-top: 0; }
  .site-nav { position: relative; }

  .hero, .split, .pdp, .cart-body, .checkout-body, .account-body, .listing-body, .qv-panel, .search-cols {
    grid-template-columns: 1fr;
  }
  .listing-body, .account-body { background: none; }
  .hero-copy, .split-copy, .gallery, .cart-lines, .checkout-form, .rail, .side, .qv-media {
    border-right: 0; border-left: 0; padding-right: 0; padding-left: 0;
  }
  .hero-copy { padding-block: var(--space-6); border-bottom: var(--rule); }
  .hero-media { min-height: 0; aspect-ratio: 3 / 2; }
  .split-copy { padding: var(--space-6) 0; }
  .pdp-info, .summary, .osummary, .orders, .grid-pad, .toolbar { padding-left: 0; }
  .gallery { grid-template-columns: 1fr; }
  .thumbs { flex-direction: row; order: 2; }
  .thumb { width: 62px; }
  .pdp-info, .summary, .osummary { border-top: var(--rule); padding-top: var(--space-6); position: static; }
  .rail { position: static; display: none; padding-bottom: var(--space-6); border-bottom: var(--hair); }
  .rail.open { display: flex; }
  .filterbtn { display: inline-flex; }
  .qv-media { border-bottom: 2px solid var(--color-text); }
  .search-sugg { border-right: 0; border-bottom: var(--hair); }
  .search-panel { margin-top: 0; }
  .cells-5, .results, .cells-4, .cells-3 { grid-template-columns: repeat(2, 1fr); }
  .cells-5 > *, .cells-4 > *, .cells-3 > *, .results > * { border-right: var(--hair); }
  .cells-5 > *:nth-child(2n), .cells-4 > *:nth-child(2n), .cells-3 > *:nth-child(2n), .results > *:nth-child(2n) { border-right: 0; }
  .g3 { grid-template-columns: 1fr; }
  .listing-head { flex-direction: column; align-items: flex-start; }
}

/* House rules on a phone. Two columns leaves a ~150px measure, which breaks the
   headings mid-phrase, rags the copy badly and — because grid rows align — pads
   the short cell out to the tall one. The cells also lose their alignment: the
   left column of the second row keeps the inner padding that only the first
   cell trims. Stacked one to a row it reads as what it is, a list: full measure,
   no dead space, every rule flush to the gutter.

   The mark and the title share the first line and the copy hangs under the
   title, so each rule is two lines of block rather than four. The counters are
   dropped — the section header already says there are four, and on one column
   the order is plain — which takes a whole line out of every cell. */
@media (max-width: 620px) {
  .rules-cells { grid-template-columns: 1fr; }
  .rules-cells > *,
  .rules-cells > *:first-child,
  .rules-cells > *:last-child {
    padding: var(--space-3) 0 var(--space-4);
    border-right: 0;
  }
  .rules-cells > *:last-child { border-bottom: 0; }
  .rule-cell {
    display: grid; align-items: center;
    grid-template-columns: auto 1fr;
    column-gap: var(--space-2); row-gap: var(--space-1);
  }
  .rule-cell .ic { grid-area: 1 / 1; width: 20px; height: 20px; }
  .rule-num { display: none; }
  .rule-cell h3 { grid-area: 1 / 2; font-size: 17px; max-width: none; }
  /* Hung under the title rather than the icon, so the two lines read as one
     block instead of restarting at the gutter. */
  .rule-cell p { grid-area: 2 / 2; font-size: 14px; max-width: 52ch; }
}

/* Section head on a phone. Side by side, the head and the chips fight for a
   ~320px line: the title wraps to two lines and the chips wrap to two rows, for
   a four-line block that says very little. Stacked, the title keeps one line and
   the chips keep one row — set to scroll rather than wrap, and bled to the
   gutter so the cut-off chip shows there is more to reach. */
@media (max-width: 560px) {
  .sec-head {
    flex-direction: column; align-items: stretch;
    gap: var(--space-3); padding-bottom: var(--space-4);
  }
  .chiprow {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    margin-inline: calc(var(--gut) * -1); padding-inline: var(--gut);
  }
  .chiprow::-webkit-scrollbar { display: none; }
  /* 24px is the smallest target that passes; the chips were sitting at it. */
  .chiprow .btn { flex: none; padding: 6px 12px; font-size: 13px; }
}

/* Hero on a phone. The 12ch measure that keeps the headline in a tight stack on
   a wide screen turns it into four short lines here, and the desktop rhythm —
   16px between every part, 24px of padding top and bottom — spends another
   ~90px before the photograph. The measure opens to 15ch so the line breaks fall
   where the phrase does, the type steps down a notch, and the two buttons keep
   one row instead of wrapping into two on a 360px phone. */
@media (max-width: 560px) {
  .hero-copy { gap: var(--space-3); padding-block: var(--space-4); }
  .hero-copy h1 { font-size: 30px; line-height: 1.0; max-width: 15ch; }
  .hero-copy p { font-size: 14px; max-width: none; }
  .hero-copy .btnrow { gap: 6px; }
  .hero-copy .btn-lg { padding: 11px 13px; font-size: 13px; }
}

/* Product head on a phone. Add to bag has to be on the first screen: it is what
   the page is for, and it was landing ~250px below the fold. The photograph is
   left alone at full square — it is the piece — so every step comes out of the
   text and the furniture around it: the 32px well under the frame, the gallery
   note, the type label the breadcrumb already gave you, and the description,
   which moves below the buy block rather than sitting between the price and the
   options. Add to bag now sits at ~700px on a 390px-wide phone. */
@media (max-width: 560px) {
  .crumb { padding: var(--space-2) 0; }
  .gallery { gap: var(--space-2); padding-block: var(--space-2) 0; }
  /* The photograph keeps its square frame — it is the piece, and cropping it is
     not what was costing the screen. Every step below comes out of the text. */
  /* The note is a desk-side aside — one line says the other frames aren't shot
     yet, the other explains an arrow-key shortcut a phone hasn't got. It cost up
     to two lines directly above the name, so it goes on a phone. */
  .gallery-note { display: none; }
  .thumbs { order: 2; margin-top: var(--space-1); gap: 6px; }
  .thumb { width: 54px; }

  .pdp-info { gap: var(--space-2); padding-top: var(--space-3); padding-bottom: var(--space-6); }
  .pdp-info h1 { font-size: 27px; line-height: 1.1; }
  /* The type label repeats the breadcrumb two lines above it — Bags / Foundry
     Tote — so on a phone it is a line of screen for nothing. */
  .pdp-info > .kicker { display: none; }
  .pdp-price { font-size: 18px; }
  /* The blurb is the one block that wants room to breathe, not less of it. */
  .pdp-blurb { max-width: none; font-size: 14px; }
  .pdp-info .hr { margin-block: var(--space-1); }

  /* Leather and size are short lists — three swatches, three sizes — so they
     share a row instead of stacking two label-and-control blocks. Everything
     else keeps the full measure. */
  .pdp-info { display: grid; grid-template-columns: 1fr 1fr; }
  .pdp-info > * { grid-column: 1 / -1; }
  /* Half a measure is not much for a label carrying the selected leather —
     "Leather — Natural Tan" wrapped to two lines on a 320px phone. Tracking and
     size come in a notch so it holds one line at every phone width. */
  .pdp-info .optgroup > .spread { font-size: 10px; letter-spacing: 0.06em; }

  /* Buy first, read second. On a wide screen the blurb sits between the price
     and the options and costs nothing; on a phone it pushed Add to bag off the
     bottom of the screen, so you had to scroll past the description to reach the
     thing you came to press. Only non-interactive blocks move, so the tab order
     still runs swatches → sizes → quantity → Add to bag → specs, and the copy
     still follows the name and price for a screen reader. */
  .pdp-info > .optgroup { grid-column: auto; order: 2; }
  .pdp-info > .buyrow { order: 3; }
  .pdp-info > .pdp-ship { order: 4; }
  .pdp-info > .hr { order: 5; }
  .pdp-info > .pdp-blurb { order: 6; }
  .pdp-info > .acc { order: 7; }
}

/* Below this the two option columns are too narrow for the label whatever the
   tracking is, so they go back to one — a wrapped label costs the same line and
   reads worse. */
@media (max-width: 340px) {
  .pdp-info { grid-template-columns: 1fr; }
}

/* Quick view on a phone. Stacked, the square frame plus a desktop-padded body
   ran past 90vh, so the panel scrolled — and a glance panel you have to scroll
   is just the product page with extra steps. The frame is set by height rather
   than ratio — capping a square would leave the cell part empty — and the body
   loses a step of padding and gap, so everything the panel is for (piece, price,
   leather, Add to bag) lands on one screen. The full-square frame is one tap
   away under Full details. */
@media (max-width: 560px) {
  .backdrop { padding: var(--space-2); }
  .qv-media .ph { aspect-ratio: auto; height: 40vh; }
  .qv-body { padding: var(--space-4); gap: var(--space-2); }
  .qv-title { font-size: 22px; }
  .qv-body .closebtn { top: 2px; right: 2px; }
  /* Full details is the way out of the panel, not the thing to press — it sits
     as a plain underlined line under the button, and does not need a gap of its
     own to be read as separate. */
  .qv-body .linkbtn { font-size: 12.5px; }
}

/* Footer on a phone. One column stacked eleven link rows into a column of
   dead scroll, and each row was a 20px tap target. The three lists go two up —
   the brand block keeps the full width above them — and every link gets padding
   rather than a gap, so the target clears the 24px minimum while the section
   as a whole gets shorter, not longer. */
@media (max-width: 560px) {
  .foot-grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-6) var(--space-4);
    padding-top: var(--space-6);
  }
  .foot-grid > *:first-child { grid-column: 1 / -1; }
  /* The odd group out would otherwise leave half a row empty, so it takes the
     full width and runs its links two up in DOM order. */
  .foot-grid > *:last-child { grid-column: 1 / -1; }
  .foot-grid > *:last-child ul {
    display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--space-4);
  }
  .foot-grid h3 { margin-bottom: var(--space-2); }
  .foot-grid ul { gap: 0; }
  .foot-grid a { display: block; padding: 7px 0; font-size: 14px; }
  .foot-legal { justify-content: flex-start; gap: var(--space-2) var(--space-4); }
}

@media (max-width: 520px) {
  .topbar span:last-child { display: none; }
  .g2 { grid-template-columns: 1fr; }
  .line { grid-template-columns: 64px 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

@media print {
  .site-head, .site-foot, .backdrop, .undo { display: none; }
}
