/* ==========================================================================
   BAPP Framework Pages — Shared Design System
   Pure CSS · No Bootstrap · Ant Design + Tabler aligned
   Prefix: bf-
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design Tokens (Custom Properties)
   -------------------------------------------------------------------------- */
:root {
    /* Tell the user agent which way this document leans, so NATIVE widgets follow the
       theme: form-control fills, <option> lists, scrollbars, spinners, date pickers.
       Nothing in the bf-* namespace can reach those -- the UA paints them, and without
       this it paints them light while the app is dark. Paired with the .auto-frontend-dark
       declaration below, which is what actually flips them. */
    color-scheme: light;

    /* Primary — inherits from React Ant Design when available */
    --bf-primary:       var(--auto-frontend-primary-color, #4062ed);
    --bf-primary-rgb:   64, 98, 237;
    --bf-primary-hover: color-mix(in srgb, var(--bf-primary) 85%, black);
    /* The brand colour used as TEXT. As a surface the brand colour works in both
       themes (white on it is 5:1), but as text on the dark surface it is only 2.9:1,
       so the dark block lightens it. Use this -- never --bf-primary -- for headings,
       links and accent labels. */
    --bf-primary-text:  var(--bf-primary);

    /* Semantic */
    --bf-success:       #16a34a;
    --bf-success-rgb:   22, 163, 74;
    --bf-warning:       #f59e0b;
    --bf-warning-rgb:   245, 158, 11;
    --bf-danger:        #ef4444;
    --bf-danger-rgb:    239, 68, 68;
    --bf-info:          #3b82f6;
    --bf-info-rgb:      59, 130, 246;

    /* Surfaces */
    --bf-bg-body:       #f5f7fb;
    --bf-bg-surface:    #ffffff;
    --bf-bg-surface-secondary: #f9fafb;
    --bf-bg-muted:      #f3f4f6;

    /* Text */
    --bf-text:          var(--auto-frontend-text-color, #1f2937);
    --bf-text-secondary:#6b7280;
    --bf-text-muted:    #94a3b8;

    /* Borders */
    --bf-border:        #e5e7eb;
    --bf-border-light:  #f1f5f9;

    /* Typography */
    --bf-font:          "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --bf-font-mono:     "SF Mono", Monaco, Consolas, "Liberation Mono", monospace;
    --bf-font-size:     0.875rem;     /* 14px */
    --bf-line-height:   1.4286;

    /* Spacing (4px grid) */
    --bf-space-1:  0.25rem;   /* 4px  */
    --bf-space-2:  0.5rem;    /* 8px  */
    --bf-space-3:  0.75rem;   /* 12px */
    --bf-space-4:  1rem;      /* 16px */
    --bf-space-5:  1.25rem;   /* 20px */
    --bf-space-6:  1.5rem;    /* 24px */
    --bf-space-8:  2rem;      /* 32px */

    /* Radius — Tabler scale */
    --bf-radius-sm:  4px;
    --bf-radius:     6px;
    --bf-radius-lg:  8px;
    --bf-radius-xl:  12px;
    --bf-radius-2xl: 16px;
    --bf-radius-pill: 999px;

    /* Shadows — Tabler inspired */
    --bf-shadow:         0 0 4px rgba(31, 41, 55, 0.04);
    --bf-shadow-sm:      0 1px 2px rgba(31, 41, 55, 0.06);
    --bf-shadow-md:      0 2px 8px rgba(31, 41, 55, 0.08);
    --bf-shadow-lg:      0 4px 16px rgba(31, 41, 55, 0.10);
    --bf-shadow-hover:   0 2px 16px rgba(31, 41, 55, 0.14);

    /* Transitions */
    --bf-transition:     0.15s ease-in-out;

    /* Compatibility aliases. Page templates reach for these names; without them the
       var() is invalid at computed-value time and the declaration silently vanishes
       (a surface goes transparent, text falls back to inherited) in BOTH themes.
       Theme-dependent aliases are repeated in the dark block below, because a custom
       property resolves once, where it is declared. */
    --bf-error:         var(--bf-danger);
    --bf-error-rgb:     var(--bf-danger-rgb);
    --bf-radius-full:   var(--bf-radius-pill);
    --bf-bg:            var(--bf-bg-surface);
    --bf-bg-card:       var(--bf-bg-surface);
}

/* --------------------------------------------------------------------------
   1b. Dark Mode Tokens
   -------------------------------------------------------------------------- */
.auto-frontend-dark {
    color-scheme: dark;   /* see :root — this is what re-paints native controls */

    /* Lifted off the tenant's own brand colour, so it keeps following their branding:
       65% brand + white clears 5.4:1 on the dark surface, where the raw brand is 2.9:1. */
    --bf-primary-text:  color-mix(in srgb, var(--bf-primary) 65%, #ffffff);

    --bf-bg-body:       #111827;
    --bf-bg-surface:    #1e293b;
    --bf-bg-surface-secondary: #111827;
    --bf-bg-muted:      #1e293b;

    --bf-text:          #e5e7eb;
    --bf-text-secondary:#94a3b8;
    --bf-text-muted:    #64748b;

    --bf-border:        #334155;
    --bf-border-light:  #293548;

    --bf-shadow:        0 0 4px rgba(0, 0, 0, 0.12);
    --bf-shadow-sm:     0 1px 2px rgba(0, 0, 0, 0.16);
    --bf-shadow-md:     0 2px 8px rgba(0, 0, 0, 0.20);
    --bf-shadow-lg:     0 4px 16px rgba(0, 0, 0, 0.24);
    --bf-shadow-hover:  0 2px 16px rgba(0, 0, 0, 0.28);

    /* Surface aliases must be re-declared here: var() in the :root block resolved
       against the light surface and is inherited already-resolved. */
    --bf-bg:            var(--bf-bg-surface);
    --bf-bg-card:       var(--bf-bg-surface);
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
.bf-page {
    max-width: 1200px;
    margin: 0 auto;
    padding: var(--bf-space-5) var(--bf-space-4) var(--bf-space-8);
    font-family: var(--bf-font);
    font-size: var(--bf-font-size);
    line-height: var(--bf-line-height);
    color: var(--bf-text);
    -webkit-font-smoothing: antialiased;
}

.bf-page * { box-sizing: border-box; }

.bf-page a { color: var(--bf-primary); text-decoration: none; }
.bf-page a:hover { opacity: 0.85; }

/* --------------------------------------------------------------------------
   3. Typography
   -------------------------------------------------------------------------- */
.bf-h1 { font-size: 1.5rem;   font-weight: 600; line-height: 1.2; margin: 0 0 var(--bf-space-4); color: var(--bf-text); }
.bf-h2 { font-size: 1.25rem;  font-weight: 600; line-height: 1.2; margin: 0 0 var(--bf-space-3); color: var(--bf-text); }
.bf-h3 { font-size: 1rem;     font-weight: 600; line-height: 1.3; margin: 0 0 var(--bf-space-2); color: var(--bf-text); }
.bf-h4 { font-size: 0.875rem; font-weight: 600; line-height: 1.3; margin: 0 0 var(--bf-space-2); color: var(--bf-text); }

.bf-label {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--bf-text-secondary);
}

.bf-text-muted,
.bf-muted      { color: var(--bf-text-muted); }
.bf-text-sm    { font-size: 0.8125rem; }
.bf-text-xs    { font-size: 0.75rem; }

/* Page heading block: a title plus its subtitle, above the cards. */
.bf-page-header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--bf-space-3);
    margin-bottom: var(--bf-space-5);
}

.bf-page-title {
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.2;
    margin: 0;
    color: var(--bf-text);
}

.bf-page-header p, .bf-page-header .bf-muted { margin: var(--bf-space-1) 0 0; }

/* --------------------------------------------------------------------------
   4. Card
   -------------------------------------------------------------------------- */
.bf-card {
    background: var(--bf-bg-surface);
    border: 1px solid var(--bf-border);
    border-radius: var(--bf-radius);
    box-shadow: var(--bf-shadow);
    transition: border-color var(--bf-transition), box-shadow var(--bf-transition);
}

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

.bf-card-header {
    padding: var(--bf-space-4) var(--bf-space-5);
    border-bottom: 1px solid var(--bf-border);
    display: flex;
    align-items: center;
    gap: var(--bf-space-3);
}

.bf-card-header .bf-card-title {
    font-size: 0.875rem;
    font-weight: 600;
    margin: 0;
    flex: 1;
}

.bf-card-body {
    padding: var(--bf-space-5);
}

.bf-card-footer {
    padding: var(--bf-space-4) var(--bf-space-5);
    border-top: 1px solid var(--bf-border);
}

/* Card without hover */
.bf-card-static { transition: none; }
.bf-card-static:hover { border-color: var(--bf-border); box-shadow: var(--bf-shadow); }

/* --------------------------------------------------------------------------
   5. Stat Cards (Tabler card-sm inspired)
   -------------------------------------------------------------------------- */
.bf-stats {
    display: grid;
    gap: var(--bf-space-3);
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    margin-bottom: var(--bf-space-6);
}

.bf-stat {
    background: var(--bf-bg-surface);
    border: 1px solid var(--bf-border);
    border-radius: var(--bf-radius);
    padding: var(--bf-space-4) var(--bf-space-5);
    display: flex;
    align-items: center;
    gap: var(--bf-space-3);
    box-shadow: var(--bf-shadow);
}

/* Un card care duce undeva (bf_stat_card url=...). Ancora ia tot de la
   .bf-stat; aici doar se scoate decorul implicit de link si se anunta ca e
   clicabil -- altfel arata identic cu un card mort. */
.bf-stat-link {
    color: inherit;
    text-decoration: none;
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.bf-stat-link:hover {
    border-color: var(--bf-primary);
    box-shadow: var(--bf-shadow-md);
}

.bf-stat.bf-stat-highlight {
    background: linear-gradient(135deg, color-mix(in srgb, var(--bf-primary) 90%, black), var(--bf-primary));
    color: #fff;
    border-color: transparent;
}
.bf-stat.bf-stat-highlight .bf-stat-label { color: rgba(255, 255, 255, 0.85); }

.bf-stat-icon {
    width: 40px;
    height: 40px;
    border-radius: var(--bf-radius);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    flex-shrink: 0;
    color: #fff;
}

/* Stat icon semantic colors */
.bf-stat-icon-primary { background: var(--bf-primary); }
.bf-stat-icon-success { background: var(--bf-success); }
.bf-stat-icon-warning { background: var(--bf-warning); }
.bf-stat-icon-danger,
.bf-stat-icon-error   { background: var(--bf-danger); }
.bf-stat-icon-info    { background: var(--bf-info); }
.bf-stat-icon-neutral { background: #6b7280; }
.bf-stat-icon-purple  { background: #a855f7; }

.bf-stat-value {
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.3;
}

.bf-stat-label {
    font-size: 0.78rem;
    color: var(--bf-text-secondary);
}

/* Explicatia cifrei, ca tooltip nativ (`title`) pe un (i) linga eticheta. */
.bf-stat-info {
    margin-left: 5px;
    font-size: 0.72rem;
    color: var(--bf-text-muted);
    cursor: help;
}
.bf-stat-info:hover { color: var(--bf-primary-text); }

/* --------------------------------------------------------------------------
   6. Badges
   -------------------------------------------------------------------------- */
.bf-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.75rem;
    font-weight: 600;
    padding: 2px 10px;
    border-radius: var(--bf-radius-pill);
    line-height: 1.4;
    white-space: nowrap;
}

/* Semantic badge colors (soft) */
.bf-badge-primary   { background: rgba(var(--bf-primary-rgb), 0.10);  color: var(--bf-primary); }
.bf-badge-success   { background: rgba(var(--bf-success-rgb), 0.10);  color: var(--bf-success); }
.bf-badge-warning   { background: rgba(var(--bf-warning-rgb), 0.10);  color: var(--bf-warning); }
.bf-badge-danger    { background: rgba(var(--bf-danger-rgb),  0.10);  color: var(--bf-danger); }
.bf-badge-info      { background: rgba(var(--bf-info-rgb),    0.10);  color: var(--bf-info); }
.bf-badge-neutral,
.bf-badge-muted     { background: rgba(107, 114, 128, 0.10);          color: var(--bf-text-secondary); }
.bf-badge-purple    { background: rgba(168, 85, 247, 0.10);           color: #a855f7; }
/* Alias: templates reach for "error" as often as "danger". */
.bf-badge-error     { background: rgba(var(--bf-danger-rgb),  0.10);  color: var(--bf-danger); }

/* Size variant */
.bf-badge-sm { font-size: 0.6875rem; padding: 1px 8px; gap: 3px; }

/* Outline badge — the neutral, borderless-surface variant */
.bf-badge-outline {
    background: transparent;
    color: var(--bf-text-secondary);
    border: 1px solid var(--bf-border);
}

/* Solid badge */
.bf-badge-solid {
    background: var(--bf-primary);
    color: #fff;
}

/* Dot badge (small indicator) */
.bf-badge-dot {
    padding: 0;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
}

/* --------------------------------------------------------------------------
   7. Buttons
   -------------------------------------------------------------------------- */
.bf-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 0.5rem 1rem;
    font-family: var(--bf-font);
    font-size: var(--bf-font-size);
    font-weight: 500;
    line-height: 1.25rem;
    border-radius: var(--bf-radius);
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    transition: background var(--bf-transition), color var(--bf-transition), border-color var(--bf-transition), box-shadow var(--bf-transition), transform var(--bf-transition);
    box-shadow: var(--bf-shadow-sm);
}

.bf-btn:hover { transform: translateY(-1px); box-shadow: var(--bf-shadow-md); }
.bf-btn:active { transform: translateY(0); }
.bf-btn:disabled, .bf-btn.disabled { opacity: 0.4; pointer-events: none; }

/* Primary */
.bf-btn-primary, a.bf-btn-primary {
    background: var(--bf-primary);
    color: #fff;
    border-color: var(--bf-primary);
}
.bf-btn-primary:hover, a.bf-btn-primary:hover {
    background: var(--bf-primary-hover);
    color: #fff;
    box-shadow: 0 4px 12px rgba(var(--bf-primary-rgb), 0.35);
}

/* Secondary / Outline — bf-btn-secondary is the Ant "default" button and an alias
   of bf-btn-outline. It MUST stay defined: a bf-btn with no variant class renders
   with a transparent background and an inherited text colour, which reads as
   "almost fine" on the light surface and turns invisible once .auto-frontend-dark
   flips the surface. */
.bf-btn-outline, a.bf-btn-outline,
.bf-btn-secondary, a.bf-btn-secondary {
    background: var(--bf-bg-surface);
    color: var(--bf-text);
    border-color: var(--bf-border);
    box-shadow: none;
}
.bf-btn-outline:hover, a.bf-btn-outline:hover,
.bf-btn-secondary:hover, a.bf-btn-secondary:hover { border-color: var(--bf-primary); color: var(--bf-primary); }

/* Ghost */
.bf-btn-ghost {
    background: transparent;
    color: var(--bf-text-secondary);
    border-color: transparent;
    box-shadow: none;
}
.bf-btn-ghost:hover { background: var(--bf-bg-muted); color: var(--bf-text); }

/* Danger */
.bf-btn-danger {
    background: var(--bf-danger);
    color: #fff;
    border-color: var(--bf-danger);
}

/* Success */
.bf-btn-success {
    background: var(--bf-success);
    color: #fff;
    border-color: var(--bf-success);
}

/* Pill shape */
.bf-btn-pill { border-radius: var(--bf-radius-pill); }

/* Sizes */
.bf-btn-xs { padding: 0.1875rem 0.4375rem; font-size: 0.6875rem; border-radius: var(--bf-radius-sm); }
.bf-btn-sm { padding: 0.3125rem 0.5rem; font-size: 0.75rem; border-radius: var(--bf-radius-sm); }
.bf-btn-lg { padding: 0.6875rem 1.5rem; font-size: 1rem; border-radius: var(--bf-radius-lg); }

/* Icon-only */
.bf-btn-icon {
    padding: 0.5rem;
    min-width: 36px;
    min-height: 36px;
}

/* --------------------------------------------------------------------------
   8. Chips / Filter Pills
   -------------------------------------------------------------------------- */
.bf-chips {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-bottom: var(--bf-space-4);
    align-items: center;
}

.bf-chips-label {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--bf-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding-right: var(--bf-space-2);
}

.bf-chip {
    border: 1px solid var(--bf-border);
    background: var(--bf-bg-surface);
    color: var(--bf-text);
    border-radius: var(--bf-radius-lg);
    padding: 4px 14px;
    font-size: 0.8125rem;
    font-weight: 500;
    cursor: pointer;
    text-decoration: none;
    transition: background var(--bf-transition), color var(--bf-transition), border-color var(--bf-transition);
}

.bf-chip.active, .bf-chip.bf-chip-active {
    background: var(--bf-primary);
    color: #fff;
    border-color: transparent;
}

.bf-chip:hover:not(.active):not(.bf-chip-active) {
    border-color: var(--bf-primary);
    color: var(--bf-primary);
}

/* --------------------------------------------------------------------------
   9. Tabs (pill style)
   -------------------------------------------------------------------------- */
.bf-tabs {
    display: flex;
    gap: 4px;
    background: var(--bf-bg-surface);
    border-radius: var(--bf-radius-lg);
    padding: 4px;
    box-shadow: var(--bf-shadow);
}

.bf-tab {
    padding: 8px 18px;
    border-radius: var(--bf-radius);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    color: var(--bf-text-secondary);
    text-decoration: none;
    transition: background var(--bf-transition), color var(--bf-transition), box-shadow var(--bf-transition);
    border: none;
    background: transparent;
}

.bf-tab.active, .bf-tab.bf-tab-active {
    background: var(--bf-primary);
    color: #fff;
    box-shadow: 0 4px 12px rgba(var(--bf-primary-rgb), 0.30);
}

.bf-tab:hover:not(.active):not(.bf-tab-active) {
    color: var(--bf-text);
    background: var(--bf-bg-muted);
}

/* --------------------------------------------------------------------------
   10. Toolbar (tabs + search + action)
   -------------------------------------------------------------------------- */
.bf-toolbar {
    display: flex;
    gap: var(--bf-space-3);
    flex-wrap: wrap;
    align-items: center;
    margin-bottom: var(--bf-space-5);
}

/* --------------------------------------------------------------------------
   11. Search Input
   -------------------------------------------------------------------------- */
.bf-search {
    flex: 1;
    min-width: 200px;
    position: relative;
}

.bf-search input {
    width: 100%;
    border: 1px solid var(--bf-border);
    border-radius: var(--bf-radius);
    padding: 8px 16px 8px 38px;
    font-family: var(--bf-font);
    font-size: var(--bf-font-size);
    background: var(--bf-bg-surface);
    color: var(--bf-text);
    transition: border-color var(--bf-transition), box-shadow var(--bf-transition);
    box-shadow: var(--bf-shadow-sm);
}

.bf-search input:focus {
    outline: none;
    border-color: var(--bf-primary);
    box-shadow: 0 0 0 3px rgba(var(--bf-primary-rgb), 0.12);
}

.bf-search input::placeholder { color: var(--bf-text-muted); }

.bf-search i, .bf-search .bf-search-icon {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--bf-text-muted);
    font-size: 0.85rem;
    pointer-events: none;
}

/* --------------------------------------------------------------------------
   12. Form Controls
   -------------------------------------------------------------------------- */
.bf-input, .bf-select, .bf-textarea {
    width: 100%;
    border: 1px solid var(--bf-border);
    border-radius: var(--bf-radius);
    padding: 0.5rem 0.75rem;
    font-family: var(--bf-font);
    font-size: var(--bf-font-size);
    background: var(--bf-bg-surface);
    color: var(--bf-text);
    transition: border-color var(--bf-transition), box-shadow var(--bf-transition);
    box-shadow: 0 1px 1px rgba(31, 41, 55, 0.06);
}

.bf-input:focus, .bf-select:focus, .bf-textarea:focus {
    outline: none;
    border-color: var(--bf-primary);
    box-shadow: 0 0 0 3px rgba(var(--bf-primary-rgb), 0.12);
}

.bf-textarea { resize: vertical; min-height: 80px; }

.bf-input-sm, .bf-select-sm { padding: 0.3125rem 0.5rem; font-size: 0.8125rem; border-radius: var(--bf-radius-sm); }

.bf-form-label {
    display: block;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--bf-text);
    margin-bottom: var(--bf-space-1);
}

.bf-form-group { margin-bottom: var(--bf-space-4); }

.bf-form-hint {
    font-size: 0.75rem;
    color: var(--bf-text-muted);
    margin-top: var(--bf-space-1);
}

/* --------------------------------------------------------------------------
   13. Tables
   -------------------------------------------------------------------------- */
/* Wrapper that lets a wide table scroll instead of stretching the page. */
.bf-table-wrap {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.bf-table {
    width: 100%;
    border-collapse: collapse;
}

.bf-table th {
    padding: 0.625rem 0.75rem;
    text-align: left;
    font-weight: 600;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--bf-text-secondary);
    border-bottom: 2px solid var(--bf-border);
    background: transparent;
}

.bf-table td {
    padding: 0.625rem 0.75rem;
    font-size: var(--bf-font-size);
    color: var(--bf-text);
    border-bottom: 1px solid var(--bf-border-light);
    vertical-align: middle;
}

.bf-table tr:last-child td { border-bottom: none; }

.bf-table tr:hover td { background: var(--bf-bg-surface-secondary); }

.bf-table tr.bf-row-selected > td {
    background: rgba(var(--bf-primary-rgb), 0.10);
    box-shadow: inset 3px 0 0 0 var(--bf-primary);
}

.bf-table-compact th,
.bf-table-compact td { padding: 0.375rem 0.625rem; }

/* --------------------------------------------------------------------------
   14. Pagination
   -------------------------------------------------------------------------- */
.bf-pagination {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 4px;
    margin-top: var(--bf-space-6);
    flex-wrap: wrap;
}

.bf-page-btn, .bf-pagination-item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    height: 36px;
    padding: 0 10px;
    border-radius: var(--bf-radius);
    border: 1px solid var(--bf-border);
    background: var(--bf-bg-surface);
    color: var(--bf-text);
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background var(--bf-transition), color var(--bf-transition), border-color var(--bf-transition);
}

