/* fufusfriends.com - the page, since 2026-09-30. The palette block in :root is written by
   tools/build_site.py from tools/palette.py; never retype a hex there. Halant for
   headings, Nunito Sans for the rest, Quicksand only inside the logo artwork. */

:root {
  /* @palette G · Plum & Butter — generated by tools/build_site.py.
     Roles, not hues, in the names as well as the values. One action colour
     (--brand), and it belongs to the Etsy button; --accent carries the eyebrows
     and the open toggles; --focus-ring is its own role, though G sets it to the
     brand plum, so on the dark bands the page swaps it for chalk. Only the roles
     the page reads are written. Every value is derived and contrast-checked in
     tools/palette.py — re-run the generator, never retype a hex. */
  color-scheme: light;
  --ground: #F7F0EB;
  --surface: #FCF8F5;
  --ink: #241D17;
  --ink-muted: #756355;
  --ground-dark: #25101A;
  --chalk: #FAF6F3;
  --chalk-muted: #BFB7B0;
  --brand: #8C2F5A;
  --brand-hover: #6E1F44;
  --highlight: #EFC331;
  --accent: #4A6B3C;
  --focus-ring: #8C2F5A;
  --hairline: #DCCCBE;
  --on-brand: #FFFFFF;
  --on-ink: #FFFFFF;
  --on-accent: #FFFFFF;
  --shadow-rgb: 36, 29, 23;
  --scrim: rgba(37, 16, 26, .55);
  --scrim-deep: rgba(37, 16, 26, .95);
  /* @end palette */
  /* the page's own names for four of the generated roles */
  --dark: var(--ground-dark); --focus: var(--focus-ring); --shadow: var(--shadow-rgb);
  /* the page's own roles: the white print border, and the 8% line that keeps a pale
     photo from melting into the cream */
  --print-paper: #fff; --photo-edge: rgba(0, 0, 0, .08); --photo-edge-on-dark: rgba(255, 255, 255, .08);
  --display: "Halant", Georgia, serif;
  --body: "Nunito Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --gutter: clamp(1rem, 4vw, 2.5rem); --r: 14px;
  --ease: cubic-bezier(.2, .7, .2, 1); --spring: cubic-bezier(.34, 1.56, .64, 1); --dur: 300ms;
}
/* Quicksand is the logo's face and is set live nowhere on this page - the wordmark is
   outlined artwork - but the file ships: the kit's badges are set in it, and a declared
   face is fetched only when text uses it, so this costs nothing. Its OFL notice travels
   with it (tools/bundle.py). */
