/* ==========================================================================
   VaultedOS — Base + shared primitives
   Every section MUST build from these. Do not redefine buttons, eyebrows,
   headings, or containers inside a section file.
   ========================================================================== */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font);
  font-weight: var(--fw-medium);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text);
  background: var(--bg-deep);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
/* `list-style: none` makes Safari/VoiceOver drop list semantics entirely, so
   every unstyled list on the site stops announcing as a list. An EMPTY
   list-style-type removes the marker while keeping the semantics, which is why
   it is preferred over `none` — and it means sections don't each have to
   remember `role="list"`. `none` stays as the fallback for older engines. */
ul, ol { margin: 0; padding: 0; list-style: none; }
@supports (list-style-type: "") {
  ul, ol { list-style-type: ""; }
}
h1, h2, h3, h4, p { margin: 0; }

:focus-visible {
  outline: 2px solid var(--vos-blue);
  outline-offset: 3px;
  border-radius: 4px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */

.vos-section {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(56px, 7vw, 104px);
  /* The nav is position:fixed, so an in-page anchor lands UNDER it — measured
     at 75px (375) to 90px (1440) of the target hidden. The first two terms are
     the nav's exact geometry (its top offset + its 65px height) so this tracks
     automatically if the nav is ever resized; +16px is breathing room. */
  scroll-margin-top: calc(clamp(10px, 1.74vw, 25px) + 65px + 16px);
}

/* --container is the CONTENT width (1232 = Figma's 1440 frame less its 104px
   margins). The gutter is added OUTSIDE it, so content actually measures 1232
   at wide viewports. Putting the padding inside the max-width — the original
   bug — silently squeezed every section to ~1088. */
.vos-container {
  width: 100%;
  max-width: calc(var(--container) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Centered heading stack used by most sections. */
.vos-head { text-align: center; max-width: 720px; margin-inline: auto; }
.vos-head--left { text-align: left; margin-inline: 0; }

/* --------------------------------------------------------------------------
   Bands — dark is default; add .vos-section--light for the pastel bands.
   -------------------------------------------------------------------------- */

.vos-section--alt { background: var(--bg-deep-2); }

.vos-section--light {
  background: var(--lt-bg-wash);
  color: var(--lt-text);
}
/* --vos-blue is only 2.7:1 on white and fails AA as text. Light bands get the
   darker ink blue instead — same hue, readable. */
.vos-section--light .vos-eyebrow { color: var(--vos-blue-ink); }
.vos-section--light .vos-h2 { color: var(--lt-text); }
.vos-section--light .vos-sub,
.vos-section--light .vos-body { color: var(--lt-text-muted); }

/* Hairline divider that reads as light catching an edge. */
.vos-hairline {
  height: 1px; width: 100%; border: 0; margin: 0;
  background: var(--vos-grad-hairline);
}

/* --------------------------------------------------------------------------
   Typography primitives
   -------------------------------------------------------------------------- */

/* Eyebrow: uppercase, 18px. Figma uses SOLID blue in most frames and the
   blue→mint gradient only in the hero — so solid is the default and the
   gradient is the opt-in variant, not the other way round. */
.vos-eyebrow {
  display: inline-block;
  font-size: var(--fs-eyebrow);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--vos-blue);
}

.vos-eyebrow--grad {
  background: var(--vos-grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Mint "status" pill — the sentence-case label above each product-feature
   heading (statements / receipts / reports). All three built this by hand
   independently, so it lives here now to stop the three drifting apart. */
.vos-pill--mint {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  height: 20px;
  padding: 0 var(--sp-2);
  border-radius: var(--r-pill);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  line-height: 1;
  color: var(--vos-mint-bright);
  background: rgba(95, 252, 192, .10);
  border: 0;
}
.vos-pill--mint::before {
  content: '';
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--vos-mint-bright);
  box-shadow: 0 0 8px var(--vos-mint-bright);
}
/* #5ffcc0 on white is ~1.3:1 — light bands need the dark-green ink. */
.vos-section--light .vos-pill--mint {
  color: #0a7355;
  background: rgba(10, 115, 85, .08);
  border-color: rgba(10, 115, 85, .22);
}
/* The dot was left on the bright mint and read as a pale smudge on white. */
.vos-section--light .vos-pill--mint::before {
  background: #0a7355;
  box-shadow: none;
}

/* Eyebrow wrapped in the translucent glass pill (hero + comparison). */
.vos-eyebrow-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  height: 33px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-pill);
  background: var(--vos-grad-soft);
  backdrop-filter: blur(6.55px);
  -webkit-backdrop-filter: blur(6.55px);
}

.vos-display {
  font-size: var(--fs-display);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
}

.vos-h1 {
  font-size: var(--fs-h1);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
}

.vos-h2 {
  font-size: var(--fs-h2);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
  color: var(--text);
}

/* Feature-row heading — the 32px level inside statements/receipts/reports. */
.vos-feature-h {
  font-size: var(--fs-feature);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
}

/* 20px section sub-copy that sits under a .vos-h2. Weight is reset to 400
   because body is 500 — Figma's sub-copy is Regular, and inheriting made
   every section using this render one weight heavy. */
.vos-lead {
  font-size: var(--fs-lead);
  font-weight: var(--fw-regular);
  color: var(--text-muted);
  line-height: var(--lh-lead);
}

/* 24px card title — the level between --fs-h3 (20) and --fs-feature (32). */
.vos-title {
  font-size: var(--fs-title);
  font-weight: var(--fw-semibold);
  line-height: 1.3;
}
.vos-section--light .vos-lead { color: var(--lt-text-muted); }

.vos-h3 {
  font-size: var(--fs-h3);
  font-weight: var(--fw-semibold);
  line-height: 1.3;
}

/* Body-copy primitives reset weight to 400. Body is Medium (500) for UI, but
   Figma sets prose Regular — inheriting rendered all sub-copy a weight heavy. */
.vos-sub {
  font-size: var(--fs-body);
  font-weight: var(--fw-regular);
  color: var(--text-muted);
  line-height: var(--lh-body);
}

.vos-body {
  font-weight: var(--fw-regular);
  color: var(--text-muted);
}

.vos-label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-dim);
}

