:root {
    --palette-blue:   #4d7ce0;
    --palette-orange: #e26640;
    --palette-green:  #3fa24c;
    --palette-teal:   #2496b2;
    --palette-pink:   #e84f6e;
    --palette-purple: #845fc4;
    --palette-amber:  #9e6324;
    --palette-red:    #e44444;

    --color-bg: #faf7ff;  /* #fef9f9; #fffcfa; #f1f4f6; #fafaf9; */
    --color-bg-card: #ffffff;
    --color-text: #1c1917;
    --color-text-muted: #78716c;
    /* Neutral UI accent: focus rings, active filter pills, follow button, rail
       hover. A cool grey carrying a trace of the background's violet, so it
       recedes behind the per-topic colors instead of competing with them —
       the multicolor topic hues are the only real accents on the page. */
    --color-primary: #585563;
    --color-primary-hover: #454351;
    --color-accent: #f59e0b;
    --color-link: #2563eb;
    --color-link-hover: #1d4ed8;
    --color-border: #e7e5e4;
    --color-badge-verified: #059669;
    --color-badge-submitter: #7c3aed;
    --color-badge-admin: #dc2626;
    --color-topic-default: #797979;
    /* Used by the TomSelect topic chips in the submit/sockpuppet forms —
       kept in sync with the .topic-tag treatment below. */
    --color-topic-bg: color-mix(in srgb, var(--color-topic-default) 20%, transparent);
    --color-topic-text: color-mix(in srgb, var(--color-topic-default) 88%, black);
    --color-upvote: #f97316;
    --color-upvote-active: #ea580c;
    --color-downvote: #6366f1;
    --color-score: #44403c;

    --rail-width: 250px;
    /* The rail scrolls (overflow-y), which clips focus rings at its edges.
       It pads by this much and cancels it with an equal negative margin, so
       rings have room to bleed while content still lines up with the track. */
    --rail-bleed: 4px;
    --content-width: 700px;

    /* Below lg the page is one centered column; the topbar and footer use the
       same two numbers so their edges line up with the content. */
    --shell-max: 760px;
    --shell-pad: 1rem;

    /* Card lift: a hairline ambient shadow plus a soft drop, warmed slightly
       to sit on the off-white page background rather than pure grey. */
    --shadow-card: 0 1px 2px rgba(28, 25, 23, 0.04),
                   0 2px 6px rgba(28, 25, 23, 0.05);
    --shadow-card-hover: 0 1px 2px rgba(28, 25, 23, 0.05),
                         0 4px 12px rgba(28, 25, 23, 0.08);
}

/* Shared gutter for the mobile topbar and standalone footer. Bootstrap's
   responsive .container steps through fixed widths (540/720/960px), which
   drifts out of alignment with the fluid content column between 576px and
   992px — hence .container-fluid plus our own max-width. */
.layout-container {
    max-width: var(--shell-max);
    padding-left: var(--shell-pad);
    padding-right: var(--shell-pad);
}

/* ===================================================================
   Typography scale.

   Everything downstream is sized in rem, so the root size is the single
   knob for overall text size. Mobile keeps the 16px browser default;
   desktop (>= lg, where the rail shell takes over) steps up to 17px.
   Headings and link titles get an extra bump that applies at every width.
   =================================================================== */
html { font-size: 16px; }

@media (min-width: 992px) {
    html { font-size: 17px; }
}

h1, .h1 { font-size: 2.4rem; }
h2, .h2 { font-size: 2.05rem; }
h3, .h3 { font-size: 1.95rem; }
h4, .h4 { font-size: 1.7rem; }
h5, .h5 { font-size: 1.4rem; }

