/* ==========================================================================
   Nana Bakery — tokens, hero, and the scroll stage
   ========================================================================== */

:root {
  --amande:   #E9E3D5;
  --ink:      #080808;

  --cocoa-1:  #D8CCCE;
  --cocoa-2:  #B2999E;
  --cocoa-3:  #8B666D;
  --cocoa-4:  #65333D;
  --cocoa-5:  #3E000C;

  --white:    #FFFFFF;
  --grey-1:   #E6E6E6;
  --grey-2:   #B4B4B4;
  --grey-3:   #6A6A6A;

  --font-display: "Taviraj", "Times New Roman", serif;
  --font-body:    "Poppins", system-ui, -apple-system, sans-serif;
  --font-script:  "Parisienne", "Snell Roundhand", cursive;

  --pad-x: clamp(22px, 8.2vw, 164px);

  /* how much scrolling the hero-to-about story takes */
  --stage-h: 250svh;

  --t-cake: 1500ms;
  --ease-out-soft: cubic-bezier(0.16, 1, 0.3, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body.nb-body {
  margin: 0;
  background: var(--amande);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  /* clip, never hidden: overflow-x:hidden here would turn <body> into a scroll
     container and stop .stage-sticky from sticking */
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

[hidden] { display: none !important; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
   STAGE
   ========================================================================== */

.stage {
  position: relative;
  z-index: 0;
  width: 100%;
  height: var(--stage-h);
}

.stage-sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  background: var(--amande);

  /* driven from hero.js on every scroll frame */
  --hero-fade: 1;
  --about-in: 0;
}

/* scroll target that lands the page on the about view without JS */
.stage-anchor {
  position: absolute;
  left: 0;
  bottom: 100svh;
  width: 1px; height: 1px;
}

.hero-glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(46% 40% at 50% 44%,
      rgba(250, 196, 126, 0.46) 0%,
      rgba(250, 196, 126, 0.26) 40%,
      rgba(250, 196, 126, 0.08) 66%,
      rgba(250, 196, 126, 0) 82%);
}

/* ==========================================================================
   NAVBAR
   ========================================================================== */

.nav {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 40;
  padding: clamp(22px, 3.4vh, 44px) var(--pad-x) 0;
  opacity: var(--hero-fade);
}

.is-hero-out .nav { pointer-events: none; }

.nav-inner { position: relative; display: flex; align-items: center; width: 100%; }

/* Centred masthead. It hangs from the nav line into the empty upper third of
   the hero, and sits in the gap the four spread links leave in the middle. */
.nav-logo {
  position: absolute;
  left: 50%;
  top: clamp(2px, 0.6vh, 10px);
  translate: -50% 0;
  width: clamp(62px, 7vw, 114px);   /* capped so the box clears the cakes at 1920 */
  pointer-events: none;

  /* lifted off the cream with two thin brand-tinted layers. A black shadow at
     this size just reads as a grey square behind the gold. */
  filter: drop-shadow(0 2px 6px rgba(101, 51, 61, 0.13))
          drop-shadow(0 10px 26px rgba(101, 51, 61, 0.10));
}

.nav-logo img { display: block; width: 100%; height: auto; }

.nav-menu {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  margin: 0; padding: 0;
  list-style: none;
}

.nav-link {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(13px, 1.05vw, 19px);
  letter-spacing: 0.04em;
  color: var(--ink);
  position: relative;
  padding-bottom: 4px;
}

.nav-link::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 420ms var(--ease-out-soft);
}

@media (hover: hover) {
  .nav-link:hover::after { transform: scaleX(1); }
}
.nav-link:focus-visible::after { transform: scaleX(1); }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  width: 34px; height: 34px;
  margin-right: 16px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.nav-toggle-line {
  display: block;
  width: 26px; height: 1.5px;
  background: var(--ink);
  transition: transform 320ms var(--ease-out-soft);
}

/* ==========================================================================
   VIEW 1 — HERO
   ========================================================================== */

.hero {
  position: absolute;
  inset: 0;
  z-index: 10;
  opacity: var(--hero-fade);
}

.is-hero-out .hero { pointer-events: none; }

.hero-word-wrap {
  position: absolute;
  z-index: 10;
  top: 48%;
  left: 0; right: 0;
  transform: translateY(-50%);
  display: flex;
  justify-content: center;
  padding: 0 12px;
  pointer-events: none;
}

.hero-word {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(3rem, 17.5vw, 26rem);
  line-height: 0.92;
  letter-spacing: -0.015em;
  color: var(--ink);
  white-space: nowrap;
}

.hero-word-line { display: inline-flex; align-items: baseline; }

.hero-caret {
  display: inline-block;
  width: 0.035em;
  height: 0.72em;
  margin-left: 0.03em;
  background: var(--ink);
  opacity: 0;
  transform: translateY(0.02em);
}

.hero-word.is-typing .hero-caret { animation: nb-blink 1s steps(1, end) infinite; }

@keyframes nb-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

/* --- language toggle, sits in the hero and fades with it --- */

.lang-toggle {
  position: absolute;
  z-index: 35;
  top: clamp(74px, 11vh, 122px);
  right: var(--pad-x);
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.lang-btn {
  padding: 2px 1px;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(12px, 0.95vw, 18px);
  letter-spacing: 0.07em;
  color: var(--ink);
  opacity: 0.42;
  transition: opacity 300ms ease;
}

.lang-btn.is-on { opacity: 1; }

@media (hover: hover) {
  .lang-btn:hover { opacity: 0.8; }
  .lang-btn.is-on:hover { opacity: 1; }
}

.lang-btn:focus-visible { outline: 2px solid var(--cocoa-4); outline-offset: 3px; opacity: 1; }

.lang-sep {
  font-family: var(--font-body);
  font-size: clamp(12px, 0.95vw, 18px);
  color: var(--ink);
  opacity: 0.28;
}

/* --- bottom row --- */

.hero-foot {
  position: absolute;
  z-index: 30;
  left: 0; right: 0;
  bottom: clamp(24px, 4.2vh, 56px);
  padding: 0 var(--pad-x);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: end;
  gap: 20px;
}

.hero-foot-text {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(14px, 1.35vw, 25px);
  line-height: 1.32;
  color: var(--ink);
  transition: color 300ms ease;
}

.hero-foot-left  { justify-self: start; text-align: left; }
.hero-foot-right { justify-self: end;   text-align: right; }

@media (hover: hover) {
  .hero-foot-text:hover { color: var(--cocoa-4); }
}

.hero-browse {
  justify-self: center;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 6px;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(12px, 0.9vw, 17px);
  letter-spacing: 0.08em;
  color: var(--ink);
  position: relative;
}

.hero-browse::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 420ms var(--ease-out-soft);
}

.hero-browse-arrow {
  display: inline-flex;
  width: 1.5em;
  transition: transform 420ms var(--ease-out-soft);
}

.hero-browse-arrow svg { width: 100%; height: auto; display: block; }

@media (hover: hover) {
  .hero-browse:hover::after { transform: scaleX(1); }
  .hero-browse:hover .hero-browse-arrow { transform: translateX(6px); }
}
.hero-browse:focus-visible::after { transform: scaleX(1); }

/* ==========================================================================
   VIEW 2 — ABOUT
   ========================================================================== */

.about-panel {
  position: absolute;
  inset: 0;
  z-index: 15;
  display: flex;
  pointer-events: none;
  opacity: var(--about-in);
}

.about-panel.is-live { pointer-events: auto; }

.about-inner {
  width: min(37vw, 760px);
  margin-left: auto;
  margin-right: var(--pad-x);
  padding: 11svh 0 7svh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 32px;

  /* slides the last few pixels into place as it fades in */
  transform: translateY(calc((1 - var(--about-in)) * 26px));
}

.about-lead {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(26px, 3.6vw, 72px);
  line-height: 1.16;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.about-sign { text-align: right; }

.about-quote {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(15px, 1.5vw, 30px);
  line-height: 1.3;
  color: var(--ink);
}

/* Signature mark. Two parts: a small letterspaced lead-in, then the name in the
   script face. `.brand-pre` carries the data-ms/data-en pair; the name is a
   proper noun and reads the same in both languages. */
.about-brand {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 0.5em;
  color: var(--grey-3);
}

.about-sign .about-brand { justify-content: flex-end; }

.brand-pre {
  font-family: var(--font-body);
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.brand-name {
  font-family: var(--font-script);
  font-weight: 400;
  letter-spacing: 0.005em;
}

.about-brand .brand-pre  { font-size: clamp(10px, 0.85vw, 16px); }
.about-brand .brand-name { font-size: clamp(22px, 2.1vw, 42px); line-height: 1.1; }

/* ==========================================================================
   CAKES — travel from the hero centre to the left edge
   ========================================================================== */

.cake-wrap {
  position: absolute;
  z-index: 20;

  /* The composite has an empty band between its two rows of cakes, from 38.5%
     to 57.8% of its own height. This `top` is set so that band lands on the
     background word instead of the word sitting behind the lower two cakes.
     Moving the word or reframing the bitmap means re-deriving it. */
  top: 49%; left: 50%;
  width: min(38vw, 67svh);
  transform: translate(-50%, -50%);
  will-change: translate;
  pointer-events: none;
}

.hero-cake {
  display: block;
  width: 100%;
  height: auto;
  transform-origin: 50% 50%;
  /* the bitmap carries its own baked shadow, so no CSS drop-shadow */

  /* start state: nothing on screen */
  opacity: 0;
  transform: scale(0.04) rotate(-200deg);
}

.hero-cake.is-in {
  opacity: 1;
  transform: scale(1) rotate(0deg);
  transition:
    opacity 520ms ease-out,
    transform var(--t-cake) var(--ease-out-soft);
}

.hero-cake.is-settled { animation: nb-float 7s ease-in-out infinite; }

@keyframes nb-float {
  0%, 100% { transform: translateY(0) scale(1) rotate(0deg); }
  50%      { transform: translateY(-12px) scale(1.012) rotate(-1.1deg); }
}

/* ==========================================================================
   ENTRANCE STAGGER — nav + foot arrive after the cakes land
   ========================================================================== */

.nav-logo,
.nav-menu > .nav-item,
.hero-foot > * {
  opacity: 0;
  transform: translateY(14px);
}

.is-ui-in .nav-logo,
.is-ui-in .nav-menu > .nav-item,
.is-ui-in .hero-foot > * {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 700ms ease-out, transform 700ms var(--ease-out-soft);
}

.is-ui-in .nav-logo { transition-delay: 0ms; }

.is-ui-in .nav-menu > .nav-item:nth-child(1) { transition-delay: 120ms; }
.is-ui-in .nav-menu > .nav-item:nth-child(2) { transition-delay: 190ms; }
.is-ui-in .nav-menu > .nav-item:nth-child(3) { transition-delay: 260ms; }
.is-ui-in .nav-menu > .nav-item:nth-child(4) { transition-delay: 330ms; }

.is-ui-in .hero-foot > *:nth-child(1) { transition-delay: 200ms; }
.is-ui-in .hero-foot > *:nth-child(2) { transition-delay: 300ms; }
.is-ui-in .hero-foot > *:nth-child(3) { transition-delay: 400ms; }

/* ==========================================================================
   POINTER FOLLOWER
   ========================================================================== */

.hero-cursor {
  position: fixed;
  z-index: 60;
  top: 0; left: 0;
  width: 124px; height: 124px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(233, 227, 213, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  font-family: var(--font-display);
  font-size: 19px;
  line-height: 1.28;
  text-align: center;
  color: var(--cocoa-5);
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.7);
  transition: opacity 380ms ease, transform 380ms var(--ease-out-soft);
}

.hero-cursor.is-visible { opacity: 1; transform: translate(-50%, -50%) scale(1); }

@media (hover: none), (pointer: coarse) {
  .hero-cursor { display: none; }
}

/* ==========================================================================
   KOLEKSI — horizontal rail

   A second tall track with its own sticky viewport. Vertical scroll is
   remapped onto a horizontal translate of .rail, so the strip travels right
   to left and finishes on the CTA. Item positions are expressed against
   --rail-w, so changing the rail length keeps every item's timing intact.
   ========================================================================== */

.rail-stage {
  /* rail-w must clear the LAST item's name label, not just its image, or the
     label's tail hangs into the closing CTA frame. With seven items the last
     image centres at 50vw + 7 * --slot-step, so this has to grow with the
     item count, and --show-h with it or the strip flies past. */
  --rail-w: 470vw;
  --item-w: 21vw;
  --slot-step: 40vw;         /* centre-to-centre spacing between items */

  /* where the two back-half text beats sit along the rail. The title runs out
     near slot 3, so these carry the rest of the way to the CTA. */
  --lead-x: 200vw;
  --stmt-x: 272vw;
  --stmt-size: 11vw;

  /* Total scroll for both acts: the rail travel, then the dot wipe. The rail
     act is the first half, so this stays at twice the travel to hold the
     one-screen-of-scroll-per-screen-of-rail pace. */
  --show-h: 740svh;

  /* written from hero.js each scroll frame */
  --dot: 0px;
  --photo: 0;
  --ui: 0;

  position: relative;
  z-index: 1;
  height: var(--show-h);
  background: var(--amande);
}

.rail-sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  background: var(--amande);
}

.rail {
  position: absolute;
  z-index: 1;
  top: 0; left: 0;
  width: var(--rail-w);
  height: 100%;
  will-change: translate;
}

/* --- the long headline --- */

.rail-title {
  position: absolute;
  top: 50%;
  left: calc(0.045 * var(--rail-w));
  transform: translateY(-50%);
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 14.4vw;
  line-height: 1;
  letter-spacing: -0.015em;
  color: var(--ink);
  white-space: nowrap;
}

/* --- back-half text beats ---

   .rail-lead drops into a gap between two top-row products, so it needs no
   z-index games. .rail-statement is display type on the same band as the title
   and is deliberately earlier in the DOM than the products, which paint over it.
   Neither is touched by hero.js: it only ever queries .rail-img. */

.rail-lead {
  position: absolute;
  top: 12%;
  left: var(--lead-x);
  width: min(30vw, 520px);
  margin: 0;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(13px, 1.15vw, 22px);
  line-height: 1.7;
  color: var(--grey-3);
}

.rail-statement {
  position: absolute;
  top: 50%;
  left: var(--stmt-x);
  transform: translateY(-50%);
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--stmt-size);
  line-height: 1;
  letter-spacing: -0.015em;
  color: var(--ink);
  white-space: nowrap;
}

/* --- product items --- */

.rail-item {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 1.75vw;

  /* `left` places the IMAGE, so each item centres on the viewport at an even
     beat. The name label overhangs to the right and is not part of the sum. */
  left: calc(50vw + var(--slot) * var(--slot-step) - var(--item-w) / 2);
}

.rail-item[data-slot="1"] { --slot: 1; }
.rail-item[data-slot="2"] { --slot: 2; }
.rail-item[data-slot="3"] { --slot: 3; }
.rail-item[data-slot="4"] { --slot: 4; }
.rail-item[data-slot="5"] { --slot: 5; }
.rail-item[data-slot="6"] { --slot: 6; }
.rail-item[data-slot="7"] { --slot: 7; }

.rail-item--top    { top: 8%; }
.rail-item--bottom { top: 58%; }

.rail-link { display: block; }

.rail-img {
  display: block;
  width: var(--item-w);
  height: auto;
  transform-origin: 50% 50%;
  transition: transform 420ms var(--ease-out-soft);
  /* hero.js sets `rotate` from how far the image sits from the viewport centre */
}

@media (hover: hover) {
  .rail-link:hover .rail-img { transform: scale(1.06); }
  .rail-link:hover ~ .rail-name { text-decoration: underline; text-underline-offset: 5px; }
}

.rail-link:focus-visible .rail-img { transform: scale(1.06); }

.rail-name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(15px, 1.8vw, 36px);
  line-height: 1.28;
  color: var(--ink);
  white-space: nowrap;
}

