/* ============================================================
   Raven landing — design tokens and faces
   Display: Space Grotesk (wordmark, headings, figures)
   Body:    IBM Plex Sans (prose, labels)
   Utility: IBM Plex Mono (code, tool names, JSON, metadata)
   ============================================================ */

/* Self-hosted latin subsets — no third-party request. Only the weights the page renders
   are declared: IBM Plex Mono ships one static instance per weight, IBM Plex Sans and
   Space Grotesk are variable, so both share one file and pin wght per declaration. */
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/IBMPlexMono-latin-400.woff2') format('woff2');
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/IBMPlexMono-latin-500.woff2') format('woff2');
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('fonts/IBMPlexMono-latin-600.woff2') format('woff2');
}

@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/IBMPlexSans-latin.woff2') format('woff2');
}

@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('fonts/IBMPlexSans-latin.woff2') format('woff2');
}

@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('fonts/IBMPlexSans-latin.woff2') format('woff2');
}

@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('fonts/SpaceGrotesk-latin.woff2') format('woff2');
}

:root {
    --bg: #0a0812;
    --bg-panel: #0d0a16;
    --bg-card: #161221;
    --bg-raised: #1a1226;

    --ink: #eceaf4;
    --ink-mute: #b4adc6;

    --violet: #8b5cf6;
    --violet-bright: #a78bfa;
    --violet-text: #c4b5fd;
    --violet-deep: #7c3aed;
    --fuchsia: #d946ef;
    --danger: #ff6b6b;

    --hairline: rgba(236, 234, 244, 0.08);
    --hairline-strong: rgba(236, 234, 244, 0.16);
    --violet-edge: rgba(139, 92, 246, 0.34);
    --violet-wash: rgba(139, 92, 246, 0.1);

    --shell: 1120px;
    --gut: 1.5rem;
    --radius: 6px;
    --bar: 56px;

    --font-display: 'Space Grotesk', ui-sans-serif, system-ui, 'Segoe UI', sans-serif;
    --font-body: 'IBM Plex Sans', ui-sans-serif, system-ui, 'Segoe UI', sans-serif;
    --font-mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, 'Courier New', monospace;

    /* One label size for every uppercase micro-text role: the old pair differed by 1px,
       which was small enough to read as sloppiness and large enough to fail AA at 11px. */
    --fs-label: 0.75rem;
    --fs-sm: 0.875rem;
    --fs-base: 1rem;
    --fs-lede: 1.0625rem;
    --fs-h3: 1.125rem;
    --fs-subhead: 1.3rem;
    --fs-h2: clamp(1.6rem, 2.4vw, 2.1rem);
    --fs-h1: clamp(2.9rem, 9vw, 5.4rem);
    --target: 24px;
}

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

html {
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--bar) + 1rem);
}

body {
    font-family: var(--font-body);
    font-size: var(--fs-base);
    line-height: 1.65;
    background: var(--bg);
    color: var(--ink);
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
}

body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    opacity: 0.025;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    background-repeat: repeat;
    background-size: 200px 200px;
}

/* ---------- focus: one rule, every interactive element ---------- */

:where(a, button, input, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--violet-text);
    outline-offset: 3px;
    border-radius: 2px;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 200;
    padding: 0.6rem 1rem;
    background: var(--violet-deep);
    color: #fff;
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    text-decoration: none;
}

.skip-link:focus {
    left: 0.5rem;
    top: 0.5rem;
}

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

/* ---------- shared type ---------- */

.eyebrow {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--violet-bright);
    display: flex;
    align-items: center;
    gap: 0.6em;
}

.eyebrow::before {
    content: "";
    width: 1.5em;
    height: 1px;
    background: var(--violet);
}

code,
kbd,
.mono {
    font-family: var(--font-mono);
    font-size: 0.92em;
    color: var(--violet-text);
}

a {
    color: var(--violet-text);
}

::selection {
    background: var(--violet);
    color: #fff;
}

/* ---------- navbar ---------- */

.navbar {
    position: sticky;
    top: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: var(--bar);
    padding: 0.6rem clamp(1rem, 4vw, 2rem);
    background: rgba(10, 8, 18, 0.92);
    border-bottom: 1px solid var(--hairline);
    backdrop-filter: blur(12px) saturate(180%);
    transition: background-color 0.3s ease, box-shadow 0.3s ease;
}

