/* ==========================================================
   STORY CINEMATIC LAYER
   The go.php surface is what social traffic lands on. It has to
   carry the product in the first five seconds, without reading.

   Built against the 2026 standard, not against the old page:
   full-viewport cinematic hero, a product demo that RUNS in the
   browser rather than a screenshot of one, bento tiles that open,
   kinetic type tied to scroll, and light that moves.

   Loads after story-engine.css and wins by cascade order.
   Nothing above is deleted.
   ========================================================== */

/* ---------- 0. Motion tokens ---------- */

.story-hero,
.story-beat {
  --cin-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --cin-slow: 1.1s;
}

/* ==========================================================
   1. THE HERO. Full viewport. One moment, not a heading.
   ========================================================== */

.story-hero.cin-hero {
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: 0;
  overflow: hidden;
  isolation: isolate;
}

/* Aurora field. Three slow-drifting colour bodies on deep black.
   GPU-friendly: transform and opacity only. */
.cin-aurora {
  position: absolute;
  inset: -20%;
  z-index: 0;
  pointer-events: none;
  filter: blur(70px) saturate(130%);
  opacity: 0.75;
}
.cin-aurora span {
  position: absolute;
  display: block;
  border-radius: 50%;
  mix-blend-mode: screen;
  will-change: transform;
}
.cin-aurora span:nth-child(1) {
  width: 46vw; height: 46vw; left: 6%; top: 8%;
  background: radial-gradient(circle, rgba(139,92,255,0.55), transparent 62%);
  animation: cin-drift-a 22s var(--cin-ease) infinite alternate;
}
.cin-aurora span:nth-child(2) {
  width: 40vw; height: 40vw; right: 4%; top: 18%;
  background: radial-gradient(circle, rgba(34,211,238,0.42), transparent 62%);
  animation: cin-drift-b 27s var(--cin-ease) infinite alternate;
}
.cin-aurora span:nth-child(3) {
  width: 38vw; height: 38vw; left: 34%; bottom: 2%;
  background: radial-gradient(circle, rgba(232,121,249,0.34), transparent 64%);
  animation: cin-drift-c 31s var(--cin-ease) infinite alternate;
}
@keyframes cin-drift-a { to { transform: translate3d(9vw, 6vh, 0) scale(1.18); } }
@keyframes cin-drift-b { to { transform: translate3d(-8vw, 9vh, 0) scale(1.24); } }
@keyframes cin-drift-c { to { transform: translate3d(6vw, -7vh, 0) scale(1.14); } }

/* Fine grain over the gradients so they read as film, not as a
   CSS blur. */
.story-hero.cin-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

.cin-hero-inner {
  position: relative;
  /* No z-index on purpose. A positioned element with z-index is its
     own stacking context, and that would trap the mark's screen blend
     inside this box, away from the aurora it needs to blend against.
     Paint order is held by DOM order instead: the aurora is emitted
     first, this block second. */
  width: min(1240px, 92vw);
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  align-items: center;
  gap: clamp(24px, 4vw, 64px);
}

.cin-hero-copy { text-align: left; }

.cin-eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--story-sans);
  font-size: 11.5px; font-weight: 800;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-s);
  padding: 7px 14px;
  border-radius: 100px;
  border: 1px solid color-mix(in srgb, var(--sp-7) 34%, transparent);
  background: color-mix(in srgb, var(--sp-7) 12%, transparent);
  backdrop-filter: blur(8px);
}
.cin-eyebrow::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: var(--sp-3);
  box-shadow: 0 0 10px var(--sp-3);
  animation: cin-pulse 2.4s ease-in-out infinite;
}
@keyframes cin-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }

.story-hero.cin-hero h1 {
  text-align: left;
  font-size: clamp(40px, 6.6vw, 86px);
  line-height: 0.98;
  letter-spacing: -0.04em;
  font-weight: 900;
  margin: 22px 0 0;
  max-width: 15ch;
}

/* Kinetic type. Each word rises on load, staggered. The stagger
   index is set inline by the renderer. */
.cin-word {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.5em);
  animation: cin-word-in 0.85s var(--cin-ease) forwards;
  animation-delay: calc(var(--i, 0) * 55ms);
}
@keyframes cin-word-in { to { opacity: 1; transform: none; } }

