/* ===========================================================================
   EventanalyticsAI landing page.

   Every value in this file comes from `EventanalyticsAI Landing v2.dc.html`
   (committed at ../../design-source/). The drawing carries its styling as
   inline `style` attributes and `style-hover` attributes; this file is the
   same declarations moved into classes so that hover, focus, media queries
   and reduced-motion can exist at all.

   Colour, type, space, radius and shadow are NEVER written literally here:
   they resolve through the Nocturne tokens in nocturne.css. The literals that
   do appear (font sizes, paddings, grid tracks, path geometry) are the
   drawing's own numbers, and verify/check-styles.mjs is the gate that says so.
   =========================================================================== */

/* ---------------------------------------------------------------- page ---
   The drawing's <helmet> block: the four-layer ground, the link colours and
   the two keyframes. */

html {
  scroll-behavior: smooth;
  /* The header is sticky and about 53px tall, so a fragment jump or a
     focus-driven scroll parks the target underneath it. Every in-page scroll
     on this page stops 64px short instead. */
  scroll-padding-top: 64px;
}

body {
  margin: 0;
  text-wrap: pretty;
  background:
    radial-gradient(1400px 800px at 70% -240px, color-mix(in srgb, var(--color-accent-900) 80%, transparent), transparent 62%),
    radial-gradient(1000px 700px at -12% 30%, color-mix(in srgb, var(--color-section) 40%, transparent), transparent 55%),
    radial-gradient(1100px 800px at 110% 100%, color-mix(in srgb, black 34%, transparent), transparent 55%),
    var(--color-bg);
}

a { color: var(--color-accent); }
/* :not(.btn) because the drawing's CTAs are <button>s and here they are
   anchors — and `a:hover` (0,1,1) outranks `.btn-primary` (0,1,0), so without
   this the hero and nav CTAs change ink on hover where the drawing only
   tints their ground. */
a:hover:not(.btn) { color: var(--color-accent-300); }

@keyframes eaTicker { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes eaPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* The page's own layout constants. `--ea-edge` is where the two vertical
   rules stand; the nav sits 24px inside them and section bodies 40px. */
:root {
  --ea-max: 1240px;
  --ea-edge: max(24px, calc((100% - 1240px) / 2));
  --ea-nav-edge: max(24px, calc((100% - 1240px) / 2 + 24px));
  --ea-gutter: 40px;
}

/* Screen-reader-only text, and the skip link that becomes visible on focus. */
.ea-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.ea-skip {
  position: absolute; left: 8px; top: -60px; z-index: 100;
  padding: 10px 16px; border-radius: var(--radius-md);
  background: var(--color-surface); color: var(--color-text);
  box-shadow: var(--shadow-md); text-decoration: none;
  transition: top 120ms ease;
}
.ea-skip:focus-visible { top: 8px; color: var(--color-text); }

/* Tabular figures. The drawing sets font-feature-settings:'tnum' 1 on every
   block that carries a measured number, so columns of them line up. */
.ea-num { font-feature-settings: 'tnum' 1; }

/* ----------------------------------------------------------------- nav ---
   .nav / .nav-brand come from Nocturne; everything below is the drawing's
   override of them. The rules are scoped under .ea-nav because Nocturne's
   `.nav a` (0,1,1) outranks a bare utility class (0,1,0) — the brand and the
   links are anchors here, where the drawing used spans. */

/* The header's own height, named because two other rules subtract it and
   neither could see it. /thanks has been running on a 64px fallback since it
   was written; the bar measures 53px (11px padding either side of a 31px row),
   so that page's min-height has been 11px short the whole time. Declaring it
   here fixes that too, and puts the number next to the padding that makes it. */
:root { --ea-header-h: 53px; }
.ea-header { position: sticky; top: 0; z-index: 60; }

.ea-nav {
  backdrop-filter: blur(14px);
  background: color-mix(in srgb, var(--color-bg) 72%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--color-divider) 55%, transparent);
  padding: 11px var(--ea-nav-edge);
}

.ea-nav .ea-brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 15px; color: var(--color-text); text-decoration: none;
}
.ea-nav .ea-brand:hover { color: var(--color-accent); }

/* The mark is Emerald/public/brand/event-analytics-mark.png — the same file
   lib/brand.js serves to every hub screen, copied here rather than re-drawn.
   It ships as the isometric glyph on an opaque white rounded tile with the
   corners transparent (72% of its opaque pixels are white), which is what
   `markTiled: true` in the hub's brand object means. So this element draws no
   border, no ground and no radius of its own: the artwork already carries all
   three, and framing it again would put a box around a tile. */
.ea-brand-mark { width: 25px; height: 25px; flex: none; display: grid; place-items: center; }
.ea-mark-img { display: block; width: 100%; height: 100%; object-fit: contain; }
.ea-wordmark { white-space: nowrap; }
.ea-wordmark-ai { color: var(--color-accent); }


.ea-nav-menu { display: contents; }

.ea-nav .ea-nav-link {
  font-family: ui-monospace, Menlo, monospace;
  font-size: 11.5px; letter-spacing: 0.08em; text-transform: uppercase;
  color: inherit; text-decoration: none;
}
.ea-nav .ea-nav-link-quiet { opacity: 0.8; }
.ea-nav .ea-nav-link:hover { color: var(--color-accent); }

.ea-nav .ea-nav-cta { color: var(--color-accent); text-decoration: none; }

/* The mobile disclosure. `hidden` in the markup and un-hidden by landing.js,
   so a scripting-off browser keeps the links themselves rather than losing
   the whole navigation the way the drawing's `@media .nav a{display:none}`
   would have. */
.ea-nav-toggle {
  display: none;
  width: 36px; height: 36px; padding: 0;
  align-items: center; justify-content: center;
  background: transparent; cursor: pointer;
  border: 1px solid var(--color-neutral-700);
  border-radius: var(--radius-md);
  color: var(--color-text);
}
.ea-nav-toggle:hover { border-color: var(--color-accent-600); }
.ea-nav-toggle-bars,
.ea-nav-toggle-bars::before,
.ea-nav-toggle-bars::after {
  display: block; width: 15px; height: 1.5px; border-radius: 1px;
  background: currentColor; content: '';
}
.ea-nav-toggle-bars { position: relative; }
.ea-nav-toggle-bars::before { position: absolute; top: -5px; }
.ea-nav-toggle-bars::after { position: absolute; top: 5px; }
.ea-nav-toggle[aria-expanded='true'] { border-color: var(--color-accent-600); color: var(--color-accent); }

/* --------------------------------------------------------------- rails ---
   The two full-height hairlines that run down the page edges, fading out
   over their first and last 120px. */

.ea-rails { position: relative; }
.ea-rail {
  position: absolute; top: 0; bottom: 0; width: 1px;
  pointer-events: none;
  background: linear-gradient(to bottom, transparent, var(--color-divider) 120px, var(--color-divider) calc(100% - 120px), transparent);
}
.ea-rail-left { left: var(--ea-edge); }
.ea-rail-right { right: var(--ea-edge); }

/* Shared measure for every section body. */
.ea-pad { padding-left: var(--ea-gutter); padding-right: var(--ea-gutter); }

/* ---------------------------------------------------------------- hero --- */
/* Redrawn 2026-09-01 from design-source/EventAnalytics Hero v3.dc.html.
   Every colour resolves through a nocturne token. The drawing writes literal
   hexes (#13131b, #a78bfa, #8b7cf6 and so on); check-styles records which
   token each one lands on and why. */

.ea-hero {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column;
  /* THE DRAWING'S 100vh MINUS THE HEADER. In the drawing the header is inside
     the hero section, so its 100vh covers both; here the header is a sticky
     site-wide bar that every page shares and the hero starts underneath it.
     Taking 100vh literally overflowed the viewport by exactly the header,
     measured 84px at 805px tall, which pushed the chart's axis off screen.

     svh, not vh: on a phone `vh` is the height with the browser chrome
     RETRACTED, so a 100vh hero is taller than the screen on first paint and
     the reader lands mid-headline. --ea-header-h keeps the number in one
     place; the header itself is what sets it. */
  min-height: calc(100svh - var(--ea-header-h));
}
@supports not (height: 100svh) { .ea-hero { min-height: calc(100vh - var(--ea-header-h)); } }
/* The two drifting glows. Decorative and behind everything, so they take no
   part in layout and never intercept a pointer. */
.ea-hero-glow {
  position: absolute; border-radius: 50%; z-index: 0; pointer-events: none;
  animation: eaGlowDrift 16s ease-in-out infinite;
}
.ea-hero-glow-a {
  top: -22%; right: -12%; width: 720px; height: 720px;
  background: radial-gradient(circle, color-mix(in srgb, var(--color-accent-500) 16%, transparent) 0%, transparent 62%);
}
.ea-hero-glow-b {
  bottom: -30%; left: -14%; width: 860px; height: 860px;
  background: radial-gradient(circle, color-mix(in srgb, var(--color-accent-500) 10%, transparent) 0%, transparent 60%);
  animation-duration: 20s; animation-delay: -8s; animation-direction: reverse;
}
@keyframes eaGlowDrift {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-50px, 30px) scale(1.06); }
}