.navbar:hover {
    background: rgba(10, 8, 18, 0.95);
    box-shadow: 0 2px 16px rgba(0, 0, 0, 0.3);
}

.navbar > nav {
    min-width: 0;
}

.nav-brand {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    color: var(--ink);
    text-decoration: none;
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: 0.01em;
}

.nav-brand svg {
    display: block;
}

.nav-toggle {
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    border: 1px solid var(--hairline);
    border-radius: 8px;
    background: transparent;
    cursor: pointer;
}

.nav-toggle-bar {
    display: block;
    width: 16px;
    height: 1.5px;
    background: var(--ink-mute);
    transition: transform 0.22s ease, opacity 0.18s ease, background-color 0.18s ease;
}

.nav-toggle:hover .nav-toggle-bar {
    background: var(--violet-text);
}

.nav-links {
    display: flex;
    align-items: center;
    gap: clamp(0.75rem, 2.2vw, 1.6rem);
    list-style: none;
    overflow-x: auto;
    scrollbar-width: none;
}

.nav-links::-webkit-scrollbar {
    display: none;
}

.nav-links a {
    display: inline-block;
    color: var(--ink-mute);
    text-decoration: none;
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    letter-spacing: 0.02em;
    padding: 0.25rem 0;
    position: relative;
    white-space: nowrap;
    transition: color 0.18s;
}

.nav-links a::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 0;
    height: 1px;
    background: var(--violet);
    transition: width 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

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

.nav-links a:hover::after {
    width: 100%;
}

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

.hero {
    position: relative;
    padding: clamp(3.5rem, 8vh, 6rem) var(--gut) clamp(3rem, 6vh, 4.5rem);
    border-bottom: 1px solid var(--hairline);
    overflow: hidden;
}

.hero::before {
    content: "";
    position: absolute;
    top: 20%;
    left: 50%;
    transform: translateX(-50%);
    width: 80%;
    height: 60%;
    background: radial-gradient(ellipse, rgba(139, 92, 246, 0.12), transparent 70%);
    pointer-events: none;
    z-index: 0;
}

#hero-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    z-index: 0;
}

.hero-shell {
    position: relative;
    z-index: 1;
    max-width: var(--shell);
    margin: 0 auto;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    gap: clamp(2rem, 5vw, 4rem);
    align-items: center;
}

