/* ==========================================================================
   GMEOW VPN — gmeow.org
   One stylesheet for every page.

   WHY THIS FILE EXISTS AT ALL
   The site used to pull Tailwind from a CDN and carry an inline `tailwind.config`
   block repeated verbatim in all five pages. That meant a palette change was five
   edits that had to agree, plus a ~100KB script compiling CSS in the visitor's
   browser on every page view -- something Tailwind's own documentation says not to
   ship. Hand-written CSS with custom properties is one edit, no runtime, and no
   flash of unstyled text.

   THE PALETTE IS NOT DECORATION HERE
   Every value in `:root` is copied from `color_palette_vpn_app.txt`, the binding
   reference for the Android app. Where a value is derived rather than copied it
   says so and says from what. The site and the app are meant to read as one
   product, so a hex picked by eye on this side would break that on the first
   screenshot placed next to the other.

   THE ONE CONTRAST RULE THAT SHAPES THE WHOLE DESIGN
   Section 5 of the palette file forbids the FULL-strength sunset behind text:
   crimson #914D4D and orange #FF8250 at full strength drop muted text #8A998A
   below the readable floor and turn the pink #FFB7D5 pill into noise. So the
   sunset appears at full strength in exactly one place -- the hero, where the only
   text is large and light (#F0F4F0 on the indigo band measures about 13:1) -- and
   everywhere else it is the measured, dimmed ambient version from Section 5, which
   clears AA at every point on the screen.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */

:root {
    /* Primary branding — palette section 1 */
    --lime: #9BE638;
    --lime-dark: #7CB82D;          /* derived: --lime at 80% luminance, pressed state */
    --pink: #FFB7D5;
    --pink-deep: #FF7BB0;
    --ink: #0A0B0A;                /* outlines, and text on a lime fill. NOT a background. */

    /* Scenic accents — palette section 2 */
    --grass: #2D964B;
    --grass-deep: #1D572E;         /* derived: 55% grass over 45% ink, same as the app */
    --fuji: #3C4B73;
    --snow: #FFFFFF;
    --cloud: #FFD2B4;

    /* Sunset sky — palette section 3, full strength */
    --sky-top: #23194B;
    --sky-mid: #914D4D;
    --sky-bottom: #FF8250;

    /* Surfaces — palette section 4 */
    --ground: #161A18;
    --sunken: #101312;
    --card: #1F2421;
    --card-up: #262C28;
    --line: #313A33;

    /* Text — palette section 4 */
    --text: #F0F4F0;
    --muted: #8A998A;

    /* Status — palette section 6, derived not invented */
    --connecting: #FF8250;
    --error: #DA4E4E;

    /* Ambient sky alphas — palette section 5. These four numbers are measured,
       not chosen. Raising any of them is the fastest way to break the contrast
       floor, which is why they are named here rather than typed inline. */
    --amb-indigo: rgba(35, 25, 75, 0.38);
    --amb-cloud: rgba(255, 210, 180, 0.06);
    --amb-horizon: rgba(255, 130, 80, 0.10);

    /* Type */
    --display: "Space Grotesk", "Segoe UI", system-ui, sans-serif;
    --body: "Noto Sans", "Segoe UI", system-ui, sans-serif;
    --mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", monospace;

    /* Radii, matching the app's tailwind.config.js */
    --r-sm: .75rem;
    --r-md: 1.25rem;
    --r-lg: 1.5rem;
    --r-xl: 2rem;
    --r-2xl: 2.5rem;

    /* Layout */
    --nav-h: 72px;
    --wrap: 1180px;

    --ease: cubic-bezier(.22, .61, .36, 1);
}

/* --------------------------------------------------------------------------
   2. RESET
   -------------------------------------------------------------------------- */

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

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* Anchored headings must clear the sticky nav, or a jump link lands with its
       own heading hidden underneath the bar. */
    scroll-padding-top: calc(var(--nav-h) + 24px);
}

