/* === similar-quotes.css === */
/* similar-quotes.css
 * ============================================
 * Styles for the similar quotes search component.
 * Migrated from global_bootstrap.css during 74-6.
 *
 * Last updated: 2025-12-27
 */

/* === BASE STYLES === */
.similar-quotes-input-container {
    position: relative;
    width: 100%;
    margin: 0;
}

.similar-quotes-input {
    width: 100%;
    margin: 0;
    padding: 0.5rem;
}

.similar-quotes-submit {
    width: 100%;
    padding: 0.75rem 1rem;
    white-space: nowrap;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 3rem;
    font-size: 1.3rem;

    &:disabled {
        cursor: not-allowed;
        opacity: 0.7;
    }

    &.btn-warning {
        color: var(--bs-dark);
    }
}

.similar-quotes-form {
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0;
}

.similar-quotes-search {
    max-width: 800px;
}

/* === MOBILE STYLES === */
@media (max-width: 575.98px) {
    .similar-quotes-detail-card .card-body {
        padding: 0.25rem 0 !important;
    }

    .similar-quotes-form .btn-group .btn {
        padding: 0.5rem 0.25rem;
        font-size: 0.9rem;
    }

    .similar-quotes-input {
        border-width: 2px !important;
        min-height: 60px !important;
    }

    .similar-quotes-submit {
        padding: 0.625rem 1rem !important;
        font-size: 1.1rem !important;
    }
}

/* === DESKTOP STYLES === */
@media (min-width: 768px) {
    .similar-quotes-input {
        min-height: 80px;
        width: 100%;
        line-height: 1.5;
        border: 1px solid var(--bs-border-color);
        border-radius: 8px;
        padding: 12px 40px 12px 12px;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
        resize: none;
    }

    .similar-quotes-form {
        display: flex;
        gap: 1rem;
        align-items: center;
    }

    .similar-quotes-input-container {
        flex: 1;
        margin-bottom: 0;
    }

    .similar-quotes-submit {
        white-space: nowrap;
    }
}

/* === splash-quote.css === */
/* components/splash-quote.css
 * ============================================
 * Splash quote component for page headers.
 * Displays an inspirational quote near the top of a page
 * in a subtle, non-dominating style.
 *
 * Usage:
 *   <figure class="splash-quote">
 *     <blockquote>"Quote text here."</blockquote>
 *     <figcaption>— Author Name</figcaption>
 *   </figure>
 *
 * Last updated: 2026-01-11
 */

/* === SPLASH QUOTE BASE === */
.splash-quote {
    text-align: center;
    margin: 0 auto 1.5rem;
    padding: 0 1rem;

    /* Link wrapper - entire quote is clickable */
    & a {
        display: inline;
        text-decoration: none;
        color: inherit;

        &:hover {
            text-decoration: underline;
            text-decoration-color: var(--bs-gray-400);
            text-underline-offset: 2px;
        }

        &:focus-visible {
            outline: 2px solid var(--bs-primary);
            outline-offset: 2px;
        }
    }

    /* Quote text - inline with attribution */
    & blockquote {
        display: inline;
        font-style: italic;
        font-size: 0.9375rem;
        line-height: 1.6;
        color: var(--bs-secondary);
        margin: 0;
        quotes: "\201C" "\201D";

        &::before {
            content: open-quote;
        }

        &::after {
            content: close-quote;
        }
    }

    /* Attribution - inline after quote */
    & figcaption {
        display: inline;
        font-size: 0.9375rem;
        font-style: italic;
        color: var(--bs-gray-600);
    }
}

/* === RESPONSIVE === */
@media (max-width: 576px) {
    .splash-quote {
        margin-bottom: 1rem;

        & blockquote,
        & figcaption {
            font-size: 0.875rem;
        }
    }
}

/* === mini-console.css === */
/**
 * Mini-Console: Mobile bottom navigation
 * Feature: 038-mobile-style-refresh
 *
 * Fixed bottom bar with 5 nav items for mobile (<768px).
 * Hidden on desktop. Safe-area-inset handling for notched devices.
 *
 * Z-index: 1030 (--z-index-fixed) - same level as navbar
 * Touch targets: 44px minimum per WCAG 2.1 AA
 */

/* ==========================================================================
   Mini-Console Container
   ========================================================================== */