.hero h1 {
    font-family: var(--font-display);
    font-size: var(--fs-h1);
    font-weight: 700;
    line-height: 0.92;
    letter-spacing: -0.035em;
    background: linear-gradient(135deg, var(--ink) 0%, var(--ink) 40%, var(--violet-text) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    margin: 0.6rem 0 0.35rem;
    display: flex;
    align-items: baseline;
    gap: 0.12em;
}

.caret {
    display: inline-block;
    width: 0.09em;
    height: 0.78em;
    background: var(--fuchsia);
    transform: translateY(0.04em);
    animation: blink 1.1s steps(1, end) infinite;
}

@keyframes blink {
    0%, 49% { opacity: 1; }
    50%, 100% { opacity: 0; }
}

.hero-tagline {
    font-family: var(--font-mono);
    font-size: var(--fs-lede);
    color: var(--violet-text);
    letter-spacing: -0.01em;
    margin-bottom: 0.9rem;
}

/* Inline, not absolutely positioned against the paragraph box: the tagline wraps to two
   lines on a phone, and an anchored caret then lands on the right edge, away from the text. */
.hero-tagline::after {
    content: "";
    display: inline-block;
    width: 2px;
    height: 1.05em;
    margin-left: 0.35em;
    background: var(--fuchsia);
    vertical-align: -0.15em;
    animation: taglineBlink 1.2s ease-in-out infinite;
}

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

.hero-description {
    font-size: var(--fs-lede);
    color: var(--ink-mute);
    max-width: 46ch;
    margin-bottom: 1.6rem;
}

.hero-description strong {
    color: var(--ink);
    font-weight: 600;
}

.hero-actions {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.hero-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.1rem;
    margin-top: 1.6rem;
    padding-top: 1rem;
    border-top: 1px solid var(--hairline);
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    color: var(--ink-mute);
}

.hero-facts span::before {
    content: "· ";
    color: var(--violet);
}

/* ---------- buttons ---------- */

.btn-primary,
.btn-secondary {
    display: inline-block;
    padding: 0.62rem 1.3rem;
    border-radius: 4px;
    text-decoration: none;
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    font-weight: 500;
    letter-spacing: 0.01em;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background-color 0.18s, border-color 0.18s, color 0.18s;
}

.btn-primary {
    background: linear-gradient(135deg, var(--violet-deep), var(--violet));
    border-color: var(--violet);
    color: #fff;
    box-shadow: 0 2px 12px rgba(139, 92, 246, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.1);
    transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.btn-primary:hover {
    background: linear-gradient(135deg, var(--violet), var(--violet-bright));
    border-color: var(--violet-bright);
    box-shadow: 0 6px 24px rgba(139, 92, 246, 0.5), 0 0 0 1px var(--violet-bright), inset 0 1px 0 rgba(255, 255, 255, 0.15);
    transform: translateY(-2px);
}

.btn-secondary {
    background: transparent;
    border-color: var(--hairline-strong);
    color: var(--violet-text);
}

.btn-secondary:hover {
    background: var(--violet-wash);
    border-color: var(--violet);
}

/* ---------- sections ---------- */

.content-body {
    background: var(--bg);
    position: relative;
    z-index: 1;
}

.section {
    padding: clamp(3.5rem, 7vh, 5rem) var(--gut);
    border-bottom: 1px solid var(--hairline);
    scroll-margin-top: calc(var(--bar) + 1rem);
}

.section-inner {
    max-width: var(--shell);
    margin: 0 auto;
}

.section-head {
    margin-bottom: 2.2rem;
    max-width: 62ch;
}

.section h2 {
    font-family: var(--font-display);
    font-size: var(--fs-h2);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.15;
    background: linear-gradient(135deg, var(--ink) 0%, var(--ink) 60%, var(--ink-mute) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    margin: 0.45rem 0 0.5rem;
}

.section-desc {
    color: var(--ink-mute);
    font-size: var(--fs-lede);
}

.js .section-inner {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1), transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}

.js .section-inner.visible {
    opacity: 1;
    transform: none;
}

/* ---------- features grid ---------- */

.features-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
}

.feature-card {
    position: relative;
    background: linear-gradient(135deg, rgba(22, 18, 33, 0.6), rgba(13, 10, 22, 0.4));
    backdrop-filter: blur(12px);
    border: 1px solid var(--hairline);
    border-radius: 12px;
    padding: 1.5rem;
    overflow: hidden;
    transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), border-color 0.3s ease, box-shadow 0.3s ease;
}

.feature-card::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, rgba(139, 92, 246, 0.08), rgba(217, 70, 239, 0.04));
    opacity: 0;
    transition: opacity 0.3s ease;
}

.feature-card::after {
    content: "";
    position: absolute;
    inset: -1px;
    background: linear-gradient(135deg, var(--violet), var(--fuchsia), var(--violet));
    border-radius: 12px;
    opacity: 0;
    z-index: -1;
    transition: opacity 0.4s ease;
    background-size: 200% 200%;
    animation: gradientShift 3s ease infinite paused;
}

@keyframes gradientShift {
    0%, 100% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
}

.feature-card:hover {
    transform: translateY(-4px);
    border-color: var(--violet-edge);
    box-shadow: 0 8px 32px rgba(139, 92, 246, 0.15), 0 0 0 1px var(--violet-edge);
}

.feature-card:hover::before {
    opacity: 1;
}

.feature-card:hover::after {
    opacity: 0.4;
    animation-play-state: running;
}

.feature-card > * {
    position: relative;
    z-index: 1;
}

.feature-card p {
    font-size: var(--fs-sm);
    line-height: 1.65;
    color: var(--ink-mute);
    margin: 0;
}

/* ---------- tool registry ---------- */

.tool-toolbar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.75rem;
    align-items: start;
    margin-bottom: 1.25rem;
}

.search-input {
    width: 100%;
    padding: 0.6rem 0.85rem;
    background: var(--bg-panel);
    border: 1px solid var(--hairline-strong);
    border-radius: 4px;
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    transition: all 0.2s ease;
}

.search-input::placeholder {
    color: var(--ink-mute);
}

.search-input:focus {
    border-color: var(--violet);
    box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1), 0 2px 8px rgba(139, 92, 246, 0.15);
    outline: none;
}

