/* ============================================================
   Little Daisy — storefront theme
   All colours/fonts come from CSS variables set by the editor.
   ============================================================ */
:root{
  /* 2026-08-11: brand kit colours (primary/accent/pink/brown) — see the
     DEFAULT_THEME comment in store-core.js for the full rationale,
     including why fontDisplay/fontScript are free look-alikes rather
     than the kit's actual (paid, non-Google-Fonts) Boston Angel/Amoresa. */
  --ld-bg:#FFFBF4; --ld-ink:#2A2530; --ld-primary:#F21086; --ld-accent:#F9B73F;
  --ld-brown:#874D11;
  --ld-sky:#5BB3C4; --ld-coral:#FF6F61; --ld-leaf:#6FA287; --ld-pink:#F21086;
  --ld-radius:18px; --ld-display:'Fraunces',serif; --ld-script:'Alex Brush',cursive;
  --ld-body:'Quicksand',system-ui,sans-serif;
  --ld-logo-size:72px;
  --ld-muted:#857B83; --ld-line:#ECE2D2; --ld-card:#fff;
  --ld-shadow:0 18px 40px -24px rgba(42,37,48,.5);
  --ld-shadow-sm:0 6px 18px -12px rgba(42,37,48,.45);
}
*{box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{
  margin:0; font-family:var(--ld-body); color:var(--ld-ink); background:var(--ld-bg);
  line-height:1.6; -webkit-font-smoothing:antialiased; font-size:16px;
}
img{max-width:100%;display:block;} a{color:inherit;}
.wrap{max-width:1200px;margin:0 auto;padding:0 24px;}
h1,h2,h3{font-family:var(--ld-display);font-weight:600;line-height:1.05;letter-spacing:-.01em;margin:0;}
.eyebrow{font-family:var(--ld-body);font-weight:700;font-size:.74rem;letter-spacing:.16em;text-transform:uppercase;color:var(--ld-primary);}
.glyph{color:var(--ld-ink);width:46%;display:block;}
.glyph svg{width:100%;height:auto;}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:.5rem;font-family:var(--ld-body);font-weight:700;
  font-size:1rem;border-radius:999px;padding:.85rem 1.5rem;cursor:pointer;text-decoration:none;
  border:2px solid var(--ld-ink);transition:transform .18s,box-shadow .18s,background .2s,color .2s;line-height:1;min-height:44px;}
