/* ==========================================================================
   4ewdsr5y — COMPONENTS
   Buttons, boot terminal, product grid, product page, filters, forms.
   ========================================================================== */

/* ------------------------------------------------------------- 1. BUTTONS */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 44px;                 /* tap target floor */
  padding: var(--sp-3) var(--sp-5);
  font-size: var(--fs-sm);
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  border: 1px solid var(--rule-mid);
  color: var(--fg);
  background: transparent;
  transition: border-color var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}
.btn:hover { border-color: var(--rule-strong); background: var(--signal-soft); }

.btn-solid {
  background: var(--signal-fill);
  border-color: var(--signal-fill);
  color: var(--signal-ink);
  font-weight: 700;
}
/* Hover lifts the red toward --signal and rings it in --signal. It used to
   go to --fg, which in the dark theme is bone — the same near-white as the
   lettering, so EQUIP, REGISTER and CHECKOUT all vanished under the pointer.
   Staying red keeps --signal-ink readable on it in both themes. */
.btn-solid:hover {
  background: color-mix(in srgb, var(--signal-fill) 62%, var(--signal));
  border-color: var(--signal);
  color: var(--signal-ink);
}

/* The primary purchase control. Deliberately large and legible — this is
   the single most important element on the site. */
.btn-acquire {
  width: 100%;
  min-height: 54px;
  font-size: var(--fs-base);
  font-weight: 700;
  letter-spacing: var(--tr-wider);
}

.btn[disabled],
.btn[aria-disabled="true"] {
  color: var(--fg-faint);
  border-color: var(--rule);
  border-style: dashed;
  background: transparent;
  cursor: not-allowed;
}
.btn[disabled]:hover,
.btn[aria-disabled="true"]:hover { background: transparent; }

.btn-ghost { border-color: transparent; color: var(--fg-dim); }
.btn-ghost:hover { color: var(--fg); background: var(--signal-soft); }

/* ------------------------------------------------- 2. BOOT / LANDING */

.boot {
  position: relative;
  /* General guard so nothing decorative in here can widen the document.
     `clip` contains overflow without creating a scroll container (which
     `hidden` would) and so leaves the sticky header alone. */
  overflow: clip;
  z-index: var(--z-raised);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: calc(100svh - 104px);
  padding-block: var(--sp-7);
}

.boot-frame {
  width: 100%;
  max-width: 760px;
  border: 1px solid var(--rule-mid);
  background: color-mix(in srgb, var(--bg-panel) 82%, transparent);
  backdrop-filter: blur(6px);
}

.boot-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tr-wide);
  color: var(--fg-dim);
  text-transform: uppercase;
}
.boot-bar .spacer { margin-left: auto; }

.boot-body { padding: var(--sp-5) var(--sp-5) var(--sp-6); }

.boot-log {
  font-size: var(--fs-sm);
  color: var(--fg-dim);
  margin-bottom: var(--sp-6);
}
.boot-log li {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  padding-block: 1px;
}
.boot-log .lead {
  flex: 1;
  border-bottom: 1px dotted var(--rule-mid);
  transform: translateY(-4px);
  min-width: var(--sp-5);
}
.boot-log .val { color: var(--fg); }

/* Boot lines reveal in sequence. The whole sequence is budgeted by
   --boot-total in theme.css and is short by design: content is in the DOM
   and painted immediately, this only staggers opacity. */
.boot-log li {
  opacity: 0;
  animation: boot-in var(--dur) var(--ease) forwards;
  animation-delay: calc(var(--i, 0) * var(--boot-step));
}
@keyframes boot-in { to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .boot-log li { opacity: 1; animation: none; }
}

/* ----------------------------------------------------- 3. PROMPT MENU */

/* Keyboard-navigable menu. Unlike the reference site, the legend under it
   describes controls that are genuinely wired up: arrows and Home/End move
   the selection, Enter opens it, and hover/focus moves it too. */
.menu {
  border-top: 1px solid var(--rule);
  perspective: 900px;
  perspective-origin: left center;
}

