
/* ===========================================================================
   Informed Trader — marketing site stylesheet.

   Shared by /, /how-it-works and /get-started. It is ONE file rather than an
   inline block per page for a single reason: the palette below is a design
   token set, and three copies of a token set drift. The same argument core's
   decisions #63 makes about duplicated infrastructure.

   Every graphic on the site is inline SVG or a CSS gradient, and the two
   typefaces are served from /fonts on this origin (below), so a page makes no
   request to any other site of its own accord.

   THEMING. :root carries the DARK values and [data-theme="light"] overrides
   them, so dark is the default with no JavaScript involved. A tiny inline
   <head> script (components/theme-boot.ts; the same snippet in each static
   page) sets data-theme BEFORE first paint from the reader's remembered
   choice, or else their device's light/dark setting — so the page never
   flashes the wrong palette. The toggles remember a click in localStorage
   ("it-theme"); with nothing remembered the device keeps deciding, live.

   The palette is lifted from core/frontend/app/globals.css so the marketing
   page and the product read as one thing.

   SPLIT IN TWO SINCE cloud #89. This file holds the tokens, the marketing
   pages, the legal pages and the sign-in pages. The signed-in app's rules are
   in `app.css`, which only `app/layout.tsx` links, loaded AFTER this one so
   that the `@layer` statement below fixes the layers' order (cloud #90). The
   static pages used to block their first paint on all 44KB (gzipped) of both
   halves, about 72% of it rules they never use. The palette is still in ONE
   place, here, which is what cloud #23b's "one file" was protecting.
   A rule a static page needs goes in this file, wherever it was written: the
   footer's legal row and the legal prose were in the app half and moved here
   in the split, and `test_marketing_nav` checks that no class a static page
   uses is styled only in app.css.
   =========================================================================== */

/* CASCADE LAYERS (cloud #90). Every rule in this file and in app.css sits
   in one of the five layers named below, and between two layers the later
   one wins, whatever either selector's specificity. Inside one layer nothing
   changed: specificity, then order. So a rule written here for the marketing
   or sign-in pages can no longer outrank an app rule by being more specific,
   which is how `.card h3` sized the app's card titles and `.field input`
   shaped the valuation slider for as long as either existed. Both still
   render exactly as before; app.css says how, where each one is. `app` is
   declared here, though app.css fills it, so that its place is fixed by the
   first stylesheet every page loads.

   A rule outside every layer would outrank all of them, so there is none.
   A browser too old for layers (before Chrome 99, Firefox 97 and Safari
   15.4, all early 2022) skips every layer block, so it now gets no styles
   from these files at all, where before it lost only the colours written
   with color-mix(). Every browser that has color-mix() has layers. */
@layer tokens, base, site, auth, app;

@layer tokens {

/* ---------------------------------------------------------------------------
   FONTS, self-hosted (cloud #85). These blocks are Google Fonts' own CSS for
   Outfit 400/500/700/800/900 and JetBrains Mono 400/500/700, with only the
   URLs changed to files in public/fonts. Each family is a variable font, so
   every weight of a subset points at the same file.

   The per-weight blocks are kept rather than collapsed into one
   `font-weight: 400 900` range, and that is deliberate: this stylesheet asks
   for weight 600 in places, and with no 600 face declared the browser rounds
   it to 700. A range would render a true 600 instead, which is a visible
   change to every page. Mirroring the old declarations keeps the site
   rendering exactly as it did when the fonts came from Google.

   The file names carry the font version, so a newer upstream release is a new
   file name rather than new bytes under an old one.
   --------------------------------------------------------------------------- */

/* cyrillic-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-cyrillic-ext.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-cyrillic.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-greek.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-cyrillic-ext.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-cyrillic.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-greek.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-cyrillic-ext.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-cyrillic.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-greek.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/jetbrainsmono-v24-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/outfit-v15-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/outfit-v15-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/outfit-v15-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/outfit-v15-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/outfit-v15-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/outfit-v15-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(/fonts/outfit-v15-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(/fonts/outfit-v15-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url(/fonts/outfit-v15-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url(/fonts/outfit-v15-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: dark;

  --bg:            #0D1016;
  --surface:       #14171F;
  --border:        #272B35;
  --raised:        #322259;

  --accent:        #9064F7;
  --accent-ink:    #160C28;
  --accent-soft:   rgba(144, 100, 247, 0.14);
  --accent-line:   rgba(144, 100, 247, 0.34);
  /* The accent as INK, which is not the same colour as the accent as a FILL —
     the same split --pos-ink/--neg-ink already needed. Measured in dark:
     #9064F7 reading on its own tint is 4.20:1 over the page and 3.89:1 over a
     card, both under the floor, because --accent-soft lightens the ground it
     is read against. This clears 5.69:1 at worst and 7.09:1 on plain
     background. Light needs no such value — its accent measures 4.68-6.09
     everywhere — so there it is simply --accent, and the pair stays honest
     rather than inventing a second light colour nobody needed. */
  --accent-ink-soft: #A98BFF;

  --pos:           #31B97A;
  --pos-bg:        #153727;
  --neg:           #E85454;
  --neg-bg:        #411616;
  /* Text-weight variants of the two above. --pos/--neg are fills and marks;
     as INK on their own tint they measure 5.19:1 and 4.31:1 here, and worse in
     light mode. These clear both the tint and the card surface in each theme. */
  --pos-ink:       #4BD79A;
  --neg-ink:       #F07070;

  --text:          #F2F2F5;
  --muted:         #9AA0AC;

  --grad-a:        #181325;
  --grad-b:        #261E38;
  --grad-c:        #341C4A;

  --logo-bg:       #322259;
  --logo-ink:      #E7E4F1;

  /* The trust band is deliberately the inverse of the page in dark mode: a
     pale, high-contrast slab directly under the hero. A guarantee should not
     look like a footnote. */
  --band-bg:       #E7E4F1;
  --band-ink:      #1B1230;
  --band-muted:    #4A3D68;
  --band-line:     rgba(27, 18, 48, 0.16);

  /* Hero text sits on the gradient, which is dark in BOTH themes but reaches
     #5E3BB0 at its lightest. These are sized against that worst stop (5.48:1)
     rather than against the dark end, and so they do NOT flip with the theme —
     the same reasoning core's sidebar tokens carry (decisions #48). */
  --hero-ink:      #F2F2F5;
  --hero-muted:    #DCD7EA;
  /* The trust band is pale in BOTH themes too, so its accent cannot be the
     page accent: #9064F7 on #E7E4F1 measures 3.13:1. */
  --band-accent:   #5B23DE;

  /* Form controls. A 1px --border hairline is right for a card edge and too
     faint for an input a user has to aim at, so inputs get their own slightly
     stronger line — and a placeholder needs to read as a hint without failing
     contrast, which --muted at 7.25:1 comfortably does. */
  --input-border:  #363B47;
  --placeholder:   #9AA0AC;

  --header-bg:     rgba(13, 16, 22, 0.72);
  --shadow-lg:     0 30px 80px -30px rgba(0, 0, 0, 0.85);
  --shadow-md:     0 18px 40px -22px rgba(0, 0, 0, 0.75);

  --font-display: 'Outfit', ui-rounded, 'SF Pro Rounded', 'Segoe UI Variable Display', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', SFMono-Regular, Menlo, Consolas, monospace;

  --shell: 1200px;
}