.btn--primary{background:var(--ld-primary);color:#fff;box-shadow:0 4px 0 var(--ld-ink);}
.btn--primary:hover{transform:translateY(-2px);box-shadow:0 6px 0 var(--ld-ink);}
.btn--primary:active{transform:translateY(2px);box-shadow:0 1px 0 var(--ld-ink);}
.btn--ghost{background:var(--ld-card);color:var(--ld-ink);box-shadow:0 4px 0 var(--ld-ink);}
.btn--ghost:hover{transform:translateY(-2px);box-shadow:0 6px 0 var(--ld-ink);}
.btn:focus-visible{outline:3px solid var(--ld-sky);outline-offset:3px;}
.btn svg{width:18px;height:18px;flex:none;}
.btn[disabled]{opacity:.5;cursor:not-allowed;transform:none!important;}

/* ---------- announcement + header ---------- */
.announce{background:var(--ld-ink);color:var(--ld-bg);text-align:center;font-size:.82rem;font-weight:600;
  letter-spacing:.02em;padding:.55rem 1rem;}
.topbar{position:sticky;top:0;z-index:50;background:color-mix(in srgb,var(--ld-bg) 88%,transparent);
  backdrop-filter:blur(10px);border-bottom:1px solid var(--ld-line);}
.topbar__inner{display:flex;align-items:center;gap:1.5rem;padding:.7rem 24px;}
.brand{display:flex;align-items:center;gap:.6rem;text-decoration:none;}
/* 2026-08-06: bumped 38px->58px at Vincent's request ("make it bigger,
   see screenshot") — the footer's small ".sm" mark scaled up with it
   (30px->44px) to keep the same size relationship. logo-pulse (below)
   already animates this exact element, same keyframe as the Story
   section's photo — see the 2026-08-06 note on .brand__markimg.
   2026-08-11: width/height now driven by --ld-logo-size (admin-editable
   "Logo size" slider in the theme editor, default 72px) instead of a
   hardcoded value — see the DEFAULT_THEME header.logoSize note. */
.brand__mark{width:var(--ld-logo-size,58px);height:var(--ld-logo-size,58px);display:block;}
.brand__mark.sm{width:calc(var(--ld-logo-size,58px) * .76);height:calc(var(--ld-logo-size,58px) * .76);}
.brand__mark svg{width:100%;height:100%;animation:spin 16s linear infinite;}
/* 2026-08-11: was object-fit:cover + border-radius:999px — that forced a
   SECOND circular crop on top of the logo artwork's own circular border
   (already baked into the source file, on a wide margin), which is what
   was chopping the badge down to an illegible sliver at header size
   ("still not appearing"). object-fit:contain shows the whole logo,
   uncropped; the new logo asset (daisy-ibanez-logo.png, the real brand
   artwork Vincent supplied, replacing the old off-brand JPG) is also
   tightly cropped to its own content so it reads bigger inside the same
   box on top of that. */
.brand__markimg{width:100%;height:100%;border-radius:0;display:block;object-fit:contain;
  /* 2026-08-06: this is the SAME logo-pulse keyframe the Story section's
     .story-card__img already uses (see below) — the header logo has
     always moved the same way; it just read as more subtle at the old
     38px. Kept identical on purpose rather than inventing a second
     animation, per Vincent's "move like the Story section" ask. */
  animation:logo-pulse 4.5s ease-in-out infinite;}
@keyframes spin{to{transform:rotate(360deg);}}
@keyframes logo-pulse{0%,100%{transform:scale(1) rotate(0deg);}50%{transform:scale(1.06) rotate(4deg);}}
.brand__txt{font-family:var(--ld-display);font-weight:600;font-size:1.3rem;line-height:1;}
.brand__txt small{display:block;font-family:var(--ld-body);font-weight:600;font-size:.62rem;letter-spacing:.22em;
  text-transform:uppercase;color:var(--ld-primary);margin-top:3px;}
.topbar__nav{display:flex;gap:1.6rem;margin-left:auto;}
.topbar__nav a{text-decoration:none;font-weight:600;font-size:.96rem;position:relative;padding:.3rem 0;}
.topbar__nav a::after{content:"";position:absolute;left:0;right:0;bottom:-2px;height:2px;background:var(--ld-primary);
  transform:scaleX(0);transform-origin:left;transition:transform .22s;}
.topbar__nav a:hover::after{transform:scaleX(1);}
.topbar__actions{display:flex;align-items:center;gap:.3rem;margin-left:0;}
.topbar__nav+.topbar__actions{margin-left:0;}
.icon-btn{position:relative;display:inline-grid;place-items:center;width:44px;height:44px;border-radius:12px;
  border:none;background:none;cursor:pointer;color:var(--ld-ink);transition:background .18s;text-decoration:none;}
.icon-btn svg{width:23px;height:23px;}
.icon-btn:hover{background:color-mix(in srgb,var(--ld-ink) 8%,transparent);}
.icon-btn:focus-visible{outline:3px solid var(--ld-sky);outline-offset:2px;}
.cart-count{position:absolute;top:4px;right:3px;background:var(--ld-primary);color:#fff;font-family:var(--ld-body);
  font-size:.66rem;font-weight:800;min-width:18px;height:18px;border-radius:999px;display:grid;place-items:center;padding:0 4px;}
.topbar__menu{display:none;}

/* ---------- sections ---------- */
.sec{padding:0;}
.sec.block{padding:5rem 0;}
.sec__head{text-align:center;max-width:640px;margin:0 auto 3rem;}
.sec__head h2{font-size:clamp(2rem,4.4vw,3rem);margin:.35rem 0;}
.sec__sub{color:var(--ld-muted);margin:.4rem 0 0;}

/* hero — headline + trust badges on the left, a 3-card photo/video
   collage on the right (2 photos + 1 video by default; each slot can
   hold either, uploaded from the theme editor). */
.hero{padding:4.5rem 0 4rem;position:relative;overflow:hidden;}
.hero__inner{display:grid;grid-template-columns:1.05fr .95fr;gap:3rem;align-items:center;}
.hero__title{font-size:clamp(2.6rem,6vw,4.4rem);margin:.5rem 0 1.2rem;}
/* 2026-08-11: brand script font (Amoresa look-alike) on the hero's
   flourish word — mirrors how "Daisy" gets the romantic-script treatment
   in the brand kit. font-weight forced to 400 since Alex Brush only
   ships one weight; letting it inherit the h1's 600 would trigger a
   faux-bold synthesis that looks heavy/ugly on a script face. Sized up
   slightly (script faces read visually smaller than serif/sans at the
   same font-size due to their thinner strokes). */
.hero__title .hl{font-style:normal;font-family:var(--ld-script);font-weight:400;
  font-size:1.15em;color:var(--ld-pink);position:relative;white-space:nowrap;}
.hero__sub{font-size:1.15rem;color:var(--ld-muted);max-width:38ch;margin:0 0 1.8rem;}
.hero__cta{display:flex;gap:.8rem;flex-wrap:wrap;}
.hero__note{font-family:var(--ld-display);font-style:italic;font-size:1.02rem;color:var(--ld-sky);margin:1.4rem 0 0;}
.hero__badges{display:flex;gap:1.6rem;flex-wrap:wrap;margin-top:1.8rem;}
.hero__badge{display:flex;align-items:center;gap:.5rem;font-size:.85rem;font-weight:700;color:color-mix(in srgb,var(--ld-ink) 82%,transparent);}
.hero__badge svg{width:18px;height:18px;color:var(--ld-leaf);flex:none;}
/* 2026-08-01: size now driven by --hero-scale (theme editor's "Collage
   size" slider on the Hero section, set inline in store-core.js). Every
   px length that composes the collage is wrapped in calc(...*var(...))
   so the whole hand-placed arrangement (which card overlaps which,
   the "no card fully hides another" layout) scales together rather
   than cards growing while their positions stay fixed apart — that
   would just make them overlap more, not read as "bigger". `left:31%`
   on c3 and the `right:0`/`left:0`/`top:0` edge anchors on c1/c2 are
   percentages or zero, so they don't need calc() — they already scale
   (or stay pinned) correctly on their own. `.hero__collage` has no
   fixed height from an ancestor and `.hero{overflow:hidden}` only
   clips content that doesn't fit its own auto-height box — since this
   height grows too, nothing gets clipped by growing the scale.
   Deliberately NOT applied in the two mobile @media blocks below,
   which already have their own hand-tuned sizes (vw-based on the
   smallest breakpoint) — scaling those as well risks overflow on
   narrow screens for comparatively little benefit, since mobile is
   already full-width. */
.hero__collage{position:relative;height:calc(400px * var(--hero-scale,1));}
.hero__blob{position:absolute;width:340px;height:340px;right:-6%;top:2%;border-radius:50%;z-index:0;
  background:radial-gradient(circle at 35% 35%,color-mix(in srgb,var(--ld-accent) 45%,transparent),transparent 70%);filter:blur(6px);}
.hero__collage-card{position:absolute;border-radius:22px;border:2px solid var(--ld-ink);box-shadow:var(--ld-shadow-sm);
  overflow:hidden;}
/* Each of the 3 slots gets its own tint AND its own position/size band so no
   slot can ever fully cover another — important while slots are still empty
   placeholders (no real photo/video uploaded yet), since the placeholder
   background was otherwise identical between slots and one slot could
   visually "disappear" entirely behind another. */
.hero__collage-card.c1{left:0;top:calc(64px * var(--hero-scale,1));width:calc(222px * var(--hero-scale,1));height:calc(176px * var(--hero-scale,1));transform:rotate(-7deg);z-index:2;
  background:repeating-linear-gradient(45deg,color-mix(in srgb,var(--ld-accent) 22%,#fff),
  color-mix(in srgb,var(--ld-accent) 22%,#fff) 12px,color-mix(in srgb,var(--ld-accent) 34%,#fff) 12px,
  color-mix(in srgb,var(--ld-accent) 34%,#fff) 24px);}
.hero__collage-card.c2{right:0;top:0;width:calc(214px * var(--hero-scale,1));height:calc(192px * var(--hero-scale,1));transform:rotate(6deg);z-index:1;
  background:repeating-linear-gradient(45deg,color-mix(in srgb,var(--ld-sky) 24%,#fff),
  color-mix(in srgb,var(--ld-sky) 24%,#fff) 12px,color-mix(in srgb,var(--ld-sky) 38%,#fff) 12px,
  color-mix(in srgb,var(--ld-sky) 38%,#fff) 24px);}
.hero__collage-card.c3{left:31%;top:calc(216px * var(--hero-scale,1));width:calc(210px * var(--hero-scale,1));height:calc(164px * var(--hero-scale,1));transform:rotate(-2deg);z-index:3;
  background:repeating-linear-gradient(45deg,color-mix(in srgb,var(--ld-pink) 26%,#fff),
  color-mix(in srgb,var(--ld-pink) 26%,#fff) 12px,color-mix(in srgb,var(--ld-pink) 40%,#fff) 12px,
  color-mix(in srgb,var(--ld-pink) 40%,#fff) 24px);}
.hero__collage-el{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;}
.hero__collage-ph{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;text-align:center;
  padding:12px;font-size:.72rem;font-weight:700;text-transform:uppercase;letter-spacing:.03em;
  color:color-mix(in srgb,var(--ld-ink) 65%,transparent);}
.hero__collage-play{position:absolute;top:8px;right:8px;width:30px;height:30px;
  border-radius:999px;background:rgba(42,37,48,.68);display:grid;place-items:center;pointer-events:none;}
.hero__collage-play svg{width:14px;height:14px;color:#fff;}

/* marquee */
.marquee{background:var(--ld-ink);color:var(--ld-bg);overflow:hidden;white-space:nowrap;padding:.7rem 0;
  border-top:3px solid var(--ld-accent);border-bottom:3px solid var(--ld-accent);}
.marquee__track{display:inline-block;animation:slide var(--spd,26s) linear infinite;font-family:var(--ld-display);font-size:1.05rem;}
.marquee__track span{padding:0 1rem;} .marquee__track .dot{color:var(--ld-accent);}
@keyframes slide{to{transform:translateX(-50%);}}

/* collections */
.grid-collections{display:grid;grid-template-columns:repeat(3,1fr);gap:1.4rem;}
.card-collection{position:relative;display:flex;flex-direction:column;justify-content:flex-end;min-height:260px;
  padding:1.8rem;border-radius:var(--ld-radius);text-decoration:none;color:var(--ld-ink);border:2px solid var(--ld-ink);
  background:color-mix(in srgb,var(--tint) 20%,#fff);box-shadow:0 6px 0 var(--ld-ink);transition:transform .18s,box-shadow .18s;overflow:hidden;}
.card-collection:hover{transform:translateY(-4px);box-shadow:0 10px 0 var(--ld-ink);}
.card-collection__glyph{position:absolute;top:1.2rem;right:1.2rem;width:64px;color:color-mix(in srgb,var(--tint) 70%,var(--ld-ink));}
.card-collection__glyph svg{width:100%;}
.card-collection h3{font-size:1.55rem;}
.card-collection p{margin:.3rem 0 0;font-weight:500;color:color-mix(in srgb,var(--ld-ink) 80%,transparent);}
.card-collection__cta{margin-top:1rem;font-weight:700;font-size:.92rem;}

/* how it works — 3 numbered steps */
.how-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.6rem;}
.how-card{background:var(--ld-card);border:2px solid var(--ld-ink);border-radius:var(--ld-radius);padding:1.8rem;box-shadow:0 6px 0 var(--ld-ink);}
.how-card__n{width:44px;height:44px;border-radius:12px;border:2px solid var(--ld-ink);display:grid;place-items:center;
  font-family:var(--ld-display);font-weight:700;margin-bottom:1rem;color:var(--ld-ink);}
.how-card h3{font-size:1.2rem;margin:0 0 .4rem;}
.how-card p{color:var(--ld-muted);margin:0;font-size:.96rem;}

/* contact banner */
.contact-card{background:color-mix(in srgb,var(--ld-sky) 22%,#fff);border:2px solid var(--ld-ink);
  border-radius:calc(var(--ld-radius) + 8px);box-shadow:0 8px 0 var(--ld-ink);padding:3rem;text-align:center;}
.contact-card h2{font-size:clamp(1.8rem,4vw,2.6rem);}
.contact-card p{color:color-mix(in srgb,var(--ld-ink) 78%,transparent);margin:.5rem auto 0;max-width:52ch;}
.contact-card__cta{display:flex;gap:.8rem;flex-wrap:wrap;justify-content:center;margin-top:1.6rem;}

/* video showcase — three auto-scaling promo videos */
/* 2026-08-01: column count now comes from the theme editor's "Columns"
   slider (1-3) via --vt-cols, set inline per-render in store-core.js.
   Falls back to 2 (was a hardcoded 3) so cards read bigger by default. */
.video-trio{display:grid;grid-template-columns:repeat(var(--vt-cols,2),1fr);gap:1.4rem;}
.video-card{display:flex;flex-direction:column;gap:.8rem;}
.video-card__frame{position:relative;width:100%;aspect-ratio:var(--ratio,4/5);border-radius:var(--ld-radius);
  border:2px solid var(--ld-ink);box-shadow:0 6px 0 var(--ld-ink);overflow:hidden;background:color-mix(in srgb,var(--ld-accent) 14%,#fff);}
.video-card__el{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;}
.video-card__ph{position:absolute;inset:0;display:grid;place-items:center;}
.video-card__ph .daisy-spin{width:34%;}
.video-card__meta{text-align:center;}
.video-card__meta h3{font-size:1.15rem;margin:0 0 .2rem;}
.video-card__meta p{margin:0;font-size:.9rem;color:color-mix(in srgb,var(--ld-ink) 75%,transparent);}

/* product grid — 2-level category filter (2026-08-03): .filters__main
   is the row of main categories (Cakes/Plaster Figurines/Magnets);
   each main gets its own .filters__sub row of subcategory chips,
   present in the DOM from the start but [hidden] until that main is
   selected (see storefront.js selectFilter()). */
.filters{display:flex;flex-direction:column;align-items:center;margin-bottom:2.4rem;}
.filters__main{display:flex;gap:.55rem;justify-content:center;flex-wrap:wrap;}
.filters__sub{display:flex;gap:.5rem;justify-content:center;flex-wrap:wrap;margin-top:.7rem;}
.filters__sub[hidden]{display:none;}
.chip{font-family:var(--ld-body);font-weight:600;border:2px solid var(--ld-ink);background:var(--ld-card);
  border-radius:999px;padding:.5rem 1.2rem;cursor:pointer;min-height:42px;transition:background .18s,color .18s,transform .12s;}
.chip:hover{transform:translateY(-1px);}
.chip[aria-pressed="true"]{background:var(--ld-ink);color:var(--ld-bg);}
.chip--sub{padding:.4rem .95rem;min-height:36px;font-size:.9rem;border-width:1.5px;opacity:.92;}
/* 2026-08-05b: featured-subcategory spotlight pill — sits in its own
   row ABOVE .filters__main (see store-core.js's "featured" section
   case), so a seasonal/event subcategory the owner wants shoppers to
   land on first stands out from the ordinary chip row rather than
   just being first-in-line among identical pills. Deliberately bigger
   + gradient-backed + a small ★ badge rather than just reusing .chip's
   look — normal chips communicate "these are equal choices", this one
   needs to read as "this one is different, look here first". */
.filters__featured{display:flex;justify-content:center;margin-bottom:.9rem;}
.chip--featured{--tint:var(--ld-accent);display:inline-flex;align-items:center;gap:.55rem;
  padding:.65rem 1.5rem;min-height:48px;font-size:1.02rem;border-width:2.5px;
  background:linear-gradient(135deg,color-mix(in srgb,var(--tint) 28%,var(--ld-card)),var(--ld-card));
  box-shadow:0 3px 0 color-mix(in srgb,var(--tint) 55%,var(--ld-ink));}
.chip--featured:hover{transform:translateY(-2px);}
.chip--featured[aria-pressed="true"]{background:var(--ld-ink);color:var(--ld-bg);box-shadow:0 3px 0 color-mix(in srgb,var(--tint) 70%,#000);}
.chip--featured__badge{display:inline-flex;align-items:center;font-size:.72rem;font-weight:800;letter-spacing:.04em;
  text-transform:uppercase;padding:.2rem .55rem;border-radius:999px;background:var(--tint);color:var(--ld-ink);}
/* 2026-08-05d: the featured subcategory's ORDINARY chip (rendered
   first in its row now, see store-core.js) gets a subtle gold outline
   — enough to visually connect it back to the spotlight pill above
   without duplicating that pill's own bold treatment here too. */
.chip--sub-featured{border-color:#E0AD00;box-shadow:0 0 0 1px #E0AD00 inset;}
/* 2026-08-05e: featured-products preview strip — real photos of the
   spotlighted subcategory's items, right below the spotlight pill.
   Horizontal scroll rather than wrapping so it stays a single
   glanceable row even with several items on a narrow phone; each
   thumbnail is a genuine [data-open] target (see store-core.js) so
   tapping it jumps straight into that product's lightbox. */
.featured-preview{display:flex;justify-content:center;margin:0 0 1.6rem;}
.featured-preview__scroll{display:flex;gap:1.4rem;overflow-x:auto;max-width:100%;padding:.15rem .3rem .8rem;scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;}
.featured-preview__scroll::-webkit-scrollbar{height:6px;}
.featured-preview__scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--ld-ink) 25%,transparent);border-radius:999px;}
/* 2026-08-05g: the item wrapper just fixes a WIDTH for the scroll row
   — the card inside (a real .card-product, see store-core.js) supplies
   its own border/shadow/hover/aspect-ratio, identical to a card in the
   grid below. That's the whole point of this change: "same size as
   the other product photos" is true by construction, not by
   coincidence, because it IS the same card component. */
.featured-preview__item{flex:0 0 auto;width:min(300px,72vw);scroll-snap-align:start;}
.featured-preview__item .card-product{height:100%;}
.grid-products{display:grid;gap:1.8rem;grid-template-columns:repeat(4,1fr);}
.grid-products[data-cols="3"]{grid-template-columns:repeat(3,1fr);}
.grid-products[data-cols="2"]{grid-template-columns:repeat(2,1fr);}
/* ---- GALLERY-STYLE product tile (2026-08-01) ----
   The photo fills the whole card (4:5), name + category sit on a
   gradient scrim over it, and "Add" fades in on hover. No price is
   rendered anywhere on the public site. */
.card-product{position:relative;background:var(--ld-card);border:2px solid var(--ld-ink);border-radius:var(--ld-radius);
  overflow:hidden;box-shadow:0 5px 0 var(--ld-ink);transition:transform .18s,box-shadow .18s;display:block;}
.card-product:hover{transform:translateY(-5px);box-shadow:0 9px 0 var(--ld-ink);}
.card-product__media{aspect-ratio:4/5;display:grid;place-items:center;background:color-mix(in srgb,var(--tint) 16%,#fff);position:relative;overflow:hidden;cursor:pointer;}
.card-product__media .glyph{width:42%;color:color-mix(in srgb,var(--tint) 72%,var(--ld-ink));}
.card-product__count{position:absolute;top:.8rem;right:.8rem;z-index:3;background:rgba(42,37,48,.72);color:#fff;
  font-size:.62rem;font-weight:700;letter-spacing:.02em;padding:.24rem .6rem;border-radius:999px;}

/* caption overlaid on the image */
.card-product__caption{position:absolute;left:0;right:0;bottom:0;z-index:2;cursor:pointer;
  padding:2.8rem 1.1rem 1rem;color:#fff;pointer-events:none;
  background:linear-gradient(to top,rgba(30,26,35,.88) 0%,rgba(30,26,35,.62) 42%,rgba(30,26,35,0) 100%);}
.card-product__cat{font-size:.68rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  margin:0 0 .1rem;color:rgba(255,255,255,.82);}
.card-product__name{font-family:var(--ld-display);font-size:1.18rem;line-height:1.2;margin:0;color:#fff;
  text-shadow:0 1px 3px rgba(0,0,0,.35);}
/* only rendered when SHOW_PRICES is true in store-core.js */
.card-product__price{display:block;font-family:var(--ld-display);font-weight:600;font-size:1.05rem;
  margin-top:.15rem;color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.35);}

/* product media gallery — up to 15 photos/videos, auto-advance while in view / on hover */
.gal-slide{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;
  transition:opacity .55s ease;transform:scale(1.06);}
/* the active slide drifts very slowly (Ken Burns) so a still photo still
   feels alive between transitions — pauses with the rest on hover */
.gal-slide.is-active{opacity:1;animation:gal-drift 9s ease-out forwards;}
@keyframes gal-drift{from{transform:scale(1.06)}to{transform:scale(1.005)}}
.card-product:hover .gal-slide.is-active{animation-play-state:paused;}
/* dots sit at the TOP-CENTRE now (between the badge and the count pill) —
   the bottom of the tile belongs to the overlaid caption. */
.gal-dots{position:absolute;top:1rem;left:50%;transform:translateX(-50%);z-index:4;
  display:flex;justify-content:center;gap:.32rem;flex-wrap:wrap;max-width:58%;
  background:rgba(30,26,35,.42);padding:.3rem .5rem;border-radius:999px;backdrop-filter:blur(2px);}
.gal-dot{width:6px;height:6px;padding:0;border-radius:999px;border:1.5px solid rgba(255,255,255,.85);
  background:rgba(255,255,255,.35);cursor:pointer;transition:background .2s,transform .2s;box-shadow:0 1px 2px rgba(0,0,0,.25);}
.gal-dot.is-active{background:#fff;transform:scale(1.25);}
/* 9+ media: shrink so a 15-item product still keeps its dots on one row */
.gal-dots--many{gap:.24rem;}
.gal-dots--many .gal-dot{width:5px;height:5px;border-width:1px;}
@media (prefers-reduced-motion: reduce){ .gal-slide,.gal-slide.is-active{transition:none;animation:none;transform:none;} }
.card-product__badge{position:absolute;top:.8rem;left:.8rem;z-index:3;background:var(--ld-ink);color:var(--ld-bg);
  font-size:.68rem;font-weight:700;letter-spacing:.04em;padding:.28rem .7rem;border-radius:999px;}

/* "Add" — floats over the image, revealed on hover/focus (always shown on touch) */
.btn-add{display:inline-flex;align-items:center;gap:.3rem;font-family:var(--ld-body);font-weight:700;font-size:.9rem;
  border:2px solid var(--ld-ink);background:var(--ld-accent);color:var(--ld-ink);border-radius:999px;padding:.5rem .85rem;
  cursor:pointer;min-height:40px;transition:background .18s,transform .18s,color .18s,opacity .18s;
  position:absolute;right:.9rem;bottom:.9rem;z-index:5;opacity:0;transform:translateY(6px);
  box-shadow:0 3px 0 var(--ld-ink);}
.card-product:hover .btn-add,.card-product:focus-within .btn-add{opacity:1;transform:translateY(0);}
.btn-add svg{width:16px;height:16px;}
.btn-add:hover{background:var(--ld-leaf);color:#fff;}
/* touch / coarse pointers have no hover — keep the button permanently visible */
@media (hover:none){ .btn-add{opacity:1;transform:none;} }
/* the caption's gradient must not swallow the button's click target */
.card-product__caption{padding-right:6.5rem;}

/* story / rich text */
.story-card{display:grid;grid-template-columns:1.3fr 1fr;gap:2.5rem;align-items:center;background:var(--ld-card);
  border:2px solid var(--ld-ink);border-radius:calc(var(--ld-radius) + 8px);box-shadow:0 8px 0 var(--ld-ink);padding:3rem;}
.story-card h2{font-size:clamp(1.8rem,4vw,2.6rem);margin:.4rem 0 1rem;}
.story-card p{color:var(--ld-muted);margin:0;}
.stat-row{display:flex;gap:2.4rem;margin-top:1.8rem;flex-wrap:wrap;}
.stat b{font-family:var(--ld-display);font-size:1.9rem;color:var(--ld-primary);display:block;line-height:1;}
.stat span{font-size:.8rem;font-weight:700;color:var(--ld-muted);}
.story-card__art{display:grid;place-items:center;}
.daisy-spin{width:160px;display:block;}.daisy-spin svg{width:100%;animation:spin 22s linear infinite;}
/* 2026-08-11: was object-fit:cover — fine for an actual photo, but this
   field now defaults to the same logo artwork as the header (see
   store-core.js's s_story.settings.image), and cover+circle would crop
   its outer ring text exactly like the header logo bug this session
   fixed. contain avoids that; the circle border-radius stays since a
   transparent PNG contained inside it still reads as a clean round
   badge, just without cropping content off the edges. */
.story-card__img{width:min(260px,80%);height:auto;aspect-ratio:1;object-fit:contain;border-radius:999px;
  animation:logo-pulse 4.5s ease-in-out infinite;}

/* image with text */
.imgtext{display:grid;grid-template-columns:1fr 1fr;gap:2.5rem;align-items:center;}
.imgtext--rev .imgtext__art{order:2;}
.imgtext__art{aspect-ratio:4/3;border-radius:var(--ld-radius);border:2px solid var(--ld-ink);box-shadow:0 6px 0 var(--ld-ink);
  display:grid;place-items:center;background:color-mix(in srgb,var(--tint) 18%,#fff);}
.imgtext__art .glyph{width:34%;color:color-mix(in srgb,var(--tint) 70%,var(--ld-ink));}
.imgtext__copy h2{font-size:clamp(1.7rem,3.6vw,2.4rem);margin:.4rem 0 1rem;}
.imgtext__copy p{color:var(--ld-muted);margin:0 0 1.4rem;}

/* newsletter */
.news-card{background:color-mix(in srgb,var(--ld-sky) 22%,#fff);border:2px solid var(--ld-ink);
  border-radius:calc(var(--ld-radius) + 8px);box-shadow:0 8px 0 var(--ld-ink);padding:3rem;text-align:center;}
.news-card h2{font-size:clamp(1.8rem,4vw,2.6rem);}
.news-card p{color:color-mix(in srgb,var(--ld-ink) 75%,transparent);margin:.4rem 0 0;}
.news-form{display:flex;gap:.6rem;max-width:460px;margin:1.5rem auto 0;flex-wrap:wrap;}
.news-form input{flex:1;min-width:200px;border:2px solid var(--ld-ink);border-radius:999px;padding:.8rem 1.3rem;
  font-family:var(--ld-body);font-size:1rem;min-height:48px;}
.news-form input:focus{outline:3px solid var(--ld-accent);outline-offset:2px;}
.news-msg{font-family:var(--ld-display);font-style:italic;min-height:1.4em;margin:.8rem 0 0;color:var(--ld-ink);}

/* gallery */
.gallery{display:grid;grid-template-columns:repeat(4,1fr);gap:1.2rem;}
.gal-tile{aspect-ratio:1;border-radius:var(--ld-radius);border:2px solid var(--ld-ink);display:grid;place-items:center;
  background:color-mix(in srgb,var(--tint) 18%,#fff);box-shadow:0 5px 0 var(--ld-ink);}
.gal-tile .glyph{width:40%;color:color-mix(in srgb,var(--tint) 70%,var(--ld-ink));}

/* ============================================================
   Build Your Cake (2026-08-06) — custom-cake configurator that
   replaced the "Collection cards" section. Two-column layout: a
   sticky rotating-3D cake on the left, the step-by-step builder
   form on the right; stacks on tablet/phone (art on top).
   2026-08-10: swapped the 3-tier "blueprint" cake for a single-layer
   birthday cake with 4 flickering candles (.cb-flame), removed the
   colour-swatch picker in favour of a free-text box, and made every
   step past #1 render `hidden` until its Continue arrow is used
   (.cb-continue/.cb-step--done/.cb-step[hidden]) — see storefront.js's
   initCakeBuilder()/cbAdvanceStep() for the reveal logic.
   ============================================================ */
.cb-layout{display:grid;grid-template-columns:.85fr 1.3fr;gap:3rem;align-items:start;}
.cb-art{position:sticky;top:96px;}
.cb-art__stage{position:relative;aspect-ratio:1/1;display:grid;place-items:center;perspective:1400px;}
/* the flat SVG "spins" via a real 3D rotateY on a perspective'd parent
   (a constant rotateX tilt sells the depth) — no canvas/WebGL needed,
   and it's built from currentColor/var(--ld-*) so it always matches
   whatever palette the theme editor has set. */
.cb-cake3d{width:66%;transform-style:preserve-3d;animation:cb-spin3d 13s linear infinite;
  filter:drop-shadow(0 22px 26px rgba(42,37,48,.3));}
.cb-cake3d__svg{width:100%;height:auto;display:block;}
@keyframes cb-spin3d{
  0%{transform:rotateX(7deg) rotateY(0deg);}
  50%{transform:rotateX(7deg) rotateY(180deg);}
  100%{transform:rotateX(7deg) rotateY(360deg);}
}
/* flickering candle flames — each one gets its own timing offset so
   they don't flicker in unison, plus a soft warm glow. transform-box
   is needed because these are individual <path> elements inside one
   shared SVG viewBox — without it, percentage transform-origin would
   anchor to the whole SVG canvas instead of each flame's own shape. */
.cb-flame{transform-box:fill-box;transform-origin:50% 100%;animation:cb-flame-flicker 1.1s ease-in-out infinite;
  filter:drop-shadow(0 0 4px rgba(255,178,56,.85));}
.cb-flame--1{animation-delay:.05s;}
.cb-flame--2{animation-delay:.3s;animation-duration:1.3s;}
.cb-flame--3{animation-delay:.15s;animation-duration:.95s;}
.cb-flame--4{animation-delay:.4s;animation-duration:1.2s;}
@keyframes cb-flame-flicker{
  0%,100%{transform:scaleY(1) rotate(-2deg);}
  25%{transform:scaleY(1.14) rotate(3deg);}
  50%{transform:scaleY(.9) rotate(-3deg);}
  75%{transform:scaleY(1.08) rotate(2deg);}
}
.cb-ring{position:absolute;border:1.6px dashed color-mix(in srgb,var(--ld-ink) 32%,transparent);border-radius:999px;}
.cb-ring--1{inset:8%;animation:cb-ring-spin 32s linear infinite;}
.cb-ring--2{inset:19%;animation:cb-ring-spin 24s linear infinite reverse;}
@keyframes cb-ring-spin{to{transform:rotate(360deg);}}
/* small twinkling sparkles scattered around the art stage — purely
   decorative, echoes the lit-candle "make a wish" mood. */
.cb-spark{position:absolute;color:var(--ld-accent);font-size:1rem;animation:cb-spark-twinkle 2.4s ease-in-out infinite;}
.cb-spark--1{top:10%;right:14%;animation-delay:0s;}
.cb-spark--2{bottom:28%;left:4%;font-size:.75rem;animation-delay:.8s;}
.cb-spark--3{top:42%;right:0;font-size:.6rem;animation-delay:1.5s;}
@keyframes cb-spark-twinkle{0%,100%{opacity:.15;transform:scale(.7);}50%{opacity:1;transform:scale(1.15);}}
.cb-floattag{position:absolute;font-family:var(--ld-body);font-weight:700;font-size:.68rem;letter-spacing:.03em;
  text-transform:uppercase;white-space:nowrap;background:var(--ld-card);color:var(--ld-ink);
  border:1.6px solid var(--ld-ink);border-radius:999px;padding:.35rem .75rem;box-shadow:0 3px 0 var(--ld-ink);
  animation:cb-float 5s ease-in-out infinite;}
.cb-floattag--1{top:2%;left:-4%;animation-delay:0s;}
.cb-floattag--2{top:16%;right:-8%;animation-delay:.6s;}
.cb-floattag--3{bottom:20%;left:-10%;animation-delay:1.2s;}
.cb-floattag--4{bottom:0;right:-4%;animation-delay:1.8s;}
@keyframes cb-float{0%,100%{transform:translateY(0);}50%{transform:translateY(-8px);}}

.cb-form{display:flex;flex-direction:column;gap:1.7rem;}
.cb-step{transition:opacity .2s ease;}
.cb-step[hidden]{display:none;}
.cb-step__label{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;font-family:var(--ld-display);
  font-weight:600;font-size:1.06rem;margin:0 0 .75rem;}
.cb-step__n{display:inline-grid;place-items:center;width:26px;height:26px;border-radius:999px;flex:none;
  background:var(--ld-ink);color:var(--ld-bg);font-family:var(--ld-body);font-size:.76rem;font-weight:800;
  position:relative;transition:background .2s;}
/* progressive-reveal "done" state — the number badge swaps for a
   checkmark (text content stays the digit for a11y/no-JS fallback,
   ::after just paints over it) once a step's Continue arrow is used. */
.cb-step--done .cb-step__n{background:var(--ld-leaf,#6FA287);color:transparent;}
.cb-step--done .cb-step__n::after{content:"✓";position:absolute;inset:0;display:grid;place-items:center;
  color:#fff;font-size:.8rem;font-weight:900;}
.cb-step__hint{font-family:var(--ld-body);font-weight:600;font-size:.72rem;color:var(--ld-muted);}
.cb-step--row{display:grid;grid-template-columns:1fr 1.5fr;gap:1.8rem;align-items:start;}
.cb-step--row .cb-continue{grid-column:1/-1;}
.cb-empty{color:var(--ld-muted);font-size:.86rem;font-style:italic;margin:0;}

/* the arrow control that unhides the next question — greyed out and
   inert until its step's answer requirement is met (required steps
   only; optional steps render this already-enabled). */
.cb-continue{display:inline-flex;align-items:center;gap:.45rem;margin-top:1.1rem;font-family:var(--ld-body);
  font-weight:700;font-size:.86rem;border:2px solid var(--ld-ink);border-radius:999px;padding:.55rem 1.15rem;
  cursor:pointer;transition:background .15s,color .15s,opacity .15s,transform .12s,box-shadow .15s;}
.cb-continue svg{width:15px;height:15px;}
.cb-continue:not(:disabled){background:var(--ld-ink);color:var(--ld-bg);box-shadow:0 3px 0 var(--ld-primary);}
.cb-continue:not(:disabled):hover{transform:translateX(2px);}
.cb-continue:disabled{background:var(--ld-card);color:var(--ld-muted);box-shadow:none;opacity:.55;cursor:not-allowed;}

.cb-chips{display:flex;flex-wrap:wrap;gap:.5rem;}
.cb-chip{font-family:var(--ld-body);font-weight:600;font-size:.9rem;border:2px solid var(--ld-ink);
  background:var(--ld-card);border-radius:999px;padding:.5rem 1.1rem;cursor:pointer;min-height:40px;
  transition:background .18s,color .18s,transform .12s,box-shadow .18s;}
.cb-chip:hover{transform:translateY(-1px);}
.cb-chip[aria-pressed="true"]{background:var(--ld-ink);color:var(--ld-bg);box-shadow:0 3px 0 var(--ld-primary);}

.cb-input{width:100%;margin-top:.8rem;border:2px solid var(--ld-ink);border-radius:12px;padding:.75rem 1rem;
  font-family:var(--ld-body);font-size:.94rem;background:var(--ld-card);color:var(--ld-ink);}
.cb-input:focus{outline:3px solid var(--ld-accent);outline-offset:1px;}

.cb-stepper{display:inline-flex;align-items:center;gap:.9rem;border:2px solid var(--ld-ink);border-radius:999px;
  padding:.4rem .5rem;background:var(--ld-card);}
.cb-stepper__btn{width:34px;height:34px;border-radius:999px;border:2px solid var(--ld-ink);background:var(--ld-bg);
  cursor:pointer;display:grid;place-items:center;transition:background .15s;}
.cb-stepper__btn:hover{background:var(--ld-accent);}
.cb-stepper__btn svg{width:16px;height:16px;}
.cb-stepper__val{font-family:var(--ld-display);font-weight:700;font-size:1.2rem;min-width:2.4ch;text-align:center;}

.cb-upload{display:flex;align-items:center;gap:1rem;flex-wrap:wrap;}
.cb-upload__btn{display:inline-flex;align-items:center;gap:.55rem;font-family:var(--ld-body);font-weight:700;
  border:2px dashed var(--ld-ink);border-radius:14px;padding:.85rem 1.3rem;background:var(--ld-card);cursor:pointer;
  transition:background .15s;}
.cb-upload__btn:hover{background:color-mix(in srgb,var(--ld-accent) 18%,var(--ld-card));}
.cb-upload__btn svg{width:19px;height:19px;}
.cb-upload__preview{position:relative;width:84px;height:84px;border-radius:14px;overflow:hidden;flex:none;
  border:2px solid var(--ld-ink);box-shadow:0 3px 0 var(--ld-ink);}
.cb-upload__preview[hidden]{display:none;}
.cb-upload__preview img{width:100%;height:100%;object-fit:cover;display:block;}
.cb-upload__rm{position:absolute;top:2px;right:2px;width:22px;height:22px;border-radius:999px;border:none;
  background:var(--ld-ink);color:#fff;display:grid;place-items:center;cursor:pointer;padding:0;}
.cb-upload__rm svg{width:11px;height:11px;}
.cb-upload__busy{font-size:.84rem;color:var(--ld-muted);font-style:italic;}

.cb-contact{display:grid;gap:1rem;}
.cb-foot{border-top:1px solid var(--ld-line);padding-top:1.4rem;margin-top:.2rem;}
.cb-note{font-size:.82rem;color:var(--ld-muted);margin:0 0 1rem;}
.cb-done{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.4rem;padding:3rem 1rem;}
.cb-done[hidden]{display:none;}
.cb-done h3{font-size:1.5rem;margin:.5rem 0 0;}
.cb-done p{color:var(--ld-muted);margin:0;max-width:34ch;}

/* footer */
.footer{background:var(--ld-ink);color:var(--ld-bg);padding:3.5rem 0 1.6rem;margin-top:3rem;}
.footer__grid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:2rem;}
.footer__brand .brand__mark{margin-bottom:.6rem;}
.footer h4{font-family:var(--ld-display);font-weight:600;margin:0 0 .8rem;color:var(--ld-accent);}
.footer a{display:block;text-decoration:none;padding:.22rem 0;opacity:.85;font-size:.94rem;}
.footer a:hover{opacity:1;color:var(--ld-accent);}
.footer__brand p{opacity:.8;max-width:34ch;font-size:.94rem;}
.footer__base{text-align:center;margin-top:2.4rem;padding-top:1.4rem;border-top:1px solid rgba(255,255,255,.16);
  font-size:.85rem;opacity:.72;}
/* 2026-08-11: brand brown + Quicksand (not italic Fraunces/gold) — this
   handwritten-style footer note plays the same "tagline" role as
   "Where Sweetness Meets Creativity" in the brand kit, which is set in
   Quicksand/brown, not a display serif. */
.footer__base .hand{font-family:var(--ld-body);font-weight:600;font-style:normal;color:var(--ld-brown);font-size:1.05rem;opacity:1;}

/* ---------- cart drawer ---------- */
.scrim{position:fixed;inset:0;background:rgba(42,37,48,.5);opacity:0;visibility:hidden;transition:opacity .25s;z-index:90;}
.scrim.open{opacity:1;visibility:visible;}
.drawer{position:fixed;top:0;right:0;height:100%;width:min(420px,92vw);background:var(--ld-bg);z-index:100;
  transform:translateX(100%);transition:transform .3s cubic-bezier(.2,.8,.2,1);display:flex;flex-direction:column;
  border-left:2px solid var(--ld-ink);box-shadow:-24px 0 50px -24px rgba(0,0,0,.4);}
.drawer.open{transform:translateX(0);}
.drawer__head{display:flex;align-items:center;justify-content:space-between;padding:1.2rem 1.4rem;border-bottom:1px solid var(--ld-line);}
.drawer__head h3{font-size:1.35rem;}
.drawer__items{flex:1;overflow-y:auto;padding:.6rem 1.4rem;}
.line{display:grid;grid-template-columns:52px 1fr auto;gap:.9rem;align-items:center;padding:.9rem 0;border-bottom:1px solid var(--ld-line);}
.line__media{width:52px;height:52px;border-radius:12px;display:grid;place-items:center;background:color-mix(in srgb,var(--tint) 16%,#fff);border:1.5px solid var(--ld-ink);}
.line__media .glyph{width:58%;color:var(--ld-ink);}
.line__name{font-family:var(--ld-display);font-weight:600;font-size:1.02rem;}
.line__meta{font-size:.82rem;color:var(--ld-muted);}
.qty{display:inline-flex;align-items:center;gap:.5rem;margin-top:.35rem;}
.qty button{width:28px;height:28px;border:2px solid var(--ld-ink);background:var(--ld-card);border-radius:8px;cursor:pointer;display:grid;place-items:center;}
.qty button svg{width:15px;height:15px;}
.line__total{font-family:var(--ld-display);font-weight:600;}
.line__rm{background:none;border:none;color:var(--ld-primary);cursor:pointer;font-size:.8rem;font-weight:700;margin-top:.2rem;padding:0;}
.drawer__foot{padding:1.3rem 1.4rem;border-top:1px solid var(--ld-line);}
.drawer__sum{display:flex;justify-content:space-between;font-family:var(--ld-display);font-size:1.3rem;font-weight:600;margin-bottom:1rem;}
.drawer__empty{text-align:center;color:var(--ld-muted);padding:3rem 1rem;}
.drawer__empty .ic{width:54px;margin:0 auto 1rem;color:var(--ld-line);}

/* toast */
.toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%) translateY(160%);background:var(--ld-ink);
  color:var(--ld-bg);padding:.85rem 1.4rem;border-radius:999px;font-weight:700;z-index:130;box-shadow:var(--ld-shadow);
  transition:transform .3s cubic-bezier(.2,.8,.2,1);border:2px solid var(--ld-accent);font-size:.95rem;}
.toast.show{transform:translateX(-50%) translateY(0);}

/* banner */
.demo-banner{text-align:center;font-size:.82rem;font-weight:700;padding:.45rem;background:color-mix(in srgb,var(--ld-accent) 22%,#fff);
  color:var(--ld-ink);border-bottom:1px solid var(--ld-line);}
.demo-banner a{color:var(--ld-primary);}

/* ---------- responsive ---------- */
@media (max-width:900px){
  .hero__inner{grid-template-columns:1fr;gap:2.4rem;} .hero__collage{height:260px;max-width:420px;margin:1rem auto 0;}
  .grid-collections{grid-template-columns:1fr;} .story-card{grid-template-columns:1fr;text-align:center;}
  /* Build Your Cake: art panel moves above the form and un-stickies —
     stacking two sticky/tall columns on a narrow screen just wastes
     scroll space. The stage also shrinks so the floating blueprint
     labels stop crowding off the edge of the viewport. */
  .cb-layout{grid-template-columns:1fr;gap:2rem;}
  .cb-art{position:static;max-width:280px;margin:0 auto;}
  .cb-step--row{grid-template-columns:1fr;gap:1.4rem;}
  .video-trio{grid-template-columns:1fr;max-width:360px;margin:0 auto;}
  .how-grid{grid-template-columns:1fr;}
  .stat-row{justify-content:center;} .imgtext,.imgtext--rev .imgtext__art{grid-template-columns:1fr;order:0;}
  .imgtext{grid-template-columns:1fr;}
  .grid-products,.grid-products[data-cols="3"]{grid-template-columns:repeat(2,1fr);}
  .gallery{grid-template-columns:repeat(2,1fr);}
  .footer__grid{grid-template-columns:1fr 1fr;}
  .topbar__nav{display:none;} .topbar__menu{display:inline-grid;}
  /* 2026-08-05 bugfix: `.topbar__nav{margin-left:auto}` is what used to
     push the phone/WhatsApp/cart/menu icons to the right edge of the
     header — but that rule lives on the nav element, which is hidden
     here. With no nav, nothing had an auto margin any more, so the icon
     row collapsed to sit right next to the logo instead of the right
     edge (icons "bunched up" against the brand). Give the actions
     group its own auto margin so it's still pushed right with no nav. */
  .topbar__actions{margin-left:auto;}
  /* 2026-08-06: the bigger 58px mark needs a little less room once the
     nav links are gone and space is tighter on tablet/phone widths.
     2026-08-11: capped via min() against --ld-logo-size instead of a
     flat override — so cranking the desktop "Logo size" slider up
     doesn't blow out the mobile header layout, but a smaller chosen
     size is still respected down here too. */
  .brand__mark{width:min(var(--ld-logo-size,58px),48px);height:min(var(--ld-logo-size,58px),48px);}
  /* 2026-08-05 bugfix: the hero collage's 3 photo/video cards used to
     only get viewport-scaled (vw-based) sizes below 520px. Between
     521-900px they kept their full desktop pixel sizes (e.g. card c3 at
     top:216px + height:164px = 380px of vertical space) inside a
     collage box that this same breakpoint caps at 300px tall — so c3
     visibly got cropped by `.hero{overflow:hidden}` on any tablet/
     large-phone width in that range. Moving the same compact vw-based
     card sizing up to this breakpoint (instead of only ≤520px) fixes
     it at every width ≤900px; ≤520px already matched this query too so
     nothing changes for small phones. */
  .hero__collage-card.c1{left:0;top:10px;width:52vw;height:150px;}
  .hero__collage-card.c2{right:0;top:0;width:44vw;height:170px;}
  .hero__collage-card.c3{left:26%;top:70px;width:56vw;height:130px;}
  /* NOTE: do not add a .lb-panel override in this block — the product
     lightbox's mobile rules live in a dedicated @media block placed
     AFTER the lightbox section further down this file, on purpose (see
     the 2026-08-04 comment there) so it correctly wins the cascade. */
}
@media (max-width:520px){
  /* 2026-08-01: the catalogue reads as a gallery now — hold 2 columns on
     phones (was 1) and tighten the gutter so it scans like a photo feed. */
  .grid-products,.grid-products[data-cols="3"],.grid-products[data-cols="2"]{grid-template-columns:repeat(2,1fr);gap:.9rem;}
  .card-product__name{font-size:1rem;}
  /* 2026-08-05 bugfix: this used to reset padding-right to .7rem, which
     removes the space the base rule (further down this file) reserves
     for the floating "Add" button. `.btn-add` is always visible on
     touch (see `@media (hover:none)`), so on a real phone that meant
     the product name could run underneath/behind the Add button
     instead of wrapping clear of it. Keep a smaller-but-real reserve
     matching the shrunk mobile button size instead of dropping it to 0. */
  .card-product__caption{padding:2.2rem .7rem .7rem;padding-right:5rem;}
  .card-product .btn-add{right:.5rem;bottom:.5rem;padding:.4rem .6rem;min-height:34px;font-size:.8rem;}
  .footer__grid{grid-template-columns:1fr;} .sec.block{padding:3.4rem 0;}
  .story-card,.news-card,.contact-card{padding:2rem;}
  /* 2026-08-05: brand text can't overflow the header on the narrowest
     phones once the icon row is correctly pinned to the right edge
     (see the ≤900px fix above) — truncate gracefully instead of
     wrapping/overlapping the icons. */
  .brand{min-width:0;flex:1 1 auto;}
  .brand__mark{width:min(var(--ld-logo-size,58px),42px);height:min(var(--ld-logo-size,58px),42px);}
  .brand__txt{min-width:0;overflow:hidden;}
  .brand__txt,.brand__txt small{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}
  /* 2026-08-05b: the featured pill's larger desktop sizing (1.02rem
     text, 1.5rem side padding) is exactly the kind of thing that wraps
     awkwardly or crowds the badge on a narrow phone — shrink it back
     toward normal chip proportions here, badge included. */
  .chip--featured{padding:.5rem 1.05rem;min-height:42px;font-size:.92rem;gap:.4rem;}
  .chip--featured__badge{font-size:.66rem;padding:.16rem .45rem;}
  /* 2026-08-05g: on a phone, one card at ~80vw reads as "the featured
     item", with just enough of a second one peeking in to hint the row
     scrolls — matches the 2-col grid's own mobile card width roughly. */
  .featured-preview__item{width:80vw;}
  /* Build Your Cake: the floating blueprint labels are a desktop flourish
     — on a narrow phone they'd overlap the cake art or run off-screen,
     so trim to the two that fit cleanly and pull them inward. */
  .cb-art{max-width:220px;}
  .cb-floattag--2,.cb-floattag--3{display:none;}
  .cb-floattag--1{left:0;} .cb-floattag--4{right:0;}
  .cb-stepper__val{font-size:1.05rem;}
}
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;}html{scroll-behavior:auto;}}

/* ============================================================
   Intro — scroll-expand hero (vanilla port)
   ============================================================ */
.intro{position:relative;min-height:100dvh;display:block;overflow:hidden;padding:0;}
.intro__bg{position:absolute;inset:0;background-size:cover;background-position:center;will-change:opacity;z-index:0;}
.intro__bg--ph{background:
  radial-gradient(120% 120% at 20% 10%, color-mix(in srgb,var(--ld-accent) 55%,#fff), transparent 55%),
  radial-gradient(120% 120% at 90% 30%, color-mix(in srgb,var(--ld-sky) 55%,#fff), transparent 55%),
  linear-gradient(160deg, color-mix(in srgb,var(--ld-coral) 35%,var(--ld-bg)), var(--ld-bg));}
.intro__bg::after{content:"";position:absolute;inset:0;background:rgba(42,37,48,.10);}
.intro__viewport{position:relative;z-index:2;height:100dvh;display:flex;flex-direction:column;align-items:center;justify-content:center;}
.intro__media{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:min(300px,82vw);height:min(400px,52vh);
  border-radius:22px;overflow:hidden;box-shadow:0 22px 60px -20px rgba(0,0,0,.45);will-change:width,height;z-index:1;border:3px solid rgba(255,255,255,.5);}
.intro__mediaEl{width:100%;height:100%;object-fit:cover;display:block;}
.intro__mediaEl--ph{display:grid;place-items:center;background:
  linear-gradient(160deg,color-mix(in srgb,var(--ld-accent) 60%,#fff),color-mix(in srgb,var(--ld-coral) 50%,#fff));}
.intro__mediaEl--ph .daisy-spin{width:42%;}
.intro__shade{position:absolute;inset:0;background:rgba(42,37,48,.28);}
.intro__meta{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.4rem;color:#fff;z-index:2;text-align:center;padding:1rem;}
.intro__kicker{font-family:var(--ld-body);font-weight:700;letter-spacing:.18em;text-transform:uppercase;font-size:.8rem;margin:0;text-shadow:0 1px 8px rgba(0,0,0,.4);}
.intro__hint{font-family:var(--ld-display);font-style:italic;font-size:1.1rem;margin:0;text-shadow:0 1px 8px rgba(0,0,0,.4);}
.intro__title{position:relative;z-index:3;display:flex;flex-direction:column;align-items:center;gap:.3rem;pointer-events:none;}
.intro__word{font-family:var(--ld-display);font-weight:600;font-size:clamp(3rem,9vw,6.5rem);line-height:.95;color:var(--ld-ink);
  will-change:transform;text-shadow:0 2px 20px rgba(255,255,255,.4);}
.intro__cue{position:absolute;bottom:2.2rem;left:50%;transform:translateX(-50%);width:26px;height:42px;border:2px solid var(--ld-ink);
  border-radius:14px;z-index:3;opacity:.6;}
.intro__cue span{position:absolute;top:7px;left:50%;width:4px;height:8px;background:var(--ld-ink);border-radius:2px;transform:translateX(-50%);animation:cue 1.5s infinite;}
@keyframes cue{0%{opacity:0;transform:translate(-50%,0)}40%{opacity:1}100%{opacity:0;transform:translate(-50%,14px)}}
.intro__content{position:relative;z-index:2;opacity:1;}
.intro-about{text-align:center;padding:4rem 24px 1rem;max-width:900px;}
.intro-about__h{font-size:clamp(2rem,4.5vw,3.2rem);margin:.4rem 0 1rem;}
.intro-about__lead{font-size:1.2rem;color:var(--ld-muted);max-width:60ch;margin:0 auto;}
.intro-feats{display:grid;grid-template-columns:repeat(3,1fr);gap:1.4rem;margin-top:2.6rem;text-align:left;}
.intro-feat{background:var(--ld-card);border:2px solid var(--ld-ink);border-radius:var(--ld-radius);padding:1.6rem;box-shadow:0 6px 0 var(--ld-ink);}
.intro-feat__ic{width:64px;height:64px;border-radius:16px;display:grid;place-items:center;margin-bottom:1rem;
  background:color-mix(in srgb,var(--tint) 18%,#fff);border:2px solid var(--ld-ink);}
.intro-feat__ic .glyph{width:54%;color:color-mix(in srgb,var(--tint) 72%,var(--ld-ink));}
.intro-feat h3{font-size:1.25rem;margin:0 0 .4rem;}
.intro-feat p{color:var(--ld-muted);margin:0;font-size:.96rem;}

/* editor static variant: no scroll hijack, everything visible */
.intro--static{min-height:auto;}
.intro--static .intro__viewport{height:auto;padding:3rem 0 1rem;}
.intro--static .intro__media{position:relative;top:auto;left:auto;transform:none;margin:0 auto 1.5rem;width:min(560px,80%);height:min(340px,44vh);}
.intro--static .intro__title{margin-bottom:1rem;}
.intro--static .intro__cue{display:none;}

@media (max-width:900px){ .intro-feats{grid-template-columns:1fr;} }

/* ---------- product photos ---------- */
.card-product__media.has-img{background:none;padding:0;}
.card-product__media img,.card-product__media video{width:100%;height:100%;object-fit:cover;}
.line__media img,.line__media video{width:100%;height:100%;object-fit:cover;border-radius:inherit;}

/* ---------- drawer: cart total row, details form, done state ----------
   2026-07-26: checkout replaced discount codes + "place order" with a
   3-step call/WhatsApp lead-capture flow — see storefront.js. */
.drawer__foot .r{display:flex;justify-content:space-between;font-size:.95rem;padding:.15rem 0;color:var(--ld-muted);}
.drawer__foot .r.tot{font-family:var(--ld-display);font-size:1.3rem;font-weight:600;color:var(--ld-ink);margin-bottom:1rem;align-items:baseline;}
/* 2026-08-01: when SHOW_PRICES is off the right-hand slot carries a
   reassurance line instead of a total (see store-core.js). */
.drawer__foot .r.tot .tot__note{font-family:var(--ld-body);font-size:.82rem;font-weight:600;color:var(--ld-muted);}

.drawer-form{display:flex;flex-direction:column;gap:.9rem;padding-top:.6rem;}
.drawer-form .muted{color:var(--ld-muted);font-size:.92rem;margin:0;}
.field2{display:flex;flex-direction:column;gap:.3rem;font-size:.86rem;font-weight:700;}
.field2 .muted{font-weight:500;color:var(--ld-muted);}
.field2 input,.field2 textarea{border:2px solid var(--ld-ink);border-radius:10px;padding:.7rem .9rem;
  font-family:var(--ld-body);font-size:.95rem;min-height:44px;color:var(--ld-ink);background:var(--ld-card);}
.field2 textarea{resize:vertical;min-height:auto;}
.field2 input:focus,.field2 textarea:focus{outline:3px solid var(--ld-accent);outline-offset:1px;}
.pref-row{display:flex;gap:.6rem;}
.pref-btn{flex:1;border:2px solid var(--ld-ink);background:var(--ld-card);color:var(--ld-ink);border-radius:10px;
  padding:.6rem;font-weight:700;cursor:pointer;font-family:var(--ld-body);font-size:.92rem;}
.pref-btn.is-on{background:var(--ld-ink);color:var(--ld-bg);}

.drawer-done{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;padding:2rem;gap:.8rem;}
.drawer-done__ic{width:64px;height:64px;border-radius:999px;background:var(--ld-leaf);border:2px solid var(--ld-ink);
  display:grid;place-items:center;color:#fff;}
.drawer-done__ic svg{width:30px;height:30px;}
.drawer-done h3{font-size:1.5rem;margin:0;}
.drawer-done p{color:var(--ld-muted);margin:0;max-width:32ch;}

/* ---------- product lightbox (photos + videos) ---------- */
.lb-scrim{position:fixed;inset:0;background:rgba(42,37,48,.65);z-index:210;display:flex;align-items:center;
  justify-content:center;padding:20px;opacity:0;visibility:hidden;transition:opacity .22s;}
.lb-scrim.open{opacity:1;visibility:visible;}
/* 2026-08-04: popup enlarged to ~75-80% of the browser window (was capped at
   940px/88vh, which read as small — and its text column could go too narrow,
   see the responsive fix note above). Width is capped (not fixed) at ~78vw;
   height is capped too (max-height only, not a forced height) so the panel
   hugs its content — most products have short info text (name + 2 buttons,
   no description), so forcing a fixed tall panel left a lot of empty white
   space next to the photo. .lb-info gets its own max-height+overflow so an
   unusually long description scrolls instead of stretching the whole panel
   or getting clipped by the panel's overflow:hidden. */
.lb-panel{width:min(1240px,78vw);max-height:82vh;background:var(--ld-card);
  border:2px solid var(--ld-ink);border-radius:20px;overflow:hidden;display:grid;
  grid-template-columns:minmax(320px,1.5fr) minmax(280px,1fr);}
.lb-viewer{display:flex;flex-direction:column;min-height:0;min-width:0;}
/* 2026-08-04b: photo is the primary object, not the text — gave it a bigger
   share of the grid (1.5fr vs 1fr, was 1.15fr) and softened the object-fit:
   contain letterbox bars from solid black to the same warm tint as the box
   background, so square/portrait product photos don't show harsh black
   voids on the sides inside the wider 4:3 frame. */
.lb-main{position:relative;aspect-ratio:4/3;max-height:100%;background:color-mix(in srgb,var(--ld-accent) 14%,#fff);overflow:hidden;}
.lb-main-el{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;background:transparent;}
.lb-main-ph{position:absolute;inset:0;display:grid;place-items:center;}
.lb-main-ph .daisy-spin{width:34%;}
.lb-nav{position:absolute;top:50%;transform:translateY(-50%);width:40px;height:40px;border-radius:999px;
  border:2px solid var(--ld-ink);background:#fff;cursor:pointer;display:grid;place-items:center;}
.lb-nav svg{width:18px;height:18px;}
.lb-nav--prev{left:10px;} .lb-nav--next{right:10px;}
.lb-close{position:absolute;top:10px;right:10px;width:36px;height:36px;border-radius:999px;border:2px solid var(--ld-ink);
  background:#fff;cursor:pointer;display:grid;place-items:center;}
.lb-close svg{width:16px;height:16px;}
.lb-count{position:absolute;bottom:10px;right:14px;background:rgba(42,37,48,.75);color:#fff;font-size:.72rem;
  font-weight:700;padding:.2rem .6rem;border-radius:999px;}
.lb-thumbs{display:flex;gap:.5rem;padding:.8rem;overflow-x:auto;border-top:1px solid var(--ld-line);}
.lb-thumb{position:relative;flex:0 0 auto;width:64px;height:50px;border-radius:8px;border:2px solid var(--ld-ink);
  padding:0;cursor:pointer;overflow:hidden;background:#000;}
.lb-thumb.is-on{border-color:var(--ld-primary);}
.lb-thumb img,.lb-thumb video{width:100%;height:100%;object-fit:cover;display:block;}
.lb-thumb-play{position:absolute;inset:0;display:grid;place-items:center;background:rgba(42,37,48,.35);}
.lb-thumb-play svg{width:14px;height:14px;color:#fff;}
.lb-info{padding:1.8rem;overflow-y:auto;max-height:82vh;min-width:0;}
.lb-cat{font-size:.72rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ld-muted);margin:0;}
.lb-info h3{font-size:1.6rem;margin:.2rem 0 .6rem;}
/* .lb-price removed 2026-08-01 — prices are not advertised publicly. */
.lb-desc{margin-top:.8rem;}
.lb-desc{color:var(--ld-muted);margin:0 0 1.4rem;overflow-wrap:break-word;}

/* ---------- lightbox: tag badges + flavor/size pickers (2026-08-05) ----------
   Fill the info panel's white space with product details at a glance:
   fulfilment/stock/preorder tags right under the name, then an
   optional flavor and/or size picker the shopper must resolve before
   either CTA activates (see productMissingSelection() in
   store-core.js). */
.lb-tags{display:flex;flex-wrap:wrap;gap:.4rem;margin:.5rem 0 0;}
.lb-tag{display:inline-flex;align-items:center;font-family:var(--ld-body);font-size:.74rem;font-weight:700;
  padding:.28rem .7rem;border-radius:999px;border:1.5px solid var(--ld-ink);
  background:color-mix(in srgb,var(--tint) 20%,#fff);color:color-mix(in srgb,var(--tint) 55%,var(--ld-ink));}
.lb-tag small{font-weight:600;opacity:.8;margin-left:.25em;}
.lb-opt-group{margin-top:1.1rem;}
.lb-opt-label{font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ld-muted);margin:0 0 .45rem;}
.lb-opt-row{display:flex;flex-wrap:wrap;gap:.5rem;}
.lb-opt{font-family:var(--ld-body);font-weight:600;font-size:.88rem;border:2px solid var(--ld-ink);background:var(--ld-card);
  border-radius:999px;padding:.42rem 1rem;cursor:pointer;min-height:38px;transition:background .16s,color .16s,transform .12s;}
.lb-opt:hover{transform:translateY(-1px);}
.lb-opt.is-on{background:var(--ld-ink);color:var(--ld-bg);}
.lb-hint{font-size:.84rem;font-weight:600;color:var(--ld-primary);margin:1rem 0 0;}
.lb-cta{display:flex;gap:.7rem;flex-wrap:wrap;margin-top:1.2rem;}
.lb-cta .btn[disabled]{opacity:.45;}

/* ---------- product lightbox — responsive ----------
   Placed AFTER the base rules above on purpose (see the note in the
   max-width:900px block earlier in this file) so it correctly wins the
   cascade and the popup stacks into one column with real scrolling on
   narrower windows/tablets, instead of being forced into a squeezed
   2-column layout with scrolling disabled. */
@media (max-width:900px){
  .lb-panel{grid-template-columns:1fr;width:min(560px,94vw);height:auto;max-height:92vh;overflow-y:auto;}
  .lb-main{max-height:60vh;}
}
@media (max-width:520px){
  .lb-info{padding:1.2rem;}
}
