/* Material 3 Expressive layer (live since 2026-09-23; designed in mockup/m3e/, rounds 7-9).
   Loaded after style.css + theme.css on the nine public pages only (not admin.html).
   Keeps Sweet Sip's pink/mint/cocoa, Outfit + Geist, the 3D can and the card scallop. */

/* ---------- Tokens ---------- */
:root {
  /* Tonal containers: M3's "container" roles in Sweet Sip hues. Text on them is
     --cocoa (≥9:1 light, ≥6:1 for 0.75 muted text in dark, computed). */
  --m3-primary-container: #ffd9df;   /* pink  */
  --m3-secondary-container: #cdebd8; /* mint  */
  --m3-tertiary-container: #fbe3c6;  /* the combo amber already used for its icon */
  --m3-surface-high: rgba(var(--surface-rgb), 0.94);
  --m3-surface-container: #fbf1ee; /* nav region: a warm tone of the cream surface */
  --m3-surface-container-high: #f6e9e4; /* text fields, choice cards */
  --m3-state: rgba(var(--ink-rgb), 0.08);        /* hover state layer */
  --m3-state-press: rgba(var(--ink-rgb), 0.12);

  /* Shape scale (M3 + Expressive extra-extra-large) */
  --m3-s: 8px;
  --m3-m: 14px;
  --m3-l: 20px;
  --m3-xl: 28px;
  --m3-xxl: 40px;

  /* Springs as CSS linear() curves, sampled from M3's motion tokens.
     fast spatial ≈ stiffness 800, damping ratio 0.6 (visible overshoot);
     default spatial ≈ stiffness 380, ratio 0.8 (a small settle). Colour and
     opacity never use these: effects stay on --ease-out. */
  --m3-spring-fast: linear(0, 0.22 6%, 0.62 14%, 0.96 23%, 1.1 31%, 1.12 36%, 1.08 44%, 1.01 56%, 0.985 66%, 1);
  --m3-spring: linear(0, 0.16 7%, 0.52 17%, 0.83 28%, 1 40%, 1.03 50%, 1.015 64%, 1);
  --m3-fast: 380ms;
  --m3-default: 520ms;
}

@media (prefers-color-scheme: dark) {
  :root {
    --m3-primary-container: #4a2330;
    --m3-secondary-container: #1e3a2b;
    --m3-tertiary-container: #43301a;
    --m3-surface-container: #2d221d;
    --m3-surface-container-high: #3b2d27;
  }
}

/* ---------- Type: emphasized display + headline ---------- */
.hero h1 {
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.02;
}
@media (min-width: 861px) {
  .hero h1 { font-size: min(clamp(2.6rem, 5.4vw, 4.3rem), 9vh); }
}
@media (max-width: 860px) {
  .hero h1 { font-size: clamp(2.3rem, 9.5vw, 3.2rem); }
}
/* A tonal highlight on the key phrase, the M3E marketing move.
   A rounded pill behind the words only: an inline-block (the phrase never
   splits) with the fill on ::before, inset to the glyphs so it can't reach
   the lines above or below. It grows in from the left once, on the spring.
   (A plain inline background filled the font's ~1.25em content box, taller
   than the 1.02 line box, and spilled onto the neighbouring lines.) */
.m3-hl {
  position: relative;
  isolation: isolate;
  display: inline-block;
  padding: 0 0.12em;
  margin: 0 -0.12em;
}
.m3-hl::before {
  content: '';
  position: absolute;
  inset: 0.1em 0 0.05em;
  z-index: -1;
  border-radius: 0.28em;
  background: var(--m3-secondary-container); /* mint on the pink end: echoes the logo split */
  transform-origin: left center;
}
@media (prefers-reduced-motion: no-preference) {
  .m3-hl::before { animation: hlGrow 800ms var(--m3-spring) 450ms both; }
}
@keyframes hlGrow { from { transform: scaleX(0); } }

.section-head h2,
.section-head h1 {
  font-weight: 700;
  font-size: clamp(2rem, 4.2vw, 3rem);
  letter-spacing: -0.03em;
  line-height: 1.05;
}

/* ---------- Header: nav with an M3 active-indicator pill ---------- */
.main-nav { gap: 4px; }
.main-nav a {
  margin: 0;
  padding: 10px 16px;
  border-radius: 23px; /* half-height: morphs smoothly */
  transition: background-color 150ms var(--ease-out), border-radius var(--m3-fast) var(--m3-spring-fast);
}
.main-nav a.active::after,
.main-nav a:hover::after { display: none; }
.main-nav a.active { background: var(--m3-secondary-container); }
@media (hover: hover) and (pointer: fine) {
  .main-nav a:not(.active):hover { background: var(--m3-state); }
}
@media (hover: hover) and (pointer: fine) {
  .main-nav a:hover { border-radius: var(--m3-m); }
}
.main-nav a:active { border-radius: 10px; transform: scale(0.94); }
.main-nav a { position: relative; isolation: isolate; }
.main-nav a:focus-visible { outline: 3px solid var(--cocoa); outline-offset: 2px; }

