/* ============================================================================
   VIDNT marketing site — design system
   © 2014–2026 Vimmi Communications. All rights reserved.

   Structure modelled on the OVHcloud IA study (docs/design/OVH_PATTERN_STUDY.md).
   NO third-party CSS, imagery, copy or icons are reproduced. The three ideas
   taken from that study are architectural, not visual:

     1. one --scale multiplier rescales every size in the system   (§12a)
     2. every surface colour ships bound to its legible foreground (§12b)
     3. brutal constraint: 3 radii, 2 button heights, one spacing scale (§12c)

   Spacing names say DIRECTION, not just size:
     --inset-*  padding inside a box
     --inline-* horizontal rhythm
     --stack-*  vertical rhythm
   ========================================================================= */

/* ---------- 1. tokens ---------------------------------------------------- */

:root {
  /* the single multiplier — change this one value and the whole UI rescales */
  --scale: 1;

  /* size ladder */
  --s-01: calc(0.125rem * var(--scale));   /*  2px */
  --s-02: calc(0.25rem  * var(--scale));   /*  4px */
  --s-03: calc(0.5rem   * var(--scale));   /*  8px */
  --s-04: calc(0.75rem  * var(--scale));   /* 12px */
  --s-05: calc(1rem     * var(--scale));   /* 16px */
  --s-06: calc(1.5rem   * var(--scale));   /* 24px */
  --s-07: calc(2rem     * var(--scale));   /* 32px */
  --s-08: calc(3rem     * var(--scale));   /* 48px */
  --s-09: calc(4rem     * var(--scale));   /* 64px */
  --s-10: calc(6rem     * var(--scale));   /* 96px */

  --inset-sm: var(--s-04);  --inset-md: var(--s-05);  --inset-lg: var(--s-06);
  --inline-sm: var(--s-04); --inline-md: var(--s-05); --inline-lg: var(--s-07);
  --stack-sm: var(--s-05);  --stack-md: var(--s-07);  --stack-lg: var(--s-09);
  --stack-xl: var(--s-10);

  /* exactly three radii */
  --radius-01: 4px;
  --radius-02: 8px;
  --radius-03: 16px;

  /* exactly two button heights */
  --btn-h-md: calc(3.25rem * var(--scale));  /* 52px */
  --btn-h-sm: calc(2.25rem * var(--scale));  /* 36px */

  /* layout */
  --container: 1280px;
  --container-text: 760px;
  --topbar-h: 44px;
  --navbar-h: 56px;

  /* hero slide travel — how long one slide takes to walk across the band.
     JS lowers it for arrow/dot clicks; autoplay keeps the full 4s glide. */
  --hero-travel: 4s;
  --hero-ease: cubic-bezier(.42, 0, .28, 1);

  /* type — VIDNT uses a free stack; no licensed webfont, no CDN request */
  --font: "Source Sans Pro", "Trebuchet MS", arial, "Segoe UI", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Type scale taken from the reference's own marketing stylesheet, by
     frequency of use: 1rem ×13 · .875rem ×10 · 1.25rem ×8 · .75rem ×6 ·
     2rem ×3 · 1.5rem ×3 · 2.25rem ×2 · 1.75rem ×2 · 1.125rem ×1.
     Their LARGEST heading anywhere is 2.25rem (36px) — a flat, small,
     workmanlike scale. Ours topped out at 3.5rem (56px), 55% bigger,
     which is most of why the pages read as different sizes of thing. */
  --fs-display: clamp(1.75rem, 1.4rem + 1.2vw, 2.25rem);  /* their max, 36px */
  --fs-h1: clamp(1.5rem, 1.25rem + 1vw, 2rem);
  --fs-h2: clamp(1.25rem, 1.1rem + .6vw, 1.75rem);
  --fs-h3: 1.5rem;
  --fs-h4: 1.25rem;
  --fs-lead: 1.25rem;
  --fs-body: 1rem;
  --fs-ui: 0.875rem;
  --fs-fine: 0.75rem;

  --lh-tight: 1.15;
  --lh-head: 1.25;
  --lh-body: 1.6;

  /* --- colour: every surface is bound to its legible foreground ---
     Measured from the reference's OWN marketing stylesheet (116 KB,
     132 colour literals). The correction that mattered: their large
     ground areas are BLUE, not neutral. Frequency in their file —
       #0050d7 ×31  primary        #00185e ×13  deep navy ground
       #000e9c ×10  second deep    #4d5592  ×8  muted indigo
       #85d9fd  ×6 / #bef1ff ×4 / #def8ff ×4   light cyan washes
     We previously painted those same regions #1a1a1a and #f2f2f2,
     which is why the page read as black-and-grey next to theirs. */
  /* The logo's own blue, sampled from the supplied asset (#3470f5).
     It gets its own token deliberately: a logo is an asset, and it must
     not shift because someone re-themed the interface. Earlier today the
     wordmark silently became OVH's blue when --brand was swapped — that is
     exactly the failure this prevents. Changing --brand never moves it. */
  --logo-blue:        #3470f5;

  --brand:            #0050d7;   /* their primary — most-used colour, ×31    */
  --brand-on:         #ffffff;
  --brand-ink:        #000e9c;   /* brand on light, for text/links           */
  --brand-wash:       #def8ff;   /* light cyan wash                          */
  --brand-wash-on:    #00185e;

  --ink:              #1a1a1a;
  --ink-2:            #4d4d4d;
  --ink-3:            #666666;

  --canvas:           #ffffff;
  --canvas-on:        var(--ink);
  --raised:           #ffffff;
  --raised-on:        var(--ink);
  --sunken:           #bef1ff;   /* was #f2f2f2 grey — 13.9% of the page     */
  --sunken-on:        #00185e;
  --deep:             #00185e;   /* was #1a1a1a black — 9.9% of the page     */
  --deep-on:          #ffffff;
  --deep-dim:         #bef1ff;
  --deep-2:           #000e9c;   /* second deep blue, for stacked bands      */
  --indigo:           #4d5592;   /* muted indigo, for quieter accents        */

  --line:             #e6e6e6;
  --line-strong:      #cccccc;

  --ok:               #2b8000;   --ok-wash: #e8f6ee;
  --warn:             #ff8b00;   --warn-wash: #fdf3e3;
  --stop:             #bf0020;   --stop-wash: #fdecec;

  /* "not decided yet" marker — see .tbd */
  --tbd-bg-a: #fff6d6; --tbd-bg-b: #ffefba;
  --tbd-line: #b58900; --tbd-ink: #6b5200;

  --shadow-1: 0 1px 2px rgba(14, 20, 36, .06), 0 1px 3px rgba(14, 20, 36, .04);
  --shadow-2: 0 2px 6px rgba(14, 20, 36, .07), 0 8px 24px rgba(14, 20, 36, .07);
  --shadow-3: 0 12px 40px rgba(14, 20, 36, .14);

  --focus: 0 0 0 3px rgba(0, 80, 215, .35);
}

/* SINGLE LIGHT WORLD — deliberate, and it matches the reference.
   ovhcloud.com does not respond to prefers-color-scheme at all: their marketing
   site is white on every machine. We previously shipped a dark override here,
   which meant a visitor whose OS is in dark mode saw a different site from the
   one we designed — and that is exactly what happened on review.
   The console keeps the dark Google-console look; that is a monitoring surface
   and a separate stylesheet. This file is task/marketing, and it is light.
   `only light` also stops the browser force-darkening form controls. */
:root { color-scheme: only light; }