body {
    background-color: var(--color-bg);
    color: var(--color-text);
    font-family: system-ui, -apple-system, sans-serif;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* Floating background shapes are a parked feature — styles live in
   static/css/_parked/bg-shapes.css (not linked). See
   templates/_parked/bg_shapes.html for re-enable instructions. */

/* page-title row: heading area at the top of the content column */
.page-header-bar {
    padding: 0 0 1rem;
}

a {
    color: var(--color-link);
    text-decoration: none;
}

a:hover {
    color: var(--color-link-hover);
}

.welcome-banner > div {
    background-color: color-mix(in srgb, var(--palette-blue) 20%, white);
    font-size: 0.9rem;
}


.welcome-banner .btn-close {
    transform: scale(0.75);
    padding-top: 1rem;
}


.welcome-banner-title {
    color: var(--palette-blue);
    font-weight: 600;
    font-size: 1.2rem;
}

.welcome-banner a {
    color: var(--palette-blue)!important;
    font-weight: 500;
    text-decoration:none;
}

.welccome-banner > a:visited {
    color: var(--palette-blue)!important;
    text-decoration:none;
}

.alert {
    --alert-color: var(--palette-blue);
    background-color: color-mix(in srgb, var(--alert-color) 15%, transparent);
    color: var(--color-text);
    border: none;
    /* border: 1px solid color-mix(in srgb, var(--alert-color) 30%, transparent); */
}

.alert-success                    { --alert-color: var(--palette-green); }
.alert-danger, .alert-error       { --alert-color: var(--palette-red); }
.alert-warning                    { --alert-color: var(--palette-orange); }
.alert-info                       { --alert-color: var(--palette-blue); }

.alert .btn-close {
    filter: none;
    opacity: 0.5;
    transform: scale(0.7);
    padding: 1.25rem 0.75rem;
}

.navbar {
    position: sticky;
    top: 0;
    z-index: 1030;
    /* The topbar only exists below lg, where it sits directly on the page
       rather than floating over a scrolling column — so it matches the page
       background and separates with a hairline instead of a shadow. */
    background-color: var(--color-bg) !important;
    border-bottom: 1px solid var(--color-border);
    --bs-navbar-color: rgba(28, 25, 23, 0.8);
    --bs-navbar-hover-color: rgba(28, 25, 23, 1);
    --bs-navbar-active-color: rgba(28, 25, 23, 1);
}

.navbar .nav-link {
    color: rgb(97, 82, 75);
}

.navbar .nav-link:hover {
    color: rgb(43, 37, 33);
}

.navbar-brand,
.rail-brand {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 700;
    letter-spacing: -0.5px;
    color: var(--color-text);
}

.navbar-brand { font-size: 1.8rem; }

.logo-svg {
    object-fit: contain;
    flex-shrink: 0;
}

.navbar .logo-svg { height: 32px; width: 32px; }

.brand-wordmark { line-height: 1; }

.navbar-icon-btn {
    border: none !important;
    box-shadow: none !important;
    padding: 0.375rem 0.5rem;
    color: rgba(28, 25, 23, 0.8);
}

.navbar-icon-btn:focus,
.navbar-icon-btn:active {
    outline: none;
    box-shadow: none !important;
}

.navbar-icon-btn:hover {
    color: rgba(28, 25, 23, 1);
}

.navbar-menu-icon {
    transition: transform 0.25s ease;
}

.navbar-toggler[aria-expanded="true"] .navbar-menu-icon {
    transform: rotate(90deg);
}

/* The panel takes a full row of the wrapping navbar, so the search box drops
   below the brand when the magnifier opens it. Spacing lives here rather than
   in utility classes on the markup so the medium-width rules below can move
   the whole thing into the top row without fighting !important. */
#navSearch {
    width: 100%;
}

.navbar-search {
    max-width: 270px;
    margin: 0.5rem auto;
    position: relative;
}

/* Menu items live behind the hamburger at the right edge, so they read better
   right-aligned under it than stacked on the left. The row padding Bootstrap
   gives .nav-link suits a horizontal bar; in this vertical stack it leaves the
   list looking loose. */
#navMain .navbar-nav {
    align-items: flex-end;
}