/* --- closing call to action --- */

.rail-cta {
  position: absolute;
  top: 50%;
  left: calc(var(--rail-w) - 50vw);
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding-bottom: 8px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: clamp(17px, 2.4vw, 48px);
  letter-spacing: 0.02em;
  color: var(--ink);
  white-space: nowrap;
}

.rail-cta::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 420ms var(--ease-out-soft);
}

.rail-cta-arrow {
  display: inline-flex;
  width: 1.1em;
  transition: transform 420ms var(--ease-out-soft);
}

.rail-cta-arrow svg { width: 100%; height: auto; display: block; }

@media (hover: hover) {
  .rail-cta:hover::after { transform: scaleX(1); }
  .rail-cta:hover .rail-cta-arrow { transform: translateX(8px); }
}
.rail-cta:focus-visible::after { transform: scaleX(1); }

@media (max-width: 900px) {
  .rail-stage {
    --rail-w: 585vw;
    --item-w: 46vw;
    --slot-step: 56vw;       /* tighter than desktop: seven items, narrow screen */
    --show-h: 745svh;
    --lead-x: 250vw;
    --stmt-x: 330vw;
    --stmt-size: 16vw;

    /* clear of the title, which is 10.1% tall and centred, plus breathing room */
    --rail-split: 7%;
  }

  .rail-lead { width: 52vw; font-size: clamp(12px, 3.1vw, 17px); line-height: 1.65; }

  .rail-title { font-size: 22vw; }

  /* name sits under the image instead of beside it. The image stays the item's
     first child at its left edge, so the centring maths is unchanged. */
  .rail-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 1.4vh;
  }

  /* Both rows are anchored to the centre line rather than to the top of the
     viewport: the upper row hangs its BOTTOM edge --rail-split above centre,
     the lower row puts its TOP edge the same distance below. Balance then holds
     whatever the item height works out to, which is what pinning both rows with
     `top` could not do: the title ended up with 10.7% of air above it and the
     lower row sitting 3.1% on top of it. */
  .rail-item--top    { top: auto; bottom: calc(50% + var(--rail-split)); }
  .rail-item--bottom { top: calc(50% + var(--rail-split)); }

  .rail-name { font-size: clamp(14px, 3.9vw, 22px); }

  .rail-cta { font-size: clamp(15px, 4.6vw, 26px); gap: 10px; }
}