.mini-console {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    /* Height: 44px content (minimum touch target) + safe area for notched devices */
    height: calc(44px + env(safe-area-inset-bottom, 0));
    padding-bottom: env(safe-area-inset-bottom, 0);
    background: white;
    border-top: 1px solid var(--bs-border-color, #D2B48C);
    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    align-items: center;
    z-index: var(--z-index-fixed, 1030);
}

/* ==========================================================================
   Navigation Items
   ========================================================================== */

.mini-console-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 44px;
    min-width: 44px; /* Touch target */
    min-height: 44px; /* Touch target */
    padding: 2px 0;
    color: var(--bs-secondary, #2F4F4F);
    text-decoration: none;
    background: transparent;
    border: none;
    cursor: pointer;
    transition: color 0.15s ease;
    /* Reset button styles */
    font-family: inherit;
    font-size: inherit;
    line-height: 1;
}

.mini-console-item:hover,
.mini-console-item:focus {
    color: var(--bs-primary, #8B4513);
}

.mini-console-item:active {
    transform: scale(0.95);
}

/* Active state */
.mini-console-item.active {
    color: var(--bs-primary, #8B4513);
}

/* ==========================================================================
   Icons
   ========================================================================== */

.mini-console-item .bi {
    font-size: 1.25rem;
    line-height: 1;
    margin-bottom: 2px;
}

/* ==========================================================================
   Labels
   ========================================================================== */

.mini-console-label {
    font-size: 0.625rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

/* ==========================================================================
   Responsive: Hide on desktop (>=768px)
   ========================================================================== */

@media (min-width: 768px) {
    .mini-console {
        display: none;
    }
}

/* ==========================================================================
   Content spacing: Reserve space above mini-console on mobile
   ========================================================================== */

@media (max-width: 767.98px) {
    /* Page footer needs padding to not be hidden behind mini-console + sticky search
     * Mini-console: 44px, Sticky search: ~50px (when visible on home), buffer: 10px.
     * Scoped to the page footer (footer.container-fluid) — a bare `footer` selector
     * also matches semantic in-content <footer> elements (e.g. blockquote attribution
     * .quote-originator) and injected 110px of dead space below quote cards. */
    footer.container-fluid {
        padding-bottom: calc(110px + env(safe-area-inset-bottom, 0)) !important;
    }

    /* Main content area needs margin at bottom */
    main.container-fluid {
        margin-bottom: calc(54px + env(safe-area-inset-bottom, 0));
    }
}

/* ==========================================================================
   Accessibility
   ========================================================================== */

/* Focus visible for keyboard navigation */
.mini-console-item:focus-visible {
    outline: 2px solid var(--bs-primary, #8B4513);
    outline-offset: -2px;
    border-radius: 4px;
}

/* ==========================================================================
   Chat Expansion Isolation: Disable non-chat items while chat is expanded
   ========================================================================== */

/* When chat is expanded, mini-console must sit ABOVE the chat sidebar (z-index 1040)
   so clicks on nav items reach the JS handler for close+navigate behavior. */
body:has(.chat-sidebar.chat-expanded) .mini-console {
    z-index: 1041;
}

body:has(.chat-sidebar.chat-expanded) .mini-console-item:not(.mini-console-chat) {
    opacity: 0.5;
    transition: opacity 0.15s ease;
}

/* ==========================================================================
   Loading Overlay: Full-screen spinner for slow mobile navigation
   ========================================================================== */

.mini-console-loading {
    position: fixed;
    inset: 0;
    background: rgba(255, 255, 255, 0.85);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: calc(var(--z-index-fixed, 1030) + 10);
}

@media (min-width: 768px) {
    .mini-console-loading {
        display: none !important;
    }
}

/* Reduced motion preference */
@media (prefers-reduced-motion: reduce) {
    .mini-console-item,
    body:has(.chat-sidebar.chat-expanded) .mini-console-item:not(.mini-console-chat) {
        transition: none;
    }

    .mini-console-item:active {
        transform: none;
    }

    .mini-console-loading .spinner-border {
        animation: none;
    }
}

/* === progress-bar.css === */
/**
 * Navigation Progress Bar
 * Feature: 038-mobile-style-refresh (FR-009)
 *
 * Thin top-of-viewport progress indicator for page transitions.
 * Essential in PWA standalone mode where no browser chrome provides loading feedback.
 *
 * Z-index: 1040 (above navbar at 1030)
 */

/* ==========================================================================
   Progress Bar Container
   ========================================================================== */

.nav-progress {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    z-index: 1040;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.nav-progress.active {
    opacity: 1;
}

/* ==========================================================================
   Progress Bar Track
   ========================================================================== */

.nav-progress-bar {
    height: 100%;
    width: 0;
    background: var(--bs-primary, #8B4513);
    transition: width 0.3s ease;
}

.nav-progress.active .nav-progress-bar {
    animation: progress-indeterminate 1.5s ease-in-out infinite;
}

/* ==========================================================================
   Animation: Indeterminate progress
   ========================================================================== */

@keyframes progress-indeterminate {
    0% {
        width: 0;
        margin-left: 0;
    }
    50% {
        width: 70%;
        margin-left: 15%;
    }
    100% {
        width: 0;
        margin-left: 100%;
    }
}

/* ==========================================================================
   Accessibility: Reduced motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    .nav-progress,
    .nav-progress-bar {
        transition: none;
    }

    .nav-progress.active .nav-progress-bar {
        animation: none;
        width: 100%;
    }
}

/* === toast.css === */
/**
 * Toast Notification Component
 * Feature: 051-optimistic-collect (FR-009)
 *
 * Accessible toast notifications for error/success feedback.
 * Bottom-center position, auto-dismiss, optional action buttons.
 *
 * Z-index: 9999 (above all other elements)
 */

/* ==========================================================================
   Toast Container
   ========================================================================== */

.qs-toast-container {
    position: fixed;
    bottom: 1rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 9999;
    pointer-events: none;
    /* Safe area inset for iOS devices */
    padding-bottom: env(safe-area-inset-bottom, 0);
}

/* ==========================================================================
   Toast Base Styles
   ========================================================================== */

.qs-toast {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    background: var(--qs-toast-bg, #1a1a1a);
    color: var(--qs-toast-text, #fff);
    border-radius: 0.5rem;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
    pointer-events: auto;
    opacity: 0;
    transform: translateY(1rem);
    transition: opacity 200ms ease-out, transform 200ms ease-out;
    max-width: min(90vw, 400px);
    min-width: 280px;
}

.qs-toast--visible {
    opacity: 1;
    transform: translateY(0);
}

.qs-toast--hiding {
    opacity: 0;
    transform: translateY(0.5rem);
}

/* ==========================================================================
   Toast Type Variants
   ========================================================================== */

.qs-toast--error {
    border-left: 4px solid var(--bs-danger, #dc3545);
}

.qs-toast--success {
    border-left: 4px solid var(--bs-success, #198754);
}

.qs-toast--info {
    border-left: 4px solid var(--bs-info, #0dcaf0);
}

/* ==========================================================================
   Toast Content
   ========================================================================== */

.qs-toast__message {
    flex: 1;
    font-size: 0.9rem;
    line-height: 1.4;
}

/* ==========================================================================
   Toast Action Button
   ========================================================================== */

.qs-toast__action {
    background: transparent;
    border: 1px solid currentColor;
    color: inherit;
    padding: 0.25rem 0.5rem;
    border-radius: 0.25rem;
    cursor: pointer;
    font-size: 0.85rem;
    transition: background 150ms ease;
    white-space: nowrap;
}

.qs-toast__action:hover {
    background: rgba(255, 255, 255, 0.15);
}

.qs-toast__action:focus {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

/* ==========================================================================
   Toast Close Button
   ========================================================================== */

.qs-toast__close {
    background: transparent;
    border: none;
    color: rgba(255, 255, 255, 0.6);
    font-size: 1.25rem;
    cursor: pointer;
    padding: 0;
    line-height: 1;
    margin-left: 0.25rem;
}

.qs-toast__close:hover {
    color: #fff;
}

.qs-toast__close:focus {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

/* ==========================================================================
   Accessibility: Reduced motion
   ========================================================================== */

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

/* ==========================================================================
   Mobile Adjustments
   ========================================================================== */

@media (max-width: 480px) {
    .qs-toast-container {
        left: 0.5rem;
        right: 0.5rem;
        transform: none;
        bottom: 0.5rem;
    }

    .qs-toast {
        max-width: 100%;
        min-width: auto;
    }
}

/* === hero-cards.css === */
/* Hero Cards - Landing page feature showcase
 * Scroll story format with icon + screenshot cards
 */

.hero-cards-section {
    padding-top: 3rem;
    padding-bottom: 1rem;
}

.hero-cards-section .section-title {
    margin-bottom: 2.5rem;
}

/* Feature card base styling */
.hero-cards-section .card {
    transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
}

.hero-cards-section .card:hover {
    transform: translateY(-4px);
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);
}

/* Icon styling */
.hero-cards-section .feature-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 4rem;
    height: 4rem;
    border-radius: 50%;
    background: rgba(var(--bs-primary-rgb), 0.1);
}

.hero-cards-section .feature-icon i {
    font-size: 2rem;
}

/* Screenshot container */
.hero-cards-section .feature-screenshot {
    max-width: 100%;
    overflow: hidden;
    border-radius: 0.5rem;
    box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.1);
}

.hero-cards-section .feature-screenshot img {
    width: 100%;
    height: auto;
    display: block;
}

/* Transparent images (no frame/shadow) */
.hero-cards-section .feature-screenshot.no-frame {
    border-radius: 0;
    box-shadow: none;
}

/* Card body adjustments for screenshot cards */
.hero-cards-section .card.has-screenshot .card-body {
    padding-top: 1.5rem;
}

/* Trending anchor link styling */
.hero-cards-section a.trending-anchor {
    text-decoration: none;
    color: inherit;
}

.hero-cards-section a.trending-anchor:hover {
    text-decoration: none;
}

.hero-cards-section a.trending-anchor:hover .card {
    transform: translateY(-4px);
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);
}

/* Card text refinements */
.hero-cards-section .card-title {
    color: var(--bs-primary);
    font-weight: 600;
}

.hero-cards-section .card-text {
    color: var(--bs-secondary);
    line-height: 1.6;
}

/* Nested card cluster for stacking short cards alongside tall cards */
.hero-cards-section .card-cluster {
    display: flex;
    flex-direction: column;
    gap: 1.5rem; /* Match g-4 gutter */
    height: 100%;
}

.hero-cards-section .card-cluster .card {
    flex: 1; /* Equal height distribution */
}

/* Hover effect for linked cards within cluster */
.hero-cards-section .card-cluster a:hover .card {
    transform: translateY(-4px);
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);
}

/* Responsive adjustments */
@media (max-width: 767.98px) {
    .hero-cards-section {
        padding-top: 2rem;
        padding-bottom: 0.5rem;
    }

    .hero-cards-section .feature-icon {
        width: 3.5rem;
        height: 3.5rem;
    }

    .hero-cards-section .feature-icon i {
        font-size: 1.75rem;
    }
}

/* === genre-tree.css === */
/* Native disclosure tree for book genres. */

.bi-bookshelf::before {
    width: 1em;
    height: 1em;
    content: "";
    background-color: currentcolor;
    mask: url("../../images/bookshelf.e94551734626.svg") center / contain no-repeat;
}

.genre-tree {
    max-width: 64rem;
    margin-inline: auto;
}

.genre-tree-list {
    margin: 0;
}

.genre-tree-list .genre-tree-list {
    margin-left: 0.75rem;
    padding-left: 1.25rem;
    border-left: 1px solid var(--bs-border-color);
}

.genre-tree-item {
    position: relative;
    margin-block: 0.25rem;
}

.genre-tree-list .genre-tree-list > .genre-tree-item::before {
    position: absolute;
    top: 1.15rem;
    left: -1.25rem;
    width: 0.9rem;
    border-top: 1px solid var(--bs-border-color);
    content: "";
}

.genre-tree-summary,
.genre-tree-leaf {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    min-height: 2.25rem;
    padding: 0.35rem 0.6rem;
    border-radius: 0.375rem;
}

.genre-tree-summary {
    cursor: pointer;
}

.genre-tree-summary:hover,
.genre-tree-leaf:hover {
    background: var(--bs-light);
}

.genre-tree-summary:focus-visible,
.genre-tree-summary a:focus-visible,
.genre-tree-leaf a:focus-visible {
    outline: 3px solid rgba(var(--bs-primary-rgb), 0.45);
    outline-offset: 2px;
}

.genre-tree-summary a,
.genre-tree-leaf a {
    color: var(--bs-body-color);
    font-weight: 600;
    text-decoration: none;
}

.genre-tree-summary a:hover,
.genre-tree-leaf a:hover {
    color: var(--bs-primary);
    text-decoration: underline;
}

.genre-tree-count {
    min-width: 2rem;
    margin-left: auto;
    padding: 0.1rem 0.5rem;
    color: var(--bs-secondary-color);
    font-size: 0.8rem;
    text-align: center;
    background: var(--bs-tertiary-bg);
    border-radius: 999px;
}

@media (min-width: 768px) {
    .genre-tree-list .genre-tree-list {
        margin-left: 1rem;
        padding-left: 1.5rem;
    }

    .genre-tree-list .genre-tree-list > .genre-tree-item::before {
        left: -1.5rem;
        width: 1.15rem;
    }
}

/* === recent-snippet.css === */
/* components/recent-snippet.css
 * ============================================
 * Home-page recent quotes partial (spec 112).
 * Constrains the rendered height of the quote text so a single long modern
 * quote (Twitter/podcast captures commonly run 300–500c) can't dominate
 * the above-fold real estate. Truncation is purely visual; the canonical
 * text is preserved server-side and shown in full on the dedicated
 * /recent/{added,quoted}/ pages.
 *
 * Scoped to #recent-snippet-wrapper so other quote-card surfaces are
 * unaffected.
 *
 * Clamp target is the inner .quote-text-body span, NOT the .quote-text
 * blockquote: the blockquote is a flex item, which blockifies the legacy
 * -webkit-box display value (CSS Display L3), so line-clamp won't apply to it.
 * Clamping the inner span gives a real ellipsis for free. quote-clamp.ts
 * detects overflow and injects a Show more/less toggle; .is-expanded removes
 * the clamp. Without JS the clamp + ellipsis still render and each card's
 * permalink links to the full quote.
 */

#recent-snippet-wrapper .quote-text-body {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 6;
    line-clamp: 6;
    overflow: hidden;
}

#recent-snippet-wrapper .quote-text-body.is-expanded {
    display: block;
    -webkit-line-clamp: unset;
    line-clamp: unset;
    overflow: visible;
}

/* Show more / less toggle (injected by quote-clamp.ts). font-style:normal so it
 * doesn't inherit the blockquote's italic; its own line under the clamped text. */
#recent-snippet-wrapper .quote-clamp-toggle {
    display: block;
    width: fit-content;
    margin-top: 0.35rem;
    padding: 0;
    border: 0;
    background: none;
    font-size: 0.875rem;
    font-style: normal;
    line-height: 1.2;
    color: var(--bs-primary);
    cursor: pointer;
}

#recent-snippet-wrapper .quote-clamp-toggle:hover,
#recent-snippet-wrapper .quote-clamp-toggle:focus-visible {
    text-decoration: underline;
}

/* === recent-gate.css === */
/* components/recent-gate.css
 * ============================================
 * "Frosted door" CTA shown to unverified anonymous visitors in place of the
 * Recently Added / Recently Quoted feed (spec 112 FR-010, FR-012).
 *
 * Goal: an inviting doorway that shows the *shape* of what's behind the gate
 * (decorative ghost quote-cards) without rendering any real quote text — the
 * Article XVI.1 data-prep contract forbids leaking quote/originator/source
 * data, and CSS blur would not hide DOM text from scrapers anyway. The ghost
 * cards are pure silhouettes (no text nodes); the CTA sits on top of them and
 * lets just their tops peek out, so they cost almost no vertical space.
 *
 * Scoped to .recent-cta-card. Design tokens only — no hardcoded hex.
 */

.recent-cta-card {
    position: relative;
    overflow: hidden;
    max-width: 880px;
    /* Warm cream pane so the white ghost quote-cards read as cards, mirroring
       the real feed (white cards on the cream page background). */
    background-color: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.05);
}

/* ── Decorative preview layer (behind the CTA) ──────────────────────────── */

.recent-gate__ghosts {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    /* Two rows of naturally-sized quote-cards behind the CTA — a feed-like
       frosted-glass overlay, not two tall cards with empty middles. */
    align-items: start;
    align-content: start;
    gap: var(--space-3, 1rem);
    padding: 0.75rem var(--space-4, 1.5rem);
    overflow: hidden;
    opacity: 0.9;
    filter: blur(1.8px);
    pointer-events: none;
    user-select: none;
}

.ghost-card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--bs-card-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius, 0.375rem);
    /* Tight top padding so the action dots + first "line" sit near the top and
       are visible in the thin peek band. */
    padding: 0.7rem 0.85rem;
    box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.04);
}

.ghost-actions {
    position: absolute;
    top: 0.7rem;
    right: 0.85rem;
    display: flex;
    gap: 0.3rem;
}

.ghost-actions span {
    width: 1rem;
    height: 1rem;
    border-radius: 0.25rem;
    background: color-mix(in srgb, var(--bs-secondary) 18%, transparent);
}

/* Quote "lines" — echo the italic quote body of a real card. */
.ghost-line {
    height: 0.7rem;
    border-radius: 0.35rem;
    margin-bottom: 0.5rem;
    background: color-mix(in srgb, var(--bs-secondary) 23%, transparent);
}

.ghost-line--lg { width: 80%; }
.ghost-line--md { width: 64%; }
.ghost-line--sm { width: 46%; }

/* Footer with a divider above — mirrors a real quote card: quote lines up top,
   then attribution + Find-Similar button beneath the rule. */
.ghost-foot {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.6rem;
    padding-top: 0.7rem;
    border-top: 1px solid color-mix(in srgb, var(--bs-secondary) 12%, transparent);
}

.ghost-avatar {
    flex: 0 0 auto;
    width: 1.3rem;
    height: 1.3rem;
    border-radius: 50%;
    background: color-mix(in srgb, var(--bs-primary) 30%, transparent);
}

.ghost-line--name {
    width: 7rem;
    height: 0.6rem;
    margin-bottom: 0;
    background: color-mix(in srgb, var(--bs-primary) 28%, transparent);
}

/* Find-Similar button silhouette, pushed to the right edge of the footer. */
.ghost-find {
    margin-left: auto;
    width: 5.5rem;
    height: 1.5rem;
    border-radius: 0.3rem;
    background: color-mix(in srgb, var(--bs-primary) 15%, transparent);
}

/* ── Foreground CTA (sits on top of the ghosts) ─────────────────────────── */

.recent-gate__cta {
    position: relative;
    z-index: 1;
    /* Top padding reveals the clear card-tops; below, a TRANSLUCENT cream veil
       keeps the ghost cards faintly visible behind the text (frosted glass)
       while staying legible. Never reaches full opacity. */
    padding: 2.5rem var(--space-4, 1.5rem) var(--space-4, 1.5rem);
    background: linear-gradient(
        to bottom,
        transparent 0,
        color-mix(in srgb, var(--bs-body-bg) 32%, transparent) 1.5rem,
        color-mix(in srgb, var(--bs-body-bg) 58%, transparent) 3rem,
        color-mix(in srgb, var(--bs-body-bg) 64%, transparent) 100%
    );
}

.recent-gate__eyebrow {
    margin-bottom: 0.35rem;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--bs-primary);
    text-shadow: 0 1px 2px var(--bs-body-bg);
}

