/* ============================================================
   AllyVora page — ported from "AllyVORA Landing v3"

   Loaded AFTER home.css and scoped entirely under `body.av`. It carries
   this page's layout, motion and square-cornered shape — not its colours.
   Every colour comes from the active site theme, so the theme switcher in
   the header moves this page with the rest of the site.

   Type: Space Grotesk (display + labels) · Archivo 300 (body)
   ============================================================ */

body.av {
  /* No palette here any more. Every colour comes from the active site
     theme, so the header's theme switcher moves this page with the rest of
     the site. What is left is the page's own shape: square corners, its own
     typefaces, and the light weight the design was drawn at. */
  --radius: 2px;
  --radius-sm: 2px;

  --ff-display: "Space Grotesk", system-ui, sans-serif;
  --ff-body: "Archivo", system-ui, sans-serif;
  --ff-mono: "Space Grotesk", ui-monospace, monospace;
  --ff-serif: "Space Grotesk", system-ui, sans-serif;

  font-family: var(--ff-body);
  font-weight: 300;
  background: var(--bg);
  color: var(--ink);
}


/* the canvas network replaces the dotted bit field */
body.av::before { display: none; }

body.av ::selection { background: color-mix(in srgb, var(--lime-b) 55%, transparent); color: var(--ink); }

body.av h1, body.av h2, body.av h3 {
  font-family: var(--ff-display);
  font-weight: 600;
  letter-spacing: -0.035em;
}

/* The reference centres its content on a 1280px measure. Scoped to <main>
   on purpose: the header and footer are shared with every other page and
   run full-bleed there, so capping them here would make this one page's
   chrome narrower than the rest of the site. */
/* The site measure, not this page's own. Each product page arrived with a
   different one from its reference (1280, 1200, 1160, 1140); with the rest
   of the site and the footer held to --maxw, four near-misses read as
   misalignment rather than as four designs. */
body.av main .wrap { max-width: var(--maxw); padding-inline: 44px; }

