/* ============================================================
   Cooked Apps — "food menu" theme design system.
   Shared by every restyled page. Linked alongside
   /assets/js/checker-grid.js, which drives the checker
   background and panel snapping this file lays out.
   ============================================================ */

:root {
  color-scheme: light;

  /* ---------- 1.1 colour tokens ---------- */
  --cream: #FAF8EE;
  --orange: #F24E12;       /* checker dark squares, rules, 24px+ display type only */
  --orange-ink: #C73C0A;   /* orange text under 24px (4.8:1 on cream) */
  --rust: #A93408;         /* body copy, button fill (6.2:1 on cream) */
  --stamp: #2D6A80;        /* stamp + focus outlines */
  --stamp-2: #8A3568;      /* sticker ink, "small batch only" */
  --stamp-3: #3B7A3F;      /* sticker ink, "kitchen approved" */
  --stamp-4: #B23A3A;      /* sticker ink, "shipped with love" */
  --shade-top: #F6EEDC;
  --shade-side: #EEDFC6;
  --shade-deep: #E6D2B4;

  --btn-fill: var(--rust);  /* button fill — a distinct "fun" hue in dark mode */
  --btn-ink: var(--cream);  /* button text, contrasts against --btn-fill */

  /* ---------- 1.2 type ---------- */
  --serif: "Fraunces", Georgia, serif;
  --sans: "Archivo", "Helvetica Neue", Arial, sans-serif;

  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.66 0 0 0 0 0.2 0 0 0 0 0.03 0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");

  /* ---------- 1.3 checker grid ---------- */
  /* --s and --checker-offset-x are written in px by checker-grid.js,
     snapped to whole device pixels so panel edges never drift off
     the grid at fractional zoom or high-density screens. */
  --s: 22px;
  --checker-offset-x: 0px;
}

/* ---------- dark mode ----------
   Off by default; html[data-theme="dark"] is set by theme-toggle.js
   (localStorage, falling back to prefers-color-scheme) before first
   paint. The checker/grid-bg tile artwork below is a separate dark
   SVG rather than a token swap — --orange stays orange (rules,
   display type) rather than becoming the checker colour the way it
   does in light mode, so the checkerboard itself goes quiet dark
   grey on black while text/rules keep their warmth. */