.menu-item {
  display: flex;
  align-items: center;
  width: 100%;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-3);
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-md);
  letter-spacing: var(--tr-wide);
  color: var(--fg-dim);
  text-align: left;
  transform-origin: left center;
  backface-visibility: hidden;
  transition: color var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease),
              padding-left var(--dur-fast) var(--ease),
              transform var(--dur-slow) var(--ease);
}
.menu-item .marker {
  width: 1.2em;
  color: transparent;
  flex: none;
}
.menu-item .lead {
  flex: 1;
  border-bottom: 1px dotted var(--rule-mid);
  transform: translateY(-5px);
  min-width: var(--sp-5);
}
.menu-item .tail {
  font-size: var(--fs-xs);
  color: var(--fg-faint);
  letter-spacing: var(--tr-wide);
  flex: none;
}

.menu-item:hover,
.menu-item[data-selected="true"] {
  color: var(--fg);
  background: var(--signal-soft);
  padding-left: var(--sp-4);
}
.menu-item[data-selected="true"] .marker { color: var(--signal); }
.menu-item[data-selected="true"] .tail { color: var(--fg-dim); }

.menu-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  margin-top: var(--sp-4);
  font-size: var(--fs-xs);
  color: var(--fg-faint);
  letter-spacing: var(--tr-wide);
}
.menu-legend kbd {
  font: inherit;
  border: 1px solid var(--rule-mid);
  padding: 1px var(--sp-2);
  margin-right: var(--sp-2);
  color: var(--fg-dim);
}

/* --------------------------------------------------- 4. PAGE HEADINGS */

.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-4) var(--sp-6);
  padding-block: var(--sp-6) var(--sp-5);
  border-bottom: 1px solid var(--rule);
}
.page-head .spacer { margin-left: auto; }
.page-title {
  font-size: var(--fs-xl);
  letter-spacing: var(--tr-wide);
  line-height: var(--lh-tight);
}

.crumb {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-xs);
  color: var(--fg-faint);
  letter-spacing: var(--tr-wide);
  margin-bottom: var(--sp-2);
}
.crumb a:hover { color: var(--signal); }

/* ------------------------------------------------------- 5. FILTER BAR */

.filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  padding-block: var(--sp-4);
}
.filters .spacer { margin-left: auto; }

.chip {
  min-height: 36px;
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--rule);
  font-size: var(--fs-sm);
  letter-spacing: var(--tr-wide);
  color: var(--fg-dim);
  transition: color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease);
}
.chip:hover { color: var(--fg); border-color: var(--rule-mid); }
.chip[aria-pressed="true"] {
  color: var(--signal-ink);
  background: var(--signal-fill);
  border-color: var(--signal-fill);
  font-weight: 700;
}
/* The grid's way back into the stockroom (shop.html): a link dressed as a
   chip, at the start of the filter row. */
.chip-back {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  text-decoration: none;
}
/* On a phone the chips wrap as a block, and first in the row the link took a
   row of its own; after them it sits beside the search, in the space left
   of it. */
@media (max-width: 640px) {
  [data-filters-row] > [data-filters] { order: 1; }
  [data-filters-row] > .chip-back { order: 2; }
  [data-filters-row] > .spacer { order: 3; }
  [data-filters-row] > .search { order: 4; }
}

.search {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 36px;
  padding-inline: var(--sp-3);
  border: 1px solid var(--rule);
  color: var(--fg-faint);
}
.search:focus-within { border-color: var(--rule-strong); color: var(--fg-dim); }
.search input {
  width: 190px;
  max-width: 40vw;
  font-size: var(--fs-sm);
  letter-spacing: var(--tr-wide);
  color: var(--fg);
}
.search input::placeholder { color: var(--fg-faint); }

/* ------------------------------------------------------ 6. PRODUCT GRID */

/* Cards get real room. minmax(300px) yields 4 columns at max width, 3 from
   ~1240px, 2 from ~940px and 1 below ~640px. */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--sp-6) var(--sp-5);
  padding-block: var(--sp-6) var(--sp-8);
}

/* The no-JavaScript catalogue. Plain links, no prices — see the comment in
   shop.html for why this must not restate them. */
.nojs-catalogue {
  list-style: none;
  padding: 0;
  margin: var(--sp-5) 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--sp-3) var(--sp-5);
}
.nojs-catalogue a {
  color: var(--fg);
  letter-spacing: var(--tr-wide);
  font-size: var(--fs-sm);
}

