/* ============================================================================
   Vendra One — marketing site
   Rewritten 2026-08-01 on the "V-kærven" tokens. Loads AFTER brand.css and
   invents no colour, radius or spacing of its own; anything new belongs in
   brand.css so the site and the app cannot drift.

   The previous file had grown in four appended "v2 / polish" layers, with the
   footer and .plan each defined twice and later blocks quietly overriding
   earlier ones. Every selector those pages rely on is preserved here — including
   the inner-element ones like .stat .sn and .frame-top .d — but each is now
   defined exactly once.

   Typography follows the brand sheet: Schibsted Grotesk throughout, IBM Plex
   Mono for labels and figures. There is no serif in this brand, so Fraunces is
   gone; it was the main reason the site read as a different product to the app.

   Rhythm: eyebrow -> headline -> lead -> content, on alternating grounds
   (paper / canvas / ink) so the page has a pulse instead of one long scroll.
   ========================================================================= */

/* Bridge: older markup still says var(--p), var(--navy), var(--slate). Map them
   onto the brand tokens rather than hunting every call site across 19 pages. */
:root {
  --p:     var(--brand-accent);
  --pd:    var(--brand-accent-strong);
  --pl:    var(--brand-accent-soft);
  --navy:  var(--brand-ink);
  --navy2: #23262c;
  --ink:   var(--brand-ink);
  --slate: var(--fg-muted);
  --soft:  var(--fg-subtle);
  --line:  var(--border);
  --line2: var(--surface-sunken);
  --bg:    var(--brand-canvas);
  --bg2:   var(--surface-sunken);
  --card:  var(--surface-raised);
  --green: var(--color-ok);
  --gold:  var(--color-warn);
  --sans:  var(--font-sans);
  --mono:  var(--font-mono);
  --sh:    var(--shadow-sm);
  --sh2:   var(--shadow-lg);
  --rad:   var(--radius-lg);
  --ease:  var(--ease-out);
  --wrap:  1180px;
}

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  font-family: var(--sans);
  font-size: 16px;
  line-height: var(--leading-loose);
  background: var(--brand-paper);
  color: var(--fg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg, video { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; text-underline-offset: 3px; }
/* The ring was outline:none plus --shadow-focus, an 18%-alpha wash measuring
   1.28:1 against paper where the floor is 3:1 - and box-shadow is not painted
   at all in Windows High Contrast, so keyboard focus was invisible there
   outright. Two tones rather than one: an ink outline for the shape, a paper
   halo so the same ring survives on the dark hero and the navy sections
   without a per-section override. Forced colours get the system Highlight,
   because that is the only colour the reader has agreed to see. */
:focus-visible {
  /* !important on the two ring properties only. :focus-visible and .btn carry
     the same specificity and .btn is written further down, so without it a
     focused button keeps its own lift shadow and loses the halo - which on the
     dark hero leaves an ink outline on an ink ground. border-radius stays a
     normal declaration on purpose, so a pill button keeps its pill and a bare
     link still gets the softened corner. */
  outline: 3px solid var(--brand-ink, #15171B) !important;
  outline-offset: 2px !important;
  box-shadow: 0 0 0 6px var(--brand-paper, #FAF9F6) !important;
  border-radius: var(--radius-sm);
}
@media (forced-colors: active) {
  :focus-visible {
    outline: 3px solid Highlight !important;
    outline-offset: 2px !important;
    box-shadow: none !important;
  }
}

/* ---- skip link ----------------------------------------------------------
   First stop in the tab order on every page, and the only way past the header
   and the nav without pressing Tab eight times on each of them. Moved
   off-screen with a transform rather than display:none, which would take it
   out of the tab order and defeat the point. */
.skip-link {
  position: absolute; left: var(--space-4); top: var(--space-4);
  z-index: 9999;
  transform: translateY(-200%);
  background: var(--brand-ink, #15171B); color: var(--brand-paper, #FAF9F6);
  font-size: .875rem; font-weight: var(--weight-semi);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-sm);
}
.skip-link:focus-visible { transform: none; }
@media (prefers-reduced-motion: no-preference) {
  .skip-link { transition: transform var(--duration-fast) var(--ease); }
}

/* ------------------------------------------------------------- structure */
.wrap { width: min(var(--wrap), 100% - var(--space-12)); margin-inline: auto; }
@media (max-width: 640px) { .wrap { width: calc(100% - var(--space-6)); } }

section { padding-block: clamp(var(--space-16), 7vw, 128px); scroll-margin-top: 84px; }
@media (max-width: 900px) { section { padding-block: var(--space-16); } }

.tint { background: var(--bg); }
.navy-sec { background: var(--surface-inverse); color: rgba(250,249,246,.78); }
.navy-sec h1, .navy-sec h2, .navy-sec h3, .navy-sec h4, .navy-sec b { color: var(--fg-inverse); }
.navy-sec p, .navy-sec li, .navy-sec span { color: rgba(250,249,246,.72); }
.navy-sec .eyebrow { color: var(--brand-accent-light); }

/* ------------------------------------------------------------ typography */
/* Display type, revised 2026-08-03.
   The old setting was 600 weight tracked -3% — a dense, tight headline that
   read as "app UI" rather than "considered product". The change borrows the
   editorial treatment: lighter weight, positive tracking, and line-height
   pulled almost to the cap height, so a headline reads as a composed object
   instead of a paragraph in bold.

   What is deliberately NOT borrowed is the serif. Schibsted Grotesk is the
   brand, it is what the app is set in, and it is the single thing that keeps
   this reading as software. Wide tracking on a grotesk gets the same calm
   without pretending to be an estate agent. */
h1, h2, h3, h4 {
  font-family: var(--sans);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
  color: var(--fg);
}
/* Only the two display sizes open up. h3 and h4 are labels doing work in a
   card, and tracking them out would just make them harder to read. */
h1 {
  font-size: clamp(2.25rem, 1.15rem + 4vw, 3.75rem);
  font-weight: 400;
  letter-spacing: 0.04em;
  line-height: 1.06;
}
h2 {
  font-size: clamp(1.75rem, 1.15rem + 2.1vw, 2.5rem);
  font-weight: 400;
  letter-spacing: 0.02em;
  line-height: 1.14;
}
h3, h4 { font-weight: var(--weight-semi); }
h3 { font-size: 1.25rem; letter-spacing: var(--tracking-tight); }
h4 { font-size: 1rem; letter-spacing: var(--tracking-tight); }
p { color: var(--slate); text-wrap: pretty; }

/* Kept for markup that still asks for it — now an accent emphasis, not a serif. */
.serif-em { font-style: normal; font-weight: var(--weight-semi); color: var(--p); }

.eyebrow {
  /* Was a mono, uppercase, 0.19em-tracked label floating above an oversized
     headline - the kicker every generated landing page opens with, and the
     shape the design review named first. It reads as a sentence now, and it
     carries the accent dot from the mark, which is the one piece of this brand
     nothing else on the web has. Same element, same strings: no markup and no
     translation had to move to do it. */
  font-family: var(--sans);
  font-size: .8125rem;
  font-weight: var(--weight-semi);
  letter-spacing: 0;
  text-transform: none;
  color: var(--slate);
}
.eyebrow::before {
  content: ''; display: inline-block; vertical-align: 0.14em;
  width: 6px; height: 6px; margin-right: var(--space-2);
  border-radius: 50%; background: var(--p);
}
.navy-sec .eyebrow::before, .hero-dark .eyebrow::before,
.dark-page .tint .eyebrow::before, .about-hero .eyebrow::before {
  background: var(--brand-accent-light);
}
.lead { font-size: clamp(1.0625rem, 1rem + .35vw, 1.1875rem); color: var(--slate); line-height: var(--leading-loose); }
.sec-head { max-width: 46rem; margin-bottom: var(--space-16); }
.sec-head h2 { margin: var(--space-5) 0 var(--space-4); }
.sec-head.center { margin-inline: auto; text-align: center; }
.sec-lead, .center > p.lead { max-width: 62ch; margin-inline: auto; }

.underline {
  background-image: linear-gradient(var(--p), var(--p));
  background-size: 100% 2px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  padding-bottom: 2px;
}

/* --------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  font-family: var(--sans); font-weight: var(--weight-semi); font-size: .9375rem; line-height: 1;
  padding: var(--space-3) var(--space-6);
  border: 1px solid transparent; border-radius: var(--radius-md);
  cursor: pointer; white-space: nowrap; background: none;
  /* One transition, declared once. There were three of these — here, in the
     "polish" layer and again in the "depth" layer — and the last one won while
     quietly dropping border-color, so .btn-light and .btn-ghost snapped their
     outline on hover instead of easing it. Every property a button actually
     animates is listed here and nowhere else. */
  transition: background-color .18s var(--ease),
              border-color .18s var(--ease),
              color .18s var(--ease),
              transform .18s var(--ease),
              box-shadow .18s var(--ease);
}
/* Settles rather than snaps, and goes down under the finger. The press was
   written twice and cancelled once: :active said translateY(1px) in one layer
   and translateY(0) in a later one, so no button moved when pressed. */
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(1px); }
/* Flat, no glow. The old drop-shadowed buttons were the loudest thing on a
   page whose whole point is calm. */
.btn-p { background: var(--p); color: var(--fg-on-accent); }
.btn-p:hover { background: var(--pd); color: var(--fg-on-accent); }
.btn-navy { background: var(--navy); color: var(--fg-inverse); }
.btn-navy:hover { background: var(--navy2); color: var(--fg-inverse); }
.btn-light { background: var(--card); color: var(--navy); border-color: var(--line); }
.btn-light:hover { background: var(--bg2); color: var(--navy); }
.btn-ghost { color: var(--navy); border-color: var(--line); }
.btn-ghost:hover { background: var(--bg2); color: var(--navy); }
.btn-w { background: var(--card); color: var(--navy); }
.btn-w:hover { background: var(--brand-paper); color: var(--navy); }
.btn-sm { padding: var(--space-2) var(--space-4); font-size: .875rem; }
.btn-lg { padding: var(--space-4) var(--space-8); font-size: 1rem; }
.btn-arrow svg { transition: transform var(--duration-fast) var(--ease); }
.btn:hover .btn-arrow svg, .btn-arrow:hover svg { transform: translateX(3px); }
.linkbtn { border: 0; background: none; color: var(--p); font: inherit; font-weight: var(--weight-semi); font-size: .875rem; cursor: pointer; }
.linkbtn:hover { text-decoration: underline; }

/* --------------------------------------------------------- announce strip */
.strip { background: var(--navy); color: rgba(250,249,246,.72); font-size: .8rem; text-align: center; padding: var(--space-2) var(--space-4); }
.strip b { color: var(--fg-inverse); }
.strip a { color: var(--brand-accent-light); font-weight: var(--weight-semi); }

/* ---------------------------------------------------------------- header */
header.site {
  position: sticky; top: 0; z-index: var(--z-sticky);
  background: rgba(255,255,255,.82);
  backdrop-filter: saturate(1.6) blur(14px);
  border-bottom: 1px solid var(--line);
}
header.site .bar { display: flex; align-items: center; gap: var(--space-8); height: 68px; }
.logo {
  display: flex; align-items: center; gap: .31em;
  font-family: var(--sans); font-weight: var(--weight-semi); font-size: 1.15rem;
  letter-spacing: var(--tracking-display); color: var(--navy);
}
.logo svg { flex: none; }

nav.main { display: flex; align-items: center; gap: var(--space-6); margin-right: auto; }
nav.main a { position: relative; font-size: .9375rem; font-weight: var(--weight-medium); color: var(--slate); padding-block: var(--space-2); }
nav.main a:hover, nav.main a.on { color: var(--navy); }
nav.main a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--p); border-radius: var(--radius-xs);
  /* Was left/right 50% animated to 0: two layout properties recalculated per
     frame on every nav hover. scaleX from the centre draws the identical line
     on the compositor instead. */
  transform: scaleX(0);
  transition: transform var(--duration-base) var(--ease);
}
nav.main a:hover::after, nav.main a.on::after { transform: scaleX(1); }

.has-menu { position: relative; }
.menu {
  position: absolute; top: 130%; left: -14px; width: 290px; padding: var(--space-2);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--sh2); opacity: 0; visibility: hidden; transform: translateY(6px);
  transition: opacity var(--duration-base) var(--ease), transform var(--duration-base) var(--ease), visibility var(--duration-base);
}
.has-menu:hover .menu { opacity: 1; visibility: visible; transform: none; }
.menu a { display: flex; gap: var(--space-3); padding: var(--space-3); border-radius: var(--radius-sm); color: var(--navy); }
.menu a:hover { background: var(--bg2); }
.mi-ic { flex: none; width: 34px; height: 34px; border-radius: var(--radius-sm); background: var(--pl); color: var(--pd); display: grid; place-items: center; }
.mi-t { font-weight: var(--weight-semi); font-size: .875rem; }
.mi-d { font-size: .75rem; color: var(--soft); line-height: 1.4; }

.hdr-cta { display: flex; align-items: center; gap: var(--space-3); }
.hdr-cta .login { font-size: .9rem; font-weight: var(--weight-medium); color: var(--slate); padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm); }
.hdr-cta .login:hover { background: var(--bg2); color: var(--navy); }
.burger { display: none; background: none; border: 0; cursor: pointer; padding: var(--space-2); }

.mob-nav { display: none; }

/* Below 560px the header ran 294px wide inside a 343px column, so the whole
   site scrolled sideways on a phone — the trial button and the burger sat past
   the right edge. Hiding the language picker or the trial button would have
   fixed the number and broken something people use, so instead every part gets
   smaller: the picker drops to its globe, the button to two words, the gaps to
   one step. Nothing is lost, and it fits with room to spare. */
@media (max-width: 560px) {
  .hdr-cta { gap: var(--space-2); }
  .hdr-cta .lb-code, .hdr-cta .lb-sep, .hdr-cta .lb-cur, .hdr-cta .lb-chev { display: none; }
  .hdr-cta .lang-btn { padding: var(--space-2); }
  .hdr-cta .btn-p { padding-inline: var(--space-3); font-size: .8125rem; white-space: nowrap; }
  .bar .logo span, .bar .logo .logo-word-sub { display: none; }
}
/* Nothing on a marketing page is worth a sideways scrollbar. This is the
   backstop for anything a future section gets wrong. */
@media (max-width: 920px) { html, body { overflow-x: hidden; } }

@media (max-width: 920px) {
  nav.main, .hdr-cta .login { display: none; }
  .burger { display: block; }
  .mob-nav.open {
    display: block; position: fixed; inset: 68px 0 0; z-index: var(--z-overlay);
    background: var(--surface-raised); padding: var(--space-6); overflow: auto;
  }
  .mob-nav a { display: block; padding: var(--space-4) 0; font-size: 1.05rem; font-weight: var(--weight-medium); color: var(--navy); border-bottom: 1px solid var(--line); }
}

/* ------------------------------------------------------------------ hero */
.hero { padding-block: clamp(var(--space-16), 8vw, 120px) clamp(var(--space-16), 7vw, 104px); overflow: hidden; }
.hero-grid { display: grid; grid-template-columns: 1.02fr .98fr; gap: clamp(var(--space-8), 6vw, 96px); align-items: center; }
.hero .eyebrow { display: block; margin-bottom: var(--space-5); }
.hero h1 { margin-bottom: var(--space-6); }
/* 60 characters is the measure that was already right; only the space
   around it changes. */
.hero .lead { max-width: 32em; margin-bottom: var(--space-8); }
.hero-cta { display: flex; gap: var(--space-3); flex-wrap: wrap; align-items: center; }
.hero-tr { display: flex; gap: var(--space-2) var(--space-6); flex-wrap: wrap; margin-top: var(--space-6); font-family: var(--mono); font-size: .75rem; color: var(--soft); }
.hero-tr span { display: flex; align-items: center; gap: var(--space-2); }
.hero-tr svg { color: var(--green); }
.hero-alt { margin-top: var(--space-3); font-size: .875rem; color: var(--soft); }

/* The two prices, in the hero. The hero's own promise is that the prices are
   on the page, so they are on it before the first scroll rather than 15.591px
   down it. Sized as a statement, not as small print. */
.hero-price {
  margin-top: var(--space-4);
  font-size: .9375rem; font-weight: var(--weight-medium);
  color: var(--slate); line-height: var(--leading-loose);
}
.hero-price a { color: var(--p); font-weight: var(--weight-semi); white-space: nowrap; }
.hero-dark .hero-price { color: rgba(250,249,246,.82); }
.hero-dark .hero-price a { color: var(--brand-accent-light); }
.hero-alt a { color: var(--p); font-weight: var(--weight-semi); border-bottom: 1px solid var(--brand-accent-light); }
.hero-alt a:hover { border-bottom-color: var(--p); }

/* -------------------------------------------------------- product frame */
.frame { background: var(--navy); border: 1px solid var(--navy); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--sh2); }
.frame-top { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); background: #1d2027; border-bottom: 1px solid #2a2e36; }
.frame-top .d { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.frame-url { flex: 1; max-width: 340px; margin-left: var(--space-3); padding: var(--space-1) var(--space-3); background: var(--navy); border-radius: var(--radius-xs); font-family: var(--mono); font-size: .7rem; color: var(--brand-accent-light); }
/* .65rem was 10.4px — under the 11px floor for functional text, and this is a
   status label, not smallprint. Now .7rem, which is also what .frame-url and
   .shot-cap use, so the chrome around the demo has one mono size. */
.frame-live { margin-left: auto; display: flex; align-items: center; gap: var(--space-1); font-family: var(--mono); font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; color: #7fd0aa; }
.frame-live .dot { width: 7px; height: 7px; border-radius: 50%; background: #7fd0aa; }
/* @keyframes lp removed with its last two users: a pulsing dot beside a
   LIVE label promises data arriving, and the demo frame shows sample data
   that never changes. The label is true; the heartbeat was not. */
.shot-embed { position: relative; width: 100%; overflow: hidden; background: var(--bg); }
.shot-embed iframe { position: absolute; top: 0; left: 0; border: 0; transform-origin: top left; background: var(--bg); }
.shot-embed .glass { position: absolute; inset: 0; z-index: 2; cursor: pointer; }
.shot-cap { margin-top: var(--space-3); text-align: center; font-family: var(--mono); font-size: .7rem; color: var(--soft); }

/* ----------------------------------------------------------------- cards */
.grid2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-6); }
.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }
.grid4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-6); }
.grid2 > *, .grid3 > *, .grid4 > * { display: flex; flex-direction: column; }
@media (max-width: 980px) { .grid3, .grid4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .grid2, .grid3, .grid4 { grid-template-columns: 1fr; } }

