/* ============================================================
   CARPCORE — Nishikigoi Herbiary shared design system
   A screen-printed risograph plate. NOT software, NOT an OS UI.
   Hard rules: no gradients (flat spot inks + halftone only), no OS
   chrome, no glossy bevels (depth = hard offset shadows + halftone +
   overlap), real product photos in taped frames, hand-drawn inked
   edges via SVG displacement filters (never nested). Full-bleed.
   Uses the real CARPCORE theme palette so it sits with the header/footer.
   Every home section adds `.cc-herb` to opt in.
   ============================================================ */
.cc-herb{
  /* paper — driven by the active color scheme (single source of truth) */
  --paper:var(--color-background); --paper-d:var(--color-brand-paper-dark); --paper-l:var(--color-brand-paper-light);
  /* ink + brand */
  --ink:var(--color-foreground); --navy:var(--color-brand-navy);
  --coral:var(--color-brand-coral); --lime:var(--color-brand-lime); --cer:var(--color-brand-cerulean); --pink:var(--color-brand-pink);
  --butter:var(--color-brand-butter); --grape:var(--color-brand-grape); --teal:var(--color-brand-teal); --mint:var(--color-brand-mint);
  --water:var(--color-brand-cerulean); --water-d:var(--color-brand-cerulean-deep); --good:var(--color-brand-forest);
  /* unified hard-offset depth scale + card shape (Phase 4 polish) */
  --sh-sm:3px 3px 0 var(--ink); --sh-md:6px 7px 0 var(--ink);
  --sh-lg:8px 9px 0 var(--ink); --sh-hover:10px 13px 0 var(--ink);
  /* press-stamp: on :active the element travels its shadow offset and the
     shadow collapses — pressed into the paper. Mirrors --sh-md/--sh-sm. */
  --press-md:translate(6px,7px); --press-sm:translate(3px,3px);
  --r-card:8px 5px 9px 6px;

  position:relative; width:100%; box-sizing:border-box;
  background:var(--paper); color:var(--ink);
  font-family:'Nunito',sans-serif;
  padding:clamp(34px,5vw,72px) clamp(16px,4vw,64px);
  overflow:hidden;
}
.cc-herb *{box-sizing:border-box;}
/* kill any horizontal page-scroll on small screens — every section already clips,
   this is belt-and-suspenders against stray transforms/shadows/decoration */
html, body{ overflow-x:clip; }
/* printed seam between stacked plates */
.cc-herb + .cc-herb::before{content:"";position:absolute;left:0;right:0;top:0;border-top:3px solid var(--ink);filter:url(#rough);z-index:3;}

/* ---- heavy paper texture: fine grain + coarse fibre + halftone dots ---- */
.cc-herb::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;mix-blend-mode:multiply;opacity:.5;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23f)' opacity='0.4'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='7'%3E%3Ccircle cx='1.3' cy='1.3' r='1' fill='%232C2218' fill-opacity='0.14'/%3E%3C/svg%3E");
  background-size:auto, 7px 7px;
}
.cc-herb > *{position:relative;z-index:1;}

/* full-bleed content by default; only text-heavy blocks get a readable cap */
.cc-herb__in{width:100%;}

/* ================= type / headings ================= */
.cc-herb .eyebrow{
  display:inline-flex;align-items:center;gap:7px;
  font-family:'Dela Gothic One',sans-serif;font-size:10px;letter-spacing:2px;text-transform:uppercase;
  color:var(--ink);background:var(--paper-l);border:2px solid var(--ink);
  padding:4px 10px;box-shadow:var(--sh-sm);
}
.cc-herb .eyebrow .dot{width:7px;height:7px;border-radius:50%;background:var(--lime);border:1.5px solid var(--ink);animation:cc-h-pulse 2.4s ease-in-out infinite;flex:none;}

.cc-herb .mast{font-family:'Mochiy Pop P One',sans-serif;line-height:.92;color:var(--ink);margin:0;
  font-size:clamp(34px,7vw,76px);letter-spacing:.5px;
  text-shadow:5px 5px 0 var(--coral), -2px -2px 0 rgb(var(--color-brand-cerulean-rgb) / .4);}