@font-face { font-family: "Quicksand"; font-weight: 300 700; font-display: swap; src: url("assets/fonts/quicksand-var-latin.woff2") format("woff2-variations"); }
@font-face { font-family: "Halant"; font-weight: 400; font-display: swap; src: url("assets/fonts/halant-regular-latin.woff2") format("woff2"); }
@font-face { font-family: "Halant"; font-weight: 700; font-display: swap; src: url("assets/fonts/halant-bold-latin.woff2") format("woff2"); }
@font-face { font-family: "Nunito Sans"; font-weight: 400; font-display: swap; src: url("assets/fonts/nunitosans-400-latin.woff2") format("woff2"); }
@font-face { font-family: "Nunito Sans"; font-weight: 700; font-display: swap; src: url("assets/fonts/nunitosans-700-latin.woff2") format("woff2"); }

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 5rem; }
body { margin: 0; font: 1rem/1.6 var(--body); color: var(--ink); background: var(--ground); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
img { display: block; max-width: 100%; height: auto; }
/* Halant at its regular weight, the way A and C set it; the emphasised words carry the
   bold and the plum */
h1, h2 { font-family: var(--display); font-weight: 400; line-height: 1.08; letter-spacing: -.02em; margin: 0; }
h1 em, h2 em { font-style: normal; font-weight: 700; color: var(--brand); }
h3 { margin: 0; font-size: 1.05rem; }
h1, h2, h3 { text-wrap: balance; }
p, blockquote, li { text-wrap: pretty; }
p, ul, ol, dl, figure, blockquote { margin: 0; } ul, ol { list-style: none; padding: 0; }
a { color: inherit; text-underline-position: from-font; text-decoration-skip-ink: auto; } button { font: inherit; color: inherit; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 6px; }
.wrap { max-width: 1200px; margin: 0 auto; padding: 0 var(--gutter); }
.kicker { font-weight: 700; font-size: .76rem; letter-spacing: .12em; text-transform: uppercase; color: var(--accent); }
/* the arrows are drawn: Nunito Sans has no ↗ or ←, so the glyphs came from whatever font
   the OS had. Stroked in currentColor at a fixed 2px, the weight of the 700 labels. */
.ico { width: .78em; height: .78em; flex: none; fill: none; stroke: currentColor; stroke-width: 2px; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; vertical-align: -.06em; overflow: visible; }
.ico path { vector-effect: non-scaling-stroke; }
.ico-mail { width: 1em; height: 1em; stroke-width: 1.5px; }   /* an envelope at .78em closes up */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.skip { position: absolute; left: 1rem; top: -4rem; background: var(--ink); color: var(--on-ink); padding: .6rem 1rem; border-radius: 8px; z-index: 100; }
.skip:focus { top: 1rem; }

/* every .cta ends on the ↗, so its right side is a little tighter than its left */
.cta { display: inline-flex; align-items: center; justify-content: center; gap: .45rem; min-height: 44px; padding: .7rem 1.05rem .7rem 1.25rem; border-radius: 10px; color: var(--on-brand); font-weight: 700; font-size: .95rem; text-decoration: none; white-space: nowrap; position: relative; isolation: isolate; }
/* THE BUTTON NEVER MOVES. The fill is a plate behind the label that shrinks on press, so
   the text stays put: scaling the whole button re-rasterised the label and it wobbled.
   Hover is colour only - a lift read as odd (the user's call, 2026-10-05). */
.cta::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: var(--brand); transition: scale 150ms ease-out, background-color 150ms; }
.cta-lg { padding: .95rem 1.35rem .95rem 1.6rem; font-size: 1.05rem; }
.ghost.cta-lg { padding: .95rem 1.6rem; }   /* no arrow, so even sides */
.ghost { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: calc(.7rem + 1.5px) calc(1.25rem + 1.5px); border-radius: 10px; font-weight: 700; text-decoration: none; white-space: nowrap; position: relative; isolation: isolate; }
/* the same plate; its 1.5px edge is an inset shadow, so it can shrink with the plate */
.ghost::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; box-shadow: inset 0 0 0 1.5px var(--hairline); transition: scale 150ms ease-out, box-shadow 150ms; }
/* pressing darkens a labelled button; only icon buttons shrink, since a scaled label re-renders and wobbles */
.cta:active::before { scale: .96; background: var(--brand-hover); }
.ghost:active::before { scale: .96; box-shadow: inset 0 0 0 1.5px var(--ink); }
.x:active, .arrow:active { scale: .97; }
@media (hover: hover) {
  .cta:hover::before { background: var(--brand-hover); }
  .ghost:hover::before { box-shadow: inset 0 0 0 1.5px var(--ink); }
}

/* ---------- header (A): a rule, underline on hover ---------- */
.bar { position: sticky; top: 0; z-index: 30; display: flex; align-items: center; gap: 1rem; padding: .6rem var(--gutter); background: color-mix(in srgb, var(--ground) 92%, transparent); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border-bottom: 1px solid var(--hairline); }
.logo { display: block; margin-right: auto; }
.logo img { height: 30px; width: auto; }   /* the kit's on-screen floor for the lockup */
@media (max-width: 374px) { .cta-verb { display: none; } }   /* "Shop on Etsy" fits beside the 30px logo from 375px, with room to spare */
.bar nav { display: none; gap: .2rem; margin-right: .8rem; }
.bar nav a { text-decoration: none; font-weight: 600; font-size: .9rem; color: var(--ink); padding: .5rem .7rem; }
.bar nav a:focus-visible { color: var(--brand); text-decoration: underline; text-underline-offset: .45em; text-decoration-thickness: 1.5px; }
@media (hover: hover) { .bar nav a:hover { color: var(--brand); text-decoration: underline; text-underline-offset: .45em; text-decoration-thickness: 1.5px; } }
@media (min-width: 720px) { .bar nav { display: flex; } }