.vp-grid, .values-grid, .help-cats, .founders, .contact-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }
@media (max-width: 980px) { .vp-grid, .values-grid, .help-cats, .founders, .contact-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .vp-grid, .values-grid, .help-cats, .founders, .contact-grid { grid-template-columns: 1fr; } }

.vp, .help-cat, .contact-card, .founder, .hour, .proof-i, .demo-card, .ct-route {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  padding: var(--space-6);
  transition: border-color var(--duration-base) var(--ease),
              box-shadow var(--duration-base) var(--ease),
              transform var(--duration-base) var(--ease);
}
.vp:hover, .help-cat:hover, .demo-card:hover, .ct-route:hover {
  border-color: var(--border-strong); box-shadow: var(--shadow-md); transform: translateY(-2px);
}
.vp .n { font-family: var(--mono); font-size: 1.5rem; color: var(--p); line-height: 1; margin-bottom: var(--space-3); }
.vp h3, .help-cat h3, .contact-card h3 { font-size: 1.0625rem; margin-bottom: var(--space-2); }
.vp p, .help-cat a, .contact-card p { font-size: .9375rem; color: var(--slate); }
.help-cat a { display: block; padding-block: var(--space-1); }
.help-cat a:hover { color: var(--p); }
.contact-card a { color: var(--p); font-weight: var(--weight-semi); }

/* ------------------------------------------------------------ split rows */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-16); align-items: center; }
.split.rev .split-media { order: -1; }
.split-media { min-width: 0; }
.split-media img { border-radius: var(--radius-lg); box-shadow: var(--sh2); }
@media (max-width: 900px) { .split, .hero-grid { grid-template-columns: 1fr; gap: var(--space-12); } .split.rev .split-media { order: 0; } }

.feat-list { display: grid; gap: var(--space-4); margin-top: var(--space-6); }
.feat-list .fl { display: flex; gap: var(--space-3); align-items: flex-start; }
.feat-list .fic { flex: none; width: 34px; height: 34px; margin-top: 2px; border-radius: var(--radius-sm); background: var(--pl); color: var(--pd); display: grid; place-items: center; }
.navy-sec .feat-list .fic { background: rgba(127,178,206,.18); color: var(--brand-accent-light); }
.feat-list b { font-size: .9375rem; font-weight: var(--weight-semi); color: var(--navy); }
.feat-list span { display: block; font-size: .875rem; color: var(--slate); }

/* ------------------------------------------------------------ statement band
   These used to be stock photos of handshakes and open-plan offices loaded from
   a US CDN — generic enough to belong to any SaaS, and an odd thing to serve on
   a site whose main claim is that European data stays in Europe. The band is now
   type on ink with the mark as a watermark: nothing to download, nothing that
   could have been any other company's page. */
.photo-band { position: relative; min-height: 280px; display: flex; align-items: flex-end;
  border-radius: var(--radius-xl); overflow: hidden; background: var(--surface-inverse); }
.photo-band::before {
  content: '';
  position: absolute; right: -4%; top: 50%; transform: translateY(-50%);
  width: 46%; aspect-ratio: 1; opacity: .07;
  background: currentColor;
  color: var(--brand-accent-light);
  /* The V-kærven silhouette, masked so it takes the accent rather than being a
     second image request. */
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath d='M18.4 17.4 A20 20 0 1 0 45.6 17.4 L32 34 Z'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath d='M18.4 17.4 A20 20 0 1 0 45.6 17.4 L32 34 Z'/%3E%3C/svg%3E") center/contain no-repeat;
  pointer-events: none;
}
.photo-band .ov { position: relative; z-index: 1; width: 100%; padding: var(--space-12) var(--space-8); color: var(--fg-inverse); }
/* h2 as well as h3: a photo band is a top-level <section>, so on a page where
   the band is a peer of the other sections its caption is an h2. The level is
   an outline decision and must not be a visual one, so font-weight and
   line-height are pinned here — the base rules give h2 400/1.14 and h3
   --weight-semi/--leading-tight, and without these two lines retagging a
   caption would quietly restyle it. */
.photo-band .ov h2,
.photo-band .ov h3 { color: var(--fg-inverse); font-size: clamp(1.35rem, 1.1rem + 1.1vw, 1.875rem); font-weight: var(--weight-semi); line-height: var(--leading-tight); max-width: 18em; letter-spacing: var(--tracking-display); }
.photo-band .ov p { color: rgba(250,249,246,.72); margin-top: var(--space-3); max-width: 34em; }

/* Where a decorative photo sat beside a text column, a brand panel keeps the
   two-column rhythm without pretending to show something real. */
.brand-panel {
  position: relative;
  /* width:100% and a floor are both needed: these panels sit in flex columns
     where aspect-ratio alone resolves against a zero-width box and collapses. */
  width: 100%;
  aspect-ratio: 4 / 3;
  min-height: 240px;
  /* Beside a text column 4:3 is right; full width it would be 885px of empty
     panel, which reads as a failed image rather than a deliberate one. */
  max-height: 420px;
  border-radius: var(--radius-xl);
  background: var(--bg2); border: 1px solid var(--line); overflow: hidden;
  display: grid; place-items: center;
}
.brand-panel::after {
  content: '';
  /* Sized from the panel's HEIGHT, not its width. At full width the 4:3 ratio
     wants 885px but max-height caps the panel at 420, and a mark measured as
     42% of the width was then 495px tall inside a 420px box - a circle with its
     top and bottom sliced off. Driving it from height cannot outgrow the box. */
  height: 55%; width: auto; max-width: 42%; aspect-ratio: 1;
  opacity: .16; background: var(--color-primary);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath d='M18.4 17.4 A20 20 0 1 0 45.6 17.4 L32 34 Z'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath d='M18.4 17.4 A20 20 0 1 0 45.6 17.4 L32 34 Z'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* ---- dark bands ----
   The alternating band goes dark, so the page reads as stripes of ink and paper
   rather than paper and slightly-greyer-paper. Cards keep their white and start
   to float, which is the effect the reference gets most of its depth from.

   Only the homepage for now: dark-page is put on <body> there, so every other
   page keeps the light band until it has been looked at on its own. */
.dark-page .tint{
  position:relative; overflow:hidden; isolation:isolate;
  background: var(--brand-ink);
  color: rgba(250,249,246,.74);
}
.dark-page .tint h1,.dark-page .tint h2,.dark-page .tint h3,.dark-page .tint h4{
  color: var(--brand-paper);
}
.dark-page .tint .eyebrow{ color: var(--brand-accent-light); }
.dark-page .tint .lead,.dark-page .tint p{ color: rgba(250,249,246,.72); }
.dark-page .tint .serif-em{ color: var(--brand-accent-light); }
.dark-page .tint a:not(.btn){ color: var(--brand-accent-light); }

/* Cards float rather than sit in a panel. The lift on hover is what makes a
   grid of them feel like objects instead of a table. */
.dark-page .tint .card,
.dark-page .tint .proof-i,
.dark-page .tint .tc-group,
.dark-page .tint .plan{
  background: var(--surface-raised);
  border-color: rgba(250,249,246,.1);
  box-shadow: var(--lift-dark);
  transition: transform .2s var(--ease), box-shadow .2s var(--ease);
}
.dark-page .tint .card:hover,
.dark-page .tint .proof-i:hover{
  transform: translateY(-3px);
  box-shadow: var(--lift-hover);
}
/* Text inside a white card is dark again — the band's colour must not leak in. */
.dark-page .tint .card,.dark-page .tint .card p,.dark-page .tint .card span,
.dark-page .tint .proof-i,.dark-page .tint .proof-i span{ color: var(--fg); }
.dark-page .tint .card h3,.dark-page .tint .card h4,.dark-page .tint .card b,
.dark-page .tint .proof-i b{ color: var(--fg); }
.dark-page .tint .card .muted,.dark-page .tint .proof-i span{ color: var(--fg-muted); }

/* Buttons on the dark band */
.dark-page .tint .btn-light{
  background: transparent; color: var(--brand-paper);
  border-color: rgba(250,249,246,.34);
}
.dark-page .tint .btn-light:hover{ background: rgba(250,249,246,.1); }
.dark-page .tint .btn-p{ background:var(--accent-warm); border-color:var(--accent-warm); color:var(--accent-warm-on); font-weight:600; }
.dark-page .tint .btn-p:hover{ background:var(--accent-warm-lift); border-color:var(--accent-warm-lift); }

/* One drifting shape per dark band, alternating side, so the stripes do not
   look like four copies of the same rectangle. */
.dark-page .tint::before{
  content:''; position:absolute; z-index:-1; pointer-events:none;
  width: clamp(16rem, 26vw, 26rem); aspect-ratio: 1.15;
  background: var(--brand-accent-light); opacity:.13;
  border-radius: 55% 45% 48% 52% / 48% 54% 46% 52%;
  right:-8%; top:-18%;
  animation: blobDrift 30s ease-in-out infinite alternate;
}
.dark-page .tint:nth-of-type(even)::before{
  right:auto; left:-9%; top:auto; bottom:-20%;
  background:var(--accent-warm); opacity:.11;
  animation-duration: 38s;
}
@media (prefers-reduced-motion: reduce){ .dark-page .tint::before{ animation:none; } }

/* ---- integrations bubble ----
   A light section with one large saturated object in it, rather than a dark
   section. Text sits on a solid shape whose colour is set here, so nothing can
   inherit dark-on-dark the way the full-section version did. */
.bubble-row{
  display:grid; grid-template-columns: 1fr 1fr; gap: var(--space-10, 40px);
  align-items:center;
}
.bubble{
  position:relative; order:2;
  background: var(--brand-ink); color: rgba(250,249,246,.8);
  padding: clamp(32px, 4vw, 52px);
  /* one squared corner is what makes a blob read as speech */
  border-radius: var(--blob-c);
}
.bubble h2{ color: var(--brand-paper); font-size: clamp(1.7rem,1.2rem+1.9vw,2.6rem);
  line-height:1.08; letter-spacing:-.03em; margin:0 0 var(--space-3); }
.bubble p{ color: rgba(250,249,246,.74); margin:0 0 var(--space-5); max-width:26em; }
.bubble .btn-p{ background:var(--accent-warm); border-color:var(--accent-warm); color:var(--accent-warm-on); font-weight:600; }
.bubble .btn-p:hover{ background:var(--accent-warm-lift); border-color:var(--accent-warm-lift); }
.bubble-ico{
  display:grid; place-items:center; width:44px; height:44px; border-radius:14px;
  background: rgba(127,178,206,.18); color: var(--brand-accent-light);
  margin-bottom: var(--space-4);
}
.bubble-ico svg{ width:22px; height:22px; }

/* the loose tiles the reference floats beside the bubble */
.bubble-tiles{ position:relative; order:1; min-height: 22rem; }
.btile{
  position:absolute; display:grid; place-items:center;
  background: var(--surface-raised); border:1px solid var(--line); border-radius: var(--radius-lg);
  font-size:.82rem; font-weight:600; color: var(--fg);
  box-shadow: var(--lift-rest);
  animation: btileFloat 7s ease-in-out infinite alternate;
}
.b1{ width:7rem; height:5rem; left:4%;  top:6%;  }
.b2{ width:8rem; height:5.5rem; left:40%; top:0;   animation-delay:-1.4s }
.b3{ width:7.5rem;height:5rem; left:20%; top:44%; animation-delay:-2.8s }
.b4{ width:6.5rem;height:4.5rem;left:58%; top:52%; animation-delay:-4.2s }
.bdot{ position:absolute; border-radius:50%; }
.d1{ width:4.5rem; height:4.5rem; background:var(--brand-accent-light); opacity:.4; left:66%; top:18%; }
.d2{ width:6rem; height:6rem; background:var(--accent-warm); opacity:.24; left:2%; top:60%; }
@keyframes btileFloat{ from{ transform:translateY(0) } to{ transform:translateY(-9px) } }
@media (prefers-reduced-motion: reduce){ .btile{ animation:none } }

@media (max-width: 860px){
  .bubble-row{ grid-template-columns:1fr; }
  .bubble{ order:1; border-radius: var(--radius-xl); }
  .bubble-tiles{ order:2; min-height:16rem; }
}

/* ---- dark hero ----
   Deep ground, one warm accent, organic shapes. Scoped so the other pages keep
   their current hero until each has been looked at on its own. */
.hero-dark{
  position:relative; overflow:hidden; isolation:isolate;
  background: var(--brand-ink); color: var(--brand-paper);
  border-radius: 0 0 var(--curve-page) var(--curve-page);
  padding-block: clamp(56px, 7vw, 96px) clamp(64px, 8vw, 108px);
}
.hero-dark .eyebrow{ color: var(--brand-accent-light); }
.hero-dark h1{
  color: var(--brand-paper);
  font-size: clamp(2.6rem, 1.7rem + 4.2vw, 4.6rem);
  line-height: 1.02; letter-spacing: -.035em; font-weight: 600;
}
.hero-dark .lead{ color: rgba(250,249,246,.76); font-size: clamp(1rem, .95rem + .3vw, 1.18rem); }

/* --soft is a light-ground colour (#696C70). It reads 5.0 on paper and 4.5 on
   canvas, but this hero is the ink ground, where it falls to 3.4 - under the
   4.5 these sizes need. The block above already re-coloured the eyebrow, the
   headline, the lead and the buttons and simply stopped before the two
   quietest lines, which is why it went unnoticed.

   .72 is the same step the footer chip uses on ink, one notch below .lead's
   .76, so the hierarchy survives the fix instead of flattening. It measures
   9.2. */
.hero-dark .hero-alt,
.hero-dark .hero-tr,
.hero-dark .hero-tr span { color: rgba(250,249,246,.72); }
.hero-dark .hero-alt a { color: var(--brand-accent-light); border-bottom-color: rgba(127,178,206,.5); }
.hero-dark .hero-alt a:hover { border-bottom-color: var(--brand-accent-light); }
.hero-dark .serif-em{ color: var(--brand-accent-light); font-style: normal; }

/* The one warm thing on the page, which is why it pulls the eye. */
.hero-dark .btn-p{
  background:var(--accent-warm); border-color:var(--accent-warm); color:var(--accent-warm-on); font-weight:600;
  box-shadow: 0 10px 26px -12px rgba(232,115,74,.75);
}
.hero-dark .btn-p:hover{ background:var(--accent-warm-lift); border-color:var(--accent-warm-lift); transform: translateY(-1px); }
.hero-dark .btn-light{
  background: transparent; color: var(--brand-paper);
  border-color: rgba(250,249,246,.34);
}
.hero-dark .btn-light:hover{ background: rgba(250,249,246,.1); border-color: rgba(250,249,246,.55); }

/* Organic shapes. border-radius with eight values gives the lopsided blob the
   reference uses; a circle would read as a bubble instead. */
.hero-dark .blob,.hero-dark .squig{ position:absolute; z-index:-1; pointer-events:none; }
.hero-dark .blob{ filter: blur(.5px); }
.blob-a{
  width: clamp(20rem, 34vw, 34rem); aspect-ratio: 1.1;
  right: -6%; top: -14%;
  background: var(--brand-accent-light); opacity:.2;
  border-radius: var(--blob-a);
  animation: blobDrift 26s ease-in-out infinite alternate;
}
.blob-b{
  width: clamp(13rem, 22vw, 22rem); aspect-ratio: 1;
  left: -7%; bottom: -22%;
  background: var(--accent-warm); opacity:.14;
  border-radius: var(--blob-b);
  animation: blobDrift 34s ease-in-out infinite alternate-reverse;
}
.squig{
  width: clamp(6rem, 9vw, 10rem); height: clamp(6rem, 9vw, 10rem);
  right: 12%; bottom: 8%;
  border: 9px solid var(--accent-warm); opacity:.3;
  border-radius: 50%; border-top-color: transparent; border-left-color: transparent;
  transform: rotate(24deg);
}
@keyframes blobDrift{
  from{ transform: translate3d(0,0,0) rotate(0deg) scale(1); }
  to  { transform: translate3d(-2.5%, 3%, 0) rotate(9deg) scale(1.07); }
}
@media (prefers-reduced-motion: reduce){ .blob-a,.blob-b{ animation:none; } }

/* The band under a dark hero needs its own top edge; the shared rule assumes a
   light background above it. */
.hero-dark + .statband{ padding-top: var(--space-10, 40px); }
.hero-dark + .statband .statband-in{ border-top:0; }

/* ---- stat band ----
   The reference puts three enormous figures on a quiet rule directly under the
   hero, and it works because the eye lands on them before any prose. Same
   shape here; the numbers are ones we can stand behind. */
.statband{ padding: var(--space-8) 0 var(--space-6); }
.statband-in{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(10rem,1fr));
  gap: var(--space-6); max-width:58rem; margin:0 auto;
  padding: var(--space-6) 0; border-block:1px solid var(--line);
}
.stat{ text-align:center; }
.stat b{
  display:block; font-size: clamp(2.4rem, 1.8rem + 2.6vw, 3.4rem);
  font-weight:600; line-height:1; letter-spacing:-.035em;
  color: var(--color-primary); font-variant-numeric:tabular-nums;
}
.stat span{
  display:block; margin-top:8px; font-size:.83rem; color: var(--fg-muted);
  line-height:1.45; max-width:11em; margin-inline:auto;
}