.ea-hero-inner {
  position: relative; z-index: 2; flex: 1;
  display: flex; flex-direction: column; justify-content: center;
  max-width: var(--ea-max); width: 100%; margin: 0 auto;
  padding-top: 56px; padding-bottom: 40px; box-sizing: border-box;
}

.ea-hero-title {
  font-family: var(--font-heading); font-weight: 500;
  font-size: clamp(40px, 8vw, 112px);
  line-height: 1.0; letter-spacing: -0.03em;
  margin: 0 0 0 -0.045em;
  text-wrap: balance;
}
.ea-hero-line { display: block; }
.ea-accent-dot { color: var(--color-accent); }

/* Under the headline now, and short. The drawing caps it at 520px, which is
   what keeps it reading as a subtitle rather than a paragraph. */
.ea-hero-lede {
  margin: 26px 0 0; max-width: 520px;
  font-size: 14.5px; line-height: 1.5; letter-spacing: 0.01em;
  color: color-mix(in srgb, var(--color-text) 72%, transparent);
}

.ea-hero-grid {
  display: flex; align-items: flex-start; gap: 32px;
  margin-top: 26px;
}
.ea-hero-ask { flex: 1 1 auto; min-width: 0; max-width: 860px; }

/* The query bar. The drawing paints a 1px panning gradient as the border, so
   the border IS the padding of a gradient-filled wrapper and the input sits
   inside it at one radius less. */
.ea-query {
  position: relative; display: block; border-radius: 14px; padding: 1px;
  background: linear-gradient(120deg,
    color-mix(in srgb, var(--color-accent-400) 65%, transparent),
    color-mix(in srgb, var(--color-accent-400) 35%, transparent),
    color-mix(in srgb, var(--color-accent-500) 15%, transparent),
    color-mix(in srgb, var(--color-accent-400) 65%, transparent));
  background-size: 220% 100%;
  animation: eaBorderPan 7s linear infinite;
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.35),
              0 0 46px color-mix(in srgb, var(--color-accent-500) 10%, transparent);
}
@keyframes eaBorderPan {
  0% { background-position: 0% 50%; }
  100% { background-position: 220% 50%; }
}
.ea-query-field { display: block; }
.ea-query-input {
  display: block; width: 100%; box-sizing: border-box;
  background: color-mix(in srgb, var(--color-surface) 62%, var(--color-bg));
  border: none; border-radius: 13px;
  padding: 20px 68px 20px 20px;
  font: inherit; font-size: 16.5px;
  color: color-mix(in srgb, var(--color-text) 92%, transparent);
  transition: background 0.2s;
}
.ea-query-input:focus { background: color-mix(in srgb, var(--color-surface) 80%, var(--color-bg)); }
/* No `outline: none`. The bar is the hero's primary control and a colour-only
   focus cue does not reach the 3:1 WCAG 2.2 SC 1.4.11 asks of an indicator.
   The negative offset tucks Nocturne's ring inside the 20px padding instead of
   letting it straddle the gradient edge, which is what _ds/styles.css does for
   `.input`. */
.ea-query-input:focus-visible { outline-offset: -3px; }
.ea-query-input::placeholder { color: var(--color-neutral-500); }

.ea-query-go {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--color-text) 16%, transparent);
  background: transparent; display: grid; place-items: center; cursor: pointer;
  transition: border-color 0.16s, background 0.16s;
}
.ea-query-go svg { stroke: color-mix(in srgb, var(--color-text) 50%, transparent); }
.ea-query-go:hover {
  border-color: color-mix(in srgb, var(--color-text) 32%, transparent);
  background: color-mix(in srgb, var(--color-text) 4%, transparent);
}

.ea-chips { margin-top: 14px; }
.ea-chip-row { display: flex; gap: 10px; flex-wrap: wrap; }
.ea-chip {
  font-family: inherit; font-size: 13px; padding: 8px 15px; cursor: pointer;
  border: 1px solid var(--color-neutral-800); border-radius: 999px;
  background: color-mix(in srgb, var(--color-text) 1.5%, transparent);
  color: var(--color-neutral-400);
  text-align: left;
  transform: translateY(0);
  transition: border-color 0.16s, color 0.16s, background 0.16s, transform 0.16s;
}
.ea-chip:hover {
  border-color: var(--color-accent-700); color: var(--color-accent-200);
  background: color-mix(in srgb, var(--color-accent-500) 8%, transparent);
  transform: translateY(-1px);
}

/* ---- the answer card ---- */
.ea-answer { flex: 0 0 300px; margin-left: auto; pointer-events: none; }
.ea-answer-card {
  background: color-mix(in srgb, var(--color-surface) 70%, var(--color-bg));
  border: 1px solid color-mix(in srgb, var(--color-accent-500) 28%, transparent);
  border-radius: 14px; padding: 15px 17px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.45),
              0 0 30px color-mix(in srgb, var(--color-accent-500) 8%, transparent);
  backdrop-filter: blur(6px);
  opacity: 0.45; transition: opacity 0.6s ease;
}
.ea-answer.is-on .ea-answer-card { opacity: 1; }
.ea-answer-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.ea-answer-metric {
  font-size: 12px; font-weight: 600; letter-spacing: 0.01em; padding-top: 4px;
  color: var(--color-accent-300);
}
.ea-answer-stat { text-align: right; }
/* Gradient text, as drawn. `color` is the fallback and is not decoration: a
   browser without background-clip:text paints the number in it, and Nocturne's
   forced-colors block overrides -webkit-text-fill-color, so the figure survives
   a high-contrast mode instead of turning transparent. */
