/* ============================================================================
   final/css/homepage.css — LANE: THE HOME PAGE REWORK (owner, 2026-08-26)
   Written by final/20-homepage.mjs. Linked LAST in <head>, so it wins every
   equal-specificity fight against theme.css / sf-base.css / sf-refresh.css /
   tailwind. It does NOT automatically beat the two <style> blocks that live in
   index.html's BODY (#coa-proof's own block and #home-sections-css) — those are
   later in document order — so every rule that fights one of them is written at
   `body #<section> …`, which outranks their `#<section> …` on specificity and
   settles it without a single !important.

   ── NO COLOUR IS NAMED IN THIS FILE ────────────────────────────────────────
   Not one hex, not one rgb(). The client's sf-refresh.css re-pins the --sf-*
   tokens PER SECTION: #featured-strip, #categories and #home-faq are LIGHT
   plates (white ground, near-black ink, deep-teal accent) while #assurance,
   #coa-proof and #cta-banner stay navy. Everything below resolves through those
   tokens, so the same rule paints correctly on both grounds — and the section
   reorder needed no colour work at all, because the plates follow the ids.

   ── EVERYTHING IS DESIGNED AT 375px FIRST ──────────────────────────────────
   Mobile is the default in every block here and the media queries only ever
   ADD; product cards are two-wide on a phone (owner, explicitly); every tap
   target is >= 44px; nothing is revealed on hover only; and nothing can scroll
   the page sideways — the one wide thing on the page, the featured rail,
   scrolls inside its own overflow-x container.
   ========================================================================== */

/* Line-art glyphs, carried as MASKS rather than as background images. A mask
   takes its colour from `background-color`, so every icon below repaints with
   --sf-accent instead of being baked at a fixed hex — the same rule the hero
   figure and the chrome are held to. The stroke inside each data URI is
   `black` on purpose: under a mask only the ALPHA matters, and spelling it as
   a keyword keeps the `#` out of the URI so nothing has to be escaped. */
:root {
  --cc-ico-grid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.5' y='3.5' width='7' height='7' rx='1.5'/%3E%3Crect x='13.5' y='3.5' width='7' height='7' rx='1.5'/%3E%3Crect x='3.5' y='13.5' width='7' height='7' rx='1.5'/%3E%3Crect x='13.5' y='13.5' width='7' height='7' rx='1.5'/%3E%3C/svg%3E");
  --cc-ico-chain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.5 14.5a4 4 0 0 1 0-5.66l2.12-2.12a4 4 0 1 1 5.66 5.66l-1.06 1.06'/%3E%3Cpath d='M14.5 9.5a4 4 0 0 1 0 5.66l-2.12 2.12a4 4 0 1 1-5.66-5.66l1.06-1.06'/%3E%3C/svg%3E");
  --cc-ico-bolt: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M13 2.5 4.5 13.5H11l-1 8 8.5-11H12z'/%3E%3C/svg%3E");
  --cc-ico-flask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 2.5v7L4.6 19a2 2 0 0 0 1.7 3h11.4a2 2 0 0 0 1.7-3L14 9.5v-7'/%3E%3Cpath d='M8.5 2.5h7'/%3E%3Cpath d='M7 15h10'/%3E%3C/svg%3E");
  --cc-ico-drop: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3c3.5 4 6 6.7 6 10a6 6 0 0 1-12 0c0-3.3 2.5-6 6-10z'/%3E%3C/svg%3E");
  --cc-ico-layers: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 2.8 21 7.6 12 12.4 3 7.6z'/%3E%3Cpath d='M3 12.2 12 17l9-4.8'/%3E%3Cpath d='M3 16.6 12 21.4l9-4.8'/%3E%3C/svg%3E");
  --cc-ico-cell: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M7 12.5c2.2-3.4 7.8-3.4 10 0-2.2 3.4-7.8 3.4-10 0z'/%3E%3C/svg%3E");
  --cc-ico-hex: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 2.6 20 7.2v9.6L12 21.4 4 16.8V7.2z'/%3E%3C/svg%3E");
  --cc-ico-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 5l7 7-7 7'/%3E%3C/svg%3E");
  --cc-ico-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5.2 5.2L20 6.9'/%3E%3C/svg%3E");
}

/* ══════════════════════════════════════════════════════════════════════════
   1. THE TRUST BAND — directly under the hero now
   Four cells, icon LEFT and text RIGHT, on a 2x2 grid. Not four centred
   icon-on-top cards: the reference composition is a compact two-column list,
   and it reads as a fact sheet rather than as a badge row.
   The 2px cyan left rule sf-refresh.css puts on .assure-card comes off — with
   an icon in the first column it is a second marker for the same job.
   ═════════════════════════════════════════════════════════════════════════ */
