/* ==========================================================================
   Public website layout
   Header, hero, cards, note reading page, sidebars, footer.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */
/* Taller header on laptops and desktops - the compact 56px bar left the nav,
   search and buttons crammed onto one thin line. */
@media (min-width: 992px) {
    :root { --header-h: 66px; }
}

.site-header {
    position: sticky;
    top: 0;
    z-index: 1030;
    background: color-mix(in srgb, var(--surface) 86%, transparent);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid var(--border);
    box-shadow: 0 8px 24px -20px rgba(15, 23, 42, .55);
}
[data-theme="dark"] .site-header {
    box-shadow: 0 8px 24px -18px rgba(0, 0, 0, .8);
}
/* Browsers without backdrop-filter get an opaque bar rather than a see-through
   one that lets page content bleed through while scrolling. */
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
    .site-header { background: var(--surface); }
}
.header-inner {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: var(--sp-3);
    height: var(--header-h);
}
@media (min-width: 992px) {
    .header-inner { gap: var(--sp-4); }
}

.site-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1.08rem;
    font-weight: 800;
    color: var(--text);
    letter-spacing: -.02em;
    white-space: nowrap;
    flex-shrink: 0;
}
.site-brand:hover { color: var(--brand); text-decoration: none; }
.site-brand img { height: 32px; width: auto; }
.brand-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px; height: 34px;
    background: linear-gradient(135deg, color-mix(in srgb, var(--brand) 84%, #fff), var(--brand-dark));
    color: #fff;
    border-radius: 10px;
    font-size: .88rem;
    font-weight: 800;
    letter-spacing: .01em;
    box-shadow: 0 6px 14px -6px color-mix(in srgb, var(--brand) 75%, transparent);
    transition: transform .18s ease, box-shadow .18s ease;
}
.site-brand:hover .brand-mark {
    transform: translateY(-1px);
    box-shadow: 0 9px 18px -6px color-mix(in srgb, var(--brand) 80%, transparent);
}

.main-nav {
    display: flex;
    align-items: center;
    gap: 2px;
    margin-left: auto;
    min-width: 0;
}
.main-nav a {
    position: relative;
    display: inline-flex;
    align-items: center;
    padding: 8px 13px;
    border-radius: 9px;
    color: var(--text);
    font-size: .9rem;
    font-weight: 600;
    white-space: nowrap;
    transition: color .16s ease, background-color .16s ease;
}
.main-nav a:hover { background: var(--surface-2); color: var(--brand); text-decoration: none; }
.main-nav a.is-active { color: var(--brand); background: var(--brand-light); font-weight: 700; }
[data-theme="dark"] .main-nav a.is-active { background: var(--surface-2); }

/* A short accent bar under the current item so the active page is readable at
   a glance instead of relying on the pale tint alone. */
.main-nav a.is-active::after,
.nav-parent.is-active::after {
    content: "";
    position: absolute;
    left: 13px; right: 13px; bottom: 3px;
    height: 2px;
    border-radius: 2px;
    background: var(--brand);
    opacity: .6;
}

/* Parent items with children collapse into a dropdown instead of spilling
   every child across the header as a sibling link. */
.nav-item { position: relative; }
.nav-parent {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 8px 13px;
    border: 0;
    border-radius: 9px;
    background: none;
    color: var(--text);
    font-family: inherit;
    font-size: .9rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: color .16s ease, background-color .16s ease;
}
.nav-parent:hover { background: var(--surface-2); color: var(--brand); }
.nav-parent.is-active { color: var(--brand); background: var(--brand-light); font-weight: 700; }
[data-theme="dark"] .nav-parent.is-active { background: var(--surface-2); }
.nav-caret { font-size: .6rem; line-height: 1; opacity: .75; transition: transform .15s ease; }
.nav-parent[aria-expanded="true"] .nav-caret { transform: rotate(180deg); }
.main-nav .nav-dropdown { left: 0; right: auto; min-width: 190px; }

/* Mobile: children sit indented under their parent. */
.mobile-nav-sub { padding-left: var(--sp-4); border-left: 2px solid var(--border); margin: 4px 0 4px 12px; }
.mobile-nav-sub a { font-size: .95rem; color: var(--text-muted); }
.mobile-nav-sub a:last-child { border-bottom: 0; }

.header-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
    flex-shrink: 0;
}
.main-nav + .header-actions { margin-left: var(--sp-3); }

.header-search {
    position: relative;
    width: min(250px, 24vw);
    transition: width .2s ease;
}
.header-search input {
    width: 100%;
    height: 38px;
    padding: 0 14px 0 38px;
    border: 1px solid transparent;
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text);
    font-size: .875rem;
    transition: background-color .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.header-search input::placeholder { color: var(--text-soft); }
.header-search input:hover { border-color: var(--border-strong); }
.header-search:focus-within { width: min(310px, 30vw); }
.header-search input:focus {
    background: var(--surface);
    border-color: var(--brand);
    outline: none;
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand) 16%, transparent);
}
.header-search .search-icon {
    position: absolute;
    left: 13px; top: 50%;
    display: flex;
    transform: translateY(-50%);
    color: var(--text-soft);
    pointer-events: none;
    transition: color .16s ease;
}
.header-search .search-icon svg { width: 16px; height: 16px; display: block; }
.header-search:focus-within .search-icon { color: var(--brand); }

.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px; height: 38px;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: var(--surface-2);
    color: var(--text-muted);
    cursor: pointer;
    font-size: 1.05rem;
    line-height: 1;
    flex-shrink: 0;
    transition: color .16s ease, background-color .16s ease, border-color .16s ease, transform .16s ease;
}
.theme-toggle:hover {
    color: var(--brand);
    background: var(--brand-light);
    border-color: color-mix(in srgb, var(--brand) 40%, transparent);
    transform: translateY(-1px);
}

/* Hairline between the search / theme controls and the account buttons. */
.header-divider {
    width: 1px;
    height: 24px;
    margin: 0 2px;
    background: var(--border);
    flex-shrink: 0;
}
[data-theme="dark"] .header-divider { background: var(--border-strong); }
@media (max-width: 575px) {
    .header-divider { display: none; }
}

/* Pill-shaped account buttons, matching the rounded search and theme toggle. */
.header-actions .btn-sm {
    min-height: 38px;
    padding: 8px 17px;
    border-radius: 999px;
    font-size: .86rem;
    transition: background-color .16s ease, box-shadow .18s ease, transform .18s ease;
}
.header-actions .btn-primary {
    box-shadow: 0 6px 16px -8px color-mix(in srgb, var(--brand) 85%, transparent);
}
.header-actions .btn-primary:hover {
    box-shadow: 0 10px 22px -8px color-mix(in srgb, var(--brand) 85%, transparent);
    transform: translateY(-1px);
}
.header-actions .btn-ghost { color: var(--text); }

.nav-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 38px; height: 38px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    cursor: pointer;
    flex-shrink: 0;
}
.nav-toggle span {
    display: block;
    width: 18px; height: 2px;
    background: var(--text);
    position: relative;
}
.nav-toggle span::before, .nav-toggle span::after {
    content: "";
    position: absolute;
    left: 0;
    width: 18px; height: 2px;
    background: var(--text);
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after { top: 6px; }

/* User dropdown */
.user-menu { position: relative; flex-shrink: 0; }
.user-menu-trigger {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    max-width: 170px;
    padding: 3px 10px 3px 3px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    cursor: pointer;
    color: var(--text);
    font-size: .84rem;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
}
.user-menu-trigger > span:not(.avatar) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.user-menu-trigger:hover { border-color: var(--brand); }
.avatar {
    width: 26px; height: 26px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--brand);
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: .74rem;
    font-weight: 700;
    flex-shrink: 0;
}
.avatar-lg { width: 64px; height: 64px; font-size: 1.4rem; }

.dropdown-panel {
    position: absolute;
    right: 0; top: calc(100% + 8px);
    min-width: 226px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 6px;
    z-index: 1040;
}
.dropdown-panel[hidden] { display: none; }
.dropdown-panel a, .dropdown-panel button {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 12px;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--text);
    font-size: .9rem;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
}
.dropdown-panel a:hover, .dropdown-panel button:hover { background: var(--surface-2); text-decoration: none; }
.dropdown-divider { height: 1px; background: var(--border); margin: 6px 0; }
.dropdown-header { padding: 10px 12px; border-bottom: 1px solid var(--border); margin-bottom: 6px; }
.dropdown-header strong { display: block; font-size: .92rem; }
.dropdown-header span { font-size: .8rem; color: var(--text-muted); word-break: break-all; }

