/* GTFS.Guru Styles */
:root {
    /* The original Slate palette, kept. What was decorative slop here was the
       orbs, the grid overlay and the gradient headline drawn on top of it, not
       the colours themselves. The one structural change is that these are now
       flat fills: the surfaces below are opaque, so panels no longer stack
       translucent layers over one another. */
    --bg-dark: #020617;
    /* Slate 950 */
    --bg-elevated: #070f22;
    --surface: #111c33;
    --surface-raised: #1a2745;
    --bg-card: #111c33;
    --border: #24334f;
    --border-strong: #3a4a69;

    --text-primary: #f8fafc;
    --text-secondary: #94a3b8;

    --accent-primary: #38bdf8;
    /* Sky 400 */
    --accent-secondary: #818cf8;
    /* Indigo 400 */
    --accent-tint: rgba(56, 189, 248, 0.1);
    --accent-tint-strong: rgba(56, 189, 248, 0.2);
    --accent-glow: rgba(56, 189, 248, 0.5);

    --success: #4ade80;
    --error: #f87171;
    --warning: #fbbf24;
    --info: #60a5fa;

    /* Two radii, no more: controls take sm, panels take md. */
    --radius-sm: 6px;
    --radius-md: 10px;

    --font-heading: 'Inter', system-ui, sans-serif;
    --font-body: 'Inter', system-ui, sans-serif;
    --font-mono: 'Fira Code', ui-monospace, monospace;
}

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

body {
    /* The two blurred orbs used to wash the top of the page in blue and
       indigo; that ambient colour was the only thing keeping the page from
       reading as grey text on near-black. This does the same job honestly:
       one linear stop, no circles, no blur, no animation, painted once on the
       body layer instead of forcing a full repaint above a z-index:-1 element. */
    background-color: var(--bg-dark);
    background-image: linear-gradient(158deg, #14213f 0, #0a1026 45%, var(--bg-dark) 75%);
    background-repeat: no-repeat;
    /* Constrained to the first screenful. Percentage stops on body resolve
       against the whole document height, so without this the wash would still
       be tinting the footer 5000px down. */
    background-size: 100% 1100px;
    /* So the grid layer below resolves its height against the document rather
       than the viewport. Does not affect position:fixed descendants. */
    position: relative;
    color: var(--text-primary);
    font-family: var(--font-body);
    line-height: 1.6;
    overflow-x: hidden;
}
/* The 40px grid, on a pseudo-element instead of a <div> repeated in 16 files.
   It covers the first screenful and is masked out below it, rather than tiling
   the whole page: a uniform full-bleed techno-grid is the part that reads as
   stock, the texture near the headline is the part that reads as an
   instrument. Absolute rather than fixed on purpose -- a viewport-anchored
   layer would fade at the bottom of every screenful instead of once. */
body::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    /* Never taller than the document, or the layer would add scroll height of
       its own on the short pages (privacy, terms, contact). */
    height: min(1500px, 100%);
    z-index: -1;
    pointer-events: none;
    background-image:
        linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px);
    background-size: 40px 40px;
    -webkit-mask-image: linear-gradient(180deg, #000 0, #000 40%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 0, #000 40%, transparent 100%);
}


/* Typography */
h1,
h2,
h3,
.logo-text {
    font-family: var(--font-heading);
    font-weight: 700;
    /* Inter needs negative tracking at display sizes or it reads loose. */
    letter-spacing: -0.02em;
}

h2 {
    letter-spacing: -0.015em;
}

h3 {
    letter-spacing: -0.01em;
}

a {
    text-decoration: none;
    color: inherit;
    transition: color 0.15s ease;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    /* 2rem each side costs 64px of a 375px screen; taper it on small viewports. */
    padding: 0 clamp(1.25rem, 4vw, 2rem);
}

.highlight {
    color: var(--accent-primary);
}

/* Emphasis inside a headline. Was a sky-to-purple gradient clip; one flat
   accent does the same job without the gradient. */
.gradient-text {
    color: var(--accent-primary);
}

/* Navigation */
.glass-nav {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    /* The one place blur is kept (and its mobile dropdown below). It is
       functional here: content scrolls under a fixed bar and needs separating
       from it. Every decorative blur elsewhere is gone. */
    background: rgba(2, 6, 23, 0.8);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--border);
    z-index: 100;
    padding: 0.8rem 0;
}

.nav-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.logo {
    display: flex;
    align-items: center;
}

.logo-text {
    font-size: 1.5rem;
    letter-spacing: -0.02em;
}

.nav-links {
    display: flex;
    align-items: center;
    /* Five items now that the reference pages sit under one Documentation
       entry; the earlier eight shrank and wrapped inside themselves at 1024px. */
    gap: clamp(1rem, 1.9vw, 2rem);
}

/* --- Documentation dropdown ---------------------------------------------
   A <details> rather than a scripted menu: focusable, toggles on Enter/Space
   and still opens with JavaScript off. */
.nav-dropdown {
    position: relative;
}

.nav-dropdown > summary {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    color: var(--text-secondary);
    font-weight: 500;
    font-size: 0.95rem;
    white-space: nowrap;
    cursor: pointer;
    list-style: none;
}

.nav-dropdown > summary::-webkit-details-marker {
    display: none;
}

.nav-dropdown > summary::after {
    content: "";
    width: 0.4rem;
    height: 0.4rem;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
}

.nav-dropdown[open] > summary::after {
    transform: translateY(1px) rotate(225deg);
}

.nav-dropdown > summary:hover,
.nav-dropdown[open] > summary {
    color: var(--text-primary);
}

.nav-dropdown-panel {
    position: absolute;
    top: calc(100% + 0.6rem);
    left: 0;
    min-width: 12rem;
    display: flex;
    flex-direction: column;
    padding: 0.4rem 0;
    /* Fully opaque: the bar's own blur pulls the hero's accent colours
       through anything translucent and the labels lose contrast. */
    background: #0b1220;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45);
    z-index: 20;
}

.nav-dropdown-panel a {
    padding: 0.5rem 0.9rem;
}

.nav-dropdown-panel a:hover {
    background: rgba(255, 255, 255, 0.06);
}

.nav-links a {
    color: var(--text-secondary);
    font-weight: 500;
    font-size: 0.95rem;
    white-space: nowrap;
}

.logo-text {
    white-space: nowrap;
}

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

.nav-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

/* Hidden on desktop; the mobile block below turns it on. 44px = min touch target. */
.nav-toggle {
    display: none;
    width: 44px;
    height: 44px;
    padding: 0;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    cursor: pointer;
    transition: background-color 0.2s, border-color 0.2s;
}

.nav-toggle:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: var(--border-strong);
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.6rem 1.2rem;
    border-radius: var(--radius-sm);
    font-weight: 600;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
    cursor: pointer;
    border: none;
    font-family: var(--font-body);
}

.btn-primary {
    background: var(--text-primary);
    color: var(--bg-dark);
}

.btn-primary:hover {
    background: #fff;
}

.btn:active {
    transform: translateY(1px);
}

/* There was no disabled style at all: "Compare feeds" sits disabled until two
   files are picked and looked fully live the whole time. */
.btn:disabled,
.btn[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
}

.btn:disabled:hover,
.btn[disabled]:hover {
    background: inherit;
}

.btn:disabled:active,
.btn[disabled]:active {
    transform: none;
}

.btn-secondary {
    background: var(--surface-raised);
    color: var(--text-primary);
    border: 1px solid var(--border-strong);
}

.btn-secondary:hover {
    background: #1c2942;
    border-color: #475569;
}

.btn-outline {
    background: transparent;
    border: 1px solid var(--border-strong);
    color: var(--text-secondary);
}

.btn-outline:hover {
    border-color: var(--text-primary);
    color: var(--text-primary);
}

.btn-lg {
    padding: 0.8rem 1.5rem;
    font-size: 1.05rem;
}

.btn-sm {
    padding: 0.4rem 0.8rem;
    font-size: 0.85rem;
}

