/* ═══════════════════════════════════════════════════════════════════
   CloudVault – Design System
   Variables → base → layout → components → KeePass → admin → modals
   → toast → Bootstrap dark overrides → responsive
   ═══════════════════════════════════════════════════════════════════ */

/* ── Design tokens ─────────────────────────────────────────────── */
:root {
  /* surfaces */
  --cv-bg:          #f5f6f8;
  --cv-surface:     #ffffff;
  --cv-surface-2:   #f8f9fa;
  --cv-surface-3:   #f0f4f8;

  /* borders */
  --cv-border:      #e2e6ea;
  --cv-border-2:    #d0d5dd;

  /* text */
  --cv-text:        #212529;
  --cv-text-2:      #495057;
  --cv-text-3:      #6c757d;
  --cv-text-4:      #9ca3af;

  /* accent (primary blue) */
  --cv-accent:      #0d6efd;
  --cv-accent-h:    #0b5ed7;
  --cv-accent-sub:  rgba(13,110,253,.11);

  /* semantic */
  --cv-danger:      #dc3545;
  --cv-danger-sub:  rgba(220,53,69,.1);
  --cv-success:     #198754;
  --cv-success-sub: rgba(25,135,84,.1);
  --cv-warning:     #f59e0b;
  --cv-warning-sub: rgba(245,158,11,.1);

  /* navbar – always dark brand colour regardless of theme */
  --cv-nav-bg:      #16213e;
  --cv-nav-text:    #8fa8c8;
  --cv-nav-hover:   rgba(255,255,255,.08);

  /* selection */
  --cv-sel-bg:      #deeeff;

  /* KeePass sidebar – intentionally dark in both themes */
  --cv-kp-bg:       #1c2a3a;
  --cv-kp-mid:      #f0f2f5;
  --cv-kp-mid-bdr:  #dde1e7;

  /* shadows */
  --cv-shadow-sm:   0 1px 3px rgba(0,0,0,.05);
  --cv-shadow-md:   0 4px 16px rgba(0,0,0,.09);
  --cv-shadow-lg:   0 8px 40px rgba(0,0,0,.13);
}

[data-theme="dark"] {
  --cv-bg:          #0d1a2e;
  --cv-surface:     #162340;
  --cv-surface-2:   #1c2d4a;
  --cv-surface-3:   #1e3356;

  --cv-border:      #2a3f5f;
  --cv-border-2:    #3a5070;

  --cv-text:        #e6edf3;
  --cv-text-2:      #b8c8d8;
  --cv-text-3:      #8b9db5;
  --cv-text-4:      #4d6b8a;

  --cv-accent:      #58a6ff;
  --cv-accent-h:    #79b8ff;
  --cv-accent-sub:  rgba(88,166,255,.15);

  --cv-danger:      #f47067;
  --cv-danger-sub:  rgba(244,112,103,.15);
  --cv-success:     #3fb950;
  --cv-success-sub: rgba(63,185,80,.15);
  --cv-warning:     #e3b341;
  --cv-warning-sub: rgba(227,179,65,.15);

  --cv-sel-bg:      rgba(88,166,255,.16);

  --cv-kp-bg:       #0d1a2e;
  --cv-kp-mid:      #1c2d4a;
  --cv-kp-mid-bdr:  #2a3f5f;

  --cv-shadow-sm:   0 1px 3px rgba(0,0,0,.3);
  --cv-shadow-md:   0 4px 16px rgba(0,0,0,.45);
  --cv-shadow-lg:   0 8px 40px rgba(0,0,0,.6);
}

/* ── Reset / base ──────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html, body {
    font-family: 'Inter', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
    font-size: 14px;
    line-height: 1.5;
    color: var(--cv-text);
    background: var(--cv-bg);
    margin: 0;
    height: 100%;
}

/* ── Page shell ────────────────────────────────────────────────── */
.cv-page {
    display: flex;
    flex-direction: column;
    height: 100vh;
    overflow: hidden;
}

/* ── Navbar ────────────────────────────────────────────────────── */
.cv-navbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 52px;
    padding: 0 1.25rem;
    background: var(--cv-nav-bg);
    flex-shrink: 0;
    box-shadow: 0 1px 0 rgba(255,255,255,.05);
}