.pcard { display: flex; flex-direction: column; }

.pcard-plate {
  position: relative;
  aspect-ratio: 4 / 5;
  background: var(--bg-plate);
  border: 1px solid var(--rule);
  overflow: hidden;
  transition: border-color var(--dur) var(--ease);
}
.pcard:hover .pcard-plate { border-color: var(--rule-mid); }

/* Photography shot on a white sweep: add data-photo="on-white" to the plate
   and it stays light in both themes rather than punching a hole in the dark
   UI. Cutouts on transparent backgrounds need nothing. */
.pcard-plate[data-photo="on-white"],
.gal-main[data-photo="on-white"] { background: #f4f2ed; }

/* Reticle corners. Four brackets drawn as eight 1px gradient slivers, so no
   extra elements are needed in the markup. */
.pcard-plate::before,
.gal-main::before {
  content: "";
  position: absolute;
  inset: 10px;
  pointer-events: none;
  z-index: 2;
  background:
    linear-gradient(var(--rule-strong), var(--rule-strong)) 0 0 / 11px 1px no-repeat,
    linear-gradient(var(--rule-strong), var(--rule-strong)) 0 0 / 1px 11px no-repeat,
    linear-gradient(var(--rule-strong), var(--rule-strong)) 100% 0 / 11px 1px no-repeat,
    linear-gradient(var(--rule-strong), var(--rule-strong)) 100% 0 / 1px 11px no-repeat,
    linear-gradient(var(--rule-strong), var(--rule-strong)) 0 100% / 11px 1px no-repeat,
    linear-gradient(var(--rule-strong), var(--rule-strong)) 0 100% / 1px 11px no-repeat,
    linear-gradient(var(--rule-strong), var(--rule-strong)) 100% 100% / 11px 1px no-repeat,
    linear-gradient(var(--rule-strong), var(--rule-strong)) 100% 100% / 1px 11px no-repeat;
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.gal-main::before { opacity: 0.55; }
.pcard:hover .pcard-plate::before,
.pcard:focus-visible .pcard-plate::before { opacity: 1; }

/* Scan sweep. Runs only while the card is hovered. */
.pcard-plate::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: 38%;
  top: -38%;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to bottom,
    transparent, var(--signal-soft) 45%, var(--signal-soft) 55%, transparent);
  opacity: 0;
}
.pcard:hover .pcard-plate::after {
  opacity: 1;
  animation: plate-scan 1.7s linear infinite;
}
@keyframes plate-scan { from { top: -38%; } to { top: 100%; } }

.pcard-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: var(--sp-5);
  transition: transform var(--dur-slow) var(--ease);
}
.pcard:hover .pcard-img { transform: scale(1.03); }

.pcard-flag {
  position: absolute;
  left: 0; top: 0;
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tr-wide);
  background: var(--bg);
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.pcard-flag[data-status="sold-out"] { color: var(--alert); }
.pcard-flag[data-status="coming-soon"] { color: var(--fg-dim); }

.pcard-idx {
  position: absolute;
  right: var(--sp-3); top: var(--sp-3);
  font-size: var(--fs-2xs);
  /* --fg-faint is tuned against --bg; the plate is lighter, so step up a
     level here to stay above 4.5:1. */
  color: var(--fg-dim);
  letter-spacing: var(--tr-wide);
}

.pcard-meta {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  padding-top: var(--sp-3);
}
.pcard-name {
  font-size: var(--fs-sm);
  letter-spacing: var(--tr-wide);
  color: var(--fg);
}
.pcard:hover .pcard-name { color: var(--signal); }
.pcard-price {
  margin-left: auto;
  font-size: var(--fs-sm);
  color: var(--fg-dim);
  font-variant-numeric: tabular-nums;
  flex: none;
}
.pcard-blurb {
  padding-top: var(--sp-1);
  font-size: var(--fs-sm);
  color: var(--fg-faint);
  line-height: var(--lh-snug);
}

.empty {
  padding: var(--sp-9) 0;
  text-align: center;
  color: var(--fg-dim);
  font-size: var(--fs-sm);
}

/* ------------------------------------------------------ 7. PRODUCT PAGE */