/* ---------- the v3 motion vocabulary ---------- */
@keyframes av-word   { from { transform: translateY(105%) rotate(2deg); } to { transform: none; } }
@keyframes av-rise   { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }
@keyframes av-wipe   { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes av-sweep  { from { transform: translateX(-260px); } to { transform: translateX(100vw); } }
@keyframes av-ring   { 0% { transform: scale(0.6); opacity: 0.7; } 100% { transform: scale(2.4); opacity: 0; } }
@keyframes av-pip    { 0%, 100% { opacity: 0.25; transform: scale(0.8); } 50% { opacity: 1; transform: scale(1.15); } }

/* ============================================================
   CANVAS — the event network behind the whole page
   ============================================================ */
.av-net {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.2s ease;
}
.av-net.on { opacity: 1; }

/* Content sits above the field on a translucent wash, so the network reads
   through without ever fighting the type.

   The z-index matters: the canvas is position:fixed with z-index 0, and a
   positioned box outranks a non-positioned one in the same stacking
   context — so the footer (static in home.css) would be painted UNDER the
   canvas without this. */
body.av main > section,
body.av .footer {
  position: relative;
  z-index: 1;
  background: color-mix(in srgb, var(--bg) 84%, transparent);
  backdrop-filter: blur(8px);
}

/* The hero is the exception, and it matters: it is the one screen where
   the network has to be plainly visible. A 0.84 wash plus an 8px blur
   left it a flat lavender panel with the traffic barely readable behind
   it, which read as "the page does not move". Transparent here. */
body.av main > section.av-hero {
  background: none;
  backdrop-filter: none;
}

/* the header is sticky, so an in-page jump has to stop short of it */
body.av main > section[id] { scroll-margin-top: 84px; }

/* ============================================================
   NAV
   ============================================================ */
body.av .nav {
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
/* the home nav's lime sweep would read as the wrong brand here */
body.av .nav::after {
  background: linear-gradient(90deg, transparent, var(--accent) 50%, transparent);
}

body.av .brand .bp { font-family: var(--ff-display); font-weight: 600; letter-spacing: -0.02em; }
body.av .brand .bb { font-family: var(--ff-display); font-weight: 600; color: var(--accent-2); }
body.av .brand .caret { background: var(--accent); }

body.av .nav-links a {
  font-family: var(--ff-display);
  font-weight: 500;
  font-size: 14px;
  letter-spacing: -0.005em;
  color: color-mix(in srgb, var(--ink) 75%, transparent);
}
body.av .nav-links a::after { background: var(--accent); }
body.av .nav-links a:hover, body.av .nav-links a.on { color: var(--ink); }

/* Re-point the shimmer gradient at the violet palette. The home rule sets
   -webkit-text-fill-color: transparent, so the colour has to come back
   through the gradient — leaving it unset would blank the labels. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  body.av .nav-links a:not(.on) {
    background-image: linear-gradient(100deg,
      color-mix(in srgb, var(--ink) 75%, transparent) 0%, color-mix(in srgb, var(--ink) 75%, transparent) 38%,
      var(--accent) 48%, var(--accent-2) 52%,
      color-mix(in srgb, var(--ink) 75%, transparent) 62%, color-mix(in srgb, var(--ink) 75%, transparent) 100%);
  }
  body.av .nav-links a:not(.on):hover {
    background-image: none;
    color: var(--ink);
    -webkit-text-fill-color: var(--ink);
  }
}

body.av .mobile-menu { background: color-mix(in srgb, var(--bg) 97%, transparent); }
body.av .mobile-menu a:not(.btn) { font-family: var(--ff-display); font-weight: 500; }
body.av .mobile-menu a:not(.btn):hover { color: var(--accent-2); }
body.av .menu-btn { border-radius: 2px; border-color: color-mix(in srgb, var(--ink) 35%, transparent); }
body.av .menu-btn .bars i { background: var(--ink); }
body.av .menu-btn .bars i:nth-child(2) { background: var(--accent); }

/* ============================================================
   BUTTONS — squared keys, sentence case, no uppercase mono
   ============================================================ */
body.av .btn {
  font-family: var(--ff-display);
  font-weight: 500;
  font-size: 15px;
  letter-spacing: 0;
  text-transform: none;
  border-radius: 2px;
  padding: 16px 28px;
  transition: background .3s ease, color .3s ease, gap .3s ease, transform .3s ease, box-shadow .25s ease;
}
body.av .btn:hover { transform: none; gap: 18px; }
body.av .btn-primary {
  background: var(--ink);
  color: var(--bg);
  box-shadow: none;
}
body.av .btn-primary:hover { background: var(--accent-2); color: var(--bg); box-shadow: none; }
body.av .btn .arr { transition: none; }
body.av .btn:hover .arr { transform: none; }

/* the secondary action is a lime highlighter stroke, not a bordered key */
body.av .btn-ghost {
  border: none; padding: 0 0 4px;
  background: none;
  font-size: 15px; color: color-mix(in srgb, var(--ink) 80%, transparent);
  box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--ink) 30%, transparent);
  transition: box-shadow .25s ease, color .25s ease;
}
body.av .btn-ghost:hover {
  background: none; border: none;
  color: var(--ink);
  box-shadow: inset 0 -8px 0 color-mix(in srgb, var(--lime-b) 60%, transparent);
}


/* ============================================================
   HERO — word-by-word reveal over the network
   ============================================================ */
.av-hero { padding: 15vh 0 100px; }

.av-kicker {
  margin: 0 0 30px;
  font-family: var(--ff-display);
  font-size: 12px; font-weight: 500;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: color-mix(in srgb, var(--ink) 80%, transparent);
  display: inline-flex; align-items: center; gap: 11px;
  animation: av-rise .8s cubic-bezier(.16,1,.3,1) .15s both;
}
/* the live pip: a filled dot with a ring pushing out of it */
.av-pip { position: relative; display: inline-flex; width: 9px; height: 9px; flex: none; }
.av-pip i, .av-pip u { position: absolute; inset: 0; border-radius: 50%; }
.av-pip i { background: var(--accent); animation: av-pip 1.9s ease-in-out infinite; }
.av-pip u { border: 1px solid var(--accent); animation: av-ring 1.9s ease-out infinite; }