/* ---------- 2. base ------------------------------------------------------ */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important;
    animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--canvas-on);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0; line-height: var(--lh-head); text-wrap: balance;
  color: var(--ink); font-weight: 700; letter-spacing: -0.015em; }
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }
h4 { font-size: var(--fs-h4); letter-spacing: 0; }
p  { margin: 0; }
ul, ol { margin: 0; padding: 0; }
img, svg { max-width: 100%; }
a { color: var(--brand-ink); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible { outline: none; box-shadow: var(--focus); border-radius: var(--radius-01); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: var(--s-05); top: -100px; z-index: 200;
  background: var(--brand); color: var(--brand-on);
  padding: var(--inset-sm) var(--inset-md); border-radius: var(--radius-01);
}
.skip:focus { top: var(--s-05); }

/* ---------- 3. layout primitives ----------------------------------------- */
/* CONTAINER LADDER. The reference does not use one fixed max-width: its
   container steps 100% → 728 → 1088 → 1280 at exactly the three breakpoints
   this file already uses (768 / 1120 / 1600), with a flat 1rem inline pad at
   every size. Ours ran 1280 wide from 768px upward, so the same headline
   wrapped across a line more than theirs and every grid cell was wider.
   --container (1280) is now the TOP step rather than the only one.          */

:root {
  --wrap-max: 100%;
  --wrap-pad: var(--s-05);          /* 16px at every width, as theirs is    */
  --band-gap: calc(3.5rem * var(--scale));   /* 56px between two sections   */
}
@media (min-width: 768px)  { :root { --wrap-max: 728px; } }
@media (min-width: 1120px) { :root { --wrap-max: 1088px; } }
@media (min-width: 1600px) { :root { --wrap-max: var(--container); } }

.wrap { width: 100%; max-width: var(--wrap-max); margin-inline: auto;
  padding-inline: var(--wrap-pad); }

/* VERTICAL RHYTHM. Measured on the reference: consecutive sections are 56px
   apart — full stop — and a section only insets its own content when it
   paints a ground (32px). We were padding every band by 64px top AND bottom,
   so our sections sat 128px apart: twice their rhythm, which is most of why
   the page felt like a different document at the same zoom.                 */
.band { padding-block: 0; }
.band + .band { margin-top: var(--band-gap); }
main > .band:first-child { margin-top: var(--band-gap); }

/* grounds inset their own ink */
.band--tight, .band--sunken, .band--deep, .band--wash, .band--cta {
  padding-block: var(--s-07); }

/* a page whose first band already paints a ground sits flush under the header,
   and the hero always does */
main > .band--hero:first-child,  main > .band--notice:first-child,
main > .band--tight:first-child, main > .band--sunken:first-child,
main > .band--deep:first-child,  .band--notice + .band { margin-top: 0; }
.band--hero { padding-block: 0; }

.band--sunken { background: var(--sunken); color: var(--sunken-on); }
.band--wash   { background: var(--brand-wash); color: var(--brand-wash-on); }
.band--deep { background: var(--deep); color: var(--deep-on); }
.band--deep h1, .band--deep h2, .band--deep h3, .band--deep h4 { color: #fff; }
.band--deep .lead, .band--deep p { color: var(--deep-dim); }

/* LEGIBILITY REPAIR on every blue ground. .eyebrow resolves to --brand-ink
   (#000e9c) and .fine/.link-arrow to dark neutrals: correct on white, and on
   the navy band effectively invisible. The bands already repaired headings
   and paragraphs and missed these three. Found on steer.html; fixed here so
   every page inherits it. */
.band--deep .eyebrow, .band--deep .fine, .band--deep .link-arrow,
.band--cta  .eyebrow, .band--cta  .fine, .band--cta  .link-arrow,
.band--hero .eyebrow, .band--hero .fine, .band--hero .link-arrow { color: var(--deep-dim); }
.band--deep .link-arrow:hover, .band--cta .link-arrow:hover,
.band--hero .link-arrow:hover { color: #fff; }

/* The two blue grounds. On the reference exactly two bands are blue — the one
   at the very top and the one at the very bottom — and both are the same
   left-to-right gradient between their two deep blues. Everything between
   them is white but for a single tinted strip.                              */
.band--hero, .band--cta {
  background: linear-gradient(to right, var(--deep-2), var(--brand));
  color: var(--deep-on);
}
.band--hero h1, .band--hero h2, .band--hero h3, .band--hero h4,
.band--cta  h1, .band--cta  h2, .band--cta  h3, .band--cta  h4 { color: #fff; }
.band--cta .lead, .band--cta p, .band--hero .lead { color: var(--deep-dim); }

/* section header: title, optional standfirst, optional link on the same line.
   24px to whatever follows — the reference's title-to-content gap.          */
.sec-head { margin-bottom: var(--s-06); }
.sec-head--split { display: flex; flex-direction: column; gap: var(--s-04); }
@media (min-width: 768px) {
  .sec-head--split { flex-direction: row; align-items: baseline;
    justify-content: space-between; gap: var(--s-07); }
}
.sec-head--center { text-align: center; margin-inline: auto; }

.stack   { display: flex; flex-direction: column; gap: var(--stack-sm); }
.stack-2 { display: flex; flex-direction: column; gap: var(--s-03); }
.row     { display: flex; flex-wrap: wrap; gap: var(--s-04); align-items: center; }

/* 16px — the reference's column gutter is 2 × 0.5rem */
.grid { display: grid; gap: var(--s-05); grid-template-columns: 1fr; }
@media (min-width: 768px)  { .grid--2 { grid-template-columns: repeat(2, 1fr); }
                             .grid--3 { grid-template-columns: repeat(2, 1fr); }
                             .grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1120px) { .grid--3 { grid-template-columns: repeat(3, 1fr); }
                             .grid--4 { grid-template-columns: repeat(4, 1fr); } }

/* A two-column row that stays stacked past the medium breakpoint and splits
   only at the large one. The system had 1/2/2, 1/2/3 and 1/2/4 but nothing
   that waits: a product-page hero is the one row where copy and art sit on
   top of each other until there is real room. (from steer.html) */
.grid--2lg { grid-template-columns: 1fr; }
@media (min-width: 1120px) {
  .grid--2lg { grid-template-columns: 1.05fr .95fr; gap: var(--s-07); }
}

/* Alternating explainer rows: source order stays copy-then-art, so the
   reading order and the accessibility tree never change — only the desktop
   column flips. (from steer.html) */
@media (min-width: 768px) { .flip-md > :last-child { order: -1; } }

/* A jumped-to section must clear the sticky chrome, or the heading you asked
   for lands underneath the header. (from steer.html) */
main section[id], main article[id] {
  scroll-margin-top: calc(var(--navbar-h) + var(--band-gap));
}
@media (min-width: 1120px) {
  main section[id], main article[id] {
    scroll-margin-top: calc(var(--topbar-h) + var(--navbar-h) + var(--band-gap));
  }
}

.measure { max-width: var(--container-text); }
.lead { font-size: var(--fs-lead); color: var(--ink-2); }
.fine { font-size: var(--fs-fine); color: var(--ink-3); }
.center { text-align: center; margin-inline: auto; }

.eyebrow {
  font-size: var(--fs-fine); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--brand-ink);
}

/* ---------- 4. buttons --------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-03); height: var(--btn-h-md);
  padding-inline: var(--inline-lg);
  border-radius: var(--radius-02); border: 2px solid transparent;
  /* their label is 14px/600 inside a 52px button — a small word in a large
     target, which is why their buttons read as calm rather than shouty */
  font: inherit; font-weight: 600; font-size: var(--fs-ui);
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background-color .15s, border-color .15s, color .15s, transform .05s;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn--sm { height: var(--btn-h-sm); padding-inline: var(--inline-md);
  font-size: var(--fs-ui); }
.btn--block { width: 100%; }

.btn--primary { background: var(--brand); color: var(--brand-on); }
.btn--primary:hover { background: var(--brand-ink); }

.btn--secondary { background: transparent; color: var(--brand-ink);
  border-color: var(--line-strong); }
.btn--secondary:hover { border-color: var(--brand); background: var(--brand-wash); }

.btn--ghost { background: transparent; color: var(--ink); }
.btn--ghost:hover { background: var(--sunken); }

/* On a blue ground the filled button inverts: white box, blue label. The
   reference does this on both of its blue bands, and it is the only way a
   filled button stays a button when the band behind it is already the brand
   colour. */
.band--deep .btn--secondary, .band--hero .btn--secondary, .band--cta .btn--secondary {
  color: #fff; border-color: rgba(255,255,255,.35); background: transparent; }
.band--deep .btn--secondary:hover, .band--hero .btn--secondary:hover,
.band--cta .btn--secondary:hover { border-color: #fff; background: rgba(255,255,255,.10); }
.band--deep .btn--primary, .band--hero .btn--primary, .band--cta .btn--primary {
  background: #fff; color: var(--brand); }
.band--deep .btn--primary:hover, .band--hero .btn--primary:hover,
.band--cta .btn--primary:hover { background: var(--brand-wash); color: var(--brand-ink); }

.link-arrow { display: inline-flex; align-items: center; gap: var(--s-02);
  font-weight: 650; color: var(--brand-ink); }
.link-arrow .ico { transition: transform .15s; }
.link-arrow:hover .ico { transform: translateX(3px); }

/* OVH pattern (Amnon 2026-08-18): the call to action inside a card is a solid
   blue button, not a text link. Applies to every card CTA site-wide; the
   `.spacer` rule already pins it to the bottom of the card. */
.card .link-arrow, .kpi-item .link-arrow {
  background: var(--brand); color: #fff; font-weight: 700;
  padding: 11px 20px; border-radius: 8px; text-decoration: none;
  align-self: flex-start; width: auto;
  transition: background .18s ease, transform .18s ease, box-shadow .18s ease;
}
.card .link-arrow:hover, .kpi-item .link-arrow:hover {
  background: #003ea8; transform: translateY(-1px);
  box-shadow: 0 8px 18px -8px rgba(0,24,94,.55); color: #fff;
}
/* the card tints blue on hover — keep the button readable on it */
.card:hover .link-arrow { background: var(--brand); color: #fff; }
.card .link-arrow.spacer { margin-top: auto; }
/* the arrow glyph rides inside the button */
.card .link-arrow .ico { width: .9em; height: .9em; }

/* ---------- 5. icons ----------------------------------------------------- */
/* Original VIDNT icon set — drawn for this site, sprite in assets/icons.svg  */

.ico { width: 1.25em; height: 1.25em; flex: none; display: inline-block;
  vertical-align: -0.2em; fill: none; stroke: currentColor; stroke-width: 1.75;
  stroke-linecap: round; stroke-linejoin: round; }
.ico--lg { width: 2rem; height: 2rem; stroke-width: 1.5; }
.ico--xl { width: 2.5rem; height: 2.5rem; stroke-width: 1.4; }
.ico-tile {
  width: calc(3rem * var(--scale)); height: calc(3rem * var(--scale));
  display: grid; place-items: center; border-radius: var(--radius-02);
  background: var(--brand-wash); color: var(--brand-wash-on); flex: none;
}

/* ---------- 6. header: topbar + product navbar --------------------------- */

.site-header { position: sticky; top: 0; z-index: 50; background: var(--raised);
  border-bottom: 1px solid var(--line); }

.topbar { height: var(--topbar-h); display: none; align-items: center;
  background: var(--deep-2); border-bottom: none;
  font-size: var(--fs-ui); }
@media (min-width: 1120px) { .topbar { display: flex; } }
.topbar .wrap { display: flex; align-items: center; justify-content: flex-end;
  gap: var(--inline-md); }
.topbar a { color: rgba(255,255,255,.85); font-weight: 500; }
.topbar a:hover { color: #fff; }

.navbar { height: var(--navbar-h); display: flex; align-items: center;
  gap: var(--inline-md); }
.navbar .wrap { display: flex; align-items: center; gap: var(--inline-md);
  width: 100%; }

/* wordmark: "vid" ink + "NT" brand */
/* The wordmark is a two-part lockup: the name, and what the name stands for.
   The tagline used to be hidden below 1600px, which meant almost nobody ever
   saw it — on a phone, on a laptop, on most desktops, "VIDNT" arrived with no
   explanation at all. For a name nobody knows yet, that is the one thing you
   cannot afford to hide. It is now always rendered: stacked under the name on
   narrow screens, inline beside it once there is room. */
.wordmark { display: inline-grid; grid-template-columns: auto;
  align-content: center; gap: 0; row-gap: 1px;
  color: var(--ink); text-decoration: none; flex: none; line-height: 1; }
.wordmark .mark { font-weight: 800; font-size: 1.25rem;
  letter-spacing: -.03em; line-height: 1.05; }
.wordmark b { color: var(--logo-blue); font-weight: 800; }
.wordmark:hover { text-decoration: none; }
.wordmark small { font-size: .5rem; font-weight: 600; letter-spacing: .07em;
  color: var(--ink-3); text-transform: uppercase; white-space: nowrap;
  line-height: 1.1; }

/* once the navbar has room, the tagline sits beside the name on one line */
@media (min-width: 1120px) {
  .wordmark { grid-template-columns: auto auto; align-items: baseline;
    column-gap: var(--s-03); }
  .wordmark .mark { font-size: 1.375rem; }
  .wordmark small { font-size: .5625rem; }
}

.nav-toggle { display: inline-grid; place-items: center; width: 40px; height: 40px;
  margin-left: auto; border: 1px solid var(--line-strong); background: transparent;
  border-radius: var(--radius-01); color: var(--ink); cursor: pointer; }
@media (min-width: 1120px) { .nav-toggle { display: none; } }

.nav-actions { display: none; margin-left: auto; gap: var(--s-04);
  align-items: center; }
@media (min-width: 1120px) { .nav-actions { display: flex; } }

/* --- level 1: product tabs. Each tab is a REAL link (study §1) --- */
.nav-tabs { display: none; list-style: none; height: 100%; }
@media (min-width: 1120px) { .nav-tabs { display: flex; align-items: stretch; } }
.nav-tabs > li { display: flex; }
.nav-tabs > li > a {
  display: flex; align-items: center; padding-inline: 28px;
  font-size: 17px; font-weight: 600; color: var(--brand);
  letter-spacing: .002em;
  border-bottom: 3px solid transparent;
}
/* OVH-style thin vertical separator between menu items */
.nav-tabs > li + li::before { content: ""; width: 1px; height: 22px;
  background: var(--line-strong, #c9d2e0); align-self: center; }
.nav-tabs > li > a:hover,
.nav-tabs > li[data-open] > a { color: var(--brand-ink);
  border-bottom-color: var(--brand); text-decoration: none; }

/* --- the mega panel --- */
.mega {
  position: absolute; left: 0; right: 0; top: 100%;
  background: var(--raised); border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-2); padding-block: var(--stack-md);
  display: none;
}
.nav-tabs > li[data-open] .mega { display: block; }
/* Amnon 2026-08-18, against the OVHcloud reference he sent: the panel is a
   full-width white sheet; columns are separated by hairlines rather than by
   space alone; the group heading is a SMALL UPPERCASE GREY label, the item
   itself is blue and large, and the description under it is dark grey at
   reading size. The previous build had all three in near-black at one
   weight, which is why it read as a list instead of a menu. */
.mega .wrap { display: grid; gap: 0;
  grid-template-columns: repeat(3, 1fr); align-items: start; }
.mega-col { padding-inline: var(--s-07); }
.mega-col:first-child { padding-left: 0; }
.mega-col + .mega-col { border-left: 1px solid var(--line); }
.mega-col > h4 { display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-04); font-size: 13px; font-weight: 700; line-height: 1.2;
  text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3);
  border-bottom: 0; padding-bottom: 0; margin-bottom: var(--s-05); }
.mega-col > h4 .link-arrow { font-size: 13px; font-weight: 600;
  text-transform: none; letter-spacing: 0; color: var(--brand); }
.mega-list { list-style: none; display: flex; flex-direction: column;
  gap: var(--s-05); }
.mega-list a { display: block; color: var(--brand); font-weight: 600;
  font-size: 17px; line-height: 1.25; }
.mega-list a:hover { color: var(--brand-ink); text-decoration: underline; }
.mega-list .desc { display: block; font-size: 15px; font-weight: 400;
  color: var(--ink-2); margin-top: 4px; line-height: 1.45;
  text-decoration: none; }
.mega-list a:hover .desc { text-decoration: none; }

/* use-case chips — entry by problem, not by product (study §1) */
.mega-chips { grid-column: 1 / -1; border-top: 1px solid var(--line);
  padding-top: var(--s-05); display: flex; flex-wrap: wrap;
  gap: var(--s-03); align-items: center; }
.mega-chips .label { font-size: var(--fs-fine); font-weight: 700;
  text-transform: uppercase; letter-spacing: .07em; color: var(--ink-3);
  margin-right: var(--s-03); }
.chip { display: inline-flex; align-items: center; gap: var(--s-02);
  padding: var(--s-02) var(--s-04); border: 1px solid var(--line-strong);
  border-radius: 999px; font-size: var(--fs-ui); color: var(--ink); }
.chip:hover { border-color: var(--brand); background: var(--brand-wash);
  color: var(--brand-wash-on); text-decoration: none; }

/* --- mobile drawer: same tree, drill-down (study §1 / §8) --- */
.drawer { position: fixed; inset: 0; z-index: 100; background: var(--canvas);
  display: none; flex-direction: column; overflow-y: auto; }
.drawer[data-open] { display: flex; }
@media (min-width: 1120px) { .drawer { display: none !important; } }
.drawer-head { position: sticky; top: 0; background: var(--raised);
  border-bottom: 1px solid var(--line); display: flex; align-items: center;
  gap: var(--s-04); padding: var(--inset-sm) var(--inline-md); height: var(--navbar-h); }
.drawer-close { margin-left: auto; width: 40px; height: 40px; display: grid;
  place-items: center; border: 1px solid var(--line-strong); background: transparent;
  border-radius: var(--radius-01); color: var(--ink); cursor: pointer; }
.drawer-body { padding: var(--inset-md) var(--inline-md) var(--stack-lg); }
.drawer-panel { display: none; }
.drawer-panel[data-active] { display: block; }
.drawer-item { display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-04); width: 100%; padding: var(--inset-sm) 0;
  border: 0; border-bottom: 1px solid var(--line); background: transparent;
  font: inherit; font-weight: 650; font-size: var(--fs-h4); color: var(--ink);
  text-align: left; cursor: pointer; }
.drawer-item:hover { color: var(--brand-ink); text-decoration: none; }
.drawer-back { display: inline-flex; align-items: center; gap: var(--s-03);
  padding: var(--inset-sm) 0; border: 0; background: transparent; font: inherit;
  font-weight: 650; color: var(--brand-ink); cursor: pointer; }

/* ---------- 7. hero slider ------------------------------------------------ */
/* Declarative contract, same idea as the study §2 — behaviour configured on
   the markup, not hard-coded in JS:
     data-slider  data-slider-viewport  data-slider-slide
     data-slider-autoplay="7000"  data-slider-loop  data-slider-pager="dot"
   Unlike the reference, our headings live in the HTML, so the hero survives
   with JavaScript disabled.                                                 */

/* Correction to an earlier reading of the reference: the page IS predominantly
   white, but the hero is not one of the white parts. Measured on the live
   mirror, the hero band is a full-bleed left-to-right gradient between their
   two deep blues, 574px tall at 1512, and the closing CTA is the same
   gradient. Ground colour therefore does the same job on both pages: it marks
   the beginning and the end, and nothing in between. */
.hero { position: relative; overflow: hidden; }
.hero-viewport { position: relative; overflow: hidden; display: grid;
  grid-template-columns: minmax(0, 100%); }
/* The reference imposes NO height on a slide — `.odss-slider__slide` carries
   only `min-width:100%`, and the band is exactly as tall as its content.
   Ours was 1,108 px per slide (a screen and a half), so the viewport showed
   the pager and then one enormous slide, which reads as "the slider is gone". */
.hero-slide { display: grid; visibility: hidden; grid-area: 1 / 1;
  min-width: 0; padding-block: var(--s-05); align-content: stretch; }
/* Amnon 2026-08-18: the two CTAs must land on the SAME pixel on every slide.
   They could not: `.wrap` was only as tall as its own copy, so the column had
   no free space and the `margin-top: auto` that pins the button row resolved
   to 0. The slide is a grid now and the wrap fills it, which gives the column
   real free space — the row is then pushed to a constant bottom edge, and the
   buttons sit at the same height on all six. */
.hero-slide > .wrap { min-height: 100%; }
/* Amnon 2026-08-18: the change of slide has to be a TRAVEL you can watch, not
   a cut. Both slides are on screen for the whole transition — the outgoing one
   walks out to the left while the incoming one walks in from the right, and
   because they sit in the same grid cell the two translations tile exactly:
   at any moment the leaving slide's right edge IS the entering slide's left
   edge, so it reads as one strip sliding past. 4s on autoplay (his number);
   a person who clicks an arrow gets the same motion, faster. */
.hero-slide[data-active], .hero-slide[data-leaving] { visibility: visible; }
.hero-slide[data-leaving] { pointer-events: none; }
/* Amnon 2026-08-18: the FIRST slide must already be there when the page
   opens — nobody should watch it arrive. The travel is therefore gated on
   data-moved, which the slider sets the first time it actually changes
   slide; until then slide 1 simply is where it belongs. */
.hero-viewport[data-moved] .hero-slide[data-active]  {
  animation: hero-in  var(--hero-travel, 4s) var(--hero-ease) both; }
.hero-viewport[data-moved] .hero-slide[data-leaving] {
  animation: hero-out var(--hero-travel, 4s) var(--hero-ease) both; }
.hero-viewport[data-moved][data-dir="back"] .hero-slide[data-active]  { animation-name: hero-in-back; }
.hero-viewport[data-moved][data-dir="back"] .hero-slide[data-leaving] { animation-name: hero-out-back; }
@keyframes hero-in    { from { transform: translateX(100%) }  to { transform: none } }
@keyframes hero-out   { from { transform: none } to { transform: translateX(-100%) } }
@keyframes hero-in-back  { from { transform: translateX(-100%) } to { transform: none } }
@keyframes hero-out-back { from { transform: none } to { transform: translateX(100%) } }
@keyframes fade { from { opacity: 0 } to { opacity: 1 } }
@media (prefers-reduced-motion: reduce) {
  .hero-viewport[data-moved] .hero-slide[data-active] { animation: fade .4s ease both; }
  .hero-slide[data-leaving] { visibility: hidden; animation: none; } }
/* Their slide splits into two equal halves from 768 up — copy on one side,
   art on the other — and stacks below it. Not 1.05/.95: dead equal.        */
.hero-slide .wrap { display: grid; gap: var(--s-06); align-items: center;
  grid-template-columns: minmax(0, 1fr); }
@media (min-width: 768px) {
  /* Amnon 2026-08-18: the headline was being squeezed into half the band.
     The copy column takes the larger share; the art still has plenty. */
  .hero-slide .wrap { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); }
}
@media (min-width: 1180px) {
  /* Amnon 2026-08-18: shorten the band without shrinking the headline — a
     wider copy column turns the four-line headlines into three. */
  .hero-slide .wrap { grid-template-columns: minmax(0, 1.32fr) minmax(0, .68fr); }
}
/* Amnon 2026-08-18: the CTA buttons must sit in the SAME spot on every
   slide. Base spacing lives here (inline margins removed from the HTML);
   in the two-column layout the copy column stretches to the slide's full
   height and the last row is pushed to the bottom. Mobile keeps flow. */
.hero-slide .stack > .row { margin-top: var(--s-04); }
@media (min-width: 768px) {
  .hero-slide .wrap { align-items: stretch; }
  .hero-slide .wrap > .stack { justify-content: flex-start; }
  .hero-slide .wrap > .slot,
  .hero-slide .wrap > [class*="slot"] { align-self: center; }
  .hero-slide .stack > .row:last-child { margin-top: auto; padding-top: var(--s-04); }
}
/* The reference imposes no height on a slide and pads it modestly — its whole
   hero band, pager included, is 574px at 1512. Ours was 48px top and bottom
   plus a 16px control strip, which pushed the band past 600 and cost the
   second section its foothold at the bottom of the first screen. */
/* Slide 1 is the opening statement: the headline and the three facts carry it,
   at a size you can read across a room (Amnon 2026-08-18). */
.hero-slide[data-active] .hero-points--lead li {
  font-size: clamp(17px, 1.55vw, 23px); line-height: 1.45;
  padding-block: 6px; font-weight: 500; }
.hero-slide[data-active] .hero-points--lead .ico { width: 1.15em; height: 1.15em; }
.hero-slide[data-active] .hero-points--lead { gap: var(--s-03); margin-top: var(--s-05); }
/* Amnon 2026-08-18: the opening sentence is the slide. Big on every one of
   them — this is the second, larger pass; the first was still too timid. */
/* Each line of a hero headline is its own block, so the break lands where the
   copy says it should and never inside a hyphenated word (Amnon 2026-08-18).
   NB: `.hero h1` further down sets --fs-display at the same specificity and
   would win on source order, so these carry the extra `.hero` to outrank it. */
/* Each line is its own block so the break lands where the copy says. It is
   NOT nowrap: a line longer than the column has to wrap rather than ride out
   over the artwork next to it (Amnon 2026-08-18 — slide 4 was doing exactly
   that). The hyphens inside the words are non-breaking, so a word still
   never splits. */
.hero .hero-slide h1 span { display: block; text-wrap: balance;
  max-width: 100%; }
.hero .hero-slide h1 { font-size: clamp(32px, 4.6vw, 66px);
  letter-spacing: -.035em; line-height: 1.04; overflow-wrap: normal; }
@media (min-width: 1120px) {
  .hero .hero-slide h1 { font-size: clamp(44px, 4.6vw, 66px); }
}
/* and the line under it stays deliberately quiet */
.hero .hero-slide .hero-sub { color: var(--deep-dim); font-weight: 500;
  font-size: clamp(14px, 1.05vw, 17px); line-height: 1.5;
  max-width: 46ch; margin-top: var(--s-04); }

@media (min-width: 1120px) { .hero-slide { padding-block: var(--s-07); } }
.hero h1 { color: #fff; font-size: var(--fs-display); letter-spacing: -.03em; }
.hero .lead { color: var(--deep-dim); font-size: var(--fs-lead); }
.hero .eyebrow { color: var(--sunken); }
/* Amnon 2026-08-18: the three points run on as ONE line instead of stacking
   three deep — the band was paying three rows for what reads fine as a
   sentence, and the slider had to come down in height. */
.hero-points { list-style: none; display: flex; flex-direction: row;
  flex-wrap: wrap; align-items: center; column-gap: var(--s-05);
  row-gap: var(--s-03); color: var(--deep-dim); margin-top: var(--s-05); }
.hero-points li { display: inline-flex; gap: var(--s-02); align-items: center;
  color: var(--deep-dim); font-size: var(--fs-fine); }
.hero-points .ico { color: var(--sunken); margin-top: 0; flex: none; }
/* the art slot sits on a blue ground here, so it cannot use the light hatch */
.hero .slot { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.30);
  color: var(--deep-dim); }
/* A .slot is a PLACEHOLDER: hatched fill + dashed border say "art goes here".
   Once a real asset is inside it (Amnon's numbered drop, 2026-08-18), the
   placeholder dressing must go — otherwise transparent line art reads as a
   striped box floating on the page. */
.slot:has(.img-live), .slot:has(> img) {
  background: none; border: 0; padding: 0; min-height: 0;
}

.hero .slot b { color: #fff; }

.hero-controls { display: flex; align-items: center; justify-content: center;
  gap: var(--s-03); padding-block: var(--s-03) var(--s-05); }
/* Pager colours, measured from the reference's slider component:
     dot            padding:6px · #85d9fd · border-radius:50%
     progress track #b3b3b3 · height:4px · radius:2px · max-width:270px
     progress fill  #0050d7
   Ours used neutral grey for the dot, which is why the control strip read
   as monochrome next to theirs. */
.hero-dots { display: flex; gap: var(--s-03); list-style: none; }
.hero-dot { width: 12px; height: 12px; padding: 0; border-radius: 50%;
  border: 0; background: #85d9fd; cursor: pointer;
  transition: background-color .6s ease-in-out, width .3s ease; }
.hero-dot[aria-current="true"] { background: var(--brand); width: 28px;
  border-radius: 999px; }
.hero-prog { position: relative; background: #b3b3b3; height: 4px;
  border-radius: 2px; max-width: 270px; width: calc(100% - 40px);
  margin-inline: auto; overflow: hidden; }
.hero-prog__bar { position: absolute; inset: 0 0 0 auto; width: 100%;
  background: var(--brand); }
.hero-pause { width: 32px; height: 32px; display: grid; place-items: center;
  border: 1px solid rgba(255,255,255,.45); background: transparent; color: #fff;
  border-radius: 999px; cursor: pointer; }
.hero-arrows { position: absolute; left: 0; right: 0; top: 50%;
  transform: translateY(-50%); display: flex; justify-content: space-between;
  padding-inline: 10px; pointer-events: none; z-index: 4; }
.hero-arrow { pointer-events: auto; width: 40px; height: 40px; display: grid;
  place-items: center; border: 1px solid rgba(255,255,255,.45);
  background: rgba(8,22,64,.28); color: #fff;
  border-radius: 999px; cursor: pointer; }
@media (max-width: 760px) { .hero-arrow { width: 34px; height: 34px; }
  .hero-arrows { padding-inline: 6px; } }
.hero-arrow:hover, .hero-pause:hover { border-color: #fff; color: var(--brand);
  background: #fff; }

/* ---------- 8. cards ------------------------------------------------------ */
/* Their card, measured off the live page: 8px radius, 16px padding, a 1px
   #ccc hairline, white fill, NO shadow. Ours was 16px radius / 24px padding /
   a much fainter #e6e6e6 line, which made every card read as bigger and
   softer than the same card on their grid. 16px is also the gap between two
   cards, so a card's inner padding and the gutter beside it are one value. */

.card { background: var(--raised); color: var(--raised-on);
  border: 1px solid var(--line-strong); border-radius: var(--radius-02);
  padding: var(--inset-md); display: flex; flex-direction: column;
  gap: var(--s-04); }
.card--link { transition: border-color .15s, box-shadow .15s, transform .15s; }
.card--link:hover { border-color: var(--brand); box-shadow: var(--shadow-2);
  transform: translateY(-2px); text-decoration: none; }
.card--flat { border-radius: var(--radius-02); padding: var(--inset-md); }
/* the one large box on the page — the reference keeps a single wide, rounded,
   tinted container for its mid-page block, and that is what the 16px radius
   is for */
.card--box { background: var(--brand-wash); color: var(--brand-wash-on);
  border-color: transparent; border-radius: var(--radius-03);
  padding: var(--s-07) var(--inset-lg); gap: var(--s-06); }
@media (min-width: 768px) { .card--box { padding: var(--s-08) var(--s-07); } }
.card--box p { color: var(--brand-wash-on); }
.card h3, .card h4 { margin: 0; }
.card p { color: var(--ink-2); }
.card .spacer { margin-top: auto; }
/* four across, a card is 250-ish px wide: the card title drops one step so a
   three-word heading does not become three lines */
.grid--4 .card h3 { font-size: var(--fs-h4); }

/* A tinted card edge — the reference's tile hairline is a light cyan, not a
   neutral grey. It is how blue reaches the white parts of the page without
   becoming a ground. (from steer.html) */
.card--tint { border-color: var(--sunken); }
.card--tint.card--link:hover { border-color: var(--brand); }

/* Checklist inside a card: title, description, checklist, then the call to
   action pinned to the bottom edge. (from steer.html) */
.checklist { list-style: none; display: flex; flex-direction: column;
  gap: var(--s-03); font-size: var(--fs-ui); color: var(--ink-2); }
.checklist li { display: flex; gap: var(--s-03); align-items: flex-start; }
.checklist .ico { color: var(--brand); margin-top: .15em; }

/* ---------- 8b. the full-bleed card rail ---------------------------------- */
/* One band on the reference ignores the container entirely and runs a row of
   equal cards from edge to edge, inset only by the width of its arrows. Below
   the widest breakpoint the row scrolls sideways one card at a time. Ours is
   the same geometry without a line of JavaScript: scroll-snap does it, and at
   1120 and up the three cards simply fit and nothing scrolls.               */

.rail { display: flex; gap: var(--s-05); overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; padding-inline: var(--wrap-pad);
  padding-block: var(--s-02); scrollbar-width: thin; }
.rail > * { flex: 0 0 min(400px, 82%); scroll-snap-align: start; }
@media (min-width: 768px) {
  .rail { padding-inline: var(--s-07); }
  .rail > * { flex-basis: min(400px, 46%); }
}
@media (min-width: 1120px) {
  /* 64px of gutter each side is what their arrows occupy; past 1408px of
     content the rail stops growing so the cards never become billboards */
  .rail { overflow-x: visible; scroll-snap-type: none;
    padding-inline: max(var(--s-09), calc((100% - 1408px) / 2)); }
  .rail > * { flex: 1 1 0; min-width: 0; }
}

/* a card is a flex column, so an inline-flex child still stretches to the full
   width unless it is told not to — a badge that spans the card reads as a bar */
.card > .badge { align-self: flex-start; }
.badge { display: inline-flex; align-items: center; gap: var(--s-02);
  padding: 2px var(--s-03); border-radius: var(--radius-01);
  font-size: var(--fs-fine); font-weight: 700; letter-spacing: .02em; }
.badge--new  { background: var(--brand-wash); color: var(--brand-wash-on); }
.badge--ok   { background: var(--ok-wash);   color: var(--ok); }
.badge--warn { background: var(--warn-wash); color: var(--warn); }
.badge--soon { background: var(--sunken); color: var(--ink-3);
  border: 1px solid var(--line); }

/* ---------- 9. image slots ------------------------------------------------ */
/* Deliberate placeholders at real dimensions. Every one is labelled with what
   belongs there and at what size, so the art brief writes itself.            */

.slot {
  display: grid; place-items: center; text-align: center;
  background: repeating-linear-gradient(45deg,
      var(--sunken), var(--sunken) 10px,
      color-mix(in srgb, var(--sunken) 92%, var(--ink)) 10px,
      color-mix(in srgb, var(--sunken) 92%, var(--ink)) 20px);
  border: 1px dashed var(--line-strong); border-radius: var(--radius-03);
  color: var(--ink-3); font-size: var(--fs-fine); font-family: var(--mono);
  padding: var(--inset-md); min-height: 160px;
}
.slot b { display: block; color: var(--ink-2); font-family: var(--font);
  font-size: var(--fs-ui); margin-bottom: 2px; }
.slot--hero { min-height: 300px; }
.slot--wide { min-height: 220px; }
.slot--sq { aspect-ratio: 1; min-height: 0; }

/* ---------- 10. stepper (read-only map, hidden on mobile — study §5) ------ */

.stepper { display: none; list-style: none; gap: var(--s-03);
  align-items: center; padding-block: var(--stack-sm); }
@media (min-width: 768px) { .stepper { display: flex; } }
.stepper li { display: flex; align-items: center; gap: var(--s-03);
  color: var(--ink-3); font-size: var(--fs-ui); font-weight: 650; }
.stepper li::after { content: ""; width: 40px; height: 1px;
  background: var(--line-strong); margin-inline: var(--s-03); }
.stepper li:last-child::after { display: none; }
.stepper .n { width: 28px; height: 28px; display: grid; place-items: center;
  border-radius: 999px; border: 2px solid var(--line-strong);
  font-size: var(--fs-fine); }
.stepper li[aria-current="step"] { color: var(--brand-ink); }
.stepper li[aria-current="step"] .n { border-color: var(--brand);
  background: var(--brand); color: var(--brand-on); }
.stepper li[data-done] { color: var(--ink-2); }
.stepper li[data-done] .n { border-color: var(--ok); color: var(--ok); }
/* mobile substitute: just say where you are */
.step-mobile { font-size: var(--fs-ui); font-weight: 650; color: var(--ink-3);
  padding-block: var(--stack-sm); }
@media (min-width: 768px) { .step-mobile { display: none; } }

/* ---------- 11. forms ----------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: var(--s-02); }
.field > label { font-size: var(--fs-ui); font-weight: 650; color: var(--ink); }
.field .hint { font-size: var(--fs-fine); color: var(--ink-3); }
.input, .select, .textarea {
  width: 100%; height: var(--btn-h-md); padding-inline: var(--inset-md);
  font: inherit; font-size: var(--fs-body); color: var(--ink);
  background: var(--raised); border: 1px solid var(--line-strong);
  border-radius: var(--radius-02);
}
.textarea { height: auto; padding-block: var(--inset-sm); min-height: 120px; }
.input:focus, .select:focus, .textarea:focus { border-color: var(--brand);
  box-shadow: var(--focus); outline: none; }
.input-group { display: flex; gap: var(--s-03); flex-wrap: wrap; }
.input-group .input { flex: 1 1 260px; }

/* ---------- 12. tables + summary ------------------------------------------ */

.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.t { width: 100%; border-collapse: collapse; font-size: var(--fs-ui);
  min-width: 560px; }
table.t th, table.t td { text-align: left; padding: var(--inset-sm) var(--inset-md);
  border-bottom: 1px solid var(--line); vertical-align: top; }
table.t th { font-weight: 700; color: var(--ink); background: var(--sunken); }
table.t td.num { text-align: right; font-variant-numeric: tabular-nums; }

.summary { border: 1px solid var(--line); border-radius: var(--radius-03);
  background: var(--raised); overflow: hidden; }
.summary-row { display: flex; justify-content: space-between; gap: var(--s-05);
  padding: var(--inset-md) var(--inset-lg); border-bottom: 1px solid var(--line); }
.summary-row:last-child { border-bottom: 0; }
.summary-row.total { background: var(--sunken); font-weight: 700;
  font-size: var(--fs-h4); }
.summary-row .num { font-variant-numeric: tabular-nums; }

/* ---------- 13. notices --------------------------------------------------- */

.notice { display: flex; gap: var(--s-04); padding: var(--inset-md);
  border-radius: var(--radius-02); border: 1px solid var(--line);
  background: var(--sunken); color: var(--ink-2);
  /* Amnon 2026-08-18: at --fs-ui this was too small to read. */
  font-size: clamp(17px, 1.25vw, 21px); line-height: 1.5; }
.notice .ico { flex: none; margin-top: .15em; width: 1.35em; height: 1.35em; }
.notice--info { background: var(--brand-wash); border-color: transparent;
  color: var(--brand-wash-on); }
.notice--warn { background: var(--warn-wash); border-color: transparent;
  color: var(--warn); }
.notice--ok { background: var(--ok-wash); border-color: transparent; color: var(--ok); }
.notice strong { color: inherit; }

/* The hatched PLACEHOLDER marker is gone for production (Amnon 2026-08-19).
   The three remaining spans carry real copy now, so they read as ordinary
   text rather than as something unfinished. */
.tbd { font-weight: 650; }

/* ---------- 13b. page-level blocks used by the home skeleton -------------- */

/* The thin line above the hero. On the reference it is the first thing inside
   the page body: one row, container width, ~52px tall, no ground of its own —
   a place to say one current thing without spending a section on it.        */
.strip { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-04);
  padding-block: var(--s-04); font-size: var(--fs-ui); color: var(--ink-2); }
.strip .msg { flex: 1 1 200px; min-width: 0; }
.strip .tag { display: inline-flex; align-items: center; padding: 2px var(--s-03);
  border-radius: var(--radius-01); background: var(--brand-wash);
  color: var(--brand-wash-on); font-size: var(--fs-fine); font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; }
/* the link only jumps to the far end once there is a far end to jump to;
   below 768 it stays in the flow so the strip does not become three lines */
@media (min-width: 768px) { .strip .link-arrow { margin-left: auto; } }

/* Long-form. Their last white band before the closing CTA is a single column
   of running text at three quarters of the container — no cards, no grid. It
   is where the page stops selling and starts explaining.                    */
.prose { max-width: var(--container-text); }
.prose h3 { margin-top: var(--s-06); font-size: var(--fs-h4); }
.prose p  { margin-top: var(--s-03); color: var(--ink-2); }
.prose > :first-child { margin-top: 0; }

/* The tinted strip. Exactly one band between the two blue ones carries a
   ground on the reference — a low, centred, full-width row. Ours carries the
   standards instead of customer logos, but it is the same band.             */
.strip-items { display: grid; gap: var(--s-05); grid-template-columns: 1fr;
  text-align: center; }
@media (min-width: 768px)  { .strip-items { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1120px) { .strip-items { grid-template-columns: repeat(4, 1fr); } }
.strip-items p { color: inherit; opacity: .85; }

/* closing CTA: title on one side, buttons on the other, one row from 768 up */
.cta-row { display: flex; flex-direction: column; gap: var(--s-06); }
@media (min-width: 768px) {
  .cta-row { flex-direction: row; align-items: center;
    justify-content: space-between; gap: var(--s-07); }
  .cta-row .row { flex: none; }
}

/* ---------- 13c. in-page anchor nav + disclosure (from steer.html) -------- */

/* Sticky strip directly under the sticky site header. Below the medium
   breakpoint the pills scroll inside their own box, so the PAGE never scrolls
   sideways. Sits under the header's z-index so the mega-menu opens over it. */
.subnav { position: sticky; top: var(--navbar-h); z-index: 40;
  padding-block: var(--s-03); background: var(--raised);
  border-bottom: 1px solid var(--line); }
@media (min-width: 1120px) {
  .subnav { top: calc(var(--topbar-h) + var(--navbar-h)); }
}
.subnav-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none; }
.subnav-scroll::-webkit-scrollbar { display: none; }
.subnav-list { list-style: none; display: flex; align-items: center;
  gap: var(--s-02); width: max-content; min-width: 100%; }
.subnav-list a { display: inline-flex; align-items: center;
  height: var(--btn-h-sm); padding-inline: var(--inline-md);
  border-radius: 999px; font-size: var(--fs-ui); font-weight: 650;
  color: var(--ink-2); white-space: nowrap; }
.subnav-list a:hover, .subnav-list a:focus-visible {
  background: var(--brand-wash); color: var(--brand-wash-on);
  text-decoration: none; }

/* Disclosure accordion — native <details>, no script. */
.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary { display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-05); padding-block: var(--inset-md); cursor: pointer;
  font-size: var(--fs-h4); font-weight: 650; color: var(--ink);
  list-style: none; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::marker { content: ""; }
.faq summary:hover { color: var(--brand-ink); }
.faq summary .ico { color: var(--brand); transition: transform .15s; }
.faq details[open] summary .ico { transform: rotate(180deg); }
.faq .faq-body { padding-bottom: var(--inset-md); color: var(--ink-2); }

/* ---------- 14. footer ---------------------------------------------------- */

.site-footer { background: var(--deep); color: var(--deep-dim);
  padding-block: var(--stack-lg) var(--stack-md); font-size: var(--fs-ui); }
.site-footer .grid { gap: var(--s-06); }
.site-footer h4 { color: #fff; font-size: var(--fs-ui); text-transform: uppercase;
  letter-spacing: .07em; margin-bottom: var(--s-04); }
.site-footer a { color: var(--deep-dim); }
.site-footer a:hover { color: #fff; }
.site-footer ul { list-style: none; display: flex; flex-direction: column;
  gap: var(--s-03); }
.footer-bottom { margin-top: var(--stack-md); padding-top: var(--s-05);
  border-top: 1px solid rgba(255,255,255,.12); display: flex; flex-wrap: wrap;
  gap: var(--s-04); align-items: center; justify-content: space-between;
  font-size: var(--fs-fine); }

/* ---------- 15. funnel components ----------------------------------------
   Folded in from the per-page <style data-collect="funnel"> blocks on
   pricing / order / signup / check, which had grown four near-identical
   copies of the same five components. Nothing here introduces a colour, a
   type size, a fourth radius, a second pair of button heights or a fourth
   breakpoint: it is all existing tokens, promoted to one place so the funnel
   cannot drift page to page.                                                */

/* a divider inside a card, the same hairline the menu columns draw */
.rule { border: 0; border-top: 1px solid var(--line); margin: 0; }

/* tick lists */
.ticks { list-style: none; display: flex; flex-direction: column; gap: var(--s-04); }
.ticks li { display: flex; gap: var(--s-04); align-items: flex-start; }
.ticks .ico { flex: none; margin-top: .15em; color: var(--brand); }
.ticks--muted .ico { color: var(--ink-3); }
.band--deep .ticks .ico { color: var(--deep-dim); }
.band--deep .fine a { color: #fff; text-decoration: underline; }

/* label / value rows — used by plan cards and by the order summary */
.plan-specs { list-style: none; display: flex; flex-direction: column; }
.spec { display: flex; flex-wrap: wrap; justify-content: space-between;
  gap: var(--s-03); padding-block: var(--s-03);
  border-bottom: 1px solid var(--line); font-size: var(--fs-ui); }
.spec:last-child { border-bottom: 0; }
.spec-k { color: var(--ink-2); }
.spec-v { font-weight: 700; color: var(--ink); text-align: right; }

/* the funnel's two-column shape: wide column carries the thing, narrow column
   carries the total and the one action, and sticks while the wide one
   scrolls. Stacked below 1120 with the summary FIRST — what you are about to
   do outranks the detail of it. Order and signup share it so the page does
   not change shape underneath the visitor. */
.ocols { display: grid; gap: var(--s-06); grid-template-columns: 1fr;
  grid-template-areas: "rail" "main"; }
.orail { grid-area: rail; }
.omain { grid-area: main; }
@media (min-width: 1120px) {
  .ocols { grid-template-columns: minmax(0, 1fr) 340px; gap: var(--s-07);
    grid-template-areas: "main rail"; align-items: start; }
  .orail { position: sticky;
    top: calc(var(--topbar-h) + var(--navbar-h) + var(--s-04)); }
}
.ocard-head { display: flex; flex-wrap: wrap; align-items: flex-start;
  justify-content: space-between; gap: var(--s-04); }
.ocard-title { font-size: var(--fs-h3); }

/* sticky anchor rail beside priced content (pricing page) */
.pcols { display: grid; gap: var(--s-06); grid-template-columns: 1fr; }
.prail-title { font-size: var(--fs-fine); font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: var(--s-03); }
.prail-list { list-style: none; display: flex; flex-wrap: wrap;
  gap: var(--s-02) var(--s-05); }
.prail-list a { display: inline-block; padding-block: var(--s-02);
  font-size: var(--fs-ui); font-weight: 650; color: var(--ink-2); }
.prail-list a:hover { color: var(--brand-ink); text-decoration: none; }
.prail-list a[aria-current] { color: var(--brand-ink); }
.prail-cta { display: none; }
@media (min-width: 1120px) {
  .pcols { grid-template-columns: 220px minmax(0, 1fr); gap: var(--s-07);
    align-items: start; }
  .prail { position: sticky;
    top: calc(var(--topbar-h) + var(--navbar-h) + var(--s-04)); }
  .prail-list { flex-direction: column; flex-wrap: nowrap; gap: 0;
    border-left: 2px solid var(--line-strong); }
  .prail-list a { margin-left: -2px; padding: var(--s-03) var(--s-04);
    border-left: 2px solid transparent; }
  .prail-list a[aria-current] { border-left-color: var(--brand); }
  .prail-cta { display: inline-flex; margin-top: var(--s-05); }
}

/* billing-term control */
.termbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-04); }
.termbar-label { font-size: var(--fs-ui); font-weight: 700; }
.seg { display: inline-flex; gap: var(--s-02); padding: var(--s-02);
  background: var(--raised); border: 1px solid var(--line-strong);
  border-radius: var(--radius-02); }
.seg .btn { border-color: transparent; }
.seg .btn[aria-pressed="true"] { background: var(--brand); color: var(--brand-on);
  border-color: var(--brand); }
.termbar-note { flex-basis: 100%; }
@media (min-width: 768px) { .termbar-note { flex-basis: auto; } }

/* plan card: a flag row that holds its height with or without a badge, the
   title, the price with its action directly beneath, a rule, then rows. The
   action sits high on purpose — it does not hunt the bottom of a ragged list. */
.plan { gap: var(--s-04); }
.plan--lead { border-color: var(--brand); box-shadow: var(--shadow-2); }
.plan-flag { min-height: 22px; display: flex; align-items: flex-start; }
.plan-head { gap: var(--s-02); }
.plan-title { font-size: var(--fs-h4); }
@media (min-width: 1120px) {
  .plan-title { min-height: calc(2 * var(--lh-head) * var(--fs-h4)); }
}
.price { display: flex; flex-direction: column; gap: var(--s-03); }
.price-line { display: flex; flex-wrap: wrap; align-items: baseline;
  gap: var(--s-02); font-weight: 700; }
.price-line[hidden] { display: none; }   /* a class beats the UA [hidden] rule */
.price-pre, .price-suf { font-size: var(--fs-ui); font-weight: 650;
  color: var(--ink-3); }
.price-val { font-size: var(--fs-body); }   /* every price line one line tall */
.price-ref { font-size: var(--fs-fine); color: var(--ink-3); }
.plan-foot { margin-top: auto; }

/* comparison table: one column per plan, body grouped by full-width category
   rows, every other row label + one value per plan */
.matrix { min-width: 680px; }
.matrix th[scope="col"] { vertical-align: top; }
.matrix .matrix-rowhead { width: 40%; }
.matrix-plan  { display: block; font-size: var(--fs-body); }
.matrix-price { display: block; font-weight: 400; margin-block: var(--s-02); }
.matrix-cta   { font-size: var(--fs-fine); }
.matrix th[scope="row"] { background: transparent; font-weight: 400;
  color: var(--ink-2); }
.matrix tr.cat td { background: var(--brand-wash); color: var(--brand-wash-on);
  font-weight: 700; font-size: var(--fs-fine); letter-spacing: .07em;
  text-transform: uppercase; }
.matrix .mark { font-weight: 650; }
.matrix .mark--no { color: var(--ink-3); font-weight: 400; }

/* form card (signup) */
.fcard { gap: var(--s-05); }
.legend { font-size: var(--fs-fine); font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-3); }
.check { display: flex; gap: var(--s-03); align-items: flex-start; cursor: pointer; }
.check input { flex: none; width: 18px; height: 18px; margin-top: .15em;
  accent-color: var(--brand); }
.fcard .btn:disabled { opacity: .55; cursor: not-allowed; }
.fcard .btn:disabled:active { transform: none; }

/* grouped card rows + numbered close (check) */
.group { display: flex; flex-direction: column; gap: var(--s-05); }
.group-title { font-size: var(--fs-h4); color: var(--ink-2);
  padding-bottom: var(--s-03); border-bottom: 1px solid var(--line); }
.steps { list-style: none; display: grid; gap: var(--s-05);
  grid-template-columns: 1fr; }
@media (min-width: 768px) {
  /* Amnon 2026-08-19: 1-2-3 is a sequence, so draw the sequence. The arrow
     sits in the gutter between cards and the last step does not get one. */
  .steps { grid-template-columns: repeat(3, 1fr); gap: var(--s-08); }
  .steps li { position: relative; }
  .steps li:not(:last-child)::after {
    content: ""; position: absolute; top: 16px; right: calc(var(--s-08) * -1 + 6px);
    width: 30px; height: 3px; background: var(--brand); border-radius: 2px; }
  .steps li:not(:last-child)::before {
    content: ""; position: absolute; top: 10px; right: calc(var(--s-08) * -1 + 2px);
    border-left: 10px solid var(--brand);
    border-top: 6px solid transparent; border-bottom: 6px solid transparent; z-index: 1; }
}
.steps li { display: flex; gap: var(--s-04); align-items: flex-start; }
.steps-n { flex: none; width: 32px; height: 32px; display: grid;
  place-items: center; border-radius: 999px; background: var(--brand);
  color: var(--brand-on); font-size: var(--fs-ui); font-weight: 700; }
.steps h4 { margin-bottom: var(--s-02); }

/* One disclosure component, two markups. steer.html puts a chevron <svg>
   inside the summary; pricing.html has no icon and wants a +/– marker. Rather
   than ship two .faq components, the marker is drawn only when there is no
   icon to rotate. */
.faq summary::after { content: "+"; font-size: 1.5rem; line-height: 1;
  font-weight: 400; color: var(--brand-ink); }
.faq details[open] summary::after { content: "–"; }
.faq summary:has(.ico)::after { content: none; }
.faq details > p { max-width: var(--container-text); color: var(--ink-2);
  padding-bottom: var(--inset-md); }

/* ---------- 16. review mode (?ids=1) -------------------------------------- */
/* Off by default and invisible to real visitors. Turned on with ?ids=1 (or the
   floating toggle), it paints every element's permanent id on screen so a
   change request can name the exact box: "H-04.2 — make this two columns".
   Ids come from _number.py; the catalogue is docs/VIDNT_SITE_ELEMENT_MAP.md. */

.idbadge {
  position: absolute; z-index: 90; top: 0; left: 0;
  font: 700 11px/1.4 var(--mono);
  padding: 2px 6px; border-radius: 0 0 var(--radius-01) 0;
  cursor: pointer; user-select: all; white-space: nowrap;
  pointer-events: auto;
}
.idbadge--block  { background: #d92d6b; color: #fff; }
.idbadge--object { background: #fff; color: #7a1339; border: 1px solid #d92d6b;
                   border-top: 0; border-left: 0; font-weight: 600; }
.idbadge:hover { filter: brightness(1.12); }
.idbadge.copied::after { content: " ✓ copied"; }

body.ids-on [data-id] { outline: 1px dashed rgba(217, 45, 107, .55);
                        outline-offset: -1px; }
body.ids-on [data-id]:hover { outline-color: #d92d6b; outline-width: 2px; }

.idtoggle {
  position: fixed; right: 12px; bottom: 12px; z-index: 120;
  display: inline-flex; align-items: center; gap: 6px;
  height: var(--btn-h-sm); padding: 0 var(--inset-md);
  border: 1px solid var(--line-strong); border-radius: 999px;
  background: var(--raised); color: var(--ink-2); box-shadow: var(--shadow-2);
  font: 600 var(--fs-fine)/1 var(--font); cursor: pointer;
}
.idtoggle:hover { border-color: #d92d6b; color: #d92d6b; }
body.ids-on .idtoggle { background: #d92d6b; border-color: #d92d6b; color: #fff; }
@media print { .idbadge, .idtoggle { display: none !important; } }

/* ---------- 16. comparison pages ---------------------------------------- */
/* A quoted competitor claim must LOOK like a quotation and never like our own
   copy. The rule down the side and the different ground do that work; the
   source line under it is what makes the claim checkable rather than asserted.
   On a page that compares us to a named company, that distinction is the
   difference between a fair comparison and a misrepresentation. */

.card blockquote {
  margin: var(--s-04) 0;
  padding: var(--s-04) var(--s-05);
  border-left: 3px solid var(--brand);
  background: var(--canvas);
  border-radius: 0 var(--radius-01) var(--radius-01) 0;
  font-size: var(--fs-body);
  color: var(--ink-2);
  quotes: none;
}
.card blockquote p { margin: 0; }
.card blockquote + p { margin-top: var(--s-05); }

/* the vendor column is tinted so the eye never confuses their words for ours */
.card--tint blockquote { background: var(--raised); }

/* ---------- 17. comparison pages — claim ↔ answer pairs ------------------ */
/* WHY THIS SECTION EXISTS: a vs-<vendor> page has to hold two things next to
   each other — one block of the vendor's own published words, and our answer
   to that exact block — and the reader must never lose which answer belongs
   to which claim. A two-column grid alone cannot carry that: the moment the
   columns stack on a phone, "left" and "right" stop meaning anything. So the
   pairing is carried THREE ways at once, and any one of them is enough:
     1. a topic number printed on BOTH blocks, in text
     2. a drawn connector pointing from our answer at the block it answers
     3. source order — the claim is always before the answer in the DOM, so
        the stacked reading order and the screen-reader order are both right
   Nothing here introduces a token, a breakpoint, a radius or a button height. */

.vs-flow  { display: flex; flex-direction: column; gap: var(--stack-md); }
.vs-topic { display: flex; flex-direction: column; gap: var(--s-05); }

/* THE PAIR. Source order is claim-then-answer. At 1120 the answer is MOVED to
   column 1 by the grid rather than reordered in the markup, so the layout
   flips and the reading order does not. */
.pair { display: grid; grid-template-columns: 1fr; gap: var(--s-06); }
@media (min-width: 1120px) {
  .pair { grid-template-columns: 1fr 1fr; column-gap: var(--s-08);
          align-items: start; }
  .pair-them { grid-column: 2; grid-row: 1; }
  .pair-us   { grid-column: 1; grid-row: 1; }
}
/* our answer is the bordered frame — brand edge, so it never reads as a quote */
.pair-us { position: relative; border-color: var(--brand); }

/* THE CONNECTOR — a line and an arrowhead drawn in the GAP between the two
   blocks, never outside the container, so it cannot widen the page at any
   width. Stacked, it is a short vertical mark pointing UP at the claim
   directly above. Side by side, it is a rule crossing the gutter and
   pointing RIGHT at the claim beside it. */
.pair-us::before, .pair-us::after { content: ""; position: absolute; }
.pair-us::before { left: var(--s-06); top: calc(-1 * var(--s-06));
  width: 2px; height: var(--s-06); background: var(--brand); }
.pair-us::after  { left: calc(var(--s-06) - 3px); top: calc(-1 * var(--s-06));
  width: 0; height: 0; border-left: 4px solid transparent;
  border-right: 4px solid transparent; border-bottom: 6px solid var(--brand); }
@media (min-width: 1120px) {
  .pair-us::before { left: auto; right: calc(-1 * var(--s-08));
    top: var(--s-07); width: var(--s-08); height: 2px; }
  .pair-us::after  { left: auto; right: calc(-1 * var(--s-08));
    top: calc(var(--s-07) - 4px);
    border-left: 6px solid var(--brand); border-right: 0;
    border-top: 4px solid transparent; border-bottom: 4px solid transparent; }
}

/* the label row that carries the topic number on both halves of a pair */
.pair-tag { display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s-03); font-size: var(--fs-fine); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.pair-tag .badge { text-transform: none; letter-spacing: .02em; }

/* the source line: what makes a quoted claim checkable rather than asserted.
   Pinned to the bottom edge so it reads as provenance, not as body copy. */
.pair-src { margin-top: auto; padding-top: var(--s-04);
  border-top: 1px solid var(--line); font-size: var(--fs-fine);
  color: var(--ink-3); }
.pair-src a { overflow-wrap: anywhere; }   /* a long URL must never widen the page */

/* a label read off a diagram is neither their prose nor ours — it is a string
   in an image, and it is set in the mono face so it cannot be mistaken for
   either. Deliberately wrappable: nowrap here would overflow a 390px phone. */
.vs-label { font-family: var(--mono); font-size: var(--fs-fine);
  background: var(--sunken); color: var(--sunken-on);
  padding: 1px var(--s-02); border-radius: var(--radius-01);
  overflow-wrap: anywhere; }
.vs-labels { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s-02); }

/* "here is what we do NOT know" — the block that keeps the page honest, and
   the only thing on it that is neither a quotation nor a demonstrable claim */
.vs-note { border: 1px solid var(--line-strong);
  border-left: 3px solid var(--warn);
  border-radius: 0 var(--radius-01) var(--radius-01) 0;
  padding: var(--s-04) var(--s-05); font-size: var(--fs-ui); color: var(--ink-2); }
.vs-note b { color: var(--ink); }

/* The scannable summary: seven rows of argument in four columns, wide enough
   that no cell becomes a word ladder, scrolling inside .table-scroll so the
   PAGE never scrolls sideways.
   Written as `table.vs-table`, not `.vs-table`, on purpose: the base rule is
   `table.t { min-width: 560px }` (0,0,1,1), so a bare class selector (0,0,1,0)
   loses to it whatever the source order — the override silently does nothing. */
table.vs-table { min-width: 820px; }
table.vs-table th:first-child, table.vs-table td:first-child { width: 18%; }
table.vs-table caption { text-align: left; padding-bottom: var(--s-04); }


/* per-slide hero tints (Amnon 2026-08-18): each slide a slightly different,
   slightly lighter blue — lighter toward the right — so the rotation is
   visible. :has() fallback = the base gradient, which is slide 1's. */
.band--hero:has(.hero-slide:nth-of-type(2)[data-active]) {
  background: linear-gradient(100deg, #08339c, #1a63e8 72%, #2b74f0); }
.band--hero:has(.hero-slide:nth-of-type(3)[data-active]) {
  background: linear-gradient(100deg, #0a3fb4, #2e79f2 72%, #4189f7); }
.band--hero:has(.hero-slide:nth-of-type(4)[data-active]) {
  background: linear-gradient(100deg, #0c4ccc, #4189f7 72%, #5f9dfa); }

/* Amnon 2026-08-18: "only the content moves — the whole slide has to come in
   from the side". So each slide paints its OWN full-width ground and travels
   as one panel, copy and colour together. The two panels tile edge to edge
   during the move, and the leading edge casts a shadow onto the one it is
   pushing out, which is what makes it read as a physical slide. */
.hero-slide { background: linear-gradient(to right, var(--deep-2), var(--brand));
  box-shadow: -26px 0 44px -22px rgba(0, 6, 40, .55); }
.hero-slide:nth-of-type(2) {
  background: linear-gradient(100deg, #08339c, #1a63e8 72%, #2b74f0); }
.hero-slide:nth-of-type(3) {
  background: linear-gradient(100deg, #0a3fb4, #2e79f2 72%, #4189f7); }
.hero-slide:nth-of-type(4) {
  background: linear-gradient(100deg, #0c4ccc, #4189f7 72%, #5f9dfa); }


/* ── site-wide hover interactions (Amnon 2026-08-18): light-blue tint +
      slight movement on anything interactive ─────────────────────────── */
a, .btn, .vtab, .chip, .drawer-item, .mega-list a {
  transition: color .15s ease, background-color .15s ease,
              border-color .15s ease, box-shadow .18s ease,
              transform .18s ease; }
.nav-tabs > li > a:hover { background: #eaf3ff; }
.mega-list a:hover, .drawer-item:hover, .mega-chips .chip:hover {
  background: #eaf3ff; border-radius: 8px; }
.btn:hover { transform: translateY(-1px); }
.btn--primary:hover { box-shadow: 0 6px 16px rgba(0,80,215,.28); }
.vtab:hover:not([aria-selected="true"]) { background: #d9ebff;
  border-color: #7fb3ff; transform: translateY(-1px); }
.site-footer a:hover { color: #9cc9ff; }
.topbar a, .nav-tabs > li > a, .site-footer a { text-decoration: none; }
@media (prefers-reduced-motion: reduce) {
  a, .btn, .vtab, .card, .chip, .drawer-item, .mega-list a {
    transition: none; }
  .btn:hover, .card:hover, .vtab:hover:not([aria-selected="true"]) {
    transform: none; }
}


/* ── interactive card grid: scroll-in reveal + hover lift (Amnon spec,
      2026-08-18; light-blue accent per his correction, not "warmer") ──── */
main .card, main .kpi-item {
  /* Amnon 2026-08-18: the resting outline on every card is BLUE and it has to
     read as blue at a glance — the first pass was so pale it looked grey.
     Rest is a clear mid blue; hover goes to the brand blue. */
  border-color: #7fb3ff; border-width: 1.5px;
  transition: transform 300ms cubic-bezier(.22,1,.36,1),
              box-shadow 250ms ease, background-color 250ms ease,
              border-color 250ms ease, opacity 500ms cubic-bezier(.22,1,.36,1);
  will-change: transform;
}
main .card:hover, main .kpi-item:hover { border-color: var(--brand); }
/* the same soft-blue outline on the other interactive blocks */
.vtab, .vpanel, .mig-chip, .drawer-item, details.faq, .slot {
  border-color: #7fb3ff; }
.vtab:hover, .vpanel:hover, .drawer-item:hover, details.faq:hover {
  border-color: var(--brand); }
/* hidden until scrolled into view — only when the JS hook is present */
.js-anim main .card:not(.is-visible),
.js-anim main .kpi-item:not(.is-visible) { opacity: 0; transform: translateY(14px); }
/* Amnon 2026-08-18: only a card that actually goes somewhere behaves like a
   button — hand cursor, lift, full tint. A card that is just information
   gets a whisper of colour on hover and nothing else, so the page stops
   promising clicks it cannot honour. "Clickable" = the card IS a link, or
   it carries one (a link, a button, or something wired to the modal). */
main a.card:hover,
main .card:has(a[href]):hover,
main .card:has(button):hover,
main .card:has([data-axm-open]):hover,
main .kpi-item:has(a[href]):hover {
  transform: translateY(-5px) scale(1.02);
  background: #d9ebff; border-color: var(--brand);
  box-shadow: 0 18px 40px -16px rgba(0,0,0,.25);
}
main .card:not(a):not(:has(a[href])):not(:has(button)):not(:has([data-axm-open])):hover,
main .kpi-item:not(:has(a[href])):hover {
  transform: none; box-shadow: none;
  background: var(--brand-wash, #eef4ff); border-color: #9ac6ff;
}
@media (prefers-reduced-motion: reduce) {
  main .card, main .kpi-item {
    transition: background-color 200ms ease, border-color 200ms ease,
                box-shadow 200ms ease; }
  .js-anim main .card:not(.is-visible),
  .js-anim main .kpi-item:not(.is-visible) { opacity: 1; transform: none; }
  .card:hover { transform: none; }
}


/* the hand is reserved for things that really are pressable (Amnon
   2026-08-18) — a card only earns it when it is, or contains, a link. */
a, button, .btn, .vtab, .chip, .drawer-item,
.mega-list a, summary, .hero-arrow, .hero-pause, .hero-dots li {
  cursor: pointer; }
a.card, .card:has(a[href]), .card:has(button), .card:has([data-axm-open]),
.kpi-item:has(a[href]) { cursor: pointer; }
.card:not(a):not(:has(a[href])):not(:has(button)):not(:has([data-axm-open])),
.kpi-item:not(:has(a[href])) { cursor: default; }


/* ═══════════ phone layout corrections (Amnon 2026-08-18) ═══════════════════
   Three things he called out on the phone: the burger sat on the right with
   the wordmark shoved left, the hero slide was so tall the pager and pause
   button were off-screen, and the footer ran as one endless column. */

@media (max-width: 1119px) {
  /* burger hard left, wordmark dead centre. The nav tabs and actions are
     display:none at this width, so they claim no grid cell. */
  .navbar .wrap { display: grid; grid-template-columns: 40px 1fr 40px;
    align-items: center; }
  .nav-toggle { grid-column: 1; grid-row: 1; margin-left: 0; justify-self: start; }
  .wordmark   { grid-column: 2; grid-row: 1; justify-self: center;
    text-align: center; justify-items: center; }
}

@media (max-width: 767px) {
  /* On a phone the slide is the headline and the picture. Nothing else:
     Amnon 2026-08-18 — "don't show the three sentences and the two buttons
     at all on mobile". The CTAs live in the bottom tab bar instead. */
  .hero-slide .hero-points,
  .hero-slide .stack > .row { display: none; }
  .hero-slide { padding-block: var(--s-05) var(--s-04); }
  .hero-slide .wrap { gap: var(--s-04); }
  .hero-slide h1,
  .hero-slide:first-of-type h1 { font-size: clamp(27px, 7.6vw, 36px);
    letter-spacing: -.03em; }
  .hero-slide .lead { font-size: 1rem; }
  .hero-slide[data-active] .hero-points--lead li,
  .hero-slide .hero-points li { font-size: 15px; line-height: 1.4;
    padding-block: 2px; }
  .hero-slide[data-active] .hero-points--lead { gap: var(--s-02);
    margin-top: var(--s-04); }
  .hero-slide .hero-points { gap: var(--s-02); margin-top: var(--s-04); }
  .hero-slide .stack > .row { margin-top: var(--s-04); }
  .hero-slide .slot, .hero-slide .slot--hero { min-height: 0; }
  .hero-slide .slot img, .hero-slide .slot svg,
  .hero-slide figure img, .hero-slide figure svg {
    max-height: 26vh; width: auto; max-width: 100%; margin-inline: auto; }
  .hero-controls { padding-block: var(--s-02) var(--s-04); }

  /* footer: two columns, not one long scroll */
  .site-footer .grid { grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-05) var(--s-05); }
  .site-footer .grid > * { min-width: 0; }
  .footer-bottom { justify-content: flex-start; }
}

/* ═══════════ phone tab bar ════════════════════════════════════════════════
   Fixed to the bottom of the window on phones, the way an app does it, so
   the four destinations people actually want are always one thumb away
   (Amnon 2026-08-18). Hidden once the real navbar has room. */
.tabbar { display: none; }
@media (max-width: 1119px) {
  .tabbar { position: fixed; inset: auto 0 0 0; z-index: 60;
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
    background: var(--raised); border-top: 1px solid var(--line);
    box-shadow: 0 -6px 20px -12px rgba(0,24,94,.45);
    padding-bottom: env(safe-area-inset-bottom, 0px); }
  .tabbar-item { display: grid; justify-items: center; gap: 3px;
    padding: 9px 4px 10px; font-size: 11px; font-weight: 650;
    letter-spacing: .01em; color: var(--ink-2); text-decoration: none;
    line-height: 1.1; }
  .tabbar-item .ico { width: 21px; height: 21px; }
  .tabbar-item:hover, .tabbar-item[aria-current="page"] { color: var(--brand);
    text-decoration: none; }
  .tabbar-item--cta { color: var(--brand); }
  /* nothing at the end of a page may hide behind the bar */
  body { padding-bottom: 62px; }
  .drawer { padding-bottom: 62px; }
}

/* ═══════════ KPI numbers ══════════════════════════════════════════════════
   Amnon 2026-08-18 — no rings. The figure runs up and settles (JS), the unit
   after it is set smaller so the digits carry the line, and the four cards
   are the same size so the row reads as one measurement, not four notes. */
.kpi-odo { display: flex; align-items: baseline; justify-content: center;
  gap: .06em; font-size: clamp(40px, 5.2vw, 64px); font-weight: 800;
  letter-spacing: -.035em; line-height: 1; color: var(--brand);
  font-variant-numeric: tabular-nums; min-height: 1.05em; }
.kpi-odo--ok { color: var(--ok); }
.odo-digits { display: inline-block; }
.odo-lit { display: inline-block; font-size: .52em; font-weight: 700;
  letter-spacing: 0; opacity: .85; }

/* one row, four equal cards, everything on the same baseline */
.kpi-row--4 { display: grid; gap: var(--s-05);
  grid-template-columns: minmax(0, 1fr); align-items: stretch; }
@media (min-width: 768px)  { .kpi-row--4 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (min-width: 1120px) { .kpi-row--4 { grid-template-columns: repeat(4, minmax(0,1fr)); } }
.kpi-row--4 .kpi-item { display: flex; flex-direction: column; height: 100%;
  text-align: center; padding: var(--s-06) var(--s-05); }
.kpi-row--4 .kpi-name { min-height: 2.6em; display: flex; align-items: center;
  justify-content: center; }
.kpi-row--4 .kpi-sub { margin-top: auto; }

/* ═══════════ standards band: cards + the patents column ═══════════════════
   Amnon 2026-08-18 — every standard is a card that links to the published
   specification, and a third column on the right carries the part that is
   ours (the patents) with links into the pages we already have. */
/* the quote carries the middle of the home page now, where a picture used to
   sit that said nothing the copy had not already said (Amnon 2026-08-18) */
.std-quote { max-width: 940px; margin: var(--s-07) auto var(--s-08, var(--s-07));
  text-align: center; padding-block: var(--s-05); }
.std-quote p { font-size: clamp(24px, 3.1vw, 40px); font-weight: 700;
  line-height: 1.22; letter-spacing: -.02em; color: var(--ink);
  text-wrap: balance; margin: 0; }
.std-quote cite { display: block; margin-top: var(--s-04); font-style: normal;
  font-size: var(--fs-ui); color: var(--ink-3); line-height: 1.5; }
.std-quote cite a { color: var(--brand); }

.std-layout { display: grid; gap: var(--s-06); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1120px) {
  .std-layout { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    align-items: start; }
}
.std-cards { display: grid; gap: var(--s-05);
  grid-template-columns: minmax(0, 1fr); }
@media (min-width: 768px) {
  .std-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.std-card { display: flex; flex-direction: column; gap: var(--s-03);
  text-decoration: none; color: inherit; }
.std-card h4 { color: var(--ink); }
.std-card:hover h4 { color: var(--brand-ink); }
.std-card .std-link { margin-top: auto; padding-top: var(--s-03);
  color: var(--brand); font-weight: 650; font-size: var(--fs-ui);
  display: inline-flex; align-items: center; gap: var(--s-02); }
.std-card:hover { text-decoration: none; }

.std-patents { display: flex; flex-direction: column; gap: var(--s-03); }
.std-patents h3 { font-size: var(--fs-h3, 1.45rem); line-height: 1.2; }
.std-links { list-style: none; display: flex; flex-direction: column;
  gap: var(--s-03); margin-top: var(--s-03); }
.std-links a { color: var(--brand); font-weight: 600; font-size: var(--fs-ui); }
.std-patents .link-arrow { margin-top: var(--s-04); }

/* ═══════════ CTA sizing + the brand name in running text ══════════════════
   Amnon 2026-08-18, from the steer.html screenshot: two CTAs sitting in the
   same row of cards were different widths. Every call to action inside a card
   now carries the same minimum width with its label centred, so a short label
   and a long one still line up. */
.card .link-arrow, .kpi-item .link-arrow, .card .btn {
  min-width: 240px; max-width: 100%; justify-content: center; text-align: center; }

/* The name is a lockup, not a shouted word: "vid" takes the surrounding text
   colour, "NT" takes the logo blue, one notch smaller than the copy around
   it so it reads as a mark rather than as emphasis. On the deep-blue grounds
   the logo blue has too little contrast, so it lifts to the pale blue. */
.vidnt { font-weight: 800; letter-spacing: -.02em; font-size: .94em;
  white-space: nowrap; }
.vidnt i { font-style: normal; font-weight: 800; color: var(--logo-blue, #2b6ef5); }
.band--hero .vidnt i, .band--deep .vidnt i, .band--cta .vidnt i,
.site-footer .vidnt i, .band--hero h1 .vidnt i { color: #9cc9ff; }

/* ═══════════ what the name stands for, at the top of a phone ══════════════
   Amnon 2026-08-18: on a phone the Video Neural Transmission line was eating
   the top of the hero. It now sits in the header beside the logo — the logo
   stays dead centre, the line sits to its right — and the hero gets that
   height back. Above 1120 the header has its own room and the hero keeps
   the large version bottom-right. */
.nav-vnt { display: none; }
@media (max-width: 1119px) {
  .navbar .wrap { grid-template-columns: 1fr auto 1fr; }
  .nav-toggle { grid-column: 1; justify-self: start; }
  .wordmark   { grid-column: 2; justify-self: center; }
  /* it has to fit next to the logo on a 390px screen: the words wrap, the
     column is allowed to shrink, and the wordmark gives up a few pixels. */
  .navbar .wordmark img { height: 26px !important; }
  .nav-vnt { display: block; grid-column: 3; grid-row: 1; justify-self: start;
    padding-left: var(--s-03); min-width: 0; max-width: 100%; overflow: hidden;
    font-size: clamp(7px, 1.9vw, 9px); font-weight: 700;
    letter-spacing: .05em; text-transform: uppercase; line-height: 1.3;
    color: var(--ink-3); white-space: normal; word-break: normal; }
  .nav-vnt b { display: block; font-weight: 600; text-transform: none;
    letter-spacing: .01em; font-size: .95em; color: var(--ink-3); opacity: .85; }
}
@media (max-width: 767px) {
  /* the hero's own copy of it comes off, and the band starts higher */
  .band--hero .hero-tagline { display: none; }
  .hero-slide { padding-block: var(--s-04) var(--s-04); }
}

/* ═══════════ icon cards: the icon leads, on the left ══════════════════════
   Amnon 2026-08-18 — "the icons are beautiful, make them bigger, put them on
   the left, the text on the right, the heading between them". So a card whose
   first child is a live icon becomes two columns: a large icon that spans
   both text rows and sits centred against them, the heading on the first row
   and the body on the second. The standards cards on the home page keep
   their stacked layout — they carry a CTA under the copy. */
main .card:has(> figure.img-live):not(.std-card) {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--s-05); row-gap: var(--s-02); align-items: center;
}
main .card:has(> figure.img-live):not(.std-card) > figure.img-live {
  grid-column: 1; grid-row: 1 / span 2; align-self: center; margin: 0;
}
main .card:has(> figure.img-live):not(.std-card) > figure.img-live img {
  /* the markup carries an inline 72px; the icons deserve more room */
  width: 104px !important; height: 104px !important;
}
main .card:has(> figure.img-live):not(.std-card) > h4 {
  grid-column: 2; align-self: end; margin: 0; }
main .card:has(> figure.img-live):not(.std-card) > p {
  grid-column: 2; align-self: start; margin: 0; }
/* on a phone the icon goes back on top — two columns would squeeze the copy */
@media (max-width: 560px) {
  main .card:has(> figure.img-live):not(.std-card) {
    grid-template-columns: minmax(0, 1fr); }
  main .card:has(> figure.img-live):not(.std-card) > figure.img-live {
    grid-row: auto; }
  main .card:has(> figure.img-live):not(.std-card) > figure.img-live img {
    width: 84px !important; height: 84px !important; }
  main .card:has(> figure.img-live):not(.std-card) > h4,
  main .card:has(> figure.img-live):not(.std-card) > p { grid-column: 1; }
}

/* ── Signals head (steer.html #signals) ───────────────────────────────────────
   Amnon 2026-08-18: the section used to open on a measure-width column that
   read as "these signals are public, anyone can use them". The headline now
   runs the full width in brand blue and says what the product actually is:
   the data is shared, the decision is ours.                                   */
.sig-head { display: grid; gap: 12px; max-width: none; justify-items: center;
  text-align: center; }
.sig-head h2 {
  max-width: none;
  color: var(--brand);
  font-size: clamp(30px, 3.6vw, 52px);
  line-height: 1.08;
  letter-spacing: -.02em;
  text-wrap: balance;
}
.sig-head h2 br { display: none; }
@media (min-width: 900px) { .sig-head h2 br { display: inline; } }
.sig-head .lead { max-width: 74ch; margin-inline: auto; }

/* ── Cookie notice ────────────────────────────────────────────────────────────
   Amnon 2026-08-19: it is meant to be in the way. A full-width bar across the
   bottom on the brand deep blue, at reading size — not a card in a corner a
   visitor can look past. It stays until accepted; there is no Decline because
   the site sets no tracking or advertising cookies, so there is nothing to
   withhold consent from (see legal.html#cookies).                            */
.cookie-note {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 96;
  background: var(--deep); color: #fff;
  border-top: 3px solid var(--brand);
  box-shadow: 0 -18px 40px -22px rgba(0, 8, 40, .75);
  padding: var(--s-06) var(--s-06) calc(var(--s-06) + env(safe-area-inset-bottom));
  transform: translateY(100%); transition: transform .35s cubic-bezier(.2,.7,.2,1);
}
.cookie-note[data-in] { transform: none; }
.cookie-inner { max-width: 1088px; margin-inline: auto; display: flex;
  align-items: center; justify-content: space-between; gap: var(--s-07);
  flex-wrap: wrap; }
.cookie-note p { margin: 0; font-size: 16.5px; line-height: 1.55;
  color: rgba(255,255,255,.9); max-width: 76ch; }
.cookie-note a { color: #fff; font-weight: 700; text-decoration: underline;
  text-underline-offset: 3px; }
.cookie-note a:hover { color: #cfe0ff; }
.cookie-note .row { margin: 0; flex: none; }
.cookie-note button {
  font: inherit; font-size: 16px; font-weight: 700; cursor: pointer;
  color: var(--deep); background: #fff; border: 0;
  padding: .85rem 2.4rem; border-radius: var(--radius-02);
}
.cookie-note button:hover { background: #dce8ff; }
@media (max-width: 720px) {
  .cookie-note { bottom: 56px; padding: var(--s-05); }
  .cookie-note p { font-size: 15px; }
  .cookie-note .row, .cookie-note button { width: 100%; }
  .cookie-note button { justify-content: center; }
}
@media (prefers-reduced-motion: reduce) {
  .cookie-note { transition: none; transform: none; }
}

/* ── About page ───────────────────────────────────────────────────────────── */
.about-punch {
  margin: 0; font-size: clamp(19px, 1.8vw, 25px); line-height: 1.45;
  font-weight: 620; color: var(--brand); text-wrap: balance;
  border-left: 3px solid var(--brand); padding-left: var(--s-06);
}
.about-fine { margin: 0; font-size: 14px; color: var(--ink-2); }
.site-footer a i { font-style: normal; color: var(--logo-blue, #2b6ef5); }

/* ── Footer mark ─────────────────────────────────────────────────────────────
   Amnon 2026-08-18: the logo carries a line naming the company behind it.     */
.footer-mark { display: grid; gap: 12px; justify-items: center; text-align: center;
  width: 100%; }
.footer-plate { display: inline-flex; align-items: center; justify-content: center;
  background: #fff; border: 1px solid rgba(255,255,255,.35);
  border-radius: var(--radius-03); padding: 14px 22px;
  box-shadow: 0 10px 26px -18px rgba(0,0,0,.6); }
.footer-plate img { display: block; height: 34px; width: auto; }
.footer-attr, .footer-copy { font-size: 12.5px; line-height: 1.5;
  color: rgba(255,255,255,.66); letter-spacing: .01em; }
.footer-attr i { font-style: normal; color: rgba(255,255,255,.9); }
.footer-copy { color: rgba(255,255,255,.5); }

/* ── Brain descriptor ────────────────────────────────────────────────────────
   The category line for the brain (Amnon 2026-08-18). Sits between the
   headline and the lead: headline says what it does, this says what it is.   */
.brain-descriptor {
  margin: 0; color: var(--brand);
  font-size: clamp(19px, 2.05vw, 29px); line-height: 1.22;
  font-weight: 680; letter-spacing: -.015em; text-wrap: balance;
}

/* slide 5 — the innovation slide. Amnon 2026-08-18: "dark blue toward the
   purple". Same deep-to-light travel as the other four, different family, so
   it reads as the odd one out on purpose. */
.band--hero:has(.hero-slide:nth-of-type(5)[data-active]) {
  background: linear-gradient(100deg, #191065, #3b2a9e 72%, #4f3cc4); }
.hero-slide:nth-of-type(5) {
  background: linear-gradient(100deg, #191065, #3b2a9e 72%, #4f3cc4); }
/* slide 6 shares slide 5's purple (Amnon: "in the new purple you made") */
.band--hero:has(.hero-slide:nth-of-type(6)[data-active]) {
  background: linear-gradient(100deg, #191065, #3b2a9e 72%, #4f3cc4); }
.hero-slide:nth-of-type(6) {
  background: linear-gradient(100deg, #191065, #3b2a9e 72%, #4f3cc4); }

/* ── Icon cards: big icon left, text right ───────────────────────────────────
   Amnon 2026-08-18: same treatment the artwork cards already got — the icon
   is worth seeing, so it moves out of the stack, grows, and sits beside the
   copy, centred against it.

   Done by taking the tile out of flow and reserving its width as padding,
   rather than with a grid span: the cards have no explicit rows, so a
   `grid-row: 1 / -1` collapses to a single row and the tile rides at the top. */
main .card:has(> .ico-tile) {
  position: relative;
  padding-left: calc(var(--inset-md) + 76px + var(--s-06));
  min-height: calc(76px + 2 * var(--inset-md));
}
main .card:has(> .ico-tile) > .ico-tile {
  position: absolute; left: var(--inset-md); top: 50%;
  transform: translateY(-50%);
  width: 76px; height: 76px; border-radius: var(--radius-03);
}
main .card:has(> .ico-tile) > .ico-tile .ico--lg { width: 40px; height: 40px; }

@media (max-width: 560px) {
  main .card:has(> .ico-tile) {
    padding-left: calc(var(--inset-md) + 58px + var(--s-05));
    min-height: calc(58px + 2 * var(--inset-md));
  }
  main .card:has(> .ico-tile) > .ico-tile { width: 58px; height: 58px; }
  main .card:has(> .ico-tile) > .ico-tile .ico--lg { width: 30px; height: 30px; }
}

/* ── Lead form states ─────────────────────────────────────────────────────── */
.hint.err { color: #b3261e; font-weight: 600; }
.lead-notice { margin-top: var(--s-05); padding: var(--s-05); border-radius: var(--radius-02);
  font-size: 14px; line-height: 1.55; background: #fff4e5; border: 1px solid #f2c98a;
  color: #6b4a12; }
.lead-notice[data-kind="warn"] a { color: var(--brand); font-weight: 650; }
.lead-done { display: grid; gap: 10px; justify-items: center; text-align: center;
  padding: var(--s-08) var(--s-06); }
.lead-done .ico--lg { width: 46px; height: 46px; color: #1a7f4b; }
.lead-done h2 { margin: 0; font-size: clamp(22px, 2.2vw, 30px); }
.lead-done p { margin: 0; color: var(--ink-2); }

/* Review scaffolding is gone for production (Amnon 2026-08-19): the IMG-NN
   captions under artwork were there so assets could be marked off one by one.
   The markup is stripped; this keeps any that creep back from shipping. */
.img-num { display: none !important; }

/* ── Generic comparison table (vs.html) ──────────────────────────────────────
   Amnon 2026-08-19: bigger type, the two answer columns exactly equal, and a
   real phone layout — a 760px table that scrolls sideways is not a mobile
   table, it is a desktop table you have to drag.                            */
.cmp-note, .cmp-close { max-width: 70ch; margin-inline: auto; text-align: center; }
.cmp-note  { color: var(--ink-2); font-size: 15px; line-height: 1.6; margin-block: 0; }
.cmp-close { font-size: clamp(17px, 1.5vw, 21px); font-weight: 620; color: var(--ink);
  margin-block: 0; text-wrap: balance; }

.cmp-wrap { border: 1px solid var(--line); border-radius: var(--radius-03);
  overflow: hidden; }
.cmp { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 16px; }
.cmp thead th {
  text-align: left; padding: 16px 20px; background: var(--brand); color: #fff;
  font-size: 15px; font-weight: 650; }
.cmp thead th:first-child { width: 28%; }
.cmp thead th:nth-child(2), .cmp thead th:nth-child(3) { width: 36%; }
.cmp tbody th {
  text-align: left; padding: 20px; font-weight: 650; font-size: 16px;
  color: var(--ink); vertical-align: top; background: #f5f9ff; line-height: 1.4; }
.cmp td { padding: 20px; vertical-align: top; line-height: 1.6; color: var(--ink-2); }
.cmp-txt { display: block; margin-top: 10px; }
.cmp tbody tr + tr th, .cmp tbody tr + tr td { border-top: 1px solid var(--line); }
.cmp-mark { display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 50%; font-size: 15px; font-weight: 700; }
.cmp-yes  { background: #d8f5e4; color: #0f7a4a; }
.cmp-half { background: #fdeecf; color: #8a5a00; font-size: 12px; }
.cmp-no   { background: #fde0dc; color: #b3261e; }

/* phones: every row becomes its own card, each answer labelled */
@media (max-width: 860px) {
  .cmp-wrap { border: 0; border-radius: 0; }
  .cmp, .cmp tbody, .cmp tr, .cmp th, .cmp td { display: block; width: auto; }
  .cmp thead { display: none; }
  .cmp tbody tr { border: 1px solid var(--line); border-radius: var(--radius-03);
    margin-bottom: var(--s-05); overflow: hidden; }
  .cmp tbody th { background: #f5f9ff; font-size: 17px; padding: 16px 18px;
    border-bottom: 1px solid var(--line); }
  .cmp td { padding: 16px 18px; font-size: 15.5px; }
  .cmp td + td { border-top: 1px solid var(--line); }
  .cmp td::before { content: attr(data-col); display: block; font-size: 12px;
    letter-spacing: .08em; text-transform: uppercase; font-weight: 700;
    color: var(--ink-3); margin-bottom: 8px; }
  .cmp tbody tr + tr th, .cmp tbody tr + tr td { border-top: 0; }
  .cmp tbody tr + tr th { border-bottom: 1px solid var(--line); }
  .cmp td + td { border-top: 1px solid var(--line); }
}

/* vs.html — make the vidNT column read as the featured winner (Amnon 2026-08-19).
   Fix: the "NT" was logo-blue on the blue header, so it read as invisible. */
.cmp thead th .vidnt i { color: #cfe6ff; }
.cmp thead th:first-child, .cmp thead th:nth-child(3) { background: #56647d; }   /* context columns recede */
.cmp thead th:nth-child(2) {                                                     /* vidNT header — the star */
  background: var(--brand); box-shadow: inset 0 4px 0 #9fdcff; font-size: 17px; }
.cmp thead th:nth-child(2) .vidnt { font-size: 1.12em; }
.cmp td[data-col="vidNT"] {                                                      /* vidNT answers — tinted + framed */
  background: var(--brand-wash);
  box-shadow: inset 1px 0 0 #bcd7f4, inset -1px 0 0 #bcd7f4; }
.cmp-mark { width: 30px; height: 30px; font-size: 16px;                          /* bigger, clearer marks */
  box-shadow: 0 1px 3px rgba(9,20,45,.12); }
.cmp-half { font-size: 13px; }

/* ---------- 18. the stream-check result panel ----------------------------- */
/* The answer from POST /api/v1/probe/stream, printed. Nothing in this block
   computes, scales or grades anything — the JS formats values the server sent
   and this file only makes them readable. It is built from primitives that
   already exist: .card / .card--flat for each finding, .badge for the one-word
   reading, .rule for the hairline, .notice--warn for a failure. The only new
   pieces are the label/value list and the pending spinner.                  */

.probe { display: flex; flex-direction: column; gap: var(--s-06); }
/* a class selector beats the UA rule for [hidden], so say it here */
.probe[hidden] { display: none; }

/* Amnon 2026-08-20: the two columns read ragged, because the six cards are
   nowhere near the same length — Manifest carries five rows, Liveness two.
   `align-items: start` let every card shrink to its own content, so the
   right-hand column stepped up and down beside the left one.

   Stretch instead, so the two cards in a row share a height and the grid has
   a straight line across it. The cost of stretching is dead space at the
   bottom of the shorter card, which is fixed rather than hidden: .probe-kv
   takes the slack (`flex: 1`) so its rows sit under the heading and the
   card's own note is pushed to the bottom edge with `margin-top: auto`. A
   short card then looks composed rather than padded. */
.probe-grid { align-items: stretch; }
.probe-grid > .card { height: 100%; }
.probe-grid > .card > .probe-kv { flex: 1 1 auto; align-content: start; }
.probe-grid > .card > p.fine { margin-top: auto; }

.probe-card-head { display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-04); flex-wrap: wrap; }
.probe-card-head h4 { font-size: var(--fs-h4); }

/* Label left, measured value right. The value is monospaced and tabular so a
   column of figures lines up and cannot be misread, and it wraps rather than
   truncates — a header value that is cut off is a value we did not report. */
.probe-kv { margin: 0; display: grid; align-items: baseline;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--s-03) var(--s-05); font-size: var(--fs-ui); }
.probe-kv dt { color: var(--ink-3); }
.probe-kv dd { margin: 0; text-align: right; color: var(--ink);
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere; }

.probe-pending { flex-direction: row; align-items: center; gap: var(--s-05); }
.probe-spin { flex: none; width: 20px; height: 20px; border-radius: 50%;
  border: 2px solid var(--line-strong); border-top-color: var(--brand);
  animation: probe-spin .8s linear infinite; }
@keyframes probe-spin { to { transform: rotate(360deg); } }
/* the global reduced-motion rule crushes durations to .01ms, which would turn
   an infinite spin into a strobe — so drop the animation outright instead */
@media (prefers-reduced-motion: reduce) {
  .probe-spin { animation: none; border-top-color: var(--line-strong); }
}

.probe-errors { list-style: disc; padding-left: var(--s-06);
  display: flex; flex-direction: column; gap: var(--s-02); }

/* check.html — heading and illustration share one band above 1120px and
   stack below it. Centred vertically so the art reads as set against the
   copy rather than hung off its top corner; centred horizontally once
   stacked, because a left-hung image under a left-aligned heading is the
   ragged look this replaces. The intrinsic width/height stay on the <img>
   so the row reserves its space before the file arrives. */
.check-intro { align-items: center; }
.check-intro > figure.img-live { margin: 0; }
.check-intro > figure.img-live img { display: block; width: 100%;
  max-width: 620px; height: auto; margin-inline: auto; }
@media (min-width: 1120px) {
  .check-intro > figure.img-live img { margin-inline: 0 auto; }
}

/* Findings — the explained reading of a measurement, above the grid. They
   are .notice boxes, so they already inherit the page's warn / info wash;
   this only stops a stack of them running together. */
.probe-findings { gap: var(--s-04); }
.probe-findings .probe-note { margin: 0; }

/* The verbatim line the check produced. It is the thing an engineer pastes
   into their own ticket, so it stays selectable, wraps rather than
   truncates, and is visibly quoted rather than written by us. */
.probe-evidence { color: var(--ink-3); }
.probe-evidence code { font-family: var(--mono); overflow-wrap: anywhere;
  word-break: break-word; }


/* ── 19 · Ecosystem wall ────────────────────────────────────────────────────
   Amnon 2026-08-20: ONE list, name + logo, headed "Integrated and Support".

   The hard part is that the 21 entries do not have 21 comparable logos. The
   CDNs have corporate marks; the players mostly do not — hls.js and dash.js
   are wordmarks, and AVPlayer / ExoPlayer are Apple's and Google's own APIs,
   whose logos we must not put on our page.

   So a tile shows a logo WHEN one is supplied and a set wordmark when it is
   not, and both are sized to the same optical weight. Nothing ever renders as
   a broken image, and the wall looks deliberate at every stage of being
   filled in — which is what lets it ship today and improve later. */

.eco-grid {
  display: grid; gap: 1px;
  grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
  background: var(--rule, #e6eaf0);
  border: 1px solid var(--rule, #e6eaf0);
  border-radius: 10px; overflow: hidden;
}
.eco-tile {
  background: #fff;
  min-height: 88px; padding: 14px 12px;
  display: flex; align-items: center; justify-content: center;
  text-align: center;
}
/* The logo, when there is one. Held to a common optical weight so a tall
   wordmark and a square glyph do not fight each other. */
.eco-tile img {
  max-width: 108px; max-height: 30px; width: auto; height: auto;
  display: block; object-fit: contain;
  filter: grayscale(1); opacity: .74;
  transition: filter .18s ease, opacity .18s ease;
}
.eco-tile:hover img { filter: grayscale(0); opacity: 1; }

/* The fallback: a set wordmark, not a placeholder. This is what most of the
   player row will use permanently. */
.eco-name {
  font-size: 14.5px; font-weight: 600; letter-spacing: -.01em;
  color: var(--ink-2, #3d4854); line-height: 1.25;
}
.eco-name small { display: block; font-weight: 500; font-size: 11.5px;
  letter-spacing: .04em; text-transform: uppercase; opacity: .55; margin-top: 3px; }

.eco-note { font-size: 13px; color: var(--muted, #6a7684); }

/* ── ecosystem, text-link version (Amnon 2026-08-20): names only, no logos,
   A–Z per category, a category-colour dot for identity, hover tints, opens the
   provider's own site in a new tab. Safer than logos and good for SEO. ── */
.eco-cat { font-size: .72rem; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-3); margin: 0 0 var(--s-04); }
.eco-cat + .eco-grid { margin-bottom: var(--s-07); }
/* spaced individual cards (not a hairline-divided block) */
.eco-grid--cdn, .eco-grid--drm, .eco-grid--player {
  gap: 10px; background: none; border: 0; border-radius: 0; overflow: visible; }
a.eco-tile { text-decoration: none; gap: 9px; min-height: 62px;
  background: #fff; border: 1px solid var(--line, #e6eaf0); border-radius: 10px;
  color: var(--ink); font-weight: 650; font-size: .95rem; letter-spacing: -.01em;
  transition: color .15s ease, background .15s ease, border-color .15s ease; }
a.eco-tile::before { content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--eco-dot, var(--brand)); flex: none; transition: background .15s ease; }
/* click / hover: dark navy card, white text */
a.eco-tile:hover, a.eco-tile:focus-visible, a.eco-tile:active {
  background: var(--deep, #00185e); border-color: var(--deep, #00185e);
  color: #fff; text-decoration: none; }
a.eco-tile:hover::before, a.eco-tile:focus-visible::before, a.eco-tile:active::before { background: #fff; }
a.eco-tile:hover small, a.eco-tile:focus-visible small, a.eco-tile:active small { color: rgba(255,255,255,.72); }
a.eco-tile small { display: block; font-weight: 500; font-size: 11px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-3); margin-top: 2px; }
.eco-grid--cdn    a.eco-tile { --eco-dot: #0050d7; }
.eco-grid--drm    a.eco-tile { --eco-dot: #2b8000; }
.eco-grid--player a.eco-tile { --eco-dot: #8a5a00; }

@media (max-width: 560px) {
  .eco-grid { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
  .eco-tile { min-height: 74px; }
  .eco-tile img { max-width: 88px; max-height: 26px; }
  a.eco-tile { min-height: 60px; }
}

/* ── partner / affiliate CTA cards above the footer (Amnon 2026-08-20) ── */
.cta-cards { display: grid; gap: 16px; grid-template-columns: 1fr; max-width: 820px;
  margin-inline: auto; }
@media (min-width: 640px) { .cta-cards { grid-template-columns: 1fr 1fr; } }
.cta-card { display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 4px; padding: 26px 22px; background: #fff; border: 1px solid var(--line, #e6e6e6);
  border-radius: var(--radius-03); text-decoration: none;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease; }
.cta-card:hover { border-color: var(--brand); text-decoration: none;
  box-shadow: 0 14px 34px -18px rgba(6,16,40,.4); transform: translateY(-2px); }
.cta-card .cta-ico { width: 46px; height: 46px; border-radius: 50%; display: grid;
  place-items: center; background: var(--brand-wash); color: var(--brand); margin-bottom: 8px; }
.cta-card .cta-ico .ico { width: 20px; height: 20px; }
.cta-card h3 { margin: 0; font-size: 1.15rem; letter-spacing: -.01em; color: var(--ink); }
.cta-card p { margin: 0; font-size: .9rem; color: var(--ink-2); }
.cta-card:hover p { color: var(--brand-ink); }

/* ── "Ask your AI about vidNT" modal (Amnon 2026-08-20) ── */
.aia-back{position:fixed;inset:0;background:rgba(6,16,40,.55);backdrop-filter:blur(2px);
  display:none;align-items:center;justify-content:center;padding:20px;z-index:125}
.aia-back[open]{display:flex}
.aia{background:#fff;border:1px solid var(--line,#cfe2fb);border-radius:16px;max-width:460px;width:100%;
  padding:26px 26px 22px;box-shadow:0 30px 70px -24px rgba(6,16,40,.5);position:relative}
.aia-close{position:absolute;top:12px;right:14px;border:0;background:none;font-size:1.5rem;line-height:1;
  color:var(--ink-3);cursor:pointer;padding:4px 8px;border-radius:8px}
.aia-close:hover{background:#f0f5fc}
.aia .eyebrow{color:var(--brand-ink)}
.aia h2{font-size:1.4rem;margin:8px 0 6px;letter-spacing:-.02em;color:var(--ink)}
.aia-lead{color:var(--ink-2);font-size:.94rem;margin:0 0 18px;line-height:1.5}
.aia-seg{display:flex;gap:8px;margin-bottom:16px}
.aia-seg button{flex:1;padding:9px 8px;border:1px solid var(--line,#cfe2fb);background:#fff;
  border-radius:10px;font:inherit;font-size:.88rem;font-weight:650;color:var(--ink-2);cursor:pointer;
  transition:all .12s ease}
.aia-seg button[aria-selected="true"]{background:var(--brand);border-color:var(--brand);color:#fff}
.aia-go{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;background:var(--brand);
  color:#fff;font-weight:700;font-size:.95rem;padding:12px 14px;border:0;border-radius:11px;cursor:pointer;
  text-decoration:none;transition:background .15s}
.aia-go:hover{background:var(--brand-ink)}
.aia-alt{display:flex;gap:10px;justify-content:center;margin-top:12px}
.aia-alt button{border:1px solid var(--line,#cfe2fb);background:#fff;color:var(--brand-ink);
  font:inherit;font-size:.82rem;font-weight:600;padding:7px 13px;border-radius:9px;cursor:pointer}
.aia-alt button:hover{background:var(--brand-wash)}
.aia-fine{font-size:.76rem;color:var(--ink-3);margin:12px 0 0;line-height:1.5;text-align:center}
.aia-fine a{color:var(--brand-ink);font-weight:600}
.topbar a.topbar-ai{color:#fff;font-weight:700;
  margin-left:6px;padding-left:16px;border-left:1px solid rgba(255,255,255,.28)}
.topbar a.topbar-ai:hover{color:#fff}

/* equal-width buttons within a CTA row, so parallel choices align cleanly
   instead of each sizing to its own label (Amnon 2026-08-20) */
.row--even { align-items: stretch; }
.row--even .btn { flex: 1 1 0; min-width: 0; }
@media (max-width: 560px) { .row--even { flex-direction: column; }
  .row--even .btn { flex: none; width: 100%; } }
