/* ==========================================================================
   PUFFINS — Global Stylesheet
   Brand palette: Navy #0F2740 · Orange #FF8A00 · Yellow #FFC257 · Cream #FFF7EE
   ========================================================================== */

:root{
  --navy:      #0F2740;
  --navy-80:   #24405e;
  --orange:    #FF8A00;
  --orange-dk: #a35000;
  --orange-hover: #e67900;
  --yellow:    #FFC257;
  --cream:     #FFF7EE;
  --white:     #FFFFFF;
  --ink:       #16233266;
  --line:      #e7ddce;
  --text:      #1c2a3a;
  --text-soft: #52606f;
  --radius-sm: 10px;
  --radius-md: 18px;
  --radius-lg: 28px;
  --shadow-sm: 0 2px 10px rgba(15,39,64,.08);
  --shadow-md: 0 10px 30px rgba(15,39,64,.12);
  --maxw: 1180px;
  --gradient-brand: linear-gradient(90deg,#17b3a3 0%, #6a4bd6 25%, #d6389a 55%, #ff8a00 80%, #ffc257 100%);
  /* Accent tokens — from brand reference video (assets/video/puffins-showcase.mp4):
     --rust/--olive echo its warm sunburst template slides; --ink is reused (previously
     unused) as the editorial motif's hairline rule color from its cream/black slides. */
  --rust:      #C1502E;
  --olive:     #5B6B3A;
}

*,*::before,*::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }
body{
  margin:0;
  font-family:'Poppins', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  color:var(--text);
  background:var(--white);
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
img{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{
  outline:3px solid var(--orange); outline-offset:2px; border-radius:4px;
}
ul{ margin:0; padding:0; list-style:none; }
h1,h2,h3,h4{ margin:0 0 .5em; font-weight:700; line-height:1.15; letter-spacing:-.01em; }
p{ margin:0 0 1em; }
button{ font-family:inherit; cursor:pointer; }
.container{ max-width:var(--maxw); margin:0 auto; padding:0 20px; }
section{ padding:64px 0; }
@media (min-width:900px){ section{ padding:96px 0; } }

.eyebrow{
  display:inline-flex; align-items:center; gap:9px;
  font-size:1.2rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
  color:var(--orange-dk); margin-bottom:16px;
}
.eyebrow::before{
  content:""; width:26px; height:4px; border-radius:3px;
  background:var(--gradient-brand); background-size:200% 100%;
  animation:eyebrow-shimmer 3.5s ease-in-out infinite;
}
@keyframes eyebrow-shimmer{ 0%,100%{ background-position:0% 50%; } 50%{ background-position:100% 50%; } }
@media (prefers-reduced-motion:reduce){ .eyebrow::before{ animation:none; } }

.h1{ font-size:clamp(2.4rem,6.5vw,4.4rem); font-weight:800; letter-spacing:-.02em; line-height:1.05; }
.h2{ font-size:clamp(1.9rem,4.8vw,3rem); font-weight:800; letter-spacing:-.015em; }
.h2-cheerful{
  font-family:'Baloo 2', 'Poppins', system-ui, sans-serif;
  text-transform:uppercase; letter-spacing:.01em;
  background:var(--gradient-brand); background-size:200% 100%;
  -webkit-background-clip:text; background-clip:text; color:transparent; -webkit-text-fill-color:transparent;
  animation:cheerful-shimmer 6s ease-in-out infinite;
}
@keyframes cheerful-shimmer{ 0%,100%{ background-position:0% 50%; } 50%{ background-position:100% 50%; } }
@media (prefers-reduced-motion:reduce){ .h2-cheerful{ animation:none; } }
.lead{ font-size:1.15rem; color:var(--text-soft); max-width:640px; }

/* ---------- Story tagline: "simple grain" settles in, then "crunch" puffs
   up out of it ---------- driven by initStoryTaglinePuff() in
   scroll-motion.js. Deliberately namespaced as --tag-* rather than reusing
   the ambient --rv-* names: this element sits inside .section-head, which
   already drives its OWN --rv-o/--rv-s/--rv-rx via initCascadeReveal(), and
   those inherit down to children by default — reusing the same names here
   would have this element's opacity/scale silently double up with its
   ancestor's. Two halves, two independent curves: the plain half settles
   with a normal ease-out; the crunchy half arrives on a delayed window and
   visibly overshoots past full size before springing back — not a plain
   fade/slide, and it echoes what the sentence itself describes. */
.story-tagline{
  display:flex; flex-wrap:wrap; justify-content:center; align-items:baseline;
  gap:.35em; margin:8px 0 20px; font-size:clamp(1.25rem,3vw,1.8rem);
}
.story-tagline-plain{
  color:var(--text-soft); font-weight:600;
  opacity:var(--tag-po,1); transform:scale(var(--tag-ps,1));
  transform-origin:center;
}
.story-tagline-pop{
  font-family:'Baloo 2','Poppins',system-ui,sans-serif; font-weight:800; font-size:1.2em;
  letter-spacing:.01em; text-transform:uppercase; display:inline-block;
  background:var(--gradient-brand); background-size:220% 100%;
  -webkit-background-clip:text; background-clip:text; color:transparent; -webkit-text-fill-color:transparent;
  opacity:var(--tag-co,1); transform:scale(var(--tag-cs,1)) rotate(var(--tag-cr,0deg));
  transform-origin:center; animation:cheerful-shimmer 5s ease-in-out infinite;
}
@media (prefers-reduced-motion:reduce){ .story-tagline-pop{ animation:none; } }

/* ---------- Word-flip: a word that boomerangs between text and an emoji ----------
   Continuous cycle (word -> emoji -> word -> emoji...) driven by
   initWordFlip() in main.js on a timer, not scroll — this is a small,
   perpetual decorative flourish on a single word, not content people need
   to read reliably, so a plain setInterval loop is the right tool (unlike
   the scroll-progress system used for entrance/position animation
   elsewhere on the site). The CSS here just provides the "blink": scale
   and fade out, swap the text node in JS, scale and fade back in. */
.word-flip{ display:inline-block; transition:transform .22s cubic-bezier(.34,1.56,.64,1), opacity .18s ease; }
.word-flip.is-flipping{ transform:scale(.35) rotate(6deg); opacity:0; }
@media (prefers-reduced-motion:reduce){ .word-flip{ transition:none; } }

/* Buttons */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:14px 28px; border-radius:999px; font-weight:600; font-size:.98rem;
  border:2px solid transparent; transition:transform .15s ease, box-shadow .15s ease, background .15s ease;
  white-space:nowrap;
}
.btn:hover{ transform:translateY(-2px); }
.btn:active{ transform:scale(.97); }
@media (prefers-reduced-motion:reduce){ .btn{ transition:background .15s ease; } .btn:hover{ transform:none; } }
.btn-primary{ background:var(--orange); color:var(--navy); box-shadow:0 8px 20px rgba(255,138,0,.35); }
.btn-primary:hover{ background:var(--orange-hover); }
.btn-outline{ border-color:var(--navy); color:var(--navy); background:transparent; }
.btn-outline:hover{ background:var(--navy); color:var(--white); }
.btn-light{ background:var(--white); color:var(--navy); }
.btn-light:hover{ background:var(--cream); }
.btn-sm{ padding:10px 20px; font-size:.88rem; }
.btn-block{ width:100%; }

/* ---------- Header ---------- */
.site-header{
  position:sticky; top:0; z-index:100;
  background:rgba(255,255,255,.96); backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);
  box-shadow:0 2px 16px rgba(15,39,64,.05);
}
.site-header::after{
  content:""; display:block; height:3px; background:var(--gradient-brand);
  opacity:.9;
}
.header-inner{
  position:relative; display:grid; grid-template-columns:1fr auto 1fr;
  column-gap:16px; align-items:center; height:96px; transition:height .25s ease;
}
@media (min-width:900px){ .header-inner{ height:128px; } }
.brand{ display:flex; align-items:center; gap:10px; font-weight:800; font-size:1.3rem; color:var(--navy); }
.brand-mark{ height:70px; width:auto; display:block; transition:height .25s ease; }
@media (min-width:900px){ .brand-mark{ height:80px; } }
.site-header.is-shrunk .brand-mark{ height:44px; }
.site-header.is-shrunk .header-inner{ height:68px; }
.site-header.is-shrunk ~ .nav-mobile{ inset:68px 0 0 0; }
.brand .tag{ display:none; }
@media (min-width:640px){
  .brand .tag{ display:inline-block; font-size:.6rem; font-weight:600; letter-spacing:.12em; color:var(--text-soft); text-transform:uppercase; margin-left:2px; }
}

.nav-link{ font-weight:700; font-size:1.25rem; letter-spacing:.01em; color:var(--text); padding:12px 0; position:relative; white-space:nowrap; }
.nav-link.active,.nav-link:hover{ color:var(--orange-dk); }
.nav-link::after{
  content:""; position:absolute; left:0; right:0; bottom:-4px; height:3px; border-radius:3px;
  background:var(--gradient-brand); transform:scaleX(0); transform-origin:left; transition:transform .25s ease;
}
.nav-link:hover::after{ transform:scaleX(1); }
.nav-link.active::after{ transform:scaleX(1); }
@media (prefers-reduced-motion:reduce){ .nav-link::after{ transition:none; } }
.nav-link-left{ justify-self:end; }
.nav-link-right{ justify-self:start; }
@media (max-width:479px){
  .nav-link{ display:none; }
}