.ea-answer-stat-v {
  display: block; font-size: 21px; font-weight: 700; line-height: 1;
  color: var(--color-accent-400);
  background: linear-gradient(120deg, var(--color-accent-300), var(--color-accent-400));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
@media (forced-colors: active) {
  .ea-answer-stat-v { -webkit-text-fill-color: currentColor; background: none; }
}
.ea-answer-stat-c { display: block; font-size: 10.5px; margin-top: 3px; color: var(--color-neutral-500); }
.ea-answer-text { margin: 10px 0 12px; font-size: 14px; line-height: 1.45; color: var(--color-text); }
.ea-answer-bars { display: flex; align-items: flex-end; gap: 5px; height: 40px; }
.ea-answer-bar {
  flex: 1; border-radius: 3px 3px 1px 1px;
  background: color-mix(in srgb, var(--color-accent-400) 22%, transparent);
  transition: height 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.ea-answer-bar.is-on { background: linear-gradient(180deg, var(--color-accent-400), var(--color-accent-600)); }
.ea-answer-src { margin-top: 10px; font-size: 10.5px; color: var(--color-neutral-600); }

/* SHORT VIEWPORTS. The hero is content-sized, not viewport-sized: min-height
   is a floor, and at a 112px headline over two lines the content comes to
   about 836px whatever the screen does. The drawing has the same property and
   is drawn on a tall artboard, so on a 13-inch laptop (805px of viewport, less
   53px of header) the chart's time axis fell below the fold.

   Trimming the headline and the gutters rather than the chart, because the
   chart is the half that has to be seen for the hero to make its point: a
   pacing curve with no axis is decoration. 900px is where the numbers stop
   fitting, not a device. */
@media (max-height: 900px) {
  .ea-hero-title { font-size: clamp(40px, 6.2vw, 84px); }
  .ea-hero-inner { padding-top: 32px; padding-bottom: 24px; }
  .ea-hero-lede { margin-top: 18px; }
  .ea-hero-grid { margin-top: 18px; }
}

/* ---- the entrance ----
   The drawing fades the chart in on a stagger, 0.4s to 2.5s, so the picture
   assembles rather than appearing whole: gridlines, then the comparison line,
   then the axis and legend, then the marker and its tooltip last. Each element
   carries its own delay in the drawing; here one keyframe and a delay per
   class does the same thing.

   Everything below is suppressed under prefers-reduced-motion at the foot of
   this block, where it becomes "already visible" rather than "never arrives" —
   a fade-in that is merely cancelled leaves opacity at 0 and the chart blank. */
@keyframes eaFadeIn { from { opacity: 0; } to { opacity: 1; } }
/* ONE CLASS DEEP, NOT A DESCENDANT SELECTOR. This was
   `.ea-hero-chart [class^="ea-"]`, which is 0,2,0 and therefore outranked
   `.ea-line-now` at 0,1,0 — so the shared fade replaced the stroke-drawing
   animation and the 2026 line never drew, and replaced the marching dashes on
   the projection too. Both were invisible on the page while every rule looked
   correct in isolation. A wildcard that reaches further than the rules it sits
   beside will always win an argument it was not meant to be in. */
.ea-grid-line, .ea-hero-area, .ea-line-prior, .ea-now-drop, .ea-now-stem,
.ea-now-foot, .ea-hero-pin, .ea-hero-tip, .ea-hero-legend, .ea-hero-axis {
  opacity: 0; animation: eaFadeIn 1s ease-out forwards;
}
.ea-grid-line:nth-of-type(1) { animation-delay: 0.4s; }
.ea-grid-line:nth-of-type(2) { animation-delay: 0.55s; }
.ea-grid-line:nth-of-type(3) { animation-delay: 0.7s; }
.ea-line-prior { animation-delay: 0.6s; }
.ea-hero-area { animation-duration: 1.4s; animation-delay: 1.6s; }
.ea-hero-legend { animation-delay: 1.8s; }
.ea-hero-axis-1 { animation-delay: 1.8s; }
.ea-hero-axis-2 { animation-delay: 1.9s; }
.ea-hero-axis-3 { animation-delay: 2s; }
.ea-hero-axis-4 { animation-delay: 2.1s; }
.ea-now-drop { animation-delay: 2s; }
.ea-now-foot { animation-duration: 0.6s; animation-delay: 2.2s; }
.ea-now-stem { animation-duration: 0.8s; animation-delay: 2.4s; }
.ea-hero-pin { animation-duration: 0.6s; animation-delay: 2s; }
.ea-hero-tip { animation-duration: 0.9s; animation-delay: 2.5s; }

/* ---- the pacing chart ---- */
.ea-hero-chart {
  position: relative; z-index: 1; pointer-events: none;
  height: clamp(230px, 30vh, 350px);
}
.ea-hero-chart-plot { position: absolute; left: 0; right: 0; top: 0; bottom: 28px; }
.ea-hero-svg { display: block; width: 100%; height: 100%; }

.ea-grid-line { stroke: color-mix(in srgb, var(--color-text) 3.5%, transparent); stroke-width: 1; }
.ea-hero-area-top { stop-color: color-mix(in srgb, var(--color-accent-400) 12%, transparent); }
.ea-hero-area-bottom { stop-color: transparent; }
.ea-hero-area { fill: url(#ea-hero-area-fade); }
.ea-line-prior { fill: none; stroke: color-mix(in srgb, var(--color-accent-500) 20%, transparent); stroke-width: 1.2; }
.ea-line-now {
  fill: none; stroke: color-mix(in srgb, var(--color-accent-400) 75%, transparent); stroke-width: 1.6;
  stroke-dasharray: 2000; stroke-dashoffset: 2000;
  animation: eaDrawLine 2.2s cubic-bezier(0.33, 0, 0.2, 1) 0.2s forwards;
}
@keyframes eaDrawLine { to { stroke-dashoffset: 0; } }
.ea-line-proj {
  fill: none; stroke: color-mix(in srgb, var(--color-accent-500) 45%, transparent);
  stroke-width: 1.2; stroke-dasharray: 3 8;
  opacity: 0;
  animation: eaFadeIn 1.2s ease-out 2.2s forwards, eaDashMarch 6s linear 2.2s infinite;
}
@keyframes eaDashMarch { to { stroke-dashoffset: -110; } }
.ea-now-drop { stroke: color-mix(in srgb, var(--color-text) 5%, transparent); stroke-width: 1; }
.ea-now-stem { stroke: color-mix(in srgb, var(--color-accent-400) 55%, transparent); stroke-width: 1.4; }
.ea-now-foot { fill: color-mix(in srgb, var(--color-accent-500) 35%, transparent); }

.ea-hero-pin {
  position: absolute; left: 62.5%; top: 56.2%;
  width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 50%;
  background: var(--color-accent-400);
  box-shadow: 0 0 12px color-mix(in srgb, var(--color-accent-400) 80%, transparent);
}
.ea-hero-pin-ring {
  position: absolute; inset: -7px; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--color-accent-400) 55%, transparent);
  animation: eaRingPulse 2.6s cubic-bezier(0.2, 0.6, 0.3, 1) 3s infinite;
}
@keyframes eaRingPulse {
  0% { transform: scale(0.5); opacity: 0.8; }
  70% { opacity: 0.18; }
  100% { transform: scale(2.6); opacity: 0; }
}

.ea-hero-tip {
  position: absolute; left: calc(62.5% - 16px); top: calc(56.2% - 12px);
  transform: translate(-100%, -100%);
  background: color-mix(in srgb, var(--color-bg) 92%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-accent-500) 26%, transparent);
  border-radius: 12px; padding: 11px 14px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.45);
}
.ea-hero-tip-label { font-size: 11px; color: var(--color-accent-2); }
.ea-hero-tip-value { margin-top: 5px; font-size: 19px; font-weight: 700; line-height: 1; color: var(--color-accent-100); }
.ea-hero-tip-delta { margin-top: 4px; font-size: 11px; color: var(--color-accent-300); }

.ea-hero-legend {
  position: absolute; bottom: 8px; right: var(--ea-gutter);
  display: flex; gap: 18px; font-size: 11px; color: var(--color-neutral-500);
}
.ea-hero-key { display: flex; align-items: center; gap: 6px; }
.ea-hero-key span { width: 14px; height: 0; }
.ea-hero-key-now { border-top: 1.6px solid color-mix(in srgb, var(--color-accent-400) 85%, transparent); }
.ea-hero-key-prior { border-top: 1.4px solid color-mix(in srgb, var(--color-accent-500) 30%, transparent); }
.ea-hero-key-proj { border-top: 1.4px dotted color-mix(in srgb, var(--color-accent-500) 55%, transparent); }

.ea-hero-axis { position: absolute; bottom: 6px; font-size: 11px; color: var(--color-neutral-600); }
.ea-hero-axis-1 { left: var(--ea-gutter); }
.ea-hero-axis-2 { left: 50%; transform: translateX(-50%); }
.ea-hero-axis-3 { left: 75%; transform: translateX(-50%); }
.ea-hero-axis-4 { right: var(--ea-gutter); }

/* Under 1100px the drawing drops the answer card outright rather than stacking
   it: at that width the ask column is already the whole screen and a 300px
   card beneath it would be a second hero. */
@media (max-width: 1100px) {
  .ea-answer { display: none; }
}
/* Every motion here is decoration. None of it carries information, so all of
   it stops for a reader who asked it to. */
@media (prefers-reduced-motion: reduce) {
  .ea-hero-glow, .ea-line-now, .ea-line-proj, .ea-hero-pin-ring, .ea-query {
    animation: none;
  }
  .ea-line-now { stroke-dashoffset: 0; }
  .ea-answer-card, .ea-answer-bar { transition: none; }
  /* Cancelling a fade-in leaves it at opacity 0, which is a blank chart rather
     than a still one. Everything the entrance animates is simply already
     there. */
  .ea-grid-line, .ea-hero-area, .ea-line-prior, .ea-now-drop, .ea-now-stem,
  .ea-now-foot, .ea-hero-pin, .ea-hero-tip, .ea-hero-legend, .ea-hero-axis {
    opacity: 1; animation: none;
  }
}

/* ---- shared with the other three pages ----
   These left site.css with the 2026-09-01 hero rewrite and had to come back:
   the home hero was the only place THIS page used them, but /platform,
   /pricing and /thanks still do. The class-coverage test caught it,
   which is what that test is for. */
.ea-spark { fill: var(--color-accent-400); flex: none; }
.ea-tick { position: absolute; top: 28px; color: var(--color-neutral-600); font-size: 15px; line-height: 1; }
.ea-tick-left { left: 28px; }
.ea-tick-right { right: 28px; }
.ea-cta-solid { padding: 9px 18px; }
.ea-cta-ghost { padding: 9px 10px; }

/* -------------------------------------------------------------- ticker ---
   `showTicker`, off in the drawing. `hidden` in the markup; these rules are
   what it looks like when it is on. */

.ea-ticker {
  border-top: 1px solid color-mix(in srgb, var(--color-divider) 60%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--color-divider) 60%, transparent);
  background: color-mix(in srgb, black 24%, transparent);
  overflow: hidden; padding: 11px 0;
}
.ea-ticker-track {
  display: flex; width: max-content; gap: 56px;
  animation: eaTicker 46s linear infinite;
  font-family: ui-monospace, Menlo, monospace;
  font-size: 11.5px; letter-spacing: 0.06em;
  color: var(--color-neutral-500); white-space: nowrap;
}
.ea-ticker-run { display: flex; gap: 56px; }
.ea-up { color: var(--color-accent-300); }
.ea-down { color: var(--color-neutral-400); }

/* --------------------------------------------------------------- bento --- */

