/* ==========================================================================
   tabularasa.cl - styles.css
   Numbered TOC (keep updated - convention borrowed from benjaopazoc.cl):
     1. Reset + fonts
     2. Layout primitives
     3. Header / nav
     4. Hero
     5. Buttons + badges (site-level marketing controls)
     6. Section headings / feature grid
     7. Feature card flip + demo modal
     8. Showcase window chrome (title bar, menu bar, tab strip) - app-faithful
     9. Toolbar (app-faithful)
    10. Grid (app-faithful)
    11. Status bar (app-faithful)
    12. Search bar (app-faithful)
    13. Popovers / dropdowns (app-faithful)
    14. Download section
    15. Footer
    16. Scrollbars (app-faithful)
    17. Responsive
    18. Reduced motion / accessibility
    19. Ambient background grid (decorative)
    20. Pricing page
    21. Linux install guide page (linux.html)
   ========================================================================== */

/* ---- 1. Reset + fonts --------------------------------------------------- */

@font-face {
    font-family: "JetBrains Mono";
    src: url("../fonts/JetBrainsMono-Regular.a0bf60ef0f.ttf") format("truetype");
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "lucide";
    src: url("../fonts/lucide.ebcd4c55d7.ttf") format("truetype");
    font-weight: 400;
    font-style: normal;
    font-display: block; /* icon glyphs must not flash as tofu/text */
}

* {
    box-sizing: border-box;
}

/* Browser canvas, scrollbars and form controls follow the site's theme, not
   the OS ("light dark" would follow the OS - light canvas under a dark site).
   The <head> color-scheme meta covers the moment before this file loads. */
html {
    color-scheme: light dark;
}

html[data-theme="dark"] {
    color-scheme: dark;
}

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

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-chrome);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

img,
svg {
    max-width: 100%;
    display: block;
}

a {
    color: inherit;
}

.icon {
    font-family: var(--font-icon);
    font-style: normal;
    line-height: 1;
    display: inline-block;
}

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

/* ---- 2. Layout primitives ------------------------------------------------ */

.container {
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--space-3);
}

.section {
    padding-block: var(--space-6);
}

/* Showcase gets less top padding than other sections - keeps the interactive
   demo close enough to the fold to be visible on ~13" laptop viewports. */
#showcase {
    padding-top: var(--space-4);
}

.section-head {
    max-width: 640px;
    margin-bottom: var(--space-5);
}

/* Used on the showcase section-head so the interactive demo below it sits
   higher on the page - visible without scrolling on ~13" laptop viewports. */
.section-head-tight {
    margin-bottom: var(--space-3);
}

.eyebrow {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent);
    margin: 0 0 var(--space-2);
}

.section-head h2 {
    font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2.1rem);
    margin: 0 0 var(--space-2);
    letter-spacing: -0.01em;
}

.section-head h2 .accent-text,
.section-head p .accent-text {
    color: var(--accent);
}

/* --accent stays fixed-luminance across themes (theming.md) - unreadable as a
   real link's own text color in light mode. Keep the brand tint on the
   underline only, full-contrast --text for the glyphs themselves. */
.section-head p a.accent-text {
    color: var(--text);
    text-decoration-color: var(--accent);
    text-underline-offset: 2px;
}

.section-head p {
    color: var(--dim);
    margin: 0;
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.skip-link {
    position: absolute;
    left: var(--space-2);
    top: -48px;
    background: var(--accent);
    color: var(--on-accent-text);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    font-weight: 600;
    z-index: 100;
    transition: top 0.2s var(--ease);
}

.skip-link:focus {
    top: var(--space-2);
}

/* ---- 3. Header / nav ------------------------------------------------------ */

.site-header {
    position: sticky;
    top: 0;
    z-index: 40;
    height: 64px;
    display: flex;
    align-items: center;
    background: color-mix(in srgb, var(--bg) 88%, transparent);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid transparent;
    transition:
        border-color 0.25s var(--ease),
        background 0.25s var(--ease);
}

.site-header.is-scrolled {
    border-bottom-color: var(--border);
    background: color-mix(in srgb, var(--bg) 96%, transparent);
}

.site-header .container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
}

.brand {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: 600;
    font-size: 15px;
    text-decoration: none;
    letter-spacing: -0.01em;
}

.brand-mark {
    width: 14px;
    height: 14px;
    border-radius: 4px;
    background: var(--accent);
    flex: none;
}

.brand-name {
    font-family: var(--font-mono);
}

/* Visible at every width - below 860px only .nav-pricing shows (Pricing was
   the one link that isn't reachable any other way on mobile now that
   Download lives in the hamburger); Features/Demo rejoin it >=860px below.
   See docs/decisions/mobile-nav.md. */
.main-nav {
    display: flex;
    align-items: center;
    gap: var(--space-4);
}

.main-nav a {
    text-decoration: none;
    color: var(--dim);
    font-size: 14.5px;
    transition: color 0.2s var(--ease);
}

.main-nav a:not(.nav-pricing) {
    display: none;
}

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

.main-nav a.is-current {
    color: var(--text);
    font-weight: 600;
}

.header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.lang-toggle,
.theme-toggle {
    width: 36px;
    height: 36px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text);
    display: grid;
    place-items: center;
    cursor: pointer;
    flex: none;
    transition:
        background 0.2s var(--ease),
        border-color 0.2s var(--ease);
}

.lang-toggle {
    font-family: var(--font-mono);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.lang-toggle:hover {
    background: var(--hover);
}

.theme-toggle:hover {
    background: var(--hover);
}

.theme-toggle svg {
    width: 17px;
    height: 17px;
}

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

/* Full nav + persistent Download only reappear at >=860px (see the media
   query below) - below that, .nav-toggle opens .mobile-nav instead, and
   Download moves into that panel since it's not worth a persistent header
   slot on a small screen (docs/decisions/mobile-nav.md). */
/* .header-actions prefix (not just .nav-download-desktop alone) matters:
   .btn's own `display: inline-flex` is equal specificity and defined later
   in this file, so a bare single-class selector here would silently lose
   the cascade and never actually hide on mobile. */
.header-actions .nav-download-desktop {
    display: none;
}

.nav-toggle {
    width: 36px;
    height: 36px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text);
    display: grid;
    place-items: center;
    cursor: pointer;
    flex: none;
}

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