/* Search suggestions */
.search-suggestions {
    position: absolute;
    left: 0; right: 0; top: calc(100% + 6px);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    max-height: 340px;
    overflow-y: auto;
    z-index: 1050;
}
.search-suggestions[hidden] { display: none; }
.search-suggestions a {
    display: block;
    padding: 10px 14px;
    color: var(--text);
    font-size: .9rem;
    border-bottom: 1px solid var(--border);
}
.search-suggestions a:last-child { border-bottom: 0; }
.search-suggestions a:hover, .search-suggestions a.is-highlighted { background: var(--surface-2); text-decoration: none; }
.search-suggestions .suggestion-meta { display: block; font-size: .78rem; color: var(--text-muted); }
.search-suggestions .suggestion-empty { padding: 14px; color: var(--text-muted); font-size: .88rem; text-align: center; }

/* Mobile navigation drawer */
.mobile-nav {
    position: fixed;
    inset: var(--header-h) 0 0 0;
    background: var(--surface);
    padding: var(--sp-4);
    overflow-y: auto;
    z-index: 1025;
    border-top: 1px solid var(--border);
}
.mobile-nav[hidden] { display: none; }
.mobile-nav a {
    display: block;
    padding: 13px 12px;
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 1rem;
    font-weight: 500;
    border-bottom: 1px solid var(--border);
}
.mobile-nav a:hover { background: var(--surface-2); text-decoration: none; }
.mobile-nav a.is-active { color: var(--brand); font-weight: 600; }
.mobile-nav-section { margin-top: var(--sp-4); }
.mobile-nav-section h4 {
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--text-soft);
    margin-bottom: 6px;
}

/* Tight laptop widths: tighten the nav, and keep a narrower search rather than
   dropping it entirely - it is the main way readers find a note. */
@media (max-width: 1279px) {
    .main-nav a, .nav-parent { padding: 7px 10px; font-size: .86rem; }
    .main-nav a.is-active::after, .nav-parent.is-active::after { left: 10px; right: 10px; }
    .header-search { width: min(190px, 20vw); }
    .header-search:focus-within { width: min(250px, 26vw); }
}
@media (max-width: 1079px) {
    .header-search { display: none; }
}

@media (max-width: 991px) {
    .main-nav { display: none; }
    .nav-toggle { display: inline-flex; }
    .header-search { display: none; }
    .header-actions { margin-left: auto; }
}

/* --------------------------------------------------------------------------
   Phone header: brand + primary action on the bar, section links underneath
   -------------------------------------------------------------------------- */
/* Hidden everywhere except phones - tablets keep the hamburger drawer. */
.mobile-nav-strip {
    display: none;
    border-top: 1px solid var(--border);
    background: color-mix(in srgb, var(--surface) 92%, transparent);
}
.mobile-nav-strip-inner {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 44px;
}
.mobile-nav-strip-links {
    display: flex;
    align-items: stretch;
    gap: 2px;
    flex: 1 1 auto;
    min-width: 0;
    height: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    /* Five labels are spread across the row; the scroll above is only a
       fallback for unusually long labels. */
    justify-content: space-between;
    /* Pull the first label back under the brand - the link padding would
       otherwise push it 6px past the brand mark. */
    margin-left: -6px;
}
.mobile-nav-strip-links::-webkit-scrollbar { display: none; }
.mobile-nav-strip-links a {
    display: inline-flex;
    align-items: center;
    padding: 0 6px;
    white-space: nowrap;
    /* Never squeeze a label - an unusually long menu scrolls instead. */
    flex: 0 0 auto;
    font-size: .87rem;
    font-weight: 600;
    /* Near-black, not muted grey - the strip is the only nav on phones and the
       labels were washing out against the bar. Token, not a literal #000, so
       dark mode still gets a light label instead of black on black. */
    color: var(--text);
    border-bottom: 2px solid transparent;
}
.mobile-nav-strip-links a:hover { color: var(--brand); text-decoration: none; }
.mobile-nav-strip-links a.is-active {
    /* Home included - the brand-blue underline still marks the current page. */
    color: var(--text);
    border-bottom-color: var(--brand);
}
.mobile-nav-strip .theme-toggle {
    width: 32px;
    height: 32px;
    font-size: .92rem;
}
@media (max-width: 767px) {
    /* Anchors have to clear both header rows. */
    html { scroll-padding-top: calc(var(--header-h) + 60px); }

    .mobile-nav-strip { display: block; }

    /* Labels moved to the strip, so the drawer and its trigger are redundant. */
    .nav-toggle { display: none; }
    .header-inner > .header-actions > .theme-toggle { display: none; }
    .mobile-nav { inset: calc(var(--header-h) + 44px) 0 0 0; }

    /* --- The phone bar itself: brand on the left, one action on the right --- */
    :root { --header-h: 58px; }

    /* Respect notches when the phone is held in landscape. */
    .header-inner,
    .mobile-nav-strip-inner {
        padding-left: max(var(--sp-4), env(safe-area-inset-left));
        padding-right: max(var(--sp-4), env(safe-area-inset-right));
    }

    /* .main-nav is hidden but still a sibling, so its adjacent rule would pin
       the actions next to the brand and leave the right half of the bar empty. */
    .header-inner > .header-actions {
        margin-left: auto;
        gap: 8px;
    }

    .site-brand { font-size: 1.06rem; gap: 9px; }
    .site-brand .brand-mark {
        width: 32px; height: 32px;
        border-radius: 11px;
        font-size: .82rem;
    }
    .site-brand img { height: 30px; }

    .header-actions .btn-sm {
        min-height: 36px;
        padding: 7px 18px;
        font-weight: 700;
        letter-spacing: .01em;
    }
    .header-actions .btn-primary {
        background: linear-gradient(135deg, color-mix(in srgb, var(--brand) 88%, #fff), var(--brand-dark));
        box-shadow: 0 8px 18px -9px color-mix(in srgb, var(--brand) 90%, transparent);
    }
    .header-actions .btn-primary:active { transform: translateY(1px); }
    .header-actions .btn-ghost { padding: 7px 12px; }
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */
.hero {
    /* Positioning context for the technology rails, which are absolute inside
       the hero so they end with it instead of following the whole page. */
    position: relative;
    padding: var(--sp-8) 0 var(--sp-7);
    background:
        radial-gradient(1000px 380px at 50% -80px, color-mix(in srgb, var(--brand) 14%, transparent), transparent),
        var(--surface);
    border-bottom: 1px solid var(--border);
    text-align: center;
}

/* Phone, homepage only: the 64px top band left dead space under the sticky
   header. Scoped to body.page-home so no other page or breakpoint moves. */
@media (max-width: 599px) {
    body.page-home .hero { padding-top: var(--sp-4); }
}

.hero h1 { max-width: 760px; margin: 0 auto var(--sp-3); }
.hero-lead {
    max-width: 620px;
    margin: 0 auto var(--sp-5);
    font-size: 1.08rem;
    color: var(--text-muted);
}
.hero-search { max-width: 640px; margin: 0 auto; position: relative; }
.hero-search form { display: flex; gap: 10px; }
.hero-search input {
    flex: 1 1 auto;
    min-width: 0;
    height: 54px;
    padding: 0 20px;
    font-size: 1rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
}
.hero-search input:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 20%, transparent);
    outline: none;
}
.hero-search .btn { height: 54px; flex-shrink: 0; }
.hero-suggestions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin-top: var(--sp-4);
}
.hero-stats {
    display: flex;
    justify-content: center;
    gap: var(--sp-6);
    margin-top: var(--sp-6);
    flex-wrap: wrap;
}
.hero-stat strong { display: block; font-size: 1.6rem; color: var(--brand); line-height: 1.2; }
.hero-stat span { font-size: .85rem; color: var(--text-muted); }

/* --------------------------------------------------------------------------
   Sections
   -------------------------------------------------------------------------- */
.section { padding: var(--sp-7) 0; }
.section-alt { background: var(--surface); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.section-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--sp-3);
    margin-bottom: var(--sp-5);
    flex-wrap: wrap;
}
.section-head h2 { margin: 0 0 4px; }
.section-head p { margin: 0; color: var(--text-muted); font-size: .95rem; }

/* --------------------------------------------------------------------------
   Grids and cards
   -------------------------------------------------------------------------- */
