/* ============================================================
 * Truffle Pig — Shadow Marketing Landing (TP-68 v3)
 *
 * v3 redesign:
 *  - Counter region removed (giant number, tier progress).
 *  - Truffle bucket replaces it: 3 truffles drop as required fields
 *    fill; harvest animation on submit success.
 *  - Atmospheric layer: topographic map background, magnifying-glass
 *    cursor reveal of hidden phrases, redacted polaroid notes.
 *  - Form-focus sniff: pig glows + scales when form has focus.
 *  - Typing mud splatters near email input.
 *  - Footer flex-pinned to viewport bottom on standard laptop.
 *  - prefers-reduced-motion: reduce kills every interactive animation.
 *
 * Self-contained: declares its own surface/slate/pink palette; the
 * --lp-pink-* tokens never bridge to the app's @theme.
 * Pink anchors hand-tuned + AA-verified (TP-68 commit 1 + bumped
 * border anchors from v2: #f0b5cc light / #783050 dark).
 * ============================================================ */

:root {
  --surface-0:        #f6f7f9;
  --surface-1:        #ffffff;
  --surface-2-inset:  #f1f5f9;
  --border-card:      #d4d9e1;
  --border-divider:   #e5e7eb;
  --slate-fill:       #8796ab;
  --slate-muted:      #627085;
  --slate-body:       #475569;
  --slate-heading:    #0f172a;
  --shadow-card-rest: 0 1px 3px rgba(15, 23, 42, 0.04), 0 1px 2px rgba(15, 23, 42, 0.02);

  --lp-pink-tint:   #fef3f8;
  --lp-pink-border: #f0b5cc;
  --lp-pink-fill:   #e94a87;
  --lp-pink-bg:     #d63572;
  --lp-pink-text:   #b8265f;
  --lp-pink-on-bg:  #ffffff;

  /* Truffle / mud / parchment — used by bucket + redacted notes + mud splat */
  --truffle-brown: #5a3818;
  --truffle-dark:  #3a2410;
  --mud-brown:     #6b4423;
  --parchment-bg:  #fff9e6;
  --parchment-edge:#d4c98a;
  --parchment-ink: #3d3520;

  --sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --gutter: 24px;
}

html.dark {
  --surface-0:        #0f1117;
  --surface-1:        #1e2030;
  --surface-2-inset:  #161825;
  --border-card:      #373e50;
  --border-divider:   #2e3245;
  --slate-fill:       #5d6c81;
  --slate-muted:      #8a98ad;
  --slate-body:       #cbd5e1;
  --slate-heading:    #f8fafc;
  --shadow-card-rest: 0 1px 3px rgba(0, 0, 0, 0.3);

  --lp-pink-tint:   #2a1620;
  --lp-pink-border: #783050;
  --lp-pink-fill:   #e35a8e;
  --lp-pink-text:   #f4a8c4;

  --parchment-bg:   #2a2615;
  --parchment-edge: #5a4d20;
  --parchment-ink:  #d4c98a;
}

* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0;
  font-family: var(--sans);
  color: var(--slate-body);
  background: var(--surface-0);
  font-size: 16px; line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;  /* mag overlay + map bg are full-bleed; lock x-overflow */
}
a { color: inherit; }
img { max-width: 100%; display: block; }

/* ============ STAGE 2: TOPOGRAPHIC MAP BACKGROUND ============ */
.shadow-map-bg {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  z-index: 0;
  pointer-events: none;
  color: var(--slate-heading);
  opacity: 0.055;
}
html.dark .shadow-map-bg { opacity: 0.085; }
.shadow-map-grid line { stroke-opacity: 0.6; }
.shadow-map-coords text { opacity: 0.7; }

/* ============ STAGE 4: MAGNIFYING GLASS OVERLAY ============ */
.shadow-mag-overlay {
  position: fixed;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  --mx: -200px; --my: -200px;  /* off-screen by default so phrases stay hidden */
  -webkit-mask-image: radial-gradient(circle 140px at var(--mx) var(--my),
                                       rgba(0,0,0,1) 38%,
                                       rgba(0,0,0,0.45) 70%,
                                       transparent 100%);
          mask-image: radial-gradient(circle 140px at var(--mx) var(--my),
                                       rgba(0,0,0,1) 38%,
                                       rgba(0,0,0,0.45) 70%,
                                       transparent 100%);
}
.shadow-mag-phrase {
  position: absolute;
  font-size: 13px;
  font-style: italic;
  color: var(--lp-pink-text);
  letter-spacing: 0.04em;
  white-space: nowrap;
  text-shadow: 0 1px 6px rgba(214, 53, 114, 0.25);
}
html.dark .shadow-mag-phrase { color: var(--lp-pink-text); }