.nav-toggle svg {
    width: 19px;
    height: 19px;
}

.nav-toggle .icon-close {
    display: none;
}

.nav-toggle[aria-expanded="true"] .icon-menu {
    display: none;
}

.nav-toggle[aria-expanded="true"] .icon-close {
    display: block;
}

/* Sticky, not static - .site-header is sticky too, but a plain sibling
   below it scrolls out of view with the rest of the page past the first
   64px, making the panel only reachable at the very top otherwise. */
.mobile-nav {
    position: sticky;
    top: 64px;
    z-index: 39;
    border-bottom: 1px solid var(--border);
    background: var(--panel);
}

.mobile-nav[hidden] {
    display: none;
}

.mobile-nav .container {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding-block: var(--space-2) var(--space-3);
}

.mobile-nav a:not(.btn) {
    padding: var(--space-2) 0;
    color: var(--dim);
    text-decoration: none;
    font-size: 15.5px;
}

.mobile-nav a.is-current {
    color: var(--text);
    font-weight: 600;
}

.mobile-nav .btn {
    margin-top: var(--space-1);
}

/* ---- 4. Hero -------------------------------------------------------------- */

.hero {
    padding-block: var(--space-5);
    text-align: center;
}

.hero-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--dim);
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 5px 12px;
    margin-bottom: var(--space-3);
}

.hero-badge .dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--green);
    flex: none;
}

.hero h1 {
    font-size: clamp(2.1rem, 1.7rem + 2.6vw, 3.4rem);
    line-height: 1.08;
    letter-spacing: -0.02em;
    margin: 0 0 var(--space-3);
}

.hero h1 .accent-text {
    color: var(--accent);
}

.hero-sub {
    max-width: 560px;
    margin: 0 auto var(--space-4);
    color: var(--dim);
    font-size: 17px;
}

.hero-ctas {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
}

.hero-cta-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-2);
}

.hero-meta {
    font-family: var(--font-mono);
    font-size: 12.5px;
    color: var(--faint);
}

.hero-meta a {
    color: var(--dim);
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* Linux-only: shown by the <head> OS guess (`html[data-platform]`), so it's
   right from the first paint - no JS toggle, no layout shift. */
.hero-guide-link {
    display: none;
    margin: calc(var(--space-2) * -1) 0 0;
    font-size: 14.5px;
}

html[data-platform="linux"] .hero-guide-link {
    display: block;
}

.hero-guide-link a {
    color: var(--text);
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-underline-offset: 3px;
}

.hero-guide-link a:hover {
    color: var(--accent);
    text-decoration-color: var(--accent);
}

/* ---- 5. Buttons + badges -------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 46px;
    padding: 0 20px;
    border-radius: var(--radius-sm);
    font-size: 14.5px;
    font-weight: 600;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    transition:
        transform 0.2s var(--ease),
        background 0.2s var(--ease),
        border-color 0.2s var(--ease);
    white-space: nowrap;
}

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

.btn-primary {
    /* Mirrors theme::primary_button / Palette::on_accent_text - see
       docs/decisions/theming.md. */
    background: var(--accent);
    color: var(--on-accent-text);
}

.btn-primary:hover {
    filter: brightness(1.04);
}

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

.btn-secondary:hover {
    background: var(--hover);
}

.btn svg {
    width: 18px;
    height: 18px;
}

.btn-sm {
    height: 36px;
    padding: 0 14px;
    font-size: 13px;
}

/* ---- 6. Feature grid ------------------------------------------------------ */

.feature-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-3);
}

.feature-card {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
}

/* A colored badge, not a bare glyph - gives each card its own anchor point
   instead of reading as one identical box after another (docs/decisions/
   feature-media.md). Same treatment at every width, not mobile-only. */
.feature-card .icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--accent-soft);
    font-size: 19px;
    color: var(--accent);
    margin-bottom: var(--space-3);
}

.feature-card h3 {
    font-size: 15.5px;
    margin: 0 0 6px;
}

.feature-card p {
    margin: 0;
    color: var(--dim);
    font-size: 15px;
    line-height: 1.6;
}

.feature-card p .accent-text,
.feature-card h3 .accent-text {
    color: var(--accent);
}

/* Same fix as .section-head p a.accent-text above - the trust-card's
   "Enshittification" link is a real link, not decorative emphasis. */
.feature-card h3 a.accent-text {
    color: var(--text);
    text-decoration-color: var(--accent);
    text-underline-offset: 2px;
}

.feature-card .status-pill {
    display: inline-block;
    margin-top: var(--space-2);
    font-family: var(--font-mono);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 2px 8px;
    border-radius: 999px;
}

.status-pill.is-shipped {
    color: var(--green);
    background: color-mix(in srgb, var(--green) 14%, transparent);
}

.status-pill.is-roadmap {
    color: var(--orange);
    background: color-mix(in srgb, var(--orange) 14%, transparent);
}

/* Scoped to .container, not the full-width #trust section itself - a
   full-bleed background here would paint over the ambient-grid decorative
   effect in the side gutters (docs/decisions/ambient-grid.md), which only
   shows through because sections are otherwise transparent. --panel-2 (not
   --panel, which the cards themselves use) keeps the cards visible against
   it. padding-block gives the eyebrow text room to breathe inside the
   panel instead of touching its top edge. */
#trust > .container {
    background: var(--panel-2);
    border-radius: var(--radius-lg);
    padding-block: var(--space-5);
}

/* ---- 7. Feature card flip + demo modal ------------------------------------ */

/* Only the four "Shipped" feature cards get `.is-flippable` (index.html) —
   the roadmap card and the trust-section cards reuse `.feature-card` but
   stay plain, since there's no real demo to show for an unbuilt feature. */
.feature-card.is-flippable {
    background: none;
    border: none;
    padding: 0;
    perspective: 1200px;
    cursor: pointer;
}

.feature-card.is-flippable:focus-visible {
    outline: none; /* moved to the flipper so it traces the visible card, not this 0-size wrapper */
}

