/* =================================================================
 * main.css — RTL base styles + theme variables
 * =================================================================
 * Theme variables centralize colors and sizing.
 *
 * Theme selection (per-user, stored as ui.theme in user_settings):
 *   "auto"  → no [data-theme] attribute on <html>; the media query
 *             at the bottom of this section follows the OS preference.
 *   "light" → <html data-theme="light">; same as :root defaults.
 *   "dark"  → <html data-theme="dark">; the dark overrides apply.
 *
 * Status pills, inline-styled cards in views, and other hard-coded
 * colors stay light — only the chrome that uses these variables flips.
 * Improving the per-component dark contrast is a follow-up.
 */

:root {
    --color-bg:           #f5f7fa;
    --color-surface:      #ffffff;
    --color-text:         #1a202c;
    --color-text-muted:   #718096;
    --color-border:       #e2e8f0;
    --color-primary:      #2d3748;
    --color-primary-text: #ffffff;
    --color-accent:       #3182ce;
    --color-accent-hover: #2b6cb0;
    --color-success:      #0a8a3a;
    --color-danger:       #c53030;
    --color-warning:      #d69e2e;
}

/* Explicit dark theme — user chose "חשוך" in personal settings. */
[data-theme="dark"] {
    --color-bg:           #0f172a;
    --color-surface:      #1e293b;
    --color-text:         #f1f5f9;
    --color-text-muted:   #94a3b8;
    --color-border:       #334155;
    --color-primary:      #020617;
    --color-primary-text: #f1f5f9;
    --color-accent:       #60a5fa;
    --color-accent-hover: #93c5fd;
}

/* Auto theme — no explicit attribute, follow OS dark-mode preference. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]):not([data-theme="dark"]) {
        --color-bg:           #0f172a;
        --color-surface:      #1e293b;
        --color-text:         #f1f5f9;
        --color-text-muted:   #94a3b8;
        --color-border:       #334155;
        --color-primary:      #020617;
        --color-primary-text: #f1f5f9;
        --color-accent:       #60a5fa;
        --color-accent-hover: #93c5fd;
    }
}

:root {

    --space-xs: 0.25rem;
    --space-sm: 0.5rem;
    --space-md: 1rem;
    --space-lg: 1.5rem;
    --space-xl: 2rem;

    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 12px;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
    --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.08);
    --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12);

    --sidebar-width: 240px;
    --header-height: 56px;

    --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Rubik", "Arial Hebrew", Arial, sans-serif;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html, body { height: 100%; }

body {
    font-family: var(--font-family);
    font-size: 14px;
    line-height: 1.6;
    color: var(--color-text);
    background: var(--color-bg);
    direction: rtl;
}

/* Native <select> in this RTL UI. Many selects are width:100%, so the OS
   dropdown renders full-width and the (short) RTL option text pins to the far
   edge — that's the "escaping to the other side". Capping the width keeps the
   control AND its native dropdown a sane size (the popup matches the control's
   width). Global, so it fixes every over-wide select at once. max-width only
   ever shrinks over-wide selects — narrower ones are untouched. RTL alignment
   kept; the inherited dir="ltr" on specific fields still wins by specificity. */
select {
    direction: rtl;
    text-align: right;
    max-width: 30rem;
}
select option {
    direction: rtl;
}
    color: var(--color-accent);
    text-decoration: none;
}
a:hover { color: var(--color-accent-hover); text-decoration: underline; }

/* ---------- Layout ---------- */
.app-shell {
    display: grid;
    grid-template-columns: var(--sidebar-width) 1fr;
    grid-template-rows: var(--header-height) 1fr;
    grid-template-areas:
        "sidebar header"
        "sidebar main";
    min-height: 100vh;
}

.app-header {
    grid-area: header;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    padding: 0 var(--space-lg);
    box-shadow: var(--shadow-sm);
    position: sticky;
    top: 0;
    z-index: 10;
}

.app-header h1 {
    font-size: 1rem;
    font-weight: 600;
}

.app-header .header-actions {
    margin-inline-start: auto;
    display: flex;
    gap: var(--space-md);
    align-items: center;
}

.app-sidebar {
    grid-area: sidebar;
    background: var(--color-primary);
    color: var(--color-primary-text);
    padding: var(--space-md) 0;
    overflow-y: auto;
}

.app-sidebar .brand {
    padding: 0 var(--space-lg) var(--space-lg);
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    margin-bottom: var(--space-md);
    font-weight: 700;
    font-size: 1rem;
}

.app-sidebar nav ul { list-style: none; }
.app-sidebar nav li a {
    display: block;
    padding: var(--space-sm) var(--space-lg);
    color: rgba(255, 255, 255, 0.8);
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}
.app-sidebar nav li a:hover {
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    text-decoration: none;
}
.app-sidebar nav li a.active {
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
    border-inline-start: 3px solid var(--color-accent);
}

.app-main {
    grid-area: main;
    padding: var(--space-lg);
    overflow-y: auto;
}

.app-footer {
    text-align: center;
    color: var(--color-text-muted);
    font-size: 0.85rem;
    padding: var(--space-md);
}

/* ---------- Card / Surface ---------- */
.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-lg);
    box-shadow: var(--shadow-sm);
}
.card + .card { margin-top: var(--space-md); }
.card h2 { margin-bottom: var(--space-md); font-size: 1.125rem; }