#navMain .nav-link {
    padding-top: 0.15rem;
    padding-bottom: 0.15rem;
}

/* Above this width there is room to keep the search box on screen full time,
   so it takes the magnifier's place in the top row — right-aligned, with the
   hamburger still to its right — instead of dropping into a row of its own.
   Below this, and up to the breakpoint where the rail takes over, the
   magnifier comes back and opens the centered panel. */
@media (min-width: 576px) and (max-width: 991.98px) {
    .navbar-search-toggler {
        display: none;
    }

    #navSearch.collapse:not(.show) {
        display: block;
    }

    /* Order puts the field ahead of the hamburger; margin-left pins that pair
       to the right edge. #navMain still wraps to its own row below (it carries
       Bootstrap's flex-basis: 100%), so it needs to sort last. */
    #navSearch {
        order: 1;
        width: auto;
        margin-left: auto;
    }

    .navbar-actions {
        order: 2;
    }

    #navMain {
        order: 3;
    }

    .navbar-search {
        width: 240px;
        margin: 0 0.5rem 0 0;
    }
}

.navbar-search .form-control {
    border-color: var(--color-border);
    border-radius: 999px;
    font-size: 1rem;
    padding: 0.25rem 0.75rem;
}

.navbar-search .form-control::placeholder {
    color: var(--bs-navbar-color);
}

.navbar-search .form-control:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 0.15rem color-mix(in srgb, var(--color-primary) 25%, transparent);
}

.navbar-search-dropdown {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 0.25rem;
    padding: 0.5rem 0.75rem;
    background: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    font-size: 0.9rem;
    z-index: 1000;
}

.navbar-search:focus-within .navbar-search-dropdown {
    display: block;
}

/* Cards pick up their lead topic's color on hover (set inline as --card-color
   in partials/link_card.html); untagged links fall back to the primary. */
.link-card {
    background: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 1rem;
    margin-bottom: 0.75rem;
    box-shadow: var(--shadow-card);
    transition: border-color 0.15s, box-shadow 0.15s;
}

.link-card:hover {
    border-color: color-mix(in srgb, var(--card-color, var(--color-primary)) 45%, transparent);
    box-shadow: var(--shadow-card-hover);
}

.link-title {
    font-weight: 600;
    color: var(--color-text);
    font-size: 1.15rem;
}

.link-domain {
    color: var(--color-text-muted);
    font-size: 0.85rem;
}