body {
    margin: 0;
    background: var(--ground);
    color: var(--text);
    font-family: var(--body);
    font-size: 16px;
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

img, svg { display: block; max-width: 100%; }
/* `display: block` above is an author rule, so it beats the browser's own
   `[hidden] { display: none }` and a hidden icon would still be painted. This
   puts the attribute back in charge. */
img[hidden], svg[hidden] { display: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

h1, h2, h3, h4 {
    font-family: var(--display);
    font-weight: 700;
    line-height: 1.12;
    letter-spacing: -.02em;
    margin: 0;
}

p { margin: 0; }
ul, ol { margin: 0; padding: 0; }

:focus-visible {
    outline: 2px solid var(--lime);
    outline-offset: 3px;
    border-radius: 6px;
}

::selection { background: var(--lime); color: var(--ink); }

.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;
}

.skip {
    position: absolute; left: 16px; top: -60px; z-index: 100;
    background: var(--lime); color: var(--ink);
    padding: .6rem 1rem; border-radius: var(--r-sm);
    font-family: var(--display); font-size: .8rem;
    transition: top .18s var(--ease);
}
.skip:focus { top: 16px; }

/* --------------------------------------------------------------------------
   3. THE AMBIENT SKY — the background of every page

   Ported layer for layer from the app's GhibliBackdrop: flat ground, indigo glow
   fading out by 55% of the viewport, cloud fluff in the top third only, a thin
   warm horizon from 70% down. Fixed rather than scrolling, so the page moves
   through one sky instead of repeating it.
   -------------------------------------------------------------------------- */

.sky {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        /* layer 4 — distant sunset, bottom 30%, deliberately thin */
        linear-gradient(to top, var(--amb-horizon) 0%, rgba(255, 130, 80, 0) 30%),
        /* layer 2 — night sky, fades out by 55% height */
        linear-gradient(to bottom, var(--amb-indigo) 0%, rgba(35, 25, 75, 0) 55%),
        /* layer 1 — the ground everything above composites onto */
        var(--ground);
}

/* Layer 3 — cloud fluff. Three overlapping circles per cloud rather than one:
   a single low-alpha circle reads as a smudge, overlapping ones read as fluff.
   Same idiom as the app, same 0.06 alpha, top third only. */
.sky__clouds { position: absolute; inset: 0; overflow: hidden; }

.sky__puff {
    position: absolute;
    border-radius: 999px;
    background: var(--amb-cloud);
    will-change: transform;
}

.sky__puff:nth-child(1) { left: -6%;  top: 8vh;  width: 190px; height: 190px; animation: drift 64s linear infinite; }
.sky__puff:nth-child(2) { left: 8%;   top: 12vh; width: 130px; height: 130px; animation: drift 64s linear infinite; }
.sky__puff:nth-child(3) { left: 1%;   top: 15vh; width: 112px; height: 112px; animation: drift 64s linear infinite; }
.sky__puff:nth-child(4) { right: -8%; top: 19vh; width: 164px; height: 164px; animation: drift-back 82s linear infinite; }
.sky__puff:nth-child(5) { right: 7%;  top: 23vh; width: 108px; height: 108px; animation: drift-back 82s linear infinite; }

@keyframes drift      { from { transform: translateX(0); }    to { transform: translateX(90px); } }
@keyframes drift-back { from { transform: translateX(0); }    to { transform: translateX(-70px); } }

/* --------------------------------------------------------------------------
   4. LAYOUT
   -------------------------------------------------------------------------- */

.wrap {
    width: 100%;
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: 24px;
}

.section { padding-block: clamp(64px, 9vw, 116px); }
.section--tight { padding-block: clamp(48px, 6vw, 76px); }

.section + .section { border-top: 1px solid color-mix(in srgb, var(--line) 55%, transparent); }

.eyebrow {
    display: inline-flex; align-items: center; gap: .5rem;
    font-family: var(--mono);
    font-size: .68rem;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--lime);
    margin-bottom: 1rem;
}
.eyebrow::before {
    content: ""; width: 22px; height: 2px;
    background: var(--lime); border-radius: 2px;
}

.h-sec { font-size: clamp(1.75rem, 4vw, 2.65rem); }
.h-sub {
    margin-top: 1rem;
    color: var(--muted);
    font-size: clamp(.95rem, 1.4vw, 1.06rem);
    max-width: 62ch;
}

.lead { font-size: clamp(1rem, 1.5vw, 1.12rem); color: var(--muted); }

.grid { display: grid; gap: 20px; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); }

/* One wide column beside a narrow one, for a form and the small print that
   belongs next to it. It collapses at the same width as the nav, because a form
   squeezed into half a phone is worse than a form under its own sidebar. */
.grid--split { grid-template-columns: 1fr; }
@media (min-width: 900px) { .grid--split { grid-template-columns: 1.5fr 1fr; gap: 24px; } }

/* A plain vertical stack that does not stretch its last child to fill the
   column. Used for the sidebar beside a tall form. */
.stack { display: grid; gap: 20px; align-content: start; }

/* --------------------------------------------------------------------------
   5. NAV
   -------------------------------------------------------------------------- */

.nav {
    position: sticky; top: 0; z-index: 60;
    height: var(--nav-h);
    display: flex; align-items: center;
    /* Transparent at rest so the hero sky runs behind it, opaque once the page
       scrolls and real content would otherwise pass underneath. */
    background: transparent;
    border-bottom: 1px solid transparent;
    transition: background .28s var(--ease), border-color .28s var(--ease), backdrop-filter .28s var(--ease);
}
.nav.is-stuck {
    background: color-mix(in srgb, var(--ground) 88%, transparent);
    backdrop-filter: blur(14px) saturate(1.1);
    border-bottom-color: var(--line);
}

