/* ═══════════════════════════════════════════════════════════════════
   /categories/ — the browse-all-ranges page.
   Tokens only; tokens.css is the only file allowed to define a colour.

   MOBILE FIRST. Everything below the first breakpoint IS the phone
   layout; every @media in this file is min-width. The list rows, the
   subcategory scroller and the "Shop all" control are the same
   components on both — the breakpoint changes the form factor, never
   the feature set (§9.1).
   ═══════════════════════════════════════════════════════════════════ */

.cat-page{padding-block:var(--sp-4) var(--sp-10)}
.cat-page-head{margin-top:var(--sp-4)}
.cat-page h1{font-size:1.5rem;font-weight:800;letter-spacing:-.01em}
/* 16px floor for anything a customer reads (§9.2). .sec-head .sub is
   .9375rem for a section subtitle; this one is the page's opening
   sentence, so it is body copy and sits at the floor. */
.cat-page-head .sub{font-size:1rem;color:var(--ink-2);max-width:56ch}

.cat-ranges{display:flex;flex-direction:column;gap:var(--sp-4);margin-top:var(--sp-5)}

/* ── One range ──────────────────────────────────────────────────── */
.cat-range{background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);padding:var(--sp-4);
  /* The subcategory scroller lives inside; the card keeps its corners
     (UI_UX §9.7 rule 2) and nothing bleeds past the viewport edge. */
  overflow:hidden}

.cat-range-head{display:flex;align-items:center;gap:var(--sp-3);min-height:var(--tap)}
/* §9.3 — an icon beside a heading is ≥26px, sized in em off the parent
   so the pair scales together. */
.cat-range-head .ico{width:1.6em;height:1.6em;color:var(--brand-ink)}
.cat-range-head h2{font-size:1.25rem;font-weight:800;letter-spacing:-.01em;min-width:0}
/* The heading IS the link to the range, so it carries the 44px target
   itself rather than borrowing the row's. inline-flex, not a 44px
   line-height, so a two-word range name still wraps cleanly. */
.cat-range-head h2 a{color:var(--ink);display:inline-flex;align-items:center;
  min-height:var(--tap);line-height:1.25}
.cat-range-head h2 a:hover{color:var(--brand-ink)}

.cat-range-note{font-size:1rem;line-height:1.55;color:var(--ink-2);
  max-width:65ch;margin-top:var(--sp-1)}

/* ── Subcategories — a contained scroller, never a truncated list ──
   §9.10 forbids a silent cut and §9.16 already answers this for the
   header strip: carry ALL of them and let the row scroll, so no link
   is hidden behind a guess about how many fit. Momentum on, scrollbar
   hidden, and the last pill sits partly cut at the edge so the swipe
   is discoverable (UI_UX §9.7 rule 4). */
.cat-subs{margin-top:var(--sp-3);overflow-x:auto;overscroll-behavior-x:contain;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;
  margin-inline:calc(var(--sp-4) * -1);padding-inline:var(--sp-4)}
.cat-subs::-webkit-scrollbar{display:none}
.cat-subs-track{display:flex;gap:var(--sp-2);width:max-content;padding-block:2px}
.cat-sub{display:inline-flex;align-items:center;min-height:var(--tap);
  padding:0 var(--sp-4);border:1px solid var(--line);border-radius:var(--r-full);
  background:var(--surface);color:var(--ink);font-size:1rem;font-weight:600;
  white-space:nowrap}
.cat-sub:hover{border-color:var(--brand);color:var(--brand-ink);background:var(--brand-xlight)}
.cat-sub:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* The SAME strip on a listing page (/product-category/…), where the
   ground is .wrap rather than a range card.
   THE BLEED MUST BE --gutter, NOT --sp-4. They are equal on a phone and
   then diverge: base.css moves --gutter to --sp-5 at 768px and --sp-8 at
   1280px. Reusing the card's fixed --sp-4 above would leave this row
   inset from the product grid it belongs to at every desktop width — the
   kind of drift a phone-only check never catches. */