.grid { display: grid; gap: var(--sp-4); }
.grid-cards { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
/* Wide enough that a category name sits beside its icon without wrapping the
   card into a tall, ragged column. */
.grid-categories { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

/*
 * A minmax() track never shrinks below its minimum, so on a phone narrower
 * than the minimum plus the page padding the cards overflow and get clipped
 * at both edges. Below the small breakpoint the grids drop to one column that
 * is free to shrink instead.
 */
@media (max-width: 575.98px) {
    .grid-cards,
    .grid-categories,
    .grid-2,
    .note-nav,          /* 250px minimum, inside the sheet's own padding */
    .form-row           /* 240px minimum, inside a card's own padding */
        { grid-template-columns: minmax(0, 1fr); }
}

.category-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: var(--sp-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    color: var(--text);
    transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.category-card:hover {
    border-color: var(--brand);
    transform: translateY(-2px);
    box-shadow: var(--shadow);
    text-decoration: none;
    color: var(--text);
}
.category-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px; height: 42px;
    border-radius: 11px;
    background: var(--brand-light);
    color: var(--brand-dark);
    font-weight: 800;
    font-size: .95rem;
    flex-shrink: 0;
}
[data-theme="dark"] .category-icon { background: var(--surface-2); color: var(--text); }

/* Icon and name sit side by side, with the description on its own line below. */
.category-card-head {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}
.category-card h3 { margin: 0; font-size: 1rem; line-height: 1.3; min-width: 0; }
.category-card p { margin: 0; font-size: .85rem; color: var(--text-muted); }
.category-count { font-size: .8rem; color: var(--text-soft); margin-top: auto; padding-top: 6px; }

.note-card {
    display: flex;
    flex-direction: column;
    position: relative;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.note-card:hover { border-color: var(--brand); transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.note-card-image { display: block; aspect-ratio: 16 / 9; background: var(--surface-2); overflow: hidden; }
.note-card-image img { width: 100%; height: 100%; object-fit: cover; transition: transform .3s ease; }
.note-card:hover .note-card-image img { transform: scale(1.03); }
.note-card-body { padding: var(--sp-5) var(--sp-4) var(--sp-4); display: flex; flex-direction: column; gap: 10px; flex: 1; }
.note-card-title { margin: 0; font-size: 1.05rem; line-height: 1.35; letter-spacing: -.01em; }
.note-card-title a {
    color: var(--text);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.note-card-title a:hover { color: var(--brand); text-decoration: none; }

/* --------------------------------------------------------------------------
   Whole-card click target
   A transparent overlay link is laid over the whole card so a click anywhere
   on it opens the note. It is hidden from assistive tech and unfocusable, so
   the visible title link stays the one real link on the card. Anything with
   its own destination or action - the category badge, the featured image,
   Read more, Save - is lifted back above the overlay.
   Cards outside this component opt in by adding .card-clickable.
   -------------------------------------------------------------------------- */
.card-clickable { position: relative; }

.card-overlay-link {
    position: absolute;
    inset: 0;
    z-index: 1;
}

.note-card .note-card-image,
.note-card .badge,
.note-card .note-card-foot,
.note-card .flex-between,
.card-clickable .badge,
.card-clickable .note-card-meta {
    position: relative;
    z-index: 2;
}

.note-card:hover .note-card-title a,
.card-clickable:hover .card-title-link { color: var(--brand); }

.note-card-desc { margin: 0; font-size: .88rem; color: var(--text-muted); line-height: 1.6; }

/* Base meta row: a wrapping line of spans. search.php and user/bookmarks.php
   build their own cards on top of this, so it has to stay a row. */
.note-card-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-top: auto;
    padding-top: var(--sp-3);
    border-top: 1px solid var(--border);
    font-size: .78rem;
    color: var(--text-soft);
}
.note-card-meta > span { display: inline-flex; align-items: center; gap: 4px; }

.note-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
    /* The meta row used to carry margin-top:auto; the foot pins itself to the
       bottom now so footers still line up across a row of cards. */
    margin-top: auto;
    padding-top: var(--sp-2);
}
.bookmark-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 36px;
    padding: 6px 12px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text-muted);
    font-size: .84rem;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
}
.bookmark-btn:hover { border-color: var(--brand); color: var(--brand); }
.bookmark-btn.is-active { background: var(--brand); border-color: var(--brand); color: #fff; }

/* Resource links */
.resource-card {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-3);
    padding: var(--sp-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
}
.resource-card:hover { border-color: var(--brand); text-decoration: none; color: var(--text); }
.resource-card strong { display: block; font-size: .96rem; }
.resource-card p { margin: 2px 0 0; font-size: .84rem; color: var(--text-muted); }
.resource-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px; height: 38px;
    border-radius: 9px;
    background: var(--surface-2);
    color: var(--brand);
    font-weight: 800;
    flex-shrink: 0;
}

/* CTA */
.cta-panel {
    padding: var(--sp-7) var(--sp-5);
    background: linear-gradient(135deg, var(--brand), var(--brand-dark));
    border-radius: var(--radius-lg);
    color: #fff;
    text-align: center;
}
.cta-panel h2 { color: #fff; }
.cta-panel p { color: rgba(255, 255, 255, .9); max-width: 560px; margin: 0 auto var(--sp-4); }
.cta-panel .btn-secondary { background: #fff; color: var(--brand-dark); border-color: #fff; }
.cta-panel .btn-secondary:hover { background: rgba(255, 255, 255, .9); color: var(--brand-dark); }

/* --------------------------------------------------------------------------
   Note reading page - three column documentation layout

   The reading column is a raised sheet and the two rails sit on the page
   background. That separation is what makes a long note read as a document
   instead of a wall of text floating in the viewport. Everything here is
   scoped to the reading page so the rest of the site is untouched.
   -------------------------------------------------------------------------- */
.page-note {
    --rail-left: 264px;
    --rail-right: 268px;
    --doc-gap: 36px;
    --doc-top: calc(var(--header-h) + 20px);
}

/* The reading page runs wider than the rest of the site: with two rails
   placed, the middle column still needs a comfortable measure. */
.container-doc { max-width: 1400px; }

/* Reading progress --------------------------------------------------------
   A hairline over the sticky header. Width is set from JS; with JS off the
   bar simply stays at zero width and nothing else shifts. */
.reader-progress {
    position: fixed;
    inset: 0 0 auto 0;
    height: 3px;
    z-index: 1040;
    pointer-events: none;
}
.reader-progress span {
    display: block;
    width: 0;
    height: 100%;
    border-radius: 0 3px 3px 0;
    background: var(--brand);
    background: linear-gradient(90deg, var(--brand), color-mix(in srgb, var(--brand) 45%, #22d3ee));
}

.doc-layout {
    display: grid;
    grid-template-columns: var(--rail-left) minmax(0, 1fr) var(--rail-right);
    gap: var(--doc-gap);
    align-items: start;
    padding: var(--sp-5) 0 var(--sp-8);
}
.doc-main-col { min-width: 0; }

.doc-sidebar {
    position: sticky;
    top: var(--doc-top);
    max-height: calc(100vh - var(--doc-top) - 24px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-bottom: var(--sp-4);
    scrollbar-width: thin;
    scrollbar-color: var(--border-strong) transparent;
}
.doc-sidebar::-webkit-scrollbar { width: 6px; }
.doc-sidebar::-webkit-scrollbar-track { background: transparent; }
.doc-sidebar::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 999px; }

/* The reading sheet -------------------------------------------------------- */
.doc-sheet {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: clamp(22px, 2.6vw, 40px) clamp(20px, 3vw, 44px);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 18px 40px -32px rgba(15, 23, 42, .45);
}
[data-theme="dark"] .doc-sheet { box-shadow: none; }
.doc-block { margin-top: var(--sp-5); }

/* Section heads used for Resources, Related and Comments. */
.doc-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-3);
    margin-bottom: var(--sp-4);
}
.doc-section-head h2 {
    margin: 0;
    font-size: 1.18rem;
    letter-spacing: -.01em;
}
.doc-section-head .doc-section-note { font-size: .82rem; color: var(--text-muted); }

/* --------------------------------------------------------------------------
   Left rail - where the note sits inside its category
   -------------------------------------------------------------------------- */
.rail-panel {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    overflow: hidden;
}
.rail-head {
    padding: 13px 14px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
}
.rail-eyebrow {
    display: block;
    margin-bottom: 3px;
    font-size: .66rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--text-soft);
}
.rail-title {
    display: block;
    font-size: .97rem;
    font-weight: 700;
    color: var(--text);
    line-height: 1.35;
}
a.rail-title:hover { color: var(--brand); text-decoration: none; }
.rail-count { display: block; margin-top: 3px; font-size: .76rem; color: var(--text-muted); }
.rail-body { padding: 8px; }

.topic-tree { list-style: none; margin: 0; padding: 0; font-size: .865rem; }
.topic-tree li { margin: 0; }
.topic-tree a {
    display: block;
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    line-height: 1.42;
}
.topic-tree a:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.topic-tree a.is-current {
    font-weight: 600;
    color: var(--brand-dark);
    background: var(--brand-light);
    background: color-mix(in srgb, var(--brand) 12%, transparent);
    box-shadow: inset 2px 0 0 var(--brand);
}
[data-theme="dark"] .topic-tree a.is-current {
    color: color-mix(in srgb, var(--brand) 55%, #fff);
    background: color-mix(in srgb, var(--brand) 22%, transparent);
}

/* Subcategory grouping inside the tree. */
.topic-group {
    display: block;
    padding: 12px 10px 5px;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--text-soft);
}
.topic-sub {
    list-style: none;
    margin: 0 0 4px;
    padding: 0 0 0 9px;
    border-left: 1px solid var(--border);
}
.topic-sub a { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }

/* --------------------------------------------------------------------------
   Right rail - table of contents and supporting material
   -------------------------------------------------------------------------- */
.sidebar-block { margin-bottom: var(--sp-5); }
.sidebar-block:last-child { margin-bottom: 0; }
.sidebar-block h3 {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
    font-size: .69rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--text-soft);
}

.toc-list {
    position: relative;
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: .845rem;
}
/* The rail behind the items; the active item paints its own segment over it. */
.toc-list::before {
    content: "";
    position: absolute;
    left: 0; top: 2px; bottom: 2px;
    width: 2px;
    border-radius: 2px;
    background: var(--border);
}
.toc-list a {
    display: block;
    padding: 6px 8px 6px 14px;
    border-left: 2px solid transparent;
    color: var(--text-muted);
    line-height: 1.45;
}
.toc-list a:hover { color: var(--text); text-decoration: none; }
.toc-list a.is-active {
    font-weight: 600;
    color: var(--brand);
    border-left-color: var(--brand);
}
.toc-list .toc-h3 { padding-left: 28px; font-size: .81rem; }

/* Numbered list used for the popular notes block. */
.rank-list { list-style: none; margin: 0; padding: 0; }
.rank-list li {
    display: flex;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
}
.rank-list li:last-child { border-bottom: 0; padding-bottom: 0; }
.rank-list li:first-child { padding-top: 0; }
.rank-num {
    flex: 0 0 16px;
    font-size: .72rem;
    font-weight: 800;
    color: var(--text-soft);
    font-variant-numeric: tabular-nums;
    line-height: 1.6;
}
.rank-list a { font-size: .845rem; color: var(--text-muted); line-height: 1.45; }
.rank-list a:hover { color: var(--brand); text-decoration: none; }

.link-list { list-style: none; margin: 0; padding: 0; font-size: .845rem; }
.link-list li + li { margin-top: 2px; }
.link-list a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    line-height: 1.4;
}
.link-list a:hover { background: var(--surface-2); color: var(--brand); text-decoration: none; }
.link-list a.is-current { font-weight: 600; color: var(--text); background: var(--surface-2); }
.link-list .link-ext { flex: 0 0 auto; font-size: .8rem; color: var(--text-soft); }
.link-list .link-count {
    flex: 0 0 auto;
    min-width: 22px;
    padding: 1px 6px;
    border-radius: 999px;
    background: var(--surface-3);
    color: var(--text-muted);
    font-size: .72rem;
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
}
[data-theme="dark"] .link-list .link-count { background: var(--surface-2); }