/* ---------- Buttons: M3E shape morph ----------
   Round at rest → square on hover → squarer + squished on press, then a spring
   pop on release (m3e.js adds .m3-pop and a ripple from the touch point).
   Rest radii are exact half-heights, never 999px: a transition from 999px to
   16px spends most of its time above the pill size and then snaps.
   Radii from M3's button table: square M 16, pressed M 12 / L 16. */
.btn {
  --r-rest: 24px;  --r-hover: 16px;  --r-press: 12px;
  position: relative;
  isolation: isolate;
  min-height: 48px;
  padding: 0 24px;
  justify-content: center;
  border-radius: var(--r-rest);
  transition:
    border-radius var(--m3-fast) var(--m3-spring-fast),
    transform var(--m3-fast) var(--m3-spring-fast),
    background-color 150ms var(--ease-out),
    color 150ms var(--ease-out);
}
.product-card .price-row .btn,
.buy-chip-btn { --r-rest: 22px; --r-hover: 14px; --r-press: 10px; min-height: 44px; padding: 0 20px; }
.hero-actions .btn,
.btn-lg { --r-rest: 28px; --r-hover: 20px; --r-press: 16px; min-height: 56px; padding: 0 32px; font-size: 1.1rem; }

/* State layer instead of the lift: controls tint, objects lift. */
.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: currentColor;
  opacity: 0;
  transition: opacity 150ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover { transform: none; }
  .btn:not(:disabled):hover { border-radius: var(--r-hover); }
  .btn:not(:disabled):hover::before { opacity: 0.08; }
}
.btn:focus-visible { border-radius: var(--r-hover); outline: 3px solid var(--cocoa); outline-offset: 3px; }
.btn:not(:disabled):active {
  border-radius: var(--r-press);
  transform: scale(0.95, 0.92);
}
.btn:not(:disabled):active::before { opacity: 0.08; } /* + the 0.1 ripple ≈ M3's pressed layer */

/* No coloured glows (a known debt): M3 fills are flat. */
.btn-primary, .btn-secondary { box-shadow: none; }

/* Outline → tonal: the M3 "tonal button", one step below filled. */
.btn-outline {
  border: none;
  background: var(--m3-primary-container);
  color: var(--cocoa);
}
.hero-actions .btn-outline { background: var(--m3-surface-high); }

/* ---------- Shared press feedback (m3e.js) ---------- */
/* Ripple: an effect, so it scales on the default spatial curve but fades on ease-out. */
.m3-ripple-host {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
  pointer-events: none;
  z-index: -1;
}
.m3-ripple {
  position: absolute;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.1;
  transform: translate(-50%, -50%) scale(0);
  animation: m3Ripple 520ms var(--ease-out) forwards;
}
.m3-ripple.is-out { opacity: 0; transition: opacity 260ms var(--ease-out); }
@keyframes m3Ripple { to { transform: translate(-50%, -50%) scale(1); } }

/* Release: squash → stretch → settle, a hand-tuned spring (ease-out per segment). */
.m3-pop { animation: m3Pop 520ms var(--ease-out); }
@keyframes m3Pop {
  0%   { transform: scale(0.95, 0.92); }
  35%  { transform: scale(1.05, 1.07); }
  65%  { transform: scale(0.985, 0.98); }
  100% { transform: none; }
}

/* ---------- Hero flavour picker: selection morphs the shape ---------- */
.flavour-swatch {
  border-radius: 22px; /* half of 44px, so the morph to 14px is continuous */
  transition:
    border-radius var(--m3-fast) var(--m3-spring-fast),
    background-color 150ms var(--ease-out),
    border-color 150ms var(--ease-out);
}
.flavour-swatch[aria-pressed="true"] {
  border-radius: var(--m3-m);
  background: var(--m3-secondary-container);
  border-color: transparent;
}
.flavour-swatch .dot { transition: border-radius var(--m3-fast) var(--m3-spring-fast), transform var(--m3-fast) var(--m3-spring-fast); }
.flavour-swatch[aria-pressed="true"] .dot { border-radius: 32%; }
@media (min-width: 861px) and (prefers-reduced-motion: no-preference) {
  .flavour-picker { border-radius: var(--m3-xl); }
  .flavour-picker .flavour-swatch[aria-pressed="true"] { background: transparent; }
  .flavour-picker .flavour-swatch[aria-pressed="true"] .dot { transform: scale(1.15); }
}

/* Hero price card: an M3 card, xl corners, nested photo corner. */
.buy-chip { border-radius: var(--m3-xl); }
.buy-chip-photo { border-radius: var(--m3-m); }

/* ---------- Product cards ---------- */
.product-card {
  border-radius: var(--m3-xl);
  box-shadow: 0 1px 2px rgba(var(--shade-rgb), 0.06), 0 4px 14px rgba(var(--shade-rgb), 0.06);
  transition:
    transform var(--m3-default) var(--m3-spring),
    border-radius var(--m3-default) var(--m3-spring),
    box-shadow 200ms var(--ease-out);
}
/* The scallop stays (brand signature). Inset past the largest corner so the
   morph never curves under it. */
