/* =========================================================
   Spark Hive — Video overlay system
   Shared styles for the talking-head broadcast kit.

   Companion to slides/slides.css. Where slides.css dresses a
   full-bleed 1920×1080 canvas, this file dresses elements that
   sit ON TOP of live footage — so the governing rule here is
   what it does NOT cover: the speaker.

   ── The one law ────────────────────────────────────────────
   The centre 46% of frame belongs to the speaker's face.
   Everything hugs an edge or a corner. `.shv-safe` draws the
   guide so you can prove it.

   ── Authoring scale ────────────────────────────────────────
   Overlay artwork is authored in DESIGN UNITS — 880×495 for
   16:9, 304×540 for 9:16 — the same numbers the Claude Design
   artboards use. `.shv-frame` scales those up to true output
   size, so a coordinate here matches a coordinate there 1:1.
   Edit in design units; never hand-multiply.
   ========================================================= */

:root {
  /* Overlay surfaces. Paper is PURE WHITE, same as every other ground in
     this system — no cream, no beige, no off-yellow. The original video
     brief asked for a warm #FAF7F2; that was rejected as off-brand, so
     if a warm off-white reappears in overlay work, it is a bug. */
  --shv-paper:        var(--sh-white);
  --shv-paper-edge:   var(--sh-ink-200);
  --shv-placeholder:  #8C8882;  /* stand-in for footage — not a brand colour */
  --shv-speaker:      #7B776F;  /* stand-in for the person — not a brand colour */

  /* Dot-grid bed at overlay scale — coarser than --sh-paper-dot so it
     still reads as structure after a 2.2× blow-up. Image and size are
     separate vars: unlike --sh-paper-dot (built for the `background`
     shorthand) these are consumed by background-image/background-size,
     where a `0 0 / 24px 24px` position-size clause is invalid and
     silently kills the whole declaration. */
  --shv-dot: radial-gradient(circle, rgba(71, 28, 120, 0.15) 1.6px, transparent 1.8px);
  --shv-dot-size: 24px 24px;

  /* Paper-cut-out elevation: a hard offset plus soft ambient. Overlays
     need more punch than --sh-shadow-sticky because they compete with
     moving footage underneath. */
  --shv-lift:       2px 3px 0 rgba(26, 26, 26, 0.18), 0 12px 24px rgba(26, 26, 26, 0.20);
  --shv-lift-heavy: 2px 3px 0 rgba(26, 26, 26, 0.22), 0 12px 24px rgba(26, 26, 26, 0.22);

  /* The shared cycle. Every overlay runs in / hold / out on the same
     9 seconds so entrances and exits can be judged against each other. */
  --shv-cycle: 9s;
  --shv-ease:  cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ─────────────────────────────────────────────────────────
   Frame + authoring canvas
   ───────────────────────────────────────────────────────── */

/* A frame of footage at true output size. Put one overlay inside. */
.shv-frame {
  position: relative;
  overflow: hidden;
  background: var(--shv-placeholder);
  font-family: var(--sh-font-sans);
}
.shv-frame--16x9 { width: 1920px; height: 1080px; --shv-scale: 2.1818182; }
.shv-frame--9x16 { width: 1080px; height: 1920px; --shv-scale: 3.5526316; }

/* The design-unit canvas. Authored small, rendered large. */
.shv-art {
  position: absolute;
  top: 0;
  left: 0;
  transform: scale(var(--shv-scale));
  transform-origin: top left;
}
.shv-frame--16x9 .shv-art { width: 880px; height: 495px; }
.shv-frame--9x16 .shv-art { width: 304px; height: 540px; }

/* Stand-in speaker: head + shoulders, dead centre, so clearance is
   visible. Never ships — it is the thing the overlay must avoid. */
.shv-speaker {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  pointer-events: none;
}
.shv-speaker::before {
  content: "";
  width: 132px;
  height: 132px;
  border-radius: 50%;
  background: var(--shv-speaker);
}
.shv-speaker::after {
  content: "";
  width: 340px;
  height: 210px;
  margin-top: 14px;
  border-radius: 170px 170px 0 0;
  background: var(--shv-speaker);
}
.shv-frame--9x16 .shv-speaker::before { width: 92px; height: 92px; }
.shv-frame--9x16 .shv-speaker::after { width: 232px; height: 150px; }

/* The safe-zone guide: centre 46% of width, 6%–86% of height.
   Toggle by adding/removing this element — nothing should cross it. */
.shv-safe {
  position: absolute;
  left: 27%;
  right: 27%;
  top: 6%;
  bottom: 14%;
  border: 1.5px dashed rgba(255, 255, 255, 0.5);
  border-radius: 10px;
  pointer-events: none;
}

.shv-frame-label {
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.45);
  pointer-events: none;
}

/* ─────────────────────────────────────────────────────────
   Motion — the shared 9s cycle
   In at 0–7%, hold to 86%, out by 100%. Stagger siblings with
   .shv-delay-1/2/3 rather than inventing new timings.
   ───────────────────────────────────────────────────────── */

