/* ============================================================
   SWEETFRONT COMPONENTS v4 — shared by the hub and both demos
   .plate · .poster · .label · .order-strip · .chip · .spec-row ·
   .table-editorial · .quote-pull · .stat-band · .panel · forms ·
   .cta-sticky. Tokens and base rules come from system.css,
   colours from each page's own style.css.
   ============================================================ */

/* ---------- .plate — seed-catalog double frame + museum placard ---------- */
/* one hairline, not a frame inside a frame (simplified 20 Sep): the picture is the object, a contact shadow lifts it */
.plate { margin: 0; }
.plate-inner {
  position: relative;
  display: block;
  overflow: hidden;
  border: 1px solid var(--rule-soft);
  aspect-ratio: var(--ar, 4 / 5);
  background: var(--bg);
}
.plate-inner > img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.plate figcaption {
  display: flex;
  justify-content: space-between;
  gap: 8px 16px;
  flex-wrap: wrap;
  margin-top: 10px;
  color: var(--muted);
}
.plate-dark { background: transparent; border-color: var(--rule-dark); }
.plate-dark .plate-inner { border-color: var(--rule-dark-soft); }
.plate-dark figcaption { color: var(--muted-dark); }
a.plate-inner { color: inherit; box-shadow: 0 26px 40px -30px color-mix(in oklab, var(--fg) 55%, transparent); }

/* M5 — tilt (micro.js feeds --tilt-x / --tilt-y, each −.5 … .5): at most ±0.6°, one element per page */
[data-tilt] { transition: transform var(--t-slow) var(--ease); }
@media (hover: hover) and (pointer: fine) {
  [data-tilt]:hover { transform: perspective(900px) rotateX(calc(var(--tilt-y, 0) * -1.2deg)) rotateY(calc(var(--tilt-x, 0) * 1.2deg)); }
}

/* Atmosphere photographs only (never product shots — colour sells the product):
   one recipe for every photo = one film. See docs/PHOTO-SLOTS.md */
.plate-photo > img { filter: grayscale(1) contrast(1.06) brightness(.97); }
.plate-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--tone, var(--dark-a));
  mix-blend-mode: color;
  opacity: .82;
}
.plate-photo::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(180deg, rgba(251, 247, 238, .10), transparent 40%);
}

/* Typographic poster — fills a plate where a photograph is not supplied */
.poster {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-rows: auto 1fr auto;
  padding: clamp(18px, 4vw, 30px);
  color: var(--on-dark);
  background: var(--dark-a);
  background: radial-gradient(130% 100% at 20% 0%, var(--dark-a) 0%, var(--dark-b) 60%, var(--dark-c) 100%);
}
.poster::before {
  content: "";
  position: absolute;
  inset: 10px;
  border: 1px solid var(--rule-dark-soft);
  pointer-events: none;
}
.poster p { margin: 0; max-width: none; }
.poster-top { display: flex; justify-content: space-between; gap: 12px; color: var(--muted-dark); }
.hero-plate .plate-inner { container-type: inline-size; }
.poster-big {
  align-self: center;
  font-family: var(--display);
  font-variation-settings: 'SOFT' 20, 'WONK' 1;
  font-weight: 600;
  font-size: clamp(5.5rem, 3rem + 11vw, 10.5rem);
  line-height: .9;
  letter-spacing: -.04em;
  font-variant-numeric: lining-nums;
}
@supports (font-size: 1cqw) { .poster-big { font-size: min(50cqw, 15rem); } }   /* numerals span the plate */
.poster-big small { font-size: .34em; letter-spacing: 0; font-weight: 500; font-style: italic; margin-left: .12em; }
.poster-mark { color: var(--accent-on-dark); }
.poster-sub { color: var(--on-dark); font-weight: 600; }
/* hero entrance, demo side: the numerals settle, their two captions follow (the plate itself stays put —
   it is the view-transition target coming from the hub) */
@media (prefers-reduced-motion: no-preference) {
  .poster-big { animation: numerals-settle 1.3s var(--ease-expo) backwards; }
  .poster-top, .poster-sub { animation: rise-in .8s var(--ease-expo) .5s backwards; }
  @keyframes numerals-settle { from { opacity: 0; transform: scale(1.09); } }
}