body #assurance .assure-wrap {
  max-width: 960px;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.35rem 2.4rem;
}
body #assurance .assure-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 0.9rem;
  row-gap: 3px;
  align-items: start;
  padding-left: 0;
  border-left: 0;
}
body #assurance .assure-ico {
  grid-column: 1;
  grid-row: 1 / span 2;
  width: 28px;
  height: 28px;
  margin-top: 1px;
}
body #assurance .assure-k {
  grid-column: 2;
  grid-row: 1;
  font-size: 1rem;
  font-weight: 750;
  letter-spacing: -0.018em;
  line-height: 1.25;
}
body #assurance .assure-v {
  grid-column: 2;
  grid-row: 2;
  font-size: 0.88rem;
  line-height: 1.5;
}
@media (min-width: 34rem) {
  body #assurance .assure-wrap { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ══════════════════════════════════════════════════════════════════════════
   2. THE FEATURED STRIP — a 3-across snap rail (2 on a phone)

   THE OWNER'S BUG, AND THE ONE RULE THAT CAUSED IT. theme.css ships the
   hero-product-forward layout's "first card featured 2x2" flourish:

       body.layout-hero-product-forward .sf-product-grid > *:first-child
         { grid-column: span 2; grid-row: span 2; }

   On an auto-fill grid that resolves to two or three columns — every viewport
   from roughly 560px to 1000px — the first tile IS the full width of the page.
   That is "a single product taking up the whole width of the page", exactly as
   reported. The rule is a LAYOUT AXIS in the engine and is not edited there;
   the override below is scoped to #featured-strip, so products.html keeps it.

   Specificity: theirs is (0,3,1). `body #featured-strip .hero-products > *` is
   (1,1,1), and one id outranks any number of classes.
   ═════════════════════════════════════════════════════════════════════════ */
body #featured-strip .strip-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1rem;
  justify-content: flex-start;
  margin-bottom: 1.25rem;
}
/* On a phone the headline takes a row of its own and the link + arrows share
   the next one; from 48rem they all sit on one line, headline left. */
body #featured-strip .strip-head > div:first-child { flex: 1 1 100%; min-width: 0; }
body #featured-strip .strip-h { font-size: clamp(1.35rem, 2.4vw, 1.9rem); }
body #featured-strip .strip-all {
  margin-right: auto;
  font-size: 0.85rem;
  padding: 0.35rem 0;
}
body #featured-strip .cc-fp-nav { display: flex; gap: 0.5rem; margin-left: auto; }
@media (min-width: 48rem) {
  body #featured-strip .strip-head > div:first-child { flex: 1 1 auto; }
  body #featured-strip .strip-all { margin-right: 0; margin-left: auto; }
  body #featured-strip .cc-fp-nav { margin-left: 0; }
}

/* Real buttons, 44px, ALWAYS visible. A carousel arrow that appears on hover
   does not exist on the phone this rework was asked for. They carry no
   .sf-btn-* class and no data-cta, so qa.mjs's cta-count does not see them —
   they are a scroll control, not a call to action, and this page sits exactly
   on its 3 primary + 2 secondary budget. */
body #featured-strip .cc-fp-arrow {
  width: 44px;
  height: 44px;
  flex: none;
  display: grid;
  place-items: center;
  padding: 0;
  border-radius: 50%;
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--sf-text) 24%, transparent);
  color: var(--sf-text);
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
body #featured-strip .cc-fp-arrow svg { width: 18px; height: 18px; }
body #featured-strip .cc-fp-arrow:hover:not(:disabled),
body #featured-strip .cc-fp-arrow:focus-visible {
  background: var(--sf-accent);
  border-color: var(--sf-accent);
  color: var(--sf-bg);
}
body #featured-strip .cc-fp-arrow:focus-visible { outline: 2px solid var(--sf-accent); outline-offset: 2px; }
/* A disabled control is exempt from the contrast floor, and an arrow that
   cannot scroll must LOOK like it cannot. */
body #featured-strip .cc-fp-arrow:disabled { opacity: 0.3; cursor: default; }

/* THE RAIL. `overflow-x: auto` on the grid itself is what keeps the page from
   ever scrolling sideways: the wide thing scrolls inside its own box. */