[data-theme="light"] {
  color-scheme: light;

  --bg:            #FFFFFF;
  --surface:       #F0F2F4;
  --border:        #E5E7EB;
  --raised:        #F5EEFC;

  --accent:        #6D34F4;
  --accent-ink:    #FFFFFF;
  --accent-soft:   rgba(109, 52, 244, 0.10);
  --accent-line:   rgba(109, 52, 244, 0.26);
  --accent-ink-soft: #6D34F4;

  --pos:           #238B5A;
  --pos-bg:        #E7F8F0;
  --neg:           #D32222;
  --neg-bg:        #FCEDED;
  --pos-ink:       #186640;
  --neg-ink:       #B81C1C;

  --text:          #141824;
  --muted:         #5A6472;

  --grad-a:        #362460;
  --grad-b:        #442786;
  --grad-c:        #5E3BB0;

  --logo-bg:       #F5EEFC;
  --logo-ink:      #4A2E8F;

  --band-bg:       #F5EEFC;
  --band-ink:      #241546;
  --band-muted:    #55447C;
  --band-line:     rgba(36, 21, 70, 0.14);

  --band-accent:   #5B23DE;

  --input-border:  #CBD1D9;
  --placeholder:   #5A6472;

  --header-bg:     rgba(255, 255, 255, 0.80);
  --shadow-lg:     0 30px 70px -34px rgba(20, 24, 36, 0.35);
  --shadow-md:     0 16px 36px -24px rgba(20, 24, 36, 0.30);
}

} /* @layer tokens */

@layer base {

/* --- reset ---------------------------------------------------------------- */

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 84px;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 1.0625rem;
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  transition: background-color .35s ease, color .35s ease;
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
h1, h2, h3, p { margin: 0; }

/* --- shared primitives ---------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: 20px;
  min-width: 0;
}

/* Every uppercase monospace label on the page routes through .mono, so the
   tracking and casing are set in exactly one place. */
.mono {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-weight: 500;
}

.display {
  font-weight: 900;
  letter-spacing: -0.035em;
  line-height: 1.02;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border-radius: 999px;
  padding: 15px 26px;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.78125rem;
  font-weight: 700;
  white-space: nowrap;
  border: 1.5px solid transparent;
  transition: transform .18s ease, background-color .2s ease,
              border-color .2s ease, box-shadow .2s ease, color .2s ease;
}
.btn .arrow { transition: transform .18s ease; }
.btn:hover .arrow { transform: translateX(3px); }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.btn-solid {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: 0 10px 30px -12px var(--accent);
}
.btn-solid:hover { filter: brightness(1.08); box-shadow: 0 14px 34px -12px var(--accent); }

/* The ghost button sits on the hero gradient, which is dark in BOTH themes —
   so its colours are light in both and must not flip with the palette. */
.btn-ghost {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(231, 228, 241, 0.34);
  color: var(--hero-ink);
}
.btn-ghost:hover { background: rgba(255, 255, 255, 0.11); border-color: rgba(231, 228, 241, 0.6); }

/* The outline button for ordinary page backgrounds. NOT .btn-ghost — that one
   is tuned for the hero gradient, which is dark in both themes, so its fixed
   light colours would be invisible on a white page. */
.btn-outline {
  background: transparent;
  border-color: var(--border);
  color: var(--text);
}
.btn-outline:hover { background: var(--accent-soft); border-color: var(--accent-line); }

.btn-sm { padding: 11px 20px; font-size: 0.71875rem; }

/* --- reveal on scroll ----------------------------------------------------- */

.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .7s cubic-bezier(.22,.61,.36,1),
              transform .7s cubic-bezier(.22,.61,.36,1);
}
.js .reveal.in-view { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  * { animation: none !important; }
}

} /* @layer base */

@layer site {

/* ===========================================================================
   1. HEADER
   =========================================================================== */

/* "Skip to content" on the static pages (WCAG 2.4.1). Out of sight until it
   has focus, then over the header's top-left corner. Its z-index is above the
   sticky header (60) and the menu overlay (80), so nothing paints over it
   while it is focused. Text on surface is the ordinary card pair, and the
   accent border stands in for the focus ring every control here uses. */
.skip-link {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 100;
  padding: 10px 16px;
  border: 2px solid var(--accent);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text);
  font-size: 0.875rem;
  font-weight: 700;
  transform: translateY(-200%);
}
.skip-link:focus { transform: none; }
/* The skip target. `<main id="main">` is focusable only so the jump lands
   there, and a ring drawn around the whole page would read as a fault. The id
   exists only on the static pages; the app's own <main> elements carry none. */
#main:focus { outline: none; }

.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--header-bg);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--border);
  transition: background-color .35s ease, border-color .35s ease;
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: 68px;
}

.brand { display: inline-flex; align-items: center; gap: 11px; min-width: 0; }

.logomark {
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 10px;
  background: var(--logo-bg);
  display: grid;
  place-items: center;
  transition: background-color .35s ease;
}
.logomark svg { width: 20px; height: 20px; }

