/* ======== THEMES ======== */
:root[data-theme="dark"] {
    --bg: #0a0a0a;
    --bg-elev: #111111;
    --bg-card: #141414;
    --border: #1f1f1f;
    --border-strong: #2a2a2a;
    --text: #f5f5f2;
    --text-dim: #a3a3a0;
    --text-mute: #6b6b68;
    --accent: #008b55;
    --accent-dim: rgba(0, 139, 85, 0.14);
    --accent-glow: rgba(0, 139, 85, 0.28);
    --accent-bg: rgba(0, 139, 85, 0.06);
    --green: #4ade80;
    --blue: #60a5fa;
    --yellow: #facc15;
    --term-bg: #0d0d0d;
    --card-shadow:
        0 50px 100px rgba(0, 0, 0, 0.5), 0 0 80px var(--accent-glow);
    --grid-line: rgba(255, 255, 255, 0.015);
    --code-bg: #141414;

    /* Platform-era additions. "Coming soon" deliberately borrows the muted
       text/border pair rather than the accent: an unshipped service must never
       read as available at a glance. */
    --soon-fg: #a3a3a0;
    --soon-bg: rgba(255, 255, 255, 0.04);
    --soon-border: #2a2a2a;
    --live-fg: #4ade80;
    --live-bg: rgba(74, 222, 128, 0.1);
    --lift-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
}

:root[data-theme="light"] {
    --bg: #ffffff;
    /* Surfaces are neutral greys rather than the previous warm cream tones:
       against a pure white page, warm off-whites read as a colour cast. */
    --bg-elev: #f4f4f5;
    --bg-card: #ffffff;
    --border: #e4e4e7;
    --border-strong: #d1d1d6;
    --text: #1a1a1a;
    --text-dim: #52525b;
    --text-mute: #85858a;
    --accent: #007447;
    --accent-dim: rgba(0, 116, 71, 0.1);
    --accent-glow: rgba(0, 116, 71, 0.16);
    --accent-bg: rgba(0, 116, 71, 0.04);
    --green: #16a34a;
    --blue: #2563eb;
    --yellow: #ca8a04;
    --term-bg: #1a1a1a;
    --card-shadow:
        0 20px 60px rgba(0, 0, 0, 0.08),
        0 0 60px rgba(0, 116, 71, 0.12);
    /* No grid or hero glow in light mode: the page is meant to read as flat
       white, and both overlays tint it. Kept as variables/rules rather than
       deleted outright because the dark theme still uses them. */
    --grid-line: transparent;
    --code-bg: #f4f4f5;

    --soon-fg: #85858a;
    --soon-bg: #f4f4f5;
    --soon-border: #d1d1d6;
    --live-fg: #15803d;
    --live-bg: rgba(21, 128, 61, 0.08);
    /* Light mode keeps lift subtle — the page reads as flat white, so a heavy
       shadow would fight the deliberate no-glow decision above. */
    --lift-shadow: 0 8px 24px rgba(0, 0, 0, 0.07);
}

:root[data-theme="light"] body::after,
:root[data-theme="light"] .cta-strip::before {
    display: none;
}

/* Derived from --accent rather than hand-tuned per theme, so it stays correct
   if the brand green ever changes. Used only where a control needs to read as
   more prominent than the accent's normal use in text and icons — currently
   just the primary button, which was reading as too close in weight to the
   page's other green accents to register as "the button to press." */
:root {
    --accent-strong: color-mix(in srgb, var(--accent) 85%, black 15%);
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    scroll-behavior: smooth;
    overflow-x: hidden;
}

body {
    font-family: "Ubuntu", sans-serif;
    background: var(--bg);
    color: var(--text);
    line-height: 1.55;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    transition:
        background 0.3s ease,
        color 0.3s ease;
}

/* Grid background */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    background-image:
        linear-gradient(var(--grid-line) 1px, transparent 1px),
        linear-gradient(
            90deg,
            var(--grid-line) 1px,
            transparent 1px
        );
    background-size: 48px 48px;
    pointer-events: none;
    z-index: 0;
}

body::after {
    content: "";
    position: absolute;
    top: -200px;
    left: 50%;
    transform: translateX(-50%);
    width: min(900px, 100vw);
    height: min(900px, 100vw);
    background: radial-gradient(
        circle,
        var(--accent-glow) 0%,
        transparent 60%
    );
    pointer-events: none;
    z-index: 0;
    opacity: 0.5;
}

a {
    color: inherit;
    text-decoration: none;
}

.container {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 32px;
    position: relative;
    z-index: 1;
}

.mono {
    font-family: "Ubuntu Mono", Monaco, "Courier New", monospace;
}

/* ======== NAV ======== */
nav {
    position: sticky;
    top: 0;
    z-index: 100;
    backdrop-filter: blur(20px);
    background: color-mix(in srgb, var(--bg) 75%, transparent);
    border-bottom: 1px solid var(--border);
}

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

.logo {
    font-family: "Ubuntu Mono", Monaco, monospace;
    font-weight: 700;
    font-size: 18px;
    letter-spacing: -0.02em;
    display: flex;
    align-items: center;
    gap: 10px;
}

.logo-dot {
    width: 8px;
    height: 8px;
    background: var(--accent);
    border-radius: 50%;
    box-shadow: 0 0 12px var(--accent);
    animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
    0%,
    100% {
        opacity: 1;
    }
    50% {
        opacity: 0.4;
    }
}

.nav-links {
    display: flex;
    align-items: center;
    gap: 28px;
    font-family: "Ubuntu Mono", monospace;
    font-size: 14px;
}

.nav-links a {
    color: var(--text-dim);
    transition: color 0.2s;
}

.nav-links a:hover {
    color: var(--text);
}

.nav-links a.btn-primary {
    color: #ffffff;
}

.nav-actions {
    display: flex;
    align-items: center;
    gap: 14px;
}

/* Hamburger. Hidden above the breakpoint; the bars are spans rather than an
   SVG so the close state can be built by transforming them. */
.nav-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 32px;
    height: 32px;
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
}

.nav-toggle-bar {
    display: block;
    width: 18px;
    height: 1.5px;
    margin: 0 auto;
    background: var(--text);
    border-radius: 2px;
    transition:
        transform 0.2s ease,
        opacity 0.2s ease;
}