.product-card::before { left: var(--m3-xxl); right: var(--m3-xxl); }
@media (hover: hover) and (pointer: fine) {
  .product-card:hover {
    border-radius: var(--m3-xxl);
    box-shadow: 0 2px 4px rgba(var(--shade-rgb), 0.06), 0 14px 32px rgba(var(--shade-rgb), 0.12);
  }
}
.product-card .product-photo { border-radius: var(--m3-l); }

/* Icon disc → M3E 4-lobe cookie; turns a little on hover. */
.product-card .emoji {
  border-radius: 0;
  -webkit-mask: url(images/cookie4.svg) center / 100% 100% no-repeat;
  mask: url(images/cookie4.svg) center / 100% 100% no-repeat;
  transition: transform var(--m3-default) var(--m3-spring);
}
@media (hover: hover) and (pointer: fine) {
  .product-card:hover .emoji { transform: rotate(45deg); }
  .product-card:hover .emoji svg { transform: rotate(-45deg); }
}
.product-card .emoji svg { transition: transform var(--m3-default) var(--m3-spring); }

/* Status chips: small corners, so they never read as buttons. */
.stock-badge { border-radius: var(--m3-s); }

/* Card Add: tonal mint (pink stays the bag/checkout colour). */
.product-card .price-row .add-to-cart.btn-primary {
  border: none;
  background: var(--m3-secondary-container);
  color: var(--cocoa);
}
@media (hover: hover) and (pointer: fine) {
  .product-card .price-row .add-to-cart.btn-primary:not(:disabled):hover {
    background: var(--m3-secondary-container);
    color: var(--cocoa);
  }
}
.price { font-variant-numeric: tabular-nums; }