/* four proof points as cards rather than a list — the reference's
   differentiator row, which reads faster than stacked text */
.proof-cards{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));
  gap: var(--space-4);
}
.proof-cards .proof-i{
  /* The icon sits beside the text on the heading's own line rather than in a
     tile stacked above it. It used to also carry a 3px rule in the brand accent
     down its left edge, added to make the card look less generic — but a thick
     coloured tab on one side of a card is itself the stock template shape, and
     against a 20px radius it read as a crescent rather than a rule. The card
     now rests exactly like .tc-group and .dc-card, which it already shares its
     lift and transition with: raised surface, one hairline, one radius. The
     accent is still here, it just waits for the pointer — :hover below takes
     the border to --brand-accent-light. Markup untouched. */
  flex-direction:row; align-items:flex-start; gap: var(--space-3);
  padding: var(--space-5);
  background: var(--surface-raised); border:1px solid var(--line);
  border-radius: var(--radius-lg);
  transition: border-color .16s ease, transform .16s ease, box-shadow .16s ease;
}
.proof-cards .proof-i:hover{
  border-color: var(--brand-accent-light);
  transform: translateY(-2px);
  box-shadow: 0 10px 26px -18px rgba(21,23,27,.3);
}
.proof-cards .proof-i svg{ flex:none; margin-top: 3px; }
.proof-cards .proof-i b{ display:block; font-size:.92rem; margin-bottom:4px; }
.proof-cards .proof-i span{ display:block; font-size:.83rem; color: var(--fg-muted); line-height:1.55; }

@media(prefers-reduced-motion:reduce){ .proof-cards .proof-i{ transition:none; } }
@media(max-width:560px){
  .statband-in{ grid-template-columns:repeat(2,1fr); gap: var(--space-5); }
}

/* ---- trust centre ----
   Four numbers, then three columns of controls, then the gaps. The gaps get
   the warmest treatment on the page on purpose: they are the section a serious
   buyer reads first, and burying them would defeat the point of writing them. */
.tc-facts{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));
  gap: var(--space-4); max-width:52rem; margin:0 auto;
}
.tc-fact{
  text-align:center; padding: var(--space-5) var(--space-3);
  background: var(--surface-raised); border:1px solid var(--line); border-radius: var(--radius-lg);
}
.tc-fact b{
  display:block; font-size:1.9rem; font-weight:600; letter-spacing:-.02em; line-height:1;
  color: var(--color-primary); font-variant-numeric:tabular-nums;
}
.tc-fact span{ display:block; margin-top:6px; font-size:.79rem; color: var(--fg-muted); line-height:1.45; }

.tc-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(19rem,1fr)); gap: var(--space-6); }
.tc-group{
  background: var(--surface-raised); border:1px solid var(--line);
  border-radius: var(--radius-xl); padding: var(--space-6);
}
.tc-group h3{ margin:0 0 4px; font-size:1.02rem; }
.tc-note{ margin:0 0 var(--space-4); font-size:.82rem; color: var(--fg-muted); line-height:1.5; }
.tc-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap: var(--space-4); }
.tc-list li{ display:flex; gap:10px; align-items:flex-start; }
.tc-tick{
  flex:none; width:19px; height:19px; margin-top:2px; border-radius:50%;
  background:#E9F3EC; color:#2E6F4E; display:grid; place-items:center;
}
.tc-tick svg{ width:11px; height:11px; }
.tc-list b{ display:block; font-size:.87rem; font-weight:600; line-height:1.4; }
.tc-list em{ display:block; font-style:normal; font-size:.8rem; color: var(--fg-muted);
  line-height:1.55; margin-top:2px; }

.tc-table{ max-width:46rem; margin:0 auto; overflow-x:auto; }
.tc-table table{ width:100%; border-collapse:collapse; background: var(--surface-raised);
  border:1px solid var(--line); border-radius: var(--radius-lg); overflow:hidden; }
.tc-table th,.tc-table td{ padding: var(--space-4); text-align:left; font-size:.86rem;
  border-bottom:1px solid var(--line); }
.tc-table th{ font-size:.74rem; text-transform:uppercase; letter-spacing:.05em;
  color: var(--fg-muted); font-weight:600; background: var(--surface-sunken); }
.tc-table tr:last-child td{ border-bottom:0; }

.tc-gaps{ display:flex; flex-direction:column; gap: var(--space-4); max-width:46rem; margin:0 auto; }
.tc-gap{
  padding: var(--space-5); border-radius: var(--radius-lg);
  background:#FDF7EC; border:1px solid #EFE0C4;
}
.tc-gap b{ display:block; font-size:.94rem; font-weight:600; color:#5C4A28; margin-bottom:4px; }
.tc-gap span{ display:block; font-size:.85rem; color:#7A6742; line-height:1.6; }
.tc-gap a{ color:#5C4A28; }

@media(max-width:560px){
  .tc-group{ padding: var(--space-5); }
  .tc-fact b{ font-size:1.6rem; }
}

/* ---- how it goes ----
   A numbered sequence rather than four equal cards, because the claim is that
   these happen in an order. The connecting rule is drawn between the markers
   rather than behind them, so it cannot show through a translucent number. */
.wsteps{ display:grid; gap: var(--space-5); max-width:40rem; margin:0 auto; }
.wstep{ display:grid; grid-template-columns:auto 1fr; gap: var(--space-4); align-items:start;
  position:relative; }
.wstep:not(:last-child)::before{
  content:''; position:absolute; left:19px; top:44px; bottom:calc(var(--space-5) * -1);
  width:2px; background: var(--line);
}
/* .wstep .wstep-n, not .wstep-n. The description rule below is
   `.wstep span` — one class plus one type, 0,1,1 — which outranks a bare
   class at 0,1,0. So the step number was being painted in muted grey on
   its own near-black circle: four blank discs where 1 2 3 4 should be.
   Same pattern as .feat-list .fic, which was written this way already. */
.wstep .wstep-n{
  width:40px; height:40px; flex:none; border-radius:50%;
  display:grid; place-items:center; position:relative; z-index:1;
  background: var(--brand-ink); color: var(--brand-paper);
  font-family: var(--font-mono); font-size:.9rem; font-weight:600;
}
.wstep b{ display:block; font-size:1rem; margin-bottom:3px; }
/* Scoped to the inner div so it can never reach the number again. The
   44ch cap also made the column look left-hung inside a 46rem box; the
   box is now the width of its own content. */
.wstep > div span{ display:block; font-size:.87rem; color: var(--fg-muted); line-height:1.6; }

/* ---- the five services, as a plain list of what each one is ---- */
.wserv{ display:grid; grid-template-columns:repeat(auto-fit,minmax(15rem,1fr)); gap: var(--space-4); }
.wserv-i{
  padding: var(--space-5); border:1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface-raised); box-shadow: var(--lift-rest);
  transition: transform .18s var(--ease), box-shadow .18s var(--ease);
}
.wserv-i:hover{ transform: translateY(-3px); box-shadow: var(--lift-hover); }
.wserv-top{ display:flex; align-items:baseline; justify-content:space-between; gap:10px; margin-bottom:6px; }
.wserv-top b{ font-size:.95rem; }
.wserv-top span{
  font-family: var(--font-mono); font-size:.85rem; font-weight:600;
  font-variant-numeric: tabular-nums; white-space:nowrap;
}
.wserv-top em{ font-style:normal; font-size:.7rem; color: var(--fg-muted); margin-left:2px; }
.wserv-i p{ margin:0; font-size:.84rem; color: var(--fg-muted); line-height:1.6; }

@media (prefers-reduced-motion: reduce){ .wserv-i{ transition:none; } }
@media (max-width:560px){
  .wstep{ gap: var(--space-3); }
  .wstep:not(:last-child)::before{ left:17px; }
  .wstep-n{ width:36px; height:36px; }
}

/* ---- website service picker ----
   Each row is a <label> wrapping its checkbox, so the whole row is a hit target
   and the state stays in the input rather than in a variable that has to be
   kept in sync with it. No JavaScript is involved in the click itself. */
.plan-project .wx{
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}
.wx-head{ font-size:.85rem; font-weight:600; }
.wx-note{ margin:2px 0 var(--space-4); font-size:.78rem; color: var(--fg-muted); }
.wx-row{
  display:grid; grid-template-columns:auto 1fr auto; align-items:start; gap:10px;
  padding:10px 12px; margin-bottom:6px;
  border:1px solid var(--line); border-radius: var(--radius-md);
  cursor:pointer; background: var(--surface-raised);
  transition: border-color .14s var(--ease), background .14s var(--ease);
}
.wx-row:hover{ border-color: var(--brand-accent-light); }
.wx-row.on{ border-color: var(--color-primary); background: #F6FAFC; }
.wx-row input{ margin-top:3px; width:16px; height:16px; accent-color: var(--color-primary); cursor:pointer; }
.wx-body{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.wx-body b{ font-size:.86rem; font-weight:600; }
.wx-body span{ font-size:.77rem; color: var(--fg-muted); line-height:1.5; }
.wx-price{
  font-family: var(--font-mono); font-size:.8rem;
  font-variant-numeric: tabular-nums; color: var(--fg); white-space:nowrap;
  padding-top:1px;
}
.wx-total{
  display:flex; align-items:baseline; justify-content:flex-end; gap:6px;
  margin-top: var(--space-4); padding-top: var(--space-4);
  border-top:1px solid var(--line);
}
.wx-total b{
  font-family: var(--font-mono);
  font-size:1.25rem; font-weight:600; font-variant-numeric: tabular-nums;
}
.wx-total span{ font-size:.8rem; color: var(--fg-muted); }
/* Shown only when nothing is ticked, because "0 kr / month afterwards" reads
   as a bug rather than as the offer it actually is. */
.wx-none{ margin: var(--space-2) 0 0; font-size:.8rem; color: var(--fg-muted); text-align:right; }

/* A project card carries a configurator, so it runs taller than a seat card.
   Letting it stretch keeps the three cards' footers on one line. */
.plan-project{ display:flex; flex-direction:column; }
.plan-project .cta{ margin-top:auto; }

@media (prefers-reduced-motion: reduce){ .wx-row{ transition:none; } }

/* ---- team-size slider ----
   The one control on the page that has to feel good under a finger, because
   its whole job is to let somebody watch the per-seat number fall. */
.seatbar{
  max-width: 46rem; margin: 0 auto var(--space-8);
  background: var(--surface-raised); border: 1px solid var(--line);
  border-radius: var(--radius-xl); padding: var(--space-6) var(--space-8) var(--space-5);
  box-shadow: 0 1px 2px rgba(21,23,27,.04), 0 12px 32px -22px rgba(21,23,27,.18);
}
.seatbar-top{ display:flex; align-items:baseline; justify-content:space-between; gap: var(--space-4); }
.seatbar-top label{ font-size:.95rem; font-weight:600; }
.seat-n{
  font-family: var(--font-mono);
  font-size: 1.5rem; font-weight: 600; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--color-primary);
}

/* A range input cannot be styled as one piece across engines, so the track is
   painted with a gradient stop at --fill and the thumb drawn per vendor. */
#seat-range{
  -webkit-appearance:none; appearance:none;
  width:100%; height: 6px; margin: var(--space-4) 0 var(--space-2);
  border-radius: var(--radius-pill); cursor: pointer; background: transparent;
}
#seat-range::-webkit-slider-runnable-track{
  height:6px; border-radius:var(--radius-pill);
  background: linear-gradient(90deg, var(--color-primary) var(--fill,20%), var(--surface-sunken) var(--fill,20%));
}
#seat-range::-moz-range-track{ height:6px; border-radius:var(--radius-pill); background: var(--surface-sunken); }
#seat-range::-moz-range-progress{ height:6px; border-radius:var(--radius-pill); background: var(--color-primary); }
#seat-range::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none;
  width:24px; height:24px; margin-top:-9px; border-radius:50%;
  background: var(--surface-raised); border:2px solid var(--color-primary);
  box-shadow: 0 1px 3px rgba(21,23,27,.2);
  transition: transform .12s ease, box-shadow .12s ease;
}
#seat-range::-moz-range-thumb{
  width:22px; height:22px; border-radius:50%;
  background: var(--surface-raised); border:2px solid var(--color-primary);
  box-shadow: 0 1px 3px rgba(21,23,27,.2);
}
#seat-range:hover::-webkit-slider-thumb{ transform: scale(1.08); }
#seat-range:active::-webkit-slider-thumb{ transform: scale(1.14); box-shadow: 0 0 0 6px rgba(47,109,147,.14); }
/* No outline:none here any more. The thumb ring below is webkit-only, so
   suppressing the real outline left Firefox with no indicator at all on
   the one control on /pricing the page invites you to drag. */
#seat-range:focus-visible::-webkit-slider-thumb{ box-shadow: 0 0 0 4px rgba(47,109,147,.28); }

.seat-scale{
  /* Absolute, not space-between: each label sits at its own value's
     position on the track, so the thumb and the number under it agree. */
  position:relative; height:1.2em;
  font-size:.72rem; color: var(--fg-muted); font-variant-numeric: tabular-nums;
}
.seat-scale span{ position:absolute; transform:translateX(-50%); }
/* The outer two would hang off the ends if they were centred. */
.seat-scale span:first-child{ transform:none; }
.seat-scale span:last-child{ transform:translateX(-100%); }
.seat-out{ margin-top: var(--space-5); padding-top: var(--space-5); border-top:1px solid var(--line); text-align:center; }
.seat-total{ display:flex; align-items:baseline; justify-content:center; gap:8px; flex-wrap:wrap; }
.seat-total b{ font-size: clamp(1.8rem, 1.4rem + 1.4vw, 2.4rem); font-weight:600; letter-spacing:-.02em; line-height:1; }
.seat-total span{ font-size:.9rem; color: var(--fg-muted); }
.seat-save{ margin: var(--space-2) 0 0; font-size:.85rem; color: var(--fg-muted); }
.seat-save b{ color: #2E6F4E; font-weight:600; }
.seat-ent{ margin: var(--space-3) 0 0; font-size:.85rem; color: var(--fg-muted); }

/* what a team of this size pays in total, under the per-seat headline */
.plan .ptotal{ font-size:.85rem; color: var(--fg); margin-top: 2px; }
.plan .ptotal b{ font-weight:600; }

@media (max-width: 560px){
  .seatbar{ padding: var(--space-5) var(--space-5) var(--space-4); }
  .seatbar-top{ flex-direction:column; gap: var(--space-1); align-items:flex-start; }
}
@media (prefers-reduced-motion: reduce){
  #seat-range::-webkit-slider-thumb{ transition:none; }
}

/* -------------------------------------------------------- compare table
   Four columns of prose cannot fit a phone. Without this wrapper the table
   simply overflowed its section and the right-hand columns were clipped off
   the page — the comparison was unreadable on mobile, which is most of the
   traffic that reaches a "why us" page. */
.cmp-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: var(--rad); }
.cmp { width: 100%; min-width: 620px; border-collapse: collapse; background: var(--card); border: 1px solid var(--line); border-radius: var(--rad); overflow: hidden; }
.cmp th, .cmp td { padding: var(--space-4); text-align: left; font-size: .9375rem; border-bottom: 1px solid var(--line2); }
.cmp thead th { background: var(--navy); color: var(--fg-inverse); font-family: var(--mono); font-size: .7rem; font-weight: var(--weight-medium); text-transform: uppercase; letter-spacing: var(--tracking-label); }
.cmp thead th.us { background: var(--p); }
.cmp td:first-child { font-weight: var(--weight-semi); color: var(--navy); }
.cmp .yes { color: var(--green); font-weight: var(--weight-semi); }
.cmp .no { color: var(--color-bad); font-weight: var(--weight-semi); }
.cmp .mid { color: var(--gold); font-weight: var(--weight-semi); }
.cmp tbody tr:hover { background: var(--bg2); }

/* ----------------------------------------------------------- trust/quote */
.trust { display: flex; align-items: center; justify-content: center; gap: var(--space-8); flex-wrap: wrap; }
.trust .tl { font-weight: var(--weight-semi); font-size: 1.05rem; color: var(--soft); }
.quote { max-width: 52rem; margin-inline: auto; text-align: center; }
.quote blockquote { font-size: clamp(1.25rem, 1rem + 1.1vw, 1.875rem); line-height: var(--leading-snug); letter-spacing: var(--tracking-tight); color: var(--navy); font-weight: var(--weight-medium); }
.quote .qby { margin-top: var(--space-5); display: flex; align-items: center; justify-content: center; gap: var(--space-3); font-size: .9rem; color: var(--slate); }
.quote .qav { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; }
.quote .qby b { color: var(--navy); }

/* --------------------------------------------------------------- pricing */
.seg { display: inline-flex; gap: var(--space-1); padding: var(--space-1); background: var(--bg2); border: 1px solid var(--line); border-radius: var(--radius-md); }
.seg button { border: 0; background: none; cursor: pointer; font: inherit; font-weight: var(--weight-semi); font-size: .875rem; padding: var(--space-2) var(--space-4); border-radius: var(--radius-sm); color: var(--slate); transition: background var(--duration-fast), color var(--duration-fast); }
.seg button.on { background: var(--card); color: var(--navy); box-shadow: var(--shadow-sm); }
.cur-sel, .lang-sel { border: 1px solid var(--line); border-radius: var(--radius-md); padding: var(--space-2) var(--space-3); font: inherit; font-size: .875rem; font-weight: var(--weight-medium); background: var(--card); color: var(--navy); cursor: pointer; }

.plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6); align-items: stretch; margin-top: var(--space-8); }
@media (max-width: 980px) { .plans { grid-template-columns: 1fr; max-width: 30rem; margin-inline: auto; } }
.plan { position: relative; display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-xl); padding: var(--space-8) var(--space-6); transition: border-color var(--duration-base) var(--ease), box-shadow var(--duration-base) var(--ease); }
.plan:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); }
.plan.pop { border-color: var(--p); box-shadow: 0 0 0 1px var(--p); }
.plan.pop:hover { box-shadow: 0 0 0 1px var(--p), var(--shadow-md); }
.pop-tag { position: absolute; top: 0; left: var(--space-6); transform: translateY(-50%); background: var(--p); color: var(--fg-on-accent); font-family: var(--mono); font-size: .65rem; text-transform: uppercase; letter-spacing: .08em; padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill); }
.plan h3 { font-size: 1.25rem; }
.pdesc { font-size: .875rem; color: var(--slate); margin: var(--space-2) 0 var(--space-4); min-height: 3.1em; }
.price { display: flex; align-items: baseline; gap: var(--space-2); }
.price .amt { font-size: 2.5rem; font-weight: var(--weight-semi); letter-spacing: var(--tracking-display); color: var(--navy); font-variant-numeric: tabular-nums; }
.price .per { font-family: var(--mono); font-size: .75rem; color: var(--soft); }
.billed { font-family: var(--mono); font-size: .72rem; color: var(--soft); margin: var(--space-1) 0 var(--space-4); }
.plan ul { list-style: none; display: grid; gap: var(--space-3); margin-bottom: var(--space-6); flex: 1 1 auto; align-content: start; }
.plan li { display: flex; gap: var(--space-2); align-items: flex-start; font-size: .875rem; color: var(--slate); }
.plan li svg { flex: none; margin-top: 3px; }
.plan .cta { margin-top: auto; }
.plan .cta .btn { width: 100%; padding: var(--space-4); font-size: .9375rem; }
.plan .cta-note { text-align: center; font-family: var(--mono); font-size: .7rem; color: var(--soft); margin-top: var(--space-2); }
.buy-strip { position: sticky; bottom: 0; z-index: var(--z-sticky); background: rgba(255,255,255,.92); backdrop-filter: blur(12px); border-top: 1px solid var(--line); padding: var(--space-3) 0; margin-top: var(--space-8); }
.buy-strip .inner { display: flex; align-items: center; justify-content: center; gap: var(--space-4); flex-wrap: wrap; }
.buy-strip b { font-size: .9375rem; color: var(--navy); }
.buy-strip span { font-size: .8125rem; color: var(--soft); }
.guarantee { display: flex; align-items: center; justify-content: center; gap: var(--space-6); flex-wrap: wrap; margin-top: var(--space-6); }
.guarantee span { display: inline-flex; align-items: center; gap: var(--space-2); font-size: .875rem; color: var(--slate); font-weight: var(--weight-medium); }

/* ------------------------------------------------------------------- FAQ */
.faq-list { max-width: 50rem; margin-inline: auto; display: grid; gap: var(--space-3); }
.faq-item { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; }
.faq-item.open { border-color: var(--border-strong); }
.faq-q { width: 100%; display: flex; justify-content: space-between; align-items: center; gap: var(--space-4); text-align: left; background: none; border: 0; cursor: pointer; font: inherit; font-weight: var(--weight-semi); font-size: 1rem; color: var(--navy); padding: var(--space-5) var(--space-6); }
.faq-q::after { content: '+'; font-size: 1.3rem; font-weight: 400; color: var(--p); line-height: 1; }
.faq-item.open .faq-q::after { content: '−'; }
/* max-height:0 hid an answer from the eye and from nobody else: the panel
   still computed display:block, visibility:visible, so all eight answers sat
   in the accessibility tree at once and a screen reader read the FAQ as one
   wall of text with no questions in it. [hidden] is the real thing, and it
   also retires the max-height/padding transition - two layout properties
   animated on every toggle, which is what the design pass flagged. */
.faq-a { overflow: hidden; padding: 0 var(--space-6) var(--space-5); font-size: .9375rem; color: var(--slate); }
.faq-a[hidden] { display: none; }

/* -------------------------------------------------------------- CTA band */
.cta-band { background: var(--navy); color: var(--fg-inverse); border-radius: var(--radius-xl); padding: var(--space-16) var(--space-12); text-align: center; }
.cta-band h2 { color: var(--fg-inverse); }
.cta-band p { color: rgba(250,249,246,.72); max-width: 34em; margin: var(--space-3) auto var(--space-6); }
@media (max-width: 700px) { .cta-band { padding: var(--space-12) var(--space-6); } }

/* ---------------------------------------------------- demo / hours / proof */
.demo-band { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }
.demo-card { display: block; }
.demo-card .dc-badge { display: inline-flex; align-items: center; gap: var(--space-2); font-family: var(--mono); font-size: .65rem; text-transform: uppercase; letter-spacing: .08em; color: var(--green); background: var(--color-ok-soft); border-radius: var(--radius-pill); padding: var(--space-1) var(--space-3); margin-bottom: var(--space-3); }
.demo-card .dc-badge .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); }
.demo-card h3 { font-size: 1.1875rem; margin-bottom: var(--space-2); }
.demo-card p { font-size: .9375rem; margin-bottom: var(--space-4); }
.demo-card .dc-go { display: inline-flex; align-items: center; gap: var(--space-2); font-weight: var(--weight-semi); font-size: .9375rem; color: var(--p); }
.demo-card .dc-go svg { transition: transform var(--duration-base) var(--ease); }
.demo-card:hover .dc-go svg { transform: translateX(4px); }

.hours, .bpts { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-5); }
.hour { text-align: center; }
.hour .hn { font-size: 2.25rem; font-weight: var(--weight-semi); letter-spacing: var(--tracking-display); color: var(--navy); line-height: 1; font-variant-numeric: tabular-nums; }
.hour .hu { font-family: var(--mono); font-size: .7rem; text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--p); margin: var(--space-2) 0; }
.hour .hl { font-size: .875rem; color: var(--slate); line-height: 1.5; }
.hours-note { text-align: center; font-size: .8125rem; color: var(--soft); margin-top: var(--space-4); max-width: 56em; margin-inline: auto; }

.proof { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); }
.proof-i { display: flex; gap: var(--space-3); align-items: flex-start; padding: var(--space-4); }
.proof-i svg { flex: none; margin-top: 2px; }
.proof-i b { display: block; font-size: .875rem; color: var(--ink); margin-bottom: var(--space-1); }
.proof-i span { font-size: .8125rem; color: var(--soft); line-height: 1.5; }

.loop4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); text-align: center; }
@media (max-width: 900px) { .demo-band, .hours, .proof, .bpts { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 820px) { .loop4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .demo-band, .hours, .proof, .bpts, .loop4 { grid-template-columns: 1fr; } }

.stat-row { display: flex; gap: var(--space-12); flex-wrap: wrap; margin-top: var(--space-8); }
.stat .sn { font-size: 2.25rem; font-weight: var(--weight-semi); letter-spacing: var(--tracking-display); color: var(--navy); line-height: 1; font-variant-numeric: tabular-nums; }
.stat .sl { font-family: var(--mono); font-size: .7rem; text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--soft); margin-top: var(--space-2); }

/* ---------------------------------------------------------------- footer */
footer.site { background: var(--navy); color: rgba(250,249,246,.7); }
.foot-top { padding: var(--space-16) 0 var(--space-8); }
/* Five rigid columns squeezed the link lists to about eleven characters, so
   "DPA & sub-processors" and "Refer a friend" wrapped onto two lines while the
   brand column had room to spare. Letting the link columns size to their own
   content fixes both ends of that. */
.foot-grid {
  display: grid;
  grid-template-columns: minmax(15rem, 1.6fr) repeat(3, max-content) minmax(16rem, 1.2fr);
  gap: var(--space-12) var(--space-8);
  align-items: start;
}
@media (max-width: 1100px) {
  .foot-grid { grid-template-columns: repeat(3, 1fr); }
  .foot-grid > :first-child, .foot-grid > .fnews { grid-column: 1 / -1; }
}
@media (max-width: 640px) { .foot-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 920px) { .foot-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .foot-grid { grid-template-columns: 1fr; } }
footer.site h3 { color: var(--fg-inverse); font-family: var(--mono); font-size: .7rem; font-weight: var(--weight-medium); letter-spacing: var(--tracking-label); text-transform: uppercase; margin-bottom: var(--space-4); }
footer.site a {
  display: block; color: rgba(250,249,246,.68); font-size: .875rem;
  padding-block: 5px; width: fit-content;
  transition: color var(--duration-fast) var(--ease), transform var(--duration-fast) var(--ease);
}
footer.site a:hover { color: var(--fg-inverse); transform: translateX(2px); }
/* The headings were the same weight as the links they label. */
footer.site h4 + a { margin-top: 2px; }
footer.site .flogo { display: flex; align-items: center; gap: .31em; color: var(--fg-inverse); font-weight: var(--weight-semi); font-size: 1.1rem; letter-spacing: var(--tracking-display); margin-bottom: var(--space-3); }
footer.site .fdesc { font-size: .9rem; color: rgba(250,249,246,.6); max-width: 26em; line-height: var(--leading-loose); }
.made-dk { display: inline-flex; align-items: center; gap: var(--space-2); margin-top: var(--space-4); font-family: var(--mono); font-size: .7rem; color: rgba(250,249,246,.72); background: rgba(250,249,246,.06); border: 1px solid rgba(250,249,246,.12); padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill); }
.fsoc { display: flex; gap: var(--space-2); margin-top: var(--space-4); }
.fsoc a { width: 34px; height: 34px; border-radius: var(--radius-sm); background: rgba(250,249,246,.07); display: grid; place-items: center; padding: 0; }
.fsoc a:hover { background: var(--p); }
.fnews p { font-size: .85rem; color: rgba(250,249,246,.6); margin-bottom: var(--space-3); }
.fnews .nrow { display: flex; gap: var(--space-2); }

/* Visible to a screen reader, invisible on screen. The footer newsletter field
   had a placeholder and no label, which is a hint rather than a name - and a
   placeholder disappears the moment somebody starts typing into it. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}
.fnews input { flex: 1; min-width: 0; background: rgba(250,249,246,.07); border: 1px solid rgba(250,249,246,.16); color: var(--fg-inverse); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); font: inherit; font-size: .85rem; }
/* .45 measured 4.34:1 against the footer ground, under the 4.5:1 floor for
   text this size. .62 clears it and still reads as a placeholder. */
.fnews input::placeholder { color: rgba(250,249,246,.62); }
.fnews button { background: var(--p); color: var(--fg-on-accent); border: 0; border-radius: var(--radius-sm); padding: 0 var(--space-4); font: inherit; font-weight: var(--weight-semi); font-size: .85rem; cursor: pointer; }
.fmail { display: inline-block; margin-top: var(--space-4); font-size: .875rem; font-weight: var(--weight-semi); color: var(--brand-accent-light); border-bottom: 1px solid rgba(127,178,206,.35); padding-bottom: 2px; }
.fmail:hover { color: var(--fg-inverse); border-color: var(--fg-inverse); }
/* .fbottom itself is declared once, in the footer block further down — every
   property it set here was re-set there, so this copy computed to nothing. */
/* On anything narrower than a laptop the badges get their own line rather than
   fighting the copyright for the same one. */
@media (max-width: 860px) { .fbottom { justify-content: flex-start; } .fbottom .ftrust { order: -1; width: 100%; } }
.fbottom .fb-links { display: flex; flex-wrap: wrap; }
.fbottom .fb-links a { display: inline-block; color: rgba(250,249,246,.55); padding: 0 var(--space-3); border-left: 1px solid rgba(250,249,246,.16); }
.fbottom .fb-links a:first-child { border-left: 0; padding-left: 0; }
.fbottom .fb-links a:hover { color: var(--fg-inverse); }

/* The statement band. Its height lives here rather than inline so it can shrink
   when the columns stack — beside a paragraph 340px reads as a panel, under one
   it reads as a large empty rectangle with two lines in it. */
.split-media .photo-band { min-height: 340px; }
@media (max-width: 900px) {
  .split-media .photo-band { min-height: 0; padding-block: var(--space-12); }
}

/* Product visuals, self-hosted.
   Stock photography of people pointing at laptops was removed for two reasons
   and neither has changed: it says nothing about the product, and it was served
   from a US CDN on a site whose argument is EU data residency. These are SVG,
   drawn from the real interface, on our own domain — so they stay sharp at any
   size, weigh a few kilobytes, and the claim in the footer stays true. */
.shot-fig { margin: 0; }
.shot-fig img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line); border-radius: var(--radius-xl);
  box-shadow: var(--shadow-md); background: var(--card);
}
.shot-fig figcaption {
  margin-top: var(--space-3); font-size: .8125rem; line-height: var(--leading-loose);
  color: var(--soft);
}

/* Trust row. Two claims, both of which we can actually stand behind and both of
   which link to the evidence — the DPA page and Stripe's own page. A badge that
   links nowhere is decoration; one that links to the proof is an argument. */
/* .ftrust's layout is re-declared verbatim further down; only the pill styling
   below survives the cascade, so the layout line is kept in one place. */
.ftrust a {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-size: .75rem; font-weight: var(--weight-medium);
  color: rgba(250,249,246,.62);
  border: 1px solid rgba(250,249,246,.16); border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  transition: border-color var(--duration-fast), color var(--duration-fast);
}
.ftrust a:hover { color: var(--fg-inverse); border-color: rgba(250,249,246,.42); }
.ftrust svg { flex: none; opacity: .8; }
@media (max-width: 720px) { .ftrust { width: 100%; } }

/* -------------------------------------------------------- page hero/prose */
.page-hero { padding: var(--space-16) 0 var(--space-8); background: var(--bg); border-bottom: 1px solid var(--line); }
.page-hero .eyebrow { display: block; margin-bottom: var(--space-2); }
.page-hero h1 { font-size: clamp(2rem, 1.4rem + 2.4vw, 3rem); }
.page-hero p { margin-top: var(--space-3); max-width: 40em; }
.about-hero { background: var(--navy); color: var(--fg-inverse); padding: var(--space-16) 0; }
.about-hero .eyebrow { color: var(--brand-accent-light); }
.about-hero h1 { color: var(--fg-inverse); max-width: 14em; }
.about-hero p { color: rgba(250,249,246,.72); max-width: 40em; margin-top: var(--space-4); }

.prose { max-width: 48rem; margin-inline: auto; }
.prose h2 { font-size: 1.5rem; margin: var(--space-12) 0 var(--space-3); }
.prose h3 { font-size: 1.125rem; margin: var(--space-6) 0 var(--space-2); }
.prose p, .prose li { color: var(--slate); margin-bottom: var(--space-3); }
.prose ul, .prose ol { margin: var(--space-3) 0 var(--space-3) var(--space-6); }
.prose a { color: var(--p); font-weight: var(--weight-semi); }
.prose .updated { font-family: var(--mono); font-size: .75rem; color: var(--soft); margin-bottom: var(--space-5); }
.prose .toc { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-md); padding: var(--space-4) var(--space-5); margin: var(--space-4) 0 var(--space-6); }
.prose .toc a { display: inline-block; margin: var(--space-1) var(--space-3) var(--space-1) 0; font-size: .875rem; }

.pol-meta { font-family: var(--mono); font-size: .75rem; color: var(--soft); margin-top: var(--space-4); border-top: 1px solid var(--line); padding-top: var(--space-3); display: inline-block; }
.pol-wrap { display: grid; grid-template-columns: 250px 1fr; gap: var(--space-12); align-items: start; }
.pol-toc { position: sticky; top: 88px; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: var(--space-4); max-height: calc(100vh - 120px); overflow: auto; }
.pol-toc h4 { font-family: var(--mono); font-size: .7rem; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--soft); margin-bottom: var(--space-2); }
.pol-toc a { display: block; font-size: .8125rem; color: var(--slate); padding: var(--space-1) var(--space-2); border-radius: var(--radius-xs); line-height: 1.4; }
.pol-toc a:hover { background: var(--bg2); color: var(--navy); }
.pol-body h2 { font-size: 1.125rem; font-weight: var(--weight-semi); color: var(--navy); margin: var(--space-8) 0 var(--space-3); padding-top: var(--space-4); border-top: 1px solid var(--line2); }
.pol-body h2:first-child { margin-top: 0; border-top: 0; padding-top: 0; }
.pol-body p { font-size: .875rem; line-height: 1.75; color: var(--slate); margin-bottom: var(--space-3); }
.pol-body b { color: var(--ink); font-weight: var(--weight-semi); }
@media (max-width: 960px) { .pol-wrap { grid-template-columns: 1fr; gap: var(--space-6); } .pol-toc { position: static; max-height: none; } }

/* ------------------------------------------------------------------ forms */
.cform label, .ct-form label, .modal label { display: block; font-size: .78rem; font-weight: var(--weight-semi); color: var(--slate); margin: var(--space-3) 0 var(--space-2); }
.cform input, .cform textarea, .cform select,
.ct-form input, .ct-form textarea, .ct-form select,
.help-search input, .modal input {
  width: 100%; font: inherit; font-size: .9375rem;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line); border-radius: var(--radius-md);
  background: var(--card); color: var(--ink);
  transition: border-color var(--duration-fast), box-shadow var(--duration-fast);
}
.cform input:focus, .cform textarea:focus, .ct-form input:focus,
.ct-form select:focus, .ct-form textarea:focus, .modal input:focus {
  border-color: var(--p); box-shadow: var(--shadow-focus);
}
.ct-form { max-width: 48rem; margin-inline: auto; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-xl); padding: var(--space-8); }
.cf-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.cf-send { display: flex; align-items: center; gap: var(--space-4); margin-top: var(--space-6); flex-wrap: wrap; }
.cf-note { font-family: var(--mono); font-size: .75rem; color: var(--soft); }
.help-search { max-width: 36rem; margin-inline: auto; }
@media (max-width: 700px) { .cf-row { grid-template-columns: 1fr; } .ct-form { padding: var(--space-6); } }