.cc-herb .subbar{display:inline-block;background:var(--ink);color:var(--paper-l);
  font-family:'Dela Gothic One',sans-serif;font-size:11px;letter-spacing:2px;text-transform:uppercase;
  padding:5px 14px;box-shadow:4px 4px 0 var(--butter);}

.cc-herb .stamp{display:inline-block;background:var(--coral);color:var(--paper-l);border:2px solid var(--ink);
  font-family:'Dela Gothic One',sans-serif;font-size:10px;letter-spacing:1px;text-transform:uppercase;
  padding:4px 9px;box-shadow:var(--sh-sm);}
.cc-herb .stamp--cer{background:var(--cer);}
.cc-herb .stamp--lime{background:var(--lime);}

/* readable body + headings */
.cc-herb .prose{font-family:'Nunito',sans-serif;font-size:clamp(1rem,1.4vw,1.12rem);line-height:1.55;color:var(--ink);}
.cc-herb .prose strong{font-weight:900;}

/* ================= catalogue grid — shared by the homepage grid
   section (template-parts/home/grid.php) and the WooCommerce shop/
   category archive (archive-product.php) ================= */
.cc-shop__carp{ position:absolute; right:-8%; top:12%; width:46%; max-width:620px; aspect-ratio:256/128; opacity:.05; z-index:0; transform:scaleX(-1) rotate(4deg); }
.cc-herb--shop .cc-herb__in{ max-width:1600px; margin-inline:auto; }
.cc-shop__head{ display:flex; flex-direction:column; gap:.8rem; align-items:flex-start; margin-bottom:clamp(1.4rem,3vw,2.6rem); }
.cc-shop__head-row{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; width:100%; }
/* .shopgrid itself (woocommerce/loop/loop-start.php + loop-end.php)
   isn't scoped to .cc-herb--shop — it's the grid wrapper for every
   WooCommerce product loop that uses woocommerce_product_loop_start()/
   _end(), which also includes "related products" on the single product
   page and cart cross-sells, not just the shop archive. */
.shopgrid{ display:grid; grid-template-columns:repeat(var(--cols,4),minmax(0,1fr));
  gap:clamp(32px,3.6vw,56px) clamp(18px,2.4vw,34px); align-items:start; padding:10px 4px 14px; }