.cin-hero-sub {
  font-family: var(--story-sans);
  font-size: clamp(16px, 1.35vw, 19px);
  line-height: 1.6;
  color: var(--ink-s);
  max-width: 46ch;
  margin: 22px 0 0;
  opacity: 0;
  animation: cin-word-in 0.9s var(--cin-ease) 0.42s forwards;
}

.cin-hero-cta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px;
  margin-top: 30px;
  opacity: 0;
  animation: cin-word-in 0.9s var(--cin-ease) 0.56s forwards;
}
.cin-cta-primary {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--story-sans);
  font-size: 15px; font-weight: 800;
  color: #06070c;
  text-decoration: none;
  padding: 14px 26px;
  border-radius: 100px;
  background: linear-gradient(100deg, #22d3ee, #8b5cff 55%, #e879f9);
  box-shadow: 0 10px 40px -12px rgba(139,92,255,0.75);
  transition: transform 0.25s var(--cin-ease), box-shadow 0.25s var(--cin-ease);
}
.cin-cta-primary:hover {
  transform: translateY(-2px) scale(1.015);
  box-shadow: 0 16px 52px -12px rgba(139,92,255,0.95);
  text-decoration: none;
}
.cin-cta-note {
  font-family: var(--story-sans);
  font-size: 13.5px; color: var(--ink-f);
}

/* ---------- The living mark ----------
   Two stacked copies of the same art. The base sits quiet. The
   bright copy is revealed by a band that travels across it, so
   light appears to move through the ridges. */

.cin-mark {
  position: relative;
  justify-self: center;
  width: min(100%, 520px);
  aspect-ratio: 1;
  /* Deliberately carries NO opacity, transform, filter or will-change.
     Any of those would make this element a stacking context, and a
     stacking context isolates its children's blending. The images
     below screen-blend against the aurora behind this element, so the
     entrance animation lives on the images, never on this wrapper. */
}
@keyframes cin-mark-in { from { opacity: 0; transform: scale(0.94); } to { opacity: 1; transform: none; } }