/* ==========================================================================
   ULASAN — dot wipe, then a testimonial slider

   Act two of .rail-stage. The whole panel lives inside .testi-mask, which sits
   in the same sticky viewport as the rail and is clipped to a circle. The dot
   opens dead centre, which is exactly where the rail has just parked its CTA,
   so it appears to swallow that text and then the whole screen.
   ========================================================================== */

.testi-mask {
  position: absolute;
  z-index: 2;                 /* opens on top of the rail, CTA included */
  inset: 0;
  background: var(--ink);
  clip-path: circle(var(--dot) at 50% 50%);
}

/* scrolling to #reviews should land on the testimonial, not the rail */
.rail-stage > .stage-anchor {
  top: calc((var(--show-h) - 100svh) * 0.85);
  bottom: auto;
}

/* --- background photo --- */

/* the dot must read as solid black while it grows; the photo only arrives
   once it has covered the screen */
.testi-media { position: absolute; inset: 0; opacity: var(--photo, 0); }

.testi-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 28%;
  opacity: 0;
  transition: opacity 620ms ease;
}

.testi-photo.is-active { opacity: 1; }

/* keeps the white type legible over any of the three photos */
.testi-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom, rgba(8,8,8,0.62) 0%, rgba(8,8,8,0.34) 34%,
                               rgba(8,8,8,0.38) 68%, rgba(8,8,8,0.66) 100%);
}

/* --- overlaid UI --- */

.testi-ui {
  position: absolute;
  inset: 0;
  padding: clamp(26px, 5svh, 62px) var(--pad-x);
  color: var(--white);
  opacity: var(--ui);
  pointer-events: none;
}

.rail-stage.is-live .testi-ui { pointer-events: auto; }

.testi-head {
  position: absolute;
  top: clamp(26px, 5svh, 62px);
  left: var(--pad-x);
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(26px, 3.3vw, 66px);
  line-height: 1.18;
  color: var(--white);
}

.testi-quote {
  position: absolute;
  top: clamp(26px, 5svh, 62px);
  right: var(--pad-x);
  width: min(38vw, 760px);
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(19px, 2.6vw, 52px);
  line-height: 1.22;
  color: var(--white);
}

/* --- arrows: the only way through this section --- */

.testi-arrow {
  position: absolute;
  top: 30%;
  width: clamp(52px, 5vw, 78px);
  height: clamp(52px, 5vw, 78px);
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0);
  border-radius: 50%;
  background: none;
  color: var(--white);
  cursor: pointer;
  transition: border-color 320ms ease, background-color 320ms ease, transform 320ms var(--ease-out-soft);
}

.testi-arrow svg { width: 52%; height: auto; display: block; }

