/* ============================================================
   518 Official — APPAREL page layout
   css/pages/apparel.css?v=3 — loads AFTER tokens.css + site.css.
   Page-scoped classes only (ap-*). Never restyles the shared
   shell. No :root, no token overrides, no literal brand color —
   everything routes through tokens (the --rizz and --drop families
   only). NOTE: never write a token wildcard as "--rizz*" followed
   by a slash inside a comment — the "*" + "/" pair CLOSES the
   comment, and CSS error recovery then eats the next rule whole.
   That exact typo silently deleted .ap-tint from this sheet.

   V2 — THE STORE IS REAL. The concept-line sheet this replaces
   styled six imaginary products, "not for sale" slabs and a
   colorway-swatch system for garments that did not exist. All of
   that is deleted: 518officialapparel.com is live, the eleven products
   in data/products.json are listed and buyable there, and this
   page is their catalogue.

   PALETTE LAW: this page is the ONE commerce surface, so DROP
   AMBER lives here — the live-store flag, the price chips, the
   store CTAs. Text ON an amber fill is --bg (near-black), never
   ivory (ivory on --drop measures 1.99:1 and FAILS). Amber COPY
   on dark grounds is --drop-text (9.52:1). Chrome — card hover,
   borders, ticks, focus — stays cobalt.

   COMMERCE LAW: no cart, no checkout, no stock claim, no
   simulated basket. Every buy affordance is an external anchor to
   that product's own store_url. Every price carries the "at
   publishing" framing on the chip itself AND the full sentence
   under its grid (.ap-price-law) — a naked number never renders.

   PHOTOGRAPHY LAW: every cover-cropped photo carries its measured
   face-safe object-position through an .ap-fp-* class (values from
   the armory Vision run, mirrored in data/media.json "focal").
   Back-shots are crop-safe and use .ap-fp-safe. No photo is
   presented as a packshot of a specific SKU — captions say so.

   Editorial rhythm (top -> bottom):
     hero      black + haze, copy + real lookbook frame (LCP)
     store     black, the one commerce destination + price honesty
     rail      black, three real collections
     01 OFF    black, capitol lookbook art + 4 product cards
     02 OUTTA  band (--bg-2 lift), garage back-print art + 2 cards
     03 BADDIE black, designed panel (no photo) + 5 cards
     lookbook  band, 3 real frames incl. the silent brand film
     close     black, store CTA
   ============================================================ */

/* Punctuation accent — decorative display glyphs only, never body copy */
.ap-tint { color: var(--drop-text); }

/* Shared amber pulse dot — the live-store signal */
.ap-dot {
  width: 9px;
  height: 9px;
  flex: none;
  border-radius: 50%;
  background: var(--drop);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--drop) 25%, transparent),
              0 0 18px color-mix(in srgb, var(--drop) 35%, transparent);
  animation: ap-pulse 2.6s var(--ease-io) infinite;
}

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

/* External-destination arrow — every one of these leaves the site.
   inline-block, so it rides the label's baseline but stays outside the
   label's underline. Inside a .btn the button's own flex `gap` already
   sets the space, so the margin would double it (measured 16px). */
.ap-ext {
  display: inline-block;
  margin-left: 0.4em;
  font-size: 0.85em;
  line-height: 1;
}

.btn .ap-ext { margin-left: 0; }

/* ============================================================
   FACE-SAFE CROP LAW — binding object-position values.
   Measured focal points (armory Vision), mirrored in
   data/media.json "focal". A cover-cropped photo without one of
   these classes is a bug. Flyers are NEVER cover-cropped and so
   have no entry here.
   ============================================================ */
.ap-fp-detail-01  { object-position: 57.2% 27.4%; }
.ap-fp-detail-03  { object-position: 48.8% 33.1%; }
.ap-fp-capitol-01 { object-position: 57.3% 20.2%; }
.ap-fp-capitol-06 { object-position: 58.8% 19.4%; }
.ap-fp-safe       { object-position: 50% 50%; }   /* back-shots — no faces */