.nav__inner {
    width: 100%; max-width: var(--wrap); margin-inline: auto;
    padding-inline: 24px;
    display: flex; align-items: center; gap: 1.5rem;
}

.brand { display: flex; align-items: center; gap: .65rem; margin-right: auto; }
.brand__mark {
    width: 38px; height: 38px; border-radius: 12px;
    background: var(--card);
    border: 1px solid var(--line);
    display: grid; place-items: center;
    overflow: hidden;
}
.brand__mark img { width: 30px; height: 30px; }
.brand__name {
    font-family: var(--display); font-weight: 700;
    font-size: 1.06rem; letter-spacing: -.01em;
}
.brand__name span { color: var(--lime); }

.nav__links { display: none; align-items: center; gap: .35rem; }
@media (min-width: 900px) { .nav__links { display: flex; } }

.nav__link {
    padding: .5rem .8rem; border-radius: 999px;
    font-size: .9rem; color: var(--muted);
    transition: color .18s var(--ease), background .18s var(--ease);
}
.nav__link:hover { color: var(--text); background: color-mix(in srgb, var(--card-up) 70%, transparent); }
.nav__link[aria-current="page"] { color: var(--lime); }

.nav__burger {
    width: 42px; height: 42px; border-radius: 12px;
    background: var(--card); border: 1px solid var(--line);
    display: grid; place-items: center; cursor: pointer;
}
@media (min-width: 900px) { .nav__burger { display: none; } }

.drawer {
    position: fixed; inset: var(--nav-h) 0 0; z-index: 55;
    background: color-mix(in srgb, var(--sunken) 97%, transparent);
    backdrop-filter: blur(18px);
    border-top: 1px solid var(--line);
    padding: 28px 24px;
    display: flex; flex-direction: column; gap: .35rem;
    overflow-y: auto;
}
.drawer[hidden] { display: none; }
.drawer a {
    padding: .95rem 1rem; border-radius: var(--r-md);
    font-family: var(--display); font-size: 1.05rem;
    border: 1px solid transparent;
}
.drawer a:hover, .drawer a[aria-current="page"] {
    background: var(--card); border-color: var(--line);
}
.drawer a[aria-current="page"] { color: var(--lime); }
.drawer .btn { margin-top: 1rem; }

/* --------------------------------------------------------------------------
   6. BUTTONS & PILLS
   -------------------------------------------------------------------------- */

.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
    padding: .85rem 1.4rem;
    border-radius: 999px;
    border: 1px solid transparent;
    font-family: var(--display); font-weight: 700;
    font-size: .95rem; letter-spacing: -.01em;
    cursor: pointer;
    transition: transform .16s var(--ease), background .18s var(--ease),
                box-shadow .18s var(--ease), border-color .18s var(--ease);
}
.btn:active { transform: translateY(1px); }

.btn--lime {
    background: var(--lime);
    /* Lime is bright enough that only near-black clears contrast on it. Never
       white — that is the rule in the app's colors.js and it holds here. */
    color: var(--ink);
    box-shadow: 0 8px 26px -10px color-mix(in srgb, var(--lime) 70%, transparent);
}
.btn--lime:hover { background: var(--lime-dark); }

.btn--ghost {
    background: color-mix(in srgb, var(--card) 76%, transparent);
    border-color: var(--line);
    color: var(--text);
}
.btn--ghost:hover { background: var(--card-up); border-color: color-mix(in srgb, var(--lime) 45%, var(--line)); }

.btn--pink { background: var(--pink); color: var(--ink); }
.btn--pink:hover { background: var(--pink-deep); }

.btn--wide { width: 100%; }
.btn--lg { padding: 1rem 1.7rem; font-size: 1rem; }

.pill {
    display: inline-flex; align-items: center; gap: .45rem;
    padding: .35rem .8rem; border-radius: 999px;
    font-family: var(--mono); font-size: .68rem;
    letter-spacing: .1em; text-transform: uppercase;
    border: 1px solid var(--line);
    background: color-mix(in srgb, var(--card) 80%, transparent);
    color: var(--muted);
}
.pill--lime {
    color: var(--lime);
    border-color: color-mix(in srgb, var(--lime) 42%, transparent);
    background: color-mix(in srgb, var(--lime) 12%, transparent);
}
.pill--pink {
    color: var(--pink);
    border-color: color-mix(in srgb, var(--pink) 42%, transparent);
    background: color-mix(in srgb, var(--pink) 12%, transparent);
}
.pill--warm {
    color: var(--connecting);
    border-color: color-mix(in srgb, var(--connecting) 42%, transparent);
    background: color-mix(in srgb, var(--connecting) 12%, transparent);
}