.btn-block {
    display: flex;
    width: 100%;
}

.btn-link {
    background: none;
    border: none;
    color: var(--text-secondary);
    text-decoration: underline;
    font-size: 0.9rem;
    margin-top: 1rem;
}

.width-full {
    width: 100%;
}

/* Hero Section */
.hero-section {
    padding-top: 96px;
    padding-bottom: 72px;
    position: relative;
}

/* One column, with the validator running full width below the copy rather
   than squeezed into a 50/50 split beside it. The validator is the product,
   not an illustration of it, and at half width its notice list, MCP preview
   and result actions all had to wrap. */
.hero-container {
    display: grid;
    grid-template-columns: 1fr;
    gap: 3rem;
    text-align: center;
}

.hero-sub {
    margin-left: auto;
    margin-right: auto;
}

.badge-row,
.hero-actions,
.stats-row {
    justify-content: center;
}

.hero-visual {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2.5rem;
}

.hero-container > *,
.tech-grid > * {
    min-width: 0;
}

.badge-row {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
}

.badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0.25rem 0.75rem;
    background: var(--accent-tint);
    color: var(--accent-primary);
    border: 1px solid var(--accent-tint-strong);
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 500;
}

.ml-2 {
    margin-left: 0.5rem;
}

h1 {
    /* Fluid: at 375px this resolves to 2rem, which keeps the longest line
       ("Ensure your transit") inside the content box instead of being clipped
       by body{overflow-x:hidden}. Desktop is unchanged at 3.5rem. */
    font-size: clamp(2rem, 6vw, 3.5rem);
    line-height: 1.1;
    margin-bottom: 1rem;
    overflow-wrap: break-word;
    text-wrap: balance;
}

.hero-sub {
    font-size: 1.15rem;
    color: var(--text-secondary);
    margin-bottom: 2rem;
    max-width: 620px;
}

.hero-actions {
    display: flex;
    gap: 1rem;
    /* The stats row used to follow here and needed the air. The validator card
       follows now, and the hero grid already puts 3rem between them. */
    margin-bottom: 0;
    flex-wrap: wrap;
}

/* Below the validator, not above it. These numbers are context for a reader
   who has already seen what the tool does; in front of the file picker they
   were a paragraph of stats between the promise and the product. */
.stats-row {
    display: flex;
    gap: clamp(1.5rem, 5vw, 4rem);
    flex-wrap: wrap;
    padding-top: 2rem;
    border-top: 1px solid var(--border);
    width: 100%;
    max-width: 940px;
}

.stat-item {
    text-align: left;
}

.stat-number {
    font-size: 2rem;
    font-weight: 700;
    color: var(--text-primary);
    font-family: var(--font-mono);
    letter-spacing: -0.03em;
}

.stat-suffix {
    font-size: 1.5rem;
    font-family: var(--font-mono);
    color: var(--accent-primary);
}

.stat-prefix {
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.stat-label {
    display: block;
    font-size: 0.85rem;
    color: var(--text-secondary);
    margin-top: -5px;
}

/* The rule count links through to the reference that explains the two
   numbers: 110 checks, which between them emit 191 distinct notice codes. */
.stat-label a {
    color: inherit;
    text-decoration: underline;
    text-decoration-color: var(--border-strong);
    text-underline-offset: 3px;
}

.stat-label a:hover {
    color: var(--text-primary);
    text-decoration-color: var(--accent-primary);
}

/* Panel. Named .glass-card for history; there is no glass left in it.
   Opaque fill plus a hairline border, which is all the separation a panel on
   a flat background needs. */
.glass-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

/* Validator UI */
.validator-ui {
    width: 100%;
    max-width: 940px;
    min-height: 380px;
    /* The hero centres its copy; the panel is a UI and stays left-aligned. */
    text-align: left;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.validator-header {
    background: rgba(255, 255, 255, 0.03);
    padding: 0.8rem 1.2rem;
    display: flex;
    align-items: center;
    border-bottom: 1px solid var(--border);
    justify-content: space-between;
}

.window-title {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text-secondary);
}

.secure-badge {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 0.75rem;
    color: var(--success);
    background: rgba(74, 222, 128, 0.1);
    padding: 2px 8px;
    border-radius: var(--radius-md);
}

.validator-body {
    flex-grow: 1;
    padding: 2rem;
    display: flex;
    flex-direction: column;
}

.validator-mode-switch {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px;
    margin-bottom: 1rem;
    padding: 4px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: rgba(0, 0, 0, 0.16);
}

.validator-mode {
    border: 0;
    border-radius: var(--radius-sm);
    padding: 0.55rem 0.8rem;
    color: var(--text-secondary);
    background: transparent;
    font: inherit;
    font-size: 0.84rem;
    font-weight: 650;
    cursor: pointer;
}

.validator-mode.active {
    color: var(--text-primary);
    background: rgba(255, 255, 255, 0.09);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.24);
}

.upload-state {
    flex-grow: 1;
    border: 2px dashed var(--border-strong);
    border-radius: var(--radius-md);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    transition: all 0.3s;
    cursor: pointer;
    min-height: 260px;
}

.diff-inputs {
    padding-top: 0.35rem;
}

.diff-intro {
    margin: 0 0 1rem;
    color: var(--text-secondary);
    font-size: 0.88rem;
    line-height: 1.5;
}

.diff-source-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
}

.diff-source-picker {
    min-width: 0;
    padding: 1rem;
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    background: rgba(255, 255, 255, 0.025);
    text-align: left;
    cursor: pointer;
    transition: border-color 160ms ease, background 160ms ease;
}

.diff-source-picker:hover,
.diff-source-picker.ready {
    border-color: var(--accent-primary);
    background: rgba(255, 255, 255, 0.05);
}

.diff-source-picker span,
.diff-source-picker strong {
    display: block;
}

.diff-source-picker strong {
    margin: 0.45rem 0 0.25rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.9rem;
}

.diff-source-picker > span:last-child {
    color: var(--text-secondary);
    font-size: 0.76rem;
}

.diff-source-label,
.diff-eyebrow {
    color: var(--accent-primary);
    font-size: 0.7rem;
    font-weight: 750;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.diff-run-btn {
    width: 100%;
    justify-content: center;
    margin-top: 1rem;
}

.diff-limit-note {
    margin: 0.65rem 0 0;
    text-align: center;
    font-size: 0.75rem;
}

.upload-state:hover {
    border-color: var(--accent-primary);
    background: rgba(255, 255, 255, 0.02);
}

/* Keyboard focus lands on the button inside, so the whole zone lights up with
   it — otherwise the focus ring reads as belonging to nothing in particular. */
.upload-state:focus-within {
    border-color: var(--accent-primary);
    background: rgba(255, 255, 255, 0.03);
}

.upload-icon {
    width: 48px;
    height: 48px;
    color: var(--text-secondary);
    margin-bottom: 1rem;
}

.upload-state h3 {
    margin-bottom: 0.75rem;
}

.upload-limit-note {
    margin: 0.85rem 1rem 0;
    max-width: 34ch;
    text-align: center;
    font-size: 0.78rem;
    line-height: 1.45;
}

.upload-limit-note a {
    color: var(--accent-primary);
}

/* --- URL input ----------------------------------------------------------
   The placeholder used to be the only thing naming this field, so it vanished
   the moment anyone typed. */
.url-input-container {
    margin-top: 1.25rem;
    text-align: left;
}

.url-label {
    display: block;
    margin-bottom: 0.4rem;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-secondary);
}

.url-input-row {
    display: flex;
    gap: 8px;
}

#url-input {
    flex-grow: 1;
    min-width: 0;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border-strong);
    border-radius: 8px;
    padding: 0.6rem 1rem;
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 0.9rem;
}

#url-analyze-btn {
    padding: 0.6rem 1rem;
    white-space: nowrap;
}

.url-hint {
    margin: 0.5rem 0 0;
    font-size: 0.76rem;
    line-height: 1.5;
}