/* The brand film's poster AND its video both crop to the film's
   measured focal (51.8% 18.7%) — site.css sets object-fit: cover on
   both layers but leaves the position to the page that frames it. */
.ap-look-vslot .vslot-poster,
.ap-look-vslot video { object-position: 51.8% 18.7%; }

/* ============================================================
   HERO — "Rep the 518. Shop the Line."
   ============================================================ */
.ap-hero {
  position: relative;
  overflow: clip;
  padding-top: calc(var(--header-h) + clamp(3rem, 8vw, 6.5rem));
  padding-bottom: var(--sect-pad);
  border-bottom: 1px solid var(--line);
}

/* Oversized ghost numerals — depth, never read (ivory routed via color-mix) */
.ap-ghost {
  position: absolute;
  right: -0.04em;
  bottom: -0.12em;
  z-index: var(--z-base);
  font-family: var(--font-logo);
  font-weight: 700;
  font-size: clamp(7rem, 26vw, 20rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: color-mix(in srgb, var(--ivory) 3.5%, transparent);
  pointer-events: none;
  user-select: none;
}

.ap-hero-grid {
  position: relative;
  z-index: var(--z-content);
  display: grid;
  gap: clamp(var(--sp-6), 5vw, var(--sp-8));
  align-items: center;
}

@media (min-width: 980px) {
  .ap-hero-grid { grid-template-columns: 1.05fr 0.95fr; }
}

.ap-hero-copy { max-width: 46rem; min-width: 0; }

.ap-hero-copy .eyebrow { margin-bottom: var(--sp-5); }

.ap-h1 {
  font-size: clamp(2rem, 5.2vw, 3.8rem);
  line-height: 0.94;
}

/* Two-beat lockup: the rally line reads first, the instruction is the mass */
.ap-h1 .l1 {
  display: block;
  font-size: 0.5em;
  letter-spacing: 0.04em;
  color: var(--ivory-80);
  margin-bottom: 0.1em;
}

.ap-h1 .l2 { display: block; }

.ap-lead {
  margin-top: var(--sp-5);
  max-width: 44ch;
}

/* Amber drop flag under the hero copy — the store's one warm signal */
.ap-hero .drop-flag {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
  padding: 0.5rem 0.95rem;
  border: 1px solid color-mix(in srgb, var(--drop) 45%, transparent);
  border-radius: var(--r-sm);
  font-family: var(--font-label);
  font-weight: 600;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--drop-text);
  white-space: nowrap;
}

.ap-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-top: var(--sp-6);
}

/* Honest microcopy under the CTAs — smoke passes AA at 15px */
.ap-mail-note {
  margin-top: var(--sp-4);
  font-size: var(--fs-small);
  color: var(--smoke);
  max-width: 52ch;
}

/* ---------- Hero lookbook frame (the LCP image) ---------- */
.ap-hero-fig {
  margin: 0;
  min-width: 0;
}

.ap-hero-fig picture { display: block; }

.ap-hero-fig img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-2);
  background: var(--panel);
}

@media (min-width: 980px) {
  .ap-hero-fig img { aspect-ratio: 4 / 5; }
}

/* Caption law: the shoot is a shoot, never a packshot */
.ap-fig-cap {
  margin-top: var(--sp-3);
  font-family: var(--font-label);
  font-weight: 500;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--smoke);
}

/* Fact rail — three quiet anchors under the fold line */
.ap-meta {
  display: grid;
  gap: 0;
  margin-top: var(--sp-7);
  border-top: 1px solid var(--line);
}

.ap-meta li {
  padding-block: var(--sp-4);
  border-bottom: 1px solid var(--line);
}

.ap-meta .m-k {
  display: block;
  font-family: var(--font-label);
  font-weight: 600;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--smoke);
  margin-bottom: var(--sp-1);
}

