/*
  Motion-enhancement layer — getwiever.com.

  WHY A SECOND STYLESHEET: styles.css sits at the 24 KB-gzipped stop-and-split
  line (README payload gate), and every rule in THIS file is decorative motion.
  It is loaded with media="(prefers-reduced-motion: no-preference)", which
  double-gates it: for reduced-motion visitors the browser still fetches it
  (low priority, so it can react if the preference flips) but never APPLIES a
  rule from it and never render-blocks on it. They lose nothing but polish.
  Consequences of that loading strategy — read before adding rules here:

  - NOTHING LOAD-BEARING GOES IN THIS FILE. No layout, no color a visitor
    needs, no state (released/pre-release), no focus styling. If removing this
    file entirely would break anything but delight, the rule is in the wrong
    file.
  - THE RESTING STATE STILL LIVES IN styles.css (ADR-102: resting = finished).
    Rules here may REWIND-and-animate only inside @supports guards, exactly
    like layer 5's .reveal pattern.
  - The grep gates in site/README.md are unaffected: this file contains no
    script hooks, and animation here must never require JS. motion.js does not
    know this file exists.
  - forced-colors: the UA strips backgrounds/shadows on its own, but any rule
    that HIDES authored text behind a pseudo (the trust count-up) must be
    wrapped in @media (forced-colors: none) or high-contrast users see the
    text twice.
  - html[data-motion="paused"]: the header toggle that set it was removed
    2026-07-25, but the enumerated-pause contract still stands in styles.css
    layer 7. Every INFINITE animation added here is also listed in the pause
    block at the bottom of this file, so the toggle can return without a hunt.
*/

