/* ================================================================
   TRACIVEX — HERO: two-column layout, status strip, packet flow
   Append to app.css. Everything here is scoped to .hero, so nothing
   else on the site is affected.
   ================================================================ */

/* ----------------------------------------------------------------
   SHELL
   The flow canvas spans the whole hero, not just the right column,
   because the dots start inside the headline and finish inside the
   mark. Copy sits above it so type stays crisp and the dots read as
   emerging from the letterforms.
   ---------------------------------------------------------------- */
.hero {
  position: relative;
  isolation: isolate;
}

.hero-flow {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  overflow: visible;
  pointer-events: none;
}

.hero-grid {
  position: relative;
  z-index: 1;
  display: grid;
  gap: clamp(40px, 4vw, 72px);
}

/* Bounds what the copy can claim, so the rest belongs to the mark. Without
   it the column is set by whichever child happens to be widest — usually the
   status strip — and the mark is left with whatever is over. */
.hero-copy {
  min-width: 0;
  max-width: 37rem;
}

.hero-visual {
  position: relative;
  min-height: clamp(320px, 34vw, 520px);
}

@media (min-width: 1024px) {
  .hero-grid {
    /* The copy column hugs its own measure instead of absorbing the slack.
       A 1fr copy column swallows everything the type does not need, which
       leaves dead space sitting between the text and the gap and pins the
       mark against the right edge. Sizing it to max-content hands that
       slack to the mark's column, so the mark is centred in the space
       that is genuinely empty.

       The headline and lead still wrap by their own measures (14ch / 52ch
       from app.css), so nothing about the type changes. */
    grid-template-columns: minmax(0, max-content) minmax(260px, 1fr);
    align-items: center;
    gap: clamp(24px, 2.4vw, 44px);
  }
}

/* Mark cells — the group is what deforms, so the box is the transform
   reference rather than the whole canvas. */
.kf-cell {
  transform-box: fill-box;
  transform-origin: center;
  will-change: transform, filter;
}

/* ----------------------------------------------------------------
   STATUS STRIP
   Replaces the plain eyebrow. Same information, but the live dot and
   the hairline segments make it read as instrumentation rather than
   as a label.
   ---------------------------------------------------------------- */
.hero-status {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 var(--sp-4);
  font-family: var(--ff-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-3);
  margin-bottom: clamp(24px, 3vw, 40px);
}

.hero-status .rule {
  width: 28px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--c-text-4));
}

.hero-status .seg {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}

.hero-status .seg + .seg::before {
  content: '';
  width: 1px;
  height: 10px;
  margin-right: var(--sp-4);
  background: var(--c-border-strong);
}

.hero-status .live {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--c-accent);
  box-shadow: 0 0 0 0 color-mix(in oklab, var(--c-accent) 60%, transparent);
  animation: kf-pulse 2.6s ease-out infinite;
}

@keyframes kf-pulse {
  0% {
    box-shadow: 0 0 0 0 color-mix(in oklab, var(--c-accent) 55%, transparent);
  }
  70% {
    box-shadow: 0 0 0 7px color-mix(in oklab, var(--c-accent) 0%, transparent);
  }
  100% {
    box-shadow: 0 0 0 0 color-mix(in oklab, var(--c-accent) 0%, transparent);
  }
}

.hero-status .num {
  color: var(--c-text-2);
}

/* ----------------------------------------------------------------
   HEADLINE

   12ch, narrower than the 14ch in app.css. At 14ch the second line
   takes "analysis for iPhone" and the accent phrase gets split across
   the line break, with "and iPad." stranded below.

   Lines break greedily, so the measure has to sit above the width of
   "iPhone and iPad." (572px) and below the width of "analysis for
   iPhone" (613px). 12ch is 579px, mid-range. Widen past 12.7ch or
   narrow below 11.9ch and the phrase splits again.

   Do not add text-wrap: balance here either — it evens the lines out
   and overrides all of the above.
   ---------------------------------------------------------------- */
.hero .hero-title {
  max-width: 12ch;
  margin-bottom: clamp(20px, 2.2vw, 28px);
}

/* The two device words are the emitters. The glow is deliberately far
   below the threshold of a "glow effect" — it only reads as the words
   sitting in the same light as the stream leaving them. */
.hero-title .accent {
  color: var(--c-accent);
  text-shadow: 0 0 38px color-mix(in oklab, var(--c-accent) 22%, transparent);
}

/* Measure left to app.css (52ch). */
.hero .hero-lead {
  margin-bottom: clamp(28px, 3vw, 40px);
}

.hero .hero-lead strong {
  color: var(--c-text-1);
  font-weight: 450;
}

/* ----------------------------------------------------------------
   SPEC RAIL
   Four claims in mono under the calls to action. Optional — delete
   the block in the markup if you'd rather keep the hero sparse.
   ---------------------------------------------------------------- */
.hero-specs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3) 0;
  margin-top: clamp(32px, 4vw, 52px);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--c-border);
  font-family: var(--ff-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-text-4);
}

.hero-specs span {
  display: inline-flex;
  align-items: center;
  padding-right: var(--sp-5);
}

.hero-specs span + span {
  padding-left: var(--sp-5);
  border-left: 1px solid var(--c-border);
}

/* ----------------------------------------------------------------
   NARROW
   No mark below the breakpoint. The hero falls back to a single
   column of type, which is what the page looked like before any of
   this was added.

   Both elements are hidden, not just the column: the canvas has to
   go too, or the mark would still paint at its last transform. The
   script measures the column, finds it collapsed, drops its
   particles and stops its loop — so this costs nothing on a phone.
   ---------------------------------------------------------------- */
@media (max-width: 1023.98px) {
  .hero-visual,
  .hero-flow {
    display: none;
  }
}

@media (max-width: 620px) {
  .hero-specs span {
    padding-right: var(--sp-4);
  }
  .hero-specs span + span {
    padding-left: var(--sp-4);
  }
}

/* ----------------------------------------------------------------
   REDUCED MOTION
   The script never starts its loop, so the mark simply sits still.
   These rules make the component safe on its own too.
   ---------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .kf-cell {
    transform: none !important;
    filter: none !important;
  }
  .hero-status .live {
    animation: none;
  }
}