body #featured-strip .hero-products {
  --cc-fp-gap: 12px;
  display: flex;
  gap: var(--cc-fp-gap);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-left: 0;
  padding-bottom: 0.4rem;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--sf-text) 26%, transparent) transparent;
}
/* TWO ACROSS ON A PHONE (owner, explicitly), three from 48rem up. The basis is
   written out per breakpoint rather than solved from a column count: dividing
   by a var() inside calc() is legal CSS and works, but this is a live store and
   a flat percentage cannot be got wrong by a parser. Each card gives up its
   share of the gaps — one gap over two columns, two gaps over three. */
body #featured-strip .hero-products > * {
  /* Kills the engine's 2x2 feature-card span dead. */
  grid-column: auto;
  grid-row: auto;
  flex: 0 0 calc(50% - 6px);
  min-width: 0;
  scroll-snap-align: start;
}
@media (min-width: 48rem) {
  body #featured-strip .hero-products { --cc-fp-gap: 16px; }
  body #featured-strip .hero-products > * { flex: 0 0 calc(33.3333% - 10.667px); }
}

/* THE CARD. Plate on top, then category, name, price, and a full-width View
   bar pinned to the bottom edge so a row of cards ends on one straight line
   whatever their names do. */
body #featured-strip .hero-product-tile {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  text-decoration: none;
  border-radius: var(--sf-card-radius, 12px);
  transition: border-color .18s ease, box-shadow .18s ease, transform .18s cubic-bezier(.34, 1.56, .64, 1);
}
body #featured-strip .hero-product-tile:focus-visible { outline: 2px solid var(--sf-accent); outline-offset: 3px; }
body #featured-strip .hero-tile-img {
  aspect-ratio: 1 / 1;
  display: grid;
  place-items: center;
  background: var(--sf-photo-bg, var(--sf-surface));
}
body #featured-strip .hero-tile-img img { width: 100%; height: 100%; }
body #featured-strip .hero-tile-info {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1 1 auto;
  padding: 0.7rem 0.7rem 0.7rem;
}
/* The catalogue category, from client.json. NOT an eyebrow: it labels a card,
   there is no heading under it, its class is not named for the idiom, and its
   tracking sits well under the 0.12em the micro-header detector looks for.
 *
 * ITS HIERARCHY IS COLOUR, NOT SIZE, and that is forced rather than chosen.
 * sf-final-mobile.css pins .hero-tile-name to `14px !important` below 768px —
 * the client's own "big enough to read on mobile" floor — so a category label
 * cannot be made smaller than the name on a phone without going under that
 * floor itself. 0.82rem is ~14px at the mobile root, and the separation comes
 * from --sf-muted against --sf-text. Above 48rem the name grows and the size
 * hierarchy comes back on its own. */
body #featured-strip .cc-fp-cat {
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--sf-muted);
  line-height: 1.2;
}
body #featured-strip .hero-tile-name {
  font-size: 0.95rem;
  font-weight: 750;
  letter-spacing: -0.015em;
  line-height: 1.3;
  color: var(--sf-text);
}
body #featured-strip .hero-tile-price {
  font-size: 1.02rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--sf-text);
}
body #featured-strip .hero-tile-was {
  font-size: 0.85rem;
  text-decoration: line-through;
  color: var(--sf-muted);
}
/* THE VIEW BAR IS GENERATED, NOT MARKUP, and that is the point: the whole card
   is already one <a>, so a second focusable control inside it would be a
   duplicate tab stop and a fifth CTA element. It reads as a button and behaves
   as part of the link. */
body #featured-strip .hero-tile-info::after {
  content: "View";
  margin-top: auto;
  display: block;
  text-align: center;
  padding: 0.6rem;
  font-size: 0.85rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  border-radius: var(--sf-btn-radius, 999px);
  background: var(--sf-text);
  color: var(--sf-bg);
  transition: background-color .18s ease;
}
body #featured-strip .hero-product-tile:hover .hero-tile-info::after,
body #featured-strip .hero-product-tile:focus-visible .hero-tile-info::after {
  background: var(--sf-accent);
}

/* ══════════════════════════════════════════════════════════════════════════
   3. THE TESTING SECTION — one column, a card of numbered rows, a banner

   The rail's ROWS ARE NOT TOUCHED. The reference composition shows eight named
   assays and a test count; those are the reference site's claims. This client
   publishes purity and net content per lot and nothing else, so inventing
   assay names here would be a claim about testing that did not happen. Three
   honest rows beat eight invented ones.
   ═════════════════════════════════════════════════════════════════════════ */
body #coa-proof .coa2-grid {
  grid-template-columns: minmax(0, 1fr);
  max-width: 920px;
  gap: 2rem;
}
body #coa-proof .coa2-lede { max-width: 68ch; margin-bottom: 0; }
body #coa-proof .std-rail { width: 100%; }
body #coa-proof .std-rail .std-item {
  grid-template-columns: 44px minmax(0, 1fr) auto;
  align-items: start;
}
body #coa-proof .std-rail .std-d { max-width: 72ch; }
/* The status marker. A check and nothing else — a WORD here would be a status
   claim this page has not made, and the heading above the rail ("How we handle
   what we ship") already says these are the standard. */