/* The gradient word treatment — "write it!"
   Two sections independently hit the same footgun: overriding the gradient with
   the `background` SHORTHAND silently resets background-clip to border-box, so
   the text renders as a solid coloured bar instead of clipped type. Declared
   with background-IMAGE, and the clip is !important so a shorthand override
   can't defeat it. If you are re-colouring this, set `background-image`. */
.vos-grad-text {
  background-image: var(--vos-grad);
  -webkit-background-clip: text !important;
  background-clip: text !important;
  color: transparent;
}

/* --------------------------------------------------------------------------
   Buttons — exact Figma geometry: 44px tall, 12px radius, 24px inline pad.
   -------------------------------------------------------------------------- */

.vos-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: var(--h-control);
  padding: var(--sp-2) var(--sp-6);
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-ui);
  white-space: nowrap;
  cursor: pointer;
  border: 1px solid transparent;
  background: transparent;
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.vos-btn:hover { transform: translateY(-1px); }
/* A real pressed state, not just "cancel the hover lift" — the button sinks
   below its resting position and dims, so a press reads on every variant. */
.vos-btn:active {
  transform: translateY(1px) scale(.985);
  filter: brightness(.92);
  transition-duration: 60ms;
}

/* Primary: transparent fill, blue hairline border, soft outer bloom. */
.vos-btn--primary {
  color: #fff;
  border-color: var(--vos-blue);
  background: rgba(80, 161, 249, .06);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  box-shadow: 0 0 18px rgba(80, 161, 249, .30),
              inset 0 1px 0 rgba(255, 255, 255, .06);
}
.vos-btn--primary:hover {
  background: rgba(80, 161, 249, .14);
  box-shadow: 0 0 26px rgba(80, 161, 249, .48),
              inset 0 1px 0 rgba(255, 255, 255, .10);
}

