/* ============================================================
   CyberBackstop — hero.css
   Hero section only. Consumes the --cb-* tokens defined in css/base.css.
   No token block here, no !important, no shared component rules
   (.cb-btn / .cb-wrap / .cb-eyebrow / .cb-display / .cb-lead live in base.css).
   Load order: base.css, then hero.css.
   ============================================================ */


/* ------------------------------------------------------------
   1. Section shell
   ------------------------------------------------------------ */

.cb-hero {
  position: relative;
  overflow: hidden;              /* clips the over-sized particle canvas */
  isolation: isolate;            /* contains the canvas screen blend */
  background-color: var(--cb-bg);
  /* Matches the page rhythm from base.css; falls back if that token moves.
     The hero brings its own band — do NOT add .cb-section/.cb-ground. */
  padding-block: var(--cb-section-y, clamp(48px, 8vw, 104px));
}

/* Night-game bloom. Purely decorative; degrades to flat --cb-bg
   if color-mix() is unsupported. */
.cb-hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    radial-gradient(120% 90% at 78% 8%,
      color-mix(in srgb, var(--cb-glow-warm) 11%, transparent) 0%,
      transparent 62%),
    radial-gradient(90% 80% at 8% 96%,
      color-mix(in srgb, var(--cb-glow-cool) 7%, transparent) 0%,
      transparent 60%);
}

/* Chalk hairline along the bottom edge — the foul line. */
.cb-hero::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 1px;
  z-index: 1;
  background-color: var(--cb-line);
}

.cb-hero__inner {
  position: relative;
  z-index: 2;
  display: grid;
  align-items: center;
  gap: clamp(28px, 5vw, 64px);
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 900px) {
  .cb-hero__inner {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  }
}


/* ------------------------------------------------------------
   2. Copy column
   ------------------------------------------------------------ */

.cb-hero__eyebrow {
  margin-block: 0 14px;
}

.cb-hero__title {
  margin-block: 0 18px;
  font-size: clamp(2.75rem, 7.5vw, 5.25rem);
  line-height: 0.94;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

.cb-hero__lead {
  margin-block: 0 32px;
  max-width: 52ch;
}

/* This is a <p>, so it inherits base.css's `p { max-width: 68ch }`.
   Release it — the button row sizes itself. */
.cb-hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-block: 0;
  max-width: none;
}


/* ------------------------------------------------------------
   3. Animation stage
   The SVG mark and the particle canvas share one box and one
   coordinate space: viewBox 0 0 100 100, xMidYMid meet.
   hero.js reproduces that mapping so canvas impacts land exactly
   on the SVG strokes.
   ------------------------------------------------------------ */

.cb-hero__stage {
  position: relative;
  width: 100%;
  max-width: 460px;
  margin-inline: auto;
  aspect-ratio: 1 / 1;
}

@media (min-width: 900px) {
  .cb-hero__stage {
    max-width: min(460px, 62vh);
  }
}