body #coa-proof .std-rail .std-item::after {
  content: "";
  grid-column: 3;
  grid-row: 1;
  align-self: start;
  margin-top: 0.95rem;
  width: 20px;
  height: 20px;
  flex: none;
  background-color: var(--sf-accent-4, var(--sf-accent));
  -webkit-mask: var(--cc-ico-check) center / 20px 20px no-repeat;
  mask: var(--cc-ico-check) center / 20px 20px no-repeat;
}

/* The closing banner. Its wash is mixed FROM --sf-accent rather than picked,
   so it is this client's colour at this client's strength; the ink stays
   --sf-text (14.3:1 on the darkest composited stop of this section) rather
   than a faded muted, because the wash lifts the ground under it and a faded
   ink composites whatever it is standing on. */
body #coa-proof .cc-tb {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.1rem 1.6rem;
  padding: 1.5rem 1.5rem;
  border-radius: var(--sf-radius, 16px);
  background: linear-gradient(118deg,
    color-mix(in srgb, var(--sf-accent) 20%, transparent) 0%,
    color-mix(in srgb, var(--sf-accent) 6%, transparent) 100%);
  border: 1px solid color-mix(in srgb, var(--sf-accent) 40%, transparent);
}
body #coa-proof .cc-tb-text { flex: 1 1 22rem; min-width: 0; }
body #coa-proof .cc-tb-h {
  font-family: var(--sf-font-display, inherit);
  font-size: clamp(1.08rem, 1.9vw, 1.35rem);
  font-weight: 800;
  letter-spacing: -0.026em;
  line-height: 1.25;
  color: var(--sf-text);
  margin: 0 0 0.4rem;
}
body #coa-proof .cc-tb-p {
  font-size: 0.88rem;
  line-height: 1.65;
  color: var(--sf-text);
  margin: 0;
  max-width: 66ch;
}
body #coa-proof .cc-tb-btn { flex: 0 0 auto; white-space: nowrap; }
@media (max-width: 34rem) {
  body #coa-proof .cc-tb-btn { width: 100%; text-align: center; }
}

/* ══════════════════════════════════════════════════════════════════════════
   4. THE CATEGORY CARDS — a 2-up grid, built entirely out of the build's
   own chip anchors. SF:HOME_CATEGORIES is regenerated from the client's real
   catalogue on every build, so nothing here rewrites it: the icon tile is a
   ::before, the glyph is an absolutely-placed masked ::after, and the chevron
   rides .cat-chip-label's ::after. The only markup this lane touches in this
   region is the noun after the number.
   ═════════════════════════════════════════════════════════════════════════ */
body #categories .sf-catalog { max-width: 920px; }
body #categories .cat-rail-head {
  display: block;
  text-align: center;
  margin-bottom: 0.5rem;
}
body #categories .cat-rail-h { font-size: clamp(1.4rem, 2.6vw, 2rem); }
body #categories .cc-cat-sub {
  text-align: center;
  max-width: 52ch;
  margin: 0 auto 1.7rem;
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--sf-muted);
}
body #categories .cat-rail {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.7rem;
}
body #categories .cat-chip {
  position: relative;
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 0.85rem;
  row-gap: 2px;
  /* right padding leaves the chevron its lane */
  padding: 0.8rem 2.5rem 0.8rem 0.85rem;
  min-height: 44px;
  border-radius: var(--sf-card-radius, 12px);
  --cc-cat-ico: var(--cc-ico-hex);
}
/* the tinted icon tile */
body #categories .cat-chip::before {
  content: "";
  grid-column: 1;
  grid-row: 1 / span 2;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--sf-accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--sf-accent) 26%, transparent);
}
/* the glyph, laid over the tile (masked, so it takes the accent) */
body #categories .cat-chip::after {
  content: "";
  position: absolute;
  left: calc(0.85rem + 11px);
  top: 50%;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  background-color: var(--sf-accent);
  -webkit-mask: var(--cc-cat-ico) center / 22px 22px no-repeat;
  mask: var(--cc-cat-ico) center / 22px 22px no-repeat;
}
body #categories .cat-chip-label {
  grid-column: 2;
  grid-row: 1;
  align-self: end;
  font-size: 0.95rem;
  font-weight: 750;
  letter-spacing: -0.015em;
  line-height: 1.25;
  color: var(--sf-text);
}
/* the chevron. It rides the label's ::after because .cat-chip's own two
   pseudo-elements are already the tile and the glyph. */