/* Open state: top and bottom bars rotate into an X, middle fades out. */
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) {
    transform: translateY(6.5px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) {
    opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) {
    transform: translateY(-6.5px) rotate(-45deg);
}

/* Nav dropdown */
.nav-dropdown {
    position: relative;
}

.nav-dropdown-trigger {
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    color: var(--text-dim);
    font-family: "Ubuntu Mono", monospace;
    font-size: 14px;
    transition: color 0.2s;
}

/* .open is set by index.js so the trigger also works as a click/Escape
   disclosure, not only on hover. */
.nav-dropdown:hover .nav-dropdown-trigger,
.nav-dropdown.open .nav-dropdown-trigger,
.nav-dropdown:focus-within .nav-dropdown-trigger {
    color: var(--text);
}

.nav-dropdown-menu {
    position: absolute;
    top: 100%;
    left: 50%;
    padding: 6px 0;
    background: var(--bg-elev);
    border: 1px solid var(--border);
    min-width: 140px;
    display: flex;
    flex-direction: column;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateX(-50%) translateY(-4px);
    transition: opacity 0.15s, transform 0.15s, visibility 0.15s;
    z-index: 20;
}

.nav-dropdown:hover .nav-dropdown-menu,
.nav-dropdown.open .nav-dropdown-menu,
.nav-dropdown:focus-within .nav-dropdown-menu {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateX(-50%) translateY(0);
}

.nav-dropdown-menu a {
    display: block;
    padding: 10px 16px;
    font-size: 13px;
    color: var(--text-dim);
    transition: color 0.15s, background 0.15s;
    white-space: nowrap;
}

.nav-dropdown-menu a:hover {
    color: var(--accent);
    background: color-mix(in srgb, var(--accent) 8%, transparent);
}

/* Theme toggle — a single flip button rather than a two-segment control. */
.theme-toggle {
    display: flex;
    align-items: center;
}

.theme-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    background: var(--bg-elev);
    border: 1px solid var(--border);
    border-radius: 50%;
    color: var(--text-dim);
    cursor: pointer;
    font-family: inherit;
    transition:
        color 0.2s,
        background 0.2s,
        border-color 0.2s;
}

.theme-btn:hover {
    color: var(--accent);
    border-color: var(--border-strong);
}

.theme-btn svg {
    width: 15px;
    height: 15px;
}

/* Show the icon for the theme a click moves *to*, so the button reads as an
   action ("go dark") rather than as a status indicator of the current theme.
   The aria-label set by index.js says so explicitly for screen readers. */
.theme-btn .icon-sun {
    display: none;
}

.theme-btn .icon-moon {
    display: block;
}

:root[data-theme="dark"] .theme-btn .icon-moon {
    display: none;
}

:root[data-theme="dark"] .theme-btn .icon-sun {
    display: block;
}

.btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 18px;
    font-family: "Ubuntu Mono", monospace;
    font-size: 14px;
    font-weight: 500;
    border-radius: 6px;
    transition: all 0.2s;
    border: 1px solid transparent;
    cursor: pointer;
    background: none;
    color: inherit;
}

.btn-primary {
    background: var(--accent-strong);
    color: #ffffff;
    font-weight: 700;
}

.btn-primary:hover {
    filter: brightness(1.08);
    transform: translateY(-1px);
    box-shadow: 0 8px 24px var(--accent-glow);
}

.btn-ghost {
    border-color: var(--border-strong);
    color: var(--text-dim);
}

.btn-ghost:hover {
    border-color: var(--text-dim);
    color: var(--text);
}

/* ======== HERO ======== */
.hero {
    padding: 96px 0 80px;
    position: relative;
}

.eyebrow {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    max-width: 100%;
    padding: 6px 14px;
    border: 1px solid var(--border-strong);
    border-radius: 100px;
    font-family: "Ubuntu Mono", monospace;
    font-size: 12px;
    color: var(--text-dim);
    background: var(--bg-elev);
    margin-bottom: 32px;
    overflow-wrap: anywhere;
}

.eyebrow-dot {
    width: 6px;
    height: 6px;
    background: var(--green);
    border-radius: 50%;
    box-shadow: 0 0 8px var(--green);
}

h1 {
    font-family: "Ubuntu", sans-serif;
    font-size: clamp(40px, 6vw, 72px);
    font-weight: 700;
    line-height: 1.02;
    letter-spacing: -0.035em;
    margin-bottom: 24px;
    max-width: 14ch;
    overflow-wrap: anywhere;
}

h1 .highlight {
    color: var(--accent);
    font-style: italic;
    font-weight: 400;
}

/* Problem statement. Sits between the headline and the sub, and outranks the
   sub: full --text rather than --text-dim, and a size that reads as a
   continuation of the headline rather than as body copy. */
/* Three short sentences, so the measure is set to break them roughly one per
   line rather than to fit a paragraph. Narrower than a reading measure on
   purpose: at this size the lead is scanned, not read. */
.hero-lead {
    font-size: clamp(20px, 2.2vw, 24px);
    font-weight: 500;
    color: var(--text);
    max-width: 40ch;
    line-height: 1.4;
    letter-spacing: -0.015em;
    margin-bottom: 18px;
}

.hero-sub {
    font-size: 19px;
    color: var(--text-dim);
    max-width: 56ch;
    margin-bottom: 40px;
    line-height: 1.5;
}

.hero-sub code {
    font-family: "Ubuntu Mono", Monaco, monospace;
    font-size: 15px;
    padding: 2px 6px;
    background: var(--bg-elev);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text);
    overflow-wrap: anywhere;
}

.hero-ctas {
    display: flex;
    gap: 12px;
    align-items: center;
    margin-bottom: 28px;
    flex-wrap: wrap;
}

.btn-lg {
    padding: 14px 22px;
    font-size: 14px;
}

/* Compact confidence row directly under the CTAs. Deliberately not .badge or
   .trust-item — both already carry specific meaning elsewhere (live service
   status; the fuller cards in #trust) and reusing either here would blur that
   vocabulary. A plain checkmark glyph rather than an icon: at this size and
   density an SVG per item would be visual noise, not signal. */
/* Generic compact checkmark row. Used in the hero as-is (spacing there comes
   from .hero-ctas' margin-bottom and the section's own bottom padding, since
   it is the last element in .hero .container) and again in #trust with its
   own contextual margin below. */
.trust-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 24px;
    list-style: none;
    font-family: "Ubuntu Mono", monospace;
    font-size: 12.5px;
    color: var(--text-mute);
}