/* Secondary: glass fill with the gold wave bleeding up from the bottom. */
/* `overflow: hidden` here used to silently CLIP a long label instead of letting
   the button grow. Only the gold wave needs clipping, so it clips itself via
   clip-path and the button no longer hides its own content. */
.vos-btn--gold {
  color: #fff;
  background: rgba(255, 255, 255, .05);
  box-shadow: var(--shadow-btn);
  text-shadow: 0 2px 8.6px rgba(0, 0, 0, .9);
}
/* Glow is contained INSIDE the button box and shaped by the gradient itself,
   so the button needs no overflow clipping and can never hide its own label. */
.vos-btn--gold::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(78% 150% at 50% 128%,
              rgba(255, 195, 0, .85) 0%,
              rgba(255, 195, 0, .30) 38%,
              transparent 68%);
  z-index: -1;
  transition: opacity var(--dur) var(--ease);
}
.vos-btn--gold:hover::before { opacity: .78; }

/* Ghost: for light bands and tertiary actions. */
.vos-btn--ghost {
  color: var(--text);
  border-color: var(--stroke-strong);
  background: var(--bg-panel);
}
.vos-btn--ghost:hover { border-color: var(--vos-blue); background: var(--bg-panel-2); }

.vos-section--light .vos-btn--ghost {
  color: var(--lt-text);
  border-color: var(--lt-stroke);
  background: #fff;
}

/* --------------------------------------------------------------------------
   Surfaces — glass card, per the "glass edge" house style.
   -------------------------------------------------------------------------- */

.vos-card {
  position: relative;
  border-radius: var(--r-xl);
  border: 1px solid var(--stroke);
  background: var(--bg-panel);
  backdrop-filter: blur(var(--blur-glass));
  -webkit-backdrop-filter: blur(var(--blur-glass));
  box-shadow: var(--shadow-card);
}

/* Sharp light-catch on the upper-left / lower-right edges. */
.vos-card--edge::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg,
              rgba(255,255,255,.30) 0%,
              rgba(255,255,255,.02) 32%,
              rgba(255,255,255,.02) 68%,
              rgba(139,227,202,.24) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.vos-section--light .vos-card {
  border-color: var(--lt-stroke);
  background: var(--lt-panel);
  box-shadow: var(--shadow-card-lt);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* --------------------------------------------------------------------------
   Ambient background helpers (the radial glows behind dark sections)
   -------------------------------------------------------------------------- */

.vos-glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  pointer-events: none;
  z-index: -1;
  opacity: .5;
}
.vos-glow--blue { background: radial-gradient(circle, rgba(80,161,249,.55), transparent 68%); }
.vos-glow--mint { background: radial-gradient(circle, rgba(139,227,202,.40), transparent 68%); }

/* Engraved guilloche texture — the banknote line-work behind dark sections. */
.vos-engrave::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .5;
  background-image:
    repeating-radial-gradient(circle at 78% 42%,
      transparent 0 13px, rgba(255,255,255,.030) 13px 14px),
    repeating-radial-gradient(circle at 8% 88%,
      transparent 0 17px, rgba(80,161,249,.030) 17px 18px);
}

/* --------------------------------------------------------------------------
   Scroll reveal — opt in with .vos-reveal; script.js adds .is-in.
   -------------------------------------------------------------------------- */

/* Progressive enhancement: the hidden start state is applied ONLY when the
   `js` class is present (set by an inline script in <head>). Without it the
   content renders normally. Previously a JS failure — or an observer that
   never fired — left whole sections permanently invisible. */
.js .vos-reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}
.js .vos-reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js .vos-reveal { opacity: 1; transform: none; transition: none; }
}