/* ---------- .label — a printed label, pure typography (text stays HTML) ---------- */
.label {
  position: relative;
  width: min(100%, 300px);
  margin: auto;
  padding: 24px 20px 20px;
  display: grid;
  gap: 12px;
  text-align: center;
  background: var(--card, var(--bg));   /* the label is the lightest thing on the inset plate */
  border: 1px solid var(--fg);
  box-shadow: 0 22px 26px -22px rgba(28, 25, 23, .38);   /* one contact shadow: the label is an object lying on paper */
}
.label::before {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1px solid var(--rule-soft);
  pointer-events: none;
}
.label p { margin: 0; max-width: none; }
.label-maker { color: var(--fg); font-weight: 600; font-size: .8125rem; }
.label-rule { width: 36px; height: 1px; margin-inline: auto; background: var(--fg); }
.label-name {
  font-family: var(--display);
  font-variation-settings: 'SOFT' 20, 'WONK' 1;
  font-weight: 600;
  font-size: clamp(1.75rem, 1.3rem + 1.6vw, 2.5rem);
  line-height: 1;
  letter-spacing: -.015em;
}
.label-name em { display: block; font-weight: 500; }
.label-swatch {
  height: 30px;
  margin-inline: -20px;
  background: var(--swatch);
  box-shadow: 0 -1px 0 var(--fg), 0 1px 0 var(--fg);   /* the band's two ink lines: drawn, not a box */
  transition: background-color var(--t-slow) var(--ease);
}
.label-meta { color: var(--muted); font-size: .8125rem; }
.label-kind { font-family: var(--display); font-style: italic; font-size: 1rem; color: var(--muted); }
@media (forced-colors: active) { .label-swatch { border-block: 1px solid CanvasText; } }   /* shadows are not painted there */
.plate-label .plate-inner {
  display: grid;
  place-items: center;
  padding: 36px 16px;
  aspect-ratio: auto;
  min-height: 320px;
  border: 0;
  /* printer's crop marks in the four corners */
  --c: var(--rule);
  background:
    linear-gradient(90deg, var(--c) 0 16px, transparent 16px calc(100% - 16px), var(--c) calc(100% - 16px)) 14px 14px / calc(100% - 28px) 1px no-repeat,
    linear-gradient(90deg, var(--c) 0 16px, transparent 16px calc(100% - 16px), var(--c) calc(100% - 16px)) 14px calc(100% - 14px) / calc(100% - 28px) 1px no-repeat,
    linear-gradient(180deg, var(--c) 0 16px, transparent 16px calc(100% - 16px), var(--c) calc(100% - 16px)) 14px 14px / 1px calc(100% - 28px) no-repeat,
    linear-gradient(180deg, var(--c) 0 16px, transparent 16px calc(100% - 16px), var(--c) calc(100% - 16px)) calc(100% - 14px) 14px / 1px calc(100% - 28px) no-repeat,
    var(--bg-2);
}
.plate-label { padding: 0; border: 0; }   /* one inset tile — no double frame around a label (CLARITY v5 2.5) */

/* ---------- .stamp + .signature — the hand (CHARACTER v6: one of each per page, both true) ---------- */
.stamp {
  position: absolute;
  z-index: 1;
  margin: 0;
  padding: 5px 10px 4px;
  border: 2px solid currentColor;
  color: var(--accent-text);
  font-weight: 600;
  white-space: nowrap;
  transform: rotate(-3.5deg);
  pointer-events: none;
}
.poster .stamp { color: var(--accent-on-dark-text, var(--accent-on-dark)); }
.signature { display: grid; gap: 4px; justify-items: start; margin: 22px 0 0; max-width: none; }
.signature svg { display: block; width: 168px; height: auto; color: var(--fg); overflow: visible; }
.section-dark .signature svg { color: var(--on-dark); }
.section-dark .signature .mono { color: var(--muted-dark); }

/* order strip — shared by both demos' shop sections */
.order-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 28px;
  margin-top: 44px;
}
.order-line { margin: 0; max-width: none; font-weight: 600; }
.order-line a { display: inline-block; color: var(--accent-text); padding: 13px 2px; margin: -13px -2px; } /* ≥44px target */