/* height: 100% - .feature-card itself stretches to the tallest card in its
   grid row (default grid align-items: stretch), but this inner wrapper
   wouldn't inherit that automatically, so cards with shorter copy would
   visibly shrink-wrap instead of matching their row. */
.feature-card-flipper {
    position: relative;
    height: 100%;
    transition: transform 0.5s var(--ease);
    transform-style: preserve-3d;
}

.feature-card.is-flippable:focus-visible .feature-card-flipper {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--radius-lg);
}

.feature-card.is-flipped .feature-card-flipper {
    transform: rotateY(180deg);
}

.feature-card-face {
    box-sizing: border-box;
    height: 100%;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
    backface-visibility: hidden;
}

.feature-card-front {
    position: relative;
}

.feature-card-back {
    position: absolute;
    inset: 0;
    transform: rotateY(180deg);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    padding: 0;
}

.feature-card-gif {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.feature-card-back-fallback {
    display: none;
    color: var(--faint);
    font-size: 12.5px;
    font-family: var(--font-chrome);
    text-align: center;
    padding: var(--space-3);
}

.feature-card-back.has-no-gif .feature-card-gif {
    display: none;
}

.feature-card-back.has-no-gif .feature-card-back-fallback {
    display: block;
}

.feature-card-play {
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
    width: 30px;
    height: 30px;
    border-radius: 50%;
    border: 1px solid var(--border);
    background: color-mix(in srgb, var(--panel) 80%, transparent);
    color: var(--text);
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: background 0.2s var(--ease), color 0.2s var(--ease), border-color 0.2s var(--ease);
}

.feature-card-play:hover {
    background: var(--accent-soft);
    color: var(--accent);
    border-color: color-mix(in srgb, var(--accent) 35%, transparent);
}

.feature-card-play svg {
    width: 15px;
    height: 15px;
}

/* Discovery hint (feature-cards.js) - previews the flip gesture and pulses
   the play button once, first time the card scrolls into view. */
@keyframes feature-card-nudge {
    0%,
    100% {
        transform: rotateY(0deg);
    }
    30% {
        transform: rotateY(-10deg);
    }
    60% {
        transform: rotateY(6deg);
    }
    80% {
        transform: rotateY(-3deg);
    }
}

.feature-card-flipper.is-nudging {
    animation: feature-card-nudge 1.1s ease-in-out;
}

@keyframes feature-card-play-nudge {
    0% {
        box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent);
    }
    100% {
        box-shadow: 0 0 0 10px color-mix(in srgb, var(--accent) 0%, transparent);
    }
}

.feature-card-play.is-nudging {
    animation: feature-card-play-nudge 0.9s ease-out 2;
}

/* Demo modal — hidden by default via the `hidden` attribute in index.html.
   `[hidden]` must be re-declared here: an author `display` rule on the same
   element always beats the UA stylesheet's default `[hidden]{display:none}`,
   so without this override the modal would stay visible (and eat clicks)
   even while the `hidden` attribute is present. */
.feature-modal {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-3);
}

.feature-modal[hidden] {
    display: none;
}

.feature-modal-backdrop {
    position: absolute;
    inset: 0;
    background: color-mix(in srgb, black 60%, transparent);
}

.feature-modal-dialog {
    position: relative;
    z-index: 1;
    width: min(720px, 100%);
    max-height: 85vh;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: 0 24px 60px -20px var(--shadow-color);
    padding: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.feature-modal-title {
    margin: 0;
    font-size: 16px;
    padding-right: var(--space-5);
}

.feature-modal-media {
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--grid);
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 160px;
}

.feature-modal-gif {
    display: block;
    width: 100%;
    max-height: 65vh;
    object-fit: contain;
}

.feature-modal-fallback {
    display: none;
    color: var(--faint);
    font-size: 13.5px;
    font-family: var(--font-chrome);
    padding: var(--space-5);
    text-align: center;
}

.feature-modal-media.has-no-gif .feature-modal-gif {
    display: none;
}

.feature-modal-media.has-no-gif .feature-modal-fallback {
    display: block;
}

.feature-modal-close {
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
    width: 32px;
    height: 32px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text);
    display: grid;
    place-items: center;
    cursor: pointer;
}

.feature-modal-close:hover {
    background: var(--hover);
}

.feature-modal-close svg {
    width: 16px;
    height: 16px;
}

/* ---- 8. Showcase window chrome ------------------------------------------- */

.showcase-frame {
    border-radius: var(--radius-lg);
    border: 1px solid var(--border);
    overflow: hidden;
    box-shadow: 0 24px 60px -20px var(--shadow-color);
    background: var(--bg);
    /* Isolates the app-faithful design tokens: this subtree always renders in
     the "app" palette below, independent of whatever the marketing shell
     is doing - see docs/decisions/theming.md. */
}

.tr-titlebar {
    height: 32px;
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 12px;
    background: var(--titlebar);
    border-bottom: 1px solid var(--border);
}

.tr-dots {
    display: flex;
    gap: 6px;
}

.tr-dots span {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--faint);
    opacity: 0.6;
}

.tr-titlebar-title {
    font-size: 12px;
    color: var(--dim);
    font-weight: 500;
    letter-spacing: 0.2px;
    margin-inline: auto;
    font-family: var(--font-chrome);
}

.tr-menubar {
    height: 28px;
    flex: none;
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: 0 14px;
    background: var(--panel);
    border-bottom: 1px solid var(--border);
    font-size: 12.5px;
    color: var(--faint);
    overflow-x: auto;
}

.tr-tabstrip {
    height: 34px;
    flex: none;
    display: flex;
    align-items: stretch;
    background: var(--panel-2);
    border-bottom: 1px solid var(--border);
    overflow-x: auto;
}

.tr-tab {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 14px;
    font-size: 12.5px;
    color: var(--dim);
    border-right: 1px solid var(--border);
    white-space: nowrap;
    flex: none;
}

.tr-tab.is-active {
    background: var(--grid);
    color: var(--text);
    box-shadow: inset 0 2px 0 var(--accent);
}

.tr-tab-dirty {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--dim);
}

