/* OWNER: Lane B (content and motion). Hero styles: glow, doodles, tablets, pause control.
   Linked by layouts/base.njk after sections.css. Ported from ../wireframe/src/css/wireframe.css
   (hero, tablets, entrance, carousel, doodles) and brand.css (glow), on the --cd-* tokens.
   Every page hero has the glow and the doodles; only a hero with tablets (Home) has the
   tablet rules, selected with :has(.cd-devices). Motion runs only under html.cd-hero-motion
   (set by js/hero-motion.js, never under reduced motion) and stops under html.clue-motion-paused
   (the template's stored pause). State classes are cd-is-*; the component's own custom properties
   are --cdm-* (local to the hero, never tokens: --cd-* is defined only in tokens.css). */

/* ── Every hero: layout and glow ───────────────────────────────────────────────────────────── */
/* The hero sits directly under the sticky header. The layer and the control are positioned
   against the section; isolation keeps the doodles (z-index -1) above the glow and below the
   text. Glow: brightest at the top center over the heading, teal blooming in from the edges. */
.cd-s-hero {
  position: relative;
  isolation: isolate;
  text-align: center;
  padding-block: calc(var(--cd-section-y) + var(--cd-space-5)) var(--cd-section-y);
  background:
    radial-gradient(ellipse 55% 45% at 50% 0%, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 70%),
    radial-gradient(ellipse 40% 70% at 0% 100%, rgba(var(--cd-teal-glow-deep-rgb), 0.38) 0%, rgba(var(--cd-teal-glow-rgb), 0.15) 45%, rgba(var(--cd-teal-glow-rgb), 0) 75%),
    radial-gradient(ellipse 40% 70% at 100% 100%, rgba(var(--cd-teal-glow-deep-rgb), 0.38) 0%, rgba(var(--cd-teal-glow-rgb), 0.15) 45%, rgba(var(--cd-teal-glow-rgb), 0) 75%),
    radial-gradient(ellipse 30% 45% at 0% 0%, rgba(var(--cd-teal-glow-rgb), 0.17) 0%, rgba(var(--cd-teal-glow-rgb), 0) 70%),
    radial-gradient(ellipse 30% 45% at 100% 0%, rgba(var(--cd-teal-glow-rgb), 0.17) 0%, rgba(var(--cd-teal-glow-rgb), 0) 70%),
    radial-gradient(ellipse 70% 50% at 50% 100%, rgba(var(--cd-teal-glow-rgb), 0.15) 0%, rgba(var(--cd-teal-glow-rgb), 0) 70%),
    linear-gradient(180deg, var(--cd-surface) 0%, var(--cd-surface-tint) 100%);
}
/* The hero's bottom edge (Dan, 2026-10-27): the white section below rises into the hero along the
   site's one curve (sections.css, --cdb-below, --cdb-depth), drawn by .cd-hero-edge over the
   hero's bottom strip, above the tablets, so the outer tablets' bottom corners sit behind it. Only
   a soft black shadow follows the curve, no line (Dan, 2026-10-27): --cd-edge-shadow as a drop
   shadow on the unmasked wrapper. Nothing in the hero moves or resizes: the 1px bottom border
   stays (transparent) so the hero keeps its height. Without mask support the edge is straight,
   with the same shadow cast onto the section below. */