.ea-bento-section {
  max-width: var(--ea-max); margin: 0 auto;
  padding-top: 80px; padding-bottom: 40px;
}
.ea-section-head { display: flex; align-items: baseline; gap: 20px; flex-wrap: wrap; margin-bottom: 30px; }
.ea-section-head-tight { margin-bottom: 8px; }
.ea-h2 {
  font-size: clamp(30px, 3.4vw, 44px); line-height: 1.12;
  letter-spacing: -0.02em; margin: 0;
}

.ea-bento { display: grid; grid-template-columns: repeat(12, 1fr); gap: 14px; }

.ea-card {
  border: 1px solid color-mix(in srgb, var(--color-divider) 70%, transparent);
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--color-surface) 55%, var(--color-bg));
  padding: 20px;
}
.ea-card:hover { border-color: var(--color-accent-700); }
.ea-card-7 { grid-column: span 7; }
.ea-card-5 { grid-column: span 5; }
.ea-card-4 { grid-column: span 4; }
.ea-card-6 { grid-column: span 6; }

.ea-card-top { display: flex; align-items: baseline; gap: 10px; }
.ea-card-top-baseline { display: flex; align-items: baseline; }
.ea-card-name { margin: 0 0 2px; font-size: 13px; font-family: var(--font-heading); font-weight: 500; }
.ea-card-top .ea-card-name { margin: 0; }
.ea-card-7 .ea-card-name { font-size: 14px; }
.ea-card-top-baseline .ea-card-name { margin: 0 0 2px; }

.ea-pill-accent {
  margin-left: auto; font-size: 10.5px; padding: 2px 8px; border-radius: 5px;
  background: var(--color-accent-800); color: var(--color-accent-200);
}

.ea-card-sub { margin: 0 0 14px; font-size: 11px; color: var(--color-neutral-500); }
.ea-card-7 .ea-card-sub { margin: 2px 0 14px; font-size: 11.5px; }
.ea-card-sub-wide { margin-bottom: 16px; }
.ea-card-foot { margin: 12px 0 0; font-size: 10.5px; color: var(--color-neutral-500); }

.ea-card-link { margin-left: auto; font-size: 11px; color: var(--color-accent-300); text-decoration: none; }
.ea-card-link:hover { color: var(--color-accent-200); text-decoration: underline; }

/* Registration pacing */
.ea-figure { margin: 0; }
.ea-chart-pacing { width: 100%; height: auto; display: block; }
.ea-gridline { stroke: var(--color-neutral-900); stroke-width: 1; }
.ea-area { fill: var(--color-accent-500); opacity: 0.12; }
.ea-line-now { fill: none; stroke: var(--color-accent-400); stroke-width: 2; }
.ea-line-prev { fill: none; stroke: var(--color-neutral-600); stroke-width: 1.4; stroke-dasharray: 4 5; }
.ea-line-head { fill: var(--color-accent-300); }

.ea-copilot-note {
  display: flex; align-items: center; gap: 10px;
  margin: 14px 0 0; padding: 9px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-accent-800);
  background: color-mix(in srgb, var(--color-accent-900) 30%, transparent);
  font-size: 12px; color: color-mix(in srgb, var(--color-text) 82%, transparent);
}
.ea-spark-sm { flex: none; }
.ea-copilot-tag { color: var(--color-accent-300); }

/* Copilot */
.ea-card-copilot { display: flex; flex-direction: column; }
.ea-copilot-head {
  display: flex; align-items: center; gap: 8px;
  padding-bottom: 10px; border-bottom: 1px solid var(--color-divider);
}
.ea-copilot-head .ea-card-name { margin: 0; }
.ea-grounded { margin-left: auto; }
.ea-bubble-row { display: flex; justify-content: flex-end; margin: 12px 0 10px; }
.ea-bubble {
  font-size: 12.5px; padding: 7px 11px;
  border-radius: 8px 8px 2px 8px;
  background: var(--color-accent-900); color: var(--color-accent-100);
  max-width: 30ch;
}
.ea-copilot-answer {
  margin: 0 0 10px; font-size: 12.5px; line-height: 1.6;
  color: color-mix(in srgb, var(--color-text) 82%, transparent);
}
.ea-leadbars {
  display: grid; grid-template-columns: max-content 1fr max-content;
  gap: 6px 9px; align-items: center; font-size: 11px;
}
.ea-leadbar-label { color: var(--color-neutral-400); }
.ea-leadbar-bar { height: 7px; border-radius: 2px; }
.ea-fill-1 { background: var(--color-accent-500); width: 100%; }
.ea-fill-2 { background: var(--color-accent-600); width: 76%; }
.ea-fill-3 { background: var(--color-accent-700); width: 57%; }
.ea-sources {
  margin: auto 0 0; padding-top: 12px; font-size: 10px;
  color: var(--color-neutral-500); font-family: ui-monospace, Menlo, monospace;
}
.ea-sql { color: var(--color-accent-300); text-decoration: none; }
.ea-sql:hover { color: var(--color-accent-200); text-decoration: underline; }

/* Hall traffic */
.ea-heat { display: grid; grid-template-columns: repeat(8, 1fr); gap: 3px; }
.ea-cell { aspect-ratio: 1.4 / 1; border-radius: 3px; }
.ea-h0 { background: color-mix(in srgb, var(--color-section) 35%, var(--color-bg)); }
.ea-h1 { background: color-mix(in srgb, var(--color-section) 65%, var(--color-bg)); }
.ea-h2 { background: var(--color-section); }
.ea-h3 { background: var(--color-section-glow); }
.ea-h4 { background: var(--color-section-ghost); }
.ea-h5 { background: var(--color-accent-400); }

/* Alerts */
.ea-rule { display: flex; gap: 5px; flex-wrap: wrap; margin: 0 0 12px; font-size: 11px; }
.ea-token { padding: 4px 8px; border: 1px solid var(--color-neutral-700); border-radius: 5px; }
.ea-token-quiet { color: var(--color-neutral-400); }
.ea-token-accent { border-color: var(--color-accent-600); color: var(--color-accent-300); }
.ea-alert {
  border: 1px solid var(--color-accent-2-700); border-radius: 7px;
  padding: 10px 12px; font-size: 11px;
  background: color-mix(in srgb, var(--color-bg) 55%, transparent);
}
.ea-alert-head { display: flex; align-items: center; gap: 6px; margin: 0 0 6px; }
.ea-alert-mark {
  width: 16px; height: 16px; flex: none;
  display: grid; place-items: center;
}
.ea-alert-from { font-family: var(--font-heading); font-weight: 500; font-size: 11.5px; }
.ea-alert-time { color: var(--color-neutral-500); font-size: 10px; }
.ea-alert-body { margin: 0; line-height: 1.5; color: color-mix(in srgb, var(--color-text) 80%, transparent); }
.ea-alert-link { color: var(--color-accent-300); text-decoration: none; }
.ea-alert-link:hover { color: var(--color-accent-200); text-decoration: underline; }

/* Attendee 360 */
.ea-merge { display: flex; flex-direction: column; gap: 6px; font-size: 11px; }
.ea-sources-row { display: flex; gap: 5px; flex-wrap: wrap; margin: 0; }
.ea-source { padding: 4px 8px; border-radius: 5px; background: var(--color-surface); box-shadow: var(--shadow-sm); }
.ea-source-a { border-left: 2px solid var(--color-accent-400); }
.ea-source-b { border-left: 2px solid var(--color-accent-2-500); }
.ea-source-c { border-left: 2px solid var(--color-neutral-500); }
.ea-merge-lines { width: 100%; height: 26px; display: block; }
.ea-merge-lines path { fill: none; stroke: var(--color-accent-800); stroke-width: 1.3; }
.ea-merge-out {
  align-self: center; margin: 0; padding: 6px 12px; border-radius: 6px;
  background: var(--color-surface); box-shadow: var(--shadow-md);
  border: 1px solid var(--color-accent-700); text-align: center;
}
.ea-merge-out-name { display: block; font-family: var(--font-heading); font-weight: 500; font-size: 12px; }
.ea-merge-out-meta { display: block; font-size: 9.5px; color: var(--color-neutral-500); }

/* Benchmarks */
.ea-bench { display: flex; flex-direction: column; gap: 12px; font-size: 11px; }
.ea-bench-row { margin: 0; display: grid; grid-template-columns: 104px 1fr 40px; gap: 10px; align-items: center; }
.ea-bench-label { color: var(--color-neutral-400); }
.ea-bench-track { position: relative; height: 7px; border-radius: 2px; background: var(--color-neutral-800); display: block; }
.ea-bench-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 2px; background: var(--color-neutral-500); }
.ea-bench-median { position: absolute; top: -3px; width: 2px; height: 13px; background: var(--color-accent-300); }
.ea-bench-value { text-align: right; }

/* Integrations */
.ea-logos { display: flex; gap: 6px; flex-wrap: wrap; font-size: 11.5px; list-style: none; margin: 0; padding: 0; }
.ea-logos li { padding: 4px 10px; border: 1px solid var(--color-neutral-800); border-radius: 6px; color: var(--color-neutral-300); }