.recent-gate__title {
    color: var(--bs-secondary);
    font-weight: 700;
    /* Lift the headline off the frosted cards behind it. */
    text-shadow: 0 1px 3px var(--bs-body-bg), 0 0 6px var(--bs-body-bg);
}

.recent-gate__body {
    max-width: 44ch;
    margin-inline: auto;
    text-shadow: 0 1px 2px var(--bs-body-bg), 0 0 5px var(--bs-body-bg);
}

.recent-gate__helper {
    color: color-mix(in srgb, var(--bs-secondary) 62%, transparent);
    text-shadow: 0 1px 2px var(--bs-body-bg);
}

/* ── Responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 575.98px) {
    .recent-gate__ghosts {
        grid-template-columns: 1fr;
    }

    /* Single column on mobile — keep the first two cards (two stacked rows),
       drop the second row's pair. */
    .recent-gate__ghosts .ghost-card--row2 {
        display: none;
    }
}

/* === collection-suggestions.css === */
.collection-suggestions {
  margin: 2rem 0 1.5rem;
  padding-top: 0.75rem;
}

.collection-suggestions__ornament {
  color: #7a4a23;
  font-size: 1rem;
  letter-spacing: 0.8em;
  line-height: 1.2;
  text-align: center;
}

.collection-suggestions__label,
.collection-suggestions__footer {
  color: #5f4632;
  font-style: italic;
  margin: 0.45rem 0 1rem;
  text-align: center;
}