/* ---------- hero (D) ---------- */
.hero { max-width: 1200px; margin: 0 auto; padding: 2.5rem var(--gutter) 3rem; display: grid; gap: 2rem; }
.hero .kicker { font-size: .72rem; }
.hero h1 { font-size: clamp(2.4rem, 5.4vw, 4.2rem); margin: .8rem 0 1.1rem; max-width: 16ch; }
.lede { font-size: 1.1rem; color: var(--ink-muted); max-width: 34rem; }
.hero-actions { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.6rem; }
.hero-set { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; padding-bottom: 1.2rem; }
.hero-set img { aspect-ratio: 4 / 5; object-fit: cover; border-radius: var(--r); width: 100%; outline: 1px solid var(--photo-edge); outline-offset: -1px; }
.hero-set li:nth-child(even) { transform: translateY(1.2rem); }
@media (min-width: 900px) {
  .hero { grid-template-columns: 1fr 1fr; align-items: center; padding-top: 3.5rem; padding-bottom: 4rem; }
  .hero-set { gap: .8rem; padding-bottom: 1.6rem; }
  .hero-set li:nth-child(even) { transform: translateY(1.6rem); }
}

/* ---------- facts (D) ---------- */
.facts { background: var(--surface); border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); }
.facts-grid { display: grid; gap: 1.2rem; padding-top: 1.4rem; padding-bottom: 1.4rem; }
.facts-grid div { display: grid; gap: .15rem; align-content: start; }   /* a shorter column keeps its text under its heading */
.facts-grid strong { font-size: .95rem; }
.facts-grid span { font-size: .9rem; color: var(--ink-muted); text-wrap: pretty; }
@media (min-width: 720px) { .facts-grid { grid-template-columns: repeat(3, 1fr); gap: 2.5rem; } }

/* ---------- collection: A tabs + B slide, C thread, D cards ---------- */
.shop { padding: 4rem 0 5rem; }   /* ends on the last row of tiles; the header, the hero and every detail already carry the Etsy button */
.shop h2 { font-size: clamp(2.2rem, 5vw, 3.4rem); }
.group { padding: 2.5rem 0 0; }   /* at least twice the gap between tiles */
.group[hidden] { display: none; }
.group-head { display: flex; align-items: baseline; justify-content: space-between; gap: .7rem; margin-bottom: 1.2rem; padding-bottom: .6rem; border-bottom: 1px solid var(--hairline); }
.group-head h3 { font-family: var(--display); font-weight: 400; font-size: 1.7rem; letter-spacing: -.01em; }
.group-head span { font-size: .78rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-muted); }
.grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: .8rem; }
.tile a { all: unset; display: block; width: 100%; cursor: pointer; border-radius: var(--r); overflow: hidden; background: var(--surface); position: relative; box-shadow: 0 1px 0 var(--hairline); transition: transform 150ms var(--ease), box-shadow 150ms var(--ease); will-change: transform; }   /* its own layer: the hover lift can't snap the caption */
.tile a:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.pic { display: block; position: relative; overflow: hidden; border-radius: var(--r) var(--r) 0 0; }
.pic img { width: 100%; aspect-ratio: 1; object-fit: cover; transition: transform 150ms var(--ease); }
/* the photo's edge sits on the frame, not the image, so the hover zoom can't crop it */
.pic::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1px var(--photo-edge); pointer-events: none; }
/* the character line, A's white bubble, on hover */
.bubble { position: absolute; left: .7rem; top: .7rem; max-width: 78%; background: var(--surface); color: var(--ink); font-weight: 600; font-size: .82rem; line-height: 1.35; padding: .45rem .7rem; border-radius: 6px; box-shadow: 0 1px 0 var(--hairline); opacity: 0; transform: translateY(4px); transition: opacity 150ms 60ms, transform 150ms var(--ease) 60ms; }
.tile a:focus-visible .bubble { opacity: 1; transform: none; }
@media (hover: hover) {
  .tile a:hover { transform: translateY(-3px); box-shadow: 0 18px 34px -22px rgba(var(--shadow), .5); }
  .tile a:hover .pic img { transform: scale(1.04); }
  .tile a:hover .bubble { opacity: 1; transform: none; }
  .tile a:active { transform: translateY(-1px); }   /* pressed: it settles back towards the shelf */
}
.empty { display: grid; justify-items: start; gap: 1rem; padding-top: 2rem; }
.empty p { color: var(--ink-muted); max-width: 34rem; }
.cap { display: grid; gap: .1rem; padding: .65rem .8rem .75rem; }
.cap b { font-size: .92rem; line-height: 1.25; }
.cap b, .bubble { text-wrap: balance; }   /* two-line names: pretty cannot fix a one-word last line */
.cap small { font-size: .78rem; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
@media (min-width: 720px) {
  .grid { grid-template-columns: repeat(4, 1fr); gap: 1.1rem; }
  .cap { grid-template-columns: 1fr auto; align-items: baseline; gap: .6rem; }
  .cap small { white-space: nowrap; }
}
@media (hover: none) { .bubble { display: none; } }   /* no hover, no half-shown caption; the line is in the detail */

/* ---------- how (A) ---------- */
.how { background: var(--surface); border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); padding: 4.5rem 0 5rem; }   /* the facts strip's band */
.how h2 { font-size: clamp(1.9rem, 4vw, 2.8rem); margin-bottom: 2.2rem; }
.steps { display: grid; gap: 1.6rem; }
.steps li { border-top: 1px solid var(--hairline); padding-top: 1.1rem; }
.steps b { display: block; font-family: var(--display); font-weight: 400; font-size: 2.4rem; line-height: 1; color: var(--brand); margin-bottom: .7rem; }
.steps h3 { font-weight: 700; font-size: 1.05rem; }
.steps p { color: var(--ink-muted); }
.inline { text-decoration: none; } .inline span { text-decoration: underline; }   /* the underline stops at the word, not under the arrow */
@media (min-width: 720px) { .steps { grid-template-columns: repeat(3, 1fr); gap: 2.5rem; } }