.tr-tab-add {
    width: 34px;
    display: grid;
    place-items: center;
    color: var(--faint);
    font-size: 16px;
    flex: none;
}

/* ---- 9. Toolbar ------------------------------------------------------------ */

.tr-toolbar {
    position: relative;
    min-height: 46px;
    flex: none;
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: 0 12px;
    background: var(--panel);
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
    row-gap: 4px;
}

.tr-toolbar-group {
    display: flex;
    align-items: center;
    gap: 2px;
}

.tr-group-label {
    font-family: var(--font-mono);
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--faint);
    margin-right: 4px;
}

.tr-divider {
    width: 1px;
    align-self: stretch;
    margin-block: 8px;
    background: var(--border);
    flex: none;
}

/* Pushes everything from here to the toolbar's right edge (Find/Go to/Order
   by/Group by/Filter), matching the real app's toolbar layout. */
.tr-toolbar-right-start {
    margin-left: auto;
}

.tr-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 30px;
    padding: 0 6px;
    border-radius: 6px;
    border: none;
    background: transparent;
    color: var(--text);
    font-family: var(--font-chrome);
    font-size: 12.5px;
    cursor: pointer;
    transition:
        background 0.15s var(--ease),
        color 0.15s var(--ease);
    position: relative;
}

.tr-btn .icon {
    font-size: 15px;
}

.tr-btn .chev {
    font-size: 10px;
    margin-left: 2px;
    color: var(--faint);
}

.tr-btn:hover,
.tr-btn.is-active {
    background: var(--accent-soft);
    color: var(--accent);
}

.tr-btn.is-active .chev {
    color: var(--accent);
}

.tr-btn[disabled] {
    color: var(--faint);
    cursor: not-allowed;
    background: none;
}

.tr-btn[disabled]:hover {
    background: none;
}

/* ---- 10. Grid ---------------------------------------------------------------- */

.tr-grid-scroll {
    overflow: auto;
    max-height: 420px;
    background: var(--grid);
}

.tr-grid {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--font-mono);
    font-size: 12px;
}

.tr-grid thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--panel-2);
    color: var(--text);
    font-weight: 500;
    padding: 6px 8px;
    height: 26px;
    border-bottom: 1px solid var(--border);
    border-right: 1px solid var(--border);
    user-select: none;
    white-space: nowrap;
}

/* `<th>` must keep its default table-cell display for the header row to lay
   out horizontally - the drag/label/sort flex layout lives on this inner
   wrapper instead of the cell itself. */
.tr-col-head {
    display: flex;
    align-items: center;
    gap: 6px;
}

.tr-grid thead th.tr-col-gutter {
    cursor: default;
}

/* Three independent zones - drag (reorder), label (click selects the
   column), sort chevron (click stacks/toggles) - not one whole-header
   click target, matching the real app. */
.tr-col-drag {
    cursor: grab;
    color: var(--faint);
    font-size: 11px;
    flex: none;
}

.tr-col-drag:hover {
    color: var(--dim);
}

.tr-col-label {
    cursor: pointer;
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tr-col-label:hover {
    color: var(--accent);
}

.tr-col-sort {
    cursor: pointer;
    font-size: 10px;
    color: var(--faint);
    flex: none;
}

.tr-col-sort.is-active,
.tr-col-sort:hover {
    color: var(--accent);
}

.tr-grid tbody td {
    padding: 6px 8px;
    border-bottom: 1px solid var(--border);
    border-right: 1px solid var(--border);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 220px;
}

.tr-grid.is-wrapped tbody td {
    white-space: normal;
    overflow-wrap: anywhere;
}

.tr-grid tbody tr.tr-row-even td {
    background: var(--grid);
}

.tr-grid tbody tr.tr-row-odd td {
    background: var(--grid-alt);
}

.tr-grid tbody tr:hover td {
    background: var(--hover);
}

.tr-grid tbody tr.is-row-selected td {
    background: var(--line-selection);
}

.tr-grid tbody tr td.is-cell-selected {
    background: var(--block-selection);
    outline: 1px solid var(--accent);
    outline-offset: -1px;
}

.tr-col-gutter {
    color: var(--gutter-text);
    background: var(--gutter) !important;
    text-align: right;
    width: 1%;
    cursor: pointer;
}

.tr-grid tbody td.tr-col-gutter:hover {
    background: var(--hover) !important;
}

.tr-col-id {
    color: var(--dim);
}

.tr-group-header td {
    background: color-mix(
        in srgb,
        var(--panel-2) 75%,
        var(--purple) 25%
    ) !important;
    color: var(--text);
    font-weight: 600;
    cursor: pointer;
}

.tr-group-header .chev {
    color: var(--purple);
    margin-right: 6px;
    font-size: 10px;
}

.tr-group-header .count {
    color: var(--dim);
    font-weight: 400;
    margin-left: 6px;
}

.tr-group-agg {
    margin-left: 14px;
    display: inline-flex;
    gap: 10px;
}

.tr-group-header .agg-label {
    text-transform: uppercase;
    font-size: 9px;
    letter-spacing: 0.4px;
    color: var(--faint);
    font-weight: 400;
    margin-right: 3px;
}

.tr-group-header .agg-value {
    color: var(--dim);
    font-weight: 400;
}

mark.tr-match {
    background: var(--match-bg);
    color: inherit;
    border-radius: 2px;
    padding: 0 1px;
}

mark.tr-match.is-current {
    background: var(--current-match-bg);
}

/* Diverging heatmap: high -> blue, low -> red, set inline per-cell via JS
   custom property --heat (0..1) so the scale stays data-driven. */
.tr-cell-heat {
    background: color-mix(
        in srgb,
        var(--blue) calc(var(--heat, 0.5) * 100%),
        var(--red) calc((1 - var(--heat, 0.5)) * 100%)
    ) !important;
    color: var(--panel-2);
}

:root[data-theme="light"] .tr-cell-heat {
    color: var(--text);
}

.tr-empty-row td {
    text-align: center;
    color: var(--faint);
    padding: 24px;
    font-family: var(--font-chrome);
}

/* ---- 11. Status bar --------------------------------------------------------- */

.tr-statusbar {
    min-height: 30px;
    flex: none;
    display: flex;
    align-items: stretch;
    background: var(--panel-2);
    font-family: var(--font-mono);
    font-size: 11.5px;
    flex-wrap: wrap;
}

.tr-status-zone {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 12px;
    min-height: 30px;
}

.tr-status-left {
    border-right: 1px solid var(--border);
    color: var(--dim);
    flex-wrap: wrap;
}

.tr-status-left .agg-label {
    text-transform: uppercase;
    font-size: 9.5px;
    letter-spacing: 0.5px;
    color: var(--faint);
    margin-right: 3px;
}

.tr-status-left .agg-value {
    color: var(--text);
}

.tr-status-center {
    flex: 1;
    gap: 7px;
    flex-wrap: wrap;
    min-width: 140px;
}

.tr-rules-label {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--faint);
}