/* The left rail's second block sits outside the panel, so it needs the
   panel's own inset back to line its labels up with the tree above. */
.rail-secondary { margin-top: var(--sp-5); padding: 0 6px; }
.rail-more {
    display: inline-block;
    margin: 8px 0 0 10px;
    font-size: .79rem;
    font-weight: 600;
    color: var(--text-muted);
}
.rail-more:hover { color: var(--brand); text-decoration: none; }

.rail-top-link {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: .8rem;
    font-weight: 600;
    color: var(--text-muted);
}
.rail-top-link:hover { color: var(--brand); text-decoration: none; }

/* --------------------------------------------------------------------------
   Note header
   -------------------------------------------------------------------------- */
.note-header { margin-bottom: var(--sp-5); }

.note-eyebrow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 14px;
    font-size: .8rem;
}
.note-header h1 {
    margin-bottom: 14px;
    font-size: clamp(1.85rem, 1.35rem + 1.9vw, 2.5rem);
    line-height: 1.18;
    letter-spacing: -.025em;
}
.note-lead {
    max-width: 66ch;
    margin-bottom: var(--sp-5);
    font-size: 1.09rem;
    line-height: 1.62;
    color: var(--text-muted);
}

.ico {
    flex: 0 0 auto;
    width: 15px; height: 15px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: .8;
}


.note-figure { margin: 0 0 var(--sp-5); }
.note-figure img {
    width: 100%;
    border-radius: var(--radius);
    border: 1px solid var(--border);
}

/* --------------------------------------------------------------------------
   Reading column typography refinements
   -------------------------------------------------------------------------- */
.page-note .note-content { font-size: 1.035rem; line-height: 1.8; }
.page-note .note-content > h2,
.page-note .note-content > h3,
.page-note .note-content > h4 { scroll-margin-top: calc(var(--header-h) + 24px); }
.page-note .note-content > h2 {
    margin-top: var(--sp-7);
    padding-top: 0;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--border);
    font-size: clamp(1.32rem, 1.12rem + .55vw, 1.55rem);
}
.page-note .note-content > h2:first-child { margin-top: 0; }
.page-note .note-content > h3 { margin-top: var(--sp-6); font-size: 1.1rem; }
.page-note .note-content > h3 + p { margin-top: 0; }
.page-note .note-content li { margin-bottom: 6px; }
.page-note .note-content > p:last-child { margin-bottom: 0; }

/* Heading anchors - the small link that appears on hover, as in most docs. */
.heading-anchor {
    margin-left: 8px;
    font-weight: 400;
    color: var(--text-soft);
    opacity: 0;
    transition: opacity .12s ease;
    text-decoration: none;
}
.note-content h2:hover .heading-anchor,
.note-content h3:hover .heading-anchor,
.heading-anchor:focus-visible { opacity: 1; }
.heading-anchor:hover { color: var(--brand); text-decoration: none; }

/* A quieter callout than the solid brand wash. */
.page-note .note-content blockquote {
    border-left: 3px solid var(--brand);
    border-radius: 0 var(--radius) var(--radius) 0;
    background: color-mix(in srgb, var(--brand) 7%, transparent);
    color: var(--text);
}
[data-theme="dark"] .page-note .note-content blockquote {
    background: color-mix(in srgb, var(--brand) 16%, transparent);
}
.page-note .note-content table { font-size: .92rem; }
.page-note .note-content table th {
    font-size: .78rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.page-note .resource-card { background: var(--surface-2); }
[data-theme="dark"] .page-note .resource-card { background: color-mix(in srgb, var(--surface-2) 55%, transparent); }

.note-tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: var(--sp-6) 0 0;
    padding-top: var(--sp-4);
    border-top: 1px solid var(--border);
}
.note-tags-label {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--text-soft);
    margin-right: 2px;
}

/* Author card closing the article. */
.author-card {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    margin-top: var(--sp-5);
    padding: var(--sp-4);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-2);
}
[data-theme="dark"] .author-card { background: color-mix(in srgb, var(--surface-2) 55%, transparent); }
.author-card .avatar { width: 46px; height: 46px; font-size: 1.05rem; }
.author-card-body { min-width: 0; }
.author-card-eyebrow {
    display: block;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--text-soft);
}
.author-card-name { font-size: 1rem; font-weight: 700; color: var(--text); }
.author-card p { margin: 6px 0 0; font-size: .88rem; color: var(--text-muted); }

/* --------------------------------------------------------------------------
   Previous / next
   -------------------------------------------------------------------------- */
.note-nav {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: var(--sp-3);
    margin: var(--sp-5) 0 0;
}
.note-nav a {
    display: block;
    padding: 15px 18px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.note-nav a:hover {
    border-color: var(--brand);
    box-shadow: 0 12px 24px -20px rgba(15, 23, 42, .6);
    transform: translateY(-1px);
    text-decoration: none;
}
.note-nav small {
    display: block;
    margin-bottom: 5px;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-soft);
}
.note-nav strong { font-size: .95rem; font-weight: 600; line-height: 1.4; }
.note-nav .nav-next { text-align: right; }

/* --------------------------------------------------------------------------
   Mobile accordions - the two rails collapse into these below 1200px
   -------------------------------------------------------------------------- */
.mobile-toc { display: none; margin-bottom: var(--sp-5); }
.accordion-panel {
    margin-bottom: var(--sp-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-2);
    overflow: hidden;
}
[data-theme="dark"] .accordion-panel { background: color-mix(in srgb, var(--surface-2) 55%, transparent); }
.accordion-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    width: 100%;
    padding: 12px 16px;
    background: none;
    border: 0;
    color: var(--text);
    font-family: inherit;
    font-size: .9rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}