body #categories .cat-chip-label::after {
  content: "";
  position: absolute;
  right: 0.95rem;
  top: 50%;
  transform: translateY(-50%);
  width: 17px;
  height: 17px;
  background-color: color-mix(in srgb, var(--sf-accent) 80%, transparent);
  -webkit-mask: var(--cc-ico-chevron) center / 17px 17px no-repeat;
  mask: var(--cc-ico-chevron) center / 17px 17px no-repeat;
}
/* the count was an accent pill; as a card it is a quiet second line */
body #categories .cat-chip-count {
  grid-column: 2;
  grid-row: 2;
  align-self: start;
  justify-self: start;
  padding: 0;
  border-radius: 0;
  background: none;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--sf-muted);
}
body #categories .cat-chip:hover .cat-chip-label::after,
body #categories .cat-chip:focus-visible .cat-chip-label::after { right: 0.75rem; }
@media (min-width: 34rem) {
  body #categories .cat-rail { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* "All Compounds" is the way in, so it takes the full first row. */
  body #categories .cat-chip-all { grid-column: 1 / -1; }
}
/* Per-facet glyphs, keyed off the href the build wrote. Anything the list does
   not name keeps the hexagon set on .cat-chip above, so a new category added to
   the catalogue gets an icon rather than an empty tile. */
body #categories .cat-chip-all { --cc-cat-ico: var(--cc-ico-grid); }
body #categories .cat-chip[href*="cat=peptide"] { --cc-cat-ico: var(--cc-ico-chain); }
body #categories .cat-chip[href*="cat=metabolic"] { --cc-cat-ico: var(--cc-ico-bolt); }
body #categories .cat-chip[href*="cat=research-compound"] { --cc-cat-ico: var(--cc-ico-flask); }
body #categories .cat-chip[href*="cat=supplies"] { --cc-cat-ico: var(--cc-ico-drop); }
body #categories .cat-chip[href*="cat=blend"] { --cc-cat-ico: var(--cc-ico-layers); }
body #categories .cat-chip[href*="cat=mitochondrial"] { --cc-cat-ico: var(--cc-ico-cell); }

/* ══════════════════════════════════════════════════════════════════════════
   5. THE FAQ SEAM
   #home-faq now follows #categories and both are light plates, so the two need
   a seam where the section rhythm used to supply one.

   NOTHING HERE COMPENSATES FOR THE CLOSING CTA'S BADGE ROW, and that is the
   correct answer rather than an omission. An earlier version of this file
   carried `.cta-badges { margin-top: 0 }` plus a `:has()` rule to put the
   margin back — written when the badge row was merely EMPTIED and its wrapper
   still shipped. The wrapper is now DELETED outright (20-homepage.mjs §7), so
   both rules matched nothing and came out. There is nothing left to
   compensate: .sf-ctaband-text is a plain block, not a flex or grid container,
   so it contributed no gap; .sf-ctaband-sub is already `margin: 0`; and the
   card is `align-items: center`, so losing the row simply makes the card
   shorter and re-centres both columns. Which is what the owner asked for.
   ═════════════════════════════════════════════════════════════════════════ */
body #home-faq { border-top: 1px solid var(--sf-border-color, color-mix(in srgb, var(--sf-text) 12%, transparent)); }

/* ══════════════════════════════════════════════════════════════════════════
   6. MOTION IS OPT-IN
   Nothing in this file animates on load and there is not one @keyframes here,
   so there is no reveal that could ship a section invisible. What is left are
   the hover/press transitions and the rail's smooth scroll — all of which come
   off for a visitor who asked for less motion. (The rail's scroll behaviour is
   also switched in script, because scrollBy's `behavior` option ignores CSS.)
   ═════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  body #featured-strip .hero-products { scroll-behavior: auto; }
  body #featured-strip .cc-fp-arrow,
  body #featured-strip .hero-product-tile,
  body #featured-strip .hero-tile-info::after,
  body #categories .cat-chip { transition: none; }
  body #featured-strip .hero-product-tile:hover { transform: none; }
  body #categories .cat-chip:hover { transform: none; }
  body #categories .cat-chip:hover .cat-chip-label::after { right: 0.95rem; }
}

/* Print: the rail is a scroll box on screen and a clipped strip on paper. */
@media print {
  body #featured-strip .hero-products { display: grid; grid-template-columns: repeat(3, 1fr); overflow: visible; }
  body #featured-strip .cc-fp-nav { display: none; }
}