/* ---------- .chip — tint, not a bare border ---------- */
.chip {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border: 1px solid currentColor;
  border-radius: 0;
  background: transparent;
  background: color-mix(in oklab, currentColor 8%, transparent);
  font-weight: 600;
  white-space: nowrap;
}
.chip-wrap { white-space: normal; }   /* long standalone chips may wrap on phones */
.chip-ok { color: var(--ok); }
.chip-out { color: var(--muted); background: color-mix(in oklab, var(--cool, currentColor) 20%, transparent); border-color: var(--cool, currentColor); }   /* the one cool note */
.chip-pre { color: var(--fg); }

/* ---------- .spec-row — product / index row (replaces mini illustrations) ---------- */
.spec-list { list-style: none; margin: 0; padding: 0; }
.spec-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 4px 12px;
  padding: 22px 8px;
  border-bottom: 1px solid var(--rule);   /* one hairline per row: the leader rule that ties a name to its right-aligned price (≥ 3:1) */
  transition: background-color var(--t-fast) var(--ease);
}
.spec-row p { margin: 0; }
.sr-name { font-family: var(--display); font-variation-settings: 'SOFT' 14, 'WONK' 1; font-weight: 600; font-size: var(--fs-h3); line-height: 1.2; margin: 0 0 4px; transition: transform var(--t-fast) var(--ease); }
.sr-note { color: var(--muted); max-width: 60ch; }
.spec-row .sr-meta { grid-column: 1; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-top: 8px; color: var(--fg); font-weight: 600; }
@media (min-width: 640px) {
  .spec-row { grid-template-columns: minmax(0, 1fr) auto; column-gap: 20px; }
  .spec-row .sr-meta { grid-column: 2; align-self: start; justify-content: flex-end; margin-top: 4px; text-align: right; }
}
@media (hover: hover) and (pointer: fine) {
  /* M2 — the row answers the pointer: a breath of the page accent and a 3px nudge of the name */
  .spec-row:hover { background: rgba(28, 25, 23, .03); background: color-mix(in oklab, var(--accent) 5%, transparent); }
  .spec-row:hover .sr-name { transform: translateX(3px); }
}