.nav-toggle{
  position:absolute; top:50%; right:0; transform:translateY(-50%) scale(1) rotate(0deg);
  display:flex; flex-direction:column; justify-content:center; gap:5px;
  width:46px; height:46px; border-radius:14px; border:1px solid var(--line); background:var(--white);
  transition:transform .35s cubic-bezier(.34,1.56,.64,1), box-shadow .2s ease, border-color .2s ease;
}
.nav-toggle:hover{ transform:translateY(-50%) scale(1.1) rotate(-4deg); box-shadow:var(--shadow-sm); border-color:var(--orange); }
.nav-toggle:active{ transform:translateY(-50%) scale(0.88) rotate(2deg); }
.nav-toggle span{
  /* Square (not rounded) caps: a border-radius on a 2px-tall bar gets
     clamped to a full pill shape either way, and that rounding eats a much
     bigger share of a short bar's length than a long bar's — reading as
     "different thickness" even when the height is identical. Flat ends
     read as equal weight regardless of length. */
  height:2px; background:var(--navy); margin:0 auto; border-radius:0;
  transition:width .3s cubic-bezier(.34,1.56,.64,1), transform .3s cubic-bezier(.34,1.56,.64,1), opacity .2s ease, background .2s ease;
}
/* Tapered stack, widest at top to narrowest at bottom — the middle bar
   carries the brand orange as a small, playful accent rather than three
   identical navy lines. */
.nav-toggle span:nth-child(1){ width:22px; }
.nav-toggle span:nth-child(2){ width:16px; background:var(--orange); }
.nav-toggle span:nth-child(3){ width:10px; }
/* Hover: a staggered little bounce — each bar hops in sequence, top to
   bottom, like a tiny wave — rather than a static icon waiting to be
   clicked. Skipped while open so it doesn't fight the X-morph below. */
@keyframes bar-hop{
  0%,100%{ transform:translateY(0) scaleX(1); }
  35%{ transform:translateY(-3px) scaleX(1.12); }
  65%{ transform:translateY(1px) scaleX(0.94); }
}
.nav-toggle:hover:not(.is-open) span{ animation:bar-hop .7s cubic-bezier(.34,1.56,.64,1) infinite; }
.nav-toggle:hover:not(.is-open) span:nth-child(1){ animation-delay:0s; }
.nav-toggle:hover:not(.is-open) span:nth-child(2){ animation-delay:.09s; }
.nav-toggle:hover:not(.is-open) span:nth-child(3){ animation-delay:.18s; }
/* Open state: bars morph to equal length and colour as they spring into a
   clean X, with a little overshoot rather than a flat linear rotation. */
.nav-toggle.is-open span{ width:20px; background:var(--navy); }
.nav-toggle.is-open span:nth-child(1){ transform:translateY(7px) rotate(45deg); }
.nav-toggle.is-open span:nth-child(2){ opacity:0; transform:scaleX(0); }
.nav-toggle.is-open span:nth-child(3){ transform:translateY(-7px) rotate(-45deg); }
/* A small orange "pop" flash on every toggle click (JS: spawnToggleBurst
   in main.js), reusing the same burst language as the flavour chips. */
.toggle-burst{
  position:absolute; left:50%; top:50%; width:100%; height:100%; border-radius:14px;
  background:var(--orange); opacity:.3; transform:translate(-50%,-50%) scale(.3);
  pointer-events:none; animation:toggle-burst-anim .45s ease-out forwards;
}
@keyframes toggle-burst-anim{ to{ transform:translate(-50%,-50%) scale(1.7); opacity:0; } }
@media (prefers-reduced-motion:reduce){
  .nav-toggle{ transition:border-color .2s ease; }
  .nav-toggle:hover{ transform:translateY(-50%); box-shadow:none; }
  .nav-toggle:active{ transform:translateY(-50%); }
  .nav-toggle span{ transition:opacity .2s ease; }
  .nav-toggle:hover:not(.is-open) span{ animation:none; }
  .toggle-burst{ display:none; }
}

.nav-mobile{
  position:fixed; inset:96px 0 0 0; background:var(--white); z-index:99;
  overflow-y:auto; padding:20px 20px 40px;
  opacity:0; visibility:hidden; transform:translateY(-10px);
  transition:opacity .22s ease, transform .22s ease, visibility 0s linear .22s;
}
@media (min-width:900px){ .nav-mobile{ inset:128px 0 0 0; } }
.nav-mobile.is-open{
  opacity:1; visibility:visible; transform:none;
  transition:opacity .22s ease, transform .22s ease, visibility 0s linear 0s;
}
.nav-mobile li{ opacity:0; transform:translateY(8px); transition:opacity .3s ease, transform .3s ease; }
.nav-mobile.is-open li{ opacity:1; transform:none; }
.nav-mobile.is-open li:nth-child(1){ transition-delay:.04s; }
.nav-mobile.is-open li:nth-child(2){ transition-delay:.08s; }
.nav-mobile.is-open li:nth-child(3){ transition-delay:.12s; }
.nav-mobile.is-open li:nth-child(4){ transition-delay:.16s; }
.nav-mobile.is-open li:nth-child(5){ transition-delay:.2s; }
@media (prefers-reduced-motion:reduce){
  .nav-mobile,.nav-mobile li{ transition:none; }
}
.nav-mobile ul{ display:flex; flex-direction:column; gap:2px; }
.nav-mobile a{ display:block; padding:16px 6px; font-weight:600; font-size:1.05rem; border-bottom:1px solid var(--line); }
.nav-mobile .btn{ margin-top:20px; }

/* ---------- Hero ---------- */
.hero{
  background:linear-gradient(180deg,var(--cream) 0%, #fff 100%);
  overflow:hidden; position:relative;
  padding:48px 0 40px;
}
@media (min-width:900px){ .hero{ padding:70px 0 60px; } }
.hero-grid{ display:grid; gap:36px; align-items:center; }
@media (min-width:900px){ .hero-grid{ grid-template-columns:1.05fr .95fr; gap:48px; } }
.hero-copy .btnrow{ display:flex; flex-wrap:wrap; gap:14px; margin-top:28px; }
.hero-media{
  position:relative; max-width:400px; margin:0 auto;
  transform:perspective(700px) rotateX(var(--tilt-rx,0deg)) rotateY(var(--tilt-ry,0deg));
}
/* The packshot's motion is scroll-progress-driven (assets/js/scroll-motion.js
   initHeroCanister) rather than a looping CSS keyframe — it arrives from the
   right as the visitor scrolls the first half-screen, and unwinds exactly
   backward on scroll-up, rather than idling on a fixed loop. */
.hero-media img{
  position:relative; z-index:1; border-radius:var(--radius-lg); box-shadow:var(--shadow-md); width:100%;
  opacity:var(--rv-o,1);
  transform:perspective(1200px) translateX(var(--rv-x,0px)) rotateY(var(--rv-ry,0deg)) translateY(var(--rv-y,0px)) scale(var(--rv-s,1));
}
.hero-blob{
  position:absolute; inset:-8% -18%; z-index:0; border-radius:50%;
  background:conic-gradient(from 180deg,#17b3a3,#6a4bd6,#d6389a,#ff8a00,#ffc257,#17b3a3);
  filter:blur(70px); opacity:.28;
  animation:blob-spin 22s linear infinite;
}
@keyframes blob-spin{ 0%{ transform:rotate(0deg) scale(1); } 50%{ transform:rotate(180deg) scale(1.08); } 100%{ transform:rotate(360deg) scale(1); } }
@media (prefers-reduced-motion:reduce){ .hero-blob{ animation:none; } }

.hero-copy .eyebrow,.hero-copy .h1,.hero-copy .lead,.hero-copy .btnrow{
  animation:hero-fade-up .7s ease both;
}
.hero-copy .eyebrow{ animation-delay:.05s; }
.hero-copy .h1{ animation-delay:.15s; }
.hero-copy .lead{ animation-delay:.32s; }
.hero-copy .btnrow{ animation-delay:.48s; }
@keyframes hero-fade-up{ from{ opacity:0; transform:translateY(18px); } to{ opacity:1; transform:translateY(0); } }
@media (prefers-reduced-motion:reduce){
  .hero-copy .eyebrow,.hero-copy .h1,.hero-copy .lead,.hero-copy .btnrow{ animation:none; }
}

.hero-hl{ position:relative; color:var(--orange); display:inline-block; }
.hero-hl::after{
  content:""; position:absolute; left:-3px; right:-3px; bottom:.06em; height:.32em; z-index:-1;
  background:var(--gradient-brand); opacity:.3; border-radius:4px;
  transform-origin:left; transform:scaleX(0);
  animation:hl-sweep .9s cubic-bezier(.4,0,.2,1) .85s forwards;
}
@keyframes hl-sweep{ to{ transform:scaleX(1); } }
@media (prefers-reduced-motion:reduce){ .hero-hl::after{ animation:none; transform:scaleX(1); } }
.hero-floatcard{
  position:absolute; z-index:2; left:-18px; bottom:14%; background:var(--white);
  border-radius:var(--radius-md); box-shadow:var(--shadow-md); padding:14px 18px;
  display:flex; flex-direction:column; gap:2px; animation:float-y 4.5s ease-in-out infinite;
}
.hero-floatcard strong{ font-size:1.1rem; color:var(--navy); }
.hero-floatcard span{ font-size:.72rem; color:var(--text-soft); max-width:150px; }
@media (max-width:899px){ .hero-floatcard{ left:auto; right:8px; } }
@keyframes float-y{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-10px); } }
.hero-stats{ display:flex; gap:22px; margin-top:32px; flex-wrap:wrap; }
/* Scroll-progress entrance (initHeroStatsReveal in scroll-motion.js) — pops
   in with a spring overshoot as each stat scrolls into view, reversible on
   scroll-up like every other reveal in that system. Defaults render fully
   visible, so this degrades safely with JS disabled or prefers-reduced-motion. */