.pdp {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(340px, 0.7fr);
  gap: var(--sp-7);
  padding-block: var(--sp-6) var(--sp-8);
  align-items: start;
}

/* A grid item's automatic minimum size is its MIN-CONTENT, so a column refuses
   to go narrower than the widest thing in it. The widest thing here is the size
   chart's table: 331.5px for the five-column tops chart. Stacked on a 320px
   phone that left 288px of room and pushed the info column 28px past the
   screen — and because `html` carries `overflow-x: clip`, that 28px was cut off
   the right of the status line, the specs and the chart rather than scrolling.
   With the floor lifted the column fits the screen and .table-scroll scrolls
   the table inside its own box, which is what it exists for. */
.pdp > * { min-width: 0; }

/* --- gallery --- */
.gal-main {
  position: relative;
  aspect-ratio: 4 / 5;
  max-height: 78vh;
  margin-inline: auto;
  background: var(--bg-plate);
  border: 1px solid var(--rule);
  overflow: hidden;
}
.gal-main img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: var(--sp-6);
}

.gal-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px; height: 64px;
  display: grid;
  place-items: center;
  color: var(--fg-dim);
  background: color-mix(in srgb, var(--bg) 55%, transparent);
  border: 1px solid var(--rule);
  transition: color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.gal-btn:hover { color: var(--fg); border-color: var(--rule-strong); }
.gal-btn[data-dir="prev"] { left: var(--sp-3); }
.gal-btn[data-dir="next"] { right: var(--sp-3); }
.gal-btn[hidden] { display: none; }

/* Image counter. Always renders a real integer — never NaN. */
.gal-count {
  position: absolute;
  right: var(--sp-3); bottom: var(--sp-3);
  padding: var(--sp-1) var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--fg-dim);
  background: color-mix(in srgb, var(--bg) 70%, transparent);
  border: 1px solid var(--rule);
  font-variant-numeric: tabular-nums;
}

.gal-thumbs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}
.gal-thumb {
  width: 76px;
  aspect-ratio: 4 / 5;
  background: var(--bg-plate);
  border: 1px solid var(--rule);
  padding: var(--sp-1);
  transition: border-color var(--dur-fast) var(--ease);
}
.gal-thumb img { width: 100%; height: 100%; object-fit: contain; }
.gal-thumb:hover { border-color: var(--rule-mid); }
.gal-thumb[aria-current="true"] { border-color: var(--signal); }

/* --- info column --- */
.pdp-info { position: sticky; top: 78px; }

.pdp-name {
  font-size: var(--fs-lg);
  letter-spacing: var(--tr-wide);
  line-height: var(--lh-tight);
}
.pdp-price {
  font-size: var(--fs-md);
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}
.pdp-desc {
  font-size: var(--fs-sm);
  color: var(--fg-dim);
  line-height: var(--lh-body);
  max-width: 56ch;
}

.specs { border-top: 1px solid var(--rule); }
.specs li {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-sm);
  color: var(--fg-dim);
  line-height: var(--lh-snug);
}
.specs li::before {
  content: attr(data-n);
  color: var(--fg-faint);
  flex: none;
  font-variant-numeric: tabular-nums;
}

/* --- sizes --- */
.sizes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
.size {
  min-width: 56px;
  min-height: 44px;
  padding-inline: var(--sp-3);
  border: 1px solid var(--rule-mid);
  font-size: var(--fs-sm);
  letter-spacing: var(--tr-wide);
  color: var(--fg);
  transition: border-color var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}
.size:hover:not([disabled]) { border-color: var(--rule-strong); }
.size[aria-pressed="true"] {
  background: var(--signal-fill);
  border-color: var(--signal-fill);
  color: var(--signal-ink);
  font-weight: 700;
}
.size[disabled],
.size[aria-disabled="true"] {
  color: var(--fg-faint);
  border-color: var(--rule);
  border-style: dashed;
  text-decoration: line-through;
  cursor: not-allowed;
}
.size[aria-disabled="true"]:hover { border-color: var(--rule); }

.buy-note {
  font-size: var(--fs-xs);
  color: var(--fg-faint);
  line-height: var(--lh-snug);
  margin-top: var(--sp-3);
}
.buy-note[data-tone="alert"] { color: var(--alert); }