.cin-mark img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  /* cover, not contain. The source is 1024x1536 portrait inside a
     square box. Under contain the drawn art is only 347px wide, so
     the radial mask below - which is sized to the 520px ELEMENT box -
     never reaches the art's own left and right edges. Production
     showed exactly that: a hard purple rectangle with straight
     vertical sides. cover makes the drawn art fill the box, so the
     mask fades all four edges. object-position is 40 percent, not
     centre, because the lit print sits slightly above the middle of
     the source frame and a centred crop clips its top. */
  object-fit: cover;
  object-position: 50% 40%;
  /* The art is light drawn on its own black ground. Masking alone
     still leaves that ground visible as a rectangle once anything
     coloured sits behind it. Screen blending drops pure black to
     nothing and keeps every lit ridge, which is the correct
     treatment for glow art and needs no cutout. */
  mix-blend-mode: screen;
  /* Screen alone leaves a faint edge because the source ground is a
     very dark navy rather than pure black, so the ground still has to
     be masked away.

     Not a circle. A circular mask is measured to the box diagonal, so
     at the middle of each box edge it is still about 22 percent opaque
     and paints a short straight line there. Production showed that
     line. Two crossed linear fades, intersected, fade every edge to
     nothing over the outer 15 percent and leave the centre untouched,
     which is what the print itself needs: its glow runs almost to the
     top and bottom of the source frame. */
  -webkit-mask-image:
    linear-gradient(to right, transparent 0, #000 15%, #000 85%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 15%, #000 85%, transparent 100%);
  mask-image:
    linear-gradient(to right, transparent 0, #000 15%, #000 85%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 15%, #000 85%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  -webkit-mask-size: 100% 100%, 100% 100%;
  mask-size: 100% 100%, 100% 100%;
  -webkit-mask-repeat: no-repeat, no-repeat;
  mask-repeat: no-repeat, no-repeat;
  animation: cin-mark-in 1.3s var(--cin-ease) 0.2s both;
}
/* Two layers, and the gap between them is the whole effect. The base
   is the print at rest. The lit layer is the same print much brighter,
   showing only inside the reader spot. If the base were already at
   full brightness there would be nothing for the spot to reveal, so
   the base sits back and the spot does the lighting. A press lifts the
   spot to the whole frame, which is the bright reference-art reading
   HC asked for, on demand rather than always. */
.cin-mark img.cin-mark-base {
  /* Brightness only. NEVER saturate below 1 on this art.
     RGB is the theme. A saturate() under 1 pulls the rainbow toward
     grey, and grey over the deep navy ground reads as olive and teal:
     colours that are not in the palette and that nobody asked for. HC
     caught it the moment it shipped. Screen blending saturates fast,
     so the base still has to sit back for the reader spot to have
     anything to add, but brightness is the correct lever. It scales
     every channel by the same factor and leaves every hue alone. */
  filter: saturate(1.15) brightness(0.6);
  transition: filter 0.5s var(--cin-ease);
}
/* Selector must out-rank .cin-mark img, which also sets mask-image.
   As .cin-mark-lit alone it lost the cascade and every mask below was
   dead code: the sweep this replaced never ran in production either,
   for the same reason. Measured, not guessed - computed mask-size read
   back two layers where the rule declares three. */
.cin-mark img.cin-mark-lit {
  filter: saturate(1.35) brightness(1.9);
  /* Same two edge fades as the base layer, plus the reader spot. All
     three intersect, so the spot can never paint outside the faded
     edge and re-draw the rectangle the fades just removed.

     The spot is where the print is actually lit. Its centre and radius
     come from story-cinematic.js: the pointer when someone is over the
     mark, a slow drift when nobody is, and the whole frame for a beat
     when it is pressed. With no JS the fallbacks below light the middle
     and the mark still reads as a mark. */
  -webkit-mask-image:
    linear-gradient(to right, transparent 0, #000 15%, #000 85%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 15%, #000 85%, transparent 100%),
    radial-gradient(circle var(--cin-mr, 170px) at var(--cin-mx, 50%) var(--cin-my, 46%), #000 0, #000 32%, transparent 72%);
  mask-image:
    linear-gradient(to right, transparent 0, #000 15%, #000 85%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 15%, #000 85%, transparent 100%),
    radial-gradient(circle var(--cin-mr, 170px) at var(--cin-mx, 50%) var(--cin-my, 46%), #000 0, #000 32%, transparent 72%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  -webkit-mask-size: 100% 100%, 100% 100%, 100% 100%;
  mask-size: 100% 100%, 100% 100%, 100% 100%;
  -webkit-mask-repeat: no-repeat, no-repeat, no-repeat;
  mask-repeat: no-repeat, no-repeat, no-repeat;
}

/* ---- The mark is a reader ------------------------------------
   Pointer over it lights the print under the pointer. Pressing it
   takes a full read. Four points on the ridges say what the product
   does. Everything here degrades to a still, lit mark. */

.cin-mark { cursor: crosshair; }
.cin-mark.is-read img.cin-mark-base { filter: saturate(1.2) brightness(1.3); }

/* The ring that leaves the centre on a press. One pulse, no loop. */
.cin-mark-ring {
  position: absolute; left: 50%; top: 46%;
  width: 78%; aspect-ratio: 1;
  transform: translate(-50%, -50%) scale(0.24);
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.55);
  opacity: 0;
  pointer-events: none;
}
.cin-mark.is-read .cin-mark-ring { animation: cin-ring 1s var(--cin-ease) forwards; }
@keyframes cin-ring {
  0%   { opacity: 0.9; transform: translate(-50%,-50%) scale(0.24); }
  100% { opacity: 0;   transform: translate(-50%,-50%) scale(1.18); }
}

.cin-mark-hint {
  position: absolute; left: 50%; bottom: -6px;
  transform: translateX(-50%);
  font-family: var(--story-sans);
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-f);
  white-space: nowrap;
  opacity: 0;
  animation: cin-word-in 0.9s var(--cin-ease) 1.8s forwards;
  transition: opacity 0.4s var(--cin-ease);
  pointer-events: none;
}
.cin-mark.is-touched .cin-mark-hint { opacity: 0; animation: none; }

/* ---- The four points ---- */

.cin-sr {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

.cin-node {
  position: absolute;
  left: var(--x); top: var(--y);
  width: 0; height: 0;
}
.cin-node-dot {
  position: absolute; left: -11px; top: -11px;
  width: 22px; height: 22px;
  padding: 0; margin: 0;
  border: 0; background: none;
  cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.cin-node-dot::before {
  content: '';
  position: absolute; inset: 7px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 3px rgba(255,255,255,0.16), 0 0 14px 2px rgba(255,255,255,0.5);
  transition: transform 0.3s var(--cin-ease), box-shadow 0.3s var(--cin-ease);
}
.cin-node-dot::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.4);
  opacity: 0;
  animation: cin-node-ping 3.4s var(--cin-ease) infinite;
  animation-delay: calc(var(--n) * 0.85s);
}
@keyframes cin-node-ping {
  0%   { opacity: 0.55; transform: scale(0.5); }
  55%  { opacity: 0;    transform: scale(1.35); }
  100% { opacity: 0;    transform: scale(1.35); }
}
.cin-node-dot:hover::before,
.cin-node-dot:focus-visible::before,
.cin-node.is-open .cin-node-dot::before {
  transform: scale(1.5);
  box-shadow: 0 0 0 4px rgba(255,255,255,0.22), 0 0 22px 4px rgba(255,255,255,0.75);
}
.cin-node-dot:focus-visible { outline: 2px solid #fff; outline-offset: 4px; border-radius: 50%; }

.cin-node-card {
  position: absolute;
  left: 18px; top: -12px;
  width: min(210px, 60vw);
  display: block;
  padding: 12px 14px;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,0.14);
  background: rgba(10, 12, 22, 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 18px 44px rgba(0,0,0,0.55);
  opacity: 0;
  transform: translateY(6px) scale(0.98);
  transition: opacity 0.28s var(--cin-ease), transform 0.28s var(--cin-ease);
  pointer-events: none;
}
.cin-node-right .cin-node-card { left: auto; right: 18px; }
.cin-node:hover .cin-node-card,
.cin-node:focus-within .cin-node-card,
.cin-node.is-open .cin-node-card {
  opacity: 1;
  transform: none;
}
.cin-node-label {
  display: block;
  font-family: var(--story-sans);
  font-size: 11px; font-weight: 800;
  letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--sp-3);
  margin-bottom: 5px;
}
.cin-node-line {
  display: block;
  font-family: var(--story-sans);
  font-size: 13.5px; line-height: 1.5;
  color: var(--ink-s);
}

@media (prefers-reduced-motion: reduce) {
  .cin-node-dot::after { animation: none; }
  .cin-mark.is-read .cin-mark-ring { animation: none; }
  .cin-node-card { transition: none; }
}

/* Under 760px the mark sits behind the copy and the cards would cover
   the headline. Points and hint come off; the reader spot still runs,
   so a finger dragged across the print still lights it. */
@media (max-width: 760px) {
  .cin-node, .cin-mark-hint { display: none; }
  .cin-mark { cursor: default; }
}

/* Core bloom under the mark. */
.cin-mark::before {
  content: '';
  position: absolute; left: 50%; top: 50%;
  width: 58%; height: 58%;
  transform: translate(-50%,-50%);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,0.22), transparent 62%);
  filter: blur(26px);
  animation: cin-breathe 6s ease-in-out infinite;
}
@keyframes cin-breathe { 0%,100% { opacity: 0.6; } 50% { opacity: 1; } }

.cin-scrollcue {
  position: absolute;
  bottom: 26px; left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  font-family: var(--story-sans);
  font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--ink-f);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  opacity: 0;
  animation: cin-word-in 1s var(--cin-ease) 1.1s forwards;
}
.cin-scrollcue span {
  width: 1px; height: 34px;
  background: linear-gradient(180deg, var(--ink-f), transparent);
  animation: cin-cue 2.2s ease-in-out infinite;
}
@keyframes cin-cue { 0%,100% { transform: scaleY(0.4); opacity: 0.4; } 50% { transform: scaleY(1); opacity: 1; } }