/* Each word rides up out of its own overflow-hidden box. The mask is what
   sells it, so the boxes must stay inline-block with the overflow clipped. */
.av-hero .av-display {
  margin: 0;
  font-size: clamp(44px, 6.8vw, 104px);
  line-height: 1.0;
  letter-spacing: -0.04em;
  max-width: 16ch;
  display: flex; flex-wrap: wrap; gap: 0 0.26em;
}
.av-hero .av-display .w { display: inline-block; overflow: hidden; padding-bottom: 0.08em; }
.av-hero .av-display .w > span {
  display: inline-block;
  animation: av-word .85s cubic-bezier(.16,1,.3,1) both;
}
.av-hero .av-display .w:nth-child(1) > span { animation-delay: .20s; }
.av-hero .av-display .w:nth-child(2) > span { animation-delay: .27s; }
.av-hero .av-display .w:nth-child(3) > span { animation-delay: .34s; }
.av-hero .av-display .w:nth-child(4) > span { animation-delay: .41s; }
.av-hero .av-display .w:nth-child(5) > span { animation-delay: .48s; }
.av-hero .av-display .w:nth-child(6) > span { animation-delay: .55s; }
.av-hero .av-display .w:nth-child(7) > span { animation-delay: .62s; }
.av-hero .av-display .w:nth-child(8) > span { animation-delay: .69s; }
.av-hero .av-display .w:nth-child(9) > span { animation-delay: .76s; }
.av-hero .av-display .w.hot > span { color: var(--accent-2); }

.av-hero /* The descriptive heading: subordinate to the tagline in size, but the
   page's actual H1. */
.av-h1 {
  margin: 26px 0 0;
  max-width: 30ch;
  font-family: var(--ff-display);
  font-size: clamp(19px, 2.1vw, 27px);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--ink);
  animation: av-rise .9s cubic-bezier(.16,1,.3,1) .9s both;
}

/* the question-and-answer block */
.av-qa {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 0 44px;
  margin-top: 34px;
}
.av-qa > div {
  padding: 22px 0;
  border-top: 1px solid var(--line);
}
.av-qa h3 {
  margin: 0 0 8px;
  font-size: 17px; font-weight: 600; letter-spacing: -0.01em;
}
.av-qa p { margin: 0; font-size: 15.5px; line-height: 1.65; color: var(--ink-2); }
.av-qa a { color: var(--accent-2); border-bottom: 1px solid color-mix(in srgb, var(--accent-2) 45%, transparent); }
.av-qa a:hover { color: var(--ink); border-color: var(--ink); }

.av-lead a { color: var(--accent-2); border-bottom: 1px solid color-mix(in srgb, var(--accent-2) 45%, transparent); }
.av-lead a:hover { color: var(--ink); border-color: var(--ink); }

.av-lead {
  margin: 36px 0 0; max-width: 56ch;
  font-size: 18.5px; line-height: 1.6;
  color: color-mix(in srgb, var(--ink) 82%, transparent);
  text-wrap: pretty;
  animation: av-rise .9s cubic-bezier(.16,1,.3,1) .86s both;
}

.av-actions {
  display: flex; align-items: center; gap: 24px; flex-wrap: wrap;
  margin-top: 44px;
  animation: av-rise .9s cubic-bezier(.16,1,.3,1) .98s both;
}

/* the instrumentation line under the fold */
.av-hint {
  margin-top: 76px;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  font-family: var(--ff-display); font-size: 11.5px; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: color-mix(in srgb, var(--ink) 80%, transparent);
  animation: av-rise .9s cubic-bezier(.16,1,.3,1) 1.1s both;
}
.av-hint .rule { width: 28px; height: 1px; background: color-mix(in srgb, var(--ink) 30%, transparent); }

/* ============================================================
   SWEEP RULES + MARQUEE
   ============================================================ */
