/* ============================================================================
   roles.css — Saytomo role-page immersive component kit (SHARED across all 9
   role landing pages). Link AFTER saytomo.css. Reuses every saytomo.css token
   and keyframe (do NOT redefine them here). Per-page accent is driven by a single
   custom property: set  <body style="--role:var(--koi-lav)">  and the whole kit
   re-tints. CSP-clean: pure CSS, no scripts — interactivity (tilt / spotlight /
   scenes / counts / hero demo) is wired by /js/roles.js against these classes.

   Sections
     1.  Accent system (--role / --role-soft / --role-ink)
     2.  Polished image placeholder (.ph)
     3.  3D kit (.rp-3d, layers, .rp-tilt, orb, card-flip, .rp-spot)
     4.  Scene / stage (sticky scrolling scenes)
     5.  Surfaces (glass card, glow, conic orb, gradient text, waveform, marquee)
     6.  Misc helpers (key chips, count display, mock-UI primitives)
     7.  Reduced-motion
     8.  Responsive
   ========================================================================== */

/* ── 1. Accent system ──────────────────────────────────────────────────────
   --role defaults to the brand accent; each page overrides it on <body>. Soft &
   ink derivations are computed once so components can lean on them. */
:root,
[style*="--role"]{
  --role: var(--accent);
}
body{
  --role-soft: color-mix(in srgb, var(--role) 16%, white);
  --role-mid:  color-mix(in srgb, var(--role) 42%, white);
  --role-ink:  color-mix(in srgb, var(--role) 62%, #14181E);
  --role-deep: color-mix(in srgb, var(--role) 30%, #14181E);
  --role-glow: color-mix(in srgb, var(--role) 55%, transparent);
}

/* ── 2. Polished image placeholder ─────────────────────────────────────────
   A finished-looking gradient panel (NOT a dashed box). Honors inline
   aspect-ratio, carries a faint animated sheen, and exposes a tiny --mono corner
   label slot via data-img (rendered with the .ph-tag span in markup). */
.ph{
  position:relative;
  display:block;
  width:100%;
  border-radius:22px;
  overflow:hidden;
  background:
    radial-gradient(120% 90% at 18% 12%, color-mix(in srgb,var(--role) 22%,white), transparent 60%),
    linear-gradient(135deg, var(--role-soft), var(--bg-2));
  border:1px solid var(--line);
  box-shadow:0 30px 64px -42px rgba(40,50,70,.45), 0 1px 0 rgba(255,255,255,.7) inset;
}
.ph::before{ /* faint koi blob for depth */
  content:"";
  position:absolute; inset:auto -10% -28% auto;
  width:62%; height:80%;
  background:radial-gradient(circle, color-mix(in srgb,var(--accent-2) 40%,transparent), transparent 70%);
  filter:blur(34px); opacity:.5;
  pointer-events:none;
}
.ph::after{ /* animated diagonal sheen sweep */
  content:"";
  position:absolute; inset:0;
  background:linear-gradient(115deg, transparent 30%, rgba(255,255,255,.55) 47%, transparent 60%);
  transform:translateX(-120%);
  animation:phSheen 6.5s var(--ease) infinite;
  pointer-events:none;
}
@keyframes phSheen{ 0%,55%{ transform:translateX(-120%);} 78%,100%{ transform:translateX(120%);} }
.ph-tag{
  position:absolute; left:14px; bottom:13px;
  font-family:var(--mono); font-size:10.5px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--role-ink);
  background:rgba(255,255,255,.7); backdrop-filter:blur(6px);
  padding:5px 11px; border-radius:100px; border:1px solid rgba(255,255,255,.6);
}
.ph-ico{ /* centered glyph hint so an empty panel still reads as art-to-come */
  position:absolute; inset:0; display:grid; place-items:center;
  color:var(--role-ink); opacity:.5;
}

/* ── 3. 3D kit ─────────────────────────────────────────────────────────────*/
.rp-3d{ perspective:1300px; perspective-origin:50% 40%; }
.rp-3d-inner{ transform-style:preserve-3d; transition:transform .5s var(--ease-out); }
.rp-3d-layer{ transform-style:preserve-3d; will-change:transform; }
.rp-3d-layer.d1{ transform:translateZ(28px); }
.rp-3d-layer.d2{ transform:translateZ(60px); }
.rp-3d-layer.d3{ transform:translateZ(96px); }

/* base for JS pointer-tilt (roles.js sets .style.transform on pointermove) */
.rp-tilt{
  transform-style:preserve-3d;
  transition:transform .35s var(--ease-out), box-shadow .35s var(--ease-out);
  will-change:transform;
}
/* moving specular sheen + role-accent glow that follow the pointer (roles.js feeds
   --sx/--sy in %). A clip on the card keeps the sheen inside the rounded corners. */
.rp-tilt{ position:relative; isolation:isolate; }
.rp-tilt::after{
  content:""; position:absolute; inset:0; z-index:2; pointer-events:none;
  border-radius:inherit; opacity:0;
  background:
    radial-gradient(420px circle at var(--sx,50%) var(--sy,0%),
      rgba(255,255,255,.55), transparent 42%),
    radial-gradient(520px circle at var(--sx,50%) var(--sy,0%),
      color-mix(in srgb,var(--role) 28%,transparent), transparent 56%);
  transition:opacity .4s var(--ease);
  mix-blend-mode:soft-light;
}
.rp-tilt:hover::after{ opacity:1; }
.rp-tilt:hover{
  box-shadow:
    0 44px 90px -42px color-mix(in srgb,var(--role) 50%,rgba(40,60,120,.5)),
    0 1px 0 rgba(255,255,255,.95) inset;
}

/* showstopper 3D orb — concentric depth rings at distinct translateZ planes rotating
   in 3D, a refractive glass core (layered radial + conic + caustics), an outer halo
   pulse, and orbiting accent particles. The whole assembly floats (bob) and reacts to
   the hero pointer-parallax (it lives inside the .rp-3d scene). */
.rp-orb{
  position:relative; display:grid; place-items:center;
  width:clamp(248px,28vw,340px); aspect-ratio:1;
  transform-style:preserve-3d;
  animation:floaty 7s var(--ease) infinite;
}
/* volumetric aura cast behind the whole orb — bolder bloom for more presence */
.rp-orb::before{
  content:""; position:absolute; inset:-28%; border-radius:50%; z-index:-1;
  background:radial-gradient(circle at 50% 46%, var(--role-glow), color-mix(in srgb,var(--accent-2) 30%,transparent) 38%, transparent 66%);
  filter:blur(40px); opacity:1;
  animation:orbAura 9s var(--ease) infinite;
}
.rp-orb-ring{
  position:absolute; inset:0; border-radius:50%;
  border:1px solid color-mix(in srgb,var(--role) 40%,transparent);
  transform-style:preserve-3d;
}
/* three tilted gyroscope rings, each on its own depth plane + axis */
.rp-orb-ring.r1{ transform:translateZ(8px); animation:orbSpinA 17s linear infinite; }
.rp-orb-ring.r2{ inset:11%; border-style:dashed; border-color:color-mix(in srgb,var(--accent-2) 46%,transparent); transform:translateZ(34px); animation:orbSpinB 23s linear infinite; }
.rp-orb-ring.r3{ inset:23%; border-width:1.5px; border-color:color-mix(in srgb,var(--koi-mint) 60%,transparent); transform:translateZ(64px); animation:orbSpinC 30s linear infinite reverse; }
/* a 4th, near-vertical hairline ring for extra 3D read (added in markup as .r4; optional) */
.rp-orb-ring.r4{ inset:5%; border-color:color-mix(in srgb,var(--koi-sky) 55%,transparent); transform:translateZ(-12px); animation:orbSpinD 26s linear infinite; }
@keyframes orbSpinA{ from{ transform:translateZ(8px) rotateX(66deg) rotateZ(0); } to{ transform:translateZ(8px) rotateX(66deg) rotateZ(360deg); } }
@keyframes orbSpinB{ from{ transform:translateZ(34px) rotateX(62deg) rotateY(14deg) rotateZ(0); } to{ transform:translateZ(34px) rotateX(62deg) rotateY(14deg) rotateZ(-360deg); } }
@keyframes orbSpinC{ from{ transform:translateZ(64px) rotateX(70deg) rotateZ(0); } to{ transform:translateZ(64px) rotateX(70deg) rotateZ(360deg); } }
@keyframes orbSpinD{ from{ transform:translateZ(-12px) rotateY(74deg) rotateZ(0); } to{ transform:translateZ(-12px) rotateY(74deg) rotateZ(360deg); } }
@keyframes orbAura{ 0%,100%{ opacity:.7; transform:scale(1); } 50%{ opacity:1; transform:scale(1.08); } }

/* refractive glass core — sits forward of the rings on its own plane */
.rp-orb-core{
  position:relative; width:48%; aspect-ratio:1; border-radius:50%;
  overflow:hidden; transform:translateZ(86px);
  box-shadow:
    0 38px 80px -22px var(--role-glow),
    0 2px 1px rgba(255,255,255,.95) inset,
    0 -10px 26px -10px color-mix(in srgb,var(--role) 50%,transparent) inset;
}
/* swirling chromatic body behind the glass */
.rp-orb-core::before{
  content:""; position:absolute; inset:-36%;
  background:conic-gradient(from 0deg, var(--role), var(--accent-2), var(--koi-mint), var(--koi-sky), var(--koi-rose), var(--role));
  filter:blur(14px); animation:spin 14s linear infinite;
}
/* frosted glass disc + a top-left specular highlight = the refraction read */
.rp-orb-core::after{
  content:""; position:absolute; inset:5px; border-radius:50%;
  background:
    radial-gradient(60% 50% at 32% 26%, rgba(255,255,255,.92), rgba(255,255,255,.28) 40%, transparent 62%),
    radial-gradient(120% 120% at 70% 84%, color-mix(in srgb,var(--role) 30%,transparent), transparent 60%),
    rgba(255,255,255,.42);
  backdrop-filter:blur(7px); -webkit-backdrop-filter:blur(7px);
}
/* a soft caustic glow ring just inside the rim, lifted toward the viewer */
.rp-orb-glass{
  position:absolute; inset:26%; border-radius:50%; z-index:3; pointer-events:none;
  transform:translateZ(96px);
  background:radial-gradient(circle at 38% 30%, rgba(255,255,255,.8), transparent 46%);
  box-shadow:0 0 26px 2px color-mix(in srgb,var(--role) 34%,transparent) inset;
  mix-blend-mode:screen; opacity:.9;
  animation:floaty 7s var(--ease) infinite;
}
.rp-orb-halo{
  position:absolute; inset:14%; border-radius:50%;
  border:1.5px solid var(--role); opacity:0;
  animation:haloPulse 2.8s var(--ease-out) infinite;
}
/* orbiting accent particles — a positioned wrapper spins; each dot rides the rim */
.rp-orb-orbit{
  position:absolute; inset:0; transform-style:preserve-3d;
  transform:translateZ(48px) rotateX(64deg);
  animation:spin 18s linear infinite;
}
.rp-orb-orbit.o2{ inset:14%; transform:translateZ(70px) rotateX(58deg) rotateY(20deg); animation:spin 12s linear infinite reverse; }
.rp-orb-dot{
  position:absolute; top:-4px; left:50%; width:8px; height:8px; margin-left:-4px;
  border-radius:50%; background:radial-gradient(circle at 35% 30%, #fff, var(--role));
  box-shadow:0 0 12px 1px var(--role-glow);
}
.rp-orb-dot.d2{ top:auto; bottom:-4px; background:radial-gradient(circle at 35% 30%, #fff, var(--accent-2)); }
.rp-orb-dot.d3{ top:50%; left:-4px; margin-top:-4px; background:radial-gradient(circle at 35% 30%, #fff, var(--koi-mint)); }

/* 3D card-flip — hover (or .is-flipped) rotates the inner; faces are back-hidden */
.rp-flip{ perspective:1100px; }
.rp-flip-inner{
  position:relative; transform-style:preserve-3d;
  transition:transform .7s var(--ease-out);
}
.rp-flip:hover .rp-flip-inner,
.rp-flip.is-flipped .rp-flip-inner{ transform:rotateY(180deg); }
.rp-flip-face{ position:absolute; inset:0; backface-visibility:hidden; -webkit-backface-visibility:hidden; }
.rp-flip-back{ transform:rotateY(180deg); }

/* cursor spotlight overlay — roles.js feeds --mx/--my; we paint a soft radial */
.rp-spot{ position:relative; }
.rp-spot::after{
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(420px at var(--mx,50%) var(--my,30%),
            color-mix(in srgb,var(--role) 26%,transparent), transparent 62%);
  opacity:.7; transition:opacity .4s var(--ease);
  mix-blend-mode:soft-light;
}

/* ── 4. Scene / stage ──────────────────────────────────────────────────────
   Captions (.rp-scene) dim by default; the active one (.is-on) lights up.
   Visuals (.rp-stage) hide + blur by default; the active one enters in 3D. */
.rp-scene{
  opacity:.32;
  transform:translateX(-6px);
  transition:opacity .55s var(--ease), transform .55s var(--ease-out);
}
.rp-scene.is-on{ opacity:1; transform:none; }
.rp-stage{
  position:absolute; inset:0;
  opacity:0; visibility:hidden;
  /* bolder out-of-frame state: a deeper rotation + more travel for a dramatic swap */
  transform:rotateY(30deg) rotateX(-6deg) translateZ(-180px) translateX(7%) scale(.88);
  filter:blur(16px);
  transition:opacity .62s var(--ease-out), transform .9s var(--ease-out), filter .62s var(--ease-out);
  transform-style:preserve-3d;
}
.rp-stage.is-on{
  opacity:1; visibility:visible;
  transform:translateZ(40px);
  filter:none;
  /* the active mock floats forward with depth + a continuous gentle bob */
  animation:stageBob 7s var(--ease) .9s infinite;
}
/* the floating active mock reads with a deeper, role-tinted shadow */
.rp-stage.is-on .rp-mock{
  box-shadow:
    0 50px 90px -38px color-mix(in srgb,var(--role) 46%,rgba(40,50,70,.6)),
    0 12px 30px -18px rgba(40,50,70,.4),
    0 1px 0 rgba(255,255,255,.9) inset;
}
@keyframes stageBob{ 0%,100%{ transform:translateZ(40px) translateY(0) rotateX(0); } 50%{ transform:translateZ(56px) translateY(-10px) rotateX(1.4deg); } }

/* vertical 1–N progress rail beside the scrolling scenes (JS sets --rp-progress 0..1
   and toggles .is-passed on each pip). Reduced-motion safe (transitions removed there). */
.rp-rail{
  position:sticky; top:30vh; display:flex; flex-direction:column; align-items:center; gap:0;
  width:34px; flex:none;
}
.rp-rail-track{
  position:relative; width:2px; flex:1; min-height:220px; border-radius:2px;
  background:color-mix(in srgb,var(--role) 18%,var(--line));
  overflow:hidden;
}
.rp-rail-fill{
  position:absolute; left:0; top:0; width:100%;
  height:calc(var(--rp-progress,0) * 100%);
  background:linear-gradient(180deg, var(--accent-2), var(--role));
  border-radius:2px; box-shadow:0 0 12px var(--role-glow);
  transition:height .4s var(--ease-out);
}
.rp-rail-pips{
  position:absolute; inset:0; display:flex; flex-direction:column; justify-content:space-between; align-items:center;
}
.rp-pip{
  position:relative; width:26px; height:26px; border-radius:50%;
  display:grid; place-items:center;
  font-family:var(--mono); font-size:11px; font-weight:600;
  color:var(--ink-3); background:var(--paper);
  border:1.5px solid color-mix(in srgb,var(--role) 22%,var(--line));
  box-shadow:0 6px 14px -8px rgba(40,50,70,.4);
  transition:color .35s var(--ease), background .35s var(--ease), border-color .35s var(--ease), transform .35s var(--ease-out);
}
.rp-pip.is-passed{
  color:#fff; border-color:transparent;
  background:linear-gradient(180deg, var(--accent-2), var(--role));
  transform:scale(1.12);
  box-shadow:0 8px 20px -8px var(--role-glow), 0 0 0 5px var(--role-soft);
}

/* ── 5. Surfaces ───────────────────────────────────────────────────────────*/
/* glassmorphism card */
.rp-glass{
  background:rgba(255,255,255,.72);
  backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);
  border:1px solid rgba(255,255,255,.7);
  border-radius:24px;
  box-shadow:0 30px 70px -34px rgba(40,60,120,.4), 0 1px 0 rgba(255,255,255,.9) inset;
}
/* soft accent glow halo (decorative) */
.rp-glow{
  position:absolute; border-radius:50%;
  background:radial-gradient(circle, var(--role), transparent 70%);
  filter:blur(60px); opacity:.4; pointer-events:none;
}
/* conic-gradient mini orb (decorative bullet) */
.rp-conic{
  border-radius:50%; overflow:hidden; position:relative;
}
.rp-conic::before{
  content:""; position:absolute; inset:-30%;
  background:conic-gradient(from 0deg, var(--role), var(--accent-2), var(--koi-mint), var(--role));
  filter:blur(8px); animation:spin 11s linear infinite;
}
/* gradient text helper — slow animated sheen across the gradient (tasteful, subtle) */
.rp-grad{
  background:linear-gradient(100deg, var(--role-ink), var(--accent-2) 40%, var(--accent) 60%, var(--role-ink));
  background-size:220% 100%;
  -webkit-background-clip:text; background-clip:text; color:transparent;
  animation:rpGradShift 9s var(--ease) infinite;
}
@keyframes rpGradShift{ 0%,100%{ background-position:0% 50%; } 50%{ background-position:100% 50%; } }
/* CSS waveform — bars with barEq; container sets gap/height in markup */
.rp-wave{ display:flex; align-items:center; gap:4px; }
.rp-wave i{
  display:block; width:4px; border-radius:4px; transform-origin:center;
  background:linear-gradient(180deg, var(--role), var(--accent-2));
  animation:barEq 1s var(--ease) infinite;
}
/* marquee row helper (duplicate content inside .rp-mq-track for seamless loop) */
.rp-mq{ overflow:hidden; -webkit-mask:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent); mask:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent); }
.rp-mq-track{ display:flex; gap:14px; width:max-content; animation:marquee 38s linear infinite; }
.rp-mq:hover .rp-mq-track{ animation-play-state:paused; }

/* floating ambient particles — roles.js spawns .rp-particle dots into a .rp-particles
   layer with per-dot inline left/size/duration/delay. Pure transform/opacity motion. */
.rp-particles{ position:absolute; inset:0; z-index:1; pointer-events:none; overflow:hidden; }
.rp-particle{
  position:absolute; bottom:-12px; border-radius:50%;
  background:radial-gradient(circle at 34% 30%, #fff, var(--role));
  box-shadow:0 0 10px 1px var(--role-glow);
  opacity:0; will-change:transform,opacity;
  animation:rpRise linear infinite;
}
.rp-particle.alt{ background:radial-gradient(circle at 34% 30%, #fff, var(--accent-2)); }
.rp-particle.alt2{ background:radial-gradient(circle at 34% 30%, #fff, var(--koi-mint)); }
@keyframes rpRise{
  0%{ transform:translateY(0) translateX(0) scale(.6); opacity:0; }
  12%{ opacity:.85; }
  50%{ transform:translateY(-46vh) translateX(14px) scale(1); }
  88%{ opacity:.7; }
  100%{ transform:translateY(-94vh) translateX(-12px) scale(.7); opacity:0; }
}
/* dark-section particle variant (faint white motes over the #14181E CTA) */
.rp-particle.onDark{ background:radial-gradient(circle at 34% 30%, #fff, color-mix(in srgb,var(--accent-2) 70%,#fff)); box-shadow:0 0 10px 1px rgba(138,123,245,.5); }

/* ── full-bleed ambient environment ─────────────────────────────────────────
   A continuous, atmospheric backdrop kit so a whole page reads as one environment
   instead of stacked bands. All layers are decorative (aria-hidden), sit BEHIND
   content (z-index:0), are transform/opacity-only, and are killed under
   prefers-reduced-motion (section 7). Compose them inside a position:relative
   section that has overflow:clip/hidden (never over the sticky stage ancestor).

   .rp-amb        — the layer wrapper (full-bleed, behind content)
   .rp-aurora     — slow-drifting koi gradient-mesh / aurora field (depth + bloom)
   .rp-aurora.b   — a second, counter-drifting field for parallax depth
   .rp-stars      — a faint static starfield (radial dots), very low opacity
   .rp-grain      — subtle film grain (multiply), fixed cost
   .rp-seam.top / .rp-seam.bot — soft gradient bleeds that dissolve a section edge
     into its neighbour so transitions feel seamless                              */
.rp-amb{ position:absolute; inset:0; z-index:0; pointer-events:none; overflow:hidden; }
.rp-aurora{
  position:absolute; inset:-18%;
  background:
    radial-gradient(40% 46% at 22% 28%, color-mix(in srgb,var(--role) 34%,transparent), transparent 62%),
    radial-gradient(36% 44% at 78% 34%, color-mix(in srgb,var(--accent-2) 28%,transparent), transparent 62%),
    radial-gradient(42% 50% at 60% 82%, color-mix(in srgb,var(--koi-mint) 30%,transparent), transparent 64%),
    radial-gradient(32% 40% at 12% 78%, color-mix(in srgb,var(--koi-sky) 32%,transparent), transparent 62%);
  filter:blur(46px); opacity:.72;
  animation:rpAuroraA 30s var(--ease) infinite;
}
.rp-aurora.b{
  background:
    radial-gradient(36% 40% at 70% 20%, color-mix(in srgb,var(--koi-rose) 18%,transparent), transparent 62%),
    radial-gradient(40% 44% at 26% 64%, color-mix(in srgb,var(--accent-2) 16%,transparent), transparent 64%),
    radial-gradient(32% 38% at 88% 74%, color-mix(in srgb,var(--role) 20%,transparent), transparent 62%);
  opacity:.45; animation:rpAuroraB 38s var(--ease) infinite;
}
/* Where a real generated backdrop is wired (.rp-art present in the section), the redundant
   ambient auroras STEP BACK so the art reads instead of being flattened into a flat colour
   block — the art itself is the atmosphere there. Art-less sections keep their full auroras.
   (Scoped by DOM: .rp-art is the section's first child, .rp-amb follows it.) */
.rp-art ~ .rp-amb .rp-aurora{ opacity:.26; }
.rp-art ~ .rp-amb .rp-aurora.b{ opacity:.16; }
@keyframes rpAuroraA{ 0%,100%{ transform:translate3d(0,0,0) scale(1); } 50%{ transform:translate3d(3%,-3%,0) scale(1.08); } }
@keyframes rpAuroraB{ 0%,100%{ transform:translate3d(0,0,0) scale(1.04); } 50%{ transform:translate3d(-4%,3%,0) scale(1); } }
/* faint star/depth layer — two layered radial-dot grids drifting very slowly */
.rp-stars{
  position:absolute; inset:-40px; opacity:.5;
  background-image:
    radial-gradient(1.4px 1.4px at 20% 30%, color-mix(in srgb,var(--role-ink) 55%,transparent), transparent),
    radial-gradient(1.2px 1.2px at 70% 18%, color-mix(in srgb,var(--accent-2) 55%,transparent), transparent),
    radial-gradient(1px 1px at 44% 72%, color-mix(in srgb,var(--ink-3) 50%,transparent), transparent),
    radial-gradient(1.4px 1.4px at 86% 64%, color-mix(in srgb,var(--role-ink) 45%,transparent), transparent),
    radial-gradient(1px 1px at 12% 84%, color-mix(in srgb,var(--accent-2) 45%,transparent), transparent),
    radial-gradient(1.2px 1.2px at 60% 48%, color-mix(in srgb,var(--ink-3) 45%,transparent), transparent);
  background-repeat:repeat; background-size:340px 340px;
  animation:rpStars 60s linear infinite;
}
@keyframes rpStars{ from{ transform:translate3d(0,0,0); } to{ transform:translate3d(-340px,-170px,0); } }
/* subtle film grain — fixed cost, multiply blend, no animation needed */
.rp-grain{
  position:absolute; inset:0; opacity:.35; mix-blend-mode:multiply;
  background-image:radial-gradient(rgba(20,24,30,.05) 1px, transparent 1px);
  background-size:4px 4px;
}
/* seamless section seams — a soft vertical bleed at a section edge */
.rp-seam{ position:absolute; left:0; right:0; height:clamp(80px,12vh,160px); z-index:0; pointer-events:none; }
.rp-seam.top{ top:0; background:linear-gradient(180deg, var(--bg), transparent); }
.rp-seam.bot{ bottom:0; background:linear-gradient(0deg, var(--bg), transparent); }
.rp-seam.top.warm{ background:linear-gradient(180deg, var(--warm), transparent); }
.rp-seam.bot.warm{ background:linear-gradient(0deg, var(--warm), transparent); }

/* full-bleed GENERATED-ART slot — a .ph used as a background layer (data-img). The .ph
   gradient is an accurate fallback so the page looks finished before the image lands;
   the owner drops a same-origin image into .rp-artfill (background-image) to swap in. */
.rp-art{ position:absolute; inset:0; z-index:0; pointer-events:none; border-radius:0; border:0; box-shadow:none; overflow:hidden; }
.rp-art .ph{ position:absolute; inset:0; border-radius:0; border:0; box-shadow:none; height:100%; }
.rp-art .ph-tag{ left:auto; right:14px; bottom:14px; }
/* when an image is wired in, this layer carries it (set background-image inline/in a rule) */
.rp-artfill{ position:absolute; inset:0; background-size:cover; background-position:center; filter:saturate(1.25) contrast(1.12); }

/* faint animated mesh/grain veil — a fixed-cost decorative layer over a section */
.rp-mesh{
  position:absolute; inset:0; z-index:1; pointer-events:none; opacity:.5;
  background:
    radial-gradient(40% 50% at 18% 22%, color-mix(in srgb,var(--role) 16%,transparent), transparent 60%),
    radial-gradient(36% 46% at 82% 70%, color-mix(in srgb,var(--accent-2) 14%,transparent), transparent 60%);
  animation:meshDrift 24s var(--ease) infinite;
}
@keyframes meshDrift{ 0%,100%{ transform:translate(0,0) scale(1); } 50%{ transform:translate(2%,-2%) scale(1.06); } }

/* springy hover — for buttons/pills that should feel alive */
.rp-spring{ transition:transform .42s cubic-bezier(.34,1.56,.64,1), box-shadow .35s var(--ease-out); }
.rp-spring:hover{ transform:translateY(-3px) scale(1.025); }
.rp-spring:active{ transform:translateY(-1px) scale(.99); transition-duration:.12s; }

/* ── 6. Misc helpers ───────────────────────────────────────────────────────*/
/* key chip (which Saytomo key drives a scene) */
.rp-key{
  display:inline-flex; align-items:center; gap:8px;
  font-family:var(--mono); font-size:11px; font-weight:600; letter-spacing:.06em; text-transform:uppercase;
  color:#fff; padding:6px 13px; border-radius:100px;
  background:linear-gradient(180deg, var(--accent-2), var(--role));
  box-shadow:0 10px 24px -12px var(--role-glow);
}
.rp-key.is-ghost{ background:var(--paper); color:var(--role-ink); border:1px solid var(--line); box-shadow:none; }
.rp-key i{ width:6px; height:6px; border-radius:50%; background:rgba(255,255,255,.9); }

/* count-up number */
.rp-count{ font-variant-numeric:tabular-nums; letter-spacing:-.04em; }

/* tiny mock-UI primitives reused inside scene stages */
.rp-mock{ background:var(--paper); border:1px solid var(--line); border-radius:16px; box-shadow:0 26px 56px -34px rgba(40,50,70,.5); }
.rp-mock-bar{ display:flex; align-items:center; gap:6px; padding:11px 14px; border-bottom:1px solid var(--line-2); }
.rp-dot{ width:9px; height:9px; border-radius:50%; }
.rp-line{ height:9px; border-radius:6px; background:var(--bg-2); }
.rp-hl{ background:color-mix(in srgb,var(--role) 32%,transparent); border-radius:4px; padding:0 3px; box-decoration-break:clone; -webkit-box-decoration-break:clone; }

/* ── 7. Reduced-motion ─────────────────────────────────────────────────────*/
@media (prefers-reduced-motion: reduce){
  *{ animation:none !important; transition:none !important; }
  .rp-scene, .rp-stage{ opacity:1 !important; transform:none !important; filter:none !important; }
  .rp-stage{ position:relative !important; }     /* stack legibly when all shown */
  .rp-stage.is-on .rp-mock{ box-shadow:0 26px 56px -34px rgba(40,50,70,.5) !important; }
  .ph::after{ display:none !important; }
  /* kill every added effect: parallax, orbit, particles, sheen, rail, glow drift */
  .rp-3d{ perspective:none !important; }
  .rp-3d-inner{ transform:none !important; }
  .rp-3d-layer.d1,.rp-3d-layer.d2,.rp-3d-layer.d3{ transform:none !important; }
  .rp-orb, .rp-orb-core, .rp-orb-glass, .rp-orb-ring,
  .rp-orb-orbit, .rp-orb::before{ transform:none !important; }
  .rp-orb-ring, .rp-orb-orbit{ opacity:.5; }
  .rp-orb-core::after{ transform:translateZ(0) !important; }
  .rp-particles, .rp-particle{ display:none !important; }
  .rp-mesh{ animation:none !important; }
  /* full-bleed ambient: keep a calm static wash, kill all drift */
  .rp-aurora, .rp-aurora.b, .rp-stars{ animation:none !important; transform:none !important; }
  .rp-aurora{ opacity:.4 !important; }
  .rp-aurora.b{ opacity:.3 !important; }
  .rp-stars{ opacity:.3 !important; }
  .rp-tilt::after{ display:none !important; }
  .rp-spot::after{ display:none !important; }   /* no cursor spotlight */
  .rp-rail-fill{ transition:none !important; }
}

/* ── 8. Responsive ─────────────────────────────────────────────────────────*/
@media (max-width:820px){
  .rp-3d{ perspective:none; }
  .rp-3d-layer.d1,.rp-3d-layer.d2,.rp-3d-layer.d3{ transform:none; }
  .rp-stage{ transform:translateY(20px) scale(.98); filter:blur(8px); }   /* drop the Y-rotation on touch */
  .rp-stage.is-on{ transform:none; animation:none; }
  .rp-rail{ display:none; }   /* the vertical rail is desktop-only chrome */
}
@media (max-width:600px){
  .ph{ border-radius:18px; }
  .rp-glass{ border-radius:20px; }
  .rp-orb{ width:clamp(190px,68vw,250px); }
}