.url-hint a {
    color: var(--accent-primary);
}

.sub-text {
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.processing-state {
    text-align: center;
    padding: 3rem 0;
}

.spinner {
    width: 40px;
    height: 40px;
    border: 3px solid var(--border);
    border-radius: 50%;
    border-top-color: var(--accent-primary);
    animation: spin 1s linear infinite;
    margin: 0 auto 1rem;
}

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

/* Results */
.result-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
}

.diff-result-state {
    width: 100%;
}

.diff-result-heading {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

.diff-result-heading h3 {
    margin: 0.2rem 0 0;
}

.diff-time {
    color: var(--text-secondary);
    font-size: 0.75rem;
    white-space: nowrap;
}

.diff-headline,
.diff-metrics {
    display: grid;
    gap: 0.6rem;
}

.diff-headline {
    grid-template-columns: 1fr 1fr;
    margin-bottom: 0.7rem;
}

.diff-metrics {
    grid-template-columns: repeat(3, 1fr);
    margin-bottom: 0.9rem;
}

.diff-headline > div,
.diff-metric {
    padding: 0.75rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.035);
}

.diff-headline strong,
.diff-metric strong {
    display: block;
    font-size: 1.25rem;
}

.diff-headline span,
.diff-metric span {
    color: var(--text-secondary);
    font-size: 0.75rem;
}

.diff-headline .introduced strong {
    color: var(--error);
}

.diff-headline .resolved strong {
    color: var(--success);
}

.diff-section {
    border-top: 1px solid var(--border);
}

.diff-section summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 0;
    cursor: pointer;
    font-size: 0.86rem;
    font-weight: 650;
    list-style: none;
}

.diff-section summary::-webkit-details-marker {
    display: none;
}

.diff-section summary span {
    color: var(--text-secondary);
    font-size: 0.75rem;
    font-weight: 500;
}

.diff-list {
    display: grid;
    gap: 0.35rem;
    max-height: 190px;
    margin: 0 0 0.85rem;
    padding: 0;
    overflow: auto;
    list-style: none;
}

.diff-list li {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.45rem 0.6rem;
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.035);
    color: var(--text-secondary);
    font-size: 0.78rem;
}

.diff-list code {
    overflow-wrap: anywhere;
    color: var(--text-primary);
}

@media (max-width: 560px) {
    .diff-source-grid,
    .diff-headline {
        grid-template-columns: 1fr;
    }

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

.score-ring {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    border: 4px solid var(--success);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    margin-bottom: 2rem;
}

.score-number {
    font-size: 2.5rem;
    font-weight: 800;
    line-height: 1;
}

.score-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    color: var(--text-secondary);
    letter-spacing: 1px;
}

.stats-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    width: 100%;
    margin-bottom: 1.5rem;
}

.stat {
    background: rgba(255, 255, 255, 0.05);
    padding: 0.8rem;
    border-radius: var(--radius-sm);
    text-align: center;
    font-weight: 500;
}

.stat .red {
    color: var(--error);
    font-weight: bold;
    margin-right: 4px;
}

.stat .yellow {
    color: var(--warning);
    font-weight: bold;
    margin-right: 4px;
}

.result-actions {
    width: 100%;
}

.secondary-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    margin-top: 1rem;
}

/* Comparison Section */
.comparison-section {
    padding: 80px 0;
}

/* Section grounds alternate between the two darkest steps so the page has
   rhythm without any card sitting on a decorated background. */
.checks-section,
.download-section,
#faq {
    background: var(--bg-elevated);
}

/* --- What the report checks ---------------------------------------------
   Placed before the benchmark table: a first-time reader wants to know what
   the tool looks at before they care how fast it looks at it. */
.checks-section {
    padding: 80px 0;
}

.checks-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 1.25rem;
}

.check-card {
    padding: 1.5rem;
}

.check-card h3 {
    margin-bottom: 0.5rem;
    font-size: 1.05rem;
}

.check-card p {
    margin: 0;
    color: var(--text-secondary);
    font-size: 0.92rem;
    line-height: 1.6;
}

.check-card code {
    font-family: var(--font-mono);
    font-size: 0.85rem;
    overflow-wrap: anywhere;
}

.checks-footnote {
    margin: 2rem 0 0;
    text-align: center;
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.checks-footnote a {
    color: var(--accent-primary);
}

.section-header {
    text-align: center;
    margin-bottom: 3rem;
}

.section-header h2 {
    /* Was a flat 2.5rem, which on a 390px screen ate two full lines. */
    font-size: clamp(1.75rem, 5vw, 2.5rem);
    margin-bottom: 0.5rem;
    text-wrap: balance;
}

.section-header p {
    font-size: 1.1rem;
    color: var(--text-secondary);
}

/* Screen-reader-only: keeps the table caption available to assistive tech and
   parsers without showing it in the layout. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.comparison-table {
    width: 100%;
    /* `separate` rather than `collapse` so the card keeps its rounded corners. */
    border-collapse: separate;
    border-spacing: 0;
    overflow: hidden;
}

.comparison-table th,
.comparison-table td {
    width: 33.33%;
    padding: 1.5rem 2rem;
    text-align: left;
    vertical-align: middle;
    border-bottom: 1px solid var(--border);
    font-weight: 400;
}

.comparison-table tbody tr:last-child th,
.comparison-table tbody tr:last-child td {
    border-bottom: none;
}

.comparison-row.header th {
    background: var(--surface-raised);
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    font-size: 0.85rem;
    letter-spacing: 1px;
}

.col-feature {
    font-weight: 500;
}

.col-old {
    color: var(--text-secondary);
    opacity: 0.8;
}

.col-new {
    color: var(--text-primary);
    font-weight: 600;
}

.col-new.highlight {
    color: var(--success);
}

@media (max-width: 768px) {

    /* One card per row: the header cells stop carrying meaning once the
       columns stack, so each cell repeats on its own line instead. */
    .comparison-table,
    .comparison-table tbody,
    .comparison-table tr,
    .comparison-table th,
    .comparison-table td {
        display: block;
        width: 100%;
    }

    .comparison-table thead {
        display: none;
    }

    .comparison-table tbody tr {
        padding: 1.5rem 2rem;
        border-bottom: 1px solid var(--border);
        text-align: center;
    }

    .comparison-table tbody tr:last-child {
        border-bottom: none;
    }

    .comparison-table th,
    .comparison-table td {
        padding: 0.25rem 0;
        border-bottom: none;
        text-align: center;
    }

    .col-feature {
        color: var(--accent-primary);
        margin-bottom: 0.25rem;
    }
}

/* Download Section */
.download-section {
    padding: 80px 0;
}

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

.download-card {
    padding: 2.5rem;
    text-align: center;
    transition: transform 0.3s;
}

.download-card:hover {
    transform: translateY(-5px);
    background: rgba(30, 41, 59, 0.8);
}

.os-icon {
    font-size: 2rem;
    color: var(--text-secondary);
    margin-bottom: 1rem;
}

.download-card h3 {
    margin-bottom: 0.5rem;
}

.download-card .sub-text {
    margin-bottom: 2rem;
}

/* Tech Section */
.tech-section {
    padding: 80px 0;
    background: rgba(0, 0, 0, 0.2);
}

.tech-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3rem;
}

.tech-header {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 1rem;
}

.tech-icon {
    color: var(--accent-primary);
}

.code-block {
    position: relative;
    padding: 1.5rem;
    background: var(--bg-elevated);
    max-width: 100%;
}

.install-cmd-row {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 0.8rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}

.install-cmd-row code {
    color: var(--warning);
    font-family: var(--font-mono);
    min-width: 0;
    overflow-wrap: anywhere;
}

pre {
    overflow-x: auto;
    max-width: 100%;
    font-family: var(--font-mono);
    font-size: 0.9rem;
    color: #e2e8f0;
}