/* ---------- Shop filters → M3E connected button group ---------- */
.filter-bar { gap: 3px; }
.filter-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  border-radius: var(--m3-s);
  background: var(--m3-surface-high);
  padding: 10px 20px;
  min-height: 48px;
  font-size: 0.95rem;
  transition:
    border-radius var(--m3-fast) var(--m3-spring-fast),
    transform var(--m3-fast) var(--m3-spring-fast),
    background-color 150ms var(--ease-out),
    color 150ms var(--ease-out);
}
.filter-btn:first-child { border-radius: 24px var(--m3-s) var(--m3-s) 24px; }
.filter-btn:last-child  { border-radius: var(--m3-s) 24px 24px var(--m3-s); }
.filter-btn.active { border-radius: 24px; }
/* Hover squares the outer corners of the ends; press squeezes any segment. */
@media (hover: hover) and (pointer: fine) {
  .filter-btn:not(.active):hover { border-radius: var(--m3-m); }
}
.filter-btn:active { border-radius: var(--m3-s); }
@media (hover: hover) and (pointer: fine) {
  .filter-btn:not(.active):hover { background: rgba(var(--surface-rgb), 1); box-shadow: inset 0 0 0 999px var(--m3-state); }
}
.filter-btn:active { transform: scale(0.96); }
/* Selected gets a check: a cue that isn't colour alone. */
.filter-btn.active::before {
  content: '';
  width: 18px;
  height: 18px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.filter-btn:focus-visible { outline: 3px solid var(--cocoa); outline-offset: 2px; }

/* ---------- Category bento: tonal containers that morph ---------- */
.bento .category-tile,
.bento .category-tile.category-tile--hero {
  border-radius: var(--m3-xxl);
  box-shadow: none;
  transition: border-radius var(--m3-default) var(--m3-spring), transform var(--m3-default) var(--m3-spring);
}
.category-tile::before { display: none; } /* scallop stays on product cards only */
.bento .category-tile.category-tile--hero { background: var(--m3-secondary-container); }
.bento .category-tile:nth-child(2) { background: var(--m3-primary-container); }
.bento .category-tile:nth-child(3) { background: var(--m3-tertiary-container); }
.bento .category-tile.category-tile--hero h3 { font-size: clamp(2.2rem, 3.6vw, 3rem); font-weight: 700; letter-spacing: -0.03em; }
@media (hover: hover) and (pointer: fine) {
  .bento .category-tile:hover { border-radius: 64px; transform: none; }
}
.category-tile:active { transform: scale(0.98); }
.category-tile:focus-visible { outline: 3px solid var(--cocoa); outline-offset: 3px; }

/* Icon → 9-lobe cookie on the page surface, spinning a notch on hover. */
.bento .tile-icon {
  position: relative;
  isolation: isolate;
  border-radius: 0;
  background: transparent !important;
}
.bento .tile-icon::before {
  content: '';
  position: absolute;
  inset: -4px;
  z-index: -1;
  background: var(--m3-surface-high);
  -webkit-mask: url(images/cookie9.svg) center / 100% 100% no-repeat;
  mask: url(images/cookie9.svg) center / 100% 100% no-repeat;
  transition: transform var(--m3-default) var(--m3-spring);
}
@media (hover: hover) and (pointer: fine) {
  .bento .category-tile:hover .tile-icon::before { transform: rotate(40deg) scale(1.06); }
}
.tile-art { opacity: 0.14; }

/* ---------- Phone: M3E flexible navigation bar, floating ----------
   Keeps Sweet Sip's floating bar (sticky before the footer), in M3E form: a
   fully rounded surface-container, no glass, a secondary-container pill
   indicator that stretches out from the centre on the fast spatial spring,
   and the active icon a notch bigger (Phosphor has no filled set loaded here,
   so size stands in for "filled", as M3 allows with a heavier weight). */
@media (max-width: 760px) {
  .tab-bar {
    padding: 6px;
    border-radius: 39px; /* half of its 78px height */
    background: var(--m3-surface-container);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: 0 2px 6px rgba(var(--shade-rgb), 0.08), 0 10px 28px rgba(var(--shade-rgb), 0.14);
    animation: m3BarIn 620ms var(--m3-spring) both;
  }
  .tab-bar a {
    position: relative;
    isolation: isolate;
    gap: 4px;
    min-height: 60px;
    padding: 6px 2px;
    border-radius: 33px; /* half of 66px */
    color: rgba(var(--ink-rgb), 0.78);
    transition: color 150ms var(--ease-out), border-radius var(--m3-fast) var(--m3-spring-fast);
  }
  .tab-bar a:active { transform: none; border-radius: 12px; } /* squarer than hover (20px) */
  .tab-bar a .tab-icon {
    position: relative;
    isolation: isolate;
    width: 56px;
    height: 32px;
    border-radius: 16px;
    background: transparent;
    transition: transform var(--m3-fast) var(--m3-spring-fast);
  }
  .tab-bar a:active .tab-icon { transform: scale(0.88); }
  .tab-bar a .tab-icon svg { transition: transform var(--m3-default) var(--m3-spring); }
  .tab-bar a .tab-icon::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: var(--m3-secondary-container);
    transform: scaleX(0.2);
    opacity: 0;
    transition: transform var(--m3-default) var(--m3-spring-fast), opacity 150ms var(--ease-out);
  }
  .tab-bar a.active { color: var(--cocoa); font-weight: 700; }
  .tab-bar a.active .tab-icon { background: transparent; animation: none; }
  .tab-bar a.active .tab-icon::before { transform: none; opacity: 1; }
  .tab-bar a.active .tab-icon svg { transform: scale(1.14); }
  /* Keeps page-load entry lively: the indicator stretches in after the bar lands. */
  @media (prefers-reduced-motion: no-preference) {
    .tab-bar a.active .tab-icon::before { animation: m3Indicator 560ms var(--m3-spring-fast) 180ms both; }
  }
  .tab-bar a:focus-visible { outline: 3px solid var(--cocoa); outline-offset: -3px; }

  /* Bag bar → M3E floating toolbar: fully rounded, the CTA a filled button that
     morphs like every other button. Cocoa stays (it's the island's colour). */
  .bag-bar {
    bottom: calc(106px + env(safe-area-inset-bottom)); /* clears the taller 78px bar */
    min-height: 60px;
    padding: 8px 8px 8px 22px;
    border-radius: 30px;
    transition: transform var(--m3-default) var(--m3-spring), opacity 150ms var(--ease-out), border-radius var(--m3-fast) var(--m3-spring-fast);
  }
  .bag-bar:active { transform: scale(0.97); border-radius: var(--m3-l); }
  .bag-bar-cta {
    position: relative;
    isolation: isolate;
    min-height: 44px;
    padding: 0 18px;
    border-radius: 22px;
    transition: border-radius var(--m3-fast) var(--m3-spring-fast);
  }
  .bag-bar:active .bag-bar-cta { border-radius: 10px; }
}
@keyframes m3BarIn {
  from { opacity: 0; transform: translateY(24px) scale(0.92); }
}
@keyframes m3Indicator {
  from { transform: scaleX(0.2); opacity: 0; }
}

/* ---------- Quick view: M3 dialog corners ---------- */
.modal-card { border-radius: var(--m3-xl); }
/* Same 9-lobe cookie as the category and review icons (a photo keeps its rounded frame). */
.modal-emoji:not(.has-photo) {
  border-radius: 0;
  -webkit-mask: url(images/cookie9.svg) center / 100% 100% no-repeat;
  mask: url(images/cookie9.svg) center / 100% 100% no-repeat;
}
.modal-overlay.open .modal-emoji:not(.has-photo) { animation: m3CheckIn 700ms var(--m3-spring) both; }
@media (prefers-reduced-motion: reduce) { .modal-overlay.open .modal-emoji { animation: none; } }