html[data-theme="dark"] {
  color-scheme: dark;
  --cream: #2A2521;
  --orange: #FF6A3D;
  --orange-ink: #FF9269;
  --rust: #EFE3D3;
  --stamp: #6BBBDA;
  --stamp-2: #E896C9;
  --stamp-3: #8FE39A;
  --stamp-4: #FF9B8A;
  --shade-top: #322C27;
  --shade-side: #251F1B;
  --shade-deep: #171310;
  --btn-fill: #FF4F81;
  --btn-ink: #1A1410;
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  background-color: var(--cream);
  /* 2x2 SVG tile, crispEdges — not a conic-gradient, which leaves
     notches at fractional sizes. background-size/position are set by
     checker-grid.js once --s and --checker-offset-x are known. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2 2' width='2' height='2' shape-rendering='crispEdges'%3E%3Crect width='2' height='2' fill='%23F24E12'/%3E%3Crect width='1' height='1' fill='%23FAF8EE'/%3E%3Crect x='1' y='1' width='1' height='1' fill='%23FAF8EE'/%3E%3C/svg%3E");
  background-size: calc(var(--s) * 2) calc(var(--s) * 2);
  background-position: var(--checker-offset-x) 0;
}

/* Secondary (text) pages swap the bold checkerboard for a quiet
   thin-line grid — same square size and offset, so it still snaps
   to the panel edges, just a lot less visual noise behind a long
   read. */
html.grid-bg {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1' width='1' height='1'%3E%3Crect width='1' height='1' fill='%23FAF8EE'/%3E%3Cpath d='M0 0H1M0 0V1' stroke='%23C73C0A' stroke-opacity='.2' stroke-width='.035'/%3E%3C/svg%3E");
  background-size: var(--s) var(--s);
  background-position: var(--checker-offset-x) 0;
}

html[data-theme="dark"] {
  background-color: #0D0B0A;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2 2' width='2' height='2' shape-rendering='crispEdges'%3E%3Crect width='2' height='2' fill='%230D0B0A'/%3E%3Crect width='1' height='1' fill='%232A2521'/%3E%3Crect x='1' y='1' width='1' height='1' fill='%232A2521'/%3E%3C/svg%3E");
}
html[data-theme="dark"].grid-bg {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1' width='1' height='1'%3E%3Crect width='1' height='1' fill='%230D0B0A'/%3E%3Cpath d='M0 0H1M0 0V1' stroke='%23FF9269' stroke-opacity='.22' stroke-width='.035'/%3E%3C/svg%3E");
}

body {
  display: flow-root;
  margin: 0;
  color: var(--rust);
  font-family: var(--serif);
  font-variation-settings: "SOFT" 100, "WONK" 0;
  font-size: 1.1875rem;
  line-height: 1.55;
}

@media (max-width: 640px) {
  body { font-size: 1.0625rem; }
}

h1, h2, h3, .price, .signoff, .dish, .stamp text {
  font-variation-settings: "SOFT" 100, "WONK" 0;
}

a { color: inherit; }
a:focus-visible,
button:focus-visible,
.btn:focus-visible {
  outline: 2px solid var(--stamp);
  outline-offset: 4px;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- 1.4 panels ---------- */
.panel, .hero, .sheet {
  position: relative;
  background-color: var(--cream);
  background-image: var(--grain);
  box-shadow: inset 0 0 0 2px var(--orange);
  /* checker-grid.js reveals these once the first snapped layout has
     run, so there is no visible jump as squares/margins settle. */
  visibility: hidden;
}
.grid-ready .panel,
.grid-ready .hero,
.grid-ready .sheet {
  visibility: visible;
}

.hero {
  display: grid;
  align-content: end;
  justify-content: center;
  padding: 3rem 1.25rem;
  text-align: center;
  overflow: hidden;
  /* Traps the stacking comparison between the full-bleed .masthead-figure
     and the in-flow content on top of it (.masthead, .hero-cue) to this
     one local context, so it doesn't depend on where .hero happens to
     sit in the rest of the page's stacking order. */
  isolation: isolate;
}

/* Title block for a "solo" panel (support/privacy/terms/design-system):
   sits at the top of the one merged .sheet panel, with a divider
   rule separating it from the body content below instead of being
   its own separate boxed panel. */
.panel-title {
  padding-bottom: 1.75rem;
  margin-bottom: 1.75rem;
  border-bottom: 1.5px solid var(--orange);
  text-align: left;
}
.panel-title .pill { margin-top: 0; margin-bottom: 1.5rem; }
.panel-title .section-title { margin-bottom: 0; text-align: left; justify-content: flex-start; }
.panel-title .section-title::before { flex: 0 0 0; border-top: 0; }
.panel-title .section-title::after { flex: 1; }

/* ---------- theme toggle ---------- */
.theme-toggle {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 200;
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  background: var(--cream);
  box-shadow: inset 0 0 0 1.5px var(--orange);
  border: 0;
  border-radius: 50%;
  color: var(--orange-ink);
  cursor: pointer;
  transition: transform .2s cubic-bezier(.2, 1.4, .4, 1), background-color .15s ease, color .15s ease;
}
.theme-toggle:hover { transform: scale(1.08); }
.theme-toggle:active { transform: scale(.96); }
.theme-toggle svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
html[data-theme="dark"] .theme-toggle .moon,
.theme-toggle .sun { display: none; }
html[data-theme="dark"] .theme-toggle .sun,
.theme-toggle .moon { display: block; }

.sheet {
  padding: 4rem clamp(1.25rem, 5vw, 3.5rem) 3rem;
}
@media (max-width: 640px) {
  .sheet { padding: 3rem 1.1rem 2.5rem; }
}

.menu, .content { max-width: 44rem; margin: 0 auto; }
.content { max-width: 70ch; }
.content p, .content ul, .content ol { max-width: 70ch; }

/* ---------- oval label / link pill ---------- */
.pill {
  display: inline-block;
  padding: .3rem 1.1rem .25rem;
  border: 1.5px solid var(--orange);
  border-radius: 50%;
  font-family: var(--sans);
  font-weight: 500;
  font-size: .8rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1.2;
  color: var(--orange-ink);
  text-decoration: none;
  transition: background-color .15s ease, color .15s ease, transform .2s cubic-bezier(.2, 1.4, .4, 1);
}
.hero-cue {
  position: relative;
  z-index: 1;
  justify-self: center;
  margin-top: 2.25rem;
  text-decoration: none;
  border-color: transparent;
}
.hero-cue:hover { background: var(--orange); color: var(--cream); transform: scale(1.05); }
.hero-cue:active { transform: scale(.98); }

/* The oval border is drawn by pill-draw.js as an SVG rect instead of
   the CSS border above (which is kept, just made transparent, so the
   box's size is identical either way) — pathLength="1" normalises the
   dash length regardless of the pill's actual size, the same trick
   the shopfront's line draw-in uses, so one keyframe animates any
   pill from an empty outline to fully drawn. */
.pill-stroke {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}
.pill-stroke rect {
  fill: none;
  stroke: var(--orange);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}
.hero-cue.is-drawing .pill-stroke rect {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: cooked-pill-draw .7s ease forwards;
}
@keyframes cooked-pill-draw {
  to { stroke-dashoffset: 0; }
}

/* ---------- info table ---------- */
.info {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border: 1.5px solid var(--orange);
  font-family: var(--sans);
  font-weight: 500;
  font-size: .85rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  line-height: 1.25;
  color: var(--orange-ink);
  text-align: center;
}
.info > * {
  padding: .6rem .5rem;
  border-left: 1.5px solid var(--orange);
  border-top: 1.5px solid var(--orange);
}
.info > .wide { grid-column: 1 / -1; border-top: 0; border-left: 0; }
.info > :nth-child(2) { border-left: 0; }
@media (max-width: 640px) {
  .info { font-size: .7rem; }
  .info > * { padding: .55rem .3rem; }
}

/* ---------- stamp ---------- */
.stamp {
  position: absolute;
  z-index: 20;
  width: 7.5rem;
  height: 7.5rem;
  display: block;
  color: var(--stamp-ink, var(--stamp));
  --stamp-rotate: -12deg;
  --stamp-scale: 1;
  border: 0;
  margin: 0;
  padding: 0;
  background: transparent;
  font: inherit;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  opacity: 0;
  transform: rotate(var(--stamp-rotate)) scale(var(--stamp-scale));
}
.stamp svg { width: 100%; height: 100%; display: block; overflow: visible; pointer-events: none; }

/* On the two round sticker designs, the ring of curved copy spins
   slowly and continuously around the fixed centre wordmark — the
   hexagon and ribbon designs have no ring, so this only ever targets
   the circular ones. */
.stamp-ring {
  transform-box: fill-box;
  transform-origin: center;
  animation: cooked-stamp-ring-spin 26s linear infinite;
}
@keyframes cooked-stamp-ring-spin {
  to { transform: rotate(360deg); }
}

/* A click cycles the sticker: lift off, swap the SVG, stamp back
   down at the new design's own angle/size (set via --stamp-rotate/
   --stamp-scale in stamp.js). Idle gets a slow, barely-there sway
   so the corner doesn't go completely static between clicks. */
.stamp.is-entering { animation: cooked-stamp-in .4s cubic-bezier(.2, 1.5, .4, 1) forwards; }
.stamp.is-idle { opacity: 1; animation: cooked-stamp-idle 6s ease-in-out infinite; }
.stamp.is-lifting { opacity: 1; animation: cooked-stamp-lift .16s ease-in forwards; }
.stamp.is-landing { opacity: 1; animation: cooked-stamp-land .38s cubic-bezier(.2, 1.5, .4, 1) forwards; }

@keyframes cooked-stamp-in {
  from { opacity: 0; transform: rotate(calc(var(--stamp-rotate) - 12deg)) scale(calc(var(--stamp-scale) * 1.7)); }
  to   { opacity: 1; transform: rotate(var(--stamp-rotate)) scale(var(--stamp-scale)); }
}
@keyframes cooked-stamp-idle {
  0%, 100% { transform: rotate(var(--stamp-rotate)) scale(var(--stamp-scale)); }
  50%      { transform: rotate(calc(var(--stamp-rotate) + 3deg)) scale(var(--stamp-scale)); }
}
@keyframes cooked-stamp-lift {
  to { opacity: 0; transform: rotate(calc(var(--stamp-rotate) + 8deg)) scale(calc(var(--stamp-scale) * 1.15)) translateY(-8px); }
}
@keyframes cooked-stamp-land {
  from { opacity: 0; transform: rotate(calc(var(--stamp-rotate) - 18deg)) scale(calc(var(--stamp-scale) * 1.6)); }
  to   { opacity: 1; transform: rotate(var(--stamp-rotate)) scale(var(--stamp-scale)); }
}

.masthead-foot .stamp { left: -5.5rem; top: -3rem; }

/* The info bar overlaps the bottom of the 3D shopfront on purpose
   (see index.html's .masthead-foot) — a solid backing keeps its
   text readable over whatever part of the model happens to be
   underneath, instead of legibility depending on the model's own
   colours at that point. */
.masthead-foot .info { background: var(--cream); }

@media (max-width: 640px) {
  .stamp { width: 5.25rem; height: 5.25rem; }
  .masthead-foot .stamp { left: -.5rem; top: -2.2rem; }
}

/* Small sticker badges pinned to a menu card's own corner (see
   .item, which sets position:relative + visible overflow so these
   can hang half off the card edge like something slapped on). */
.stamp--sm { width: 6.4rem; height: 6.4rem; }
.item-sticker--tr { right: -3rem; top: -3rem; }
.item-sticker--bl { left: -3rem; bottom: -3rem; }
.item-sticker--r { right: -3rem; bottom: -3rem; }
@media (max-width: 640px) {
  .stamp--sm { width: 5.2rem; height: 5.2rem; }
  .item-sticker--tr { right: -2.1rem; top: -2.1rem; }
  .item-sticker--bl { left: -2.1rem; bottom: -2.1rem; }
  .item-sticker--r { right: -2.1rem; bottom: -2.1rem; }
}

/* ---------- section title ---------- */
.section-title {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  margin: 0 0 1.75rem;
  font-weight: 650;
  font-size: clamp(2.25rem, 7vw, 3rem);
  line-height: 1;
  color: var(--orange);
  white-space: nowrap;
  text-transform: lowercase;
}
.section-title::before,
.section-title::after {
  content: "";
  flex: 1;
  border-top: 1.5px solid var(--orange);
}
.section { margin-top: 4.5rem; }
.section:first-child { margin-top: 0; }

/* ---------- menu grid ---------- */
.menu-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.75rem;
}
.menu-grid .item-card--featured { grid-column: 1 / -1; }

@media (max-width: 760px) {
  .menu-grid { grid-template-columns: 1fr; gap: 1.25rem; }
}

/* Groups a card (or a pair of cards) under a running label, e.g.
   "house special" over the featured card, "most popular" over the
   two-up pair — spans the full grid row regardless of column count. */
.menu-group-label {
  grid-column: 1 / -1;
  margin: 0;
  font-family: var(--sans);
  font-weight: 600;
  font-size: .85rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--orange-ink);
}
.menu-group-label:not(:first-child) { margin-top: .5rem; }
.menu-group-label.is-centered { text-align: center; }