.trust-strip li {
    display: flex;
    align-items: center;
    gap: 7px;
}

.trust-strip li::before {
    content: "\2713";
    color: var(--accent);
    font-size: 11px;
}

/* Sits between the #trust heading and the fuller trust-grid cards below it —
   a fast-scan summary before the detail, not a duplicate of it. */
#trust .trust-strip {
    margin: 24px 0 44px;
}

/* ======== SECTION ======== */
section {
    padding: 96px 0;
    position: relative;
}

.section-label {
    font-family: "Ubuntu Mono", monospace;
    font-size: 12px;
    color: var(--accent);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    margin-bottom: 16px;
}

h2 {
    font-family: "Ubuntu", sans-serif;
    font-size: clamp(32px, 4vw, 48px);
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1.05;
    margin-bottom: 20px;
    max-width: 20ch;
    overflow-wrap: anywhere;
}

h2 .highlight {
    color: var(--accent);
    font-style: italic;
    font-weight: 400;
}

/* Product and solution pages carry an <h1> for document structure, but should
   not shout like the homepage hero. These metrics deliberately mirror the h2
   rule above — the pages previously used an h2 here, and the change is meant to
   be semantic only, not visual. Same rationale as .doc-page h1 further down,
   which does the equivalent for the legal pages. */
.page-hero h1 {
    font-size: clamp(32px, 4vw, 48px);
    letter-spacing: -0.03em;
    line-height: 1.05;
    margin-bottom: 20px;
    max-width: 20ch;
}

.page-hero h1 .highlight {
    color: var(--accent);
    font-style: italic;
    font-weight: 400;
}

.section-sub {
    font-size: 17px;
    color: var(--text-dim);
    max-width: 56ch;
    margin-bottom: 56px;
}

/* ======== CODE TABS ======== */
.code-tabs {
    background: var(--code-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    overflow: hidden;
    max-width: 100%;
}

.tabs-header {
    display: flex;
    border-bottom: 1px solid var(--border);
    background: var(--bg-elev);
    flex-wrap: wrap;
}

.tab {
    padding: 14px 20px;
    font-family: "Ubuntu Mono", monospace;
    font-size: 14px;
    color: var(--text-mute);
    cursor: pointer;
    border: none;
    background: none;
    border-bottom: 2px solid transparent;
    transition: all 0.15s;
}

.tab:hover {
    color: var(--text-dim);
}

.tab.active {
    color: var(--text);
    border-bottom-color: var(--accent);
}

.tab-copy {
    margin-left: auto;
    padding: 14px 20px;
    font-family: "Ubuntu Mono", monospace;
    font-size: 12px;
    color: var(--text-mute);
    cursor: pointer;
    background: none;
    border: none;
    transition: color 0.2s;
}

.tab-copy:hover {
    color: var(--text);
}

.code-panel {
    padding: 28px 24px;
    font-family: "Ubuntu Mono", Monaco, monospace;
    font-size: 14.5px;
    line-height: 1.75;
    white-space: pre;
    overflow-x: auto;
    display: none;
    color: var(--text);
    max-width: 100%;
}

.code-panel.active {
    display: block;
}

:root[data-theme="dark"] .tok-key {
    color: #c084fc;
}
:root[data-theme="dark"] .tok-str {
    color: #86efac;
}
:root[data-theme="dark"] .tok-fn {
    color: #60a5fa;
}
:root[data-theme="dark"] .tok-com {
    color: #6b6b68;
    font-style: italic;
}
:root[data-theme="dark"] .tok-var {
    color: #fbbf24;
}
:root[data-theme="dark"] .tok-op {
    color: var(--text-dim);
}

:root[data-theme="light"] .tok-key {
    color: #7c3aed;
}
:root[data-theme="light"] .tok-str {
    color: #16a34a;
}
:root[data-theme="light"] .tok-fn {
    color: #2563eb;
}
:root[data-theme="light"] .tok-com {
    color: #8a8680;
    font-style: italic;
}
:root[data-theme="light"] .tok-var {
    color: #b45309;
}
:root[data-theme="light"] .tok-op {
    color: var(--text-dim);
}

/* ======== FEATURE BUCKETS ======== */
.features {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0;
    margin-top: 48px;
    border: 1px solid var(--border);
    border-radius: 12px;
    overflow: hidden;
    background: var(--bg-card);
}

.feature {
    padding: 36px;
    border-right: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    position: relative;
    transition: background 0.2s;
}

.feature:hover {
    background: var(--accent-bg);
}

.feature:nth-child(2n) {
    border-right: none;
}
.feature:nth-last-child(-n + 2) {
    border-bottom: none;
}

/* Six outcomes read better as two rows of three than three rows of two once
   there is room. The 2-column border rules above have to be reset explicitly
   before the 3-column ones apply, or a stray divider is left mid-row. */
@media (min-width: 1000px) {
    .features {
        grid-template-columns: repeat(3, 1fr);
    }
    .feature:nth-child(2n) {
        border-right: 1px solid var(--border);
    }
    .feature:nth-last-child(-n + 2) {
        border-bottom: 1px solid var(--border);
    }
    .feature:nth-child(3n) {
        border-right: none;
    }
    .feature:nth-last-child(-n + 3) {
        border-bottom: none;
    }
}

.feature-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 20px;
}

.feature-num {
    font-family: "Ubuntu Mono", monospace;
    font-size: 12px;
    color: var(--accent);
    letter-spacing: 0.05em;
    font-weight: 700;
}

.feature-icon {
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-mute);
}

.feature-icon svg {
    width: 20px;
    height: 20px;
    stroke-width: 1.5;
}

.feature h3 {
    font-family: "Ubuntu", sans-serif;
    font-size: 20px;
    font-weight: 500;
    margin-bottom: 10px;
    letter-spacing: -0.01em;
}

.feature p {
    font-size: 14.5px;
    color: var(--text-dim);
    line-height: 1.6;
}

.feature code {
    font-family: "Ubuntu Mono", monospace;
    font-size: 12.5px;
    padding: 1px 6px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--accent);
}

.step {
    display: flex;
    gap: 16px;
    align-items: flex-start;
}

.step-num {
    font-family: "Ubuntu Mono", monospace;
    font-size: 12px;
    color: var(--accent);
    background: var(--accent-dim);
    border: 1px solid var(--accent);
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-weight: 700;
}

