/*
 * Valzeo Visibility — shared shell.
 *
 * Tokens, surfaces, controls, nav and footer, shared by every page so they
 * cannot drift apart. Page-specific layout stays in the page.
 *
 * The design language is the app's own: tinted canvas, two blooms, surfaces lit
 * from above with indigo-carrying shadows, gradient pill controls, Newsreader
 * at 400 for display. Light only.
 */

:root {
  --canvas: #f7f8fb;
  --ink: #171a21;
  --indigo: #3b3f8f;
  --indigo-lift: #4b4fa6;
  --indigo-wash: #e9ebf5;
  --quiet: #565d6a;
  --quieter: #6a7180;
  --alert: #a63b4a;
  /*
   * Two ambers, because the brand one cannot carry text: #c98a3e sits at 2.75
   * against the canvas, well under the 4.5 a reader needs. It stays for marks
   * and rules; --amber-ink (4.91) is the one allowed to say anything.
   *
   * The palette now has three jobs rather than two and a decoration:
   * indigo = measured, red = absent, amber = winnable.
   */
  --amber: #c98a3e;
  --amber-ink: #96611f;
  --amber-wash: #f7eddd;
  --border: rgba(59, 63, 143, 0.13);
  --radius: 0.875rem;
  --radius-xl: 1.225rem;
  --serif: "Newsreader", ui-serif, Georgia, serif;
  --sans: "Geist", ui-sans-serif, system-ui, sans-serif;
  --mono: "Geist Mono", ui-monospace, monospace;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  color-scheme: light;
}

* { box-sizing: border-box; }

/* No scroll-behavior here on purpose: there are no in-page anchors left on the
   site, so smooth scrolling had nothing to smooth. Reinstate it, with its
   reduced-motion counterpart, if anchor links ever come back. */

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0313rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -20;
  pointer-events: none;
  background:
    radial-gradient(68% 42% at 12% 0%, rgba(99, 106, 214, 0.16) 0%, rgba(247, 248, 251, 0) 62%),
    radial-gradient(52% 36% at 92% 4%, rgba(214, 169, 120, 0.2) 0%, rgba(247, 248, 251, 0) 64%);
}

.wrap { max-width: 64rem; margin-inline: auto; padding-inline: max(20px, 5vw); }
.wrap-text { max-width: 46rem; }

a { color: inherit; }
:focus-visible { outline: 2px solid var(--indigo); outline-offset: 3px; border-radius: 4px; }

/* ---- surfaces ------------------------------------------------------------ */

.surface {
  border-radius: var(--radius-xl);
  background: linear-gradient(180deg, #ffffff 0%, #fafbfe 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    0 0 0 1px var(--border),
    0 1px 2px rgba(23, 26, 33, 0.04),
    0 8px 18px -8px rgba(59, 63, 143, 0.10),
    0 24px 48px -20px rgba(59, 63, 143, 0.16);
}
.surface-raised {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    0 0 0 1px var(--border),
    0 2px 4px rgba(23, 26, 33, 0.04),
    0 14px 28px -10px rgba(59, 63, 143, 0.13),
    0 44px 72px -32px rgba(59, 63, 143, 0.26);
}
.lift { transition: transform 260ms var(--ease), box-shadow 260ms var(--ease); }
/* Gated to real pointers. On touch, :hover latches after a tap and the card
   stays lifted with nothing to un-lift it. */
@media (hover: hover) and (pointer: fine) {
  .lift:hover {
    transform: translateY(-2px);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 1),
      0 0 0 1px rgba(59, 63, 143, 0.24),
      0 2px 4px rgba(23, 26, 33, 0.04),
      0 14px 28px -10px rgba(59, 63, 143, 0.15),
      0 44px 72px -32px rgba(59, 63, 143, 0.28);
  }
}

/* ---- nav ----------------------------------------------------------------- */