.bf-page-btn:hover, .bf-pagination-item:hover {
    border-color: var(--bf-primary);
    color: var(--bf-primary);
}

.bf-page-btn.active, .bf-page-btn.bf-page-active,
.bf-pagination-item.active, .bf-pagination-item.bf-page-active {
    background: var(--bf-primary);
    color: #fff;
    border-color: transparent;
}

.bf-page-btn.disabled, .bf-pagination-item.disabled {
    opacity: 0.35;
    pointer-events: none;
}

.bf-page-info {
    font-size: 0.78rem;
    color: var(--bf-text-muted);
    padding: 0 var(--bf-space-2);
    user-select: none;
}

/* --------------------------------------------------------------------------
   15. Alerts / Response Blocks
   -------------------------------------------------------------------------- */
.bf-alert {
    padding: var(--bf-space-3) var(--bf-space-4);
    border-radius: var(--bf-radius-lg);
    font-size: 0.85rem;
    line-height: 1.5;
    margin-bottom: var(--bf-space-4);
}

.bf-alert-info    { background: rgba(var(--bf-info-rgb), 0.06);    border-left: 3px solid var(--bf-info); }
.bf-alert-success { background: rgba(var(--bf-success-rgb), 0.06); border-left: 3px solid var(--bf-success); }
.bf-alert-warning { background: rgba(var(--bf-warning-rgb), 0.06); border-left: 3px solid var(--bf-warning); }
.bf-alert-danger  { background: rgba(var(--bf-danger-rgb), 0.06);  border-left: 3px solid var(--bf-danger); }