/* ---------- .table-editorial — hairline grid, zebra, cards under 640px ---------- */
.table-editorial { display: block; width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.table-editorial tbody { display: block; }
.table-editorial thead { display: none; }   /* phones: td::before carries the column label */
.table-editorial tbody tr {
  display: block;
  border: 1px solid var(--rule-soft);
  border-radius: 0;
  padding: 10px 0;
  margin-bottom: 14px;
  background: var(--card, var(--bg));
}
.table-editorial tbody th {
  display: block;
  text-align: left;
  padding: 6px 14px;
  font-family: var(--display);
  font-size: 1.125rem;
  font-weight: 600;
}
.table-editorial tbody td { display: flex; gap: 10px; padding: 6px 14px; text-align: left; }
.table-editorial tbody td::before {
  content: attr(data-label);
  flex: 0 0 112px;
  font-family: var(--mono);
  text-transform: uppercase;
  letter-spacing: .08em;
  font-size: .875rem;
  font-weight: 600;
  color: var(--muted);
  padding-top: 3px;
}
@media (min-width: 640px) {
  .table-editorial { display: table; }
  .table-editorial thead {
    display: table-header-group;
  }
  .table-editorial tbody { display: table-row-group; }
  /* hairlines live on the rows, not on every cell (CLARITY v5 2.5) */
  .table-editorial thead tr { border-bottom: 2px solid var(--fg); }
  .table-editorial tbody tr { display: table-row; border: 0; border-bottom: 1px solid var(--rule-soft); padding: 0; margin: 0; background: transparent; }
  .table-editorial tbody tr:nth-child(even) { background: rgba(28, 25, 23, .03); background: color-mix(in oklab, var(--fg) 3%, transparent); }
  .table-editorial thead th {
    font-family: var(--mono);
    text-transform: uppercase;
    letter-spacing: .09em;
    font-size: .8125rem;
    font-weight: 600;
    color: var(--muted);
    text-align: left;
    padding: 12px 16px;
  }
  .table-editorial tbody th, .table-editorial tbody td {
    display: table-cell;
    padding: 16px;
    vertical-align: top;
  }
  .table-editorial tbody th { font-size: 1.0625rem; }
  .table-editorial tbody td::before { content: none; }
}

/* not every chapter opens the same way: here the title stands left and the lead answers it on the right */
@media (min-width: 860px) {
  .sec-head-split { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: 48px; align-items: end; }
  .sec-head-split .sec-label { grid-column: 1 / -1; }
  .sec-head-split .sec-title { margin-bottom: 0; }
  .sec-head-split .lead { margin: 0; max-width: 54ch; }
}

/* ---------- .quote-pull ---------- */
.quote-pull {
  font-family: var(--display);
  font-style: italic;
  font-variation-settings: 'SOFT' 30, 'WONK' 1;
  font-weight: 500;
  font-size: clamp(1.875rem, 1.2rem + 2.8vw, 3.5rem);
  line-height: 1.1;
  letter-spacing: -.015em;
  max-width: 18ch;
  margin: 0;
  text-indent: -.42em;          /* opening quote hangs into the margin */
  hanging-punctuation: first;
  color: var(--fg);
}
.section-dark .quote-pull { color: var(--on-dark); }
@supports (hanging-punctuation: first) { .quote-pull { text-indent: 0; } }

/* ---------- .stat-band ---------- */
.stat-band {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 56px 0 0;
  border-top: 1px solid var(--rule-soft);
}
.section-dark .stat-band { border-top-color: var(--rule-dark-soft); }
.stat { display: flex; flex-direction: column-reverse; gap: 6px; padding: 22px 16px 22px 0; border-bottom: 1px solid var(--rule-soft); }
.section-dark .stat { border-bottom-color: var(--rule-dark-soft); }
.stat dt { color: var(--muted); }
.section-dark .stat dt { color: var(--muted-dark); }
.stat dd {
  margin: 0;
  font-family: var(--display);
  font-variation-settings: 'SOFT' 14, 'WONK' 1;
  font-weight: 600;
  font-size: clamp(2rem, 1.5rem + 1.6vw, 2.75rem);
  line-height: 1;
  font-variant-numeric: tabular-nums lining-nums;
}
.stat:nth-child(even) { padding-left: 20px; border-left: 1px solid var(--rule-soft); }
.section-dark .stat:nth-child(even) { border-left-color: var(--rule-dark-soft); }
@media (min-width: 860px) {
  .stat-band { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .stat { border-bottom: 0; }
  .stat + .stat { padding-left: 28px; border-left: 1px solid var(--rule-soft); }
  .section-dark .stat + .stat { border-left-color: var(--rule-dark-soft); }
}

/* ---------- .panel — inset paper-2 surface ---------- */
.panel {
  background: var(--bg-2);
  border: 1px solid var(--rule-soft);
  border-radius: 0;
  padding: 28px 24px;
}
.panel > :last-child { margin-bottom: 0; }
/* value ladder (CLARITY v5 2.2): paper → inset panel (--bg-2) → lifted card (--card).
   A panel that sits on a --bg-2 band, and the page's one featured panel, are cards. */
.band .panel, .panel-feature { background: var(--card, var(--bg)); }
/* featured panel: double frame + the page's one stamped card */
.panel-feature { position: relative; padding: 36px 28px; box-shadow: 4px 4px 0 var(--fg); }
.panel-feature::before {
  content: "";
  position: absolute;
  inset: 6px;
  border: 1px solid var(--rule-soft);
  pointer-events: none;
}
.price {
  font-family: var(--display);
  font-variation-settings: 'SOFT' 14, 'WONK' 1;
  font-weight: 600;
  font-size: var(--fs-price);
  line-height: 1;
  font-variant-numeric: tabular-nums lining-nums;
}
.price-md { font-size: 2rem; }
.price-unit { color: var(--muted); font-size: .9375rem; }   /* the unit beside a display-size price: body type, not mono */

/* hairline feature rows (pricing, benefits) */
.rows { list-style: none; margin: 0; padding: 0; }
.rows li { padding: 12px 0; border-top: 1px solid var(--rule-soft); color: var(--muted); }
.rows li:last-child { border-bottom: 1px solid var(--rule-soft); }

/* ---------- FORMS ---------- */
.field-label { display: block; margin: 0 0 8px; font-size: .9375rem; font-weight: 600; color: var(--muted); }
.input {
  width: 100%;
  min-height: 56px;
  padding: 0 16px;
  border: 2px solid var(--rule);
  border-radius: 0;
  background: var(--card, var(--bg));
  color: var(--fg);
  font-family: var(--body);
  font-size: 1.0625rem;
}
.input::placeholder { color: var(--muted); }
.input:user-invalid, .input[aria-invalid="true"] { border-color: var(--accent); border-width: 3px; }
.section-dark .field-label { color: var(--muted-dark); }
.section-dark .input { background: transparent; border-color: var(--rule-dark); color: var(--on-dark); }
.section-dark .input::placeholder { color: var(--muted-dark); }
.section-dark .input:user-invalid, .section-dark .input[aria-invalid="true"] { border-color: var(--focus-dark); }

/* ---------- .cta-sticky — mobile action bar (demos) ---------- */
.cta-sticky {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 80;
  display: flex;
  gap: 10px;
  padding: 8px 12px calc(8px + env(safe-area-inset-bottom));
  background: var(--bg);
  border-top: 1px solid var(--rule);
}
.cta-sticky .btn { flex: 1 1 auto; padding-inline: 16px; }
.cta-sticky .cta-call { flex: 0 0 auto; }
@media (max-width: 859px) {
  html { scroll-padding-bottom: calc(76px + env(safe-area-inset-bottom)); }   /* WCAG 2.4.11 focus not obscured */
  body.has-cta-sticky { padding-bottom: calc(64px + env(safe-area-inset-bottom)); }
}
@media (min-width: 860px) { .cta-sticky { display: none; } }

/* ==========================================================================
   SECTION PAGING — docs/SECTION-PAGING.md (chapters 5 variant B, 6, 7)
   Shared here instead of three style.css copies; doc tokens map to the contract:
   --ink → --fg · --fire / --honey / --maple → --accent(-text).
   ========================================================================== */
.section-index { display: none; }
.scroll-progress { display: none; }

@media (min-width: 64rem) and (hover: hover) and (pointer: fine) {
  .section-index {
    display: block;
    position: fixed;
    right: max(20px, env(safe-area-inset-right));
    top: calc(50% + var(--head-h) / 2);   /* centre of the area below the sticky header, not of the whole window */
    top: round(down, calc(50% + var(--head-h) / 2), 1px);   /* …on whole pixels: a hairline on a half pixel smears over two rows */
    transform: translateY(var(--tab-shift, -50%));   /* micro.js: the RAIL stays on that line while the tab grows upwards with the name */
    z-index: 40;
    /* a paper tab: --muted numerals vanish on the dark bands, and mix-blend-mode: difference
       would turn the brand accent cyan — so the register carries its own ground */
    --tab-bg: var(--bg);
    --tab-rule: var(--rule-soft);
    padding: calc(var(--name-h, 0px) + 8px) 6px 8px;   /* --name-h: room for the current chapter's name, measured by micro.js */
    background: var(--tab-bg);
    border: 1px solid var(--tab-rule);
    border-radius: 0;
    transition: background-color var(--t-base) var(--ease), border-color var(--t-base) var(--ease), opacity var(--t-base) var(--ease);
  }
  /* a type poster is a picture, not a chapter: the register steps aside while one is under it (keyboard focus brings it back) */
  .section-index.is-poster { opacity: 0; pointer-events: none; }
  .section-index.is-poster:focus-within { opacity: 1; pointer-events: auto; }
  /* over a dark sheet the tab turns dark with it (micro.js watches the ground under its middle row) */
  .section-index.is-dark {
    --fg: var(--on-dark);
    --muted: var(--muted-dark);
    --accent: var(--accent-on-dark);
    --focus: var(--focus-dark);
    --tab-bg: var(--dark-c);
    --tab-rule: var(--rule-dark-soft);
  }
  /* ONE paper tab: the name of the current chapter, written along the rail, and under it the rail of ticks.
     The tab is exactly as tall as the word needs (a fixed slot left it half empty; a separate cap on top of the rail
     showed a seam and a sideways step at 125 % scaling — owner, 20–21 Sep). The ticks never move.
     No numerals: bare numbers read like console output. */
  .section-index ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; align-items: center; gap: 0; }
  .section-index.named a { display: block; box-sizing: border-box; width: 34px; padding: 8px 6px; text-decoration: none; }   /* 22px tick + padding: the tab never changes width */
  .section-index.named a::before {
    content: "";
    display: block;
    width: 12px;
    height: 2px;
    margin-inline: auto;
    background: var(--muted);
    opacity: .75;   /* 3.8:1 on paper — a tick is the whole visible control (non-text 3:1) */
    transition: width var(--t-base) var(--ease), opacity var(--t-base) var(--ease), background-color var(--t-base) var(--ease);
  }
  .section-index.named a:hover::before, .section-index.named a:focus-visible::before { opacity: 1; background: var(--fg); }
  .section-index.named a[aria-current]::before { width: 22px; opacity: 1; background: var(--accent); }
  /* every name is laid out where the current one stands — inside the tab, above the ticks, along the rail — and is
     invisible. Leaving a state is instant (transition: none here), entering one fades in (transition on the state). */
  .section-index.named span {
    position: absolute;
    left: 0; top: 12px;
    width: 100%;
    line-height: 46px;            /* = the tab's inner width: the line sits on the rail's axis */
    writing-mode: vertical-rl;    /* fallback: the name reads downwards */
    writing-mode: sideways-lr;    /* reads upwards, its start next to the ticks */
    font-family: var(--body);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .07em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--fg);
    opacity: 0;
    pointer-events: none;
    transition: none;
  }
  .section-index.named a[aria-current] span { opacity: 1; transition: opacity var(--t-base) var(--ease); }
  /* another chapter under the pointer (or the keyboard): its name is a chip beside its tick — a tooltip, so nothing
     in the tab moves or resizes under the cursor */
  .section-index.named a:not([aria-current]):hover, .section-index.named a:not([aria-current]):focus-visible { position: relative; }
  .section-index.named a:not([aria-current]):hover span, .section-index.named a:not([aria-current]):focus-visible span {
    left: auto; right: calc(100% + 12px); top: 50%;
    width: auto;
    transform: translateY(-50%);
    padding: 5px 9px;
    background: var(--tab-bg);
    border: 1px solid var(--tab-rule);
    line-height: 1.2;
    writing-mode: horizontal-tb;
    opacity: 1;
    transition: opacity var(--t-base) var(--ease);
  }
}