.step-content h4 {
    font-size: 16px;
    font-weight: 500;
    margin-bottom: 4px;
    font-family: "Ubuntu", sans-serif;
}

.step-content p {
    font-size: 14px;
    color: var(--text-dim);
    line-height: 1.5;
}

.step-content code {
    font-family: "Ubuntu Mono", monospace;
    font-size: 12.5px;
    color: var(--accent);
    background: var(--bg);
    padding: 1px 6px;
    border-radius: 3px;
    border: 1px solid var(--border);
}

/* ======== DEVELOPER INTERFACE ======== */
/* Supporting copy under the CLI/API/MCP tabs. Dimmer and narrower than
   .section-sub so it reads as a footnote to the code, not as a second
   introduction to the section. */
.dev-note {
    margin-top: 20px;
    font-size: 14px;
    line-height: 1.7;
    color: var(--text-mute);
    max-width: 68ch;
}

.dev-links {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 32px;
    margin-top: 20px;
}

/* ======== TRUST ======== */
/* Claims a visitor can check themselves, in place of invented usage metrics.
   Denser than .service-card — no icon, no badge, no link — because these are
   read as a list, not browsed as a set of products. */
/* 300px rather than 260px so six items land as 3+3 at desktop instead of a
   ragged 4+2, matching the rhythm of the .features grid directly above. */
.trust-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 16px;
    margin-top: 48px;
}

.trust-item {
    padding: 24px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 12px;
}

.trust-item h3 {
    font-size: 15px;
    font-weight: 500;
    letter-spacing: -0.01em;
    margin-bottom: 8px;
}

.trust-item p {
    font-size: 14px;
    line-height: 1.65;
    color: var(--text-dim);
    margin: 0;
}

.trust-item code {
    font-family: "Ubuntu Mono", monospace;
    font-size: 13px;
    color: var(--accent);
}

/* ======== BUILT WITH NYAS ======== */
/* Deliberately lighter than a card grid: these are named categories, not
   claims that need the weight of a bordered tile, and a fourth icon-card
   pattern on the same page would blur into the services grid and #why. Plain
   tags with a bullet, sized to read as a quick list rather than something to
   individually study. */
.use-case-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 14px 16px;
    list-style: none;
    margin-top: 40px;
}

.use-case-grid li {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 10px 18px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 100px;
    font-size: 14.5px;
    color: var(--text-dim);
}

.use-case-grid li::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
    flex-shrink: 0;
}

/* ======== FAQ ======== */
.faq-list {
    max-width: 800px;
    border-top: 1px solid var(--border);
}

.faq-item {
    border-bottom: 1px solid var(--border);
}

.faq-q {
    width: 100%;
    padding: 24px 0;
    background: none;
    border: none;
    cursor: pointer;
    text-align: left;
    color: var(--text);
    font-size: 17px;
    font-family: "Ubuntu", sans-serif;
    font-weight: 500;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 20px;
    transition: color 0.2s;
}

.faq-q:hover {
    color: var(--accent);
}

.faq-icon {
    font-family: "Ubuntu Mono", monospace;
    color: var(--text-mute);
    font-size: 16px;
    transition: transform 0.2s;
    flex-shrink: 0;
    font-weight: 400;
}

.faq-item.open .faq-icon {
    transform: rotate(45deg);
    color: var(--accent);
}

.faq-a {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease;
    color: var(--text-dim);
    font-size: 15px;
    line-height: 1.65;
}

.faq-a-inner {
    padding-bottom: 24px;
    padding-right: 40px;
    max-width: 100%;
    overflow-x: auto;
}

.faq-a-inner p + p {
    margin-top: 12px;
}

.faq-a-inner a {
    color: var(--accent);
    text-decoration: none;
}

.faq-a-inner a:hover {
    text-decoration: underline;
}

.faq-a code {
    font-family: "Ubuntu Mono", monospace;
    font-size: 14px;
    background: var(--bg-elev);
    padding: 1px 6px;
    border-radius: 3px;
    color: var(--text);
}

.ext-table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 16px;
    font-family: "Ubuntu Mono", monospace;
    font-size: 14px;
}

.ext-table th {
    text-align: left;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
    color: var(--text-mute);
    font-weight: 400;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-size: 11px;
}

.ext-table td {
    padding: 9px 12px;
    border-bottom: 1px dashed var(--border);
    vertical-align: top;
}

.ext-table tr:last-child td {
    border-bottom: none;
}

.ext-table td:first-child {
    white-space: nowrap;
}

.ext-optional {
    display: inline-block;
    margin-top: 16px;
    padding: 10px 14px;
    background: var(--accent-bg);
    border: 1px solid var(--border-strong);
    border-radius: 6px;
    font-size: 14px;
    color: var(--text-dim);
}

.ext-optional strong {
    color: var(--accent);
}

/* ======== CTA STRIP ======== */
.cta-strip {
    padding: 88px 0;
    text-align: center;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    position: relative;
}

.cta-strip::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(
        ellipse at center,
        var(--accent-glow) 0%,
        transparent 60%
    );
    opacity: 0.5;
    pointer-events: none;
}

.cta-strip h2 {
    margin: 0 auto 24px;
}

.cta-strip .hero-ctas {
    justify-content: center;
    margin-bottom: 0;
}

/* ======== FOOTER ======== */
footer {
    padding: 56px 0 32px;
}

.foot-grid {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr;
    gap: 48px;
    margin-bottom: 48px;
}

.foot-brand {
    font-family: "Ubuntu Mono", monospace;
    font-size: 14px;
    color: var(--text-dim);
    line-height: 1.7;
    max-width: 36ch;
}

/* The global `a { text-decoration: none }` would make this link invisible as
   a link inside body copy, unlike the footer's list items which read as
   links from position alone. The underline is the only cue here. */
.foot-brand a {
    text-decoration: underline;
    text-underline-offset: 2px;
    text-decoration-color: var(--border-strong);
    transition: color 0.2s, text-decoration-color 0.2s;
}

.foot-brand a:hover {
    color: var(--text);
    text-decoration-color: var(--text-dim);
}

.foot-col h5 {
    font-family: "Ubuntu Mono", monospace;
    font-size: 11px;
    color: var(--text-mute);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    margin-bottom: 16px;
}