/* --------------------------------------------------------------------------
   16. Empty State
   -------------------------------------------------------------------------- */
.bf-empty {
    text-align: center;
    padding: var(--bf-space-8) var(--bf-space-4);
    color: var(--bf-text-muted);
}

.bf-empty i, .bf-empty .bf-empty-icon {
    font-size: 2.5rem;
    color: #cbd5e1;
    margin-bottom: var(--bf-space-3);
    display: block;
    width: 100%;
    text-align: center;
}

.auto-frontend-dark .bf-empty i,
.auto-frontend-dark .bf-empty .bf-empty-icon { color: #475569; }

.bf-empty p { margin: var(--bf-space-2) 0 0; }

/* --------------------------------------------------------------------------
   17. Avatars
   -------------------------------------------------------------------------- */
.bf-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    font-weight: 700;
    flex-shrink: 0;
    background: var(--bf-primary);
    color: #fff;
}

.bf-avatar-sm { width: 24px; height: 24px; font-size: 0.625rem; }
.bf-avatar-lg { width: 40px; height: 40px; font-size: 0.875rem; }
.bf-avatar-xl { width: 52px; height: 52px; font-size: 1.1rem; }

/* Rounded-square avatar — the shape the auto-frontend uses for the avatar
   column of a content-type table (/erp/ct/*). Pair it with a per-name
   background from `string_to_color()` to match those tables exactly. */