.wordmark {
  font-weight: 800;
  font-size: 1.03125rem;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.header-actions { display: flex; align-items: center; gap: 10px; }

.icon-btn {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 11px;
  border: 1px solid var(--border);
  display: grid;
  place-items: center;
  color: var(--text);
  transition: background-color .2s ease, border-color .2s ease;
}
.icon-btn:hover { background: var(--accent-soft); border-color: var(--accent-line); }
.icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.icon-btn svg { width: 18px; height: 18px; }

/* The header CTA is hidden on small screens rather than squeezed: the hero
   carries both calls to action six lines further down, so nothing is lost, and
   at 320px the logo + toggle + hamburger already use most of the row. */
.header-cta { display: none; }
@media (min-width: 760px) { .header-cta { display: inline-flex; } }

/* "Log in" (cloud #60). The outline beside the solid CTA keeps it the
   secondary action wherever both show. Unlike the CTA it earns a place on a
   phone — the whole point is that a returning user should not have to hunt —
   so it appears as soon as the row can hold it, at a tighter padding until
   the CTA joins it. Below that width the menu carries it. */
.header-login { display: none; }
@media (min-width: 400px) {
  .header-login { display: inline-flex; padding-inline: 14px; }
}
@media (min-width: 760px) { .header-login { padding-inline: 20px; } }

.theme-toggle .moon { display: none; }
[data-theme="light"] .theme-toggle .sun { display: none; }
[data-theme="light"] .theme-toggle .moon { display: block; }

/* ===========================================================================
   2. HERO
   =========================================================================== */

.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: linear-gradient(145deg, var(--grad-a) 0%, var(--grad-b) 52%, var(--grad-c) 100%);
  color: var(--hero-ink);
  padding-block: clamp(56px, 9vw, 104px) clamp(64px, 10vw, 120px);
  transition: background .45s ease;
}

/* Two soft radial washes, layered under the content to fake depth without an
   image asset. */
.hero::before,
.hero::after {
  content: "";
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  pointer-events: none;
}
.hero::before {
  width: 620px; height: 620px;
  top: -220px; right: -180px;
  background: radial-gradient(circle, rgba(144,100,247,.40) 0%, rgba(144,100,247,.16) 42%, transparent 72%);
}
.hero::after {
  width: 520px; height: 520px;
  bottom: -260px; left: -160px;
  background: radial-gradient(circle, rgba(49,185,122,.20) 0%, rgba(49,185,122,.07) 44%, transparent 74%);
}

.hero-grid {
  display: grid;
  gap: clamp(40px, 6vw, 64px);
  align-items: center;
}

.hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 0.6875rem;
  color: var(--hero-muted);
  border: 1px solid rgba(231, 228, 241, 0.28);
  border-radius: 999px;
  padding: 7px 14px;
  margin-bottom: 26px;
  background: rgba(255, 255, 255, 0.045);
}
.dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--pos);
  box-shadow: 0 0 0 4px rgba(49, 185, 122, 0.18);
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(49,185,122,.16); }
  50%      { box-shadow: 0 0 0 7px rgba(49,185,122,.04); }
}

.hero h1 {
  font-size: clamp(2.5rem, 9.4vw, 5.6rem);
  max-width: 13ch;
  margin-bottom: 26px;
}

.hero p.lede {
  font-size: clamp(1.02rem, 2.1vw, 1.2rem);
  line-height: 1.62;
  color: var(--hero-muted);
  max-width: 52ch;
  margin-bottom: 34px;
}

.hero-ctas { display: flex; flex-direction: column; gap: 12px; align-items: stretch; }
.hero-note { margin-top: 16px; font-size: 0.65625rem; color: var(--hero-muted); }
/* The disclaimer under the hero (cloud #84): a full sentence, so it is set in
   the body face at a readable size rather than as a 10.5px mono label. */
.hero-disclaimer { margin-top: 10px; font-size: 0.78125rem; line-height: 1.5; color: var(--hero-muted); max-width: 46ch; }

@media (min-width: 520px) {
  .hero-ctas { flex-direction: row; align-items: center; }
  .hero-ctas .btn { flex: none; }
}
@media (min-width: 980px) {
  .hero-grid { grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr); }
}

/* --- hero graphic --------------------------------------------------------- */

.hero-art {
  position: relative;
  min-width: 0;
  border-radius: 22px;
  padding: 14px;
  background: linear-gradient(160deg, rgba(255,255,255,.10), rgba(255,255,255,.02));
  border: 1px solid rgba(231, 228, 241, 0.16);
  box-shadow: var(--shadow-lg), 0 0 0 1px rgba(144,100,247,.10) inset;
  animation: float 9s ease-in-out infinite;
  /* Promote once, so the infinite transform does not re-rasterise the
     card's subtree on every frame. */
  will-change: transform;
}
@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}
.hero-art svg { width: 100%; height: auto; }

.art-chip {
  position: absolute;
  bottom: 26px;
  right: 26px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: #E7E4F1;
  background: rgba(13, 16, 22, 0.66);
  border: 1px solid rgba(231, 228, 241, 0.18);
  border-radius: 999px;
  padding: 7px 13px;
  backdrop-filter: blur(6px);
  /* Must never wrap: it is absolutely positioned inside the chart panel, so a
     second line grows leftward out of the card. At 320px the full string does
     not fit, hence the droppable middle segment below. */
  white-space: nowrap;
}
@media (max-width: 559px) {
  .art-chip { font-size: 0.5625rem; padding: 6px 11px; bottom: 18px; right: 18px; letter-spacing: .08em; }
  .art-chip .chip-opt { display: none; }
}

/* ===========================================================================
   3. TRUST BAND
   =========================================================================== */

.band {
  background: var(--band-bg);
  color: var(--band-ink);
  border-block: 1px solid var(--band-line);
  padding-block: clamp(38px, 5.5vw, 62px);
  transition: background-color .35s ease, color .35s ease;
}

.band-inner {
  display: grid;
  gap: 22px;
  justify-items: start;
  align-items: center;
}

.band-shield {
  flex: none;
  width: 52px; height: 52px;
  border-radius: 16px;
  background: var(--band-ink);
  color: var(--band-bg);
  display: grid;
  place-items: center;
}
.band-shield svg { width: 26px; height: 26px; }