.ct-routes { display: grid; gap: var(--space-3); margin-top: var(--space-5); }
.ct-route { display: flex; gap: var(--space-4); align-items: flex-start; padding: var(--space-4) var(--space-5); border-radius: var(--radius-lg); }
.ct-route:hover { transform: translateX(3px); }
.ct-route .ct-ic { flex: none; width: 38px; height: 38px; border-radius: var(--radius-md); background: var(--pl); color: var(--pd); display: grid; place-items: center; font-weight: var(--weight-semi); font-size: .95rem; }
.ct-route b { display: block; font-size: .9375rem; color: var(--ink); margin-bottom: var(--space-1); }
.ct-route span span { display: block; font-size: .85rem; color: var(--slate); line-height: 1.5; }

/* ------------------------------------------------------------ about page */
.timeline { max-width: 48rem; margin-inline: auto; position: relative; padding-left: var(--space-8); }
.timeline::before { content: ''; position: absolute; left: 7px; top: 6px; bottom: 6px; width: 2px; background: var(--line); }
.tl-item { position: relative; padding-bottom: var(--space-6); }
.tl-item::before { content: ''; position: absolute; left: calc(-1 * var(--space-8) + 2px); top: 6px; width: 12px; height: 12px; border-radius: 50%; background: var(--p); box-shadow: 0 0 0 4px var(--pl); }
.tl-item .yr { font-family: var(--mono); font-size: .875rem; color: var(--p); font-weight: var(--weight-medium); }
.tl-item h3 { font-size: 1.0625rem; margin: var(--space-1) 0; }
.tl-item p { font-size: .9rem; }
.founder { text-align: center; }
.founder .av { width: 64px; height: 64px; border-radius: 50%; margin: 0 auto var(--space-3); background: var(--p); color: var(--fg-on-accent); display: grid; place-items: center; font-weight: var(--weight-semi); font-size: 1.25rem; }
.founder b { display: block; color: var(--navy); }
.founder span { font-family: var(--mono); font-size: .75rem; color: var(--soft); }

/* ------------------------------------------------------ language picker */
.lang { position: relative; }
.lang-btn { display: flex; align-items: center; gap: var(--space-2); border: 1px solid var(--line); background: var(--card); color: var(--navy); border-radius: var(--radius-md); padding: var(--space-2) var(--space-3); font: inherit; font-size: .78rem; font-weight: var(--weight-semi); cursor: pointer; transition: border-color var(--duration-fast); }
.lang-btn:hover { border-color: var(--border-strong); }
.lang-btn svg { opacity: .55; }
.lb-sep { width: 1px; height: 11px; background: var(--line); display: inline-block; }
.lb-cur { color: var(--soft); }
.lb-chev { opacity: .45; }
.lang-pop { position: absolute; right: 0; top: calc(100% + var(--space-2)); width: 290px; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--sh2); padding: var(--space-3); opacity: 0; visibility: hidden; transform: translateY(-6px); transition: opacity var(--duration-base) var(--ease), transform var(--duration-base) var(--ease), visibility var(--duration-base); z-index: var(--z-dropdown); }
.lang-pop.open { opacity: 1; visibility: visible; transform: none; }
/* .68rem was 10.88px. These two are the group labels inside the picker — SPROG
   and VALUTA — so they are the names of the two menus, not decoration, and they
   belong above the 11px floor like the other mono micro-labels. The picker is
   built by site.js, which is why a scan of the page source alone does not find
   this one: it only exists once the header script has run. */
.lp-h { font-family: var(--mono); font-size: .7rem; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--soft); margin: 0 var(--space-1) var(--space-2); }
.lp-h2 { margin-top: var(--space-3); padding-top: var(--space-3); border-top: 1px solid var(--line2); }
.lp-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 3px; }
.lp-item { display: flex; align-items: center; gap: var(--space-2); border: 0; background: none; padding: var(--space-2); border-radius: var(--radius-sm); cursor: pointer; font: inherit; font-size: .83rem; color: var(--ink); text-align: left; }
.lp-item:hover { background: var(--bg2); }
.lp-item.on { background: var(--pl); color: var(--pd); font-weight: var(--weight-semi); }
.lp-item .fl { font-size: 1rem; line-height: 1; }
/* Machine languages. Deliberately a plain select rather than another grid of
   flags: it is a long tail, not a choice we are recommending, and the eight
   above it should stay visually first-class. */
.lp-more { display: grid; gap: var(--space-2); }
.lp-more select {
  width: 100%; font: inherit; font-size: .82rem; color: var(--ink);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--card);
}
.lp-undo {
  justify-self: start; font: inherit; font-size: .76rem; font-weight: var(--weight-semi);
  color: var(--p); background: none; border: 0; padding: 0; cursor: pointer; text-decoration: underline;
}
.lp-fine { font-size: .68rem; line-height: 1.45; color: var(--soft); margin: 0; }

.lp-cur { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.lp-cur button { border: 1px solid var(--line); background: var(--card); border-radius: var(--radius-xs); padding: var(--space-1) var(--space-2); font: inherit; font-size: .76rem; font-weight: var(--weight-semi); color: var(--slate); cursor: pointer; }
.lp-cur button.on { background: var(--navy); border-color: var(--navy); color: var(--fg-inverse); }
@media (max-width: 900px) { .lang-pop { right: -40px; width: 265px; } }
/* Under 560px the picker collapses to its globe and moves away from the right
   edge, so anchoring the popover to that button pushed 58px of it off the left
   of the screen at 360px — a flag and the selected currency among it, with no
   way to reach them. Positioning it against the header instead lets it span
   the page, the same full-bleed shape .mob-nav already uses. */
@media (max-width: 560px) {
  .lang { position: static; }
  .lang-pop { left: var(--space-4); right: var(--space-4); width: auto; }
}

/* ------------------------------------------------------- modal and toast */
.modal-bg { position: fixed; inset: 0; background: rgba(21,23,27,.45); z-index: var(--z-modal); display: none; align-items: flex-start; justify-content: center; padding: 9vh var(--space-4); }
.modal-bg.open { display: flex; }
.modal { background: var(--card); border-radius: var(--radius-xl); padding: var(--space-8); width: 420px; max-width: 100%; box-shadow: var(--sh2); }
#toasts { position: fixed; bottom: var(--space-5); right: var(--space-5); z-index: var(--z-toast); display: flex; flex-direction: column; gap: var(--space-2); }
.toast { background: var(--navy); color: var(--fg-inverse); font-size: .85rem; font-weight: var(--weight-medium); padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); box-shadow: var(--sh2); }
.toast.ok { background: var(--green); }

/* --------------------------------------------------- auth / login screen */
.auth-body { margin: 0; background: var(--bg); }
.auth { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1.05fr); min-height: 100vh; }
.auth-brand { position: relative; background: var(--navy); color: var(--fg-inverse); padding: var(--space-8) var(--space-12); display: flex; flex-direction: column; justify-content: space-between; overflow: hidden; }
.ab-top { display: flex; align-items: center; justify-content: space-between; }
.auth-brand .logo { color: var(--fg-inverse); font-size: 1.25rem; }
.auth-brand .lang-btn { background: rgba(250,249,246,.1); border-color: rgba(250,249,246,.24); color: var(--fg-inverse); }
.auth-brand .lb-cur { color: var(--brand-accent-light); }
.ab-mid { max-width: 30em; }
.ab-mid h2 { font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.25rem); color: var(--fg-inverse); margin-bottom: var(--space-4); max-width: 13em; }
.ab-mid > p { color: rgba(250,249,246,.72); font-size: .95rem; margin-bottom: var(--space-6); }
.bpts { list-style: none; display: grid; gap: var(--space-4); grid-template-columns: 1fr; }
.bpts li { display: flex; gap: var(--space-3); align-items: flex-start; }
.bp-ic { flex: none; width: 22px; height: 22px; border-radius: 50%; background: rgba(127,178,206,.2); color: var(--brand-accent-light); display: grid; place-items: center; font-size: .7rem; font-weight: var(--weight-semi); }
.bpts b { display: block; font-size: .9rem; color: var(--fg-inverse); }
.bpts span { font-size: .82rem; color: rgba(250,249,246,.66); line-height: 1.5; }
.ab-foot { font-size: .78rem; color: rgba(250,249,246,.55); }
.ab-foot a { color: var(--brand-accent-light); }
.ab-dot { margin: 0 var(--space-2); opacity: .5; }

.auth-form { display: flex; align-items: center; justify-content: center; padding: var(--space-12) var(--space-6); background: var(--bg); }
.auth-card { width: 100%; max-width: 400px; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-xl); padding: var(--space-8); box-shadow: var(--sh2); }
.auth-card.wide { max-width: 560px; }
.ac-badge { display: inline-block; font-family: var(--mono); font-size: .66rem; text-transform: uppercase; letter-spacing: .08em; color: var(--pd); background: var(--pl); padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill); margin-bottom: var(--space-3); }
.ac-badge.ok { color: var(--green); background: var(--color-ok-soft); }
.auth-card h1 { font-size: 1.65rem; margin-bottom: var(--space-2); }
.auth-card .sub { font-size: .9rem; color: var(--slate); margin-bottom: var(--space-5); }
.auth-card label { display: block; font-size: .78rem; font-weight: var(--weight-semi); color: var(--slate); margin: var(--space-3) 0 var(--space-2); }
.auth-card input { width: 100%; border: 1px solid var(--line); border-radius: var(--radius-md); padding: var(--space-3) var(--space-4); font: inherit; font-size: .93rem; }
.auth-card input:focus { border-color: var(--p); box-shadow: var(--shadow-focus); }
.auth-card .err { display: none; background: var(--color-bad-soft); border: 1px solid rgba(163,74,60,.25); color: var(--color-bad); border-radius: var(--radius-sm); padding: var(--space-3); font-size: .83rem; }
.pw-wrap { position: relative; }
.pw-eye { position: absolute; right: var(--space-2); top: 50%; transform: translateY(-50%); border: 0; background: none; cursor: pointer; font-size: .95rem; opacity: .45; padding: var(--space-2); }
.pw-eye:hover { opacity: .8; }
.auth-go { width: 100%; margin-top: var(--space-5); padding: var(--space-4); }
.auth-alt { margin-top: var(--space-4); font-size: .85rem; color: var(--slate); text-align: center; }
.auth-alt a { color: var(--p); font-weight: var(--weight-semi); }
.auth-back { display: block; text-align: center; margin-top: var(--space-5); font-size: .8rem; color: var(--soft); }
.auth-back:hover { color: var(--navy); }

.chooser { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.appcard { position: relative; display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-5); border-radius: var(--radius-lg); background: var(--navy); color: var(--fg-inverse); overflow: hidden; transition: transform var(--duration-base) var(--ease), box-shadow var(--duration-base) var(--ease); }
.appcard:hover { transform: translateY(-3px); box-shadow: var(--sh2); }
.appcard.locked { filter: grayscale(.8); opacity: .6; cursor: not-allowed; }
.appcard.locked:hover { transform: none; box-shadow: none; }
.ac-ic { width: 38px; height: 38px; border-radius: var(--radius-md); background: rgba(250,249,246,.14); display: grid; place-items: center; margin-bottom: var(--space-1); }
.ac-t { font-size: 1.05rem; font-weight: var(--weight-semi); }
.ac-d { font-size: .8rem; color: rgba(250,249,246,.72); line-height: 1.45; min-height: 2.6em; }
.ac-state { align-self: flex-start; font-family: var(--mono); font-size: .64rem; text-transform: uppercase; letter-spacing: .06em; padding: var(--space-1) var(--space-2); border-radius: var(--radius-pill); margin-top: var(--space-1); }
.ac-state.on { background: rgba(127,208,170,.2); color: #a7dcc4; }
.ac-state.trial { background: rgba(212,163,115,.2); color: #e0c09a; }
.ac-state.off { background: rgba(250,249,246,.14); color: rgba(250,249,246,.8); }
.ac-go { display: inline-flex; align-items: center; gap: var(--space-2); font-size: .85rem; font-weight: var(--weight-semi); margin-top: var(--space-2); }
.appcard:hover .ac-go svg { transform: translateX(3px); transition: transform var(--duration-base) var(--ease); }
.ch-foot { display: flex; align-items: center; justify-content: space-between; margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid var(--line2); font-size: .82rem; color: var(--soft); }
@media (max-width: 900px) {
  .auth { grid-template-columns: 1fr; }
  .auth-brand { padding: var(--space-6); }
  .bpts { display: none; }
  .chooser { grid-template-columns: 1fr; }
}

/* ============================================================ articles ====
   Help pages and blog posts share one template. A single column, capped at a
   readable measure — long-form is the one place where a 1180px grid actively
   hurts, because nobody reads a 140-character line. */
.art { padding-block: var(--space-12) var(--space-24); }
.art-wrap { max-width: 46rem; }
.art-crumb { font-family: var(--mono); font-size: .75rem; color: var(--soft); margin-bottom: var(--space-4); }
.art-crumb a { color: var(--p); }
.art-crumb span { margin-inline: var(--space-2); }
.art h1 { font-size: clamp(1.875rem, 1.4rem + 2vw, 2.75rem); margin-bottom: var(--space-4); }
.art .lead { margin-bottom: var(--space-4); }
.art-meta { font-family: var(--mono); font-size: .75rem; color: var(--soft); margin-bottom: var(--space-6); }

.art-toc {
  display: grid; gap: var(--space-1);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: var(--space-5);
  margin-block: var(--space-8);
}
.art-toc b { font-family: var(--mono); font-size: .7rem; text-transform: uppercase;
  letter-spacing: var(--tracking-label); color: var(--soft); margin-bottom: var(--space-2); font-weight: var(--weight-medium); }
.art-toc a { font-size: .9375rem; color: var(--slate); padding-block: var(--space-1); }
.art-toc a:hover { color: var(--p); }

.art-body { font-size: 1.0625rem; line-height: 1.75; }
.art-body h2 { font-size: 1.375rem; margin: var(--space-12) 0 var(--space-4); scroll-margin-top: 90px; }
.art-body p { margin-bottom: var(--space-4); color: var(--slate); }
.art-body b, .art-body strong { color: var(--ink); font-weight: var(--weight-semi); }
.art-body ul, .art-body ol { margin: 0 0 var(--space-4) var(--space-6); color: var(--slate); }
.art-body li { margin-bottom: var(--space-2); }
.art-body a { color: var(--p); font-weight: var(--weight-medium); text-decoration: underline; }
.art-body code { font-family: var(--mono); font-size: .88em; background: var(--bg2);
  padding: 2px 6px; border-radius: var(--radius-xs); }

/* An aside for the thing that bites people. Deliberately not a bright banner —
   it should read as a colleague's margin note, not an alert. */
.art-note {
  background: var(--bg2); border-left: 3px solid var(--p);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  padding: var(--space-4) var(--space-5); margin-block: var(--space-6);
  font-size: 1rem; color: var(--slate);
}

.art-rel { margin-top: var(--space-16); padding-top: var(--space-8); border-top: 1px solid var(--line); }
.art-rel h3 { font-size: 1rem; margin-bottom: var(--space-4); }
.art-rel a { display: block; padding: var(--space-3) 0; border-bottom: 1px solid var(--line2);
  font-size: .9375rem; font-weight: var(--weight-medium); color: var(--navy); }
.art-rel a:hover { color: var(--p); }

.art-cta { margin-top: var(--space-12); background: var(--surface-inverse); color: var(--fg-inverse);
  border-radius: var(--radius-xl); padding: var(--space-8); text-align: center; }
.art-cta h3 { color: var(--fg-inverse); font-size: 1.25rem; }
.art-cta p { color: rgba(250,249,246,.72); margin: var(--space-2) 0 var(--space-6); }

/* ---- blog index ---- */
.post-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-6); }
@media (max-width: 780px) { .post-grid { grid-template-columns: 1fr; } }
.post-card {
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-xl); padding: var(--space-8);
  transition: border-color var(--duration-base) var(--ease),
              box-shadow var(--duration-base) var(--ease),
              transform var(--duration-base) var(--ease);
}
.post-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); transform: translateY(-2px); }
.post-card h3 { margin: var(--space-3) 0 var(--space-2); font-size: 1.1875rem; color: var(--navy); }
.post-card p { font-size: .9375rem; color: var(--slate); flex: 1; }
.post-card .int-more { margin-top: var(--space-4); font-size: .875rem; font-weight: var(--weight-semi); color: var(--p); }
.post-card .art-meta { margin: 0; }

/* ------------------------------------------------------------ animation */
@keyframes rvIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
/* No animation by default any more — the load-time version had finished before
   anyone scrolled to it. rv-wait is applied by script, so nothing is hidden
   unless the script that reveals it is definitely running. */
.reveal { }
.reveal.rv-wait{ opacity:0; transform:translateY(18px);
  transition:opacity .62s var(--ease), transform .62s var(--ease); }
.reveal.rv-wait.rv-in{ opacity:1; transform:none; }
@media (prefers-reduced-motion: reduce) { .reveal { animation: none; } }

/* ------------------------------------------------------------ utilities */
.mt-s { margin-top: var(--space-3); }
.center { text-align: center; }
.mx-auto { margin-inline: auto; }

/* ---- polish ----
   Small things, all of them things you feel rather than notice. */