/* Each letter is its own span carrying a --i index (written inline in
   the HTML); hovering the label scales every letter up with a colour
   shift, staggered by index so the effect ripples across the word
   instead of popping all at once. */
.menu-group-label span {
  display: inline-block;
  transition: transform .35s cubic-bezier(.2, 1.4, .4, 1), color .35s ease;
  transition-delay: calc(var(--i, 0) * 30ms);
}
.menu-group-label:hover span {
  transform: translateY(-.15em) scale(1.35);
  color: var(--orange);
}

/* ---------- menu item ---------- */
/* The card article and its .item-actions bar are DOM siblings inside
   this wrapper, not parent/child — .item-actions sits immediately
   after the article with zero gap, reading as one attached unit,
   while still being a separate element after (not inside) it. Flex
   column + the article's flex:1 below is what keeps .item-actions
   lined up across a stretched row of two-up cards: the article
   absorbs whatever extra height .menu-grid's row-stretch gives the
   card, and the actions bar (flex:none) just sits after however
   tall that turns out to be. */
/* isolation here (not on .item) so a card's sticker — a positioned
   descendant of .item with its own z-index — compares against its
   new sibling .item-actions within one predictable local context,
   instead of being trapped inside .item and losing to whatever
   paints after it. */
.item-card { display: flex; flex-direction: column; isolation: isolate; }
.item-card > .item { flex: 1 1 auto; }
.item-card > .item-actions { flex: none; }