.band-statement {
  font-family: var(--font-mono);
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.32;
  font-size: clamp(1.06rem, 3.2vw, 1.85rem);
  text-wrap: balance;
}
.band-statement .never { color: var(--band-accent); }

.band-sub {
  font-size: 0.90625rem;
  line-height: 1.6;
  color: var(--band-muted);
  max-width: 62ch;
  margin-top: 12px;
}

@media (min-width: 860px) {
  .band-inner { grid-template-columns: auto minmax(0, 1fr); gap: 28px; }
}

/* ===========================================================================
   4-6. FEATURE SECTIONS
   =========================================================================== */

.feature { padding-block: clamp(56px, 8vw, 92px) 0; }
.feature:last-of-type { padding-bottom: clamp(56px, 8vw, 92px); }
.feature + .feature { padding-top: clamp(40px, 6vw, 72px); }

.feature-grid {
  display: grid;
  gap: clamp(30px, 5vw, 56px);
  align-items: center;
}
@media (min-width: 900px) {
  .feature-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.06fr); }
  /* Alternate which side the graphic sits on, so three identically-structured
     sections do not read as one long column. */
  .feature:nth-of-type(even) .feature-copy { order: 2; }
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 0.65625rem;
  font-weight: 500;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 6px 11px;
  margin-bottom: 22px;
}

.feature h2 {
  font-size: clamp(1.95rem, 5.4vw, 3.1rem);
  max-width: 15ch;
  margin-bottom: 16px;
}

.subhead {
  font-size: 0.71875rem;
  color: var(--accent);
  margin-bottom: 18px;
}
.feature-body { color: var(--muted); max-width: 46ch; font-size: 1.03125rem; }

.feature-art {
  min-width: 0;
  border-radius: 20px;
  padding: 12px;
  background: linear-gradient(160deg, var(--surface), var(--bg));
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md);
}
.feature-art > svg { width: 100%; height: auto; border-radius: 12px; }

/* --- check note under the landing thesis card -------------------------- */

.schema-note {
  display: flex; align-items: center; gap: 8px;
  margin-top: 14px; padding-top: 14px;
  border-top: 1px solid var(--border);
  font-family: var(--font-mono); text-transform: uppercase;
  letter-spacing: .1em; font-size: 0.59375rem; color: var(--muted);
}
.schema-note .ok { color: var(--pos-ink); }

/* The landing page's readable thesis card: a call written the way the app
   shows it. */
.thesis-reason { color: var(--muted); font-size: 0.875rem; line-height: 1.6; margin-bottom: 14px; }

/* --- scorecard grid (section 6) ------------------------------------------ */

.score-wrap { padding: 4px; }
.score-head {
  display: flex; flex-wrap: wrap; gap: 10px 18px;
  align-items: baseline; margin-bottom: 16px;
}
.score-title { font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .11em; font-size: 0.65625rem; color: var(--muted); }

.score-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(26px, 1fr));
  gap: 6px;
  margin-bottom: 18px;
}
.cell {
  aspect-ratio: 1;
  border-radius: 6px;
  display: grid; place-items: center;
  font-size: 0.75rem; font-weight: 700;
  border: 1px solid transparent;
}
.cell.hit  { background: var(--pos-bg); color: var(--pos-ink); border-color: color-mix(in srgb, var(--pos) 34%, transparent); }
.cell.miss { background: var(--neg-bg); color: var(--neg-ink); border-color: color-mix(in srgb, var(--neg) 34%, transparent); }
.cell.none { background: var(--surface); color: var(--muted); border-color: var(--border); }

.score-call {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; padding: 13px 15px;
  font-family: var(--font-mono); font-size: clamp(0.625rem, 2.3vw, 0.75rem);
  text-transform: uppercase; letter-spacing: .07em;
}
.score-call .up { color: var(--pos-ink); font-weight: 700; }
.score-call .down { color: var(--neg-ink); font-weight: 700; }
.score-call .sep { color: var(--muted); }

/* A bucket the backend would report as sufficient:false keeps its numbers and
   loses ALL emphasis — decisions #69(b) enforced at the render layer. */
.score-weak {
  margin-top: 12px; padding: 12px 15px;
  border: 1px dashed var(--border); border-radius: 12px;
  color: var(--muted); font-size: 0.78125rem;
}
.score-weak b { color: var(--text); font-weight: 700; }

/* --- valuation panel (section 6b) ----------------------------------------- */

.verdict-rows { display: grid; gap: 8px; margin-bottom: 14px; }
.verdict-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 10px 15px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px;
}
.verdict-row dt { margin: 0; color: var(--muted); font-size: 0.8125rem; }
.verdict-row dd { margin: 0; font-family: var(--font-mono); font-size: 0.875rem; font-weight: 700; }

/* --- bottom info bar ------------------------------------------------------ */

.infobar {
  display: flex; align-items: center; gap: 14px;
  margin-top: clamp(30px, 4.5vw, 44px);
  padding: 18px 0 0;
  border-top: 1px solid var(--border);
  transition: border-color .2s ease;
}
.infobar:hover { border-color: var(--accent-line); }
.infobar-icon {
  flex: none; width: 34px; height: 34px; border-radius: 10px;
  background: var(--accent-soft); color: var(--accent);
  display: grid; place-items: center;
}
.infobar-icon svg { width: 17px; height: 17px; }
/* The label wraps rather than ending in an ellipsis (cloud #92). It fits one
   line from 375px at the default text size, but at 320px three of the four
   were cut ("MORE ABOUT THE TRACK REC…"), and with a larger text size all of
   them were: a link that hides its own words does not say where it goes. */
.infobar-label {
  flex: 1 1 auto; min-width: 0;
  font-family: var(--font-mono); text-transform: uppercase;
  letter-spacing: .12em; font-size: 0.71875rem; font-weight: 700;
}
.infobar-go {
  flex: none; width: 38px; height: 38px; border-radius: 50%;
  border: 1.5px solid var(--border); color: var(--text);
  display: grid; place-items: center;
  transition: background-color .2s ease, border-color .2s ease,
              color .2s ease, transform .2s ease;
}
.infobar:hover .infobar-go {
  background: var(--accent); border-color: var(--accent);
  color: var(--accent-ink); transform: translateX(3px);
}
.infobar:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