.ap-meta .m-v {
  display: block;
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ivory);
  line-height: 1.25;
  overflow-wrap: anywhere;   /* "518officialapparel.com" must not blow the 360px floor */
}

@media (min-width: 560px) {
  .ap-meta { grid-template-columns: repeat(3, 1fr); }
  .ap-meta li {
    padding-inline: 0;
    padding-right: var(--sp-5);
    border-bottom: none;
    border-top: 1px solid var(--line);
    margin-top: -1px;
  }
}

/* ============================================================
   THE STORE — the one commerce destination, stated plainly
   ============================================================ */
.ap-store-sect {
  background-image: linear-gradient(to bottom,
    color-mix(in srgb, var(--ivory) 3.5%, transparent) 0, transparent 200px);
}

.ap-store {
  position: relative;
  display: grid;
  gap: var(--sp-5);
  border: 1px solid color-mix(in srgb, var(--drop) 32%, transparent);
  border-radius: var(--r-md);
  padding: clamp(1.75rem, 4.5vw, 3rem);
  background: linear-gradient(180deg, var(--panel), transparent);
}

@media (min-width: 768px) {
  .ap-store {
    grid-template-columns: auto 1fr;
    align-items: start;
    gap: var(--sp-7);
  }
}

.ap-store-flag {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  font-family: var(--font-label);
  font-weight: 600;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--drop-text);
  white-space: nowrap;
}

.ap-store-title {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 3.6vw, 2.4rem);
  text-transform: uppercase;
  line-height: 1.08;
  color: var(--ivory);
  margin-bottom: var(--sp-4);
}

.ap-store p { max-width: 56ch; }

.ap-store p + p { margin-top: var(--sp-4); }

.ap-store strong {
  color: var(--drop-text);
  font-weight: 600;
}

.ap-store-cta { margin-top: var(--sp-5); }

/* ============================================================
   COLLECTIONS RAIL — the three real lines
   Whole card = tap target (house Click Protocol: stretched link,
   content links z-raise above the stretch layer).
   ============================================================ */
.ap-rail {
  display: grid;
  gap: var(--sp-5);
  grid-template-columns: 1fr;
}

@media (min-width: 768px) {
  .ap-rail { grid-template-columns: repeat(3, 1fr); }
}

.ap-rail-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: clamp(1.25rem, 3vw, 2rem);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--ivory) 5%, transparent);
  transition:
    transform var(--dur-2) var(--ease),
    border-color var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease);
}

.ap-rail-card:hover,
.ap-rail-card:focus-within {
  transform: translateY(-4px);
  border-color: var(--rizz-hot);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--ivory) 5%, transparent),
              var(--glow-rizz-soft);
}

.ap-rail-idx { color: var(--smoke); }

.ap-rail-name {
  font-size: clamp(1.35rem, 2.4vw, 1.85rem);
  overflow-wrap: anywhere;
}

/* Stretched link — the whole rail card is the anchor's hit area */
.ap-rail-link {
  text-decoration: none;
  color: var(--ivory);
}

.ap-rail-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;   /* house Click Protocol layer */
  border-radius: var(--r-md);
}

.ap-rail-desc {
  font-size: var(--fs-small);
  color: var(--ivory-60);
  max-width: 34ch;
}

.ap-rail-count {
  margin-top: auto;
  padding-top: var(--sp-4);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-family: var(--font-label);
  font-weight: 600;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--smoke);
}

.ap-rail-count::before {
  content: "";
  width: 26px;
  height: 2px;
  background: var(--rizz-line);
  flex: none;
}

/* ============================================================
   COLLECTION HEAD — section copy beside its lookbook art
   ============================================================ */
.ap-coll-top {
  display: grid;
  gap: clamp(var(--sp-6), 4vw, var(--sp-7));
  margin-bottom: clamp(var(--sp-6), 4vw, var(--sp-8));
}

@media (min-width: 980px) {
  .ap-coll-top {
    grid-template-columns: 1.25fr 0.75fr;
    align-items: center;
  }
}