/* Lazy/deferred loading spinner: centered like the ornament/label above it. Scoped to a
   direct-child spinner so the loaded section's full-width cards (also in __list) are untouched. */
.collection-suggestions__list > .spinner-border {
  display: block;
  margin-inline: auto;
}

.collection-suggestions__more {
  border-color: #7a4a23;
  color: #7a4a23;
  display: block;
  margin: 0.5rem auto 0;
}

.collection-suggestions__more:hover,
.collection-suggestions__more:focus {
  background: #7a4a23;
  border-color: #7a4a23;
  color: #fff;
}

.collection-suggestions--tease {
  margin-bottom: 1rem;
}

article[data-suggestion-slot="true"] {
  margin-inline-start: 1.75rem;
  position: relative;
}

article[data-suggestion-slot="true"]::before {
  color: #7a4a23;
  content: "•\A•\A•";
  font-size: 1rem;
  inset-block-start: 1rem;
  inset-inline-start: -1.25rem;
  line-height: 1.05;
  pointer-events: none;
  position: absolute;
  text-align: center;
  white-space: pre-line;
}

[data-suggestion-slot="true"] .collection-drag-handle,
[data-suggestion-slot="true"] [data-collection-select],
[data-suggestion-slot="true"] [data-editor-url],
[data-suggestion-slot="true"] [data-reorder-item] {
  display: none;
}