.tr-rules-empty {
    font-style: italic;
    color: var(--faint);
}

.tr-status-right {
    border-left: 1px solid var(--border);
    color: var(--faint);
    gap: 10px;
    margin-left: auto;
}

.tr-badge {
    padding: 2px 6px;
}

/* Rule pill (sort / filter / group) - tint@8% fill + tint@35% border. */
.tr-pill {
    display: inline-flex;
    align-items: center;
    height: 20px;
    border-radius: 999px;
    font-size: 11px;
    overflow: hidden;
    border: 1px solid;
}

.tr-pill-icon,
.tr-pill-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 0 6px;
    cursor: pointer;
}

.tr-pill-label {
    padding: 0 2px;
    white-space: nowrap;
}

.tr-pill-close {
    /* ICON.CLOSE is a lucide-font codepoint - without this it renders as
       tofu, since only .icon sets font-family: var(--font-icon). */
    font-family: var(--font-icon);
    cursor: pointer;
    opacity: 0.75;
}

.tr-pill-close:hover {
    opacity: 1;
}

.tr-pill.is-sort {
    background: color-mix(in srgb, var(--accent) 8%, transparent);
    border-color: color-mix(in srgb, var(--accent) 35%, transparent);
    color: var(--accent);
}

.tr-pill.is-filter {
    background: color-mix(in srgb, var(--green) 8%, transparent);
    border-color: color-mix(in srgb, var(--green) 35%, transparent);
    color: var(--green);
}

.tr-pill.is-group {
    background: color-mix(in srgb, var(--purple) 8%, transparent);
    border-color: color-mix(in srgb, var(--purple) 35%, transparent);
    color: var(--purple);
}

/* ---- 12. Search bar ---------------------------------------------------------- */

.tr-searchbar {
    display: none;
    min-height: 30px;
    align-items: center;
    gap: 10px;
    padding: 0 12px;
    background: var(--panel-2);
    border-top: 1px solid var(--border);
    font-family: var(--font-chrome);
}

.tr-searchbar.is-open {
    display: flex;
}

.tr-searchbar input {
    flex: 1;
    min-width: 0;
    background: var(--grid);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 5px 8px;
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 12px;
}

.tr-searchbar input:focus {
    outline: none;
    border-color: var(--accent);
}

.tr-search-count {
    font-size: 11.5px;
    color: var(--faint);
    font-family: var(--font-mono);
    white-space: nowrap;
}

.tr-search-btn {
    /* Same tofu-glyph fix as .tr-pill-close - ICON.CLOSE needs the lucide font. */
    font-family: var(--font-icon);
    background: none;
    border: none;
    color: var(--faint);
    cursor: pointer;
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: 5px;
}

.tr-search-btn:hover {
    background: var(--hover);
    color: var(--text);
}

/* ---- 13. Popovers / dropdowns ------------------------------------------------ */

.tr-popover-anchor {
    position: relative;
}

.tr-popover {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    min-width: 190px;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: 7px;
    box-shadow: 0 10px 30px var(--shadow-color);
    padding: 5px;
    z-index: 30;
    display: none;
}

.tr-popover.is-open {
    display: block;
}

.tr-popover-title {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--faint);
    padding: 5px 8px 6px;
}

.tr-popover-row {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 5px 8px;
    border-radius: 5px;
    background: none;
    border: none;
    color: var(--text);
    font-family: var(--font-chrome);
    font-size: 12.5px;
    text-align: left;
    cursor: pointer;
}

.tr-popover-row:hover {
    background: var(--accent-soft);
    color: var(--accent);
}

.tr-popover-row.is-selected {
    color: var(--accent);
}

.tr-popover-row .sample {
    margin-left: auto;
    color: var(--faint);
    font-size: 11px;
}

/* Filter builder - single hardcoded-shape rule, not a real multi-filter
   stack (docs/decisions/demo-table.md). SQL query tab is present for
   fidelity but is itself just another gated "coming soon" trigger. */
/* The Filter button's own anchor div opts out of .tr-popover-anchor's
   position: relative (see .tr-filter-anchor below) so this popover escapes
   up to position against .tr-toolbar instead - anchoring to the Filter
   button itself overflowed off the left edge on narrower widths where the
   toolbar wraps and the button no longer sits near the toolbar's right
   edge (see docs/decisions/demo-table.md). */
.tr-filter-popover {
    left: auto;
    right: 12px;
    min-width: 280px;
    padding: 0;
}

.tr-filter-anchor {
    position: static;
}

.tr-filter-gated {
    padding: 10px 10px 12px;
    color: var(--dim);
    font-size: 12.5px;
    font-family: var(--font-chrome);
    max-width: 260px;
}

.tr-filter-tabs {
    display: flex;
    gap: var(--space-3);
    padding: 8px 10px 0;
    border-bottom: 1px solid var(--border);
}

.tr-filter-tab {
    font-size: 12px;
    font-family: var(--font-chrome);
    color: var(--dim);
    padding-bottom: 7px;
    cursor: pointer;
    border-bottom: 2px solid transparent;
}

.tr-filter-tab.is-active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

.tr-filter-row {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 10px;
}

.tr-filter-select,
.tr-filter-value {
    background: var(--panel);
    border: 1px solid var(--border);
    color: var(--text);
    font-family: var(--font-chrome);
    font-size: 12px;
    border-radius: 5px;
    padding: 4px 6px;
    height: 28px;
}