/* --------------------------------------------------------------------------
   7. CARDS
   -------------------------------------------------------------------------- */

.card {
    background: color-mix(in srgb, var(--card) 88%, transparent);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    padding: 26px;
    /* The card is what licenses body text anywhere on the page: it is opaque
       enough that the sky behind it stops mattering to contrast. */
    backdrop-filter: blur(6px);
}
.card--up { background: var(--card-up); }
.card--flat { backdrop-filter: none; background: var(--card); }
.card--pad-lg { padding: clamp(26px, 4vw, 44px); }

.card--hover { transition: transform .22s var(--ease), border-color .22s var(--ease); }
.card--hover:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--lime) 38%, var(--line));
}

.ico {
    width: 44px; height: 44px; border-radius: 14px;
    display: grid; place-items: center; margin-bottom: 1.1rem;
    background: color-mix(in srgb, var(--lime) 13%, transparent);
    color: var(--lime);
    flex: none;
}
.ico--pink { background: color-mix(in srgb, var(--pink) 13%, transparent); color: var(--pink); }
.ico--warm { background: color-mix(in srgb, var(--connecting) 13%, transparent); color: var(--connecting); }
.ico--red  { background: color-mix(in srgb, var(--error) 13%, transparent);  color: var(--error); }
.ico svg { width: 22px; height: 22px; }

.card h3 { font-size: 1.14rem; margin-bottom: .55rem; }
.card p { color: var(--muted); font-size: .93rem; }

.card__note {
    margin-top: 1rem; padding-top: 1rem;
    border-top: 1px dashed color-mix(in srgb, var(--line) 90%, transparent);
    font-family: var(--mono); font-size: .72rem;
    color: color-mix(in srgb, var(--muted) 85%, transparent);
    letter-spacing: .02em;
}

/* The same small print without the rule above it, for the one place it closes a
   block rather than annotating a card. */
.card__note--bare { border-top: 0; padding-top: 0; margin-top: 1.1rem; }

/* --------------------------------------------------------------------------
   8. HERO — the only full-strength sunset on the site
   -------------------------------------------------------------------------- */

.hero {
    position: relative;
    isolation: isolate;
    margin-top: calc(var(--nav-h) * -1);
    /* The app mark used to sit above the headline and carried its own 92-132px
       of height. With the mark gone the headline would ride up against the nav,
       so a part of that height comes back here as padding -- the text still sits
       higher than it did, and the bar still has air under it. */
    padding-top: calc(var(--nav-h) + clamp(58px, 8.2vw, 116px));
    padding-bottom: clamp(360px, 40vw, 500px);
    overflow: hidden;
}

/* The gradient stops are placed against where the land actually is, exactly as
   GhibliScene derives them: indigo through the upper half where the headline
   sits, crimson through the mountain, orange along the ridge. */
.hero__sky {
    position: absolute; inset: 0; z-index: -2;
    background: linear-gradient(
        to bottom,
        var(--sky-top) 0%,
        var(--sky-top) 34%,
        var(--sky-mid) 63%,
        var(--sky-bottom) 77%,
        var(--sky-bottom) 100%
    );
}

/* Cloud fluff at 0.20 rather than 0.06, because nothing on the hero reads
   against the backdrop. The band starts below the nav — a puff under the nav
   would put pink and muted text over peach, which is the one combination
   Section 5 rules out. */