/* qw-1ytd.6: truncate long suggestion quotes to a preview so a single multi-paragraph
   quote can't dominate the bottom of the collection feed. */
[data-suggestion-slot="true"] blockquote {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  overflow: hidden;
}

/* === quote-share-row.css === */
@font-face {
    font-family: "Caveat";
    src: url("../../fonts/Caveat-Variable.ccf2f844ded8.ttf") format("truetype");
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
}

@font-face {
    font-family: "EB Garamond";
    src: url("../../fonts/EBGaramond-Variable.90a58d69f647.ttf") format("truetype");
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
}

.quote-share-strip {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: min(90%, 38rem);
    gap: 1rem;
    overflow-x: auto;
    padding: 0.25rem;
    scroll-snap-type: x mandatory;
}

.quote-share-card {
    scroll-snap-align: start;
    width: 100%;
    border: 2px solid transparent;
    border-radius: 0.75rem;
    padding: 0.375rem;
    color: inherit;
    background: transparent;
    cursor: pointer;
    font: inherit;
}

.quote-share-card:focus-visible,
.quote-share-card[aria-pressed="true"] {
    border-color: var(--bs-primary);
    outline: 3px solid color-mix(in srgb, var(--bs-primary) 35%, transparent);
    outline-offset: 2px;
}

.quote-share-card canvas {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 0.5rem;
}

.quote-share-card span {
    display: block;
    margin-top: 0.5rem;
    text-align: center;
    font-weight: 600;
}

/* 44px matches the designer's controls and Apple/Material touch guidance;
   btn-sm alone renders 31px, and a bare .form-check-input is 16px, which fails
   WCAG 2.2 SC 2.5.8 (24x24 minimum) even counting the associated label. */
.quote-share-actions .btn {
    min-height: 44px;
}

.quote-share-description-toggle {
    min-height: 44px;
    /* Set apart from the button group: these are different kinds of control,
       and 8px of flex gap read as crowding against the Download button. */
    margin-inline-start: 1rem;
    padding-inline: 0.25rem;
    cursor: pointer;
}

.quote-share-description-toggle .form-check-input {
    width: 1.5rem;
    height: 1.5rem;
    cursor: pointer;
}

.quote-share-credit {
    align-self: center;
    max-width: 32rem;
}

.quote-share-credit summary {
    cursor: pointer;
    min-height: 44px;
    padding: 0.65rem 0;
}