/* Selection in the brand's own colour. The browser default is a blue that
   belongs to no palette on this page. */
::selection{ background: var(--brand-accent-light); color: var(--brand-ink); }

/* There was a warm double-ring here for .hero-dark .btn-p and .bubble .btn-p,
   meant to strengthen focus where the default ring reads faintly against
   coral. It never painted once, and could not: the global :focus-visible rule
   near the top of this file sets outline, outline-offset and box-shadow with
   !important, and an !important author declaration beats a normal one whatever
   its specificity — so a rule that only declared box-shadow normally always
   lost. Removed rather than made !important, because the global ring is the
   accessible behaviour and it is already correct here: 3px solid ink plus a
   6px paper halo, which is what survives on the dark hero.
   If you are about to add a per-section focus ring: it will not paint either
   unless you !important it, and doing that costs the paper halo that makes
   focus visible on the dark grounds in the first place. */

/* Button transition and press moved to the .btn block itself, where they are
   declared once. */

/* Inline links underline from the left instead of the whole rule arriving at
   once — the same information, delivered with a direction. */
.sec-lead a:not(.btn), .lead a:not(.btn), p a:not(.btn){
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0 1px; background-repeat: no-repeat;
  background-position: 0 100%;
  transition: background-size .24s var(--ease);
}
.sec-lead a:not(.btn):hover, .lead a:not(.btn):hover, p a:not(.btn):hover{
  background-size: 100% 1px;
}

/* One curve for the page: --curve-page, set on .hero-dark above and quartered
   on the bubble's squared corner, so the page has one shape. */
.bubble{ border-bottom-left-radius: calc(var(--curve-page) / 4); }

/* Figures and their labels on one baseline. The stat band's numbers are
   tabular already; this stops the label drifting when a figure is two digits
   on one card and three on the next. */
.stat{ display:flex; flex-direction:column; align-items:center; justify-content:flex-start; }
.stat b{ min-height: 1em; }

/* Cards everywhere lift by the same amount, from the same tokens. Previously
   the proof cards, the trust groups and the plan cards each had their own. */
.proof-cards .proof-i,.tc-group,.dc-card{
  box-shadow: var(--lift-rest);
  transition: transform .18s var(--ease), box-shadow .18s var(--ease), border-color .18s var(--ease);
}
.proof-cards .proof-i:hover,.tc-group:hover,.dc-card:hover{
  transform: translateY(-3px); box-shadow: var(--lift-hover);
}

/* Headings share one optical treatment rather than three. */
h1,h2{ text-wrap: balance; }
.lead,.sec-lead{ text-wrap: pretty; }

@media (prefers-reduced-motion: reduce){
  .btn,.proof-cards .proof-i,.tc-group,.dc-card{ transition:none; }
  .btn:active,.btn-p:hover{ transform:none; }
}

/* ---- blog index ----
   Generated from the files in blog/, so the list cannot advertise a post that
   has been deleted — which is exactly what went wrong when these were hand-
   maintained. Whole card is the link; the arrow moves on hover so the target
   feels like one object rather than a card with a link inside it. */
.bgrid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(19rem,1fr)); gap: var(--space-5); }
.bcard{
  display:flex; flex-direction:column; justify-content:space-between; gap: var(--space-4);
  padding: var(--space-6); text-decoration:none; color:inherit;
  background: var(--surface-raised); border:1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--lift-rest);
  transition: transform .18s var(--ease), box-shadow .18s var(--ease), border-color .18s var(--ease);
}
.bcard-tag{ font-family: var(--mono); font-size:.66rem; text-transform:uppercase; letter-spacing: var(--tracking-label); color: var(--p); margin-bottom: var(--space-2); }
.bcard-meta{ font-family: var(--mono); font-size:.72rem; color: var(--soft); margin-top: var(--space-3); }
.split-media a.photo-band{ display:flex; text-decoration:none; }
.split-media a.photo-band .ov h3{ font-family: var(--mono); font-size:.72rem; letter-spacing: var(--tracking-label); text-transform:uppercase; }
.bcard:hover{ transform: translateY(-3px); box-shadow: var(--lift-hover); border-color: var(--brand-accent-light); }
.bcard-body{ display:flex; flex-direction:column; gap:6px; }
.bcard-body b{ font-size:1.05rem; font-weight:600; line-height:1.3; letter-spacing:-.012em; }
.bcard-body > span{ font-size:.87rem; color: var(--fg-muted); line-height:1.6; }
.bcard-go{
  display:inline-flex; align-items:center; gap:6px;
  font-size:.84rem; font-weight:600; color: var(--color-primary);
}
.bcard-go svg{ transition: transform .18s var(--ease); }
.bcard:hover .bcard-go svg{ transform: translateX(3px); }
@media (prefers-reduced-motion: reduce){
  .bcard,.bcard-go svg{ transition:none; }
  .bcard:hover{ transform:none; }
}

/* ---- language picker ----
   Two hand-written languages, shown as buttons rather than a select. The
   previous control was a dropdown of thirty-odd Google Translate options, of
   which exactly two were ever written by a person. */
.lp-langs{ display:grid; grid-template-columns:1fr 1fr; gap:6px; padding:0 4px 4px; }
.lp-langs button{
  display:flex; align-items:center; gap:7px; justify-content:flex-start;
  padding:8px 11px; border:1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-raised); font:inherit; font-size:.84rem;
  color: var(--fg); cursor:pointer;
  transition: border-color .14s var(--ease), background .14s var(--ease);
}
.lp-langs button:hover{ border-color: var(--brand-accent-light); }
.lp-langs button.on{ border-color: var(--color-primary); background:#F4F9FC; font-weight:600; }
.lp-fl{ font-size:1rem; line-height:1; }
@media (prefers-reduced-motion: reduce){ .lp-langs button{ transition:none; } }

/* The one line that stops somebody expecting to try a website for a week. */
.trial-note{
  max-width: 40rem; margin: 0 auto var(--space-6);
  font-size: .87rem; color: var(--fg-muted); line-height: 1.6;
}

/* ---- website order form ----
   Ten questions is a lot to look at, so the required two sit at the top in
   their own group and the rest read as an invitation rather than a wall. */
.worder{ max-width: 46rem; margin: 0 auto; }
/* Four contact fields, so two columns — not auto-fit. A 13rem minimum
   resolved to three columns at desktop widths, which stranded the fourth
   field alone on its own row beside two empty cells. */
.wo-grid{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap: var(--space-4); }
@media (max-width:560px){ .wo-grid{ grid-template-columns:1fr; } }
.wo-q{ display:flex; flex-direction:column; gap: var(--space-4); margin-top: var(--space-4); }
.wo-f{ display:flex; flex-direction:column; gap:5px; }
.wo-f.wide{ grid-column:1/-1; }
.wo-f > span:first-child{ font-size:.85rem; font-weight:600; display:flex; align-items:baseline; gap:7px; }
/* The warm accent is a background colour: as text on paper it measures 2.86:1.
   Same family, taken deep enough to read (5.27:1) — the required marker is the
   one label on the form that must never be missed. */
.wo-f em{ font-style:normal; font-size:.7rem; font-weight:600; color:#B4441C;
  text-transform:uppercase; letter-spacing:.05em; }
.wo-f input[type=text],.wo-f input:not([type]),.wo-f input[type=email],.wo-f input[type=tel],
.wo-f textarea,.wo-f select{
  width:100%; font:inherit; font-size:.9rem; padding:10px 12px;
  border:1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-raised); color: var(--fg);
}
.wo-f textarea{ resize:vertical; line-height:1.55; }
.wo-f input:focus,.wo-f textarea:focus,.wo-f select:focus{
  border-color: var(--color-primary); box-shadow:0 0 0 3px rgba(47,109,147,.14);
}
.wo-f input[type=range]{ width:100%; accent-color: var(--color-primary); }
.wo-pages{ font-family: var(--font-mono); font-size:.82rem;
  color: var(--fg-muted); font-variant-numeric: tabular-nums; }

.wo-extras{ margin-top: var(--space-8); padding-top: var(--space-6); border-top:1px solid var(--line); }
.wo-extras > b{ font-size:.95rem; }
.wo-extras > p{ margin:2px 0 var(--space-4); font-size:.82rem; color: var(--fg-muted); }
.wo-x{ display:grid; grid-template-columns:auto 1fr auto; gap:10px; align-items:start;
  padding:10px 12px; margin-bottom:6px; cursor:pointer;
  border:1px solid var(--line); border-radius: var(--radius-md); background: var(--surface-raised);
  transition: border-color .14s var(--ease), background .14s var(--ease); }