/* ---------- Extended FAB to the bag (desktop, only once the bag has items) ---------- */
.m3-fab { display: none; }
@media (min-width: 761px) {
  .m3-fab {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 30;
    display: inline-flex;
    align-items: center;
    gap: 12px;
    min-height: 64px;
    padding: 0 24px 0 20px;
    border-radius: var(--m3-l);
    background: var(--m3-primary-container);
    color: var(--cocoa);
    font: 600 1.05rem/1 var(--font-display);
    box-shadow: 0 3px 6px rgba(var(--shade-rgb), 0.12), 0 10px 24px rgba(var(--shade-rgb), 0.14);
    transition:
      border-radius var(--m3-fast) var(--m3-spring-fast),
      transform var(--m3-default) var(--m3-spring),
      opacity 150ms var(--ease-out),
      gap var(--m3-default) var(--m3-spring),
      padding var(--m3-default) var(--m3-spring);
  }
  @starting-style {
    .m3-fab { transform: scale(0.6); opacity: 0; }
  }
  .m3-fab:has(.cart-badge[hidden]) { display: none; }
  .m3-fab svg { width: 24px; height: 24px; }
  .m3-fab .cart-badge { margin-left: 0; min-width: 24px; height: 24px; font-size: 0.8rem; }
  @media (hover: hover) and (pointer: fine) {
    .m3-fab:hover { border-radius: var(--m3-xl); }
  }
  .m3-fab:active { border-radius: var(--m3-xl); transform: scale(0.96); }
  .m3-fab:focus-visible { outline: 3px solid var(--cocoa); outline-offset: 3px; }
}

/* FAB behaviour (m3e.js), which also clears the round-7/8 audit flags where it
   covered the hero picker, price card, lede and footer links:
   - .is-away: hidden while the page's own bag button / hero is on screen, and
     at the footer.
   - .is-collapsed: M3's extended FAB shrinks to an icon FAB while scrolling
     down and extends again on scroll up. Width and corners ride the spring. */
@media (min-width: 761px) {
  .m3-fab.is-away { transform: translateY(24px) scale(0.6); opacity: 0; pointer-events: none; visibility: hidden; transition: transform var(--m3-fast) var(--m3-spring-fast), opacity 150ms var(--ease-out), visibility 0s 150ms; }
  .m3-fab-label {
    display: inline-block;
    max-width: 7em;
    overflow: hidden;
    white-space: nowrap;
    transition: max-width var(--m3-default) var(--m3-spring), opacity 150ms var(--ease-out);
  }
  .m3-fab.is-collapsed { gap: 8px; padding: 0 16px; border-radius: var(--m3-l); }
  .m3-fab.is-collapsed .m3-fab-label { max-width: 0; opacity: 0; }
}

/* ---------- Motion everywhere (all spatial = springs, all fades = ease-out) ---------- */
/* Scroll reveal: rise + grow on the default spatial spring. main.js still owns
   the stagger delays and clears them on transitionend. */
.reveal {
  transform: translateY(32px) scale(0.96);
  transition: opacity 300ms var(--ease-out), transform 720ms var(--m3-spring);
}
.reveal.in-view { transform: none; }

/* Hero entrance: headline, lede and actions arrive in a short sequence. */
@media (prefers-reduced-motion: no-preference) {
  .hero h1, .hero .lede, .hero-actions { animation: m3Rise 760ms var(--m3-spring) both; }
  .hero .lede { animation-delay: 90ms; }
  .hero-actions { animation-delay: 170ms; }
  .section-head h2, .section-head h1 { transition: letter-spacing 700ms var(--m3-spring); }
  .section-head.reveal:not(.in-view) h2 { letter-spacing: 0.02em; }
}
@keyframes m3Rise { from { opacity: 0; transform: translateY(28px) scale(0.97); } }

/* Cards: pressing an object squashes it a little (touch and mouse). */
.product-card:active { transform: scale(0.98); }

/* Page changes between the M3E pages: a shared-axis style transition, and the
   nav indicators travel from the old page's item to the new one. */
@view-transition { navigation: auto; }
.site-header { view-transition-name: m3-header; }
.main-nav a.active { view-transition-name: m3-nav-indicator; }
@media (max-width: 760px) {
  .tab-bar { view-transition-name: m3-tabbar; }
  .tab-bar a.active .tab-icon { view-transition-name: m3-tab-indicator; }
}
::view-transition-group(m3-nav-indicator),
::view-transition-group(m3-tab-indicator) { animation-duration: 520ms; animation-timing-function: var(--m3-spring-fast); }
::view-transition-old(root) { animation: 160ms var(--ease-out) both m3PageOut; }
::view-transition-new(root) { animation: 520ms var(--m3-spring) both m3PageIn; }
@keyframes m3PageOut { to { opacity: 0; transform: scale(0.98); } }
@keyframes m3PageIn { from { opacity: 0; transform: translateY(24px) scale(0.99); } }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

/* =====================================================================
   Round 9: the same M3E layer on Saved, Bag, About, Reviews and the
   policy pages. Shared parts (header, buttons, cards, tab bar, FAB) are
   already above; this is only what those pages add.
   ===================================================================== */

/* ---------- Panels (bag lines, order summary, review form) ---------- */
.cart-panel {
  border-radius: var(--m3-xl);
  box-shadow: 0 1px 2px rgba(var(--shade-rgb), 0.06), 0 4px 14px rgba(var(--shade-rgb), 0.06);
}
.cart-item { padding: 12px 0; }
.cart-thumb .emoji {
  border-radius: 0;
  background: var(--m3-primary-container);
  -webkit-mask: url(images/cookie4.svg) center / 100% 100% no-repeat;
  mask: url(images/cookie4.svg) center / 100% 100% no-repeat;
}
.cart-thumb .product-photo { border-radius: var(--m3-m); }

