/* Plated — portfolio stylesheet (v2). Colour comes entirely from five variables that
   each dish overrides; the page cross-fades between them as you scroll.
   v2: sauce work flows across section seams (no clipping, no edge masks), reveals are
   transitions rather than pops, photos sit on plates, new type pairing. */
:root {
  --plate: #f4efe6;
  --ink: #241b16;
  --sauce: #8a5a3c;
  --sauce2: #3b241a;
  --garnish: #d9b98c;
  --sauce-text: var(--sauce);
  --serif: "EB Garamond", "Cormorant Garamond", Georgia, serif;
  --sans: "Public Sans", "Helvetica Neue", Arial, sans-serif;
  --ease: cubic-bezier(.2, .8, .2, 1);
}
/* derived tones, computed wherever a palette is set: the root (site palette), every section (its own inline
   palette) and the fixed chrome (the scroll blend, written by app.js) */
:root, section, .topbar, .nav-dots, .index, .lightbox {
  --ink-soft: color-mix(in oklab, var(--ink) 72%, var(--plate));
  --fade: color-mix(in oklab, var(--page, var(--plate)) 72%, transparent);
  --line: color-mix(in oklab, var(--ink) 16%, var(--plate));
  --panel: color-mix(in oklab, var(--plate) 82%, white);
  --plate-rim: color-mix(in oklab, var(--plate) 70%, white);
  --plate-shadow: color-mix(in oklab, var(--ink) 30%, transparent);
}
section { color: var(--ink); }
/* the legibility halos follow the blended page colour; app.js writes --page on these hosts, so --fade is computed here */
.text, .cover-text, .eyebrow-top, .chapter > .inner, .colophon > .inner { --fade: color-mix(in oklab, var(--page, var(--plate)) 72%, transparent); }

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--plate);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
body.no-scroll { overflow: hidden; }
a { color: inherit; }
img { max-width: 100%; display: block; }
h1, h2, h3 { font-family: var(--serif); font-weight: 400; margin: 0; line-height: 1; letter-spacing: -0.005em; }
.lbl { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-soft); font-weight: 500; }

/* ---------- top bar ---------- */
.topbar {
  position: fixed; inset: 0 0 auto 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 28px; font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
  pointer-events: none;
}
.topbar > * { pointer-events: auto; }
.topbar .brand { transition: opacity .5s var(--ease), transform .5s var(--ease); font-family: var(--serif); text-transform: none; letter-spacing: 0; font-size: 20px; text-decoration: none; padding: 6px 12px; margin-left: -12px; border-radius: 999px; background: color-mix(in oklab, var(--plate) 70%, transparent); backdrop-filter: blur(6px); }
.topbar .actions { display: flex; gap: 10px; align-items: center; }
body.on-cover .topbar .brand { opacity: 0; transform: translateY(-6px); pointer-events: none; }
.btn {
  font: inherit; font-size: 12px; letter-spacing: .12em; text-transform: uppercase; text-decoration: none; cursor: pointer;
  background: color-mix(in oklab, var(--plate) 86%, transparent); color: var(--ink); border: 1px solid var(--line); backdrop-filter: blur(6px);
  border-radius: 999px; padding: 9px 18px; transition: background .3s, color .3s, border-color .3s; display: inline-flex; align-items: center;
}
.btn:hover { background: var(--ink); color: var(--plate); border-color: var(--ink); }
.btn.primary { background: var(--ink); color: var(--plate); border-color: var(--ink); }
.btn.primary:hover { background: var(--sauce); border-color: var(--sauce); }
.print-wrap { position: relative; }
.print-menu {
  position: absolute; right: 0; top: 46px; min-width: 280px; padding: 8px; border-radius: 14px;
  background: var(--panel); border: 1px solid var(--line); box-shadow: 0 20px 50px color-mix(in oklab, var(--ink) 22%, transparent);
  display: flex; flex-direction: column; gap: 2px; text-transform: none; letter-spacing: 0;
}
.print-menu button { font: inherit; text-align: left; background: none; border: 0; cursor: pointer; padding: 10px 12px; border-radius: 9px; display: flex; flex-direction: column; gap: 2px; color: var(--ink); }
.print-menu button:hover { background: color-mix(in oklab, var(--ink) 8%, transparent); }
.print-menu b { font-family: var(--serif); font-weight: 400; font-size: 17px; }
.print-menu span { font-size: 12px; color: var(--ink-soft); }

/* ---------- nav dots ---------- */
.nav-dots {
  position: fixed; right: 22px; top: 50%; transform: translateY(-50%); z-index: 20;
  display: flex; flex-direction: column; gap: 9px; margin: 0; padding: 0; list-style: none; align-items: flex-end;
}
.nav-dots a { display: flex; align-items: center; gap: 10px; text-decoration: none; }
.nav-dots i { display: block; width: 8px; height: 8px; border-radius: 50%; background: var(--ink); opacity: .22; transition: opacity .3s, transform .3s; }
.nav-dots .lab { font-family: var(--serif); font-style: italic; font-size: 13px; color: var(--ink); opacity: 0; transform: translateX(6px); transition: opacity .3s, transform .3s; white-space: nowrap; pointer-events: none; background: var(--page, var(--plate)); padding: 3px 10px; border-radius: 999px; border: 1px solid var(--line); }
.nav-dots a.active i { opacity: 1; transform: scale(1.45); }
.nav-dots a:hover .lab { opacity: 1; transform: none; }
.nav-dots a:hover i { opacity: .6; }

/* ---------- sections ---------- */
/* Sections no longer clip. Each section's sauce work sits on the seam with the next one and is allowed
   to run past the bottom edge; main clips only the very last spill at the end of the page. */
main { overflow: clip; }
section { position: relative; min-height: 100svh; overflow: visible; }
section .art { position: absolute; inset: -60px 0; z-index: 0; pointer-events: none; }
section .art svg { width: 100%; height: 100%; overflow: visible; }
section > .inner { position: relative; z-index: 1; isolation: isolate; }