.accordion-trigger .accordion-label { display: inline-flex; align-items: center; gap: 9px; }
.accordion-trigger[aria-expanded="true"] { border-bottom: 1px solid var(--border); }
.accordion-trigger .accordion-icon { color: var(--text-muted); font-size: .7rem; transition: transform .2s ease; }
.accordion-trigger[aria-expanded="true"] .accordion-icon { transform: rotate(180deg); }
.accordion-body { padding: var(--sp-3) var(--sp-4) var(--sp-4); }
.accordion-body[hidden] { display: none; }

/* Floating back to top, shown once the right rail is gone. */
.reader-top {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 1020;
    display: none;
    align-items: center;
    justify-content: center;
    width: 44px; height: 44px;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-muted);
    box-shadow: var(--shadow-lg);
    cursor: pointer;
    opacity: 0;
    transform: translateY(8px);
    transition: opacity .2s ease, transform .2s ease;
}
.reader-top.is-visible { opacity: 1; transform: none; }
.reader-top:hover { color: var(--brand); border-color: var(--brand); }

@media (max-width: 1279px) {
    .page-note { --rail-left: 240px; --doc-gap: 28px; }
    .doc-layout { grid-template-columns: var(--rail-left) minmax(0, 1fr); }
    .doc-sidebar-right { display: none; }
    .mobile-toc { display: block; }
    .reader-top { display: flex; }
}
@media (max-width: 991px) {
    .doc-layout { grid-template-columns: minmax(0, 1fr); padding-top: var(--sp-4); }
    .doc-sidebar-left { display: none; }
}
@media (max-width: 767px) {
    .doc-sheet {
        border-radius: var(--radius);
        padding: var(--sp-5) var(--sp-4);
    }
    .doc-sidebar { position: static; max-height: none; }
}

/* --------------------------------------------------------------------------
   Comments on the reading page
   -------------------------------------------------------------------------- */
.page-note .comment-list { margin-top: var(--sp-2); }
.page-note .comment { padding: var(--sp-4) 0; gap: 14px; }
.page-note .comment:first-child { padding-top: 0; }
.page-note .comment .avatar { width: 36px; height: 36px; font-size: .9rem; }
.page-note .comment-head strong { font-size: .92rem; }
.page-note .comment-text { color: var(--text-muted); }
.page-note .comment-replies { padding-left: var(--sp-4); }

/* Print: rails, actions and chrome come off; the sheet loses its frame. */
@media print {
    .reader-progress, .reader-top, .doc-section-head .doc-section-note { display: none !important; }
    .doc-sheet { border: 0; box-shadow: none; padding: 0; }
}

/* --------------------------------------------------------------------------
   Comments
   -------------------------------------------------------------------------- */
.comment-list { list-style: none; margin: 0; padding: 0; }
.comment {
    display: flex;
    gap: var(--sp-3);
    padding: var(--sp-4) 0;
    border-bottom: 1px solid var(--border);
}
.comment:last-child { border-bottom: 0; }
.comment-body { flex: 1; min-width: 0; }
.comment-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.comment-head strong { font-size: .93rem; }
.comment-head time { font-size: .8rem; color: var(--text-soft); }
.comment-text { font-size: .93rem; margin: 0; word-break: break-word; }
.comment-replies { list-style: none; margin: var(--sp-3) 0 0; padding: 0 0 0 var(--sp-5); border-left: 2px solid var(--border); }

/* --------------------------------------------------------------------------
   Auth pages
   -------------------------------------------------------------------------- */
.auth-wrap {
    min-height: calc(100vh - var(--header-h));
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--sp-6) var(--sp-4);
}
.auth-card {
    width: 100%;
    max-width: 440px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: var(--sp-6);
}
.auth-card h1 { font-size: 1.5rem; margin-bottom: 6px; }
.auth-card .auth-sub { color: var(--text-muted); font-size: .93rem; margin-bottom: var(--sp-5); }
.auth-footer { margin-top: var(--sp-5); padding-top: var(--sp-4); border-top: 1px solid var(--border); text-align: center; font-size: .9rem; color: var(--text-muted); }

.password-meter { height: 5px; background: var(--surface-3); border-radius: 999px; overflow: hidden; margin-top: 8px; }
.password-meter span { display: block; height: 100%; width: 0; transition: width .2s ease, background-color .2s ease; }

/* --------------------------------------------------------------------------
   User dashboard
   -------------------------------------------------------------------------- */
.user-layout { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: var(--sp-5); padding: var(--sp-5) 0 var(--sp-7); }
.user-nav { list-style: none; margin: 0; padding: 0; }
.user-nav a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: .93rem;
    font-weight: 500;
}
.user-nav a:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.user-nav a.is-active { background: var(--brand); color: #fff; font-weight: 600; }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--sp-4); }
.stat-card {
    padding: var(--sp-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}
.stat-card .stat-label { font-size: .8rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: .05em; }
.stat-card .stat-value { font-size: 1.8rem; font-weight: 800; color: var(--text); line-height: 1.2; margin-top: 4px; }
.stat-card .stat-note { font-size: .8rem; color: var(--text-soft); }

.folder-tree { list-style: none; margin: 0; padding: 0; }
.folder-tree li { margin-bottom: 2px; }
.folder-tree a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 9px 12px;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: .91rem;
}
.folder-tree a:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.folder-tree a.is-active { background: var(--brand-light); color: var(--brand-dark); font-weight: 600; }
[data-theme="dark"] .folder-tree a.is-active { background: var(--surface-2); color: var(--text); }
.folder-tree .folder-child { padding-left: 26px; }
.folder-count { font-size: .78rem; color: var(--text-soft); }

.personal-note-card {
    padding: var(--sp-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--brand);
    border-radius: var(--radius);
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.personal-note-card h3 { margin: 0; font-size: 1rem; }
.personal-note-card p { margin: 0; font-size: .87rem; color: var(--text-muted); }
.personal-note-card .note-foot {
    margin-top: auto;
    padding-top: 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-size: .78rem;
    color: var(--text-soft);
}

@media (max-width: 767px) {
    .user-layout { grid-template-columns: minmax(0, 1fr); }
    .user-nav { display: flex; overflow-x: auto; gap: 6px; padding-bottom: 6px; }
    .user-nav a { white-space: nowrap; }
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
.site-footer {
    position: relative;
    margin-top: var(--sp-7);
    padding: var(--sp-7) 0 var(--sp-4);
    background:
        radial-gradient(760px 240px at 8% 0, color-mix(in srgb, var(--brand) 18%, transparent), transparent 70%),
        var(--secondary);
    color: #cbd5e1;
    overflow: hidden;
}
/* Hairline of brand colour along the top edge. */
.site-footer::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--brand) 70%, transparent), transparent);
}
.site-footer a { color: #cbd5e1; font-size: .9rem; }
.site-footer a:hover { color: #fff; }
.site-footer p { font-size: .9rem; color: #94a3b8; line-height: 1.7; }

/*
 * Explicit tracks at each breakpoint.
 * NOTE: do not reintroduce `1.6fr repeat(auto-fit, ...)` here - the grid spec
 * forbids combining an auto-repeat with a flexible track, so browsers drop the
 * whole declaration and the footer silently collapses to one column.
 */
.footer-grid {
    display: grid;
    align-items: start;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-5);
    margin-bottom: var(--sp-5);
}
@media (min-width: 600px) {
    .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-6) var(--sp-6); }
}
@media (min-width: 992px) {
    .footer-grid {
        grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
        gap: var(--sp-6) var(--sp-5);
    }
}