.filter-buttons {
    display: flex;
    gap: 0.35rem;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.filter-btn {
    padding: 0.42rem 0.75rem;
    background: transparent;
    border: 1px solid var(--hairline);
    color: var(--ink-mute);
    border-radius: 3px;
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    letter-spacing: 0.02em;
    transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.filter-btn:hover {
    border-color: var(--violet-edge);
    color: var(--ink);
    transform: translateY(-1px);
    box-shadow: 0 2px 8px rgba(139, 92, 246, 0.15);
}

.filter-btn[aria-pressed="true"] {
    background: var(--violet-wash);
    border-color: var(--violet);
    color: var(--violet-text);
}

.registry-status {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    color: var(--ink-mute);
    margin-bottom: 0.9rem;
}

.tools-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
    gap: 0.75rem;
    list-style: none;
}

.tool-item {
    min-width: 0;
}

.tool-item .tool-card {
    height: 100%;
}

.tool-card {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    text-align: left;
    background: linear-gradient(135deg, rgba(22, 18, 33, 0.7), rgba(13, 10, 22, 0.5));
    backdrop-filter: blur(8px);
    border: 1px solid var(--hairline);
    border-radius: 8px;
    padding: 0.9rem;
    color: var(--ink);
    font: inherit;
    cursor: pointer;
    transition: all 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
    position: relative;
    overflow: hidden;
}

.tool-card::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, rgba(139, 92, 246, 0.06), rgba(217, 70, 239, 0.03));
    opacity: 0;
    transition: opacity 0.25s ease;
}

.tool-card:hover {
    transform: translateY(-2px);
    border-color: var(--violet-edge);
    background: linear-gradient(135deg, rgba(26, 18, 38, 0.8), rgba(13, 10, 22, 0.6));
    box-shadow: 0 4px 16px rgba(139, 92, 246, 0.12);
}

.tool-card:hover::before {
    opacity: 1;
}

.tool-card-built {
    border-color: var(--violet);
    background: var(--bg-raised);
}

.tool-card-header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.6rem;
}

.tool-name {
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: var(--fs-base);
    color: var(--violet-text);
    overflow-wrap: anywhere;
}

.tool-category-badge {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0.1rem 0.4rem;
    background: rgba(217, 70, 239, 0.12);
    border: 1px solid rgba(217, 70, 239, 0.3);
    color: var(--fuchsia);
    border-radius: 2px;
    white-space: nowrap;
}

.tool-desc {
    font-size: var(--fs-sm);
    line-height: 1.55;
    color: var(--ink-mute);
}

.tool-params {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: auto;
}

.param {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    padding: 0.1rem 0.4rem;
    background: rgba(236, 234, 244, 0.05);
    border: 1px solid var(--hairline);
    border-radius: 2px;
    color: var(--ink-mute);
}

.param-type {
    color: var(--fuchsia);
}

.param-required {
    border-color: var(--violet-edge);
    background: var(--violet-wash);
    color: var(--violet-text);
}

.param-none {
    border-style: dashed;
    background: transparent;
}

.card-hint {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-mute);
    opacity: 0;
    transition: opacity 0.18s;
}

.tool-card:hover .card-hint,
.tool-card:focus-visible .card-hint {
    opacity: 1;
}

.no-results {
    /* Sits after the grid, not in it: the empty state is not a tool, so it has no listitem. */
    margin-top: 0.75rem;
    border: 1px dashed var(--hairline-strong);
    border-radius: var(--radius);
    padding: 2rem;
    text-align: center;
    color: var(--ink-mute);
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
}

.no-results button {
    margin-left: 0.5rem;
    background: none;
    border: 0;
    border-bottom: 1px solid var(--violet);
    color: var(--violet-text);
    font: inherit;
    cursor: pointer;
    padding: 0;
}

/* ---------- protocol console ---------- */

.console {
    background: linear-gradient(135deg, rgba(13, 10, 22, 0.8), rgba(10, 8, 18, 0.6));
    backdrop-filter: blur(12px);
    border: 1px solid var(--violet-edge);
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 0 24px rgba(139, 92, 246, 0.08), 0 0 0 1px rgba(139, 92, 246, 0.05);
    transition: box-shadow 0.3s ease, border-color 0.3s ease;
}

.console:hover {
    box-shadow: 0 0 32px rgba(139, 92, 246, 0.15), 0 0 0 1px rgba(139, 92, 246, 0.1);
    border-color: var(--violet);
}