.cd-s-hero { border-bottom: 1px solid transparent; box-shadow: var(--cd-edge-shadow); }
.cd-hero-edge { display: none; }
@supports (mask-image: url("")) or (-webkit-mask-image: url("")) {
  /* The transparent border keeps the hero's height; the glow stops above it, so it shows white. */
  .cd-s-hero { background-clip: padding-box; box-shadow: none; }
  .cd-hero-edge {
    display: block;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 4;
    height: var(--cdb-depth);
    pointer-events: none;
    filter: drop-shadow(var(--cd-edge-shadow));
    /* The shadows go up onto the hero only: nothing leaks below the strip's straight bottom. */
    clip-path: inset(-1rem 0 0 0);
  }
  .cd-hero-edge::before {
    content: "";
    position: absolute;
    inset: 0 0 -1px;
    background: var(--cd-surface);
    -webkit-mask: var(--cdb-below) 0 0 / 100% 100% no-repeat;
    mask: var(--cdb-below) 0 0 / 100% 100% no-repeat;
  }
}
.cd-hero-text { margin: 0 auto; }
.cd-hero-text h1 { margin-bottom: var(--cd-space-5); }
/* Wide enough for the longest bodyBreak first line (Plans) to hold as one desktop line. */
.cd-hero-text .cd-lede { max-width: 56rem; margin: 0 auto; }
.cd-hero-text .cd-lede p { margin-bottom: 0; }
/* The hero swash (design pass item 3): one static aqua stroke under one existing phrase per hero,
   chosen in the page JSON ("swash") and wrapped in span.cd-swash by the template. 120-180px wide,
   centered under the phrase, just below its descenders; the lede's line height leaves it clear of
   the next line. The shape is one path, in the mask below. */
.cd-hero-text .cd-lede p { line-height: 1.75; }
.cd-swash { position: relative; white-space: nowrap; }
@supports (mask-image: url("")) or (-webkit-mask-image: url("")) {
  .cd-swash::after {
    content: "";
    position: absolute;
    left: 50%;
    top: calc(100% + 0.06em);
    width: clamp(7.5rem, calc(100% + 0.75rem), 11.25rem);
    height: 0.45em;
    translate: -50% 0;
    background: var(--cd-teal-glow);
    pointer-events: none;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 12' preserveAspectRatio='none'%3E%3Cpath d='M4 9.2C42 4.2 98 2.6 156 5.4' fill='none' stroke='black' stroke-width='3.6' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 12' preserveAspectRatio='none'%3E%3Cpath d='M4 9.2C42 4.2 98 2.6 156 5.4' fill='none' stroke='black' stroke-width='3.6' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  }
}
.cd-hero-text .cd-actions { margin-top: var(--cd-space-6); }
.cd-s-hero .cd-ph.cd-wide,
.cd-s-hero .cd-figure.cd-wide { margin-top: var(--cd-space-8); }

/* ── Pause/play control ────────────────────────────────────────────────────────────────────── */
/* Dan, 2026-10-27: a very small, light, understated icon. A 12px glyph (two bars, or a triangle
   while paused) in the muted text color, no border, no fill, no visible text, tucked into the
   top right corner of the full-width hero on every page (0.75rem in from its top and right edges,
   not the content edge), clear of the header, the centered text and the tablets. The button is a 24px target (websites.md tier 2; it is not a primary action);
   its name is the aria-label. The muted color keeps the glyph over 3:1 on the glow (WCAG 1.4.11;
   check motion measures it). Focus shows the global ring. Shown only while motion is possible. */
/* The same icon button pauses a content recording (.cd-recording-toggle, sections.css places it). */
.cd-hero-toggle {
  position: absolute;
  top: var(--cd-space-3);
  right: var(--cd-space-3);
  z-index: 5;
}
.cd-motion-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  border-radius: var(--cd-radius-sm);
  background: none;
  color: var(--cd-muted);
  cursor: pointer;
  transition: color var(--cd-duration) var(--cd-ease);
}
.cd-hero-motion .cd-motion-toggle { display: inline-flex; }
.cd-motion-toggle:hover { color: var(--cd-ink); }
.cd-motion-toggle svg { width: 0.75rem; height: 0.75rem; flex: none; fill: currentColor; }
.cd-motion-toggle .cd-motion-icon-play { display: none; }
.clue-motion-paused .cd-motion-toggle .cd-motion-icon-play { display: block; }
.clue-motion-paused .cd-motion-toggle .cd-motion-icon-pause { display: none; }