/* cover: name on the left, the index on the right */
.cover .inner { min-height: 100svh; display: grid; grid-template-columns: 1.1fr 1fr; gap: clamp(32px, 6vw, 96px); align-items: center; padding: clamp(90px, 12vh, 130px) clamp(24px, 6vw, 96px) 70px; max-width: 1500px; margin: 0 auto; }
.cover .kicker { font-size: 12px; letter-spacing: .3em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 .6em; }
.cover h1 { font-size: clamp(3.4rem, 8.8vw, 8rem); margin: 0 0 .12em; line-height: .94; letter-spacing: -0.01em; }
.cover .tagline { font-family: var(--serif); font-style: italic; font-size: clamp(1.3rem, 2.4vw, 2rem); color: var(--ink-soft); margin: 0; }
.cover .lead { max-width: 40ch; margin: 1.6em 0 0; color: var(--ink-soft); }
.cover .cta { display: flex; align-items: center; gap: 14px; margin-top: 2.2em; }
.cover .cta .or { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
.cover .cta .contents { display: none; }
.scroll-cue { display: none; }

/* index list: shared by the cover panel and the overlay */
.index-list { display: flex; flex-direction: column; gap: 22px; }
.index-list .chap { display: flex; flex-direction: column; gap: 2px; }
.index-list .head { display: flex; align-items: baseline; gap: 12px; padding-bottom: 8px; margin-bottom: 4px; border-bottom: 1px solid var(--line); }
.index-list .head .k { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--sauce-text); }
.index-list .head .title { font-family: var(--serif); font-style: italic; font-size: 1.55rem; }
.index-list .head .cnt { margin-left: auto; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }
.index-list .row { display: flex; align-items: baseline; gap: 14px; padding: 4px 6px; margin: 0 -6px; border-radius: 8px; text-decoration: none; transition: background .25s; }
.index-list .row:hover { background: color-mix(in oklab, var(--ink) 7%, transparent); }
.index-list .row .n { font-family: var(--serif); font-style: italic; font-size: 12px; color: var(--sauce-text); width: 22px; flex: none; }
.index-list .row .t { font-family: var(--serif); font-size: 1.15rem; line-height: 1.25; }
.index-list .row .y { margin-left: auto; font-size: 10px; letter-spacing: .14em; color: var(--ink-soft); flex: none; }
.cover-index { padding: 26px 30px; border-radius: 18px; background: var(--panel); border: 1px solid var(--line); }

/* index overlay */
.index { position: fixed; inset: 0; z-index: 40; background: color-mix(in oklab, var(--plate) 92%, transparent); backdrop-filter: blur(14px); overflow-y: auto; padding: 24px; }
.index-inner { max-width: 720px; margin: 0 auto; padding: 8px 0 60px; }
.index-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 26px; }
.index-head .brand { font-family: var(--serif); font-size: 26px; }
.index .index-list .row .t { font-size: 1.5rem; }
.index .index-list .row { padding: 8px 8px; }