/* ==========================================================================
   THE WAY BACK (demos only) — a demo is a room in the studio's house: the door out is always in sight.
   Phones / touch: a tab hanging from the header at the top of the page. Desktop with a mouse: a ribbon in the LEFT
   gutter, the mirror of the chapter register in the right one — it never covers content (the gutter is 72px).
   At the end of the page the studio speaks again in its own colours. Remove all of it for a real client site.
   ========================================================================== */
.back-wrap { position: relative; z-index: 30; height: 0; }
.back-tab {
  --tab-bg: var(--bg);
  --tab-rule: var(--rule-soft);
  position: absolute;
  left: 0; top: 0;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 16px 0 14px;
  background: var(--tab-bg);
  border: 1px solid var(--tab-rule);
  border-top: 0;   /* it hangs from the header's hairline */
  font-family: var(--body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .07em;
  line-height: 1;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  color: var(--fg);
}
.back-tab::before {   /* a chevron drawn, not typed: it points left however the label is set */
  content: "";
  flex: none;
  width: 7px; height: 7px;
  border-left: 2px solid var(--accent-text);
  border-bottom: 2px solid var(--accent-text);
  transform: rotate(45deg);
  transition: transform var(--t-fast) var(--ease);
}
.back-tab:hover::before, .back-tab:focus-visible::before { transform: translateX(-3px) rotate(45deg); }
/* where the tab hangs over the hero (everything but desktop-with-a-mouse) the hero keeps clear of it */
@media (max-width: 63.99rem), (hover: none), (pointer: coarse) {
  .back-wrap ~ main > section:first-child > .hero-grid { padding-top: 72px; }
}
@media (min-width: 64rem) and (hover: hover) and (pointer: fine) {
  .back-tab {
    position: fixed;
    left: max(20px, env(safe-area-inset-left));
    top: var(--head-h);
    flex-direction: column;
    gap: 14px;
    width: 48px;   /* the register's width, in the opposite gutter */
    min-height: 0;
    padding: 18px 0 16px;
    transition: background-color var(--t-base) var(--ease), border-color var(--t-base) var(--ease), color var(--t-base) var(--ease);
  }
  .back-tab-label { writing-mode: vertical-rl; writing-mode: sideways-lr; }   /* reads upwards, towards the chevron */
  .back-tab:hover::before, .back-tab:focus-visible::before { transform: translateX(-2px) rotate(45deg); }
  /* over a dark sheet the ribbon turns dark with it, like the register (micro.js · initGround) */
  .back-tab.is-dark {
    --fg: var(--on-dark);
    --accent-text: var(--accent-on-dark);
    --focus: var(--focus-dark);
    --tab-bg: var(--dark-c);
    --tab-rule: var(--rule-dark-soft);
  }
}
/* the end of a demo: the hub's palette, re-scoped, so the buttons and the pen stroke are the studio's */
.studio-return {
  --bg: #FAF6EF; --fg: #1C1917; --muted: #57534E;
  --accent: #9A3412; --accent-text: #9A3412; --on-accent: #FAF6EF;
  --focus: #9A3412;
  padding: 56px 0 64px;
  background: var(--bg);
  color: var(--fg);
}
.studio-return-inner { display: grid; gap: 28px; }
.studio-return-say {
  margin: 0;
  max-width: 20ch;
  font-family: var(--display);
  font-variation-settings: 'SOFT' 20, 'WONK' 1;
  font-weight: 600;
  font-size: var(--fs-h2);
  line-height: 1.06;
  letter-spacing: -.015em;
}
.studio-return-say em { font-weight: 500; color: var(--accent-text); }
.studio-return-go { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 24px; }
@media (min-width: 860px) {
  .studio-return { padding: 72px 0 80px; }
  .studio-return-inner { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: end; }
  .studio-return-go { justify-content: flex-end; }
}

/* progress bar — 0 kB JS; sits above the sticky header (z-index 90), otherwise it would be hidden */
@supports (animation-timeline: scroll()) {
  @media (min-width: 64rem) and (prefers-reduced-motion: no-preference) {
    .scroll-progress {
      display: block;
      position: fixed;
      inset: 0 0 auto 0;
      z-index: 95;
      height: 2px;
      background: var(--accent);
      transform-origin: left;
      animation: progress linear both;
      animation-timeline: scroll(root);
    }
    @keyframes progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  }
}

/* Where paging.js animates the scroll itself, native smoothing has to be OFF: otherwise every rAF scrollTo()
   is smoothed a second time. Measured: the page crawled 75px in 750ms and reached its target after 1.9s.
   html { scroll-behavior: smooth } (system.css) still serves phones, touch and everything paging does not run on. */
@media (min-width: 64rem) and (hover: hover) and (pointer: fine) {
  html { scroll-behavior: auto; }
  /* the register lives in the right gutter: keep a gutter for it on every desktop width */
  .container { width: min(100% - 144px, 1240px); }
  /* every chapter is ONE full window below the header: each turn of the wheel shows one composed screen, and no
     cut-off headline of the next chapter shows under it (first the lone "WORK" label under the hero, then ten more
     places — owner, 20–21 Sep). Minus the 8px gap paging.js parks sections at: exactly one page, never "tall".
     The content is centred in the spare height; chapters taller than the window stay as they were.
     In a hero the copy is centred and a demo note stays at the end (the auto margins below). */
  main[data-paging] > section[data-snap] { display: flex; flex-direction: column; justify-content: center; min-height: calc(100vh - var(--head-h) - 8px); }
  main[data-paging] > section:first-child > .hero-grid { margin-block: auto; }
}

/* chapter 7 — native anchors (phones, reduced motion, no JS) land below the header */
section[id] { scroll-margin-top: var(--scroll-pad, 96px); }

@media (prefers-reduced-motion: reduce) {
  .section-index, .section-index.named a::before, .section-index.named span,
  .section-index.named a[aria-current] span,
  .section-index.named a:not([aria-current]):hover span, .section-index.named a:not([aria-current]):focus-visible span,
  .back-tab, .back-tab::before { transition: none; }
}
/* High Contrast strips author backgrounds: the ticks are backgrounds, so they take system colours there */
@media (forced-colors: active) {
  .section-index.named a::before { background: CanvasText; opacity: 1; forced-color-adjust: none; }
  .section-index.named a[aria-current]::before { background: Highlight; }
}

/* ==========================================================================
   HEIGHT-AWARE COMPACTION — desktop only (the same condition as paging.js).
   One wheel gesture must show one WHOLE section, so on short laptop screens
   the vertical rhythm tightens instead of letting content fall off the page.
   ========================================================================== */
@media (min-width: 64rem) and (max-height: 900px) {
  .section-lg { padding-block: 96px; }
  .sec-head { margin-bottom: 32px; }
  .sec-head .lead { max-width: 60ch; }
}
@media (min-width: 64rem) and (max-height: 780px) {
  :root { --fs-h2: 2.5rem; --fs-lead: 1.1875rem; --head-h: 57px; }
  .head-inner { min-height: 56px; padding-block: 4px; }
  .section, .section-lg { padding-block: 64px; }
  .sec-head { margin-bottom: 24px; }
  .sec-title { margin-bottom: 14px; }
  .table-editorial thead th { padding: 9px 16px; }
  .table-editorial tbody th, .table-editorial tbody td { padding: 11px 16px; }
  .spec-row { padding: 15px 8px; }
  .panel { padding: 22px; }
  .panel-feature { padding: 28px; }
  .rows li { padding: 9px 0; }
  .stat-band { margin-top: 32px; }
  .stat { padding-block: 16px; }
  .plate-label .plate-inner { min-height: 0; padding-block: 24px; }
}

/* tier C — basic laptops (1366x768 leaves a ~620px window): the tightest rhythm, nothing hidden */
@media (min-width: 64rem) and (max-height: 680px) {
  :root { --fs-h2: 2.125rem; --fs-lead: 1.125rem; }
  body { line-height: 1.65; }            /* VISION floor for body copy; saves a line here and there */
  .section, .section-lg { padding-block: 48px; }
  .sec-head { margin-bottom: 16px; }
  .sec-label { margin-bottom: 10px; }
  .sec-title { margin-bottom: 10px; }
  .hero-h1 { margin-bottom: 14px; }
  .demo-strip a { padding-block: 9px; }
  .table-editorial thead th { padding: 7px 16px; }
  .table-editorial tbody th, .table-editorial tbody td { padding: 8px 16px; }
  .spec-row { padding: 11px 8px; }
  .panel { padding: 18px 20px; }
  .rows li { padding: 6px 0; }
  .stat-band { margin-top: 22px; }
  .stat { padding-block: 12px; }
  .stat dd { font-size: 1.75rem; }
  .quote-pull { font-size: 2rem; }
}

/* ==========================================================================
   CRAFT v8 — the small print of typography (docs/CRAFT-v8.md). Last in this file on purpose: it re-voices labels
   that system.css and the components above set in mono.
   ========================================================================== */
html { font-synthesis: none; font-kerning: normal; }   /* never a faked bold, italic or small cap: every face in use is a real file */
h1, .hero-h1 { letter-spacing: -.028em; }
h2, .sec-title { letter-spacing: -.018em; }
h3, .h3, .sr-name { letter-spacing: -.008em; }
p, li, blockquote { hanging-punctuation: first; }
li::marker { color: var(--accent); }
/* NAMES in Inter capitals, DATA in mono. (True small caps need an smcp table; this Inter file has none.)
   Mono stays on section numbers, prices and units, stock states and the printed objects: poster, label, stamp, tag. */
.sec-label, .eyebrow, .season-line, .nav-list a, .foot-h, .stat dt, .stat-hero-cap, .work-meta, .cap-line,
.table-editorial thead th, .table-editorial tbody td::before {
  font-family: var(--body);
  font-size: .875rem;
  font-weight: 600;
  letter-spacing: .07em;
}
@media (min-width: 768px) {
  .sec-label, .eyebrow, .season-line, .nav-list a, .foot-h, .stat dt, .stat-hero-cap, .work-meta, .cap-line,
  .table-editorial thead th { font-size: .8125rem; }
}
/* whoever asks for more contrast gets it: no muted text, no faint hairlines */
@media (prefers-contrast: more) { :root { --muted: var(--fg); --rule-soft: var(--rule); } }