/* ------------------------------------------------------ statement band ---
   The one full-bleed saturated field the Nocturne guide allows at page
   scale — the --color-section family, used as presence rather than accent. */

.ea-band {
  margin-top: 64px;
  background:
    radial-gradient(1000px 480px at 78% -30%, color-mix(in srgb, var(--color-section-glow) 75%, transparent), transparent 62%),
    var(--color-section);
}
.ea-band-inner { max-width: var(--ea-max); margin: 0 auto; padding-top: 88px; padding-bottom: 84px; }
.ea-band-title {
  font-size: clamp(36px, 4.6vw, 64px); line-height: 1.06;
  letter-spacing: -0.025em; margin: 0; max-width: 20ch;
}
.ea-stats { display: flex; gap: 20px 56px; flex-wrap: wrap; margin: 44px 0 0; }
/* dt before dd is what the spec wants inside a <dl> <div>; column-reverse
   puts the number back on top without reordering the DOM, so a screen
   reader still hears "Events benchmarked, 412". */
.ea-stat { display: flex; flex-direction: column-reverse; }
.ea-stat-value { margin: 0; margin-inline-start: 0; font-family: var(--font-heading); font-weight: 500; font-size: clamp(30px, 3vw, 42px); line-height: 1.1; }
.ea-stat-label {
  margin: 8px 0 0; font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 64%, transparent);
}

/* ----------------------------------------------------- capability index --- */