.foot-col ul {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.foot-col a {
    font-size: 14px;
    color: var(--text-dim);
    transition: color 0.2s;
}
.foot-col a:hover {
    color: var(--text);
}

.foot-bottom {
    padding-top: 32px;
    border-top: 1px solid var(--border);
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-family: "Ubuntu Mono", monospace;
    font-size: 12px;
    color: var(--text-mute);
    flex-wrap: wrap;
    gap: 12px;
}

/* ======== RESPONSIVE ======== */
@media (max-width: 900px) {
    .container {
        padding: 0 20px;
    }

    /* Below this width, relying on overflow-x: auto for code is a mobile trap:
       a long DATABASE_URL= line just runs off the right edge of the card with
       no visible cue that there is more to see, since a resting native
       scrollbar is invisible on touch until the reader happens to swipe. Wrap
       instead. This does cost the deliberate indentation alignment in the
       multi-line JS/Python examples, but a wrapped-and-readable line beats a
       clipped one; overflow-wrap: anywhere (not word-break: break-all) only
       breaks where a normal wrap has no other option, so it does not fracture
       identifiers that do fit. */
    .code-panel {
        white-space: pre-wrap;
        overflow-wrap: anywhere;
    }
    .nav-toggle {
        display: flex;
    }

    /* The same .nav-links element the desktop bar uses becomes a full-width
       panel below the nav. There is only ever one copy of the links; the
       previous rule hid the anchors but left the dropdown triggers stranded as
       loose words in the bar. */
    .nav-links {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        padding: 8px 20px 20px;
        background: var(--bg);
        border-bottom: 1px solid var(--border);
        box-shadow: var(--lift-shadow);
        max-height: calc(100vh - 64px);
        overflow-y: auto;
    }

    .nav-links.open {
        display: flex;
    }

    .nav-links > a {
        padding: 13px 4px;
        border-bottom: 1px solid var(--border);
    }

    /* Dropdowns flatten into labelled groups: on a touch panel there is no
       hover, and a nested flyout inside a scrolling sheet is worse than just
       showing the items. */
    .nav-dropdown {
        border-bottom: 1px solid var(--border);
        padding: 13px 0 6px;
    }

    .nav-dropdown-trigger {
        display: block;
        width: 100%;
        text-align: left;
        padding: 0 4px 4px;
        color: var(--text-mute);
        font-size: 12px;
        letter-spacing: 0.08em;
        text-transform: uppercase;
        cursor: default;
    }

    .nav-dropdown-menu,
    .nav-dropdown:hover .nav-dropdown-menu,
    .nav-dropdown:focus-within .nav-dropdown-menu {
        display: flex;
        position: static;
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
        transform: none;
        transition: none;
        background: none;
        border: 0;
        padding: 0;
        min-width: 0;
    }

    .nav-dropdown-menu a {
        padding: 10px 4px 10px 14px;
        font-size: 14px;
    }

    /* The CTA stays in the bar but tightens up so logo + toggle + CTA +
       hamburger fit on a 375px viewport. */
    .nav-cta {
        padding: 9px 13px;
        font-size: 12.5px;
    }
    .nav-actions {
        gap: 10px;
    }
    .hero {
        padding: 48px 0 40px;
    }
    section {
        padding: 64px 0;
    }
    .features {
        grid-template-columns: 1fr;
    }
    .feature {
        border-right: none;
    }
    .feature:nth-last-child(2) {
        border-bottom: 1px solid var(--border);
    }
    .dev-links {
        gap: 10px 20px;
    }
    .foot-grid {
        grid-template-columns: 1fr 1fr;
        gap: 32px;
    }
    h1 {
        font-size: 40px;
    }
}

/* ======== PRODUCTS ======== */
.product-links {
    display: flex;
    flex-direction: column;
    max-width: 860px;
    border-top: 1px solid var(--border);
}

.product-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 24px 4px;
    border-bottom: 1px solid var(--border);
    text-decoration: none;
    color: var(--text);
    transition: color 0.15s;
}

.product-link:hover {
    color: var(--accent);
}

.product-link:hover .product-link-arrow {
    transform: translateX(4px);
}

.product-link-info {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.product-link-name {
    font-size: 17px;
    font-weight: 500;
}

.product-link-desc {
    font-size: 14px;
    color: var(--text-dim);
}

.product-link:hover .product-link-desc {
    color: var(--text-dim);
}

.product-link-arrow {
    font-size: 20px;
    flex-shrink: 0;
    transition: transform 0.15s;
    color: var(--accent);
}

/* ======== PRODUCT PAGES (database.html / storage.html) ======== */

.product-page-body {
    display: flex;
    flex-direction: column;
    gap: 48px;
    max-width: 860px;
    margin-top: 48px;
    padding-bottom: 80px;
}

.product-page-block h3 {
    font-size: 18px;
    font-weight: 500;
    margin-bottom: 16px;
}

.product-page-block p {
    font-size: 15px;
    color: var(--text-dim);
    line-height: 1.7;
    margin-bottom: 20px;
}

.product-feature-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.product-feature-list li {
    font-size: 15px;
    color: var(--text-dim);
    padding-left: 20px;
    position: relative;
}

.product-feature-list li::before {
    content: "✓";
    position: absolute;
    left: 0;
    color: var(--accent);
    font-size: 13px;
}

.product-page-cta {
    display: flex;
    gap: 16px;
    align-items: center;
    flex-wrap: wrap;
}

/* CLI block */
.cli-panel.code-panel {
    padding: 0;
    white-space: normal;
}

.cli-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
}

.cli-row:last-child {
    border-bottom: none;
}

.cli-label {
    display: block;
    font-size: 12px;
    color: var(--text-dim);
    margin-bottom: 4px;
}

.cli-cmd {
    font-family: "Ubuntu Mono", monospace;
    font-size: 14px;
    color: var(--accent);
}

.cli-copy {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
    padding: 6px 14px;
    font-family: "Ubuntu Mono", monospace;
    font-size: 12px;
    color: var(--text-dim);
    background: none;
    border: 1px solid var(--border);
    border-radius: 4px;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s;
}

.cli-copy:hover {
    color: var(--text);
    border-color: var(--text-dim);
}

/* ==============================================================================
   PLATFORM COMPONENTS
   ==============================================================================

   Added when the site moved from a two-product page (Postgres + storage) to a
   developer-cloud platform. Everything below composes from the existing tokens
   rather than hardcoding colour, so both themes stay in sync automatically.
   ============================================================================ */