.hero-stats > div{
  opacity:var(--rv-o,1);
  transform:translateY(var(--rv-y,0px)) scale(var(--rv-s,1));
  will-change:transform,opacity;
}
.hero-stats div strong{
  display:block; font-size:2.1rem;
  font-family:'Baloo 2','Poppins',system-ui,sans-serif;
  letter-spacing:.01em;
  background:var(--gradient-brand); background-size:300% 100%;
  -webkit-background-clip:text; background-clip:text; color:transparent; -webkit-text-fill-color:transparent;
  animation:cheerful-shimmer 5s ease-in-out infinite;
}
.hero-stats div span{ font-size:.92rem; color:var(--text-soft); }
@media (prefers-reduced-motion:reduce){ .hero-stats div strong{ animation:none; } }
.wave-divider{ display:block; width:100%; height:60px; margin-top:-2px; }

/* ---------- Full-bleed photo hero (interior pages) ---------- */
.hero-photo{
  position:relative; overflow:hidden; color:#fff;
  padding:100px 0 56px; background-size:cover; background-position:center;
}
.hero-photo::before{
  content:""; position:absolute; inset:0;
  background:linear-gradient(180deg, rgba(15,39,64,.55) 0%, rgba(15,39,64,.88) 100%);
}
.hero-photo .container{ position:relative; z-index:1; }
.hero-photo .breadcrumb{ color:#b9c6d3; }
.hero-photo .breadcrumb a{ color:#fff; }
.hero-photo .eyebrow{ color:var(--yellow); }
.hero-photo .eyebrow::before{ background:var(--yellow); }
.hero-photo .h1{ color:#fff; }
.hero-photo .lead{ color:#dbe4ec; }
@media (min-width:900px){ .hero-photo{ padding:140px 0 76px; } }

.hero-accent{
  position:absolute; z-index:2; border-radius:var(--radius-md);
  box-shadow:var(--shadow-md); border:4px solid rgba(255,255,255,.92);
  object-fit:cover; display:none;
}
@media (min-width:820px){
  .hero-accent{ display:block; }
  .hero-accent-tr{ top:26px; right:32px; width:130px; height:130px; transform:rotate(6deg); animation:accent-float-a 6s ease-in-out infinite; }
  .hero-accent-bl{ bottom:26px; right:190px; width:150px; height:110px; transform:rotate(-5deg); animation:accent-float-b 7s ease-in-out infinite; }
}
@keyframes accent-float-a{ 0%,100%{ transform:rotate(6deg) translateY(0); } 50%{ transform:rotate(6deg) translateY(-10px); } }
@keyframes accent-float-b{ 0%,100%{ transform:rotate(-5deg) translateY(0); } 50%{ transform:rotate(-5deg) translateY(8px); } }
@media (prefers-reduced-motion:reduce){ .hero-accent-tr,.hero-accent-bl{ animation:none; } }

/* ---------- Bold full-bleed statement section ---------- */
.statement{
  background:var(--navy); color:#fff; padding:70px 0; text-align:center; overflow:hidden;
}
.statement .stmt-text{
  font-size:clamp(1.8rem,6vw,3.6rem); font-weight:800; letter-spacing:-.02em; line-height:1.08;
  text-transform:uppercase; margin:0; max-width:900px; margin-inline:auto;
}
.statement .stmt-text em{ font-style:normal; color:var(--yellow); }
.statement .eyebrow{ justify-content:center; color:var(--yellow); }
.statement .eyebrow::before{ background:var(--yellow); }

/* ---------- Cards / sections ---------- */
.section-head{ max-width:680px; margin:0 auto 44px; text-align:center; }
.section-head.left{ margin:0 0 44px; text-align:left; }

/* minmax(0, ...) everywhere below, not bare 1fr: a plain `1fr` track's
   minimum size defaults to its content's min-content width, so a single
   long word/badge or a fixed-width child (the product carousel, at
   --c3d-w) can force the whole grid — and the page — wider than the
   viewport on narrow screens. minmax(0,1fr) lets the track actually shrink
   to fit; found while checking the flavour-preview feature on mobile,
   fixed at the source since every .grid-2/3/4 on the site shared it. */
.grid{ display:grid; gap:24px; }
.grid-2{ grid-template-columns:minmax(0,1fr); }
.grid-3{ grid-template-columns:minmax(0,1fr); }
.grid-4{ grid-template-columns:repeat(2,minmax(0,1fr)); }
@media (min-width:700px){
  .grid-2{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .grid-3{ grid-template-columns:repeat(3,minmax(0,1fr)); }
  .grid-4{ grid-template-columns:repeat(4,minmax(0,1fr)); }
}

.card{
  background:var(--white); border:1px solid var(--line); border-radius:var(--radius-md);
  padding:28px; box-shadow:var(--shadow-sm); transition:box-shadow .18s ease;
}
.card:hover{ --hover-y:-4px; box-shadow:var(--shadow-md); }
.card:hover .icon{ --hover-is:1.12; --hover-ir:-6deg; }
.card .icon{
  width:52px; height:52px; border-radius:14px; display:flex; align-items:center; justify-content:center;
  font-size:1.5rem; margin-bottom:16px; background:var(--cream);
}
.card h3{ font-size:1.1rem; }
.card p{ color:var(--text-soft); font-size:.95rem; margin-bottom:0; }

/* ---------- Claymorphism treatment: "What is Puffins?" feature cards ----------
   Scoped to .grid-4 .card only — this exact 4-card layout on index.html and
   why-puffins.html — so the plain .card elsewhere (Contact, Create Your Own)
   is untouched. Soft, puffy, single-tone depth via paired light/dark shadows
   instead of a hard border. Only surface treatment changes here: the custom
   properties driving the scroll-reveal and pointer-tilt system (defined
   earlier in this file) are left completely alone, so that keeps working
   unchanged — this just adds a bigger box-shadow on hover and an inset
   "pressed" shadow on active on top of that, for a tactile, squishy feel. */
.grid-4 .card{
  background:var(--cream); border:none; border-radius:28px; padding:32px 28px;
  box-shadow:
    9px 9px 18px rgba(196,163,112,.28),
    -9px -9px 18px rgba(255,255,255,.95),
    inset 1px 1px 2px rgba(255,255,255,.6),
    inset -2px -2px 4px rgba(196,163,112,.12);
  transition:box-shadow .25s ease;
}
.grid-4 .card:hover{
  box-shadow:
    13px 13px 26px rgba(196,163,112,.32),
    -13px -13px 26px rgba(255,255,255,1),
    inset 1px 1px 2px rgba(255,255,255,.7),
    inset -2px -2px 4px rgba(196,163,112,.1);
}
.grid-4 .card:active{
  --hover-y:1px;
  box-shadow:
    inset 7px 7px 14px rgba(196,163,112,.3),
    inset -7px -7px 14px rgba(255,255,255,.85);
}
.grid-4 .card .icon{
  border-radius:20px;
  box-shadow:
    5px 5px 10px rgba(196,163,112,.25),
    -5px -5px 10px rgba(255,255,255,.9);
}
@media (prefers-reduced-motion:reduce){ .grid-4 .card{ transition:none; } }

.bg-navy{ background:var(--navy); color:var(--white); }
.bg-navy .text-soft{ color:#c7d3de; }
.bg-cream{ background:var(--cream); }

/* Product cards */
.product-card{
  background:var(--white); border:1px solid var(--line); border-radius:var(--radius-lg);
  overflow:hidden; box-shadow:var(--shadow-sm); display:flex; flex-direction:column; height:100%;
}
.product-card .media{ aspect-ratio:4/3; overflow:hidden; background:var(--cream); }
.product-card .media img{ width:100%; height:100%; object-fit:cover; transition:transform .4s ease; }
.product-card:hover .media img{ transform:scale(1.06); }
.product-card:hover{ box-shadow:var(--shadow-md); --hover-y:-4px; }
.product-card{ transition:box-shadow .18s ease; }
.product-card .body{ padding:22px; display:flex; flex-direction:column; gap:10px; flex:1; }
.product-card .badges{ display:flex; gap:8px; flex-wrap:wrap; }
.badge{
  font-size:.72rem; font-weight:700; letter-spacing:.03em; padding:5px 10px; border-radius:999px;
  background:var(--cream); color:var(--navy); border:1px solid var(--line);
}
.badge.orange{ background:#fff1de; color:var(--orange-dk); border-color:#ffdca8; }
.product-card .price{ font-weight:700; color:var(--navy); margin-top:auto; display:flex; align-items:center; justify-content:space-between; gap:10px; }

/* Flavour chips */
.flavor-row{ display:flex; gap:10px; flex-wrap:wrap; }
.flavor-chip{
  padding:10px 16px; border-radius:999px; border:1.5px solid var(--line); font-weight:600; font-size:.88rem;
  background:var(--white); color:var(--text); transition:transform .15s ease, border-color .15s ease, background .15s ease;
}
.flavor-chip:hover{ border-color:var(--orange); transform:translateY(-2px); }
.flavor-chip[aria-pressed="true"]{ border-color:var(--orange); background:#fff1de; color:var(--orange-dk); }
@media (prefers-reduced-motion:reduce){ .flavor-chip:hover{ transform:none; } }
.flavor-chip.soon{ opacity:.7; }
.flavor-chip.soon[aria-pressed="true"]{ opacity:1; }

/* Flavour preview — deliberately loud "world swap" behind the packshot, plus
   a claymorphic identity card. The brief: it should look like the customer's
   world got switched, not like a colour quietly faded. See
   updateFlavorPreview() in main.js for how .flash/.warp/.shake/.punch/.glow/
   .flip-out are all triggered together on a real click; page load just sets
   the end state, no animation to skip for reduced-motion there. */
/* overflow:hidden is load-bearing, not decorative: .flavor-world deliberately
   extends past the stage on every side (see below) to sell a big blurred
   "world," and without clipping here that pokes past the viewport edge and
   forces real page-level horizontal scroll on narrow screens — it did,
   until this was added. The blur (58px) means the clip edge itself is never
   a hard line, so cropping it costs nothing visually. */
.flavor-stage{
  position:relative; overflow:hidden; border-radius:var(--radius-lg);
  --flavor-color:var(--orange);
}
.flavor-world{
  position:absolute; left:-32%; right:-32%; top:-34%; bottom:-6%; z-index:0;
  border-radius:50%; filter:blur(58px); opacity:.4; pointer-events:none;
  background:radial-gradient(circle at 42% 38%, var(--flavor-color) 0%, transparent 68%);
  transform:scale(.8) rotate(0deg);
}
.flavor-stage .flavor-accent-bar, .flavor-stage .carousel3d{ position:relative; z-index:1; }
.flavor-flash{
  position:absolute; inset:0; z-index:2; border-radius:var(--radius-lg);
  background:#fff; opacity:0; pointer-events:none;
}
.flavor-flash.flash{ animation:flavor-flash .35s ease-out; }
@keyframes flavor-flash{ 0%{ opacity:0; } 12%{ opacity:.85; } 100%{ opacity:0; } }
.flavor-world.warp{ animation:world-warp 1s cubic-bezier(.34,1.56,.64,1); }
@keyframes world-warp{
  0%{ transform:scale(.8) rotate(0deg); opacity:.4; }
  30%{ transform:scale(.15) rotate(-22deg); opacity:.06; }
  55%{ transform:scale(1.55) rotate(14deg); opacity:.65; }
  75%{ transform:scale(1.05) rotate(-5deg); opacity:.45; }
  100%{ transform:scale(.8) rotate(0deg); opacity:.4; }
}
.flavor-stage.shake{ animation:flavor-shake .5s cubic-bezier(.36,.07,.19,.97); }
@keyframes flavor-shake{
  0%, 100%{ transform:translate(0,0) rotate(0deg); }
  15%{ transform:translate(-6px,3px) rotate(-1.2deg); }
  30%{ transform:translate(6px,-3px) rotate(1.2deg); }
  45%{ transform:translate(-5px,2px) rotate(-.8deg); }
  60%{ transform:translate(4px,-2px) rotate(.8deg); }
  75%{ transform:translate(-2px,1px) rotate(-.4deg); }
}
.carousel3d.punch{ animation:flavor-punch .55s cubic-bezier(.34,1.56,.64,1); }
@keyframes flavor-punch{
  0%{ transform:scale(1,1); }
  30%{ transform:scale(1.1,.9); }
  55%{ transform:scale(.94,1.08); }
  100%{ transform:scale(1,1); }
}
@media (prefers-reduced-motion:reduce){
  .flavor-flash.flash, .flavor-world.warp, .flavor-stage.shake, .carousel3d.punch{ animation:none; }
}

.flavor-accent-bar{
  height:7px; border-radius:999px; margin-bottom:14px;
  background:var(--orange); transform-origin:left;
}
.flavor-accent-bar.wipe{ animation:accent-wipe .5s cubic-bezier(.4,0,.2,1); }
@keyframes accent-wipe{
  0%{ transform:scaleX(0); box-shadow:0 0 0 0 var(--flavor-color); }
  60%{ box-shadow:0 0 18px 3px var(--flavor-color); }
  100%{ transform:scaleX(1); box-shadow:0 0 0 0 transparent; }
}
@media (prefers-reduced-motion:reduce){ .flavor-accent-bar.wipe{ animation:none; } }

/* Claymorphic identity card — soft, puffy, coloured to match the flavour via
   the inherited --flavor-color custom property and color-mix(), so every
   flavour gets its own "clay" without per-flavour CSS. */
.flavor-preview{
  --flavor-color:var(--orange);
  margin-top:16px; padding:16px 18px; border-radius:24px;
  background:color-mix(in srgb, var(--flavor-color) 16%, #fbf7f1);
  box-shadow:
    9px 9px 20px color-mix(in srgb, var(--flavor-color) 38%, transparent),
    -8px -8px 18px rgba(255,255,255,.85),
    inset 1px 1px 2px rgba(255,255,255,.6),
    inset -6px -6px 14px color-mix(in srgb, var(--flavor-color) 20%, transparent);
  overflow:hidden; perspective:700px;
  transition:background .45s ease, box-shadow .45s ease;
}
.flavor-preview.glow{ animation:clay-squish .55s cubic-bezier(.34,1.56,.64,1); }
@keyframes clay-squish{
  0%{ transform:scale(1,1); }
  35%{ transform:scale(1.05,.93); }
  65%{ transform:scale(.96,1.05); }
  100%{ transform:scale(1,1); }
}
@media (prefers-reduced-motion:reduce){ .flavor-preview.glow{ animation:none; } }
.flavor-preview-inner{ display:flex; align-items:center; gap:12px; transform-style:preserve-3d; }
.flavor-preview-inner.flip-out{ animation:preview-flip .55s cubic-bezier(.4,0,.2,1); }
@keyframes preview-flip{
  0%{ transform:rotateX(0deg) scale(1); }
  50%{ transform:rotateX(-150deg) scale(.82); }
  100%{ transform:rotateX(-360deg) scale(1); }
}
@media (prefers-reduced-motion:reduce){ .flavor-preview-inner.flip-out{ animation:none; } }
.flavor-preview-dot{
  width:28px; height:28px; border-radius:50%; flex:none;
  background:color-mix(in srgb, var(--flavor-color) 88%, #fff 4%);
  box-shadow:
    3px 3px 7px color-mix(in srgb, var(--flavor-color) 55%, transparent),
    -3px -3px 7px rgba(255,255,255,.85),
    inset -3px -3px 5px color-mix(in srgb, var(--flavor-color) 45%, #000 12%),
    inset 2px 2px 4px rgba(255,255,255,.7);
}
.flavor-preview strong{ display:block; color:var(--navy); font-size:.94rem; }
.flavor-preview-tagline{ display:block; color:var(--text-soft); font-size:.82rem; }

/* Flavour-coloured (plus white/yellow) puffs that scatter and tumble from a
   clicked chip — see spawnFlavorConfetti() in main.js. position:fixed so
   they escape the chip's own overflow:hidden (used for the ripple burst
   below) and the page's layout entirely; each is removed on animationend. */
.flavor-confetti{
  position:fixed; border-radius:50%;
  transform:translate(-50%,-50%) rotate(0deg); pointer-events:none; z-index:80;
  animation:confetti-puff .75s cubic-bezier(.2,.7,.3,1) forwards;
}
@keyframes confetti-puff{
  0%{ transform:translate(-50%,-50%) scale(0) rotate(0deg); opacity:1; }
  25%{ transform:translate(calc(-50% + var(--dx) * .35), calc(-50% + var(--dy) * .35)) scale(1.25) rotate(calc(var(--rot) * .3)); opacity:1; }
  100%{ transform:translate(calc(-50% + var(--dx)), calc(-50% + var(--dy) + 40px)) scale(.3) rotate(var(--rot)); opacity:0; }
}
@media (prefers-reduced-motion:reduce){ .flavor-confetti{ display:none; } }

/* Steps / timeline */
.steps{ display:grid; gap:22px; grid-template-columns:1fr; counter-reset:step; }
@media (min-width:700px){ .steps{ grid-template-columns:repeat(5,1fr); } }
.step{ text-align:center; }
.step .num{
  counter-increment:step; content:counter(step);
  width:44px; height:44px; border-radius:50%; background:var(--gradient-brand);
  color:#fff; display:flex; align-items:center; justify-content:center; font-weight:700; margin:0 auto 12px;
}
.step .num::before{ content:counter(step); }

/* ---------- Believe/Blend/Build/Belong/Bloom — neo-brutalist treatment ----
   Deliberately raw, not the soft cream/shadow language the rest of the site
   uses: flat un-gradiented colour per card (cycled from the same five
   --gradient-brand stops, just solid instead of blended), thick hairline-
   free borders, a hard offset shadow with zero blur instead of --shadow-md's
   soft one, blocky square number tags instead of circles, and a slight
   per-card rotation (alternating left/right) so the row reads as pasted-on
   rather than machine-aligned. Straightens and "lifts" on hover — the
   shadow grows instead of softening. Still rides the existing .step
   scroll-reveal from initCascadeReveal() in scroll-motion.js; only the
   surface changed, not the entrance mechanics. */
.steps-brutalist{ gap:26px 22px; }
/* transform composes with the .step entry reveal from initCascadeReveal()
   (perspective/rotateX/translateY/scale via --rv-*), not replaces it — this
   is one shared `transform` property, so the static brutalist tilt (rotate)
   is appended onto the same chain rather than overwriting the scroll-in
   animation. */
.steps-brutalist .step{
  text-align:left; background:var(--white); border:3px solid var(--navy);
  padding:22px 20px 24px; box-shadow:7px 7px 0 var(--navy);
  transform:perspective(1200px) rotateX(var(--rv-rx,0deg)) translateY(var(--rv-y,0px)) scale(var(--rv-s,1)) rotate(var(--step-rot,0deg));
  transition:transform .18s ease, box-shadow .18s ease;
}
.steps-brutalist .step:nth-child(odd){ --step-rot:-1.4deg; }
.steps-brutalist .step:nth-child(even){ --step-rot:1.4deg; }
.steps-brutalist .step:hover{
  transform:perspective(1200px) rotateX(var(--rv-rx,0deg)) translateY(calc(var(--rv-y,0px) - 3px)) scale(var(--rv-s,1)) rotate(0deg) translateX(-3px);
  box-shadow:11px 11px 0 var(--navy);
}
.steps-brutalist .step:nth-child(1) .num{ background:#17b3a3; }
.steps-brutalist .step:nth-child(2) .num{ background:#6a4bd6; color:#fff; }
.steps-brutalist .step:nth-child(3) .num{ background:#d6389a; color:#fff; }
.steps-brutalist .step:nth-child(4) .num{ background:var(--orange); }
.steps-brutalist .step:nth-child(5) .num{ background:var(--yellow); }
.steps-brutalist .step .num{
  width:40px; height:40px; border-radius:0; border:3px solid var(--navy);
  color:var(--navy); font-weight:900; font-size:1.05rem;
  box-shadow:3px 3px 0 var(--navy); margin:0 0 16px;
}
.steps-brutalist .step h3{
  font-family:'Baloo 2','Poppins',system-ui,sans-serif; text-transform:uppercase;
  font-weight:800; letter-spacing:.02em; font-size:1.2rem!important;
  color:var(--navy); margin-bottom:8px;
}
.steps-brutalist .step p{
  font-size:.92rem!important; color:var(--text)!important; font-weight:500; line-height:1.5;
}
@media (prefers-reduced-motion:reduce){ .steps-brutalist .step{ transition:none; } }
@media (max-width:479px){ .steps-brutalist .step{ transform:none; } }

/* Team grid */
.team-grid{ display:grid; gap:22px; grid-template-columns:repeat(2,1fr); }
@media (min-width:700px){ .team-grid{ grid-template-columns:repeat(3,1fr); } }
@media (min-width:1000px){ .team-grid{ grid-template-columns:repeat(5,1fr); } }
/* ---------- Team cards: skeuomorphic ID badges ----------
   Reads as a physical laminated badge clipped to a lanyard, not a flat
   web card: a warm paper-toned gradient (not a flat fill) with an inset
   highlight along the top edge and an inset shadow along the bottom
   (::before is the metal clip, ::after the rivet) simulate a raised,
   slightly domed surface lit from above; the outer shadow is the badge
   casting light onto the page behind it. transform/opacity are still
   owned by the shared .card,.product-card,.team-card rule further down
   (scroll-reveal + pointer-tilt + hover-lift all compose there) — only
   the surface treatment changes here. */
.team-card{
  position:relative; margin-top:10px;
  background:linear-gradient(160deg, #fffdf9 0%, #f7efdd 55%, #eedfc0 100%);
  border:1px solid #e4d4ac; border-radius:16px;
  padding:28px 18px 20px; text-align:center;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.85),
    inset 0 -10px 16px -12px rgba(120,90,40,.35),
    0 14px 24px -10px rgba(120,90,40,.28),
    0 2px 5px rgba(120,90,40,.14);
  transition:box-shadow .18s ease;
}
/* lanyard clip + rivet, centred above the badge */
.team-card::before{
  content:""; position:absolute; top:-9px; left:50%; transform:translateX(-50%);
  width:30px; height:13px; border-radius:6px 6px 2px 2px;
  background:linear-gradient(180deg,#e4e9ed,#9aa4b0);
  box-shadow:0 2px 3px rgba(15,39,64,.3), inset 0 1px 0 rgba(255,255,255,.7);
}
.team-card::after{
  content:""; position:absolute; top:-2px; left:50%; transform:translateX(-50%);
  width:5px; height:5px; border-radius:50%;
  background:#69727d; box-shadow:inset 0 1px 1px rgba(0,0,0,.5);
}
.team-card:hover{
  --hover-y:-4px;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.85),
    inset 0 -10px 16px -12px rgba(120,90,40,.35),
    0 20px 30px -10px rgba(120,90,40,.34),
    0 3px 6px rgba(120,90,40,.16);
}
.team-card img{
  width:88px; height:88px; border-radius:50%; object-fit:cover; margin:0 auto 14px;
  padding:4px; box-sizing:content-box;
  background:conic-gradient(from 180deg,#fff2d2,#d9b466,#fff2d2 50%,#b9873a,#fff2d2);
  box-shadow:0 4px 9px -2px rgba(120,90,40,.4), inset 0 0 0 3px #fffdf9;
  /* Scroll-synced pop-and-spin, driven by the same progress value as the
     card's own fade/lift — see initTeamReveal() in scroll-motion.js. No
     transition here for the same reason as the rest of the scroll-progress
     system: this must stay locked exactly to scroll position, not animate
     on a timer. */
  opacity:var(--photo-o,1);
  transform:scale(var(--photo-s,1)) rotate(var(--photo-r,0deg)) translateY(var(--photo-y,0px));
  will-change:transform,opacity;
}
.team-card h3{ font-size:1rem; margin-bottom:2px; text-shadow:0 1px 0 rgba(255,255,255,.7); }
.team-card .role{ font-size:.78rem; font-weight:700; color:var(--orange-dk); margin-bottom:8px; }
.team-card .bio{ font-size:.85rem; color:var(--text-soft); margin-bottom:0; }

/* Testimonials */
.quote-card{ background:var(--white); border:1px solid var(--line); border-radius:var(--radius-md); padding:26px; box-shadow:var(--shadow-sm); }
.quote-card .stars{ color:var(--orange); letter-spacing:2px; margin-bottom:10px; }
.quote-card .who{ font-weight:700; margin-top:14px; font-size:.9rem; }
.quote-card .who span{ display:block; font-weight:400; color:var(--text-soft); font-size:.8rem; }

/* Newsletter / CTA band */
.cta-band{
  background:var(--navy); color:var(--white); border-radius:var(--radius-lg);
  padding:44px 28px; text-align:center; position:relative; overflow:hidden;
}
.cta-band::before{
  content:""; position:absolute; inset:auto -10% -60% -10%; height:220px; background:var(--gradient-brand); filter:blur(60px); opacity:.35;
}
.cta-band .btnrow{ display:flex; gap:14px; justify-content:center; flex-wrap:wrap; margin-top:22px; position:relative; }

/* Forms */
.form-field{ margin-bottom:18px; }
.form-field label{ display:block; font-weight:600; font-size:.9rem; margin-bottom:6px; }
.form-field input,.form-field select,.form-field textarea{
  width:100%; padding:13px 14px; border-radius:var(--radius-sm); border:1.5px solid var(--line);
  font-family:inherit; font-size:.96rem; background:var(--white); color:var(--text);
}
.form-field input:focus,.form-field select:focus,.form-field textarea:focus{
  outline:none; border-color:var(--orange); box-shadow:0 0 0 3px rgba(255,138,0,.18);
}
.form-field .hint{ font-size:.78rem; color:var(--text-soft); margin-top:5px; }
.form-row{ display:grid; gap:16px; grid-template-columns:1fr; }
@media (min-width:640px){ .form-row{ grid-template-columns:1fr 1fr; } }
.radio-group{ display:flex; gap:16px; flex-wrap:wrap; }
.radio-group label{ display:flex; align-items:center; gap:8px; font-weight:500; font-size:.92rem; }
.form-note{ font-size:.82rem; color:var(--text-soft); }
.form-success{
  display:none; background:#e9f8ee; border:1px solid #b7e8c6; color:#1a6b34;
  padding:16px 18px; border-radius:var(--radius-sm); font-weight:600; margin-bottom:18px;
}
.form-success.show{ display:block; }
.honeypot{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }

/* FAQ accordion */
.accordion-item{ border-bottom:1px solid var(--line); }
.accordion-q{
  width:100%; text-align:left; background:none; border:0; padding:20px 4px; font-weight:600; font-size:1rem;
  display:flex; align-items:center; justify-content:space-between; gap:16px; color:var(--text);
}
.accordion-q .plus{ font-size:1.3rem; color:var(--orange); transition:transform .2s ease; flex:none; }
.accordion-item[data-open="true"] .plus{ transform:rotate(45deg); }
.accordion-a{ max-height:0; overflow:hidden; transition:max-height .25s ease; }
.accordion-item[data-open="true"] .accordion-a{ max-height:400px; }
.accordion-a p{ padding:0 4px 20px; color:var(--text-soft); }

/* Placeholder / coming-soon notice used for regulated info pending SIF approval */
.pending{
  border:1.5px dashed #ffcf8f; background:#fff8ec; color:#8a5a00;
  border-radius:var(--radius-sm); padding:14px 16px; font-size:.88rem; font-weight:500;
}
.pending strong{ color:var(--orange-dk); }

/* Nutrition table */
.nutri-table{ width:100%; border-collapse:collapse; font-size:.92rem; }
.nutri-table th,.nutri-table td{ text-align:left; padding:10px 12px; border-bottom:1px solid var(--line); }
.nutri-table th{ color:var(--text-soft); font-weight:600; width:60%; }

/* Tabs (product detail) */
.tabs-nav{ display:flex; gap:6px; overflow-x:auto; border-bottom:1px solid var(--line); margin-bottom:24px; }
.tabs-nav button{
  padding:12px 18px; border:0; background:none; font-weight:600; color:var(--text-soft); white-space:nowrap;
  border-bottom:3px solid transparent;
}
.tabs-nav button[aria-selected="true"]{ color:var(--navy); border-color:var(--orange); }
.tab-panel{ display:none; }
.tab-panel.active{ display:block; }

/* Breadcrumb */
.breadcrumb{ font-size:.85rem; color:var(--text-soft); margin-bottom:18px; }
.breadcrumb a:hover{ color:var(--orange-dk); }

/* Footer */
.site-footer{ background:var(--navy); color:#dfe6ec; padding:64px 0 28px; }
.footer-grid{ display:grid; gap:36px; grid-template-columns:1fr; margin-bottom:40px; }
@media (min-width:800px){ .footer-grid{ grid-template-columns:1.4fr 1fr 1fr 1fr; } }
.footer-brand{ display:flex; align-items:center; gap:10px; font-weight:800; font-size:1.2rem; color:#fff; margin-bottom:14px; }
.footer-brand img{ height:30px; }
.footer-tagline{
  font-size:clamp(1.4rem,3.2vw,1.9rem); font-weight:800; letter-spacing:-.01em; text-transform:uppercase;
  color:#fff; margin:0 0 20px; line-height:1.15;
}
.footer-tagline span{ color:var(--yellow); }
.site-footer h4{ color:#fff; font-size:.85rem; letter-spacing:.06em; text-transform:uppercase; margin-bottom:16px; }
.site-footer ul li{ margin-bottom:10px; }
.site-footer a{ color:#c3ceda; font-size:.92rem; }
.site-footer a:hover{ color:var(--yellow); }
.footer-social{ display:flex; gap:12px; margin-top:16px; }
.footer-social a{
  width:38px; height:38px; border-radius:50%; border:1px solid #33475f; display:flex; align-items:center;
  justify-content:center; font-size:1rem;
}
.footer-social a:hover{ background:var(--orange); border-color:var(--orange); color:var(--navy); }
.footer-bottom{
  border-top:1px solid #24405e; padding-top:24px; display:flex; flex-wrap:wrap; gap:14px;
  align-items:center; justify-content:space-between; font-size:.82rem; color:#93a3b3;
}
.footer-bottom ul{ display:flex; gap:18px; flex-wrap:wrap; }

/* Utility */
.mt-0{ margin-top:0; } .mb-0{ margin-bottom:0; }
.text-center{ text-align:center; }
.text-soft{ color:var(--text-soft); }
.skip-link{
  position:absolute; left:-9999px; top:auto; background:var(--navy); color:#fff; padding:12px 18px; z-index:1000; border-radius:8px;
}
.skip-link:focus{ left:16px; top:16px; }

/* Legal pages */
.prose{ max-width:760px; }
.prose h2{ margin-top:2em; font-size:1.35rem; }
.prose h3{ font-size:1.1rem; margin-top:1.6em; }
.prose ul{ list-style:disc; padding-left:1.3em; margin-bottom:1em; }
.prose li{ margin-bottom:.4em; }
.prose .updated{ color:var(--text-soft); font-size:.9rem; }

/* 404 */
.error-page{ text-align:center; padding:110px 0 90px; }
.error-page .code{ font-size:clamp(4rem,14vw,7rem); font-weight:800; color:var(--orange); line-height:1; }

/* ---------- Scroll-progress motion ----------
   Written by assets/js/scroll-motion.js as a continuous function of scroll
   position (see that file's header comment) — every --rv-* custom property
   below is recomputed every frame from live geometry, never toggled once
   and left. Deliberately NO `transition` on any of these rules: a
   transition would race the next scroll update and lag behind the
   finger/wheel, which breaks "the animation should remain exactly at that
   halfway point." Any "spring"/overshoot feel comes from easing PROGRESS
   itself in JS (still a pure function of scroll position), not from a
   CSS-timed transition. Custom properties default to their fully-resolved,
   fully-visible values, so this degrades safely with JS disabled or under
   prefers-reduced-motion (scroll-motion.js simply never registers anything
   in that case, and these elements render at the defaults below). */
.section-head, .quote-card, .step, .cta-band, .stmt-text{
  opacity:var(--rv-o,1);
  transform:perspective(1200px) rotateX(var(--rv-rx,0deg)) translateY(var(--rv-y,0px)) scale(var(--rv-s,1));
  will-change:transform,opacity;
}
/* .card / .product-card / .team-card also carry pointer-driven hover tilt
   (--tilt-*, initTiltEffect in main.js) and a CSS-only hover lift
   (--hover-y, set by the :hover rules above) — all three sources compose
   into one transform here instead of any of them overwriting another. */
.card, .product-card, .team-card{
  opacity:var(--rv-o,1);
  transform:
    perspective(1200px)
    rotateX(calc(var(--rv-rx,0deg) + var(--tilt-rx,0deg)))
    rotateY(var(--tilt-ry,0deg))
    translateY(calc(var(--rv-y,0px) + var(--tilt-ty,0px) + var(--hover-y,0px)))
    scale(var(--rv-s,1));
  will-change:transform,opacity;
}
.card .icon{
  opacity:var(--rv-io,1);
  transform:scale(calc(var(--rv-is,1) * var(--hover-is,1))) rotate(var(--hover-ir,0deg));
}

/* ---------- Our Story: 3D cascade ---------- */
.story-reveal > p{
  opacity:var(--rv-o,1);
  filter:blur(var(--rv-b,0px));
  transform:perspective(1400px) rotateX(var(--rv-rx,0deg)) translateY(var(--rv-y,0px)) scale(var(--rv-s,1));
  will-change:transform,opacity,filter;
}
.story-reveal > p:nth-child(odd){ transform-origin:0% 100%; }
.story-reveal > p:nth-child(even){ transform-origin:100% 100%; }
.story-reveal-quote{
  opacity:var(--rv-o,1);
  box-shadow:var(--rv-shadow,none);
  transform:perspective(1400px) rotateX(var(--rv-rx,0deg)) rotateZ(var(--rv-rz,0deg)) translateY(var(--rv-y,0px)) scale(var(--rv-s,1));
  transform-origin:50% 100%;
  will-change:transform,opacity,box-shadow;
}

/* ---------- Header scroll state ---------- */
.site-header.is-scrolled{ box-shadow:0 4px 20px rgba(15,39,64,.08); }

/* ---------- Image carousel (The Crunch) — auto-advancing slide carousel, JS-driven ---------- */
.image-carousel{
  position:relative; overflow:hidden; border-radius:var(--radius-lg); box-shadow:var(--shadow-md);
  aspect-ratio:4/3; background:var(--navy-80);
}
.image-carousel-track{
  display:flex; width:100%; height:100%;
  transition:transform .7s cubic-bezier(.65,0,.35,1);
}
.image-carousel-slide{ flex:0 0 100%; width:100%; height:100%; }
.image-carousel-slide img{ width:100%; height:100%; object-fit:cover; display:block; }
.image-carousel-dots{
  position:absolute; left:0; right:0; bottom:16px; z-index:2;
  display:flex; justify-content:center; gap:8px;
}
.image-carousel-dot{
  width:9px; height:9px; padding:0; border:none; border-radius:50%;
  background:rgba(255,255,255,.45); cursor:pointer;
  transition:background .2s ease, transform .2s ease;
}
.image-carousel-dot:hover{ background:rgba(255,255,255,.7); }
.image-carousel-dot.is-active{ background:var(--white); transform:scale(1.3); }
@media (prefers-reduced-motion:reduce){
  .image-carousel-track{ transition:none; }
}

/* ---------- Health pulse (animated "health-loving snack" showcase, CSS/SVG only, no video file) ---------- */
.health-pulse{ position:relative; height:240px; display:flex; align-items:center; justify-content:center; }
.health-pulse .pulse-line{ width:100%; height:110px; overflow:visible; }
.health-pulse .pulse-line path{
  fill:none; stroke:var(--orange); stroke-width:3.5; stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:700; stroke-dashoffset:700;
  animation:pulse-draw 3.6s ease-in-out infinite;
}
@keyframes pulse-draw{
  0%{ stroke-dashoffset:700; }
  55%{ stroke-dashoffset:0; }
  100%{ stroke-dashoffset:0; }
}
.health-pulse .pulse-badges{ position:absolute; inset:0; }
.health-pulse .pulse-badge{
  position:absolute; display:inline-flex; align-items:center; gap:8px;
  background:var(--white); border:1px solid var(--line); border-radius:999px;
  padding:8px 14px; font-weight:700; font-size:.82rem; color:var(--navy);
  box-shadow:var(--shadow-sm); opacity:0;
  animation:pulse-badge-in 4.8s ease-in-out infinite;
  animation-delay:var(--d, 0s);
}
.health-pulse .pulse-badge em{ font-style:normal; color:var(--text-soft); font-weight:600; }
.health-pulse .pulse-badge:nth-child(1){ top:4%; left:0; }
.health-pulse .pulse-badge:nth-child(2){ top:64%; left:10%; }
.health-pulse .pulse-badge:nth-child(3){ top:0; right:2%; }
.health-pulse .pulse-badge:nth-child(4){ top:62%; right:0; }
@keyframes pulse-badge-in{
  0%{ opacity:0; transform:translateY(10px) scale(.9); }
  8%{ opacity:1; transform:translateY(0) scale(1); }
  25%{ opacity:1; transform:translateY(0) scale(1); }
  33%{ opacity:0; transform:translateY(-6px) scale(.95); }
  100%{ opacity:0; }
}
@media (max-width:899px){ .health-pulse{ height:280px; } }
@media (prefers-reduced-motion:reduce){
  .health-pulse{ height:auto; display:block; }
  .health-pulse .pulse-line path{ animation:none; stroke-dashoffset:0; }
  .health-pulse .pulse-badges{ position:static; display:flex; flex-wrap:wrap; justify-content:center; gap:10px; margin-top:14px; }
  .health-pulse .pulse-badge{ position:static; opacity:1; animation:none; transform:none; }
}

/* ---------- Trust marquee ---------- */
/* overflow-x only: clips the ticker text's infinite horizontal scroll. */
.marquee{ position:relative; overflow-x:hidden; border-top:1px solid var(--line); border-bottom:1px solid var(--line); background:var(--cream); }
.marquee-track{
  display:flex; width:max-content; gap:48px; padding:22px 0; animation:marquee-scroll 26s linear infinite;
}
.marquee:hover .marquee-track{ animation-play-state:paused; }
.marquee-track span{
  display:inline-flex; align-items:center; gap:10px; font-weight:700; font-size:.95rem; color:var(--navy);
  white-space:nowrap; letter-spacing:.02em;
}
.marquee-track span::before{ content:"●"; color:var(--orange); font-size:.5rem; }
@keyframes marquee-scroll{ from{ transform:translateX(0); } to{ transform:translateX(-50%); } }
@media (prefers-reduced-motion:reduce){ .marquee-track{ animation:none; } }

/* ==========================================================================
   POLISH PASS 2 — page-load fade, scroll progress, magnetic/tilt interactions,
   torn-edge divider, flavour-chip burst, and small-screen refinements.
   ========================================================================== */

/* ---------- Page load fade-in ---------- */
body{ animation:page-fade-in .5s ease both; }
@keyframes page-fade-in{ from{ opacity:0; } to{ opacity:1; } }
@media (prefers-reduced-motion:reduce){ body{ animation:none; } }

/* ---------- Scroll progress bar ---------- */
.scroll-progress{
  position:fixed; top:0; left:0; height:3px; width:100%; z-index:200;
  background:var(--gradient-brand); background-size:200% 100%;
  transform:scaleX(0); transform-origin:left; pointer-events:none;
}
@media (prefers-reduced-motion:reduce){ .scroll-progress{ display:none; } }

/* ---------- Magnetic buttons ---------- */
.btn.is-magnetic{
  --mx:0px; --my:0px;
  transform:translate(var(--mx),var(--my));
  transition:transform .35s cubic-bezier(.22,1,.36,1), box-shadow .15s ease, background .15s ease;
}
.btn.is-magnetic:active{ transform:translate(var(--mx),var(--my)) scale(.97); transition:transform .1s ease; }

/* ---------- Button shine sweep ---------- */
.btn-primary,.btn-light{ position:relative; overflow:hidden; }
.btn-primary::before,.btn-light::before{
  content:""; position:absolute; top:0; left:-60%; width:35%; height:100%;
  background:linear-gradient(120deg, transparent, rgba(255,255,255,.6), transparent);
  transform:skewX(-20deg); transition:left .55s ease; pointer-events:none;
}
.btn-primary:hover::before,.btn-light:hover::before{ left:130%; }
@media (prefers-reduced-motion:reduce){ .btn-primary::before,.btn-light::before{ display:none; } }

/* ---------- Tilt (3D hover) on cards + hero media ---------- */
.tilt-target{ transition:transform .2s ease-out; will-change:transform; }

/* ---------- Hero cursor-reactive glow ----------
   Shifted via margin, not transform: .hero-blob already has a running
   `blob-spin` transform animation, which would silently win over (and hide)
   a second transform declared here. */
@media (hover:hover) and (pointer:fine){
  .hero.has-glow .hero-blob{
    margin-left:calc((var(--mx, 50%) - 50%) * .3);
    margin-top:calc((var(--my, 50%) - 50%) * .3);
    transition:margin .6s ease;
  }
}

/* ---------- Torn / kettle-cut edge under the home hero ---------- */
.hero::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:14px; pointer-events:none;
  background:
    linear-gradient(-45deg, var(--cream) 7px, transparent 0) 0 bottom,
    linear-gradient(45deg, var(--cream) 7px, transparent 0) 0 bottom;
  background-repeat:repeat-x; background-size:14px 14px;
}

/* ---------- Flavour chip click burst ---------- */
.flavor-chip{ position:relative; overflow:hidden; }
.chip-burst{
  position:absolute; border-radius:50%; background:var(--orange); opacity:.45;
  transform:translate(-50%,-50%) scale(0); pointer-events:none;
  animation:chip-burst-anim .55s ease-out forwards;
}
@keyframes chip-burst-anim{ to{ transform:translate(-50%,-50%) scale(5.5); opacity:0; } }
@media (prefers-reduced-motion:reduce){ .chip-burst{ display:none; } }

/* ---------- Small-screen refinements ---------- */
@media (max-width:479px){
  .container{ padding:0 16px; }
  .grid-4{ grid-template-columns:1fr; }
  .hero-stats{ gap:16px 22px; }
  .team-card img{ width:76px; height:76px; }
}
.tab-panel{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
@media (max-width:560px){
  .health-pulse{ height:auto; display:block; }
  .health-pulse .pulse-line path{ animation:none; stroke-dashoffset:0; }
  .health-pulse .pulse-badges{ position:static; display:flex; flex-wrap:wrap; justify-content:center; gap:10px; margin-top:14px; }
  .health-pulse .pulse-badge{ position:static; opacity:1; animation:none; transform:none; }
}

/* ==========================================================================
   REDESIGN SPEC PASS — dynamic feel, 3D swipe carousels, product count/label,
   showcase video stub, swipeable flavour row.
   ========================================================================== */

/* ---------- Smoother cross-page navigation where supported (no-op elsewhere) ---------- */
@view-transition{ navigation:auto; }

/* ---------- Product category label + live count badge ---------- */
.category-head{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; justify-content:center; }
.product-count{
  display:inline-flex; align-items:center; font-size:.78rem; font-weight:700; letter-spacing:.03em;
  padding:5px 12px; border-radius:999px; background:var(--cream); color:var(--orange-dk); border:1px solid #ffdca8;
}

/* ---------- Homepage product-range video showcase ----------
   Source is a square (1080x1080) brand video — aspect-ratio:1/1 with
   object-fit:contain (not cover/16:9) so its baked-in text isn't cropped,
   width-capped so it doesn't dominate the full container on wide screens. */
.product-showcase{ position:relative; }
.product-showcase [hidden]{ display:none; }
.showcase-video{
  width:100%; max-width:480px; margin:0 auto; display:block; aspect-ratio:1/1;
  object-fit:contain; background:var(--navy-80);
  border-radius:var(--radius-lg); box-shadow:var(--shadow-md);
}

/* ---------- Swipeable flavour row on narrow screens (keeps every option visible, no carousel hiding) ---------- */
@media (max-width:480px){
  .flavor-row{ flex-wrap:nowrap; overflow-x:auto; scroll-snap-type:x proximity; -webkit-overflow-scrolling:touch; padding-bottom:6px; }
  .flavor-row .flavor-chip{ scroll-snap-align:start; flex:none; }
}

/* ---------- 3D swipe carousel (product gallery, testimonials) ---------- */
.carousel3d{ position:relative; --c3d-w:min(72%,380px); }
.carousel3d-viewport{
  position:relative; height:var(--c3d-h,320px); perspective:1100px; overflow:hidden;
  touch-action:pan-y;
}
.carousel3d-item{
  position:absolute; top:0; left:50%; width:var(--c3d-w); margin-left:calc(var(--c3d-w) / -2);
  transition:transform .45s cubic-bezier(.22,1,.36,1), opacity .45s ease, filter .45s ease;
  will-change:transform,opacity,filter; cursor:grab; user-select:none; -webkit-user-select:none;
}
.carousel3d-viewport.is-dragging .carousel3d-item{ transition:none; cursor:grabbing; }
.carousel3d-item img{
  /* contain, not cover: the product gallery mixes a tall portrait packshot
     with landscape lifestyle shots in the same carousel — cover cropped the
     packshot's top (logo) and bottom off entirely at a fixed 4:3 box. A
     square contain box with a cream backdrop shows every photo in full,
     letterboxed instead of cropped. */
  width:100%; display:block; aspect-ratio:1/1; object-fit:contain; background:var(--cream);
  border-radius:var(--radius-lg); box-shadow:var(--shadow-md); pointer-events:none;
}
.carousel3d-nav{ display:flex; align-items:center; justify-content:center; gap:14px; margin-top:18px; }
.carousel3d-btn{
  width:40px; height:40px; border-radius:50%; border:1px solid var(--line); background:var(--white);
  font-size:1.1rem; line-height:1; color:var(--navy); display:flex; align-items:center; justify-content:center;
  transition:background .15s ease;
}
.carousel3d-btn:hover:not(:disabled){ background:var(--cream); }
.carousel3d-btn:disabled{ opacity:.35; cursor:default; }
.carousel3d-dots{ display:flex; align-items:center; gap:8px; }
.carousel3d-dot{ width:8px; height:8px; padding:0; border:0; border-radius:50%; background:var(--line); transition:width .2s ease, background .2s ease; }
.carousel3d-dot.is-active{ width:22px; border-radius:5px; background:var(--orange); }
@media (prefers-reduced-motion:reduce){
  .carousel3d-item{ transition:opacity .2s ease; }
}

/* ---------- "Puff" chat assistant (site-wide) ----------
   Built by initAssistant() in main.js — injected on every page, not
   hardcoded per-page markup. Uses the Puff mascot (assistantIconMarkup in
   main.js) — same artwork as the nav logo (assets/img/brand/puff-mascot.png,
   the .brand-mark img in every header) — so the assistant is visibly Puff.
   Rule-based Q&A over
   assets/js/assistant-data.js + live product data — see that file's header
   comment for why it never invents regulated figures. */
.assistant-launcher{
  position:fixed; right:20px; bottom:20px; z-index:150; width:60px; height:60px; border-radius:50%;
  background:transparent; border:0; padding:0; box-shadow:var(--shadow-md);
  display:flex; align-items:center; justify-content:center; opacity:1;
  transition:transform .15s ease, opacity .2s ease;
}
.assistant-launcher:hover{ transform:translateY(-2px) scale(1.05); }
.assistant-icon{ width:100%; height:100%; object-fit:cover; border-radius:50%; animation:chat-icon-bob 2.6s ease-in-out infinite; }
@keyframes chat-icon-bob{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-2px); } }
.assistant-launcher .assistant-ping{
  position:absolute; top:-2px; right:-2px; width:14px; height:14px; border-radius:50%;
  background:var(--orange); border:2px solid var(--white);
}
.assistant-launcher[aria-expanded="true"] .assistant-ping{ display:none; }

.assistant-panel{
  position:fixed; right:20px; bottom:90px; z-index:150; width:340px; max-width:calc(100vw - 32px);
  height:min(560px, calc(100vh - 110px)); background:var(--white); border-radius:var(--radius-lg);
  box-shadow:var(--shadow-md); border:1px solid var(--line); display:flex; flex-direction:column;
  overflow:hidden; opacity:0; transform:translateY(12px) scale(.97); pointer-events:none;
  transition:opacity .18s ease, transform .18s ease;
}
.assistant-panel.is-open{ opacity:1; transform:translateY(0) scale(1); pointer-events:auto; }

.assistant-head{
  background:var(--navy); color:var(--white); padding:14px 16px; display:flex; align-items:center; gap:10px; flex-shrink:0;
}
.assistant-head .assistant-avatar{ width:34px; height:34px; flex-shrink:0; }
.assistant-head .assistant-avatar .assistant-icon{ animation:chat-icon-bob 2.6s ease-in-out infinite; }
.assistant-head strong{ display:block; font-size:.96rem; }
.assistant-head span{ display:block; font-size:.76rem; color:#cfe0ee; }
.assistant-close{
  margin-left:auto; background:transparent; border:0; color:var(--white); font-size:1.3rem; line-height:1;
  width:28px; height:28px; border-radius:50%; display:flex; align-items:center; justify-content:center;
}
.assistant-close:hover{ background:rgba(255,255,255,.15); }

.assistant-messages{ flex:1; overflow-y:auto; padding:14px 16px; display:flex; flex-direction:column; gap:10px; }
.assistant-msg{ max-width:86%; padding:9px 13px; border-radius:var(--radius-md); font-size:.9rem; line-height:1.45; }
.assistant-msg.bot{ align-self:flex-start; background:var(--cream); color:var(--text); border-bottom-left-radius:4px; }
.assistant-msg.user{ align-self:flex-end; background:var(--navy); color:var(--white); border-bottom-right-radius:4px; }

/* Single scrollable row instead of wrapping — with 8 chips, wrapping ate
   most of the panel's height and squeezed the message log down to a couple
   of cut-off lines. A horizontal strip (common "suggestion chip" pattern)
   stays a fixed, small height no matter how many chips get added later. */
.assistant-quick-replies{
  display:flex; flex-wrap:nowrap; gap:6px; padding:0 16px 12px; flex-shrink:0;
  overflow-x:auto; scrollbar-width:thin;
}
.assistant-quick-replies::-webkit-scrollbar{ height:5px; }
.assistant-quick-replies::-webkit-scrollbar-thumb{ background:var(--line); border-radius:999px; }
.assistant-chip{
  background:var(--white); border:1px solid var(--line); color:var(--navy); border-radius:999px;
  padding:6px 12px; font-size:.8rem; font-weight:600; white-space:nowrap; flex-shrink:0;
}
.assistant-chip:hover{ border-color:var(--orange); color:var(--orange-dk); }

.assistant-form{ display:flex; gap:8px; padding:12px 16px; border-top:1px solid var(--line); flex-shrink:0; }
.assistant-form input{
  flex:1; border:1px solid var(--line); border-radius:999px; padding:10px 14px; font:inherit; font-size:.88rem; min-width:0;
}
.assistant-form input:focus-visible{ outline:2px solid var(--orange); outline-offset:1px; }
.assistant-form button{
  background:var(--orange); color:var(--navy); border:0; border-radius:50%; width:38px; height:38px;
  flex-shrink:0; display:flex; align-items:center; justify-content:center; font-size:1rem;
}
.assistant-form button:hover{ background:var(--orange-hover); }

@media (max-width:480px){
  .assistant-panel{ right:16px; bottom:84px; width:calc(100vw - 32px); }
  .assistant-launcher{ right:16px; bottom:16px; }
}
@media (prefers-reduced-motion:reduce){
  .assistant-launcher, .assistant-panel{ transition:none; }
  .assistant-icon{ animation:none; }
}

/* ==========================================================================
   Accent layer — sourced from the brand reference video (see :root comment).
   Reusable utilities, applied selectively (homepage + Why Puffins), not a
   site-wide repaint of the existing navy/orange/cream identity.
   ========================================================================== */

/* ---------- Editorial motif (cream/black minimalist slide style) ---------- */
.editorial-rule{
  display:flex; align-items:center; gap:16px; margin:0 0 18px;
  color:var(--text-soft); font-size:.78rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
}
.editorial-rule::before,.editorial-rule::after{ content:""; flex:1; height:1px; background:var(--ink); }
.editorial-head{
  font-weight:800; letter-spacing:-.02em; line-height:1.02; color:var(--text); margin:0 0 .4em;
}
.editorial-list{ border-top:1px solid var(--ink); margin-top:8px; }
.editorial-item{
  display:grid; grid-template-columns:1fr; gap:6px; padding:22px 0; border-bottom:1px solid var(--ink);
}
@media (min-width:700px){
  .editorial-item{ grid-template-columns:220px 1fr; gap:24px; align-items:baseline; }
}
.editorial-label{ font-weight:800; font-size:.95rem; letter-spacing:.02em; text-transform:uppercase; color:var(--olive); }
.editorial-item p{ margin:0; color:var(--text-soft); }

/* ---------- Sunburst accent (rust-orange template style, CSS-only, no image asset) ----------
   Restrained/low-opacity on purpose — this is a texture layer behind existing
   content, not a repaint; kept off dark (.bg-navy/.statement) backgrounds where
   rust-on-navy would lose contrast and barely read. */
.sunburst-accent{ position:relative; isolation:isolate; overflow:hidden; }
.sunburst-accent::before{
  content:""; position:absolute; inset:-25% -10%; z-index:-1; pointer-events:none;
  background:repeating-conic-gradient(from 0deg, var(--rust) 0deg 8deg, transparent 8deg 22deg);
  opacity:.07;
}
@media (prefers-reduced-motion:reduce){ .sunburst-accent::before{ opacity:.05; } }