.console-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding: 0.5rem 0.9rem;
    background: var(--violet-wash);
    border-bottom: 1px solid var(--violet-edge);
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    color: var(--violet-text);
    letter-spacing: 0.02em;
}

.console-meta {
    color: var(--ink-mute);
    white-space: nowrap;
}

.console-body {
    padding: 0.9rem;
    min-height: 168px;
    max-height: 420px;
    overflow-y: auto;
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    line-height: 1.6;
    scrollbar-width: thin;
}

.console-body:focus-visible {
    outline-offset: -3px;
}

.console-line {
    white-space: pre-wrap;
    word-break: break-word;
}

.console-line + .console-line {
    margin-top: 0.3rem;
}

.line-request {
    color: var(--violet-text);
}

.line-response {
    color: var(--ink);
}

.line-system {
    color: var(--fuchsia);
}

.line-error {
    color: var(--danger);
}

.line-key {
    color: var(--ink-mute);
}

.console-input {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.55rem 0.9rem;
    border-top: 1px solid var(--hairline);
    background: var(--bg-card);
}

.prompt {
    /* --violet measured 4.34:1 on the input bar, under the 4.5:1 floor at this size. */
    color: var(--violet-text);
    font-family: var(--font-mono);
    font-weight: 600;
    line-height: 1.65;
}

.console-input textarea {
    flex: 1;
    min-height: 2.6rem;
    resize: vertical;
    background: transparent;
    border: none;
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    line-height: 1.6;
}

.console-input textarea::placeholder {
    color: var(--ink-mute);
}

.console-actions {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    align-items: center;
    margin-top: 0.9rem;
}

.ghost-btn {
    padding: 0.35rem 0.7rem;
    background: var(--bg-card);
    border: 1px solid var(--hairline-strong);
    color: var(--violet-text);
    border-radius: 3px;
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
    position: relative;
    overflow: hidden;
}

.ghost-btn::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, rgba(139, 92, 246, 0.1), rgba(217, 70, 239, 0.05));
    opacity: 0;
    transition: opacity 0.2s ease;
}

.ghost-btn:hover {
    background: var(--violet-wash);
    border-color: var(--violet);
    transform: translateY(-1px);
    box-shadow: 0 2px 8px rgba(139, 92, 246, 0.2);
}

.ghost-btn:hover::before {
    opacity: 1;
}

.console-note {
    font-size: var(--fs-sm);
    color: var(--ink-mute);
    margin-top: 0.9rem;
    max-width: 74ch;
}

/* ---------- architecture ---------- */

.arch-stack {
    display: grid;
    gap: 0;
}

.arch-layer {
    background: linear-gradient(135deg, rgba(22, 18, 33, 0.7), rgba(13, 10, 22, 0.5));
    backdrop-filter: blur(8px);
    border: 1px solid var(--hairline);
    border-left: 2px solid transparent;
    border-radius: 8px;
    padding: 1.2rem;
    transition: border-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}

.arch-layer:hover {
    border-color: var(--violet-edge);
    border-left-color: var(--violet);
    box-shadow: 0 4px 20px rgba(139, 92, 246, 0.1);
    transform: translateX(4px);
}

.arch-items {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.arch-item {
    padding: 0.32rem 0.65rem;
    background: var(--violet-wash);
    border: 1px solid var(--violet-edge);
    border-radius: 3px;
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    color: var(--ink);
}

.arch-connector {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.55rem 0 0.55rem 1.6rem;
}

.arch-connector::before {
    content: "";
    position: relative;
    top: -0.55rem;
    width: 1px;
    height: 100%;
    min-height: 1.4rem;
    background: var(--violet-edge);
}

.connector-label {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    color: var(--violet-text);
    padding: 0.25rem 0.6rem;
    border: 1px dashed var(--violet-edge);
    border-radius: 3px;
    background: var(--bg);
}

/* ---------- front doors ---------- */

.doors-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
}

.door {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 1.1rem;
    background: linear-gradient(135deg, rgba(22, 18, 33, 0.7), rgba(13, 10, 22, 0.5));
    border: 1px solid var(--hairline);
    border-top: 2px solid var(--violet-edge);
    border-radius: 8px;
}

.door p {
    font-size: var(--fs-sm);
    color: var(--ink-mute);
}

.door .codeblock {
    margin: 0;
}