.bf-avatar-square { border-radius: var(--bf-radius); }

/* Inline image thumbnail (table cells, lightbox triggers) */
.bf-img-thumb {
    width: 48px;
    height: 48px;
    object-fit: cover;
    border-radius: var(--bf-radius);
    border: 1px solid var(--bf-border);
    background: var(--bf-bg-muted);
    cursor: pointer;
    display: block;
}

/* --------------------------------------------------------------------------
   18. Meta / Inline Info
   -------------------------------------------------------------------------- */
.bf-meta {
    display: flex;
    gap: var(--bf-space-4);
    font-size: 0.78rem;
    color: var(--bf-text-secondary);
    flex-wrap: wrap;
    align-items: center;
}

.bf-meta i { margin-right: 4px; }

.bf-meta a {
    color: var(--bf-text-secondary);
    text-decoration: none;
    transition: color var(--bf-transition);
}
.bf-meta a:hover { color: var(--bf-primary); }

/* --------------------------------------------------------------------------
   19. Vote Component
   -------------------------------------------------------------------------- */
.bf-vote {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    min-width: 48px;
}

.bf-vote-btn {
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px;
    font-size: 1.1rem;
    color: var(--bf-text-muted);
    transition: color var(--bf-transition), transform 0.1s;
    border-radius: var(--bf-radius);
}
.bf-vote-btn:hover { color: var(--bf-primary); transform: scale(1.2); }
.bf-vote-btn.voted-up  { color: var(--bf-success); }
.bf-vote-btn.voted-down { color: var(--bf-danger); }