/* dish */
.dish .inner {
  min-height: 100svh; display: grid; grid-template-columns: 1.05fr 1fr; gap: clamp(28px, 5vw, 80px);
  align-items: center; padding: clamp(80px, 9vh, 110px) clamp(24px, 6vw, 96px) 13svh;
  max-width: 1500px; margin: 0 auto;
}
.dish:nth-of-type(even) .inner { grid-template-columns: 1fr 1.05fr; }
.dish:nth-of-type(even) .visual { order: 2; }
.visual { display: flex; flex-direction: column; align-items: center; gap: 16px; justify-self: center; width: 100%; }
.hero { margin: 0; position: relative; aspect-ratio: 1; width: min(100%, 54svh); }
.hero a { position: absolute; inset: 0; display: block; }
.hero img, .hero .plate { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero.frame-blob img, .hero.frame-blob .plate { border-radius: 46% 54% 52% 48% / 44% 42% 58% 56%; }
.hero.frame-round img, .hero.frame-round .plate { border-radius: 50%; }
.hero.frame-arch img, .hero.frame-arch .plate { border-radius: 999px 999px 28px 28px; }
.hero.frame-rect img, .hero.frame-rect .plate { border-radius: 16px; }
.hero img { position: relative; z-index: 1; box-shadow: 0 34px 60px -32px var(--plate-shadow), inset 0 0 0 1px color-mix(in oklab, var(--ink) 10%, transparent); transition: transform .8s var(--ease); }
.hero a:hover img { transform: scale(1.012); }
/* how many photos there are, on the photo: tells the reader it opens */
.hero .count { position: absolute; left: 50%; bottom: 7%; transform: translateX(-50%); z-index: 3; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; font-weight: 500; color: #fff; background: rgba(20, 16, 14, .55); backdrop-filter: blur(6px); padding: 6px 12px; border-radius: 999px; white-space: nowrap; pointer-events: none; transition: background .3s; }
.hero a:hover .count { background: rgba(20, 16, 14, .75); }
.hero.cutout .count { bottom: 2%; }
/* the phone-only eyebrow above the photo (see the 860px rules); it gets the same soft halo as the copy */
.visual .eyebrow-top { display: none; position: relative; }
.visual .eyebrow-top::before { content: ""; position: absolute; inset: -60% -8%; z-index: -1; background: radial-gradient(ellipse farthest-side at 30% 50%, var(--page, var(--plate)) 40%, var(--fade) 70%, transparent 100%); pointer-events: none; }
/* the plate: a ceramic disc a shade lighter than the page, sitting a little behind the photo */
.hero::before { content: ""; position: absolute; inset: -5.5%; z-index: 0; border-radius: inherit; background: radial-gradient(circle at 42% 36%, var(--plate-rim), color-mix(in oklab, var(--plate) 90%, white) 62%, color-mix(in oklab, var(--plate) 88%, var(--ink)) 100%); box-shadow: 0 18px 40px -18px var(--plate-shadow), inset 0 -2px 6px color-mix(in oklab, var(--ink) 10%, transparent), inset 0 1px 0 rgba(255,255,255,.5); }
.hero.frame-blob::before { border-radius: 46% 54% 52% 48% / 44% 42% 58% 56%; }
.hero.frame-round::before { border-radius: 50%; }
.hero.frame-arch::before { border-radius: 999px 999px 34px 34px; }
.hero.frame-rect::before { border-radius: 22px; }
.hero .plate { position: absolute; inset: 0; background: transparent; z-index: 1; }
.hero:has(.plate)::before { display: none; }
.hero .plate svg { width: 100%; height: 100%; }

/* background-removed cutouts float on the page instead of sitting in a frame */
.hero.cutout img { object-fit: contain; border-radius: 0; box-shadow: none; filter: drop-shadow(0 26px 30px color-mix(in oklab, var(--ink) 34%, transparent)); position: relative; z-index: 2; }
/* cutouts sit on a shallow plate seen from a low angle, with a sauce drag painted under the food */
.hero.cutout::before { content: ""; position: absolute; inset: auto -4% 0 -4%; height: 34%; z-index: 0; border-radius: 50%; background: radial-gradient(ellipse at 50% 40%, var(--plate-rim), color-mix(in oklab, var(--plate) 92%, white) 60%, color-mix(in oklab, var(--plate) 86%, var(--ink)) 100%); box-shadow: 0 16px 30px -14px var(--plate-shadow), inset 0 -3px 6px color-mix(in oklab, var(--ink) 12%, transparent), inset 0 1px 0 rgba(255,255,255,.55); }
.hero.cutout::after { content: ""; position: absolute; left: 14%; right: 6%; bottom: 8%; height: 14%; z-index: 1; border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%; transform: rotate(-6deg); background: linear-gradient(90deg, var(--sauce) 0 38%, color-mix(in oklab, var(--sauce) 70%, transparent) 70%, transparent 100%); -webkit-mask: linear-gradient(90deg, #000 0 30%, #000 60%, transparent 100%); mask: linear-gradient(90deg, #000 0 30%, #000 60%, transparent 100%); opacity: .9; }
body.anim section.live .hero.cutout img { animation: settle 1.6s var(--ease) .1s both; }
@keyframes settle { from { transform: translateY(-10px); } to { transform: none; } }

/* the other finished photos, under the hero */
.gallery { display: flex; align-items: center; gap: 10px; }
.gallery .lbl { margin-right: 6px; }
.gallery a { display: block; width: 84px; height: 84px; border-radius: 14px; overflow: hidden; transition: transform .4s var(--ease); }
.gallery a:hover { transform: translateY(-3px); }
.gallery img { width: 100%; height: 100%; object-fit: cover; }

.text { position: relative; }
/* legibility halos: farthest-side ellipses so the fade reaches zero before the box edge and never draws a rectangle */
.text::before { content: ""; position: absolute; inset: -10% -12%; z-index: -1; background: radial-gradient(ellipse farthest-side at 50% 50%, var(--page, var(--plate)) 42%, var(--fade) 64%, transparent 100%); pointer-events: none; }
.cover-text { position: relative; }
.cover-text::before { content: ""; position: absolute; inset: -12% -16%; z-index: -1; background: radial-gradient(ellipse farthest-side at 50% 50%, var(--page, var(--plate)) 40%, var(--fade) 62%, transparent 100%); pointer-events: none; }
.chapter .inner::before, .colophon .inner::before { content: ""; position: absolute; inset: -14% -10%; z-index: -1; background: radial-gradient(ellipse farthest-side at 50% 50%, var(--page, var(--plate)) 36%, var(--fade) 60%, transparent 100%); pointer-events: none; }
.chapter .inner, .colophon .inner { z-index: 1; }
.text .eyebrow { display: flex; }
.text .eyebrow, .visual .eyebrow-top { gap: 18px; align-items: baseline; font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 1.1em; font-weight: 500; }
.text .num, .eyebrow-top .num { font-family: var(--serif); font-style: italic; font-size: 1.1rem; color: var(--sauce-text); letter-spacing: 0; text-transform: none; }
.text h2 { font-size: clamp(2.8rem, 5.3vw, 5.1rem); margin: 0 0 .22em; text-wrap: balance; }
.text .sub { font-family: var(--serif); font-style: italic; font-size: 1.3rem; line-height: 1.35; color: var(--ink-soft); margin: 0 0 1.1em; }
.text .desc { max-width: 56ch; margin: 0 0 1.4em; }
.text .meta { font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 1.4em; display: flex; gap: 1.6em; flex-wrap: wrap; }

details.ingredients { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: .2em 0; max-width: 60ch; }
details.ingredients summary { cursor: pointer; list-style: none; display: grid; grid-template-columns: auto 1fr auto; align-items: baseline; gap: 14px; padding: .8em 0; }
details.ingredients summary::-webkit-details-marker { display: none; }
details.ingredients summary .preview { font-family: var(--serif); font-style: italic; font-size: .98rem; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
details.ingredients summary::after { content: "+"; font-family: var(--serif); font-size: 1.5rem; line-height: 0; transition: transform .35s var(--ease); }
details.ingredients[open] summary::after { transform: rotate(45deg); }
details.ingredients[open] summary .preview { visibility: hidden; }
details.ingredients .groups { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1em 2em; padding: .2em 0 1.2em; }
details.ingredients h3 { font-style: italic; font-size: 1.05rem; margin-bottom: .4em; color: var(--sauce-text); }
details.ingredients ul { margin: 0; padding: 0; list-style: none; font-size: .95rem; color: var(--ink-soft); }
details.ingredients li { padding: .1em 0; }

.tags { display: flex; gap: .5em; flex-wrap: wrap; list-style: none; padding: 0; margin: 1.4em 0 0; }
.tags li { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; border: 1px solid var(--line); border-radius: 999px; padding: .35em .9em; color: var(--ink-soft); background: color-mix(in oklab, var(--plate) 70%, transparent); }

/* prep / process photos: a quiet strip under the entry, never the hero */
.process { display: flex; align-items: center; gap: 8px; margin-top: 1.5em; flex-wrap: wrap; }
.process .lbl { margin-right: 8px; display: flex; flex-direction: column; gap: 2px; text-decoration: none; }
.process .lbl small { font-size: 10px; letter-spacing: .1em; text-transform: none; font-family: var(--serif); font-style: italic; font-size: 13px; color: var(--sauce-text); }
/* process steps read as a numbered sequence: muted until hovered, a step number in the corner */
.process a.step, .process a.more { display: block; position: relative; width: 56px; height: 56px; border-radius: 10px; overflow: hidden; transition: transform .4s var(--ease), filter .4s; border: 1px solid var(--line); filter: saturate(.7) contrast(.95); }
.process a.step:hover, .process a.more:hover { transform: translateY(-3px); filter: none; }
.process a i { position: absolute; left: 4px; top: 4px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: color-mix(in oklab, var(--ink) 82%, transparent); color: var(--plate); font: 500 10px/16px var(--sans); text-align: center; font-style: normal; }
.process img { width: 100%; height: 100%; object-fit: cover; }
.process a.more { display: flex; align-items: center; justify-content: center; border: 1px solid var(--line); font-size: 12px; color: var(--ink-soft); text-decoration: none; }

/* chapter dividers */
/* chapter opener: a short section. The title sits in its upper half and the sweep lies on the seam below it,
   like a rule under the heading, leading into the first dish. */
.chapter { min-height: 54svh; display: grid; place-items: start center; text-align: center; }
.chapter .inner { padding: 16vh 6vw 6vh; }
.chapter .num { display: block; margin-bottom: .6em; }
.chapter h2 { font-size: clamp(3.2rem, 9.4vw, 8rem); font-style: italic; margin-bottom: .15em; }
.chapter .sub { margin-bottom: .6em; }
.chapter .meta { justify-content: center; }

/* colophon */
.colophon { display: grid; place-items: center; text-align: center; min-height: 70svh; }
.colophon .inner { padding: 12vh 6vw; }
.colophon .num { display: block; margin-bottom: .8em; }
.colophon h2 { font-size: clamp(2.4rem, 6vw, 5rem); margin-bottom: .2em; }
.colophon .sub { margin-bottom: .8em; }
.colophon .contact { font-family: var(--serif); font-size: 1.3rem; text-decoration: none; border-bottom: 1px solid var(--line); }
.colophon .cta { display: flex; justify-content: center; gap: 12px; margin-top: 2.4em; }

/* lightbox: a Plate / Process switch (top), the photo, a filmstrip in two groups, then a bottom bar
   (previous, caption, next). The buttons stay on phones; gestures come on top of them, never instead of them.
   The photo is absolutely positioned inside the stage so its max-height resolves against the stage: as a
   plain grid child the percentage never resolved and tall photos ran past the screen. */
.lightbox { position: fixed; inset: 0; z-index: 50; background: rgb(18 16 15 / var(--dim, 1)); color: #fff; display: grid; grid-template-rows: auto minmax(0, 1fr) auto auto; overscroll-behavior: contain; -webkit-user-select: none; user-select: none; }
.lightbox .top { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px; padding-top: max(12px, env(safe-area-inset-top)); }
.lightbox .sets { display: flex; gap: 4px; padding: 3px; border-radius: 999px; background: rgba(255, 255, 255, .08); }
.lightbox .set { width: auto; height: 38px; padding: 0 14px; border-radius: 999px; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; background: none; display: flex; align-items: center; gap: 8px; opacity: .6; }
.lightbox .set b { font-weight: 500; }
.lightbox .set span { font-size: 10px; opacity: .8; letter-spacing: .08em; }
.lightbox .set.on { background: rgba(255, 255, 255, .16); opacity: 1; }
.lightbox .set:hover, .lightbox .set:focus-visible { opacity: 1; }
.lightbox .stage { position: relative; min-height: 0; touch-action: none; cursor: default; overflow: hidden; }
.lightbox .stage img { position: absolute; inset: 0 16px; margin: auto; width: auto; height: auto; max-width: calc(100% - 32px); max-height: 100%; object-fit: contain; border-radius: 8px; box-shadow: 0 30px 80px rgba(0, 0, 0, .5); transition: transform .28s var(--ease), opacity .3s; will-change: transform; -webkit-user-drag: none; }
.lightbox.loading .stage img { opacity: .35; }
.lightbox.zoomed .stage { cursor: grab; }
.lightbox.zoomed .stage:active { cursor: grabbing; }
.lightbox.zoomed .stage img { border-radius: 0; box-shadow: none; }
.lightbox button { background: rgba(255, 255, 255, .1); color: #fff; border: 0; width: 44px; height: 44px; border-radius: 50%; font-size: 26px; line-height: 1; cursor: pointer; display: grid; place-items: center; transition: background .3s; flex: none; }
.lightbox button:hover, .lightbox button:focus-visible { background: rgba(255, 255, 255, .24); outline: none; }
/* filmstrip: the plate group, then the process group, each labelled; the current photo is outlined */
.lightbox .strip { display: flex; gap: 18px; padding: 12px 16px 4px; overflow-x: auto; scrollbar-width: none; scroll-padding-inline: 16px; }
.lightbox .strip::-webkit-scrollbar { display: none; }
.lightbox .strip .grp { display: flex; align-items: center; gap: 6px; flex: none; }
.lightbox .strip .grp + .grp { padding-left: 18px; border-left: 1px solid rgba(255, 255, 255, .18); }
.lightbox .strip .g { font-size: 10px; letter-spacing: .16em; text-transform: uppercase; opacity: .55; writing-mode: vertical-rl; transform: rotate(180deg); margin-right: 2px; }
.lightbox .strip a { position: relative; display: block; width: 46px; height: 46px; border-radius: 7px; overflow: hidden; opacity: .55; outline: 2px solid transparent; outline-offset: 2px; transition: opacity .25s, outline-color .25s; flex: none; }
.lightbox .strip a:hover { opacity: .85; }
.lightbox .strip a.on { opacity: 1; outline-color: #fff; }
.lightbox .strip img { width: 100%; height: 100%; object-fit: cover; }
.lightbox .strip .grp[data-set="process"] a { filter: saturate(.75); }
.lightbox .strip .grp[data-set="process"] a.on { filter: none; }
.lightbox .strip a i { position: absolute; left: 3px; top: 3px; min-width: 14px; height: 14px; padding: 0 3px; border-radius: 7px; background: rgba(0, 0, 0, .7); color: #fff; font: 500 9px/14px var(--sans); font-style: normal; text-align: center; }
.lightbox .bar { display: grid; grid-template-columns: 44px 1fr 44px; align-items: center; gap: 14px; padding: 8px 12px 16px; padding-bottom: max(16px, env(safe-area-inset-bottom)); }
/* one photo: the arrows keep their place so the caption stays centred, they just do not show */
.lightbox.single .prev, .lightbox.single .next { visibility: hidden; }
.lightbox .cap { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 2px; min-width: 0; }
.lightbox .cap .t { font-family: var(--serif); font-size: 1.15rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.lightbox .cap .k { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; opacity: .75; }
.lightbox[data-set="process"] .cap .k { color: #f3c98b; }
.lightbox .cap .hint { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; opacity: .4; }
@media (hover: hover) and (pointer: fine) { .lightbox .cap .hint { display: none; } }
@media (min-width: 861px) {
  /* desktop: arrows float beside the photo, caption sits under it */
  .lightbox .stage img { inset: 0 80px; max-width: calc(100% - 160px); }
  .lightbox .strip { justify-content: center; }
  .lightbox .bar { grid-template-columns: 1fr; padding: 6px 24px 18px; }
  .lightbox .bar .prev, .lightbox .bar .next { position: absolute; top: 50%; transform: translateY(-50%); }
  .lightbox .bar .prev { left: 18px; }
  .lightbox .bar .next { right: 18px; }
}

/* ---------- reveal (screen only, opt-in via body.anim) ----------
   Nothing pops. Sauce is already half-laid when a section arrives and finishes its stroke; dots and
   crumbs settle from 60% to full; text and photo drift up a few pixels. Everything is a transition, so
   it also eases back out when app.js re-arms a section. */
body.anim mask path { stroke-dasharray: 1; stroke-dashoffset: .3; transition: stroke-dashoffset calc(var(--t, 1.6s) * .6) var(--ease) calc(var(--d, 0s) * .5); }
body.anim section.live mask path { stroke-dashoffset: 0; }
/* the sculpted relief (shade image + hairlines) sits outside the drawing mask: masking a large image re-rasters
   every frame of the reveal. It fades in briefly once the stroke has drawn. */
body.anim .relief { opacity: 0; transition: opacity .4s var(--ease) calc(var(--d, 0s) * .5 + var(--t, 1.6s) * .55); }
body.anim section.live .relief { opacity: 1; }
body.anim .dot, body.anim .crumb, body.anim .quenelle {
  transform-box: fill-box; transform-origin: center; transform: scale(.6); opacity: 0;
  transition: transform .6s cubic-bezier(.2, 1.2, .4, 1) calc(var(--d, 0s) * .5), opacity .45s var(--ease) calc(var(--d, 0s) * .5);
}
body.anim section.live .dot, body.anim section.live .crumb, body.anim section.live .quenelle { transform: scale(1); opacity: 1; }
body.anim .text > *, body.anim .cover-text > *, body.anim .cover-index { opacity: 0; transform: translateY(10px); transition: opacity .5s var(--ease), transform .6s var(--ease); }
body.anim section.live .text > *, body.anim section.live .cover-text > *, body.anim section.live .cover-index { opacity: 1; transform: none; }
/* baked art that arrives after its section is already on screen shows finished rather than half-revealed */
.art.settled * { transition-duration: 0s !important; transition-delay: 0s !important; animation-duration: 0s !important; }
/* app.js drives .visual's and .art's transforms for parallax (their own compositor layers for the session) */
.dish .visual, .dish .art, .chapter .art { will-change: transform; }
/* app.js drives .visual's transform for parallax, so the photo only fades */
body.anim .visual { opacity: 0; transition: opacity .5s var(--ease); }
body.anim section.live .visual { opacity: 1; }
body.anim .text > :nth-child(1) { transition-delay: .02s; }
body.anim .text > :nth-child(2) { transition-delay: .06s; }
body.anim .text > :nth-child(3) { transition-delay: .1s; }
body.anim .text > :nth-child(4) { transition-delay: .14s; }
body.anim .text > :nth-child(5) { transition-delay: .18s; }
body.anim .text > :nth-child(6) { transition-delay: .22s; }
body.anim .text > :nth-child(7) { transition-delay: .26s; }
body.anim .cover-text > :nth-child(2) { transition-delay: .06s; }
body.anim .cover-text > :nth-child(3) { transition-delay: .12s; }
body.anim .cover-text > :nth-child(4) { transition-delay: .18s; }
body.anim .cover-text > :nth-child(5) { transition-delay: .24s; }
body.anim .cover-index { transition-delay: .2s; }


@media (prefers-reduced-motion: reduce) { body.anim mask path, body.anim .dot, body.anim .crumb, body.anim .quenelle, body.anim .text > *, body.anim .cover-text > *, body.anim .cover-index, body.anim .visual, body.anim .hero.cutout img { animation-duration: .01s !important; animation-delay: 0s !important; transition-duration: .01s !important; transition-delay: 0s !important; } }

/* ---------- responsive ---------- */
@media (max-width: 960px) {
  /* the cover is a short opening card on small screens, not a full empty screen */
  .cover { min-height: 0; }
  .cover .inner { grid-template-columns: 1fr; gap: 36px; padding: 96px 24px 64px; min-height: 0; }
  /* phones and small tablets: the dish list collapses behind a Contents button (opens the index overlay) */
  .cover-index { display: none; }
  .cover .cta .or { display: none; }
  .cover .cta .contents { display: inline-flex; }
}
@media (max-width: 860px) {
  /* phones: no SVG blur filters (they re-rasterise on every reveal frame at 3x density) */
  .plating [filter] { filter: none; }
  /* phones: photos, text and cutouts are simply there; the sauce work still draws itself in */
  body.anim .visual, body.anim .text > *, body.anim .cover-text > *, body.anim .cover-index { opacity: 1; transform: none; transition: none; }
  body.anim section.live .hero.cutout img { animation: none; }
  /* each dish is its own page: a hairline rule and clear air above it, the eyebrow first, then the photo */
  .dish { min-height: 0; }
  .dish .inner, .dish:nth-of-type(even) .inner { grid-template-columns: 1fr; gap: 26px; padding: 124px 20px 72px; align-content: start; min-height: 0; }
  /* the opener: cover copy, then the chapter title straight after, then the chapter sweep leads into dish one.
     The cover draws no art of its own on phones (two strokes 300px apart read as clutter). */
  .cover .art { display: none; }
  .cover .inner { padding-bottom: 8px; }
  .chapter { min-height: 0; }
  .chapter .inner { padding: 40px 24px 150px; }
  .dish + .dish::before { content: ""; position: absolute; top: 0; left: 20px; right: 20px; height: 1px; background: var(--line); z-index: 2; }
  section .art { inset: -24px 0; }
  .dish:nth-of-type(even) .visual { order: 0; }
  .visual { align-items: stretch; gap: 14px; }
  .visual .eyebrow-top { display: flex; margin: 0 0 2px; }
  .text .eyebrow { display: none; }
  .hero, .hero.frame-round, .hero.frame-blob, .hero.frame-arch, .hero.frame-rect { width: 100%; aspect-ratio: 4 / 5; max-height: 58svh; }
  .hero.frame-round img, .hero.frame-blob img, .hero.frame-arch img, .hero.frame-rect img, .hero .plate { border-radius: 18px; }
  /* the plate rim follows the photo's rounded shape instead of a disc peeking out behind the corners */
  .hero::before, .hero.frame-round::before, .hero.frame-blob::before, .hero.frame-arch::before, .hero.frame-rect::before { inset: -3.5%; border-radius: 26px; }
  .hero .count { bottom: 12px; left: auto; right: 12px; transform: none; }
  .hero.cutout .count { bottom: 4px; }
  /* thumbnails: one row that scrolls sideways, never wraps */
  .gallery { overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding: 4px 0; margin: 0 -20px; padding-inline: 20px; scroll-padding-inline: 20px; }
  .gallery::-webkit-scrollbar { display: none; }
  .gallery a { width: 72px; height: 72px; border-radius: 10px; flex: none; }
  .gallery a:hover { transform: none; }
  /* the fixed bar gets a soft fade so copy scrolling under it stays readable */
  .topbar::before { content: ""; position: absolute; inset: 0 0 -24px; z-index: -1; background: linear-gradient(to bottom, var(--page, var(--plate)) 30%, transparent); opacity: .92; pointer-events: none; }
  .nav-dots { display: none; }
  .topbar { padding: 14px 18px; }
  .text .desc { max-width: none; }
  details.ingredients summary .preview { display: none; }
  .index-list .row .t { font-size: 1.05rem; }
  /* phones: one dish is a short stack. The thumbnails fold into the photo count (the viewer has the
     filmstrip), the tags go, the print button goes, and the type comes down a step. */
  body { font-size: 16px; }
  .topbar .print-wrap { display: none; }
  .text h2 { font-size: 2.3rem; margin-bottom: .2em; }
  .text .sub { font-size: 1.1rem; margin-bottom: .9em; }
  .text .desc { margin-bottom: 1.1em; }
  .gallery, .tags { display: none; }
  .visual { gap: 10px; }
  .hero, .hero.frame-round, .hero.frame-blob, .hero.frame-arch, .hero.frame-rect { max-height: 52svh; }
  .process { margin-top: 1.1em; gap: 0; }
  .process a.step, .process a.more { display: none; }
  .process .lbl { flex-direction: row; align-items: baseline; gap: 10px; margin: 0; }
  .process .lbl::after { content: "›"; font-family: var(--serif); font-size: 1.2rem; line-height: 1; color: var(--sauce-text); }
  details.ingredients summary { padding: .7em 0; }
  .lightbox .stage img { inset: 0 8px; max-width: calc(100% - 16px); border-radius: 6px; }
  .lightbox .set { padding: 0 11px; height: 34px; }
  .lightbox .strip { padding-top: 10px; }
  .lightbox .strip a { width: 40px; height: 40px; }
}

@media (max-height: 480px) { .lightbox .strip { display: none; } .lightbox .top { padding-block: 6px; } .lightbox .bar { padding-block: 4px 8px; } }

/* =====================================================================
   PRINT / EXPORT FORMATS
   ===================================================================== */
body[class*="format-"] { transition: none; background: var(--plate); }
body[class*="format-"] .topbar, body[class*="format-"] .nav-dots, body[class*="format-"] .index, body[class*="format-"] .lightbox, body[class*="format-"] .hero .count, body[class*="format-"] .eyebrow-top, body[class*="format-"] .cover .cta, body[class*="format-"] .colophon .cta { display: none; }
body[class*="format-"] main { overflow: visible; }
body[class*="format-"] section { break-after: page; page-break-after: always; overflow: hidden; background: var(--plate); color: var(--ink); }
body[class*="format-"] section:last-of-type { break-after: auto; page-break-after: auto; }
body[class*="format-"] .el, body[class*="format-"] .text > *, body[class*="format-"] .cover-text > *, body[class*="format-"] .cover-index, body[class*="format-"] .visual { animation: none !important; transition: none !important; opacity: 1; transform: none; }
body[class*="format-"] section .art { inset: 0; transform: none !important; }
body[class*="format-"] .hero::before { box-shadow: none; }
body[class*="format-"] .visual { transform: none !important; }
body[class*="format-"] mask path { stroke-dashoffset: 0 !important; }
body[class*="format-"] details.ingredients summary { pointer-events: none; }
body[class*="format-"] details.ingredients summary::after { display: none; }
body[class*="format-"] .hero img { box-shadow: none; }
body[class*="format-"] .btn, body[class*="format-"] .topbar .brand { backdrop-filter: none; }
body[class*="format-"] .hero.cutout img { filter: none; }

/* book: A4 portrait */
body.format-book section { width: 210mm; height: 297mm; min-height: 0; margin: 0 auto; }
body.format-book .cover .inner { grid-template-columns: 1fr; gap: 12mm; padding: 26mm 18mm 20mm; min-height: 0; height: 100%; align-content: start; }
body.format-book .cover h1 { font-size: 58pt; }
body.format-book .cover .lead { display: none; }
body.format-book .cover-index { padding: 6mm 8mm; }
body.format-book .index-list { gap: 5mm; }
body.format-book .index-list .row { padding: 1px 4px; }
body.format-book .index-list .row .t { font-size: 11pt; }
body.format-book .index-list .head .title { font-size: 15pt; }
body.format-book .dish .inner, body.format-book .dish:nth-of-type(even) .inner {
  grid-template-columns: 1fr; grid-template-rows: 100mm 1fr; gap: 6mm; padding: 14mm 18mm 48mm; min-height: 0; height: 100%; align-items: start;
}
body.format-book .visual, body.format-book .dish:nth-of-type(even) .visual { order: 0; flex-direction: row; align-items: center; justify-content: center; gap: 8mm; height: 100mm; }
body.format-book .hero { width: 100mm; height: 100mm; aspect-ratio: auto; max-height: none; flex: none; }
body.format-book .gallery { flex-direction: column; gap: 4mm; }
body.format-book .gallery a { width: 28mm; height: 28mm; border-radius: 3mm; }
body.format-book .text h2 { font-size: 30pt; }
body.format-book .text .sub { font-size: 13pt; margin-bottom: .6em; }
body.format-book .text .desc { font-size: 10pt; margin-bottom: .8em; }
body.format-book details.ingredients { max-width: none; }
body.format-book details.ingredients summary .preview { display: none; }
body.format-book details.ingredients ul { font-size: 8.5pt; }
body.format-book details.ingredients .groups { grid-template-columns: repeat(4, 1fr); gap: .6em 1.6em; padding-bottom: .4em; }
body.format-book .tags { display: none; }
body.format-book .process a { width: 16mm; height: 16mm; }
body.format-book .chapter { height: 297mm; min-height: 0; }
body.format-book .chapter h2 { font-size: 56pt; }
body.format-book .colophon .inner { padding: 60mm 18mm; }

/* cards: A5 landscape */
body.format-cards section { width: 210mm; height: 148mm; min-height: 0; margin: 0 auto; }
body.format-cards .cover .inner { grid-template-columns: 1fr; padding: 20mm 14mm; min-height: 0; height: 100%; align-content: center; }
body.format-cards .cover h1 { font-size: 44pt; }
body.format-cards .cover-index, body.format-cards .cover .lead { display: none; }
body.format-cards .dish .inner, body.format-cards .dish:nth-of-type(even) .inner {
  grid-template-columns: 1fr 1.15fr; gap: 8mm; padding: 16mm 14mm 22mm; min-height: 0; height: 100%; align-items: center;
}
body.format-cards .visual, body.format-cards .dish:nth-of-type(even) .visual { order: 0; }
body.format-cards .hero { width: 100mm; height: 100mm; aspect-ratio: auto; max-height: none; flex: none; }
body.format-cards .gallery, body.format-cards .process, body.format-cards .tags { display: none; }
body.format-cards .text h2 { font-size: 22pt; }
body.format-cards .text .sub { font-size: 11pt; margin-bottom: .5em; }
body.format-cards .text .desc { font-size: 8.5pt; margin-bottom: .6em; }
body.format-cards details.ingredients summary .preview { display: none; }
body.format-cards details.ingredients ul { font-size: 7pt; }
body.format-cards details.ingredients .groups { grid-template-columns: repeat(3, 1fr); gap: .4em 1.2em; padding-bottom: .4em; }
body.format-cards details.ingredients h3 { font-size: .9rem; margin-bottom: .2em; }
body.format-cards details.ingredients summary { padding: .4em 0; }
body.format-cards .smear, body.format-cards .crumbs { display: none; }
body.format-cards .colophon { display: none; }

/* sheet: A4 portrait, single page */
body.format-sheet section { width: 210mm; min-height: 0; margin: 0 auto; break-after: auto; page-break-after: auto; }
body.format-sheet .cover { height: 60mm; }
body.format-sheet .cover .inner { grid-template-columns: 1fr; padding: 12mm 14mm; min-height: 0; }
body.format-sheet .cover h1 { font-size: 34pt; }
body.format-sheet .cover .lead, body.format-sheet .cover .kicker, body.format-sheet .cover-index { display: none; }
body.format-sheet .sheet { height: 237mm; }
body.format-sheet .sheet .inner { height: 100%; }
body.format-sheet .sheet-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6mm 5mm; padding: 4mm 14mm 10mm; }
body.format-sheet .sheet-grid .cell .thumb { aspect-ratio: 1; border-radius: 50%; overflow: hidden; margin-bottom: 3mm; }
body.format-sheet .sheet-grid .cell img, body.format-sheet .sheet-grid .cell svg { width: 100%; height: 100%; object-fit: cover; display: block; }
body.format-sheet .sheet-grid .cell .thumb img.cutout { object-fit: contain; }
body.format-sheet .sheet-grid .cell .thumb:has(img.cutout) { border-radius: 0; }
body.format-sheet .sheet-grid .cell h3 { font-size: 12pt; }
body.format-sheet .sheet-grid .cell p { font-size: 7.5pt; color: var(--ink-soft); margin: .2em 0 0; }
body.format-sheet .sheet-grid .cell .swatches { display: flex; gap: 2px; margin-top: 2mm; }
body.format-sheet .sheet-grid .cell .swatches i { width: 5mm; height: 3mm; border-radius: 2px; display: block; }
body.format-sheet .sheet-foot { padding: 6mm 14mm 0; display: flex; justify-content: space-between; font-size: 8pt; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }
body.format-sheet .dish, body.format-sheet .colophon, body.format-sheet .chapter { display: none; }

@media print {
  html, body { background: var(--plate); }
  body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .topbar, .nav-dots, .index, .lightbox, .no-print { display: none !important; }
  section { break-inside: avoid; }
}

/* ---------- texture lab (opt-in; see textures.js) ---------- */
/* the sculpt look travels with the SVG (`.plating.sculpt`, emitted by the engine) so baked art renders the same on the live page; the lab textures still key off the body class */
body[class*="texture-"] .plating [filter], body[class*="texture-"] .plating path[stroke="#fff"][stroke-dasharray], .plating.sculpt [filter], .plating.sculpt path[stroke="#fff"][stroke-dasharray] { display: none; } /* the engine's own shadows and gloss strokes: the filter lights the sauce instead */
body.texture-oil .plating .el, body.texture-oil .plating .dots, body.texture-oil .plating .crumbs, body.texture-oil .plating .splatter { filter: url(#tex-oil); }
body.texture-gloss .plating .el, body.texture-gloss .plating .dots, body.texture-gloss .plating .crumbs, body.texture-gloss .plating .splatter { filter: url(#tex-gloss); }
body.texture-velvet .plating .el, body.texture-velvet .plating .dots, body.texture-velvet .plating .crumbs, body.texture-velvet .plating .splatter { filter: url(#tex-velvet); }
.plating.sculpt .el:not(.swoosh):not(.smear):not(.raster), .plating.sculpt .dots, .plating.sculpt .crumbs, .plating.sculpt .splatter { filter: url(#tex-velvetdeep); }
/* baked pages carry the filtered pieces as images (the filter already applied); they fade in once, no scaling */
.plating .el.raster { filter: none !important; }
body.anim .el.raster { opacity: 0; transition: opacity .6s var(--ease) calc(var(--d, 0s) * .5); }
body.anim section.live .el.raster { opacity: 1; }
.plating.sculpt .hm, .plating.sculpt .hm * { display: initial; }
body.texture-glaze .plating .el, body.texture-glaze .plating .dots, body.texture-glaze .plating .crumbs, body.texture-glaze .plating .splatter { filter: url(#tex-glaze); }
body[class*="texture-"] .plating .dots .el, body[class*="texture-"] .plating .crumbs .el, body[class*="texture-"] .plating .smear .el, body[class*="texture-"] .plating .swoosh .el, .plating.sculpt .dots .el, .plating.sculpt .crumbs .el, .plating.sculpt .smear .el, .plating.sculpt .swoosh .el, .plating.sculpt .zest .el { filter: none; } /* filtered once at group level; tiny flung pieces never on their own */
.lab-switch { position: fixed; left: 16px; bottom: 16px; z-index: 60; display: flex; flex-direction: column; gap: 4px; padding: 10px 12px; border-radius: 16px; max-width: min(92vw, 720px); background: var(--panel); border: 1px solid var(--line); box-shadow: 0 12px 30px color-mix(in oklab, var(--ink) 20%, transparent); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; }
.lab-switch .row { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; }
.lab-switch span { color: var(--ink-soft); padding: 0 6px; min-width: 96px; }
.lab-switch button { font: inherit; letter-spacing: inherit; text-transform: inherit; cursor: pointer; border: 1px solid transparent; background: transparent; color: var(--ink); border-radius: 999px; padding: 6px 10px; }
.lab-switch button.on { background: var(--ink); color: var(--plate); }
.lab-sculpt { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 14px; padding: 6px 0 4px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); margin: 4px 0; }
.lab-sculpt .sl { display: grid; grid-template-columns: 92px 1fr 44px; align-items: center; gap: 8px; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); }
.lab-sculpt input[type=range] { width: 100%; accent-color: var(--ink); height: 18px; }
.lab-sculpt output { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink); }
.lab-sculpt .row { grid-column: 1 / -1; }
@media (max-width: 860px) { .lab-switch { left: 8px; right: 8px; bottom: 8px; max-height: 40vh; overflow-y: auto; } .lab-switch span { min-width: 70px; } body[class*="texture-"] .plating .el, .plating.sculpt .el { filter: none; } }
/* lab dials (colour is applied to the palettes in app.js, not as a filter on the moving art) */
body.lab-frame-noplate .hero::before { display: none; }
body.lab-frame-rect .hero img, body.lab-frame-rect .hero::before, body.lab-frame-rect .hero .plate { border-radius: 22px !important; }
body.lab-frame-bare .hero::before { display: none; }
body.lab-frame-bare .hero img, body.lab-frame-bare .hero .plate { border-radius: 10px !important; }
body.lab-type-large .text h2 { font-size: clamp(3.4rem, 6.6vw, 6.6rem); }
body.lab-type-large .cover h1 { font-size: clamp(3.8rem, 10.5vw, 9.6rem); }
body.lab-type-large .chapter h2 { font-size: clamp(3.6rem, 11vw, 9.5rem); }
body[class*="format-"] .lab-switch { display: none; }

/* ============================================================================
   Plating update — CSS additions.
   Append to style.css, after the existing `body[class*="texture-"]` block
   (around line 474). Nothing here needs the original rules to be edited.
   ============================================================================ */

/* REQUIRED. style.css:471 puts tex-velvetdeep on every .el except .swoosh and .smear.
   The zest now computes its own shading from the true surface normal of a twisted slab,
   so the filter would dome it a second time and flatten the twist back out. Exclude it
   the same way the swoosh and smear already are, in every texture mode. */
body.texture-sculpt .plating .zest .el,
body.texture-oil    .plating .zest .el,
body.texture-gloss  .plating .zest .el,
body.texture-velvet .plating .zest .el,
body.texture-glaze  .plating .zest .el { filter: none; }

/* OPTIONAL. The new rake and lip hairlines on the sculpted sweep are filled paths, not
   strokes, so style.css:467 does not touch them — that rule only hides
   path[stroke="#fff"][stroke-dasharray]. These hooks are here so you can dial the line
   work down per texture without touching the engine. */
/* (The package shipped an `opacity: inherit` hook on .rake-dark / .rake-light here. It is deliberately gone:
   the engine sets each hairline's opacity as an SVG attribute (0.26–0.44), and a CSS opacity beats the
   attribute, so the hook rendered every rake line solid black. Dial the lines with Plating.setParams({ rakeLine })
   instead.) */

/* OPTIONAL. Kill the drawn line work but keep the relief channels, for a quieter sweep:
   body.texture-sculpt .plating .rake-dark,
   body.texture-sculpt .plating .rake-light,
   body.texture-sculpt .plating .lip-light,
   body.texture-sculpt .plating .lip-dark { display: none; }
   The same thing is available from script without re-rendering cost:
   Plating.setParams({ rakeLine: 0 })  — relief only
   Plating.setParams({ rake: 0 })      — no rake at all, back to the old blank sweep */

/* The placement-preset picker: review furniture, not part of the design. It appears on the lab, or once a
   profile has been asked for by link, so a set of placements can be compared on a phone with a thumb. */
.preset-pick { position: fixed; right: 12px; bottom: 12px; z-index: 60; display: flex; flex-direction: column;
  align-items: flex-end; gap: 6px; font: 12px/1.3 "Public Sans", system-ui, sans-serif; }
.preset-pick .pp-now { border: 1px solid rgba(40,30,20,.18); background: rgba(255,253,248,.94); color: #241b16;
  border-radius: 999px; padding: 7px 14px; cursor: pointer; box-shadow: 0 6px 18px rgba(40,30,20,.16);
  backdrop-filter: blur(6px); font: inherit; }
.preset-pick .pp-now::after { content: " ▾"; color: #9a8a72; }
.preset-pick .pp-list { display: flex; flex-direction: column; gap: 2px; padding: 5px; min-width: 176px;
  background: #fffdf8; border: 1px solid #d8cdb8; border-radius: 12px; box-shadow: 0 16px 40px rgba(40,30,20,.24); }
.preset-pick .pp-list button { display: block; width: 100%; text-align: left; border: 0; background: none;
  color: #241b16; border-radius: 8px; padding: 7px 9px; cursor: pointer; font: inherit; }
.preset-pick .pp-list button i { display: block; font-style: normal; font-size: 10px; letter-spacing: .04em;
  text-transform: uppercase; color: #9a8a72; margin-top: 2px; }
.preset-pick .pp-list button:hover { background: #f2ead9; }
.preset-pick .pp-list button.on { background: #241b16; color: #fbf7ef; }
.preset-pick .pp-list button.on i { color: #bfae92; }
@media print { .preset-pick { display: none; } }