/* ===========================================================================
   7. NAV OVERLAY
   =========================================================================== */

.nav-overlay {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  /* `hidden` alone would be enough, but the overlay animates, so it needs a
     state in which it is both invisible AND not focusable. */
  visibility: hidden;
  opacity: 0;
  transition: opacity .28s ease, visibility 0s linear .28s;
}
.nav-overlay.open { visibility: visible; opacity: 1; transition: opacity .28s ease, visibility 0s; }

.nav-top { display: flex; align-items: center; justify-content: space-between; height: 68px; }

.nav-items {
  flex: 1 1 auto;
  display: flex; flex-direction: column; justify-content: center;
  gap: clamp(2px, 1vw, 8px);
  padding-block: 24px;
  overflow-y: auto;
}
.nav-link {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: clamp(10px, 2vw, 16px) 0;
  border-bottom: 1px solid var(--border);
  font-weight: 900; letter-spacing: -0.03em; line-height: 1.05;
  font-size: clamp(1.9rem, 8vw, 3.6rem);
  transition: color .2s ease, padding-left .22s ease;
}
.nav-link:hover, .nav-link:focus-visible { color: var(--accent); padding-left: 10px; }
.nav-link .navarrow { flex: none; width: clamp(22px, 5vw, 32px); height: auto; opacity: .5; transition: opacity .2s ease, transform .2s ease; }
.nav-link:hover .navarrow { opacity: 1; transform: translateX(4px); }

/* Pricing and Docs have nothing behind them yet. They say so instead of
   linking to a 404 — an honest dead end beats a broken one. */
.nav-link.soon { color: var(--muted); pointer-events: none; }
.nav-soon {
  font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .12em;
  font-size: 0.625rem; font-weight: 500; color: var(--muted);
  border: 1px solid var(--border); border-radius: 6px; padding: 4px 8px;
  align-self: center; white-space: nowrap;
}
/* Log in and Get started at the foot of the menu (cloud #60): on a phone this
   is the only header there is, so both ways in have to be here. */
.nav-actions {
  display: flex; flex-wrap: wrap; gap: 12px;
  padding-top: 8px;
  padding-bottom: max(24px, env(safe-area-inset-bottom));
}
.nav-actions .btn { flex: 1 1 140px; justify-content: center; }
body.nav-open { overflow: hidden; }

/* ===========================================================================
   INTERIOR PAGES (/how-it-works, /get-started)
   =========================================================================== */

.page-head {
  background: linear-gradient(145deg, var(--grad-a) 0%, var(--grad-b) 55%, var(--grad-c) 100%);
  color: var(--hero-ink);
  padding-block: clamp(48px, 7vw, 84px);
  transition: background .45s ease;
}
.page-head h1 { font-size: clamp(2.2rem, 7.6vw, 4.2rem); max-width: 16ch; margin-bottom: 20px; }
.page-head p { color: var(--hero-muted); max-width: 56ch; font-size: clamp(1rem, 2vw, 1.15rem); }

/* Landing: the watchlist problem, stated before any feature. Plain prose, so
   it reads as an argument rather than another card. */
.why { padding-bottom: 0; }
.why .section-title { max-width: 22ch; }
.why-body { max-width: 62ch; }
.why-body p { color: var(--muted); font-size: clamp(1rem, 2vw, 1.1rem); margin-bottom: 16px; }
.why-body p:last-child { margin-bottom: 0; }
.page-head .hero-eyebrow { margin-bottom: 22px; }

.section { padding-block: clamp(48px, 7vw, 80px); }
.section-title { font-size: clamp(1.6rem, 4.6vw, 2.4rem); margin-bottom: 14px; }
.section-lede { color: var(--muted); max-width: 60ch; margin-bottom: 34px; }

/* --- numbered pipeline steps --------------------------------------------- */