/* ------------------------------------------------------------------ badges --
   Two states only: shipped and coming-soon. The soon variant intentionally
   avoids --accent so a skim-reader cannot mistake an unshipped service for an
   available one. */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
    padding: 3px 9px;
    border-radius: 100px;
    font-family: "Ubuntu Mono", monospace;
    font-size: 11px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
}

.badge-live {
    color: var(--live-fg);
    background: var(--live-bg);
    border: 1px solid transparent;
}

.badge-soon {
    color: var(--soon-fg);
    background: var(--soon-bg);
    border: 1px solid var(--soon-border);
}

.badge-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: currentColor;
}

/* ------------------------------------------------------------- service grid --
   The platform overview. Cards carry .service-card for styling and
   .platform-service for machine readers, following the doubled-class
   convention already used elsewhere on this page. */

/* Group headings above each grid carry the live/soon distinction that used to
   live in a sentence above both grids. Reuses the badge color tokens (not the
   badge component itself — this sits above eight cards, not on one) so
   "available today" and "coming soon" stay the same two colors everywhere on
   the page. */
.service-group-head {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: "Ubuntu Mono", monospace;
    font-size: 12px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin-top: 48px;
    margin-bottom: 16px;
}

.service-group-head.is-live {
    color: var(--live-fg);
}

.service-group-head.is-soon {
    color: var(--soon-fg);
}

/* The first heading sits right under the section intro, so it does not need
   the 48px that separates the second group from the grid above it. */
.section-sub + .service-group-head {
    margin-top: 0;
}

.service-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 16px;
}

.service-grid + .service-group-head {
    padding-top: 8px;
    border-top: 1px solid var(--border);
}

.service-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 28px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 12px;
    transition:
        transform 0.18s ease,
        box-shadow 0.18s ease,
        border-color 0.18s ease;
}

.service-card:hover {
    transform: translateY(-2px);
    border-color: var(--border-strong);
    box-shadow: var(--lift-shadow);
}

/* Coming-soon cards are visually recessed and do not lift: nothing about them
   should invite a click, because there is nothing to click through to. */
.service-card.is-soon {
    background: var(--bg-elev);
    border-style: dashed;
}

.service-card.is-soon:hover {
    transform: none;
    box-shadow: none;
    border-color: var(--border);
}

.service-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.service-icon {
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    background: var(--accent-dim);
    color: var(--accent);
}

.service-card.is-soon .service-icon {
    background: var(--soon-bg);
    color: var(--soon-fg);
}

.service-icon svg {
    width: 18px;
    height: 18px;
    stroke-width: 1.6;
}

.service-name {
    font-size: 18px;
    font-weight: 500;
    letter-spacing: -0.01em;
}

.service-card.is-soon .service-name {
    color: var(--text-dim);
}

.service-desc {
    font-size: 14.5px;
    color: var(--text-dim);
    line-height: 1.6;
    flex: 1;
}

.service-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    color: var(--accent);
    transition: gap 0.15s ease;
}

.service-link:hover {
    gap: 10px;
}

/* Stand-in for the CTA on shipped cards, so coming-soon cards keep the same
   height without offering an action. */
.service-note {
    font-family: "Ubuntu Mono", monospace;
    font-size: 12.5px;
    color: var(--text-mute);
}

/* ---------------------------------------------------------------- workflow --
   Git push -> build -> deploy -> global -> scale. The connector between steps
   animates a short pulse along its length; it is purely decorative, so it is
   switched off entirely under prefers-reduced-motion (see the block at the end
   of this file). */

/* Four steps, four columns. This said repeat(5, 1fr) while the workflow still
   had a "Global" stage; after that step was folded into "Deploy" the empty
   fifth column silently squeezed the remaining four into 80% of the row. */
.flow {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0;
    margin-top: 56px;
}

.flow-step {
    position: relative;
    padding: 0 16px;
}

.flow-step:first-child {
    padding-left: 0;
}

.flow-step:last-child {
    padding-right: 0;
}

.flow-marker {
    position: relative;
    display: flex;
    align-items: center;
    height: 32px;
    margin-bottom: 20px;
}

.flow-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--bg);
    border: 2px solid var(--accent);
    flex-shrink: 0;
    z-index: 1;
}

/* The rail runs from this step's dot to the next one. The last step has no
   successor, so it gets no rail.
   -32px is the gap between two steps' content boxes: 16px of this step's
   padding-right plus 16px of the next step's padding-left. */
.flow-step:not(:last-child) .flow-marker::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 12px;
    right: -32px;
    height: 1px;
    background: var(--border-strong);
}

/* The pulse is a short gradient segment swept along the rail by animating
   background-position rather than transform. Percentages are relative to the
   rail's own width, so this stays correct at every viewport width instead of
   travelling a fixed pixel distance and stopping short. */
.flow-step:not(:last-child) .flow-marker::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 12px;
    right: -32px;
    height: 1px;
    background-image: linear-gradient(
        90deg,
        transparent,
        var(--accent) 50%,
        transparent
    );
    background-size: 40% 100%;
    background-repeat: no-repeat;
    animation: flow-pulse 3s linear infinite;
}

.flow-step:nth-child(2) .flow-marker::after {
    animation-delay: 0.6s;
}
.flow-step:nth-child(3) .flow-marker::after {
    animation-delay: 1.2s;
}
/* No delay rule for the fourth step: it is the last child, so it has no rail
   to sweep. */

@keyframes flow-pulse {
    from {
        background-position: -40% 0;
        opacity: 0;
    }
    15% {
        opacity: 1;
    }
    85% {
        opacity: 1;
    }
    to {
        background-position: 140% 0;
        opacity: 0;
    }
}

/* Icon and step number share a row, mirroring .feature-meta in the "why"
   grid so the two sections use one visual grammar for the same idea. The icon
   sits below the rail rather than on it: the rail is anchored to the 12px dot,
   and dropping a 32px tile into that row would push the connector off-centre
   at every step. */
.flow-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
}

.flow-icon {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    border-radius: 8px;
    background: var(--accent-bg);
    border: 1px solid var(--border);
    color: var(--accent);
}

.flow-icon svg {
    width: 16px;
    height: 16px;
    stroke-width: 1.6;
}

.flow-num {
    font-family: "Ubuntu Mono", monospace;
    font-size: 11px;
    letter-spacing: 0.08em;
    color: var(--accent);
}