.bf-vote-count {
    font-size: 1rem;
    font-weight: 700;
    color: var(--bf-text);
}

/* --------------------------------------------------------------------------
   20. Grid utilities
   -------------------------------------------------------------------------- */
.bf-grid      { display: grid; gap: var(--bf-space-3); }
.bf-grid-2    { grid-template-columns: repeat(2, 1fr); }
.bf-grid-3    { grid-template-columns: repeat(3, 1fr); }
.bf-grid-4    { grid-template-columns: repeat(4, 1fr); }
.bf-grid-auto { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.bf-flex      { display: flex; }
.bf-flex-wrap { flex-wrap: wrap; }
.bf-gap-1     { gap: var(--bf-space-1); }
.bf-gap-2     { gap: var(--bf-space-2); }
.bf-gap-3     { gap: var(--bf-space-3); }
.bf-gap-4     { gap: var(--bf-space-4); }
.bf-items-center   { align-items: center; }
.bf-justify-between { justify-content: space-between; }

/* Text alignment */
.bf-text-left   { text-align: left; }
.bf-text-center { text-align: center; }
.bf-text-right  { text-align: right; }

/* --------------------------------------------------------------------------
   21. Spacing utilities
   -------------------------------------------------------------------------- */
.bf-mb-0 { margin-bottom: 0; }
.bf-mb-1 { margin-bottom: var(--bf-space-1); }
.bf-mb-2 { margin-bottom: var(--bf-space-2); }
.bf-mb-3 { margin-bottom: var(--bf-space-3); }
.bf-mb-4 { margin-bottom: var(--bf-space-4); }
.bf-mb-5 { margin-bottom: var(--bf-space-5); }
.bf-mb-6 { margin-bottom: var(--bf-space-6); }
.bf-mt-0 { margin-top: 0; }
.bf-mt-1 { margin-top: var(--bf-space-1); }
.bf-mt-2 { margin-top: var(--bf-space-2); }
.bf-mt-3 { margin-top: var(--bf-space-3); }
.bf-mt-4 { margin-top: var(--bf-space-4); }
.bf-mt-6 { margin-top: var(--bf-space-6); }
.bf-ml-1 { margin-left: var(--bf-space-1); }
.bf-ml-2 { margin-left: var(--bf-space-2); }
.bf-mr-1 { margin-right: var(--bf-space-1); }
.bf-mr-2 { margin-right: var(--bf-space-2); }

/* --------------------------------------------------------------------------
   22. Key-Value List (stat rows inside cards)
   -------------------------------------------------------------------------- */
.bf-kv-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--bf-space-2) 0;
    border-bottom: 1px solid var(--bf-border-light);
}
.bf-kv-row:last-child { border-bottom: none; }
.bf-kv-label { font-size: 0.85rem; color: var(--bf-text-secondary); }
.bf-kv-value { font-size: 0.95rem; font-weight: 600; color: var(--bf-text); }

/* --------------------------------------------------------------------------
   23. Modal
   -------------------------------------------------------------------------- */
.bf-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s, visibility 0.2s;
}
.bf-modal-backdrop.open { opacity: 1; visibility: visible; }

.bf-modal {
    background: var(--bf-bg-surface);
    border-radius: var(--bf-radius-lg);
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);
    width: 100%;
    max-width: 520px;
    max-height: calc(100vh - 3rem);
    display: flex;
    flex-direction: column;
    transform: translateY(12px) scale(0.98);
    transition: transform 0.2s;
    overflow: hidden;
}
.bf-modal-backdrop.open .bf-modal { transform: translateY(0) scale(1); }

/* Sizes */
.bf-modal-sm { max-width: 380px; }
.bf-modal-lg { max-width: 720px; }
.bf-modal-full { max-width: calc(100vw - 2rem); }

.bf-modal-header {
    padding: var(--bf-space-4) var(--bf-space-5);
    border-bottom: 1px solid var(--bf-border);
    display: flex;
    align-items: center;
    gap: var(--bf-space-3);
    flex-shrink: 0;
}

.bf-modal-title {
    font-size: 1rem;
    font-weight: 600;
    margin: 0;
    flex: 1;
    color: var(--bf-text);
}

.bf-modal-close {
    background: none;
    border: none;
    cursor: pointer;
    padding: var(--bf-space-1);
    font-size: 1.1rem;
    color: var(--bf-text-muted);
    border-radius: var(--bf-radius);
    transition: background var(--bf-transition), color var(--bf-transition);
    line-height: 1;
}
.bf-modal-close:hover { background: var(--bf-bg-muted); color: var(--bf-text); }

.bf-modal-body {
    padding: var(--bf-space-5);
    overflow-y: auto;
    flex: 1;
}

.bf-modal-footer {
    padding: var(--bf-space-4) var(--bf-space-5);
    border-top: 1px solid var(--bf-border);
    display: flex;
    justify-content: flex-end;
    gap: var(--bf-space-2);
    flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   24. Drawer (slide-in panel)
   -------------------------------------------------------------------------- */
.bf-drawer-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    z-index: 1000;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s, visibility 0.2s;
}
.bf-drawer-backdrop.open { opacity: 1; visibility: visible; }

.bf-drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 420px;
    max-width: calc(100vw - 2rem);
    background: var(--bf-bg-surface);
    box-shadow: -8px 0 32px rgba(0, 0, 0, 0.15);
    z-index: 1001;
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.bf-drawer-backdrop.open .bf-drawer { transform: translateX(0); }

/* Sizes */
.bf-drawer-sm { width: 320px; }
.bf-drawer-lg { width: 560px; }

.bf-drawer-header {
    padding: var(--bf-space-4) var(--bf-space-5);
    border-bottom: 1px solid var(--bf-border);
    display: flex;
    align-items: center;
    gap: var(--bf-space-3);
    flex-shrink: 0;
}

.bf-drawer-title {
    font-size: 1rem;
    font-weight: 600;
    margin: 0;
    flex: 1;
    color: var(--bf-text);
}

.bf-drawer-close {
    background: none;
    border: none;
    cursor: pointer;
    padding: var(--bf-space-1);
    font-size: 1.1rem;
    color: var(--bf-text-muted);
    border-radius: var(--bf-radius);
    transition: background var(--bf-transition), color var(--bf-transition);
    line-height: 1;
}
.bf-drawer-close:hover { background: var(--bf-bg-muted); color: var(--bf-text); }

.bf-drawer-body {
    padding: var(--bf-space-5);
    overflow-y: auto;
    flex: 1;
}