/* ==========================================================
   2. THE LIVE DEMO. The product runs, it is not screenshotted.
   ========================================================== */

.story-demo {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: stretch;
  gap: 18px;
  max-width: 1060px;
  margin: 34px auto 0;
  text-align: left;
}

.story-demo-pane {
  position: relative;
  border-radius: 18px;
  padding: 22px 24px;
  border: 1px solid var(--border);
  background: linear-gradient(180deg, rgba(255,255,255,0.045), rgba(255,255,255,0.015));
  backdrop-filter: blur(6px);
  overflow: hidden;
}
.story-demo-in::before,
.story-demo-out::before {
  content: '';
  position: absolute; left: 0; right: 0; top: 0; height: 2px;
}
.story-demo-in::before  { background: linear-gradient(90deg, transparent, #64748b, transparent); }
.story-demo-out::before { background: linear-gradient(90deg, transparent, var(--sp-3), transparent); }

.story-demo-out {
  border-color: color-mix(in srgb, var(--sp-3) 26%, var(--border));
  box-shadow: 0 18px 60px -30px color-mix(in srgb, var(--sp-3) 70%, transparent);
}

.story-demo-label {
  font-family: var(--story-sans);
  font-size: 10.5px; font-weight: 800;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-f);
  margin-bottom: 12px;
}
.story-demo-out .story-demo-label { color: var(--sp-3); }

.story-demo-raw {
  font-family: var(--fm);
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--ink-s);
  margin: 0;
  min-height: 4.9em;
}
.story-demo-raw::after {
  content: '';
  display: inline-block;
  width: 2px; height: 1.05em;
  margin-left: 2px;
  vertical-align: -0.18em;
  background: var(--sp-3);
  animation: cin-caret 1s step-end infinite;
}
.story-demo.is-done .story-demo-raw::after { display: none; }
@keyframes cin-caret { 50% { opacity: 0; } }