.steps { display: grid; gap: 16px; }
@media (min-width: 760px) { .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.step {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: clamp(18px, 3vw, 26px);
  min-width: 0;
  scroll-margin-top: 92px;
}
.step-n {
  font-family: var(--font-mono); font-size: 0.6875rem; letter-spacing: .14em;
  color: var(--accent); font-weight: 700; display: block; margin-bottom: 12px;
}
.step h3 { font-size: clamp(1.15rem, 3vw, 1.4rem); font-weight: 800; letter-spacing: -0.02em; margin-bottom: 10px; }
.step p { color: var(--muted); font-size: 0.96875rem; }
.step .pill {
  display: inline-block; margin-top: 14px;
  font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .1em;
  font-size: 0.59375rem; color: var(--muted);
  border: 1px solid var(--border); border-radius: 6px; padding: 5px 9px;
}
.step.is-guard { border-color: color-mix(in srgb, var(--accent) 42%, var(--border)); }

/* --- generic card list ---------------------------------------------------- */

.cards { display: grid; gap: 16px; }
@media (min-width: 720px) { .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 16px; padding: clamp(18px, 3vw, 24px); min-width: 0;
}
.card h3 { font-size: 1.1rem; font-weight: 800; letter-spacing: -0.015em; margin-bottom: 8px; }
/* `:where()` keeps this at element specificity (0,0,1). As `.card p` (0,1,1) it
   out-ranked every single-class style on a paragraph inside any card — so a
   `<p class="metric-label">` rendered 15px instead of 9.5px, a hint 15px
   instead of 12px, and the valuation's headline figure 15px and muted instead
   of 26px (cloud #54, measured with getComputedStyle). A plain paragraph in a
   card, which is what this rule is for, is unchanged. */
:where(.card) p { color: var(--muted); font-size: 0.9375rem; }

.checklist { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.checklist li { display: flex; gap: 12px; align-items: flex-start; color: var(--muted); font-size: 1rem; }
.checklist svg { flex: none; width: 20px; height: 20px; margin-top: 2px; color: var(--pos-ink); }
.checklist b { color: var(--text); font-weight: 700; }

.cta-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; align-items: center; }
.cta-note { font-size: 0.75rem; color: var(--muted); }
.cta-note a { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.cta-note a:hover { color: var(--accent); }

.callout {
  border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: 12px; padding: 18px 20px; background: var(--surface);
  color: var(--muted); font-size: 0.9375rem; margin-top: 28px;
}
.callout b { color: var(--text); }

/* ===========================================================================
   FOOTER
   =========================================================================== */

.site-footer {
  border-top: 1px solid var(--border);
  padding-block: 40px;
  color: var(--muted);
  font-size: 0.8125rem;
}
.footer-inner { display: flex; flex-wrap: wrap; gap: 16px 28px; justify-content: space-between; align-items: center; }
.footer-nav { display: flex; flex-wrap: wrap; gap: 8px 20px; }
.footer-nav a { font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .1em; font-size: 0.65625rem; }
.footer-nav a:hover { color: var(--accent); }

/* --- footer legal row -----------------------------------------------------
   A second row under the existing footer line, carrying the operator
   statement and the two legal links. It is a ROW rather than a fourth child of
   `.footer-inner` because that row is `justify-content: space-between` — a
   sentence of this length dropped into it would push the nav around and wrap
   badly at every width between 600 and 900px. */
.footer-legal {
  margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--border);
  display: grid; gap: 10px;
}
.footer-legal p { font-size: 0.78125rem; line-height: 1.6; color: var(--muted); max-width: 78ch; }
.footer-legal-links {
  display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: baseline;
  font-family: var(--font-mono); text-transform: uppercase;
  letter-spacing: .1em; font-size: 0.65625rem;
}
/* Underlined, not just coloured. These are the two links on the page somebody
   may be actively looking for, and `a { text-decoration: none }` at the top of
   this file means an unstyled link here is invisible as a link. */
.footer-legal-links a {
  color: var(--muted); text-decoration: underline;
  text-underline-offset: 3px; text-decoration-color: var(--border);
}
.footer-legal-links a:hover { color: var(--accent); text-decoration-color: var(--accent); }
/* --muted, not --border. A border colour used as TEXT measures 1.34:1 here —
   the separator was invisible rather than subtle, which is not a quieter
   version of doing its job. Measured, not eyeballed. */
.footer-legal-links span { color: var(--muted); }

/* --- legal prose ----------------------------------------------------------
   `/terms` and `/privacy`. This block exists because the marketing stylesheet
   deliberately has no prose rhythm: the reset at the top sets
   `h1, h2, h3, p { margin: 0 }`, there is no styled `ol`/`ul`, and
   `a { text-decoration: none }`. Every stacked paragraph elsewhere on the site
   carries a bespoke class, which works for three paragraphs and not for
   fifteen numbered clauses.

   Everything here uses existing tokens; no new colour is introduced. */
.legal { max-width: 72ch; }
.legal h2 {
  font-size: clamp(1.15rem, 3vw, 1.4rem); font-weight: 800;
  letter-spacing: -0.02em; margin: 40px 0 12px;
}
.legal h2:first-child { margin-top: 0; }
.legal h3 { font-size: 1rem; font-weight: 700; margin: 24px 0 8px; }
.legal p, .legal li { color: var(--muted); font-size: 0.9375rem; line-height: 1.7; }
.legal p + p { margin-top: 12px; }
.legal ul, .legal ol { margin: 12px 0 0; padding-left: 22px; display: grid; gap: 8px; }
.legal ul { list-style: disc; }
.legal ol { list-style: decimal; }
.legal li::marker { color: var(--muted); }
.legal strong, .legal b { color: var(--text); font-weight: 700; }
/* Inline links have to declare themselves — see the reset note above. */
.legal a {
  color: var(--accent-ink-soft); text-decoration: underline;
  text-underline-offset: 3px;
}
.legal a:hover { text-decoration-thickness: 2px; }
.legal-updated {
  font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .1em;
  font-size: 0.65625rem; color: var(--muted); margin-bottom: 28px;
}
/* The one block on these pages that should stop the eye. */
.legal .callout { margin-top: 0; margin-bottom: 28px; }

} /* @layer site */

@layer auth {

/* ===========================================================================
   AUTH — /login
   =========================================================================== */

.auth-shell { min-height: 100vh; display: grid; }
@media (min-width: 980px) {
  /* The gradient panel is decoration and the form is the task, so the form
     column is the wider one and comes SECOND in the source — a screen reader
     and a narrow viewport both reach the form first. */
  .auth-shell { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr); }
  .auth-aside { order: -1; }
}

.auth-aside {
  display: none;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: linear-gradient(160deg, var(--grad-a) 0%, var(--grad-b) 52%, var(--grad-c) 100%);
  color: var(--hero-ink);
  padding: clamp(32px, 5vw, 56px);
  flex-direction: column;
  /* TWO children — the brand, and one block holding the headline and the
     points. With three, space-between stranded them at the extremes of a tall
     column with a void in the middle. */
  justify-content: space-between;
  gap: 40px;
}
@media (min-width: 980px) { .auth-aside { display: flex; } }

/* The same soft washes the hero uses. Without them a tall narrow column of the
   sidebar gradient reads as flat near-black next to the landing page. */
.auth-aside::before,
.auth-aside::after {
  content: "";
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  pointer-events: none;
}
.auth-aside::before {
  width: 520px; height: 520px; top: -200px; right: -220px;
  background: radial-gradient(circle, rgba(144,100,247,.40) 0%, rgba(144,100,247,.15) 42%, transparent 72%);
}
.auth-aside::after {
  width: 460px; height: 460px; bottom: -200px; left: -200px;
  background: radial-gradient(circle, rgba(49,185,122,.18) 0%, rgba(49,185,122,.06) 44%, transparent 74%);
}