.door-meta {
    margin-top: auto;
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    color: var(--ink-mute);
}

/* ---------- refusals ---------- */

.rules {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 2.5rem;
    list-style: none;
}

.rule {
    position: relative;
    padding: 1.1rem 0 1.1rem 1.5rem;
    border-top: 1px solid var(--hairline);
}

.rule::before {
    content: "×";
    position: absolute;
    left: 0;
    top: 1.05rem;
    font-family: var(--font-mono);
    color: var(--violet);
}

.rule p {
    font-size: var(--fs-sm);
    line-height: 1.6;
    color: var(--ink-mute);
}

/* ---------- spec sheet + endpoints ---------- */

.spec-sheet {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
    gap: 0 1.5rem;
    border-top: 1px solid var(--hairline);
}

.spec-item {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--hairline);
}

.spec-term {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-mute);
}

.spec-value {
    font-family: var(--font-display);
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--violet-text);
    text-align: right;
}

.spec-value-small {
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    font-weight: 500;
    color: var(--ink);
}

.spec-note {
    margin: 0 0 2.5rem;
    font-size: var(--fs-sm);
    color: var(--ink-mute);
    padding: 0.75rem 0 0;
}

.section h3 {
    font-family: var(--font-display);
    font-size: var(--fs-h3);
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.3;
    color: var(--ink);
    margin-bottom: 0.7rem;
}

.section-inner > h3 {
    /* A heading that opens a block of its own, rather than sitting inside a card or a step.
       It has to out-rank the step headings below it, which share the same element. */
    margin-top: 2.6rem;
    font-size: var(--fs-subhead);
    color: var(--violet-text);
}

.section-inner > .step-note {
    margin-bottom: 1.8rem;
}

.table-wrap {
    overflow-x: auto;
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
}

table {
    width: 100%;
    border-collapse: collapse;
    min-width: 520px;
}

caption {
    text-align: left;
    padding: 0.75rem 1rem;
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-mute);
    border-bottom: 1px solid var(--hairline);
}

th,
td {
    padding: 0.6rem 1rem;
    text-align: left;
    border-bottom: 1px solid var(--hairline);
    font-size: var(--fs-sm);
    vertical-align: top;
}

thead th {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-mute);
    background: var(--bg-panel);
}

tbody tr:last-child th,
tbody tr:last-child td {
    border-bottom: 0;
}

tbody th {
    font-family: var(--font-body);
    font-weight: 500;
    color: var(--ink);
    white-space: nowrap;
}

tbody td {
    font-family: var(--font-mono);
    color: var(--violet-text);
    overflow-wrap: anywhere;
}

tbody tr:hover th,
tbody tr:hover td {
    background: var(--bg-card);
}

/* ---------- setup ---------- */

.install-steps {
    display: grid;
    gap: 1.75rem;
    max-width: 760px;
    margin-bottom: 2.2rem;
}

.step {
    display: grid;
    grid-template-columns: 2rem minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

.step-number {
    width: 2rem;
    height: 2rem;
    display: grid;
    place-items: center;
    border: 1px solid var(--violet);
    border-radius: 50%;
    color: var(--violet-text);
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    font-weight: 500;
}

.step-content p {
    color: var(--ink-mute);
    font-size: var(--fs-sm);
    max-width: 60ch;
}

.codeblock {
    /* Toolbar strip above the code: an absolutely positioned Copy button sat on top of the
       first command, which the narrow door cards made impossible to read. */
    display: flex;
    flex-direction: column;
    background: var(--bg-panel);
    border: 1px solid var(--violet-edge);
    border-left: 2px solid var(--violet);
    border-radius: 4px;
    margin: 0 0 0.6rem;
}

.codebar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 0.25rem 0.3rem 0.25rem 0.6rem;
    border-bottom: 1px solid var(--violet-edge);
    background: rgb(139 92 246 / 5%);
}

.code-lang {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    letter-spacing: 0.06em;
    color: var(--ink-mute);
}

.codeblock pre {
    padding: 0.7rem 0.9rem;
    overflow-x: auto;
    margin: 0;
    background: transparent;
    border: 0;
}

.codeblock code {
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    line-height: 1.6;
    color: var(--ink);
    white-space: pre-wrap;
    overflow-wrap: break-word;
}