.story-demo-heard {
  font-family: var(--story-sans);
  font-size: 17px; font-weight: 700;
  line-height: 1.45;
  color: var(--ink);
  margin: 0;
  opacity: 0; transform: translateY(6px);
  transition: opacity 0.5s var(--cin-ease), transform 0.5s var(--cin-ease);
}
.story-demo-result {
  font-family: var(--story-sans);
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink-s);
  margin: 12px 0 0;
  opacity: 0; transform: translateY(6px);
  transition: opacity 0.5s var(--cin-ease) 0.12s, transform 0.5s var(--cin-ease) 0.12s;
}
.story-demo.is-revealed .story-demo-heard,
.story-demo.is-revealed .story-demo-result { opacity: 1; transform: none; }

.story-demo-arrow {
  display: grid; place-items: center;
  color: var(--sp-3);
  opacity: 0.35;
  transition: opacity 0.4s var(--cin-ease);
}
.story-demo-arrow svg { width: 26px; height: 26px; }
.story-demo.is-revealed .story-demo-arrow { opacity: 1; }

.story-demo-note {
  font-family: var(--story-sans);
  font-size: 13px;
  color: var(--ink-f);
  text-align: center;
  margin: 14px auto 0;
  max-width: 60ch;
}

/* ==========================================================
   3. BENTO. Tiles open, they do not just sit there.
   ========================================================== */

@media (min-width: 900px) {
  .story-expand-set.cin-bento {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
    max-width: 1060px;
  }
  .story-expand-set.cin-bento .story-expand:first-child:nth-last-child(odd) { grid-column: span 2; }
}

.story-expand { border-radius: 18px; }
.story-expand-summary { padding: 19px 22px; }

/* ==========================================================
   4. Scroll-linked type. Headlines resolve as they arrive.
   ========================================================== */

.story-beat .section-title,
.story-beat .story-plain,
.story-beat .story-demo,
.story-beat .story-expand-set,
.story-beat .story-proof {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.7s var(--cin-ease), transform 0.7s var(--cin-ease);
}
.story-beat.is-seen .section-title,
.story-beat.is-seen .story-plain,
.story-beat.is-seen .story-demo,
.story-beat.is-seen .story-expand-set,
.story-beat.is-seen .story-proof {
  opacity: 1;
  transform: none;
}
.story-beat.is-seen .story-plain { transition-delay: 0.08s; }
.story-beat.is-seen .story-demo { transition-delay: 0.12s; }
.story-beat.is-seen .story-expand-set { transition-delay: 0.16s; }
.story-beat.is-seen .story-proof { transition-delay: 0.2s; }

/* The engine adds is-seen. If JS never runs, nothing may stay
   invisible: this is the fail-open. */
.no-js .story-beat .section-title,
.no-js .story-beat .story-plain,
.no-js .story-beat .story-demo,
.no-js .story-beat .story-expand-set,
.no-js .story-beat .story-proof { opacity: 1; transform: none; }

/* ==========================================================
   5. Phone. The hero stacks, the demo stacks, nothing clips.
   ========================================================== */

