/* Cik Gebu’s · site.css
   tokens · base · type · components · bands & edges · (header/footer · home · menu · tempah · hubungi
   added by later tasks) · motion (always last) */

/* ── tokens ─────────────────────────────────────────────────────────── */
:root {
  --sun: #FFC83D; --sun-deep: #F9B01C; --amber: #F29A1F;
  --cream: #FFF4DA; --paper: #FFFAF0;
  --choco: #4E2612; --choco-2: #7A3F1D;
  --berry: #E5534B; --blush: #F7A8A0;
  --berry-ink: #D4281F;   /* berry as text: 12% darker, 4.9:1 on paper (berry itself is 3.6:1) */
  --font-display: 'Fredoka', 'Baloo 2', ui-rounded, system-ui, sans-serif;
  --font-script: 'Oleo Script', 'Lobster Two', cursive;
  --font-body: 'Nunito', ui-rounded, system-ui, sans-serif;
  --wrap: 1160px;
  /* viewport-fit=cover lets a landscape iPhone run the page under its notch / Dynamic Island and round corners:
     the gutter grows to the safe area there (the insets are 0 everywhere else) */
  --gutter: max(clamp(16px, 4vw, 32px), env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  --band-y: clamp(64px, 9vw, 112px);
  --line: 3px;
  --header-h: 68px;
  --ease-pop: cubic-bezier(.34, 1.56, .64, 1);
}
@media (max-width: 759px) { :root { --header-h: 60px; } }

/* ── base ───────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body { margin: 0; background: var(--paper); color: var(--choco); font: 400 1.0625rem/1.65 var(--font-body); overflow-x: clip; }
img, svg { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; }
p { margin: 0 0 1em; }
:focus-visible { outline: 3px solid var(--choco); outline-offset: 3px; }
.nw { white-space: nowrap; }
.vh { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip { position: absolute; left: -999px; top: 10px; z-index: 100; padding: .6em 1em; background: var(--cream); border: var(--line) solid var(--choco); border-radius: 999px; font-weight: 800; }
.skip:focus { left: var(--gutter); }
.wrap { width: min(100% - 2 * var(--gutter), var(--wrap)); margin-inline: auto; }
.icon { width: 1em; height: 1em; fill: currentColor; flex: none; display: inline-block; vertical-align: -.125em; }

/* ── type ───────────────────────────────────────────────────────────── */
h1, h2, h3 { margin: 0; font-family: var(--font-display); font-weight: 700; line-height: 1.04; letter-spacing: .005em; text-wrap: balance; }
h1 { font-size: clamp(2.7rem, 7vw, 5.2rem); line-height: 1.14; } /* outlined + dropped: at 1.04 a descender touched the line below */
h2 { font-size: clamp(2.1rem, 4.4vw, 3.3rem); }
h3 { font-size: clamp(1.2rem, 1.8vw, 1.45rem); line-height: 1.15; }
.outline { color: var(--cream); -webkit-text-stroke: var(--stroke, .15em) var(--choco); paint-order: stroke fill; filter: drop-shadow(0 var(--drop, .07em) 0 var(--choco)); }
.eyebrow { margin: 0 0 .35rem; font: 400 clamp(1.3rem, 2.2vw, 1.6rem)/1.2 var(--font-script); color: var(--choco-2); }
.lead { font-size: clamp(1.1rem, 1.5vw, 1.25rem); max-width: 32em; text-wrap: pretty; } /* no one-word last line ("gebu.", "tersenyum.") */

/* ── components ─────────────────────────────────────────────────────── */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: .5em; min-height: 52px; padding: .75em 1.5em; border: var(--line) solid var(--choco); border-radius: 999px; font: 600 1.08rem/1 var(--font-display); text-decoration: none; cursor: pointer; transition: transform .25s var(--ease-pop), background-color .2s; }
.btn:hover { transform: translateY(-3px) rotate(-1.5deg); }
.btn:active { transform: scale(.95); }
.btn--choco { background: var(--choco); color: var(--cream); }
.btn--cream { background: var(--cream); color: var(--choco); }
.btn--wide { width: 100%; }
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }

.ribbon { position: relative; z-index: 0; display: inline-block; margin: 0 1.45em .9rem; padding: .22em 1em .32em; border: var(--line) solid transparent; font: 400 clamp(1rem, 4.5vw, 1.5rem)/1.2 var(--font-script); color: var(--choco); text-align: center; text-wrap: balance; }
.ribbon::before, .ribbon::after { content: ''; position: absolute; pointer-events: none; }
.ribbon::before { z-index: -1; inset: calc(-1 * var(--line)); background: var(--cream); border: var(--line) solid var(--choco); border-radius: 6px; }
/* tails: SVGs scale with the ribbon's real height (1, 2 or 3 lines) and keep the notch angle; the two
   gradients draw each tail's inner edge, which shows only in the fold under the body */
.ribbon::after { --t: 1.7em; z-index: -2; inset: .5em -1.35em -.5em;
  background: linear-gradient(var(--choco) 0 0) calc(var(--t) - var(--line)) 0 / var(--line) 100% no-repeat,
    linear-gradient(var(--choco) 0 0) right calc(var(--t) - var(--line)) top 0 / var(--line) 100% no-repeat,
    url("../img/ribbon-tail.svg") left / var(--t) 100% no-repeat, url("../img/ribbon-tail-r.svg") right / var(--t) 100% no-repeat; }