.hero__clouds { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
.hero__puff {
    position: absolute; border-radius: 999px;
    background: var(--cloud); opacity: .2;
    will-change: transform;
}
.hero__puff:nth-child(1) { left: -8%;  top: 96px;  width: 210px; height: 210px; animation: drift 58s linear infinite; }
.hero__puff:nth-child(2) { left: 11%;  top: 132px; width: 150px; height: 150px; animation: drift 58s linear infinite; }
.hero__puff:nth-child(3) { left: 3%;   top: 156px; width: 122px; height: 122px; animation: drift 58s linear infinite; }
.hero__puff:nth-child(4) { right: -9%; top: 88px;  width: 182px; height: 182px; animation: drift-back 74s linear infinite; }
.hero__puff:nth-child(5) { right: 6%;  top: 118px; width: 118px; height: 118px; animation: drift-back 74s linear infinite; }
.hero__puff:nth-child(6) { left: 32%;  top: 210px; width: 160px; height: 160px; animation: drift 92s linear infinite; }
.hero__puff:nth-child(7) { left: 47%;  top: 236px; width: 110px; height: 110px; animation: drift 92s linear infinite; }
.hero__puff:nth-child(8) { left: 24%;  top: 248px; width: 96px;  height: 96px;  animation: drift 92s linear infinite; }

/* The land. Same shapes as the app's GhibliScene, computed from the same
   constants at a 1440x420 viewBox, so the mountain here and the mountain on
   Home are the same mountain. `slice` keeps the ridge glued to the bottom on
   any aspect ratio instead of letterboxing it. The block is tall on purpose:
   Fuji is the tallest thing in the picture, and a short strip turns it into a
   bump on a hill. */
.hero__land {
    position: absolute; left: 0; right: 0; bottom: -1px; z-index: -1;
    width: 100%; height: clamp(300px, 34vw, 470px);
    pointer-events: none;
}
.hero__land svg { width: 100%; height: 100%; }

.hero__inner { position: relative; z-index: 1; text-align: center; }

/* Every piece of hero text is either large or sits at near-full lightness.
   `--muted` never appears on the full sky. */
.hero h1 {
    font-size: clamp(2.4rem, 6.6vw, 4.5rem);
    letter-spacing: -.035em;
    max-width: 19ch;
    margin-inline: auto;
}
.hero h1 em {
    font-style: normal;
    color: var(--lime);
}
.hero__lead {
    margin: 1.4rem auto 0;
    max-width: 54ch;
    font-size: clamp(1rem, 1.7vw, 1.16rem);
    color: color-mix(in srgb, var(--text) 88%, transparent);
}
.hero__cta {
    margin-top: 2.2rem;
    display: flex; flex-wrap: wrap; gap: .9rem; justify-content: center;
}
.hero__meta {
    margin-top: 1.6rem;
    display: flex; flex-wrap: wrap; gap: .55rem; justify-content: center;
}
.hero__meta .pill {
    background: color-mix(in srgb, var(--sky-top) 62%, transparent);
    border-color: color-mix(in srgb, var(--text) 22%, transparent);
    color: color-mix(in srgb, var(--text) 86%, transparent);
}

/* --------------------------------------------------------------------------
   8b. PAGE HEAD — the hero's smaller sibling

   Only the home page gets the drawn landscape and the full-strength sunset.
   Every other page opens with this instead: the ambient sky it already sits on,
   a thin ridge to close the block off, and no gradient behind the prose. That
   keeps the hero worth looking at, and keeps a legal page from opening with a
   sunset it has no reason to carry.
   -------------------------------------------------------------------------- */

.page-head {
    position: relative;
    isolation: isolate;
    padding-block: clamp(46px, 7vw, 80px) clamp(52px, 7vw, 88px);
    overflow: hidden;
    border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}

/* A wash of the indigo, strong enough to separate the block from the page and
   far too weak to matter to contrast. */
.page-head::before {
    content: "";
    position: absolute; inset: 0; z-index: -2;
    background: linear-gradient(to bottom,
        color-mix(in srgb, var(--sky-top) 55%, transparent) 0%,
        transparent 100%);
}

.page-head__ridge {
    position: absolute; left: 0; right: 0; bottom: -1px; z-index: -1;
    width: 100%; height: clamp(70px, 8vw, 110px);
    pointer-events: none; opacity: .9;
}
.page-head__ridge svg { width: 100%; height: 100%; }

.page-head h1 {
    font-size: clamp(2rem, 5vw, 3.1rem);
    max-width: 24ch;
}
.page-head .lead { margin-top: 1.1rem; max-width: 62ch; }

/* --------------------------------------------------------------------------
   8c. SMALL LAYOUT HELPERS

   Five names, each used on more than one page. Kept deliberately short of a
   utility framework: anything that needs more than this gets a real class.
   -------------------------------------------------------------------------- */

.sec-head { margin-bottom: clamp(28px, 4vw, 40px); }
.sec-head--center { text-align: center; }
.sec-head--center .eyebrow { justify-content: center; }
.sec-head--center .h-sub { margin-inline: auto; }

.center { text-align: center; }
.center .eyebrow { justify-content: center; }
.center .h-sub { margin-inline: auto; }
.mt-md { margin-top: clamp(22px, 3vw, 30px); }
.mt-lg { margin-top: clamp(30px, 4vw, 40px); }

/* An inline link inside body prose. Outside `.legal`, links in paragraphs are
   rare enough that they get this rather than a blanket rule that would also
   catch the nav, the footer and every button. */
.link { color: var(--lime); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; text-decoration-color: color-mix(in srgb, var(--lime) 45%, transparent); }
.link:hover { text-decoration-color: var(--lime); }

/* A monospace one-liner: an email address, or the tap path to a screen inside
   the app. It sits on the sunken surface because it is something to copy, not
   something to read, and `nowrap` + `overflow-x` keep a long path from breaking
   in the middle of a word on a phone. */
.mono-line {
    display: block;
    font-family: var(--mono); font-size: .88rem;
    background: var(--sunken); border: 1px solid var(--line);
    border-radius: var(--r-sm);
    padding: .9rem 1.1rem; color: var(--lime);
    overflow-x: auto; white-space: nowrap;
}

/* --------------------------------------------------------------------------
   10. FEATURE / CONTENT PATTERNS
   -------------------------------------------------------------------------- */

.step {
    position: relative;
    padding-left: 62px;
}
.step__no {
    position: absolute; left: 0; top: 0;
    width: 44px; height: 44px; border-radius: 14px;
    display: grid; place-items: center;
    font-family: var(--display); font-weight: 700; font-size: 1.05rem;
    background: var(--lime); color: var(--ink);
}
.step h3 { font-size: 1.16rem; margin-bottom: .5rem; }
.step p { color: var(--muted); font-size: .95rem; }

/* A screen-by-screen block on the features page. */
.screen {
    display: grid; gap: 28px;
    grid-template-columns: 1fr;
    align-items: start;
}
@media (min-width: 860px) { .screen { grid-template-columns: 240px 1fr; gap: 40px; } }

.screen__head { position: sticky; top: calc(var(--nav-h) + 24px); }
@media (max-width: 859px) { .screen__head { position: static; } }
.screen__head h3 { font-size: 1.5rem; margin-bottom: .5rem; }
.screen__head p { color: var(--muted); font-size: .86rem; }

.rows { display: grid; gap: 2px; border-radius: var(--r-lg); overflow: hidden; border: 1px solid var(--line); }
.row {
    background: color-mix(in srgb, var(--card) 90%, transparent);
    padding: 20px 22px;
    display: flex; gap: 16px; align-items: flex-start;
}
.row__ico { width: 34px; height: 34px; border-radius: 11px; flex: none; display: grid; place-items: center; margin-bottom: 0; }
.row__ico svg { width: 18px; height: 18px; }
.row h4 { font-size: 1rem; margin-bottom: .3rem; font-family: var(--display); }
.row p { color: var(--muted); font-size: .88rem; }

/* A callout for the honest caveat. Warm rather than red: it is a limit worth
   knowing, not a failure. */
.note {
    border-radius: var(--r-md);
    padding: 18px 20px;
    border: 1px solid color-mix(in srgb, var(--connecting) 34%, transparent);
    background: color-mix(in srgb, var(--connecting) 8%, transparent);
}
.note h4 { font-size: .98rem; margin-bottom: .4rem; color: var(--connecting); }
.note p { font-size: .89rem; color: color-mix(in srgb, var(--text) 82%, transparent); }

.note--lime {
    border-color: color-mix(in srgb, var(--lime) 34%, transparent);
    background: color-mix(in srgb, var(--lime) 8%, transparent);
}
.note--lime h4 { color: var(--lime); }

.note--red {
    border-color: color-mix(in srgb, var(--error) 38%, transparent);
    background: color-mix(in srgb, var(--error) 8%, transparent);
}
.note--red h4 { color: var(--error); }

/* Do / do-not lists */
.checks { display: grid; gap: .7rem; list-style: none; }
.checks li { display: flex; gap: .7rem; font-size: .92rem; color: var(--muted); }
.checks li svg { width: 17px; height: 17px; flex: none; margin-top: .28rem; }
.checks--yes li svg { color: var(--lime); }
.checks--no  li svg { color: var(--error); }

/* Country marquee — conveys reach without printing a number that would be
   stale the moment a sync runs. */
.marquee {
    position: relative;
    overflow: hidden;
    mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
    -webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}
.marquee__track {
    display: flex; gap: 12px; width: max-content;
    animation: slide 46s linear infinite;
}
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__item {
    display: flex; align-items: center; gap: .5rem;
    padding: .5rem .95rem; border-radius: 999px;
    background: color-mix(in srgb, var(--card) 85%, transparent);
    border: 1px solid var(--line);
    font-family: var(--mono); font-size: .74rem;
    white-space: nowrap; color: var(--muted);
}
.marquee__item b { color: var(--text); font-weight: 500; }
@keyframes slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* --------------------------------------------------------------------------
   11. COMPARISON TABLE
   -------------------------------------------------------------------------- */

.tablewrap {
    overflow-x: auto;
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: color-mix(in srgb, var(--card) 90%, transparent);
}
table.cmp { width: 100%; border-collapse: collapse; min-width: 580px; }
table.cmp th, table.cmp td {
    padding: 15px 20px; text-align: left;
    border-bottom: 1px solid color-mix(in srgb, var(--line) 75%, transparent);
    font-size: .92rem;
}
table.cmp thead th {
    font-family: var(--display); font-size: .82rem;
    text-transform: uppercase; letter-spacing: .09em;
    color: var(--muted); background: var(--sunken);
}
table.cmp thead th:nth-child(2) { color: var(--lime); }
table.cmp thead th:nth-child(3) { color: var(--pink); }
table.cmp tbody th { font-weight: 500; font-family: var(--body); color: var(--text); }
table.cmp td { color: var(--muted); }
table.cmp tbody tr:last-child th, table.cmp tbody tr:last-child td { border-bottom: 0; }
table.cmp tbody tr:hover td, table.cmp tbody tr:hover th { background: color-mix(in srgb, var(--card-up) 60%, transparent); }

/* --------------------------------------------------------------------------
   12. FAQ
   -------------------------------------------------------------------------- */

.faq { display: grid; gap: 12px; }
.faq details {
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: color-mix(in srgb, var(--card) 88%, transparent);
    overflow: hidden;
}
.faq details[open] { border-color: color-mix(in srgb, var(--lime) 34%, var(--line)); }
.faq summary {
    padding: 18px 22px;
    cursor: pointer; list-style: none;
    font-family: var(--display); font-weight: 700; font-size: 1rem;
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
    content: ""; flex: none;
    width: 11px; height: 11px;
    border-right: 2px solid var(--lime); border-bottom: 2px solid var(--lime);
    transform: rotate(45deg) translateY(-3px);
    transition: transform .24s var(--ease);
}
.faq details[open] summary::after { transform: rotate(-135deg) translateY(-3px); }
.faq__body { padding: 0 22px 20px; color: var(--muted); font-size: .93rem; }

/* --------------------------------------------------------------------------
   13. FORM
   -------------------------------------------------------------------------- */

.field { display: grid; gap: .5rem; margin-bottom: 1.15rem; }
.field > label {
    font-family: var(--mono); font-size: .66rem;
    letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.input, .select, .textarea {
    width: 100%;
    background: var(--sunken);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    color: var(--text);
    font-family: var(--body); font-size: .95rem;
    padding: .85rem 1rem;
    transition: border-color .18s var(--ease), background .18s var(--ease);
}
.input::placeholder, .textarea::placeholder { color: color-mix(in srgb, var(--muted) 78%, transparent); }
.input:focus, .select:focus, .textarea:focus {
    outline: none; border-color: var(--lime);
    background: var(--card);
}
.textarea { resize: vertical; min-height: 140px; line-height: 1.6; }
.select {
    appearance: none;
    background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
    background-position: calc(100% - 21px) center, calc(100% - 15px) center;
    background-size: 6px 6px, 6px 6px;
    background-repeat: no-repeat;
    padding-right: 2.6rem;
}
.select option { background: var(--sunken); color: var(--text); }

.formstatus {
    margin-top: 1.1rem; padding: 1rem 1.15rem;
    border-radius: var(--r-sm); border: 1px solid var(--line);
    font-family: var(--mono); font-size: .78rem; line-height: 1.55;
}
.formstatus[hidden] { display: none; }
.formstatus.is-ok  { border-color: color-mix(in srgb, var(--lime) 45%, transparent);  background: color-mix(in srgb, var(--lime) 9%, transparent);  color: var(--lime); }
.formstatus.is-bad { border-color: color-mix(in srgb, var(--error) 48%, transparent); background: color-mix(in srgb, var(--error) 9%, transparent); color: var(--error); }

.spinner {
    width: 15px; height: 15px; flex: none;
    border: 2px solid color-mix(in srgb, var(--ink) 30%, transparent);
    border-top-color: var(--ink);
    border-radius: 999px;
    animation: spin .7s linear infinite;
}

/* --------------------------------------------------------------------------
   14. LEGAL PROSE

   Long-form reading, on the app's own card colour rather than an inverted white
   sheet. #F0F4F0 on #1F2421 measures about 14:1, so the dark surface is not a
   compromise here — it is simply the app's surface, at a comfortable measure.
   -------------------------------------------------------------------------- */

.legal { max-width: 78ch; }

.legal__toc {
    border: 1px dashed color-mix(in srgb, var(--muted) 45%, transparent);
    border-radius: var(--r-md);
    padding: 20px 24px;
    margin-bottom: 40px;
}
.legal__toc p {
    font-family: var(--mono); font-size: .64rem;
    letter-spacing: .16em; text-transform: uppercase;
    color: var(--muted); margin-bottom: .85rem;
}
.legal__toc ol {
    columns: 2; column-gap: 32px;
    list-style: none; counter-reset: toc;
    font-size: .89rem;
}
@media (max-width: 620px) { .legal__toc ol { columns: 1; } }
.legal__toc li { counter-increment: toc; margin-bottom: .4rem; break-inside: avoid; }
.legal__toc a { color: var(--muted); }
.legal__toc a::before {
    content: counter(toc) ". ";
    font-family: var(--mono); color: var(--lime);
}
.legal__toc a:hover { color: var(--text); }

.legal section { margin-bottom: 44px; }
.legal h2 {
    font-size: clamp(1.25rem, 2.4vw, 1.6rem);
    margin-bottom: 1rem;
    padding-bottom: .7rem;
    border-bottom: 1px solid var(--line);
}
.legal h3 {
    font-size: 1.02rem;
    margin: 1.7rem 0 .55rem;
    color: var(--lime);
    font-family: var(--display);
}
.legal p { margin-bottom: 1rem; color: color-mix(in srgb, var(--text) 78%, transparent); font-size: .96rem; }
.legal p:last-child { margin-bottom: 0; }
.legal a:not(.btn) {
    color: var(--lime);
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, var(--lime) 45%, transparent);
    text-underline-offset: 3px;
}
.legal a:not(.btn):hover { text-decoration-color: var(--lime); }
.legal strong { color: var(--text); font-weight: 600; }
.legal ul { list-style: none; display: grid; gap: .6rem; margin-bottom: 1rem; }
.legal ul li {
    position: relative; padding-left: 1.4rem;
    color: color-mix(in srgb, var(--text) 76%, transparent);
    font-size: .94rem;
}
.legal ul li::before {
    content: ""; position: absolute; left: 0; top: .62em;
    width: 6px; height: 6px; border-radius: 999px; background: var(--lime);
}
.legal code, .legal .kbd {
    font-family: var(--mono); font-size: .86em;
    background: var(--sunken); border: 1px solid var(--line);
    padding: .12em .45em; border-radius: 6px; color: var(--text);
}

.legal__meta {
    font-family: var(--mono); font-size: .72rem;
    color: var(--muted); letter-spacing: .02em;
}

.legal .mono-line { margin-bottom: 1rem; }

/* --------------------------------------------------------------------------
   15. FOOTER
   -------------------------------------------------------------------------- */

.footer {
    border-top: 1px solid var(--line);
    background: color-mix(in srgb, var(--sunken) 82%, transparent);
    padding-block: 56px 34px;
}
.footer__grid {
    display: grid; gap: 36px;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    margin-bottom: 40px;
}
.footer__grid > div:first-child { grid-column: span 1; }
@media (min-width: 900px) { .footer__grid { grid-template-columns: 1.5fr 1fr 1fr 1fr; } }

.footer h4 {
    font-family: var(--mono); font-size: .66rem;
    letter-spacing: .16em; text-transform: uppercase;
    color: var(--muted); margin-bottom: 1.1rem; font-weight: 400;
}
.footer ul { list-style: none; display: grid; gap: .65rem; }
.footer a { font-size: .91rem; color: var(--muted); }
.footer a:hover { color: var(--lime); }
.footer__tag { color: var(--muted); font-size: .9rem; max-width: 34ch; margin-top: .9rem; }
.footer__base {
    border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent);
    padding-top: 24px;
    display: flex; flex-wrap: wrap; gap: 12px;
    justify-content: space-between; align-items: center;
    font-family: var(--mono); font-size: .72rem; color: var(--muted);
}