.link-description {
    color: var(--color-text);
    font-size: 0.875rem;
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

@media (max-width: 575px) {
    .link-description {
        -webkit-line-clamp: 4;
    }
}

.link-description-full {
    color: var(--color-text);
    font-size: 0.875rem;
    line-height: 1.55;
}

.link-meta {
    color: var(--color-text-muted);
    font-size: 0.85rem;
}

/* Topic tags: each tag carries its topic's hue via the inline --tag-color
   custom property; everything else (tint strength, hover fill) is derived
   here so the saturation can be tuned in one place. */
.topic-tag {
    --tag: var(--tag-color, var(--color-topic-default));
    display: inline-block;
    background-color: color-mix(in srgb, var(--tag) 20%, transparent);
    color: color-mix(in srgb, var(--tag) 88%, black);
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    text-decoration: none;
    /* Keeps the TOPIC_PREFIX marker on the same line as its slug — the hair
       space between them is breakable. */
    white-space: nowrap;
    transition: background-color 0.15s, color 0.15s;
}

.topic-tag:hover {
    background-color: var(--tag);
    color: #fff;
}

/* Headings that belong to a topic/group take on its color. */
.topic-heading {
    color: color-mix(in srgb, var(--tag-color, var(--color-topic-default)) 90%, black);
}

.vote-btn {
    background: none;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    padding: 0.25rem 0.5rem;
    cursor: pointer;
    color: var(--color-text-muted);
    font-size: 0.85rem;
    transition: all 0.15s;
}

.vote-btn:hover {
    border-color: var(--color-upvote);
    color: var(--color-upvote);
}

.vote-btn.active {
    border-color: var(--color-upvote-active);
    color: var(--color-upvote-active);
    background-color: #fff7ed;
}

.vote-btn.downvote:hover {
    border-color: var(--color-downvote);
    color: var(--color-downvote);
}

.score-display {
    font-weight: 600;
    color: var(--color-score);
    font-size: 0.85rem;
}

.vote-inline {
    font-size: 0.85rem;
    gap: 0.4rem !important;
}

.link-meta-link:hover {
    text-decoration: underline;
    color: var(--color-text-muted);
}

@media (max-width: 575px) {
    .link-byline {
        width: 100%;
    }
}

.badge-verified {
    background-color: var(--color-badge-verified);
    color: white;
    font-size: 0.7rem;
    padding: 0.15rem 0.4rem;
    border-radius: 4px;
    font-weight: 600;
}

.badge-submitter {
    background-color: var(--color-badge-submitter);
    color: white;
    font-size: 0.7rem;
    padding: 0.15rem 0.4rem;
    border-radius: 4px;
    font-weight: 600;
}

.badge-admin {
    background-color: var(--color-badge-admin);
    color: white;
    font-size: 0.7rem;
    padding: 0.15rem 0.4rem;
    border-radius: 4px;
    font-weight: 600;
}

.comment-card {
    border-left: 2px solid var(--color-border);
    padding-left: 1rem;
    margin-bottom: 0.75rem;
    margin-top: 0.5rem;
    min-width: 0;
    width: 100%;
}

.comment-actions .vote-inline {
    font-size: 0.8rem;
}

.comment-actions .vote-inline .score-display {
    font-size: 0.8rem;
}

.comment-actions .vote-inline .vote-btn.downvote {
    display: none;
}

.comment-sticky {
    border-left-color: var(--color-badge-verified);
    background-color: color-mix(in srgb, var(--color-badge-verified) 5%, transparent);
    border-radius: 0 4px 4px 0;
    padding: 0.5rem 0.5rem 0.5rem 1rem;
}

.sticky-badge {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-badge-verified);
}

.comment-card .comment-card {
    margin-left: 1rem;
}

/* Admin comment feed: each entry is a comment plus a line naming the post it
   lives on, since the feed cuts across every thread on the site. */
.feed-entry {
    margin-bottom: 1.25rem;
}

.feed-entry .comment-card {
    margin-top: 0.25rem;
}

.feed-entry-context {
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.feed-entry-context a {
    color: var(--color-text-muted);
    text-decoration: underline;
}

.feed-entry-context a:hover {
    color: var(--color-text);
}

.feed-entry-reply {
    font-style: italic;
}

.comment-author {
    font-weight: 600;
    font-size: 0.9rem;
}

.comment-body {
    margin-top: 0.25rem;
}

.comment-meta {
    color: var(--color-text-muted);
    font-size: 0.8rem;
}

.anon-name {
    color: var(--color-text-muted);
    font-style: italic;
}

.time-filter .btn {
    font-size: 0.85rem;
}

.time-filter .btn.active {
    background-color: var(--color-primary);
    border-color: var(--color-primary);
    color: white;
}

.trending-topic {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--color-border);
}

.trending-count {
    color: var(--color-text-muted);
    font-size: 0.85rem;
}

.follow-btn {
    background-color: var(--color-primary);
    color: white;
    border: none;
    border-radius: 6px;
    padding: 0.4rem 1rem;
    font-size: 0.85rem;
    cursor: pointer;
}

.follow-btn:hover {
    background-color: var(--color-primary-hover);
}

.link-preview-img {
    width: 100%;
    max-height: 300px;
    object-fit: cover;
    border-radius: 6px;
    margin-bottom: 0.75rem;
    display: block;
}