/* The shared .sect-head margin would double the grid gap */
.ap-coll-head { margin-bottom: 0; min-width: 0; }

/* Below the split, the art would otherwise span the whole container and a
   4:5 frame at 900px wide is 1125px tall — a garment shot should not be a
   full screen of scrolling. Cap the frame, not the ratio. */
.ap-coll-art {
  margin: 0;
  min-width: 0;
  max-width: 26rem;
}

.ap-coll-art picture { display: block; }

.ap-coll-art img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-2);
  background: var(--panel);
}

/* Side by side, a frame that fills the whole 0.75fr column stands ~520px
   against ~175px of section copy and opens a hole in the middle of the row —
   so the frame is capped. Cap the WIDTH, never the height: max-height fights
   aspect-ratio and silently letterboxed this 4:5 frame into a ~1.18:1 band
   (measured 416x352), cropping the full-body lookbook portraits to 56% of
   their height and leaving the page carrying two different frame ratios.
   This block must sit AFTER the base .ap-coll-art rule — equal specificity,
   so source order decides (the old min-width:980px block above the base rule
   never applied at all). */
@media (min-width: 980px) {
  .ap-coll-art {
    max-width: 21rem;
    margin-inline-start: auto;
  }
}

/* ---------- BADDIE: a DESIGNED panel, not a photo ----------
   No lookbook frame is evidenced as showing this line, so nothing
   photographic may stand in for it. Typographic panel instead. */
.ap-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  /* Without this the panel sizes from its content and lands ~15px narrower
     than the photo frames it stands in for; the designed tile must measure
     exactly like the frames it replaces. */
  width: 100%;
  aspect-ratio: 4 / 5;
  padding: var(--sp-5);
  text-align: center;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-2);
  background:
    radial-gradient(120% 90% at 50% 0%,
      color-mix(in srgb, var(--drop) 8%, transparent), transparent 64%),
    var(--flyer-ground);
}

.ap-panel-mark {
  font-family: var(--font-logo);
  font-weight: 700;
  font-size: clamp(2.1rem, 5.4vw, 3.4rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ivory);
}

.ap-panel-sub {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 3.4vw, 2rem);
  line-height: 1.05;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--drop-text);
}

.ap-panel-note {
  margin-top: var(--sp-3);
  font-family: var(--font-label);
  font-weight: 500;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--smoke);
}

/* ============================================================
   PRODUCT CARDS — real names, real prices, real store links.
   No packshots: products.json ships images:[] by design.
   ============================================================ */
.ap-grid {
  display: grid;
  gap: var(--sp-5);
  grid-template-columns: 1fr;
  align-items: stretch;   /* equal cards keep orphan rows tidy */
}

@media (min-width: 620px) {
  .ap-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
  .ap-grid { grid-template-columns: repeat(3, 1fr); }
  /* the collab is a pair — two wider cards read better than 2-of-3 */
  .ap-grid--two { grid-template-columns: repeat(2, 1fr); }
}

.ap-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--flyer-ground);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  padding: clamp(1.15rem, 2.6vw, 1.6rem);
  box-shadow: var(--shadow-2), inset 0 1px 0 color-mix(in srgb, var(--ivory) 6%, transparent);
  transition:
    transform var(--dur-2) var(--ease),
    border-color var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease);
}

/* Hover stays COBALT — chrome is chrome even in the store;
   amber is reserved for price chips and store CTAs */
.ap-card:hover,
.ap-card:focus-within {
  transform: translateY(-4px);
  border-color: var(--rizz-hot);
  box-shadow: var(--shadow-2), var(--glow-rizz-soft);
}

.ap-tag {
  color: var(--drop-text);
  margin-bottom: var(--sp-2);
}

/* Store titles print EXACTLY as the store writes them — "WindBreaker",
   "SweatPants", the lowercase "outtaLine". site.css uppercases every h3,
   so this override is load-bearing honesty, not taste: a CSS transform
   would silently rewrite a name the data model requires verbatim.
   They are also long, so they must wrap rather than clip. */