/* Spacing of the info column's blocks. These were inline styles; they are
   classes now so the phone layout below can reorder and re-space them. */
.pdp-specs { margin-top: var(--sp-5); }
.pdp-sizes { margin-top: var(--sp-6); }
.pdp-buy   { margin-top: var(--sp-5); }
.pdp-chart { margin-top: var(--sp-6); }
.pdp-chart .buy-note { margin-top: var(--sp-3); }

/* The selected size's row in a size chart. */
.table tr[data-selected] th { color: var(--signal); }
.table tr[data-selected] td { color: var(--fg); }

/* The price that rides with the purchase control. Only the phone's bottom
   bar shows it; on a wide screen the masthead price is right there. */
.buy-price { display: none; }
.buy-dock  { display: none; }

/* ---- product page on a phone --------------------------------------------
   Built so the way to buy is on screen without scrolling. Measured before,
   at 375x812: the control at 1152px, sizes at 1032px, both under a 429px
   image and a 95px thumbnail strip, with the visible area ending at 777px.

   1. The purchase control docks to the bottom of the screen (js/product.js
      moves it into .buy-dock), price beside it.
   2. Sizes come straight after the image; the description follows them.
   3. The image is square, and the thumbnail strip becomes a row of dots —
      the same buttons, restyled, so they keep their labels and aria-current.
   4. Every size fits on one row.

   Phone widths only; nothing above 520px changes. */
@media (max-width: 520px) {
  body[data-buy-docked] .buy-dock {
    display: block;
    position: fixed;
    left: 0; right: 0;
    bottom: 35px;                         /* the status bar: 34px + its rule */
    z-index: var(--z-dock, 50);
    padding: 10px var(--gutter) 12px;
    background: color-mix(in srgb, var(--bg) 94%, transparent);
    backdrop-filter: blur(10px);
    border-top: 1px solid var(--rule-mid);
  }
  body[data-buy-docked] main { padding-bottom: var(--buy-dock-h, 110px); }

  .buy-dock .pdp-buy {
    margin-top: 0;
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: baseline;
    gap: 6px var(--sp-3);
  }
  .buy-dock .buy-price {
    display: block;
    grid-row: 1; grid-column: 1;
    font-size: var(--fs-base);
    color: var(--fg);
    font-variant-numeric: tabular-nums;
  }
  .buy-dock .buy-note {
    grid-row: 1; grid-column: 2;
    margin: 0;
    text-align: right;
  }
  .buy-dock .btn-acquire {
    grid-row: 2; grid-column: 1 / -1;
    min-height: 48px;
  }

  .pdp-info { display: flex; flex-direction: column; }
  /* Sizes first: with them second, under AVAILABLE, the size row landed at
     697px on a 375x812 screen — behind the bar, which starts at 673. */
  .pdp-info .pdp-sizes   { order: 1; margin-top: 0; }
  .pdp-info .pdp-chart   { order: 2; margin-top: var(--sp-5); }
  .pdp-info .status-line { order: 3; margin-top: var(--sp-5); }
  .pdp-info .pdp-specs   { order: 4; margin-top: var(--sp-5); }
  /* [data-pdp] outranks the 1000px breakpoint's rules, which come later in
     this file and would otherwise win on source order. */
  .pdp[data-pdp] { gap: var(--sp-4); padding-top: var(--sp-3); }

  /* Square, and never taller than 38% of the screen, so a shorter phone
     still gets its sizes above the bar. */
  .pdp[data-pdp] .gal-main { aspect-ratio: 1 / 1; max-height: 38svh; }
  /* The dots sit over the bottom of the image rather than under it. */
  .gal-thumbs { gap: 0; margin-top: -36px; position: relative; z-index: 1; }
  .gal-thumb {
    width: 32px; height: 32px;
    aspect-ratio: auto;
    padding: 0;
    border: 0;
    background: transparent;
    display: grid;
    place-items: center;
  }
  .gal-thumb img { display: none; }
  .gal-thumb::before {
    content: "";
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--fg-faint);
  }
  .gal-thumb[aria-current="true"]::before { background: var(--signal); }

  .sizes { flex-wrap: wrap; gap: 6px; }
  .size { flex: 1 0 44px; min-width: 44px; max-width: 72px; padding-inline: 0; }
}