.testi-arrow--prev { left: calc(var(--pad-x) - 0.6vw); }
.testi-arrow--next { right: calc(var(--pad-x) - 0.6vw); }

@media (hover: hover) {
  .testi-arrow:hover {
    border-color: rgba(255, 255, 255, 0.75);
    background: rgba(255, 255, 255, 0.08);
  }
  .testi-arrow--prev:hover { transform: translateX(-3px); }
  .testi-arrow--next:hover { transform: translateX(3px); }
}

.testi-arrow:focus-visible {
  border-color: rgba(255, 255, 255, 0.9);
  outline: 2px solid rgba(255, 255, 255, 0.55);
  outline-offset: 4px;
}


/* --- attribution, counter, hint --- */

.testi-by {
  position: absolute;
  left: var(--pad-x);
  bottom: 34%;
}

.testi-name {
  margin: 0 0 2px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(17px, 1.75vw, 35px);
  line-height: 1.2;
  color: var(--white);
}

.testi-role {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(12px, 1.05vw, 21px);
  letter-spacing: 0.09em;
  color: rgba(255, 255, 255, 0.86);
}

.testi-count {
  position: absolute;
  left: 50%;
  bottom: 34%;
  transform: translateX(-50%);
  margin: 0;
  font-family: var(--font-body);
  font-size: clamp(12px, 1.05vw, 21px);
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.9);
  white-space: nowrap;
}

.testi-hint {
  position: absolute;
  right: var(--pad-x);
  bottom: clamp(22px, 4svh, 52px);
  margin: 0;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: clamp(11px, 0.85vw, 17px);
  letter-spacing: 0.09em;
  color: rgba(255, 255, 255, 0.9);
}

/* quote, name, role and counter all swap together, so they share one fade */
.testi-quote,
.testi-name,
.testi-role,
.testi-count { transition: opacity 260ms ease; }

.rail-stage.is-swapping .testi-quote,
.rail-stage.is-swapping .testi-name,
.rail-stage.is-swapping .testi-role,
.rail-stage.is-swapping .testi-count { opacity: 0; }