.copy-tiny {
    background: rgba(255, 255, 255, 0.1);
    border: none;
    color: #fff;
    padding: 4px 8px;
    border-radius: var(--radius-sm);
    font-size: 0.75rem;
    cursor: pointer;
}

.copy-tiny:hover {
    background: rgba(255, 255, 255, 0.2);
}

/* Report Modal (keep existing mostly) */
.report-modal {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.6);
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.report-modal.hidden {
    display: none;
}

.report-modal-content {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    background: var(--surface);
}

.report-modal-header {
    padding: 1rem;
    border-bottom: 1px solid var(--border);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.report-modal-body {
    flex-grow: 1;
    overflow-y: auto;
    padding: 1rem;
}

.report-modal-footer {
    padding: 1rem;
    border-top: 1px solid var(--border);
    text-align: right;
}

.close-btn {
    background: none;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
}

/* Utils */
.hidden {
    display: none !important;
}

/* Notice Card Styles in Modal */
.notice-group {
    margin-bottom: 2rem;
}

.notice-group-header {
    display: flex;
    justify-content: space-between;
    padding: 0.5rem 1rem;
    background: rgba(255, 255, 255, 0.05);
    border-radius: var(--radius-sm);
    margin-bottom: 1rem;
    font-weight: 600;
}

.notice-group-header.error {
    color: var(--error);
    border-left: 3px solid var(--error);
}

.notice-group-header.warning {
    color: var(--warning);
    border-left: 3px solid var(--warning);
}

.notice-group-header.info {
    color: var(--info);
    border-left: 3px solid var(--info);
}

.notice-item {
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid var(--border);
    padding: 1rem;
    margin-bottom: 0.5rem;
    border-radius: var(--radius-sm);
}

.notice-code {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    font-weight: bold;
    margin-bottom: 0.25rem;
}

.notice-item.error .notice-code {
    color: var(--error);
}


.notice-item.warning .notice-code {
    color: var(--warning);
}

/* Documentation Cards */
.glass-doc-card {
    background: var(--surface);
    border: 1px solid var(--border);
    padding: 1.5rem;
    border-radius: var(--radius-md);
    transition: background-color 0.15s ease, border-color 0.15s ease;
    display: block;
    text-decoration: none;
}

/* On the guides index these sit inside a panel that already uses the surface
   fill, so they need the next step up or they vanish into their container. */
.glass-card .glass-doc-card {
    background: var(--surface-raised);
}

.glass-card .glass-doc-card:hover {
    background: #1c2942;
}

.glass-doc-card:hover {
    background: var(--surface-raised);
    border-color: var(--accent-primary);
}

.glass-doc-card i {
    color: var(--accent-primary);
    margin-bottom: 1rem;
    width: 24px;
    height: 24px;
}

.glass-doc-card h3 {
    color: var(--text-primary);
    margin-bottom: 0.5rem;
    font-size: 1.1rem;
}

.glass-doc-card p {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin-bottom: 0;
    line-height: 1.5;
}

.notice-message {
    margin-bottom: 0.5rem;
    font-size: 0.9rem;
}

.notice-location {
    display: flex;
    gap: 1rem;
    font-size: 0.8rem;
    color: var(--text-secondary);
    font-family: var(--font-mono);
}

/* Guides hub: the pointer into the 194-page notice reference. */
.notice-callout {
    max-width: 800px;
    margin: 3rem auto 0;
    padding: 2.5rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

.notice-callout h2 {
    font-size: 1.5rem;
    margin-bottom: 0.75rem;
}

.notice-callout p {
    color: var(--text-secondary);
    margin-bottom: 1.5rem;
    max-width: 62ch;
}

.notice-callout-links {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem 1.25rem;
}

.notice-callout-links code {
    font-family: var(--font-mono);
    font-size: 0.85em;
    color: var(--accent-primary);
}

.notice-callout-links a:hover code {
    text-decoration: underline;
}

/* Answer-first step list at the top of a how-to guide. Mirrors the HowTo
   structured data on the same page. */
.howto-summary {
    margin: 0 0 2rem;
    padding: 1.5rem 1.5rem 1.5rem 3rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

.howto-summary li {
    color: var(--text-secondary);
    margin-bottom: 0.75rem;
}

.howto-summary li:last-child {
    margin-bottom: 0;
}

.howto-summary strong {
    color: var(--text-primary);
}

/* Footer */
/* .footer-logo had no rule at all, so the image rendered at its intrinsic
   size. It also pointed at favicon.svg, which is a separate glyph drawn to
   survive 16px -- blown up in the footer it read as a different, cruder logo
   than the network mark in the nav. Same asset as the nav now, sized here. */
.footer-logo {
    display: block;
    /* The mark is a thin-line network drawing; below roughly 56px its nodes
       collapse into noise, which is why a separate simplified glyph exists for
       the favicon. The footer has the room, so it gets the real mark at a size
       that actually reads. */
    width: 64px;
    height: 64px;
    margin-bottom: 0.75rem;
}

footer {
    padding: 4rem 0 2rem;
    background: var(--bg-elevated);
    border-top: 1px solid var(--border);
}

.footer-container {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
}

.footer-links {
    display: flex;
    gap: 2rem;
}

.footer-links a:hover {
    color: var(--accent-primary);
}

.footer-copy {
    font-size: 0.9rem;
    /* was #475569 — only 2.66:1 on the near-black background (WCAG AA fail) */
    color: var(--text-secondary);
}

/* Scroll-reveal is gone. Every section used to start at opacity:0 and fade in
   on an IntersectionObserver, which bought nothing on a page this short and
   cost a whole class of "blank page" bugs whenever the observer did not run.
   Content is now simply visible. */

/* File Protocol Warning */
#protocol-warning {
    background: var(--warning);
    color: #333;
    text-align: center;
    padding: 0.5rem;
    font-weight: 600;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 1000;
}

/* Responsive */
@media (max-width: 900px) {
    .hero-container {
        grid-template-columns: 1fr;
        text-align: center;
    }

    .hero-container .hero-content {
        display: flex;
        flex-direction: column;
        align-items: center;
    }

    .hero-actions {
        justify-content: center;
    }

    .stats-row {
        justify-content: center;
    }

    /* .nav-links: see the consolidated mobile nav block at the end of this file */

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

.hidden {
    display: none !important;
}

/* Manual Input Section */
.manual-input-section {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
}

.input-label {
    font-size: 0.85rem;
    color: var(--text-secondary);
    font-weight: 500;
}

.text-input {
    width: 100%;
    background: rgba(0, 0, 0, 0.2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 0.6rem 0.8rem;
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 0.9rem;
    transition: border-color 0.2s;
}

.text-input:focus {
    outline: none;
    border-color: var(--accent-primary);
    background: rgba(0, 0, 0, 0.3);
}

.btn-block {
    width: 100%;
    justify-content: center;
    margin-top: 0.5rem;
}

/* Responsive */
@media (max-width: 900px) {

    .hero-container,
    .features-grid,
    .agency-content,
    .tech-grid,
    .footer-container {
        grid-template-columns: 1fr;
        flex-direction: column;
        gap: 3rem;
        text-align: center;
    }

    .hero-actions {
        justify-content: center;
    }

    /* .nav-links: see the consolidated mobile nav block at the end of this file */

    /* Simplified mobile nav for now */
    .hero-section {
        padding-top: 100px;
    }

    h1 {
        font-size: 2.5rem;
    }

    .stats-row {
        justify-content: center;
    }

    .agency-content {
        gap: 3rem;
    }

    .report-preview {
        text-align: left;
    }

    .footer-container {
        gap: 2rem;
    }
}

/* Report Modal */
.report-modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.8);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.report-modal-content {
    width: 100%;
    max-width: 900px;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.report-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1.5rem;
    border-bottom: 1px solid var(--border);
}

.report-modal-header h3 {
    margin: 0;
    font-size: 1.25rem;
}

.close-btn {
    background: transparent;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
    padding: 0.5rem;
    border-radius: var(--radius-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s;
}

.close-btn:hover {
    background: rgba(255, 255, 255, 0.1);
    color: var(--text-primary);
}

.report-modal-body {
    flex: 1;
    overflow-y: auto;
    padding: 1.5rem;
}

.report-modal-footer {
    padding: 1rem 1.5rem;
    border-top: 1px solid var(--border);
    display: flex;
    justify-content: flex-end;
}

/* Notice Groups */
.notice-group {
    margin-bottom: 1.5rem;
}

.notice-group-header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
    font-weight: 600;
    font-size: 0.9rem;
}

.notice-group-header.error {
    color: var(--error);
}

.notice-group-header.warning {
    color: var(--warning);
}

.notice-group-header.info {
    color: var(--info);
    background: rgba(255, 255, 255, 0.03);
    padding: 0.75rem 1rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: pointer;
    user-select: none;
    transition: background-color 0.2s;
}

.notice-group-header:hover {
    background: rgba(255, 255, 255, 0.05);
}

.notice-group-header.error {
    border-left: 4px solid var(--error);
}

.notice-group-header.warning {
    border-left: 4px solid var(--warning);
}

.notice-group-header.info {
    border-left: 4px solid var(--info);
}

.notice-group-title {
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.notice-group-count {
    background: rgba(255, 255, 255, 0.1);
    padding: 0.1rem 0.5rem;
    border-radius: var(--radius-md);
    font-size: 0.75rem;
    font-weight: 600;
}

.notice-group-details {
    display: none;
    border-top: 1px solid var(--border);
    max-height: 400px;
    overflow-y: auto;
}

.notice-group-details.open {
    display: block;
}

.notice-item {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border);
    font-size: 0.9rem;
}

.notice-item:last-child {
    border-bottom: none;
}

.notice-code {
    font-family: 'Fira Code', monospace;
    font-size: 0.85rem;
    color: var(--accent-primary);
    margin-bottom: 0.25rem;
}

.notice-message {
    color: var(--text-primary);
    font-size: 0.9rem;
    margin-bottom: 0.5rem;
}

.notice-location {
    display: flex;
    gap: 1rem;
    margin-top: 0.25rem;
    font-size: 0.8rem;
    color: var(--text-secondary);
    flex-wrap: wrap;
}

.notice-location span {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.notice-location code {
    background: rgba(255, 255, 255, 0.1);
    padding: 0.1rem 0.4rem;
    border-radius: var(--radius-sm);
    font-family: 'Fira Code', monospace;
}

/* Report Table Styles */
.report-table th,
.report-table td {
    padding: 0.5rem 1rem;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

.report-table th {
    font-weight: 500;
    text-align: left;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.report-table td code {
    font-size: 0.85rem;
    color: var(--text-primary);
}

.report-table tbody tr:hover {
    background: rgba(255, 255, 255, 0.02);
}

/* Result Actions */
.result-actions {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.btn-link {
    background: transparent;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
    font-size: 0.85rem;
    padding: 0.5rem;
}

.btn-link:hover {
    color: var(--text-primary);
}

/* Demo feed row */
.demo-row {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.75rem;
}

.demo-row .sub-text {
    margin: 0;
}

#try-demo-btn i {
    width: 16px;
    height: 16px;
}

/* Shared report banner */
.shared-banner {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.6rem 0.9rem;
    margin-bottom: 1rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-secondary);
    font-size: 0.85rem;
    text-align: left;
}

.shared-banner i {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.shared-banner button {
    margin-left: auto;
}

/* Toast (share link copied) */
.toast {
    position: fixed;
    left: 50%;
    bottom: 2rem;
    transform: translateX(-50%) translateY(1rem);
    z-index: 2000;
    max-width: min(90vw, 34rem);
    padding: 0.75rem 1.1rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--text-primary);
    font-size: 0.9rem;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
    opacity: 0;
    transition: opacity 0.2s ease, transform 0.2s ease;
    pointer-events: none;
}

.toast.visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

@media (prefers-reduced-motion: reduce) {
    .toast {
        transition: none;
    }
}

/* Empty State */
.empty-state {
    text-align: center;
    padding: 3rem;
    color: var(--text-secondary);
}

.empty-state i {
    width: 48px;
    height: 48px;
    color: var(--success);
    margin-bottom: 1rem;
}

.empty-state h4 {
    color: var(--text-primary);
    margin-bottom: 0.5rem;
}


.notice-item.warning .notice-code {
    color: var(--warning);
}

/* Documentation Cards */
.glass-doc-card {
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid var(--border);
    padding: 1.5rem;
    border-radius: var(--radius-md);
    transition: all 0.3s ease;
    display: block;
    text-decoration: none;
}

.glass-doc-card:hover {
    background: rgba(255, 255, 255, 0.05);
    border-color: var(--accent-primary);
    transform: translateY(-2px);
}

.glass-doc-card i {
    color: var(--accent-primary);
    margin-bottom: 1rem;
    width: 24px;
    height: 24px;
}

.glass-doc-card h3 {
    color: var(--text-primary);
    margin-bottom: 0.5rem;
    font-size: 1.1rem;
}

.glass-doc-card p {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin-bottom: 0;
    line-height: 1.5;
}

/* FAQ Article Generic Styles */
.faq-article {
    max-width: 800px;
    margin: 0 auto;
    padding: 120px clamp(1.25rem, 4vw, 2rem) 4rem;
    color: var(--text-secondary);
}

.faq-article h1 {
    /* Article titles are long ("What's the Difference Between GTFS and
       GTFS-Realtime?"); keep them fluid so they never clip on small screens. */
    font-size: clamp(1.75rem, 5.5vw, 2.5rem);
    color: var(--text-primary);
    overflow-wrap: break-word;
    margin-bottom: 2rem;
    line-height: 1.2;
}

.faq-article h2 {
    font-size: 1.8rem;
    color: var(--accent-primary);
    margin-top: 3rem;
    margin-bottom: 1rem;
}

.faq-article h3 {
    font-size: 1.4rem;
    color: var(--text-primary);
    margin-top: 2rem;
    margin-bottom: 0.75rem;
}

.faq-article p {
    margin-bottom: 1.2rem;
    font-size: 1.05rem;
    line-height: 1.7;
}

.faq-article ul,
.faq-article ol {
    margin-bottom: 1.5rem;
    padding-left: 2rem;
    color: var(--text-secondary);
}

.faq-article li {
    margin-bottom: 0.5rem;
}

.faq-article strong {
    color: var(--text-primary);
}

.faq-article a {
    color: var(--accent-primary);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    transition: all 0.2s;
}

.faq-article a:hover {
    color: var(--accent-secondary);
    border-bottom-color: var(--accent-secondary);
}

.faq-article .short-answer {
    font-size: 1.2rem;
    padding: 1.5rem;
    background: var(--accent-tint);
    border-left: 4px solid var(--accent-primary);
    border-radius: var(--radius-sm);
    margin-bottom: 2.5rem;
    color: var(--text-primary);
}

.faq-article .cta-box {
    margin-top: 4rem;
    padding: 2rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    text-align: center;
}

.faq-article .cta-box p {
    margin-bottom: 0;
}

/* Replaces the old "Back to Guides" link. A real trail, so the visible
   navigation matches the BreadcrumbList markup instead of only implying the
   parent, and it matches the trail the /notices/ pages already use. */
.crumbs {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 2rem;
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.crumbs a {
    color: var(--text-secondary);
}

.crumbs a:hover {
    color: var(--accent-primary);
}

.crumbs span[aria-hidden] {
    color: var(--border-strong);
}

.crumbs [aria-current="page"] {
    color: var(--text-primary);
}

.btn-ghost {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-secondary);
}

.btn-ghost:hover {
    color: var(--text-primary);
    background: rgba(255, 255, 255, 0.05);
}

.completion-indicator {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    margin-bottom: 1.5rem;
    animation: fadeScale 0.5s ease-out;
}

.completion-icon {
    color: var(--success);
    margin-bottom: 0.5rem;
}

/* The icon colour is the first thing read off this panel, so it tracks the
   counts rather than sitting on green. */
.completion-indicator.state-error .completion-icon {
    color: var(--error);
}

.completion-indicator.state-warning .completion-icon {
    color: var(--warning);
}

.completion-indicator.state-clean .completion-icon {
    color: var(--success);
}

.completion-icon svg {
    width: 56px;
    height: 56px;
}

.completion-text {
    font-size: 1.3rem;
    font-weight: 650;
    color: var(--text-primary);
    letter-spacing: -0.02em;
}

.completion-sub {
    margin-top: 0.35rem;
    font-size: 0.9rem;
    color: var(--text-secondary);
    max-width: 44ch;
}

/* --- Inline issue list ---------------------------------------------------
   The findings are the product. They are rendered in the result panel, not
   behind a "See More" button, and each card answers the four questions a
   reader arrives with: what, where, why, and what to change. */
.result-issues {
    width: 100%;
    margin-bottom: 1.5rem;
    text-align: left;
}

.result-issues.hidden {
    display: none;
}

.result-issues-title {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-secondary);
    margin-bottom: 0.75rem;
}

.issue-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.75rem;
}

.issue-card {
    padding: 0.9rem 1rem;
    border: 1px solid var(--border);
    border-left: 3px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.03);
}

.issue-card.error {
    border-left-color: var(--error);
}

.issue-card.warning {
    border-left-color: var(--warning);
}

.issue-topline {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.4rem;
}

.issue-severity {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    padding: 0.15rem 0.45rem;
    border-radius: 4px;
}

.issue-card.error .issue-severity {
    color: var(--error);
    background: rgba(248, 113, 113, 0.12);
}

.issue-card.warning .issue-severity {
    color: var(--warning);
    background: rgba(251, 191, 36, 0.12);
}

.issue-title {
    font-size: 1rem;
    font-weight: 600;
    margin: 0;
    flex: 1 1 auto;
    min-width: 0;
}

.issue-count {
    font-size: 0.8rem;
    color: var(--text-secondary);
    white-space: nowrap;
}

.issue-location {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
    margin: 0 0 0.4rem;
    font-size: 0.82rem;
    color: var(--text-secondary);
}

.issue-location code {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    color: var(--text-primary);
    background: rgba(255, 255, 255, 0.06);
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    overflow-wrap: anywhere;
}

.issue-reason,
.issue-fix {
    margin: 0 0 0.4rem;
    font-size: 0.9rem;
    line-height: 1.5;
    color: var(--text-secondary);
}

.issue-fix strong {
    color: var(--text-primary);
}

.issue-doc-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.85rem;
    color: var(--accent-primary);
    text-decoration: none;
    overflow-wrap: anywhere;
}

.issue-doc-link:hover {
    text-decoration: underline;
}

.issue-doc-link code {
    font-family: var(--font-mono);
    font-size: 0.8rem;
}

.issue-doc-link .issue-doc-label {
    white-space: nowrap;
}

.issue-doc-link svg,
.issue-doc-link i {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
}

.issue-more {
    margin: 0.85rem 0 0;
    font-size: 0.85rem;
    color: var(--text-secondary);
}

@keyframes fadeScale {
    from {
        opacity: 0;
        transform: scale(0.9);
    }

    to {
        opacity: 1;
        transform: scale(1);
    }
}/* Error Container */
.error-container {
    background: rgba(248, 113, 113, 0.1);
    border: 1px solid rgba(248, 113, 113, 0.3);
    color: var(--error);
    padding: 0.8rem;
    border-radius: var(--radius-sm);
    margin-bottom: 1rem;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 0.9rem;
    animation: slideDown 0.3s ease-out;
}

.error-container i {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
}

.close-error {
    background: none;
    border: none;
    color: var(--error);
    cursor: pointer;
    margin-left: auto;
    padding: 0;
    opacity: 0.7;
}

.close-error:hover {
    opacity: 1;
}

@keyframes slideDown {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}
/* --- Geographic Notice Map Modal --- */
.map-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.8);
    z-index: 1100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
}