.ea-index-section { max-width: var(--ea-max); margin: 0 auto; padding-top: 80px; padding-bottom: 24px; }
.ea-index { list-style: none; margin: 0; padding: 0; }
.ea-index-link {
  display: grid;
  grid-template-columns: 64px minmax(0, 5fr) minmax(0, 6fr) 30px;
  gap: 12px 24px; align-items: baseline;
  padding: 22px 0;
  color: var(--color-text); text-decoration: none;
  background: linear-gradient(to right, transparent, var(--color-neutral-700) 48px, var(--color-neutral-700) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
}
.ea-index-row-last .ea-index-link { background: none; }
.ea-index-link:hover,
.ea-index-link:focus-visible { color: var(--color-accent-200); }
.ea-index-num { font-family: ui-monospace, Menlo, monospace; font-size: 13px; color: var(--color-accent-300); }
.ea-index-name { font-size: 21px; font-family: var(--font-heading); font-weight: 500; letter-spacing: -0.01em; }
.ea-index-desc { font-size: 13.5px; color: var(--color-neutral-400); line-height: 1.6; }
.ea-index-arrow { color: var(--color-accent-300); }

/* --------------------------------------------------------------- quote ---
   `showQuote`, off in the drawing. */

.ea-quote-section { max-width: var(--ea-max); margin: 0 auto; padding-top: 72px; padding-bottom: 88px; }
.ea-quote { margin: 0; }
.ea-quote-text {
  font-family: var(--font-heading); font-weight: 500;
  font-size: clamp(26px, 3.2vw, 42px); line-height: 1.32;
  letter-spacing: -0.015em; max-width: 30ch; margin: 0;
  text-indent: -0.474em;
}
.ea-quote-by {
  font-size: 14.5px; margin: 28px 0 0;
  color: color-mix(in srgb, var(--color-text) 64%, transparent);
  text-indent: -1.267em;
}

/* --------------------------------------------------------------- close --- */

.ea-close {
  border-top: 1px solid color-mix(in srgb, var(--color-divider) 55%, transparent);
  background: radial-gradient(1100px 560px at 50% 120%, color-mix(in srgb, var(--color-accent-900) 70%, transparent), transparent 65%);
}
.ea-close-inner { max-width: var(--ea-max); margin: 0 auto; padding-top: 96px; padding-bottom: 104px; text-align: center; }
.ea-close-title { font-size: clamp(40px, 6vw, 88px); line-height: 1.02; letter-spacing: -0.028em; margin: 0; }
.ea-close-lede {
  margin: 24px auto 0; font-size: 15.5px; line-height: 1.7;
  color: color-mix(in srgb, var(--color-text) 74%, transparent); max-width: 52ch;
}
/* position:relative so the absolutely positioned honeypot below resolves
   against this form rather than against the initial containing block. An
   sr-only cell escaping its container is a bug this page has already been
   bitten by once: it stretched the page to 511px and nothing caught it until
   the width was measured in a browser. */
.ea-demo-form { position: relative; display: flex; gap: 8px; align-items: stretch; max-width: 460px; margin: 30px auto 0; }
.ea-demo-email { flex: 1; }
.ea-demo-submit { min-height: 36px; white-space: nowrap; }
.ea-form-status { margin: 12px 0 0; font-size: 13px; color: var(--color-accent-300); }

/* The honeypot.
 *
 * Off screen, not display:none and not visibility:hidden. Both of those are one
 * property read away for anything more careful than a blind form-filler, and a
 * honeypot a bot can see is a honeypot that catches nothing. Moving it out of
 * the viewport leaves it a real, focusable, fillable field as far as the DOM is
 * concerned.
 *
 * The container carries aria-hidden and the input carries tabindex="-1", so a
 * screen reader never announces it and a keyboard user never lands on it. That
 * pair is what keeps this from being an accessibility trap: the field is
 * invisible to people by every route people actually use, and present by every
 * route a script uses.
 *
 * left:-9999px rather than clip/inset, because the sr-only pattern used
 * elsewhere on this page collapses the box to a pixel, and some form-fillers
 * skip a zero-size input. */
.ea-hp {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* What happens to the address, said once, under the button. The page claims
 * "GDPR-ready" four lines below this; collecting an email with no word about
 * what it is for would make that claim the only mention of the subject. */
/* The one line of onward navigation on /thanks/. A confirmation page that
   only says "thank you" is a dead end; this offers the next thing to read
   without competing with the heading. */
/* Left, like everything else in this block.
   Measured on the live page: .ea-subhero-title and .ea-subhero-lede both
   compute to text-align:start at x=135 and x=140, and this paragraph was
   sitting at x=517 with its own centred text - one stray line in the middle of
   a left-aligned column. `margin: 0 auto` centres the BOX, which is what put
   it there; the first attempt at fixing it centred the TEXT too and made the
   mismatch worse rather than better. */
.ea-thanks-next {
  margin: 18px 0 0;
  max-width: 52ch;
  font-size: 14px;
  color: color-mix(in srgb, var(--color-text) 62%, transparent);
}

/* /thanks/ is a heading and two lines, so on a tall screen the footer used to
   float halfway up with a band of empty ground beneath it. Pushing the shell to
   the viewport height and letting the main column grow parks the footer at the
   bottom where it belongs, without affecting the four long pages, whose content
   already exceeds the viewport. */
.ea-thanks-page .ea-rails { min-height: calc(100vh - var(--ea-header-h, 64px)); display: flex; flex-direction: column; }
.ea-thanks-page .ea-rails > main { flex: 1 0 auto; display: flex; align-items: center; }
.ea-thanks-page .ea-rails > main > .ea-subhero { width: 100%; }
.ea-thanks-next a { color: var(--color-accent-300); }

.ea-form-note {
  margin: 10px 0 0;
  font-size: 12px;
  color: color-mix(in srgb, var(--color-text) 45%, transparent);
}

/* NOT display:none. An aria-live region that is display:none is not in the
   accessibility tree, so it is not registered as a live region before its
   text arrives — and a region created together with its content is not
   reliably announced. It stays rendered and takes no space instead. */
.ea-form-status:empty { margin: 0; height: 0; }
.ea-form-status[data-state='error'] { color: var(--color-neutral-300); }
/* The drawing sets this line to `--color-text` at 45%. Measured on the page,
   that composites to 3.91:1 against the close section's ground — 3.62:1 over
   the lightest part of its radial — and it is 12px body text, so it needs
   4.5:1. It is also the only place the page makes a compliance claim, which is
   exactly the line a buyer scans for. 55% measures 5.19:1 (4.66:1 worst case)
   and still reads as the quiet footnote it is drawn as. */
.ea-trust {
  margin: 22px 0 0; font-size: 12px; letter-spacing: 0.04em;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

/* -------------------------------------------------------------- footer --- */

.ea-footer {
  border-top: 1px solid color-mix(in srgb, var(--color-divider) 55%, transparent);
  background: color-mix(in srgb, black 30%, var(--color-bg));
}
.ea-footer-inner {
  max-width: var(--ea-max); margin: 0 auto;
  padding-top: 26px; padding-bottom: 26px;
  display: flex; align-items: center; gap: 24px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--color-neutral-500);
}
.ea-footer-brand {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-heading); font-weight: 500; font-size: 13.5px;
  color: var(--color-text); text-decoration: none;
}
.ea-footer-brand:hover { color: var(--color-accent); }
.ea-brand-mark-sm { width: 22px; height: 22px; }
.ea-footer-nav { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
.ea-footer-nav a { color: var(--color-neutral-500); text-decoration: none; }
.ea-footer-nav a:hover { color: var(--color-accent-300); }
.ea-social { display: flex; align-items: center; gap: 14px; list-style: none; margin: 0; padding: 0; }
.ea-social a {
  display: grid; place-items: center; width: 28px; height: 28px;
  border-radius: var(--radius-sm); color: var(--color-neutral-500);
}
/* fill:currentColor rather than a token, so hover and focus move the glyph
   with the link instead of needing a second rule per state. */
.ea-social svg { display: block; fill: currentColor; }
.ea-social a:hover { color: var(--color-accent-300); }

/* The footer's "All systems normal" indicator used to sit here carrying
   `margin-left: auto`, which is what pushed the copyright to the right edge.
   It was removed on request, so the push moves onto the copyright itself —
   without this the copyright slides left and sits against the nav links. */
.ea-copyright { margin: 0 0 0 auto; }

/* ==================================================== responsive ========
   The drawing carries exactly two breakpoints, 900px and 640px, expressed as
   `data-mq` tokens. They are reproduced here on the classes that replaced
   those attributes. */

@media (max-width: 900px) {
  .ea-hero-grid { grid-template-columns: 1fr; }
  .ea-bento > * { grid-column: 1 / -1; }
  .ea-index-link { grid-template-columns: 1fr; }
  .ea-index-arrow { display: none; }
  .ea-pad { padding-left: 20px; padding-right: 20px; }
}

/* Below 640px the drawing drops the nav links and puts nothing back. Here they
   fold into the disclosure instead — but ONLY once the disclosure is real.
   
   The first version of this collapsed the menu unconditionally and was worse
   than the drawing: with scripting off, `data-open` is never written and the
   toggle keeps its `hidden` attribute, so the phone got no navigation at all
   and no control to summon any. The comment in index.html claimed the
   opposite. Seven independent review passes found it; none of the four gates
   could, because they read markup and declarations rather than the cascade.

   The fix is the sibling combinator. `.ea-nav-toggle:not([hidden])` matches
   only after landing.js has cleared `hidden`, and the menu is that button's
   next sibling — so the collapse rule cannot apply unless the control that
   reverses it exists. With scripting off the links stack down the page,
   visible, which is the state this file always claimed to ship. */
@media (max-width: 640px) {
  .ea-nav { flex-wrap: wrap; }
  .ea-nav-toggle:not([hidden]) { display: inline-flex; }
  .ea-nav-menu {
    display: flex; flex-basis: 100%; width: 100%;
    flex-direction: column; align-items: flex-start; gap: 4px;
    padding: 12px 0 6px;
  }
  .ea-nav-toggle:not([hidden]) ~ .ea-nav-menu:not([data-open='true']) { display: none; }
  .ea-nav .ea-nav-link { font-size: 13px; padding: 8px 0; }
  .ea-nav .ea-nav-cta { margin-top: 6px; }
  /* The field gets its own row here, so the question keeps every pixel the
     bar can give it before the ellipsis starts. */
  .ea-query-field { flex: 1 1 100%; }
}

/* Not in the drawing. At 320px the drawn close-form leaves the email field
   about 160px wide next to a 110px button, which is not a field anybody can
   read what they typed in. */
@media (max-width: 420px) {
  .ea-demo-form { flex-wrap: wrap; }
  .ea-demo-email { flex: 1 1 100%; }
  .ea-demo-submit { flex: 1 1 100%; }
}

/* =============================================== motion and printing ==== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .ea-ticker-track { animation: none; }
  .ea-skip { transition: none; }
}

/* Printing flips the ground to white, so the palette has to flip with it.
   Retinting the tokens rather than the rules is what makes that work: every
   `color-mix(in srgb, var(--color-text) 76%, transparent)` on the page
   re-resolves against the new ink automatically. Setting only
   `body { color: #000 }` would leave all of them light grey on white. */
@media print {
  :root {
    --color-bg: #fff;
    --color-surface: #fff;
    --color-text: #14141a;
    --color-divider: color-mix(in srgb, #14141a 22%, transparent);
    --color-neutral-100: #14141a; --color-neutral-200: #1e1e26; --color-neutral-300: #2b2b34;
    --color-neutral-400: #3b3b46; --color-neutral-500: #4c4c58; --color-neutral-600: #5d5d6a;
    --color-neutral-700: #9a9aa6; --color-neutral-800: #c8c8d0; --color-neutral-900: #e4e4ea;
    --color-accent: #4b3f8f; --color-accent-100: #2b2741; --color-accent-200: #37315a;
    --color-accent-300: #4b3f8f; --color-accent-800: #ece9fb; --color-accent-900: #f5f4ff;
    --color-section: #ece9fb; --color-section-glow: #ded9f7; --color-section-ghost: #cfc9f2;
    --shadow-sm: 0 0 0 1px #c8c8d0; --shadow-md: 0 0 0 1px #c8c8d0; --shadow-lg: 0 0 0 1px #c8c8d0;
  }
  .ea-header, .ea-ticker, .ea-hero-chart, .ea-rail, .ea-nav-toggle,
  body { background: #fff; }
  .ea-band, .ea-close { background: none; }
  .ea-card { background: none; border-color: #c8c8d0; }
  .ea-index-link[href]::after { content: ' (' attr(href) ')'; font-size: 10px; }
  .ea-hero { min-height: 0; }
}

/* aria-disabled rather than [disabled] on the submit (see landing.js), so the
   button keeps focus while the request is out. The look is Nocturne's own
   .btn:disabled. */
.ea-demo-submit[aria-disabled='true'] { opacity: 0.45; cursor: not-allowed; }

/* ==========================================================================
   PLATFORM / PRICING
   Everything below serves the two inner pages. They share the nav, rails,
   close section and footer above, only their bodies differ. Their drawings are
   not in this repo: design-source/ holds Landing v2 and Hero v3 only, which is
   what README.md records.
   ========================================================================== */

/* -------------------------------------------------- shared inner-page hero */

.ea-subhero { position: relative; overflow: hidden; }
.ea-subhero-inner {
  position: relative; max-width: var(--ea-max); margin: 0 auto;
  padding-top: clamp(56px, 8vw, 110px); padding-bottom: 56px;
}
.ea-subhero-inner-tight { padding-bottom: 48px; }
.ea-tick-sub { top: 26px; }
.ea-subhero-title {
  font-family: var(--font-heading); font-weight: 500;
  font-size: clamp(44px, 7.2vw, 104px); line-height: 0.99;
  letter-spacing: -0.03em; margin: 0 0 0 -0.045em; max-width: 14ch;
}
.ea-subhero-title-wide { max-width: 16ch; }
.ea-subhero-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, 420px);
  gap: 24px 48px; align-items: end; margin-top: 36px;
}
.ea-subhero-lede {
  margin: 0; font-size: 17px; line-height: 1.65; max-width: 52ch;
  color: color-mix(in srgb, var(--color-text) 80%, transparent);
}
.ea-subhero-cta { display: flex; gap: 12px; flex-wrap: wrap; }

.ea-h2-sm {
  font-size: clamp(28px, 3.2vw, 42px); line-height: 1.2;
  letter-spacing: -0.015em; margin: 0 0 14px;
}
.ea-kicker {
  margin: 0 0 8px; font-size: 10px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--color-neutral-500);
}
/* position:relative is load-bearing, not decoration. The sr-only cells inside
   these tables (`<span class="ea-sr">Included</span>`) are position:absolute,
   so they resolve against the nearest POSITIONED ancestor. With none here that
   was .ea-rails, three levels up and outside the scroll container — so on a
   phone each hidden span sat at its static x inside the 640px-wide table,
   escaped the clip, and stretched the document to 511px at every viewport
   below 640. A visually-hidden element was causing a visible horizontal
   scrollbar. Giving the wrapper a positioning context keeps them inside it. */
.ea-tablewrap { overflow-x: auto; position: relative; }
.ea-ta-r { text-align: right; }
.ea-td-quiet { color: var(--color-neutral-400); }
.ea-accent-300 { color: var(--color-accent-300); }

/* ============================================================== PLATFORM = */

/* the product frame */
.ea-frame-section { max-width: var(--ea-max); margin: 0 auto; padding-bottom: 24px; position: relative; }
.ea-frame-glow {
  position: absolute; inset: -40px 10% auto; height: 280px; pointer-events: none;
  background: radial-gradient(60% 100% at 50% 0%, color-mix(in srgb, var(--color-accent-800) 60%, transparent), transparent 70%);
}
.ea-frame {
  position: relative; border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: var(--shadow-md);
  background: color-mix(in srgb, var(--color-surface) 72%, var(--color-bg));
}
.ea-frame-bar {
  display: flex; align-items: center; gap: 16px; padding: 10px 16px;
  border-bottom: 1px solid var(--color-divider); font-size: 13px;
}
.ea-dots { display: inline-flex; gap: 6px; flex: none; }
.ea-dots span { width: 9px; height: 9px; border-radius: 50%; background: var(--color-neutral-700); }
.ea-frame-title {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-heading); font-weight: 500; white-space: nowrap;
}
.ea-frame-tabs {
  display: flex; gap: 16px; margin-left: auto;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.ea-frame-tab-on { color: var(--color-text); box-shadow: 0 14px 0 -12px var(--color-accent); }
.ea-frame-tab-ai { color: var(--color-accent-300); }
.ea-frame-body { padding: 18px 20px 22px; display: flex; flex-direction: column; gap: 14px; }

.ea-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.ea-tile { padding: 12px 14px; border-radius: var(--radius-md); background: var(--color-surface); box-shadow: var(--shadow-sm); }
.ea-tile-label { margin: 0; font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-neutral-500); }
.ea-tile-value { margin: 6px 0 2px; font-size: 22px; font-family: var(--font-heading); font-weight: 500; }
.ea-tile-delta { margin: 0; font-size: 11.5px; color: var(--color-accent-300); }
.ea-tile-flat { margin: 0; font-size: 11.5px; color: var(--color-neutral-400); }

.ea-frame-charts { display: grid; grid-template-columns: 3fr 2fr; gap: 12px; }
.ea-panel { padding: 14px 16px; border-radius: var(--radius-md); background: var(--color-surface); box-shadow: var(--shadow-sm); }
.ea-panel .ea-card-top { margin-bottom: 2px; }
.ea-panel .ea-card-sub { margin: 0 0 10px; }
.ea-panel .ea-pill-accent { white-space: nowrap; }
.ea-area-14 { fill: var(--color-accent-500); opacity: 0.14; }
.ea-line-prev-15 { fill: none; stroke: var(--color-neutral-600); stroke-width: 1.5; stroke-dasharray: 4 5; }
.ea-chart-bars { width: 100%; height: auto; display: block; }
.ea-baseline { stroke: var(--color-neutral-800); stroke-width: 1; }
.ea-b1 { fill: var(--color-accent-400); }
.ea-b2 { fill: var(--color-accent-600); }
.ea-b3 { fill: var(--color-accent-700); }
.ea-b4 { fill: var(--color-accent-800); }
.ea-axis {
  display: flex; justify-content: space-between; margin: 6px 0 0;
  font-size: 9.5px; color: var(--color-neutral-600);
}

.ea-copilot-strip {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 0;
  padding: 11px 14px; border-radius: var(--radius-md);
  border: 1px solid var(--color-accent-800);
  background: color-mix(in srgb, var(--color-accent-900) 35%, transparent);
  font-size: 12.5px;
}
.ea-copilot-strip-text { color: color-mix(in srgb, var(--color-text) 82%, transparent); flex: 1; min-width: 220px; }
.ea-strip-cta { font-size: 12px; white-space: nowrap; }

/* the three two-column bands */
.ea-split {
  max-width: var(--ea-max); margin: 0 auto;
  padding-top: 64px; padding-bottom: 40px;
  display: grid; grid-template-columns: minmax(280px, 5fr) minmax(0, 7fr);
  gap: 28px clamp(24px, 5vw, 88px); align-items: center;
}
.ea-split-flip { grid-template-columns: minmax(0, 7fr) minmax(280px, 5fr); padding-top: 40px; padding-bottom: 40px; }
.ea-split-act { padding-top: 40px; padding-bottom: 56px; }
.ea-split-lede {
  margin: 0; font-size: 15.5px; line-height: 1.7; max-width: 46ch;
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
}
.ea-split-link { margin: 16px 0 0; font-size: 14px; }
.ea-split-link a { text-decoration: none; }

/* the source -> model -> output diagram */
.ea-flow {
  position: relative; width: 600px; max-width: 100%; aspect-ratio: 600 / 340;
  margin-left: auto; overflow: hidden; font-size: clamp(10px, 1.1vw, 16px);
}
.ea-flow-lines { position: absolute; inset: 0; width: 100%; height: 100%; }
.ea-flow-hot { fill: none; stroke: var(--color-accent-500); stroke-width: 1.5; }
.ea-flow-cool { fill: none; stroke: var(--color-accent-800); stroke-width: 1.5; }
.ea-node {
  position: absolute; display: block; border-radius: 6px;
  background: var(--color-surface); box-shadow: var(--shadow-sm);
}
.ea-node-src { left: 0; width: 26.3%; padding: 2.4% 1.8%; border-left: 2px solid var(--color-accent-400); }
.ea-node-alt { border-left-color: var(--color-accent-2-500); }
.ea-node-grey { border-left-color: var(--color-neutral-500); }
.ea-node-s1 { top: 1.8%; }
.ea-node-s2 { top: 25.9%; }
.ea-node-s3 { top: 50%; }
.ea-node-s4 { top: 74.1%; }
.ea-node-model {
  left: 39.2%; top: 42%; width: 23.3%; padding: 2.6% 2%;
  box-shadow: var(--shadow-md); border: 1px solid var(--color-accent-700);
}
.ea-node-out { left: 73.3%; width: 25.3%; padding: 2.4% 1.8%; }
.ea-node-o1 { top: 11.8%; }
.ea-node-o2 { top: 42.6%; }
.ea-node-o3 { top: 73.5%; }
.ea-node-name { display: block; font-size: 0.75em; font-family: var(--font-heading); font-weight: 500; }
.ea-node-name-lg { font-size: 0.78em; margin-top: 2px; }
.ea-node-meta { display: block; margin-top: 3px; font-size: 0.6em; color: var(--color-neutral-500); }
.ea-node-kicker { display: block; font-size: 0.56em; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent-300); }
.ea-node-kicker-grey { color: var(--color-neutral-500); }
.ea-node-out .ea-node-name { margin-top: 2px; }