@keyframes shv-in-left {
  0%        { opacity: 0; transform: translateX(-30px); }
  7%, 86%   { opacity: 1; transform: translateX(0); }
  100%      { opacity: 0; transform: translateX(-16px); }
}
@keyframes shv-in-right {
  0%        { opacity: 0; transform: translateX(30px); }
  7%, 86%   { opacity: 1; transform: translateX(0); }
  100%      { opacity: 0; transform: translateX(16px); }
}
@keyframes shv-in-up {
  0%        { opacity: 0; transform: translateY(24px); }
  7%, 86%   { opacity: 1; transform: translateY(0); }
  100%      { opacity: 0; transform: translateY(14px); }
}
/* Pop: a 7% overshoot, for numbers landing on a beat. */
@keyframes shv-pop {
  0%        { opacity: 0; transform: scale(0.80); }
  8%        { opacity: 1; transform: scale(1.07); }
  13%, 86%  { opacity: 1; transform: scale(1); }
  100%      { opacity: 0; transform: scale(0.96); }
}
/* Swipe: a marker underline wiping left→right. Needs transform-origin. */
@keyframes shv-swipe {
  0%, 6%    { opacity: 1; transform: scaleX(0); }
  17%, 88%  { opacity: 1; transform: scaleX(1); }
  100%      { opacity: 0; transform: scaleX(1); }
}
/* Draw: an SVG stroke drawing on. Pair with stroke-dasharray. */
@keyframes shv-draw {
  0%, 6%    { opacity: 1; stroke-dashoffset: 900; }
  28%, 88%  { opacity: 1; stroke-dashoffset: 0; }
  100%      { opacity: 0; stroke-dashoffset: 0; }
}
/* Breathe / blink: continuous ambient life. Off-cycle by design. */
@keyframes shv-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.08); } }
@keyframes shv-blink   { 0%, 100% { opacity: 0.5; }        50% { opacity: 1; } }

.shv-in-left  { animation: shv-in-left  var(--shv-cycle) var(--shv-ease) infinite; }
.shv-in-right { animation: shv-in-right var(--shv-cycle) var(--shv-ease) infinite; }
.shv-in-up    { animation: shv-in-up    var(--shv-cycle) var(--shv-ease) infinite; }
.shv-pop      { animation: shv-pop      var(--shv-cycle) var(--shv-ease) infinite; }
.shv-swipe    { animation: shv-swipe    var(--shv-cycle) var(--shv-ease) infinite; transform-origin: left center; }
.shv-draw     { animation: shv-draw     var(--shv-cycle) var(--shv-ease) infinite; stroke-dasharray: 900; }
.shv-breathe  { animation: shv-breathe 3s   ease-in-out infinite; }
.shv-blink    { animation: shv-blink   2.6s ease-in-out infinite; }

.shv-delay-1 { animation-delay: 0.35s; }
.shv-delay-2 { animation-delay: 0.70s; }
.shv-delay-3 { animation-delay: 1.05s; }

/* Respect the OS setting: hold the composed state, drop the movement. */
@media (prefers-reduced-motion: reduce) {
  .shv-in-left, .shv-in-right, .shv-in-up, .shv-pop,
  .shv-swipe, .shv-draw, .shv-breathe, .shv-blink {
    animation: none;
  }
  .shv-swipe { transform: scaleX(1); }
  .shv-draw  { stroke-dashoffset: 0; }
}

/* ─────────────────────────────────────────────────────────
   Surfaces — paper that survives bright footage
   ───────────────────────────────────────────────────────── */

/* Solid purple block. The most legible surface over any footage. */
.shv-block {
  background: var(--sh-cosmic-purple);
  border-radius: var(--sh-radius-wobble-1);
  box-shadow: var(--shv-lift-heavy);
  color: #fff;
}

/* Dot-grid paper cut-out. Reads as a torn notebook scrap on the video. */
.shv-paper {
  background-color: var(--shv-paper);
  background-image: var(--shv-dot);
  background-size: var(--shv-dot-size);
  border-radius: var(--sh-radius-wobble-2);
  box-shadow: var(--shv-lift);
  color: var(--sh-midnight);
}

/* Translucent plate with a purple spine — for quotes and long text.
   0.94 alpha, not less: below that the footage eats the type. */
.shv-plate {
  background: rgba(255, 255, 255, 0.94);
  border-left: 5px solid var(--sh-cosmic-purple);
  border-radius: 12px 16px 12px 18px / 14px 12px 18px 12px;
  box-shadow: 2px 3px 0 rgba(26, 26, 26, 0.14), 0 10px 22px rgba(26, 26, 26, 0.18);
}

/* Raleway Dots eyebrow, on a purple pill. Gold on bare footage fails —
   the pill is what makes the accent face legal here. One per frame. */