.copy-btn {
    min-height: calc(var(--target) + 2px);
    padding: 0.2rem 0.6rem;
    background: var(--bg-card);
    border: 1px solid var(--hairline-strong);
    border-radius: 3px;
    color: var(--ink-mute);
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.copy-btn:hover,
.copy-btn.copied {
    color: var(--violet-text);
    border-color: var(--violet);
    transform: scale(1.05);
    box-shadow: 0 2px 8px rgba(139, 92, 246, 0.2);
}

.step-note {
    font-size: var(--fs-label);
    color: var(--ink-mute);
}

.cta-links {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
}

/* ---------- footer ---------- */

footer {
    position: relative;
    z-index: 1;
    padding: 2.75rem var(--gut) 2.5rem;
    background: var(--bg);
    border-top: 1px solid var(--hairline);
    font-size: var(--fs-sm);
    color: var(--ink-mute);
}

.footer-shell {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
    gap: 1.75rem 1.5rem;
    max-width: var(--shell);
    margin: 0 auto;
}

.footer-col {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    min-width: 0;
}

.footer-wordmark {
    font-family: var(--font-display);
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--ink);
}

.footer-title {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--violet-bright);
    margin-bottom: 0.3rem;
}

.footer-fine {
    font-family: var(--font-mono);
    font-size: var(--fs-label);
}

.footer-links {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    list-style: none;
}

.footer-links a {
    /* Inline links measured 15px tall; padding to the 24px minimum keeps the underline
       glued to the text, which an absolutely positioned rule could not do once padded.
       The short labels ("Bot", "Source") also need the minimum width, not just height. */
    display: inline-block;
    min-width: var(--target);
    padding: 0.3rem 0.05rem;
    color: var(--ink-mute);
    text-decoration: none;
    transition: color 0.18s;
}

.footer-links a:hover,
.footer-links a:focus-visible {
    color: var(--violet-text);
    text-decoration: underline;
    text-underline-offset: 0.25em;
}

/* ---------- scrollbars ---------- */

::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: var(--bg);
}

::-webkit-scrollbar-thumb {
    background: var(--violet-edge);
    border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--violet);
}

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

@media (max-width: 900px) {
    /* Eight links cannot fit beside the brand at this width. Kept on one nowrap line they
       scrolled, and since the scrollbar is suppressed the last link disappeared with nothing
       to indicate it existed; wrapped, they stacked rows of links over the hero. With JS the
       links move into a panel the toggle opens. Without JS the wrapped list is what keeps
       every link reachable. */
    .nav-links {
        flex-wrap: wrap;
        justify-content: flex-end;
        row-gap: 0.4rem;
        overflow-x: visible;
    }

    .js .nav-toggle {
        display: flex;
    }

    .js .navbar > nav {
        position: absolute;
        top: 100%;
        right: 0;
        left: 0;
        display: none;
        padding: 0.25rem clamp(1rem, 4vw, 2rem) 0.5rem;
        background: var(--bg);
        border-bottom: 1px solid var(--hairline);
        box-shadow: 0 18px 32px -16px rgba(0, 0, 0, 0.85);
    }

    .js .navbar.nav-open > nav {
        display: block;
    }

    .js .nav-links {
        flex-direction: column;
        flex-wrap: nowrap;
        align-items: stretch;
        justify-content: flex-start;
        gap: 0;
    }

    .js .nav-links li + li {
        border-top: 1px solid var(--hairline);
    }

    .js .nav-links a {
        display: block;
        padding: 0.8rem 0;
    }

    .js .nav-open .nav-toggle-bar:nth-child(1) {
        transform: translateY(6.5px) rotate(45deg);
    }

    .js .nav-open .nav-toggle-bar:nth-child(2) {
        opacity: 0;
    }

    .js .nav-open .nav-toggle-bar:nth-child(3) {
        transform: translateY(-6.5px) rotate(-45deg);
    }

    .js .nav-open .nav-toggle-bar {
        background: var(--violet-text);
    }

    .hero-shell {
        grid-template-columns: 1fr;
        gap: 2rem;
    }

    .hero-description {
        max-width: 60ch;
    }

    .features-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .doors-grid,
    .rules {
        grid-template-columns: 1fr;
    }

    .tool-toolbar {
        grid-template-columns: 1fr;
    }

    .filter-buttons {
        justify-content: flex-start;
    }

    /* Console in hero: shrink on tablet so text gets room */
    .hero .console {
        max-height: 280px;
    }

    .hero .console-body {
        max-height: 200px;
        font-size: var(--fs-label);
    }
}