@media (max-width: 900px) {
  .testi-head { font-size: clamp(24px, 6.6vw, 40px); }

  .testi-quote {
    top: auto;
    bottom: 40%;
    right: var(--pad-x);
    left: var(--pad-x);
    width: auto;
    font-size: clamp(18px, 5.2vw, 30px);
  }

  .testi-arrow { top: auto; bottom: 12%; width: 50px; height: 50px;
                 border-color: rgba(255, 255, 255, 0.45); }

  .testi-by { bottom: 26%; }
  .testi-count { bottom: 26%; left: auto; right: var(--pad-x); transform: none; }

  .testi-hint { left: 0; right: 0; text-align: center; bottom: 5%; font-size: 11px; }
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

@media (max-width: 900px) {
  :root { --stage-h: 220svh; }

  .nav-toggle { display: flex; }

  /* the hamburger is the only navigation on small screens, so it does not
     fade out with the rest of the hero */
  .nav { opacity: 1; }
  .is-hero-out .nav { pointer-events: auto; }

  .nav-menu {
    position: fixed;
    inset: 0;
    z-index: 50;
    flex-direction: column;
    justify-content: center;
    gap: clamp(18px, 4vh, 40px);
    background: var(--amande);
    opacity: 0;
    visibility: hidden;
    transition: opacity 380ms ease, visibility 0s linear 380ms;
  }

  .nav-menu.is-open {
    opacity: 1;
    visibility: visible;
    transition: opacity 380ms ease, visibility 0s linear 0s;
  }

  .nav-menu > .nav-item { opacity: 1; transform: none; }
  .nav-logo { width: clamp(52px, 15vw, 78px); top: 0; }

  .nav-link { font-size: clamp(20px, 5.6vw, 30px); }

  .nav-toggle.is-open { position: relative; z-index: 60; }
  .nav-toggle.is-open .nav-toggle-line:nth-child(1) { transform: translateY(3.75px) rotate(45deg); }
  .nav-toggle.is-open .nav-toggle-line:nth-child(2) { transform: translateY(-3.75px) rotate(-45deg); }

  .cake-wrap { width: min(72vw, 46svh); top: 48%; }   /* same gap-on-word alignment as desktop */

  .lang-toggle { top: clamp(24px, 3.6vh, 46px); }

  .hero-word-wrap { top: 47%; }
  .hero-word { font-size: clamp(2.6rem, 17vw, 12rem); }

  .hero-cursor { display: none; }

  .hero-foot {
    grid-template-columns: 1fr;
    justify-items: center;
    gap: 18px;
    text-align: center;
  }

  .hero-foot-left,
  .hero-foot-right { justify-self: center; text-align: center; }

  .hero-browse { order: -1; font-size: 13px; }
  .hero-foot-text { font-size: clamp(14px, 3.6vw, 18px); }

  /* The cakes lift instead of sliding, so about stacks underneath them. This
     padding is tied to .cake-wrap's `top`: move the cakes down and the copy has
     to follow, or the lifted cakes land on the first line. */
  .about-inner {
    width: 100%;
    margin-left: 0;
    margin-right: 0;
    padding: 54svh var(--pad-x) 6svh;
    text-align: center;
    gap: 22px;
  }

  .about-lead { font-size: clamp(21px, 5.2vw, 34px); line-height: 1.28; }
  .about-sign { text-align: center; }
  .about-quote { font-size: clamp(15px, 3.7vw, 22px); }
  .about-brand { justify-content: center; }
  .about-sign .about-brand { justify-content: center; }
  .about-brand .brand-pre  { font-size: clamp(10px, 2.6vw, 14px); }
  .about-brand .brand-name { font-size: clamp(21px, 5.4vw, 32px); }
}

@media (max-width: 480px) {
  .cake-wrap { width: min(76vw, 42svh); }
  .hero-foot { bottom: 22px; gap: 14px; }
  .about-inner { padding-top: 51svh; }
}

/* ==========================================================================
   TEMPAH — pickup and delivery, with the four bakes cross-fading in the middle
   ========================================================================== */

.order-section {
  position: relative;
  z-index: 1;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: clamp(60px, 9svh, 120px) var(--pad-x);
  background:
    radial-gradient(52% 46% at 50% 56%,
      rgba(244, 206, 156, 0.72) 0%,
      rgba(246, 216, 174, 0.42) 40%,
      rgba(240, 224, 198, 0.16) 68%,
      rgba(233, 227, 213, 0) 84%),
    var(--amande);
}

.order-inner {
  width: min(70vw, 1300px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(30px, 5svh, 66px);
}

.order-head {
  margin: 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(30px, 4.3vw, 86px);
  line-height: 1.14;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* One grid for both columns so the left and right rows line up with each
   other, which a pair of independent flex columns would not guarantee. */
.order-grid {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-rows: auto repeat(3, 1fr);
  column-gap: clamp(18px, 3vw, 64px);
  row-gap: clamp(18px, 3.4svh, 48px);
  align-items: start;

  /* the reference spreads these rows down the viewport rather than bunching
     them around the loaf */
  min-height: clamp(300px, 48svh, 560px);
}

.order-label {
  grid-row: 1;
  margin: 0;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(11px, 1vw, 20px);
  letter-spacing: 0.08em;
  color: var(--grey-3);
}

.order-item {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(15px, 1.7vw, 34px);
  line-height: 1.28;
  color: var(--ink);
}

.order-label[data-col="l"],
.order-item[data-col="l"] { grid-column: 1; text-align: left; }

.order-label[data-col="r"],
.order-item[data-col="r"] { grid-column: 3; text-align: right; }

.order-item[data-row="2"] { grid-row: 2; }
.order-item[data-row="3"] { grid-row: 3; }
.order-item[data-row="4"] { grid-row: 4; }

/* --- the cross-fading bake --- */

.order-media {
  grid-column: 2;
  grid-row: 1 / -1;
  align-self: center;
  justify-self: center;
  position: relative;
  width: min(26vw, 420px);
  aspect-ratio: 1 / 1;
}

.order-bake {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  transition: opacity 900ms ease;
}

.order-bake.is-active { opacity: 1; }

/* --- call to action --- */

.order-cta {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 7px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: clamp(13px, 1.1vw, 22px);
  letter-spacing: 0.08em;
  color: var(--ink);
}

.order-cta::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 420ms var(--ease-out-soft);
}

.order-cta-arrow {
  display: inline-flex;
  width: 1.3em;
  transition: transform 420ms var(--ease-out-soft);
}

.order-cta-arrow svg { width: 100%; height: auto; display: block; }

@media (hover: hover) {
  .order-cta:hover::after { transform: scaleX(1); }
  .order-cta:hover .order-cta-arrow { transform: translateX(7px); }
}
.order-cta:focus-visible::after { transform: scaleX(1); }

@media (max-width: 900px) {
  .order-inner { width: 100%; gap: clamp(26px, 4svh, 44px); }

  .order-head { font-size: clamp(26px, 7.4vw, 44px); }

  .order-grid {
    grid-template-columns: 1fr;
    grid-template-rows: none;
    min-height: 0;
    row-gap: 14px;
    justify-items: center;
  }

  /* The desktop pins use class+attribute selectors, so a bare `.order-item`
     reset loses to them and every item stacks into the same cell. They have to
     be unpinned by selectors of the same weight. */
  .order-media,
  .order-label[data-col="l"],
  .order-label[data-col="r"],
  .order-item[data-col="l"],
  .order-item[data-col="r"],
  .order-item[data-row="2"],
  .order-item[data-row="3"],
  .order-item[data-row="4"] {
    grid-column: 1;
    grid-row: auto;
    text-align: center;
  }

  /* stacked reading order: bake, pickup list, delivery list */
  .order-media               { order: -1; width: min(58vw, 300px); margin-bottom: 10px; }
  .order-label[data-col="l"] { order: 0; }
  .order-item[data-col="l"]  { order: 1; }
  .order-label[data-col="r"] { order: 2; }
  .order-item[data-col="r"]  { order: 3; }

  .order-label { margin-top: 12px; }
  .order-item { font-size: clamp(15px, 4.2vw, 22px); }
}

/* ==========================================================================
   CTA E-MEL + JURNAL

   No pinned track here on purpose: the line has to sit right under the order
   section rather than a viewport away from it. Both the horizontal slide and
   the ink fill are driven from the line's own position in the viewport, so
   they advance together as it scrolls past.
   ========================================================================== */

.mail-section {
  position: relative;
  z-index: 1;
  padding: clamp(40px, 8svh, 110px) 0 clamp(26px, 4svh, 58px);
  background: var(--amande);
  overflow: clip;          /* the slide can never push the page sideways */

  /* written from hero.js each scroll frame */
  --fill: 0%;
  --mail-in: 0;
}

.mail-track {
  display: flex;
  justify-content: center;
  opacity: var(--mail-in);
}

.mail-link { display: block; }

.mail-fill {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.5rem, 6.8vw, 9.5rem);
  line-height: 1.08;
  letter-spacing: -0.015em;
  white-space: nowrap;

  /* the un-inked state, and the fallback if background-clip:text is missing */
  color: #D3C7B1;
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .mail-fill {
    background-image: linear-gradient(90deg,
      var(--ink) 0, var(--ink) var(--fill),
      #D3C7B1 var(--fill), #D3C7B1 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}

.mail-rule {
  display: block;
  width: min(70vw, 1300px);
  height: 1px;
  margin: clamp(18px, 3.5svh, 48px) auto 0;
  background: rgba(8, 8, 8, 0.34);
}

/* --- jurnal + footer share one pinned viewport --- */

.end-stage {
  position: relative;
  z-index: 1;
  height: 200svh;
  background: var(--amande);

  --slide: 100%;          /* written from hero.js each scroll frame */
}

.end-sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  background: var(--amande);
}

.journal-panel {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  padding: 0 var(--pad-x);
}

.journal-inner {
  width: min(70vw, 1300px);
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: clamp(24px, 4vw, 80px);
  align-items: start;
}

.journal-head {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(26px, 2.9vw, 58px);
  line-height: 1.18;
  color: var(--ink);
}

.journal-col {
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 2.4svh, 30px);
  padding-top: clamp(6px, 3.4svh, 46px);
}

.journal-note {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(13px, 1vw, 20px);
  line-height: 1.5;
  color: var(--grey-3);
}

.journal-form {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: clamp(14px, 2svh, 26px);
}

.journal-input {
  width: 100%;
  padding: 0 0 10px;
  border: 0;
  border-bottom: 1px solid rgba(8, 8, 8, 0.34);
  border-radius: 0;
  background: none;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(13px, 1.05vw, 21px);
  letter-spacing: 0.03em;
  color: var(--ink);
  transition: border-color 300ms ease;
}

.journal-input::placeholder { color: var(--grey-2); letter-spacing: 0.05em; }
.journal-input:focus { outline: none; border-bottom-color: var(--ink); }
.journal-input:user-invalid { border-bottom-color: var(--cocoa-4); }

.journal-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 11px;
  padding: 0 0 6px;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: clamp(12px, 1.05vw, 21px);
  letter-spacing: 0.05em;
  color: var(--ink);
}

.journal-btn::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 420ms var(--ease-out-soft);
}

.journal-btn-arrow {
  display: inline-flex;
  width: 1.25em;
  transition: transform 420ms var(--ease-out-soft);
}

.journal-btn-arrow svg { width: 100%; height: auto; display: block; }

@media (hover: hover) {
  .journal-btn:hover::after { transform: scaleX(1); }
  .journal-btn:hover .journal-btn-arrow { transform: translateX(7px); }
}
.journal-btn:focus-visible::after { transform: scaleX(1); }

.journal-msg {
  margin: 0;
  align-self: flex-end;
  text-align: right;
  font-family: var(--font-body);
  font-size: clamp(12px, 0.92vw, 18px);
  line-height: 1.45;
  color: var(--cocoa-4);
  min-height: 1.45em;
}