/* ---------- Status pills ---------- */
.pill {
    display: inline-block;
    padding: 0.125rem 0.5rem;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 500;
}
.pill-ok      { background: #d1fae5; color: #064e3b; }
.pill-down    { background: #fee2e2; color: #7f1d1d; }
.pill-pending { background: #fef3c7; color: #78350f; }

/* ---------- Buttons ---------- */
.btn {
    display: inline-block;
    padding: 0.5rem 1rem;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font: inherit;
    cursor: pointer;
    text-decoration: none;
}
.btn-primary { background: var(--color-accent); color: #fff; }
.btn-primary:hover { background: var(--color-accent-hover); color: #fff; text-decoration: none; }
.btn-ghost { background: transparent; color: var(--color-text); border-color: var(--color-border); }

/* ---------- Mobile responsive ---------- */
@media (max-width: 768px) {
    .app-shell {
        grid-template-columns: 1fr;
        grid-template-areas:
            "header"
            "main";
    }
    .app-sidebar {
        position: fixed;
        inset-inline-start: 0;
        top: var(--header-height);
        bottom: 0;
        width: var(--sidebar-width);
        transform: translateX(100%);  /* RTL: hide off-screen to the right */
        transition: transform 0.2s;
        z-index: 20;
    }
    .app-sidebar.open { transform: translateX(0); }
}

/* ---------- Loading state ---------- */
.is-loading {
    pointer-events: none;
    opacity: 0.6;
}

/* ---------- A11y (Phase 11.2d) ---------- */
/* Skip-to-main-content link — invisible by default, visible on keyboard focus.
   Lets keyboard / screen-reader users bypass the sidebar nav on every page. */
.skip-link {
    position: absolute;
    inset-inline-start: -9999px;
    top: auto;
    z-index: 100;
    background: #1d4ed8;
    color: #fff;
    padding: 0.5rem 1rem;
    border-radius: 0 0 6px 6px;
    text-decoration: none;
    font-weight: 600;
}
.skip-link:focus {
    inset-inline-start: 1rem;
    top: 0;
}

/* Strong focus indicator — Chrome's default outline is too thin for
   accessibility. 3px solid + offset visible on every interactive element. */
:focus-visible {
    outline: 3px solid #1d4ed8;
    outline-offset: 2px;
    border-radius: 2px;
}
.btn:focus-visible {
    outline-offset: 3px;
}

/* Visually-hidden helper — text only readable by screen readers. Use it
   to add context to icon-only buttons, e.g. <button aria-label="..."> or
   <span class="sr-only">. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Honor reduced-motion preference for users who get sick from animations. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ── Map feature (Phase A) ───────────────────────────────────────────── */
.kv-map-blocklabel span {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    color: #1e3a5f;
    background: rgba(255, 255, 255, 0.7);
    padding: 0 4px;
    border-radius: 3px;
    white-space: nowrap;
    pointer-events: none;
    transform: translateX(-50%);
}
.kv-map-label {
    font-size: 12px;
    direction: rtl;
}
/* Area-grave caption — text that sits ON the shape, no floating tooltip box.
   Strips Leaflet's default white background / border / shadow / pointer so a
   tiny 1×2 m area-grave shows a clean centered label instead of a bubble. */
.kv-map-agtag,
.kv-map-agtag.leaflet-tooltip {
    background: transparent;
    border: 0;
    box-shadow: none;
    padding: 0;
    margin: 0;
    font-size: 10px;
    line-height: 1.05;
    font-weight: 700;
    color: #0f172a;
    text-align: center;
    direction: rtl;
    white-space: nowrap;
    text-shadow: 0 0 2px #fff, 0 0 3px #fff, 0 0 1px #fff;
    pointer-events: none;
}
.kv-map-agtag::before,
.kv-map-agtag::after { display: none !important; }

/* (Old per-layer .kv-tf* transform handles removed — the amber
   group outline (.kv-gh*) now handles single + multi-selection
   resize/rotate.) */

/* Area-grave caption — anchored at the TOP-RIGHT corner, flowing down-left,
   font scaled to the shape (set inline by placeAgLabel), never overflowing. */
.kv-agtag { background: transparent; border: 0; }
.kv-agtag .kv-agtag-in {
    position: absolute;
    top: 0; right: 0;               /* top-right corner sits on the AG corner */
    text-align: right;
    direction: rtl;
    white-space: nowrap;
    overflow: hidden;
    font-weight: 700;
    line-height: 1.05;
    color: #0f172a;
    text-shadow: 0 0 2px #fff, 0 0 3px #fff, 0 0 1px #fff;
    pointer-events: none;
}

/* Edit-management menu (snapshots / reset / grid) — shown only in edit mode */
.kv-editmenu {
    background: #fff; border: 1px solid #94a3b8; border-radius: 8px;
    padding: 8px 10px; box-shadow: 0 1px 6px rgba(0,0,0,.18);
    font-size: .85rem; min-width: 196px; max-width: 240px; direction: rtl;
    display: flex; flex-direction: column; gap: 8px;
}
.kv-em-title { font-weight: 700; font-size: .92rem; }
.kv-em-sec { border-top: 1px solid #e2e8f0; padding-top: 6px; display: flex; flex-direction: column; gap: 5px; }
.kv-em-sec:first-of-type { border-top: 0; padding-top: 0; }
.kv-em-h { font-weight: 600; color: #475569; font-size: .8rem; }
.kv-em-row { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.kv-em-row input[type=text] { flex: 1; min-width: 0; }
.kv-em-row input[type=number] { width: 46px; }
.kv-em-row select { flex: 1; min-width: 0; }
.kv-em-check { gap: 6px; }
.kv-em-btn {
    background: #f1f5f9; border: 1px solid #cbd5e1; border-radius: 5px;
    padding: 4px 9px; cursor: pointer; font: inherit; font-size: .82rem;
}
.kv-em-btn:hover { background: #e2e8f0; }
.kv-em-danger { color: #b91c1c; border-color: #fca5a5; }
.kv-em-danger:hover { background: #fee2e2; }

/* Per-grave caption (owner / deceased) — centered in the cell, rotates with
   it, font scaled to the cell (set inline by placeGraveLabel), hidden when
   the cell is too small to read. */
.kv-gravelabel { background: transparent; border: 0; }
.kv-gravelabel .kv-gravelabel-in {
    position: absolute;
    top: 0; left: 0;                 /* anchored at the cell centroid */
    transform-origin: center center;
    white-space: nowrap;
    overflow: hidden;
    text-align: center;
    direction: rtl;
    font-weight: 600;
    line-height: 1.0;
    color: #1f2937;
    text-shadow: 0 0 2px #fff, 0 0 3px #fff;
    pointer-events: none;
}
/* Leaflet container should inherit our font + sit under modals. */
#kvMap .leaflet-container { font-family: inherit; }

/* Group-selection transform handles (corner = resize, ⟳ = rotate).
   Drawn around the union bbox of all selected layers in multi-select. */
.kv-gh {
    background: #f59e0b;
    border: 1px solid #fff;
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(0,0,0,0.2);
}
.kv-gh-nw, .kv-gh-se { cursor: nwse-resize; }
.kv-gh-ne, .kv-gh-sw { cursor: nesw-resize; }
.kv-gh-rotate {
    background: #fff;
    border: 1px solid #f59e0b;
    border-radius: 50%;
    color: #d97706;
    font-size: 14px;
    line-height: 16px;
    text-align: center;
    cursor: grab;
}
.kv-gh-rotate:active { cursor: grabbing; }
/* Touch: keep the handle visually small but widen the grab area with a
   transparent pad (events on ::before dispatch to the handle element).
   No position:relative here — Leaflet already positions .kv-gh absolutely. */
@media (hover: none), (pointer: coarse) {
    .kv-gh::before { content: ''; position: absolute; inset: -11px; }
}

/* Map edit toggle button (Phase B) */
.kv-map-editbtn {
    background: #fff;
    border: 1px solid #94a3b8;
    border-radius: 6px;
    padding: 6px 12px;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 1px 4px rgba(0,0,0,0.15);
}
.kv-map-editbtn.active { background: #16a34a; color: #fff; border-color: #15803d; }

/* Edit-control button group (Phase 22f) — ✏ main + ▼ panel-toggles dropdown.
   Sit side-by-side in the bottom-left corner. ▼ is hidden until edit mode
   is on (no panels to toggle otherwise). */
.kv-editctl {
    display: flex; gap: 4px; align-items: stretch;
    position: relative;          /* anchors the absolutely-positioned popup */
}
.kv-map-paneltoggle {
    background: #fff;
    border: 1px solid #94a3b8;
    border-radius: 6px;
    padding: 6px 10px;
    font: inherit; font-weight: 600;
    cursor: pointer;
    box-shadow: 0 1px 4px rgba(0,0,0,0.15);
    line-height: 1;
}
.kv-map-paneltoggle:hover { background: #f1f5f9; }

/* Per-panel show/hide checkbox popup. Opens above the ▼ button. */
.kv-panel-popup {
    position: absolute;
    bottom: calc(100% + 4px); inset-inline-start: 0;
    background: #fff;
    border: 1px solid #94a3b8;
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.18);
    padding: 8px 10px;
    min-width: 200px;
    z-index: 1000;
    direction: rtl;
}
.kv-panel-popup-title {
    font-weight: 700; margin-bottom: 6px; color: #475569;
    font-size: .82rem;
}
.kv-panel-popup-row {
    display: flex; align-items: center; gap: 8px;
    padding: 4px 4px;
    cursor: pointer;
    font-size: .9rem;
    border-radius: 4px;
}
.kv-panel-popup-row:hover { background: #f1f5f9; }
.kv-panel-popup-row input[type=checkbox] { margin: 0; cursor: pointer; }

/* Map grave icon (anonymous / burial-tier) */
.kv-grave-icon { font-size: 14px; color: #6b7280; text-align: center; line-height: 16px; }

/* Floating-panel chrome: drag header + collapse button. Applied to the
   edit-management menu, GPS anchor, and background controls — anything
   the user might want to move out of the way or temporarily shrink.
   The wrapper uses CSS transform so it doesn't fight Leaflet's control-
   corner positioning (left/top stay as Leaflet placed them; transform
   shifts the box visually). */
.kv-fp { position: relative; }
.kv-fp-bar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 6px;
    cursor: move; user-select: none;
    /* Pull to panel edges so the header sits flush with the rounded border.
       The two panels we wrap have padding: 8px 10px — these negatives match. */
    margin: -8px -10px 6px -10px;
    padding: 5px 9px;
    background: #f1f5f9; border-bottom: 1px solid #e2e8f0;
    border-radius: 7px 7px 0 0;
    font-weight: 700; font-size: .85rem;
    color: #1e293b;
    touch-action: none;  /* let pointer events drive the drag on touch */
}
.kv-fp-bar:hover { background: #e2e8f0; }
.kv-fp-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kv-fp-collapse {
    border: 1px solid transparent; background: transparent; cursor: pointer;
    width: 22px; height: 22px; font-size: 1.05rem; line-height: 1; padding: 0;
    border-radius: 4px; color: #475569;
}
.kv-fp-collapse:hover { background: #fff; border-color: #cbd5e1; color: #1e293b; }
.kv-fp.kv-fp-collapsed > *:not(.kv-fp-bar) { display: none !important; }
.kv-fp.kv-fp-collapsed .kv-fp-bar {
    margin-bottom: -8px; border-bottom: 0; border-radius: 6px;
}

/* Snapped to an edge (Phase 22c) — drop the outer rounded corner so
   the panel reads as docked, and tighten the bar's accent stripe. */
.kv-fp.kv-fp-snap-right {
    border-top-right-radius: 0; border-bottom-right-radius: 0;
    border-right-width: 0;
    box-shadow: -1px 1px 4px rgba(0,0,0,0.15);
}
.kv-fp.kv-fp-snap-left {
    border-top-left-radius: 0; border-bottom-left-radius: 0;
    border-left-width: 0;
    box-shadow: 1px 1px 4px rgba(0,0,0,0.15);
}
.kv-fp.kv-fp-snap-right .kv-fp-bar {
    border-top-right-radius: 0;
    border-left: 3px solid #9333ea;   /* docked marker on the inboard side */
}
.kv-fp.kv-fp-snap-left .kv-fp-bar {
    border-top-left-radius: 0;
    border-right: 3px solid #9333ea;
}

/* ─── Phase 22d — real Photoshop-style dock columns ───────────────────
   The map page wraps #kvMap in a flex container with sibling
   .kv-dock-left and .kv-dock-right rails. Rails are width:0 (collapsed)
   until JS adds .kv-dock-has-panels — then they grow to 240px and the
   map shrinks via flex:1 to make room. Panels moved into a rail get
   .kv-fp-docked and lose their transform/shadow so they sit in normal
   flex flow, stacked top-to-bottom, each at the rail's full width. */
.kv-map-wrap {
    display: flex; align-items: stretch; width: 100%; gap: 0;
    border: 1px solid var(--color-border); border-radius: 8px;
    background: #f8fafc; overflow: hidden;
    /* The page is RTL (Hebrew). Without `direction: ltr` here, the flex
       order flips — .kv-dock-left ends up VISUALLY on the right and
       vice versa. We force LTR for the flex layout but restore RTL on
       every child so Hebrew text inside the panels still reads right. */
    direction: ltr;
}
.kv-map-wrap > .kv-map,
.kv-map-wrap > .kv-dock {
    direction: rtl;
}
.kv-map-wrap > .kv-map {
    flex: 1 1 auto; min-width: 0; height: 100%;
    /* The map div's own border was on the floor; the wrap carries it now. */
    border-radius: 0;
}
.kv-dock {
    flex: 0 0 0; width: 0;
    overflow: hidden; box-sizing: border-box;
    background: #f1f5f9;
    transition: flex-basis .15s ease, width .15s ease, padding .15s ease;
    display: flex; flex-direction: column; gap: 6px;
}
.kv-dock.kv-dock-has-panels {
    flex: 0 0 240px; width: 240px;
    padding: 8px;
    overflow-y: auto;
    border-inline-start: 1px solid var(--color-border);
}
.kv-dock.kv-dock-left.kv-dock-has-panels {
    border-inline-start: 0;
    border-inline-end: 1px solid var(--color-border);
}

/* A docked panel: ignore the transform-based floating styles and let
   flex stack it. */
.kv-fp.kv-fp-docked {
    transform: none !important;
    box-shadow: none;
    width: 100%; margin: 0;
    border-radius: 6px;
    border-width: 1px !important;
    position: relative;
    /* The Geoman/Leaflet control corner pushes its kids with margin —
       drop those when docked. */
    margin-bottom: 0;
}
.kv-fp.kv-fp-docked + .kv-fp.kv-fp-docked {
    margin-top: 4px;
}
.kv-fp.kv-fp-docked .kv-fp-bar {
    cursor: grab;
}
.kv-fp.kv-fp-docked .kv-fp-bar:active {
    cursor: grabbing;
}

/* Edge highlight while dragging a panel near a dock zone (Phase 22e).
   Inset shadow on the corresponding side tells the user "release here
   and the panel docks". Inline on the map element so it's drawn above
   the map vectors but below Leaflet's marker pane / popup pane. */
.kv-map.kv-dock-target-left {
    box-shadow: inset 5px 0 0 0 rgba(147, 51, 234, 0.55);
    transition: box-shadow .08s ease-out;
}
.kv-map.kv-dock-target-right {
    box-shadow: inset -5px 0 0 0 rgba(147, 51, 234, 0.55);
    transition: box-shadow .08s ease-out;
}

/* Map background control (Phase E) */
.kv-map-bgctl {
    background: #fff; border: 1px solid #94a3b8; border-radius: 6px;
    padding: 8px 10px; box-shadow: 0 1px 4px rgba(0,0,0,0.15);
    font-size: .85rem; display: flex; flex-direction: column; gap: 6px; min-width: 150px;
}
.kv-bgctl-title { font-weight: 700; }
.kv-bgctl-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.kv-bgctl-row input[type=range] { flex: 1; }
.kv-bgctl-upload { cursor: pointer; color: #2563eb; font-weight: 600; }
.kv-bgctl-btn {
    background: #f1f5f9; border: 1px solid #cbd5e1; border-radius: 4px;
    padding: 4px 8px; cursor: pointer; font: inherit; font-size: .82rem;
}
.kv-bgctl-btn.active { background: #9333ea; color: #fff; border-color: #7e22ce; }
.kv-bgctl-danger { color: #b91c1c; }

/* Background editor (Phase 22) — numeric fields + actions */
.kv-bgctl-hint {
    font-size: .72rem; color: #64748b; line-height: 1.35;
    background: #f8fafc; border: 1px dashed #cbd5e1; border-radius: 4px;
    padding: 4px 6px;
}
.kv-bgctl-grid {
    display: grid; grid-template-columns: 1fr 1fr; gap: 4px 6px;
    margin-top: 2px;
}
.kv-bgctl-cell {
    display: flex; flex-direction: column; gap: 1px;
    font-size: .72rem; color: #475569;
}
.kv-bgctl-cell input[type=number] {
    width: 100%; padding: 3px 5px; font: inherit; font-size: .82rem;
    border: 1px solid #cbd5e1; border-radius: 4px; box-sizing: border-box;
    direction: ltr; text-align: left;
}
.kv-bgctl-cell input[type=number]:focus {
    outline: 0; border-color: #9333ea; box-shadow: 0 0 0 2px rgba(147,51,234,.15);
}
.kv-bgctl-row > button { flex: 1; }
.kv-bgctl-btn.kv-bgctl-save {
    background: #dcfce7; border-color: #86efac; color: #166534; font-weight: 600;
}
.kv-bgctl-btn.kv-bgctl-save:hover { background: #bbf7d0; }

/* Phase 22 — merge panel history rows */
.kv-merge-hist {
    display: flex; flex-direction: column; gap: 3px;
    font-size: .78rem;
    max-height: 200px;
    overflow-y: auto;
}
.kv-merge-hist-row {
    display: flex; align-items: center; justify-content: space-between; gap: 4px;
    padding: 3px 4px;
    border: 1px solid #e2e8f0; border-radius: 4px;
    background: #f8fafc;
}
.kv-merge-hist-row > button { padding: 2px 6px; font-size: .72rem; }
.kv-merge-hist-row.kv-merge-hist-row-active {
    background: #fef3c7; border-color: #f59e0b;
}

/* Phase 23 — per-record file explorer */
/* DOC-T8e — Finder-style explorer. No dedicated dropzone — the whole
   card accepts file drops and shows a subtle overlay while dragging. */
.kv-doc-explorer {
    display: flex; flex-direction: column; gap: 6px;
    margin-top: 8px;
    position: relative;
}
.kv-doc-explorer-dragover::after {
    content: '⬇ שחרר כדי להעלות';
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    background: rgba(37, 99, 235, .08);
    border: 2px dashed #2563eb; border-radius: 8px;
    color: #1d4ed8; font-size: 1rem; font-weight: 600;
    pointer-events: none; z-index: 10;
}
.kv-doc-progress {
    margin-top: 4px; padding: 5px 9px;
    background: #ecfeff; border: 1px solid #67e8f9; border-radius: 4px;
    color: #155e75; font-size: .82rem;
}

/* DOC-T8h — Finder-style status footer. Centered, muted, sits below the
   grid. Counts files + folders + selection, updates on every render. */
.kv-doc-footer {
    padding: 4px 10px;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
    text-align: center;
    font-size: .75rem;
    color: #64748b;
    min-height: 24px;
}

/* DOC-T8d — fixed-height container so the card doesn't shrink when
   empty or expand when overflowing. Internal scroll keeps it tidy. */
.kv-doc-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    gap: 8px;
    min-height: 320px;
    max-height: 480px;
    overflow-y: auto;
    padding: 8px;
    background: #f8fafc;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
    align-content: start;       /* don't stretch rows to fill the height */
}
.kv-doc-empty {
    grid-column: 1 / -1;
    align-self: center;
    justify-self: center;
    text-align: center; color: #94a3b8;
    padding: 24px 12px;
    font-size: .9rem;
}
.kv-doc-loading {
    grid-column: 1 / -1;
    align-self: center;
    justify-self: center;
    color: #64748b; padding: 12px;
}
/* DOC-T8e — Finder-style cards: no border, no per-bucket tint.
   Just an icon/thumbnail on top, name below. Selection = subtle blue
   pill behind the name + icon. Hover = subtle gray. */
.kv-doc-card {
    position: relative;
    display: flex; flex-direction: column;
    align-items: center; text-align: center;
    padding: 6px 4px 4px;
    border-radius: 6px;
    cursor: default;
    user-select: none;
    transition: background .12s;
}
.kv-doc-card:hover     { background: rgba(0, 0, 0, .04); }
.kv-doc-card-selected  { background: #dbeafe; }
.kv-doc-card-selected:hover { background: #bfdbfe; }
.kv-doc-card-droptarget { background: rgba(34, 197, 94, .18); outline: 2px solid #16a34a; outline-offset: -2px; }
.kv-doc-card-folder    { cursor: pointer; }
.kv-doc-card-folder:hover { background: rgba(217, 119, 6, .08); }

/* Tile = the icon/thumbnail block; overlay sits inside it. */
.kv-doc-tile {
    position: relative;
    width: 76px; height: 76px;
    display: flex; align-items: center; justify-content: center;
    overflow: hidden;
    border-radius: 4px;
}
.kv-doc-tile img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    border-radius: 4px;
    box-shadow: 0 1px 2px rgba(0,0,0,.1);
}
.kv-doc-tile-icon {
    font-size: 3rem; line-height: 1;
    filter: drop-shadow(0 1px 1px rgba(0,0,0,.1));
}
/* Filename underneath the tile — Finder-style two-line clamp */
.kv-doc-tile-name {
    margin-top: 4px;
    font-size: .75rem;
    color: #1e293b;
    line-height: 1.2;
    max-width: 96px;
    word-break: break-word;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    text-overflow: ellipsis;
}
.kv-doc-card-selected .kv-doc-tile-name { color: #1e3a8a; }
/* Back-compat shims so list view's anchor still gets a color */
.kv-doc-card-preview { color: inherit; text-decoration: none; }
.kv-doc-card-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.kv-doc-card-icon { display: flex; align-items: center; justify-content: center; height: 100%; font-size: 2.2rem; color: #64748b; }

/* DOC-T8d — explorer toolbar (top strip with new-folder, breadcrumb,
   selection bar, view switch). One unified bar replaces the scattered
   button rows we had before. */
.kv-doc-toolbar {
    display: flex; align-items: center; gap: 12px;
    padding: 6px 10px;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
    min-height: 38px;
    flex-wrap: wrap;
}
.kv-doc-toolbar-left, .kv-doc-toolbar-right {
    display: flex; align-items: center; gap: 6px;
}
.kv-doc-breadcrumb {
    flex: 1 1 auto;
    min-width: 0;
    font-size: .82rem; color: #475569;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kv-doc-crumb {
    color: #2563eb; text-decoration: none;
    padding: 1px 4px; border-radius: 3px;
}
.kv-doc-crumb:hover { background: #e0e7ff; }
.kv-doc-crumb-sep { color: #94a3b8; }

/* DOC-T8i — kv-doc-tb-btn family removed; replaced by .kv-doc-seg + .kv-doc-tb-more */

/* DOC-T8e — Finder folder = same tile shape, just an amber-tinted icon.
   The .kv-doc-card-folder hover background is set above. */
.kv-doc-card-folder .kv-doc-tile-icon { color: #d97706; }
.kv-doc-card-del-btn { display: none; }   /* Phase 23 inline delete buttons replaced by context menu */
.kv-doc-chip { display: none; }            /* old chips replaced by overlay + context menu */
.kv-doc-chip-folder { display: none; }

/* DOC-T8e — corner overlay badge: bottom-end of the tile (Finder uses
   bottom-right for shortcut arrow; we put bucket indicator there too). */
.kv-doc-overlay {
    position: absolute; bottom: 1px; right: 1px;
    width: 18px; height: 18px; line-height: 18px;
    text-align: center;
    background: #fff;
    border-radius: 50%;
    font-size: .72rem;
    box-shadow: 0 1px 2px rgba(0,0,0,.2);
    z-index: 2;
}
.kv-doc-overlay-system  { color: #d97706; }
.kv-doc-overlay-private { color: #b91c1c; }
.kv-doc-chip-type { display: none; }

/* DOC-T8b — selection state (click/Ctrl-click/Shift-click) */
.kv-doc-card-selected {
    box-shadow: 0 0 0 2px #2563eb inset;
    background: #eff6ff;
}
.kv-doc-card-droptarget {
    box-shadow: 0 0 0 3px #16a34a inset;
    background: #dcfce7;
}
.kv-doc-card[draggable="true"] { cursor: grab; }
.kv-doc-card[draggable="true"]:active { cursor: grabbing; }

/* DOC-T8g — selection bar removed from toolbar entirely; batch actions
   now live in the context menu of any selected file. */

/* DOC-T8b — right-click context menu */
.kv-doc-ctx {
    position: fixed; z-index: 2000;
    min-width: 180px;
    background: #fff; border: 1px solid #cbd5e1; border-radius: 6px;
    box-shadow: 0 4px 16px rgba(0,0,0,.15);
    padding: 4px;
    font-size: .85rem;
    direction: rtl;
}
.kv-doc-ctx button {
    display: block; width: 100%; text-align: start;
    padding: 6px 10px;
    background: none; border: none; cursor: pointer;
    font: inherit; color: #1e293b;
    border-radius: 4px;
}
.kv-doc-ctx button:hover { background: #f1f5f9; }
.kv-doc-ctx button.kv-doc-ctx-danger { color: #b91c1c; }
.kv-doc-ctx button.kv-doc-ctx-danger:hover { background: #fef2f2; }

/* DOC-T8b — properties modal */
.kv-doc-modal-bg {
    position: fixed; inset: 0; z-index: 1900;
    background: rgba(15,23,42,.4);
    display: flex; align-items: center; justify-content: center;
}
.kv-doc-modal {
    background: #fff; border-radius: 8px; min-width: 320px; max-width: 90vw;
    padding: 16px 18px; box-shadow: 0 10px 30px rgba(0,0,0,.2);
    direction: rtl;
}
.kv-doc-modal h3 { margin: 0 0 12px; font-size: 1rem; color: #1e293b; }
.kv-doc-modal table { width: 100%; border-collapse: collapse; }
.kv-doc-modal th, .kv-doc-modal td { text-align: start; padding: 4px 6px; border-bottom: 1px solid #f1f5f9; font-size: .85rem; }
.kv-doc-modal th { color: #64748b; font-weight: 600; width: 35%; }
.kv-doc-modal td { color: #1e293b; word-break: break-word; }
.kv-doc-modal-actions { margin-top: 12px; text-align: start; }
.kv-doc-modal-actions button {
    background: #2563eb; color: #fff; border: none; border-radius: 4px;
    padding: 6px 14px; font: inherit; cursor: pointer;
}

/* DOC-T8c — view switch (grid ↔ list) */
/* DOC-T8i — iOS-style segmented control. Shared base for both
   bucket-toggle and view-switch so they look like one coherent set. */
.kv-doc-seg {
    display: inline-flex;
    background: #f1f5f9;
    border-radius: 7px;
    padding: 2px;
    font-size: .78rem;
    line-height: 1;
}
.kv-doc-seg button {
    background: transparent; border: none; cursor: pointer;
    padding: 4px 10px;
    font: inherit; color: #64748b;
    border-radius: 5px;
    transition: background .12s, color .12s, box-shadow .12s;
    min-width: 30px;
}
.kv-doc-seg button:hover { color: #1e293b; }
.kv-doc-seg button.kv-doc-seg-active {
    background: #fff;
    color: #1e293b;
    box-shadow: 0 1px 2px rgba(0,0,0,.08), 0 0 0 0.5px rgba(0,0,0,.04);
    font-weight: 600;
}
/* Color carries the bucket meaning — blue for public, red for private */
.kv-doc-bucket-toggle button[data-bucket="public"].kv-doc-seg-active  { color: #1d4ed8; }
.kv-doc-bucket-toggle button[data-bucket="private"].kv-doc-seg-active { color: #b91c1c; }
.kv-doc-viewswitch button { font-size: .9rem; padding: 4px 8px; }

/* DOC-T8e — context menu separator + submenu chevron */
.kv-doc-ctx-sep {
    height: 1px; background: #e2e8f0; margin: 4px 0;
}
.kv-doc-ctx-has-sub::after {
    content: '‹'; float: left; color: #94a3b8; font-weight: 700;
}
.kv-doc-ctx button.kv-doc-ctx-heading {
    color: #94a3b8; font-size: .7rem; padding: 4px 10px 2px;
    cursor: default; font-weight: 600;
    text-transform: uppercase; letter-spacing: .02em;
    background: none !important;
}

/* DOC-T8i — ⋯ toolbar button: matches segmented controls' pill aesthetic */
.kv-doc-tb-more {
    background: #f1f5f9;
    border: none;
    border-radius: 7px;
    padding: 0;
    width: 32px; height: 26px;
    font-size: 1.05rem; font-weight: 700; line-height: 1;
    color: #475569; cursor: pointer;
    transition: background .12s, color .12s;
}
.kv-doc-tb-more:hover { background: #e2e8f0; color: #1e293b; }

/* DOC-T8f — ⋯ menu button on cards. On desktop, only show on hover/focus
   /selected. On touch (no hover) ALWAYS visible — primary menu trigger. */
.kv-doc-card-more {
    position: absolute; top: 3px; right: 3px;
    width: 26px; height: 26px;
    background: rgba(255, 255, 255, 0.95);
    border: 1px solid #e2e8f0; border-radius: 50%;
    text-align: center; line-height: 22px;
    cursor: pointer;
    font-size: 1rem; font-weight: 700;
    color: #475569;
    padding: 0;
    z-index: 3;
}
.kv-doc-card-more:hover { background: #f1f5f9; color: #1e293b; }
@media (hover: hover) {
    .kv-doc-card-more { opacity: 0; transition: opacity .12s; }
    .kv-doc-card:hover .kv-doc-card-more,
    .kv-doc-card:focus-within .kv-doc-card-more,
    .kv-doc-card-selected .kv-doc-card-more { opacity: 1; }
}

/* DOC-T8f — toolbar select-mode button removed (now in ⋯ menu) */

/* DOC-T8f — when select-mode is on, show a faint checkbox overlay on each
   tile so the mode is visually obvious. Selected ones get a filled check. */
.kv-doc-explorer-selectmode .kv-doc-card[data-doc-id]::before {
    content: '○';
    position: absolute; top: 3px; left: 3px;
    width: 22px; height: 22px; line-height: 20px;
    text-align: center;
    background: rgba(255, 255, 255, 0.95);
    border: 1px solid #cbd5e1; border-radius: 50%;
    color: #94a3b8; font-size: 1rem; font-weight: 700;
    z-index: 2;
}
.kv-doc-explorer-selectmode .kv-doc-card-selected[data-doc-id]::before {
    content: '✓';
    background: #2563eb; border-color: #2563eb; color: #fff;
}

/* DOC-T8i — responsive toolbar. Gentle bumps only — keep the iOS pill
   aesthetic tight. The segmented controls already have nice tap targets
   (their padding gives ~30px height) — no need to bloat them. */
@media (max-width: 600px) {
    .kv-doc-toolbar { padding: 5px 7px; gap: 5px; }
    /* Slightly bigger touch targets on the segmented pills, no width bloat */
    .kv-doc-seg button { padding: 6px 11px; font-size: .8rem; }
    .kv-doc-viewswitch button { padding: 6px 9px; font-size: 1rem; }
    .kv-doc-tb-more { width: 34px; height: 30px; font-size: 1.1rem; }
    /* Breadcrumb on its own line on very small screens */
    .kv-doc-breadcrumb {
        flex-basis: 100%; order: 99;
        padding-top: 2px; border-top: 1px solid #f1f5f9;
    }
    /* Tiles slightly bigger for thumb-friendly */
    .kv-doc-tile { width: 84px; height: 84px; }
    .kv-doc-tile-icon { font-size: 3.2rem; }
    .kv-doc-tile-name { max-width: 104px; font-size: .8rem; }
    .kv-doc-grid { min-height: 360px; max-height: 60vh; }
    .kv-doc-ctx { min-width: 220px; }
    .kv-doc-ctx button { padding: 10px 14px; font-size: .9rem; }
}

/* DOC-T8f — touch devices specifically: bigger ⋯, comfortable spacing */
@media (hover: none) {
    .kv-doc-card-more {
        width: 30px; height: 30px; line-height: 26px;
        font-size: 1.15rem;
    }
    /* The drag-onto-folder gesture doesn't work on touch — disable
       draggable visually to avoid the "grab" cursor showing. */
    .kv-doc-card[draggable="true"] { cursor: pointer; }
    /* Bigger tap targets on toolbar buttons even on phones with hover-spoofing */
    .kv-doc-tb-btn { min-height: 40px; }
}

/* DOC-T8d — list layout: dense rows, tight padding, small icons. The
   container keeps its fixed-height scroll from .kv-doc-grid. */
.kv-doc-grid-list {
    display: block;
    padding: 0;                  /* rows have their own padding */
    background: #fff;
    grid-template-columns: none;
}
.kv-doc-row {
    display: grid;
    /* DOC-T8j — 6 cols: icon · name · type · size · date · ⋯ */
    grid-template-columns: 22px 1fr 90px 60px 110px 26px;
    align-items: center;
    gap: 6px;
    padding: 3px 6px 3px 8px;
    border-bottom: 1px solid #f1f5f9;
    font-size: .78rem;
    line-height: 1.2;
    cursor: pointer;
}
.kv-doc-row:last-child { border-bottom: none; }
.kv-doc-row-header {
    position: sticky; top: 0; z-index: 1;
    background: #f8fafc;
    font-weight: 600; color: #64748b; font-size: .7rem;
    text-transform: uppercase; letter-spacing: .02em;
    cursor: default;
    padding: 4px 8px;
}
.kv-doc-row.kv-doc-card-selected { background: #eff6ff; }
.kv-doc-row.kv-doc-card-droptarget { background: #dcfce7; }
.kv-doc-row-icon { position: relative; font-size: .95rem; text-align: center; }
.kv-doc-row-overlay {
    position: absolute; top: -3px; right: -5px;
    font-size: .55rem;
    background: #fff; border-radius: 50%;
    width: 12px; height: 12px; line-height: 12px;
    box-shadow: 0 1px 2px rgba(0,0,0,.15);
}
.kv-doc-row-name {
    color: #1e293b; text-decoration: none;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kv-doc-row-name:hover { text-decoration: underline; color: #1d4ed8; }
.kv-doc-row-type, .kv-doc-row-size, .kv-doc-row-date {
    color: #64748b; font-size: .72rem;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* List-mode folder rows: subtle amber hover */
.kv-doc-grid-list .kv-doc-card-folder.kv-doc-row { background: #fffbeb; }
.kv-doc-grid-list .kv-doc-card-folder.kv-doc-row:hover { background: #fef3c7; }
.kv-doc-grid-list .kv-doc-row:hover { background: #f8fafc; }
.kv-doc-grid-list .kv-doc-card-folder.kv-doc-row:hover { background: #fef3c7; }
/* Hide the grid-only preview/icon blocks when in list mode */
.kv-doc-grid-list .kv-doc-card-preview img,
.kv-doc-grid-list .kv-doc-card-icon,
.kv-doc-grid-list .kv-doc-overlay { display: none; }
/* In list view we use .kv-doc-row-more (inline) instead of the grid's
   absolute-positioned .kv-doc-card-more — hide the latter inside rows. */
.kv-doc-grid-list .kv-doc-card-more { display: none; }

/* DOC-T8j — inline ⋯ button for list rows (last grid cell) */
.kv-doc-row-more {
    background: transparent; border: none;
    width: 26px; height: 26px;
    font-size: 1rem; font-weight: 700;
    color: #94a3b8; cursor: pointer;
    border-radius: 4px;
    padding: 0;
    align-self: center;
}
.kv-doc-row-more:hover { background: #f1f5f9; color: #1e293b; }
@media (hover: none) {
    .kv-doc-row-more { color: #64748b; width: 30px; height: 30px; font-size: 1.1rem; }
}

/* ========================================================================
   M1 — Mobile responsive foundation
   ========================================================================
   Three breakpoints used across the app:
     - 768px  → sidebar collapses to overlay (existing, from line 225)
     - 600px  → toolbar buttons shrink (used by doc-explorer)
     - 480px  → "phone" mode: tables → cards, grids stack, dense layouts
   Tablet-friendly main content padding kicks in at 768px.
   ======================================================================== */

/* Main content gutter — phones need real edge padding, not the inherited
   sidebar layout's zero-padding. */
@media (max-width: 768px) {
    .app-main { padding: 12px 10px; }
}
@media (max-width: 480px) {
    .app-main { padding: 10px 8px; }
}

/* ---------- Generic table styles (cross-cutting baseline) ----------
   Most list views built ad-hoc <table>s without shared styling. Add a
   minimal opt-in baseline so the M2 wrap looks polished. */
.kv-table {
    width: 100%; border-collapse: collapse; font-size: 0.9rem;
}
.kv-table th, .kv-table td {
    padding: 0.5rem 0.6rem; text-align: start; vertical-align: middle;
    border-bottom: 1px solid var(--color-border, #e5e7eb);
}
.kv-table thead th {
    font-weight: 600; color: var(--color-text-muted, #64748b);
    background: #f8fafc; font-size: 0.82rem;
    position: sticky; top: 0; z-index: 1;
}
.kv-table tbody tr:hover { background: #f8fafc; }

/* ---------- .kv-table-wrap — horizontal scroll for wide tables ----------
   Wrap any table with `<div class="kv-table-wrap">` to keep the page
   layout from exploding on narrow viewports. The shadow at edges hints
   that there's more content scrollable. */
.kv-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: var(--radius-sm, 6px);
    /* The shadows hint "there's more horizontally" — common iOS pattern */
    background:
        linear-gradient(90deg, #fff 30%, rgba(255,255,255,0)) start center,
        linear-gradient(-90deg, #fff 30%, rgba(255,255,255,0)) end center,
        radial-gradient(farthest-side at 0 50%, rgba(0,0,0,0.12), transparent) start center,
        radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,0.12), transparent) end center;
    background-repeat: no-repeat;
    background-size: 30px 100%, 30px 100%, 14px 100%, 14px 100%;
    background-attachment: local, local, scroll, scroll;
}
.kv-table-wrap > table,
.kv-table-wrap > .kv-table {
    min-width: 100%;
    /* Avoid letting cells word-wrap into mush; a horizontal scroll is
       readable, a 4-line cell isn't. Override per-cell if needed. */
    white-space: nowrap;
}
.kv-table-wrap > table th,
.kv-table-wrap > table td { white-space: nowrap; }

/* ---------- .kv-table-cards — card-flip layout below 480px ----------
   For "hot" list views (customers, purchases, payments) we want each row
   to render as a stacked card on phones instead of a horizontally-scrolling
   table. Markup convention: every <td> gets `data-label="header text"`.
   The label renders to the right of each cell value on mobile. */
@media (max-width: 480px) {
    .kv-table-cards { display: block; white-space: normal !important; }
    .kv-table-cards thead { display: none; }
    .kv-table-cards tbody, .kv-table-cards tr {
        display: block; width: 100%;
    }
    .kv-table-cards tr {
        border: 1px solid var(--color-border, #e5e7eb);
        border-radius: var(--radius-sm, 6px);
        padding: 8px 10px;
        margin-bottom: 8px;
        background: #fff;
    }
    .kv-table-cards td {
        display: flex; justify-content: space-between; align-items: baseline;
        gap: 12px;
        padding: 4px 0;
        border: none;
        white-space: normal !important;
        font-size: 0.88rem;
    }
    .kv-table-cards td::before {
        content: attr(data-label);
        color: var(--color-text-muted, #64748b);
        font-size: 0.75rem; font-weight: 600;
        flex-shrink: 0;
    }
    /* Cells without data-label (action buttons, etc.) span full width
       without a label column. */
    .kv-table-cards td:not([data-label]) {
        justify-content: flex-end;
        padding-top: 6px;
        border-top: 1px solid #f1f5f9;
        margin-top: 4px;
    }
    .kv-table-cards td:not([data-label])::before { content: none; }
    /* Wrap modifier becomes a no-op when cards mode is on (cards already
       reflow vertically); kill the gradient shadows in this mode. */
    .kv-table-wrap.has-cards { background: none; }
}

/* ---------- Definition lists (key-value show pages) ----------
   show.php uses `grid-template-columns: 200px 1fr` patterns. On phones
   the 200px label eats half the screen. .kv-deflist makes the grid
   responsive: 2-col on desktop, stacked on phone. */
.kv-deflist {
    display: grid;
    grid-template-columns: minmax(140px, max-content) 1fr;
    gap: 6px 16px;
    align-items: baseline;
}
.kv-deflist dt {
    color: var(--color-text-muted, #64748b);
    font-size: 0.82rem; font-weight: 600;
}
.kv-deflist dd { margin: 0; }
@media (max-width: 480px) {
    .kv-deflist {
        grid-template-columns: 1fr;
        gap: 2px 0;
    }
    .kv-deflist dt { padding-top: 6px; }
    .kv-deflist dd { padding-bottom: 6px; border-bottom: 1px solid #f1f5f9; }
    .kv-deflist dd:last-child { border-bottom: none; }
}

/* ---------- Generic form-row helper ----------
   For multi-column form layouts that should stack on phones. Replaces
   ad-hoc `display:grid; grid-template-columns: repeat(2,1fr)` in views. */
.kv-form-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 10px 14px;
}

/* ---------- Tap-target friendly buttons on touch devices ----------
   Existing .btn is a bit cramped (~30px) on phones; bump it without
   touching desktop layout. */
@media (hover: none), (max-width: 480px) {
    .btn { min-height: 40px; padding: 9px 16px; font-size: 0.92rem; }
    .btn-ghost, .btn-secondary { min-height: 38px; }
    input[type="text"], input[type="email"], input[type="tel"],
    input[type="number"], input[type="search"], input[type="password"],
    input[type="date"], textarea, select {
        min-height: 40px; padding: 9px 11px; font-size: 16px;  /* 16px avoids iOS auto-zoom */
    }
}

/* ---------- Hide / show by viewport (utility classes) ---------- */
.kv-only-mobile  { display: none; }
.kv-only-desktop { display: initial; }
@media (max-width: 480px) {
    .kv-only-mobile  { display: initial; }
    .kv-only-desktop { display: none; }
}

/* ---------- Stack-on-phone helper ----------
   Add `.kv-stack-on-phone` to a flex container that has multiple
   side-by-side controls (filters bar, header actions) so they stack
   vertically with full-width children on phones. */
@media (max-width: 480px) {
    .kv-stack-on-phone {
        flex-direction: column !important;
        align-items: stretch !important;
    }
    .kv-stack-on-phone > * { width: 100%; }
}

/* ---------- Card padding shrinks on phones ---------- */
@media (max-width: 480px) {
    .card { padding: 12px 10px; }
}

/* ---------- Sticky table headers in scroll-wrap don't make sense
   inside a horizontally-scrolling container; disable. */
.kv-table-wrap .kv-table thead th { position: static; }

/* ---------- M4/M6 polish: header on phones ----------
   Push button base styling (replaces former inline styles in header.php).
   On phones below 600px we hide the label and show only the bell icon. */
.header-push-btn {
    padding: 5px 10px;
    border: 1px solid var(--color-border);
    background: #fff;
    border-radius: 14px;
    cursor: pointer;
    font: inherit; font-size: 0.8rem;
    color: inherit;
}
.header-push-btn.header-push-btn--on { background: #d1fae5; color: #065f46; }
.header-push-btn:hover { background: #f1f5f9; }
.header-push-label { display: inline; }

@media (max-width: 600px) {
    .app-header { padding: 0 8px; gap: 6px; }
    .app-header h1 { display: none; }   /* sidebar already shows app name */
    /* Current-company chip is up to 240px wide with nowrap — on a phone it
       crushes the search box. Hide it here; the sidebar drawer carries the
       company name on mobile (see .sidebar-company). !important is required
       because the chip carries an inline display:inline-flex. */
    .app-header .header-company { display: none !important; }
    .app-header .header-search { margin: 0; flex: 1; max-width: none; }
    .app-header .header-search input { font-size: 16px; padding: 7px 9px; }  /* avoid iOS zoom */
    /* Push button → just the bell. The label hides, the button becomes a
       compact circle. !important because the button has inline display:''
       set by JS. */
    .header-push-btn {
        width: 36px; height: 36px; padding: 0;
        border-radius: 50%;
        font-size: 1rem; line-height: 1;
        display: flex !important; align-items: center; justify-content: center;
    }
    .header-push-label { display: none; }
    /* Show just the leading icon character from the label text via tiny CSS
       trick: hide label and rely on a fixed icon. The actual emoji shown
       is set in the label text — but since hidden, we add it here. */
    .header-push-btn::before { content: '🔔'; }
    .header-push-btn.header-push-btn--on::before { content: '🔔'; color: #065f46; }
}
@media (max-width: 600px) {
    /* Health pill not useful on mobile — hide entirely */
    #health-pill { display: none !important; }
}

/* ---------- M4 polish: cards stack vertically on phones if they were
   side-by-side via flex; flex-wrap is usually set already. ---------- */
@media (max-width: 480px) {
    /* Page H2 headers shrink a notch for breathing room */
    .card > h2:first-child, .card > h3:first-child { font-size: 1.05rem; }
    /* Padding around buttons in cards gets uniform */
    .card form { margin-bottom: 0; }
}

/* ========================================================================
   M5 — Sidebar + header overhaul for mobile, page-header stacking,
        nested-table card-flip, global polish
   ======================================================================== */

/* ---------- Sidebar overlay backdrop ----------
   When the sidebar opens on mobile, dim everything behind it so it's
   visually a "drawer", not a half-floating panel. Add a high z-index. */
@media (max-width: 768px) {
    .app-sidebar {
        /* Must stay above Leaflet — Leaflet panes go 200-700 and
           Leaflet controls reach 1000, so anything below 1001 lets the
           map render in front of the open drawer. */
        z-index: 1100;
        box-shadow: -4px 0 16px rgba(0, 0, 0, 0.15);
    }
    /* Pseudo-backdrop attached to the sidebar — no extra markup needed.
       It only appears when .open is on, covering the rest of the screen. */
    .app-sidebar.open::before {
        content: '';
        position: fixed;
        top: 0; bottom: 0;
        right: 0; left: 0;
        background: rgba(15, 23, 42, 0.4);
        z-index: -1;     /* behind the sidebar itself, inside its stacking context */
        animation: kv-fade-in .15s ease-out;
    }
    /* Prevent body scrolling while drawer is open — JS adds .kv-drawer-lock */
    body.kv-drawer-lock { overflow: hidden; }
}
@keyframes kv-fade-in { from { opacity: 0; } to { opacity: 1; } }

/* Hide the hamburger button on desktop — sidebar is always visible there
   so the button does nothing. */
@media (min-width: 769px) {
    .app-header [data-action="toggle-sidebar"] { display: none; }
}
/* On mobile, make hamburger prominent (44×44 minimum touch target) */
@media (max-width: 768px) {
    .app-header [data-action="toggle-sidebar"] {
        min-width: 44px; min-height: 44px;
        padding: 0; font-size: 1.4rem; line-height: 1;
        background: transparent; border: none;
        color: var(--color-text);
    }
    .app-header [data-action="toggle-sidebar"]:hover { background: #f1f5f9; }
}

/* ---------- M6 — Page header polish on phones.
   Without `:has()` (spotty mobile support), we add a `kv-page-head` class
   via a tiny inline-script injected by the layout — see layout.php.
   Backstop: any first-child flex div in .app-main with an h2 also gets
   compact h2 + button sizing. */
@media (max-width: 480px) {
    .kv-page-head { padding: 0 !important; }
    .kv-page-head > h2 { font-size: 1.15rem !important; }
    .kv-page-head > .btn,
    .kv-page-head > form > .btn,
    .kv-page-head > a.btn {
        padding: 8px 12px !important;
        font-size: 0.88rem !important;
    }
    /* Action containers inside page-header (margin-inline-start: auto)
       wrap their buttons nicely if they overflow */
    .kv-page-head > div { gap: 6px !important; }
}

/* ---------- M6: explicit .kv-cards-on-phone class for tables that should
   flip to a card-stack on phones. Replaces the `:has()` selector which
   has spotty support on older mobile browsers. The view adds the class
   on the <table>, then we hide the head and stack each row as a card. */
@media (max-width: 480px) {
    table.kv-cards-on-phone,
    .kv-table-wrap > table.kv-cards-on-phone { display: block !important; white-space: normal !important; min-width: 0 !important; }
    table.kv-cards-on-phone thead { display: none; }
    table.kv-cards-on-phone tbody,
    table.kv-cards-on-phone tr { display: block; width: 100%; }
    table.kv-cards-on-phone tr {
        border: 1px solid var(--color-border, #e5e7eb);
        border-radius: var(--radius-sm, 6px);
        padding: 10px 12px; margin-bottom: 8px;
        background: #fff;
        box-shadow: 0 1px 2px rgba(0,0,0,.04);
    }
    table.kv-cards-on-phone td {
        display: flex !important;
        justify-content: space-between !important;
        align-items: baseline !important;
        gap: 12px;
        padding: 6px 0 !important;
        border: none !important;
        text-align: start !important;
        white-space: normal !important;
        font-size: 0.9rem;
    }
    table.kv-cards-on-phone td[data-label]::before {
        content: attr(data-label);
        color: var(--color-text-muted, #64748b);
        font-size: 0.78rem; font-weight: 600;
        flex-shrink: 0;
        text-align: start;
    }
    /* Disable horizontal scroll shadows on the wrap when its table flips */
    .kv-table-wrap:has(> table.kv-cards-on-phone) { background: none; overflow: visible; }
}

/* ---------- Prevent horizontal page overflow caused by stray inline styles
   in user views. html-level guard — any descendant that overflows still
   triggers internal scroll inside its own container, never the body. */
html, body { max-width: 100%; overflow-x: hidden; }

/* ---------- .app-main extra padding gone on tiniest screens
   (already 8px from M1, even less here for max content width) */
@media (max-width: 360px) {
    .app-main { padding: 8px 6px; }
    .card { padding: 10px 8px; }
}

/* ========================================================================
   M7 — compact KPIs, table↔cards toggle, etc.
   ======================================================================== */

/* Home dashboard KPI cards — compact on phones so 4-6 fit in one screen. */
@media (max-width: 480px) {
    .kv-kpi-grid { grid-template-columns: repeat(2, 1fr) !important; gap: 6px !important; }
    .kv-kpi-card {
        padding: 8px 10px !important;
        background: #fff;
        border: 1px solid var(--color-border);
        border-radius: var(--radius-sm);
    }
    .kv-kpi-card-title { font-size: 0.72rem !important; margin-bottom: 2px !important; }
    .kv-kpi-card-value { font-size: 1.15rem !important; font-weight: 700 !important; line-height: 1.1 !important; }
    .kv-kpi-card-sub   { font-size: 0.7rem !important; margin-top: 1px !important; }
}

/* Even tinier — 1 column at 360px feels nicer than 2 cramped */
@media (max-width: 360px) {
    .kv-kpi-grid { grid-template-columns: 1fr !important; }
}

/* M7 — table↔cards toggle. Default below 480px = cards.
   body.kv-tables-as-table forces table view even on phone (with scroll). */
@media (max-width: 480px) {
    body.kv-tables-as-table table.kv-cards-on-phone {
        display: table !important;
        white-space: nowrap !important;
        min-width: 100% !important;
    }
    body.kv-tables-as-table table.kv-cards-on-phone thead { display: table-header-group !important; }
    body.kv-tables-as-table table.kv-cards-on-phone tbody { display: table-row-group !important; }
    body.kv-tables-as-table table.kv-cards-on-phone tr {
        display: table-row !important;
        border-radius: 0 !important;
        padding: 0 !important;
        margin: 0 !important;
        box-shadow: none !important;
        background: transparent !important;
    }
    body.kv-tables-as-table table.kv-cards-on-phone td {
        display: table-cell !important;
        justify-content: initial !important;
        gap: 0 !important;
        padding: 6px 8px !important;
        text-align: start !important;
        white-space: nowrap !important;
    }
    body.kv-tables-as-table table.kv-cards-on-phone td::before { content: none !important; }
}

/* The toggle button in the header — only visible on mobile */
.header-table-mode { display: none; }
@media (max-width: 600px) {
    .header-table-mode {
        display: inline-flex; align-items: center; justify-content: center;
        width: 36px; height: 36px;
        border: 1px solid var(--color-border); border-radius: 50%;
        background: #fff;
        font-size: 0.95rem; line-height: 1;
        cursor: pointer;
    }
    .header-table-mode:hover { background: #f1f5f9; }
    .header-table-mode--cards { color: #1d4ed8; }
    .header-table-mode--table { color: #475569; }
}

/* =================================================================
 * M8 — Mobile map panels (dropdown from ▼ button → panel overlay)
 *
 * Desktop: each panel is a floating draggable in a Leaflet corner;
 * the ▼ next to ✏ עריכה pops a checkbox list of show/hide prefs.
 *
 * Mobile: floating-panel paradigm overlaps + covers the map (see
 * user screenshots), and the per-panel show/hide pref isn't useful
 * (there's no room to lay them all out anyway). So:
 *   1. Side dock rails are hidden — no room on a phone.
 *   2. Panels stay in their Leaflet corners but are kept hidden
 *      (display:none) by refreshEditOnlyPanels.
 *   3. The existing ▼ popup, on mobile, lists each available panel
 *      as a big tappable row instead of a checkbox.
 *   4. Tapping a row hoists that panel into .kv-map-wrap and turns
 *      it into a top-anchored full-width sheet over the map.
 *   5. ✕ (was −) in the sheet, or tapping outside it, closes it.
 *      Closing returns the panel to its Leaflet-corner parent and
 *      lets refreshEditOnlyPanels re-hide it.
 * ================================================================= */
@media (max-width: 768px) {
    /* No room for side rails on a phone */
    .kv-dock.kv-dock-left,
    .kv-dock.kv-dock-right {
        display: none !important;
        flex: 0 0 0 !important; width: 0 !important;
    }

    .kv-map-wrap {
        position: relative;            /* anchor for the panel overlay */
        height: 65vh !important;
        min-height: 320px !important;
    }

    /* ── Mobile popup (▼ tap-to-open list) — compact card near trigger ── */
    .kv-panel-popup--mobile {
        position: fixed !important;
        left: 8px !important;
        right: auto !important;
        bottom: 64px !important;       /* just above the ✏ + ▼ buttons */
        width: min(80vw, 240px) !important;
        max-width: none !important;
        min-width: 0 !important;
        max-height: 50vh;
        overflow-y: auto;
        padding: 4px !important;
        z-index: 1100;
    }
    .kv-panel-popup--mobile .kv-panel-popup-title {
        padding: 4px 8px;
        margin-bottom: 2px;
    }
    .kv-panel-popup-open {
        display: block;
        width: 100%;
        padding: 10px 12px !important;
        text-align: start;
        background: #fff;
        border: 0 !important;
        border-bottom: 1px solid var(--color-border) !important;
        border-radius: 0 !important;
        font: inherit; font-size: 0.9rem !important;
        color: #1e293b;
        cursor: pointer;
    }
    .kv-panel-popup-open:last-child { border-bottom: 0 !important; }
    .kv-panel-popup-open:active { background: #eef2ff; }

    /* ── The panel itself when shown via mobile open ──
       Compact card anchored above the ✏ + ▼ buttons (bottom-left), so
       the user can keep editing the map while the panel stays open. */
    .kv-fp.kv-fp-mobile {
        position: absolute !important;
        top: auto !important;
        bottom: 60px !important;
        left: 8px !important;
        right: auto !important;
        inset-inline: auto !important;
        margin: 0 !important;
        padding: 0 !important;
        width: min(85vw, 300px) !important;
        max-height: 45vh !important;
        overflow-y: auto !important;
        background: #fff !important;
        border: 1px solid var(--color-border) !important;
        border-radius: 8px !important;
        box-shadow: 0 8px 24px rgba(0,0,0,0.28) !important;
        transform: none !important;
        z-index: 1000;
        direction: rtl;
    }
    /* Override desktop "collapsed → body hidden" — mobile doesn't use that */
    .kv-fp.kv-fp-mobile.kv-fp-collapsed > *:not(.kv-fp-bar) {
        display: revert !important;
    }
    .kv-fp.kv-fp-mobile .kv-fp-bar {
        margin: 0 !important;
        padding: 5px 9px !important;
        background: #f1f5f9 !important;
        border-radius: 8px 8px 0 0 !important;
        border-bottom: 1px solid var(--color-border) !important;
        cursor: default !important;
        touch-action: auto !important;
        font-size: 0.78rem !important;
    }
    /* The collapse (−) button repurposed as a close (✕) on mobile */
    .kv-fp.kv-fp-mobile .kv-fp-collapse {
        pointer-events: auto !important;
        font-size: 0.8rem !important;
        font-weight: bold !important;
        color: #b91c1c !important;
        background: #fef2f2 !important;
        border: 1px solid #fecaca !important;
        width: 22px !important; height: 22px !important;
    }
    .kv-fp.kv-fp-mobile > *:not(.kv-fp-bar) {
        padding: 6px 8px !important;
        font-size: 0.78rem !important;
    }
    /* Compact fields and buttons inside the panel body */
    .kv-fp.kv-fp-mobile input,
    .kv-fp.kv-fp-mobile select,
    .kv-fp.kv-fp-mobile textarea {
        font-size: 0.78rem !important;
        padding: 4px 6px !important;
    }
    .kv-fp.kv-fp-mobile .kv-bgctl-btn {
        padding: 4px 8px !important;
        font-size: 0.75rem !important;
    }
    .kv-fp.kv-fp-mobile .kv-bgctl-hint {
        font-size: 0.7rem !important;
        padding: 4px 6px !important;
    }
    .kv-fp.kv-fp-mobile .kv-bgctl-row { gap: 4px !important; }
    .kv-fp.kv-fp-mobile .kv-bgctl-grid { gap: 3px 4px !important; }
}

/* ============================================================
 * Dark theme — retrofit contrast for hard-coded inline colors.
 * Many views carry inline light-theme colors (background:#fff, color:#475569…)
 * that never flip, giving "dark text on dark" / glaring white boxes. These
 * attribute-selector overrides flip the COMMON palette in one place, so dark
 * mode is readable without editing 100+ views. Applies only inside the main app
 * (where <html data-theme="dark"> is set) — login/platform views are untouched.
 * ============================================================ */
[data-theme="dark"] [style*="background:#fff"],
[data-theme="dark"] [style*="background: #fff"],
[data-theme="dark"] [style*="background:#ffffff"],
[data-theme="dark"] [style*="background: #ffffff"],
[data-theme="dark"] [style*="background:#FFF"] { background-color: #1e293b !important; }

[data-theme="dark"] [style*="background:#f1f5f9"],
[data-theme="dark"] [style*="background: #f1f5f9"],
[data-theme="dark"] [style*="background:#f8f9fa"],
[data-theme="dark"] [style*="background:#f8fafc"],
[data-theme="dark"] [style*="background:#f7fafc"],
[data-theme="dark"] [style*="background: #f7fafc"],
[data-theme="dark"] [style*="background:#f5f7fa"] { background-color: #0f172a !important; }

/* Colored notice/flash boxes — flip BOTH background and text so they don't go dark-on-dark */
[data-theme="dark"] [style*="background:#d1fae5"],
[data-theme="dark"] [style*="background: #d1fae5"] { background-color: #064e3b !important; color: #a7f3d0 !important; border-color: #065f46 !important; }
[data-theme="dark"] [style*="background:#fffbeb"],
[data-theme="dark"] [style*="background:#fef3c7"],
[data-theme="dark"] [style*="background:#fef9c3"] { background-color: #422006 !important; color: #fde68a !important; border-color: #854d0e !important; }
[data-theme="dark"] [style*="background:#fee2e2"],
[data-theme="dark"] [style*="background:#fde8e8"] { background-color: #450a0a !important; color: #fecaca !important; border-color: #7f1d1d !important; }

[data-theme="dark"] [style*="color:#475569"],
[data-theme="dark"] [style*="color: #475569"],
[data-theme="dark"] [style*="color:#64748b"],
[data-theme="dark"] [style*="color:#334155"],
[data-theme="dark"] [style*="color:#6b7280"] { color: #cbd5e1 !important; }

[data-theme="dark"] [style*="color:#1e293b"],
[data-theme="dark"] [style*="color: #1e293b"],
[data-theme="dark"] [style*="color:#0f172a"],
[data-theme="dark"] [style*="color: #0f172a"],
[data-theme="dark"] [style*="color:#1a202c"],
[data-theme="dark"] [style*="color:#2d3748"],
[data-theme="dark"] [style*="color:#1f2937"],
[data-theme="dark"] [style*="color:#212529"],
[data-theme="dark"] [style*="color:#111"],
[data-theme="dark"] [style*="color:#222"],
[data-theme="dark"] [style*="color:#333"] { color: #e2e8f0 !important; }

[data-theme="dark"] [style*="border:1px solid #e2e8f0"],
[data-theme="dark"] [style*="border: 1px solid #e2e8f0"],
[data-theme="dark"] [style*="border:1px solid #cbd5e1"],
[data-theme="dark"] [style*="border-color:#e2e8f0"],
[data-theme="dark"] [style*="border-bottom:1px solid #e"],
[data-theme="dark"] [style*="border-top:1px solid #e"] { border-color: #334155 !important; }

/* Map overlays / popups + status pills */
[data-theme="dark"] .kv-em,
[data-theme="dark"] .kv-map-editbtn,
[data-theme="dark"] .kv-map-paneltoggle,
[data-theme="dark"] .kv-panel-popup,
[data-theme="dark"] .kv-em-btn { background: #1e293b !important; color: #f1f5f9 !important; border-color: #334155 !important; }
[data-theme="dark"] .kv-em-h,
[data-theme="dark"] .kv-panel-popup-title { color: #cbd5e1 !important; }
[data-theme="dark"] .pill-ok      { background: #064e3b; color: #a7f3d0; }
[data-theme="dark"] .pill-down    { background: #7f1d1d; color: #fecaca; }
[data-theme="dark"] .pill-pending { background: #78350f; color: #fde68a; }