.nav {
  position: sticky; top: 0; z-index: 20;
  backdrop-filter: saturate(180%) blur(12px);
  background: rgba(247, 248, 251, 0.82);
  border-bottom: 1px solid transparent;
  transition: border-color 200ms var(--ease);
}
/*
 * A scroll edge rather than a hairline: content fades out under the floating
 * bar instead of meeting a drawn line. The rule only appears where the chrome
 * actually overlaps content, which is once the page has moved.
 */
.nav::after {
  content: "";
  position: absolute;
  inset: 100% 0 auto 0;
  height: 18px;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(180deg, rgba(247, 248, 251, 0.9) 0%, rgba(247, 248, 251, 0) 100%);
  transition: opacity 150ms var(--ease);
}
.nav[data-scrolled="true"]::after { opacity: 1; }
.nav-inner { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 68px; }
.wordmark {
  display: inline-flex; align-items: center; text-decoration: none;
  font-weight: 700; font-size: 1.65rem; letter-spacing: 0.09em;
  text-transform: uppercase; line-height: 1;
}
.wordmark em { font-style: normal; color: var(--amber); }
.nav-right { display: flex; align-items: center; gap: 18px; }
.nav-link { font-size: 0.875rem; color: var(--quiet); text-decoration: none; transition: color 180ms var(--ease); }
.nav-link:hover { color: var(--ink); }
.nav-tag { font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--quieter); }
@media (max-width: 640px) { .nav-tag, .nav-link { display: none; } }

/* ---- controls ------------------------------------------------------------ */

.btn {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 46px; padding-inline: 24px; border-radius: 999px;
  font-weight: 600; font-size: 0.9375rem; text-decoration: none; cursor: pointer;
  color: #fff; border: 0;
  background: linear-gradient(180deg, var(--indigo-lift) 0%, var(--indigo) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.24),
    0 1px 2px rgba(59, 63, 143, 0.25),
    0 8px 18px -8px rgba(59, 63, 143, 0.55);
  /* Colour and shadow may take their time; the press must not. A tap that
     settles over 220ms reads as mush, so the transform runs at 120ms. */
  transition: background 220ms var(--ease), box-shadow 220ms var(--ease), transform 120ms ease-out;
}
.btn:hover {
  background: linear-gradient(180deg, #565bbe 0%, #42469c 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.28),
    0 2px 4px rgba(59, 63, 143, 0.28),
    0 12px 26px -10px rgba(59, 63, 143, 0.7);
}
.btn:active { transform: translateY(1px); }
.btn-sm { min-height: 40px; padding-inline: 18px; font-size: 0.875rem; }
.btn-quiet {
  color: var(--ink); background: #fff;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 1),
    0 0 0 1px var(--border),
    0 1px 2px rgba(23, 26, 33, 0.05),
    0 6px 14px -8px rgba(23, 26, 33, 0.14);
}
.btn-quiet:hover {
  background: #fff;
  box-shadow: inset 0 1px 0 #fff, 0 0 0 1px rgba(59, 63, 143, 0.24), 0 10px 20px -10px rgba(23, 26, 33, 0.2);
}
.btn svg { width: 16px; height: 16px; }

/*
 * On a phone the two hero buttons wrapped to separate lines, which read as two
 * unrelated offers rather than a primary choice and its alternative. They now
 * share one row and split it: equal flex basis, tighter padding, and the arrow
 * dropped, since it is the decoration and the words are the content.
 */
@media (max-width: 560px) {
  .actions { flex-wrap: nowrap; gap: 10px; }
  .actions .btn {
    flex: 1 1 0; min-width: 0; justify-content: center;
    padding-inline: 14px; font-size: 0.875rem; white-space: nowrap;
  }
  .actions .btn svg { display: none; }
}

/* ---- type ---------------------------------------------------------------- */

.eyebrow {
  display: inline-flex; align-items: center; gap: 9px; margin: 0;
  font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--indigo);
}
.eyebrow::before { content: ""; width: 18px; height: 1px; background: currentColor; opacity: .5; }