/* ==========================================================================
   FOOTER — slides in over the journal from the right edge
   ========================================================================== */

.site-footer {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--ink);
  color: var(--white);
  padding: clamp(26px, 5svh, 62px) var(--pad-x) clamp(20px, 3.4svh, 44px);
  translate: var(--slide) 0;
  will-change: translate;
}

.footer-grid {
  width: min(70vw, 1300px);
  height: 100%;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto 1fr auto auto;
  column-gap: clamp(20px, 3vw, 64px);
  row-gap: clamp(14px, 2.4svh, 34px);
}

.f-social { grid-area: 1 / 1; display: flex; flex-wrap: wrap; gap: clamp(10px, 1.4vw, 26px); align-items: start; }

.f-social a {
  font-family: var(--font-body);
  font-size: clamp(11px, 1.05vw, 21px);
  letter-spacing: 0.03em;
  color: var(--white);
  position: relative;
  padding-bottom: 3px;
}

.f-social a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 420ms var(--ease-out-soft);
}

@media (hover: hover) { .f-social a:hover::after { transform: scaleX(1); } }
.f-social a:focus-visible::after { transform: scaleX(1); }

.f-tag {
  grid-area: 1 / 2;
  margin: 0;
  text-align: right;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(19px, 2.3vw, 46px);
  line-height: 1.22;
  color: var(--white);
}

.f-contact { grid-area: 2 / 1; align-self: center; text-align: right; }
.f-hours   { grid-area: 2 / 2; align-self: center; text-align: right; }

.f-label {
  margin: 0 0 4px;
  font-family: var(--font-body);
  font-size: clamp(10px, 0.85vw, 17px);
  letter-spacing: 0.09em;
  color: rgba(255, 255, 255, 0.52);
}

.f-label:not(:first-child) { margin-top: clamp(12px, 2svh, 26px); }

.f-value {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(14px, 1.35vw, 27px);
  line-height: 1.4;
  color: var(--white);
}

.f-value a { position: relative; }

.f-value a::after {
  content: "";
  position: absolute;
  left: 0; bottom: -2px;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 420ms var(--ease-out-soft);
}

@media (hover: hover) { .f-value a:hover::after { transform: scaleX(1); } }
.f-value a:focus-visible::after { transform: scaleX(1); }

.f-name {
  grid-area: 3 / 1;
  align-self: end;
  margin: 0;
  color: var(--white);
}

.f-logo {
  display: block;
  width: clamp(74px, 7vw, 134px);
  height: auto;
  margin-bottom: clamp(14px, 2.2svh, 30px);
}

.f-name .brand-pre {
  display: block;
  margin-bottom: 0.5em;
  font-size: clamp(11px, 0.95vw, 19px);
  opacity: 0.62;
}

/* the script face carries long ascenders and a deep `y`, so it needs more room
   than the serif it replaced, both in size and in line box */
.f-name .brand-name {
  display: block;
  /* sized so "Creme & Crumb" stays on ONE line inside the footer's first grid
     column. At 6.4vw it needed 568px in a 482px column and broke after the
     ampersand, leaving it dangling. Wrapping is still the safety valve. */
  font-size: clamp(38px, 5.1vw, 100px);
  line-height: 1.12;
}

.f-pages {
  grid-area: 3 / 2;
  align-self: end;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: clamp(8px, 1.6svh, 22px);
  text-align: right;
}

.f-pages a {
  font-family: var(--font-body);
  font-size: clamp(11px, 0.95vw, 19px);
  letter-spacing: 0.07em;
  color: var(--white);
  text-decoration: underline;
  text-underline-offset: 5px;
  text-decoration-thickness: 1px;
  transition: opacity 300ms ease;
}

@media (hover: hover) { .f-pages a:hover { opacity: 0.62; } }

.f-copy {
  grid-area: 4 / 1 / 5 / 3;
  margin: 0;
  text-align: center;
  font-family: var(--font-body);
  font-size: clamp(10px, 0.85vw, 17px);
  letter-spacing: 0.07em;
  color: rgba(255, 255, 255, 0.72);
}

/* the ring that trails the pointer inside the footer */
.footer-cursor {
  position: fixed;
  z-index: 5;
  top: 0; left: 0;
  width: 78px; height: 78px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: 50%;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 26px;
  line-height: 1;
  color: var(--white);
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.7);
  transition: opacity 360ms ease, transform 360ms var(--ease-out-soft);
}

.footer-cursor.is-visible { opacity: 1; transform: translate(-50%, -50%) scale(1); }

@media (hover: none), (pointer: coarse) { .footer-cursor { display: none; } }

/* Both followers step aside over anything clickable. Written with .is-visible
   in the selector so it outranks the rule that turned them on, whatever order
   the two end up in. */
.hero-cursor.is-visible.is-muted,
.footer-cursor.is-visible.is-muted {
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.32);
}

@media (max-width: 900px) {
  .mail-section { padding-top: clamp(30px, 5svh, 60px); }
  .mail-fill { font-size: clamp(1.15rem, 7.3vw, 3.5rem); }
  .mail-rule { width: calc(100% - 2 * var(--pad-x)); }

  .journal-inner { grid-template-columns: 1fr; row-gap: clamp(20px, 3.4svh, 36px); width: 100%; }
  .journal-head { font-size: clamp(26px, 7.4vw, 40px); }
  .journal-col { padding-top: 0; }
  .journal-form { align-items: stretch; }
  .journal-btn { align-self: flex-end; }

  .end-stage { height: 180svh; }

  .site-footer { padding: clamp(20px, 3.4svh, 40px) var(--pad-x); }

  .footer-grid {
    width: 100%;
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto auto auto auto;
    row-gap: clamp(12px, 2svh, 22px);
    align-content: space-between;
  }

  .f-social { grid-area: auto; justify-content: center; }
  .f-tag     { grid-area: auto; text-align: center; font-size: clamp(19px, 5.6vw, 30px); }
  .f-contact { grid-area: auto; text-align: center; align-self: auto; }
  .f-hours   { grid-area: auto; text-align: center; align-self: auto; }
  .f-name    { grid-area: auto; text-align: center; align-self: auto; }
  .f-logo    { margin-left: auto; margin-right: auto; width: clamp(66px, 20vw, 100px); }
  .f-name .brand-name { font-size: clamp(34px, 12.4vw, 68px); }
  .f-pages   { grid-area: auto; align-items: center; text-align: center; align-self: auto;
               flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 14px; }
  .f-pages .f-label { width: 100%; margin: 0; }
  .f-copy    { grid-area: auto; }
  .f-label:not(:first-child) { margin-top: clamp(8px, 1.4svh, 16px); }
}

/* ==========================================================================
   HALAMAN MENU — one product per page, linked from the rail
   ========================================================================== */

.menu-top {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(22px, 4svh, 48px) var(--pad-x) 0;
}

.menu-back {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(12px, 1.05vw, 20px);
  letter-spacing: 0.04em;
  color: var(--ink);
  position: relative;
  padding-bottom: 4px;
}