.flow-step h3 {
    font-size: 16px;
    font-weight: 500;
    margin-bottom: 8px;
    letter-spacing: -0.01em;
}

.flow-step p {
    font-size: 13.5px;
    color: var(--text-dim);
    line-height: 1.6;
}

.flow-step code {
    font-family: "Ubuntu Mono", monospace;
    font-size: 12.5px;
    color: var(--accent);
}

/* ------------------------------------------------------ architecture panel --
   HTML boxes rather than an inline SVG. An SVG viewBox locks the aspect ratio,
   which forced a 640px min-width and sideways scrolling on phones; these nodes
   reflow instead, and their labels remain real text. */

/* This diagram carries more of the page's positioning than any other single
   element, so it gets the same restrained "important card" treatment — a
   border tint and a top wash — rather than a
   drop shadow, which would be the only shadow anywhere on a page that is
   otherwise flat by design. */
/* A faint dot grid as an extra background layer — no pseudo-element, no
   z-index bookkeeping for the children above it, since background layers
   stack in the order listed (first = topmost) regardless of DOM order. Echoes
   the same dot-grid body::before already paints behind the whole page, so
   this reads as a zoomed-in view of that system rather than a new motif. */
.arch {
    position: relative;
    margin-top: 48px;
    padding: 48px 40px 44px;
    background:
        radial-gradient(var(--border) 1px, transparent 1px) 0 0 / 24px 24px,
        linear-gradient(180deg, var(--accent-bg), transparent 45%),
        var(--bg-card);
    border: 1px solid var(--border-strong);
    border-radius: 14px;
    overflow: hidden;
}

.arch-project {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 28px;
    padding: 5px 12px;
    background: var(--bg-elev);
    border: 1px solid var(--border);
    border-radius: 100px;
    font-family: "Ubuntu Mono", monospace;
    font-size: 12px;
    letter-spacing: 0.02em;
    color: var(--text-dim);
}

.arch-project-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 8px var(--accent);
}

/* The spine: application -> build -> live. Stacked rather than in a row so the
   whole figure reads top-down, which is the direction the branch below it
   already forces. */
.arch-spine {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.arch-spine .arch-node {
    width: min(340px, 100%);
}

.arch-node {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    min-width: 0;
    padding: 16px 18px;
    background: var(--bg-elev);
    border: 1px solid var(--border-strong);
    border-radius: 10px;
    text-align: center;
}

.arch-node.is-primary {
    background: var(--accent-dim);
    border-color: var(--accent);
}

/* Unshipped services keep the dashed outline the SVG used, so the state still
   survives a screenshot even if the badge is missed. */
.arch-node.is-soon {
    background: var(--soon-bg);
    border-style: dashed;
    border-color: var(--soon-border);
}

/* Same glyphs as .service-icon in the grid below, at a smaller size that fits
   a compact leaf. Matching icons, not just matching names, is what lets a
   reader recognise a card a few seconds later instead of re-reading it. */
.arch-node-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    margin: 0 auto 8px;
    border-radius: 7px;
    background: var(--accent-dim);
    color: var(--accent);
}

.arch-node-icon svg {
    width: 14px;
    height: 14px;
    stroke-width: 1.8;
}

.arch-node.is-soon .arch-node-icon {
    background: var(--soon-bg);
    color: var(--soon-fg);
}

.arch-node-name {
    font-size: 13.5px;
    font-weight: 500;
    color: var(--text);
    overflow-wrap: anywhere;
}

.arch-live-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 7px;
    margin-bottom: 1px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 8px var(--accent);
    vertical-align: middle;
    animation: pulse 2s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
    .arch-live-dot {
        animation: none;
    }
}

.arch-node.is-soon .arch-node-name {
    color: var(--text-dim);
}

.arch-node-meta {
    font-family: "Ubuntu Mono", monospace;
    font-size: 11px;
    color: var(--text-mute);
    overflow-wrap: anywhere;
}

/* Connector between spine stages: a vertical rule with a solid arrowhead. */
.arch-drop {
    position: relative;
    width: 2px;
    height: 26px;
    background: var(--accent);
}

.arch-drop::after {
    content: "";
    position: absolute;
    bottom: -1px;
    left: 50%;
    transform: translateX(-50%);
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 6px solid var(--accent);
}

/* Trunk from the spine down to the branch rail. The line is absolutely
   positioned so it spans the full height uninterrupted, and the caption is
   painted over it with the panel's own background — the line then appears to
   run behind the words instead of stopping short of the rail. */
.arch-trunk {
    position: relative;
    height: 56px;
}

.arch-trunk-line {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 2px;
    transform: translateX(-1px);
    background: var(--border-strong);
}

.arch-trunk-label {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    padding: 0 10px;
    background: var(--bg-card);
    font-family: "Ubuntu Mono", monospace;
    font-size: 11px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--text-mute);
}

.arch-branch {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    column-gap: 12px;
}

/* Each leaf draws its own share of the rail. The horizontal segment reaches
   6px into the 12px gutter on each side, so neighbouring segments meet exactly
   in the middle and the rail appears continuous. First and last leaves stop at
   their own centre, which is what keeps the rail from overhanging the figure —
   no hard-coded width, so it survives any column count. */
.arch-leaf {
    position: relative;
    padding-top: 30px;
}

.arch-leaf::before {
    content: "";
    position: absolute;
    top: 0;
    height: 2px;
    background: var(--border-strong);
}

.arch-leaf:first-child::before {
    left: 50%;
    right: -6px;
}

.arch-leaf:last-child::before {
    left: -6px;
    right: 50%;
}

.arch-leaf:not(:first-child):not(:last-child)::before {
    left: -6px;
    right: -6px;
}

/* Drop from the rail into the node. */
.arch-leaf::after {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-1px);
    width: 2px;
    height: 30px;
    background: var(--border-strong);
}

.arch-branch .arch-node {
    height: 100%;
    align-items: center;
    gap: 8px;
    padding: 14px 10px;
}

/* A single leaf has no rail to draw, only a drop. */
.arch-leaf:only-child::before {
    display: none;
}

/* Six columns stop being legible well before the layout breakpoint, so the
   branch steps down twice. The rail is drawn per-leaf against the *first* and
   *last* child of the whole grid, which is only correct while every leaf shares
   one row — once the grid wraps, the rail would run off the end of row one and
   never appear on row two. So at every wrapped width the rail is replaced by a
   per-leaf stub, which still reads as "these hang off the trunk". */