.tr-filter-value {
    flex: 1;
    min-width: 0;
}

/* ---- 14. Download section ---------------------------------------------------- */

.download-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-3);
}

.download-card {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    transition: border-color 0.2s var(--ease);
}

.download-card-head {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.download-card .icon {
    font-size: 24px;
    color: var(--text);
}

.download-card h3 {
    margin: 0;
    font-size: 16px;
}

.download-card p {
    margin: 0;
    color: var(--dim);
    font-size: 14.5px;
    line-height: 1.5;
}

.download-card .meta {
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--faint);
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* `> .btn` for the single-format cards, `.dl-actions` for the Linux card's
   two-button group - whichever is the card's last flex child is what gets
   pinned to the bottom, so all three cards' buttons still line up. */
.download-card > .btn,
.download-card .dl-actions {
    margin-top: auto;
}

.download-card .btn {
    width: 100%;
}

.download-card .dl-actions {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.dl-badge {
    align-self: flex-start;
    font-family: var(--font-mono);
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--accent);
    background: var(--accent-soft);
    border-radius: 999px;
    padding: 2px 9px;
}

.download-card .dl-guide {
    font-size: 13px;
    margin-top: calc(var(--space-1) * -1);
}

.download-card .dl-guide a {
    color: var(--dim);
    text-decoration: underline;
    text-decoration-color: var(--border);
    text-underline-offset: 3px;
}

.download-card .dl-guide a:hover {
    color: var(--accent);
    text-decoration-color: var(--accent);
}

.download-note {
    text-align: center;
    color: var(--faint);
    font-size: 13px;
    margin-top: var(--space-3);
}

.download-note a {
    color: var(--dim);
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* Post-download instruction on the .../latest/linux-deb landing page
   (worker/index.js) - a .deb needs one more command after it saves, unlike
   every other format. Not used anywhere in this repo's own HTML. */
.deb-hint {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-3);
    color: var(--dim);
    font-size: 13.5px;
}

.deb-hint code {
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--text);
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 6px 12px;
}

/* Manifest-fetch-failed state on the downloads.tabularasa.cl/latest/<platform>
   landing page (worker/index.js) - not used anywhere in this repo's own HTML. */
.tr-error {
    color: var(--red);
    max-width: 40ch;
    margin-inline: auto;
}

/* ---- 15. Footer --------------------------------------------------------------- */

.site-footer {
    border-top: 1px solid var(--border);
    padding-block: var(--space-5);
    margin-top: var(--space-6);
}

.footer-grid {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.footer-brand {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
    font-family: var(--font-mono);
}

.footer-brand .brand-mark {
    width: 12px;
    height: 12px;
}

.footer-tagline {
    color: var(--faint);
    font-size: 13.5px;
    margin: 6px 0 0;
}

/* A fixed 3-column grid at every width, not a flex-wrap that reflows
   unpredictably - 3 columns holds up fine down to ~340px since each column
   is only single words or a short link list. */
.footer-links {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-3) var(--space-2);
}

.footer-col h4 {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--faint);
    margin: 0 0 var(--space-2);
}

.footer-col ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.footer-col a {
    text-decoration: none;
    color: var(--dim);
    font-size: 14px;
}

.footer-col a:hover {
    color: var(--text);
}

.footer-stub {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--faint);
    font-size: 14px;
    cursor: default;
}

.footer-stub-tag {
    font-family: var(--font-mono);
    font-size: 9.5px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--faint);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 1px 6px;
}

.footer-bottom {
    margin-top: var(--space-4);
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    justify-content: space-between;
    color: var(--faint);
    font-size: 12.5px;
}

.footer-bottom a {
    color: var(--text);
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* ---- 16. Scrollbars (app-faithful, ~13px, thumb = border -> faint) ------------ */

.tr-grid-scroll::-webkit-scrollbar,
.tr-menubar::-webkit-scrollbar,
.tr-tabstrip::-webkit-scrollbar {
    width: 13px;
    height: 13px;
}

.tr-grid-scroll::-webkit-scrollbar-thumb,
.tr-menubar::-webkit-scrollbar-thumb,
.tr-tabstrip::-webkit-scrollbar-thumb {
    background: var(--border);
    border-radius: 7px;
    border: 3px solid transparent;
    background-clip: content-box;
}

.tr-grid-scroll::-webkit-scrollbar-thumb:hover,
.tr-menubar::-webkit-scrollbar-thumb:hover,
.tr-tabstrip::-webkit-scrollbar-thumb:hover {
    background: var(--faint);
    background-clip: content-box;
}

.tr-grid-scroll::-webkit-scrollbar-corner {
    background: transparent;
}

/* ---- 17. Responsive ------------------------------------------------------------ */

@media (min-width: 640px) {
    .feature-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .download-grid {
        grid-template-columns: repeat(3, 1fr);
    }

    .footer-grid {
        flex-direction: row;
        justify-content: space-between;
    }

    .footer-links {
        gap: var(--space-6);
    }
}

@media (min-width: 860px) {
    .main-nav a:not(.nav-pricing) {
        display: inline;
    }

    .header-actions .nav-download-desktop {
        display: inline-flex;
    }

    .nav-toggle,
    .mobile-nav {
        display: none;
    }

    .feature-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* ---- 18. Reduced motion / accessibility ----------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    * {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}

/* ---- 19. Ambient background grid (decorative) ------------------------------------ */

/* Only shown once the gutters beside the centered content column are wide
   enough to be worth decorating - see docs/decisions/ambient-grid.md for the
   1300px breakpoint choice. ambient-grid.js no-ops below this width too. */
.ambient-grid {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    display: none;
}

@media (min-width: 1300px) {
    .ambient-grid {
        display: block;
    }
}

.ambient-grid-panel {
    position: absolute;
    top: 0;
    bottom: 0;
    width: calc((100vw - var(--container-max)) / 2);
    overflow: hidden;
}

.ambient-grid-panel.is-left {
    left: 0;
    mask-image: linear-gradient(to right, black, transparent);
    -webkit-mask-image: linear-gradient(to right, black, transparent);
}

.ambient-grid-panel.is-right {
    right: 0;
    mask-image: linear-gradient(to left, black, transparent);
    -webkit-mask-image: linear-gradient(to left, black, transparent);
}

/* Oversized + tilted in 3D so it reads as a table extending into the
   distance. Static and decorative only - the interactive part is the flat
   .ambient-grid-glow layer below, deliberately NOT given the same
   transform (see the decision doc for why). */
.ambient-grid-pattern {
    position: absolute;
    inset: -20% -70%;
    background-image: repeating-linear-gradient(
            var(--border) 0 1px,
            transparent 1px 44px
        ),
        repeating-linear-gradient(
            90deg,
            var(--border) 0 1px,
            transparent 1px 44px
        );
    opacity: 0.5;
}

.ambient-grid-panel.is-left .ambient-grid-pattern {
    transform: perspective(600px) rotateY(58deg);
    transform-origin: right center;
}

.ambient-grid-panel.is-right .ambient-grid-pattern {
    transform: perspective(600px) rotateY(-58deg);
    transform-origin: left center;
}

/* Mouse-tracked glow, positioned via --gx/--gy (ambient-grid.js). Defaults
   to off-screen so there's no stray glow in a corner before the first
   pointermove. */
.ambient-grid-glow {
    position: absolute;
    inset: 0;
    background: radial-gradient(
        circle 200px at var(--gx, -9999px) var(--gy, -9999px),
        var(--accent-soft),
        transparent 70%
    );
}

/* ---- 20. Pricing page ------------------------------------------------------------- */

.pricing-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-3);
    margin-bottom: var(--space-5);
    align-items: stretch;
}