.cb-hero__mark {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* The canvas deliberately overruns the stage so pitches have real
   runway before they reach the plate. It is clipped by .cb-hero.
   hero.js keeps the mark's 0..100 space anchored to the STAGE box,
   not to the canvas box, so impacts still land on the strokes. */
.cb-hero__fx {
  position: absolute;
  /* Stacked layout: the copy sits directly above, so the overrun goes
     sideways and down, never up into the CTA row. */
  top: -8%;
  left: -40%;
  display: block;
  width: 180%;
  height: 152%;
  /* base.css resets `canvas { max-width: 100% }`; this layer is
     deliberately wider than its stage, so opt out. */
  max-width: none;
  z-index: 2;
  mix-blend-mode: screen;        /* particles are light: additive on night */
  pointer-events: none;
  /* Taper the edge nearest the copy so a streak never competes with
     body text. Purely presentational; unsupported browsers just get
     the untapered canvas, which hero.js already dims with distance. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 16%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 16%);
}

@media (min-width: 900px) {
  /* Two columns: the copy is beside the stage, so reaching left is safe —
     hero.js fades pitches out with distance from the plate. */
  .cb-hero__fx {
    top: -30%;
    left: -60%;
    width: 188%;
    height: 160%;
    -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0, 0, 0, 0.4) 20%, #000 40%);
    mask-image: linear-gradient(to right, transparent 0%, rgba(0, 0, 0, 0.4) 20%, #000 40%);
  }
}


/* ------------------------------------------------------------
   4. The mark — two-weight home plate
   Chalk shoulders (top + sides), clay catch chevron (bottom V).
   ------------------------------------------------------------ */

.cb-mark__line,
.cb-mark__ghost {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.cb-mark__line--chalk,
.cb-mark__ghost--chalk {
  stroke: var(--cb-chalk-100);
  stroke-width: 6.5;
}

.cb-mark__line--clay,
.cb-mark__ghost--clay {
  stroke: var(--cb-clay-500);
  stroke-width: 9.5;
}


/* ------------------------------------------------------------
   5. Phase 1 — draw-on (0–1.4s)
   pathLength="100" normalises both paths, so one dash value works
   for a 124-unit path and a 76-unit path alike.
   ------------------------------------------------------------ */

.cb-mark__line {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  animation-name: cb-draw;
  animation-timing-function: cubic-bezier(0.22, 0.68, 0.2, 1);
  animation-fill-mode: forwards;
}

.cb-mark__line--chalk {
  animation-duration: 900ms;
  animation-delay: 120ms;
}

.cb-mark__line--clay {
  animation-duration: 760ms;
  animation-delay: 640ms;
}

@keyframes cb-draw {
  to { stroke-dashoffset: 0; }
}

/* The overshoot lives on the group transform, not on the dash
   offset — a negative dashoffset would retract the tail. */
.cb-mark__lines {
  transform-box: fill-box;
  transform-origin: center;
  animation: cb-settle 620ms cubic-bezier(0.16, 1.01, 0.3, 1.42) 900ms both;
}

@keyframes cb-settle {
  from { transform: scale(0.968); }
  to   { transform: scale(1); }
}

/* Halo fades up once the linework has landed. */
.cb-mark__halo {
  opacity: 0;
  animation: cb-halo-in 900ms ease-out 1150ms forwards;
}

@keyframes cb-halo-in {
  to { opacity: 0.4; }
}


/* ------------------------------------------------------------
   6. Phase 2 — stadium-light bloom sweep (1.2–2.0s, then ambient)
   The band is masked to the strokes; only the mark lights up.
   11s cycle: ~800ms of travel, then dark.
   ------------------------------------------------------------ */

.cb-sweep-stop--edge {
  stop-color: var(--cb-glow-warm);
  stop-opacity: 0;
}

.cb-sweep-stop--warm {
  stop-color: var(--cb-glow-warm);
  stop-opacity: 0.95;
}

.cb-sweep-stop--cool {
  stop-color: var(--cb-glow-cool);
  stop-opacity: 0.35;
}

/* Group gates visibility, band carries the travel. Splitting them
   keeps opacity and transform on separate elements — no keyframe
   property collisions, both compositor-friendly. */
.cb-mark__sweep {
  opacity: 0;
  animation: cb-sweep-gate 11s linear 1200ms infinite;
}

@keyframes cb-sweep-gate {
  0%, 0.8%  { opacity: 0; }
  2%, 5.8%  { opacity: 1; }
  7.4%, 100% { opacity: 0; }
}

.cb-mark__sweep-band {
  animation: cb-sweep 11s cubic-bezier(0.36, 0, 0.24, 1) 1200ms infinite;
}

@keyframes cb-sweep {
  0%        { transform: translateX(0); }
  7.3%      { transform: translateX(152px); }
  100%      { transform: translateX(152px); }
}


/* ------------------------------------------------------------
   7. Reduced motion — non-negotiable
   Completed mark, still bloom, no canvas, no loop.
   hero.js also refuses to start its rAF loop under this query.
   ------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {

  .cb-hero__fx {
    display: none;
  }

  .cb-mark__line {
    stroke-dashoffset: 0;
    animation: none;
  }

  .cb-mark__lines {
    transform: none;
    animation: none;
  }

  .cb-mark__halo {
    opacity: 0.45;
    animation: none;
  }

  .cb-mark__sweep {
    opacity: 0.85;
    animation: none;
  }

  /* Band parked across the middle of the mark: a still gradient. */
  .cb-mark__sweep-band {
    transform: translateX(78px);
    animation: none;
  }
}


/* ------------------------------------------------------------
   8. Narrow viewports
   ------------------------------------------------------------ */

@media (max-width: 599px) {
  .cb-hero__stage {
    max-width: 320px;
  }

  .cb-hero__actions > .cb-btn {
    flex: 1 1 auto;
    text-align: center;
  }
}