.av-rule {
  position: relative; z-index: 1;
  overflow: hidden; height: 1px;
  background: color-mix(in srgb, var(--ink) 14%, transparent);
}
.av-rule i {
  position: absolute; top: 0; left: 0; width: 260px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  animation: av-sweep 5s linear infinite;
}
.av-rule.slow i {
  background: linear-gradient(90deg, transparent, var(--lime-b), transparent);
  animation-duration: 7s; animation-delay: 1s;
}


/* ============================================================
   RELAY — three things have to be true
   ============================================================ */
.av-relay { padding: 100px 0 110px; }

.av-relay h2 {
  margin: 0 0 12px;
  font-size: clamp(28px, 3.6vw, 48px);
  line-height: 1.08; letter-spacing: -0.03em;
  max-width: 20ch;
  animation: av-wipe 1s cubic-bezier(.65,0,.35,1) 1.35s both;
}
.av-relay .av-sub {
  margin: 0 0 60px;
  font-size: 16px; color: color-mix(in srgb, var(--ink) 75%, transparent);
  max-width: 48ch;
  animation: av-rise .9s cubic-bezier(.16,1,.3,1) 1.45s both;
}

.av-trio {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 22px;
}
.av-card {
  position: relative;
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  border: 1px solid var(--line);
  padding: 30px 28px 34px;
  transition: transform .35s cubic-bezier(.16,1,.3,1), border-color .35s ease, box-shadow .35s ease;
  animation: av-rise .9s cubic-bezier(.16,1,.3,1) both;
}
.av-card:nth-child(1) { animation-delay: 1.55s; }
.av-card:nth-child(2) { animation-delay: 1.65s; }
.av-card:nth-child(3) { animation-delay: 1.75s; }

/* The reference fires these on a fixed delay from load. That works for a
   single-screen artifact; here the section is below the fold, so the wipe
   and the three cards had all finished before anyone scrolled to them —
   the section simply appeared, already static.

   So: hold them paused (fill-mode `both` keeps the from-state) until the
   section is reached, then run with a short stagger. The pause only
   applies once the script has marked the body, so with JS off the page
   still behaves exactly like the reference. */
body.av-js .av-watch h2,
body.av-js .av-watch .av-sub,
body.av-js .av-watch .av-card { animation-play-state: paused; }

body.av-js .av-watch.av-in h2,
body.av-js .av-watch.av-in .av-sub,
body.av-js .av-watch.av-in .av-card { animation-play-state: running; }

body.av-js .av-watch h2 { animation-delay: .05s; }
body.av-js .av-watch .av-sub { animation-delay: .15s; }
body.av-js .av-watch .av-card:nth-child(1) { animation-delay: .25s; }
body.av-js .av-watch .av-card:nth-child(2) { animation-delay: .35s; }
body.av-js .av-watch .av-card:nth-child(3) { animation-delay: .45s; }
.av-card:hover {
  transform: translateY(-6px);
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  box-shadow: 10px 10px 0 color-mix(in srgb, var(--lime-b) 45%, transparent);
}
.av-card .av-step {
  font-family: var(--ff-display); font-size: 11.5px; font-weight: 500;
  letter-spacing: 0.2em; color: var(--accent-2);
  margin-bottom: 20px; display: block;
}
.av-card h3 {
  margin: 0 0 12px;
  font-weight: 500; font-size: 21px; letter-spacing: -0.02em;
}
.av-card p {
  margin: 0;
  font-size: 15px; line-height: 1.62;
  color: color-mix(in srgb, var(--ink) 80%, transparent);
  text-wrap: pretty;
}

/* ============================================================
   PROOF — dark slab, lime numerals that count up
   ============================================================ */
.av-proof {
  background: var(--ink);
  backdrop-filter: none;   /* the slab is opaque; blurring behind it is wasted work */
  color: var(--bg);
  padding: 84px 0 92px;
  overflow: hidden;
}
.av-proof::before {
  content: ""; position: absolute; top: 0; left: 0;
  width: 260px; height: 2px;
  background: linear-gradient(90deg, transparent, var(--lime-b), transparent);
  animation: av-sweep 6s linear infinite;
}
.av-proof .av-kicker {
  margin: 0 0 48px;
  color: color-mix(in srgb, var(--bg) 70%, transparent);
  animation: none;
}