.bf-drawer-footer {
    padding: var(--bf-space-4) var(--bf-space-5);
    border-top: 1px solid var(--bf-border);
    display: flex;
    justify-content: flex-end;
    gap: var(--bf-space-2);
    flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   25. Private / Small Info badges
   -------------------------------------------------------------------------- */
.bf-info-badge {
    font-size: 0.72rem;
    color: var(--bf-text-secondary);
    display: inline-flex;
    align-items: center;
    gap: 3px;
}

/* --------------------------------------------------------------------------
   26. Segmented Control
   -------------------------------------------------------------------------- */
.bf-segmented {
    display: inline-flex;
    background: var(--bf-bg-muted);
    border-radius: var(--bf-radius-lg);
    padding: 3px;
    gap: 2px;
}

.bf-segmented-item {
    padding: 6px 16px;
    border-radius: var(--bf-radius);
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--bf-text-secondary);
    cursor: pointer;
    text-decoration: none;
    border: none;
    background: transparent;
    transition: background var(--bf-transition), color var(--bf-transition), box-shadow var(--bf-transition);
    white-space: nowrap;
    font-family: var(--bf-font);
    line-height: 1.4;
}

.bf-segmented-item.active, .bf-segmented-item.bf-segmented-active {
    background: var(--bf-bg-surface);
    color: var(--bf-text);
    box-shadow: var(--bf-shadow-sm);
}

.bf-segmented-item:hover:not(.active):not(.bf-segmented-active) {
    color: var(--bf-text);
}

/* Size variants */
.bf-segmented-sm .bf-segmented-item { padding: 4px 12px; font-size: 0.75rem; }
.bf-segmented-lg .bf-segmented-item { padding: 8px 20px; font-size: 0.875rem; }

/* --------------------------------------------------------------------------
   27. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 768px) {
    .bf-page { padding: var(--bf-space-4) var(--bf-space-3) var(--bf-space-6); }

    .bf-stats { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }

    .bf-toolbar { flex-direction: column; align-items: stretch; }
    .bf-tabs { overflow-x: auto; flex-shrink: 0; }

    .bf-grid-2, .bf-grid-3, .bf-grid-4 { grid-template-columns: 1fr; }

    .bf-vote { flex-direction: row; gap: var(--bf-space-2); }
}

/* ── File manager ─────────────────────────────────────────────── */
.bf-fm-root { color: var(--bf-text); }
/* The chrome bar (the toolbar) sits OUTSIDE the pane layout the fragment swap replaces,
   so it owns the spacing below itself; its children no longer add their own. */
/* Command bar: actions on the left, one hairline under the whole thing -- the row
   Explorer puts above its address bar. */
.bf-fm-chrome {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--bf-space-2);
    margin-bottom: var(--bf-space-3);
    padding-bottom: var(--bf-space-2);
    border-bottom: 1px solid var(--bf-border);
}
.bf-fm-toolbar { display: flex; gap: var(--bf-space-2); }
/* Address bar: a boxed row of crumbs with chevron separators, like Explorer's. The
   separator is generated on the crumb that FOLLOWS another one (`+`), so it never
   renders before the first or after the last -- and it is `::before` on the crumb rather
   than a `<span>` in the template because the template is shared with hosts that style
   this markup themselves. `--bf-bg-surface-secondary` is the same fill the tree panel
   uses, so the two chrome surfaces match, and it differs from the card in both themes
   (#f9fafb/#111827 vs #ffffff/#1e293b) -- the pair trap documented on
   `.bf-fm-item:hover` below. */
.bf-fm-crumbs {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--bf-space-1);
    margin-bottom: var(--bf-space-3);
    padding: var(--bf-space-1) var(--bf-space-2);
    background: var(--bf-bg-surface-secondary);
    border: 1px solid var(--bf-border);
    border-radius: var(--bf-radius);
    font-size: 0.85rem;
}
.bf-fm-crumb {
    color: var(--bf-text-secondary);
    padding: 1px var(--bf-space-1);
    border-radius: var(--bf-radius-sm);
}
.bf-fm-crumb:hover { color: var(--bf-primary); background: var(--bf-bg-muted); }
.bf-fm-crumb + .bf-fm-crumb::before {
    content: "\203A";
    /* Outside the padding box so the chevron is not part of the crumb's own hover fill,
       and `inline-block` so the margins apply. */
    display: inline-block;
    margin: 0 var(--bf-space-2) 0 calc(-1 * var(--bf-space-1));
    color: var(--bf-text-muted);
}
/* Details view. Three deliberate departures from what this list used to be, all of them
   what makes it read as a file manager rather than as a styled <ul>:

   1. No `padding-left` on the list. A listing pane starts at its own left edge; the old
      indent made every row look nested under something.
   2. No `border-bottom` per row. Explorer's details view separates rows by nothing at
      all -- the hover/selection fill does that work -- and keeps ONE hairline under the
      column header (`.bf-fm-head` below). Ruled lines on every row read as a table.
   3. No background tint on folder rows. Folders are distinguished the way Explorer
      distinguishes them: by the icon (`.bf-fm-item-folder .bf-fm-row-icon` below paints
      it with the brand colour) and by sorting first. A tinted band per folder fought
      with the row hover and made the listing stripy.
   Columns are fixed-width and shared with `.bf-fm-head-*`: that shared width is the only
   reason a row's cells line up under their header, so the two sets move together. */
.bf-fm-level { list-style: none; margin: 0; padding-left: 0; }
.bf-fm-item { display: flex; align-items: center; gap: var(--bf-space-2); min-height: 1.85rem; padding: var(--bf-space-1) var(--bf-space-3); }
.bf-fm-item-file { color: var(--bf-text); }
/* `min-width: 0` plus the ellipsis: without it a long filename pushes the size and date
   columns off their alignment (a flex item refuses to shrink below its content by
   default), which is exactly the misalignment the fixed widths exist to prevent. */