.map-modal.hidden {
    display: none;
}

.map-modal-content {
    width: min(1080px, 100%);
    height: min(720px, 90vh);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid rgba(148, 163, 184, 0.24);
    box-shadow: 0 32px 90px rgba(0, 0, 0, 0.5);
    animation: mapModalEnter 0.24s ease-out both;
}

.map-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--border, rgba(148, 163, 184, 0.2));
    flex-shrink: 0;
}

.map-modal-header h3 {
    font-size: 1.05rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.map-modal-kicker {
    display: block;
    margin-bottom: 0.18rem;
    color: var(--text-secondary);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.map-stage {
    position: relative;
    flex: 1;
    min-height: 0;
    isolation: isolate;
}

#stop-map {
    position: absolute;
    inset: 0;
}

.map-legend {
    position: absolute;
    left: 18px;
    bottom: 18px;
    z-index: 2;
    display: flex;
    gap: 1rem;
    padding: 0.62rem 0.8rem;
    border: 1px solid rgba(148, 163, 184, 0.24);
    border-radius: 999px;
    background: var(--surface-raised);
    border: 1px solid var(--border);
    color: var(--text-primary);
    font-size: 0.75rem;
    pointer-events: none;
}

.map-legend span {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.map-legend-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
}

.map-legend-dot.affected {
    background: #fb7185;
    box-shadow: 0 0 0 3px rgba(251, 113, 133, 0.22);
}

.map-legend-dot.nearest {
    background: #22d3ee;
    box-shadow: 0 0 0 3px rgba(34, 211, 238, 0.24);
}

.map-legend-line {
    width: 18px;
    height: 3px;
    border-radius: 999px;
    background: #22d3ee;
}

.notice-map-marker {
    width: 18px;
    height: 18px;
    border: 3px solid #f8fafc;
    border-radius: 50%;
    cursor: pointer;
}

.notice-map-marker--point {
    background: #fb7185;
    box-shadow: 0 0 0 6px rgba(251, 113, 133, 0.2), 0 4px 16px rgba(2, 6, 23, 0.45);
}

.notice-map-marker--nearest {
    width: 14px;
    height: 14px;
    background: #22d3ee;
    box-shadow: 0 0 0 5px rgba(34, 211, 238, 0.22), 0 4px 16px rgba(2, 6, 23, 0.45);
}

.map-pin-btn {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--accent-primary);
    padding: 0 0 0 6px;
    vertical-align: middle;
    line-height: 1;
}