.auth-aside-title {
  font-weight: 900; letter-spacing: -0.03em; line-height: 1.05;
  font-size: clamp(1.9rem, 2.8vw, 2.6rem); max-width: 14ch;
}
.auth-aside p { color: var(--hero-muted); max-width: 40ch; margin-top: 18px; }
.auth-points { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.auth-points li { display: flex; gap: 11px; align-items: flex-start; color: var(--hero-muted); font-size: 0.9375rem; }
.auth-points svg { flex: none; width: 18px; height: 18px; margin-top: 3px; color: #4BD79A; }

.auth-main {
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  padding: clamp(24px, 5vw, 48px) 20px;
  min-width: 0;
}
.auth-box { width: 100%; max-width: 430px; min-width: 0; }

.auth-brand { display: inline-flex; align-items: center; gap: 11px; margin-bottom: 30px; }
/* On wide screens the aside already carries the wordmark, so the form-side one
   would be the SECOND copy on screen at the same time. */
@media (min-width: 980px) { .auth-brand { display: none; } }

.auth-box h1 {
  font-weight: 900; letter-spacing: -0.03em; line-height: 1.06;
  font-size: clamp(1.8rem, 6vw, 2.3rem); margin-bottom: 10px;
}
.auth-lede { color: var(--muted); font-size: 0.96875rem; margin-bottom: 26px; }

.field { display: grid; gap: 7px; margin-bottom: 16px; }
.field label {
  font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .11em;
  font-size: 0.625rem; font-weight: 500; color: var(--muted);
}
.field input {
  font: inherit; font-size: 0.9375rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--input-border);
  border-radius: 11px;
  padding: 13px 14px;
  width: 100%; min-width: 0;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.field input::placeholder { color: var(--placeholder); }
.field input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.field-hint { font-size: 0.75rem; color: var(--muted); }

.auth-submit { width: 100%; margin-top: 6px; }

/* Google's own mark, on a surface that must read as a real Google button
   rather than an imitation of one. Deliberately NOT tinted by the theme: the
   four brand colours are fixed, so the plate under them is near-white in both
   themes and the label ink is dark in both. */
.btn-google {
  width: 100%;
  background: #FFFFFF;
  color: #1F1F1F;
  border-color: #DADCE0;
  font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .09em;
}
.btn-google:hover { background: #F4F5F7; border-color: #C6C9CE; filter: none; }
.btn-google svg { width: 17px; height: 17px; flex: none; }

/* Google is BUILT but not configured on this deployment. The button stays
   visible so the option is discoverable, and stops being clickable so it
   cannot send anyone to a 503. It costs nothing to keep: the moment both
   credentials are set, /auth/providers reports google:true and this class is
   simply not applied.
   Deliberately NOT dimmed with opacity — that would drag the label's contrast
   down with it. The plate and ink are muted tokens that already measure, and
   only the mark itself is desaturated. */
.btn-google.is-soon {
  background: var(--surface);
  border-color: var(--border);
  color: var(--muted);
  cursor: default;
}
.btn-google.is-soon:hover { background: var(--surface); border-color: var(--border); }
.btn-google.is-soon svg { filter: grayscale(1); opacity: .65; }

.soon-tag {
  font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .12em;
  font-size: 0.5625rem; font-weight: 500; color: var(--muted);
  border: 1px solid var(--border); border-radius: 5px;
  padding: 3px 6px; margin-left: 2px;
}
.auth-soon-note { font-size: 0.78125rem; color: var(--muted); margin-top: -6px; margin-bottom: 4px; }

.auth-divider {
  display: flex; align-items: center; gap: 14px;
  margin: 22px 0;
  color: var(--muted);
  font-family: var(--font-mono); text-transform: uppercase;
  letter-spacing: .13em; font-size: 0.625rem;
}
.auth-divider::before, .auth-divider::after {
  content: ""; flex: 1 1 auto; height: 1px; background: var(--border);
}

.alert {
  border-radius: 11px; padding: 12px 14px; margin-bottom: 18px;
  font-size: 0.875rem; line-height: 1.5;
  border: 1px solid transparent;
}
.alert-error { background: var(--neg-bg); color: var(--neg-ink); border-color: color-mix(in srgb, var(--neg) 34%, transparent); }
.alert-ok    { background: var(--pos-bg); color: var(--pos-ink); border-color: color-mix(in srgb, var(--pos) 34%, transparent); }
.alert-info  { background: var(--accent-soft); color: var(--text); border-color: var(--accent-line); }

.auth-switch { margin-top: 22px; font-size: 0.875rem; color: var(--muted); }
.auth-switch button {
  color: var(--accent); font-weight: 700;
  text-decoration: underline; text-underline-offset: 3px;
}
.auth-switch button:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.auth-switch a {
  color: var(--accent); font-weight: 700;
  text-decoration: underline; text-underline-offset: 3px;
}
.auth-switch a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

/* Password fields (cloud #60): the show/hide toggle sits inside the input's
   right edge, so the input reserves room for it. */
.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 52px; }
.pw-toggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px; border-radius: 9px;
  display: grid; place-items: center;
  color: var(--muted); background: transparent; border: 0; cursor: pointer;
}
.pw-toggle:hover { color: var(--text); background: var(--accent-soft); }
.pw-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.pw-toggle svg { width: 19px; height: 19px; }

/* The live requirements list under a new password. Met rules take the
   positive INK, which is tuned to clear the card surface in both themes
   (#23d); unmet ones stay muted rather than red, because an unmet rule while
   typing is not yet a mistake. */
.pw-checklist-wrap { margin: -6px 0 16px; }
.pw-checklist {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 5px 14px; font-size: 0.78125rem; color: var(--muted);
}
.pw-checklist li { display: flex; align-items: center; gap: 7px; min-width: 0; }
.pw-checklist li.is-met { color: var(--pos-ink); }
.pw-checklist svg { width: 14px; height: 14px; flex: none; }

.field-error { font-size: 0.78125rem; color: var(--neg-ink); margin: -8px 0 14px; }

/* "Forgot password?" under the log-in password (cloud #61). Right-aligned so
   it reads as belonging to the field above, not as a second action. */
.auth-forgot { display: flex; justify-content: flex-end; margin: -8px 0 14px; font-size: 0.8125rem; }
.auth-forgot a { color: var(--accent); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.auth-forgot a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

/* "Keep me logged in" beside "Forgot password?" (cloud #63). Wraps under
   it on a narrow phone rather than squeezing either. */
.auth-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
            gap: 8px 16px; margin: -6px 0 16px; font-size: 0.8125rem; }
.auth-check { display: inline-flex; align-items: center; gap: 8px; color: var(--text); cursor: pointer; }
.auth-check input { width: 18px; height: 18px; accent-color: var(--accent); margin: 0; }
.auth-check input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.auth-forgot-link { color: var(--accent); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.auth-forgot-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

/* The "check your email" screen, and the confirm-your-address banner. */
.verify-card { max-width: 560px; margin: clamp(24px, 6vw, 64px) auto; }
.verify-card h1 { font-size: clamp(1.6rem, 5vw, 2.1rem); font-weight: 900; letter-spacing: -0.03em; margin-bottom: 12px; }
.verify-card p { color: var(--muted); margin-bottom: 14px; }
.verify-card .verify-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.verify-banner {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px;
  padding: 10px 14px; margin: 12px 0 0;
  border: 1px solid var(--accent-line); border-radius: 12px;
  background: var(--accent-soft); color: var(--text); font-size: 0.875rem;
}
.verify-banner .btn { padding: 8px 14px; }

/* The Security page and two-factor setup (cloud #62). */
.page-crumb { font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .1em;
              font-size: 0.65625rem; color: var(--muted); margin-bottom: 6px; }
.page-crumb a { color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.page-crumb a:hover { color: var(--accent); }
.page-sub a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.sec-card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.reauth-panel { margin-bottom: 16px; border-color: var(--accent-line); }
.twofa-steps { margin: 12px 0 0; padding-left: 1.2em; display: grid; gap: 14px; }
.twofa-steps p { margin-bottom: 8px; }
/* A QR code needs contrast, not the palette: a white plate in both themes
   (the rule the Google button follows, #23c). */
.qr-plate { display: inline-block; background: #FFFFFF; border-radius: 12px; padding: 6px;
            border: 1px solid var(--border); line-height: 0; }
.qr-plate svg { width: 196px; height: 196px; max-width: 100%; }
.twofa-key { display: inline-block; font-family: var(--font-mono); font-size: 0.9375rem;
             letter-spacing: .06em; padding: 8px 12px; border-radius: 9px;
             background: var(--surface); border: 1px solid var(--border);
             word-break: break-all; user-select: all; }
.recovery-box { border: 1px solid var(--accent-line); background: var(--accent-soft);
                border-radius: 12px; padding: 14px 16px; margin: 10px 0 14px; }
.recovery-codes { list-style: none; margin: 10px 0 12px; padding: 0;
                  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
                  gap: 6px 14px; }
.recovery-codes code { font-family: var(--font-mono); font-size: 0.9375rem; letter-spacing: .04em; }
.mfa-banner { border-color: var(--border); background: var(--surface); }
.mfa-banner a { color: var(--accent-ink-soft); text-decoration: underline; text-underline-offset: 3px; }
/* The 2FA offer (cloud #69): the first-run card's accent edge, because it is
   the last step of creating the account. Scoped, for `.onboard`'s reason:
   the marketing `.card p` rule would otherwise paint the text. The setup card
   it opens is the Security page's own, so it only needs room above it. */
.mfa-prompt > .card { margin: 12px 0 0; }
.mfa-prompt .mfa-offer { border-left: 3px solid var(--accent); }
.mfa-prompt .mfa-offer .mfa-offer-text { color: var(--muted); font-size: 0.875rem; margin: 6px 0 14px; max-width: 62ch; }
.mfa-prompt .mfa-offer .verify-actions { display: flex; flex-wrap: wrap; gap: 10px; }

/* Where you're logged in (cloud #63). A row wraps its button under the text
   on a phone rather than squeezing the device name. */
.session-list { list-style: none; margin: 12px 0 14px; padding: 0; display: grid; gap: 0; }
.session-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
               gap: 8px 14px; padding: 12px 0; border-top: 1px solid var(--border); }
.session-row:first-child { border-top: 0; }
.session-main { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-width: 0; flex: 1 1 220px; }
.session-meta { flex-basis: 100%; font-size: 0.8125rem; color: var(--muted); overflow-wrap: anywhere; }
/* A settings card's buttons may wrap. `.btn` is nowrap everywhere else, which
   is right for a short label and wrong for "Turn on two-factor
   authentication" in a 288px card: measured at 320px, it ran to 346 and
   pushed the page sideways. */
.sched-card .btn { max-width: 100%; white-space: normal; text-align: center; }

/* Cloud #64: the terms tick, the Turnstile slot, the disclaimer slot, and the
   delete card. */
.auth-terms { align-items: flex-start; margin: -4px 0 16px; font-size: 0.84375rem; line-height: 1.45; }
.auth-terms input { margin-top: 2px; flex: none; }
.auth-terms a { color: var(--accent); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.turnstile-slot:not(:empty) { margin: 0 0 16px; }
.legal-slot { font-size: 0.78125rem; color: var(--muted); margin-top: 16px; }
.legal-slot p + p { margin-top: 8px; }
.legal-slot-todo { border: 1.5px dashed var(--accent-line); border-radius: 10px; padding: 10px 12px;
                   font-family: var(--font-mono); font-size: 0.6875rem; letter-spacing: .04em; }
.app-footer { padding-bottom: 96px; }
@media (min-width: 640px) { .app-footer { padding-bottom: 32px; } }
.app-footer:empty { display: none; }
.danger-card { border-color: color-mix(in srgb, var(--neg) 34%, transparent); }
/* Enabled only: a disabled danger button takes the ordinary disabled look.
   Without :not(:disabled) the dark-theme ink below outranked .btn:disabled
   and drew near-black text on the disabled surface — measured 1.06:1. */
.btn-danger.btn-solid:not(:disabled) { background: var(--neg); border-color: var(--neg); color: #FFFFFF; box-shadow: none; }
/* The dark theme's --neg is lighter, and white on it misses 4.5:1; dark ink
   on it clears it. */
[data-theme="dark"] .btn-danger.btn-solid:not(:disabled) { color: #0D1016; }
.btn-danger.btn-outline:not(:disabled) { color: var(--neg-ink); border-color: color-mix(in srgb, var(--neg) 45%, transparent); }
.field input[aria-invalid="true"] { border-color: var(--neg); }

.auth-foot {
  margin-top: 32px; padding-top: 20px; border-top: 1px solid var(--border);
  display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center;
  font-family: var(--font-mono); text-transform: uppercase;
  letter-spacing: .1em; font-size: 0.59375rem; color: var(--muted);
}
.auth-foot a:hover { color: var(--accent); }

/* The theme toggle floats on the form side, where the background is the page
   colour in both themes — on the gradient it would need the non-flipping
   treatment the hero buttons get. */
.auth-toggle { position: absolute; top: 18px; right: 18px; z-index: 2; }
.auth-main { position: relative; }

} /* @layer auth */