/* the Copilot card on Platform */
.ea-copilot-card {
  max-width: 560px; width: 100%; border-radius: var(--radius-md);
  background: var(--color-surface); box-shadow: var(--shadow-md); padding: 16px 18px;
}
.ea-copilot-card .ea-copilot-head { padding-bottom: 12px; }
.ea-bubble-lg { font-size: 13px; padding: 8px 12px; max-width: 34ch; }
.ea-copilot-card .ea-bubble-row { margin: 14px 0 12px; }
.ea-copilot-answer-lg { font-size: 13px; line-height: 1.6; color: color-mix(in srgb, var(--color-text) 84%, transparent); }
.ea-copilot-para { margin: 0 0 12px; }
.ea-leadbars-lg { gap: 7px 10px; font-size: 11.5px; }
.ea-leadbars-lg .ea-leadbar-bar { height: 8px; }
.ea-fill-4 { background: var(--color-accent-700); width: 54%; }
.ea-sources-lg { margin: 14px 0 0; padding-top: 0; font-size: 10.5px; }

/* the alert builder and its Slack preview */
.ea-act-cards { display: flex; gap: 16px; flex-wrap: wrap; justify-content: flex-end; }
.ea-alert-builder {
  flex: 1; min-width: 250px; max-width: 300px; border-radius: var(--radius-md);
  background: var(--color-surface); box-shadow: var(--shadow-sm);
  padding: 14px 16px; font-size: 12.5px;
}
.ea-rule-lg { margin: 0 0 14px; gap: 6px; font-size: inherit; }
.ea-token-lg { padding: 5px 9px; border-radius: 6px; }
.ea-notify { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 16px; }
.ea-builder-actions { display: flex; gap: 8px; justify-content: flex-end; margin: 0; }
.ea-sm-btn { font-size: 12px; }
.ea-slack {
  flex: 1; min-width: 260px; max-width: 320px; border-radius: var(--radius-md);
  border: 1px solid var(--color-accent-2-700); padding: 14px 16px; font-size: 12.5px;
  background: color-mix(in srgb, var(--color-bg) 55%, transparent);
}
.ea-slack .ea-kicker { margin-bottom: 10px; }
.ea-slack-head { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; }
.ea-alert-mark-lg { width: 22px; height: 22px; }
.ea-slack-from { font-family: var(--font-heading); font-weight: 500; font-size: 13px; }
.ea-app-tag { font-size: 9px; padding: 1px 6px; }
.ea-slack-time { color: var(--color-neutral-500); font-size: 11px; }
.ea-slack-body { margin: 0 0 10px; line-height: 1.55; color: color-mix(in srgb, var(--color-text) 82%, transparent); }
.ea-slack-link { margin: 0; font-size: 11.5px; }
.ea-slack-link a { color: var(--color-accent-300); text-decoration: none; }
.ea-slack-link a:hover { text-decoration: underline; }