.follow-btn.following {
    background-color: var(--color-bg);
    color: var(--color-primary);
    border: 1px solid var(--color-primary);
}

.auth-help-text {
    margin-top: 0.35rem;
}

.auth-help-text ul {
    padding-left: 1.25rem;
    margin-bottom: 0;
}

.site-footer {
    background-color: var(--color-bg);
    border-top: 1px solid var(--color-border);
    padding: 1.5rem 0;
    color: var(--color-text-muted);
    font-size: 0.85rem;
}

.site-footer a {
    color: var(--color-text-muted);
}

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

.site-footer-brand {
    font-weight: 600;
    color: var(--color-text);
}

/* ===================================================================
   Two-column shell: fixed left rail (desktop) + content column.
   On mobile (< lg) the rail is hidden and the topbar navbar takes over.
   =================================================================== */
.app-shell {
    flex: 1 1 auto;
    width: 100%;
}

/* Mobile: single content column under the topbar */
@media (max-width: 991.98px) {
    .app-shell {
        max-width: var(--shell-max);
        margin: 0 auto;
        padding: 1.5rem var(--shell-pad) 0;
    }
}

/* Desktop: rail + content, cluster centered */
@media (min-width: 992px) {
    .app-shell {
        display: grid;
        grid-template-columns: var(--rail-width) minmax(0, var(--content-width));
        gap: 3rem;
        max-width: calc(var(--rail-width) + 3rem + var(--content-width));
        margin: 0 auto;
        padding: 0 1.5rem;
        align-items: start;
    }

    .rail {
        position: sticky;
        top: 0;
        height: 100vh;
        flex-direction: column;
        /* Within-group step. The rail reads as three chunks — masthead + search,
           auth/nav, topics — and the groups add margin on top of this; see
           .rail-nav / .rail-topics. */
        gap: 0.65rem;
        padding: 2rem var(--rail-bleed) 1.5rem;
        margin-inline: calc(var(--rail-bleed) * -1);
        overflow-y: auto;
    }

    .app-content {
        padding: 2rem 0 3rem;
    }
}

/* Auth pages (allauth templates in templates/account/) are a single centered
   panel. They used to be fractional grid columns, which read as a narrow strip
   once the rail shrank the content column to --content-width; a fixed cap
   sizes them to the form instead of to the viewport. */
.auth-panel {
    max-width: 440px;
}

.rail-brand { font-size: 2.5rem; }
.rail .logo-svg { height: 44px; width: 44px; }

.rail-masthead {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

/* Spans the full rail width, under the whole brand lockup. */
.rail-tagline {
    margin-bottom: 0;
    margin-top: 0.5rem;
    font-size: 0.95rem;
    line-height: 1.35;
    color: var(--color-primary);
    text-wrap: balance;
}

.rail-search .form-control {
    border-color: var(--color-border);
    border-radius: 999px;
    font-size: 0.95rem;
    padding: 0.35rem 0.9rem;
}

.rail-search .form-control:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 0.15rem color-mix(in srgb, var(--color-primary) 25%, transparent);
}

/* The topic-scope toggle on topic pages: a chip that appears under the search
   box only while the search box has focus. It hangs off the rail's search box
   in flow (pushing the nav below it down) and floats over the navbar's as a
   popover — see the two placement blocks further down.

   display:none is what hides it, rather than opacity alone. Bootstrap sizes the
   collapsing #navSearch panel from its scrollHeight, and an absolutely
   positioned descendant still counts toward that — leaving the chip in the
   layout made the navbar expand to fit it and then snap back. Kept out of the
   box tree entirely, the panel measures the input alone. */