@media (max-width: 1000px) {
    .arch-branch {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        row-gap: 12px;
    }
    .arch-leaf::before {
        display: none;
    }
    .arch-leaf::after {
        height: 18px;
    }
    .arch-leaf {
        padding-top: 18px;
    }
}

@media (max-width: 560px) {
    .arch-branch {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* --------------------------------------------------------- document pages --
   Shared by privacy.html, terms.html, faq.html and blog.html. These four pages
   previously each carried their own ~150-450 line inline <style> block that
   re-implemented the tokens above; folding them here is what lets them pick up
   the theme toggle for free. */

.doc-page {
    padding: 64px 0 96px;
}

/* Document pages get a smaller h1 than the marketing pages: a 72px heading on
   a privacy policy reads as shouting, and the 14ch cap would wrap short titles
   like "Terms of Service" mid-phrase. */
.doc-page h1 {
    font-size: clamp(34px, 4.5vw, 52px);
    max-width: 20ch;
    margin-bottom: 20px;
}

.doc-intro {
    font-size: 17px;
    color: var(--text-dim);
    max-width: 68ch;
    line-height: 1.7;
    margin-bottom: 40px;
}

.doc-card {
    max-width: 860px;
    padding: 40px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 12px;
}

.doc-card h2 {
    font-size: 21px;
    font-weight: 500;
    letter-spacing: -0.015em;
    margin: 40px 0 14px;
    max-width: none;
}

.doc-card h2:first-child {
    margin-top: 0;
}

.doc-card h3 {
    font-size: 16px;
    font-weight: 500;
    margin: 24px 0 10px;
}

.doc-card p,
.doc-card li {
    font-size: 15px;
    color: var(--text-dim);
    line-height: 1.75;
}

.doc-card p {
    margin-bottom: 14px;
}

.doc-card ul,
.doc-card ol {
    margin: 0 0 16px 22px;
}

.doc-card li {
    margin-bottom: 8px;
}

.doc-card a {
    color: var(--accent);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.doc-card code {
    font-family: "Ubuntu Mono", monospace;
    font-size: 13px;
    padding: 1px 6px;
    background: var(--bg-elev);
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--accent);
}

.back-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: "Ubuntu Mono", monospace;
    font-size: 13px;
    color: var(--text-dim);
    margin-bottom: 28px;
    transition: color 0.15s;
}

.back-link:hover {
    color: var(--accent);
}

/* -------------------------------------------------------------------- blog --*/

.blog-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 20px;
    margin-top: 40px;
}

.blog-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 28px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 12px;
    transition:
        transform 0.18s ease,
        box-shadow 0.18s ease,
        border-color 0.18s ease;
}

.blog-card:hover {
    transform: translateY(-2px);
    border-color: var(--border-strong);
    box-shadow: var(--lift-shadow);
}

.blog-card h2 {
    font-size: 19px;
    font-weight: 500;
    letter-spacing: -0.015em;
    max-width: none;
    margin: 0;
}

.blog-card p {
    font-size: 14.5px;
    color: var(--text-dim);
    line-height: 1.65;
    flex: 1;
}

.blog-card ul {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.blog-card li {
    position: relative;
    padding-left: 18px;
    font-size: 14px;
    color: var(--text-dim);
    line-height: 1.6;
}

.blog-card li::before {
    content: "✓";
    position: absolute;
    left: 0;
    font-size: 12px;
    color: var(--accent);
}

.blog-card code {
    font-family: "Ubuntu Mono", monospace;
    font-size: 12.5px;
    padding: 1px 6px;
    background: var(--bg-elev);
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--accent);
}

.blog-meta {
    display: flex;
    align-items: center;
    gap: 10px;
    font-family: "Ubuntu Mono", monospace;
    font-size: 12px;
    color: var(--text-mute);
}

.blog-tag {
    padding: 2px 8px;
    border: 1px solid var(--border);
    border-radius: 100px;
    color: var(--text-dim);
}

/* --------------------------------------------------------------- responsive --*/

@media (max-width: 900px) {
    /* Two columns rather than one: four stacked steps turn a four-line idea
       into most of a screen's scrolling. */
    .flow {
        grid-template-columns: repeat(2, 1fr);
        gap: 32px 24px;
    }
    .flow-step {
        padding: 0;
    }
    /* The rail would point off the side of the step, so it is dropped rather
       than re-drawn downward — and with it the whole marker row, whose only
       remaining content is a dot anchoring a rail that no longer exists. The
       step icon carries the visual on its own here. */
    .flow-marker {
        display: none;
    }
    .doc-card,
    .arch {
        padding: 24px;
    }
    .doc-page {
        padding: 40px 0 64px;
    }
}

/* Must follow the max-width:900 block, not sit with the other 560px rules
   further up the file: both queries match on a phone, so at equal specificity
   the later rule wins and an earlier one would be overridden back to two
   columns. */
@media (max-width: 560px) {
    /* Two columns leaves no room for the step descriptions. */
    .flow {
        grid-template-columns: 1fr;
        gap: 28px;
    }
}

/* ---------------------------------------------------------- reduced motion --
   Follows the precedent set for the word rotator: decoration stops, layout and
   hover affordances stay. */

/* ======== SCROLL REVEAL ======== */
/* Opt-in per element via [data-reveal]; index.js adds .is-visible when the
   element scrolls into view. The hidden state is applied by JS (a .reveal-ready
   class on <html>) rather than living here, so that with JS disabled — or
   before index.js runs — the content is simply visible. A CSS-only hidden
   state would leave the page blank for those readers. */
.reveal-ready [data-reveal] {
    opacity: 0;
    transform: translateY(16px);
}

.reveal-ready [data-reveal].is-visible {
    opacity: 1;
    transform: none;
    transition:
        opacity 0.4s ease,
        transform 0.4s ease;
}

@media (prefers-reduced-motion: reduce) {
    /* Belt and braces: index.js also skips the observer entirely under reduced
       motion, but if the preference changes after load this keeps content up. */
    .reveal-ready [data-reveal] {
        opacity: 1;
        transform: none;
        transition: none;
    }
    .flow-step .flow-marker::after {
        animation: none;
        opacity: 0;
    }
    .service-card,
    .blog-card {
        transition: none;
    }
    .service-card:hover,
    .blog-card:hover {
        transform: none;
    }
    html {
        scroll-behavior: auto;
    }
}