.shopgrid .spec{ width:100%; }
.shopgrid .photo{ width:100%; padding:9px 9px 26px; }
.shopgrid .photo .cap{ font-size:15px; }
.shopgrid .cap.ped{ width:62%; }
.shopgrid .tag{ margin-top:13px; }
.shopgrid .tag .nm{ font-size:12px; line-height:1.25; }
.shopgrid .swing{ right:-8px; top:-10px; }
.shopgrid .spec:nth-child(even){ transform:rotate(-2deg); }
.shopgrid .spec:nth-child(odd){ transform:rotate(1.6deg); }
.shopgrid .spec:nth-child(3n) .photo{ filter:url(#rough2); }
.shopgrid .spec:nth-child(3n+1) .photo{ filter:url(#rough3); }
.shopgrid .spec:hover{ z-index:5; }
@media (max-width:1100px){ .shopgrid{ grid-template-columns:repeat(3,minmax(0,1fr)); } }
@media (max-width:760px){
  .shopgrid{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:32px 16px; }
  .shopgrid .swing{ right:-5px; }
}

/* ================= button (hard offset, no gloss) ================= */
.cc-herb .btn{
  display:inline-flex;align-items:center;gap:.5ch;cursor:pointer;text-decoration:none;
  font-family:'Dela Gothic One',sans-serif;font-size:12px;letter-spacing:1px;text-transform:uppercase;
  color:var(--paper-l);background:var(--coral);border:3px solid var(--ink);
  padding:11px 18px;box-shadow:5px 5px 0 var(--ink);
  transition:transform .1s,box-shadow .1s;
}
.cc-herb .btn:hover{transform:translate(-1px,-1px);box-shadow:6px 6px 0 var(--ink);}
.cc-herb .btn:active{transform:translate(5px,5px);box-shadow:0 0 0 var(--ink);}
.cc-herb .btn:focus-visible{outline:3px solid var(--cer);outline-offset:3px;}
.cc-herb .btn--navy{background:var(--navy);} .cc-herb .btn--cer{background:var(--cer);}
.cc-herb .btn--lime{background:var(--lime);} .cc-herb .btn--butter{background:var(--butter);}

/* ================= paper panel ================= */
.cc-herb .panel{position:relative;background:var(--paper-l);border:3px solid var(--ink);
  box-shadow:var(--sh-md);padding:16px 16px;border-radius:12px 6px 14px 7px;}
.cc-herb .panel h3{margin:0 0 10px;font-family:'Dela Gothic One',sans-serif;font-size:11px;text-transform:uppercase;
  letter-spacing:1px;position:relative;padding-bottom:7px;}
.cc-herb .panel h3::after{content:"";position:absolute;left:0;right:0;bottom:0;border-top:3px solid var(--ink);filter:url(#rough3);}

/* accent fills (real theme colours) */
.cc-herb .a-coral{--acc:var(--coral);--acc-ink:var(--color-brand-white);} .cc-herb .a-cer{--acc:var(--cer);--acc-ink:var(--color-brand-white);}
.cc-herb .a-lime{--acc:var(--lime);--acc-ink:var(--navy);} .cc-herb .a-pink{--acc:var(--pink);--acc-ink:var(--navy);}
.cc-herb .a-butter{--acc:var(--butter);--acc-ink:var(--navy);} .cc-herb .a-grape{--acc:var(--grape);--acc-ink:var(--color-brand-white);}

/* ================= taped specimen card (real product photo) ================= */
.cc-herb .spec{position:relative;display:flex;flex-direction:column;align-items:center;flex:none;text-decoration:none;color:inherit;}
.cc-herb .spec__link{position:relative;display:flex;flex-direction:column;align-items:center;width:100%;text-decoration:none;color:inherit;cursor:pointer;}
.cc-herb .spec__link:focus-visible{outline:3px solid var(--cer);outline-offset:4px;}

.cc-herb .photo{position:relative;border:3px solid var(--ink);background:var(--paper-l);
  padding:8px 8px 22px;box-shadow:var(--sh-md);border-radius:var(--r-card);filter:url(#rough);
  transition:transform .2s cubic-bezier(.3,1.5,.5,1),box-shadow .2s;}
.cc-herb .photo .tape{position:absolute;top:-9px;left:50%;transform:translateX(-50%) rotate(-3deg);
  width:46px;height:16px;background:rgb(var(--color-brand-white-rgb) / .45);border:1px solid rgb(var(--color-foreground-rgb) / .3);}
.cc-herb .photo .cap{position:absolute;left:8px;right:8px;bottom:5px;text-align:center;
  font-family:'VT323',monospace;font-size:14px;color:var(--navy);letter-spacing:1px;}
.cc-herb .photo .specimg{display:block;width:clamp(160px,22vw,220px);height:auto;max-width:100%;}
.cc-herb .spec:hover .photo{transform:translateY(-10px) rotate(-2deg);box-shadow:var(--sh-hover);}

/* fallback tee blank (only when a product has no image) */
.cc-herb .tee{width:84px;height:78px;position:relative;background:var(--coral);
  clip-path:polygon(28% 4%,38% 0,62% 0,72% 4%,100% 20%,86% 40%,78% 33%,78% 100%,22% 100%,22% 33%,14% 40%,0 20%);}
.cc-herb .tee::before{content:"";position:absolute;left:36%;top:0;width:28%;height:13%;background:var(--paper-l);
  clip-path:polygon(0 0,100% 0,80% 100%,20% 100%);}
.cc-herb .tee::after{content:"";position:absolute;inset:0;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6'%3E%3Ccircle cx='1.3' cy='1.3' r='1.1' fill='%232C2218' fill-opacity='0.4'/%3E%3C/svg%3E");
  -webkit-mask:linear-gradient(120deg,transparent 55%,var(--color-brand-black));mask:linear-gradient(120deg,transparent 55%,var(--color-brand-black));}
.cc-herb .tee.t-coral{background:var(--coral);}.cc-herb .tee.t-cer{background:var(--cer);}
.cc-herb .tee.t-butter{background:var(--butter);}.cc-herb .tee.t-grape{background:var(--grape);}
.cc-herb .tee.t-lime{background:var(--lime);}.cc-herb .tee.t-pink{background:var(--pink);}

/* keycap pedestal */
.cc-herb .cap.ped{width:96px;height:20px;border:3px solid var(--ink);margin-top:-3px;box-shadow:var(--sh-md);
  position:relative;border-radius:7px 5px 8px 6px;filter:url(#rough3);}
.cc-herb .cap.ped::before{content:"";position:absolute;left:7px;right:7px;top:3px;height:3px;background:rgb(var(--color-brand-white-rgb) / .5);}
.cc-herb .c-coral{background:var(--coral);}.cc-herb .c-cer{background:var(--cer);}.cc-herb .c-butter{background:var(--butter);}
.cc-herb .c-lime{background:var(--lime);}.cc-herb .c-pink{background:var(--pink);}.cc-herb .c-grape{background:var(--grape);}

/* tag: name + spec + status pill */
.cc-herb .tag{margin-top:11px;text-align:center;}
.cc-herb .tag .nm{display:block;font-family:'Dela Gothic One',sans-serif;font-size:11px;text-transform:uppercase;letter-spacing:.4px;color:var(--ink);}
.cc-herb .tag .sp{display:block;font-family:'VT323',monospace;font-size:14px;color:var(--navy);}

/* price swing-tag, punched on the card corner */
.cc-herb .swing{position:absolute;top:-9px;right:-13px;z-index:5;background:var(--paper-l);border:3px solid var(--ink);
  border-radius:5px 5px 8px 5px;padding:2px 8px 2px 15px;font-family:'VT323',monospace;font-size:15px;color:var(--ink);
  box-shadow:var(--sh-sm);transform:rotate(6deg);filter:url(#rough2);line-height:1.2;}
.cc-herb .swing::before{content:"";position:absolute;left:5px;top:50%;width:6px;height:6px;border:2px solid var(--ink);
  border-radius:50%;transform:translateY(-50%);background:var(--paper);}

/* press-stamp on the cards themselves (after the hover rules so :active wins) */
.cc-herb .spec__link:active .photo,
.cc-herb .cc-cat:active .photo{
  transform:var(--press-md); box-shadow:0 0 0 var(--ink);
  transition:transform .08s, box-shadow .08s;
}

/* ================= printed marquee ticker ================= */
.cc-herb .marq{position:relative;border:3px solid var(--ink);background:var(--navy);color:var(--paper-l);
  overflow:hidden;box-shadow:var(--sh-md);border-radius:8px 5px 10px 6px;filter:url(#rough);}
.cc-herb .marq .track{display:inline-block;white-space:nowrap;font-family:'VT323',monospace;font-size:18px;letter-spacing:1px;
  padding:7px 0;animation:cc-h-scroll var(--cc-h-speed,28s) linear infinite;}
.cc-herb .marq .track span{margin:0 16px;}
.cc-herb .marq .track b{color:var(--butter);font-weight:400;}

/* ================= carp print (silhouette as flat ink) ================= */
.cc-herb .carp-print{background:var(--ink);opacity:.07;pointer-events:none;
  -webkit-mask:url("carp-silhouette.svg") center/contain no-repeat;mask:url("carp-silhouette.svg") center/contain no-repeat;}

@keyframes cc-h-pulse{0%,100%{opacity:1;}50%{opacity:.45;}}
@keyframes cc-h-scroll{from{transform:translateX(0);}to{transform:translateX(-50%);}}

@media (max-width:760px){
  /* keep the marquee scroll compositor-only: an ancestor SVG filter would
     force the infinitely-animating track to re-rasterize every frame */
  .cc-herb .marq{ filter:none; }
  /* grain without the blend: 8 stacked multiply layers are real compositing
     work on phone GPUs; plain low-opacity noise reads the same at arm's length.
     (The lore band's higher-specificity screen-blend override still wins there.) */
  .cc-herb::after{ mix-blend-mode:normal; opacity:.3; }
}
@media (max-width:560px){
  /* lighter depth on phones: smaller hard-offset shadows so cards don't get
     clipped at the section edge and the page reads less heavy. Rescales every
     section at once via the shared tokens. */
  .cc-herb{ --sh-sm:2px 2px 0 var(--ink); --sh-md:4px 4px 0 var(--ink);
            --sh-lg:5px 5px 0 var(--ink); --sh-hover:6px 6px 0 var(--ink);
            --press-md:translate(4px,4px); --press-sm:translate(2px,2px); }
  /* tame the horizontal padding floor so content gets more usable width */
  .cc-herb{ padding-left:clamp(14px,4vw,64px); padding-right:clamp(14px,4vw,64px); }
}
@media (prefers-reduced-motion: reduce){ .cc-herb *{animation:none !important; transition:none !important;} }

/* ============================================================
   ALIVE — scroll choreography (the plate prints itself).
   Every pre-state is gated on html.cc-alive, added by an inline
   <head> script ONLY under (prefers-reduced-motion:no-preference)
   with IntersectionObserver support. No JS / reduced motion /
   old browser → nothing below applies; the page is fully static.
   Entrances ride the independent translate/rotate/scale props so
   they COMPOSE with — never clobber — the resting nth-child
   transform tilts (carpcore-grid.liquid, categories) and
   the hover/press transforms on .photo.
   ============================================================ */
.cc-sr{position:absolute;width:1px;height:1px;clip-path:inset(50%);overflow:hidden;white-space:nowrap;}

/* ---- headers print themselves ---- */
/* eyebrow: real text → clip-path print (no textContent mutation);
   -12px insets keep the hard-offset shadow inside the reveal */
.cc-alive .cc-herb:not(.is-inked) .eyebrow{clip-path:inset(-12px 101% -12px -12px);}
.cc-alive .cc-herb.is-inked .eyebrow{clip-path:inset(-12px -12px -12px -12px);
  transition:clip-path .42s cubic-bezier(.3,.9,.3,1) .04s;}

.cc-alive .cc-herb:not(.is-inked) .mast{opacity:0;translate:0 16px;}
.cc-alive .cc-herb.is-inked .mast{opacity:1;translate:0 0;
  transition:opacity .45s ease .12s,translate .55s cubic-bezier(.22,1,.36,1) .12s;}

.cc-alive .cc-herb .subbar{transform-origin:left center;}
.cc-alive .cc-herb:not(.is-inked) .subbar{transform:scaleX(0);}
.cc-alive .cc-herb.is-inked .subbar{transform:scaleX(1);
  transition:transform .45s cubic-bezier(.3,1,.4,1) .3s;}

/* ---- specimen cards & category tiles settle into their tilt ----
   .cc-cat carries .spec too; --i is set per-section by JS (capped 8) */
.cc-alive .cc-herb:not(.is-inked) .spec{opacity:0;translate:0 26px;rotate:3.5deg;}
.cc-alive .cc-herb:not(.is-inked) .spec:nth-child(even){rotate:-3.5deg;}
.cc-alive .cc-herb.is-inked .spec{opacity:1;translate:0 0;rotate:0deg;
  transition:opacity .4s ease,translate .55s cubic-bezier(.2,1.2,.35,1),rotate .55s cubic-bezier(.2,1.2,.35,1);
  transition-delay:calc(.1s + var(--i,0)*.07s);}

/* tape lands a beat after its photo */
.cc-alive .cc-herb:not(.is-inked) .photo .tape{opacity:0;translate:0 -7px;}
.cc-alive .cc-herb.is-inked .photo .tape{opacity:1;translate:0 0;
  transition:opacity .28s ease,translate .28s ease;
  transition-delay:calc(.36s + var(--i,0)*.07s);}

/* rubber-stamp slam (the email reward badge) — keyframes touch only
   scale/rotate so the element returns to its own resting opacity */
@keyframes cc-a-slam{0%{scale:1.55;rotate:6deg;}62%{scale:.94;rotate:-2deg;}100%{scale:1;rotate:0deg;}}
.cc-alive .cc-herb:not(.is-inked) .cc-email__badge{opacity:0;}
.cc-alive .cc-herb.is-inked .cc-email__badge{
  animation:cc-a-slam .22s cubic-bezier(.2,.8,.3,1.3) .38s both;
  transition:opacity .08s ease-out .38s;}

/* ---- printed seam draws itself left → right ---- */
.cc-alive .cc-herb + .cc-herb:not(.is-inked)::before{transform:scaleX(0);transform-origin:left center;}
.cc-alive .cc-herb + .cc-herb.is-inked::before{transform:scaleX(1);transform-origin:left center;
  transition:transform .45s cubic-bezier(.3,.9,.3,1) .05s;}

/* ---- marquee: JS velocity takeover kills the keyframe only after
   seeding x from the live matrix (no jump) ---- */
.cc-alive .marq.is-live .track{animation:none;will-change:transform;}

/* ============================================================
   DIORAMA — the page is a layered paper shadow-box. JS
   (carpcore-alive.js) writes ONE unitless --p per .cc-herb:
   section centre vs viewport centre, +1 (waiting below) → 0
   (centred, flat) → -1 (exited above). Every visual mapping
   lives here in calc(); no JS / reduced motion → --p is never
   set and every var(--p,0) collapses to a dead-flat plate.
   All depth rides the INDEPENDENT rotate/translate/scale props
   so it composes with entrance choreography (children), resting
   nth-child tilts and hover/press transforms.
   HARD RULE: .cc-feat, .cc-feat__inner and .cc-win are ancestors
   of the position:fixed tama modal — they must NEVER match a
   rule that sets transform/rotate/translate/scale/filter/
   perspective/will-change (see carpcore-featured.css).
   ============================================================ */

/* the shadow-box: perspective on the section (safe — no fixed
   descendants outside .cc-feat, which is excluded) */
.cc-alive .cc-herb:not(.cc-feat){ perspective:1000px; perspective-origin:50% 50%; }

/* 1 · plate tilt: the content plate leans back while entering,
   lies flat at centre, tips forward on exit. rotate is FREE on
   these wrappers — entrances animate their children only. */
.cc-alive .cc-herb__in{ rotate:x calc(var(--p,0) * 5.5deg); }
.cc-alive .cc-herb--marq .marq{ rotate:x calc(var(--p,0) * 3.5deg); }

/* promote the plates on desktop only (iOS layer-memory budget:
   scroll-driven transforms self-promote while animating) */
@media (min-width:761px){
  .cc-alive .cc-herb__in,
  .cc-alive .cc-herb--marq .marq{ will-change:transform; }
}

/* 2 · watermark stratum: the printed carp lies DEEP in the box —
   it lags the scroll (negative coefficient) and swells toward the
   centre so the box reads bigger than the page. translate/scale
   compose with the transform:scaleX(-1)/rotate() flips these carry. */
.cc-alive .cc-hero__carp,
.cc-alive .cc-shop__carp,
.cc-alive .cc-lore__carp{
  translate:0 calc(var(--p,0) * -120px);
  scale:calc(1.16 - var(--p,0) * var(--p,0) * 0.2);
}

/* 3 · strata inside the plate: headers ride nearest the glass
   (drift slightly faster than the plate), racks a half-step behind.
   These wrappers carry no entrance/hover transforms of their own. */
.cc-alive .cc-shop__head,
.cc-alive .cc-cats__head,
.cc-alive .cc-lore__top,
.cc-alive .cc-email__text{ translate:0 calc(var(--p,0) * 24px); }
.cc-alive .shopgrid,
.cc-alive .cc-cats__rack{ translate:0 calc(var(--p,0) * 10px); }

/* mobile: shorter throw, nearer vanishing point — the depth must
   still be FELT at arm's length, just inside smaller sections */
@media (max-width:760px){
  .cc-alive .cc-herb:not(.cc-feat){ perspective:900px; }
  .cc-alive .cc-herb__in{ rotate:x calc(var(--p,0) * 4deg); }
  .cc-alive .cc-herb--marq .marq{ rotate:x calc(var(--p,0) * 2.8deg); }
  .cc-alive .cc-hero__carp, .cc-alive .cc-shop__carp,
  .cc-alive .cc-lore__carp{
    translate:0 calc(var(--p,0) * -70px);
  }
  .cc-alive .cc-shop__head, .cc-alive .cc-cats__head,
  .cc-alive .cc-lore__top,
  .cc-alive .cc-email__text{ translate:0 calc(var(--p,0) * 16px); }
}

/* 5 · pointer flex (desktop): the corner under the cursor presses
   into the paper. .cc-p3d is set by JS on the tilt target's parent. */
@media (hover:hover) and (pointer:fine){
  .cc-alive .cc-p3d{ perspective:700px; }
  /* re-declare the photo's own pair, then ease the rotate reset */
  .cc-alive .cc-herb .photo{
    transition:transform .2s cubic-bezier(.3,1.5,.5,1),box-shadow .2s,rotate .16s ease-out;
  }
}

/* 6 · depth of field: plates are brightest at the centre of the box,
   dimming slightly at its edges (compositor-only; the wrapper carries
   no other opacity — entrances fade its CHILDREN) */
.cc-alive .cc-herb__in{ opacity:calc(1 - min(var(--p,0) * var(--p,0), 1) * 0.08); }

/* 7 · chromatic misregistration (desktop): the masthead's coral/blue
   print offsets slide with depth — the risograph plates drift out of
   register as the sheet tilts. Paint-cost bounded: 5 masts, ≥761px only. */
@media (min-width:761px){
  .cc-alive .cc-herb .mast{
    text-shadow:calc(5px + var(--p,0) * 6px) calc(5px + var(--p,0) * 6px) 0 var(--coral),
      calc(-2px - var(--p,0) * 4px) calc(-2px - var(--p,0) * 4px) 0 rgb(var(--color-brand-cerulean-rgb) / .4);
  }
}

/* 8 · press-room dust: tiny flat-ink shop marks drifting in the deep
   stratum. Injected by carpcore-alive.js ONLY under html.cc-alive, so
   the static page never carries them. Float loop is transform-only;
   the independent `translate` rides the diorama --p with a per-fleck
   multiplier so the dust visibly lives deeper than the content. */
.cc-alive .cc-dust{ position:absolute; left:var(--dx,50%); top:var(--dy,50%); z-index:0; pointer-events:none;
  opacity:.16; translate:0 calc(var(--p,0) * var(--dm,1) * -46px);
  animation:cc-dust-float var(--dd,18s) ease-in-out var(--dg,0s) infinite; }
@keyframes cc-dust-float{ 0%,100%{ transform:translateY(0) rotate(0deg); } 50%{ transform:translateY(-16px) rotate(9deg); } }
.cc-alive .cc-dust--d{ width:7px; height:7px; border-radius:50%; background:var(--coral); }
.cc-alive .cc-dust--x{ width:12px; height:12px; }
.cc-alive .cc-dust--x::before,.cc-alive .cc-dust--x::after{ content:""; position:absolute; background:var(--ink); }
.cc-alive .cc-dust--x::before{ left:5px; top:0; width:2px; height:12px; }
.cc-alive .cc-dust--x::after{ left:0; top:5px; width:12px; height:2px; }
.cc-alive .cc-dust--c{ width:11px; height:11px; border-left:2px solid var(--ink); border-top:2px solid var(--ink); }
.cc-alive .cc-dust--f{ width:8px; height:8px; background:var(--cer); rotate:45deg; }
/* navy bands: ink marks vanish on navy — flip them to paper */
.cc-alive .cc-herb--lore .cc-dust--x::before,.cc-alive .cc-herb--lore .cc-dust--x::after,
.cc-alive .cc-herb--email .cc-dust--x::before,.cc-alive .cc-herb--email .cc-dust--x::after{ background:var(--paper-l); }
.cc-alive .cc-herb--lore .cc-dust--c,.cc-alive .cc-herb--email .cc-dust--c{ border-color:var(--paper-l); }