.bf-fm-name {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--bf-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bf-fm-name:hover { color: var(--bf-primary); }
/* A folder's child/file count, in the SIZE column (Explorer leaves a folder's size
   blank; this is the closest honest equivalent). `_level.html` emits an empty
   `.bf-fm-col-modified` after it under `explorer_chrome`, which is what keeps it from
   being pushed right into the date column. */
.bf-fm-count { flex: none; width: 5.5rem; text-align: right; color: var(--bf-text-secondary); font-size: 0.78rem; }
.bf-fm-head {
    display: flex;
    align-items: center;
    gap: var(--bf-space-2);
    padding: var(--bf-space-1) var(--bf-space-3);
    border-bottom: 1px solid var(--bf-border);
    color: var(--bf-text-secondary);
    font-size: 0.78rem;
    font-weight: 400;
}
.bf-fm-head-name { flex: 1 1 auto; min-width: 0; }
.bf-fm-head-size { flex: none; width: 5.5rem; text-align: right; }
.bf-fm-head-modified { flex: none; width: 6.5rem; }
/* Status bar: the item count under the listing, Explorer's bottom strip. */
.bf-fm-status {
    margin-top: var(--bf-space-2);
    padding: var(--bf-space-2) var(--bf-space-3) 0;
    border-top: 1px solid var(--bf-border);
    color: var(--bf-text-secondary);
    font-size: 0.75rem;
}
.bf-fm-badge { background: var(--bf-bg-muted); border: 1px solid var(--bf-border); border-radius: var(--bf-radius-lg); padding: 0 var(--bf-space-2); font-size: 0.75rem; color: var(--bf-text-secondary); }
.bf-fm-empty { color: var(--bf-text-secondary); padding: var(--bf-space-3); }
.bf-fm-more { display: inline-block; margin-top: var(--bf-space-3); color: var(--bf-primary); }

.bf-fm-layout { display: flex; gap: var(--bf-space-4); align-items: flex-start; }
/* `flex-basis` reads from a CSS custom property, not a literal `240px`, so the
   splitter (Task 6) can override just that number per user -- via a variable set
   inline on THIS element (`--bf-fm-tree-width`, written by `_tree.html`'s own
   `style` attribute and by the drag script on every `mousemove`) -- while leaving
   `flex-grow`/`flex-shrink` alone. The narrow-viewport rule below still wins on
   mobile without needing `!important`: it is a plain `.bf-fm-tree` rule with the
   same specificity, later in the cascade, and does not reference the variable at
   all, so an inline custom property that only ever feeds INTO the desktop rule's
   `flex-basis` cannot leak into it. */
/* `box-sizing: border-box` is load-bearing for the splitter, not a style preference. The
   drag reads `getBoundingClientRect().width` (which includes the 1px borders) and writes
   that number back as `flex-basis`; under the browser default `content-box` those two
   measure different boxes, so every drag moved the edge ~2px further than the pointer.
   This markup is injected outside any `.bf-page` wrapper, so the sheet's own
   `.bf-page * { box-sizing: border-box }` never reaches it — it has to be set here. */
.bf-fm-tree { box-sizing: border-box; flex: 0 0 var(--bf-fm-tree-width, 240px); background: var(--bf-bg-surface-secondary); border: 1px solid var(--bf-border); border-radius: var(--bf-radius); padding: var(--bf-space-2) 0; overflow-x: auto; }
.bf-fm-tree-level { list-style: none; margin: 0; padding-left: var(--bf-space-3); }
.bf-fm-tree > .bf-fm-tree-level { padding-left: 0; }
/* The tree is genuinely nested (<li> containing <ul>), so a `.bf-fm-tree-item` has up
   to two direct children: `.bf-fm-tree-row` (chevron/spacer + name link) and -- for a
   folder with children -- its own nested `.bf-fm-tree-level` <ul>. The row wrapper is
   what makes the WHOLE row highlight on hover/selection, not just the name text: it
   used to sit on `.bf-fm-tree-link` alone, sibling to the chevron, so the highlight
   started about 1rem short of the row's own left edge -- Explorer highlights the
   entire row. `.bf-fm-tree-level` stays a plain block sibling of the row (never
   inside it), or the row's background would stretch down over the whole nested
   subtree instead of just its own line. */
.bf-fm-tree-item { display: block; list-style: none; }
.bf-fm-tree-row {
  display: flex;
  align-items: center;
  gap: var(--bf-space-1);
  padding: var(--bf-space-1) var(--bf-space-2);
  border-radius: var(--bf-radius-sm);
}
.bf-fm-tree-row:hover { background: var(--bf-bg-muted); }
.bf-fm-tree-row:hover .bf-fm-tree-link { color: var(--bf-primary); }
.bf-fm-tree-link {
  flex: 1 1 auto;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--bf-space-2);
  color: var(--bf-text);
  white-space: nowrap;
}
/* `-node-open` now means `item.is_open` (root + every ancestor on the path + any
   folder the host asked to open) -- a much wider set than the old "ancestor of the
   selection". The dimmed colour reads as "already expanded", not as a breadcrumb
   trail. Unlike the old flat siblings (where `.bf-fm-tree-item > .bf-fm-tree-link:hover`
   at (0,3,0) always outranked this rule's (0,2,0)), routing both through the new
   `.bf-fm-tree-row` wrapper makes them TIE at (0,3,0) each -- so, like the
   -node-current pair below, hover needs its own explicit repeat to keep winning. */
.bf-fm-node-open > .bf-fm-tree-row .bf-fm-tree-link { color: var(--bf-text-secondary); }
.bf-fm-node-open > .bf-fm-tree-row:hover .bf-fm-tree-link { color: var(--bf-primary); }
/* The selected node: a quiet chip with an accent edge on the left, which is how a
   desktop file manager marks the current folder -- not the saturated brand-coloured bar
   with white text this used to be (that read as a web app's active nav item and shouted
   over the whole tree).
   A brand TINT for the fill, not a grey token, because FOUR surfaces now have to stay
   mutually distinct in both themes: the panel (`--bf-bg-surface-secondary`:
   #f9fafb/#111827), a row's hover (`--bf-bg-muted`: #f3f4f6/#1e293b), the right-click
   menu that can open on top of this very row (`--bf-border`: #e5e7eb/#334155) and this.
   Every remaining `--bf-bg-*` collides with one of those in dark, where the family
   collapses to two values -- `--bf-border` was tried here first and
   test_renderer_theme_no_db caught it colliding with the menu. A tint derived from
   `--bf-primary` cannot collide with any of them by construction, follows the tenant's
   own branding, and is what Windows' own accent-tinted selection looks like.
   `transparent` as the mix partner (rather than a surface token) lets it composite over
   whatever is actually behind the row, so it works on the panel and, after a fragment
   swap, anywhere else the row is re-rendered.
   The accent is an INSET shadow, not a border-left, so switching it on cannot shift the
   row's text by 2px relative to its unselected siblings. */
.bf-fm-node-current > .bf-fm-tree-row {
    background: color-mix(in srgb, var(--bf-primary) 14%, transparent);
    box-shadow: inset 2px 0 0 var(--bf-primary);
}
.bf-fm-node-current > .bf-fm-tree-row .bf-fm-tree-link { color: var(--bf-primary-text); font-weight: 600; }
/* Hover on the already-selected row keeps the selected look: re-stated because
   `.bf-fm-tree-row:hover` would otherwise repaint it with the plain hover fill and the
   row would appear to lose its selection under the pointer. */
.bf-fm-node-current > .bf-fm-tree-row:hover { background: color-mix(in srgb, var(--bf-primary) 14%, transparent); }
.bf-fm-node-current > .bf-fm-tree-row:hover .bf-fm-tree-link { color: var(--bf-primary-text); }
.bf-fm-chevron { display: inline-flex; align-items: center; justify-content: center; width: 1rem; flex: none; color: var(--bf-text-secondary); }
.bf-fm-chevron:hover { color: var(--bf-primary); }
/* A node open only because it lies on the selection's path (see `TreeItem.
   chevron_is_static` in `bapp_framework.sdk.file_manager.service`): toggling it
   would produce the identical URL, so it renders as this plain, non-interactive
   marker instead of `.bf-fm-chevron`'s `<a>`. Same resting look (still an
   affordance-shaped icon, still pointing where the tree currently is), no hover
   colour change and a `default` cursor, so it never invites a click that does
   nothing. Ties `.bf-fm-chevron:hover` on specificity (0,2,0 each: one class + one
   pseudo-class), so it must come after that rule to win. */