@media (min-width: 640px) {
    .pricing-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* Cards are the actual decision point now (title, price, highlights, CTA) -
   the table below is supporting detail, not a duplicate action surface. */
.pricing-card {
    display: flex;
    flex-direction: column;
}

.pricing-card h2 {
    font-size: 1.3rem;
    margin: 0;
}

.pricing-card:not(.is-enterprise) h2 {
    color: var(--accent);
}

.pricing-card.is-enterprise {
    border-color: var(--accent-soft);
}

.pricing-card .pricing-price {
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    margin: var(--space-2) 0;
}

.pricing-card:not(.is-enterprise) .pricing-price {
    color: var(--accent);
}

.pricing-highlights {
    list-style: none;
    margin: var(--space-3) 0 var(--space-3);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.pricing-highlights li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 14px;
    color: var(--dim);
}

.pricing-highlights .pricing-check {
    margin-top: 2px;
    flex-shrink: 0;
}

/* margin-top: auto pins this to the bottom of the (equal-height, stretched)
   card regardless of how much the tagline/highlights above it wrap - the
   only way both cards' primary buttons reliably land on the same line. */
.pricing-card-actions {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin-top: auto;
    padding-top: var(--space-4);
    border-top: 1px solid var(--border);
}

.pricing-card-actions .btn,
.pricing-card-actions .btn-stub {
    width: 100%;
}

/* Standalone, below both cards - not tied to the Personal tier specifically,
   and out of each card's flex flow so the Download/Contact buttons above
   still land on the same line (docs/decisions/pricing.md). */
.pricing-donate-standalone {
    text-align: center;
    margin: 0 0 var(--space-5);
    font-size: 13.5px;
    color: var(--faint);
}

.pricing-contact-line {
    max-width: 760px;
    margin: var(--space-4) auto 0;
    text-align: right;
    font-size: 1.4rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--text);
}

.pricing-contact-line a {
    color: var(--accent);
    text-decoration: none;
}

.pricing-contact-line a:hover,
.pricing-contact-line a:focus-visible {
    text-decoration: underline;
}

/* Generic - reused for the inline donate link in the download section
   (index.html) as well as the standalone one here, so both read as the
   same quiet, non-competing affordance instead of two different treatments. */
.donate-link {
    color: var(--dim);
    text-decoration: underline;
    text-decoration-color: var(--border);
    text-underline-offset: 3px;
}

.donate-link:hover {
    color: var(--accent);
    text-decoration-color: var(--accent);
}

.pricing-donate-standalone .donate-link {
    margin-left: 4px;
}

.pricing-table-scroll {
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    margin-bottom: var(--space-5);
    max-width: 760px;
    margin-inline: auto;
}

.pricing-table {
    width: 100%;
    min-width: 480px;
    border-collapse: collapse;
    background: var(--panel);
}

.pricing-table th,
.pricing-table td {
    padding: var(--space-2) var(--space-3);
    text-align: left;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
}

.pricing-table th:first-child,
.pricing-table td:first-child {
    width: 46%;
}

.pricing-table th:not(:first-child),
.pricing-table td:not(:first-child) {
    width: 27%;
    text-align: center;
}

.pricing-table th {
    font-family: var(--font-mono);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text);
    font-weight: 700;
    background: var(--panel-2);
}

.pricing-table th:not(:first-child) {
    color: var(--accent);
}

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

.pricing-check {
    display: inline-flex;
    color: var(--accent);
}

/* "Not included" twin of .pricing-check - deliberately --faint, not --red:
   a tier not having something isn't an error state. */
.pricing-cross {
    display: inline-flex;
    color: var(--faint);
}

.pricing-cross svg,
.pricing-check svg {
    width: 18px;
    height: 18px;
    flex: none;
}

/* Direct support is the one line that genuinely differs between the tiers -
   tinted with the app's --orange (docs/decisions/pricing.md) so it reads as
   the differentiator rather than getting lost among the accent checks. */
.pricing-table tr.is-support th,
.pricing-highlights li.is-support {
    color: var(--orange);
}

.pricing-table tr.is-support .pricing-check,
.pricing-highlights li.is-support .pricing-check {
    color: var(--orange);
}

/* Honest stub, same convention as .footer-stub - not a real destination
   yet, styled to look intentionally inert rather than broken. */
.btn-stub {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 46px;
    padding: 0 20px;
    border-radius: var(--radius-sm);
    font-size: 14.5px;
    font-weight: 600;
    border: 1px dashed var(--border);
    color: var(--faint);
    cursor: not-allowed;
    white-space: nowrap;
}