.map-pin-btn svg,
.map-pin-btn i {
    width: 14px;
    height: 14px;
}

.map-pin-btn:hover {
    color: var(--accent-secondary);
}

.geometry-map-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.38rem 0.62rem;
    border: 1px solid rgba(34, 211, 238, 0.35);
    border-radius: 999px;
    background: rgba(34, 211, 238, 0.1);
    color: #67e8f9;
    font: inherit;
    font-size: 0.75rem;
    font-weight: 700;
    cursor: pointer;
    transition: transform 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}

.geometry-map-btn:hover {
    background: rgba(34, 211, 238, 0.17);
    border-color: rgba(34, 211, 238, 0.65);
    transform: translateY(-1px);
}

.geometry-map-btn svg,
.geometry-map-btn i {
    width: 14px;
    height: 14px;
}

@keyframes mapModalEnter {
    from {
        opacity: 0;
        transform: translateY(12px) scale(0.985);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

@media (max-width: 640px) {
    .map-modal {
        padding: 0.75rem;
    }

    .map-modal-content {
        height: 88vh;
    }

    .map-legend {
        left: 10px;
        bottom: 10px;
        gap: 0.65rem;
        max-width: calc(100% - 20px);
    }

    .stats-row {
        width: 100%;
        justify-content: space-between;
        gap: 1rem;
    }

    /* On a 390px screen the file picker used to start around 1035px, well
       below the fold. Tightening the intro and dropping the badge row brings
       it into the first screen. */
    .hero-section {
        padding-top: 84px;
        padding-bottom: 48px;
    }

    .hero-container {
        gap: 1.75rem;
    }

    .hero-container .badge-row {
        display: none;
    }

    .hero-sub {
        font-size: 1.02rem;
        margin-bottom: 1.5rem;
    }

    .hero-actions {
        width: 100%;
        gap: 0.6rem;
    }

    .hero-actions .btn-lg {
        width: 100%;
        justify-content: center;
    }

    .hero-visual {
        gap: 2rem;
    }

    h1 {
        font-size: 1.95rem;
    }

    /* "Validate a feed" only scrolls to the card directly below it here, so
       on a phone it costs a full row and buys nothing. The example and the
       download stay, side by side. */
    .hero-actions .btn-primary {
        display: none;
    }

    .hero-actions {
        flex-direction: row;
    }

    .hero-actions .btn-lg {
        flex: 1 1 0;
        width: auto;
        padding-left: 0.75rem;
        padding-right: 0.75rem;
        font-size: 0.92rem;
    }

    .upload-state {
        min-height: 200px;
        padding: 1.25rem 0.5rem;
    }

    .upload-icon {
        width: 36px;
        height: 36px;
        margin-bottom: 0.6rem;
    }

    .stat-item {
        flex: 1;
        min-width: 0;
        text-align: center;
    }

    .code-block {
        padding: 1rem;
    }

    .install-cmd-row {
        align-items: flex-start;
    }

    .footer-links {
        flex-wrap: wrap;
        justify-content: center;
        gap: 1rem 1.25rem;
    }
}

/* --- Mobile navigation ---------------------------------------------------
   Below 900px the link row used to be display:none with nothing in its place,
   so Web Validator / FAQ / Guides / Contact / Developers / GitHub were simply
   unreachable on a phone. It now collapses into a toggleable panel. */
/* Only shown inside the collapsed mobile panel. */
.nav-mobile-cta {
    display: none;
}

@media (max-width: 900px) {
    .nav-toggle {
        display: inline-flex;
    }

    /* Logo + CTA + burger together overflow a 375px bar by ~8px. The hero
       already carries "Download for Desktop", so the bar CTA moves into the
       panel instead of being cut off. */
    .nav-actions .btn {
        display: none;
    }

    /* Scoped through .nav-links so it outranks the generic `.nav-links a` rule. */
    .nav-links a.nav-mobile-cta {
        display: block;
        color: var(--accent-primary);
        font-weight: 600;
        border-top: 1px solid var(--border);
        margin-top: 0.25rem;
    }

    .nav-links {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        gap: 0;
        padding: 0.5rem 0;
        /* Fully opaque. At 0.98 the page behind still read through the panel
           wherever the content under it was bright — a white h1, the hero
           badges — and the menu labels lost contrast against it. */
        background: #0b1220;
        border-bottom: 1px solid var(--border);
        box-shadow: 0 16px 32px rgba(0, 0, 0, 0.5);
        text-align: left;
    }

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

    /* The bar centres its items; the collapsed panel is a list and must not,
       or every row shrinks to its own label width. */
    .nav-links {
        align-items: stretch;
        text-align: left;
    }

    .nav-links a {
        padding: 0.85rem clamp(1.25rem, 4vw, 2rem);
        font-size: 1rem;
        color: var(--text-primary);
    }

    .nav-links a:hover {
        background: rgba(255, 255, 255, 0.06);
    }

    /* Inside the collapsed panel the dropdown is just an expandable row; an
       absolutely positioned menu would hang off the side of the screen. */
    .nav-dropdown > summary {
        padding: 0.85rem clamp(1.25rem, 4vw, 2rem);
        font-size: 1rem;
        color: var(--text-primary);
        justify-content: space-between;
    }

    .nav-dropdown-panel {
        position: static;
        min-width: 0;
        padding: 0;
        border: 0;
        border-radius: 0;
        background: rgba(255, 255, 255, 0.03);
        backdrop-filter: none;
    }

    .nav-links .nav-dropdown-panel a {
        padding-left: calc(clamp(1.25rem, 4vw, 2rem) + 0.85rem);
    }
}

/* The panel is absolutely positioned against the nav bar. */
.glass-nav {
    position: fixed;
}

.nav-container {
    position: relative;
}

/* ChatGPT / MCP result preview.
   A collapsed disclosure below the report: an integration is worth offering,
   but not ahead of the errors the reader came to fix. */
.mcp-preview {
    width: 100%;
    margin: 1.25rem 0 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.02);
    text-align: left;
}

.mcp-preview-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 1rem;
    cursor: pointer;
    list-style: none;
}