.sticker { position: relative; margin: 0; aspect-ratio: 1; background: #fff; border-radius: 50%; box-shadow: 0 0 0 var(--line) var(--choco); rotate: var(--tilt, 0deg); transition: rotate .45s var(--ease-pop), scale .45s var(--ease-pop); }
.sticker img { position: absolute; inset: 5.5%; width: 89%; height: 89%; object-fit: cover; border-radius: 50%; }
.sticker::after { content: ''; position: absolute; inset: 8.5%; border: 2px dashed rgba(255, 250, 240, .95); border-radius: 50%; pointer-events: none; }
a:hover .sticker, a:focus-visible .sticker { rotate: calc(var(--tilt, 0deg) * -1); scale: 1.04; }
.mascot { width: var(--m, 120px); height: auto; filter: drop-shadow(0 4px 0 rgba(78, 38, 18, .18)); }

.wa-pill { display: inline-flex; align-items: center; gap: .6em; padding: .28em 1.1em .28em .28em; background: var(--cream); border: var(--line) solid var(--choco); border-radius: 999px; color: var(--choco); font: 700 1.2rem/1 var(--font-display); letter-spacing: .02em; text-decoration: none; transition: transform .25s var(--ease-pop); }
.wa-pill:hover { transform: translateY(-2px) rotate(-1deg); }
.wa-pill__icon { display: grid; place-items: center; width: 2.2em; height: 2.2em; border-radius: 50%; background: var(--choco); color: var(--cream); }
.wa-pill__icon .icon { width: 1.05em; height: 1.05em; }
.wa-pill--sm { font-size: 1rem; }
.wa-float { position: fixed; right: calc(16px + env(safe-area-inset-right)); bottom: calc(16px + env(safe-area-inset-bottom)); z-index: 60; animation: bob 5s ease-in-out infinite; }
/* the float passes over every band, the choco footer included (where its choco ring vanished): a sun halo
   around the choco ring keeps one of the two visible on any background */
.wa-float:focus-visible { box-shadow: 0 0 0 9px var(--sun); }
/* Tempah and Hubungi carry their own WhatsApp buttons (the submit, the side and thank-you pills); there the float
   covered the fields on phones and the sticky side column at 900–1280, so it shows on Utama and Menu only (the 404
   page has its own pill too, which the float sat right beside on phones). On a recipe page it sat on the right end of
   the tick rows, where a tap meant for a tick opened WhatsApp, and on the Resipi collection it covered the first
   screen on an iPhone; the collection's own WhatsApp link is in its hero lead */
body:has(main .form, main .lost, main .recipe, main .recipe-list) .wa-float { display: none; }
@media (max-width: 559px) { .wa-float { padding-right: .28em; } .wa-float .wa-pill__num { display: none; } }

.chips { display: flex; flex-wrap: wrap; gap: 10px; }
.chip { position: relative; }
.chip input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.chip span { display: inline-block; padding: .55em 1.05em; background: var(--paper); border: 2.5px solid var(--choco); border-radius: 999px; font: 600 1rem/1 var(--font-display); transition: transform .2s var(--ease-pop), background-color .15s; }
.chip input:checked + span { background: var(--sun); transform: rotate(-2deg); }
.chip input:focus-visible + span { outline: 3px solid var(--choco); outline-offset: 3px; }

.stars { display: flex; gap: 3px; color: var(--berry); }
.stars .icon { width: 20px; height: 20px; }
.deco { position: absolute; left: var(--x); top: var(--y); width: var(--s, 22px); height: var(--s, 22px); fill: var(--c, var(--cream)); pointer-events: none; animation: twinkle 3.2s ease-in-out infinite var(--d, 0s); }

/* ── bands & edges ──────────────────────────────────────────────────── */
.band { position: relative; padding-block: var(--band-y); background: var(--bg); color: var(--fg, var(--choco)); }
.band--sun { --bg: var(--sun); }
.band--cream { --bg: var(--cream); }
.band--paper { --bg: var(--paper); }
.band--choco { --bg: var(--choco); --fg: var(--cream); }
/* on the dark bands and the chip bar the default choco ring vanished: there it is sun (8.4:1 on choco) */
.band--choco :focus-visible, .cat-nav :focus-visible { outline-color: var(--sun); }
/* the scallops are the band colour cut by an alpha mask: as a colour-to-transparent gradient, WebKit dotted every
   arc with near-black pixels (730 across the pages' light edges; 0 in Chromium) */
.edge-scallop::before { --scallop: radial-gradient(circle at 20px 20px, #000 19.5px, #0000 20.5px) 0 0 / 40px 20px repeat-x;
  content: ''; position: absolute; left: 0; right: 0; bottom: calc(100% - 1px); height: 20px; background: var(--bg); -webkit-mask: var(--scallop); mask: var(--scallop); pointer-events: none; }
.edge-drip::after { content: ''; position: absolute; z-index: 2; left: 0; right: 0; top: calc(100% - 1px); height: 64px; background: url("../img/drip.svg") 0 0 / 360px 64px repeat-x; pointer-events: none; }
.edge-drip + .band { padding-top: calc(var(--band-y) + 40px); }
.section-head { max-width: 40rem; margin: 0 auto clamp(32px, 5vw, 56px); text-align: center; }
.sunburst { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
/* --sx/--sy place the rays' centre. On the heroes --sy is a length that no text can move: as a % of the band's height
   the whole ray layer jumped whenever the web fonts reflowed the copy (first-load CLS 1.46 on Utama, 0.69 on Menu).
   A % is kept only where the box has a fixed size (the nav panel, which is the viewport) */
/* centred by left/top, not translate: while the rays spin, iOS Safari tested what they overlap with the untranslated
   box (the quarter right of and below the centre), so the copy above the centre (all of a page hero's, the nav
   panel's close button) stayed in the layer underneath the rays and showed through them, veiled */
.sunburst::before { content: ''; position: absolute; left: calc(var(--sx, 50%) - 75vmax); top: calc(var(--sy, 50%) - 75vmax); width: 150vmax; height: 150vmax; background: repeating-conic-gradient(var(--sun) 0deg 6deg, var(--sun-deep) 6deg 12deg); -webkit-mask: radial-gradient(closest-side, #000 19.2%, transparent 99.2%); mask: radial-gradient(closest-side, #000 19.2%, transparent 99.2%); animation: spin 140s linear infinite; }

/* ── header & nav ───────────────────────────────────────────────────── */
.site-header { position: sticky; top: 0; z-index: 50; background: var(--sun); transition: box-shadow .2s; }
.site-header.scrolled { box-shadow: 0 var(--line) 0 var(--choco); }
main { scroll-margin-top: var(--header-h); } /* skip link lands below the sticky header */
.site-header__in { display: flex; align-items: center; gap: 18px; height: var(--header-h); }
.brand { display: flex; align-items: center; gap: 10px; margin-right: auto; text-decoration: none; }
.brand img { width: 48px; height: 48px; transition: rotate .4s var(--ease-pop); }
.brand:hover img { rotate: -12deg; }
.brand__name { font: 700 1.55rem/1 var(--font-display); color: var(--choco); }
.nav { display: flex; gap: 6px; }
.nav a { padding: .45em .9em; border-radius: 999px; font: 600 1.08rem/1 var(--font-display); text-decoration: none; transition: background-color .2s; }
.nav a:hover { background: rgba(255, 250, 240, .6); }
.nav a[aria-current] { background: var(--cream); box-shadow: inset 0 0 0 2.5px var(--choco); } /* "page", or "true" on a recipe page */
.burger, .nav-panel__close { display: grid; place-items: center; width: 46px; height: 46px; padding: 0; background: var(--cream); border: var(--line) solid var(--choco); border-radius: 50%; color: var(--choco); cursor: pointer; }
.burger .icon, .nav-panel__close .icon { width: 22px; height: 22px; }
.burger { display: none; }
@media (max-width: 759px) {
  .nav, .nav-wa { display: none; }
  .burger { display: grid; }
  .brand img { width: 42px; height: 42px; }
  .brand__name { font-size: 1.35rem; }
}
/* five links + the WhatsApp pill need 806 px; the row is 699–835 px at 760–899, where the brand name broke onto
   two lines. There the pill keeps only its phone icon (a round button; the label stays for screen readers) and the
   links are a little narrower: 679 px in all */
@media (min-width: 760px) and (max-width: 899px) {
  .nav a { padding-inline: .75em; }
  .nav-wa { padding-right: .28em; }
  .nav-wa .wa-pill__num { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
/* taller content than the screen scrolls inside the panel (safe center: never clipped above the top) */
.nav-panel { position: fixed; inset: 0; z-index: 80; display: grid; place-content: center; place-content: safe center; justify-items: center; gap: 26px; padding: 32px; background: var(--sun); overflow-y: auto; overscroll-behavior: contain; --sx: 50%; --sy: 30%; }
.nav-panel[hidden] { display: none; }
.nav-panel > :not(.sunburst) { position: relative; z-index: 1; }
.nav-panel > .nav-panel__close { position: absolute; top: 10px; right: var(--gutter); }
.nav-panel__logo { width: 120px; height: 120px; rotate: -6deg; }
/* the stickers show the number, so each is a WhatsApp link (panel, hero, footer): a block box with a round focus ring */
.nav-panel__sticker-link { display: block; border-radius: 50%; }
.nav-panel nav { display: grid; gap: 6px; text-align: center; }
.nav-panel nav a { border-radius: .3em; font: 700 clamp(2.4rem, 12vw, 3.4rem)/1.15 var(--font-display); text-decoration: none; }
.nav-panel nav a[aria-current] { text-decoration: underline wavy var(--berry) 3px; text-underline-offset: 8px; }
.nav-open body { overflow: hidden; }
/* phones turned sideways: the single column (sticker, four links, pill) needs ~560px and was clipped top and bottom.
   The sticker stands beside the links and the pill instead; reading order is unchanged (sticker, links, pill) */
@media (orientation: landscape) and (max-height: 600px) {
  .nav-panel { grid-template-columns: auto auto; grid-template-areas: "logo nav" "logo pill"; gap: 16px clamp(32px, 7vw, 72px); align-items: center; padding-block: 16px; --sx: 32%; --sy: 50%; }
  .nav-panel__sticker-link { grid-area: logo; }
  .nav-panel__logo { width: min(150px, 38vh); height: auto; }
  .nav-panel nav { grid-area: nav; gap: 2px; }
  .nav-panel nav a { font-size: clamp(1.9rem, 11vh, 2.6rem); }
  .nav-panel > .wa-pill { grid-area: pill; }
}

/* ── footer ─────────────────────────────────────────────────────────── */
.site-footer { padding-block: clamp(56px, 8vw, 88px) 28px; }
@media (max-width: 559px) { .site-footer { padding-bottom: 96px; } }
.footer__grid { display: grid; gap: 36px; }
@media (min-width: 900px) { .footer__grid { grid-template-columns: 1.1fr 1.4fr .9fr .7fr; align-items: start; } }
/* below 900: Waktu + Laman side by side (2×2 with brand + CTA from 560) instead of one long column */
@media (max-width: 899px) { .footer__grid { grid-template-columns: 1fr 1fr; gap: 36px 24px; } }
@media (max-width: 559px) { .footer__brand, .footer__cta { grid-column: 1 / -1; } }
.footer__sticker-link { display: block; width: fit-content; border-radius: 50%; }
.footer__brand img { width: 104px; height: 104px; rotate: -6deg; transition: rotate .4s var(--ease-pop); }
.footer__sticker-link:hover img { rotate: -12deg; }
.footer__name { margin: .6rem 0 0; font: 700 1.7rem/1 var(--font-display); }
.footer__tag { margin: .15rem 0 0; font: 400 1.25rem/1.2 var(--font-script); color: var(--sun); }
.footer__big { margin: 0 0 16px; font: 700 clamp(1.9rem, 3.6vw, 2.6rem)/1.05 var(--font-display); color: var(--sun); text-wrap: balance; }
.footer__h { margin: 0 0 .6rem; font: 600 1.1rem/1 var(--font-display); color: var(--sun); }
.footer__grid p + .footer__h { margin-top: 1.6rem; } /* Kawasan under Waktu, in the same column */
.site-footer ul { display: grid; gap: .35rem; margin: 0; padding: 0; list-style: none; }
.footer__grid p { text-wrap: balance; } /* "Tempahan 24 jam di / WhatsApp" → "Tempahan 24 jam / di WhatsApp" */
.site-footer a:not(.wa-pill, .footer__sticker-link) { text-decoration: none; border-bottom: 2px solid rgba(255, 200, 61, .5); }
.footer__base { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 24px; margin-top: 44px; padding-top: 20px; border-top: 2px dashed rgba(255, 244, 218, .3); font-size: .95rem; }
.footer__base p { margin: 0; text-wrap: balance; } /* the demo line left "contoh." alone at 360–400 */

/* ── home ───────────────────────────────────────────────────────────── */
/* single column: the rays centre on the sticker, which sits first at the top of the band (padding + half its width) */
.hero { overflow: hidden; padding-block: clamp(24px, 5vw, 64px) clamp(72px, 9vw, 112px); --sx: 50%; --sy: calc(clamp(24px, 5vw, 64px) + min(74vw, 440px) / 2); }
.hero__in { position: relative; display: grid; gap: 28px; align-items: center; }
.hero__art { position: relative; order: -1; justify-self: center; width: min(74vw, 440px); aspect-ratio: 1; }
@media (min-width: 900px) {
  /* two columns: the sticker is centred on the copy column, whose height follows the fonts; the rays keep the
     spot the middle of the band had with the web fonts in (310 px at 900 → 347 px from 1280) */
  .hero { --sx: 76%; --sy: clamp(310px, 10vw + 215px, 347px); }
  .hero__in { grid-template-columns: 1.08fr .92fr; gap: 40px; }
  .hero__art { order: 0; width: min(100%, 440px); }
  /* the couplet on two lines, as on phones: at 5.2rem it broke "Segebu awan, / semanis / senyuman." in the 430–605px
     copy column. "semanis senyuman." is 8.74em, so the size follows the column (col / 8.8) up to 4.3rem */
  .hero h1 { font-size: min(6.1vw - 6.4px, 4.3rem); }
}
.hero__copy .lead { margin: 18px 0 26px; }
/* phones: sticker, headline and both CTAs in the first screen; the headline sized so it breaks as
   "Segebu awan, / semanis senyuman." (8.66em line) and the CTA pair fits one row from 354 px */
@media (max-width: 559px) {
  .hero { padding-top: 16px; --sy: calc(16px + min(68vw, 300px) / 2); }
  .hero__in { gap: 18px; }
  .hero__art { width: min(68vw, 300px); }
  .hero h1 { font-size: min(11.2vw - 3.5px, 2.9rem); }
  .hero__copy .lead { margin: 14px 0 22px; }
  .hero .btn-row { gap: 10px; }
  .hero .btn { padding-inline: 1.1em; font-size: 1rem; }
}
/* single-column hero: the two low decorations would land on the feature list, so they sit in the
   bottom padding strip instead */
@media (max-width: 899px) {
  .hero > .deco:nth-of-type(4) { top: auto; bottom: 34px; }
  .hero > .deco:nth-of-type(5) { top: auto; bottom: 30px; left: 62%; }
}
/* two-column hero: the left-hand decorations sit in the margin outside the copy (--edge = the wrap's
   left offset), and are dropped where that margin is too narrow; the top sparkle clears the ribbon */
@media (min-width: 900px) {
  .hero { --edge: max(var(--gutter), (100% - var(--wrap)) / 2); }
  .hero > .deco:nth-of-type(1), .hero > .deco:nth-of-type(4) { left: calc(var(--edge) - 44px); }
  .hero > .deco:nth-of-type(2) { left: calc(var(--edge) + 540px); }
}
@media (min-width: 900px) and (max-width: 1279px) {
  .hero > .deco:nth-of-type(1), .hero > .deco:nth-of-type(4) { display: none; }
}
.hero__sticker-link { display: block; border-radius: 50%; }
.hero__sticker { width: 100%; rotate: -5deg; animation: bob 6s ease-in-out infinite; filter: drop-shadow(0 10px 0 rgba(78, 38, 18, .16)); transition: rotate .45s var(--ease-pop); }
.hero__sticker-link:hover .hero__sticker { rotate: -1deg; }
.hero__art .mascot { position: absolute; animation: bob 5s ease-in-out infinite var(--d, 0s); }
.hero__feats { display: flex; flex-direction: column; gap: 8px; margin: 26px 0 0; padding: 0; list-style: none; font: 600 1rem/1.3 var(--font-display); }
.hero__feats li { display: flex; align-items: center; gap: .45em; }
.hero__feats .icon { color: var(--berry); }

.best__row { display: flex; justify-content: center; gap: clamp(16px, 2.2vw, 36px); margin: 0; padding: 12px 0 36px; list-style: none; }
.best__row li:nth-child(even) { translate: 0 28px; }
.best__row a { display: grid; justify-items: center; gap: 12px; width: clamp(150px, 15vw, 196px); text-align: center; text-decoration: none; }
.best__row .sticker { width: 100%; }
.best__name { font: 600 1.15rem/1.15 var(--font-display); }
.best__price { padding: .3em .8em; background: var(--sun); border: 2.5px solid var(--choco); border-radius: 999px; font: 700 .95rem/1 var(--font-display); rotate: -3deg; }
@media (max-width: 899px) {
  .best__row { justify-content: flex-start; overflow-x: auto; scroll-snap-type: x mandatory; margin-inline: calc(var(--gutter) * -1); padding-inline: var(--gutter); scrollbar-width: none; }
  .best__row li { flex: none; scroll-snap-align: center; }
  .best__row li:nth-child(even) { translate: 0 16px; }
  .best__row::-webkit-scrollbar { display: none; }
}
.best__more { margin: 40px 0 0; text-align: center; }
@media (max-width: 899px) { .best__more { margin-top: 20px; } }

.custom__in { display: grid; gap: clamp(32px, 5vw, 64px); align-items: center; }
@media (min-width: 900px) { .custom__in { grid-template-columns: .95fr 1.05fr; } }
.custom__picwrap { justify-self: center; width: min(100%, 520px); }
.custom__pic { --tilt: -3deg; }
.custom__copy .lead, .story__copy .lead { margin-top: 14px; }
.custom__pairs { display: grid; gap: 18px; margin: 26px 0 30px; padding: 0; list-style: none; }
.custom__pairs li { display: grid; grid-template-columns: 44px 1fr; gap: 14px; align-items: start; }
.custom__pairs h3 { margin-bottom: 2px; }
.custom__pairs p { margin: 0; }
.icon-badge { display: grid; place-items: center; width: 44px; height: 44px; background: var(--sun); border: 2.5px solid var(--choco); border-radius: 50%; }
.icon-badge .icon { width: 22px; height: 22px; }

.steps .eyebrow { color: var(--blush); }
.steps h2 { color: var(--sun); }
.steps__list { display: grid; gap: clamp(36px, 5vw, 48px); margin: 0; padding: 0; list-style: none; }
@media (min-width: 900px) { .steps__list { grid-template-columns: repeat(3, 1fr); } }
.step { display: grid; justify-items: center; align-content: start; gap: 12px; text-align: center; } /* start: a taller step no longer stretches the others' rows */
.step__num.outline { display: grid; place-items: center; width: 132px; height: 132px; background: var(--cream); border-radius: 50%; font: 700 5rem/1 var(--font-display); color: var(--sun); rotate: var(--tilt, -4deg); }
/* the numerals' outline is a ring of 16 text-shadows (.07em, what showed of the old .14em stroke), not
   -webkit-text-stroke: Fredoka's 2 and 3 have overlapping contours, and the stroke left a cream nick in the 3 and a
   curl inside the 2 in both engines. paint-order: normal because WebKit draws the shadows only with a stroke pass */
.step__num.outline { -webkit-text-stroke: 0; paint-order: normal;
  text-shadow: .07em 0 var(--choco), .0647em .0268em var(--choco), .0495em .0495em var(--choco), .0268em .0647em var(--choco), 0 .07em var(--choco), -.0268em .0647em var(--choco), -.0495em .0495em var(--choco), -.0647em .0268em var(--choco), -.07em 0 var(--choco), -.0647em -.0268em var(--choco), -.0495em -.0495em var(--choco), -.0268em -.0647em var(--choco), 0 -.07em var(--choco), .0268em -.0647em var(--choco), .0495em -.0495em var(--choco), .0647em -.0268em var(--choco); }
.step h3 { font-size: clamp(1.5rem, 2.4vw, 1.9rem); color: var(--cream); }
.step p { max-width: 20em; margin: 0; opacity: .92; }

.story__in { display: grid; gap: clamp(32px, 5vw, 64px); align-items: center; }
@media (min-width: 900px) { .story__in { grid-template-columns: 1.05fr .95fr; } }
.story__picwrap { justify-self: center; width: min(100%, 460px); }
.story__pic { --tilt: 4deg; }
.story__sign { margin: 1.2rem 0 0; font: 400 1.6rem/1.2 var(--font-script); color: var(--choco-2); }
.story__sign .icon { color: var(--berry); }

.quotes__list { display: grid; gap: clamp(36px, 5vw, 56px); margin: 0; padding: 0; list-style: none; }
@media (min-width: 900px) { .quotes__list { grid-template-columns: repeat(3, 1fr); } .quotes__list li:nth-child(2) { translate: 0 36px; } }
.quote { margin: 0; }
.quote blockquote { margin: 12px 0 14px; font: 500 clamp(1.3rem, 2vw, 1.5rem)/1.35 var(--font-display); }
.quote blockquote::before { content: '“'; display: block; height: .5em; font: 400 4.5rem/1 var(--font-script); }
.quote blockquote p { margin: 0; text-wrap: pretty; }
.quote figcaption b { font: 600 1.1rem/1 var(--font-display); }

/* ── menu ───────────────────────────────────────────────────────────── */
/* the sun rises from the band's lower edge: --sy is that edge's height with the web fonts in (the tallest title +
   lead, Hubungi's; 372 px on phones → 530 px from 1440), so the hub stays at or just under the edge on every page */
.page-hero { overflow: hidden; padding-block: clamp(36px, 6vw, 72px) clamp(56px, 8vw, 88px); text-align: center; --sx: 50%; --sy: clamp(23.25rem, 22vw + 14.875rem, 33.125rem); }
.page-hero__in, .page-hero .wrap { position: relative; }
.page-hero h1 { max-width: 13em; margin-inline: auto; }
/* below 375 the 2.7rem floor pushed "tersenyum." onto a third line of its own ("Pilih yang / buat anda / tersenyum."
   at 320 and 360): the size follows the screen so the longest title line, "anda tersenyum." (7.6em), still fits */
@media (max-width: 559px) { .page-hero h1 { font-size: min(2.7rem, 13vw - 4.2px); } }
.page-hero .lead { margin: 18px auto 0; text-wrap: balance; } /* greedy wrap left "ya!" alone at 375 */
.page-hero .mascot { position: absolute; animation: bob 5s ease-in-out infinite var(--d, 0s); }
@media (max-width: 899px) { .page-hero .mascot { display: none; } }
.cat-nav { position: sticky; top: var(--header-h); z-index: 40; padding-block: 10px; background: var(--choco); }
/* the 5px block padding (cancelled by the negative margin) keeps a focus ring inside the scroll box */
.cat-nav__list { display: flex; justify-content: flex-start; justify-content: safe center; gap: 8px; margin: -5px 0; padding: 5px var(--gutter); list-style: none; overflow-x: auto; scrollbar-width: none; }
.cat-nav__list::-webkit-scrollbar { display: none; }
.cat-nav a { display: block; padding: .5em 1em; border: 2.5px solid rgba(255, 244, 218, .35); border-radius: 999px; color: var(--cream); font: 600 1rem/1 var(--font-display); white-space: nowrap; text-decoration: none; transition: border-color .2s; }
.cat-nav a:hover { border-color: var(--cream); }
.cat-nav a:focus-visible { outline-offset: 2px; } /* sun ring: see .band--choco */
.cat-nav a[aria-current="true"] { background: var(--sun); border-color: var(--sun); color: var(--choco); }
/* jump targets clear the sticky header + chip bar (2rem + 25px tall): a category's band edge meets the bar
   (3px tucked under it, so no sliver of the previous band shows); an item lands 24px below it */
.cat { scroll-margin-top: calc(var(--header-h) + 2rem + 22px); }
.item { scroll-margin-top: calc(var(--header-h) + 2rem + 49px); }
/* deep links from the home best-sellers (menu.html#<id>): the target item only fades in (the browser aims
   at its box mid-reveal, so the 26px slide tucked it under the chip bar), and the jump is instant so WebKit
   can re-anchor it when the web fonts reflow the page */
.js .item.reveal:target { translate: none; scale: none; transition: opacity .6s ease; }
html:has(.item:target) { scroll-behavior: auto; }
.cat__head { display: flex; align-items: center; gap: clamp(14px, 3vw, 28px); margin-bottom: clamp(28px, 4vw, 44px); }
.cat__head .mascot { --m: clamp(84px, 12vw, 124px); flex: none; }
.cat__head p { margin: 6px 0 0; max-width: 34em; text-wrap: pretty; }
.cat__items { display: grid; gap: clamp(30px, 4vw, 44px) clamp(32px, 5vw, 72px); }
@media (min-width: 900px) { .cat__items { grid-template-columns: 1fr 1fr; } }
.item { display: grid; grid-template-columns: clamp(92px, 24vw, 148px) 1fr; gap: clamp(14px, 2.5vw, 26px); align-items: center; }
/* phones: the text runs 2–3× the photo's height, so a centred photo drifted away from its name */
@media (max-width: 559px) { .item { align-items: start; } .item__pic { margin-top: 4px; } }
/* name ····· price on one line only where the item body fits the longest head ("Kek Hari Jadi Bertema"
   + "dari RM120" + a real leader = 22.5rem at the largest name size); narrower bodies (phones, and the
   two-column range up to ~1180 px) stack the price under the name instead of squeezing the name into
   a wrapped box with a stub of dots. Stacked is the base, so it is also the no-container-query fallback. */
.item__body { min-width: 0; container-type: inline-size; }
.item__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
.item__name { flex: 0 1 auto; min-width: 0; font-size: clamp(1.2rem, 1.9vw, 1.45rem); }
.item__dots { display: none; flex: 1; min-width: 12px; border-bottom: 3px dotted var(--choco-2); translate: 0 -.25em; opacity: .7; }
.item__price { flex: none; width: 100%; margin: 0; font: 700 1.15rem/1 var(--font-display); white-space: nowrap; }
.item__price small { margin-right: 2px; font: 600 .8rem/1 var(--font-body); }
@container (min-width: 22.5rem) {
  .item__head { flex-wrap: nowrap; }
  .item__dots { display: block; }
  .item__price { width: auto; }
}
.item__desc { margin: 6px 0 8px; text-wrap: pretty; } /* no one-word last lines ("cair.", "lemon.") */
.item__order { display: inline-flex; align-items: center; gap: 6px; padding-bottom: 2px; border-bottom: 3px solid var(--sun-deep); font: 600 1.02rem/1 var(--font-display); text-decoration: none; }
.item__order:hover { border-color: var(--choco); }
.menu-cta { text-align: center; }
.menu-cta .lead { margin: 14px auto 26px; text-wrap: balance; } /* 14px: H2 descenders clear the lead, as on the home page */

/* ── tempah ─────────────────────────────────────────────────────────── */
/* the title is 12.2em on one line, so it fit the 13em hero measure from ~600 px and the hero mascots
   (≥900) sat on its first and last letters; 8em breaks it "Ceritakan kek / impian anda." (6.3em and
   5.7em), balanced or not, like the two-line menu title */
#tempah-h { max-width: 8em; }
.order__in { display: grid; gap: clamp(36px, 5vw, 64px); align-items: start; }
@media (min-width: 900px) {
  .order__in { grid-template-columns: 1.15fr .85fr; }
  .preview { position: sticky; top: calc(var(--header-h) + 24px); }
  .btn--wide { width: auto; justify-self: start; } /* the form grid stretched it to the column width regardless */
}
.order__title, .preview__h { margin-bottom: 4px; font-size: clamp(1.7rem, 3vw, 2.2rem); }
/* the form title gets 4px + the form's 26px gap; the preview title had only 4px, so its "j" touched the
   phone frame. 30px matches, and lines the phone up with the first field at ≥900 */
.preview__h { margin-bottom: 30px; }
.form { display: grid; gap: 26px; container-type: inline-size; }
.field { display: grid; gap: 8px; min-width: 0; margin: 0; padding: 0; border: 0; }
.field > label, .field > legend { padding: 0; margin-bottom: 8px; font: 600 1.12rem/1.2 var(--font-display); }
.field > label { margin-bottom: 0; }
.field[hidden] { display: none; }
.req { color: var(--berry-ink); }
.hint { margin: 0; font-size: .95rem; color: var(--choco-2); text-wrap: pretty; }
.form input[type=text], .form input[type=email], .form input[type=tel], .form input[type=date], .form select, .form textarea { width: 100%; min-height: 52px; padding: .7em .95em; background: #fff; border: 2.5px solid var(--choco); border-radius: 16px; color: var(--choco); font: 500 1.05rem/1.4 var(--font-body); }
.form textarea { min-height: 110px; resize: vertical; }
/* Safari drew the "cth. …" examples in #A9A9A9 (2.4:1 on white, lighter still on iOS): a warm brown at 5.2:1 that
   still reads lighter than typed text; opacity 1 because Firefox fades placeholders */
.form ::placeholder { color: #836759; opacity: 1; }
.form select { appearance: none; padding-right: 2.6em; background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6' fill='none' stroke='%234E2612' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right .9em center / 18px; }
/* iOS styles a native date field itself: unless its width is a fixed length it forces box-sizing: content-box (and its
   own padding, min-width, min-height), so width: 100% plus padding and border ran 21–37px past the form and the whole
   Tempah page could be dragged sideways. Without the native appearance it sizes like the other fields */
.form input[type=date] { appearance: none; }
/* fields: the sun-deep ring was 1.8:1 on paper. Now a choco ring (12.5:1) with a sun gap, so it never reads as a
   thicker border. WebKit's date field never matches :focus-visible (focus sits in its day/month/year parts) */
.form :is(input, select, textarea):focus-visible, .form input[type=date]:focus { outline: 3px solid var(--choco); outline-offset: 2px; box-shadow: 0 0 0 4px var(--sun); }
/* start: a pair with a hint under one field (No. telefon) stretched the other field, whose label and input rows
   then grew — the E-mel box stood 15px taller and lower than its neighbour */
.form-grid-2 { display: grid; gap: 26px; align-items: start; }
/* Saiz + Perisa side by side only where the form (not the viewport) fits "Pandan Gula Melaka": a 600px viewport
   rule also paired them in the 455px form column at 900–920, where the value was cut off */
@container (min-width: 30rem) { .form-grid-2 { grid-template-columns: 1fr 1fr; } }
.form-error, .form-status { margin: 0; padding: .8em 1em; background: #FDE3DF; border-radius: 14px; color: #8A1F18; font-weight: 700; }
/* the phone is choco behind its children and the chat wallpaper sits on .preview__chat: with the wallpaper on
   the phone, it showed as a light hairline where the choco bar is clipped to the rounded corners */
.preview__phone { overflow: hidden; border: var(--line) solid var(--choco); border-radius: 28px; background: var(--choco); }
.preview__bar { display: flex; align-items: center; gap: 10px; padding: 12px 16px; background: var(--choco); color: var(--cream); }
.preview__bar img { width: 36px; height: 36px; }
.preview__bar b { display: block; font: 600 1.05rem/1.1 var(--font-display); }
.preview__bar small { font-size: .8rem; opacity: .8; }
.preview__chat { min-height: 280px; padding: 18px 14px 22px; background: radial-gradient(rgba(78, 38, 18, .07) 1.2px, transparent 1.5px) 0 0 / 18px 18px, #F3E7D3; }
.bubble { position: relative; max-width: 92%; margin-left: auto; padding: 10px 12px 24px; background: #DCF8C6; border-radius: 14px 4px 14px 14px; color: #1F2C24; }
.bubble__text { margin: 0; font: 400 .98rem/1.45 var(--font-body); white-space: pre-wrap; overflow-wrap: anywhere; }
.bubble__meta { position: absolute; right: 10px; bottom: 5px; font-size: .72rem; color: #5B7A63; }
.preview__cap { margin: 12px 4px 0; font-size: .95rem; color: var(--choco-2); text-wrap: pretty; }
.faq { max-width: 46rem; }
.faq details { border-bottom: 2px dashed rgba(78, 38, 18, .25); }
.faq summary { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 18px 0; font: 600 clamp(1.1rem, 1.8vw, 1.3rem)/1.25 var(--font-display); cursor: pointer; list-style: none; text-wrap: balance; }
.faq summary::-webkit-details-marker { display: none; }
/* the plus is drawn, not typed: Fredoka's '+' was a 10px mark sitting low in the 34px disc (and a smudge as ×),
   and a typed '+' was read out as part of each question */
.faq summary::after { content: ''; flex: none; width: 34px; height: 34px; background: linear-gradient(var(--choco) 0 0) center / 15px 3px no-repeat, linear-gradient(var(--choco) 0 0) center / 3px 15px no-repeat, var(--sun); border: 2.5px solid var(--choco); border-radius: 50%; transition: rotate .3s var(--ease-pop); }
.faq details[open] summary::after { rotate: 45deg; }
.faq details p { max-width: 38em; margin: 0 0 18px; text-wrap: pretty; } /* balance/pretty: no one-word last lines ("tempah?", "udara.") */

/* ── hubungi ────────────────────────────────────────────────────────── */
/* on one line (10.9em) the title ran over both hero mascots from 900 to ~1300 px (the J on the cheesecake,
   "kami." on the bento); 7em breaks it "Jom borak / dengan kami.", two lines like the Menu and Tempah titles */
#hubungi-h { max-width: 7em; }
.contact__in { display: grid; gap: clamp(36px, 5vw, 64px); align-items: start; }
@media (min-width: 900px) { .contact__in { grid-template-columns: 1.2fr .8fr; } .contact__side { position: sticky; top: calc(var(--header-h) + 24px); } }
.contact__side h3 { margin: 26px 0 6px; }
.contact__side p { text-wrap: pretty; } /* no one-word last line ("bawah.") at 375 */
.contact__side .wa-pill { margin-top: 6px; }
.form[hidden] { display: none; } /* .form's display:grid beat the hidden attribute: the form stayed under the thank-you */
.hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
.form-status a { color: inherit; font-weight: 800; white-space: nowrap; } /* the number broke at its hyphen: "011-" / "39166294" */
/* hubungi.js scrolls the panel to the top of the screen: without the margin its title landed under the sticky header */
.contact-done { outline: none; scroll-margin-top: calc(var(--header-h) + 24px); }
.contact-done .lead { margin: 10px 0 0; } /* + the title's 4px = the 14px H2-to-lead gap used on Utama */
.contact-done [data-name] { overflow-wrap: anywhere; } /* an unbroken name (or an e-mail typed as one) widened the column past a phone screen */
.contact-done .btn-row { margin-top: 18px; align-items: center; }

/* ── 404 ────────────────────────────────────────────────────────────── */
/* two lines ("Halaman tak / dijumpai."), clear of the hero mascots like the other page titles */
#lost-h { max-width: 7em; }
.lost { text-align: center; }
.lost h2 { margin-bottom: 26px; }
.lost__links { justify-content: center; margin: 0 0 40px; padding: 0; list-style: none; }
.lost__wa { margin-bottom: 12px; }

/* ── resipi ─────────────────────────────────────────────────────────── */
/* phones: the size follows the screen so the title stays on two lines, "Dari dapur kami, / untuk dapur anda." —
   the longer line is 8.3em, so at the 2.7rem floor it broke into three from 375 px down */
@media (max-width: 559px) { #resipi-h { font-size: min(2.7rem, 11.8vw - 3.8px); } }
.resipi-hero .lead a { font-weight: 700; text-decoration-thickness: 2px; text-underline-offset: .18em; }
/* five stickers round the centred copy (none below 900, like the other page heroes). The copy leaves 190 px beside it
   at 900 and 295 px at 1280: up to 1099 four small ones hug the edges, from 1100 they are full size, and the whisk
   joins them in the inner ring from 1280 */
.resipi-hero__hat { --m: 96px; left: 3%; top: 12%; --d: -.8s; }
.resipi-hero__bowl { --m: 100px; left: 3%; top: 58%; --d: -1.6s; }
.resipi-hero__book { --m: 96px; right: 3%; top: 14%; --d: -2.8s; }
.resipi-hero__mitt { --m: 88px; right: 3%; top: 58%; --d: -1.1s; }
.resipi-hero__whisk { --m: 50px; left: 15%; top: 40%; --d: -2.2s; }
@media (min-width: 1100px) {
  .resipi-hero__hat { --m: 112px; left: 6%; }
  .resipi-hero__bowl { --m: 116px; left: 5%; }
  .resipi-hero__book { --m: 120px; right: 6%; top: 16%; }
  .resipi-hero__mitt { --m: 100px; right: 10%; top: 56%; }
}
@media (max-width: 1279px) { .resipi-hero .resipi-hero__whisk { display: none; } }

/* the collection: one entry per recipe, a big photo sticker (its mascot at the edge) beside the eyebrow, name, one-line
   intro and time · level. Stacked and centred on phones; from 760 px side by side, the sticker changing sides. The name
   is the entry's one link, stretched over the whole entry, so a tap on the photo opens the recipe too */
.recipe-list { padding-block: clamp(56px, 7vw, 96px) clamp(72px, 9vw, 120px); }
.recipe-list__items { display: grid; gap: clamp(64px, 9vw, 112px); margin: 0; padding: 0; list-style: none; }
.recipe-list__item { position: relative; display: grid; justify-items: center; gap: 26px; text-align: center; }
.recipe-list__art { position: relative; width: min(68vw, 300px); }
.recipe-list__art .sticker { width: 100%; }
.recipe-list__art .mascot { position: absolute; right: -9%; bottom: -5%; width: 34%; animation: bob 5s ease-in-out infinite var(--d, 0s); }
.recipe-list__item:nth-child(2) .mascot { --d: -1.7s; }
.recipe-list__item:nth-child(3) .mascot { --d: -3.3s; }
.recipe-list__text { max-width: 30rem; }
.recipe-list .eyebrow { margin-bottom: .1rem; }
.recipe-list h2 a { text-decoration: none; }
.recipe-list h2 a::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.recipe-list__intro { margin: 12px 0 0; font-size: clamp(1.08rem, 1.5vw, 1.2rem); text-wrap: pretty; }
.recipe-list__meta { display: inline-block; margin: 16px 0 0; padding: .32em .9em; background: var(--sun); border: 2.5px solid var(--choco); border-radius: 999px; font: 700 .95rem/1.15 var(--font-display); rotate: -2deg; }
.recipe-list__meta .icon { margin-right: 1px; }
.recipe-list__meta > span { white-space: nowrap; }
.recipe-list__meta > span + span::before { content: '· '; }
.recipe-list__go { display: flex; align-items: center; gap: 6px; width: fit-content; margin: 20px auto 0; padding-bottom: 3px; border-bottom: 3px solid var(--sun-deep); font: 600 1.1rem/1 var(--font-display); }
.recipe-list__item:hover .sticker, .recipe-list__item:has(a:focus-visible) .sticker { rotate: calc(var(--tilt, 0deg) * -1); scale: 1.04; }
.recipe-list__item:hover .recipe-list__go { border-color: var(--choco); }
@media (min-width: 760px) {
  .recipe-list__item { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); justify-items: start; align-items: center; gap: clamp(36px, 6vw, 88px); text-align: left; }
  .recipe-list__item:nth-child(even) .recipe-list__art { order: 1; }
  .recipe-list__art { justify-self: center; width: min(100%, 360px); }
  .recipe-list__go { margin-inline: 0; }
}

/* Resipi lain, under each recipe: the other recipes as a row of photo stickers with their time and level */
.recipe-more { padding-block: clamp(56px, 7vw, 88px) clamp(64px, 8vw, 104px); text-align: center; }
.recipe-more__row { display: flex; justify-content: center; gap: clamp(20px, 7vw, 88px); margin: 0; padding: 0 0 24px; list-style: none; }
.recipe-more__row li { flex: 0 1 220px; min-width: 0; }
.recipe-more__row li:nth-child(even) { translate: 0 24px; }
.recipe-more__row a { display: grid; justify-items: center; gap: 10px; text-decoration: none; }
.recipe-more__row .sticker { width: 100%; }
.recipe-more__name { font: 600 clamp(1.08rem, 1.8vw, 1.3rem)/1.15 var(--font-display); text-wrap: balance; }
.recipe-more__meta { padding: .32em .8em; background: var(--sun); border: 2.5px solid var(--choco); border-radius: 999px; font: 700 .92rem/1.15 var(--font-display); rotate: -3deg; }
.recipe-more__meta .icon { margin-right: 1px; }
.recipe-more__meta > span { white-space: nowrap; }
.recipe-more__meta > span + span::before { content: '· '; }
/* phones: two stickers side by side; the time and the level under the name on two short lines, no pill */
@media (max-width: 559px) {
  .recipe-more__row li:nth-child(even) { translate: 0 14px; }
  .recipe-more__meta { padding: 0; background: none; border: 0; rotate: none; font: 600 .9rem/1.3 var(--font-display); color: var(--choco-2); }
  .recipe-more__meta > span { display: block; white-space: normal; }
  .recipe-more__meta > span + span::before { content: none; }
}

/* a recipe's own page: the recipe is one cream band under the page hero, which carries its name */
.recipe { --bg: var(--cream); scroll-margin-top: var(--header-h); }
.recipe__in { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-areas: "head" "facts" "pics" "bahan" "cara" "tips" "cta"; gap: 36px; }
@media (max-width: 899px) { .recipe__in { max-width: 38rem; } }
/* the recipe opens with its mascot beside the intro */
.recipe__head { grid-area: head; display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: clamp(14px, 3vw, 24px); }
.recipe__head .mascot { --m: clamp(84px, 11vw, 118px); }
.recipe__intro { margin: 0; font-size: clamp(1.1rem, 1.5vw, 1.2rem); max-width: 34em; text-wrap: pretty; }
.recipe__facts { grid-area: facts; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 16px; margin: 0; }
.recipe__facts div { position: relative; min-height: 44px; padding-left: 56px; }
.recipe__facts .icon-badge { position: absolute; left: 0; top: 0; }
.recipe__facts dt { font: 700 .92rem/1.2 var(--font-body); color: var(--choco-2); }
.recipe__facts dd { margin: 3px 0 0; font: 600 1.12rem/1.2 var(--font-display); }
.recipe__facts small { display: block; margin-top: 2px; font: 500 .9rem/1.25 var(--font-body); color: var(--choco-2); }
/* phones: the round photo and the tilted flat-lay share one spot, the flat-lay stuck over the photo's lower right */
.recipe__pic, .recipe__flat { grid-area: pics; }
.recipe__pic { justify-self: start; width: 74%; }
.recipe__flat { z-index: 1; justify-self: end; width: 46%; margin-top: 44%; }
.recipe__pic .sticker, .recipe__flat .snap { width: 100%; }
/* the rounded-square sticker: photos that are not round (flat-lays, steps) — white die-cut edge, choco line, stitch */
.snap { position: relative; margin: 0; aspect-ratio: 1; background: #fff; border-radius: 12%; box-shadow: 0 0 0 var(--line) var(--choco); rotate: var(--tilt, 0deg); }
.snap img { position: absolute; inset: 5%; width: 90%; height: 90%; object-fit: cover; border-radius: 8%; }
.snap::after { content: ''; position: absolute; inset: 7.5%; border: 2px dashed rgba(255, 250, 240, .95); border-radius: 6%; pointer-events: none; }
.recipe h3 { margin-bottom: 4px; font-size: clamp(1.8rem, 3vw, 2.3rem); }
.recipe h4 { margin: 22px 0 4px; font: 600 1.2rem/1.2 var(--font-display); color: var(--choco-2); }
.recipe__bahan { grid-area: bahan; }
/* tick-as-you-go: native checkboxes drawn as round ticks; the whole line is the label, so a tap anywhere ticks it */
.ticks { margin: 0; padding: 0; list-style: none; }
.ticks li + li { border-top: 2px dashed rgba(78, 38, 18, .16); }
.ticks label { display: block; position: relative; padding: .55em 0 .55em 42px; line-height: 1.45; cursor: pointer; text-wrap: pretty; }
.ticks b { font-weight: 800; }
.ticks input { -webkit-appearance: none; appearance: none; position: absolute; left: 0; top: calc(.55em + .725em - 13px); width: 28px; height: 28px; margin: 0; font: inherit; background: #fff; border: 2.5px solid var(--choco); border-radius: 50%; cursor: pointer; transition: background-color .15s; }
.ticks label:hover input:not(:checked) { background-color: var(--cream); }
.ticks input:checked { background: var(--sun) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5.5 12.5l4.2 4.2L18.5 7.8' fill='none' stroke='%234E2612' stroke-width='3.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 18px no-repeat; animation: tick .35s var(--ease-pop); }
.ticks label:has(input:checked) { color: var(--choco-2); text-decoration: line-through 2px rgba(122, 63, 29, .55); }
.recipe__method { grid-area: cara; }
.recipe__cara { counter-reset: langkah; display: grid; gap: 28px; margin: 18px 0 0; padding: 0; list-style: none; container-type: inline-size; }
.recipe__cara > li { counter-increment: langkah; display: grid; grid-template-columns: 48px minmax(0, 1fr); column-gap: 14px; align-items: start; }
/* big outline numerals, drawn like the Cara Tempah ones on Utama (a ring of text-shadows, not a text stroke) */
.recipe__cara > li::before { content: counter(langkah); justify-self: center; margin-top: -2px; font: 700 2.7rem/1 var(--font-display); color: var(--sun); rotate: -5deg;
  text-shadow: .075em 0 var(--choco), .0693em .0287em var(--choco), .053em .053em var(--choco), .0287em .0693em var(--choco), 0 .075em var(--choco), -.0287em .0693em var(--choco), -.053em .053em var(--choco), -.0693em .0287em var(--choco), -.075em 0 var(--choco), -.0693em -.0287em var(--choco), -.053em -.053em var(--choco), -.0287em -.0693em var(--choco), 0 -.075em var(--choco), .0287em -.0693em var(--choco), .053em -.053em var(--choco), .0693em -.0287em var(--choco); }
.recipe__cara > li:nth-child(even)::before { rotate: 4deg; }
.recipe__cara p { margin: 0; text-wrap: pretty; }
.recipe__cara .snap { grid-column: 2; width: min(100%, 220px); margin-top: 16px; }
/* where the list is wide enough, a step's photo stands beside its text (the text keeps 260 px or more) */
@container (min-width: 32rem) {
  .recipe__cara > li { grid-template-columns: 56px minmax(0, 1fr) clamp(140px, 30%, 200px); column-gap: 18px; }
  .recipe__cara p { grid-column: 2 / -1; }
  .recipe__cara p:not(:last-child) { grid-column: 2; }
  .recipe__cara .snap { grid-column: 3; grid-row: 1; width: 100%; margin: 4px 0 0; }
}
.recipe__tips { grid-area: tips; }
.recipe__tips ul { display: grid; gap: 14px; margin: 6px 0 0; padding: 0; list-style: none; }
.recipe__tips li { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 10px; font: 500 clamp(1.1rem, 1.6vw, 1.22rem)/1.4 var(--font-display); text-wrap: pretty; }
.recipe__tips .icon { margin-top: .25em; color: var(--berry); }
.recipe__cta { grid-area: cta; padding-top: 36px; border-top: 2px dashed rgba(78, 38, 18, .2); text-align: center; }
.recipe__cta p { margin: 0 0 16px; font: 600 clamp(1.45rem, 2.6vw, 1.9rem)/1.2 var(--font-display); text-wrap: balance; }
@media (min-width: 900px) {
  /* two columns: the title and facts beside the round photo; then the flat-lay, ingredients and tips beside the steps.
     The tips row is the flexible one: it takes up whatever height the steps have beyond the left column (the tips stay
     at its top), so nothing on the left spreads out */
  .recipe__in { grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); grid-template-rows: auto auto auto auto 1fr auto;
    grid-template-areas: "head pic" "facts pic" "flat cara" "bahan cara" "tips cara" "cta cta"; gap: 40px clamp(40px, 5vw, 80px); }
  .recipe__tips { align-self: start; }
  .recipe__pic { grid-area: pic; align-self: center; justify-self: center; width: min(100%, 440px); }
  .recipe__flat { grid-area: flat; justify-self: center; width: min(88%, 340px); margin: 8px 0 0; }
  .recipe__facts { align-self: start; }
}

/* a recipe page's short sun hero: the trail back to the collection, the name, the subtitle, then the two big buttons
   (and the share panel they open) at the top of the page. The sun rises from its lower edge, as on the other page
   heroes: --sy is that edge with the web fonts in, 289 px at 480 → 394 px from 1280 with the buttons side by side,
   355–397 px below 480 where they stack */
.recipe-hero { padding-block: clamp(24px, 4vw, 44px) clamp(48px, 6vw, 72px); --sy: min(15.625rem + 12.1vw, 25.3rem); }
@media (max-width: 479px) { .recipe-hero { --sy: 23.25rem; } }
.trail ol { display: inline-flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 0 .45em; margin: 0 0 16px; padding: .3em 1.05em; list-style: none; background: var(--cream); border: 2.5px solid var(--choco); border-radius: 999px; font: 600 1rem/1.35 var(--font-display); }
.trail li + li::before { content: '›'; content: '›' / ''; margin-right: .45em; }
.trail a { text-decoration: underline 2px; text-underline-offset: .2em; }
.trail [aria-current] { color: var(--choco-2); }
.recipe-hero h1 { max-width: 12em; }
.recipe-hero__sub { margin: 10px auto 0; font: 500 clamp(1.2rem, 2.2vw, 1.55rem)/1.3 var(--font-display); text-wrap: balance; }
.share-bar { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: clamp(22px, 3vw, 30px); }
.share-bar .btn { min-height: 60px; padding-inline: 1.5em; font-size: 1.2rem; }
.share-bar .icon { width: 1.3em; height: 1.3em; }
.share-bar__share { flex: 1 1 auto; max-width: 19rem; }
/* phones: Kongsi resipi on a row of its own (it fit beside Cetak only from ~416 px, by a few px of type) */
@media (max-width: 479px) { .share-bar__share { flex-basis: 100%; } }
/* both buttons need JavaScript: without it the share panel's links show instead (and the browser's own Print) */
.share-bar [data-share], .share-bar [data-print] { display: none; }
.js .share-bar [data-share], .js .share-bar [data-print] { display: inline-flex; }
.js .share-panel:not(.is-open) { display: none; }
.share-panel { margin-top: 22px; }
.share-panel__h { margin: 0 0 12px; font: 600 1.05rem/1.2 var(--font-display); }
.share-panel__list { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px 8px; margin: 0; padding: 0; list-style: none; }
/* the four ways to share, one row: round sticker badges with the name under them (58 px badges in 76 px wide targets;
   "WhatsApp" is 72 px of type) */
.share-link { display: grid; justify-items: center; gap: 7px; width: 76px; margin: 0; padding: 4px 0; background: none; border: 0; border-radius: 16px; color: var(--choco); font: 600 .95rem/1.15 var(--font-display); text-align: center; text-decoration: none; cursor: pointer; }
.share-link__icon { display: grid; place-items: center; width: 58px; height: 58px; background: var(--cream); border: var(--line) solid var(--choco); border-radius: 50%; transition: rotate .3s var(--ease-pop), scale .3s var(--ease-pop); }
.share-link__icon .icon { width: 28px; height: 28px; }
.share-link:hover .share-link__icon, .share-link:focus-visible .share-link__icon { rotate: -8deg; scale: 1.06; }
.share-link:active .share-link__icon { scale: .94; }
@media (max-width: 359px) {
  .share-panel__list { column-gap: 6px; }
  .share-link { width: 67px; font-size: .86rem; }
  .share-link__icon { width: 54px; height: 54px; }
}
/* "Salin pautan" (needs JavaScript) is a pill of its own under them, drawn like the WhatsApp pills */
.share-panel__copy { display: none; flex-basis: 100%; justify-content: center; }
.js .share-panel__copy { display: flex; }
.share-link--copy { display: inline-flex; align-items: center; gap: .55em; width: auto; min-height: 50px; margin-top: 6px; padding: .3em 1.15em .3em .3em; background: var(--cream); border: var(--line) solid var(--choco); border-radius: 999px; font-size: 1.05rem; }
.share-link--copy .share-link__icon { width: 36px; height: 36px; background: var(--choco); border: 0; color: var(--cream); }
.share-link--copy .share-link__icon .icon { width: 20px; height: 20px; }
/* the address, shown selected where there is no clipboard to copy it to (the whole of it fits from 320 px) */
.share-panel__url:not([hidden]) { display: block; width: min(100%, 24rem); min-height: 48px; margin: 16px auto 0; padding: .6em .7em; background: #fff; border: 2.5px solid var(--choco); border-radius: 14px; color: var(--choco); font: 600 clamp(.78rem, 3.6vw, .9rem)/1.3 var(--font-body); text-align: center; }
.share-panel__note { min-height: 1.4em; margin: 12px 0 0; font: 700 1.05rem/1.3 var(--font-display); }

@media print {
  @page { margin: 12mm 14mm; }
  /* on every page: fixed and animated things never belong on paper */
  .wa-float, .nav-panel, .skip { display: none !important; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .js .reveal { opacity: 1; translate: none; scale: none; }
  /* a recipe page: one clean sheet, on white, with the ticks to fill in by pen. The buttons, the share panel, the trail
     and Resipi lain stay on screen; under the title the sheet says where the recipe came from (the hero's
     data-print-line, CSS text: it is no text node on the page) */
  body:has(.recipe) { background: #fff; font-size: 10.5pt; }
  body:has(.recipe) :is(.site-header, .site-footer, .sunburst, .trail, .share-bar, .share-panel, .recipe-more, .recipe__flat, .recipe__cara .snap, .recipe__cta) { display: none !important; }
  body:has(.recipe) .band { padding-block: 0; background: #fff; }
  body:has(.recipe) .edge-scallop::before { display: none; }
  body:has(.recipe) .wrap { width: auto; }
  body:has(.recipe) .recipe-hero { margin-bottom: 7mm; padding-bottom: 5mm; border-bottom: 1.5px dashed rgba(78, 38, 18, .35); text-align: left; }
  .recipe-hero h1 { max-width: none; font-size: 22pt; color: var(--choco); -webkit-text-stroke: 0; filter: none; }
  .recipe-hero__sub { margin: 1mm 0 0; font-size: 12pt; }
  .recipe-hero::after { content: attr(data-print-line); display: block; margin-top: 2mm; font: 800 10pt/1.3 var(--font-body); }
  .recipe__in { max-width: none; grid-template-columns: 60mm minmax(0, 1fr) 40mm; grid-template-rows: auto; gap: 5mm 8mm;
    grid-template-areas: "head head pic" "facts facts pic" "bahan cara cara" "tips cara cara" ". cara cara"; }
  .recipe__head .mascot { --m: 16mm; }
  .recipe__intro { font-size: 10.5pt; max-width: none; }
  .recipe__facts { grid-template-columns: repeat(4, auto); justify-content: start; gap: 3mm 7mm; }
  .recipe__facts div { min-height: 0; padding-left: 9mm; }
  .recipe__facts .icon-badge { width: 7mm; height: 7mm; border-width: 1.5px; print-color-adjust: exact; -webkit-print-color-adjust: exact; }
  .recipe__facts .icon-badge .icon { width: 4mm; height: 4mm; }
  .recipe__facts dt { font-size: 8.5pt; }
  .recipe__facts dd { font-size: 10.5pt; }
  .recipe__facts small { font-size: 8.5pt; }
  /* 1.5mm down: the photo's choco ring (a box-shadow outside its box) crossed the page break, and a sliver of it
     showed at the foot of the previous sheet */
  .recipe__pic { grid-area: pic; align-self: start; justify-self: end; width: calc(100% - 1.5mm); margin: 1.5mm 1mm 0 0; }
  .recipe h3 { font-size: 14pt; }
  .recipe h4 { margin: 3mm 0 0; font-size: 11pt; }
  .ticks li + li { border-top-width: 1px; }
  .ticks label { padding: 1.2mm 0 1.2mm 7mm; line-height: 1.3; }
  .ticks input { top: calc(1.2mm + .65em - 2.25mm); width: 4.5mm; height: 4.5mm; border-width: 1.5px; print-color-adjust: exact; -webkit-print-color-adjust: exact; }
  .ticks input:checked { background-size: 3.2mm; }
  .recipe__cara { gap: 3mm; margin-top: 2mm; }
  .recipe__cara > li { grid-template-columns: 9mm minmax(0, 1fr); column-gap: 3mm; break-inside: avoid; }
  .recipe__cara > li::before { margin-top: 0; font-size: 15pt; color: var(--choco); text-shadow: none; }
  .recipe__cara p { grid-column: 2; line-height: 1.45; }
  .recipe__tips ul { gap: 2mm; margin-top: 1mm; }
  .recipe__tips li { grid-template-columns: 4mm minmax(0, 1fr); gap: 2mm; font-size: 10pt; }
  .recipe .eyebrow { font-size: 12pt; }
}

/* ── motion (keep last) ─────────────────────────────────────────────── */
@keyframes spin { to { rotate: 360deg; } }
@keyframes bob { 50% { translate: 0 -10px; } }
@keyframes twinkle { 50% { scale: .55; opacity: .55; } }
@keyframes tick { 50% { scale: 1.2; } }
@keyframes pop-open { from { opacity: 0; scale: .94; } }
.share-panel.is-open { animation: pop-open .35s var(--ease-pop); }
.js .reveal { opacity: 0; translate: 0 26px; scale: .97; transition: opacity .6s ease, translate .7s var(--ease-pop), scale .7s var(--ease-pop); transition-delay: var(--delay, 0s); }
.js .reveal.in { opacity: 1; translate: 0 0; scale: 1; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .js .reveal { opacity: 1; translate: none; scale: none; }
}