/* Hero-scale phrase between the two columns — bigger, multi-line, same
   cursor-lens reveal mechanic via inheritance from .shadow-mag-overlay. */
.shadow-mag-phrase-hero {
  position: absolute;
  font-size: clamp(28px, 3vw, 40px);
  font-weight: 600;
  font-style: italic;
  color: var(--slate-heading);  /* base color flipped from pink to slate-heading;
                                   "pig" word inside gets the pink accent via
                                   .shadow-mag-pig-word. */
  line-height: 1.2;
  /* 200px keeps the phrase fully inside the inter-column gap at every
     desktop resolution (1280-2560) — combined with the left:max() anchor
     in the inline style, right-edge clearance to the form column is a
     constant ~30px regardless of viewport. Text wraps tighter as a
     trade-off. */
  max-width: 200px;
  text-shadow: 0 2px 12px rgba(214, 53, 114, 0.20);
}
.shadow-mag-pig-word {
  color: var(--lp-pink-text);
}

/* ============ PAGE + LAYOUT ============ */
.shadow-page {
  max-width: 1120px;
  margin: 0 auto;
  padding: 32px var(--gutter) 24px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  position: relative;
  z-index: 1;  /* above map bg */
}

.shadow-layout {
  display: flex;
  flex-direction: column;
  gap: 32px;
  flex: 1;
  position: relative;  /* anchor for redacted-notes absolute positioning */
}
@media (min-width: 768px) {
  .shadow-layout {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 56px;
    align-items: start;
  }
}

/* ============ STAGE 4b: SPARKLE DISCOVERY HINTS ============
   Always-visible markers anchored at every hidden-phrase position so
   trackpad/idle-mouse users notice "something is here" without the
   mag-glass lens revealing the phrase content. Two layered signals:

     1. Pulse at rest — soft pink dot, 2.6-3.2s opacity+scale loop.
     2. Pre-glow on approach — ::after halo (240px radius) fades in
        when cursor enters ~300px proximity (toggled by .is-glowing
        from the rAF mousemove handler in shadow.html).

   Sparkles are siblings of .shadow-mag-overlay, NOT children — the
   overlay's mask-image clips its children to the cursor lens.
   See shadow.html for the markup + JS proximity calculation. */
.shadow-sparkles {
  position: fixed; inset: 0;
  z-index: 4;
  pointer-events: none;
}
.shadow-sparkle {
  position: absolute;
  width: 10px; height: 10px;
  margin-left: -5px; margin-top: -5px;
  border-radius: 50%;
  background: radial-gradient(circle,
                              rgba(233, 74, 135, 0.95) 0%,
                              rgba(233, 74, 135, 0.50) 40%,
                              rgba(233, 74, 135, 0)    100%);
  animation: shadow-sparkle-pulse 2.6s ease-in-out infinite alternate;
}
.shadow-sparkle-hero {
  width: 16px; height: 16px;
  margin-left: -8px; margin-top: -8px;
  animation-duration: 3.2s;
}
@keyframes shadow-sparkle-pulse {
  0%   { opacity: 0.35; transform: scale(0.85); }
  100% { opacity: 0.95; transform: scale(1.10); }
}
/* Pre-glow halo — class toggled by JS proximity hysteresis (300/360 px). */
.shadow-sparkle::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: 240px; height: 240px;
  margin-left: -120px; margin-top: -120px;
  border-radius: 50%;
  background: radial-gradient(circle,
                              rgba(233, 74, 135, 0.10) 0%,
                              rgba(233, 74, 135, 0.04) 50%,
                              transparent              100%);
  opacity: 0;
  transition: opacity 200ms ease-out;
  pointer-events: none;
}
.shadow-sparkle.is-glowing::after { opacity: 1; }