@media (max-width: 640px) {
    :root {
        --gut: 1rem;
    }

    .hero {
        padding: 2rem var(--gut) 1.5rem;
    }

    /* The recorded handshake is the page's only proof that the protocol claims are real,
       and hiding it here meant a phone visitor never saw it. Capped and scrollable instead. */
    .hero .console {
        margin-top: 0.5rem;
    }

    .hero .console-body {
        min-height: 0;
        max-height: 180px;
    }

    .section {
        padding: 2.5rem var(--gut);
    }

    .section-head {
        margin-bottom: 1.5rem;
    }

    .features-grid {
        grid-template-columns: 1fr;
        gap: 0.75rem;
    }

    .footer-shell {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .feature-card {
        padding: 1.1rem;
    }

    .arch-layer {
        padding: 1rem;
    }

    .arch-items {
        gap: 0.3rem;
    }

    .arch-item {
        font-size: var(--fs-label);
        padding: 0.25rem 0.5rem;
    }

    .spec-sheet {
        grid-template-columns: 1fr;
    }

    .spec-item {
        padding: 0.6rem 0;
    }

    .spec-value {
        font-size: 1.1rem;
    }

    .table-wrap {
        font-size: var(--fs-label);
    }

    th, td {
        padding: 0.5rem 0.6rem;
    }

    .install-steps {
        gap: 1.25rem;
    }

    .codeblock pre {
        padding: 0.6rem 0.7rem;
    }

    .codeblock code {
        /* Commands wrap instead of shrinking to 12px: unreadable mono was worse than a second line. */
        font-size: var(--fs-sm);
    }

    .console-body {
        font-size: var(--fs-label);
        padding: 0.7rem;
    }

    .console-input {
        padding: 0.5rem 0.7rem;
    }

    .console-actions {
        gap: 0.3rem;
    }

    .ghost-btn {
        padding: 0.3rem 0.55rem;
        min-height: var(--target);
        font-size: var(--fs-label);
    }

    .cta-links {
        flex-direction: column;
        align-items: stretch;
    }

    .cta-links .btn-primary,
    .cta-links .btn-secondary {
        text-align: center;
    }
}

@media (max-width: 560px) {
    .hero {
        padding-top: 2.5rem;
    }

    .hero-actions {
        flex-direction: column;
        align-items: stretch;
    }

    .hero-actions .btn-primary,
    .hero-actions .btn-secondary {
        text-align: center;
    }

    .tools-grid {
        grid-template-columns: 1fr;
    }

    /* The inbound matrix is 15 rows of prose and code chips; at 356px the 520px min-width turned
       the wrap into a sideways scroller that gave no hint it scrolled. Each row becomes a
       labelled block: the row header is already the label, so the column headers go. */
    table {
        min-width: 0;
    }

    .table-wrap {
        border: 0;
        overflow: visible;
    }

    caption {
        border: 1px solid var(--hairline);
        border-radius: var(--radius);
        margin-bottom: 0.6rem;
    }

    thead {
        display: none;
    }

    tbody tr {
        display: block;
        border: 1px solid var(--hairline);
        border-radius: var(--radius);
        margin-bottom: 0.5rem;
    }

    tbody th,
    tbody td {
        display: block;
        border-bottom: 0;
        padding: 0.45rem 0.7rem;
        white-space: normal;
    }

    tbody th {
        border-bottom: 1px solid var(--hairline);
        font-family: var(--font-mono);
        font-size: var(--fs-label);
        letter-spacing: 0.08em;
        text-transform: uppercase;
        color: var(--ink-mute);
    }

    tbody tr:hover th,
    tbody tr:hover td {
        background: transparent;
    }

    .step {
        grid-template-columns: 1.6rem minmax(0, 1fr);
        gap: 0.7rem;
    }

    .step-number {
        width: 1.6rem;
        height: 1.6rem;
        font-size: var(--fs-label);
    }

    .footer-shell {
        grid-template-columns: 1fr;
    }

    footer {
        padding-inline: 1rem;
    }
}

/* ---------- motion preferences ---------- */

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }

    .js .section-inner {
        opacity: 1;
        transform: none;
    }

    .caret {
        animation: none;
        opacity: 1;
    }
}