/* A short phone (a 375x667 screen measured the size row 28px under the bar
   at 38svh) gets a smaller picture, so the sizes still clear the bar. Below
   that — a 320x568 screen — the header alone takes too much of the height
   to manage it, and the bar's SELECT A SIZE takes you to them instead. */
@media (max-width: 520px) and (max-height: 700px) {
  .pdp[data-pdp] .gal-main { max-height: 30svh; }
}

.status-line {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-xs);
  letter-spacing: var(--tr-wide);
  color: var(--fg-dim);
}
.status-line .pip { width: 6px; height: 6px; flex: none; background: var(--ok); }
.status-line[data-status="sold-out"] { color: var(--alert); }
.status-line[data-status="sold-out"] .pip { background: var(--alert); }
.status-line[data-status="coming-soon"] .pip { background: var(--fg-faint); }

/* ------------------------------------------------------- 8. ARCHIVE

   Nothing: the archive (LOOKBOOK until 2026-10-09) is the darkroom alone
   (archive.html). Its grid of frames was taken out on 2026-10-08. */

/* ---------------------------------------------------- 9. PROSE / ABOUT */

.prose { max-width: 68ch; }
.prose p { font-size: var(--fs-sm); color: var(--fg-dim); line-height: var(--lh-body); }
.prose p + p { margin-top: var(--sp-4); }
.prose h2 {
  font-size: var(--fs-md);
  letter-spacing: var(--tr-wide);
  color: var(--fg);
  margin-bottom: var(--sp-3);
}
.prose a { color: var(--fg); border-bottom: 1px solid var(--rule-mid); }
.prose a:hover { color: var(--signal); border-color: var(--signal-edge); }

.doc-section { padding-block: var(--sp-6); border-top: 1px solid var(--rule); }
.doc-section:first-of-type { border-top: 0; }

.table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.table th, .table td {
  text-align: left;
  padding: var(--sp-3) var(--sp-3) var(--sp-3) 0;
  border-bottom: 1px solid var(--rule);
  font-variant-numeric: tabular-nums;
}
.table th { color: var(--fg); font-weight: 700; letter-spacing: var(--tr-wide); }
.table td { color: var(--fg-dim); }
.table-scroll { overflow-x: auto; }

/* ------------------------------------------------------ 10. RESPONSIVE */

@media (max-width: 1000px) {
  .pdp { grid-template-columns: 1fr; gap: var(--sp-6); }
  .pdp-info { position: static; }
  .gal-main { max-height: none; }
}

@media (max-width: 860px) {
  .boot { min-height: calc(100svh - 150px); padding-block: var(--sp-5); }
  .boot-frame { max-width: none; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr)); }
  .page-head { padding-block: var(--sp-5) var(--sp-4); }
}

@media (max-width: 520px) {
  .boot-body { padding: var(--sp-4); }
  .menu-item { font-size: var(--fs-base); padding-block: var(--sp-3); }
  .grid { grid-template-columns: 1fr 1fr; gap: var(--sp-5) var(--sp-3); }
  .pcard-img { padding: var(--sp-3); }
  .pcard-blurb { display: none; }
  .gal-main img { padding: var(--sp-4); }
  .search input { width: 100%; }
}


/* ==========================================================================
   VIEW TRANSITIONS
   Cross-document morph between the shop grid and the product page. Native,
   no library. Browsers without support simply navigate normally.
   ========================================================================== */

@view-transition { navigation: auto; }

/* The shared element. On the product page it is the gallery hero; on the
   grid, js/shop.js puts the same name on whichever card was clicked, so the
   two are matched across the navigation. */
.gal-main img { view-transition-name: unit-hero; }

::view-transition-old(unit-hero),
::view-transition-new(unit-hero) {
  animation-duration: 320ms;
  animation-timing-function: var(--ease);
}

/* The page body cross-fades under the morphing image. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 220ms;
  animation-timing-function: var(--ease);
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

/* ==========================================================================
   COUNTDOWN READOUTS
   ========================================================================== */

.sb-count {
  font-weight: 400;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
  margin-left: var(--sp-1);
}