/* Remove (icon button) and the steppers morph like every other button. */
.cart-item .remove-item,
.qty-step {
  border-radius: 22px;
  transition: border-radius var(--m3-fast) var(--m3-spring-fast), transform var(--m3-fast) var(--m3-spring-fast), background-color 150ms var(--ease-out), color 150ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .cart-item .remove-item:hover, .qty-step:not(:disabled):hover { border-radius: var(--m3-m); }
}
.cart-item .remove-item:active, .qty-step:not(:disabled):active { border-radius: 10px; transform: scale(0.9); }
.qty-stepper { border-radius: 22px; }

.summary-heading { font-weight: 700; letter-spacing: -0.01em; }
.cart-total { font-size: 1.3rem; font-weight: 700; letter-spacing: -0.01em; }
#cart-total { font-variant-numeric: tabular-nums; }

/* ---------- Text fields: M3 filled fields, expressive corners ----------
   Tonal fill, rounder top corners, and M3's bottom active indicator: 1.5px
   (ink 0.6, at least 3:1 on the fill) at rest, 3px --pink-text when focused,
   the danger colour once a field the customer left is invalid. */
.checkout-form label { color: var(--cocoa); }
.checkout-form input:not([type="radio"]):not([type="checkbox"]),
.checkout-form select,
.checkout-form textarea {
  border: 0;
  border-radius: var(--m3-m) var(--m3-m) 4px 4px;
  background: var(--m3-surface-container-high);
  color: var(--cocoa);
  padding: 12px 16px;
  min-height: 52px;
  box-shadow: inset 0 -1.5px 0 rgba(var(--ink-rgb), 0.6);
  transition: box-shadow 150ms var(--ease-out), background-color 150ms var(--ease-out), border-radius var(--m3-fast) var(--m3-spring-fast);
}
@media (hover: hover) and (pointer: fine) {
  .checkout-form input:not([type="radio"]):not([type="checkbox"]):hover,
  .checkout-form select:hover,
  .checkout-form textarea:hover { box-shadow: inset 0 -1.5px 0 rgba(var(--ink-rgb), 0.9), inset 0 0 0 999px var(--m3-state); }
}
.checkout-form input:not([type="radio"]):not([type="checkbox"]):focus,
.checkout-form select:focus,
.checkout-form textarea:focus {
  outline: none;
  border-radius: var(--m3-l) var(--m3-l) 4px 4px;
  box-shadow: inset 0 -3px 0 var(--pink-text);
}
.checkout-form :user-invalid:not(:focus) { box-shadow: inset 0 -3px 0 var(--danger-text); }

/* ---------- Radio choices: M3E selectable cards ----------
   Unselected: round corners on the tonal fill. Selected: squarer corners,
   the secondary container and a heavier label (M3's toggle rule, round to
   square on selection, carried to a choice card). */
.option-group legend { color: var(--cocoa); }
.payment-options { gap: 8px; }
.payment-options label {
  position: relative;
  isolation: isolate;
  border: 0;
  min-height: 56px;
  padding: 12px 18px;
  border-radius: 28px;
  background: var(--m3-surface-container-high);
  color: var(--cocoa);
  font-size: 0.92rem;
  transition: border-radius var(--m3-default) var(--m3-spring-fast), background-color 150ms var(--ease-out), transform var(--m3-fast) var(--m3-spring-fast);
}
@media (hover: hover) and (pointer: fine) {
  .payment-options label:not(:has(input:checked)):hover { border-radius: var(--m3-l); box-shadow: inset 0 0 0 999px var(--m3-state); }
}
.payment-options label:active { transform: scale(0.97); }
.payment-options label:has(input:checked) {
  border-radius: var(--m3-m);
  background: var(--m3-secondary-container);
  font-weight: 700;
}
.payment-options label:has(input:focus-visible) { outline: 3px solid var(--cocoa); outline-offset: 2px; }
.payment-options input { accent-color: var(--cocoa); width: 20px; height: 20px; flex: none; }

/* Place order: the one large button on the page. */
.checkout-form button[type="submit"],
.order-confirmation > .btn {
  --r-rest: 28px; --r-hover: 20px; --r-press: 16px;
  min-height: 56px;
  font-size: 1.1rem;
}

/* ---------- Order confirmation: the page's hero moment ---------- */
.order-confirmation { border-radius: var(--m3-xxl); }
.confirmation-check {
  width: 88px;
  height: 88px;
  border-radius: 0;
  background: var(--m3-secondary-container);
  -webkit-mask: url(images/cookie9.svg) center / 100% 100% no-repeat;
  mask: url(images/cookie9.svg) center / 100% 100% no-repeat;
}
.confirmation-check svg { width: 40px; height: 40px; }
.order-confirmation:not([hidden]) .confirmation-check { animation: m3CheckIn 900ms var(--m3-spring) both; }
@keyframes m3CheckIn { from { opacity: 0; transform: scale(0.3) rotate(-80deg); } }
.confirmation-summary { border-radius: var(--m3-l); background: var(--m3-surface-container-high); }

/* ---------- Empty states (bag, Saved) ---------- */
.empty-state { border-radius: var(--m3-xl); }