/* ── Doodles ───────────────────────────────────────────────────────────────────────────────── */
/* Line drawings in the hero's free space (js/hero-motion.js places them). The layer covers the
   whole hero section, adds no height, and sits at z-index -1 inside the section's stacking
   context: above the glow, below the tablets and the text. Ink and opacity are tokens. */
.cd-doodles { position: absolute; inset: 0; z-index: -1; overflow: hidden; contain: strict; pointer-events: none; }
.cd-doodle { position: absolute; color: var(--cd-doodle-ink); opacity: var(--cd-doodle-alpha); }
.cd-doodle-probe { visibility: hidden; }
/* Float: x (with a slight tilt) and y on different periods, so each drifts in a soft loop. */
.cd-doodle-x { animation: cd-doodle-x 3s ease-in-out infinite alternate; }
.cd-doodle-y { animation: cd-doodle-y 3s ease-in-out infinite alternate; }
/* Pop: after its lifetime (the svg's animation delay) it swells 10%, then shrinks and fades. */
.cd-doodle svg {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: cd-doodle-pop 220ms linear both;
}
/* Draw-in: every stroke has pathLength 1, so a dash of 1 sliding from offset 1 to 0 draws it.
   The dash exists only during the draw (fill backwards), so closed shapes end with a clean join. */
.cd-doodle path { animation: cd-doodle-draw 650ms cubic-bezier(0.45, 0, 0.25, 1) backwards; }
.cd-doodles.cd-is-paused *,
.clue-motion-paused .cd-doodles * { animation-play-state: paused; }
@keyframes cd-doodle-draw {
  0% { stroke-dasharray: 1 2; stroke-dashoffset: 1; opacity: 0; }
  1% { opacity: 1; }
  100% { stroke-dasharray: 1 2; stroke-dashoffset: 0; opacity: 1; }
}
@keyframes cd-doodle-x {
  from { transform: translateX(calc(-1 * var(--cdm-fx))) rotate(calc(-1 * var(--cdm-fr))); }
  to { transform: translateX(var(--cdm-fx)) rotate(var(--cdm-fr)); }
}
@keyframes cd-doodle-y {
  from { transform: translateY(calc(-1 * var(--cdm-fy))); }
  to { transform: translateY(var(--cdm-fy)); }
}
@keyframes cd-doodle-pop {
  0% { transform: scale(1); opacity: 1; animation-timing-function: cubic-bezier(0.3, 0, 0.5, 1); }
  32% { transform: scale(1.1); opacity: 1; animation-timing-function: cubic-bezier(0.5, 0, 0.8, 0.6); }
  100% { transform: scale(0.65); opacity: 0; }
}

/* ── Home: the tablets ─────────────────────────────────────────────────────────────────────── */
/* Five portrait tablets, center largest, the bottom third cut off by the next section. The crop
   happens at the hero section (full window width; its bottom is the crop line), so the
   carousel's outer tablets can slide past the screen edges instead of being cut at the container. */
.cd-s-hero:has(.cd-devices) { padding-bottom: 0; overflow: hidden; }
.cd-hero-art { position: relative; }
/* Wider than the content container: the tablets span up to the window (1rem gutters), scaling
   with a design width of 1160 units and growing past 1px a unit on wide screens. */
.cd-devices {
  /* Design width and the inner/outer tablets' horizontal offsets, in tablet units. */
  --cdm-span: 1160;
  --cdm-mid: 265;
  --cdm-out: 475;
  /* The unit fills the space under the text as far as width and height allow, so on desktop
     the crop line lands on the bottom of the window (the hero stops growing past 50rem tall):
     --cdm-above is the minimum distance from the top of the page to the tablets; 309 units show.
     The unit is a length scale, not a type size: 1.5px is its cap. */
  --cdm-above: calc(var(--cd-header-h) + 27rem);
  --cdm-u: min(1.5px, calc((100vw - 2rem) / var(--cdm-span)), calc((min(100svh, 50rem) - var(--cdm-above)) / 309));
  position: relative;
  width: calc(var(--cdm-span) * var(--cdm-u));
  left: 50%;
  transform: translateX(-50%);
  /* 24 units of headroom above the tablets so the entrance's lift is never clipped; the margin
     gives it back, so the tablets sit exactly where they would. */
  height: calc(333 * var(--cdm-u));
  margin-top: calc(3.5rem - 24 * var(--cdm-u));
}
/* Each slot is placed by its left edge in tablet units (center offset minus half the width),
   never by translateX(-50%): Safari animates transforms off the main thread and resolves the -50%
   against the starting width, so a tablet that changes size while it moves drifts, then snaps. */