/* ---- 21. Linux install guide page (linux.html) ---------------------------- */

.guide {
    max-width: 780px;
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

/* Left-aligned intro, same 780px column as the cards below it. */
.guide-hero {
    max-width: 780px;
    padding-bottom: var(--space-4);
    text-align: left;
}

.guide-hero .hero-sub {
    max-width: none;
    margin: 0;
    font-size: 19px;
    line-height: 1.6;
}

.guide-card {
    position: relative;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
}

/* Recommended path: a full accent outline (no gradient - not part of the
   site's visual language). */
.guide-card.is-primary {
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
}

.guide-card-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}

/* Same accent-badge language as .feature-card .icon (mobile-polish.md). */
.guide-card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent);
    flex: none;
}

.guide-card-icon svg {
    width: 19px;
    height: 19px;
}

.guide-card h2 {
    margin: 0;
    font-size: 1.15rem;
    letter-spacing: -0.01em;
}

.guide-badge {
    font-family: var(--font-mono);
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--accent);
    background: var(--accent-soft);
    border: 1px solid var(--accent-soft);
    border-radius: 999px;
    padding: 3px 10px;
}

.guide-card p {
    margin: 0;
    color: var(--dim);
    font-size: 14.5px;
    line-height: 1.65;
}

/* Real numbered steps. The counter lives on the <ol> so the numbers can't
   drift out of sync with the markup the way a hardcoded label would. */
.guide-steps {
    counter-reset: guide-step;
    list-style: none;
    margin: var(--space-4) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.guide-steps > li {
    position: relative;
    padding-left: 38px;
}

.guide-steps > li::before {
    counter-increment: guide-step;
    content: counter(guide-step);
    position: absolute;
    left: 0;
    top: -2px;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--on-accent-text);
    font-family: var(--font-mono);
    font-size: 12.5px;
    font-weight: 700;
    display: grid;
    place-items: center;
}

/* A step's own instruction line, and a plain section label elsewhere on the
   page - both need the extra class to outrank `.guide-card p`. */
.guide-card .guide-step,
.guide-card .guide-label {
    color: var(--text);
    font-weight: 600;
    font-size: 15px;
}

.guide-card .guide-label {
    margin-top: var(--space-4);
}

.guide-card .guide-step {
    margin-bottom: var(--space-3);
}

.guide-card .guide-step + p {
    margin-bottom: var(--space-3);
}

.guide-hero code,
.guide-card code:not(pre code) {
    font-family: var(--font-mono);
    font-size: 0.9em;
    padding: 1px 6px;
    border-radius: var(--radius-sm, 4px);
    background: var(--panel);
    border: 1px solid var(--border);
    color: var(--text);
}

.guide-card strong {
    color: var(--text);
    font-weight: 600;
}

.guide-card .guide-note {
    margin-top: var(--space-2);
    font-size: 13px;
    color: var(--faint);
}

/* The secondary "prefer your browser" escape hatch under the deb step's
   terminal commands - same quiet-link treatment as .donate-link/.dl-guide. */
.guide-card .guide-alt {
    margin-top: var(--space-2);
    font-size: 13px;
    color: var(--faint);
}

.guide-card .guide-alt a {
    color: var(--dim);
    text-decoration: underline;
    text-decoration-color: var(--border);
    text-underline-offset: 3px;
}

.guide-card .guide-alt a:hover {
    color: var(--accent);
    text-decoration-color: var(--accent);
}

.guide-list {
    margin: var(--space-2) 0 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.guide-list li {
    position: relative;
    padding-left: 22px;
    color: var(--dim);
    font-size: 14.5px;
    line-height: 1.65;
}

.guide-list li::before {
    content: "";
    position: absolute;
    left: 4px;
    top: 9px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
}

.guide-dl {
    display: flex;
    width: fit-content;
    margin: var(--space-3) auto;
}

/* One gap after every code block, whatever text/label/title follows. */
.guide-card .guide-code + p {
    margin-top: var(--space-3);
}

/* ---- Terminal-style code block ---- */

.guide-code {
    margin-top: var(--space-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--grid);
}

.guide-code-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: 5px 6px 5px var(--space-3);
    background: var(--titlebar);
    border-bottom: 1px solid var(--border);
}

.guide-code-lang {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--gutter-text);
}

.guide-code pre {
    margin: 0;
    padding: var(--space-3);
    overflow-x: auto;
}

/* `white-space: normal` on the <code> (and `pre` only on each .ln) is load-
   bearing: the newlines *between* the line spans stay in textContent - so the
   clipboard gets real line breaks - while normal white-space processing drops
   them as whitespace-only boxes between blocks, instead of rendering every
   command double-spaced. */
.guide-code code {
    font-family: var(--font-mono);
    font-size: 13px;
    line-height: 1.7;
    color: var(--text);
    white-space: normal;
}

/* The `$` is a ::before, so it's never part of code.textContent and can't end
   up in what copy-code.js puts on the clipboard. Continuation lines keep the
   same glyph, invisible, purely to stay aligned under the line above. */
.guide-code .ln {
    display: block;
    white-space: pre;
    width: max-content;
    min-width: 100%;
}

.guide-code .ln::before {
    content: "$";
    color: var(--green);
    margin-right: 10px;
    user-select: none;
}

.guide-code .ln.is-cont::before {
    color: transparent;
}

.guide-copy {
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    background: transparent;
    color: var(--dim);
    display: grid;
    place-items: center;
    cursor: pointer;
    flex: none;
}

.guide-copy:hover {
    background: var(--hover);
    border-color: var(--border);
    color: var(--text);
}

.guide-copy .icon-copied,
.guide-code.is-copied .guide-copy .icon-copy {
    display: none;
}

.guide-code.is-copied .guide-copy {
    color: var(--green);
}

.guide-code.is-copied .guide-copy .icon-copied {
    display: block;
}

.guide-back {
    text-align: center;
    margin: var(--space-2) 0 0;
    font-size: 13.5px;
}

@media (min-width: 640px) {
    .guide-card {
        padding: var(--space-5);
    }
}