/* ---------- maker (C): the one hand-taped moment on the page ---------- */
/* plum on plum-black is 2.3:1; on the dark bands and the zoom backdrop the ring is chalk */
.about, .foot, .zoom { --focus: var(--chalk); }
.about { background: var(--dark); color: var(--chalk); padding: 4.5rem var(--gutter) 5rem; overflow-x: clip; }   /* the tilted stamp pokes past the edge on phones */
.about-grid { display: grid; gap: 2.5rem; align-items: center; max-width: 1100px; }
.print { position: relative; margin: 0 auto; max-width: 400px; width: 100%; background: var(--print-paper); padding: 10px 10px 36px; box-shadow: 0 18px 40px -24px rgba(var(--shadow), .6), 0 1px 2px rgba(var(--shadow), .1); transform: rotate(-1.8deg); }
.print img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; outline: 1px solid var(--photo-edge); outline-offset: -1px; }
.print::before { content: ""; pointer-events: none; position: absolute; z-index: 2; top: -12px; left: 50%; width: 96px; height: 26px; margin-left: -48px; background: color-mix(in srgb, var(--highlight) 72%, transparent); transform: rotate(-3deg); box-shadow: 0 1px 2px rgba(var(--shadow), .1); }
.print::after { content: ""; position: absolute; z-index: 2; right: -34px; bottom: -8px; width: 108px; height: 108px; background: url("assets/img/stamp.svg") center / contain no-repeat; transform: rotate(11deg); filter: drop-shadow(0 8px 14px rgba(var(--shadow), .55)); pointer-events: none; }
.about h2 { font-size: clamp(2rem, 4.5vw, 2.9rem); margin: .5rem 0 .6rem; color: var(--chalk); }
.about .kicker { color: var(--highlight); }
.nick { font-weight: 600; margin-bottom: 1rem; }
.about blockquote { font-family: var(--display); font-weight: 400; font-size: 1.5rem; line-height: 1.3; color: var(--highlight); margin: 1.4rem 0 1rem; }
.about-text > p:not(.kicker):not(.nick):not(.about-links) { color: var(--chalk-muted); max-width: 33rem; margin-bottom: .8rem; }   /* about 70 characters */
.about-links { margin-top: 1.3rem; display: flex; flex-wrap: wrap; gap: .4rem 1.4rem; }
.about-links a { font-weight: 700; text-decoration: none; padding-bottom: .1rem; }
@media (hover: hover) { .about-links a:hover { color: var(--highlight); text-decoration: underline; text-underline-offset: .3em; text-decoration-thickness: 1.5px; } }
@media (max-width: 639px) { .print { max-width: 300px; } }
@media (min-width: 860px) { .about-grid { grid-template-columns: .8fr 1.2fr; column-gap: 4.5rem; } }