.item {
  position: relative;
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas: "plate head" "body body";
  column-gap: 1.4rem;
  row-gap: 1rem;
  padding: 1.75rem;
  background-image: var(--grain);
  /* No bottom edge — .item-actions sits flush underneath with its
     own top border, so the card reads as one continuous outline
     instead of two 1.5px strokes stacked at the seam. */
  border: 1.5px solid var(--orange);
  border-bottom: none;
}

.item--featured {
  padding: 2rem 2.25rem;
  grid-template-columns: 6.5rem 1fr;
}
.item--featured .plate { width: 6.5rem; height: 6.5rem; }
@media (max-width: 640px) {
  .item--featured { padding: 1.5rem 1.35rem; grid-template-columns: 3.75rem 1fr; }
  .item--featured .plate { width: 3.75rem; height: 3.75rem; }
}

.plate {
  grid-area: plate;
  width: 5.5rem;
  height: 5.5rem;
  border: 1px solid var(--orange);
  border-radius: 22%;
  display: grid;
  place-items: center;
  flex: none;
}
.plate svg, .plate img { width: 100%; height: 100%; border-radius: 22%; display: block; object-fit: cover; }

.item-head { grid-area: head; align-self: center; min-width: 0; container-type: inline-size; }
.item-body {
  grid-area: body;
  display: flex;
  flex-direction: column;
  min-width: 0;
  container-type: inline-size;
}