@media (max-width: 767px) {
  /* Cursor-reveal mechanic doesn't apply on touch; hide the entire
     sparkle layer (same !important hammer as .shadow-mag-overlay). */
  .shadow-sparkles { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  /* Stop the pulse loop (continuous motion) but keep sparkles visible —
     the marker is still informative as a static dot. Halo transition
     becomes instant so it's purely positional, not animated. */
  .shadow-sparkle { animation: none; opacity: 0.7; transform: none; }
  .shadow-sparkle::after { transition: none; }
}

/* ============ STAGE 5: REDACTED EVIDENCE NOTES ============ */
.shadow-evidence-notes {
  position: absolute;
  inset: 0;
  pointer-events: none;  /* won't block clicks; readable but non-interactive */
  z-index: 4;  /* above .shadow-col-form (z:3) so notes aren't occluded by
                  the form's white card when positioned in the column area */
}
.shadow-evidence-note {
  position: absolute;
  transform: rotate(var(--rot, 0));
  background: var(--parchment-bg);
  border: 1px solid var(--parchment-edge);
  border-radius: 2px;
  padding: 9px 14px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--parchment-ink);
  box-shadow: 1px 3px 8px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
  max-width: 200px;
  font-family: 'Inter', sans-serif;
  opacity: 0.88;
}
.shadow-evidence-note .redacted {
  display: inline-block;
  background: #000;
  color: #000;
  height: 0.95em;
  width: 64px;
  vertical-align: text-bottom;
  margin: 0 3px;
  border-radius: 1px;
}
@media (max-width: 767px) {
  /* Cursor-reveal mechanic doesn't work on touch devices (no hover) and
     phrases would clutter the stacked single-column layout. Hide the
     entire mag-glass overlay (5 small phrases + hero phrase) AND every
     phrase descendant under 768px. !important defeats any inline-style or
     specificity surprise. */
  .shadow-evidence-notes,
  .shadow-mag-overlay,
  .shadow-mag-phrase,
  .shadow-mag-phrase-hero {
    display: none !important;
  }
}

/* ============ LEFT COLUMN — hero ============ */
.shadow-col-hero {
  text-align: center;
  position: relative;
}
@media (min-width: 768px) {
  .shadow-col-hero { text-align: left; }
}
.shadow-headline {
  font-size: clamp(28px, 4.5vw, 44px);
  line-height: 1.1;
  letter-spacing: -0.025em;
  font-weight: 800;
  color: var(--slate-heading);
  margin: 0 0 16px;
}
.shadow-lede {
  font-size: 17px;
  line-height: 1.5;
  max-width: 480px;
  margin: 0 auto 28px;
  color: var(--slate-body);
}
@media (min-width: 768px) {
  .shadow-lede { margin: 0 0 28px; }
}

/* Pig + halo */
.shadow-pig-wrap {
  position: relative;
  display: flex;
  justify-content: center;
  margin: 8px auto 0;
}
@media (min-width: 768px) {
  .shadow-pig-wrap { justify-content: flex-start; }
}
.shadow-pig-wrap::before {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 280px; height: 280px;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, var(--lp-pink-tint) 0%, transparent 70%);
  z-index: 0;
  pointer-events: none;
  filter: blur(8px);
}
@media (min-width: 768px) {
  .shadow-pig-wrap::before { left: 90px; }
}
.shadow-pig {
  width: 180px; height: auto;
  position: relative; z-index: 1;
  object-fit: contain;
  transition: filter 0.4s ease, transform 0.4s ease;
}
@media (max-width: 380px) {
  .shadow-pig { width: 140px; }
  .shadow-pig-wrap::before { width: 220px; height: 220px; }
}

/* ============ RIGHT COLUMN — bucket + form ============ */
.shadow-col-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  position: relative;
  z-index: 3;  /* above evidence-notes (z:2) so form is always interactive */
}

/* ============ STAGE 3: TRUFFLE BUCKET ============ */
.shadow-bucket-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
}
.shadow-bucket-svg {
  width: 130px;
  height: auto;
  overflow: visible;  /* truffles can fly out beyond viewBox on harvest */
}
.shadow-bucket-caption {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--slate-muted);
  transition: color 0.3s ease;
}