.ap-name {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 1.8vw, 1.3rem);
  text-transform: none;
  line-height: 1.14;
  letter-spacing: 0;
  color: var(--ivory);
  margin-bottom: var(--sp-2);
  overflow-wrap: anywhere;
}

/* Same rule for a brand name sitting inside an uppercase label or display
   line — "51-8 x outtaLine" keeps its own casing wherever it appears. */
.ap-brandcase { text-transform: none; }

.ap-note {
  font-size: var(--fs-small);
  color: var(--ivory-60);
  max-width: 40ch;
}

/* Spec rows — size run only. Stock is the store's to know, not ours. */
.ap-spec {
  display: grid;
  gap: 0;
  margin-top: var(--sp-4);
  border-top: 1px solid var(--line);
}

.ap-spec li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-block: var(--sp-2);
  border-bottom: 1px solid var(--line);
}

.ap-spec .s-k {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--smoke);
}

.ap-spec .s-v {
  font-family: var(--font-label);
  font-weight: 500;
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ivory);
  text-align: right;
}

/* ---------- Price + buy row (pinned to the bottom of the card) ---------- */
.ap-buyrow {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-4);
  margin-top: auto;
  padding-top: var(--sp-5);
}

/* THE PRICE CHIP — an amber fill, so its text is --bg (8.63:1).
   Ivory on amber measures 1.99:1 and is forbidden. The chip carries
   its own honesty framing so no number ever renders naked. */
.ap-price {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-3);
  padding: 0.35rem 0.75rem;
  border-radius: var(--r-xs);
  background: var(--drop);
  color: var(--bg);
}

.ap-price-v {
  font-family: var(--font-logo);
  font-weight: 700;
  font-size: 1.15rem;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--bg);
}

.ap-price-k {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--bg);
  white-space: nowrap;
}

/* THE ONE BUY AFFORDANCE — an external link, never a cart control.
   Stretched over the whole card (house Click Protocol). */
/* NOT a flex container. As inline-flex the label and the ↗ became separate
   flex items: flex items are blockified, so the arrow dropped out of the
   label's underline AND lost the shared baseline (measured 8px high of it,
   floating above a rule that stopped short of it). As an inline-block the
   arrow is ordinary inline content again — one baseline, and .ap-ext's own
   inline-block keeps it off the underline by design rather than by accident.
   padding-block holds the 44px target without centring the glyphs. */
.ap-buy {
  display: inline-block;
  min-height: 44px;
  padding-block: var(--sp-2) var(--sp-1);
  font-family: var(--font-label);
  font-weight: 600;
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--drop-text);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--drop) 50%, transparent);
  text-underline-offset: 0.28em;
  transition: color var(--dur-1) var(--ease),
              text-decoration-color var(--dur-1) var(--ease);
}

.ap-buy::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;   /* house Click Protocol layer */
  border-radius: var(--r-sm);
}

.ap-card:hover .ap-buy,
.ap-buy:hover,
.ap-buy:focus-visible {
  color: var(--drop);
  text-decoration-color: var(--drop);
}

/* The honesty sentence every grid of prices must carry */
.ap-price-law {
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px dashed var(--line-strong);
  font-size: var(--fs-small);
  color: var(--smoke);
  max-width: 62ch;
}

/* ============================================================
   THE LOOKBOOK — real frames + the silent brand film
   ============================================================ */
.ap-look {
  display: grid;
  gap: var(--sp-5);
  grid-template-columns: 1fr;
}

@media (min-width: 620px) {
  .ap-look { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 980px) {
  .ap-look { grid-template-columns: repeat(3, 1fr); }
}

.ap-look-item { min-width: 0; }

.ap-look-item figure { margin: 0; }

.ap-look-item picture { display: block; }

.ap-look-item img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: var(--r-sm);
}

.ap-look-item picture img {
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-2);
  background: var(--panel);
}