/* --------------------------------------------------------------------------
   16. MOTION
   -------------------------------------------------------------------------- */

@keyframes spin    { to { transform: rotate(360deg); } }

/* Scroll reveal. The class is added by JS; without JS every element stays
   visible, which is why the hidden state lives on `.reveal` only after the
   script marks the document as capable. */
.js .reveal { opacity: 0; transform: translateY(22px); }
.js .reveal.in {
    opacity: 1; transform: none;
    transition: opacity .6s var(--ease), transform .6s var(--ease);
}
.js .reveal.in:nth-child(2) { transition-delay: .06s; }
.js .reveal.in:nth-child(3) { transition-delay: .12s; }
.js .reveal.in:nth-child(4) { transition-delay: .18s; }

.hero__inner > * { animation: rise .7s var(--ease) both; }
.hero__inner > *:nth-child(2) { animation-delay: .08s; }
.hero__inner > *:nth-child(3) { animation-delay: .16s; }
.hero__inner > *:nth-child(4) { animation-delay: .24s; }
@keyframes rise { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }

/* One switch for everyone who asked the OS not to animate things. Drifting
   clouds and a breathing glow are exactly the kind of ambient motion that
   setting exists for, so they stop rather than slow down. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
    }
    .js .reveal { opacity: 1; transform: none; }
    .marquee__track { animation: none; }
}