.menu-back::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 420ms var(--ease-out-soft);
}

@media (hover: hover) { .menu-back:hover::after { transform: scaleX(1); } }
.menu-back:focus-visible::after { transform: scaleX(1); }

/* on a menu page the toggle is part of the header, not floating in a hero */
.lang-toggle--menu { position: absolute; top: 50%; right: var(--pad-x); transform: translateY(-30%); }

.menu-page {
  position: relative;
  padding: 0 var(--pad-x) clamp(50px, 9svh, 120px);
  background:
    radial-gradient(46% 32% at 50% 30%,
      rgba(250, 196, 126, 0.34) 0%,
      rgba(250, 196, 126, 0.14) 46%,
      rgba(233, 227, 213, 0) 78%);
}

.menu-title {
  margin: clamp(26px, 5svh, 62px) 0 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(32px, 5.4vw, 108px);
  line-height: 1.1;
  letter-spacing: -0.012em;
  color: var(--ink);
}

/* the shot rides up over the title, as in the reference */
.menu-shot {
  display: flex;
  justify-content: center;
  margin-top: clamp(-26px, -3.4svh, -12px);
}

.menu-img {
  /* the svh term only bites on short landscape viewports, where it keeps the
     size picker from being pushed just under the fold */
  width: min(42vw, 620px, 58svh);
  height: auto;
  display: block;
}

.menu-price {
  margin: clamp(-40px, -5svh, -20px) 0 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(34px, 5vw, 100px);
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.menu-col {
  width: min(70vw, 1300px);
  margin: clamp(40px, 7svh, 96px) auto 0;
}

.menu-lead,
.menu-note,
.menu-outro {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(13px, 1.05vw, 21px);
  line-height: 1.6;
  color: var(--grey-3);
}

/* --- spec grid --- */

.menu-specs {
  margin: clamp(28px, 5svh, 62px) 0 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: clamp(20px, 3vw, 64px);
  row-gap: clamp(22px, 4svh, 48px);
}

.spec { min-width: 0; }
.spec--r { text-align: right; }

.spec-l {
  margin: 0 0 5px;
  font-family: var(--font-body);
  font-size: clamp(11px, 0.95vw, 19px);
  letter-spacing: 0.07em;
  color: var(--grey-3);
}

.spec-v,
.spec dd {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(16px, 1.55vw, 31px);
  line-height: 1.3;
  color: var(--ink);
}

.spec-star { font-size: 0.9em; }

/* --- what's inside --- */

.menu-h2 {
  margin: clamp(44px, 8svh, 108px) 0 clamp(16px, 2.6svh, 32px);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(26px, 3.2vw, 64px);
  line-height: 1.16;
  color: var(--ink);
}

.menu-table-wrap { margin-top: clamp(28px, 5svh, 60px); }

.menu-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-display);
  font-weight: 400;
}

.menu-table th {
  padding: 0 0 12px;
  border-bottom: 1px solid rgba(8, 8, 8, 0.28);
  text-align: left;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(11px, 0.95vw, 19px);
  letter-spacing: 0.07em;
  color: var(--ink);
}

.menu-table .th-r { text-align: right; }

.menu-table td {
  padding: clamp(13px, 2.2svh, 22px) 0;
  border-bottom: 1px solid rgba(8, 8, 8, 0.14);
  font-size: clamp(14px, 1.35vw, 27px);
  line-height: 1.3;
  color: var(--ink);
}

.menu-table td:last-child { text-align: right; }

.menu-outro { margin-top: clamp(30px, 5svh, 64px); }

/* --- call to action --- */

/* --- size picker: sits under the big price and drives it --- */

.size-picker {
  margin: clamp(14px, 2.2svh, 30px) auto 0;
  width: min(70vw, 1300px);
  text-align: center;
}

.size-picker-label,
.addon-label {
  margin: 0 0 clamp(10px, 1.6svh, 18px);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(11px, 0.95vw, 19px);
  letter-spacing: 0.07em;
  color: var(--grey-3);
}

.size-options {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(8px, 0.9vw, 16px);
}

.size-btn,
.opt-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: clamp(10px, 1.5svh, 17px) clamp(16px, 1.7vw, 32px);
  border: 1px solid rgba(8, 8, 8, 0.22);
  border-radius: 999px;
  background: none;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(13px, 1.05vw, 21px);
  line-height: 1.2;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 260ms ease, background-color 260ms ease, color 260ms ease;
}

.size-btn-price,
.opt-btn-fee {
  font-family: var(--font-display);
  font-size: 0.92em;
  color: var(--grey-3);
  transition: color 260ms ease;
}

.size-btn.is-on,
.opt-btn.is-on {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--amande);
}

.size-btn.is-on .size-btn-price,
.opt-btn.is-on .opt-btn-fee { color: var(--amande); }

@media (hover: hover) {
  .size-btn:hover,
  .opt-btn:hover { border-color: var(--ink); }
}

.size-btn:focus-visible,
.opt-btn:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* --- sizing guide: a stacked row list, never a wide table --- */

.size-guide { margin-top: clamp(20px, 3.4svh, 40px); }

.size-row {
  display: flex;
  align-items: flex-start;
  gap: clamp(16px, 2.4vw, 44px);
  padding: clamp(16px, 2.6svh, 26px) 0;
  border-bottom: 1px solid rgba(8, 8, 8, 0.14);
}

.size-row:first-child { border-top: 1px solid rgba(8, 8, 8, 0.28); }

.size-row-main { flex: 1 1 auto; min-width: 0; }

.size-row-main strong {
  display: block;
  margin-bottom: 5px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(17px, 1.65vw, 33px);
  line-height: 1.25;
  color: var(--ink);
}

.size-row-main span {
  display: block;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(13px, 1.05vw, 21px);
  line-height: 1.6;
  color: var(--grey-3);
}

.size-row-price {
  flex: 0 0 auto;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(17px, 1.65vw, 33px);
  line-height: 1.25;
  color: var(--ink);
  white-space: nowrap;
}

/* --- special request --- */

.addon { margin-top: clamp(38px, 7svh, 90px); }

.addon-chips {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(8px, 0.9vw, 14px);
}

.addon-chip {
  padding: clamp(8px, 1.2svh, 13px) clamp(14px, 1.4vw, 26px);
  border: 1px solid rgba(8, 8, 8, 0.22);
  border-radius: 999px;
  background: none;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(12px, 0.95vw, 19px);
  line-height: 1.2;
  color: var(--grey-3);
  cursor: pointer;
  transition: border-color 260ms ease, background-color 260ms ease, color 260ms ease;
}

.addon-chip[aria-pressed="true"] {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--amande);
}

@media (hover: hover) {
  .addon-chip:hover { border-color: var(--ink); color: var(--ink); }
  .addon-chip[aria-pressed="true"]:hover { color: var(--amande); }
}

.addon-chip:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.addon-note {
  width: 100%;
  margin-top: clamp(12px, 1.8svh, 20px);
  padding: clamp(11px, 1.6svh, 18px) 0;
  border: 0;
  border-bottom: 1px solid rgba(8, 8, 8, 0.28);
  border-radius: 0;
  background: none;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(13px, 1.05vw, 21px);
  color: var(--ink);
}