@media screen {

/* ── 1. Hero headline: the aurora breathes ─────────────────────────────
   The .grad text-fill drifts through the wordmark gradient. Slow and
   alternate, so it reads as light moving across the glass, not a marquee. */
.hero h1 .grad {
  background-size: 220% 100%;
  animation: enh-grad-drift 16s var(--ease) infinite alternate;
}

@keyframes enh-grad-drift {
  from { background-position: 0% 50%; }
  to   { background-position: 100% 50%; }
}

/* ── 2. Scroll reveals gain a touch of scale ───────────────────────────
   Same-name override of layer 5's keyframes (this file loads later, last
   declaration wins). Reduced-motion visitors never load this file, so the
   original flat fade remains their @supports-gated behaviour. */
@keyframes reveal {
  from { opacity: 0; transform: translateY(22px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

/* ── 3. Primary buttons: one sheen pass on hover/focus ─────────────────
   A single 700 ms sweep, not a loop — repeat requires re-entering the
   control. ::after is free on .btn-primary (checked 2026-08-07); the focus
   ring is an outline, which overflow:hidden cannot clip. */
.btn-primary {
  position: relative;
  overflow: hidden;
}

.btn-primary::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  transform: translateX(-130%) skewX(-18deg);
  background: linear-gradient(105deg,
    transparent 42%, rgba(255, 255, 255, 0.30) 50%, transparent 58%);
}

.btn-primary:hover::after,
.btn-primary:focus-visible::after {
  animation: enh-btn-sheen 700ms var(--ease-out);
}

@keyframes enh-btn-sheen {
  to { transform: translateX(130%) skewX(-18deg); }
}

/* ── 4. Trust numbers count up on scroll-in ────────────────────────────
   Scroll-driven, @supports-gated, resting state untouched: the authored
   digits ("196", "20", "4", "100%") remain in the DOM and the accessibility
   tree; this only paints a counter over them while the section crosses the
   viewport. Targets are duplicated from index.html BY HAND — if a trust
   number changes there, change it here or the count-up lands on the wrong
   value. Guarded from forced-colors, where a transparent authored layer
   would be re-coloured and double-print. */
@media (forced-colors: none) {
  @supports (animation-timeline: view()) {
    .trust-grid li .trust-num {
      position: relative;
      color: transparent;
      font-variant-numeric: tabular-nums;
      counter-reset: enh-tn calc(var(--enh-tn));
      animation: enh-count linear both;
      animation-timeline: view();
      animation-range: entry 25% entry 85%;
    }

    .trust-grid li .trust-num::before {
      content: counter(enh-tn);
      position: absolute;
      inset: 0;
      color: var(--fg);
    }

    .trust-grid li:nth-child(1) .trust-num { --enh-tn-target: 196; }
    .trust-grid li:nth-child(2) .trust-num { --enh-tn-target: 20; }
    .trust-grid li:nth-child(3) .trust-num { --enh-tn-target: 4; }
    .trust-grid li:nth-child(4) .trust-num { --enh-tn-target: 100; }
    .trust-grid li:nth-child(4) .trust-num::before { content: counter(enh-tn) "%"; }

    @keyframes enh-count {
      from { --enh-tn: 0; }
      to   { --enh-tn: var(--enh-tn-target); }
    }
  }
}

/* ── 5. Pricing card: a slow aurora ring ───────────────────────────────
   One thin conic highlight orbiting the only card on the page that asks for
   money. The mask keeps it to a 1px ring; opacity keeps it a glint rather
   than a spinner. Without @property support the angle can't interpolate and
   the ring simply holds still — acceptable degradation. */
.pricing-card {
  position: relative;
}

.pricing-card::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  pointer-events: none;
  background: conic-gradient(from var(--enh-pc-angle),
    transparent 0turn 0.62turn,
    var(--aurora-cyan) 0.78turn,
    var(--aurora-violet) 0.88turn,
    transparent 1turn);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
  opacity: 0.65;
  animation: enh-pc-spin 9s linear infinite;
}

@keyframes enh-pc-spin {
  to { --enh-pc-angle: 360deg; }
}

/* ── 6. Section eyebrows: a hairline that draws itself ─────────────────
   28px aurora rule under each section eyebrow, scaling in from the left as
   the section head enters. Static-by-default (scaleX(1)); the @supports
   block rewinds it, mirroring the .reveal pattern. */
.section-head .eyebrow {
  position: relative;
  padding-bottom: 6px;
}

.section-head .eyebrow::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 28px;
  height: 2px;
  border-radius: 1px;
  transform: translateX(-50%);
  background: var(--aurora-gradient);
}

@supports (animation-timeline: view()) {
  .section-head .eyebrow::after {
    transform-origin: left;
    animation: enh-rule-draw both var(--ease-out);
    animation-timeline: view();
    animation-range: entry 10% entry 60%;
  }

  @keyframes enh-rule-draw {
    from { transform: translateX(-50%) scaleX(0); }
    to   { transform: translateX(-50%) scaleX(1); }
  }
}

/* ── 7. Header deepens as the page scrolls ─────────────────────────────
   At rest the sticky header is a light veil; 160px of scroll settles it
   into a solid, shadowed bar. Scroll-driven and @supports-gated; without
   support the authored constant veil from styles.css simply remains. */
@supports (animation-timeline: scroll()) {
  .site-header {
    animation: enh-header-elevate linear both;
    animation-timeline: scroll();
    animation-range: 0 160px;
  }

  @keyframes enh-header-elevate {
    from {
      background: rgba(11, 13, 16, 0.38);
      box-shadow: none;
    }
    to {
      background: rgba(11, 13, 16, 0.88);
      box-shadow: 0 10px 30px -18px rgba(0, 0, 0, 0.85);
    }
  }
}

/* ── 8. FAQ answers ease open ──────────────────────────────────────────
   The [open] accent bar already exists in styles.css; this makes the
   revealed text arrive instead of appear. One shot, 260 ms. */
.faq-item[open] > p {
  animation: enh-faq-in 260ms var(--ease-out);
}

@keyframes enh-faq-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

/* ── 9. The film sits in aurora light ──────────────────────────────────
   Static (zero runtime cost): a faint cyan bloom joins the existing depth
   shadow so the promo stage reads as the page's light source. Override of
   the full shadow list from styles.css layer 8. */
.demo-stage {
  box-shadow:
    0 30px 90px -30px rgba(0, 0, 0, 0.85),
    0 0 110px -24px rgba(43, 200, 224, 0.30),
    var(--edge-highlight);
}

/* ── Enumerated pause hooks (contract with styles.css layer 7) ─────────
   Only the INFINITE loops belong here; scroll-driven and one-shot
   animations must never be play-state-paused (README: ".reveal must never
   be given animation-play-state: paused"). */
html[data-motion="paused"] .hero h1 .grad,
html[data-motion="paused"] .pricing-card::after {
  animation-play-state: paused;
}

} /* @media screen */

/* @property registrations — top level on purpose: typed custom properties
   make the count-up integer and the conic angle interpolable. Harmless when
   unsupported (the guards above degrade as documented). */
@property --enh-tn {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}

@property --enh-pc-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