/* The brand column: a little more breathing room than the link lists. */
.footer-about { max-width: 42ch; }
.footer-brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-bottom: var(--sp-3);
    color: #fff;
    font-size: 1.05rem;
    font-weight: 800;
    letter-spacing: -.02em;
}
.footer-brand:hover { color: #fff; text-decoration: none; }
.footer-brand img { height: 30px; width: auto; }
.footer-brand .brand-mark { width: 30px; height: 30px; font-size: .85rem; }
.footer-about p { margin: 0; font-size: .875rem; color: #94a3b8; line-height: 1.7; }

/* Column headings: small caps label with a short brand rule underneath. */
.site-footer h4 {
    color: #fff;
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .1em;
    margin: 0 0 var(--sp-4);
}
.footer-col h4 { position: relative; padding-bottom: 10px; }
.footer-col h4::after {
    content: "";
    position: absolute;
    left: 0; bottom: 0;
    width: 22px; height: 2px;
    border-radius: 2px;
    background: var(--brand);
}

.footer-links { list-style: none; margin: 0; padding: 0; }
.footer-links li { margin-bottom: 2px; }
.footer-links li:last-child { margin-bottom: 0; }
.footer-links a,
.footer-links .footer-static {
    display: block;
    padding: 5px 0;
    font-size: .875rem;
    line-height: 1.5;
    color: #9fb0c9;
    transition: color .15s ease, transform .15s ease;
}
.footer-links .footer-static { color: #94a3b8; }
.footer-links a:hover { color: #fff; text-decoration: none; transform: translateX(3px); }
.footer-links .footer-more { color: color-mix(in srgb, var(--brand) 70%, #fff); font-weight: 600; }
.footer-links .footer-more:hover { color: #fff; }

/* Contact column: glyph + value rows so a short list still reads as a block. */
.footer-contact li { margin-bottom: 2px; }
.footer-contact a,
.footer-contact .footer-static {
    display: grid;
    grid-template-columns: 18px 1fr;
    align-items: start;
    gap: 8px;
    padding: 5px 0;
    word-break: break-word;
}
.footer-contact .footer-ico {
    color: var(--brand);
    font-size: .85rem;
    line-height: 1.5;
    opacity: .9;
}

.footer-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3) var(--sp-5);
    margin-top: var(--sp-5);
    padding-top: var(--sp-4);
    border-top: 1px solid rgba(255, 255, 255, .10);
    flex-wrap: wrap;
    font-size: .82rem;
    color: #7f8ea8;
}
.footer-bottom a { font-size: .82rem; color: #9fb0c9; }
.footer-bottom a:hover { color: #fff; }
.footer-bottom .flex-row { display: flex; align-items: center; gap: 10px; }
.footer-bottom .flex-row > span[aria-hidden] { color: #475569; }

.social-links { display: flex; flex-wrap: wrap; gap: 8px; }
.social-links a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px; height: 34px;
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 50%;
    background: rgba(255, 255, 255, .05);
    color: #cbd5e1;
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .02em;
    transition: background .15s ease, border-color .15s ease, transform .15s ease, color .15s ease;
}
.social-links a:hover {
    background: var(--brand);
    border-color: var(--brand);
    color: #fff;
    transform: translateY(-2px);
    text-decoration: none;
}

/* --------------------------------------------------------------------------
   Phone footer: a rigid two-column list left ragged rows and dead space, so on
   phones each block becomes its own panel and the link lists flow as chips -
   they self-size to the label, which no label length can knock out of line.
   -------------------------------------------------------------------------- */
@media (max-width: 599px) {
    .site-footer { padding: var(--sp-6) 0 var(--sp-5); }
    .footer-grid { gap: var(--sp-4); margin-bottom: var(--sp-4); }

    .footer-about { max-width: none; }
    .footer-about p { font-size: .9rem; }
    .social-links { margin-top: var(--sp-4); }

    /* Every block after the brand sits in a soft panel instead of a hairline. */
    .footer-grid > .footer-col + .footer-col {
        padding: var(--sp-4);
        border: 1px solid rgba(255, 255, 255, .08);
        border-radius: var(--radius-lg);
        background: rgba(255, 255, 255, .035);
    }
    .site-footer h4 { margin-bottom: var(--sp-3); }

    /* Link lists flow as tappable chips - no columns to keep aligned. */
    .footer-col .footer-links {
        display: flex;
        flex-wrap: wrap;
        gap: var(--sp-2);
    }
    .footer-col .footer-links li { margin: 0; }
    .footer-col .footer-links a {
        display: inline-flex;
        align-items: center;
        padding: 8px 13px;
        border: 1px solid rgba(255, 255, 255, .10);
        border-radius: 999px;
        background: rgba(255, 255, 255, .05);
        font-size: .85rem;
        line-height: 1.2;
        color: #cbd5e1;
    }
    .footer-col .footer-links a:hover,
    .footer-col .footer-links a:active {
        transform: none;
        border-color: var(--brand);
        background: var(--brand);
        color: #fff;
    }
    /* "All categories" closes the block, so let it read as the accent chip. */
    .footer-col .footer-links .footer-more {
        border-color: color-mix(in srgb, var(--brand) 45%, transparent);
        background: color-mix(in srgb, var(--brand) 18%, transparent);
        color: color-mix(in srgb, var(--brand) 55%, #fff);
    }

    /* Contact rows carry an address and a glyph - keep them as full-width rows. */
    .footer-col .footer-contact { display: block; }
    .footer-col .footer-contact li { margin: 0; }
    .footer-col .footer-contact li + li { border-top: 1px solid rgba(255, 255, 255, .07); }
    .footer-col .footer-contact a,
    .footer-col .footer-contact .footer-static {
        display: grid;
        grid-template-columns: 20px minmax(0, 1fr);
        align-items: start;
        gap: 10px;
        padding: 10px 0;
        border: 0;
        border-radius: 0;
        background: none;
        font-size: .875rem;
    }
    .footer-col .footer-contact a:hover,
    .footer-col .footer-contact a:active { background: none; color: #fff; transform: none; }

    .footer-bottom {
        justify-content: center;
        flex-direction: column;
        gap: var(--sp-2);
        margin-top: var(--sp-4);
        text-align: center;
    }
    .footer-bottom .flex-row { flex-wrap: wrap; justify-content: center; }
}

/* --------------------------------------------------------------------------
   Error and maintenance pages
   -------------------------------------------------------------------------- */
.status-page {
    min-height: 70vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: var(--sp-7) var(--sp-4);
}
.status-code { font-size: clamp(4rem, 12vw, 7rem); font-weight: 800; color: var(--brand); line-height: 1; }
.status-page h1 { margin: var(--sp-3) 0; }
.status-page p { max-width: 480px; color: var(--text-muted); }

/* --------------------------------------------------------------------------
   Print
   -------------------------------------------------------------------------- */
@media print {
    .site-header, .site-footer, .doc-sidebar, .mobile-toc, #toast-container { display: none !important; }
    .doc-layout { grid-template-columns: 1fr; }
    body { background: #fff; color: #000; }
    pre { border: 1px solid #ccc; }
    pre code { color: #000; }
}

/* --------------------------------------------------------------------------
   Readable body copy - light theme
   Page copy inside <main> was drawn in the slate greys (--text-muted /
   --text-soft), which washed out against the light surfaces and was hard to
   read. Re-point the text tokens to black for the content area only, so the
   header/nav, the mobile nav and the dark footer keep their own palettes.
   Dark theme is deliberately untouched - black there would be invisible.

   Only the tokens are changed, so every element that sets its own colour on
   purpose - links, brand accents, white-on-brand buttons, the CTA panel and
   the dark code blocks - is left exactly as designed.
   -------------------------------------------------------------------------- */
html:not([data-theme="dark"]) #main-content {
    --text: #000;
    --text-muted: #000;
    --text-soft: #000;
    color: #000;
}

/* Placeholders stay grey - a black placeholder reads as a filled-in value. */
html:not([data-theme="dark"]) #main-content .form-control::placeholder,
html:not([data-theme="dark"]) #main-content input::placeholder,
html:not([data-theme="dark"]) #main-content textarea::placeholder {
    color: #6b7280;
}

/* Content headings: heavier weight so they read as headings against the now
   fully-black body copy. Scoped to <main>, so the site header/nav, the mobile
   nav and the footer headings keep the weights they already have. */
#main-content :is(h1, h2, h3, h4, h5, h6) {
    font-weight: 800;
    letter-spacing: -.015em;
}
html:not([data-theme="dark"]) #main-content :is(h1, h2, h3, h4, h5, h6) {
    color: #000;
}
/* The CTA panel sits on brand colour - its headings stay white. */
html #main-content .cta-panel :is(h1, h2, h3, h4, h5, h6) { color: #fff; }

/* --------------------------------------------------------------------------
   Contact page
   A tinted hero band, a two column body (form + ways to reach us) that folds
   to a single column on tablets and phones, and form fields with leading
   icons. Every colour comes from the design tokens, so the page stays
   consistent in light and dark and at every breakpoint.
   -------------------------------------------------------------------------- */
.contact-hero {
    position: relative;
    padding: var(--sp-5) 0 var(--sp-7);
    background:
        radial-gradient(820px 320px at 12% -70px, color-mix(in srgb, var(--brand) 17%, transparent), transparent),
        radial-gradient(700px 300px at 92% -20px, color-mix(in srgb, var(--brand) 9%, transparent), transparent),
        var(--surface);
    border-bottom: 1px solid var(--border);
    overflow: hidden;
}
.contact-hero .breadcrumbs { margin-bottom: var(--sp-5); }
.contact-hero-inner { max-width: 720px; }

.contact-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 5px 14px 5px 10px;
    margin-bottom: var(--sp-4);
    border: 1px solid color-mix(in srgb, var(--brand) 32%, transparent);
    border-radius: 999px;
    background: color-mix(in srgb, var(--brand) 11%, transparent);
    color: var(--brand-dark);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .02em;
}
[data-theme="dark"] .contact-eyebrow { color: color-mix(in srgb, var(--brand) 22%, #ffffff); }
.contact-eyebrow::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--success);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 25%, transparent);
}

.contact-hero h1 { margin-bottom: var(--sp-3); }
.contact-lead {
    max-width: 620px;
    margin: 0;
    font-size: 1.06rem;
    line-height: 1.7;
    color: var(--text-muted);
}

.contact-highlights {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2) var(--sp-5);
    margin-top: var(--sp-5);
    padding: 0;
    list-style: none;
}
.contact-highlights li {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: .88rem;
    font-weight: 600;
}
.contact-highlights svg { width: 17px; height: 17px; flex-shrink: 0; color: var(--brand); }

/* --- Body layout ---------------------------------------------------------- */
.contact-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    gap: var(--sp-6);
    align-items: start;
    padding: var(--sp-6) 0 var(--sp-8);
}
@media (max-width: 991.98px) {
    .contact-layout {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--sp-5);
        padding: var(--sp-5) 0 var(--sp-7);
    }
}
@media (min-width: 992px) {
    .contact-aside { position: sticky; top: calc(var(--header-h) + var(--sp-4)); }
}

/* Editable page copy from the CMS. Rendered as a quiet panel with tightened
   heading sizes so it introduces the form instead of competing with it. */
.contact-intro {
    margin-bottom: var(--sp-4);
    padding: var(--sp-5);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface-2);
    font-size: .95rem;
    line-height: 1.7;
}
.contact-intro > *:first-child { margin-top: 0; }
.contact-intro > *:last-child { margin-bottom: 0; }
.contact-intro :is(h1, h2, h3, h4) {
    margin: var(--sp-4) 0 var(--sp-2);
    padding: 0;
    border: 0;
    font-size: 1.02rem;
}
@media (max-width: 575.98px) {
    .contact-intro { padding: var(--sp-4); }
}

/* --- Form card ------------------------------------------------------------ */
.contact-form-card { position: relative; box-shadow: var(--shadow); }
.contact-form-card::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 4px;
    background: linear-gradient(90deg, var(--brand), color-mix(in srgb, var(--brand) 45%, #ffffff));
}
.contact-form-card .card-app-body { padding: var(--sp-6); }
@media (max-width: 575.98px) {
    .contact-form-card .card-app-body { padding: var(--sp-4); }
}

.contact-form-head { margin-bottom: var(--sp-5); }
.contact-form-head h2 { margin: 0 0 4px; font-size: 1.25rem; }
.contact-form-head p { margin: 0; font-size: .92rem; color: var(--text-muted); }

.contact-form .form-group { margin-bottom: var(--sp-4); }
.contact-form .form-label { font-size: .85rem; letter-spacing: .01em; margin-bottom: 7px; }

/* A relatively positioned shell so the leading icon can sit inside the field. */
.field-shell { position: relative; display: block; }
.field-shell .field-icon {
    position: absolute;
    left: 15px;
    top: 15px;
    width: 18px;
    height: 18px;
    color: var(--text-soft);
    pointer-events: none;
    transition: color .18s ease;
}
.field-shell:focus-within .field-icon { color: var(--brand); }

.contact-form .form-control {
    min-height: 50px;
    padding: 13px 16px;
    font-size: .96rem;
    background: var(--surface-2);
    border-color: var(--border);
    border-radius: 12px;
    transition: background-color .18s ease, border-color .18s ease, box-shadow .18s ease;
}
.contact-form .form-control:hover:not(:focus) { border-color: var(--border-strong); }
.contact-form .form-control:focus {
    background: var(--surface);
    border-color: var(--brand);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand) 15%, transparent);
}
/* Declared after the shorthand above so the icon gutter survives it. */
.contact-form .field-shell .form-control { padding-left: 46px; }
.contact-form textarea.form-control { min-height: 170px; padding-top: 14px; }
.contact-form .form-control.is-invalid {
    border-color: var(--danger);
    background: color-mix(in srgb, var(--danger) 6%, var(--surface));
}
.contact-form .form-control.is-invalid:focus {
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--danger) 16%, transparent);
}

