/* ==========================================================================
   common.css
   Shared components used by two or more workspace stylesheets. Hardcoded
   into views/home.ejs right after tokens.css/home.css, so it always loads
   before every page-specific stylesheet — routes no longer need to (and
   shouldn't) list it in their own extraCss arrays.

   ("quotes.css", mentioned in older comments in this codebase, isn't a
   separate file — its rules were merged into the bottom of issuances.css.)

   Everything in here was previously copy-pasted into multiple files with
   small, accidental differences (blur radius, shadow depth, one file
   missing a hover state, etc.) — that drift is why some modals/cards look
   slightly different depending on which page loaded last. This file picks
   ONE canonical version of each and the page files now just add what's
   actually unique to them.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. MODAL SYSTEM
   Was duplicated (with small variations) in: issuances.css, sales.css,
   guest.css, adminpanel.css, quotes.css (variants only), finance.css
   (.close-modal only).
   -------------------------------------------------------------------------- */
.modal-overlay-layer {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(15, 23, 42, 0.5);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 9999;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 12px;
    box-sizing: border-box;
}

.modal-overlay-layer.visible {
    display: flex !important;
}

.modal-window-box {
    background: var(--color-surface, #ffffff);
    border-radius: 10px;
    width: 100%;
    max-width: 520px;
    max-height: calc(100vh - 30px);
    box-shadow: var(--shadow-lg, 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04));
    animation: modalSlideUp 0.2s cubic-bezier(0.16, 1, 0.3, 1);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* Size variants — pick whichever your modal needs */
.modal-window-box.wide-variant,
.modal-window-box.modal-lg { max-width: 850px; }
.modal-window-box.narrow-variant,
.modal-window-box.modal-sm { max-width: 420px; }
.modal-window-box.swatch-variant { max-width: 480px; }
.modal-window-box.catalog-variant { max-width: 700px; }
.modal-window-box.modal-md { max-width: 580px; }
.modal-window-box.modal-xl { max-width: 840px; }

.modal-window-header {
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color, #e2e8f0);
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: var(--color-surface, #ffffff);
    flex-shrink: 0;
}

.modal-window-header h3 {
    margin: 0;
    font-size: 15px;
    font-weight: 700;
    color: var(--color-text-main, #0f172a);
}

.modal-window-header p {
    margin: 2px 0 0 0;
    font-size: 0.813rem;
    color: var(--color-text-muted, #64748b);
}

.close-modal,
.btn-modal-close,
.close-addto-modal,
.close-addto-quote-modal,
.close-catalog-modal,
.close-editcluster-modal {
    background: none;
    border: none;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    color: var(--color-text-muted, #64748b);
    padding: 2px 6px;
    border-radius: 4px;
}

.close-modal:hover,
.btn-modal-close:hover,
.close-addto-modal:hover,
.close-addto-quote-modal:hover,
.close-catalog-modal:hover,
.close-editcluster-modal:hover {
    background-color: var(--color-surface-hover, #f1f5f9);
    color: var(--color-text-main, #0f172a);
}

.modal-form-stacked {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 16px 18px;
    flex: 1;
    gap: 12px;
}

.modal-form-stacked label {
    display: block;
    font-size: 12px;
    font-weight: 600;
    margin-bottom: 4px;
    color: var(--color-text-secondary, #334155);
}

.modal-body-scrollable {
    padding: 16px;
    overflow-y: auto;
    max-height: 100%;
    box-sizing: border-box;
    flex: 1;
}

/* For a <form> that directly wraps a .modal-body-scrollable + a
   .modal-window-footer as siblings: makes the form itself participate in
   the modal's flex column correctly so the footer stays pinned and only
   the body scrolls, instead of the outer modal clipping tall content. */
.modal-form-scroll-host {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    flex: 1;
}

.modal-window-footer {
    padding: 10px 16px;
    border-top: 1px solid var(--border-color, #e2e8f0);
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    background: var(--color-surface-muted, #f8fafc);
    flex-shrink: 0;
}

.required-asterisk {
    color: var(--color-danger, #dc3545);
    font-weight: 700;
}

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

@keyframes fadeInModal {
    from { opacity: 0; }
    to { opacity: 1; }
}

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

/* --------------------------------------------------------------------------
   1b. LIGHTBOX (full-image viewer)
   Built lazily by public/js/lightbox.js. Sits above the modal system
   (z-index higher than .modal-overlay-layer) since it's mostly opened from
   inside an image grid that already lives in a modal (catalogue/guest
   detail, image manager). Thumbnails feeding it are still plain <img>
   tags cropped with object-fit: cover in their own card/grid styles
   (.gallery-card-image-box, .catimg-thumb, .inv-gallery-image-box) — this
   only owns the enlarged view.
   -------------------------------------------------------------------------- */
.lightbox-overlay {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.92);
    z-index: 10500;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 40px 72px;
    box-sizing: border-box;
}

.lightbox-overlay.visible {
    display: flex !important;
}

.lightbox-stage {
    position: relative;
    max-width: 100%;
    max-height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.lightbox-image {
    max-width: 100%;
    max-height: calc(100vh - 120px);
    object-fit: contain;
    border-radius: 6px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.lightbox-caption {
    margin-top: 10px;
    color: #f1f5f9;
    font-size: 13px;
    text-align: center;
    max-width: 60vw;
}

.lightbox-counter {
    margin-top: 4px;
    color: rgba(241, 245, 249, 0.65);
    font-size: 11px;
    font-family: monospace;
}

.lightbox-close,
.lightbox-nav {
    position: fixed;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.18);
    color: #f1f5f9;
    border-radius: 999px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s ease;
}

.lightbox-close:hover,
.lightbox-nav:hover {
    background: rgba(255, 255, 255, 0.18);
}

.lightbox-close {
    top: 18px;
    right: 18px;
    width: 40px;
    height: 40px;
}

.lightbox-nav {
    top: 50%;
    transform: translateY(-50%);
    width: 48px;
    height: 48px;
}

.lightbox-prev { left: 18px; }
.lightbox-next { right: 18px; }

body.lightbox-open {
    overflow: hidden;
}

@media (max-width: 640px) {
    .lightbox-overlay { padding: 24px 16px; }
    .lightbox-nav { width: 40px; height: 40px; }
    .lightbox-prev { left: 6px; }
    .lightbox-next { right: 6px; }
}

/* --------------------------------------------------------------------------
   2. TABS / TOGGLE BUTTONS (pill style)
   Was identical, byte-for-byte, in home.css/issuances.css (.toggle-buttons),
   adminpanel.css (.admin-tab-btn), finance.css/guest.css (.tab-btn), and
   near-identical in cogs.css (.cogs-tab, which used an underline style
   instead of the pill — migrated here to match everyone else). Each page
   keeps its own class name in its markup/JS (renaming those was out of
   scope for a CSS-only pass), but they all resolve to this one canonical
   rule now instead of four+ hand-copied near-duplicates.
   -------------------------------------------------------------------------- */
.toggle-buttons {
    display: flex;
    gap: 4px;
    margin-bottom: 12px;
    border-bottom: 1px solid var(--border-color, #e2e8f0);
    padding-bottom: 4px;
    overflow-x: auto;
    white-space: nowrap;
}

.toggle-buttons button,
.tab-btn,
.admin-tab-btn,
.cogs-tab {
    background: none;
    border: none;
    padding: 6px 12px;
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text-muted, #64748b);
    cursor: pointer;
    transition: all 0.15s ease;
    border-radius: 4px;
    font-family: inherit;
}

.toggle-buttons button:hover,
.tab-btn:hover,
.admin-tab-btn:hover,
.cogs-tab:hover {
    background-color: var(--color-surface-hover, #f1f5f9);
    color: var(--color-text-main, #1e293b);
}

.toggle-buttons button:focus-visible,
.tab-btn:focus-visible,
.admin-tab-btn:focus-visible,
.cogs-tab:focus-visible {
    outline: 2px solid var(--color-primary, #6366f1);
    outline-offset: 1px;
}

.toggle-buttons button.active,
.tab-btn.active,
.admin-tab-btn.active,
.cogs-tab.active-tab {
    background-color: var(--color-primary-soft-bg, #eeeffc);
    color: var(--color-primary, #6366f1);
}

/* --------------------------------------------------------------------------
   3. GALLERY GRID & CARD (narrow/tall catalogue-style card)
   Identical intent in home.css and issuances.css; issuances.css had the
   most recently tuned values (per its own "increased height" comments), so
   that version is the canonical one here.
   NOTE: inventory.css defines its OWN .gallery-card / .gallery-responsive-grid
   with different sizing (wider cards, shorter images) under the SAME class
   names. That's a real naming collision, not just duplication — if
   inventory.css and issuances.css/home.css ever load on the same page, one
   silently overrides the other. Left untouched for now; consider renaming
   inventory's version (e.g. .inv-gallery-card) if that page ever shares a
   shell with the others.
   -------------------------------------------------------------------------- */
.gallery-responsive-grid {
    display: grid !important;
    grid-template-columns: repeat(2, 1fr) !important;
    gap: 10px !important;
    margin-top: 10px;
}

@media (min-width: 768px) {
    .gallery-responsive-grid { grid-template-columns: repeat(3, 1fr) !important; }
}
@media (min-width: 1024px) {
    .gallery-responsive-grid { grid-template-columns: repeat(4, 1fr) !important; }
}
@media (min-width: 1280px) {
    .gallery-responsive-grid { grid-template-columns: repeat(5, 1fr) !important; }
}

.gallery-card {
    background-color: var(--color-surface, #ffffff);
    border: 1px solid var(--border-color, #e2e8f0);
    border-radius: 8px;
    padding: 10px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    height: 100%;
    min-height: 360px;
    box-sizing: border-box;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.gallery-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md, 0 4px 12px rgba(0, 0, 0, 0.08));
}

.gallery-card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
}

.gallery-card-image-box {
    width: 100%;
    height: 210px;
    background-color: var(--color-surface-muted, #f8fafc);
    border: 1px solid var(--color-border, #f1f5f9);
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    margin-bottom: 8px;
    flex-shrink: 0;
}

.gallery-card-image-box img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center;
    cursor: zoom-in;
}

.gallery-card-image-placeholder {
    font-size: 11px;
    color: var(--color-text-muted, #64748b);
    font-weight: 500;
}

.gallery-card-title {
    font-size: 13px;
    font-weight: 700;
    color: var(--color-text-main, #1e293b);
    text-transform: capitalize;
    margin: 0 0 2px 0;
    line-height: 1.3;
}

.gallery-card-subtitle {
    font-size: 11px;
    color: var(--color-text-muted, #64748b);
    margin-bottom: 6px;
}

.gallery-card-actions {
    display: flex;
    gap: 4px;
}

.gallery-card-actions button {
    padding: 4px 6px;
    font-size: 10px;
    flex: 1;
}

/* --------------------------------------------------------------------------
   3b. GALLERY CARD v2 — click-to-expand card with hover-revealed quick actions
   Card body (image/title) opens a detail modal with the full gallery and all
   management actions. A single primary action stays always-visible for the
   most common task; secondary actions surface as icon chips on image hover
   (or via a persistent overflow "⋯" affordance on touch devices, since there
   is no hover there). This sits alongside the original .gallery-card-actions
   rule above for pages that haven't migrated yet — the card-v2 class opts in.
   -------------------------------------------------------------------------- */
.gallery-card.card-v2 {
    padding: 0;
    overflow: hidden;
    cursor: pointer;
    min-height: 0;
}

.gallery-card.card-v2:hover {
    box-shadow: 0 8px 20px rgba(15, 23, 42, 0.10);
}

.card-v2-image-box {
    position: relative;
    width: 100%;
    aspect-ratio: 1 / 1;
    background-color: var(--color-surface-muted, #f8fafc);
    border-bottom: 1px solid var(--color-border, #f1f5f9);
    overflow: hidden;
    flex-shrink: 0;
}

.card-v2-image-box img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.25s ease;
}

.gallery-card.card-v2:hover .card-v2-image-box img {
    transform: scale(1.035);
}

.card-v2-image-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    color: var(--color-text-muted, #64748b);
    font-weight: 500;
}

/* top-left status chips (image count, inactive) */
.card-v2-chips {
    position: absolute;
    top: 6px;
    left: 6px;
    display: flex;
    gap: 4px;
    z-index: 2;
}

.card-v2-chip {
    background: rgba(15, 23, 42, 0.72);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.3px;
    padding: 3px 7px;
    border-radius: 9999px;
    display: inline-flex;
    align-items: center;
    gap: 3px;
}

.card-v2-chip.is-inactive {
    background: #ef4444;
}

/* Quick actions — hidden by default, revealed on card hover (desktop).
   On touch devices (no hover), .card-v2-quick sits permanently visible
   at reduced opacity via the touch fallback media query below. */
.card-v2-quick {
    position: absolute;
    top: 6px;
    right: 6px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    opacity: 0;
    transform: translateX(4px);
    transition: opacity 0.15s ease, transform 0.15s ease;
    z-index: 2;
}

.gallery-card.card-v2:hover .card-v2-quick,
.gallery-card.card-v2:focus-within .card-v2-quick {
    opacity: 1;
    transform: translateX(0);
}

.card-v2-quick-btn {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: none;
    background: rgba(255, 255, 255, 0.94);
    box-shadow: 0 1px 4px rgba(15, 23, 42, 0.25);
    font-size: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: #334155;
    transition: background 0.15s ease, transform 0.1s ease;
}

.card-v2-quick-btn:hover {
    background: #fff;
    transform: scale(1.08);
}

.card-v2-quick-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.card-v2-body {
    padding: 8px 10px 10px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.card-v2-design {
    font-size: 10px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-weight: 700;
    color: var(--color-text-muted, #94a3b8);
    letter-spacing: 0.3px;
}

.card-v2-title {
    font-size: 13px;
    font-weight: 700;
    color: var(--color-text-main, #1e293b);
    text-transform: capitalize;
    margin: 0;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.card-v2-material {
    font-size: 11px;
    font-style: italic;
    color: var(--color-text-muted, #64748b);
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.card-v2-subtitle {
    font-size: 11px;
    color: var(--color-text-muted, #64748b);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Primary action — always visible, single most-common task */
.card-v2-primary-action {
    margin-top: 6px;
    width: 100%;
    background: var(--color-primary, #6366f1);
    color: #fff;
    border: none;
    border-radius: 6px;
    padding: 6px 8px;
    font-size: 11px;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.15s ease;
}

.card-v2-primary-action:hover:not(:disabled) {
    background: var(--color-primary-hover, #2f2f92);
}

.card-v2-primary-action:disabled {
    background: var(--color-border-strong, #cbd5e1);
    cursor: not-allowed;
}

.gallery-card.card-v2.is-inactive {
    opacity: 0.75;
}

.gallery-card.card-v2.is-inactive .card-v2-image-box img {
    filter: grayscale(0.85);
}

/* Touch fallback: no hover available, so keep quick actions reachable
   at reduced-but-visible opacity rather than hidden entirely. */
@media (hover: none) {
    .card-v2-quick {
        opacity: 1;
        transform: none;
    }
}

/* SVG icons inside quick-action chips and status chips — replaces the old
   emoji glyphs with crisp, theme-colored icons that scale cleanly. */
.card-v2-quick-btn svg,
.card-v2-chip svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.card-v2-chip svg {
    width: 12px;
    height: 12px;
}

/* Favourite heart toggle: solid red fill when active reads unmistakably
   as "saved", the way a checkmark never quite did — red rather than the
   app's green "success" color, since this isn't a completion/approval
   state. Also sized down from the default 32px quick-action button so it
   doesn't visually compete with the Add-to-RFQ button next to it. */
.card-v2-quick-btn.btn-toggle-check {
    width: 24px;
    height: 24px;
}

.card-v2-quick-btn.btn-toggle-check svg {
    width: 12px;
    height: 12px;
}

.btn-toggle-check.is-on svg {
    fill: var(--color-danger, #dc3545);
    stroke: var(--color-danger, #dc3545);
}

/* --------------------------------------------------------------------------
   3c. CATALOGUE DETAIL MODAL — tabs, sub-tabs, and the inline image manager
   Replaces the old pattern of opening a second modal (image manager, add-to-
   PO/Quote/Inventory, edit metadata) on top of the card's detail modal.
   Everything now lives as a tab inside ONE modal window.
   -------------------------------------------------------------------------- */
.catalog-detail-window {
    max-width: 760px;
}

.catalog-detail-header {
    align-items: flex-start;
}

.catalog-detail-heading h3 {
    margin: 0 0 2px;
}

.catalog-detail-heading p {
    margin: 0;
    font-size: 12px;
    color: var(--color-text-muted, #64748b);
}

.icon-btn {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--color-text-muted, #64748b);
    padding: 4px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s ease, color 0.15s ease;
}

.icon-btn:hover {
    background: var(--color-surface-hover, #f1f5f9);
    color: var(--color-text-main, #1e293b);
}

/* Primary tab strip: Images / Order / Manage */
.catalog-detail-tabs {
    display: flex;
    gap: 2px;
    padding: 0 16px;
    border-bottom: 1px solid var(--border-color, #e2e8f0);
    background: var(--color-surface-muted, #f8fafc);
    flex-shrink: 0;
}

.catalog-tab-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 10px 12px;
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text-muted, #64748b);
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.catalog-tab-btn:hover {
    color: var(--color-text-secondary, #334155);
}

.catalog-tab-btn.is-active {
    color: var(--color-primary, #6366f1);
    border-bottom-color: var(--color-primary, #6366f1);
}

.catalog-tab-btn svg {
    flex-shrink: 0;
}

.catalog-tab-count {
    font-size: 11px;
    font-weight: 700;
    color: var(--color-text-muted, #94a3b8);
}

.catalog-detail-body {
    background: var(--color-surface, #fff);
}

.catalog-tab-panel {
    display: none;
}

.catalog-tab-panel.is-active {
    display: block;
}

/* Secondary tab strip within the Order tab: PO / Quote / Inventory */
.catalog-subtabs {
    display: flex;
    gap: 6px;
    margin-bottom: 14px;
    flex-wrap: wrap;
}

.catalog-subtab-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--color-surface-hover, #f1f5f9);
    border: 1px solid transparent;
    border-radius: 8px;
    padding: 7px 12px;
    font-size: 12px;
    font-weight: 600;
    color: var(--color-text-secondary, #475569);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.catalog-subtab-btn:hover {
    background: var(--color-border, #e2e8f0);
}

.catalog-subtab-btn.is-active {
    background: var(--color-primary-soft-bg, #eef2ff);
    border-color: var(--color-primary-border, #c7d2fe);
    color: var(--color-primary-soft-text, #3730a3);
}

.catalog-subtab-panel {
    display: none;
}

.catalog-subtab-panel.is-active {
    display: block;
}

.catalog-manage-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
}

/* Detail-modal section label, divider, and spec grid — used by both the
   staff catalogue detail modal (Manage tab) and the guest detail modal
   (Overview tab). Was only ever defined in issuances.css as a plain 2-col
   grid of inline "Label: value" text with no background/border — the
   guest page never loaded issuances.css, so its copy rendered completely
   unstyled. Single definition here now, redesigned as a small "spec
   card" per field (caption above value) instead of inline text. */
.modal-section-label {
    margin: 0 0 8px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--color-text-muted, #64748b);
}

.modal-section-divider {
    border: 0;
    border-top: 1px solid var(--color-border, #e2e8f0);
    margin: 0;
}

.grid-catalog-details {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
}

@media (min-width: 480px) {
    .grid-catalog-details {
        grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    }
}

.grid-catalog-details > div {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 8px 10px;
    background: var(--color-surface-muted, #f8fafc);
    border: 1px solid var(--color-border, #e2e8f0);
    border-radius: var(--radius-sm, 4px);
}

.grid-catalog-details > div > strong {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--color-text-muted, #64748b);
}

.grid-catalog-details > div > span {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text-primary, #0f172a);
}

/* Guest workspace reuses the same tab chrome under its own class names.
   The names are deliberately separate because home.ejs loads
   catalogue-items.js on every page, and that script binds click handlers to
   every .catalog-tab-btn in the document — sharing the class would make the
   staff and guest tab systems fire into each other. */
.guest-detail-tabs {
    display: flex;
    gap: 2px;
    padding: 0 16px;
    border-bottom: 1px solid var(--border-color, #e2e8f0);
    background: var(--color-surface-muted, #f8fafc);
    flex-shrink: 0;
}

.guest-tab-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 10px 12px;
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text-muted, #64748b);
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.guest-tab-btn:hover { color: var(--color-text-secondary, #334155); }

.guest-tab-btn.is-active {
    color: var(--color-primary, #6366f1);
    border-bottom-color: var(--color-primary, #6366f1);
}

.guest-tab-panel { display: none; }
.guest-tab-panel.is-active { display: block; }

/* Marked / checked state for guest catalogue cards */
.card-v2-chip.is-marked {
    background: #16a34a;
}

.gallery-card.card-v2.is-checked {
    border-color: #86efac;
    box-shadow: 0 0 0 2px rgba(22, 163, 74, 0.18);
}

.card-v2-quick-btn.danger:hover {
    background: var(--color-danger-bg, #fee2e2);
    color: var(--color-danger, #dc2626);
}

/* Per-size quantity line on RFQ line-item cards */
.card-v2-qty-line {
    font-size: 11px;
    color: var(--color-text-muted, #64748b);
    margin: 2px 0 0;
}

/* --------------------------------------------------------------------------
   3d. INLINE IMAGE MANAGER (catimg-*)
   Used both by the standalone #modalCatalogImages overlay (kept for pages
   that still open it directly) and by the Images tab inlined into the
   catalogue detail modal. Was referenced throughout catalogue-images.js and
   the EJS partials but never actually defined anywhere — this is that
   missing stylesheet.
   -------------------------------------------------------------------------- */
.catimg-dropzone {
    border: 2px dashed var(--color-border-strong, #cbd5e1);
    border-radius: 10px;
    padding: 20px 16px;
    text-align: center;
    background: var(--color-surface-muted, #f8fafc);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    transition: border-color 0.15s ease, background 0.15s ease;
    margin-bottom: 12px;
}

.catimg-dropzone.is-dragover {
    border-color: var(--color-primary, #6366f1);
    background: var(--color-primary-soft-bg, #eef2ff);
}

.catimg-dropzone svg {
    color: var(--color-text-muted, #94a3b8);
}

.catimg-dropzone-text {
    font-size: 13px;
    color: var(--color-text-secondary, #475569);
}

.catimg-dropzone-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
}

.catimg-dropzone-icon {
    font-size: 22px;
}

.catimg-file-label {
    color: var(--color-primary, #6366f1);
    font-weight: 700;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.catimg-hint {
    display: block;
    font-size: 11px;
    color: var(--color-text-muted, #94a3b8);
    margin-top: 2px;
}

.catimg-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 10px;
    min-height: 18px;
}

.catimg-count {
    font-size: 12px;
    font-weight: 700;
    color: var(--color-text-secondary, #475569);
}

.catimg-status {
    font-size: 12px;
    font-weight: 600;
}

.catimg-status[data-tone="ok"] { color: var(--color-success, #16a34a); }
.catimg-status[data-tone="busy"] { color: var(--color-text-muted, #64748b); }
.catimg-status[data-tone="danger"] { color: var(--color-danger, #ef4444); }
.catimg-status[data-tone="muted"] { color: var(--color-text-muted, #94a3b8); }

.catimg-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 10px;
}

/* View-only variant (guest detail modal): no caption/alt-text input or
   action buttons like the staff image manager has, so tiles can run
   bigger, and a plain "browsing a gallery" cursor + hover zoom reads
   better than the manager's drag-to-reorder affordance. */
.catimg-grid.catimg-grid-view {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 12px;
}

.catimg-grid-view .catimg-tile {
    cursor: default;
    transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.catimg-grid-view .catimg-tile:hover {
    box-shadow: var(--shadow-md, 0 4px 12px rgba(0, 0, 0, 0.08));
    transform: translateY(-2px);
}

.catimg-grid-view .catimg-thumb img {
    transition: transform 0.25s ease;
}

.catimg-grid-view .catimg-tile:hover .catimg-thumb img {
    transform: scale(1.05);
}

.catimg-empty {
    grid-column: 1 / -1;
    text-align: center;
    padding: 24px 12px;
    color: var(--color-text-muted, #94a3b8);
    font-size: 12px;
    font-style: italic;
}

.catimg-tile {
    margin: 0;
    border: 1px solid var(--color-border, #e2e8f0);
    border-radius: 8px;
    overflow: hidden;
    background: var(--color-surface, #fff);
    cursor: grab;
    transition: box-shadow 0.15s ease, border-color 0.15s ease;
}

.catimg-tile:active {
    cursor: grabbing;
}

.catimg-tile.is-dragging {
    opacity: 0.5;
}

.catimg-tile.is-primary {
    border-color: #fbbf24;
}

.catimg-thumb {
    position: relative;
    width: 100%;
    aspect-ratio: 1 / 1;
    background: var(--color-surface-muted, #f8fafc);
}

.catimg-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    cursor: zoom-in;
}

.catimg-badge {
    position: absolute;
    top: 4px;
    left: 4px;
    background: #fbbf24;
    color: #78350f;
    font-size: 8px;
    font-weight: 800;
    letter-spacing: 0.4px;
    padding: 2px 5px;
    border-radius: 4px;
}

.catimg-tile figcaption {
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.catimg-alt {
    width: 100%;
    box-sizing: border-box;
    font-size: 11px;
    padding: 3px 5px;
    border: 1px solid var(--color-border, #e2e8f0);
    border-radius: 4px;
    background: var(--color-surface, #fff);
    color: var(--color-text-primary, #0f172a);
}

.catimg-actions {
    display: flex;
    gap: 4px;
}

.catimg-btn {
    flex: 1;
    background: var(--color-surface-hover, #f1f5f9);
    border: none;
    border-radius: 4px;
    padding: 3px 4px;
    font-size: 10px;
    font-weight: 700;
    color: var(--color-text-secondary, #475569);
    cursor: pointer;
}

.catimg-btn:hover {
    background: var(--color-border, #e2e8f0);
}

.catimg-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.catimg-btn.danger {
    color: var(--color-danger, #ef4444);
}

.catimg-btn.danger:hover {
    background: var(--color-danger-bg, #fee2e2);
}

/* --------------------------------------------------------------------------
   4. AUTOCOMPLETE DROPDOWN
   Identical wrapper, near-identical dropdown in issuances.css/sales.css.
   -------------------------------------------------------------------------- */
.autocomplete-wrapper {
    position: relative;
}

.autocomplete-dropdown {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    width: 100%;
    z-index: 1050;
    background-color: var(--color-surface, #ffffff);
    border: 1px solid var(--border-color, #cbd5e1);
    border-top: none;
    border-radius: 0 0 6px 6px;
    max-height: 200px;
    overflow-y: auto;
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}

.autocomplete-item:hover {
    background-color: var(--color-surface-hover, #f1f5f9);
}

/* --------------------------------------------------------------------------
   5. FORM CONTROLS
   Three different versions of ".form-control" existed (issuances.css,
   quotes.css, sales.css) with different radius/padding/focus colors.
   quotes.css also only adds .modal-window-box.modal-sm and never defines
   the base — it was silently relying on another file's .form-control
   already being loaded. This is the merged, most complete version.
   -------------------------------------------------------------------------- */
.form-control,
.form-select-sm,
.form-input-sm {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--border-color, #cbd5e1);
    border-radius: 6px;
    font-size: 13px;
    color: var(--color-text-main, #1e293b);
    background-color: var(--color-surface, #ffffff);
    box-sizing: border-box;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.form-control:focus {
    outline: none;
    border-color: var(--color-primary, #6366f1);
    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.12);
}

.form-control[readonly] {
    background-color: var(--color-background, #f8fafc);
    color: var(--color-text-muted, #64748b);
    cursor: not-allowed;
}

textarea.form-control {
    resize: vertical;
    min-height: 60px;
}

select.form-control {
    appearance: none;
    background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 14px;
    padding-right: 30px;
}

/* --------------------------------------------------------------------------
   6. STATUS BADGE
   quotes.css only added new .variant-* suffixes and depended on
   issuances.css to already have loaded the base .status-badge — that
   coupling is now explicit here instead of accidental.
   -------------------------------------------------------------------------- */
.status-badge {
    padding: 3px 8px;
    border-radius: 9999px;
    font-size: 10px;
    font-weight: 700;
    display: inline-block;
    text-transform: uppercase;
}
.status-badge.variant-draft { background-color: var(--color-surface-hover, #f1f5f9); color: var(--color-text-secondary, #475569); }
.status-badge.variant-pending,
.status-badge.variant-pending_invoice { background-color: var(--color-warning-bg, #fef3c7); color: var(--color-warning-strong, #d97706); }
.status-badge.variant-approved,
.status-badge.variant-paid,
.status-badge.variant-success { background-color: var(--color-success-bg, #d1fae5); color: var(--color-success-strong, #059669); }
.status-badge.variant-completed { background-color: #e0f2fe; color: #0284c7; }
/* No shared "info" token exists (only success/warning/danger) — paired
   dark value here instead of inventing one just for this one badge. */
body[data-theme="dark"] .status-badge.variant-completed { background-color: #082f49; color: #7dd3fc; }
.status-badge.variant-converted {
    background-color: var(--color-success-bg, #dcfce7);
    color: var(--color-success-strong, #15803d);
    border: 1px solid var(--color-success, #86efac);
}
.status-badge.variant-active-quote,
.status-badge.variant-partial {
    background-color: var(--color-primary-soft-bg, #e0e7ff);
    color: var(--color-primary-soft-text, #3730a3);
    border: 1px solid var(--color-primary-border, #a5b4fc);
}
.status-badge.variant-expired,
.status-badge.variant-danger,
.status-badge.variant-bad_debt,
.status-badge.variant-inactive {
    background-color: var(--color-danger-bg, #fee2e2);
    color: var(--color-danger-strong, #991b1b);
    border: 1px solid var(--color-danger, #fca5a5);
}

/* --------------------------------------------------------------------------
   6b. BUTTONS
   Was independently redefined in guest.css, cogs.css, sales.css,
   inventory.css, issuances.css (5 files), plus extended in dashboard.css /
   adminpanel.css / finance.css. This is the merged, canonical version.
   .btn-primary is the single solid-fill CTA look — use it once per view.
   .btn-primary-soft is the new tinted variant: reach for this for
   secondary/repeated actions instead of another solid button.
   -------------------------------------------------------------------------- */
.btn-primary,
.btn-secondary,
.btn-primary-soft {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 14px;
    font-size: 0.825rem;
    font-weight: 600;
    font-family: inherit;
    border-radius: var(--radius-sm, 4px);
    cursor: pointer;
    transition: all 0.15s ease;
    text-decoration: none;
}

.btn-primary {
    background-color: var(--color-primary, #6366f1);
    color: #ffffff;
    border: 1px solid var(--color-primary, #6366f1);
}

.btn-primary:hover {
    background-color: var(--color-primary-strong, #4f46e5);
    border-color: var(--color-primary-strong, #4f46e5);
}

.btn-primary-soft {
    background-color: var(--color-primary-soft-bg, #eef2ff);
    color: var(--color-primary-soft-text, #4338ca);
    border: 1px solid var(--color-primary-border, #c7d2fe);
}

.btn-primary-soft:hover {
    background-color: var(--color-primary-border, #c7d2fe);
}

.btn-secondary {
    background-color: var(--color-surface, #ffffff);
    color: var(--color-text-secondary, #334155);
    border: 1px solid var(--color-border, #e2e8f0);
}

.btn-secondary:hover {
    background-color: var(--color-surface-hover, #f1f5f9);
    border-color: var(--color-border-strong, #cbd5e1);
}

.btn-primary:disabled,
.btn-secondary:disabled,
.btn-primary-soft:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   6b-ii. ACTION BUTTONS — the five canonical icon-only kinds
   Every workspace independently invented its own classes for these same
   five behaviors (add/save/submit, delete, cancel/close, search/filter,
   export/print/tool), which is why the same action looks different from
   page to page. This is the one shared shape: a 34px icon-only square,
   colored by kind, with the old visible caption moved into a hover tooltip
   (data-tooltip) plus an aria-label for screen readers, instead of long
   inline button text. Use `.btn-action-sm` (28px) inside dense table rows
   where the full size would blow out row height.
   -------------------------------------------------------------------------- */
.btn-action {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border-radius: var(--radius-sm, 4px);
    border: 1px solid transparent;
    cursor: pointer;
    font-family: inherit;
    line-height: 1;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
    flex-shrink: 0;
}

.btn-action svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.btn-action:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.btn-action.btn-action-sm {
    width: 28px;
    height: 28px;
}

.btn-action.btn-action-sm svg {
    width: 14px;
    height: 14px;
}

/* Tooltip driven by data-tooltip (visual) — pair with aria-label carrying
   the same text (assistive tech; not read twice since the tooltip text
   node isn't real DOM content). */
.btn-action[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%) translateY(2px);
    background: var(--color-text-primary, #0f172a);
    color: var(--color-surface, #ffffff);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    padding: 4px 8px;
    border-radius: var(--radius-sm, 4px);
    pointer-events: none;
    opacity: 0;
    z-index: 20;
    transition: opacity 0.12s ease, transform 0.12s ease;
}

.btn-action[data-tooltip]:hover::after,
.btn-action[data-tooltip]:focus-visible::after {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

/* 1. Add / Save / Submit / Confirm — solid primary fill (the CTA weight) */
.btn-action-primary {
    background: var(--color-primary, #6366f1);
    border-color: var(--color-primary, #6366f1);
    color: #ffffff;
}

.btn-action-primary:hover:not(:disabled) {
    background: var(--color-primary-strong, #4f46e5);
    border-color: var(--color-primary-strong, #4f46e5);
}

/* 2. Delete / Remove / Void — solid danger fill */
.btn-action-danger {
    background: var(--color-danger, #dc3545);
    border-color: var(--color-danger, #dc3545);
    color: #ffffff;
}

.btn-action-danger:hover:not(:disabled) {
    background: var(--color-danger-strong, #c82333);
    border-color: var(--color-danger-strong, #c82333);
}

/* 3. Cancel / Close — plain neutral outline, deliberately the lowest
   visual weight of the five so it never competes with the action next to
   it (e.g. never darker/louder than the Save button in the same footer). */
.btn-action-cancel {
    background: var(--color-surface, #ffffff);
    border-color: var(--color-border, #e2e8f0);
    color: var(--color-text-muted, #64748b);
}

.btn-action-cancel:hover:not(:disabled) {
    background: var(--color-surface-hover, #f1f5f9);
    border-color: var(--color-border-strong, #cbd5e1);
    color: var(--color-text-secondary, #334155);
}

/* 4. Search / filter trigger — ghost by default (sits inline against a
   text input most of the time), primary-tinted only on hover/focus so it
   doesn't outweigh the input field it's attached to. */
.btn-action-search {
    background: transparent;
    border-color: transparent;
    color: var(--color-text-muted, #94a3b8);
}

.btn-action-search:hover:not(:disabled),
.btn-action-search:focus-visible {
    background: var(--color-primary-soft-bg, #eef2ff);
    color: var(--color-primary, #6366f1);
}

/* 5. Export / print / barcode / other tool actions — soft-tinted outline,
   the same family as .btn-primary-soft but sized/shaped for icon-only use. */
.btn-action-tool {
    background: var(--color-primary-soft-bg, #eef2ff);
    border-color: var(--color-primary-border, #c7d2fe);
    color: var(--color-primary-soft-text, #4338ca);
}

.btn-action-tool:hover:not(:disabled) {
    background: var(--color-primary-border, #c7d2fe);
}

/* A dedicated advanced-search filter FORM's submit button needs more visual
   weight than the ghost `.btn-action-search` icon (that one is meant as a
   small adornment next to a text input, e.g. the "open advanced search"
   trigger — it disappears when it's the only thing at the bottom of a
   whole grid of visible, bordered fields). This is the "execute this
   search" submit specifically: text-first with the icon trailing, solid
   fill, sized like a real CTA. Was previously the same ghost style
   everywhere this appears (issuances PO/quote search, sales, COGS), which
   is exactly why it read as easy to miss. */
.btn-search-submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 22px;
    font-size: 0.85rem;
    font-weight: 700;
    font-family: inherit;
    border-radius: var(--radius-sm, 4px);
    border: 1px solid var(--color-primary, #6366f1);
    background: var(--color-primary, #6366f1);
    color: #ffffff;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.btn-search-submit:hover {
    background: var(--color-primary-strong, #4f46e5);
    border-color: var(--color-primary-strong, #4f46e5);
}

.btn-search-submit svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

/* A thin vertical rule separating a document header's info cluster (total,
   currency) from its tool cluster (upload/print/barcode/properties/
   delete) — every record-level workspace (PO, quote, sales, COGS) now
   keeps its tools together in this one header row instead of scattering
   them across separate panels below. */
.header-actions-divider {
    width: 1px;
    align-self: stretch;
    background: var(--color-border, #e2e8f0);
    margin: 0 2px;
}

/* --------------------------------------------------------------------------
   6c. DATA TABLE (search results / listing tables)
   ".sales-search-table" was independently authored under the identical
   class name in both cogs.css and sales.css (a real silent-collision risk,
   not intentional sharing) — this is the merged base both files' markup
   already matches. Each file keeps only what's actually unique to it
   (sales.css: hover/zebra-striping/status-badge sizing).
   -------------------------------------------------------------------------- */
.sales-search-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.sales-search-table th,
.sales-search-table td {
    padding: 10px 12px;
    border-bottom: 1px solid var(--color-border, #e2e8f0);
    text-align: left;
}

.sales-search-table th {
    background-color: var(--color-surface-muted, #f8fafc);
    color: var(--color-text-secondary, #475569);
    font-weight: 700;
}

/* --------------------------------------------------------------------------
   7. WORKSPACE PANEL CARD (generic bordered content card)
   Base look shared by issuances.css / sales.css / cogs.css. home.css keeps
   its own !important compaction rule after this — that's an intentional
   density override for that shell, not a duplicate.
   -------------------------------------------------------------------------- */
.workspace-panel-card {
    background-color: var(--color-surface, #ffffff);
    border: 1px solid var(--border-color, #e2e8f0);
    border-radius: 8px;
    padding: 14px;
    margin-bottom: 12px;
    box-shadow: var(--shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.05));
    box-sizing: border-box;
}

/* --------------------------------------------------------------------------
   8. ICONS (shared inline-SVG set, replaces emoji glyphs)
   Emoji glyphs render differently per OS/browser, can't be recolored to
   match the tokens.css palette, and don't respond to the (currently unused)
   dark theme. Icons come from views/partials/icon.ejs or /js/icons.js;
   this is just the sizing/alignment rule both share.
   -------------------------------------------------------------------------- */
.icon {
    width: 14px;
    height: 14px;
    vertical-align: -2px;
    flex-shrink: 0;
}

.icon-lg {
    width: 18px;
    height: 18px;
}

/* Utility Visibility Helpers */
.is-hidden {
  display: none !important;
}

.is-visible {
  display: flex !important; /* Ideal for modal overlays */
}

.is-block {
  display: block !important;
}

/* --------------------------------------------------------------------------
   Pagination bar — shared by every gallery grid (catalogue, inventory,
   guest catalogue) via public/js/pagination.js's renderPagination(). Kept
   as one component so the three galleries read as one system.
   -------------------------------------------------------------------------- */
.pagination-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
    padding: 12px 4px 4px;
    margin-top: 6px;
    border-top: 1px solid var(--color-border);
}

.pagination-bar.is-empty {
    display: none;
}

.pagination-info {
    font-size: 12px;
    color: var(--color-text-muted);
    white-space: nowrap;
}

.pagination-controls {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
}

.pagination-btn {
    min-width: 28px;
    height: 28px;
    padding: 0 6px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text-secondary);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.pagination-btn:hover:not(:disabled) {
    background: var(--color-surface-hover);
    border-color: var(--color-border-strong);
}

.pagination-btn.is-active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
    cursor: default;
}

.pagination-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.pagination-ellipsis {
    color: var(--color-text-muted);
    font-size: 12px;
    padding: 0 2px;
}

.pagination-size {
    font-size: 12px;
    color: var(--color-text-muted);
}

.pagination-size label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.pagination-size-select {
    padding: 3px 6px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text-primary);
    font-size: 12px;
}

/* --------------------------------------------------------------------------
   Filter breadcrumb bar — the guest catalogue's product-type / design /
   colour drill-down (see public/js/guest_front.js). Reads like a normal
   folder breadcrumb: "All > Type > Design > Colour", each segment except
   the last clickable to jump back up a level.
   -------------------------------------------------------------------------- */
.filter-breadcrumb-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin: 10px 0;
}

.filter-breadcrumb-bar:empty {
    display: none;
}

.breadcrumb-crumb {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border-radius: var(--radius-pill);
    font-size: 12px;
    font-weight: 600;
    background: none;
    border: 1px solid transparent;
    color: var(--color-text-muted);
    cursor: default;
}

.breadcrumb-crumb.is-link {
    color: var(--color-primary);
    cursor: pointer;
    background: var(--color-primary-soft-bg);
    border-color: var(--color-primary-border);
}

.breadcrumb-crumb.is-link:hover {
    background: var(--color-primary);
    color: #fff;
}

.breadcrumb-separator {
    color: var(--color-text-muted);
    font-size: 12px;
}

.breadcrumb-options {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    width: 100%;
}

.breadcrumb-option-chip {
    padding: 4px 10px;
    border-radius: var(--radius-pill);
    font-size: 12px;
    font-weight: 500;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    color: var(--color-text-secondary);
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}

.breadcrumb-option-chip:hover {
    background: var(--color-surface-hover);
    border-color: var(--color-border-strong);
}