.rating {
  margin-top: .35rem;
  font-size: 1.05rem;
  letter-spacing: .14em;
  color: var(--orange);
}

.line {
  display: flex;
  align-items: baseline;
  gap: .6rem;
  min-width: 0;
}
.dish {
  margin: 0;
  font-weight: 650;
  font-size: clamp(1.9rem, 5.5vw, 2.5rem);
  line-height: 1.05;
  color: var(--orange);
}
.leader {
  flex: 1;
  min-width: 1.5rem;
  height: 6px;
  background: radial-gradient(circle, var(--orange) 1.5px, transparent 2px) left center / 9px 6px repeat-x;
}
.price {
  font-weight: 650;
  font-size: clamp(1.6rem, 4.5vw, 2.1rem);
  line-height: 1;
  color: var(--orange);
  white-space: nowrap;
}

/* Inside a menu card, size the dish/price line off the card's own
   width (container query units) rather than the viewport — a
   featured full-width card and a narrow two-up card need different
   type scales at the very same viewport width. */
.item .dish { font-size: clamp(1.3rem, 11cqi, 2.5rem); }
.item .price { font-size: clamp(1.1rem, 9cqi, 2.1rem); }

/* The two-up cards are too narrow for the dish name, dotted leader
   and price to ever comfortably share one line at any type size —
   let the leader+price wrap to their own line under the dish name
   instead of squeezing the dish text into a mid-word wrap. */