.cd-device { position: absolute; aspect-ratio: 820 / 1180; margin-top: calc(24 * var(--cdm-u)); }
.cd-device-1 { --cdm-zoom: 1.075; width: calc(210 * var(--cdm-u)); top: calc(80 * var(--cdm-u)); left: calc(50% - (var(--cdm-out) + 105) * var(--cdm-u)); z-index: 1; }
.cd-device-2 { --cdm-zoom: 1.052; width: calc(250 * var(--cdm-u)); top: calc(40 * var(--cdm-u)); left: calc(50% - (var(--cdm-mid) + 125) * var(--cdm-u)); z-index: 2; }
.cd-device-3 { --cdm-zoom: 1; width: calc(300 * var(--cdm-u)); top: 0; left: calc(50% - 150 * var(--cdm-u)); z-index: 3; }
.cd-device-4 { --cdm-zoom: 1.052; width: calc(250 * var(--cdm-u)); top: calc(40 * var(--cdm-u)); left: calc(50% + (var(--cdm-mid) - 125) * var(--cdm-u)); z-index: 2; }
.cd-device-0 { --cdm-zoom: 1.1; width: calc(180 * var(--cdm-u)); top: calc(110 * var(--cdm-u)); left: calc(50% - (var(--cdm-out) + 280) * var(--cdm-u)); z-index: 0; opacity: 0; }
.cd-device-6 { --cdm-zoom: 1.1; width: calc(180 * var(--cdm-u)); top: calc(110 * var(--cdm-u)); left: calc(50% + (var(--cdm-out) + 100) * var(--cdm-u)); z-index: 0; opacity: 0; }
.cd-device-5 { --cdm-zoom: 1.075; width: calc(210 * var(--cdm-u)); top: calc(80 * var(--cdm-u)); left: calc(50% + (var(--cdm-out) - 105) * var(--cdm-u)); z-index: 1; }
/* The tablet itself (bezel and screen), inside the placed box so the entrance can move it. */
.cd-device-body {
  height: 100%;
  border: calc(8 * var(--cdm-u)) solid var(--cd-ink);
  border-radius: calc(14 * var(--cdm-u));
  overflow: hidden;
  background: var(--cd-surface-tint);
  box-shadow: 0 0.625rem 1.875rem rgba(19, 25, 28, 0.18);
}
.cd-device img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; border-radius: calc(6 * var(--cdm-u)); }
/* A recording covers only the screen above the crop line: full width, top aligned. All
   recordings share the center slot's shape; the side slots show more of the screen above the
   crop line, so their video zooms in slightly (--cdm-zoom per slot) to reach it. */
.cd-device video {
  display: block;
  width: 100%;
  max-width: none;
  height: auto;
  transform: scale(var(--cdm-zoom));
  transform-origin: top center;
  border-radius: calc(6 * var(--cdm-u)) calc(6 * var(--cdm-u)) 0 0;
}
/* Carousel (hero-motion.js): every few seconds each tablet moves one slot to the left. */
.cd-devices.cd-is-carousel .cd-device {
  transition: width 0.8s cubic-bezier(0.3, 0, 0.2, 1), top 0.8s cubic-bezier(0.3, 0, 0.2, 1),
    left 0.8s cubic-bezier(0.3, 0, 0.2, 1), opacity 0.8s cubic-bezier(0.3, 0, 0.2, 1);
}
.cd-devices.cd-is-carousel .cd-device video { transition: transform 0.8s cubic-bezier(0.3, 0, 0.2, 1); }