/* Horizontal drags swipe the gallery; vertical ones still scroll the page. */
.gal-main { touch-action: pan-y; }


/* ==========================================================================
   DISPLAY HEADERS
   ========================================================================== */

.masthead {
  padding-block: var(--sp-7) var(--sp-5);
  border-bottom: 1px solid var(--rule);
}
.masthead-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-3) var(--sp-5);
  margin-bottom: var(--sp-4);
}
.masthead-meta .spacer { margin-left: auto; }

/* The drop name, set as large as the viewport allows. */
.masthead .display { color: var(--fg); }

/* Product page: the name gets its own full-width band above the columns, so
   it can be large without squeezing the info column. */
.pdp-masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-4) var(--sp-6);
  padding-block: var(--sp-5) var(--sp-5);
  border-bottom: 1px solid var(--rule);
}
.pdp-masthead .spacer { margin-left: auto; }
.pdp-masthead .display-sm { max-width: 18ch; }

/* ==========================================================================
   GRID HIERARCHY
   A featured unit and an editorial cell each span two columns, breaking the
   uniform rhythm of the grid. Both collapse to full width at the 2-column
   breakpoint, so nothing ever overflows.
   ========================================================================== */

.grid { grid-auto-flow: dense; }

.pcard[data-feature="true"] { grid-column: span 2; }
.pcard[data-feature="true"] .pcard-plate { aspect-ratio: 16 / 10; }
.pcard[data-feature="true"] .pcard-name { font-size: var(--fs-md); }
.pcard[data-feature="true"] .pcard-img { padding: var(--sp-6); }

.pcard-feature-tag {
  position: absolute;
  left: 0; bottom: 0;
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-2xs);
  letter-spacing: var(--tr-wider);
  color: var(--signal-ink);
  background: var(--signal-fill);
  font-weight: 700;
}

/* Editorial cell — a campaign frame dropped into the product grid. */
.gcell {
  grid-column: span 2;
  position: relative;
  display: block;
  overflow: hidden;
  border: 1px solid var(--rule);
  background: var(--bg-plate);
  aspect-ratio: 16 / 10;
}
.gcell img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease);
}
.gcell:hover img { transform: scale(1.03); }
.gcell-body {
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--sp-5);
  background: linear-gradient(to top,
    color-mix(in srgb, var(--bg) 88%, transparent), transparent);
}
.gcell-title {
  font-size: var(--fs-lg);
  font-weight: 700;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--fg);
}
.gcell-sub {
  font-size: var(--fs-sm);
  color: var(--fg-dim);
  margin-top: var(--sp-1);
}
.gcell:hover .gcell-title { color: var(--signal); }

/* The kit counter carries the accent — the liveliest thing on the bar. */
.sb-count { color: var(--signal); }

@media (max-width: 520px) {
  .pcard[data-feature="true"] .pcard-plate,
  .gcell { aspect-ratio: 4 / 3; }
  .pcard[data-feature="true"] .pcard-img { padding: var(--sp-4); }
  .masthead { padding-block: var(--sp-5) var(--sp-4); }
}

/* The masthead is not drawn — in room view or in the grid. It first went from
   room view, where it hung as a fixed panel in the top-left corner over the
   room you are supposed to be standing in; the drop name is already in the
   status bar, so it was saying the same thing twice. When the shop became the
   plain grid at every size, it went from the grid too, on desktop and phone
   alike. Only shop.html has a .masthead.

   NOT display:none. It carries the page's only <h1>, so it is hidden the way
   base.css hides anything that still has to exist for a screen reader or a
   crawler: clipped to a pixel, still in the document, still in the
   accessibility tree. Dropping the heading from the shop would be a real loss
   to make a corner look tidier. */
.masthead {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The heading is the only part worth keeping for a reader. The breadcrumb and
   the drop telemetry go entirely, rather than being clipped along with it:
   clipping leaves the crumb's link invisible but still in the tab order, and
   a keyboard user should not land on something nobody can see. Both are
   duplicated elsewhere on screen anyway — the way home is the ##4 mark in the
   header, and the drop code is in the status bar. */
.masthead .crumb,
.masthead-meta { display: none; }