/* Truffles start hidden; reveal as the form fills required fields. */
.shadow-truffle {
  opacity: 0;
  transform: translateY(-28px) scale(0.5);
  transition: opacity 0.45s ease, transform 0.5s cubic-bezier(.34, 1.56, .64, 1);
  transform-origin: center;
  transform-box: fill-box;
}
/* Reveal rule uses :has() because the bucket SVG is a SIBLING of the form,
   not a descendant — classes toggle on the form, but the targeted truffles
   live in the bucket-wrap above it. Both share .shadow-col-form as their
   common ancestor, so :has() resolves correctly. */
.shadow-col-form:has(.shadow-form.has-truffle-1) .shadow-truffle[data-slot="1"],
.shadow-col-form:has(.shadow-form.has-truffle-2) .shadow-truffle[data-slot="2"],
.shadow-col-form:has(.shadow-form.has-truffle-3) .shadow-truffle[data-slot="3"] {
  opacity: 1;
  transform: translateY(0) scale(1);
}
.shadow-form.shadow-cta-ready ~ * .shadow-bucket-caption,
.shadow-col-form:has(.shadow-form.shadow-cta-ready) .shadow-bucket-caption {
  color: var(--lp-pink-text);
}

/* Harvest animation — bucket tilts, truffles fly out toward CTA on submit success. */
.shadow-form.shadow-success ~ * .shadow-bucket,
.shadow-col-form:has(.shadow-form.shadow-success) .shadow-bucket {
  animation: shadow-bucket-tilt 0.6s ease-out forwards;
  transform-origin: 100px 208px;
}
@keyframes shadow-bucket-tilt {
  0%   { transform: rotate(0deg)   translateY(0); }
  35%  { transform: rotate(-12deg) translateY(-8px); }
  70%  { transform: rotate(8deg)   translateY(2px); }
  100% { transform: rotate(0deg)   translateY(0); }
}
/* The 3 in-bucket truffles stay visible after submit success — they don't
   fly out. The bucket still tilts briefly (above), and the page-wide
   truffle rain (.shadow-rain-truffle particles spawned by JS) does the
   celebratory work. */

/* ============ TRUFFLE RAIN (page-wide harvest) ============ */
/* On submit success, JS spawns ~18 .shadow-rain-truffle DOM elements at
   the bucket region. They fall to the viewport bottom with gravity easing,
   rotate as they go, and PERSIST at their landing position (no fade) —
   accumulating like a real harvest. */
.shadow-rain-truffle {
  position: fixed;
  width: 18px;
  height: 18px;
  pointer-events: none;
  z-index: 6;
  border-radius: 50%;
  background:
    radial-gradient(circle at 35% 38%, var(--truffle-dark) 8%, transparent 10%),
    radial-gradient(circle at 65% 62%, var(--truffle-dark) 6%, transparent 8%),
    radial-gradient(circle at 50% 50%, var(--truffle-brown) 100%);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
  transform: translate(-50%, -50%);
  animation-name: shadow-rain-fall;
  animation-fill-mode: forwards;
  animation-timing-function: cubic-bezier(0.5, 0, 0.7, 0.5);
  /* opacity stays 1 throughout — persists at end of animation */
}
@keyframes shadow-rain-fall {
  0%   { transform: translate(-50%, -50%) rotate(0deg); }
  100% { transform: translate(
           calc(-50% + var(--drift-x, 0px)),
           calc(-50% + var(--fall-y, 600px))
         ) rotate(var(--spin, 720deg)); }
}

/* ============ FORM ============ */
.shadow-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: var(--surface-1);
  border: 1px solid var(--border-card);
  border-radius: 16px;
  padding: 20px;
  box-shadow: var(--shadow-card-rest);
  position: relative;
}
.shadow-field { display: flex; flex-direction: column; gap: 6px; }
.shadow-label {
  font-size: 13px; font-weight: 600; color: var(--slate-heading);
}
.shadow-optional { color: var(--slate-muted); font-weight: 400; }

