/* redesign-static.css — the same design language, for the 176 generated pages.

   RULE 0 — the order and payment machinery does not change.
   These pages contain no checkout. The buy bar is two links that hand off to
   the SPA (`/#product/<key>`), and this file changes their fill, radius and
   type only. It adds no element, renames nothing, and binds to nothing.
   Delete the two <link> lines and every page renders exactly as before.

   WHY A SECOND FILE. The static pages are a different design system from the
   SPA — .gal, .buybar, .intro, .catnav, .post, .box — but they COLLIDE with
   it on .card, .off, .now and .role. Loading redesign.css here would turn
   their white link-cards into dark blocks with unstyled text. Two scoped
   sheets, each independently removable.

   WHAT WAS WRONG BEFORE, measured not assumed:
   - These pages asked for 'Inter' and 'Space Grotesk' and LOADED NEITHER —
     there was no font link on any of the 176. They rendered in system sans
     while the homepage rendered in Fredoka and Space Grotesk. Same brand,
     two different typefaces depending on which page you landed on.
   - .bb-add was white on #f5491e = 3.59:1, failing AA. That is the primary
     buy button on every product page.
   - The ground was #eaecef, a cool grey that reads cheap beside the
     reference's warm white.
*/

:root {
  --d-paper: #ffffff;
  --d-tint:  #f4f2ee;
  --d-ink:   #16181c;
  --d-on-paper: #16181c;
  --d-on-paper-dim: #5f656e;
  --d-on-ink: #f6f7f8;
  --d-on-ink-dim: #a3a9b2;
  --d-acc:  #f5491e;
  --d-accD: #d63a12;   /* 4.69:1 on white — every primary fill uses this */
  --d-sun:  #ffb400;
  --d-line: #e4e1dc;
  --d-line2:#cfcbc4;
  --d-r: 10px;
  --d-r-lg: 14px;
  --d-r-pill: 999px;
  --d-e-std: cubic-bezier(.4, 0, .2, 1);
  --d-t-ui: .3s;
  --d-font: 'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  /* the page's own tokens, re-pointed so anything still reading them lands
     in the new system instead of the old grey one */
  --orange: #f5491e;
  --ink:   #16181c;
  --muted: #5f656e;
  --paper: #f4f2ee;
  --line:  #e4e1dc;
}

/* ------------------------------------------------------------------ type */

body, h1, h2, h3, h4, h5, h6, button, input, select, textarea,
.buybar a, .homebtn, .catnav a, .specs span, .card .n, .card .p, .crumb {
  font-family: var(--d-font) !important;
}
body {
  background: var(--d-tint);
  color: var(--d-on-paper);
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3 { letter-spacing: -.028em; line-height: 1.06; font-weight: 650; }
h1 { font-stretch: 84%; }
h2, h3 { font-stretch: 90%; }
.wrap { max-width: 1040px; }

/* ---------------------------------------------------------------- header */

header {
  background: rgba(255, 255, 255, .94);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--d-line);
}
header b { font-weight: 700; letter-spacing: -.02em; font-stretch: 88%; }
.homebtn {
  border: 1px solid var(--d-line2) !important;
  border-radius: var(--d-r-pill) !important;
  font-weight: 650 !important;
  padding: 8px 15px !important;
  transition: border-color var(--d-t-ui) var(--d-e-std),
              background var(--d-t-ui) var(--d-e-std);
}
.homebtn:hover { border-color: var(--d-on-paper) !important; background: var(--d-tint) !important; }
.crumb, .crumb a { color: var(--d-on-paper-dim); font-size: 12px; font-weight: 600; }

/* --------------------------------------------------- the content surfaces */

main, .intro, .box, .post {
  background: var(--d-paper);
  border: 1px solid var(--d-line);
  border-radius: var(--d-r-lg);
}
main { padding: 30px; }
h1 { font-size: clamp(1.6rem, 3.4vw, 2.1rem); }