.mcp-preview-summary::-webkit-details-marker {
    display: none;
}

.mcp-preview-summary:hover {
    background: rgba(255, 255, 255, 0.03);
}

.mcp-preview-title {
    display: block;
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--text-primary);
}

.mcp-preview-inner {
    padding: 0 1rem 1rem;
}

.mcp-preview-header,
.mcp-preview-heading,
.mcp-preview-footer,
.mcp-example-topline,
.mcp-example-location,
.mcp-clean-note {
    display: flex;
    align-items: center;
}

.mcp-preview-header,
.mcp-example-topline,
.mcp-preview-footer {
    justify-content: space-between;
}

.mcp-preview-header {
    gap: 1rem;
    margin-bottom: 0.85rem;
}

.mcp-preview-heading {
    gap: 0.65rem;
}

.mcp-preview-heading > svg,
.mcp-preview-heading > i {
    width: 20px;
    height: 20px;
    color: var(--accent-primary);
}

.mcp-preview-heading h3 {
    margin: 0;
    font-size: 1rem;
    line-height: 1.2;
}

.mcp-preview-kicker {
    display: block;
    margin-bottom: 0.12rem;
    color: var(--accent-primary);
    font-family: var(--font-mono);
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.mcp-local-label {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    flex: 0 0 auto;
    color: var(--success);
    font-size: 0.72rem;
    font-weight: 600;
}

.mcp-local-label svg,
.mcp-local-label i {
    width: 12px;
    height: 12px;
}

.mcp-verdict {
    margin: 0 0 0.8rem;
    color: #e2e8f0;
    font-size: 0.86rem;
    line-height: 1.5;
}

.mcp-examples {
    margin: 0;
    padding: 0;
    list-style: none;
}

.mcp-example {
    padding: 0.72rem 0 0.72rem 0.75rem;
    border-left: 2px solid var(--warning);
    border-bottom: 1px solid var(--border);
}

.mcp-example.error {
    border-left-color: var(--error);
}

.mcp-example:last-child {
    border-bottom: 0;
}

.mcp-example-topline {
    gap: 0.75rem;
}

.mcp-example-topline > code {
    overflow-wrap: anywhere;
    color: var(--text-primary);
    font-family: var(--font-mono);
    font-size: 0.76rem;
    font-weight: 600;
}

.mcp-example-topline > span {
    flex: 0 0 auto;
    color: var(--text-secondary);
    font-size: 0.72rem;
    text-transform: uppercase;
}

.mcp-example > p {
    margin: 0.28rem 0 0;
    color: var(--text-secondary);
    font-size: 0.76rem;
    line-height: 1.4;
}

.mcp-example-location {
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.45rem;
}

.mcp-example-location code {
    max-width: 100%;
    padding: 0.12rem 0.35rem;
    overflow-wrap: anywhere;
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.06);
    color: #cbd5e1;
    font-family: var(--font-mono);
    font-size: 0.72rem;
}

.mcp-example-fix {
    color: #bbf7d0 !important;
}

.mcp-sample-note {
    margin: 0.7rem 0 0;
    color: var(--text-secondary);
    font-size: 0.72rem;
}

.mcp-clean-note {
    gap: 0.45rem;
    margin: 0;
    color: var(--success);
    font-size: 0.8rem;
}