.bf-fm-chevron-static { cursor: default; opacity: 0.55; }
.bf-fm-chevron-static:hover { color: var(--bf-text-secondary); }
.bf-fm-tree-spacer { display: inline-flex; width: 1rem; flex: none; }
.bf-fm-tree-icon { color: var(--bf-primary); }
/* `.bf-fm-tree-row` hop is required: the row wrapper made `.bf-fm-tree-link` a GRANDCHILD
   of the `<li>`, so the old `.bf-fm-tree-root > .bf-fm-tree-link` matched nothing and the
   root/home label silently lost its weight on every host that sets `show_root_node`. The
   class-coverage gate cannot catch this -- it only checks that a class appears in some
   rule, never that a combinator chain still matches the DOM. */
.bf-fm-tree-root > .bf-fm-tree-row .bf-fm-tree-link { font-weight: 600; }
.bf-fm-row-icon { color: var(--bf-text-secondary); width: 1.1rem; margin-right: var(--bf-space-2); text-align: center; }
/* THE folder distinction in the list view, now that folder rows carry no tint and no
   weight of their own: the brand-coloured folder icon against the file rows' neutral
   type icons -- how Explorer does it too (icon + folders sorted first, never a tinted
   band). Pinned by `test_renderer_theme_no_db.test_folder_rows_are_told_apart_by_their_icon`;
   if this rule goes, folder and file rows become indistinguishable. */
.bf-fm-item-folder .bf-fm-row-icon { color: var(--bf-primary); }
.bf-fm-item { border-radius: var(--bf-radius-sm); }
/* Every row now rests on exactly ONE background -- its container `.bf-card`
   (--bf-bg-surface: #ffffff light / #1e293b dark) -- because folder rows no longer carry
   a tint of their own. The hover still has to differ from it in BOTH themes: the
   pair-distinguishability trap this file has been caught by three times.
   `--bf-bg-muted` cannot serve, being identical to the card in dark (#1e293b on
   #1e293b); `--bf-bg-surface-secondary` (#f9fafb / #111827) differs in both and is
   already this file's row-hover token (`.bf-table tr:hover td`), so a file row hovers
   exactly like a table row does. Pinned by test_renderer_theme_no_db.py. */
.bf-fm-item:hover { background: var(--bf-bg-surface-secondary); }
.bf-fm-pane { flex: 1 1 auto; min-width: 0; }
/* Drag-over state for drag-and-drop upload, added and removed by manager.html's own
   drop script (so it never appears in the markup at rest). An OUTLINE in `--bf-primary`,
   not a `--bf-bg-*` background: the pane can rest on more than one surface and, in dark
   mode, the `--bf-bg-*` family collapses to fewer distinct values than it has names --
   the pair-distinguishability trap `.bf-fm-item:hover` and `.bf-fm-menu` above each
   document having been caught by. A brand colour against any of those surfaces is
   distinct in both themes by construction, so there is no token PAIR here to collide.
   `outline` rather than `border`, and `outline-offset` negative, so switching it on
   cannot change the pane's layout size and shift the listing under the user's cursor
   mid-drag. */
.bf-fm-drop-active {
    outline: 2px dashed var(--bf-primary);
    outline-offset: -2px;
    border-radius: var(--bf-radius);
}
.bf-fm-col-size, .bf-fm-col-modified { flex: none; color: var(--bf-text-secondary); font-size: 0.78rem; }
.bf-fm-col-size { width: 5.5rem; text-align: right; }
.bf-fm-col-modified { width: 6.5rem; }
/* Splitter handle (Task 6): a thin invisible strip between the tree and the pane,
   filled in on hover/active so it reads as grabbable without drawing a permanent
   line across the layout at rest. Resting state is literally `transparent`, not a
   `--bf-bg-*` token, so it is definitionally never the same colour as whatever
   sits behind it (the card's own background) in either theme -- there is no
   token PAIR here for `test_renderer_theme_no_db.py`'s pair-guard to check, the
   same way a hover state and "no background at all" can never collide the way
   two different `--bf-bg-*` tokens already have on this branch. */
.bf-fm-splitter { flex: none; width: 6px; cursor: col-resize; align-self: stretch; background: transparent; }
.bf-fm-splitter:hover, .bf-fm-splitter:active { background: var(--bf-border); }
@media (max-width: 720px) {
  .bf-fm-layout { flex-direction: column; }
  .bf-fm-tree { flex: 1 1 auto; }
  /* Dragging a horizontal splitter makes no sense once the layout stacks into a
     column -- the tree pane's own width is no longer the thing sharing space with
     the listing pane. */
  .bf-fm-splitter { display: none; }
}

/* Right-click context menu (manager.html's own script builds this on `contextmenu`).
   Background is `--bf-border`, deliberately NOT one of the `--bf-bg-*` family: this
   floating menu can land over a list row (`.bf-card`, `--bf-bg-surface`), a folder
   row (`--bf-fm-item-folder`, `--bf-bg-muted`) or the tree panel itself (`.bf-fm-tree`,
   `--bf-bg-surface-secondary`) -- and in dark mode those three collapse to only TWO
   distinct colours (`--bf-bg-surface`/`--bf-bg-muted` both `#1e293b`, `--bf-bg-surface-
   secondary` `#111827`), so any `--bf-bg-*` token chosen for the menu would be
   invisible against at least one of them. `--bf-border` resolves to `#e5e7eb`/`#334155`
   -- distinct from all three surfaces in BOTH themes -- so the menu never disappears
   against whatever it happens to open over. See `test_renderer_theme_no_db.py`'s
   `test_menu_background_differs_from_every_surface_it_can_open_over` for the resolved
   values in both themes. */
.bf-fm-menu {
    position: fixed;
    z-index: 1100;
    min-width: 170px;
    background: var(--bf-border);
    border: 1px solid var(--bf-border-light);
    border-radius: var(--bf-radius);
    box-shadow: var(--bf-shadow-lg);
    padding: var(--bf-space-1) 0;
}
.bf-fm-menu-item {
    display: block;
    padding: var(--bf-space-2) var(--bf-space-3);
    color: var(--bf-text);
    font-size: 0.85rem;
    white-space: nowrap;
    cursor: pointer;
}
.bf-fm-menu-item:hover { background: var(--bf-bg-surface); color: var(--bf-primary); }