.quote-share-credit summary:focus-visible {
    outline: 3px solid #8b4513;
    outline-offset: 3px;
}

@media (min-width: 992px) {
    .quote-share-strip {
        grid-auto-columns: min(72%, 38rem);
    }
}

/* === collection-workbench.css === */
.collection-workbench {
  min-width: 0;
}

.collection-workbench-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
  justify-content: space-between;
  /* Chrome matches .collection-bulk-toolbar exactly so the header swap (grid
     stack, has-selection) reads as content changing inside one constant card,
     not a card popping in and out. */
  margin-block: 0.75rem 1rem;
  padding: 0.625rem;
  background: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 8px;
}

.collection-toggle-shell {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  align-items: center;
}

.collection-chip-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  min-height: 0;
  margin-block-end: 1rem;
}

.collection-chip {
  display: inline-flex;
  align-items: center;
  min-height: 2rem;
  padding-inline: 0.75rem;
  color: var(--bs-secondary);
  background: var(--bs-light);
  border: 1px solid var(--bs-border-color);
  border-radius: 999px;
}

.collection-stats-section {
  padding-block: 1rem;
  border-block-start: 1px solid var(--bs-border-color);
}

.collection-stats-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
  margin: 0;
}

.collection-stats-grid > div,
.collection-stats-list > div {
  min-width: 0;
}

.collection-stats-grid dt,
.collection-stats-list dt {
  margin-block-end: 0.125rem;
  color: var(--bs-secondary-color);
  font-size: 0.8125rem;
  font-weight: 600;
}

.collection-stats-grid dd,
.collection-stats-list dd {
  margin: 0;
  font-weight: 600;
}

.collection-stats-list {
  display: grid;
  gap: 0.75rem;
  margin: 0;
}

.collection-breakdown-list,
.collection-footprint-list {
  display: grid;
  gap: 0.5rem;
  padding: 0;
  margin: 0;
  list-style: none;
}

.collection-breakdown-list li,
.collection-footprint-list li {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  justify-content: space-between;
  min-width: 0;
}

.collection-bulk-toolbar {
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* Matches .collection-workbench-toolbar's margin-block so the two rows land at the same
     vertical position within the shared grid cell (qw-tewgr Track B). */
  margin-block: 0.75rem 1rem;
  padding: 0.625rem;
  background: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 8px;
}

.collection-bulk-toolbar__form {
  display: flex;
  /* Single row at desktop widths — the picker (select + move/copy) is the only item that
     shrinks (flex: 1 1 auto below); everything else keeps its natural size. Narrow/mobile
     widths fall back to wrapping rather than an overflow-scrolled row. */
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}

.collection-bulk-toolbar__form > * {
  flex: 0 0 auto;
}

.collection-bulk-toolbar__action-form,
.collection-bulk-toolbar__export-form {
  display: contents;
}

.collection-bulk-toolbar__clear {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  color: var(--bs-secondary-color);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--bs-border-radius-sm);
}

.collection-bulk-toolbar__clear:hover {
  color: var(--bs-body-color);
  background: var(--bs-tertiary-bg);
}

.collection-bulk-toolbar__clear:focus-visible {
  outline: 0.15rem solid var(--bs-primary);
  outline-offset: 0.125rem;
}

.collection-bulk-toolbar__count {
  margin-inline-start: -0.125rem;
  font-weight: 600;
  white-space: nowrap;
}

.collection-bulk-toolbar__picker {
  /* Bootstrap's .input-group defaults to width:100%, which makes this flex item
     claim a full toolbar row and wrap everything after it; width:auto lets it
     share the row at its natural (select max-width + buttons) size. */
  width: auto;
  flex: 0 1 auto;
  min-width: 0;
}

.collection-bulk-toolbar__select {
  min-width: 0;
  max-width: 14rem;
}

.collection-bulk-toolbar__template,
.collection-bulk-toolbar__tag {
  width: 100%;
}

.collection-bulk-toolbar__more-menu {
  min-width: 14rem;
}

.collection-bulk-toolbar__more-field {
  padding: 0.25rem 1rem 0.5rem;
}

.collection-select-check {
  width: 1.5rem;
  min-height: 2rem;
  padding-left: 1.5rem;
}

/* Gmail-style master select-all checkbox: one instance rests in #collection-workbench-toolbar,
   one lives in the bulk toolbar row; both carry [data-master-select] and share tri-state
   checked/indeterminate driven by multi-select.ts. Bootstrap's bare .form-check-input assumes
   a .form-check wrapper (float + negative margin-left); reset both since these sit directly in
   a flex row. */
.workbench-master-select {
  float: none;
  margin: 0;
  cursor: pointer;
}