/* ---------- footer (A + D) ---------- */
.foot { background: var(--dark); color: var(--chalk); padding: 3.5rem 0 1.5rem; }
.foot-grid { display: grid; gap: 2rem; }
.foot-brand img { height: 36px; width: auto; margin-bottom: .9rem; }
.foot-brand p { color: var(--chalk-muted); font-size: .95rem; max-width: 30rem; }
.foot .kicker { color: var(--highlight); margin-bottom: .5rem; }
.foot ul { display: grid; gap: 0; }
.foot a { color: var(--chalk); font-weight: 700; text-decoration: none; }
.foot ul a { display: inline-block; padding: .2rem 0; }   /* 24px+ to tap, same rhythm as before */
/* on touch, the small text links grow to the 44px aim; stacked, so their boxes don't overlap */
@media (pointer: coarse) {
  .foot ul a { padding: .45rem 0; }
  .about-links { row-gap: .9rem; }
  .about-links a { padding: .55rem 0; }
  .logo { padding: 7px 0; }
}
@media (hover: hover) { .foot a:hover { color: var(--highlight); text-decoration: underline; text-underline-offset: .3em; text-decoration-thickness: 1.5px; } }
.foot-bottom { margin-top: 2.5rem; padding-top: 1.2rem; border-top: 1px solid color-mix(in srgb, var(--chalk) 14%, transparent); display: flex; flex-wrap: wrap; justify-content: space-between; gap: .3rem 1.5rem; font-size: .85rem; color: var(--chalk-muted); }
@media (min-width: 720px) { .foot-grid { grid-template-columns: 1.5fr 1fr 1fr; gap: 3rem; } }