.cv-brand {
    display: flex;
    align-items: center;
    gap: .5rem;
    text-decoration: none;
    font-weight: 700;
    font-size: 1.05rem;
    color: #fff;
    letter-spacing: -.2px;
}
.cv-brand:hover { color: #a8d8ff; }
.cv-brand-icon {
    /* Bumped from 22px so the cloud logo carries more visual weight in
       the header. 52 px navbar - 30 px icon = 11 px top/bottom margin,
       still plenty of room above and below. Mobile uses 48 px height
       (-> 9 px top/bottom), still comfortable. */
    width: 30px;
    height: 30px;
    flex-shrink: 0;
}

.cv-navbar-right {
    display: flex;
    align-items: center;
    gap: .25rem;
}

/* Hamburger toggle — visible only at narrow viewports. The Web project
   ships this button; Desktop/Mobile hosts ignore it because their MAUI
   shell sizes never drop below the breakpoint. */
.cv-navbar-toggle {
    display: none;
    background: transparent;
    border: none;
    color: var(--cv-nav-text);
    padding: .35rem .4rem;
    cursor: pointer;
    border-radius: 6px;
    align-items: center;
    justify-content: center;
}
.cv-navbar-toggle:hover { background: var(--cv-nav-hover); color: #fff; }

/* Collapse the right-side icon row into a vertical dropdown below the
   navbar at narrow viewports. The dropdown is closed by default; the
   .cv-mobile-open class (added by MainLayout when the hamburger is
   tapped) reveals it. 900 px catches phones AND most tablet portraits
   so the user never has to horizontally scroll the navbar. */
@media (max-width: 900px) {
    .cv-navbar-toggle { display: inline-flex; }

    .cv-navbar-right {
        position: absolute;
        top: 52px;
        right: 0;
        left: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        padding: .5rem .75rem;
        background: var(--cv-nav-bg);
        border-top: 1px solid rgba(255,255,255,.08);
        box-shadow: 0 8px 16px rgba(0,0,0,.35);
        display: none;
        z-index: 1050;
    }
    .cv-navbar-right.cv-mobile-open { display: flex; }

    .cv-navbar-right .cv-btn,
    .cv-navbar-right .cv-btn-nav,
    .cv-navbar-right .cv-btn-outline,
    .cv-navbar-right .cv-btn-ghost {
        justify-content: flex-start;
        padding: .55rem .65rem;
        font-size: .9rem;
        width: 100%;
        border-radius: 6px;
    }
    .cv-navbar-right .cv-btn-nav.cv-nav-active::after { display: none; }
    .cv-navbar-right .cv-btn-nav.cv-nav-active {
        background: rgba(255,255,255,.12) !important;
    }
    .cv-navbar-right .cv-user-email {
        display: block;
        max-width: none;
        padding: .35rem .65rem .55rem;
        font-size: .82rem;
        border-bottom: 1px solid rgba(255,255,255,.08);
        margin-bottom: .35rem;
    }
}

/* Position-anchor for the dropdown — the navbar needs `position: relative`
   so the absolutely-positioned `.cv-navbar-right` slots underneath it. */
.cv-page > .cv-navbar { position: relative; }

/* Per-icon text label. Hidden on the desktop navbar (icons + tooltips
   carry the meaning there) but revealed inside the mobile dropdown so
   tap targets are tall enough and self-describing without hovering. */
.cv-nav-label { display: none; }
@media (max-width: 900px) {
    .cv-navbar-right.cv-mobile-open .cv-nav-label {
        display: inline;
        margin-left: .55rem;
    }
}

.cv-user-email {
    color: var(--cv-nav-text);
    font-size: .8rem;
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0 .5rem;
}

/* ── Navbar buttons ───────────────────────────────────────────── */
.cv-btn {
    border: none;
    border-radius: 6px;
    padding: .3rem .6rem;
    font-size: .8rem;
    font-weight: 500;
    cursor: pointer;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    transition: background .15s, color .15s;
}
.cv-btn-ghost {
    background: transparent;
    color: var(--cv-nav-text);
}
.cv-btn-ghost:hover { background: var(--cv-nav-hover); color: #fff; }
.cv-btn-outline {
    background: transparent;
    color: var(--cv-nav-text);
    border: 1px solid rgba(255,255,255,.18);
}
.cv-btn-outline:hover { background: var(--cv-nav-hover); color: #fff; border-color: rgba(255,255,255,.38); }

/* Nav icon buttons – active indicator */
.cv-btn-nav { position: relative; }
.cv-btn-nav.cv-nav-active { color: #fff !important; background: rgba(255,255,255,.1) !important; }
.cv-btn-nav.cv-nav-active::after {
    content: '';
    position: absolute;
    bottom: -2px;
    left: 50%;
    transform: translateX(-50%);
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--cv-accent);
}

/* Theme-toggle sun/moon icon */
.cv-theme-btn { font-size: .88rem; }

/* ═══════════════════════════════════════════════════════════════════
   Settings — left-nav layout
   ═══════════════════════════════════════════════════════════════════ */

.settings-layout {
    display: flex;
    flex: 1;
    min-height: 0;
    overflow: hidden;
    background: var(--cv-bg);
}

.settings-nav {
    width: 220px;
    flex-shrink: 0;
    background: var(--cv-surface);
    border-right: 1px solid var(--cv-border);
    display: flex;
    flex-direction: column;
    padding: .75rem 0;
    overflow-y: auto;
}

.settings-nav-title {
    padding: .25rem 1rem .75rem;
    font-size: 1rem;
    font-weight: 700;
    color: var(--cv-text);
    letter-spacing: -.2px;
}

.settings-nav-item {
    display: flex;
    align-items: center;
    gap: .65rem;
    width: 100%;
    padding: .55rem 1rem;
    background: transparent;
    border: none;
    border-left: 3px solid transparent;
    text-align: left;
    color: var(--cv-text-2);
    font-size: .9rem;
    cursor: pointer;
    transition: background .12s, color .12s, border-color .12s;
}
.settings-nav-item:hover { background: var(--cv-surface-3); color: var(--cv-text); }

.settings-nav-item-active {
    background: var(--cv-accent-sub);
    color: var(--cv-accent);
    border-left-color: var(--cv-accent);
    font-weight: 600;
}

.settings-nav-icon {
    display: inline-flex;
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}
.settings-nav-icon svg { width: 18px; height: 18px; }

.settings-content {
    flex: 1;
    min-width: 0;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    background: var(--cv-bg);
}

/* settings-content-inner explicitly spans the full width of the parent
   AND uses a flex column with align-items:center so every child is
   horizontally centred — independent of margin overrides from Bootstrap. */
.settings-content-inner {
    width: 100%;
    padding: 1.5rem 2rem 4rem;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* Each direct content block (section title, card, alert) takes a
   guaranteed width and max-width — flex auto-min-content would otherwise
   shrink them. */
.settings-content-inner > * {
    width: 100%;
    max-width: 720px;
    flex-shrink: 0;
}

.settings-section-title {
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--cv-text);
    letter-spacing: -.2px;
    margin: 0 0 1.25rem;
}

/* Responsive: stack nav on top on narrow viewports */
@media (max-width: 720px) {
    .settings-layout { flex-direction: column; }
    .settings-nav {
        width: 100%;
        max-height: 180px;
        border-right: none;
        border-bottom: 1px solid var(--cv-border);
        flex-direction: row;
        flex-wrap: wrap;
        padding: .5rem;
    }
    .settings-nav-title { width: 100%; padding-bottom: .25rem; }
    .settings-nav-item {
        width: auto;
        border-left: none;
        border-bottom: 2px solid transparent;
        padding: .45rem .75rem;
    }
    .settings-nav-item-active {
        border-left: none;
        border-bottom-color: var(--cv-accent);
    }
    .settings-content-inner { padding: 1rem; }
}


/* ── Files-on-Demand tree picker (Settings → Storage) ────────────── */
.fod-tree-wrap {
    border: 1px solid var(--cv-border);
    border-radius: 8px;
    background: var(--cv-surface);
    padding: .25rem 0;
    /* No overflow here on purpose — let the surrounding settings-content do
       the scrolling so the mouse wheel never gets stuck on a leaf container
       that has nothing to scroll. */
}
.fod-row {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .3rem .6rem;
    font-size: .82rem;
    border-bottom: 1px solid rgba(0,0,0,.03);
    color: var(--cv-text);
    position: relative;
}
[data-theme="dark"] .fod-row { border-bottom-color: rgba(255,255,255,.04); }
.fod-row:hover { background: var(--cv-surface-3); }
.fod-row-clickable { cursor: pointer; }
.fod-row-empty { cursor: default; }
.fod-row-empty:hover { background: transparent; }

.fod-chevron {
    display: inline-flex;
    width: 1rem;
    justify-content: center;
    color: var(--cv-text-3);
    font-size: .7rem;
    flex-shrink: 0;
}
.fod-icon { flex-shrink: 0; font-size: 1rem; }
.fod-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Custom dropdown — replaces the native <select> which renders the popup
   outside the WebView2 window (visible "flying" off to the side of the
   desktop). This stays inside the document, anchored directly below the
   trigger button. */
.fod-policy-wrap { position: relative; flex-shrink: 0; }

.fod-policy-btn {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border-2);
    border-radius: 6px;
    padding: .2rem .55rem;
    font-size: .78rem;
    color: var(--cv-text-2);
    cursor: pointer;
    min-width: 175px;
    justify-content: space-between;
    transition: border-color .12s, background .12s;
}
.fod-policy-btn:hover { border-color: var(--cv-accent); }
.fod-policy-caret { font-size: .65rem; color: var(--cv-text-3); }

.fod-policy-btn-online { background: rgba(13,110,253,.08); border-color: rgba(13,110,253,.35); color: var(--cv-accent); }
.fod-policy-btn-local  { background: rgba(25,135,84,.10); border-color: rgba(25,135,84,.35);  color: var(--cv-success); }
.fod-policy-btn-inherit { /* default — neutral colours */ }

[data-theme="dark"] .fod-policy-btn-online { background: rgba(88,166,255,.12); border-color: rgba(88,166,255,.4); }
[data-theme="dark"] .fod-policy-btn-local  { background: rgba(63,185,80,.12);  border-color: rgba(63,185,80,.4);  }

.fod-policy-menu {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    z-index: 100;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border-2);
    border-radius: 8px;
    box-shadow: var(--cv-shadow-md);
    padding: .25rem;
    min-width: 200px;
    display: flex;
    flex-direction: column;
}

.fod-policy-menu-item {
    display: flex;
    align-items: center;
    gap: .5rem;
    width: 100%;
    background: transparent;
    border: none;
    padding: .4rem .55rem;
    font-size: .82rem;
    color: var(--cv-text);
    text-align: left;
    cursor: pointer;
    border-radius: 4px;
    transition: background .1s;
}
.fod-policy-menu-item:hover { background: var(--cv-surface-3); }

.fod-policy-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}
.fod-dot-inherit { background: var(--cv-text-4); }
.fod-dot-online  { background: var(--cv-accent); }
.fod-dot-local   { background: var(--cv-success); }


/* "Back to Vault" pill shown in the navbar when we're anywhere except
   the vault page itself. Subdued accent style — present but not loud. */
.cv-btn-back {
    color: #fff !important;
    background: rgba(255,255,255,.08) !important;
    padding: .3rem .65rem !important;
    margin-left: .4rem;
    border: 1px solid rgba(255,255,255,.1);
}
.cv-btn-back:hover { background: rgba(255,255,255,.16) !important; }

/* Conflict-tray warning pill in the navbar */
.cv-conflict-pill {
    color: var(--cv-warning) !important;
    background: rgba(245, 158, 11, .15) !important;
    padding: .3rem .6rem !important;
}
.cv-conflict-pill:hover { background: rgba(245, 158, 11, .28) !important; color: #fff !important; }
.cv-conflict-count {
    font-weight: 700;
    font-size: .78rem;
    margin-left: .25rem;
}

/* ── Body / content area ───────────────────────────────────────── */
.cv-body {
    /* The body is a flex column container. It DOES NOT scroll itself —
       inner layouts either provide their own scroll (vault-layout,
       kp-page-wrap, notes-layout, auth-page) or wrap their content in
       .cv-scroll-page which takes the scroll role. Letting both .cv-body
       and an inner scroller compete creates nested scroll regions that
       interrupt the mouse wheel mid-page. */
    flex: 1;
    min-height: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* Generic scrollable page wrapper for linear-content pages (Settings,
   Admin, ActivityLog, …). Pages with their own internal layout (vault,
   keepass, notes, auth) skip this. */
.cv-scroll-page {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    background: var(--cv-bg);
}

/* Hide Edge / IE built-in password reveal & clear buttons — they duplicate
   our custom show/hide eye toggle on .auth-pw-toggle. */
input::-ms-reveal,
input::-ms-clear { display: none; }

/* Number inputs were stealing the wheel event over them (scrolling
   incremented the number instead of the page). Disable spinner + wheel
   so the wheel reliably scrolls the surrounding container. */
input[type="number"] {
    -moz-appearance: textfield;
    appearance: textfield;
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* ── Vault layout (sidebar + content) ─────────────────────────── */
.vault-layout {
    display: flex;
    flex: 1;
    overflow: hidden;
}

.vault-sidebar {
    width: 260px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    background: var(--cv-surface);
    border-right: 1px solid var(--cv-border);
    overflow: hidden;
}

.sidebar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .75rem 1rem;
    border-bottom: 1px solid var(--cv-border);
    flex-shrink: 0;
    font-size: .85rem;
    background: var(--cv-surface);
}

.sidebar-body {
    flex: 1;
    overflow-y: auto;
    padding: .5rem 0;
}

/* ── Shared-with-me sidebar section ───────────────────────────── */
.sidebar-shared-header {
    display: flex;
    align-items: center;
    gap: .35rem;
    padding: .5rem 1rem;
    font-size: .8rem;
    font-weight: 600;
    color: var(--cv-text-3);
    border-top: 1px solid var(--cv-border);
    cursor: pointer;
    user-select: none;
    background: var(--cv-surface-2);
    flex-shrink: 0;
}
.sidebar-shared-header:hover { background: var(--cv-surface-3); }
.shared-chevron { margin-left: auto; font-size: .65rem; opacity: .6; }
.sidebar-manage-btn {
    font-size: .75rem; color: var(--cv-text-3); text-decoration: none;
    padding: .1rem .3rem; border-radius: 3px;
}
.sidebar-manage-btn:hover { background: var(--cv-border); color: var(--cv-text); }

.sidebar-shared-body {
    max-height: 260px;
    overflow-y: auto;
    padding: .25rem 0;
    background: var(--cv-surface-2);
    border-top: none;
    flex-shrink: 0;
}

.shared-folder-row {
    display: flex;
    align-items: center;
    gap: .3rem;
    padding: .3rem .75rem;
    font-size: .8rem;
    cursor: pointer;
    border-radius: 4px;
    margin: 0 .25rem;
    color: var(--cv-text-2);
}
.shared-folder-row:hover { background: var(--cv-surface-3); }
.shared-folder-row.open  { background: var(--cv-border); font-weight: 600; color: var(--cv-text); }
.shared-folder-row .name {
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.vault-content {
    flex: 1;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    background: var(--cv-bg);
}

.content-section {
    padding: 1.5rem;
    flex: 1;
}

.content-empty {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ── File tree ─────────────────────────────────────────────────── */
/* min-height:100% makes the tree fill the sidebar-body so the drop
   overlay covers the whole sidebar area, not just the rendered nodes.
   Without it, a near-empty vault would have a tiny drop target hugging
   the home row + handful of folders. box-sizing:border-box keeps the
   100% reaching the parent's edges despite our own padding. */
.file-tree {
    font-size: .85rem;
    min-height: 100%;
    box-sizing: border-box;
}

/* Home row sits above the tree-list. Looks like a regular folder
   label so it visually anchors the tree, but it's a hardcoded
   drop target for the vault root and clicking it tells the host
   to navigate the central pane back to home. */
.file-tree-home {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .45rem 1rem;
    cursor: pointer;
    user-select: none;
    transition: background .1s;
    color: var(--cv-text);
    border-radius: 0;
}
.file-tree-home:hover    { background: var(--cv-surface-3); }
.file-tree-home.selected { background: var(--cv-surface-3); font-weight: 600; }
.file-tree-home .icon    { font-size: 1rem; }

/* Drag-over visual for the tree-drop layer (see tree-drop.js).
   Applied to either the .file-tree root (root drop = vault root) or a
   .folder-node <li> (drop into that folder). Pointer-events:none on
   ::before keeps the overlay from intercepting drag events that would
   otherwise toggle the highlight off mid-drag. */
.file-tree.cv-drop-target,
.folder-node.cv-drop-target {
    position: relative;
    background: rgba(13, 110, 253, 0.06);
    border-radius: .25rem;
}
.file-tree.cv-drop-target::before,
.folder-node.cv-drop-target::before {
    content: "";
    position: absolute;
    inset: 2px;
    border: 2px dashed var(--bs-primary, #0d6efd);
    border-radius: .25rem;
    pointer-events: none;
    z-index: 1;
}

.tree-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.tree-node {
    cursor: pointer;
    border-radius: 0;
    user-select: none;
}

.folder-label,
.file-node {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .45rem 1rem;
    transition: background .1s;
    white-space: nowrap;
    color: var(--cv-text);
}
.folder-label:hover,
.file-node:hover { background: var(--cv-surface-3); }

.file-node.selected,
.file-node:focus {
    background: var(--cv-sel-bg);
    font-weight: 500;
    border-left: 2px solid var(--cv-accent);
    padding-left: calc(1rem - 2px);
}

.tree-node .icon { flex-shrink: 0; font-style: normal; }
.tree-node .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; color: var(--cv-text); }
.tree-node .size  { color: var(--cv-text-4); font-size: .75rem; flex-shrink: 0; }

/* ── File extension badge (P7) ─────────────────────────────────── */
.file-ext-badge {
    font-size: .57rem;
    font-weight: 700;
    padding: .08rem .28rem;
    border-radius: 3px;
    text-transform: uppercase;
    letter-spacing: .03em;
    min-width: 2.1em;
    text-align: center;
    flex-shrink: 0;
    font-family: 'Consolas', 'Courier New', monospace;
    background: var(--cv-surface-3);
    color: var(--cv-text-3);
    border: 1px solid var(--cv-border);
    line-height: 1.65;
    display: inline-block;
}

/* image types */
.fext-img { background: #e8f0fe; color: #1a56db; border-color: #c3d9fe; }
/* documents */
.fext-doc { background: #fff3e0; color: #c35e00; border-color: #ffd9a0; }
/* archives */
.fext-zip { background: #fef9e7; color: #9e6800; border-color: #fde69c; }
/* media */
.fext-vid { background: #f3e8ff; color: #7c3aed; border-color: #d8b4fe; }
/* pdf */
.fext-pdf { background: #fee2e2; color: #dc2626; border-color: #fca5a5; }
/* code / text */
.fext-code { background: #ecfdf5; color: #059669; border-color: #a7f3d0; }

[data-theme="dark"] .fext-img  { background: rgba(26,86,219,.2);   color: #93c5fd; border-color: rgba(147,197,253,.25); }
[data-theme="dark"] .fext-doc  { background: rgba(195,94,0,.2);    color: #fdba74; border-color: rgba(253,186,116,.25); }
[data-theme="dark"] .fext-zip  { background: rgba(158,104,0,.2);   color: #fde68a; border-color: rgba(253,230,138,.25); }
[data-theme="dark"] .fext-vid  { background: rgba(124,58,237,.2);  color: #c4b5fd; border-color: rgba(196,181,253,.25); }
[data-theme="dark"] .fext-pdf  { background: rgba(220,38,38,.2);   color: #fca5a5; border-color: rgba(252,165,165,.25); }
[data-theme="dark"] .fext-code { background: rgba(5,150,105,.2);   color: #6ee7b7; border-color: rgba(110,231,183,.25); }

/* tree action buttons */
.file-node-actions,
.folder-actions {
    display: flex;
    align-items: center;
    gap: .1rem;
    flex-shrink: 0;
    margin-left: .25rem;
    opacity: 0;
    transition: opacity .12s;
}
.file-node:hover .file-node-actions,
.folder-node > .folder-label:hover .folder-actions,
.file-node-actions:focus-within,
.folder-actions:focus-within { opacity: 1; }

.file-action-btn,
.folder-action-btn {
    color: var(--cv-text-3);
    font-size: .8rem;
    line-height: 1;
    padding: 0 .2rem !important;
    text-decoration: none;
    transition: color .1s;
}
.file-action-btn:hover { color: var(--cv-accent) !important; }
.folder-action-btn:hover { color: var(--cv-accent) !important; }
.file-action-btn.file-action-danger:hover,
.folder-action-btn.folder-action-danger:hover { color: var(--cv-danger) !important; }

/* Inline rename / create input inside tree nodes */
.tree-inline-input {
    font-size: .8rem;
    padding: .1rem .35rem;
    border: 1px solid var(--cv-accent);
    border-radius: 4px;
    outline: none;
    min-width: 0;
    width: 130px;
    flex-shrink: 1;
    background: var(--cv-surface);
    color: var(--cv-text);
}
.tree-inline-row {
    display: flex;
    align-items: center;
    gap: .25rem;
}

/* ── File detail panel ─────────────────────────────────────────── */
.file-detail-header {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.5rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--cv-border);
}

.file-icon-lg { font-size: 2.5rem; line-height: 1; }

.file-detail-info { min-width: 0; }

.file-action-bar {
    display: flex;
    gap: .75rem;
    flex-wrap: wrap;
}

/* ── File detail sheet (overlay container) ───────────────────────────
   The .fd-sheet element wraps the file detail content. On desktop it
   absolute-positions over the grid pane to take it over completely;
   on mobile it slides up from the bottom as a 75 vh sheet so the grid
   stays visible behind a backdrop. The detail INNER content
   (file-detail-v2 below) is the same in both modes -- only the
   positioning/visibility changes. */
.fd-backdrop { display: none; }

.fd-sheet {
    /* Desktop default: fills the vault-content pane via the existing
       .content-section flex sizing. No special positioning needed --
       the grid sibling is hidden via .vault-grid-area--has-detail.  */
    display: block;
}

.vault-grid-area--has-detail { display: none; }

@media (max-width: 768px) {
    /* Mobile: detail becomes a bottom sheet, grid stays visible above. */
    .vault-grid-area--has-detail { display: block; }

    .fd-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, .55);
        z-index: 1040;
        animation: fd-backdrop-in .18s ease-out;
    }

    .fd-sheet {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        top: auto;
        max-height: 85vh;
        background: var(--cv-bg);
        border-top-left-radius: 18px;
        border-top-right-radius: 18px;
        z-index: 1050;
        overflow-y: auto;
        padding: 1.25rem 1rem 1.5rem;
        box-shadow: 0 -14px 36px rgba(0, 0, 0, .45);
        animation: fd-sheet-up .24s cubic-bezier(.16, 1, .3, 1);
    }
    /* Decorative drag handle. Not actually draggable -- the user closes
       the sheet by tapping outside, the ✕ button, or the back button. */
    .fd-sheet::before {
        content: '';
        display: block;
        width: 40px;
        height: 4px;
        margin: -.25rem auto .75rem;
        background: rgba(255, 255, 255, .2);
        border-radius: 999px;
    }
}

@keyframes fd-backdrop-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes fd-sheet-up {
    from { transform: translateY(100%); }
    to   { transform: translateY(0); }
}

/* ── File detail panel V2 (redesign) ───────────────────────────────
   Splits the page into three stacked regions:
     1. header (name + close)                                            full width
     2. preview tile (1fr) | actions stack (1.4fr)                       grid row
     3. properties block                                                 full width
   On viewports under 720 px the grid collapses to one column so the
   tile sits above the actions. */
.file-detail-v2 {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.fd-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--cv-border);
}
.fd-title { min-width: 0; flex: 1; }
.fd-name {
    margin: 0 0 .35rem 0;
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--cv-text);
    overflow-wrap: anywhere;
}
.fd-meta { color: var(--cv-text-muted); font-size: .9rem; }
.fd-close-btn {
    background: transparent;
    border: 1px solid var(--cv-border);
    color: var(--cv-text-muted);
    border-radius: 8px;
    width: 36px;
    height: 36px;
    cursor: pointer;
    font-size: 1.05rem;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background .12s, color .12s, border-color .12s;
}
.fd-close-btn:hover {
    background: var(--cv-hover, rgba(255,255,255,.04));
    color: var(--cv-text);
    border-color: var(--cv-text-muted);
}

.fd-grid {
    display: grid;
    grid-template-columns: minmax(220px, 280px) 1fr;
    gap: 1.5rem;
    align-items: stretch;
}
@media (max-width: 720px) {
    .fd-grid { grid-template-columns: 1fr; }
}

.fd-preview {
    background: var(--cv-card-bg, rgba(255,255,255,.03));
    border: 1px solid var(--cv-border);
    border-radius: 14px;
    aspect-ratio: 1 / 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .8rem;
    padding: 1rem;
    text-align: center;
}
.fd-preview-icon { font-size: 5.5rem; line-height: 1; }
.fd-preview-ext {
    padding: .25rem .7rem;
    background: rgba(255,255,255,.06);
    border: 1px solid var(--cv-border);
    border-radius: 6px;
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: 1px;
    color: var(--cv-text-muted);
}
.fd-preview-cta {
    background: transparent;
    border: 1px solid var(--cv-border);
    color: var(--cv-text);
    padding: .35rem .8rem;
    border-radius: 999px;
    font-size: .82rem;
    cursor: pointer;
    margin-top: .25rem;
}
.fd-preview-cta:hover { background: rgba(255,255,255,.05); }
.fd-preview-cta:disabled { opacity: .5; cursor: not-allowed; }

.fd-actions {
    display: flex;
    flex-direction: column;
    gap: .45rem;
    min-width: 0;
}
.fd-action {
    display: flex;
    align-items: center;
    gap: .8rem;
    justify-content: flex-start;
    padding: .65rem .9rem;
    width: 100%;
    text-align: left;
    font-size: .92rem;
    background: var(--cv-card-bg, rgba(255,255,255,.03));
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    color: var(--cv-text);
    cursor: pointer;
    transition: background .12s, border-color .12s, transform .04s;
}
.fd-action:hover { background: rgba(255,255,255,.06); border-color: var(--cv-text-muted); }
.fd-action:active { transform: translateY(1px); }
.fd-action:disabled { opacity: .5; cursor: not-allowed; }
.fd-action-icon {
    width: 1.5rem;
    text-align: center;
    font-size: 1.05rem;
    flex-shrink: 0;
}
.fd-action-label { flex: 1; }

.fd-action-primary {
    background: var(--cv-accent, #3b82f6);
    border-color: var(--cv-accent, #3b82f6);
    color: #fff;
}
.fd-action-primary:hover {
    background: var(--cv-accent-hover, #2563eb);
    border-color: var(--cv-accent-hover, #2563eb);
}

.fd-action-danger { color: #f06a6a; }
.fd-action-danger:hover {
    background: rgba(240, 106, 106, .12);
    border-color: #f06a6a;
    color: #ff8a8a;
}

.fd-action-divider {
    height: 1px;
    background: var(--cv-border);
    margin: .35rem 0;
}

.fd-properties {
    background: var(--cv-card-bg, rgba(255,255,255,.03));
    border: 1px solid var(--cv-border);
    border-radius: 14px;
    padding: 1rem 1.25rem;
}
.fd-properties-title {
    font-size: .8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .8px;
    color: var(--cv-text-muted);
    margin-bottom: .65rem;
}
.fd-property-row {
    display: grid;
    grid-template-columns: 160px 1fr;
    gap: 1rem;
    padding: .5rem 0;
    border-bottom: 1px solid var(--cv-border);
    align-items: center;
    font-size: .9rem;
}
.fd-property-row:last-child { border-bottom: none; }
.fd-property-label { color: var(--cv-text-muted); }
.fd-property-value {
    color: var(--cv-text);
    overflow-wrap: anywhere;
}
.fd-property-mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .82rem;
}
@media (max-width: 540px) {
    .fd-property-row {
        grid-template-columns: 1fr;
        gap: .15rem;
    }
}

/* ── Drop zone (P4 — modernised) ───────────────────────────────── */
.drop-zone {
    border: 1.5px solid var(--cv-border);
    border-radius: 12px;
    background: var(--cv-surface);
    transition: border-color .2s, background .2s, box-shadow .2s;
    padding: 2.5rem 1.5rem;
    text-align: center;
    width: 100%;
    max-width: 600px;
    margin: 0 auto;
    cursor: pointer;
}

.drop-zone:hover {
    border-color: var(--cv-accent);
    background: var(--cv-accent-sub);
    box-shadow: 0 0 0 4px var(--cv-accent-sub);
}

.drop-zone.dragging {
    border-color: var(--cv-accent);
    background: var(--cv-accent-sub);
    box-shadow: 0 0 0 4px var(--cv-accent-sub);
}

.drop-zone-inner { pointer-events: auto; }

.drop-icon {
    font-size: 2.5rem;
    line-height: 1;
    margin-bottom: .75rem;
    display: block;
    transition: transform .22s cubic-bezier(.34,1.56,.64,1);
}
.drop-zone:hover .drop-icon,
.drop-zone.dragging .drop-icon {
    transform: translateY(-5px);
}

.upload-list {
    text-align: left;
    pointer-events: auto;
}

/* ── Floating upload-progress panel (tree-drop + drop-zone + …) ─── */
.upload-panel {
    position: fixed;
    right: 1.25rem;
    bottom: 1.25rem;
    width: 360px;
    max-width: calc(100vw - 2rem);
    max-height: 70vh;
    display: flex;
    flex-direction: column;
    background: var(--cv-surface);
    color: var(--cv-text);
    border: 1px solid var(--cv-border);
    border-radius: 12px;
    box-shadow: var(--cv-shadow-lg);
    z-index: 1080;
    overflow: hidden;
    font-size: .875rem;
}

.upload-panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .625rem .875rem;
    background: var(--cv-surface-muted, rgba(0, 0, 0, .04));
    border-bottom: 1px solid var(--cv-border);
}

.upload-panel-title {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    font-weight: 600;
}

.upload-spinner {
    width: 14px;
    height: 14px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: cv-upload-spin .8s linear infinite;
}

@keyframes cv-upload-spin {
    to { transform: rotate(360deg); }
}

.upload-panel-clear {
    border: 0;
    background: transparent;
    color: var(--cv-text-muted, #6c757d);
    font-size: .8rem;
    cursor: pointer;
    padding: .125rem .375rem;
    border-radius: 4px;
}

.upload-panel-clear:hover {
    background: rgba(0, 0, 0, .06);
    color: var(--cv-text);
}

.upload-panel-list {
    overflow-y: auto;
    padding: .375rem .5rem .5rem;
}

.upload-row {
    padding: .5rem .375rem;
    border-radius: 6px;
}

.upload-row + .upload-row {
    margin-top: .25rem;
    border-top: 1px solid var(--cv-border);
    padding-top: .625rem;
}

.upload-row.is-error  { background: rgba(220, 53, 69, .06); }
.upload-row.is-done   { background: rgba(25, 135, 84, .05); }

.upload-row-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
}

.upload-row-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
}

.upload-row-pct {
    font-variant-numeric: tabular-nums;
    color: var(--cv-text-muted, #6c757d);
    font-size: .8rem;
}

.upload-row-dismiss {
    border: 0;
    background: transparent;
    color: var(--cv-text-muted, #6c757d);
    cursor: pointer;
    font-size: .9rem;
    line-height: 1;
    padding: 0 .25rem;
}

.upload-row-dismiss:hover {
    color: #dc3545;
}

.upload-row-bar {
    height: 4px;
    background: rgba(0, 0, 0, .08);
    border-radius: 2px;
    margin-top: .375rem;
    overflow: hidden;
}

.upload-row-fill {
    height: 100%;
    background: linear-gradient(90deg, #4f8cff, #1e6bff);
    transition: width .2s ease-out;
}

.upload-row.is-done .upload-row-fill  { background: #198754; }
.upload-row.is-error .upload-row-fill { background: #dc3545; }

.upload-row-meta {
    margin-top: .25rem;
    font-size: .75rem;
    color: var(--cv-text-muted, #6c757d);
}

.upload-row-error {
    color: #dc3545;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: inline-block;
    max-width: 100%;
}

/* ── Vault unlock page ─────────────────────────────────────────── */
.vault-unlock-box {
    max-width: 380px;
    margin: 0 auto;
    padding: 2rem;
    background: var(--cv-surface);
    border-radius: 12px;
    box-shadow: var(--cv-shadow-lg);
}

.vault-lock-icon {
    font-size: 2.5rem;
    margin-bottom: .5rem;
}

/* ── Auth page & card ──────────────────────────────────────────── */
.auth-page {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 0;
    padding: 2rem 1rem;
    overflow-y: auto;
    background: var(--cv-bg);
}

/* Auth shell: stacks the optional server-URL picker (native hosts) above the
   credential card, both sharing one max-width so they align. */
.auth-shell {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    width: 100%;
    max-width: 440px;
}

/* Compact server-URL picker card — shares the card visual language but stays
   subordinate to the sign-in card below it. */
.server-picker-float {
    width: 100%;
    display: flex;
    align-items: center;
    gap: .6rem;
    flex-wrap: wrap;
    padding: .7rem .95rem;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 12px;
    box-shadow: var(--cv-shadow-md);
}
.server-picker-label {
    flex-shrink: 0;
    font-size: .68rem;
    font-weight: 700;
    color: var(--cv-text-3);
    text-transform: uppercase;
    letter-spacing: .6px;
}
.server-picker-url {
    flex: 1;
    min-width: 0;
    font-size: .8rem;
    color: var(--cv-text-2);
    word-break: break-all;
    line-height: 1.35;
}

.auth-card {
    background: var(--cv-surface);
    border-radius: 16px;
    box-shadow: var(--cv-shadow-lg);
    overflow: hidden;
    max-width: 440px;
    width: 100%;
}

/* brand header – always dark navy gradient (identity anchor) */
.auth-card-header {
    background: linear-gradient(135deg, #16213e 0%, #0f3460 100%);
    padding: 2rem 2rem 1.75rem;
    text-align: center;
}

.auth-logo {
    width: 56px;
    height: 56px;
    margin: 0 auto .85rem;
    display: block;
    filter: drop-shadow(0 2px 6px rgba(0,0,0,.4));
}
/* legacy: if auth-logo is rendered as a text emoji span */
span.auth-logo { font-size: 2.75rem; line-height: 1; width: auto; height: auto; }

.auth-title {
    color: #fff;
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -.3px;
    margin-bottom: .3rem;
}

.auth-subtitle {
    color: #8fa8c8;
    font-size: .82rem;
}

.auth-card-body {
    padding: 2rem 2.25rem 2.25rem;
}

.auth-field {
    margin-bottom: 1.1rem;
}

.auth-label {
    display: block;
    font-size: .72rem;
    font-weight: 700;
    color: var(--cv-text-3);
    margin-bottom: .35rem;
    text-transform: uppercase;
    letter-spacing: .6px;
}

/* password field wrapper for show/hide toggle */
.auth-pw-wrap {
    position: relative;
    display: flex;
    align-items: center;
}
.auth-pw-wrap .form-control.auth-input { padding-right: 2.4rem; }
.auth-pw-toggle {
    position: absolute;
    right: .6rem;
    background: none;
    border: none;
    cursor: pointer;
    padding: .2rem;
    color: var(--cv-text-3);
    line-height: 1;
    font-size: .85rem;
    border-radius: 3px;
    transition: color .1s;
    display: flex;
    align-items: center;
}
.auth-pw-toggle:hover { color: var(--cv-text); }

.auth-input.form-control {
    border-radius: 8px;
    border: 1.5px solid var(--cv-border);
    padding: .7rem .9rem;
    font-size: .92rem;
    transition: border-color .15s, box-shadow .15s;
    background: var(--cv-surface);
    color: var(--cv-text);
}
.auth-input.form-control:focus {
    border-color: var(--cv-accent);
    box-shadow: 0 0 0 3px var(--cv-accent-sub);
    background: var(--cv-surface);
    color: var(--cv-text);
}
.auth-input.form-control::placeholder { color: var(--cv-text-4); }

.auth-input-otp {
    font-size: 1.5rem !important;
    letter-spacing: .4rem;
    font-weight: 600;
    font-family: monospace;
}

/* Change-password form (settings) — constrain width so the fields read as a
   compact form rather than stretching across a wide settings panel. Reuses the
   auth-field/auth-label/auth-input styling for visual consistency with login. */
.cv-pw-form {
    max-width: 380px;
}
.cv-pw-form .auth-field { margin-bottom: .9rem; }

.auth-remember {
    margin-bottom: 1.25rem;
    font-size: .85rem;
    color: var(--cv-text-3);
}

.auth-submit {
    width: 100%;
    padding: .7rem;
    border-radius: 8px !important;
    font-size: .95rem;
    font-weight: 600;
    letter-spacing: .2px;
    margin-top: .25rem;
}

/* ── Utility ───────────────────────────────────────────────────── */
a, .btn-link { color: var(--cv-accent); }

#blazor-error-ui {
    background: #fffbe6;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0,0,0,.15);
    display: none;
    left: 0;
    padding: .5rem 1rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
    font-size: .85rem;
}
#blazor-error-ui .dismiss { cursor: pointer; float: right; }
[data-theme="dark"] #blazor-error-ui { background: #2a1a00; color: var(--cv-text); }

.blazor-error-boundary {
    background: #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
    border-radius: 4px;
}
.blazor-error-boundary::after { content: "An error has occurred."; }

.loading-progress {
    position: absolute;
    display: block;
    width: 6rem;
    height: 6rem;
    inset: 25vh 0 auto 0;
    margin: 0 auto;
}
.loading-progress circle {
    fill: none;
    stroke: #e0e0e0;
    stroke-width: .6rem;
    transform-origin: 50% 50%;
    transform: rotate(-90deg);
}
.loading-progress circle:last-child {
    stroke: var(--cv-accent);
    stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * .8), 500%;
    transition: stroke-dasharray .05s ease-in-out;
}
.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(25vh + 3rem) 0 auto .2rem;
}
.loading-progress-text::after { content: var(--blazor-load-percentage-text, "Loading"); }

/* ── Utility helpers ───────────────────────────────────────────── */
.flex-1  { flex: 1; }
.flex-2  { flex: 2; }
.w-100   { width: 100%; }
.mt-1    { margin-top: .25rem; }
.mt-2    { margin-top: .5rem; }
.mt-3    { margin-top: 1rem; }
.gap-2   { gap: .5rem; }
.justify-content-center { justify-content: center; }


/* ═══════════════════════════════════════════════════════════════════
   Toast notifications (P6 – typed left-border variants)
   ═══════════════════════════════════════════════════════════════════ */

.toast {
    border-left: 3px solid transparent;
    background: var(--cv-surface);
    color: var(--cv-text);
    border-color: var(--cv-border);
    box-shadow: var(--cv-shadow-md);
}
.toast-header {
    background: var(--cv-surface-2);
    color: var(--cv-text);
    border-bottom: 1px solid var(--cv-border);
}
.toast-body { color: var(--cv-text-2); }

.toast-success { border-left-color: var(--cv-success) !important; }
.toast-danger  { border-left-color: var(--cv-danger)  !important; }
.toast-warning { border-left-color: var(--cv-warning) !important; }
.toast-info    { border-left-color: var(--cv-accent)  !important; }

.toast-icon {
    margin-right: .35rem;
    font-size: .9em;
    flex-shrink: 0;
}


/* ═══════════════════════════════════════════════════════════════════
   KeePass / KDBX Password Manager UI
   ═══════════════════════════════════════════════════════════════════ */

/* ── Page wrapper ──────────────────────────────────────────────────── */
.kp-page-wrap {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
}

.kp-page-toolbar {
    display: flex;
    align-items: center;
    gap: .75rem;
    height: 40px;
    padding: 0 1rem;
    background: var(--cv-surface);
    border-bottom: 1px solid var(--cv-border);
    flex-shrink: 0;
}

.kp-toolbar-filename {
    font-size: .8rem;
    color: var(--cv-text-3);
    font-family: monospace;
}

/* ── 3-column browser ──────────────────────────────────────────────── */
.kp-browser {
    display: flex;
    flex: 1;
    overflow: hidden;
}

/* ── Left sidebar (group tree) — always dark navy ──────────────────── */
.kp-sidebar {
    width: 220px;
    flex-shrink: 0;
    background: var(--cv-kp-bg);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.kp-sidebar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .75rem 1rem;
    border-bottom: 1px solid rgba(255,255,255,.08);
    flex-shrink: 0;
}

.kp-sidebar-title {
    color: #c8d8ea;
    font-size: .85rem;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kp-save-btn {
    background: transparent;
    border: 1px solid rgba(255,255,255,.2);
    color: #8fa8c8;
    border-radius: 5px;
    padding: .2rem .5rem;
    font-size: .75rem;
    cursor: pointer;
    white-space: nowrap;
    flex-shrink: 0;
}
.kp-save-btn:hover { background: rgba(255,255,255,.08); color: #fff; }

.kp-group-tree {
    flex: 1;
    overflow-y: auto;
    padding: .4rem 0;
}

.kp-group-item {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .45rem 1rem;
    cursor: pointer;
    user-select: none;
    transition: background .1s;
    border-radius: 0;
}
.kp-group-item:hover { background: rgba(255,255,255,.06); }
.kp-group-item.selected { background: rgba(88,166,255,.2); }

.kp-group-chevron {
    color: #8fa8c8;
    font-size: .7rem;
    width: .8rem;
    text-align: center;
    flex-shrink: 0;
    cursor: pointer;
}
.kp-group-icon  { font-size: .9rem; flex-shrink: 0; }
.kp-group-name  { color: #c8d8ea; font-size: .82rem; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kp-group-count { color: #6c8baa; font-size: .7rem; flex-shrink: 0; }

.kp-sidebar-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .5rem .75rem;
    border-top: 1px solid rgba(255,255,255,.08);
    flex-shrink: 0;
}

.kp-sidebar-action {
    background: transparent;
    border: none;
    color: #8fa8c8;
    font-size: .78rem;
    cursor: pointer;
    padding: .2rem .4rem;
    border-radius: 4px;
    transition: background .1s, color .1s;
}
.kp-sidebar-action:hover { background: rgba(255,255,255,.08); color: #fff; }
.kp-sidebar-action-lock { color: #f8d7a8; }
.kp-sidebar-action-lock:hover { background: rgba(248,215,168,.1); color: #ffc97d; }

/* ── Middle panel (entry list) ─────────────────────────────────────── */
.kp-middle {
    width: 280px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    background: var(--cv-kp-mid);
    border-right: 1px solid var(--cv-kp-mid-bdr);
    overflow: hidden;
}

.kp-middle-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .6rem 1rem;
    border-bottom: 1px solid var(--cv-kp-mid-bdr);
    flex-shrink: 0;
    background: var(--cv-kp-mid);
}

.kp-middle-title {
    font-size: .85rem;
    font-weight: 600;
    color: var(--cv-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kp-middle-count { color: var(--cv-text-4); font-size: .75rem; flex-shrink: 0; }

.kp-entry-list-header {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .6rem .75rem;
    flex-shrink: 0;
}

.kp-search-wrap { flex: 1; }

.kp-search {
    width: 100%;
    border: 1px solid var(--cv-border-2);
    border-radius: 6px;
    padding: .3rem .6rem;
    font-size: .8rem;
    background: var(--cv-surface);
    color: var(--cv-text);
    outline: none;
    transition: border-color .15s;
}
.kp-search:focus { border-color: var(--cv-accent); box-shadow: 0 0 0 2px var(--cv-accent-sub); }
.kp-search::placeholder { color: var(--cv-text-4); }

.kp-entry-list {
    flex: 1;
    overflow-y: auto;
}

.kp-entry-row {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .6rem .75rem;
    cursor: pointer;
    border-bottom: 1px solid rgba(0,0,0,.04);
    transition: background .1s;
    color: var(--cv-text);
}
[data-theme="dark"] .kp-entry-row { border-bottom-color: rgba(255,255,255,.04); }
.kp-entry-row:hover { background: var(--cv-surface-3); }
.kp-entry-row.selected { background: var(--cv-sel-bg); }

.kp-entry-icon { font-size: 1.1rem; flex-shrink: 0; }
.kp-entry-row-info { flex: 1; min-width: 0; }
.kp-entry-title { font-size: .82rem; font-weight: 500; color: var(--cv-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kp-entry-sub   { font-size: .73rem; color: var(--cv-text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kp-otp-badge   { font-size: .7rem; color: var(--cv-success); flex-shrink: 0; }

.kp-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    color: var(--cv-text-4);
    font-size: .85rem;
}

/* ── Right panel (entry detail) ────────────────────────────────────── */
.kp-detail-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    background: var(--cv-surface);
}

.kp-detail-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: var(--cv-text-4);
    font-size: .9rem;
}

.kp-detail {
    padding: 1.5rem;
    flex: 1;
}

.kp-detail-header {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    margin-bottom: 1.5rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--cv-border);
}

.kp-detail-icon    { font-size: 2rem; flex-shrink: 0; line-height: 1; }
.kp-detail-title-wrap { flex: 1; min-width: 0; }
.kp-detail-title   { font-size: 1.1rem; font-weight: 600; color: var(--cv-text); word-break: break-all; }
.kp-detail-url     { font-size: .78rem; color: var(--cv-accent); text-decoration: none; display: block; margin-top: .1rem; }
.kp-detail-url:hover { text-decoration: underline; }

.kp-detail-actions-top {
    display: flex;
    gap: .4rem;
    flex-shrink: 0;
}

.kp-detail-fields { display: flex; flex-direction: column; gap: .75rem; }

.kp-field { display: flex; flex-direction: column; gap: .2rem; }
.kp-field-label { font-size: .72rem; font-weight: 600; color: var(--cv-text-3); text-transform: uppercase; letter-spacing: .04em; }
.kp-field-row   { display: flex; align-items: center; gap: .4rem; }
.kp-field-value { flex: 1; font-size: .85rem; color: var(--cv-text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kp-field-value-url { color: var(--cv-accent); }
.kp-field-notes { font-size: .82rem; color: var(--cv-text-2); white-space: pre-wrap; background: var(--cv-surface-2); border-radius: 6px; padding: .5rem .75rem; border: 1px solid var(--cv-border); }
.kp-monospace   { font-family: 'Consolas', 'Courier New', monospace; }

.kp-copy-btn {
    background: none;
    border: 1px solid var(--cv-border);
    border-radius: 4px;
    padding: .15rem .4rem;
    font-size: .75rem;
    cursor: pointer;
    color: var(--cv-text-3);
    transition: background .1s, color .1s, border-color .1s;
    flex-shrink: 0;
}
.kp-copy-btn:hover { background: var(--cv-surface-3); color: var(--cv-accent); border-color: var(--cv-accent); }

/* ── OTP panel ─────────────────────────────────────────────────────── */
.kp-otp-panel {
    margin-top: 1rem;
    padding: .75rem 1rem;
    background: var(--cv-success-sub);
    border: 1px solid rgba(25,135,84,.25);
    border-radius: 8px;
}
[data-theme="dark"] .kp-otp-panel { border-color: rgba(63,185,80,.2); }

.kp-otp-row {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin-top: .4rem;
}

.kp-otp-code {
    font-family: 'Consolas', 'Courier New', monospace;
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--cv-success);
    letter-spacing: .1em;
}

.kp-otp-timer-wrap {
    position: relative;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
}

.kp-otp-ring { width: 36px; height: 36px; transform: rotate(-90deg); }
.kp-otp-ring-bg { fill: none; stroke: var(--cv-border); stroke-width: 3; }
.kp-otp-ring-fg { fill: none; stroke: var(--cv-success); stroke-width: 3; stroke-linecap: round; transition: stroke-dasharray .5s linear; }

.kp-otp-secs {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: .65rem;
    font-weight: 700;
    color: var(--cv-success);
}

/* ── Detail meta ───────────────────────────────────────────────────── */
.kp-detail-meta {
    margin-top: 1.25rem;
    padding-top: .75rem;
    border-top: 1px solid var(--cv-border);
    font-size: .72rem;
    color: var(--cv-text-4);
}

/* ── Unlock screen ─────────────────────────────────────────────────── */
.kp-unlock-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 1rem;
    background: var(--cv-bg);
}

.kp-unlock-box {
    background: var(--cv-surface);
    border-radius: 12px;
    box-shadow: var(--cv-shadow-md);
    padding: 2rem;
    width: 100%;
    max-width: 400px;
    text-align: center;
}

.kp-unlock-icon {
    font-size: 2.5rem;
    margin-bottom: .5rem;
    display: block;
}

.kp-unlock-filename {
    font-size: .8rem;
    color: var(--cv-text-3);
    font-family: monospace;
    margin-bottom: .75rem;
    word-break: break-all;
}

.kp-unlock-hint { font-size: .82rem; color: var(--cv-text-3); margin-bottom: .5rem; }

/* ── File picker page ──────────────────────────────────────────────── */
.kp-file-picker-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 1rem;
    background: var(--cv-bg);
}

.kp-file-picker {
    background: var(--cv-surface);
    border-radius: 12px;
    box-shadow: var(--cv-shadow-md);
    padding: 2rem;
    width: 100%;
    max-width: 440px;
    text-align: center;
}

.kp-file-list { text-align: left; }

.kp-file-list-header {
    font-size: .72rem;
    font-weight: 600;
    color: var(--cv-text-4);
    text-transform: uppercase;
    letter-spacing: .06em;
    margin-bottom: .4rem;
    padding: 0 .25rem;
}

.kp-file-item {
    display: flex;
    align-items: center;
    gap: .5rem;
    width: 100%;
    background: var(--cv-surface-2);
    border: 1px solid var(--cv-border);
    border-radius: 6px;
    padding: .5rem .75rem;
    margin-bottom: .3rem;
    cursor: pointer;
    font-size: .85rem;
    text-align: left;
    color: var(--cv-text);
    transition: background .1s, border-color .1s;
}
.kp-file-item:hover { background: var(--cv-accent-sub); border-color: var(--cv-accent); }

/* ── Shared buttons & form ─────────────────────────────────────────── */
.kp-btn {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    border: none;
    border-radius: 6px;
    padding: .35rem .75rem;
    font-size: .8rem;
    font-weight: 500;
    cursor: pointer;
    text-decoration: none;
    transition: background .15s, color .15s, border-color .15s;
    white-space: nowrap;
}
.kp-btn-primary { background: var(--cv-accent); color: #fff; }
.kp-btn-primary:hover { background: var(--cv-accent-h); }
.kp-btn-outline { background: transparent; border: 1px solid var(--cv-border); color: var(--cv-text-2); }
.kp-btn-outline:hover { background: var(--cv-surface-3); }
.kp-btn-ghost   { background: transparent; color: var(--cv-text-3); }
.kp-btn-ghost:hover { background: var(--cv-surface-3); color: var(--cv-text); }
.kp-btn-danger-ghost { background: transparent; color: var(--cv-text-4); }
.kp-btn-danger-ghost:hover { background: var(--cv-danger-sub); color: var(--cv-danger); }

.kp-form-field  { display: flex; flex-direction: column; gap: .3rem; text-align: left; }
.kp-form-field label { font-size: .78rem; font-weight: 600; color: var(--cv-text-2); }
.kp-form-row    { display: flex; gap: .5rem; align-items: flex-start; }
.kp-form-section { margin-top: .75rem; }

.kp-input {
    width: 100%;
    border: 1px solid var(--cv-border-2);
    border-radius: 6px;
    padding: .4rem .65rem;
    font-size: .85rem;
    color: var(--cv-text);
    background: var(--cv-surface);
    outline: none;
    transition: border-color .15s, box-shadow .15s;
}
.kp-input:focus { border-color: var(--cv-accent); box-shadow: 0 0 0 2px var(--cv-accent-sub); }
.kp-input::placeholder { color: var(--cv-text-4); }
.kp-textarea { resize: vertical; min-height: 70px; }

.kp-input-group { display: flex; }
.kp-input-group .kp-input { border-radius: 6px 0 0 6px; border-right: 0; flex: 1; }
.kp-input-addon {
    background: var(--cv-surface-2);
    border: 1px solid var(--cv-border-2);
    border-left: none;
    padding: .4rem .65rem;
    cursor: pointer;
    font-size: .85rem;
    color: var(--cv-text-3);
    transition: background .1s;
    white-space: nowrap;
}
.kp-input-addon:last-child { border-radius: 0 6px 6px 0; }
.kp-input-addon:not(:last-child) { border-radius: 0; }
.kp-input-addon:hover { background: var(--cv-surface-3); }

.kp-toggle-link {
    background: none;
    border: none;
    color: var(--cv-accent);
    font-size: .8rem;
    cursor: pointer;
    padding: .1rem 0;
    text-align: left;
}
.kp-toggle-link:hover { text-decoration: underline; }

.kp-icon-btn {
    background: none;
    border: none;
    cursor: pointer;
    padding: .3rem;
    border-radius: 4px;
    font-size: .85rem;
    line-height: 1;
    color: var(--cv-text-3);
}
.kp-icon-btn:hover { background: var(--cv-surface-2); color: var(--cv-text); }

/* ── Modal ─────────────────────────────────────────────────────────── */
.kp-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,.5);
    z-index: 500;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.kp-modal {
    background: var(--cv-surface);
    border-radius: 12px;
    box-shadow: var(--cv-shadow-lg);
    width: 100%;
    max-width: 540px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--cv-border);
}

.kp-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--cv-border);
    flex-shrink: 0;
}
.kp-modal-header h5 { margin: 0; font-size: 1rem; color: var(--cv-text); }

.kp-modal-close {
    background: none;
    border: none;
    font-size: 1rem;
    cursor: pointer;
    color: var(--cv-text-3);
    padding: .25rem;
    border-radius: 4px;
    line-height: 1;
}
.kp-modal-close:hover { background: var(--cv-surface-3); color: var(--cv-text); }

.kp-modal-body {
    overflow-y: auto;
    padding: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: .75rem;
    flex: 1;
}

.kp-modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: .5rem;
    padding: .75rem 1.25rem;
    border-top: 1px solid var(--cv-border);
    flex-shrink: 0;
}

/* ── KeePass toast error ────────────────────────────────────────────── */
.kp-toast-error {
    position: fixed;
    bottom: 1rem;
    right: 1rem;
    background: var(--cv-danger);
    color: #fff;
    border-radius: 8px;
    padding: .6rem 1rem;
    font-size: .85rem;
    z-index: 1000;
    box-shadow: var(--cv-shadow-md);
    animation: slideUp .2s ease;
}

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

/* ── Drag-over highlight on group nodes ─────────────────────────────── */
.kp-group-item.kp-drop-over {
    background: rgba(88,166,255,.3) !important;
    outline: 2px dashed rgba(88,166,255,.7);
    outline-offset: -2px;
}

/* draggable cursor hints */
.kp-entry-row[draggable="true"] { cursor: grab; }
.kp-entry-row[draggable="true"]:active { cursor: grabbing; }
.kp-group-item[draggable="true"] { cursor: grab; }
.kp-group-item[draggable="true"]:active { cursor: grabbing; }

/* ── Inline group-name input ────────────────────────────────────────── */
.kp-group-rename-input {
    background: rgba(255,255,255,.12);
    border: 1px solid rgba(255,255,255,.35);
    border-radius: 3px;
    color: #c8d8ea;
    font-size: .82rem;
    padding: 0 .35rem;
    flex: 1;
    min-width: 0;
    outline: none;
    height: 1.5rem;
}
.kp-group-rename-input:focus {
    border-color: rgba(88,166,255,.8);
    background: rgba(255,255,255,.18);
}

/* ── KeePass overlay / modal dialogs ────────────────────────────────── */
.kp-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,.55);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2000;
}

.kp-dialog {
    background: #1e2a3a;
    border: 1px solid rgba(255,255,255,.12);
    border-radius: 10px;
    padding: 1.75rem;
    min-width: 300px;
    max-width: 420px;
    width: 90%;
    box-shadow: var(--cv-shadow-lg);
    color: #c8d8ea;
}

.kp-dialog-icon {
    font-size: 2rem;
    text-align: center;
    margin-bottom: .75rem;
}

.kp-dialog-title {
    font-size: 1rem;
    font-weight: 600;
    color: #e0eaf8;
    text-align: center;
    margin-bottom: .5rem;
}

.kp-dialog-body {
    font-size: .85rem;
    color: #8fa8c8;
    text-align: center;
    margin-bottom: 1.25rem;
    line-height: 1.55;
}

.kp-dialog-actions {
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.kp-dialog .kp-input {
    background: rgba(255,255,255,.08);
    border-color: rgba(255,255,255,.2);
    color: #c8d8ea;
}
.kp-dialog .kp-input:focus {
    border-color: rgba(88,166,255,.7);
    background: rgba(255,255,255,.12);
}
.kp-dialog .kp-input::placeholder { color: rgba(200,216,234,.4); }


/* ═══════════════════════════════════════════════════════════════════
   Admin page
   ═══════════════════════════════════════════════════════════════════ */

.admin-page {
    padding: 1.5rem;
    max-width: 1100px;
    margin: 0 auto;
}

.admin-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
    gap: .75rem;
}
.admin-header h2 { margin: 0; font-size: 1.4rem; color: var(--cv-text); }

.admin-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 1rem;
    margin-bottom: 1.75rem;
}

.stat-card {
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    padding: 1rem 1.25rem;
    text-align: center;
    box-shadow: var(--cv-shadow-sm);
}
.stat-value {
    font-size: 1.65rem;
    font-weight: 700;
    color: var(--cv-text);
    line-height: 1.2;
}
.stat-label {
    font-size: .75rem;
    color: var(--cv-text-3);
    text-transform: uppercase;
    letter-spacing: .04em;
    margin-top: .25rem;
}

.admin-section {
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    padding: 1.25rem;
    margin-bottom: 1.5rem;
    box-shadow: var(--cv-shadow-sm);
}

.admin-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1rem;
    flex-wrap: wrap;
    gap: .5rem;
}
.admin-section-header h4 { margin: 0; font-size: 1rem; font-weight: 600; color: var(--cv-text); }

.admin-table { font-size: .85rem; margin-bottom: 0; }
.admin-table th { font-size: .75rem; text-transform: uppercase; letter-spacing: .04em; color: var(--cv-text-3); font-weight: 600; }
.admin-email { font-family: 'SF Mono', 'Fira Mono', Consolas, monospace; font-size: .82rem; word-break: break-all; color: var(--cv-text-2); }

.admin-create-form { border-color: rgba(13,110,253,.3) !important; background: var(--cv-accent-sub) !important; }


/* ═══════════════════════════════════════════════════════════════════
   Confirmation modal (Admin delete)
   ═══════════════════════════════════════════════════════════════════ */

.modal-backdrop-cv {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,.45);
    z-index: 1050;
    cursor: pointer;
}

.modal-cv {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1055;
    pointer-events: none;
}

.modal-cv-body {
    background: var(--cv-surface);
    border-radius: 12px;
    padding: 1.75rem;
    max-width: 420px;
    width: 90%;
    box-shadow: var(--cv-shadow-lg);
    pointer-events: all;
    border: 1px solid var(--cv-border);
}
.modal-cv-body h5 { margin-top: 0; font-size: 1.05rem; color: var(--cv-text); }


/* ═══════════════════════════════════════════════════════════════════
   Modal base (ShareDialog, Sign result)
   ═══════════════════════════════════════════════════════════════════ */

.cv-modal-backdrop {
    position: fixed; inset: 0;
    background: rgba(0,0,0,.55);
    display: flex; align-items: center; justify-content: center;
    z-index: 1050;
}
.cv-modal {
    background: var(--cv-surface);
    border-radius: 12px;
    box-shadow: var(--cv-shadow-lg);
    width: 100%; max-width: 440px;
    overflow: hidden;
    border: 1px solid var(--cv-border);
}
.cv-modal-header {
    display: flex; align-items: center; justify-content: space-between;
    padding: .85rem 1.25rem;
    background: linear-gradient(135deg, #16213e 0%, #0f3460 100%);
    color: #fff;
}
.cv-modal-header h5 { color: #fff; margin: 0; }
.cv-modal-close {
    background: none; border: none; color: rgba(255,255,255,.7);
    font-size: 1.1rem; cursor: pointer; line-height: 1;
}
.cv-modal-close:hover { color: #fff; }
.cv-modal-body { padding: 1.25rem; }

/* ── Share dialog ──────────────────────────────────────────────────── */

.share-url-box {
    display: flex; align-items: center; gap: .5rem;
    background: var(--cv-surface-2); border: 1px solid var(--cv-border);
    border-radius: 8px; padding: .5rem .75rem;
    overflow: hidden;
}
.share-url-text {
    flex: 1; font-size: .78rem; font-family: monospace; min-width: 0;
    color: var(--cv-accent);
}
.share-url-copy { flex-shrink: 0; font-size: .75rem; }

/* ── Share receive page ─────────────────────────────────────────────── */

.share-card {
    background: var(--cv-surface);
    border-radius: 16px;
    box-shadow: var(--cv-shadow-lg);
    width: 100%; max-width: 420px;
    overflow: hidden;
    border: 1px solid var(--cv-border);
}
.share-card-header {
    padding: 2rem 2rem 1.5rem;
    background: linear-gradient(135deg, #16213e 0%, #0f3460 100%);
    text-align: center;
    color: #fff;
}
.share-card-body { padding: 1.5rem 2rem 2rem; }

.share-status {
    display: flex; align-items: center; gap: 1rem;
}


/* ═══════════════════════════════════════════════════════════════════
   File preview modal
   ═══════════════════════════════════════════════════════════════════ */

.cv-preview-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,.72);
    z-index: 1050;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    animation: previewFadeIn .15s ease;
}

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

.cv-preview-modal {
    background: var(--cv-surface);
    border-radius: 12px;
    box-shadow: var(--cv-shadow-lg);
    display: flex;
    flex-direction: column;
    width: min(920px, 92vw);
    max-height: 88vh;
    overflow: hidden;
    animation: previewScaleIn .15s ease;
    border: 1px solid var(--cv-border);
}

@keyframes previewScaleIn {
    from { transform: scale(.96); opacity: 0; }
    to   { transform: scale(1);   opacity: 1; }
}

.cv-preview-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .75rem 1rem;
    border-bottom: 1px solid var(--cv-border);
    flex-shrink: 0;
    background: var(--cv-surface);
}

.cv-preview-filename {
    font-weight: 600;
    font-size: .9rem;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--cv-text);
}

.cv-preview-actions {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-shrink: 0;
}

.cv-preview-close {
    background: none;
    border: none;
    font-size: 1.1rem;
    line-height: 1;
    padding: .3rem .5rem;
    cursor: pointer;
    color: var(--cv-text-3);
    border-radius: 6px;
    transition: background .15s, color .15s;
}
.cv-preview-close:hover { background: var(--cv-surface-3); color: var(--cv-text); }

.cv-preview-body {
    flex: 1;
    overflow: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--cv-surface-2);
    min-height: 200px;
}

.cv-preview-loading {
    display: flex;
    align-items: center;
    color: var(--cv-text-3);
    padding: 2.5rem;
}

.cv-preview-image-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    padding: 1.5rem;
}

.cv-preview-image {
    max-width: 100%;
    max-height: 76vh;
    object-fit: contain;
    border-radius: 4px;
    box-shadow: 0 2px 16px rgba(0,0,0,.18);
}

.cv-preview-video {
    max-width: 100%;
    max-height: 76vh;
    display: block;
}

.cv-preview-audio-wrap {
    padding: 2.5rem;
    width: 100%;
}

.cv-preview-iframe {
    width: 100%;
    height: 76vh;
    border: none;
    display: block;
}

.cv-preview-text {
    width: 100%;
    margin: 0;
    padding: 1.25rem 1.5rem;
    font-family: 'Consolas', 'Fira Code', 'Courier New', monospace;
    font-size: .82rem;
    line-height: 1.65;
    white-space: pre-wrap;
    word-break: break-word;
    color: var(--cv-text);
    background: var(--cv-surface-2);
    align-self: flex-start;
    min-height: 400px;
}


/* ═══════════════════════════════════════════════════════════════════
   Notes – two-pane secure notes editor
   ═══════════════════════════════════════════════════════════════════ */

.notes-layout {
    display: flex;
    flex: 1;
    min-height: 0;
    overflow: hidden;
    background: var(--cv-bg);
}

/* ── Sidebar (note list) ──────────────────────────────────────── */
.notes-sidebar {
    width: 280px;
    flex-shrink: 0;
    background: var(--cv-surface);
    border-right: 1px solid var(--cv-border);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.notes-sidebar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .8rem 1rem;
    border-bottom: 1px solid var(--cv-border);
    flex-shrink: 0;
    background: var(--cv-surface);
}

.notes-sidebar-header .fw-semibold {
    font-size: .92rem;
    color: var(--cv-text);
    letter-spacing: -.1px;
}

.notes-list {
    flex: 1;
    overflow-y: auto;
    padding: .35rem;
}

.note-item {
    padding: .65rem .75rem;
    margin-bottom: .2rem;
    cursor: pointer;
    border-radius: 8px;
    border: 1px solid transparent;
    transition: background .12s, border-color .12s;
}
.note-item:hover { background: var(--cv-surface-3); }

.note-item.note-item-active {
    background: var(--cv-accent-sub);
    border-color: var(--cv-accent);
    border-left: 3px solid var(--cv-accent);
    padding-left: calc(.75rem - 2px);
}

.note-item-title {
    font-size: .87rem;
    font-weight: 600;
    color: var(--cv-text);
    margin-bottom: .15rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.note-item.note-item-active .note-item-title { color: var(--cv-accent); }

.note-item-date {
    font-size: .72rem;
    color: var(--cv-text-3) !important;
}

.notes-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    color: var(--cv-text-3);
    font-size: .85rem;
    padding: 2.5rem 1rem;
    text-align: center;
}
.notes-empty span:first-child { font-size: 2rem; line-height: 1; opacity: .55; }

/* ── Editor area (right pane) ─────────────────────────────────── */
.notes-editor-area {
    flex: 1;
    min-width: 0;
    display: flex;
    overflow: hidden;
    background: var(--cv-bg);
}

.notes-editor-empty {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    color: var(--cv-text-3);
    text-align: center;
}
.notes-editor-empty-icon { font-size: 3.5rem; opacity: .3; line-height: 1; }

.notes-editor {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--cv-surface);
    margin: 1rem;
    border-radius: 12px;
    box-shadow: var(--cv-shadow-sm);
    border: 1px solid var(--cv-border);
}

.notes-editor-toolbar {
    display: flex;
    align-items: center;
    padding: .6rem .9rem;
    border-bottom: 1px solid var(--cv-border);
    flex-shrink: 0;
    background: var(--cv-surface-2);
    gap: .5rem;
}

.notes-title-input.form-control {
    flex: 1;
    font-weight: 600;
    font-size: 1rem;
    border-color: transparent !important;
    box-shadow: none !important;
    background: transparent !important;
    color: var(--cv-text) !important;
    padding-left: .4rem;
}
.notes-title-input.form-control:focus { box-shadow: 0 0 0 2px var(--cv-accent-sub) !important; }
.notes-title-input.form-control::placeholder { color: var(--cv-text-4); }

.notes-textarea {
    flex: 1;
    resize: none;
    border: none;
    outline: none;
    padding: 1.25rem 1.5rem;
    font-size: .92rem;
    line-height: 1.7;
    font-family: 'Inter', 'SF Pro Text', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
    background: var(--cv-surface);
    color: var(--cv-text);
    /* In split mode the textarea sits next to .notes-preview; min-width:0
       prevents either pane from ballooning when content has long unbroken
       tokens (URLs, base64 blobs). */
    min-width: 0;
    min-height: 0;
}
.notes-textarea::placeholder { color: var(--cv-text-4); }
.notes-textarea:focus { background: var(--cv-surface); }

/* ── Unsaved-changes badge (notes editor toolbar) ───────────────────
   Quiet amber dot + label so it reads as a status, not an alert.
   The colour mirrors the auto-save warning shade used elsewhere. */
.notes-dirty-indicator {
    font-size: .72rem;
    font-weight: 500;
    color: var(--cv-warning, #c87f00);
    background: rgba(200, 127, 0, .08);
    padding: .15rem .45rem;
    border-radius: 999px;
    white-space: nowrap;
}

/* ── Markdown view-mode toggle (Edit / Split / Preview) ───────────────
   Sits in .notes-editor-toolbar between the title and the action
   buttons. The "active" mode uses the primary accent colour so it
   reads as the current state without becoming louder than the Save
   button (which is also primary but adjacent + bigger). */
.notes-mode-toggle {
    flex-shrink: 0;
}
.notes-mode-toggle .btn {
    /* Keep the segmented control compact so the title input retains
       most of the toolbar width. */
    padding-left: .55rem;
    padding-right: .55rem;
    font-size: .78rem;
    font-weight: 500;
}

/* ── Two-pane editor body (textarea + preview) ────────────────────────
   The body is the scroll region; .notes-editor itself stays a fixed-
   height card. In split mode each pane scrolls independently so a long
   note doesn't drag the preview off-screen along with the editor. */
.notes-editor-body {
    flex: 1;
    display: flex;
    flex-direction: row;
    min-height: 0;
    min-width: 0;
    background: var(--cv-surface);
}
.notes-editor-body-split > * {
    /* In split mode both panes share the body 50/50 with a thin divider. */
    flex: 1 1 50%;
    width: 50%;
    border-right: 1px solid var(--cv-border);
}
.notes-editor-body-split > *:last-child { border-right: none; }

.notes-editor-body-edit > .notes-textarea     { flex: 1; }
.notes-editor-body-preview > .notes-preview   { flex: 1; }


.notes-preview {
    padding: 1.5rem 1.5rem 1.75rem;
}

.notes-preview > .markdown-body,
.notes-preview > .notes-preview-placeholder {
    box-sizing: border-box;
}
.notes-preview-placeholder {
    color: var(--cv-text-4);
    font-style: italic;
    font-size: .9rem;
}

/* ── .markdown-body — shared by Notes, Kanban card descriptions, etc.
   Designed to match the existing Bootstrap-flavoured typography so the
   preview reads as native CloudVault content rather than a foreign island. */
.markdown-body {
    font-size: .92rem;
    line-height: 1.7;
    font-family: 'Inter', 'SF Pro Text', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
    word-wrap: break-word;
}
.markdown-body > *:first-child { margin-top: 0; }
.markdown-body > *:last-child  { margin-bottom: 0; }
.markdown-body h1, .markdown-body h2, .markdown-body h3,
.markdown-body h4, .markdown-body h5, .markdown-body h6 {
    margin: 1.25rem 0 .65rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--cv-text);
}
.markdown-body h1 { font-size: 1.5rem;  border-bottom: 1px solid var(--cv-border); padding-bottom: .3rem; }
.markdown-body h2 { font-size: 1.25rem; border-bottom: 1px solid var(--cv-border); padding-bottom: .25rem; }
.markdown-body h3 { font-size: 1.1rem; }
.markdown-body h4 { font-size: 1rem;   }
.markdown-body h5 { font-size: .92rem; color: var(--cv-text-2); }
.markdown-body h6 { font-size: .85rem; color: var(--cv-text-3); }
.markdown-body p, .markdown-body ul, .markdown-body ol, .markdown-body blockquote {
    margin: 0 0 .9rem;
}
.markdown-body ul, .markdown-body ol { padding-left: 1.6rem; }
.markdown-body li + li { margin-top: .25rem; }
.markdown-body li > p { margin-bottom: .35rem; }
.markdown-body blockquote {
    border-left: 3px solid var(--cv-accent);
    padding: .25rem .9rem;
    color: var(--cv-text-2);
    background: var(--cv-surface-2);
    border-radius: 0 6px 6px 0;
}
.markdown-body code {
    font-family: 'JetBrains Mono', 'Fira Code', Consolas, 'Courier New', monospace;
    font-size: .85em;
    background: var(--cv-surface-3);
    padding: .08rem .35rem;
    border-radius: 4px;
    color: var(--cv-text);
}
.markdown-body pre {
    background: var(--cv-surface-3);
    border-radius: 8px;
    padding: .85rem 1rem;
    overflow-x: auto;
    margin: 0 0 .9rem;
}
.markdown-body pre code {
    background: transparent;
    padding: 0;
    font-size: .82rem;
    line-height: 1.55;
}
.markdown-body a {
    color: var(--cv-accent);
    text-decoration: none;
}
.markdown-body a:hover { text-decoration: underline; }
.markdown-body hr {
    border: 0;
    border-top: 1px solid var(--cv-border);
    margin: 1.25rem 0;
}
.markdown-body table {
    width: 100%;
    border-collapse: collapse;
    margin: 0 0 .9rem;
    font-size: .88rem;
}
.markdown-body th, .markdown-body td {
    border: 1px solid var(--cv-border);
    padding: .4rem .65rem;
    text-align: left;
    vertical-align: top;
}
.markdown-body th { background: var(--cv-surface-2); font-weight: 600; }
.markdown-body img { max-width: 100%; border-radius: 6px; }
.markdown-body input[type="checkbox"] { margin-right: .35rem; }

/* ── Responsive: list/detail toggle on narrow windows ─────────────
   The list pane fills the viewport until the user picks an item;
   opening an item slides the detail pane in over the list. A
   shared `.cv-mob-back-btn` returns to the list. Same pattern KeePass
   uses; mirrored for Todos + Kanban below. */
.cv-mob-back-btn { display: none !important; }

@media (max-width: 768px) {
    .notes-layout { flex-direction: column; position: relative; }
    .notes-sidebar {
        width: 100%; max-height: none; height: 100%;
        border-right: none; border-bottom: none;
    }
    .notes-editor-area { display: none; }

    .notes-layout--detail-open .notes-sidebar    { display: none; }
    .notes-layout--detail-open .notes-editor-area { display: flex; width: 100%; height: 100%; }

    .notes-editor { margin: 0; border-radius: 0; }
    /* Split mode collapses to stacked panes on phones. */
    .notes-editor-body-split { flex-direction: column; }
    .notes-editor-body-split > * {
        flex: 1 1 50%;
        width: 100%;
        border-right: none;
        border-bottom: 1px solid var(--cv-border);
    }
    .notes-editor-body-split > *:last-child { border-bottom: none; }

    .cv-mob-back-btn {
        display: inline-flex !important;
        align-items: center; gap: .35rem;
        background: var(--cv-surface-2); border: 1px solid var(--cv-border);
        color: var(--cv-accent); font-size: .85rem; font-weight: 500;
        cursor: pointer; padding: .35rem .65rem;
        border-radius: 6px;
    }
    .cv-mob-back-btn:hover { background: var(--cv-surface-3); }
}


/* ═══════════════════════════════════════════════════════════════════
   Todo Lists — same shell as Notes, item-list body
   Naming convention: .todos-* for layout, .todo-* for individual rows
   so the markup reads as singular/plural correctly.
   ═══════════════════════════════════════════════════════════════════ */

.todos-layout {
    display: flex;
    flex: 1;
    min-height: 0;
    overflow: hidden;
    background: var(--cv-bg);
}

.todos-sidebar {
    width: 280px;
    flex-shrink: 0;
    background: var(--cv-surface);
    border-right: 1px solid var(--cv-border);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.todos-sidebar-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: .85rem 1rem;
    border-bottom: 1px solid var(--cv-border);
    font-size: 1rem;
}

.todos-list {
    flex: 1;
    overflow-y: auto;
    padding: .35rem;
}
.todo-list-item {
    padding: .55rem .65rem;
    border-radius: 8px;
    cursor: pointer;
    transition: background .12s ease, border-color .12s ease;
    border-left: 3px solid transparent;
}
.todo-list-item:hover { background: var(--cv-surface-3); }
.todo-list-item.todo-list-item-active {
    background: var(--cv-accent-sub);
    border-left-color: var(--cv-accent);
}
.todo-list-item-title {
    font-weight: 600;
    font-size: .87rem;
    color: var(--cv-text);
}
.todo-list-item.todo-list-item-active .todo-list-item-title { color: var(--cv-accent); }
.todo-list-item-meta {
    font-size: .7rem;
    color: var(--cv-text-3);
    margin-top: .15rem;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
}

.todos-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .5rem;
    padding: 2rem 1rem;
    color: var(--cv-text-3);
    font-size: .9rem;
}
.todos-empty > span:first-child { font-size: 2rem; }

.todos-area {
    flex: 1;
    min-width: 0;
    display: flex;
    overflow: hidden;
    background: var(--cv-bg);
}
.todos-editor-empty {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: var(--cv-text-3);
    gap: .5rem;
    font-size: .95rem;
}
.todos-editor-empty-icon { font-size: 3.5rem; }

.todos-board {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: var(--cv-surface);
    margin: 1rem;
    border-radius: 12px;
    box-shadow: var(--cv-shadow-md);
    overflow: hidden;
}

.todos-toolbar {
    display: flex;
    align-items: center;
    padding: .6rem .9rem;
    border-bottom: 1px solid var(--cv-border);
    background: var(--cv-surface-2);
    flex-shrink: 0;
    gap: .5rem;
}
.todos-title-input.form-control {
    flex: 1;
    font-weight: 600;
    font-size: 1rem;
    border-color: transparent !important;
    box-shadow: none !important;
    background: transparent !important;
    color: var(--cv-text) !important;
    padding-left: .4rem;
}
.todos-title-input.form-control:focus { box-shadow: 0 0 0 2px var(--cv-accent-sub) !important; }
.todos-title-input.form-control::placeholder { color: var(--cv-text-4); }

.todos-dirty-indicator {
    /* Legacy "unsaved" strip — kept for backwards-compat with any older
       host that still renders it. The auto-save flow uses
       .todos-save-status (an inline label next to the Save button) instead. */
    padding: .15rem .9rem;
    font-size: .72rem;
    color: var(--cv-warning, #c87f00);
    background: rgba(200, 127, 0, .08);
    border-bottom: 1px solid var(--cv-border);
}

/* Inline auto-save status next to the Save button in the toolbar. The
   colour shifts subtly to mirror the state: muted while idle/unsaved,
   accent while saving, success once saved, danger on failure. */
.todos-save-status {
    font-size: .72rem;
    color: var(--cv-text-3);
    min-width: 60px;
    text-align: right;
    transition: color .15s ease;
}
.todos-save-status:empty { min-width: 0; }

.todos-body {
    flex: 1;
    overflow-y: auto;
    padding: .9rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: .65rem;
}

.todos-items-empty {
    color: var(--cv-text-3);
    font-size: .9rem;
    text-align: center;
    padding: 1.5rem 0;
}

/* ── Add-new row ────────────────────────────────────────────────────── */
.todo-add-row {
    display: flex;
    gap: .5rem;
    padding-bottom: .25rem;
    border-bottom: 1px solid var(--cv-border);
    margin-bottom: .25rem;
}
.todo-add-row > input { flex: 1; }

/* ── Single item row ────────────────────────────────────────────────── */
.todo-items {
    display: flex;
    flex-direction: column;
    gap: .35rem;
}

.todo-item {
    display: flex;
    align-items: center;
    gap: .55rem;
    padding: .4rem .5rem;
    border-radius: 6px;
    transition: background .12s ease;
}
.todo-item:hover { background: var(--cv-surface-3); }

.todo-item-checkbox {
    flex-shrink: 0;
    margin-top: 0;
    cursor: pointer;
}

.todo-item-text.form-control {
    flex: 1;
    border-color: transparent !important;
    background: transparent !important;
    box-shadow: none !important;
    color: var(--cv-text) !important;
}
.todo-item-text.form-control:focus {
    background: var(--cv-surface) !important;
    border-color: var(--cv-border-2) !important;
}

.todo-item-due.form-control {
    flex: 0 0 130px;
    width: 130px;
    font-size: .78rem;
    color: var(--cv-text-2);
    background: var(--cv-surface-2) !important;
    border-color: var(--cv-border) !important;
}

.todo-item-delete {
    color: var(--cv-text-3);
    font-size: .9rem;
    padding: 0 .35rem;
    text-decoration: none !important;
}
.todo-item-delete:hover { color: var(--cv-danger, #c0392b); }

/* Completed items: muted text + strikethrough. */
.todo-item-done .todo-item-text.form-control {
    color: var(--cv-text-3) !important;
    text-decoration: line-through;
}

.todo-items-divider {
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .6px;
    color: var(--cv-text-3);
    margin: .65rem 0 .25rem;
    border-bottom: 1px solid var(--cv-border);
    padding-bottom: .25rem;
}

@media (max-width: 768px) {
    .todos-layout { flex-direction: column; position: relative; }
    .todos-sidebar {
        width: 100%; max-height: none; height: 100%;
        border-right: none; border-bottom: none;
    }
    .todos-area { display: none; }

    .todos-layout--detail-open .todos-sidebar { display: none; }
    .todos-layout--detail-open .todos-area    { display: flex; width: 100%; height: 100%; }

    .todos-board { margin: 0; border-radius: 0; }
    .todo-item-due.form-control { flex: 0 0 110px; width: 110px; }
}


/* ═══════════════════════════════════════════════════════════════════
   Kanban — same shell as Notes / Todos, horizontally-scrolling lanes
   inside the right pane.
   ═══════════════════════════════════════════════════════════════════ */

.kanban-layout {
    display: flex;
    flex: 1;
    min-height: 0;
    overflow: hidden;
    background: var(--cv-bg);
}

.kanban-sidebar {
    width: 280px;
    flex-shrink: 0;
    background: var(--cv-surface);
    border-right: 1px solid var(--cv-border);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.kanban-sidebar-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: .85rem 1rem;
    border-bottom: 1px solid var(--cv-border);
    font-size: 1rem;
}

.kanban-boards-list {
    flex: 1;
    overflow-y: auto;
    padding: .35rem;
}
.kanban-board-item {
    padding: .55rem .65rem;
    border-radius: 8px;
    cursor: pointer;
    transition: background .12s ease, border-color .12s ease;
    border-left: 3px solid transparent;
}
.kanban-board-item:hover { background: var(--cv-surface-3); }
.kanban-board-item.kanban-board-item-active {
    background: var(--cv-accent-sub);
    border-left-color: var(--cv-accent);
}
.kanban-board-item-title { font-weight: 600; font-size: .87rem; color: var(--cv-text); }
.kanban-board-item.kanban-board-item-active .kanban-board-item-title { color: var(--cv-accent); }
.kanban-board-item-meta { font-size: .7rem; color: var(--cv-text-3); margin-top: .15rem; }

.kanban-empty {
    display: flex; flex-direction: column; align-items: center; gap: .5rem;
    padding: 2rem 1rem; color: var(--cv-text-3); font-size: .9rem;
}
.kanban-empty > span:first-child { font-size: 2rem; }

.kanban-area {
    flex: 1;
    min-width: 0;
    display: flex;
    overflow: hidden;
    background: var(--cv-bg);
}
.kanban-editor-empty {
    flex: 1;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    color: var(--cv-text-3); gap: .5rem; font-size: .95rem;
}
.kanban-editor-empty-icon { font-size: 3.5rem; }

.kanban-board {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: var(--cv-surface);
    margin: 1rem;
    border-radius: 12px;
    box-shadow: var(--cv-shadow-md);
    overflow: hidden;
}

.kanban-toolbar {
    display: flex;
    align-items: center;
    padding: .6rem .9rem;
    border-bottom: 1px solid var(--cv-border);
    background: var(--cv-surface-2);
    flex-shrink: 0;
    gap: .5rem;
}
.kanban-title-input.form-control {
    flex: 1;
    font-weight: 600;
    font-size: 1rem;
    border-color: transparent !important;
    box-shadow: none !important;
    background: transparent !important;
    color: var(--cv-text) !important;
    padding-left: .4rem;
}
.kanban-title-input.form-control:focus { box-shadow: 0 0 0 2px var(--cv-accent-sub) !important; }
.kanban-title-input.form-control::placeholder { color: var(--cv-text-4); }

.kanban-dirty-indicator {
    /* Legacy "unsaved" strip; auto-save now uses .kanban-save-status (inline
       next to the Save button). Kept for backwards-compat with cached markup. */
    padding: .15rem .9rem;
    font-size: .72rem;
    color: var(--cv-warning, #c87f00);
    background: rgba(200, 127, 0, .08);
    border-bottom: 1px solid var(--cv-border);
}

.kanban-save-status {
    font-size: .72rem;
    color: var(--cv-text-3);
    min-width: 60px;
    text-align: right;
    transition: color .15s ease;
}
.kanban-save-status:empty { min-width: 0; }

/* ── Lanes track ──────────────────────────────────────────────────── */
.kanban-lanes-wrap {
    flex: 1;
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: 1rem;
    overflow-x: auto;
    overflow-y: hidden;
    background: var(--cv-bg-2, var(--cv-bg));
}

.kanban-lanes-empty {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--cv-text-3);
    font-style: italic;
}

/* ── Single lane (column) ─────────────────────────────────────────── */
.kanban-lane {
    width: 280px;
    flex-shrink: 0;
    background: var(--cv-surface-2);
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    max-height: 100%;
    box-shadow: var(--cv-shadow-sm, 0 1px 3px rgba(0,0,0,.08));
}

.kanban-lane-header {
    display: flex;
    align-items: center;
    gap: .35rem;
    padding: .55rem .6rem;
    border-bottom: 1px solid var(--cv-border);
}
.kanban-lane-title.form-control {
    flex: 1;
    font-weight: 600;
    font-size: .9rem;
    border-color: transparent !important;
    background: transparent !important;
    box-shadow: none !important;
    color: var(--cv-text) !important;
    padding: .15rem .35rem;
}
.kanban-lane-title.form-control:focus { background: var(--cv-surface) !important; }
.kanban-lane-count {
    font-size: .72rem;
    color: var(--cv-text-3);
    background: var(--cv-surface-3);
    padding: .05rem .45rem;
    border-radius: 999px;
}

.kanban-lane-body {
    flex: 1;
    overflow-y: auto;
    padding: .5rem;
    display: flex;
    flex-direction: column;
    gap: .4rem;
    /* Min-height keeps the drop target large enough to hit even when the
       lane has no cards yet. */
    min-height: 60px;
}

.kanban-lane-footer {
    padding: .35rem .5rem .5rem;
    border-top: 1px solid var(--cv-border);
}
.kanban-add-card.btn-link {
    color: var(--cv-text-3);
    text-decoration: none;
    font-size: .8rem;
    padding: .15rem .35rem;
    width: 100%;
    text-align: left;
}
.kanban-add-card.btn-link:hover { color: var(--cv-accent); }

/* ── Card ─────────────────────────────────────────────────────────── */
.kanban-card {
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 8px;
    padding: .55rem .65rem;
    cursor: pointer;
    box-shadow: 0 1px 0 rgba(0,0,0,.03);
    transition: transform .08s ease, box-shadow .12s ease, border-color .12s ease;
}
.kanban-card:hover {
    border-color: var(--cv-accent);
    box-shadow: 0 2px 6px rgba(0,0,0,.08);
    transform: translateY(-1px);
}
.kanban-card:active { cursor: grabbing; }
.kanban-card[draggable="true"] { user-select: none; }

/* CRITICAL for drag-drop: child elements (tag chips, title text, meta
   strip) must be transparent to pointer events so dragstart / dragend /
   click always fire on the <article> itself. Without this, when the user
   grabs the card by a chip span or the title text, the browser tries to
   drag THAT element (most non-image elements aren't draggable), and the
   article's @ondragstart never fires. Click handlers continue to work
   because click events on a child still bubble — pointer-events:none
   only blocks the element from being the *target*, not the path. */
.kanban-card > * { pointer-events: none; }

.kanban-card-title {
    font-size: .85rem;
    color: var(--cv-text);
    line-height: 1.35;
    word-wrap: break-word;
}
.kanban-card-due {
    margin-top: .3rem;
    font-size: .7rem;
    color: var(--cv-text-3);
}

/* Description textarea inside the card-detail modal */
.kanban-card-desc {
    font-family: 'JetBrains Mono', 'Fira Code', Consolas, 'Courier New', monospace;
    font-size: .85rem;
    line-height: 1.5;
}

/* ── Card meta strip (due date + subtask progress) ─────────────────── */
.kanban-card-meta {
    display: flex;
    align-items: center;
    gap: .55rem;
    margin-top: .3rem;
    flex-wrap: wrap;
}
.kanban-card-meta .kanban-card-due { margin-top: 0; }
.kanban-card-subtasks {
    font-size: .7rem;
    color: var(--cv-text-3);
}
.kanban-card-subtasks-complete { color: var(--cv-success, #198754); }

/* ── Tag chips on cards ───────────────────────────────────────────── */
.kanban-card-tags {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
    margin-bottom: .35rem;
}
.kanban-card-tag-chip {
    font-size: .65rem;
    padding: .05rem .4rem;
    border-radius: 999px;
    color: #fff;
    line-height: 1.3;
    /* Just enough contrast against the lane surface without making the
       chip louder than the card title. */
    text-shadow: 0 0 1px rgba(0, 0, 0, .25);
    white-space: nowrap;
}

/* ── Tag picker (inside card detail modal) ─────────────────────────── */
.kanban-tag-picker {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    align-items: center;
}
.kanban-tag-chip-button {
    font-size: .75rem;
    padding: .15rem .6rem;
    border-radius: 999px;
    border: 1px solid;
    cursor: pointer;
    transition: filter .12s ease;
}
.kanban-tag-chip-button:hover { filter: brightness(1.08); }
.kanban-tag-chip-on { font-weight: 500; }

/* ── Subtasks (card detail modal) ──────────────────────────────────── */
.kanban-subtasks {
    display: flex;
    flex-direction: column;
    gap: .25rem;
}
.kanban-subtask {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .15rem .25rem;
    border-radius: 4px;
}
.kanban-subtask:hover { background: var(--cv-surface-3); }
.kanban-subtask-check { flex-shrink: 0; margin: 0; cursor: pointer; }
.kanban-subtask-done input[type="text"] {
    color: var(--cv-text-3) !important;
    text-decoration: line-through;
}
.kanban-subtask-add {
    display: flex;
    gap: .35rem;
    margin-top: .35rem;
    padding-top: .35rem;
    border-top: 1px dashed var(--cv-border);
}
.kanban-subtask-add > input { flex: 1; }

/* ── Custom fields (card detail modal) ─────────────────────────────── */
.kanban-fields {
    display: flex;
    flex-direction: column;
    gap: .5rem;
}
.kanban-field-row {
    display: grid;
    grid-template-columns: 140px 1fr;
    align-items: center;
    gap: .65rem;
}
.kanban-field-label {
    font-size: .82rem;
    color: var(--cv-text-2);
    margin: 0;
}

/* ── Board-settings modal: tag + field editor rows ─────────────────── */
.kanban-settings-list {
    display: flex;
    flex-direction: column;
    gap: .5rem;
}
.kanban-settings-row {
    display: flex;
    align-items: center;
    gap: .5rem;
}
.kanban-tag-color {
    /* Bootstrap renders form-control-color as a fixed 3rem square; shrink
       to fit the row vertically. */
    width: 38px;
    height: 32px;
    padding: 2px;
}
.kanban-field-edit-row {
    flex-wrap: wrap;
}
.kanban-field-type-select { max-width: 140px; }
.kanban-field-options-input {
    flex-basis: 100%;
    margin-top: .25rem;
}

@media (max-width: 768px) {
    .kanban-layout { flex-direction: column; position: relative; }
    .kanban-sidebar {
        width: 100%; max-height: none; height: 100%;
        border-right: none; border-bottom: none;
    }
    .kanban-area { display: none; }

    .kanban-layout--detail-open .kanban-sidebar { display: none; }
    .kanban-layout--detail-open .kanban-area    { display: flex; width: 100%; height: 100%; }

    .kanban-board { margin: 0; border-radius: 0; }
    .kanban-lane { width: 260px; }
    .kanban-field-row { grid-template-columns: 1fr; gap: .15rem; }
}




/* ═══════════════════════════════════════════════════════════════════
   Bootstrap component overrides for dark mode
   ═══════════════════════════════════════════════════════════════════ */

[data-theme="dark"] .form-control,
[data-theme="dark"] .form-select {
    background: var(--cv-surface);
    border-color: var(--cv-border-2);
    color: var(--cv-text);
}
[data-theme="dark"] .form-control:focus,
[data-theme="dark"] .form-select:focus {
    background: var(--cv-surface);
    border-color: var(--cv-accent);
    color: var(--cv-text);
    box-shadow: 0 0 0 3px var(--cv-accent-sub);
}
[data-theme="dark"] .form-control::placeholder { color: var(--cv-text-4); }
[data-theme="dark"] .form-check-input {
    background-color: var(--cv-surface-2);
    border-color: var(--cv-border-2);
}
[data-theme="dark"] .form-check-input:checked { background-color: var(--cv-accent); border-color: var(--cv-accent); }

[data-theme="dark"] .btn-primary {
    background-color: var(--cv-accent);
    border-color: var(--cv-accent);
}
[data-theme="dark"] .btn-primary:hover { background-color: var(--cv-accent-h); border-color: var(--cv-accent-h); }
[data-theme="dark"] .btn-success { background-color: var(--cv-success); border-color: var(--cv-success); }
[data-theme="dark"] .btn-danger  { background-color: var(--cv-danger);  border-color: var(--cv-danger);  }
[data-theme="dark"] .btn-outline-secondary {
    border-color: var(--cv-border-2);
    color: var(--cv-text-3);
}
[data-theme="dark"] .btn-outline-secondary:hover { background: var(--cv-surface-3); color: var(--cv-text); }

[data-theme="dark"] .alert-danger  { background: var(--cv-danger-sub);  border-color: rgba(244,112,103,.25); color: var(--cv-danger);  }
[data-theme="dark"] .alert-success { background: var(--cv-success-sub); border-color: rgba(63,185,80,.25);  color: var(--cv-success); }
[data-theme="dark"] .alert-warning { background: var(--cv-warning-sub); border-color: rgba(227,179,65,.25); color: var(--cv-warning); }
[data-theme="dark"] .alert-info    { background: var(--cv-accent-sub);  border-color: rgba(88,166,255,.25);  color: var(--cv-accent);  }

[data-theme="dark"] .table { color: var(--cv-text); }
[data-theme="dark"] .table th { color: var(--cv-text-3); border-color: var(--cv-border); }
[data-theme="dark"] .table td { border-color: var(--cv-border); }
[data-theme="dark"] .table-striped > tbody > tr:nth-of-type(odd) > * { background-color: rgba(255,255,255,.03); }
[data-theme="dark"] .table-hover > tbody > tr:hover > * { background-color: var(--cv-surface-3); }

[data-theme="dark"] .badge.bg-secondary { background-color: var(--cv-surface-3) !important; color: var(--cv-text-2) !important; }

[data-theme="dark"] .progress { background-color: var(--cv-surface-3); }

[data-theme="dark"] .input-group-text {
    background-color: var(--cv-surface-2);
    border-color: var(--cv-border-2);
    color: var(--cv-text-3);
}

/* Bootstrap body-level CSS variables */
[data-theme="dark"] {
    --bs-body-bg:          #0d1a2e;
    --bs-body-color:       #e6edf3;
    --bs-border-color:     #2a3f5f;
    --bs-secondary-color:  #8b9db5;
    --bs-emphasis-color:   #e6edf3;
    --bs-tertiary-color:   #4d6b8a;
    --bs-tertiary-bg:      #1c2d4a;
    --bs-secondary-bg:     #162340;
    --bs-link-color:       #58a6ff;
    --bs-link-hover-color: #79b8ff;
}

/* Cards */
[data-theme="dark"] .card {
    background-color: var(--cv-surface);
    border-color: var(--cv-border);
    color: var(--cv-text);
}
[data-theme="dark"] .card-body   { background-color: var(--cv-surface);   color: var(--cv-text); }
[data-theme="dark"] .card-header { background-color: var(--cv-surface-2); border-color: var(--cv-border); color: var(--cv-text); }
[data-theme="dark"] .card-footer { background-color: var(--cv-surface-2); border-color: var(--cv-border); color: var(--cv-text); }
[data-theme="dark"] .card-title  { color: var(--cv-text); }
[data-theme="dark"] .card-text   { color: var(--cv-text-2); }
[data-theme="dark"] .card-subtitle { color: var(--cv-text-3); }

/* Text helpers */
[data-theme="dark"] .text-muted,
[data-theme="dark"] .text-secondary { color: var(--cv-text-3) !important; }
[data-theme="dark"] .text-primary   { color: var(--cv-accent)  !important; }
[data-theme="dark"] .text-dark      { color: var(--cv-text)    !important; }
[data-theme="dark"] .text-success   { color: var(--cv-success) !important; }
[data-theme="dark"] .text-danger    { color: var(--cv-danger)  !important; }
[data-theme="dark"] .text-warning   { color: var(--cv-warning) !important; }
[data-theme="dark"] .text-info      { color: var(--cv-accent)  !important; }
[data-theme="dark"] .text-body      { color: var(--cv-text)    !important; }
[data-theme="dark"] .text-body-secondary { color: var(--cv-text-3) !important; }
[data-theme="dark"] .text-body-emphasis  { color: var(--cv-text)   !important; }

/* Close button (black X → white on dark backgrounds) */
[data-theme="dark"] .btn-close { filter: invert(1) grayscale(100%) brightness(2); }

/* Button outlines */
[data-theme="dark"] .btn-outline-primary {
    border-color: var(--cv-accent); color: var(--cv-accent);
}
[data-theme="dark"] .btn-outline-primary:hover {
    background-color: var(--cv-accent); border-color: var(--cv-accent); color: #fff;
}
[data-theme="dark"] .btn-outline-success {
    border-color: var(--cv-success); color: var(--cv-success);
}
[data-theme="dark"] .btn-outline-success:hover {
    background-color: var(--cv-success); border-color: var(--cv-success); color: #fff;
}
[data-theme="dark"] .btn-outline-danger {
    border-color: var(--cv-danger); color: var(--cv-danger);
}
[data-theme="dark"] .btn-outline-danger:hover {
    background-color: var(--cv-danger); border-color: var(--cv-danger); color: #fff;
}
[data-theme="dark"] .btn-outline-warning {
    border-color: var(--cv-warning); color: var(--cv-warning);
}
[data-theme="dark"] .btn-outline-warning:hover {
    background-color: var(--cv-warning); border-color: var(--cv-warning); color: #000;
}
[data-theme="dark"] .btn-outline-info {
    border-color: var(--cv-accent); color: var(--cv-accent);
}
[data-theme="dark"] .btn-outline-info:hover {
    background-color: var(--cv-accent); border-color: var(--cv-accent); color: #fff;
}
[data-theme="dark"] .btn-outline-light {
    border-color: var(--cv-border-2); color: var(--cv-text-2);
}
[data-theme="dark"] .btn-outline-light:hover {
    background-color: var(--cv-surface-3); color: var(--cv-text);
}
[data-theme="dark"] .btn-link         { color: var(--cv-accent); }
[data-theme="dark"] .btn-link:hover   { color: var(--cv-accent-h); }
[data-theme="dark"] .btn-secondary    { background-color: var(--cv-surface-3); border-color: var(--cv-border-2); color: var(--cv-text-2); }
[data-theme="dark"] .btn-secondary:hover { background-color: var(--cv-surface-2); color: var(--cv-text); }
[data-theme="dark"] .btn-light        { background-color: var(--cv-surface-3); border-color: var(--cv-border-2); color: var(--cv-text); }
[data-theme="dark"] .btn-light:hover  { background-color: var(--cv-surface-2); }

/* Badges */
[data-theme="dark"] .badge.bg-primary   { background-color: var(--cv-accent)    !important; color: #fff                    !important; }
[data-theme="dark"] .badge.bg-success   { background-color: var(--cv-success)   !important; color: #fff                    !important; }
[data-theme="dark"] .badge.bg-danger    { background-color: var(--cv-danger)    !important; color: #fff                    !important; }
[data-theme="dark"] .badge.bg-warning   { background-color: var(--cv-warning)   !important; color: #000                    !important; }
[data-theme="dark"] .badge.bg-info      { background-color: var(--cv-accent)    !important; color: #fff                    !important; }
[data-theme="dark"] .badge.bg-light     { background-color: var(--cv-surface-3) !important; color: var(--cv-text-2)        !important; }
[data-theme="dark"] .badge.bg-dark      { background-color: var(--cv-surface-2) !important; color: var(--cv-text)          !important; }
[data-theme="dark"] .badge.text-bg-primary   { background-color: var(--cv-accent)    !important; color: #fff               !important; }
[data-theme="dark"] .badge.text-bg-secondary { background-color: var(--cv-surface-3) !important; color: var(--cv-text-2)   !important; }
[data-theme="dark"] .badge.text-bg-success   { background-color: var(--cv-success)   !important; color: #fff               !important; }
[data-theme="dark"] .badge.text-bg-danger    { background-color: var(--cv-danger)    !important; color: #fff               !important; }
[data-theme="dark"] .badge.text-bg-warning   { background-color: var(--cv-warning)   !important; color: #000               !important; }
[data-theme="dark"] .badge.text-bg-light     { background-color: var(--cv-surface-3) !important; color: var(--cv-text-2)   !important; }

/* List groups */
[data-theme="dark"] .list-group-item {
    background-color: var(--cv-surface);
    border-color: var(--cv-border);
    color: var(--cv-text);
}
[data-theme="dark"] .list-group-item:hover { background-color: var(--cv-surface-2); }
[data-theme="dark"] .list-group-item.active {
    background-color: var(--cv-accent);
    border-color: var(--cv-accent);
    color: #fff;
}
[data-theme="dark"] a.list-group-item-action { color: var(--cv-text-2); }
[data-theme="dark"] a.list-group-item-action:hover { background-color: var(--cv-surface-2); color: var(--cv-text); }

/* Dropdown */
[data-theme="dark"] .dropdown-menu {
    background-color: var(--cv-surface);
    border-color: var(--cv-border-2);
    box-shadow: var(--cv-shadow-md);
}
[data-theme="dark"] .dropdown-item { color: var(--cv-text-2); }
[data-theme="dark"] .dropdown-item:hover,
[data-theme="dark"] .dropdown-item:focus { background-color: var(--cv-surface-3); color: var(--cv-text); }
[data-theme="dark"] .dropdown-divider { border-color: var(--cv-border); }
[data-theme="dark"] .dropdown-header  { color: var(--cv-text-3); }

/* Modal */
[data-theme="dark"] .modal-content {
    background-color: var(--cv-surface);
    border-color: var(--cv-border-2);
    color: var(--cv-text);
}
[data-theme="dark"] .modal-header {
    background-color: var(--cv-surface-2);
    border-color: var(--cv-border);
}
[data-theme="dark"] .modal-footer {
    background-color: var(--cv-surface-2);
    border-color: var(--cv-border);
}
[data-theme="dark"] .modal-title { color: var(--cv-text); }
[data-theme="dark"] .modal-backdrop { background-color: #000; }

/* Nav tabs & pills */
[data-theme="dark"] .nav-tabs          { border-color: var(--cv-border); }
[data-theme="dark"] .nav-tabs .nav-link { color: var(--cv-text-3); border-color: transparent; }
[data-theme="dark"] .nav-tabs .nav-link:hover { color: var(--cv-text); border-color: var(--cv-border); }
[data-theme="dark"] .nav-tabs .nav-link.active {
    background-color: var(--cv-surface);
    border-color: var(--cv-border-2) var(--cv-border-2) var(--cv-surface);
    color: var(--cv-text);
}
[data-theme="dark"] .nav-pills .nav-link { color: var(--cv-text-3); }
[data-theme="dark"] .nav-pills .nav-link.active { background-color: var(--cv-accent); color: #fff; }

/* Accordion */
[data-theme="dark"] .accordion-item    { background-color: var(--cv-surface); border-color: var(--cv-border); }
[data-theme="dark"] .accordion-button {
    background-color: var(--cv-surface-2);
    color: var(--cv-text);
    box-shadow: none;
}
[data-theme="dark"] .accordion-button:not(.collapsed) {
    background-color: var(--cv-accent-sub);
    color: var(--cv-accent);
    box-shadow: inset 0 -1px 0 var(--cv-border);
}
[data-theme="dark"] .accordion-button::after {
    filter: invert(1) brightness(1.5);
}
[data-theme="dark"] .accordion-body    { background-color: var(--cv-surface); color: var(--cv-text); }

/* Offcanvas */
[data-theme="dark"] .offcanvas {
    background-color: var(--cv-surface);
    color: var(--cv-text);
}
[data-theme="dark"] .offcanvas-header { border-color: var(--cv-border); }

/* Hr */
[data-theme="dark"] hr { border-color: var(--cv-border); opacity: 1; }

/* Breadcrumb */
[data-theme="dark"] .breadcrumb-item a     { color: var(--cv-accent); }
[data-theme="dark"] .breadcrumb-item.active { color: var(--cv-text-3); }
[data-theme="dark"] .breadcrumb-item + .breadcrumb-item::before { color: var(--cv-text-4); }

/* Pagination */
[data-theme="dark"] .page-link {
    background-color: var(--cv-surface);
    border-color: var(--cv-border);
    color: var(--cv-text-2);
}
[data-theme="dark"] .page-link:hover { background-color: var(--cv-surface-3); color: var(--cv-text); }
[data-theme="dark"] .page-item.active .page-link { background-color: var(--cv-accent); border-color: var(--cv-accent); color: #fff; }
[data-theme="dark"] .page-item.disabled .page-link { background-color: var(--cv-surface); color: var(--cv-text-4); }

/* Tooltip / Popover */
[data-theme="dark"] .popover {
    background-color: var(--cv-surface);
    border-color: var(--cv-border-2);
}
[data-theme="dark"] .popover-header {
    background-color: var(--cv-surface-2);
    border-color: var(--cv-border);
    color: var(--cv-text);
}
[data-theme="dark"] .popover-body { color: var(--cv-text-2); }
[data-theme="dark"] .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after,
[data-theme="dark"] .bs-popover-top > .popover-arrow::after  { border-top-color: var(--cv-surface); }
[data-theme="dark"] .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after,
[data-theme="dark"] .bs-popover-bottom > .popover-arrow::after { border-bottom-color: var(--cv-surface); }

/* Spinner */
[data-theme="dark"] .spinner-border { color: var(--cv-accent); }

/* General bg utilities */
[data-theme="dark"] .bg-white   { background-color: var(--cv-surface)   !important; }
[data-theme="dark"] .bg-light   { background-color: var(--cv-surface-2) !important; }
[data-theme="dark"] .bg-dark    { background-color: var(--cv-surface-3) !important; }
[data-theme="dark"] .bg-body    { background-color: var(--cv-bg)        !important; }
[data-theme="dark"] .bg-body-secondary  { background-color: var(--cv-surface-2) !important; }
[data-theme="dark"] .bg-body-tertiary   { background-color: var(--cv-surface-3) !important; }

/* Border utilities */
[data-theme="dark"] .border        { border-color: var(--cv-border)   !important; }
[data-theme="dark"] .border-light  { border-color: var(--cv-border)   !important; }
[data-theme="dark"] .border-dark   { border-color: var(--cv-border-2) !important; }

/* Native Bootstrap Toast (our custom uses .toast-container) */
[data-theme="dark"] .toast {
    background-color: var(--cv-surface);
    border-color: var(--cv-border-2);
    color: var(--cv-text);
}
[data-theme="dark"] .toast-header {
    background-color: var(--cv-surface-2);
    border-color: var(--cv-border);
    color: var(--cv-text);
}

/* ═══════════════════════════════════════════════════════════════════
   Responsive – Navbar
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 600px) {
    .cv-navbar { padding: 0 .75rem; height: 48px; }
    .cv-user-email { display: none; }
    .cv-btn { padding: .3rem .4rem; font-size: .78rem; }
}

/* ═══════════════════════════════════════════════════════════════════
   Responsive – Vault layout (sidebar collapses on mobile)
   ═══════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════
   Vault – cloud-style toolbar / breadcrumb / folder-contents grid
   ═══════════════════════════════════════════════════════════════════ */

.vault-toolbar {
    display: flex; align-items: center; gap: .6rem;
    padding: .55rem .8rem;
    border-bottom: 1px solid var(--cv-border);
    background: var(--cv-surface-2);
    flex-wrap: wrap;
}
.vault-toolbar-actions { flex-shrink: 0; }
.vault-search { max-width: 220px; }

/* Drawer toggle / close + drawer backdrop default to hidden on desktop.
   The @media (max-width: 768px) block below flips them on. */
.vault-drawer-toggle,
.vault-drawer-close,
.vault-sidebar-backdrop { display: none; }

.vault-breadcrumb { display: flex; align-items: center; gap: .25rem; flex-wrap: wrap; }
.vault-crumb {
    background: transparent; border: 0;
    color: var(--cv-text); font-weight: 500;
    padding: .2rem .45rem; border-radius: 6px;
    cursor: pointer; font-size: .9rem;
}
.vault-crumb:hover { background: var(--cv-surface-3); color: var(--cv-accent); }
.vault-crumb-sep { color: var(--cv-text-3); margin: 0 .15rem; user-select: none; }

.vault-grid-area { flex: 1; overflow-y: auto; padding: 1rem; }
.vault-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: .8rem;
}
.vault-card {
    display: flex; flex-direction: column; align-items: center;
    padding: .9rem .55rem .65rem;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    cursor: pointer;
    transition: background .12s, transform .08s, box-shadow .12s;
    text-align: center;
    user-select: none;
}
.vault-card:hover {
    background: var(--cv-surface-2);
    box-shadow: 0 2px 12px rgba(0,0,0,.08);
    transform: translateY(-1px);
}
.vault-card-icon { font-size: 2.4rem; line-height: 1; margin-bottom: .35rem; }
.vault-card-name {
    width: 100%; font-size: .85rem; font-weight: 500;
    color: var(--cv-text); word-break: break-word;
}
.vault-card-meta { margin-top: .2rem; font-size: .7rem; }
.vault-card-folder .vault-card-name { color: var(--cv-accent); }

.vault-grid-empty {
    text-align: center; color: var(--cv-text-3);
    padding: 4rem 1rem;
}
.vault-grid-empty-icon { font-size: 3rem; opacity: .5; margin-bottom: .5rem; }

/* ── Multi-select (mobile long-press) ──────────────────────────────────
   The selection bar appears above the regular toolbar when one or more
   cards are picked. Cards in the selection set get a tinted background
   and a small ✓ chip in their top-right corner so it's obvious which
   ones are about to be acted on. The hover transform on .vault-card is
   already disabled on mobile so the chip doesn't jitter on tap. */
.vault-selection-bar {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .55rem .85rem;
    background: var(--cv-accent, #3b82f6);
    color: #fff;
    border-bottom: 1px solid var(--cv-border);
}
.vault-selection-close {
    background: rgba(255, 255, 255, .15);
    border: none;
    color: #fff;
    font-size: 1rem;
    width: 32px;
    height: 32px;
    border-radius: 6px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.vault-selection-close:hover { background: rgba(255, 255, 255, .25); }
.vault-selection-count {
    font-weight: 600;
    font-size: .92rem;
}
.vault-selection-bar .btn-outline-danger {
    background: rgba(255, 255, 255, .12);
    border-color: rgba(255, 255, 255, .35);
    color: #fff;
}
.vault-selection-bar .btn-outline-danger:hover {
    background: #f06a6a;
    border-color: #f06a6a;
}

/* ── Swipe-to-reveal action row (mobile only) ────────────────────────
   Each card is wrapped in a .cv-swipe-row. On desktop the wrapper is
   layout-neutral (no positioning, action button hidden). On mobile the
   wrapper turns into an overflow:hidden container; the action button
   sits behind the card on the right side, and JS toggles the
   .cv-swipe-row--open class to translate the card leftward and reveal
   the button. The button itself uses a plain Blazor @onclick to fire
   the deletion -- no extra interop. */
.cv-swipe-row {
    position: relative;
}
.cv-swipe-action {
    display: none;
}

@media (max-width: 768px) {
    .cv-swipe-row {
        overflow: hidden;
        border-radius: 8px;
        /* Take over the rounded corners from .vault-card so the row's
           bg behaves consistently with the card it wraps. */
        margin-bottom: .3rem;
    }
    .cv-swipe-row > .vault-card {
        position: relative;
        z-index: 1;
        margin-bottom: 0;
        transition: transform .2s cubic-bezier(.16, 1, .3, 1);
        /* Suppress the touch-callout (long-press context menu on iOS)
           so the swipe gesture isn't fighting with the system. */
        -webkit-touch-callout: none;
    }
    .cv-swipe-row--open > .vault-card {
        transform: translateX(-92px);
    }

    .cv-swipe-action {
        display: flex;
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        width: 92px;
        align-items: center;
        justify-content: center;
        background: #d73a3a;
        border: 0;
        color: #fff;
        cursor: pointer;
        z-index: 0;
        /* The action sits below the card until the row is open, so a
           tap on the closed row's right edge should NOT register on
           the action. pointer-events flips on with the open state. */
        pointer-events: none;
    }
    .cv-swipe-row--open .cv-swipe-action {
        pointer-events: auto;
    }
    .cv-swipe-action:active {
        background: #b32d2d;
    }
}

.vault-card-selected {
    background: rgba(59, 130, 246, .12) !important;
    border-color: var(--cv-accent, #3b82f6) !important;
}
.vault-card-check {
    position: absolute;
    top: 6px;
    right: 8px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--cv-accent, #3b82f6);
    color: #fff;
    font-size: .72rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
}
.vault-card { position: relative; }
@media (max-width: 768px) {
    /* In list view the icon already lives on the left; put the ✓ over
       the icon corner so it doesn't compete with the meta size text. */
    .vault-card-check {
        top: 50%;
        right: 12px;
        transform: translateY(-50%);
        position: absolute;
    }
    .vault-card-selected .vault-card-meta { display: none; }
}

@media (max-width: 768px) {
    .vault-layout {
        flex-direction: column;
        overflow: visible;
        position: relative;
    }

    /* The sidebar becomes an off-canvas drawer on mobile: full screen
       height, slides in from the left, sits over the main pane with a
       semi-transparent backdrop. Default state is OFF-screen
       (translateX(-100%)); .cv-mobile-open (set by Vault.razor when
       _navDrawerOpen is true) animates it into view. */
    .vault-sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        width: min(85vw, 320px);
        max-height: 100vh;
        z-index: 1050;
        background: var(--cv-bg);
        border-right: 1px solid var(--cv-border);
        border-bottom: none;
        overflow-y: auto;
        transform: translateX(-100%);
        transition: transform .22s cubic-bezier(.16, 1, .3, 1);
        box-shadow: 8px 0 24px rgba(0, 0, 0, .4);
        display: flex;
        flex-direction: column;
    }
    .vault-sidebar.cv-mobile-open { transform: translateX(0); }

    /* Backdrop behind the drawer. Rendered by Vault.razor only when the
       drawer is open, so on desktop it doesn't exist in the DOM. */
    .vault-sidebar-backdrop {
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, .55);
        z-index: 1040;
        animation: fd-backdrop-in .18s ease-out;
    }

    /* Show the close button only on mobile; on desktop the sidebar is
       always visible and the X would be confusing. */
    .vault-drawer-close {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        background: transparent;
        border: none;
        color: var(--cv-text-muted);
        font-size: 1rem;
        cursor: pointer;
        padding: .2rem .35rem;
        margin-left: auto;
        border-radius: 6px;
    }
    .vault-drawer-close:hover { color: var(--cv-text); background: rgba(255, 255, 255, .06); }
    .sidebar-header {
        display: flex;
        align-items: center;
        gap: .5rem;
    }

    /* Drawer toggle button -- inline only on mobile (hidden on desktop
       below via the default rule). */
    .vault-drawer-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        background: transparent;
        border: 1px solid var(--cv-border);
        color: var(--cv-text);
        border-radius: 8px;
        width: 36px;
        height: 36px;
        cursor: pointer;
        flex-shrink: 0;
    }
    .vault-drawer-toggle:hover {
        background: var(--cv-surface-2);
        border-color: var(--cv-text-muted);
    }

    /* Sticky toolbar / breadcrumb so the user always knows which folder
       they're in even after scrolling a long file list. */
    .vault-toolbar {
        position: sticky;
        top: 0;
        z-index: 10;
        padding: .45rem .65rem;
        gap: .4rem;
        flex-wrap: nowrap;
    }
    .vault-breadcrumb {
        flex: 1;
        min-width: 0;
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .vault-breadcrumb::-webkit-scrollbar { display: none; }
    .vault-crumb {
        flex-shrink: 0;
        white-space: nowrap;
        font-size: .88rem;
    }
        /* Desk-only search bar -- not enough room in the mobile toolbar
       once the drawer toggle + breadcrumb + upload buttons are in
       there. Search via the drawer is fine for now. */
    .vault-search { display: none; }
    .vault-toolbar-actions { gap: .25rem; }
    .vault-toolbar-actions .btn { padding: .35rem .5rem; }

    .vault-content { overflow-y: auto; }
    .content-section { padding: 1rem; }
    .folder-label,
    .file-node { padding: .5rem .75rem; }

    /* Grid switches to a single-column dense LIST view -- each item is
       a touch-sized row (~60 px tall) instead of a square card. The
       square-card grid wastes vertical space and tiny names truncate
       beyond uselessness. List view shows full names with ellipsis,
       puts size on the right, and gets the touch target the user
       expects from a mobile file manager. */
    .vault-grid {
        grid-template-columns: 1fr;
        gap: .3rem;
    }
    .vault-card {
        flex-direction: row;
        align-items: center;
        gap: .85rem;
        padding: .6rem .85rem;
        text-align: left;
        min-height: 60px;
        border-radius: 8px;
    }
    .vault-card:hover { transform: none; }
    .vault-card-icon {
        font-size: 1.85rem;
        margin-bottom: 0;
        width: 2rem;
        flex-shrink: 0;
        text-align: center;
    }
    .vault-card-name {
        flex: 1;
        width: auto;
        font-size: .92rem;
        margin: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        word-break: normal;
    }
    .vault-card-meta {
        margin-top: 0;
        font-size: .75rem;
        flex-shrink: 0;
        white-space: nowrap;
    }
    .vault-card-folder .vault-card-meta { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   KeePass – mobile-only UI controls (hidden on desktop)
   ═══════════════════════════════════════════════════════════════════ */

.kp-mob-groups-btn,
.kp-mob-back-btn,
.kp-sidebar-close-btn { display: none !important; }

/* ═══════════════════════════════════════════════════════════════════
   Responsive – KeePass: sidebar drawer + entry detail overlay
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {

    .kp-browser { position: relative; }
    .kp-middle { width: 100%; flex: 1; border-right: none; }

    .kp-sidebar {
        position: absolute;
        top: 0; left: 0;
        width: 80%; max-width: 300px; height: 100%;
        z-index: 60;
        transform: translateX(-110%);
        transition: transform .22s cubic-bezier(.4,0,.2,1);
    }
    .kp-sidebar.kp-sidebar--open {
        transform: translateX(0);
        box-shadow: 4px 0 32px rgba(0,0,0,.5);
    }

    .kp-mob-backdrop {
        position: absolute;
        inset: 0;
        background: rgba(0,0,0,.45);
        z-index: 59;
    }

    .kp-sidebar-close-btn {
        display: flex !important;
        align-items: center; justify-content: center;
        background: transparent; border: none;
        color: #8fa8c8; font-size: 1rem;
        cursor: pointer; padding: .2rem .35rem;
        border-radius: 4px; line-height: 1;
    }
    .kp-sidebar-close-btn:hover { background: rgba(255,255,255,.12); color: #fff; }

    .kp-mob-groups-btn {
        display: inline-flex !important;
        align-items: center; gap: .4rem;
        background: rgba(0,0,0,.06); border: 1px solid rgba(0,0,0,.1);
        color: var(--cv-text); border-radius: 6px;
        padding: .3rem .65rem; font-size: .8rem; font-weight: 600;
        cursor: pointer; flex-shrink: 0;
        max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .kp-mob-groups-btn:hover { background: rgba(0,0,0,.1); }

    .kp-middle-title { display: none; }

    .kp-detail-panel {
        position: absolute; top: 0; left: 0; right: 0; bottom: 0;
        z-index: 50;
        background: var(--cv-surface);
        transform: translateX(110%);
        transition: transform .22s cubic-bezier(.4,0,.2,1);
        display: flex !important;
        flex-direction: column;
        overflow-y: auto;
    }
    .kp-detail-panel.kp-detail-panel--open { transform: translateX(0); }

    .kp-mob-back-btn {
        display: flex !important;
        align-items: center; gap: .4rem;
        background: var(--cv-surface-2); border: none;
        border-bottom: 1px solid var(--cv-border);
        color: var(--cv-accent); font-size: .85rem; font-weight: 500;
        cursor: pointer; padding: .75rem 1rem;
        flex-shrink: 0; text-align: left; width: 100%;
    }
    .kp-mob-back-btn:hover { background: var(--cv-surface-3); }
}

@media (max-width: 600px) {
    .kp-page-toolbar { flex-wrap: wrap; gap: .4rem; padding: .6rem .75rem; }
    .kp-entry-title { font-size: .82rem; }
    .kp-field-row { flex-direction: column; gap: .15rem; }
    .kp-field-label { min-width: unset !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   Responsive – Admin page
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 600px) {
    .admin-page { padding: 1rem .75rem; }
    .admin-stats { grid-template-columns: repeat(2, 1fr); }
    .stat-value { font-size: 1.35rem; }
    .admin-section { padding: 1rem .75rem; }

    .admin-table th:nth-child(3), .admin-table td:nth-child(3),
    .admin-table th:nth-child(4), .admin-table td:nth-child(4),
    .admin-table th:nth-child(5), .admin-table td:nth-child(5) { display: none; }
}

/* ── Mobile-only: drawer + safe-area-aware tweaks ───────────────────── */

.cv-drawer-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .55);
    z-index: 1040;
    animation: cv-fade-in .15s ease-out;
}

.cv-drawer {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 78%;
    max-width: 320px;
    background: var(--cv-surface);
    box-shadow: 4px 0 20px rgba(0, 0, 0, .35);
    z-index: 1050;
    display: flex;
    flex-direction: column;
    /* Inset for status bar / gesture nav so the header isn't cropped. */
    padding-top:    var(--cv-safe-top, 0px);
    padding-bottom: var(--cv-safe-bottom, 0px);
    animation: cv-slide-in .18s ease-out;
}

@keyframes cv-fade-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes cv-slide-in { from { transform: translateX(-100%); } to { transform: translateX(0); } }

.cv-drawer-header {
    padding: 1.25rem 1.25rem 1rem;
    background: linear-gradient(135deg, #16213e 0%, #0f3460 100%);
    color: #fff;
}
.cv-drawer-brand { font-size: 1.15rem; font-weight: 700; letter-spacing: -.3px; }
.cv-drawer-email { font-size: .8rem; color: #8fa8c8; margin-top: .25rem; }

.cv-drawer-nav {
    flex: 1;
    overflow-y: auto;
    padding: .5rem 0;
}
.cv-drawer-item {
    display: flex;
    align-items: center;
    gap: .85rem;
    padding: .85rem 1.25rem;
    color: var(--cv-text);
    text-decoration: none;
    font-size: .95rem;
    user-select: none;
}
.cv-drawer-item:active,
.cv-drawer-item-active { background: var(--cv-surface-3); font-weight: 600; }
.cv-drawer-icon { font-size: 1.15rem; width: 1.5rem; text-align: center; }

.cv-drawer-footer {
    padding: 1rem 1.25rem;
    border-top: 1px solid var(--cv-border);
}

/* Mobile navbar tweaks. The shared .cv-navbar from app.css is sized
   for a desktop; on a phone we want a slimmer bar that doesn't eat
   half the screen height. */
@media (max-width: 768px) {
    .cv-navbar {
        padding: .4rem .5rem;
        min-height: 48px;
    }
    .cv-navbar .cv-brand { font-size: 1rem; }
    .cv-navbar .cv-btn   { padding: .25rem .5rem; font-size: .9rem; }
}

/* ── Mobile Vault page (file browser) ──────────────────────────────── */
.vault-mobile { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.vault-mobile-bar { background: var(--cv-surface-2); flex-shrink: 0; gap: .5rem; }
.vault-mobile .mobile-file-list { flex: 1; overflow-y: auto; }
.vault-mobile-sheet {
    position: sticky;
    bottom: 0;
    background: var(--cv-surface);
    border-top: 1px solid var(--cv-border);
    padding: 1rem;
    box-shadow: 0 -4px 16px rgba(0, 0, 0, .25);
    /* Inset for the gesture-nav so the sheet's buttons don't sit under it. */
    padding-bottom: calc(1rem + var(--cv-safe-bottom, 0px));
}

.mobile-file-item { cursor: pointer; user-select: none; transition: background .1s; }
.mobile-file-item:active { background: var(--cv-surface-3); }
.min-width-0 { min-width: 0; }

/* ── Kanban drop-target highlight (driven by kanban-drag.js) ─────────── */
.kanban-lane.kanban-lane-droptarget {
    background: rgba(13, 110, 253, .08);
    box-shadow: inset 0 0 0 2px var(--bs-primary, #0d6efd);
    border-radius: .35rem;
}

/* ── Kanban drag via pointer events (see kanban-drag.js) ─────────────── */
.kanban-card-ghost {
    box-shadow: 0 12px 32px rgba(0, 0, 0, .45);
    cursor: grabbing;
}
.kanban-card-being-dragged {
    opacity: .35;
    /* No transform — we don't want the original to shift, just dim it
       so the user sees the ghost is the active payload. */
}
[data-cv-kc-id] {
    /* Disable native text selection on draggable cards so a press-and-hold
       doesn't enter selection mode before pointermove triggers our drag. */
    user-select: none;
    -webkit-user-select: none;
    touch-action: none;
    cursor: grab;
}
[data-cv-kc-id]:active { cursor: grabbing; }

/* ── Recovery phrase (B2) ─────────────────────────────────────────────── */
.recovery-words {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
    gap: .35rem .75rem;
    margin: 1rem 0;
    padding-left: 1.5rem;
}
.recovery-words li { font-size: .95rem; }
.recovery-words code {
    background: var(--bs-tertiary-bg, #f2f2f2);
    padding: .1rem .4rem;
    border-radius: .25rem;
}