.workbench-master-select-label {
  font-size: 0.875rem;
  color: var(--bs-secondary-color);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

.quote-card.collection-quote-selected {
  border-color: var(--bs-primary);
  box-shadow: 0 0 0 0.125rem color-mix(in srgb, var(--bs-primary) 18%, transparent);
}

.collection-quick-actions {
  display: flex;
  gap: 0.375rem;
  align-items: center;
  padding: 0.5rem;
  overflow-x: auto;
  background: var(--bs-tertiary-bg);
  border-bottom: 1px solid var(--bs-border-color);
  border-radius: 0.375rem 0.375rem 0 0;
}

.collection-quick-actions[hidden] {
  display: none;
}

.collection-quick-actions .btn {
  flex: 0 0 auto;
  min-height: 2.25rem;
  white-space: nowrap;
}

.collection-undo-toast {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 1080;
  display: inline-flex;
  gap: 0.75rem;
  align-items: center;
  max-width: min(28rem, calc(100vw - 2rem));
  padding: 0.75rem 1rem;
  color: var(--bs-body-color);
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 0.5rem;
  box-shadow: var(--bs-box-shadow);
}

.collection-undo-toast__button {
  flex: 0 0 auto;
}

.collection-empty-state {
  max-width: 38rem;
  margin-inline: auto;
}

.collection-search-form {
  padding-block: 0.75rem;
  border-block: 1px solid var(--bs-border-color);
}

.collection-search-form .input-group {
  min-height: 2rem;
}

.collection-search-semantic {
  min-height: 1.5rem;
}

.collection-search-matches {
  display: grid;
  gap: 0.25rem;
  padding: 0.5rem 0.625rem;
  background: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 6px;
}

.collection-search-match {
  overflow-wrap: anywhere;
}

.collection-card-notes-focus .card-body {
  display: grid;
  gap: 0.75rem;
}

.collection-card-notes-focus__controls {
  /* Controls are last in DOM (quote-first for screen readers, qw-1zv2g);
     order:-1 keeps them visually at the top of the grid card-body. */
  order: -1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  justify-content: space-between;
  min-height: 2rem;
}

.collection-card-notes-focus__controls-secondary {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin-inline-start: auto;
}

.collection-card-notes-focus__field {
  display: grid;
  gap: 0.25rem;
  min-width: 0;
}

.collection-card-notes-focus__label {
  color: var(--bs-secondary-color);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
}

.collection-card-notes-focus__value,
.collection-card-notes-focus__quote {
  min-width: 0;
  overflow-wrap: anywhere;
}

.collection-card-notes-focus__quote {
  margin: 0;
}

.collection-card-notes-focus__expander {
  justify-self: start;
  min-height: 2rem;
  padding-inline: 0;
  text-decoration: none;
}

.collection-tag-groups {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem 0.75rem;
  min-width: 0;
  align-items: center;
}

.collection-tag-group {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  align-items: center;
  min-width: 0;
}

.collection-tag-group--personal {
  padding-inline-start: 0.625rem;
  border-inline-start: 2px solid var(--bs-primary-border-subtle);
}

.collection-tag-group__label {
  display: inline-flex;
  align-items: center;
  color: var(--bs-secondary-color);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: uppercase;
}

.collection-tag-badge {
  border: 1px solid var(--bs-border-color-translucent);
}

.collection-tag-badge--personal {
  --bs-badge-color: #5a3a13;

  color: #5a3a13;
  background-color: #fff4cf;
  border-color: #d6b57c;
}

.collection-card-notes-focus__footer {
  padding-block-start: 0.5rem;
  border-block-start: 1px solid var(--bs-border-color);
}

.collection-card-compact__body {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  min-height: 3rem;
  padding-block: 0.5rem;
}

.collection-card-compact__cover,
.collection-card-compact__link {
  flex: 0 0 auto;
}

/* Reading-order fix (qw-1zv2g finding #5c): .collection-card-compact__content is
   DOM-first so screen readers reach the quote before the editing controls; `order`
   restores the visual layout (edit/select left, cover/permalink right). */
.collection-card-compact__edit,
.collection-card-compact__body .collection-select-check {
  order: -1;
}
.collection-card-compact__cover,
.collection-card-compact__link {
  order: 1;
}

/* Live position number inside the drag rail (Organize + Manual mode only).
   Populated client-side from DOM order so it stays correct after drag, undo,
   keyboard reorder, and OOB refreshes. */
.collection-reorder-index {
  flex: 0 0 auto;
  min-width: 1.5rem;
  text-align: center;
  font-size: 1.15rem;
  font-variant-numeric: tabular-nums;
  color: var(--bs-secondary-color);
  user-select: none;
}

/* Bootstrap's .form-check leaks padding-left and a top-margin on the input;
   collection card rows share .collection-select-check across compact, standard,
   and notes-focus densities, so reset there to align the checkbox with the
   rest of the action cluster. The start-margin sets it apart from the action
   buttons so "select" doesn't read as one more action. */
.collection-select-check {
  align-self: center;
  padding-left: 0;
  min-height: 0;
  margin-block: 0;
  margin-inline-start: 0.75rem;
}
.collection-select-check .form-check-input {
  margin-top: 0;
  margin-left: 0;
  float: none;
}

.collection-card-compact__content {
  flex: 1 1 auto;
  min-width: 0;
  line-height: 1.45;
  overflow-wrap: break-word;
}

.collection-card-compact__quote {
  display: inline;
  overflow-wrap: break-word;
}

.collection-card-compact__meta {
  display: inline;
  min-width: 0;
}

.collection-card-compact__originator {
  overflow-wrap: break-word;
}

.collection-card-compact__meta .collection-tag-groups {
  display: contents;
}

.collection-card-compact__meta .collection-tag-group {
  display: inline-flex;
  gap: 0.1875rem;
  max-width: 100%;
  margin-inline-start: 0.5rem;
  vertical-align: baseline;
}

.collection-card-compact__meta .collection-tag-group__label {
  white-space: nowrap;
}

.collection-card-compact__meta .collection-tag-badge {
  display: inline-block;
  max-width: min(8rem, 100%);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: baseline;
}

.collection-card-compact__cover {
  display: inline-flex;
  gap: 0.25rem;
  align-items: center;
}

.collection-card-compact__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  min-width: 2rem;
  height: 2rem;
}

.collection-search-match mark {
  padding-inline: 0.125rem;
  color: inherit;
  background: color-mix(in srgb, var(--bs-warning) 45%, transparent);
  border-radius: 0.125rem;
}

.collection-reorder-section {
  min-width: 0;
}

.collection-reorder-list {
  min-height: 0.75rem;
}

.collection-reorder-section--pinned .collection-reorder-list:empty {
  min-height: 0.75rem;
}

/* Left gutter for the full-height drag rail (qw-tewgr Track A). Only present
   when reorder is enabled; width matches .collection-sort-rail below. */
.collection-reorder-gutter {
  padding-left: 3rem;
}

.collection-reorder-gutter article[data-reorder-item] {
  position: relative;
}

.collection-sort-rail {
  position: absolute;
  top: 0;
  right: 100%;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 3rem;
  gap: 0.25rem;
  cursor: grab;
}

.collection-sort-rail:active {
  cursor: grabbing;
}