/* purpose-built views */
.ea-views {
  border-top: 1px solid color-mix(in srgb, var(--color-divider) 45%, transparent);
  background:
    radial-gradient(900px 460px at 90% -12%, color-mix(in srgb, var(--color-accent-900) 55%, transparent), transparent 60%),
    color-mix(in srgb, var(--color-surface) 46%, var(--color-bg));
}
.ea-views-inner { max-width: var(--ea-max); margin: 0 auto; padding-top: 72px; padding-bottom: 64px; }
.ea-views-title { margin: 0 0 30px; max-width: 22ch; line-height: 1.15; letter-spacing: -0.018em; }
.ea-views-grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 16px; align-items: start; }
.ea-views-side { display: flex; flex-direction: column; gap: 16px; }
.ea-view-card {
  border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-sm);
  background: color-mix(in srgb, var(--color-surface) 72%, var(--color-bg));
}
.ea-view-head {
  display: flex; align-items: center; gap: 10px; padding: 9px 14px;
  border-bottom: 1px solid var(--color-divider); font-size: 12px;
}
.ea-view-name { font-family: var(--font-heading); font-weight: 500; }
.ea-view-tag { margin-left: auto; }
.ea-view-meta { margin-left: auto; font-size: 10.5px; color: var(--color-neutral-500); }
.ea-view-body { padding: 6px 14px 14px; }
.ea-roi-table { font-size: 12.5px; min-width: 420px; }
.ea-view-foot { margin: 12px 0 0; font-size: 11px; color: var(--color-neutral-500); }
.ea-view-foot a { color: var(--color-accent-300); text-decoration: none; }
.ea-view-foot a:hover { text-decoration: underline; }
.ea-hallgrid {
  padding: 14px; display: grid; grid-template-columns: max-content 1fr;
  gap: 8px 10px; align-items: center; font-size: 9.5px; color: var(--color-neutral-500);
}
.ea-hall-day { white-space: nowrap; }
.ea-heat-wide .ea-cell { aspect-ratio: 1.5 / 1; }
.ea-hall-axis { display: flex; justify-content: space-between; margin: 0; }
.ea-bench-lg { padding: 16px 14px; gap: 13px; font-size: 11.5px; }
.ea-bench-row-lg { grid-template-columns: 110px 1fr 44px; }
.ea-bench-track-lg { height: 8px; }
.ea-bench-median-lg { height: 14px; }

/* integrations */
.ea-integrations { max-width: var(--ea-max); margin: 0 auto; padding-top: 64px; padding-bottom: 56px; }
.ea-int-title { margin: 0 0 30px; }
.ea-int-grid { display: grid; grid-template-columns: 170px 1fr; gap: 18px 28px; align-items: baseline; }
.ea-int-kicker { margin: 0; font-size: 11px; }
.ea-int-list { display: flex; gap: 8px; flex-wrap: wrap; list-style: none; margin: 0; padding: 0; }
.ea-int-list li {
  font-size: 13px; padding: 5px 12px; border: 1px solid var(--color-neutral-800);
  border-radius: 7px; background: color-mix(in srgb, var(--color-surface) 60%, transparent);
  color: var(--color-neutral-300);
}
.ea-trust-wide { margin: 34px 0 0; }

.ea-close-inner-sub { padding-top: 88px; padding-bottom: 96px; }
.ea-close-title-sub { font-size: clamp(32px, 4.6vw, 64px); line-height: 1.05; letter-spacing: -0.025em; }
.ea-close-inner-sub .ea-close-lede { margin-top: 22px; }
.ea-close-inner-sub .ea-demo-form { margin-top: 28px; }

/* =============================================================== PRICING = */


.ea-tiers-section { max-width: var(--ea-max); margin: 0 auto; padding-top: 16px; padding-bottom: 64px; }
.ea-tiers { display: grid; grid-template-columns: repeat(3, 1fr); }
.ea-tier { padding: 30px 34px 34px 0; display: flex; flex-direction: column; }
.ea-tier-mid { padding: 30px 34px; border-left: 1px solid color-mix(in srgb, var(--color-divider) 60%, transparent); }
.ea-tier-last { padding: 30px 0 34px 34px; border-left: 1px solid color-mix(in srgb, var(--color-divider) 60%, transparent); }
.ea-tier-mark { display: block; width: 44px; height: 2px; background: var(--color-neutral-700); margin-bottom: 18px; }
.ea-tier-mark-on { background: var(--color-accent); margin-bottom: 0; }
.ea-tier-markrow { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.ea-tier-name { font-family: var(--font-heading); font-weight: 500; font-size: 17px; margin: 0; letter-spacing: normal; line-height: 1.55; }
/* The single note that stands in for the three prices. Sized like the hero's
   supporting copy rather than like a price, because it is a sentence, not a
   figure. */
.ea-pricing-note {
  margin: 0; font-family: var(--font-heading); font-weight: 500;
  font-size: clamp(20px, 2.2vw, 28px); line-height: 1.25;
  letter-spacing: -0.015em;
}

.ea-tier-blurb { margin: 16px 0 0; font-size: 13.5px; line-height: 1.6; color: color-mix(in srgb, var(--color-text) 66%, transparent); }
.ea-tier-rule {
  height: 1px; margin: 22px 0;
  background: linear-gradient(to right, transparent, var(--color-divider) 24px, var(--color-divider) calc(100% - 24px), transparent);
}
.ea-tier-list {
  display: flex; flex-direction: column; gap: 10px; flex: 1;
  list-style: none; margin: 0; padding: 0;
  font-size: 13.5px; line-height: 1.5; color: color-mix(in srgb, var(--color-text) 78%, transparent);
}
.ea-tier-cta { margin-top: 24px; align-self: flex-start; }


.ea-compare {
  border-top: 1px solid color-mix(in srgb, var(--color-divider) 45%, transparent);
  background: color-mix(in srgb, black 20%, transparent);
}
.ea-compare-inner { max-width: var(--ea-max); margin: 0 auto; padding-top: 64px; padding-bottom: 64px; }
.ea-compare-inner .ea-h2-sm { margin-bottom: 26px; }
.ea-compare-table { min-width: 640px; }
.ea-compare-lead { width: 34%; }
.ea-th-on { color: var(--color-accent-300); }
.ea-compare-table th[scope='row'] { font-weight: 400; text-transform: none; letter-spacing: normal; font-size: 14px; color: inherit; padding: var(--space-2); }
.ea-yes { color: var(--color-accent-300); }
.ea-no { color: var(--color-neutral-600); }

.ea-faq { max-width: var(--ea-max); margin: 0 auto; padding-top: 64px; padding-bottom: 72px; }
.ea-faq-title { margin: 0 0 18px; }
.ea-faq-item {
  padding: 16px 0;
  background: linear-gradient(to right, transparent, var(--color-neutral-700) 48px, var(--color-neutral-700) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
}
.ea-faq-item-last { background: none; }
.ea-faq-q { cursor: pointer; font-family: var(--font-heading); font-weight: 500; font-size: 16px; }
.ea-faq-q:hover { color: var(--color-accent-200); }
.ea-faq-a {
  margin: 12px 0 0; font-size: 14.5px; line-height: 1.7; max-width: 64ch;
  color: color-mix(in srgb, var(--color-text) 74%, transparent);
}

/* ===================================================== responsive, inner = */

@media (max-width: 900px) {
  .ea-subhero-grid { grid-template-columns: 1fr; }
  .ea-tiles { grid-template-columns: repeat(2, 1fr); }
  .ea-frame-charts { grid-template-columns: 1fr; }
  .ea-frame-tabs { display: none; }
  .ea-split, .ea-split-flip { grid-template-columns: 1fr; }
  /* `1fr` is `minmax(auto, 1fr)`, and the auto minimum is min-content — which
     .ea-flow pins at its declared 600px, so the single column stayed 600px wide
     inside a 375px viewport and pushed 245px of the page off-screen. Both lines
     are needed: min-width:0 lets the track shrink, and the width override stops
     the diagram asking for 600 in the first place. */
  .ea-split > *, .ea-split-flip > * { min-width: 0; }
  .ea-flow { width: 100%; }
  /* The Copilot card is drawn first in the flipped band; stacked, the heading
     has to lead or the answer arrives before the question. */
  .ea-split-flip > :last-child { order: -1; }
  .ea-flow { margin-left: 0; }
  .ea-views-grid { grid-template-columns: 1fr; }
  .ea-int-grid { grid-template-columns: 1fr; }
  .ea-tiers { grid-template-columns: 1fr; }
  .ea-tier, .ea-tier-mid, .ea-tier-last {
    border-left: none; padding-left: 0; padding-right: 0;
    border-top: 1px solid var(--color-divider); padding-top: 26px;
  }
  .ea-tiers > :first-child { border-top: none; padding-top: 0; }
}

@media (max-width: 640px) {
  .ea-act-cards { justify-content: flex-start; }
  .ea-alert-builder, .ea-slack { max-width: none; }
}