.wo-x:hover{ border-color: var(--brand-accent-light); }
.wo-x.on{ border-color: var(--color-primary); background:#F6FAFC; }
.wo-x input{ margin-top:3px; width:16px; height:16px; accent-color: var(--color-primary); }
.wo-x b{ display:block; font-size:.86rem; }
.wo-x span span{ display:block; font-size:.77rem; color: var(--fg-muted); line-height:1.5; }
.wo-xp{ font-family: var(--font-mono); font-size:.8rem;
  font-variant-numeric: tabular-nums; white-space:nowrap; }

.wo-total{ margin-top: var(--space-6); padding-top: var(--space-5); border-top:1px solid var(--line); }
.wo-line{ display:flex; justify-content:space-between; align-items:baseline; gap:12px;
  padding: var(--space-2) 0; font-size:.9rem; }
.wo-line b{ font-family: var(--font-mono); font-size:1.05rem;
  font-variant-numeric: tabular-nums; }
.wo-line.muted{ color: var(--fg-muted); }
.wo-fine{ margin: var(--space-3) 0 0; font-size:.78rem; color: var(--fg-muted); line-height:1.6; }
#wo-go{ margin-top: var(--space-5); width:100%; }
@media (prefers-reduced-motion: reduce){ .wo-x{ transition:none; } }


/* --- footer: company block, trust row --- */
.foot-top { padding-bottom: var(--space-8); }
.fdesc { max-width: 30rem; }
.ftp {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 10px;
  font-size: .82rem; color: rgba(250,249,246,.72);
}
.ftp svg { color: #00B67A; flex: none; }
.ftp:hover { color: var(--fg-inverse); }
.fbottom {
  display: flex; flex-wrap: wrap; gap: var(--space-4) var(--space-6);
  align-items: flex-start; justify-content: space-between;
  padding: var(--space-6) 0; border-top: 1px solid rgba(250,249,246,.14);
  font-size: .78rem; color: rgba(250,249,246,.6);
}
.fb-co { display: grid; gap: 2px; line-height: 1.5; }
.fb-co b { color: var(--fg-inverse); font-weight: 600; letter-spacing: .01em; }
.fb-co span { color: rgba(250,249,246,.55); }
.ftrust { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-5); align-items: center; }
.ftrust a { display: inline-flex; align-items: center; gap: 6px; color: rgba(250,249,246,.62); }
.ftrust a:hover { color: var(--fg-inverse); }
.ftrust a:first-child svg { color: #00B67A; }
.fb-links { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.fb-links a { color: rgba(250,249,246,.62); }
.fb-links a:hover { color: var(--fg-inverse); }
@media (max-width: 720px) {
  .fbottom { flex-direction: column; gap: var(--space-4); }
}


/* ============================================================
   PHOTOGRAPHY, DEPTH AND MOTION
   Appended deliberately: these override components defined above, and at equal
   specificity the later rule wins. Moving this block up the file silently
   turns half of it off.
   ============================================================ */

/* --- a photo behind the scrim ------------------------------------------ */
.photo-band.ph {
  background-image: var(--ph-sm);
  background-size: cover;
  /* Faces sit in the upper third of most of these photographs, and the text
     occupies 30-85% of the band. Pulling the image up puts the subject where
     the scrim is lightest and the words where it is darkest. */
  /* A 320px band crops a landscape photo to a letterbox strip, and no
     background-position saves that: move it up and you get ceiling, down and
     you get the table. The fix is height - give the photograph room above the
     text rather than making them fight for the same pixels. */
  min-height: 420px;
  background-position: center 42%;
  isolation: isolate;
}
@media (max-width: 700px) { .photo-band.ph { min-height: 340px; } }
@media (min-width: 760px) {
  .photo-band.ph { background-image: var(--ph); }
}
/* The scrim. Text sits on the dark end, so the gradient is weighted downward
   rather than flat — a flat 60% wash greys the photograph out for no gain. */
.photo-band.ph::after {
  content: '';
  position: absolute; inset: 0; z-index: 0;
  /* Measured against where the text actually lands: the heading starts 30%%
     down, so a scrim that is still only 42%% there leaves white type on a
     bright photograph. Weighted down, but strong from the top third on. */
  /* With the band taller the text genuinely sits at the bottom, so the scrim
     can stay light over the photograph and go strong only where words are. */
  background: linear-gradient(180deg,
              rgba(21,23,27,.10) 0%,
              rgba(21,23,27,.30) 38%,
              rgba(21,23,27,.74) 72%,
              rgba(21,23,27,.90) 100%);
}
/* No watermark over a photograph — two things competing in one space. */
.photo-band.ph::before { display: none; }
.photo-band.ph .ov { z-index: 1; }
/* A photograph we do not control can always be brighter than planned in one
   corner. The shadow is invisible on a dark scrim and saves the one case. */
.photo-band.ph .ov h2,
.photo-band.ph .ov h3,
.photo-band.ph .ov p { text-shadow: 0 1px 12px rgba(0,0,0,.45); }

/* A slow drift once it is on screen. transform only: animating
   background-position repaints the whole band every frame. */
.photo-band.ph { overflow: hidden; }
.photo-band.ph.rv-in { animation: phDrift 18s ease-out forwards; }
@keyframes phDrift { from { transform: scale(1.06); } to { transform: scale(1); } }

/* --- children arrive in sequence --------------------------------------- */
.reveal.rv-wait > * { opacity: 0; transform: translateY(14px); }
.reveal.rv-wait.rv-in > * {
  opacity: 1; transform: none;
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}
.reveal.rv-wait.rv-in > *:nth-child(1) { transition-delay: .00s; }
.reveal.rv-wait.rv-in > *:nth-child(2) { transition-delay: .06s; }
.reveal.rv-wait.rv-in > *:nth-child(3) { transition-delay: .12s; }
.reveal.rv-wait.rv-in > *:nth-child(4) { transition-delay: .18s; }
.reveal.rv-wait.rv-in > *:nth-child(5) { transition-delay: .24s; }
.reveal.rv-wait.rv-in > *:nth-child(6) { transition-delay: .30s; }
.reveal.rv-wait.rv-in > *:nth-child(n+7) { transition-delay: .36s; }

/* --- depth on the things you can click --------------------------------- */
.card, .vp, .plan, .help-cat, .art-card {
  /* No will-change here. Declaring it permanently on every card keeps dozens
     of compositor layers alive for an effect that only runs on hover, and the
     browser promotes the layer on its own when the transition starts. */
  transition: transform .28s var(--ease), box-shadow .28s var(--ease),
              border-color .28s var(--ease);
}
.card:hover, .vp:hover, .plan:hover, .help-cat:hover, .art-card:hover {
  transform: translateY(-3px);
  /* --lift-hover, like every other card on the site. This one had its own
     hand-rolled two-layer shadow, so .card and .plan lifted less than
     .bcard and .wserv-i did for exactly the same gesture. */
  box-shadow: var(--lift-hover);
}

/* The framed app shots get a little lift so they read as objects on the page
   rather than as part of the background. */
.frame, .shot-fig img, .photo-band {
  box-shadow: 0 24px 60px -32px rgba(21,23,27,.45), 0 4px 14px -8px rgba(21,23,27,.16);
}

/* --- honour the setting ------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .reveal.rv-wait > *,
  .reveal.rv-wait.rv-in > * { opacity: 1; transform: none; transition: none; }
  .photo-band.ph.rv-in { animation: none; }
  .card:hover, .vp:hover, .plan:hover, .help-cat:hover, .art-card:hover,
  .btn:hover, .btn:active { transform: none; }
}


/* A .brand-panel carrying a photograph is a photograph, not a panel. */
.brand-panel.ph {
  background-image: var(--ph-sm);
  background-size: cover;
  background-position: center;
  border: none;
}
@media (min-width: 760px) { .brand-panel.ph { background-image: var(--ph); } }
.brand-panel.ph::before, .brand-panel.ph::after { display: none; }


/* ============================================================
   THE FREE SITE CHECK
   ============================================================ */
.chk-form {
  display: flex; gap: var(--space-3); max-width: 34rem; margin: 0 auto;
  flex-wrap: wrap;
}
.chk-form input {
  flex: 1 1 16rem; min-width: 0;
  border: 1px solid var(--line); border-radius: var(--radius-md);
  padding: 14px 16px; font: inherit; font-size: 1rem; background: var(--surface-raised);
}
.chk-form input:focus { outline: 2px solid var(--p); outline-offset: 1px; border-color: var(--p); }
.chk-form .btn { flex: 0 0 auto; padding-inline: var(--space-6); }
.chk-fine { font-size: .78rem; color: var(--soft); margin-top: var(--space-3); }

.chk-out:empty { display: none; }
.chk-out { max-width: 46rem; margin: var(--space-8) auto 0; }
.chk-wait { text-align: center; color: var(--soft); padding: var(--space-8) 0; }

.chk-head { margin-bottom: var(--space-4); }
.chk-url { font-family: var(--mono); font-size: .84rem; color: var(--slate); word-break: break-all; }
.chk-sum { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-2);
           font-size: .82rem; align-items: baseline; }
.chk-p { color: #2E6B45; font-weight: 650; }
.chk-w { color: #8A6212; font-weight: 650; }
.chk-f { color: #A3372B; font-weight: 650; }
.chk-ms { color: var(--soft); margin-left: auto; font-family: var(--mono); font-size: .74rem; }

.chk-list { display: grid; gap: 8px; }
.chk-row {
  border: 1px solid var(--line); border-radius: var(--radius-md);
  background: var(--surface-raised); overflow: hidden;
}
.chk-row summary {
  display: grid; grid-template-columns: auto 1fr; gap: 4px 12px;
  align-items: baseline; padding: 13px 16px; cursor: pointer; list-style: none;
}
.chk-row summary::-webkit-details-marker { display: none; }
.chk-row b { font-size: .92rem; }
.chk-row .chk-d { grid-column: 2; font-size: .82rem; color: var(--slate); }
.chk-row p { margin: 0; padding: 0 16px 14px 16px; font-size: .84rem; color: var(--slate);
             border-top: 1px solid var(--line); padding-top: 12px; }
.chk-b {
  grid-row: span 2; align-self: center;
  font-size: .68rem; font-weight: 650; letter-spacing: .03em; text-transform: uppercase;
  padding: 4px 9px; border-radius: var(--radius-pill); white-space: nowrap;
}
.chk-row.pass .chk-b { background: #E7F1EA; color: #2E6B45; }
.chk-row.warn .chk-b { background: #FAF0DC; color: #8A6212; }
.chk-row.fail .chk-b { background: #F8E4E1; color: #A3372B; }
.chk-row.fail { border-color: #EBC9C3; }

.chk-cta {
  margin-top: var(--space-6); padding: var(--space-6);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: #FBF9F5; text-align: center;
}
.chk-cta.ok { background: #F6FAF7; border-color: #D8E7DD; }
.chk-cta b { display: block; font-size: 1.05rem; margin-bottom: 6px; }
.chk-cta p { color: var(--slate); font-size: .88rem; margin-bottom: var(--space-4);
             max-width: 34em; margin-inline: auto; }
.chk-err {
  padding: var(--space-5); border: 1px solid #EBC9C3; border-radius: var(--radius-md);
  background: #FDF6F4; font-size: .9rem;
}
@media (max-width: 560px) {
  .chk-form .btn { width: 100%; }
  .chk-row summary { grid-template-columns: 1fr; }
  .chk-b { grid-row: auto; justify-self: start; }
  .chk-row .chk-d { grid-column: 1; }
  .chk-ms { margin-left: 0; }
}

.lang-note{margin:0 0 var(--space-6);padding:12px 14px;border:1px solid var(--line);
  border-left:3px solid var(--p);border-radius:var(--radius-sm);background:#FBF9F5;
  font-size:.84rem;color:var(--slate)}
.lang-note b{color:var(--ink)}


/* --- integrations teaser on the CRM page --- */
.int-teaser { max-width: 46rem; margin-inline: auto; }
.it-row {
  display: flex; flex-wrap: wrap; gap: 8px; justify-content: center;
}
.it-row span {
  padding: 8px 14px; border: 1px solid var(--line); border-radius: var(--radius-pill);
  background: var(--surface-raised); font-size: .84rem; color: var(--slate);
  transition: transform .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease);
}
.it-row span:hover { transform: translateY(-2px); border-color: var(--p); color: var(--ink); }

/* Five names on this wall are marked SOON in the catalogue the same section
   links to. Shown, because they are coming - but shown as what they are, at a
   weight that does not compete with the ones you can switch on today. */
.it-row span.it-soon { background: var(--bg2); color: var(--fg-muted); border-style: dashed; }
/* .66rem was 10.56px. A SOON badge is the label that decides whether someone
   waits for an integration or goes looking elsewhere, so it is functional text
   and belongs above the 11px floor. .7rem, same as the other mono micro-labels
   that already clear it. */
.it-row span.it-soon b {
  margin-left: 6px; font-family: var(--mono); font-size: .7rem;
  font-weight: var(--weight-medium); text-transform: uppercase; letter-spacing: .08em;
  color: var(--soft);
}
.it-row span.it-soon:hover { transform: none; border-color: var(--line); color: var(--fg-muted); }


/* --- sticky order bar on the websites page --- */
@media (max-width: 620px) {
  .wbar-in { justify-content: center; text-align: center; padding: 12px var(--space-4); }
  .wbar-txt { flex: 1 1 100%; }
  .wbar .btn { width: 100%; }
}
@media (prefers-reduced-motion: reduce) { .wbar { transition: none; } }

/* the order section should read as a destination */
#order { scroll-margin-top: 84px; }
#order .sec-head h2 { font-size: clamp(1.7rem, 1.2rem + 1.8vw, 2.5rem); }


/* --- analytics consent --- */
.vt-consent{position:fixed;left:0;right:0;bottom:0;transform:translateY(110%);
  transition:transform .34s var(--ease);background:var(--ink);color:var(--fg-inverse);
  box-shadow:0 -8px 32px -12px rgba(21,23,27,.45)}
.vt-consent.in{transform:none}
.vt-in{max-width:var(--wrap);margin-inline:auto;display:flex;align-items:center;
  gap:var(--space-6);padding:16px var(--space-6);flex-wrap:wrap}
.vt-in p{margin:0;flex:1 1 22rem;font-size:.86rem;line-height:1.5;color:rgba(250,249,246,.76)}
.vt-in p b{color:var(--fg-inverse);display:block;margin-bottom:2px}
.vt-btns{display:flex;gap:8px;flex-wrap:wrap}
.vt-btns .btn{white-space:nowrap}
.vt-btns .btn:not(.btn-p){background:transparent;color:rgba(250,249,246,.82);
  border:1px solid rgba(250,249,246,.28)}
.vt-btns .btn:not(.btn-p):hover{background:rgba(250,249,246,.1);color:var(--fg-inverse)}
@media(max-width:620px){.vt-in{padding:14px var(--space-4)}.vt-btns .btn{flex:1 1 100%}}
@media(prefers-reduced-motion:reduce){.vt-consent{transition:none}}


/* --- bottom bars vs the assistant bubble ---------------------------------
   Both live in the bottom-right corner, and the assistant is z-index 9500.
   The consent banner has to sit above it (it is a question that must be
   answerable), the order bar just below it, and the bubble lifts whenever
   either bar is on screen so they never overlap. */
.vt-consent { z-index: 9600; }

body.has-bottom-bar .vch-root,
body.has-consent .vch-root {
  transform: translateY(-84px);
  transition: transform .3s var(--ease);
}
@media (max-width: 620px) {
  body.has-bottom-bar .vch-root,
  body.has-consent .vch-root { transform: translateY(-132px); }
}
@media (prefers-reduced-motion: reduce) {
  body.has-bottom-bar .vch-root, body.has-consent .vch-root { transition: none; }
}


/* ---- the website brief, as steps ---------------------------------------- */
.wo-prog{ margin-bottom: var(--space-5); }
.wo-prog-t{ display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  margin-bottom:10px; }
.wo-prog-t b{ font-size:1.05rem; }
.wo-prog-t span{ font-family:var(--mono); font-size:.72rem; color:var(--fg-muted);
  text-transform:uppercase; letter-spacing:.06em; }
.wo-bars{ display:grid; grid-template-columns:repeat(4,1fr); gap:6px; }
.wo-bar{ height:4px; border-radius:var(--radius-pill); background:var(--line); }
.wo-bar.now{ background:var(--p); }
.wo-bar.done{ background:var(--green); }
@media (prefers-reduced-motion: no-preference){
  .wo-bar{ transition: background .3s var(--ease); }
}

.wo-nav{ display:flex; gap:12px; align-items:center; flex-wrap:wrap; margin-top: var(--space-5); }
.wo-nav .btn[hidden]{ display:none; }

.wo-bad{ background:var(--color-bad-soft); border:1px solid var(--color-bad);
  color:var(--color-bad); border-radius:var(--radius-md);
  padding:10px 14px; font-size:.9rem; margin-top: var(--space-4); }

.wo-invalid{ outline:2px solid var(--color-bad) !important; outline-offset:2px; }

/* A step is swapped in, not slid — a form field that moves while you are
   reaching for it is worse than one that simply appears. */
@media (prefers-reduced-motion: no-preference){
  .wo-step:not([hidden]){ animation: woIn .28s var(--ease) both; }
  @keyframes woIn{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:none; } }
}


/* ---- the checker, in the dark hero -------------------------------------- */
.hero-check{
  /* The card is a light panel inside .hero-dark, so without its own colour it
     inherits the hero's white — white text on a beige card, which is what made
     the reset button (contrast 1.11) invisible. A panel that flips the
     background has to flip the foreground in the same rule. */
  color: var(--fg);
  background: var(--bg);
  border-radius: var(--radius-lg);
  padding: clamp(22px, 2.4vw, 32px);
  box-shadow: 0 24px 60px rgba(0,0,0,.28);
  max-width: 30rem;
}
.hero-check .hc-tag{
  display:inline-block; font-family: var(--mono); font-size:.7rem;
  text-transform:uppercase; letter-spacing:.08em;
  color: var(--green); background: var(--color-ok-soft);
  border-radius: var(--radius-pill); padding: 4px 12px; margin-bottom: 14px;
}
.hero-check h2{ font-size: clamp(1.25rem, 1.05rem + .7vw, 1.6rem); margin-bottom: 8px; }
/* --fg-muted is tuned for white; on the card's beige it lands at 4.13:1,
   just under the 4.5 minimum. A touch darker clears it. */
.hero-check p{ font-size:.9375rem; color:#4f545a; margin-bottom: 18px; }
.hc-form{ display:flex; gap:10px; flex-wrap:wrap; }
.hc-form input{
  flex:1 1 12rem; min-width:0;
  border:1px solid var(--line); border-radius: var(--radius-md);
  padding: 13px 15px; font: inherit; font-size:.95rem; background: var(--surface-raised); color: var(--fg);
}
.hc-form input:focus{ outline:2px solid var(--p); outline-offset:1px; border-color:transparent; }
.hc-form .btn{ flex:0 0 auto; }
.hc-fine{ font-size:.78rem !important; color:#4f545a;
  margin: 12px 0 0 !important; }

@media (max-width: 560px){
  .hero-check{ max-width:none; }
  .hc-form .btn{ flex:1 1 100%; justify-content:center; }
}


/* ---- the checker running, in the hero ----------------------------------- */
.hc-run{ margin-top: var(--space-4); }
.hc-track{ height:4px; border-radius: var(--radius-pill); background: var(--line);
  overflow:hidden; margin-bottom:16px; }
.hc-fill{ display:block; height:100%; width:0; background: var(--p);
  border-radius: var(--radius-pill); }
.hc-phases{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:9px; }
.hc-phases li{ display:flex; align-items:center; gap:10px;
  font-size:.875rem; color: var(--fg-muted); opacity:.45; }
.hc-phases li.on{ opacity:1; color: var(--fg); font-weight:500; }
.hc-phases li.done{ opacity:.7; }
.hc-tick{ width:15px; height:15px; border-radius:50%; flex:0 0 auto;
  border:2px solid var(--line); position:relative; }
.hc-phases li.on .hc-tick{ border-color: var(--p); }
.hc-phases li.done .hc-tick{ border-color: var(--green); background: var(--green); }
.hc-phases li.done .hc-tick::after{ content:""; position:absolute; left:3px; top:.5px;
  width:4px; height:8px; border:solid #fff; border-width:0 2px 2px 0; transform:rotate(45deg); }
@media (prefers-reduced-motion: no-preference){
  .hc-phases li{ transition: opacity .3s var(--ease), color .3s var(--ease); }
  .hc-phases li.on .hc-tick{ animation: hcPulse 1.1s ease-in-out infinite; }
  @keyframes hcPulse{ 0%,100%{ box-shadow:0 0 0 0 rgba(47,109,147,.35); }
                      50%{ box-shadow:0 0 0 5px rgba(47,109,147,0); } }
}

/* ---- the result --------------------------------------------------------- */
.hc-res{ margin-top: var(--space-4); }
.hc-sum{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:14px; }
.hc-sum span{ font-family: var(--mono); font-size:.7rem; text-transform:uppercase;
  letter-spacing:.05em; padding:4px 10px; border-radius: var(--radius-pill); }
.hc-p{ color: var(--green); background: var(--color-ok-soft); }
.hc-w{ color: #845c00; background: #fdf3e0; }   /* #9a6b00 measured 4.26:1 */
.hc-f{ color: var(--color-bad); background: var(--color-bad-soft); }

.hc-rows{ display:flex; flex-direction:column; gap:7px; margin-bottom:16px;
  max-height:16rem; overflow-y:auto; }
.hc-row{ border:1px solid var(--line); border-radius: var(--radius-md);
  padding:10px 13px; background: var(--surface-raised); }
.hc-row summary{ cursor:pointer; list-style:none; display:flex; flex-direction:column; gap:2px; }
.hc-row summary::-webkit-details-marker{ display:none; }
.hc-row summary b{ font-size:.9rem; }
.hc-row summary span{ font-size:.8rem; color: var(--fg-muted); }
.hc-row p{ font-size:.82rem !important; color: var(--fg-muted);
  margin:9px 0 0 !important; padding-top:9px; border-top:1px solid var(--line); }
.hc-row.fail{ border-left:3px solid var(--color-bad); }
.hc-row.warn{ border-left:3px solid #e0a53d; }

.hc-pass{ margin:-6px 0 16px; font-size:.8rem; color: var(--fg-muted); }
.hc-pass summary{ cursor:pointer; list-style:none; display:inline-flex; align-items:center; gap:6px; }
.hc-pass summary::-webkit-details-marker{ display:none; }
.hc-pass summary::before{ content:''; width:6px; height:6px; border-right:1.5px solid currentColor; border-bottom:1.5px solid currentColor; transform:rotate(-45deg); transition:transform .15s; }
.hc-pass[open] summary::before{ transform:rotate(45deg); }
.hc-pass ul{ list-style:none; padding:0; margin:8px 0 0; display:flex; flex-direction:column; gap:4px; }
.hc-pass li{ display:flex; gap:8px; flex-wrap:wrap; }
.hc-pass li b{ font-weight:600; color: var(--fg); }
.hc-cta{ background: var(--surface-sunken); border-radius: var(--radius-md);
  padding:15px 16px; }
.hc-cta b{ display:block; font-size:.92rem; margin-bottom:11px; }
.hc-cta p{ font-size:.85rem !important; margin:0 0 11px !important; }
.hc-cta .btn{ width:100%; justify-content:center; }
/* .btn-light is built for dark surfaces. On the card it needs a real border
   and dark text of its own, or it disappears into the beige. */
/* .hero-check .hc-again, not .hc-again: the card is a light panel nested inside
   .hero-dark, and `.hero-dark .btn-light` (0,2,0) beats a bare class (0,1,0).
   That rule paints button text white, which is right on the dark hero and
   invisible on the beige card — measured 1.11:1. A light panel inside a dark
   section has to out-specify the section, not just come after it. */
.hero-check .hc-again{ width:100%; justify-content:center; margin-top:10px;
  background: var(--surface-raised); color: var(--fg); border:1px solid var(--line); }
.hero-check .hc-again:hover{ background: var(--surface-sunken); border-color: var(--line); }
.hc-err{ background: var(--color-bad-soft); border:1px solid var(--color-bad);
  color: var(--color-bad); border-radius: var(--radius-md);
  padding:12px 14px; font-size:.88rem; margin-top: var(--space-4); }

/* One card in the demo band, centred rather than stranded in the left half. */
.demo-band:has(> .demo-card:only-child){ grid-template-columns: minmax(0, 34rem);
  justify-content:center; }


/* `hidden` sets display:none in the UA stylesheet, and .hc-form sets
   display:flex — author CSS wins, so the attribute did nothing at all and the
   form stayed on screen above its own results. */
.hc-form[hidden]{ display:none !important; }


/* ===========================================================================
   MOTION PARITY
   Not new effects — the ones already on the site, applied to the elements that
   were left out. A grid where three cards lift on hover and the fourth does
   not reads as a bug.
   =========================================================================== */

/* .hour, .card2 and .int-card were the only card types with no hover state. */
.hour, .card2, .int-card {
  transition: transform var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease);
}
.hour:hover, .card2:hover, .int-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: var(--border-strong);
}
@media (prefers-reduced-motion: reduce){
  .hour, .card2, .int-card { transition: none; }
  .hour:hover, .card2:hover, .int-card:hover { transform: none; }
}

/* ---- reading progress ---------------------------------------------------
   A 2px line under the header. On a 14,000px page there is otherwise nothing
   telling you whether you are near the end. Injected by site.js so it does not
   have to be pasted into eighteen files. */
.vp-progress{
  position: fixed; top: 0; left: 0; height: 2px; width: 100%;
  background: var(--p); z-index: var(--z-overlay); pointer-events: none;
  /* Driven by --vp-progress rather than an animated width: the same measured
     line, scaled on the compositor. site.js sets the custom property. */
  transform: scaleX(var(--vp-progress, 0)); transform-origin: left center;
  transition: transform .08s linear;
}
@media (prefers-reduced-motion: reduce){ .vp-progress{ transition: none; } }

/* ---- photo bands drift with the scroll ----------------------------------
   Small on purpose: 24px across a whole screen. Enough to read as depth,
   little enough that nobody notices it is happening. */
.photo-band[data-par]{ --par: 0px; }
.photo-band[data-par] .ov{ transform: translateY(var(--par)); }
@media (prefers-reduced-motion: reduce){
  .photo-band[data-par] .ov{ transform: none; }
}


/* ---- pricing teaser, front page ----------------------------------------
   Two cards, two numbers, two ways in. The full comparison is a page away and
   does not need repeating here. */
.ptease{ display:grid; grid-template-columns:repeat(auto-fit,minmax(17rem,1fr));
  gap: var(--space-5); max-width:52rem; margin:0 auto; }
.pt-card{
  display:block; background: var(--card); border:1px solid var(--line);
  border-radius: var(--rad);
  /* --space-7 does not exist (the scale is 1,2,3,4,5,6,8,12,16,24), and an
     invalid value makes the browser drop the whole shorthand — these cards
     had no padding at all and the text sat on the border. */
  padding: var(--space-8) var(--space-6);
  text-decoration:none; color:inherit; position:relative;
  transition: transform var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease);
}
.pt-card:hover{ transform:translateY(-3px); box-shadow: var(--shadow-md);
  border-color: var(--border-strong); }
.pt-card.pop{ border-color: var(--p); box-shadow: 0 0 0 1px var(--p); }
.pt-card b{ display:block; font-size:1.05rem; margin-bottom: var(--space-3); }
.pt-price{ display:flex; align-items:baseline; gap:7px; flex-wrap:wrap;
  margin-bottom: var(--space-3); }
.pt-price .amt{ font-size: clamp(1.7rem, 1.4rem + 1.1vw, 2.2rem); font-weight:600;
  letter-spacing:-.02em; line-height:1; }
.pt-unit{ font-size:.82rem; color: var(--fg-muted); }
.pt-card p{ font-size:.9rem; color: var(--fg-muted); margin:0 0 var(--space-5); }
.pt-go{ display:inline-flex; align-items:center; gap:7px;
  font-weight: var(--weight-semi); font-size:.9rem; color: var(--p); }
.pt-go svg{ transition: transform var(--duration-fast) var(--ease); }
.pt-card:hover .pt-go svg{ transform: translateX(4px); }
@media (prefers-reduced-motion: reduce){
  .pt-card, .pt-go svg{ transition:none; }
  .pt-card:hover{ transform:none; }
}


/* ===========================================================================
   NO WIDOWS
   A grid that leaves one item alone on a second row reads as something that
   fell off the end. Both of these had a count the column rule could not
   divide.
   =========================================================================== */

/* Five services. auto-fit gave four across and one stranded below. */
.wserv{ grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
@media (min-width: 1180px){ .wserv{ grid-template-columns: repeat(5, 1fr); } }
@media (min-width: 700px) and (max-width: 1179px){
  .wserv{ grid-template-columns: repeat(2, 1fr); }
}
/* Cards in a row match each other, so a two-line title does not make one card
   taller than its neighbours. */
.wserv-i{ display:flex; flex-direction:column; }

/* Three trust marks under the hero, on one line where there is room. */
.hero-tr{ flex-wrap: wrap; column-gap: var(--space-6); row-gap: var(--space-2); }
@media (min-width: 860px){ .hero-tr{ flex-wrap: nowrap; } }

/* The two teaser cards end level whatever their copy does. */
.ptease{ align-items: stretch; }
.pt-card{ display:flex; flex-direction:column; }
.pt-card .pt-go{ margin-top:auto; }


/* ===========================================================================
   MOTION VOCABULARY
   One set of gestures, used on every page, so the site moves like one thing.
   Timing and easing come from the tokens, not from per-effect guesses.
   =========================================================================== */
:root{
  /* A little overshoot. Linear ease-out is correct and lifeless; this settles. */
  --spring: cubic-bezier(.22,1,.36,1);
  --fx-slow: 720ms;
}

/* ---- headings wipe up behind a mask -------------------------------------
   A fade tells you the page loaded. A wipe tells you it arrived. The mask is
   the element's own box, so there is nothing extra in the markup. */
@media (prefers-reduced-motion: no-preference){
  .reveal.rv-wait h1,
  .reveal.rv-wait h2,
  .rv-wait.sec-head h2{
    clip-path: inset(0 0 100% 0);
    transform: translateY(.28em);
  }
  .reveal.rv-in h1,
  .reveal.rv-in h2,
  .rv-in.sec-head h2{
    clip-path: inset(0 0 -.25em 0);
    transform: none;
    transition: clip-path var(--fx-slow) var(--spring),
                transform var(--fx-slow) var(--spring);
  }
}

/* ---- the eyebrow draws its own rule -------------------------------------
   Every section opens the same way, which is most of what "cohesive" means. */
.eyebrow{ position:relative; }
@media (prefers-reduced-motion: no-preference){
  .eyebrow::after{
    content:''; position:absolute; top:50%; left:calc(100% + 12px);
    height:1px; width:44px; background: currentColor; opacity:.4;
    /* Width animated 0 -> 44px on every section reveal. Same drawn rule,
       scaled from its left edge, off the layout thread. */
    transform: scaleX(0); transform-origin: left center;
    transition: transform var(--fx-slow) var(--spring) 120ms;
  }
  .reveal.rv-in .eyebrow::after,
  .rv-in.sec-head .eyebrow::after{ transform: scaleX(1); }
  /* Centred headings have text on both sides; a rule hanging off one is lopsided. */
  .center .eyebrow::after, .sec-head.center .eyebrow::after{ display:none; }
}

/* ---- cards rise and settle ---------------------------------------------- */
@media (prefers-reduced-motion: no-preference){
  .reveal.rv-wait > *{ transform: translateY(16px) scale(.985); }
  .reveal.rv-in > *{
    transform: none;
    transition: opacity 520ms var(--spring), transform 620ms var(--spring);
  }
}

/* ---- a soft light follows the pointer -----------------------------------
   The one effect people actually notice. --mx/--my are set by site.js on
   pointermove; with no pointer the highlight simply never appears. */
.vp, .plan, .pt-card, .demo-card, .wserv-i, .hour, .card2, .proof-i,
.help-cat, .ct-route, .int-card, .art-card{ position:relative; isolation:isolate; }

@media (hover:hover) and (prefers-reduced-motion: no-preference){
  .vp::after, .plan::after, .pt-card::after, .demo-card::after, .wserv-i::after,
  .hour::after, .card2::after, .proof-i::after, .help-cat::after,
  .ct-route::after, .int-card::after, .art-card::after{
    content:''; position:absolute; inset:0; z-index:-1; pointer-events:none;
    border-radius:inherit; opacity:0;
    transition: opacity 260ms var(--ease);
    background: radial-gradient(220px circle at var(--mx,50%) var(--my,50%),
                                rgba(47,109,147,.10), transparent 65%);
  }
  .vp:hover::after, .plan:hover::after, .pt-card:hover::after,
  .demo-card:hover::after, .wserv-i:hover::after, .hour:hover::after,
  .card2:hover::after, .proof-i:hover::after, .help-cat:hover::after,
  .ct-route:hover::after, .int-card:hover::after, .art-card:hover::after{ opacity:1; }
}

/* ---- primary buttons take a slow shine ---------------------------------- */
@media (hover:hover) and (prefers-reduced-motion: no-preference){
  .btn-p{ position:relative; overflow:hidden; }
  .btn-p::after{
    content:''; position:absolute; top:0; bottom:0; left:-120%; width:60%;
    background: linear-gradient(100deg, transparent,
                rgba(255,255,255,.28), transparent);
    transform: skewX(-18deg); pointer-events:none;
  }
  .btn-p:hover::after{ animation: btnShine 720ms var(--ease); }
  @keyframes btnShine{ to{ left:150%; } }
}

/* ---- the dark sections drift like the hero does -------------------------
   Same idea as .blob, so both halves of the site behave alike rather than one
   being animated and the other being flat. */
.navy-sec{ position:relative; overflow:hidden; isolation:isolate; }
.navy-sec::before, .navy-sec::after{
  content:''; position:absolute; z-index:-1; border-radius:50%;
  filter: blur(70px); pointer-events:none;
}
.navy-sec::before{
  width:34rem; height:34rem; left:-10rem; top:-12rem;
  background: radial-gradient(circle, rgba(127,178,206,.20), transparent 70%);
}
.navy-sec::after{
  width:28rem; height:28rem; right:-8rem; bottom:-10rem;
  background: radial-gradient(circle, rgba(232,115,74,.14), transparent 70%);
}
@media (prefers-reduced-motion: no-preference){
  .navy-sec::before{ animation: auroraA 26s ease-in-out infinite alternate; }
  .navy-sec::after{  animation: auroraB 31s ease-in-out infinite alternate; }
  @keyframes auroraA{ to{ transform: translate3d(5rem, 3rem, 0) scale(1.12); } }
  @keyframes auroraB{ to{ transform: translate3d(-4rem, -3rem, 0) scale(1.08); } }
}


/* ---- the demo section shows the application ------------------------------
   Wide and centred, because it is the thing the heading promises rather than
   an illustration beside something else. */
.demo-live{ max-width: 62rem; margin: 0 auto; }
.demo-live .frame{ margin: 0 auto; }
.demo-cta{
  display:flex; flex-wrap:wrap; gap: var(--space-4);
  align-items:center; justify-content:center;
  margin-top: var(--space-8);
}
.demo-note{
  flex-basis:100%; text-align:center; margin:0;
  font-size:.85rem; color: var(--fg-muted);
}
@media (max-width: 560px){
  .demo-cta .btn{ flex:1 1 100%; justify-content:center; }
}


/* ===========================================================================
   /PRICING
   =========================================================================== */

.pr-hero{ padding-bottom: var(--space-8); text-align:center; position:relative;
  overflow:hidden; }
.pr-head{ max-width: 46rem; margin: 0 auto; }
.pr-hero h1{ margin: var(--space-4) 0 var(--space-5); }

/* ---- both numbers, before anything else --------------------------------- */
.pr-chips{
  display:flex; gap: var(--space-4); justify-content:center; flex-wrap:wrap;
  margin-top: var(--space-8);
}
.pr-chip{
  display:flex; align-items:baseline; gap: var(--space-3);
  background: var(--card); border:1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: var(--space-3) var(--space-6);
  text-decoration:none; color:inherit;
  box-shadow: var(--shadow-sm);
  transition: transform var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease);
}
.pr-chip:hover{ transform: translateY(-2px); box-shadow: var(--shadow-md); }
.pr-chip-k{ font-size:.82rem; font-weight: var(--weight-semi); }
.pr-chip b{ font-size:1.25rem; letter-spacing:-.02em; }
.pr-chip-u{ font-size:.75rem; color: var(--fg-muted); }
@media (prefers-reduced-motion: reduce){
  .pr-chip{ transition:none; } .pr-chip:hover{ transform:none; }
}

.pr-cur{
  display:flex; align-items:center; gap: var(--space-3); justify-content:center;
  margin-top: var(--space-6); font-size:.82rem; color: var(--fg-muted);
}

/* ---- the two products ---------------------------------------------------- */
.pr-products{ padding-top: var(--space-8); }
.pr-grid{ display:flex; flex-direction:column; gap: var(--space-6);
  max-width: 64rem; margin: 0 auto; }

/* The website is the bigger sale, so it is the one the page points at. */


.pr-kind{
  display:inline-block; align-self:flex-start;
  font-family: var(--mono); font-size:.7rem; text-transform:uppercase;
  letter-spacing:.08em; color: var(--p);
  background: var(--brand-accent-soft);
  border-radius: var(--radius-pill);
  padding: 4px 11px; margin-bottom: var(--space-4);
}
.pr-card h2{ font-size:1.4rem; margin-bottom: var(--space-2); }
.pr-desc{ font-size:.92rem; color: var(--fg-muted); margin-bottom: var(--space-6); }

.pr-price{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
.pr-amt{ font-size: clamp(2.1rem, 1.6rem + 2vw, 3rem); font-weight:600;
  letter-spacing:-.03em; line-height:1; }
.pr-unit{ font-size:.86rem; color: var(--fg-muted); }
.pr-sub{ font-size:.86rem; color: var(--fg-muted); margin-top: var(--space-3); }
.pr-sub b{ color: var(--fg); }
.pr-first{ display:block; margin-top:4px; font-size:.79rem; }

/* ---- the seat control, inside the card it prices ------------------------ */
.pr-seats{
  margin-top: var(--space-6); padding-top: var(--space-6);
  border-top:1px solid var(--line);
}
.pr-seats-top{ display:flex; align-items:baseline; justify-content:space-between;
  gap:10px; margin-bottom: var(--space-4); }
.pr-seats-top label{ font-size:.88rem; font-weight: var(--weight-semi); }
.pr-seats .seat-n{ font-size:1.3rem; font-weight:600; color: var(--p);
  font-variant-numeric: tabular-nums; }
.pr-seats .seat-save{ margin-top: var(--space-3); font-size:.82rem; }
.pr-seats .seat-ent{ margin-top: var(--space-3); font-size:.82rem; }
.pr-seats .seg{ margin-top: var(--space-5); width:100%; }
.pr-seats .seg button{ flex:1; }

/* ---- features ----------------------------------------------------------- */
.pr-feat{ list-style:none; margin: var(--space-6) 0 0; padding:0;
  display:flex; flex-direction:column; gap: var(--space-3); }
.pr-feat li{ display:flex; gap:10px; align-items:flex-start; font-size:.9rem; }
.pr-feat svg{ flex:none; margin-top:2px; }

/* ---- the website's own services ----------------------------------------- */
.pr-extras{
  margin-top: var(--space-6); padding-top: var(--space-6);
  border-top:1px solid var(--line);
}
.pr-extras > b{ display:block; font-size:.92rem; }
.pr-extras > p{ font-size:.8rem; color: var(--fg-muted); margin: 4px 0 var(--space-4); }

/* ---- the call to action sticks to the bottom of the card ---------------- */
.pr-go{ margin-top:auto; padding-top: var(--space-6); }
.pr-go .btn{ width:100%; justify-content:center; }
.pr-note{ display:block; margin-top: var(--space-3); text-align:center;
  font-size:.78rem; color: var(--fg-muted); }

.pr-fine{ margin-top: var(--space-8); font-size:.82rem; color: var(--fg-muted);
  max-width:42em; margin-inline:auto; }

/* ---- what is true of both ------------------------------------------------ */
.pr-shared{
  display:grid; gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  max-width: 62rem; margin: 0 auto;
}
.prs{
  background: var(--card); border:1px solid var(--line);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  position:relative; isolation:isolate;
  transition: transform var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease);
}
.prs:hover{ transform: translateY(-2px); box-shadow: var(--shadow-md);
  border-color: var(--border-strong); }
.prs svg{ color: var(--p); display:block; margin-bottom: var(--space-4); }
.prs b{ display:block; font-size:.95rem; margin-bottom: var(--space-2); }
.prs span{ display:block; font-size:.85rem; color: var(--fg-muted); line-height:1.6; }
@media (prefers-reduced-motion: reduce){
  .prs{ transition:none; } .prs:hover{ transform:none; }
}

@media (max-width: 640px){
  .pr-card{ padding: var(--space-6) var(--space-5); }
  .pr-chips{ gap: var(--space-3); }
  .pr-chip{ flex:1 1 100%; justify-content:center; }
}


/* ---- one band per product ------------------------------------------------
   Full width, offer on the left, that product's own detail on the right. Two
   equal columns side by side would frame them as alternatives — and it forced
   a card with five services to be the same height as one with a slider. */
.pr-band{
  display:grid; grid-template-columns: minmax(0,7fr) minmax(0,9fr);
  gap: var(--space-8);
  background: var(--card); border:1px solid var(--line);
  border-radius: var(--rad);
  padding: var(--space-8);
  position:relative; isolation:isolate;
}
.pr-band.accent{ border-color: var(--p); box-shadow: 0 0 0 1px var(--p), var(--shadow-md); }
@media (max-width: 860px){
  .pr-band{ grid-template-columns: 1fr; gap: var(--space-6); padding: var(--space-6); }
}
.pr-offer{ display:flex; flex-direction:column; }
.pr-offer .pr-go{ margin-top:auto; padding-top: var(--space-6); }
.pr-detail{ display:flex; flex-direction:column; }
/* The first thing in the right column lines up with the name, not the chip. */
.pr-detail > :first-child{ margin-top:0; }
.pr-detail .pr-feat{ margin-top: var(--space-6); }
.pr-detail > .pr-feat:first-child{ margin-top:0; }
.pr-detail .pr-seats{ margin-top:0; padding-top:0; border-top:0; }

/* The services sit two-up where there is room, so five rows are not a column
   of five. */
/* Across the whole band, so five services are three columns rather than a
   stack of five beside an empty half. */
.pr-wide{ grid-column: 1 / -1; margin-top: var(--space-8);
  padding-top: var(--space-6); border-top:1px solid var(--line); }
/* Five services. Four columns leaves one alone underneath, and no minmax
   fixes a count that does not divide — so three columns, and flex centres
   the remaining two rather than hanging them on the left. */
.wx-grid{ display:flex; flex-wrap:wrap; gap: var(--space-3); justify-content:center; }
.wx-grid > .wx-row{ flex: 1 1 calc(33.333% - var(--space-3)); min-width:13rem;
  max-width: 22rem; }
@media (max-width: 780px){ .wx-grid > .wx-row{ flex-basis: calc(50% - var(--space-3)); } }
@media (max-width: 520px){ .wx-grid > .wx-row{ flex-basis:100%; max-width:none; } }


/* ---- 404 --------------------------------------------------------------- */
.nf-grid{ display:grid; gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  max-width: 56rem; margin: 0 auto; }
.nf-card{
  display:block; text-decoration:none; color:inherit;
  background: var(--card); border:1px solid var(--line);
  border-radius: var(--radius-md); padding: var(--space-5);
  position:relative; isolation:isolate;
  transition: transform var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease);
}
.nf-card:hover{ transform: translateY(-2px); box-shadow: var(--shadow-md);
  border-color: var(--border-strong); }
.nf-card b{ display:block; font-size:.98rem; margin-bottom: var(--space-2); color: var(--p); }
.nf-card span{ display:block; font-size:.87rem; color: var(--fg-muted); line-height:1.6; }
@media (prefers-reduced-motion: reduce){
  .nf-card{ transition:none; } .nf-card:hover{ transform:none; }
}