/* Entrance (hero-motion.js adds .cd-is-in once 15% is in view): center out, each a single 1000 ms
   ease-out with no overshoot; fade in over the first 300 ms. Offsets in tablet units. Hidden
   until then only while motion runs; a stored pause shows them at rest from first paint. */
.cd-device-1 { --cdm-delay: 300ms; --cdm-dx: -8; --cdm-dy: 26; --cdm-ds: 0.96; --cdm-dr: -0.75deg; }
.cd-device-2 { --cdm-delay: 140ms; --cdm-dx: -5; --cdm-dy: 22; --cdm-ds: 0.97; --cdm-dr: -0.5deg; }
.cd-device-3 { --cdm-delay: 0ms; --cdm-dx: 0; --cdm-dy: 18; --cdm-ds: 0.97; --cdm-dr: 0deg; }
.cd-device-4 { --cdm-delay: 200ms; --cdm-dx: 5; --cdm-dy: 22; --cdm-ds: 0.97; --cdm-dr: 0.5deg; }
.cd-device-5 { --cdm-delay: 360ms; --cdm-dx: 8; --cdm-dy: 26; --cdm-ds: 0.96; --cdm-dr: 0.75deg; }
.cd-hero-motion:not(.clue-motion-paused) .cd-device-body { opacity: 0; }
.cd-hero-motion .cd-devices.cd-is-in .cd-device-body {
  animation: cd-device-fade 300ms linear var(--cdm-delay) both, cd-device-pop 1000ms var(--cdm-delay) both;
}
/* Once the entrance has played (or was skipped), drop it: the carousel swaps slot classes, which
   carry the entrance settings, and Safari would re-run part of it on every swap. */
.cd-hero-motion .cd-devices.cd-is-settled .cd-device-body { animation: none; opacity: 1; }
@keyframes cd-device-fade { to { opacity: 1; } }
@keyframes cd-device-pop {
  0% {
    transform: translate(calc(var(--cdm-dx) * var(--cdm-u)), calc(var(--cdm-dy) * var(--cdm-u))) scale(var(--cdm-ds)) rotate(var(--cdm-dr));
    animation-timing-function: cubic-bezier(0.25, 1, 0.5, 1);
  }
  100% { transform: translate(0, 0) scale(1) rotate(0deg); }
}

/* Desktop: the hero is exactly one window tall below the header (up to 50rem), with the tablets
   pinned to its bottom; spare height opens up between the button and the tablets, and the
   heading, paragraph and button sit as one group, centered above them. */
@media (min-width: 47.5625em) {
  .cd-s-hero:has(.cd-devices) {
    min-height: calc(min(100svh, 50rem) - var(--cd-header-h));
    padding-top: 3.5rem;
    display: flex;
    flex-direction: column;
  }
  .cd-s-hero:has(.cd-devices) > .cd-wrap { flex: 1; display: flex; flex-direction: column; }
  .cd-s-hero:has(.cd-devices) .cd-hero-text { margin: auto 0; }
}
/* Very short windows (a phone held sideways): size the tablets by width only and let the hero
   run below the fold; the height-based unit would go negative there. */
@media (max-height: 35em) {
  .cd-devices { --cdm-u: min(1.5px, calc((100vw - 2rem) / var(--cdm-span))); }
  .cd-s-hero:has(.cd-devices) { min-height: 0; }
}

/* ── Phones ────────────────────────────────────────────────────────────────────────────────── */
@media (max-width: 47.5em) {
  /* The tablets draw closer together so the group scales up instead of turning into a strip. */
  .cd-devices { --cdm-span: 860; --cdm-mid: 185; --cdm-out: 325; }
}

/* ── Reduced motion: no doodles, no entrance, no carousel; the control is hidden by the
   missing html.cd-hero-motion (the script never sets it). ─────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .cd-doodles { display: none; }
  .cd-device-body { opacity: 1; animation: none; }
}
