/* xovv.io site styles.
   Layout: one 5/7 grid axis down the page; dark → one light span (coverage + also offered) → dark setup and contact.
   The frosted stack is the only big motion; everything else is type, hairlines, and frosted surfaces.
   Default tone is dark; /assets/js/site.js adds body.tone-light while the coverage section fills the view. */

@property --bg { syntax: '<color>'; inherits: true; initial-value: #0C0C0E; }
@property --fg { syntax: '<color>'; inherits: true; initial-value: #F6F6F8; }
@property --fg-2 { syntax: '<color>'; inherits: true; initial-value: #D4D4DB; }
@property --fg-3 { syntax: '<color>'; inherits: true; initial-value: #A0A0AB; }
@property --fg-4 { syntax: '<color>'; inherits: true; initial-value: #7C7C87; }
@property --line { syntax: '<color>'; inherits: true; initial-value: rgba(255,255,255,.11); }
@property --field { syntax: '<color>'; inherits: true; initial-value: #121217; }
@property --accent-text { syntax: '<color>'; inherits: true; initial-value: #6C98F7; }
@property --nav-bg { syntax: '<color>'; inherits: true; initial-value: rgba(12,12,14,.72); }
@property --wordmark { syntax: '<color>'; inherits: true; initial-value: #F6F6F8; }
@property --frost-fill { syntax: '<color>'; inherits: true; initial-value: rgba(255,255,255,.04); }
@property --frost-stroke { syntax: '<color>'; inherits: true; initial-value: rgba(255,255,255,.09); }
@property --frost-edge { syntax: '<color>'; inherits: true; initial-value: rgba(255,255,255,.10); }

:root {
  --bg: #0C0C0E; --fg: #F6F6F8; --fg-2: #D4D4DB; --fg-3: #A0A0AB; --fg-4: #7C7C87;
  --line: rgba(255,255,255,.11); --field: #121217; --accent-text: #6C98F7; --nav-bg: rgba(12,12,14,.72); --wordmark: #F6F6F8;
  --frost-fill: rgba(255,255,255,.04); --frost-stroke: rgba(255,255,255,.09); --frost-edge: rgba(255,255,255,.10);
  --blue: #2563EB; --blue-press: #1D55D0; --ok: #34D399; --err: #F87171;

  --display: 'Outfit', 'Outfit Fallback', ui-sans-serif, system-ui, sans-serif;
  --mono: 'DM Mono', 'DM Mono Fallback', ui-monospace, monospace;
  --t-display: clamp(40px, 8vw, 96px);
  --t-chapter: clamp(34px, 4.6vw, 52px);
  --t-minor: clamp(26px, 3vw, 34px);
  --t-title: 18px;
  --t-lead: clamp(19px, 2vw, 22px);
  --t-body: 17px;
  --t-small: 15px;
  --t-meta: 13px;

  --gutter: clamp(32px, 6vw, 80px);
  --section: clamp(88px, 11vw, 144px);
  --ease-out: cubic-bezier(.16,1,.3,1);
  --t-fast: 120ms;
  --t: 220ms;
  color-scheme: dark;
}
body.tone-light {
  --bg: #F6F6F8; --fg: #0C0C0E; --fg-2: #2C2C32; --fg-3: #55555F; --fg-4: #6E6E78;
  --line: #DADAE1; --field: #FFFFFF; --accent-text: #2563EB; --nav-bg: rgba(246,246,248,.78); --wordmark: #2C2C32;
  --frost-fill: rgba(255,255,255,.75); --frost-stroke: rgba(12,12,14,.09); --frost-edge: rgba(255,255,255,.95);
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { scroll-behavior: smooth; scroll-padding-top: 88px; }
body {
  margin: 0; background: var(--bg); color: var(--fg); font-family: var(--display); font-weight: 400;
  -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent;
  transition: --bg .9s ease, --fg .9s ease, --fg-2 .9s ease, --fg-3 .9s ease, --fg-4 .9s ease, --line .9s ease, --field .9s ease, --accent-text .9s ease, --nav-bg .9s ease, --wordmark .9s ease, --frost-fill .9s ease, --frost-stroke .9s ease, --frost-edge .9s ease;
}
body.no-anim, body.no-anim * { transition: none !important; }
::selection { background: var(--blue); color: #fff; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.wrap { max-width: 1120px; margin: 0 auto; padding-inline: clamp(16px, 5vw, 48px); }
a { color: inherit; }
h1, h2, h3, h4 { text-wrap: balance; margin: 0; font-weight: 500; }
p, li { text-wrap: pretty; }
p { margin: 0; }
.split { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--gutter); }
.label { font-family: var(--mono); font-weight: 400; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: var(--fg-3); }
.chapter { font-size: var(--t-chapter); line-height: 1.04; letter-spacing: -.03em; margin-top: 20px; }
.minor { font-size: var(--t-minor); line-height: 1.1; letter-spacing: -.02em; }
.dim { color: var(--fg-4); }
h1 .dim, h2 .dim { display: block; }
.lead { font-size: var(--t-lead); line-height: 1.5; color: var(--fg-2); max-width: 60ch; }
.body { font-size: var(--t-body); line-height: 1.6; color: var(--fg-3); max-width: 65ch; }
.meta { font-size: var(--t-meta); line-height: 1.5; color: var(--fg-4); }
@media (min-width: 340px) { .nw { white-space: nowrap; } }

/* buttons + focus */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; font: 500 15px/1 var(--display); text-decoration: none; padding: 14px 22px; border-radius: 999px; border: 0; cursor: pointer; transition: background var(--t) var(--ease-out), color var(--t) var(--ease-out), transform 200ms var(--ease-out); }
.btn:active { transform: scale(.98); transition-duration: 80ms; }
.btn-primary { background: var(--blue); color: #fff; }
.btn-primary:active { background: var(--blue-press); }
.btn-quiet { color: var(--fg-2); background: none; padding-inline: 2px; }
.btn-quiet svg { width: 16px; height: 16px; transition: transform var(--t) var(--ease-out); }
.btn[disabled] { cursor: progress; }
@media (hover: hover) and (pointer: fine) {
  .btn-primary:hover { background: var(--blue-press); }
  .btn-quiet:hover { color: var(--fg); }
  .btn-quiet:hover svg { transform: translateX(3px); }
}
:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }
.btn-primary:focus-visible { outline-color: var(--fg); }
.skip { position: fixed; left: 50%; top: calc(72px + env(safe-area-inset-top, 0px)); z-index: 80; transform: translate(-50%, calc(-100% - 80px - env(safe-area-inset-top, 0px))); padding: 10px 16px; border-radius: 999px; background: var(--nav-bg); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); border: 1px solid var(--line); font-size: 14px; text-decoration: none; }
.skip:focus { transform: translate(-50%, 0); }

/* nav */
.nav { position: sticky; top: env(safe-area-inset-top, 0px); z-index: 50; background: var(--nav-bg); backdrop-filter: saturate(160%) blur(18px); -webkit-backdrop-filter: saturate(160%) blur(18px); border-bottom: 1px solid transparent; transition: border-color .3s; }
.nav.scrolled { border-bottom-color: var(--line); }
.nav.scrolled.joined { border-bottom-color: transparent; }
.nav-in { display: flex; align-items: center; justify-content: space-between; height: 64px; gap: 16px; }
.brand, .links a { white-space: nowrap; }
.brand { text-decoration: none; font-weight: 600; font-size: 17px; letter-spacing: .02em; color: var(--wordmark); }
.brand .x { color: var(--blue); }
/* Bigger tap areas without changing the look (44px is the comfortable minimum). */
.brand { display: inline-block; padding-block: 12px; margin-block: -12px; }
.links .btn { position: relative; }
.links .btn::after { content: ''; position: absolute; inset: -5px -4px; }
/* The tap flash is off, so links show a quick pressed state instead. */
a:not(.btn):active { opacity: .6; }
.links { display: flex; align-items: center; gap: 30px; }
.links a:not(.btn) { position: relative; font-size: 14px; color: var(--fg-3); text-decoration: none; transition: color var(--t) var(--ease-out); }
.links a:not(.btn)::after { content: ''; position: absolute; left: 0; right: 0; bottom: -7px; height: 1px; background: currentColor; opacity: 0; transition: opacity var(--t) var(--ease-out); }
.links a[aria-current]:not(.btn) { color: var(--fg); }
.links a[aria-current]:not(.btn)::after { opacity: 1; }
@media (hover: hover) and (pointer: fine) { .links a:not(.btn):hover { color: var(--fg); } }
.links .btn { padding: 10px 18px; font-size: 14px; }

/* hero */
.hero { padding-block: clamp(72px, 12vw, 152px) clamp(56px, 8vw, 96px); }
.hero h1 { font-size: var(--t-display); line-height: .96; letter-spacing: -.04em; max-width: 12ch; margin-top: 20px; }
.hero .lead { margin-top: 28px; }
.hero-ctas { display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: center; margin-top: 36px; }

/* spec strip (hero facts + also offered) */
.strip { display: grid; grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr)); column-gap: 48px; row-gap: 20px; border-top: 1px solid var(--line); }
.strip > div { padding-top: 24px; display: grid; gap: 6px; align-content: start; position: relative; }
.strip > div + div::before { content: ''; position: absolute; left: -24px; top: 24px; bottom: 0; width: 1px; background: var(--line); }
.strip b { font-weight: 500; font-size: var(--t-title); line-height: 1.3; }
.strip span { font-size: var(--t-small); line-height: 1.5; color: var(--fg-3); }
.hero .strip { margin-top: clamp(64px, 9vw, 112px); }
.hero .strip b { font-size: 22px; letter-spacing: -.01em; }

/* story */
.story { padding-block: var(--section); }
.story-body { display: grid; gap: 24px; }
.story-body .lead { color: var(--fg); }
.principles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 36px 40px; margin-top: 16px; padding-top: 36px; border-top: 1px solid var(--line); }
.principle { display: grid; gap: 8px; align-content: start; }
.principle h3 { font-size: var(--t-title); line-height: 1.3; }
.principle p { font-size: var(--t-small); line-height: 1.55; color: var(--fg-3); }

/* coverage */
.coverage { padding-block: var(--section); }
.coverage-head .body { align-self: end; }
.coverage-body { margin-top: clamp(48px, 7vw, 88px); align-items: start; }
.diagram { position: sticky; top: 88px; margin: 0; }
.diagram svg { width: 100%; height: auto; display: block; overflow: visible; }
.diagram figcaption { margin-top: 10px; text-align: center; }
.now { display: none; }
.now b { font-weight: 500; font-size: 19px; letter-spacing: -.01em; }
.pips { display: flex; gap: 4px; margin-top: 4px; }
.pips i { position: relative; flex: 1; height: 3px; border-radius: 2px; background: var(--line); transition: background .3s; cursor: pointer; }
/* Each dash is a tap target for its layer (site.js); the invisible area keeps it easy to hit. */
.pips i::after { content: ''; position: absolute; inset: -14px -2px; }
.pips i.on { background: var(--blue); }

/* frosted plates (the #frostTop / #frostTopOn gradients live in each page's SVG <defs>) */
.plate { transition: transform .45s var(--ease-out), opacity .3s; }
.plate .top { fill: url(#frostTop); stroke: rgba(37,99,235,.2); stroke-width: 1; transition: stroke .3s; }
.plate .sl { fill: rgba(206,217,242,.85); transition: fill .3s; }
.plate .sr { fill: rgba(176,194,234,.9); transition: fill .3s; }
.plate .edge { fill: none; stroke: rgba(255,255,255,.95); stroke-width: 1.5; stroke-linejoin: round; }
.plate .ico { fill: none; stroke: var(--blue); stroke-opacity: .7; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: stroke-opacity .3s; }
.plate .lead-line { stroke: #C9C9D2; stroke-width: 1; transition: stroke .3s; }
.plate .name { font-family: var(--mono); font-size: 11px; letter-spacing: .14em; fill: #8A8A95; transition: fill .3s; }
.plate.dark .top { fill: rgba(18,18,24,.95); stroke: rgba(255,255,255,.14); }
.plate.dark .sl { fill: rgba(12,12,14,.95); }
.plate.dark .sr { fill: rgba(5,5,6,.95); }
.plate.dark .edge { stroke: rgba(255,255,255,.22); }
.plate.dark .ico { stroke: #6C98F7; stroke-opacity: .8; }
.diagram.active .plate:not(.on) { opacity: .6; }
.plate.on { transform: translateY(-14px); }
.plate.on .top { fill: url(#frostTopOn); stroke: var(--blue); }
.plate.on .sl { fill: rgba(150,180,245,.85); }
.plate.on .sr { fill: rgba(120,158,240,.9); }
.plate.on .ico { stroke-opacity: 1; }
.plate.on .lead-line { stroke: var(--blue); }
.plate.on .name { fill: var(--blue); }
.plate.dark.on .top { fill: rgba(18,18,24,.95); stroke: var(--blue); }
.plate.dark.on .sl { fill: rgba(12,12,14,.95); }
.plate.dark.on .sr { fill: rgba(5,5,6,.95); }

/* frosted tiles */
.tile { width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--frost-fill); border: 1px solid var(--frost-stroke); box-shadow: inset 0 1px 0 var(--frost-edge); color: var(--fg-2); transition: background var(--t) var(--ease-out), border-color var(--t) var(--ease-out), color var(--t) var(--ease-out); }
.tile svg { width: 22px; height: 22px; }

/* layer spec list */
.layer-list { border-bottom: 1px solid var(--line); }
.layer { display: grid; grid-template-columns: 148px minmax(0, 1fr); gap: 24px; padding-block: 28px; border-top: 1px solid var(--line); }
.layer-name { display: grid; gap: 12px; align-content: start; justify-items: start; }
.layer-name h3 { font-size: var(--t-title); line-height: 1.3; }
.layer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 14px; max-width: 46ch; }
.layer li { font-size: var(--t-small); line-height: 1.45; color: var(--fg); }
.layer li span { display: block; color: var(--fg-3); margin-top: 2px; }
.layer.on .tile { background: var(--blue); border-color: var(--blue); color: #fff; box-shadow: none; }

/* beyond the standard */
.extra { margin-top: clamp(56px, 7vw, 88px); padding: clamp(24px, 4vw, 40px); border-radius: 20px; background: var(--frost-fill); border: 1px solid var(--frost-stroke); box-shadow: inset 0 1px 0 var(--frost-edge); }
.extra-head { display: grid; gap: 16px; align-content: start; justify-items: start; }
.extra-head .btn { margin-top: 8px; }
.extra-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 32px; }
.extra-item { display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 14px; align-items: start; }
.extra-item .tile { transition: transform .3s var(--ease-out), color var(--t) var(--ease-out), box-shadow .3s var(--ease-out); }
.extra-item h4 { font-size: var(--t-title); line-height: 1.3; padding-top: 2px; }
.extra-item p { font-size: var(--t-small); line-height: 1.55; color: var(--fg-3); margin-top: 4px; }
@media (hover: hover) and (pointer: fine) {
  .extra-item:hover .tile { color: var(--blue); transform: translateY(-3px); box-shadow: 0 8px 18px rgba(37,99,235,.14), inset 0 1px 0 var(--frost-edge); }
}
.fine { margin-top: 18px; }

/* also offered */
.also { margin-top: clamp(72px, 9vw, 112px); }
.also .minor { margin-top: 20px; }
.also .strip { --cols: 3; margin-top: 32px; }

/* our own setup (check states are driven by /assets/js/checks.js; a check stays neutral until checks.js marks it .ok) */
.setup { padding-block: var(--section); }
.setup-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 20px 48px; }
.setup .chapter { max-width: 22ch; }
.setup-head .body { max-width: 46ch; color: var(--fg-2); }
.setup-card { margin-top: clamp(36px, 5vw, 48px); border-radius: 20px; overflow: hidden; background: var(--frost-fill); border: 1px solid var(--frost-stroke); box-shadow: inset 0 1px 0 var(--frost-edge); }
.setup-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.setup-item { display: grid; align-content: start; gap: 12px; padding: clamp(24px, 3vw, 32px); }
.setup-item + .setup-item { border-left: 1px solid var(--frost-stroke); }
.setup-top { order: -1; display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 6px; } /* shown first; the heading comes first for screen readers */
.setup-item h3 { font-size: var(--t-title); line-height: 1.3; }
.setup-item p { font-size: var(--t-small); line-height: 1.55; color: var(--fg-3); }
.status { display: inline-flex; align-items: center; gap: 8px; padding-top: 6px; }
.setup-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 24px; padding: 8px clamp(24px, 3vw, 32px); border-top: 1px solid var(--frost-stroke); font-family: var(--mono); font-size: 12px; color: var(--fg-3); }
.setup-foot a { display: inline; padding-block: 12px; color: var(--accent-text); text-decoration: none; }
.setup-foot a .keep { white-space: nowrap; }
.setup-foot a svg { display: inline-block; width: 14px; height: 14px; margin-left: 6px; vertical-align: -2px; transition: transform var(--t) var(--ease-out); }
@media (hover: hover) and (pointer: fine) { .setup-foot a:hover svg { transform: translateX(3px); } }
@media (max-width: 860px) {
  .setup-grid { grid-template-columns: minmax(0, 1fr); }
  .setup-item + .setup-item { border-left: 0; border-top: 1px solid var(--frost-stroke); }
}
/* Card hover: a soft light follows the cursor (--mx/--my set in site.js), the hovered tile lifts and
   its icon acts out its check (lock clicks shut, the envelope gets a check, the slash draws across),
   and a confirmed dot sends out one ripple. Mouse only; nothing moves with reduced motion. */
.setup-card { position: relative; isolation: isolate; }
.setup-card::before { content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: 0; transition: opacity .4s var(--ease-out);
  background: radial-gradient(360px circle at var(--mx, 50%) var(--my, 50%), rgba(108,152,247,.10), transparent 70%); }
.setup-item .tile { transition: transform .35s var(--ease-out), color var(--t) var(--ease-out), box-shadow .35s var(--ease-out), border-color var(--t) var(--ease-out); }
.setup-item .tile svg { overflow: visible; }
.setup-item .slash, .setup-item .tick { stroke-dasharray: 1; stroke-dashoffset: 0; }
.setup-item .stamp { opacity: 0; transform-box: fill-box; transform-origin: center; transition: opacity .4s var(--ease-out); }
.setup-item .stamp circle { fill: #141418; stroke: currentColor; }
.check .dot { position: relative; }
.check .dot::after { content: ''; position: absolute; inset: 0; border-radius: 50%; border: 1.5px solid var(--ok); opacity: 0; pointer-events: none; }
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .setup-card:hover::before { opacity: 1; }
  .setup-item:hover .tile { color: var(--blue); border-color: rgba(37,99,235,.35); transform: translateY(-3px); box-shadow: 0 10px 22px rgba(37,99,235,.16), inset 0 1px 0 var(--frost-edge); }
  .setup-item:hover .shackle { animation: shackle .6s var(--ease-out); }
  .setup-item:hover .stamp { opacity: 1; animation: pop .35s var(--ease-out) both; }
  .setup-item:hover .tick { animation: draw .4s .2s var(--ease-out) both; }
  .setup-item:hover .slash { animation: draw .55s var(--ease-out) both; }
  .setup-item.ok:hover .dot::after { animation: ripple .9s var(--ease-out); }
}
/* The same moment plays by itself once a check confirms while it's on screen, and on tap (site.js adds .play):
   touch screens get it without hover, and desktop sees it once before any hover. */
@media (prefers-reduced-motion: no-preference) {
  .setup-item.play .tile { color: var(--blue); border-color: rgba(37,99,235,.35); box-shadow: 0 10px 22px rgba(37,99,235,.16), inset 0 1px 0 var(--frost-edge); }
  .setup-item.play .shackle { animation: shackle .6s var(--ease-out); }
  .setup-item.play .stamp { opacity: 1; animation: pop .35s var(--ease-out) both; }
  .setup-item.play .tick { animation: draw .4s .2s var(--ease-out) both; }
  .setup-item.play .slash { animation: draw .55s var(--ease-out) both; }
  .setup-item.play .dot::after { animation: ripple .9s var(--ease-out); }
  /* Touch: the light rides down the glass with the scroll (site.js adds .lit), and tiles press in. */
  .setup-card.lit::before { opacity: 1; }
}
@media (hover: none) {
  .setup-item:active .tile, .extra-item:active .tile { transform: scale(.94); background: rgba(37,99,235,.14); transition-duration: 90ms; }
}
@keyframes shackle { 0% { transform: translateY(0); } 35% { transform: translateY(-2.5px); } 70% { transform: translateY(.6px); } 100% { transform: translateY(0); } }
@keyframes pop { from { opacity: 0; transform: scale(.4); } to { opacity: 1; transform: scale(1); } }
@keyframes draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes ripple { 0% { opacity: .7; transform: scale(1); } 100% { opacity: 0; transform: scale(3.2); } }
.checks-noscript { margin-top: 14px; }
.checks-noscript a { color: var(--accent-text); }

/* check states, shared by the homepage and /security */
.check .dot { display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--fg-4); box-shadow: 0 0 0 4px transparent; transition: background .3s, box-shadow .3s; }
.check .val { font-family: var(--mono); font-size: 12px; color: var(--fg-4); white-space: nowrap; font-variant-numeric: tabular-nums; transition: color .3s; }
.check.ok .dot { background: var(--ok); box-shadow: 0 0 0 4px rgba(52,211,153,.14); }
.check.ok .val { color: var(--accent-text); }
.check.pending .dot { background: var(--fg-4); box-shadow: 0 0 0 4px transparent; animation: pulse 1s ease-in-out infinite; }
.check.pending .val { color: var(--fg-4); }
.check.unavailable .dot { background: var(--fg-4); box-shadow: 0 0 0 4px transparent; animation: none; }
.check.unavailable .val { color: var(--fg-4); }
/* On the frosted card the lighter grey keeps status text above 4.5:1 contrast. */
.setup-card .check:not(.ok) .val { color: var(--fg-3); }
@keyframes pulse { 50% { opacity: .35; } }

/* "Technical detail" disclosures on /security */
.verify { margin-top: 10px; font-size: var(--t-small); }
.verify summary { display: inline-flex; align-items: center; gap: 6px; min-height: 28px; cursor: pointer; list-style: none; font-family: var(--mono); font-size: 12px; color: var(--fg-4); transition: color var(--t) var(--ease-out); }
.verify summary::-webkit-details-marker { display: none; }
.verify summary::before { content: ''; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); transition: transform var(--t) var(--ease-out); }
.verify[open] summary::before { transform: rotate(45deg); }
.verify[open] summary, .verify summary:focus-visible { color: var(--fg-2); }
@media (hover: hover) and (pointer: fine) { .verify summary:hover { color: var(--fg-2); } }
.verify-body { display: grid; gap: 10px; margin-top: 10px; padding: 14px 16px; border-radius: 12px; background: var(--frost-fill); border: 1px solid var(--frost-stroke); color: var(--fg-3); line-height: 1.55; max-width: 62ch; }
.verify-body a { color: var(--accent-text); }
.verify-body code { font-family: var(--mono); font-size: 12px; color: var(--fg-2); overflow-wrap: anywhere; }
.verify-body > code { display: block; padding: 10px 12px; border-radius: 8px; background: rgba(0,0,0,.25); border: 1px solid var(--line); white-space: pre-wrap; }
/* Visually hidden, still read by screen readers (e.g. which "Technical detail" this is). */
.vh { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

/* contact (form behavior lives in /assets/js/contact.js) */
.contact { padding-block: var(--section); align-items: start; }
.contact .body { margin-top: 24px; color: var(--fg-2); }
.steps { list-style: none; padding: 0; margin: 32px 0 0; border-bottom: 1px solid var(--line); }
.steps li { display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: 12px; padding-block: 16px; border-top: 1px solid var(--line); font-size: var(--t-small); line-height: 1.5; color: var(--fg-2); }
.steps li b { font-family: var(--mono); font-weight: 400; font-size: 12px; color: var(--accent-text); padding-top: 3px; }
.where { margin-top: 20px; }
form { display: grid; gap: 22px; transition: opacity 150ms ease; }
form.leaving { opacity: 0; }
.field { display: grid; gap: 8px; }
.field label { font-size: 14px; color: var(--fg-3); }
.field input, .field textarea { width: 100%; background: var(--field); border: 1px solid var(--frost-stroke); border-radius: 12px; padding: 14px 16px; font: 400 16px/1.5 var(--display); color: var(--fg); outline: none; transition: border-color var(--t) var(--ease-out), box-shadow var(--t) var(--ease-out); }
.field textarea { min-height: 140px; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: var(--fg-4); }
.field input:focus, .field textarea:focus { border-color: rgba(37,99,235,.6); box-shadow: 0 0 0 4px rgba(37,99,235,.14); }
.field [aria-invalid="true"] { border-color: rgba(248,113,113,.7); }
.err { font-size: var(--t-meta); color: var(--err); animation: errIn 150ms ease both; }
.err:empty { display: none; }
@keyframes errIn { from { opacity: 0; } }
.row2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
/* Bot check: invisible unless it needs an interaction (contact.js adds .is-active then).
   Empty, it collapses; rendered but invisible, the button row pulls up so the form never jumps. */
.turnstile { line-height: 0; min-width: 0; max-width: 100%; }
.turnstile:empty { display: none; }
/* The bot check frame stays collapsed unless a human check is needed (bot-check.js says when). */
.turnstile iframe { display: block; width: 300px; max-width: 100%; height: 0; border: 0; color-scheme: dark; }
.turnstile.is-active iframe { height: 65px; }
.turnstile:not(:empty):not(.is-active) + .form-foot { margin-top: -22px; }
.form-foot { display: flex; flex-wrap: wrap; gap: 12px 20px; align-items: center; justify-content: space-between; }
#submitBtn { min-width: 164px; }
.form-error { font-size: var(--t-small); line-height: 1.5; color: var(--err); animation: errIn 150ms ease both; }
.sent { border: 1px solid var(--frost-stroke); background: var(--frost-fill); box-shadow: inset 0 1px 0 var(--frost-edge); border-radius: 20px; padding: clamp(32px, 5vw, 56px); display: grid; justify-items: center; align-content: center; text-align: center; gap: 14px; animation: sentIn 200ms ease both; }
@keyframes sentIn { from { opacity: 0; } }
.sent svg { width: 56px; height: 56px; color: var(--blue); }
.sent .shackle { transform: translateY(-2.5px); transition: transform .45s cubic-bezier(.5,0,.2,1.4) .3s; }
.sent.closed .shackle { transform: translateY(0); }
.sent .tick { stroke-dasharray: 9; stroke-dashoffset: 9; transition: stroke-dashoffset .4s ease .75s; }
.sent.closed .tick { stroke-dashoffset: 0; }
.sent h3 { font-size: var(--t-minor); line-height: 1.1; letter-spacing: -.02em; outline: none; }
.sent p { font-size: var(--t-small); line-height: 1.55; color: var(--fg-3); max-width: 26em; }

/* footer */
footer { border-top: 1px solid var(--line); }
.foot { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; padding-block: 28px; }
.foot nav { display: flex; gap: 20px; font-family: var(--mono); font-size: 12px; }
.foot nav a { display: inline-block; padding-block: 14px; margin-block: -14px; color: var(--fg-3); text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .foot nav a:hover { color: var(--fg); } }

@media (max-width: 960px) {
  .coverage-body { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 32px; }
  .layer { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .layer-name { grid-auto-flow: column; justify-content: start; align-items: center; gap: 14px; }
}
@media (max-width: 860px) {
  .split:not(.coverage-body) { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .hero .strip { --cols: 2; }
  .hero .strip > div:nth-child(3)::before { display: none; }
}
/* Phones: the stack becomes a slim sticky "you are here" bar joined to the nav. */
@media (max-width: 640px) {
  .coverage-body { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .diagram {
    top: calc(64px + env(safe-area-inset-top, 0px)); z-index: 5;
    display: grid; grid-template-columns: 64px minmax(0, 1fr); align-items: center; gap: 16px;
    margin-inline: calc(-1 * clamp(16px, 5vw, 48px)); padding: 8px clamp(16px, 5vw, 48px);
    background: var(--nav-bg); backdrop-filter: saturate(160%) blur(18px); -webkit-backdrop-filter: saturate(160%) blur(18px);
    border-bottom: 1px solid var(--line);
  }
  .diagram svg { width: 64px; }
  .diagram figcaption { display: none; }
  #stack .plate g.lbl { display: none; }
  #stack .plate.on { transform: translateY(-10px); }
  .now { display: grid; gap: 2px; min-width: 0; }
}
/* Section links hide before the header gets too tight to fit them on one line. */
@media (max-width: 680px) {
  .links a:not(.btn) { display: none; }
}
@media (max-width: 600px) {
  .hero h1 { max-width: none; }
  .principles, .row2, .extra-grid { grid-template-columns: minmax(0, 1fr); }
  .strip { column-gap: 32px; }
  .strip > div + div::before { left: -16px; }
  .also .strip { --cols: 1; }
  .also .strip > div::before { display: none; }
}

/* Without JavaScript: the stack stays exploded and labelled (no phone mini-bar to drive),
   and the contact form, which encrypts in the browser, gives way to a short note. */
@media (scripting: none) {
  #contactForm { display: none; }
}
@media (scripting: none) and (max-width: 640px) {
  .diagram { position: static; display: block; margin: 0 0 24px; padding: 0; background: none; backdrop-filter: none; -webkit-backdrop-filter: none; border-bottom: 0; }
  .diagram svg { width: 100%; max-width: 360px; margin-inline: auto; }
  .diagram figcaption { display: block; }
  #stack .plate g.lbl { display: inline; }
  .now { display: none; }
}

/* Gentle reveals: site.js adds .rv only to elements below the first screen, then .rv-in once
   when each scrolls into view, and removes both when done. Without the script nothing is hidden. */
.rv { opacity: 0; transform: translateY(14px); transition: opacity .6s var(--ease-out), transform .6s var(--ease-out); }
.rv.rv-in { opacity: 1; transform: none; }
@media print { .rv { opacity: 1 !important; transform: none !important; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  body, * { transition: none !important; animation: none !important; }
}