.contact-field-meta {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-3);
    margin-top: 6px;
}
.contact-field-meta .form-hint,
.contact-field-meta .char-counter { margin-top: 0; }
.contact-field-meta .char-counter { white-space: nowrap; }

.contact-form-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    flex-wrap: wrap;
    margin-top: var(--sp-5);
    padding-top: var(--sp-5);
    border-top: 1px solid var(--border);
}
.contact-privacy {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    max-width: 340px;
    margin: 0;
    font-size: .83rem;
    line-height: 1.55;
    color: var(--text-muted);
}
.contact-privacy svg { width: 16px; height: 16px; flex-shrink: 0; margin-top: 2px; color: var(--success); }

.contact-submit {
    box-shadow: 0 10px 22px -14px color-mix(in srgb, var(--brand) 90%, transparent);
    transition: background-color .16s ease, transform .18s ease, box-shadow .18s ease;
}
.contact-submit:hover {
    transform: translateY(-2px);
    box-shadow: 0 16px 28px -14px color-mix(in srgb, var(--brand) 90%, transparent);
}
.contact-submit:active { transform: translateY(0); }

@media (max-width: 575.98px) {
    .contact-form-actions { flex-direction: column-reverse; align-items: stretch; }
    .contact-submit { width: 100%; }
    .contact-privacy { max-width: none; }
}

/* --- Aside: ways to reach us --------------------------------------------- */
.contact-methods { display: grid; gap: 4px; }
.contact-method {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-3);
    padding: var(--sp-3);
    border: 1px solid transparent;
    border-radius: var(--radius);
    transition: background-color .18s ease, border-color .18s ease, transform .18s ease;
}
.contact-method:hover {
    background: var(--surface-2);
    border-color: var(--border);
    transform: translateY(-1px);
}
.contact-method-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 42px;
    height: 42px;
    border-radius: 12px;
    background: color-mix(in srgb, var(--brand) 12%, transparent);
    color: var(--brand);
    transition: background-color .18s ease, transform .18s ease;
}
.contact-method:hover .contact-method-icon {
    background: color-mix(in srgb, var(--brand) 20%, transparent);
    transform: scale(1.06);
}
.contact-method-icon svg { width: 20px; height: 20px; }
.contact-method-body { min-width: 0; }
.contact-method-label {
    display: block;
    margin-bottom: 2px;
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .07em;
    opacity: .6;
}
.contact-method-value {
    font-size: .95rem;
    font-weight: 600;
    line-height: 1.5;
    overflow-wrap: anywhere;
}
.contact-method-value a { color: var(--brand); }
.contact-method-value a:hover { text-decoration: underline; }

/* Numbered "what happens next" list in the aside. */
.contact-steps { margin: 0; padding: 0; list-style: none; counter-reset: step; display: grid; gap: var(--sp-3); }
.contact-steps li {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-3);
    font-size: .9rem;
    line-height: 1.55;
}
.contact-steps li::before {
    counter-increment: step;
    content: counter(step);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--brand) 12%, transparent);
    color: var(--brand);
    font-size: .78rem;
    font-weight: 700;
}

.contact-tip-card { border-color: color-mix(in srgb, var(--brand) 26%, var(--border)); }
.contact-tip-card .card-app-body { display: grid; gap: var(--sp-3); }
.contact-tip-card h2 { margin: 0; font-size: 1rem; }
.contact-tip-card p { margin: 0; font-size: .9rem; color: var(--text-muted); }
.contact-tip-card .btn { justify-self: start; }
@media (max-width: 575.98px) {
    .contact-tip-card .btn { justify-self: stretch; }
}

/* --------------------------------------------------------------------------
   Category cards - the subject tiles on categories.php
   Each card sets --cat-accent and --cat-ink inline (see includes/category_logos.php);
   every tint below is mixed from those two so one rule set covers every subject
   in both themes. Colour is used for accents only, never as a solid fill.
   -------------------------------------------------------------------------- */
.cat-card {
    --cat-line: color-mix(in srgb, var(--cat-accent) 16%, var(--border));
    position: relative;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
    padding: 28px 24px 18px;
    border-radius: 18px;
    border: 1px solid var(--cat-line);
    background:
        linear-gradient(180deg, color-mix(in srgb, var(--cat-accent) 7%, transparent), transparent 46%),
        var(--surface);
    box-shadow:
        0 1px 2px rgba(15, 23, 42, .04),
        0 6px 14px -8px rgba(15, 23, 42, .16),
        0 18px 34px -22px rgba(15, 23, 42, .28);
    overflow: hidden;
    isolation: isolate;
    transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
}