@container (max-width: 220px) {
  .line { flex-wrap: wrap; row-gap: .15rem; }
  .line .dish { flex-basis: 100%; }
  .line .leader { display: none; }
}

.desc { margin: .6rem 0 0; max-width: 52ch; }
.note { margin: .3rem 0 0; font-style: italic; font-size: 1.05rem; }

.extra { margin-top: 1rem; }
.extra .name {
  font-weight: 600;
  font-size: 1.3rem;
  color: var(--orange-ink);
}
.extra .price { font-size: 1.3rem; color: var(--orange-ink); white-space: nowrap; }

/* A single bordered bar for the card's one action — same
   fill-from-bottom hover language as the footer's Support/Privacy/
   Terms links (.footer .info a), reused here so a card's own action
   reads as the same kind of thing. */
.item-actions {
  display: grid;
  grid-template-columns: 1fr;
  margin-top: 0;
  border: 1.5px solid var(--orange);
}

/* A button's width carries its own content's natural size instead of
   fixed padding inflating it, so the bar fills its row edge to edge —
   height is a fixed, generous tap target instead (roughly double a
   plain text-sized cell) since that isn't fighting the same "no
   wasted horizontal space" goal. */
.item-action {
  position: relative;
  z-index: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .3rem;
  min-width: 0;
  padding: 1.2rem .3rem;
  overflow: hidden;
  font-family: var(--sans);
  font-weight: 600;
  font-size: .8rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  text-align: center;
  text-decoration: none;
  color: var(--orange-ink);
  transition: color .25s ease .05s;
}
.item-action:not(:first-child) { border-left: 1.5px solid var(--orange); }
.item-action::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  background: var(--orange);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform .3s cubic-bezier(.4, 0, .2, 1);
}
.item-action:hover,
.item-action:focus-visible { color: var(--cream); }
.item-action:hover::before,
.item-action:focus-visible::before { transform: scaleY(1); }

@media (max-width: 640px) {
  .dish { font-size: 1.75rem; }
  .item { grid-template-columns: 3.75rem 1fr; column-gap: .9rem; row-gap: .85rem; padding: 1.35rem; }
  .plate { width: 3.75rem; height: 3.75rem; }
  .item-action { font-size: .72rem; }
}

/* ---------- button ---------- */
.btn {
  position: relative;
  display: inline-block;
  padding: .7rem 1.2rem .65rem;
  font-family: var(--sans);
  font-weight: 600;
  font-size: .9rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--btn-ink);
  background: var(--btn-fill);
  border: 1.5px solid var(--btn-fill);
  border-radius: 0;
  transform: translateY(0);
  box-shadow: 0 0 0 0 rgba(169, 52, 8, 0);
  transition: background-color .15s ease, color .15s ease,
    transform .28s cubic-bezier(.2, 1.4, .4, 1),
    box-shadow .28s cubic-bezier(.2, 1.4, .4, 1);
}
.btn:hover {
  background: var(--cream);
  color: var(--btn-fill);
  transform: translateY(-3px);
  box-shadow: 0 5px 0 0 var(--btn-fill);
}
.btn:active {
  transform: translateY(-1px);
  box-shadow: 0 2px 0 0 var(--btn-fill);
  transition-duration: .08s;
}

.text-link {
  font-family: var(--serif);
  font-weight: 600;
  color: var(--orange-ink);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 4px;
}
.text-link:hover { color: var(--rust); }