.cat-subs.on-listing{margin-top:var(--sp-3);
  margin-inline:calc(var(--gutter) * -1);padding-inline:var(--gutter)}

/* The aisle you are standing in. NEVER COLOUR ALONE (§9.2): the chip
   carries bold weight and a brand border as well as the tint, and
   aria-current="page" says the same thing to a screen reader.
   Computed, not estimated (§10.4) — brand-ink on brand-light is 4.67:1
   light and 5.82:1 dark. */
.cat-sub.is-on{background:var(--brand-light);border-color:var(--brand);
  color:var(--brand-ink);font-weight:700}

/* ── The few products — a list row, not a card ──────────────────── */
.cat-items{margin-top:var(--sp-3);display:grid;grid-template-columns:minmax(0,1fr);
  gap:var(--sp-2)}
.cat-item{min-width:0}
/* height:100% so two rows sitting side by side in the ≥640px grid match
   each other when one product name wraps and the other does not. */
.cat-item-link{display:flex;align-items:center;gap:var(--sp-3);height:100%;
  min-height:calc(var(--tap) + var(--sp-5));padding:var(--sp-2);
  border:1px solid var(--line-soft);border-radius:var(--r);
  background:var(--surface);color:var(--ink)}
.cat-item-link:hover{border-color:var(--brand);background:var(--brand-xlight)}
.cat-item-link:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
/* .media is catalog.css's 1:1 box — the Store API publishes no intrinsic
   image dimensions, so the row reserves a square and nothing shifts on
   decode (§6). */
.cat-item-link .media{flex:0 0 auto;width:64px}
.cat-item-text{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1 1 auto}
/* Two lines, then it stops — the row is a preview and the product page
   carries the full name. No ellipsis is written into the copy; this is
   a layout clamp, and the whole name stays in the DOM. */
.cat-item-text .nm{font-size:1rem;font-weight:600;line-height:1.35;color:var(--ink);
  display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;overflow-wrap:anywhere}
.cat-item-text .card-price .now{font-size:1rem}
.cat-item-go{flex:0 0 auto;width:22px;height:22px;color:var(--ink-3)}

.cat-all{margin-top:var(--sp-4);width:100%}

/* The skeleton stands in at roughly the height of a painted range, so
   the list does not jump when the real thing lands. */
.cat-skel{padding:var(--sp-2) 0 var(--sp-3);border:0;background:transparent}
.cat-skel .bar{margin-inline:0}

/* ── From 640px: the list runs two across, same rows ─────────────── */
@media (min-width:640px){
  .cat-page h1{font-size:1.75rem}
  .cat-range{padding:var(--sp-5)}
  .cat-subs{margin-inline:calc(var(--sp-5) * -1);padding-inline:var(--sp-5)}
  .cat-items{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-3)}
  .cat-all{width:auto}
}

/* ── From 900px: the range header and its parts share a row ────────
   Same markup, same components — the block simply stops stacking once
   there is width for the heading, its description and its "Shop all"
   control to sit beside the products (§9.1). */
@media (min-width:900px){
  .cat-page h1{font-size:2rem}
  .cat-ranges{gap:var(--sp-5)}
  .cat-range{display:grid;grid-template-columns:minmax(0,300px) minmax(0,1fr);
    column-gap:var(--sp-6);align-items:start;padding:var(--sp-6)}
  .cat-range-head{grid-column:1;grid-row:1}
  .cat-range-note{grid-column:1;grid-row:2}
  .cat-all{grid-column:1;grid-row:3;justify-self:start;margin-top:var(--sp-4)}
  /* The scroller keeps the card's own padding as its bleed on this side. */
  .cat-subs{grid-column:2;grid-row:1;margin-top:0;
    margin-inline:0 calc(var(--sp-6) * -1);padding-inline:0 var(--sp-6)}
  .cat-items{grid-column:2;grid-row:2 / span 2;margin-top:var(--sp-3)}
}

@media (min-width:1200px){
  .cat-range{grid-template-columns:minmax(0,340px) minmax(0,1fr)}
  .cat-item-link .media{width:72px}
}