/* ---------- About: timeline ---------- */
.timeline { border-left: 0; position: relative; }
.timeline::before { /* the rail, now a rounded track */
  content: '';
  position: absolute;
  left: -4px;
  top: 6px;
  bottom: 6px;
  width: 4px;
  border-radius: 2px;
  background: rgba(var(--ink-rgb), 0.22);
}
.timeline-item::before { /* the dot: a 4-lobe cookie that spins in with its step */
  left: -40px; /* centred on the rail: 28px padding + 2px half-rail + 10px half-dot */
  top: 0;
  width: 20px;
  height: 20px;
  border-radius: 0;
  background: var(--accent);
  -webkit-mask: url(images/cookie4.svg) center / 100% 100% no-repeat;
  mask: url(images/cookie4.svg) center / 100% 100% no-repeat;
  transform: scale(0.3) rotate(-120deg);
  transition: transform 900ms var(--m3-spring);
}
.timeline-item.in-view::before { transform: none; }
.timeline-item .when {
  display: inline-block;
  padding: 4px 10px;
  border-radius: var(--m3-s);
  background: var(--m3-tertiary-container);
  font-size: 0.8rem;
  margin-bottom: 10px;
}
.timeline-item h3 { font-weight: 700; letter-spacing: -0.01em; }

/* ---------- About: values as tonal containers that morph ---------- */
.about-page .values-list { display: grid; gap: 12px; }
.about-page .value-row,
.about-page .value-row:last-child {
  border: 0;
  padding: 28px 32px;
  border-radius: var(--m3-xl);
  background: var(--m3-secondary-container);
  transition: border-radius var(--m3-default) var(--m3-spring), transform 720ms var(--m3-spring), opacity 300ms var(--ease-out);
}
.about-page .value-row:nth-child(2) { background: var(--m3-primary-container); }
.about-page .value-row:nth-child(3) { background: var(--m3-tertiary-container); }
.about-page .value-row h3 { font-weight: 700; letter-spacing: -0.02em; }
@media (hover: hover) and (pointer: fine) {
  .about-page .value-row:hover { border-radius: var(--m3-xxl); }
}
@media (max-width: 700px) {
  .about-page .value-row, .about-page .value-row:last-child { padding: 24px; }
}

/* ---------- About: closing call to action as a tonal hero container ---------- */
.about-page > section:last-of-type { position: relative; isolation: isolate; }
.about-page > section:last-of-type::before {
  content: '';
  position: absolute;
  inset: 0 24px 56px;
  z-index: -1;
  border-radius: var(--m3-xxl);
  background: var(--m3-primary-container);
}
.about-page > section:last-of-type h2 { font-weight: 700; font-size: clamp(1.9rem, 4vw, 2.6rem); letter-spacing: -0.03em; }
.about-page > section:last-of-type .btn { --r-rest: 28px; --r-hover: 20px; --r-press: 16px; min-height: 56px; padding: 0 32px; font-size: 1.1rem; }

/* ---------- Policy pages ---------- */
.legal h1 { font-weight: 700; letter-spacing: -0.03em; }
.legal h2 { font-weight: 700; letter-spacing: -0.02em; }
.legal-updated {
  display: inline-block;
  padding: 6px 12px;
  border-radius: var(--m3-s);
  background: var(--m3-surface-high);
  color: var(--cocoa);
}
.legal-table { border-radius: var(--m3-xl); box-shadow: 0 1px 2px rgba(var(--shade-rgb), 0.06), 0 4px 14px rgba(var(--shade-rgb), 0.06); }
.legal-table thead th { background: var(--m3-secondary-container); }
.legal li::marker { color: var(--pink-text); }

/* ---------- Reviews ---------- */
.review-product-visual .emoji {
  border-radius: 0;
  -webkit-mask: url(images/cookie9.svg) center / 100% 100% no-repeat;
  mask: url(images/cookie9.svg) center / 100% 100% no-repeat;
}
.review { border-radius: var(--m3-l); }
.star-input label { border-radius: 22px; transition: border-radius var(--m3-fast) var(--m3-spring-fast), background-color 150ms var(--ease-out); }
.star-input svg { transition: transform var(--m3-fast) var(--m3-spring-fast), color 150ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .star-input label:hover { border-radius: var(--m3-m); background: var(--m3-state); }
  .star-input label:hover svg { transform: scale(1.12) rotate(-8deg); }
}
.star-input label:has(input:checked) svg { transform: scale(1.18); }

@media (prefers-reduced-motion: reduce) {
  .timeline-item::before, .star-input label:has(input:checked) svg { transform: none; }
  .order-confirmation:not([hidden]) .confirmation-check { animation: none; }
}

/* ---------- Every remaining control gets the same M3E feedback (2026-09-23) ----------
   A probe of all 187 controls found these without a hover shape change and/or the
   press ripple + pop. js/m3e.js's SEL now lists them too. */

/* Heart (save): an M3 icon toggle. Round at rest, square once saved (selected), squarer
   on hover, squashed on press. */