h1 {
  margin: 20px 0 0;
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(2.3rem, 5.6vw, 3.5rem);
  line-height: 1.04; letter-spacing: -0.03em; text-wrap: balance;
}
h2 {
  margin: 14px 0 0;
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.7rem, 3.2vw, 2.3rem);
  line-height: 1.08; letter-spacing: -0.02em; text-wrap: balance;
}
h3 { font-size: 1rem; font-weight: 600; letter-spacing: -0.01em; margin: 0 0 6px; }
.lede { margin: 20px 0 0; max-width: 46ch; color: var(--quiet); }
.sub { margin: 14px 0 0; max-width: 54ch; color: var(--quiet); font-size: 0.9688rem; line-height: 1.55; }

/* ---- document pages ------------------------------------------------------ */

.doc { padding-block: clamp(40px, 6vw, 64px) 0; }
.doc section { margin-top: clamp(34px, 5vw, 52px); }
.doc p { color: var(--quiet); max-width: 68ch; }
.doc li { color: var(--quiet); }
.doc ul { padding-left: 1.15em; display: grid; gap: 9px; max-width: 66ch; }
.doc b, .doc strong { color: var(--ink); font-weight: 600; }
.doc-updated { margin-top: 18px; font-family: var(--mono); font-size: 0.75rem; color: var(--quieter); }
.callout { margin-top: 24px; padding: 22px 24px; }
.callout p:first-child { margin-top: 0; }
.callout p:last-child { margin-bottom: 0; }

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

footer {
  margin-top: clamp(56px, 9vw, 96px); padding-block: 26px 48px;
  border-top: 1px solid var(--border);
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px 24px;
  font-size: 0.8438rem; color: var(--quieter);
}
footer a { color: var(--quiet); text-decoration: none; }
footer a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.foot-links { display: flex; flex-wrap: wrap; gap: 8px 20px; }

/* ---- reveal -------------------------------------------------------------- */

/*
 * Hidden only when JavaScript is actually running. The reveal targets are the
 * largest blocks on the site — the metric strip, the comparison, the report
 * panels — and parking them at opacity 0 in plain CSS means a blocked or broken
 * script leaves a visitor looking at voids where the proof should be. The `js`
 * class is set by an inline script in the head, before first paint.
 */
html.js .reveal { opacity: 0; transform: translateY(14px); transition: opacity 420ms var(--ease), transform 420ms var(--ease); }
html.js .reveal[data-in="true"] { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  /* Matches html.js .reveal on specificity — a bare .reveal here would lose to
     it and leave reduced-motion visitors looking at hidden blocks. */
  html.js .reveal { opacity: 1; transform: none; transition: none; }
  .lift:hover { transform: none; }
}

/* ---- the other two accessibility signals --------------------------------- */

/*
 * Translucency is decoration here, never information: when it is turned down
 * the bar becomes solid and the blur goes away entirely, rather than thinning.
 */
@media (prefers-reduced-transparency: reduce) {
  .nav { background: #fff; backdrop-filter: none; border-bottom: 1px solid var(--border); }
  .nav[data-scrolled="true"]::after { display: none; }
}

/*
 * More contrast: quiet greys go to near-ink, the tinted canvas flattens to
 * white, and every surface takes a defined border instead of relying on a
 * shadow to separate it from the page.
 */
@media (prefers-contrast: more) {
  :root {
    --canvas: #ffffff;
    --quiet: #2f3541;
    --quieter: #3b4250;
    --indigo: #2b2f76;
    --border: rgba(23, 26, 33, 0.42);
  }
  body::before { display: none; }
  .surface, .metric, .fact { box-shadow: none; border: 1px solid var(--border); }
  .nav { background: #fff; backdrop-filter: none; border-bottom: 1px solid var(--border); }
}