/* --------------------------------------------------------------- gallery */

.gal .hero { border-radius: var(--d-r); background: var(--d-tint); }
.gal .thumbs img {
  border-radius: 7px;
  background: var(--d-tint);
  border: 1px solid var(--d-line);
  transition: border-color var(--d-t-ui), transform var(--d-t-ui) var(--d-e-std);
}
.gal .thumbs img:hover { border-color: var(--d-acc); transform: translateY(-2px); }

/* ------------------------------------------------------- price and specs */

.role { color: var(--d-on-paper-dim); font-weight: 600; }
.specs span {
  background: var(--d-tint) !important;
  border: 1px solid var(--d-line) !important;
  border-radius: var(--d-r-pill) !important;
  font-weight: 600;
}
/* the raw brand orange is 3.59:1 on white and fails AA — the site's own
   darker token measures 4.69:1 */
.price .now {
  color: var(--d-accD);
  font-weight: 800;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}
.price .mrp { color: var(--d-on-paper-dim); font-variant-numeric: tabular-nums; }
.price .off {
  background: var(--d-accD) !important;
  color: #fff !important;
  border-radius: var(--d-r-pill) !important;
  font-weight: 700;
}
.taxline { color: var(--d-on-paper-dim); }
.stock { color: #0a7d33; }

/* ------------------------------------------------------------- buy bar
   The reference's fixed bottom action bar. Two links out to the SPA — no
   checkout logic lives here. */

.buybar {
  background: rgba(255, 255, 255, .95);
  backdrop-filter: blur(16px);
  border-top: 1px solid var(--d-line);
  box-shadow: 0 -14px 34px -16px rgba(22, 24, 28, .26);
}
.buybar a {
  border-radius: var(--d-r-pill) !important;
  font-weight: 700 !important;
  letter-spacing: -.01em;
  transition: background var(--d-t-ui) var(--d-e-std),
              border-color var(--d-t-ui) var(--d-e-std),
              transform .075s cubic-bezier(0, 0, .2, 1);
}
.buybar a:active { transform: scale(.97); }
.bb-add { background: var(--d-accD) !important; color: #fff !important; }
.bb-add:hover { background: var(--d-acc) !important; }
.bb-buy {
  border: 1.5px solid var(--d-on-paper) !important;
  color: var(--d-on-paper) !important;
  background: #fff !important;
}
.bb-buy:hover { background: var(--d-tint) !important; }
@media (min-width: 700px) { .buybar { border-radius: var(--d-r-lg) var(--d-r-lg) 0 0; } }

/* ----------------------------------------------------------------- prose */

.body { color: #2b2e34; }
.body > p, .body h3 + ul, .body h3 + p, .body .tcard {
  border-radius: var(--d-r) !important;
  border: 1px solid var(--d-line) !important;
  box-shadow: none !important;
}
.body h3 {
  border-radius: var(--d-r) var(--d-r) 0 0 !important;
  border: 1px solid var(--d-line) !important;
  border-bottom: 0 !important;
  letter-spacing: .085em;
  font-weight: 700;
  color: var(--d-on-paper);
}
.body h3 + ul, .body h3 + p {
  border-top: 0 !important;
  border-radius: 0 0 var(--d-r) var(--d-r) !important;
}
.body li:before { color: var(--d-accD); }
.body .earnline {
  border-radius: var(--d-r) !important;
  border-color: #f0dcb4 !important;
  background: #fff8ec !important;
  color: #7a4f10 !important;
}
.body .earnline .el-i { color: var(--d-accD); }
.body .tcard {
  transition: border-color var(--d-t-ui) var(--d-e-std),
              transform var(--d-t-ui) var(--d-e-std);
}
.body .tcard:hover { border-color: var(--d-on-paper) !important; transform: translateY(-2px); }
.body .tcard .tc-i { border-radius: var(--d-r) !important; background: var(--d-tint) !important; }
.body .tcard .tc-i svg { color: var(--d-accD); }
.body .pd-assure {
  border-radius: var(--d-r) !important;
  background: var(--d-tint) !important;
  border-color: var(--d-line) !important;
}

table.sheet th { color: var(--d-on-paper-dim); font-weight: 600; }
table.sheet th, table.sheet td { border-bottom: 1px solid var(--d-line); }
table.sheet td { font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------- related / listing
   The reference's defining move, matched to the SPA: the card BODY is a
   solid colour with light text, and the photograph keeps its own light
   well above it. Orange on ink measures 4.96:1. */

.grid { gap: 12px; }
.card {
  background: var(--d-ink) !important;
  border: 0 !important;
  border-radius: var(--d-r) !important;
  padding: 0 !important;
  overflow: hidden;
  transition: transform var(--d-t-ui) var(--d-e-std),
              box-shadow var(--d-t-ui) var(--d-e-std);
}
.card:hover { transform: translateY(-4px); box-shadow: 0 16px 34px -14px rgba(22, 24, 28, .3); }
.card img {
  background: #fff !important;
  border-radius: 0 !important;
  margin: 0 !important;
  height: 130px !important;
}
.card .n { color: var(--d-on-ink); padding: 10px 11px 0; font-weight: 650; }
.card .p {
  color: var(--d-acc);
  padding: 4px 11px 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.catnav a {
  background: var(--d-paper) !important;
  border: 1px solid var(--d-line2) !important;
  border-radius: var(--d-r-pill) !important;
  font-weight: 650 !important;
  transition: border-color var(--d-t-ui) var(--d-e-std),
              background var(--d-t-ui) var(--d-e-std);
}
.catnav a:hover { border-color: var(--d-on-paper) !important; background: var(--d-tint) !important; }

.intro, .box, .post { padding: 26px 28px; }
.intro p, .box p, .post p { color: #2b2e34; line-height: 1.68; }
.muted { color: var(--d-on-paper-dim); }

/* ------------------------------------------------------------------ blog */

.post .byline { color: var(--d-on-paper-dim); font-size: 12.5px; font-weight: 600; }
.post .pd-lead { font-size: 17px; line-height: 1.6; color: var(--d-on-paper); font-weight: 500; }
.bloggrid { gap: 12px; }
.bcard {
  background: var(--d-paper);
  border: 1px solid var(--d-line);
  border-radius: var(--d-r);
  transition: transform var(--d-t-ui) var(--d-e-std), border-color var(--d-t-ui);
}
.bcard:hover { transform: translateY(-3px); border-color: var(--d-on-paper); }
.bcard .bd { color: var(--d-on-paper-dim); }

/* -------------------------------------------------------- nav and footer */

.botnav {
  background: rgba(255, 255, 255, .96);
  backdrop-filter: blur(14px);
  border-top: 1px solid var(--d-line);
}
.botnav .bn { color: var(--d-on-paper-dim); font-weight: 600; }
.botnav .bn:hover { color: var(--d-accD); }
footer { color: var(--d-on-paper-dim); }

a:focus-visible, .card:focus-visible, button:focus-visible {
  outline: 2px solid var(--d-accD) !important;
  outline-offset: 3px;
  border-radius: 6px;
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ------------------------------------------- contrast, found by measuring
   Three misses the sweep caught on the generated pages. */

/* The "TOYS" half of the header wordmark was the raw brand orange on white
   at 3.59:1. Same failure, same fix as everywhere else: the darker token. */
header b span { color: var(--d-accD); }

/* The earnline icon measured 4.45:1 on the cream panel — just under. One
   step darker clears it at 5.25:1. */
.body .earnline .el-i { color: #c2340f; }

/* The trust-card chevron was #b6bdc6 on white = 1.89:1. It is an affordance,
   not decoration, so it gets a real colour. */
.body .tcard .tc-a { color: var(--d-on-paper-dim); }

/* ------------------------------------------------ tap targets, touch only

   Measured at 375px: .homebtn was 32px, the .catnav pills 30px, and the two
   buy-bar buttons 43px — one pixel short. This store is 96.6% mobile, so
   these are the real interaction surfaces.

   Desktop keeps the tighter proportions deliberately; only coarse pointers
   get the larger boxes. Breadcrumb and in-prose links are left alone —
   WCAG 2.5.8 exempts links inline in a sentence, and padding them out would
   break the line. */

@media (max-width: 760px) {
  .homebtn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .catnav a {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .catnav { gap: 9px; }
}

/* The buy bar is the primary conversion control on every product page, so it
   clears 44px at every width, not just on touch. */
.buybar a {
  min-height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* the header brand link measured 36px */
@media (max-width: 760px) {
  .home { min-height: 44px; align-items: center; }
}

/* ----------------------------------------- bottom nav — desktop only off

   Matches the SPA: the phone bottom bar is switched off at 900px, the width
   at which the site's header nav takes over. Below that it stays.

   On these pages the bar also props up the buy bar, which must NOT go
   anywhere — it is the primary conversion control. It simply drops to the
   bottom edge once the nav bar beneath it is gone. */

@media (min-width: 900px) {
  body .botnav { display: none !important; }
  body { padding-bottom: 0; }
  .buybar { bottom: 0; }
}

/* =========================================== SCROLL REVEAL — CSS ONLY

   These pages load no site JavaScript at all: a static page's only script is
   the Google tag. So the reveal the SPA uses - an IntersectionObserver adding
   a class - is not available here, and shipping a script to 181 pages to
   animate some paragraphs would be the wrong trade on a catalogue whose
   mobile LCP is already the site's known problem.

   Scroll-driven animation does it in CSS, on the compositor, with no request
   and no main-thread work. And it has a property an observer-based reveal
   does not: IT CANNOT LEAVE CONTENT INVISIBLE. `view()` resolves the timeline
   from the element's own position, so an element already on screen at load
   computes straight to the end of its range - there is no class waiting to
   arrive, no failsafe to miss, and nothing that can sit at opacity 0 because
   a script never ran. That is Trap 6 made structurally impossible instead of
   merely guarded against.

   The @supports guard means a browser without scroll-driven animations shows
   the content plainly and immediately, which is the correct failure.

   NOTHING IN THE BUY PATH IS ANIMATED - not the gallery, the price, the stock
   line, the tax line, the earn line or the buy bar. A customer must never
   wait on a transition to see what a machine costs or how to order it. Only
   the reading matter below it moves. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .intro, .body, .specs, .incl, .tcards, .rel, .box, .post,
    .grid > .card, .bloggrid > .bcard {
      animation: sr-rise both linear;
      animation-timeline: view();
      /* finished well before the element reaches the middle of the screen: a
         reveal still running once the reader has arrived at it is a reveal
         that is in the way */
      animation-range: entry 0% entry 38%;
    }
  }
}
/* TRANSFORM ONLY. NOTHING HERE FADES FROM ZERO, AND THAT IS THE WHOLE POINT.

   `animation-fill-mode: both` means an element sitting BEFORE its range holds
   the `from` frame. If that frame carried `opacity: 0`, then any element whose
   ViewTimeline never advances is invisible - and a timeline that never
   advances is not hypothetical: `view()` resolves against the nearest SCROLL
   CONTAINER, so an element inside a horizontally-scrolling strip (the related
   -products rail is one) has a timeline whose vertical progress never
   changes. It would sit at the `from` frame for the life of the page.

   Across 181 generated pages that is not a risk worth taking to buy a fade.
   Moving 14px is still a reveal; being invisible is a broken page. If this
   animation never runs - unsupported browser, inactive timeline, reduced
   motion - every word is fully legible, just 14px lower.

   This is Trap 6 obeyed rather than argued with. */
@keyframes sr-rise {
  from { transform: translateY(14px); }
  to   { transform: none; }
}