.shadow-field input[type="email"],
.shadow-field input[type="text"] {
  width: 100%;
  padding: 10px 13px;
  border: 1px solid var(--border-card);
  border-radius: 8px;
  background: var(--surface-1);
  color: var(--slate-heading);
  font: inherit;
  font-size: 15px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.shadow-field input:focus {
  outline: none;
  border-color: var(--lp-pink-fill);
  box-shadow: 0 0 0 3px var(--lp-pink-tint);
}

.shadow-audience {
  border: 0; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.shadow-audience legend { padding: 0; margin-bottom: 6px; }
.shadow-radio {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 11px;
  border: 1px solid var(--border-card);
  border-radius: 8px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  font-size: 14px;
}
.shadow-radio:hover { border-color: var(--lp-pink-border); background: var(--lp-pink-tint); }
.shadow-radio input { accent-color: var(--lp-pink-bg); }

.shadow-honeypot {
  position: absolute; left: -9999px; top: -9999px;
  width: 1px; height: 1px; overflow: hidden;
  opacity: 0; pointer-events: none;
}

/* CTA — base + ready-state pulsing pink glow */
.shadow-cta-wrap {
  position: relative;
  display: flex;
  justify-content: center;
}
.shadow-cta {
  background: var(--lp-pink-bg);
  color: var(--lp-pink-on-bg);
  border: 1px solid var(--lp-pink-bg);
  border-radius: 10px;
  padding: 13px 22px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: transform 0.1s ease-out, filter 0.15s, box-shadow 0.3s;
  width: 100%;
}
.shadow-cta:hover:not(:disabled) { filter: brightness(1.08); transform: translateY(-1px); }
.shadow-cta:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

.shadow-form.shadow-cta-ready .shadow-cta {
  animation: shadow-cta-pulse 1.4s ease-in-out infinite;
}
@keyframes shadow-cta-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(214, 53, 114, 0.45); }
  50%      { box-shadow: 0 0 0 10px rgba(214, 53, 114, 0); }
}

.shadow-privacy {
  font-size: 12px; color: var(--slate-muted);
  text-align: center;
  margin: 0;
}

.shadow-error {
  font-size: 13px; color: #cc3934;
  background: #fef4f4;
  border: 1px solid #facac9;
  border-radius: 8px;
  padding: 10px 12px;
  margin: 0;
}
html.dark .shadow-error { color: #f46b6b; background: #382330; border-color: #6e282f; }

.shadow-success-state {
  text-align: center;
  background: var(--lp-pink-tint);
  border: 1px solid var(--lp-pink-border);
  border-radius: 12px;
  padding: 18px;
  animation: shadow-fade-in 0.35s ease-out;
}
.shadow-success-headline {
  font-size: 18px; font-weight: 700;
  color: var(--lp-pink-text);
  margin: 0 0 6px;
}
.shadow-success-detail {
  font-size: 14px; color: var(--slate-body); margin: 0;
}
.shadow-success-num { font-weight: 700; }
@keyframes shadow-fade-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Tier badge — only rendered in the success card (renamed from
   .shadow-counter-tier in v3). */
.shadow-tier-badge {
  font-size: 14px;
  font-weight: 700;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--lp-pink-border);
  letter-spacing: 0.02em;
  display: inline-block;
}
.shadow-tier-badge[data-tier="Founders"] {
  background: var(--lp-pink-bg);
  color: var(--lp-pink-on-bg);
  border-color: var(--lp-pink-bg);
}
.shadow-tier-badge[data-tier="Trailblazer"] {
  background: var(--lp-pink-tint);
  color: var(--lp-pink-text);
  border-color: var(--lp-pink-border);
}
.shadow-tier-badge[data-tier="Early"] {
  background: var(--surface-2-inset);
  color: var(--slate-body);
  border-color: var(--border-divider);
}

/* ============ STAGE 7: MUD SPLATTERS ============ */
.shadow-mud-splat {
  position: fixed;
  width: 7px; height: 7px;
  background: var(--mud-brown);
  border-radius: 50%;
  pointer-events: none;
  z-index: 4;
  opacity: 1;
  transform: scale(1);
  animation: shadow-mud-fade 0.85s ease-out forwards;
  box-shadow: 0 0 5px rgba(107, 68, 35, 0.45);
}
@keyframes shadow-mud-fade {
  from { opacity: 1; transform: scale(1) translateY(0); }
  to   { opacity: 0; transform: scale(0.4) translateY(10px); }
}