.fav-btn {
  border-radius: 22px;
  transition: border-radius var(--m3-fast) var(--m3-spring-fast), transform var(--m3-fast) var(--m3-spring-fast), background-color 150ms var(--ease-out), color 150ms var(--ease-out);
}
.fav-btn.is-fav { border-radius: var(--m3-m); }
@media (hover: hover) and (pointer: fine) {
  .fav-btn:hover { border-radius: var(--m3-m); }
  .fav-btn.is-fav:hover { border-radius: 10px; }
}
.fav-btn:active { border-radius: 8px; transform: scale(0.88); }

/* Quick view close: a standard icon button. */
.modal-close {
  border-radius: 22px;
  transition: border-radius var(--m3-fast) var(--m3-spring-fast), transform var(--m3-fast) var(--m3-spring-fast), background-color 150ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .modal-close:hover { border-radius: var(--m3-m); box-shadow: inset 0 0 0 999px var(--m3-state); }
}
.modal-close:active { border-radius: 8px; transform: scale(0.9); }

/* Logo: the mark rounds off on hover and dips on press. */
.brand { border-radius: var(--m3-l); }
.brand img { transition: border-radius var(--m3-default) var(--m3-spring), transform var(--m3-fast) var(--m3-spring-fast); }
@media (hover: hover) and (pointer: fine) {
  .brand:hover img { border-radius: 23px; transform: rotate(-6deg); }
}
.brand:active img { border-radius: 8px; transform: scale(0.92); }

/* Flavour dots: unselected ones square up on hover (selected is already square). */
@media (hover: hover) and (pointer: fine) {
  .flavour-swatch:not([aria-pressed="true"]):hover { border-radius: var(--m3-l); }
  .flavour-swatch[aria-pressed="true"]:hover { border-radius: 10px; }
}
.flavour-swatch:active { border-radius: 10px; }

/* Selected filter / choice card: hover still answers, one step squarer. */
@media (hover: hover) and (pointer: fine) {
  .filter-btn.active:hover { border-radius: var(--m3-l); }
  .payment-options label:has(input:checked):hover { border-radius: 10px; box-shadow: inset 0 0 0 999px var(--m3-state); }
}
.payment-options label:active { border-radius: 10px; }

/* Review stars: the press squares the target too, not just the icon. */
.star-input label:active { border-radius: 8px; }
.star-input label:active svg { transform: scale(0.86); }

/* Phone bar + bag bar with a mouse (narrow desktop windows, tablets with trackpads). */
@media (max-width: 760px) and (hover: hover) and (pointer: fine) {
  .tab-bar a:hover { border-radius: var(--m3-l); background: var(--m3-state); }
  .tab-bar a:active { border-radius: 12px; }
  .bag-bar:hover { border-radius: var(--m3-l); }
  .bag-bar:hover .bag-bar-cta { border-radius: var(--m3-m); }
}

/* Footer links, "Back to shop": M3 text buttons. No container at rest; on hover a
   tinted container appears and squares up; press squashes it. Underlines stay, so
   links still read as links. */
.site-footer p:not(.footer-credit) a,
.footer-legal a,
.back-link {
  position: relative;
  isolation: isolate;
  border-radius: 16px;
  transition: border-radius var(--m3-fast) var(--m3-spring-fast), transform var(--m3-fast) var(--m3-spring-fast), background-color 150ms var(--ease-out), color 150ms var(--ease-out);
}
/* Desktop: one text line tall (the links sit ~26px apart; any vertical padding made
   neighbouring pills overlap). Same size as before for a mouse, now with feedback. */
.site-footer p:not(.footer-credit) a { display: inline-block; padding: 0 10px; margin: 0 -10px; }
.back-link { padding: 0 12px; margin-left: -12px; }
@media (max-width: 760px), (pointer: coarse) {
  .site-footer p:not(.footer-credit) a { padding: 10px; margin: 0 -10px; }
}
@media (hover: hover) and (pointer: fine) {
  .site-footer p:not(.footer-credit) a:hover,
  .footer-legal a:hover,
  .back-link:hover { border-radius: 8px; background: var(--m3-state); }
}
.site-footer p:not(.footer-credit) a:active,
.footer-legal a:active,
.back-link:active { border-radius: 6px; transform: scale(0.95); }
.site-footer p:not(.footer-credit) a:focus-visible,
.footer-legal a:focus-visible,
.back-link:focus-visible { outline: 3px solid var(--cocoa); outline-offset: 2px; border-radius: 8px; }

/* Cards are big: a softer pop than the buttons' squash-and-stretch. */
.product-card.m3-pop,
.category-tile.m3-pop { animation-name: m3PopSoft; }
@keyframes m3PopSoft {
  0%   { transform: scale(0.98); }
  45%  { transform: scale(1.012); }
  100% { transform: none; }
}

/* Reduced motion: shapes still change (state), but instantly. */
@media (prefers-reduced-motion: reduce) {
  .product-card:hover .emoji,
  .product-card:hover .emoji svg,
  .bento .category-tile:hover .tile-icon::before,
  .reveal, .btn:active, .m3-pop, .tab-bar a.active .tab-icon svg { transform: none; }
  .m3-pop, .m3-ripple, .tab-bar { animation: none; }
}