.addon-note::placeholder { color: rgba(8, 8, 8, 0.38); }
.addon-note:focus { outline: none; border-bottom-color: var(--ink); }

/* the price a chip adds, shown on the chip itself */
.chip-fee {
  margin-left: 8px;
  font-family: var(--font-display);
  font-size: 0.95em;
  opacity: 0.72;
}

/* --- delivery --- */

.opt-group { margin-top: clamp(30px, 5.4svh, 66px); }

.opt-options {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(8px, 0.9vw, 14px);
}

.opt-note {
  margin: clamp(12px, 1.8svh, 20px) 0 0;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(12px, 0.95vw, 19px);
  line-height: 1.6;
  color: var(--grey-3);
}

/* --- running total --- */

.total {
  margin-top: clamp(30px, 5.4svh, 66px);
  padding-top: clamp(18px, 3svh, 34px);
  border-top: 1px solid rgba(8, 8, 8, 0.28);
}

.total-value {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(28px, 3.4vw, 68px);
  line-height: 1.05;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.total-break {
  margin: clamp(6px, 1svh, 12px) 0 0;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(12px, 0.95vw, 19px);
  line-height: 1.6;
  color: var(--grey-3);
}

.menu-cta {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin: clamp(38px, 7svh, 90px) auto 0;
  padding-bottom: 7px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: clamp(13px, 1.15vw, 23px);
  letter-spacing: 0.07em;
  color: var(--ink);
}

.menu-col { display: flex; flex-direction: column; align-items: stretch; }
.menu-cta { align-self: center; }

.menu-cta::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 420ms var(--ease-out-soft);
}

.menu-cta-arrow {
  display: inline-flex;
  width: 1.3em;
  transition: transform 420ms var(--ease-out-soft);
}

.menu-cta-arrow svg { width: 100%; height: auto; display: block; }

@media (hover: hover) {
  .menu-cta:hover::after { transform: scaleX(1); }
  .menu-cta:hover .menu-cta-arrow { transform: translateX(7px); }
}
.menu-cta:focus-visible::after { transform: scaleX(1); }

/* ==========================================================================
   404
   ========================================================================== */

.nf-page {
  min-height: 74svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: clamp(40px, 8svh, 110px) var(--pad-x) clamp(30px, 6svh, 80px);
}

.nf-logo { width: clamp(88px, 9vw, 150px); height: auto; display: block; }

.nf-code {
  margin: clamp(16px, 2.6svh, 30px) 0 0;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(11px, 0.95vw, 19px);
  letter-spacing: 0.3em;
  color: var(--grey-3);
}

.nf-title {
  margin: clamp(8px, 1.4svh, 16px) 0 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(30px, 4.4vw, 84px);
  line-height: 1.12;
  letter-spacing: -0.012em;
  color: var(--ink);
}

.nf-lead {
  margin: clamp(14px, 2.4svh, 28px) 0 0;
  width: min(56ch, 100%);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(13px, 1.05vw, 21px);
  line-height: 1.6;
  color: var(--grey-3);
}

.nf-actions {
  margin-top: clamp(24px, 4svh, 46px);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(10px, 1.2vw, 18px);
}

.nf-btn {
  padding: clamp(12px, 1.7svh, 18px) clamp(20px, 2.2vw, 40px);
  border: 1px solid rgba(8, 8, 8, 0.22);
  border-radius: 999px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: clamp(12px, 1vw, 20px);
  letter-spacing: 0.07em;
  color: var(--ink);
  transition: border-color 260ms ease, background-color 260ms ease, color 260ms ease;
}

.nf-btn--solid { border-color: var(--ink); background: var(--ink); color: var(--amande); }

@media (hover: hover) {
  .nf-btn:hover { border-color: var(--ink); }
  .nf-btn--solid:hover { background: transparent; color: var(--ink); }
}

.nf-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.menu-copy {
  margin: 0;
  padding: 0 var(--pad-x) clamp(26px, 4svh, 52px);
  text-align: center;
  font-family: var(--font-body);
  font-size: clamp(10px, 0.85vw, 17px);
  letter-spacing: 0.07em;
  color: var(--grey-3);
}

@media (max-width: 900px) {
  .menu-top { justify-content: flex-start; padding-top: clamp(18px, 3svh, 34px); }
  .menu-back { font-size: 12px; }
  .lang-toggle--menu { transform: translateY(-50%); }

  .menu-title { font-size: clamp(28px, 8.4vw, 52px); }
  .menu-img { width: min(76vw, 420px); }
  .menu-price { font-size: clamp(30px, 9vw, 56px); }

  /* The desktop overlaps are fixed pixels tuned for 78px title type and a 72px
     price. At mobile sizes those same pixels swallow a whole line, so the shot
     sat on the title and the price sat inside the image. Both are re-stated
     here against the smaller type rather than inherited. */
  .menu-shot { margin-top: 0; }
  .menu-price { margin-top: clamp(-12px, -1.4svh, -6px); }
  .menu-col { width: 100%; }

  .menu-specs { grid-template-columns: 1fr; row-gap: 22px; }
  .spec--r { text-align: left; }

  .menu-h2 { font-size: clamp(24px, 7vw, 38px); }
  .menu-table td { font-size: clamp(14px, 4vw, 20px); }
  .menu-cta { align-self: center; }

  .size-picker { width: 100%; }
  .size-btn { flex: 1 1 auto; padding: 12px 10px; font-size: clamp(12px, 3.5vw, 16px); }
  .size-options { gap: 8px; }

  /* the price column would squeeze the description on a narrow screen */
  .size-row { flex-direction: column; gap: 6px; }
  .size-row-price { font-size: clamp(16px, 4.6vw, 22px); }

  .addon-chip { font-size: clamp(11px, 3.2vw, 15px); }
  .chip-fee { margin-left: 6px; }
  .opt-btn { flex: 1 1 auto; padding: 11px 12px; font-size: clamp(11px, 3.2vw, 15px); }
  .total-value { font-size: clamp(26px, 8vw, 44px); }
}

/* ==========================================================================
   REDUCED MOTION
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .hero-cake,
  .hero-cake.is-in {
    opacity: 1;
    transform: scale(1) rotate(0deg);
    transition: none;
    animation: none;
  }

  .hero-cake.is-settled { animation: none; }

  .nav-menu > .nav-item,
  .hero-foot > * { opacity: 1; transform: none; transition: none; }

  .about-inner { transform: none; }

  .rail-img { rotate: none !important; }

  .testi-photo { transition: none; }
  .order-bake { transition: none; }

  /* no wipe or slide: the line is simply inked and present */
  .mail-section { --fill: 100%; --mail-in: 1; }

  /* the footer is simply in place, no slide */
  .end-stage { --slide: 0%; }
  .footer-cursor { display: none; }

  .hero-word.is-typing .hero-caret { animation: none; opacity: 0; }

  .hero-cursor { display: none; }
}