.mcp-clean-note svg,
.mcp-clean-note i {
    width: 16px;
    height: 16px;
}

.mcp-preview-footer {
    gap: 0.75rem 1rem;
    margin-top: 0.85rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
    color: var(--text-secondary);
    font-size: 0.72rem;
}

.mcp-preview-footer a {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    min-height: 32px;
    flex: 0 0 auto;
    color: var(--accent-primary);
    font-weight: 600;
}

.mcp-preview-footer a:hover {
    color: #7dd3fc;
}

.mcp-preview-footer svg,
.mcp-preview-footer i {
    width: 13px;
    height: 13px;
}

.mcp-developer-strip {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 2rem;
    margin-top: 3rem;
    padding: 1.6rem 0;
    border-top: 1px solid var(--accent-tint-strong);
    border-bottom: 1px solid var(--accent-tint);
}

.mcp-developer-strip h3 {
    margin: 0.15rem 0 0.3rem;
    font-size: 1.2rem;
}

.mcp-developer-strip p {
    max-width: 720px;
    margin: 0;
    color: var(--text-secondary);
    font-size: 0.9rem;
}

.mcp-developer-strip .btn {
    flex: 0 0 auto;
}

.result-state .result-actions {
    flex-wrap: wrap;
}

.result-state .result-actions .btn {
    flex: 1 1 96px;
}

@media (max-width: 640px) {
    .mcp-preview-header,
    .mcp-preview-footer,
    .mcp-developer-strip,
    .mcp-example-topline {
        align-items: flex-start;
        flex-direction: column;
    }

    .mcp-example-topline {
        gap: 0.2rem;
    }

    .mcp-preview-footer a {
        min-height: 44px;
    }

    .mcp-developer-strip {
        text-align: left;
    }
}

@media (prefers-reduced-motion: reduce) {
    .mcp-preview,
    .mcp-preview.is-ready {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* Keyboard focus must stay visible everywhere (buttons reset outlines above). */
a:focus-visible,
button:focus-visible,
input:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* --- Connect an MCP client --- */
.connect-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.8);
    z-index: 1100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
}

.connect-modal.hidden {
    display: none;
}

.connect-modal-content {
    width: min(680px, 100%);
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid rgba(148, 163, 184, 0.24);
    box-shadow: 0 32px 90px rgba(0, 0, 0, 0.5);
    /* The modal lives inside the hero <header>, which centers its text below
       768px. Instructions and paths read as a left-aligned column. */
    text-align: left;
}

.connect-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid rgba(148, 163, 184, 0.2);
    flex-shrink: 0;
}

.connect-modal-header h3 {
    font-size: 1.05rem;
}

.connect-modal-body {
    padding: 1.25rem;
    overflow-y: auto;
    flex: 1;
    min-height: 0;
}

.connect-modal-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.85rem 1.25rem;
    border-top: 1px solid rgba(148, 163, 184, 0.2);
    font-size: 0.8rem;
    color: var(--text-secondary);
    flex-shrink: 0;
}

.connect-modal-footer a {
    color: var(--accent-primary);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.connect-intro {
    font-size: 0.88rem;
    color: var(--text-secondary);
    margin-bottom: 1.25rem;
}

.connect-step {
    margin-bottom: 1.5rem;
}

.connect-step:last-child {
    margin-bottom: 0;
}

.connect-step h4 {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.92rem;
    margin-bottom: 0.65rem;
}

.connect-step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background: var(--accent-tint);
    color: var(--accent-primary);
    font-size: 0.75rem;
    font-weight: 700;
    flex-shrink: 0;
}

.connect-tabs {
    display: flex;
    gap: 0.35rem;
    flex-wrap: wrap;
    margin-bottom: 0.65rem;
}

.connect-tab {
    background: rgba(148, 163, 184, 0.1);
    border: 1px solid transparent;
    color: var(--text-secondary);
    padding: 0.3rem 0.7rem;
    border-radius: var(--radius-sm);
    font-size: 0.78rem;
    font-family: inherit;
    cursor: pointer;
    transition: color 0.15s ease, background 0.15s ease;
}

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

.connect-tab.is-active {
    background: var(--accent-tint);
    border-color: var(--accent-tint-strong);
    color: var(--accent-primary);
}

.connect-snippet {
    position: relative;
    margin-bottom: 0.5rem;
}

.connect-snippet pre {
    background: rgba(2, 6, 23, 0.7);
    border: 1px solid rgba(148, 163, 184, 0.18);
    border-radius: var(--radius-sm);
    padding: 0.8rem 4.5rem 0.8rem 0.8rem;
    font-family: var(--font-mono);
    font-size: 0.76rem;
    line-height: 1.6;
    color: var(--text-primary);
    overflow-x: auto;
    white-space: pre;
}

.connect-snippet .copy-tiny {
    position: absolute;
    top: 0.55rem;
    right: 0.55rem;
    /* Opaque, not the translucent default: install commands are long enough to
       scroll horizontally underneath this button. */
    background: #1e293b;
    border: 1px solid rgba(148, 163, 184, 0.3);
    box-shadow: 0 0 0 4px rgba(2, 6, 23, 0.7);
}

.connect-snippet .copy-tiny:hover {
    background: #334155;
}

/* Snippets scroll rather than wrap so paths and commands stay copyable, but
   the suggested prompt is prose and reads better wrapped. */
#connect-prompt {
    white-space: pre-wrap;
    word-break: break-word;
}

.connect-field input {
    width: 100%;
    background: rgba(2, 6, 23, 0.7);
    border: 1px solid rgba(148, 163, 184, 0.24);
    border-radius: var(--radius-sm);
    padding: 0.55rem 0.7rem;
    color: var(--text-primary);
    font-family: var(--font-mono);
    font-size: 0.8rem;
}

.connect-hint {
    font-size: 0.76rem;
    color: var(--text-secondary);
    margin-top: 0.4rem;
}

.connect-hint code {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    background: rgba(148, 163, 184, 0.12);
    padding: 0.1rem 0.3rem;
    border-radius: var(--radius-sm);
}

.connect-hint a {
    color: var(--accent-primary);
    text-decoration: none;
}

.connect-hint a i,
.connect-hint a svg {
    width: 0.7rem;
    height: 0.7rem;
    vertical-align: -1px;
}

.connect-link {
    background: none;
    border: none;
    padding: 0;
    color: var(--accent-primary);
    font-family: inherit;
    font-size: inherit;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.connect-link:hover {
    text-decoration: underline;
}

@media (max-width: 640px) {
    .connect-modal {
        padding: 0.75rem;
    }

    .connect-modal-content {
        max-height: 94vh;
    }

    .connect-snippet pre {
        font-size: 0.7rem;
    }
}
/* Motion preference, site-wide backstop.
   The three blocks above neutralise specific components; this one covers
   everything else, including animations added later — the entrance animations
   (fadeScale, slideDown, mapModalEnter) and any CSS transition.

   The loading spinner is deliberately exempt. It is progress feedback for a
   WASM validation that can run for a minute on a large feed, and a spinner
   frozen after one turn reads as a hung page. It is a 40px rotation at a fixed
   point, not the large-area movement this preference exists to suppress. */
@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    .spinner {
        animation-duration: 1s !important;
        animation-iteration-count: infinite !important;
    }
}


/* --- Focus visibility ----------------------------------------------------
   Every path through this page can now be walked with Tab, which only helps
   if the ring is actually visible against the dark ground. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
    border-radius: 4px;
}


/* Benchmark table: the conditions travel with the numbers, so a figure is
   never read without the feed and machine it came from. */
.col-note {
    display: block;
    margin-top: 0.2rem;
    font-family: var(--font-body);
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--text-secondary);
}

.benchmark-note {
    max-width: 78ch;
    margin: 1.25rem auto 0;
    font-size: 0.82rem;
    line-height: 1.6;
    color: var(--text-secondary);
    text-align: center;
}

.benchmark-note a,
.comparison-table a {
    color: var(--accent-primary);
}