.search-scope {
    --tag: var(--tag-color, var(--color-topic-default));
    display: none;
    align-items: center;
    gap: 0.4rem;
    /* The rail scrolls on the y axis, which also clips x, so the chip stays
       inside the input's width and truncates a long slug instead of being cut
       off mid-word at the rail edge. */
    max-width: 100%;
    margin-top: 0.45rem;
    padding: 0.2rem 0.7rem;
    border: 1px solid color-mix(in srgb, var(--tag) 30%, transparent);
    border-radius: 999px;
    background-color: var(--color-bg-card);
    font-size: 0.78rem;
    line-height: 1.4;
    color: var(--color-text-muted);
    cursor: pointer;
    /* allow-discrete lets the display switch participate in the transition, so
       the chip can still fade in on the way to display:inline-flex; browsers
       without it simply snap, which is the same end state. */
    transition: opacity 0.15s ease, transform 0.15s ease,
                background-color 0.15s, border-color 0.15s, color 0.15s,
                display 0.15s allow-discrete;
}

/* Focus anywhere in the form reveals it — including focus on the checkbox
   itself, so clicking the toggle doesn't dismiss the thing being clicked. */
.navbar-search:focus-within .search-scope,
.rail-search:focus-within .search-scope {
    display: inline-flex;
    opacity: 1;
}

/* Rail: sits in normal flow, so revealing it pushes the nav and topic list
   below it down rather than covering them — and the push is animated.

   Height can't transition from 0 to auto, so .rail-scope-slot animates its
   max-height and clips the chip on the way. The earlier version made the form
   a grid and animated a 0fr → 1fr row, which made the search input a grid item:
   while the fr row interpolated, leftover space landed in the auto row above it
   (align-content defaults to stretch) and the input visibly stretched and
   snapped back. Nothing here touches the input's box. The 3rem ceiling is
   roughly double the chip's real height — the chip is a single nowrap line, so
   it can't outgrow it, and the slack is small enough not to skew the timing. */
.rail-scope-slot {
    overflow: hidden;
    max-height: 0;
    transition: max-height 0.18s ease;
}

.rail-search:focus-within .rail-scope-slot {
    max-height: 3rem;
}

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

.rail-search .search-scope {
    display: inline-flex;
    opacity: 0;
    transition: opacity 0.18s ease, background-color 0.15s, border-color 0.15s,
                color 0.15s;
}

/* Navbar: floats over the page as a popover, centered on the search box. */
.navbar-search .search-scope {
    position: absolute;
    top: 100%;
    left: 50%;
    z-index: 1000;
    box-shadow: var(--shadow-card);
    opacity: 0;
    transform: translate(-50%, -0.25rem);
}

.navbar-search:focus-within .search-scope {
    transform: translate(-50%, 0);
}

/* The pre-reveal state the navbar popover animates out of. */
@starting-style {
    .navbar-search:focus-within .search-scope {
        opacity: 0;
        transform: translate(-50%, -0.25rem);
    }
}

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

/* Checked is the default state, and the tint is what ties the chip to its
   topic; unchecked drains back to a plain card-colored popover. */
.search-scope:has(:checked) {
    background-color: color-mix(in srgb, var(--tag) 18%, var(--color-bg-card));
    border-color: color-mix(in srgb, var(--tag) 45%, transparent);
    color: color-mix(in srgb, var(--tag) 88%, black);
}

.search-scope span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.search-scope strong {
    font-weight: 600;
}

.search-scope .form-check-input {
    /* Bootstrap's .form-check-input assumes a floated layout inside
       .form-check; this chip lays it out with flex instead. */
    float: none;
    margin: 0;
    flex-shrink: 0;
    width: 0.85rem;
    height: 0.85rem;
    border-color: color-mix(in srgb, var(--tag) 50%, transparent);
    cursor: pointer;
}

.search-scope .form-check-input:checked {
    background-color: var(--tag);
    border-color: var(--tag);
}

.search-scope .form-check-input:focus {
    border-color: var(--tag);
    box-shadow: 0 0 0 0.15rem color-mix(in srgb, var(--tag) 25%, transparent);
}