/* ============ FOOTER ============ */
.shadow-footer {
  text-align: center;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--border-divider);
  font-size: 12px;
  color: var(--slate-muted);
  position: relative;
  z-index: 3;
}
.shadow-footer p { margin: 0; }
.shadow-footer-brand { font-weight: 600; color: var(--slate-body); }
/* Attribution link to warsawdynamics.com — visually identical to the
   surrounding span at rest (color inherit, no underline), with an
   underline + darken on hover as the only clickability cue. Keeps the
   "quiet attribution" tone — pink stays reserved for hero/CTA accents. */
a.shadow-footer-brand { text-decoration: none; color: inherit; }
a.shadow-footer-brand:hover { text-decoration: underline; color: var(--slate-heading); }

/* ============ PIG ANIMATIONS — idle / focus-sniff / typing / dance ============ */
.shadow-pig {
  animation: shadow-pig-idle 4s ease-in-out infinite alternate;
  transform-origin: center bottom;
  will-change: transform, filter;
}
@keyframes shadow-pig-idle {
  0%   { transform: translateY(0)   rotate(-1.5deg); }
  50%  { transform: translateY(-6px) rotate(0deg); }
  100% { transform: translateY(0)   rotate(1.5deg); }
}

/* STAGE 7: form-focus sniff — pig scales + glows when form has focus.
   filter: drop-shadow() tracks the pig's silhouette (not a bounding rectangle). */
.shadow-layout:has(.shadow-form:focus-within) .shadow-pig {
  animation: shadow-pig-wag 0.5s ease-in-out infinite alternate,
             shadow-pig-glow-pulse 2s ease-in-out infinite alternate;
  transform: scale(1.05);
}
@keyframes shadow-pig-wag {
  0%   { transform: scale(1.05) rotate(-4deg); }
  100% { transform: scale(1.05) rotate(4deg); }
}
@keyframes shadow-pig-glow-pulse {
  0%, 100% { filter: drop-shadow(0 0 18px rgba(214, 53, 114, 0.40)); }
  50%      { filter: drop-shadow(0 0 30px rgba(214, 53, 114, 0.65)); }
}

/* Typing bounce */
.shadow-pig.shadow-pig-typing {
  animation: shadow-pig-bounce 0.18s ease-out;
}
@keyframes shadow-pig-bounce {
  0%   { transform: translateY(0)    scale(1); }
  50%  { transform: translateY(-12px) scale(1.04); }
  100% { transform: translateY(0)    scale(1); }
}

/* Submit-success happy hop */
.shadow-layout:has(.shadow-form.shadow-success) .shadow-pig {
  animation: shadow-pig-dance 0.8s ease-out forwards;
}
@keyframes shadow-pig-dance {
  0%   { transform: translateY(0)    scale(1)    rotate(0deg); }
  20%  { transform: translateY(-22px) scale(1.12) rotate(-6deg); }
  50%  { transform: translateY(0)    scale(0.94) rotate(4deg); }
  75%  { transform: translateY(-8px) scale(1.03) rotate(-2deg); }
  100% { transform: translateY(0)    scale(1)    rotate(0deg); }
}

/* ============ REDUCED-MOTION GUARD ============ */
@media (prefers-reduced-motion: reduce) {
  .shadow-pig,
  .shadow-layout:has(.shadow-form:focus-within) .shadow-pig,
  .shadow-pig.shadow-pig-typing,
  .shadow-layout:has(.shadow-form.shadow-success) .shadow-pig {
    animation: none;
    transform: none;
    filter: none;
  }
  .shadow-truffle { transition: opacity 0.15s; }
  .shadow-form.shadow-success ~ * .shadow-bucket,
  .shadow-col-form:has(.shadow-form.shadow-success) .shadow-bucket {
    animation: none;
  }
  .shadow-form.shadow-cta-ready .shadow-cta { animation: none; }
  .shadow-mud-splat { display: none; }
  .shadow-rain-truffle { display: none; }
  .shadow-cta { transition: none; }
  .shadow-success-state { animation: none; }
  /* Magnifying-glass: JS skips mousemove handler under reduced-motion;
     phrases stay hidden (mask anchor pinned off-screen). */
}