.av-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 40px 36px;
}
.av-stat b {
  display: block;
  font-family: var(--ff-display); font-weight: 500;
  font-size: clamp(40px, 4.6vw, 62px); line-height: 1;
  letter-spacing: -0.035em;
  /* the bright charge is a fill colour, not a text one — these figures are
     read against the page ground */
  color: var(--accent-2);
}
.av-stat p {
  margin: 14px 0 0;
  font-size: 14.5px; line-height: 1.55;
  color: color-mix(in srgb, var(--bg) 78%, transparent);
}

/* ============================================================
   CTA — headline and key on one baseline
   ============================================================ */
.av-go { padding: 110px 0 118px; }
.av-go .wrap {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 52px; flex-wrap: wrap;
}
.av-go h2 {
  margin: 0;
  font-size: clamp(32px, 4.6vw, 64px); line-height: 1.03;
  letter-spacing: -0.035em; max-width: 15ch;
  text-wrap: balance;
}
.av-go .btn-primary { background: var(--accent-2); padding: 18px 32px; white-space: nowrap; }
.av-go .btn-primary:hover { background: var(--ink); transform: translateY(-2px); }

/* ============================================================
   FOOTER
   ============================================================ */
body.av .footer { border-top: 1px solid var(--line); }
body.av .foot-status { font-family: var(--ff-display); letter-spacing: 0.18em; }
body.av .foot-status .live { background: var(--accent); }
body.av .foot-status .foot-bin { color: var(--accent-2); }
body.av .foot-say p { font-weight: 300; }
body.av .foot-say .ital {
  font-family: var(--ff-display); font-style: normal; font-weight: 500;
  color: var(--accent-2);
}
body.av .foot-mail { font-family: var(--ff-display); border-bottom-color: var(--lime-b); }
body.av .foot-mail:hover { color: var(--accent-2); border-color: var(--accent-2); }
body.av .foot-links h4, body.av .foot-bottom { font-family: var(--ff-display); }
body.av .foot-mark .bp { color: var(--ink); }
body.av .foot-mark .bb { color: var(--accent-2); }
body.av .foot-mark .caret { background: var(--lime-b); }

/* ============================================================
   RESPONSIVE + REDUCED MOTION
   ============================================================ */
@media (max-width: 680px) {
  body.av main .wrap { padding-inline: 20px; }
  /* The secondary action is styled as an underlined text link rather than
     a bordered key, which left it 27px tall — fine for a cursor, too small
     for a thumb. The padding grows the target; the stroke stays where the
     text is. */
  body.av .btn-ghost { padding: 12px 0 14px; }
  .av-hero { padding: 12vh 0 72px; }
  .av-hero .av-display { font-size: clamp(34px, 10vw, 54px); max-width: none; }
  .av-hero .av-lead { font-size: 16.5px; }
  .av-hint { margin-top: 48px; }
  .av-actions { gap: 18px; }
  .av-relay { padding: 72px 0; }
  .av-go { padding: 72px 0 80px; }
}

/* See the note in vorasphere.css: hiding each variant behind its own query
   left a device reporting hover:none with pointer:fine showing both. */
.av-hint .on-touch { display: none; }
@media (hover: none) and (pointer: coarse) {
  .av-hint .on-pointer { display: none; }
  .av-hint .on-touch { display: inline; }
  /* also at tablet widths, where the 680px rule below does not reach */
  body.av .btn-ghost { padding: 12px 0 14px; }
}

@media (prefers-reduced-motion: reduce) {
  .av-hero .av-display .w > span,
  .av-kicker, .av-hero .av-lead, .av-actions, .av-hint,
  .av-relay h2, .av-relay .av-sub, .av-card {
    animation: none;
    opacity: 1;
    transform: none;
    clip-path: none;
  }
  .av-rule i, .av-proof::before,
  .av-pip i, .av-pip u { animation: none; }
  .av-net { transition: none; }
}