.rail-nav {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

/* Between-group step, on top of the rail's own gap. Whitespace does the
   grouping rather than rules — the rail already has plenty of edges in the
   search field and the topic pills. */
.rail-nav,
.rail-topics {
    margin-top: 1.15rem;
}

.rail-link {
    color: var(--color-text);
    font-weight: 500;
    font-size: 1rem;
    padding: 0.3rem 0;
}

.rail-link:hover { color: var(--color-primary); }
.rail-link.active { color: var(--color-primary); font-weight: 600; }

/* Logged-out auth affordance, shared by the rail and the mobile topbar. A plain
   "Log in / Sign up" text pair read as one more nav row and made both halves
   equally weak; this gives sign-up one clear target and demotes log-in to a
   quiet line under it. Blue because the welcome banner already makes blue the
   site's sign-up cue.

   The base is the tinted pill the rail uses. The topbar overrides it to a solid
   fill (.auth-cta-sm): the rail is a quiet sidebar where an outline reads fine,
   while the topbar pill has to hold its own next to the wordmark. */
.auth-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.3rem 1rem;
    border: 1px solid color-mix(in srgb, var(--palette-blue) 30%, transparent);
    border-radius: 999px;
    background-color: color-mix(in srgb, var(--palette-blue) 20%, white);
    color: var(--palette-blue);
    font-weight: 600;
    font-size: 0.9rem;
    line-height: 1.4;
    white-space: nowrap;
    transition: background-color 0.15s ease, border-color 0.15s ease,
                color 0.15s ease;
}

.auth-cta:hover {
    background-color: color-mix(in srgb, var(--palette-blue) 16%, transparent);
    border-color: color-mix(in srgb, var(--palette-blue) 45%, transparent);
    color: color-mix(in srgb, var(--palette-blue) 85%, black);
}

/* Topbar variant: solid, and sized to the search field beside it. The line box
   is set in rem rather than as a multiplier so it matches the input's 1rem x 1.5
   regardless of the pill's own smaller font-size; with equal vertical padding
   and the border standing in for the input's, the two boxes come out the same
   height. */
.auth-cta-sm {
    padding: 0.25rem 0.85rem;
    border-color: transparent;
    background-color: var(--palette-blue);
    color: #fff;
    font-size: 0.85rem;
    line-height: 1.5rem;
}

.auth-cta-sm:hover {
    background-color: color-mix(in srgb, var(--palette-blue) 85%, black);
    border-color: transparent;
    color: #fff;
}

/* Narrow phones can't fit the wordmark, the pill and both icon buttons on one
   row, and wrapping to a second row costs more than the shortcut is worth —
   logged-out visitors still get sign-up from the welcome banner, the menu and
   the footer. */
@media (max-width: 349.98px) {
    .auth-cta-sm { display: none; }
}

/* align-items keeps the pill at its content width instead of stretching across
   the rail — full width made it shout. */
.rail-auth {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
}

.rail-auth-note {
    margin: 0;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.rail-auth-note a {
    color: var(--color-text-muted);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.rail-auth-note a:hover { color: var(--color-text); }

.rail-topics {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.rail-topic-group-name {
    display: block;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    /* Same mix as .topic-tag's text, so the heading reads as part of the
       group of pills under it. --tag-color comes from the group wrapper. */
    color: color-mix(in srgb, var(--tag-color, var(--color-topic-default)) 88%, black);
    font-weight: 600;
    margin-bottom: 0.35rem;
}

.rail-topic-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

/* Footer folded into the bottom of the rail */
.rail-footer {
    margin-top: auto;
    padding-top: 1rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.rail-footer a { color: var(--color-text-muted); }
.rail-footer a:hover { color: var(--color-text); }
.rail-footer-copy { width: 100%; }

/* The topic marker ends in a hair space, which is breakable -- same reason
   .topic-tag sets this. Keeps "RSS: /essays" from splitting after the slash. */
.feed-link { white-space: nowrap; }

.submit-form { max-width: 560px; }