.shv-eyebrow {
  display: inline-block;
  padding: 6px 14px 7px;
  border-radius: var(--sh-radius-pill);
  background: var(--sh-cosmic-purple);
  box-shadow: 2px 3px 0 rgba(26, 26, 26, 0.18);
  font-family: var(--sh-font-accent);
  font-size: 13px;
  letter-spacing: var(--sh-track-wider);
  text-transform: uppercase;
  color: var(--sh-radiant-gold);
}

/* Small paper chip behind a label — plain purple type at small sizes
   disappears on bright footage; the chip is the fix. */
.shv-chip {
  display: inline-block;
  padding: 5px 12px 6px;
  border-radius: 14px 18px 12px 16px / 16px 12px 18px 14px;
  background: rgba(255, 255, 255, 0.95);
  box-shadow: 2px 3px 0 rgba(26, 26, 26, 0.16);
  font-weight: 700;
  font-size: 14px;
  color: var(--sh-cosmic-purple);
}

/* ─────────────────────────────────────────────────────────
   Type roles on footage
   ───────────────────────────────────────────────────────── */

.shv-name   { font-weight: 900; font-size: 30px; line-height: 1.1; color: #fff; }
.shv-role   { font-weight: 400; font-size: 15px; letter-spacing: 0.02em; color: #fff; }
.shv-stat   { font-weight: 900; font-size: 82px; line-height: 1; color: var(--sh-radiant-gold); -webkit-text-stroke: 2px var(--sh-cosmic-purple); }
.shv-hand   { font-family: var(--sh-font-hand); font-size: 31px; line-height: 1.25; color: var(--sh-cosmic-purple); }
.shv-source { font-weight: 400; font-size: 12px; line-height: 1.4; color: var(--sh-midnight); opacity: 0.75; }

/* Gold on footage is only ever legal with a purple stroke behind it.
   This is the single rule that decides whether an overlay survives. */
.shv-gold-on-video {
  color: var(--sh-radiant-gold);
  -webkit-text-stroke: 5px var(--sh-cosmic-purple);
  paint-order: stroke fill;
}

/* Marker underline. Give it a width and let .shv-swipe wipe it on. */
.shv-underline {
  height: 5px;
  border-radius: 3px;
  background: var(--sh-radiant-gold);
}
.shv-underline--teal { background: var(--sh-spark-teal); }

/* ─────────────────────────────────────────────────────────
   Recurring devices
   The vocabulary that repeats across the series. Each one is a
   hand path — no ruler lines, no geometric primitives.
   ───────────────────────────────────────────────────────── */

/* Framework card — 520×160 design units, numbered step on paper. */
.shv-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 22px;
  width: 520px;
  min-height: 160px;
  padding: 0 30px;
  box-sizing: border-box;
  background-color: var(--shv-paper);
  background-image: var(--shv-dot);
  background-size: var(--shv-dot-size);
  border-radius: 18px 13px 20px 15px / 15px 20px 13px 18px;
  box-shadow: var(--shv-lift);
}
.shv-card__num {
  flex: 0 0 auto;
  font-family: var(--sh-font-hand);
  font-size: 120px;
  line-height: 0.8;
  color: var(--sh-spark-teal);
}
.shv-card__title {
  font-weight: 700;
  font-size: 34px;
  line-height: 1.15;
  color: var(--sh-cosmic-purple);
}

/* Checkbox stack — the "Easier If" fill-in. */
.shv-check { display: flex; align-items: center; gap: 18px; }
.shv-check__box {
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  border: 4px solid var(--sh-cosmic-purple);
  border-radius: 7px 5px 8px 6px / 6px 8px 5px 7px;
}
.shv-check__line { font-family: var(--sh-font-hand); font-size: 44px; line-height: 1; color: var(--sh-cosmic-purple); }
.shv-check__answer { font-family: var(--sh-font-hand); font-size: 34px; line-height: 1; color: var(--sh-spark-teal); }

/* Strike-through swap — struck word, then its replacement. The gold
   stroke crosses at x-height and overshoots the last letter ~15px;
   a stroke that stops short reads as an underline, not a strike. */
.shv-strike { position: relative; display: inline-block; }
.shv-strike__mark {
  position: absolute;
  left: -3%;
  top: 46%;
  width: 112%;
  height: 0.34em;
  overflow: visible;
}

/* Marker swatch — two passes, because one pass reads as a flat fill. */
.shv-swatch { position: relative; display: inline-block; }

.shv-note {
  font-family: var(--sh-font-hand);
  font-size: 23px;
  line-height: 1.3;
  color: var(--sh-cosmic-purple);
}

/* Unapproved copy, marked by copy.js. Deliberately visible: a made-up
   statistic must never be mistaken for a sourced one. Clears itself
   when the entry leaves PLACEHOLDERS in copy.js. */
[data-copy-placeholder] {
  text-decoration: underline dotted var(--sh-radiant-gold);
  text-underline-offset: 0.18em;
  text-decoration-thickness: 2px;
}