@media (max-width: 899px) {
  .cin-hero-inner {
    grid-template-columns: 1fr;
    text-align: left;
    gap: 26px;
    padding: 96px 0 84px;
  }
  .story-hero.cin-hero { min-height: auto; }
  .story-hero.cin-hero h1 { font-size: clamp(34px, 9vw, 52px); max-width: 100%; }
  .cin-mark { width: min(78%, 320px); order: -1; }
  .cin-scrollcue { display: none; }
  .story-demo {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .story-demo-arrow { transform: rotate(90deg); }
  .story-demo-pane { padding: 18px 18px; }
  .story-demo-raw { font-size: 13.5px; min-height: 6.2em; }
  .story-demo-heard { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .cin-aurora span,
  .cin-mark-lit,
  .cin-mark::before,
  .cin-eyebrow::before,
  .cin-scrollcue span { animation: none !important; }
  .cin-word,
  .cin-hero-sub,
  .cin-hero-cta,
  .cin-mark { opacity: 1 !important; transform: none !important; animation: none !important; }
  .story-beat .section-title,
  .story-beat .story-plain,
  .story-beat .story-demo,
  .story-beat .story-expand-set,
  .story-beat .story-proof { opacity: 1 !important; transform: none !important; }
}

/* ==========================================================
   9. CASCADE REPAIR. The story type was declared and never rendered.

   includes/styles.php declares `.section p, .section li { font-size:
   15px; line-height: 1.6 }` at specificity (0,1,1). Every paragraph
   the story renderer emits sits inside `<section class="section ...
   story-beat">`, so that rule matched them directly. The story
   engine's own type was set either on a wrapper (.story-plain, which
   reaches the text only by inheritance, and inheritance loses to any
   direct match at any specificity) or on a bare class (.story-demo-raw
   at (0,1,0), which loses on specificity). Both routes lost.

   Measured on the live page before this block existed: the demo's
   input, its restatement, its result and its note ALL computed
   15px/24px. The whole point of that panel is the size step between
   the small mono line a person typed and the large line DreamerOS
   heard, and that step was not on the page. The mobile rules were
   dead the same way.

   Fix is specificity, not !important: qualify with .story-beat so
   each selector reaches (0,2,1) and beats .section p honestly. Values
   are unchanged from what the original rules already declared, so
   this changes nothing except whether they take effect.
   ========================================================== */

.story-beat .story-plain p { font-size: 17px; line-height: 1.8; }
.story-beat p.story-demo-raw { font-size: 14.5px; line-height: 1.65; }
.story-beat p.story-demo-heard { font-size: 17px; line-height: 1.45; }
.story-beat p.story-demo-result { font-size: 14.5px; line-height: 1.6; }
.story-beat p.story-demo-note { font-size: 13px; }

@media (max-width: 720px) {
  .story-beat .story-plain p { font-size: 15.5px; }
}
@media (max-width: 640px) {
  .story-beat p.story-demo-raw { font-size: 13.5px; }
  .story-beat p.story-demo-heard { font-size: 16px; }
}

/* ==========================================================
   10. The node card must be reachable with a pointer.

   WCAG 2.2 SC 1.4.13 Content on Hover or Focus requires content
   revealed by hover to be hoverable itself. .cin-node is a zero-size
   box and the card carried pointer-events: none, so the only hoverable
   thing was the 22px dot. Moving the pointer toward the card dropped
   the hover and the card vanished before it could be reached.

   The card now takes pointer events, and a transparent bridge spans
   the gap between dot and card so the hover survives the trip. The
   bridge only exists while the card is showing, so it never blocks
   anything underneath at rest.
   ========================================================== */

.cin-node-card { pointer-events: none; }
.cin-node:hover .cin-node-card,
.cin-node:focus-within .cin-node-card,
.cin-node.is-open .cin-node-card { pointer-events: auto; }

/* The bridge spans the gap and NOTHING else. The dot is 22px centred on
   the node origin, so it ends 11px out; the card starts at 18px. The
   gap is exactly 7px. A wider bridge overlaps the dot and swallows the
   click that opens the card, which is what a first attempt at 22px did.
   Measured, then narrowed. */
.cin-node-card::before {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  left: -7px; width: 7px;
}
.cin-node-right .cin-node-card::before { left: auto; right: -7px; }