.collection-sort-rail__grip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  color: var(--bs-secondary-color);
  /* Bootstrap theme vars keep the chip visible in light and dark (incl. Dark
     Reader, which preserves real borders but washes out bare glyphs). */
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius-sm);
}

.collection-sort-rail__grip:hover,
.collection-sort-rail__grip:focus-visible {
  color: var(--bs-body-color);
}

.collection-sidebar-targets {
  display: none;
  gap: 0.25rem;
}

@media (min-width: 992px) {
  body.collection-drag-active .collection-sidebar-targets {
    display: grid;
  }
}

.collection-sidebar-target {
  min-height: 2.25rem;
  padding: 0.375rem 0.5rem;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--bs-body-color);
}

.collection-sidebar-target.active {
  background: var(--bs-tertiary-bg);
  border-color: var(--bs-border-color);
}

.collection-sidebar-target.sortable-ghost,
.collection-sidebar-target:hover {
  border-color: var(--bs-primary);
}

.collection-sidebar-target--readonly {
  color: var(--bs-secondary-color);
}

.drag-handle {
  width: 2rem;
  height: 2rem;
  padding: 0;
  cursor: grab;
}

.drag-handle:active {
  cursor: grabbing;
}

.quote-card[data-reorder-item="true"] {
  transition: transform 120ms ease, box-shadow 120ms ease, opacity 120ms ease;
}

.quote-card[data-reorder-item="true"]:focus-visible {
  outline: 0.2rem solid var(--bs-primary);
  outline-offset: 0.125rem;
}

.collection-quote-ghost {
  opacity: 0.55;
}

.collection-quote-reorder-pending {
  box-shadow: 0 0 0 0.15rem color-mix(in srgb, var(--bs-primary) 35%, transparent);
}

.collection-pin-button__control {
  display: inline-grid;
  place-items: center;
  min-width: 2rem;
  min-height: 2rem;
  padding: 0;
}

.collection-pin-button__control[aria-pressed="true"] {
  color: #5a3a13;
  border-color: color-mix(in srgb, var(--bs-warning) 70%, var(--bs-border-color));
  box-shadow: 0 0.25rem 0.75rem color-mix(in srgb, var(--bs-warning) 18%, transparent);
}

.collection-pin-button__control[data-collection-pin-pending="true"] {
  transform: translateY(-1px);
}

.collection-drawer-edit #drawer-field-notes.form-control {
  background:
    linear-gradient(
      90deg,
      color-mix(in srgb, var(--bs-warning) 45%, var(--bs-border-color)) 0 0.35rem,
      color-mix(in srgb, var(--bs-warning-bg-subtle, #fff3cd) 48%, var(--bs-body-bg) 52%) 0.35rem 100%
    );
  border-color: color-mix(in srgb, var(--bs-warning) 42%, var(--bs-border-color));
}

.collection-drawer-edit #drawer-field-notes.form-control:focus {
  background:
    linear-gradient(
      90deg,
      color-mix(in srgb, var(--bs-warning) 50%, var(--bs-primary)) 0 0.35rem,
      color-mix(in srgb, var(--bs-warning-bg-subtle, #fff3cd) 42%, var(--bs-body-bg) 58%) 0.35rem 100%
    );
  border-color: var(--bs-primary);
  box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--bs-primary) 20%, transparent);
}

.collection-workbench-drawer.offcanvas {
  --bs-offcanvas-width: min(40vw, 720px);
}

@media (max-width: 767.98px) {
  .collection-card-compact__meta,
  .collection-card-compact__cover {
    display: none;
  }

  /* qw-1ytd.8: condense the control header on mobile — the stat chips become a single
     horizontal-scroll row instead of wrapping to 3, so content isn't pushed far down. */
  .collection-chip-strip {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    margin-block-end: 0.75rem;
  }

  .collection-chip-strip::-webkit-scrollbar {
    display: none;
  }

  .collection-chip {
    flex: 0 0 auto;
  }

  /* Rail shrinks on mobile but never disappears (qw-tewgr Track A). */
  .collection-reorder-gutter {
    padding-left: 2rem;
  }

  .collection-sort-rail {
    width: 2rem;
  }

  .collection-reorder-index {
    font-size: 0.9rem;
  }
}

@media (max-width: 991.98px) {
  .collection-workbench-drawer.offcanvas-end {
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 60vh;
    max-height: calc(100vh - 3.5rem);
    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);
    border-left: 0;
    transform: translateY(100%);
  }

  .collection-workbench-drawer.offcanvas-end.show,
  .collection-workbench-drawer.offcanvas-end.showing {
    transform: none;
  }
}

/* qw-tewgr Track B: contextual action bar. The mode/density toggle row and the bulk-selection
   toolbar occupy the same CSS-grid cell so switching between them never shifts the chip strip
   or quote list below — the cell's reserved height is the max of both rows at every viewport.
   visibility (not display) toggles which row is shown: it keeps the shared height intact and
   drops the hidden row out of tab order / accessibility tree. multi-select.ts toggles
   has-selection on [data-workbench-header-stack]; keyboard.ts's Escape-to-clear-selection check
   mirrors the same class. */
.workbench-header-stack {
  display: grid;
}

.workbench-header-stack > * {
  grid-area: 1 / 1;
}

#collection-bulk-toolbar-slot {
  visibility: hidden;
}

.workbench-header-stack.has-selection #collection-workbench-toolbar {
  visibility: hidden;
}

.workbench-header-stack.has-selection #collection-bulk-toolbar-slot {
  visibility: visible;
}

/* Empty-collection edge case: #collection-workbench-toolbar isn't rendered at all when there
   are zero quotes and no active search, so the slot is the stack's only child. With no quotes
   there are no checkboxes, so has-selection can never apply here — collapse the slot fully
   instead of reserving height for a bulk toolbar that can never appear. */
.workbench-header-stack > #collection-bulk-toolbar-slot:only-child {
  display: none;
}