/* ---------- redacted row ---------- */
.redact {
  display: inline-block;
  width: 11rem;
  height: 1.5rem;
  border: 1.5px solid var(--orange);
  background: repeating-linear-gradient(-45deg, var(--orange) 0 4px, transparent 4px 9px);
  opacity: .6;
}
.redact.short { width: 7.5rem; }
@media (max-width: 640px) {
  .redact { width: 7rem; }
  .redact.short { width: 4.5rem; }
}

.soon-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.1rem; }
.soon-list .price { opacity: .6; }
.soon-copy { margin: 1.75rem 0 0; text-align: center; font-style: italic; }

/* ---------- bordered content block (in the oven / kitchen) ---------- */
.panel-block {
  padding: 1.75rem 2rem;
  background-image: var(--grain);
  box-shadow: inset 0 0 0 1.5px var(--orange);
}
@media (max-width: 640px) {
  .panel-block { padding: 1.35rem 1.25rem; }
}

/* ---------- kitchen / footer ---------- */
.kitchen p { margin: 0 auto; max-width: 44ch; text-align: center; }
.kitchen p + p { margin-top: 1rem; }

.footer { margin-top: 5rem; text-align: center; }
.signoff {
  margin: 0;
  font-style: italic;
  font-weight: 600;
  font-size: clamp(2.25rem, 8vw, 3.25rem);
  line-height: 1.05;
  color: var(--orange);
  text-transform: lowercase;
}
.footer .info { grid-template-columns: repeat(4, 1fr); max-width: 32rem; margin: 2rem auto 0; color: var(--orange-ink); }
.footer .info a {
  position: relative;
  z-index: 0;
  overflow: hidden;
  text-decoration: none;
  color: var(--orange-ink);
  transition: color .25s ease .05s;
}
.footer .info a::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  background: var(--orange);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform .3s cubic-bezier(.4, 0, .2, 1);
}
.footer .info a:hover,
.footer .info a:focus-visible { color: var(--cream); }
.footer .info a:hover::before,
.footer .info a:focus-visible::before { transform: scaleY(1); }
.footer .info > :first-child { border-left: 0; }
.footer .info > * { border-top: 0; }
.footer .info > :nth-child(2) { border-left: 1.5px solid var(--orange); }
.legal { margin: 1rem 0 0; font-size: .95rem; }

/* ---------- long-form legal copy (tasks 4-6) ---------- */
.content h2:not(.section-title) {
  margin: 3rem 0 1rem;
  font-weight: 650;
  font-size: clamp(1.5rem, 4vw, 1.9rem);
  color: var(--orange);
}
.content h2:not(.section-title):first-child { margin-top: 0; }
.content h3 {
  margin: 2rem 0 .75rem;
  font-weight: 600;
  font-size: 1.2rem;
  color: var(--rust);
}
.content p { margin: 1rem 0; }
.content a { color: var(--orange-ink); text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
.content a:hover { color: var(--rust); }

/* ---------- motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .stamp-ring { animation: none; }
  .stamp, .stamp.is-idle, .stamp.is-entering, .stamp.is-lifting, .stamp.is-landing {
    animation: none;
    opacity: 1;
    transform: rotate(var(--stamp-rotate)) scale(var(--stamp-scale));
  }
  .btn { transition: background-color .15s ease, color .15s ease; }
  .btn:hover, .btn:active { transform: none; box-shadow: none; }
  .pill { transition: background-color .15s ease, color .15s ease; }
  .hero-cue:hover, .hero-cue:active { transform: none; }
  .footer .info a::before { transition: none; }
  .item-action { transition: color .15s ease; }
  .item-action::before { transition: none; }
  .menu-group-label span { transition: color .15s ease; transition-delay: 0s; }
  .menu-group-label:hover span { transform: none; }
  .theme-toggle { transition: background-color .15s ease, color .15s ease; }
  .theme-toggle:hover, .theme-toggle:active { transform: none; }
}