/* The film tile matches the photo tiles so the row reads as one sheet */
.ap-look-vslot {
  aspect-ratio: 4 / 5;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-2);
}

.ap-look-vslot .vslot-poster {
  aspect-ratio: auto;   /* the slot owns the ratio here */
  border: 0;
  box-shadow: none;
  border-radius: 0;
}

/* ============================================================
   CLOSING CTA — the store, one more time
   ============================================================ */
.ap-close {
  border-top: 1px solid var(--line);
  background:
    radial-gradient(80% 120% at 50% 100%,
      color-mix(in srgb, var(--ivory) 6%, transparent), transparent 72%),
    var(--bg);
}

.ap-close .eyebrow--center { margin-bottom: var(--sp-4); }

.ap-close-title {
  font-size: clamp(2.2rem, 6vw, 4.2rem);
  max-width: 16ch;
  margin-inline: auto;
}

.ap-close-lead {
  margin: var(--sp-4) auto 0;
  max-width: 48ch;
}

.ap-close-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-4);
  margin-top: var(--sp-6);
}

.ap-relay-note {
  margin: var(--sp-5) auto 0;
  font-size: var(--fs-small);
  color: var(--smoke);
  max-width: 52ch;
}

/* ============================================================
   .btn-drop — the amber commerce CTA (brand-law-sanctioned page
   button; values via tokens, text on amber is --bg, never ivory)
   ============================================================ */
.btn-drop {
  background: var(--drop);
  border-color: transparent;
  color: var(--bg);
}

.btn-drop:hover {
  background: color-mix(in srgb, var(--drop) 86%, white);
  color: var(--bg);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--drop) 30%, transparent),
              0 0 28px color-mix(in srgb, var(--drop) 26%, transparent);
  transform: translateY(-1px);
}

.btn-drop:active {
  background: color-mix(in srgb, var(--drop) 80%, black);
  color: var(--bg);
}

/* ============================================================
   REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .ap-dot { animation: none; }
  .ap-card,
  .ap-rail-card { transition: none; }
  .ap-card:hover,
  .ap-card:focus-within,
  .ap-rail-card:hover,
  .ap-rail-card:focus-within { transform: none; }
  .btn-drop:hover { transform: none; }
}

/* ============================================================
   SMALL-SCREEN GUARD (360px design floor)
   ============================================================ */
@media (max-width: 400px) {
  .ap-hero .drop-flag,
  .ap-store-flag {
    white-space: normal;
    text-align: left;
  }
  .ap-spec li {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-1);
  }
  .ap-spec .s-v { text-align: left; }
  .ap-price {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-1);
  }
}

/* ============================================================
   THE LINE, MOVING — 51-8 lookbook verticals
   These were shot 9:16 and they keep it. They deliberately do
   NOT reuse .ap-look-vslot: that tile is 4/5 with object-fit
   cover, so a 9:16 clip dropped into it loses ~30% of the frame
   top and bottom and takes the top of a head with it. Same law
   as .md-vclip--tall in media.css — never letterbox or
   cover-crop a vertical into a landscape frame.

   The width cap sits on the ITEM, not the .vslot, so the caption
   shares an edge with the media it labels (the overhang Cindy
   caught on media.html 2026-08-17).
   ============================================================ */
.ap-motion {
  display: grid;
  gap: var(--sp-5);
  grid-template-columns: 1fr;
}

@media (min-width: 620px) {
  .ap-motion { grid-template-columns: repeat(2, 1fr); }
}

.ap-motion-item {
  min-width: 0;
  width: 100%;
  max-width: min(100%, 20rem);
  margin-inline: auto;
}

.ap-motion-item figure { margin: 0; }

.ap-motion-item .vslot {
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-2);
}

/* 9:16 on the poster drives the slot height; the <video> is
   absolutely positioned over it and inherits the same box. */
.ap-motion-item .vslot-poster { aspect-ratio: 9 / 16; }