/* ---------- detail: D's content, A's presentation ---------- */
.detail { border: 0; padding: 0; margin: 0; max-width: none; max-height: none; position: fixed; inset: auto 0 0 0; width: 100%; height: 94dvh; background: var(--ground); color: var(--ink); border-radius: 22px 22px 0 0; overflow: auto; scroll-padding-top: 4.5rem; }   /* focus never lands under the sticky head */
.detail::backdrop { background: var(--scrim); }
/* the dialog takes focus to scroll; on a full-screen page an outside ring would be off-screen */
.detail:focus-visible, .zoom:focus-visible { outline-offset: -3px; }
body:has(.detail[open]) { overflow: hidden; }
.detail[open] { animation: up 260ms var(--ease); }   /* opened often: short */
.detail.still[open] { animation: none; }   /* opened by the URL on page load: already there */
@keyframes up { from { transform: translateY(100%); } to { transform: none; } }
.detail-head { position: sticky; top: 0; z-index: 2; display: grid; place-items: center; align-content: start; gap: .3rem; padding: .6rem 0; min-height: 3.6rem; background: linear-gradient(in oklab, var(--ground) 70%, transparent); }
.handle { width: 44px; height: 5px; border-radius: 3px; background: var(--hairline); }
.back { display: none; }
.x { position: absolute; right: .8rem; top: .5rem; width: 44px; height: 44px; border-radius: 50%; border: 0; background: var(--surface); color: var(--ink); cursor: pointer; box-shadow: 0 6px 16px -8px rgba(var(--shadow), .35); font-size: 0; transition: scale 200ms ease-out, color 150ms; }
/* chevrons and the x are drawn */
.arrow::before, .x::before { content: ""; position: absolute; inset: 0; margin: auto; }
.arrow::before { width: 9px; height: 9px; border: solid currentColor; border-width: 0 0 2px 2px; transform: translateX(2px) rotate(45deg); }
.arrow.next::before { transform: translateX(-2px) rotate(-135deg); }
.x::before { width: 14px; height: 14px; background: linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat, linear-gradient(currentColor, currentColor) center / 2px 100% no-repeat; transform: rotate(45deg); }
.detail-body { display: grid; gap: 2rem; padding: 0 1rem 3rem; }
.detail-body > *, .detail-top > * { min-width: 0; }
.detail-top { display: grid; gap: 1.4rem; }
.detail-media { position: relative; }
.photo-open { all: unset; display: block; cursor: zoom-in; width: 100%; border-radius: 18px; transition: scale 200ms ease-out; }
.photo-open:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }   /* outside, on the paper, not on the photo */
.photo-open[hidden], .video-wrap[hidden] { display: none; }
.video-wrap { position: relative; }
#dt-video { display: block; width: 100%; height: auto; max-height: 70dvh; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 18px; background: var(--surface); outline: 1px solid var(--photo-edge); outline-offset: -1px; }
/* pause, bottom left: the arrows' pale disc, away from them, so it reads as a control and not a third arrow */
.video-toggle { position: absolute; left: .7rem; bottom: .7rem; width: 44px; height: 44px; border-radius: 50%; border: 0; background: color-mix(in srgb, var(--surface) 92%, transparent); color: var(--ink); cursor: pointer; box-shadow: 0 4px 14px -6px rgba(var(--shadow), .5); transition: background-color 150ms, scale 200ms ease-out; }
.video-toggle::before { content: ""; position: absolute; inset: 0; margin: auto; width: 10px; height: 12px; background: linear-gradient(currentColor, currentColor) left / 3px 100% no-repeat, linear-gradient(currentColor, currentColor) right / 3px 100% no-repeat; }
.video-toggle.paused::before { width: 0; height: 0; background: none; border-style: solid; border-width: 6px 0 6px 10px; border-color: transparent transparent transparent currentColor; transform: translateX(1px); }
.video-toggle:focus-visible { outline: 3px solid var(--ink); outline-offset: -3px; }
.video-toggle:active { scale: .97; }
/* the video's thumb carries a small play mark */
.thumbs button.is-video { position: relative; }
.thumbs button.is-video::after { content: ""; position: absolute; inset: 0; margin: auto; width: 0; height: 0; border-style: solid; border-width: 7px 0 7px 11px; border-color: transparent transparent transparent #fff; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .5)); transform: translateX(1px); }
#dt-main { width: 100%; max-height: 70dvh; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 18px; background: var(--surface); outline: 1px solid var(--photo-edge); outline-offset: -1px; }
.arrow { position: absolute; top: calc(50% - 2.2rem); transform: translateY(-50%); width: 44px; height: 44px; border-radius: 50%; border: 0; background: color-mix(in srgb, var(--surface) 92%, transparent); color: var(--ink); cursor: pointer; box-shadow: 0 4px 14px -6px rgba(var(--shadow), .5); transition: background-color 150ms, scale 200ms ease-out; }
.arrow.prev { left: .7rem; } .arrow.next { right: .7rem; }
.arrow:focus-visible { outline: 3px solid var(--ink); outline-offset: -3px; }   /* inside its own pale disc, whatever the photo is */
@media (hover: hover) {
  .arrow:hover, .video-toggle:hover { background: var(--surface); }
  .x:hover { color: var(--brand); }
  .thumbs button:not([aria-current="true"]):hover { opacity: .85; }
  .sections summary:hover { color: var(--brand); }
  .detail-nav a:hover { color: var(--brand-hover); }
}
.arrow[hidden] { display: none; }
/* 4px of room on every side so a focus ring isn't clipped by the scroller; the margin keeps the row aligned */
.thumbs { display: flex; gap: .4rem; padding: calc(.6rem - 4px) 4px 4px; margin: 4px -4px 0; overflow-x: auto; }
.thumbs button { all: unset; flex: none; width: 56px; height: 56px; border-radius: 8px; overflow: hidden; cursor: pointer; opacity: .6; border: 2px solid transparent; transition: scale 200ms ease-out; }
.thumbs button[aria-current="true"] { opacity: 1; border-color: var(--brand); }
.thumbs img { width: 100%; height: 100%; object-fit: cover; border-radius: 6px; outline: 1px solid var(--photo-edge); outline-offset: -1px; }   /* 8px less the 2px border */
.intro h2 { font-size: clamp(1.9rem, 4.5vw, 2.6rem); margin: .3rem 0 .7rem; }
.intro h2:focus { outline: none; }
#dt-count, .zoom-count { font-variant-numeric: tabular-nums; }
.voice { display: inline-block; background: var(--highlight); color: var(--ink); font-weight: 700; font-size: .85rem; padding: .4rem .7rem; border-radius: 6px; margin-bottom: 1rem; }
.blurb { color: var(--ink-muted); margin-bottom: 1.2rem; max-width: 34rem; }
.specs { display: grid; grid-template-columns: auto 1fr; gap: .3rem 1.2rem; font-size: .92rem; padding: .9rem 0; border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); margin-bottom: 1.2rem; }
.specs dt { color: var(--ink-muted); } .specs dd { margin: 0; font-weight: 700; }
#dt-buy { width: 100%; }
.hint { text-align: center; font-size: .82rem; color: var(--ink-muted); margin: .6rem 0 0; }
.sections details { border-top: 1px solid var(--hairline); }
.sections details:last-of-type { border-bottom: 1px solid var(--hairline); }
.sections summary { cursor: pointer; list-style: none; transition: color 150ms; display: flex; justify-content: space-between; align-items: center; min-height: 44px; padding: .7rem 0; font-weight: 700; font-size: .95rem; }
.sections summary::-webkit-details-marker { display: none; }
.sections summary::after { content: ""; flex: none; width: 26px; height: 26px; border-radius: 50%; --bar: var(--accent); background: linear-gradient(var(--bar), var(--bar)) center / 10px 2px no-repeat, linear-gradient(var(--bar), var(--bar)) center / 2px 10px no-repeat, var(--surface); box-shadow: inset 0 0 0 1px var(--hairline); transition: transform 200ms cubic-bezier(.2, 0, 0, 1); }   /* no bounce: the fill is the cue */
.sections details[open] summary::after { transform: rotate(45deg); --bar: var(--on-accent); background-color: var(--accent); box-shadow: none; }
.sections ul { padding: 0 0 1rem; display: grid; gap: .3rem; color: var(--ink-muted); font-size: .92rem; max-width: 52ch; }   /* 1ch is a "0"; in Nunito Sans 52ch holds about 70 characters */
.detail-nav { display: flex; justify-content: space-between; gap: 1rem; }   /* the sections' closing hairline is the rule above it */
.detail-nav a { all: unset; cursor: pointer; border-radius: 6px; font-weight: 700; font-size: .92rem; color: var(--brand); min-height: 44px; display: inline-flex; align-items: center; gap: .3rem; transition: color 150ms; }
.detail-nav a:active, .back:active { color: var(--brand-hover); }
.detail-nav a[hidden] { visibility: hidden; display: inline-flex; }
.detail-nav [data-step="1"] { text-align: end; justify-content: flex-end; }   /* a wrapped name stays against its › */
/* `all: unset` above outranks the global ring, so these buttons get it back by name */
.back:focus-visible, .detail-nav a:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
/* ink, not plum: the current thumb already wears a plum border; full opacity so the ring isn't dimmed */
.thumbs button:focus-visible { opacity: 1; outline: 2px solid var(--ink); outline-offset: 1px; }
.thumbs button:active, .photo-open:active { scale: .97; }
@media (min-width: 768px) {
  .detail { inset: 0; height: 100dvh; border-radius: 0; }
  .detail[open] { animation-name: page-in; }
  @keyframes page-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
  .handle, .detail .x { display: none; }
  .detail-head { display: flex; justify-content: space-between; align-items: center; max-width: 960px; margin: 0 auto; padding: 1rem var(--gutter) 0; background: var(--ground); }
  .back { all: unset; border-radius: 6px; display: inline-flex; align-items: center; gap: .4rem; min-height: 44px; cursor: pointer; font-weight: 700; font-size: .95rem; }
  .back span { transition: transform var(--dur) var(--ease); }
  @media (hover: hover) { .back:hover { color: var(--brand); } .back:hover span { transform: translateX(-4px); } }
  .detail-body { max-width: 960px; margin: 0 auto; row-gap: 2rem; padding: 1.2rem var(--gutter) 3rem; }
  /* the photo sticks only beside the intro, never over the rows below */
  .detail-top { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 2.6rem; align-items: start; }
  .detail-media { position: sticky; top: 4.75rem; }   /* below the 60px sticky head */
}

/* ---------- zoom ---------- */
.zoom { border: 0; padding: 0; margin: 0; max-width: none; max-height: none; width: 100vw; height: 100dvh; background: transparent; display: none; place-items: center; }
.zoom[open] { display: grid; }
.zoom::backdrop { background: var(--scrim-deep); }
.zoom img { max-width: calc(100vw - 2rem); max-height: calc(100dvh - 5rem); width: auto; height: auto; object-fit: contain; border-radius: 12px; cursor: zoom-out; outline: 1px solid var(--photo-edge-on-dark); outline-offset: -1px; }
.zoom .x { position: fixed; right: 1rem; top: 1rem; }
.zoom .arrow { position: fixed; top: 50%; }
.zoom-count { position: fixed; left: 0; right: 0; bottom: 1rem; text-align: center; color: var(--chalk); font-weight: 700; font-size: .8rem; letter-spacing: .1em; pointer-events: none; }

@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } *, *::before, *::after { transition-duration: 1ms !important; animation-duration: 1ms !important; } }