/* Accent rail along the top edge, stronger on hover. */
.cat-card::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    background: linear-gradient(90deg, var(--cat-accent), color-mix(in srgb, var(--cat-accent) 25%, transparent));
    opacity: .55;
    transition: opacity .22s ease;
}

.cat-card:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--cat-accent) 38%, var(--border));
    box-shadow:
        0 1px 2px rgba(15, 23, 42, .05),
        0 10px 20px -10px rgba(15, 23, 42, .20),
        0 26px 44px -24px color-mix(in srgb, var(--cat-accent) 45%, rgba(15, 23, 42, .35));
}
.cat-card:hover::before { opacity: 1; }

.cat-card:focus-within {
    border-color: color-mix(in srgb, var(--cat-accent) 45%, var(--border));
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--cat-accent) 26%, transparent), var(--shadow-lg);
}

/* --- Header: logo, name, count ------------------------------------------- */
.cat-card-head {
    display: flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
}

.cat-card:hover .cat-mark {
    transform: scale(1.06);
    box-shadow:
        inset 0 0 0 1px color-mix(in srgb, var(--cat-accent) 40%, transparent),
        0 8px 18px -8px color-mix(in srgb, var(--cat-accent) 85%, transparent);
}

.cat-identity { min-width: 0; }
.cat-name {
    margin: 0;
    font-size: 1.12rem;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -.01em;
}
.cat-name-link { color: var(--text); text-decoration: none; }
.cat-name-link:hover { color: var(--text); text-decoration: none; }
/* Stretched link: the whole tile is clickable, the topic tags sit above it. */
.cat-name-link::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
}
.cat-name-link:focus-visible { outline: none; }

.cat-count {
    display: block;
    margin-top: 2px;
    font-size: .8rem;
    font-weight: 500;
    color: var(--text-soft);
}

/* --- Description ---------------------------------------------------------- */
/* Clamped to two lines so a long blurb never makes one card taller. */
.cat-desc {
    margin: 0;
    font-size: .875rem;
    line-height: 1.65;
    color: var(--text-muted);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: calc(.875rem * 1.65 * 2);
}

/* --- Topic tags ----------------------------------------------------------- */
.cat-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
    /* Two rows' worth, so cards line up whether a subject has two topics or five. */
    min-height: 60px;
    align-content: flex-start;
}

.cat-tag {
    position: relative;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    max-width: 100%;
    padding: 4px 10px;
    border: 1px solid color-mix(in srgb, var(--cat-accent) 20%, transparent);
    border-radius: 8px;
    background: color-mix(in srgb, var(--cat-accent) 7%, transparent);
    color: var(--text);
    font-size: .755rem;
    font-weight: 500;
    line-height: 1.6;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}
.cat-tag > span { overflow: hidden; text-overflow: ellipsis; }
.cat-tag b {
    font-weight: 700;
    font-size: .72rem;
    color: var(--cat-ink);
    opacity: .85;
}
a.cat-tag:hover {
    background: color-mix(in srgb, var(--cat-accent) 15%, transparent);
    border-color: color-mix(in srgb, var(--cat-accent) 42%, transparent);
    color: var(--cat-ink);
    text-decoration: none;
}

/* Topics with nothing published yet stay present but recede. */
.cat-tag.is-empty {
    background: transparent;
    border-color: var(--border-strong);
    color: var(--text-muted);
}
a.cat-tag.is-empty:hover {
    border-color: color-mix(in srgb, var(--cat-accent) 34%, transparent);
    color: var(--cat-ink);
}

.cat-tag-more {
    background: transparent;
    border-style: dashed;
    border-color: color-mix(in srgb, var(--cat-accent) 34%, transparent);
    color: var(--cat-ink);
    font-weight: 600;
}

/* --- Bottom action -------------------------------------------------------- */
.cat-cta {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-top: auto;
    padding-top: 14px;
    border-top: 1px solid color-mix(in srgb, var(--cat-accent) 12%, var(--border));
    color: var(--cat-ink);
    font-size: .82rem;
    font-weight: 600;
    letter-spacing: .005em;
    opacity: .85;
    transition: opacity .22s ease;
}
.cat-cta svg {
    flex-shrink: 0;
    margin-left: auto;
    transition: transform .22s ease;
}
.cat-card:hover .cat-cta { opacity: 1; }
.cat-card:hover .cat-cta svg { transform: translateX(4px); }

/* --- Dark theme ----------------------------------------------------------- */
/* The hand picked ink tones are tuned for white; on dark, lift them off the
   accent instead so every subject keeps its identity and stays readable. */
[data-theme="dark"] .cat-card {
    --cat-ink: color-mix(in srgb, var(--cat-accent) 55%, #ffffff);
    --cat-line: color-mix(in srgb, var(--cat-accent) 22%, var(--border));
    background:
        linear-gradient(180deg, color-mix(in srgb, var(--cat-accent) 12%, transparent), transparent 46%),
        var(--surface);
    box-shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 18px 34px -24px rgba(0, 0, 0, .8);
}
[data-theme="dark"] .cat-card:hover {
    box-shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 26px 44px -24px color-mix(in srgb, var(--cat-accent) 40%, rgba(0, 0, 0, .85));
}
[data-theme="dark"] .cat-tag { background: color-mix(in srgb, var(--cat-accent) 14%, transparent); }
[data-theme="dark"] .cat-tag.is-empty { background: transparent; }

@media (max-width: 575.98px) {
    .cat-card { padding: 24px 18px 16px; }
    .cat-card .cat-mark { width: 48px; height: 48px; border-radius: 14px; }
    .cat-name { font-size: 1.05rem; }
}

/* --------------------------------------------------------------------------
   Home page technology rails
   Two columns of logo cards drifting top-to-bottom in the empty gutters either
   side of .container-app. Decorative only, so pointer-events are off and the
   markup is aria-hidden - a click anywhere passes straight through to the page.

   Scope. The markup lives inside <section class="hero"> and is positioned
   absolute against it, so the rails start and end with the hero band and
   scroll away with it. They are not fixed to the viewport and do not follow
   the reader down past the first screen.

   Sizing. .container-app caps at 1240px, so the free space on each side is
   (viewport - 1240) / 2 plus the container's own 16px padding. The width is a
   clamp() of that space rather than a set of fixed steps, so the rail always
   uses what the gutter actually has: it never has to be re-tuned for one more
   laptop size. 1272 (not 1240) is subtracted because 100vw counts the
   scrollbar, which the layout width does not - without that margin the rail
   comes out about 8px too wide on Windows and clips the text.

   The 1350px floor is the narrowest viewport that still leaves room for the
   56px minimum plus its offset. Below it there is no gutter worth using, so
   the rails stay hidden and phones and tablets are untouched.
   -------------------------------------------------------------------------- */
.tech-rail { display: none; }

@media (min-width: 1350px) {
    body.page-home .tech-rail {
        display: block;
        position: absolute;
        top: 0;
        bottom: 0;
        width: clamp(56px, calc((100vw - 1272px) / 2), 96px);
        z-index: 0;
        overflow: hidden;
        pointer-events: none;
        /* Fade the ends so cards drift in and out instead of being cut off. */
        -webkit-mask-image: linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent);
        mask-image: linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent);
    }
    body.page-home .tech-rail-left { left: 4px; }
    body.page-home .tech-rail-right { right: 4px; }

    .tech-rail-track {
        display: flex;
        flex-direction: column;
        align-items: center;
        /* The list is rendered twice; travelling -50% lands copy two exactly
           where copy one started, so the restart is invisible. */
        animation: tech-rail-drift 46s linear infinite;
    }
    .tech-rail-right .tech-rail-track { animation-duration: 58s; }

    .tech-rail-card {
        display: flex;
        flex-direction: column;
        align-items: center;
        /* Capped so the cards stay the same compact size on a wide rail
           instead of stretching to fill it. */
        width: min(100%, 72px);
        gap: 5px;
        flex: 0 0 auto;
        margin-bottom: 14px;
        padding: 9px 4px 7px;
        border: 1px solid var(--border);
        border-radius: var(--radius);
        background: var(--surface);
        box-shadow: var(--shadow-sm);
    }
    .tech-rail-card img { width: 30px; height: 30px; display: block; }
    .tech-rail-card span {
        font-size: .62rem;
        font-weight: 600;
        line-height: 1.1;
        color: var(--text-muted);
        text-align: center;
        letter-spacing: .01em;
        white-space: nowrap;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
    }
}

@keyframes tech-rail-drift {
    from { transform: translateY(-50%); }
    to   { transform: translateY(0); }
}

/* The global reduced-motion rule collapses every animation to .01ms, which
   would freeze the rails mid-list. Hide them outright instead. */
@media (prefers-reduced-motion: reduce) {
    .tech-rail { display: none !important; }
}
