/*!
 * Elalamy Gate Pass — Vehicle gate management system.
 * Copyright (c) 2026 Mahmoud ElMoataz <Mahmoud.ElMoataz@live.com>
 * All rights reserved. See LICENSE.
 */
@import url("../vendor/fonts/noto-sans-arabic/noto-sans-arabic.css");

/* ==========================================================================
   Elalamy Gate Pass — app styles (layered on Bootstrap 5.3, RTL-aware).
   Brand green + neutral surfaces. Logical properties throughout so the
   Arabic RTL build mirrors automatically. Modern CSS (color-mix, conic-
   gradient, dvh) is used with plain fallbacks first so older browsers and
   devices still render correctly.
   ========================================================================== */

:root {
    --gp-brand: #16a163;
    --gp-brand-2: #12a05c;
    --gp-brand-ink: #14231b;
    --gp-page: #f6f8f7;
    --gp-card: #ffffff;
    --gp-border: #e6ebe8;
    --gp-input-bg: #f2f4f5;
    --gp-muted: #7a8580;
    --gp-danger: #d92d20;
    --gp-side-bg: #10231a;
    /* Pre-mixed tints used where color-mix() isn't available. */
    --gp-brand-soft: #d7efe3;
    --gp-active: #3aa877;

    --bs-primary: var(--gp-brand);
    --bs-success: var(--gp-brand);
    --bs-body-font-family: "Noto Sans Arabic", system-ui, -apple-system,
        "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body.gp-body {
    font-family: "Noto Sans Arabic", system-ui, -apple-system, "Segoe UI",
        Roboto, "Helvetica Neue", Arial, sans-serif;
    background: var(--gp-page);
    color: var(--gp-brand-ink);
    min-height: 100vh;      /* fallback for browsers without dvh */
    min-height: 100dvh;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    -webkit-tap-highlight-color: transparent;
    /* The mobile sidebar drawer sits off-canvas (translateX) — clip any
       resulting horizontal scroll so no page ever pans sideways on a phone. */
    overflow-x: hidden;
}

/* Media never overflows its container on small screens. */
img, svg, video, canvas { max-width: 100%; height: auto; }
/* Long plate strings / codes wrap instead of forcing horizontal scroll. */
.gp-vcard-plate, .gp-activity-plate, .gp-plate-box-value, .gp-code {
    overflow-wrap: anywhere;
}

.btn-success {
    --bs-btn-bg: var(--gp-brand);
    --bs-btn-border-color: var(--gp-brand);
    --bs-btn-hover-bg: var(--gp-brand-2);
    --bs-btn-hover-border-color: var(--gp-brand-2);
    --bs-btn-active-bg: var(--gp-brand-2);
}

/* ============================ Auth / login ============================= */

.gp-auth-shell {
    min-height: 100vh;
    min-height: 100dvh;
    display: grid;
    place-items: center;
    padding: 1.5rem;
    position: relative;
}
.gp-auth-lang { position: absolute; inset-block-start: 1rem; inset-inline-end: 1rem; }
/* Language switch pill — clean white capsule with a brand-green globe, used on
   both the guard and back-office login pages. */
.gp-lang-btn {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.42rem 0.85rem; border-radius: 999px;
    background: var(--gp-card); border: 1px solid var(--gp-border);
    color: var(--gp-brand-ink); font-size: 0.82rem; font-weight: 700;
    text-decoration: none; line-height: 1;
    box-shadow: 0 1px 4px rgba(20, 35, 27, 0.06);
    transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.gp-lang-btn .bi, .gp-lang-btn .gp-lucide { color: var(--gp-brand); font-size: 1.05rem; line-height: 1; }
.gp-lang-btn:hover, .gp-lang-btn:focus-visible {
    background: var(--gp-brand-soft); border-color: var(--gp-brand); color: var(--gp-brand-ink);
    box-shadow: 0 2px 8px rgba(22, 161, 99, 0.16);
}
.gp-auth-card {
    width: min(420px, 100%);
    background: var(--gp-card);
    border: 1px solid var(--gp-border);
    border-radius: 18px;
    box-shadow: 0 10px 30px rgba(20, 35, 27, 0.07);
    padding: 2rem;
}
.gp-auth-brand {
    display: flex; align-items: center; justify-content: center;
    gap: 0.7rem; margin-block-end: 1.15rem; direction: ltr;
}
/* Tighter, bolder field labels — matches the deck's denser card. */
.gp-auth-form .form-label { font-weight: 600; margin-block-end: 0.35rem; color: var(--gp-brand-ink); }
/* Brand mark = the green outline car glyph beside the wordmark (no box),
   matching the design deck's login lockup. */
.gp-auth-brand-mark {
    display: grid; place-items: center; font-size: 2.4rem; color: var(--gp-brand);
    line-height: 1;
}
.gp-auth-brand-text { display: flex; flex-direction: column; line-height: 1.1; }
.gp-auth-brand-title { font-weight: 800; font-size: 1.35rem; color: var(--gp-brand-ink); }
.gp-auth-brand-sub { color: var(--gp-muted); font-size: 0.95rem; }
.gp-auth-submit { padding-block: 0.7rem; font-weight: 700; }

/* Filled fields (guard number + PIN) — ONE light-grey pill with the field icon
   floating inside at the end (no separate icon box), matching the design deck. */
.gp-auth-field { position: relative; }
.gp-auth-field .form-control {
    background: var(--gp-input-bg); border: 1px solid var(--gp-border); border-radius: 12px;
    font-weight: 600; padding-block: 0.68rem; padding-inline-end: 2.8rem;
}
.gp-auth-field .form-control::placeholder { color: var(--gp-muted); opacity: 1; font-weight: 500; }
.gp-auth-field-ic {
    position: absolute; top: 0; bottom: 0; inset-inline-end: 0.95rem; z-index: 4;
    display: flex; align-items: center; color: var(--gp-muted); pointer-events: none;
}
/* Clickable show/hide-password eye inside a filled auth field. */
.gp-auth-eye {
    position: absolute; top: 0; bottom: 0; inset-inline-end: 0.55rem; z-index: 4;
    display: inline-flex; align-items: center; padding: 0 0.35rem;
    background: none; border: 0; color: var(--gp-muted); cursor: pointer;
    transition: color 0.15s ease;
}
.gp-auth-eye:hover, .gp-auth-eye:focus-visible { color: var(--gp-brand-ink); }

/* "Staff member? → Back-office login" cross-link under the guard login. */
.gp-auth-alt {
    margin-block-start: 1.3rem; padding-block-start: 1.05rem;
    border-block-start: 1px solid var(--gp-border);
    text-align: center; font-size: 0.85rem; color: var(--gp-muted);
}
.gp-auth-alt a { color: var(--gp-brand); font-weight: 700; text-decoration: none; white-space: nowrap; }
.gp-auth-alt a:hover { text-decoration: underline; }
.gp-auth-foot {
    position: absolute; inset-block-end: 1.25rem; inset-inline: 0;
    text-align: center; color: var(--gp-muted); font-size: 0.8rem; direction: ltr;
}

/* ===================== Back-office (staff) login ===================== */
/* A split screen: green Elalamy brand panel + white sign-in card. Stacks on
   narrow viewports. Distinct from the guard login, same green brand system. */
.gp-admin-auth {
    min-height: 100vh; min-height: 100dvh;
    display: grid; grid-template-columns: 1.05fr 1fr; position: relative;
}
.gp-admin-auth-lang { position: absolute; inset-block-start: 1rem; inset-inline-end: 1rem; z-index: 3; }

/* Brand panel */
.gp-admin-brandside {
    position: relative; overflow: hidden; color: #fff;
    display: grid; place-items: center; padding: 2.5rem;
    background: linear-gradient(150deg, var(--gp-brand) 0%, #0f7f4b 100%);
}
/* Soft depth: two faint light blooms over the gradient. */
.gp-admin-brandside::before {
    content: ""; position: absolute; inset: 0;
    background:
        radial-gradient(60% 55% at 85% 12%, rgba(255,255,255,0.16), transparent 60%),
        radial-gradient(50% 45% at 12% 92%, rgba(255,255,255,0.10), transparent 60%);
}
.gp-admin-brandside-inner { position: relative; width: min(400px, 100%); display: flex; flex-direction: column; gap: 1.6rem; }
.gp-admin-brand { display: flex; align-items: center; gap: 0.75rem; direction: ltr; }
.gp-admin-brand-mark {
    width: 52px; height: 52px; border-radius: 14px; flex: 0 0 auto;
    display: grid; place-items: center; font-size: 1.7rem; color: #fff;
    background: rgba(255,255,255,0.16); border: 1px solid rgba(255,255,255,0.25);
}
.gp-admin-brand-text { display: flex; flex-direction: column; line-height: 1.05; }
.gp-admin-brand-title { font-weight: 800; font-size: 1.5rem; }
.gp-admin-brand-sub { font-size: 1rem; color: rgba(255,255,255,0.85); }
.gp-admin-badge {
    display: inline-block; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em;
    text-transform: uppercase; padding: 0.25rem 0.7rem; border-radius: 999px;
    background: rgba(255,255,255,0.18); border: 1px solid rgba(255,255,255,0.22);
}
.gp-admin-tagline { font-size: 1.35rem; font-weight: 700; line-height: 1.4; margin: 0.7rem 0 0; }
.gp-admin-featlist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.7rem; }
.gp-admin-featlist li { display: flex; align-items: center; gap: 0.6rem; font-size: 0.98rem; color: rgba(255,255,255,0.92); }
.gp-admin-featlist .bi { flex: 0 0 auto; font-size: 1.1rem; opacity: 0.95; }
.gp-admin-brand-foot { color: rgba(255,255,255,0.7); font-size: 0.8rem; direction: ltr; }

/* Form panel */
.gp-admin-formside { display: grid; place-items: center; padding: 2.5rem 1.5rem; background: var(--gp-input-bg); }
.gp-admin-formcard {
    width: min(400px, 100%); background: var(--gp-card);
    border: 1px solid var(--gp-border); border-radius: 18px;
    box-shadow: 0 10px 30px rgba(20, 35, 27, 0.07); padding: 2rem;
}
.gp-admin-form-head { margin-block-end: 1.4rem; }
.gp-admin-welcome { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--gp-brand); }
.gp-admin-heading { font-size: 1.5rem; font-weight: 800; color: var(--gp-brand-ink); margin: 0.35rem 0 0.3rem; }
.gp-admin-subhead { color: var(--gp-muted); font-size: 0.9rem; margin: 0; }
.gp-admin-guardhint {
    margin-block-start: 1.4rem; padding-block-start: 1.1rem; border-block-start: 1px solid var(--gp-border);
    text-align: center; font-size: 0.85rem; color: var(--gp-muted);
}
.gp-admin-guardhint a { color: var(--gp-brand); font-weight: 700; text-decoration: none; white-space: nowrap; }
.gp-admin-guardhint a:hover { text-decoration: underline; }

/* Stack on tablets/phones: brand becomes a compact top banner. */
@media (max-width: 820px) {
    /* Stack: a compact green header that hugs its content (row auto), then the
       form fills the rest (row 1fr) — no more empty green band. */
    .gp-admin-auth { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
    /* Extra top padding clears the absolute language pill so it doesn't overlap
       the brand lockup on the compact mobile header (generous for large fonts). */
    .gp-admin-brandside { min-height: 0; padding: 4.4rem 1.5rem 1.9rem; }
    .gp-admin-auth-lang { inset-block-start: 0.9rem; }
    .gp-admin-brandside-inner { gap: 1rem; }
    .gp-admin-tagline { font-size: 1.1rem; }
    .gp-admin-featlist, .gp-admin-brand-foot { display: none; }
    .gp-admin-formside { padding: 2rem 1.25rem 3rem; }
    .gp-admin-heading { font-size: 1.35rem; }
}

/* ============================ Guard app =============================== */

/* Reserve clears the ~72px nav plus its safe-area inset with breathing room, so
   the CTA never hides behind the bottom nav on notched phones. */
.gp-body--guard { padding-block-end: calc(6.5rem + env(safe-area-inset-bottom)); }
.gp-guard-topbar {
    position: sticky; top: 0; z-index: 5;
    display: flex; align-items: center; justify-content: space-between;
    padding: 0.85rem 1rem; background: var(--gp-card);
    border-block-end: 1px solid var(--gp-border);
}
.gp-guard-brand { font-weight: 800; color: var(--gp-brand-ink); display: inline-flex; align-items: center; gap: 0.4rem; }
.gp-guard-topbar-actions { display: inline-flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; justify-content: flex-end; }
.gp-guard-brand .gp-lucide { color: var(--gp-brand); }
.gp-guard-main { max-width: 520px; margin-inline: auto; padding: 1.15rem 1rem; }
.gp-guard-title { font-size: 1.3rem; font-weight: 800; margin-block-end: 0.75rem; }

.gp-guard-bottomnav {
    position: fixed; inset-block-end: 0; inset-inline: 0; z-index: 20;
    display: grid; grid-template-columns: repeat(3, 1fr);
    background: var(--gp-card); border-block-start: 1px solid var(--gp-border);
    padding-block-end: env(safe-area-inset-bottom);
}
.gp-guard-navitem {
    display: flex; flex-direction: column; align-items: center; gap: 0.15rem;
    margin: 0.4rem; padding: 0.5rem 0.35rem; border-radius: 12px;
    color: var(--gp-muted); text-decoration: none; font-size: 0.72rem;
}
/* Active tab = filled green pill with white icon + label (matches the deck).
   The lucide SVG inherits the pill's white via currentColor. */
.gp-guard-navitem.is-active { background: var(--gp-brand); color: #fff; font-weight: 700; }

/* Entry capture — single-column cards */
.gp-entry-form { display: flex; flex-direction: column; gap: 0.9rem; }
/* Plate input: a filled light-grey rounded box (no hard border) — matching the
   design deck. Focus still gets the brand ring from the polish layer. */
.gp-plate-input {
    font-weight: 700; letter-spacing: 0.04em; font-size: 1.15rem;
    background: var(--gp-input-bg); border: 1px solid var(--gp-border); border-radius: 10px;
    padding-block: 0.65rem;
}
.gp-plate-input::placeholder { font-weight: 600; color: var(--gp-muted); opacity: 1; }

.gp-cap-card {
    display: block; background: var(--gp-card); border: 1px solid var(--gp-border);
    border-radius: 16px; padding: 1rem 1.1rem;
}
.gp-cap-photo { cursor: pointer; }
.gp-cap-head { display: flex; align-items: center; gap: 0.5rem; }
.gp-cap-ic { color: var(--gp-brand); flex: 0 0 auto; display: inline-flex; align-items: center; }
.gp-cap-title { font-weight: 800; font-size: 1rem; color: var(--gp-brand-ink); }
.gp-req { color: var(--gp-danger); font-weight: 700; margin-inline-start: 2px; }
.gp-cap-hint { color: var(--gp-muted); font-size: 0.82rem; margin-block: 0.25rem 0.6rem; }
.gp-cap-card .gp-plate-input { margin-block-start: 0.3rem; }

/* Capture drop area: dashed frame with a placeholder, replaced by the photo. */
.gp-cap-drop {
    margin-block-start: 0.5rem; border: 1.6px dashed #bcc4c0;
    border-radius: 12px; background: var(--gp-input-bg); overflow: hidden;
    /* Deck proportion: a ~1.85:1 landscape box (min-height floors it on old
       browsers that ignore aspect-ratio). */
    aspect-ratio: 1.85 / 1; min-height: 150px;
    display: flex; align-items: center; justify-content: center;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.gp-cap-card:hover .gp-cap-drop { border-color: var(--gp-brand); }
/* Placeholder (matches the design deck): a dashed grey box holding one muted
   camera+plus glyph, then the "tap to capture" label. */
.gp-cap-placeholder {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 0.55rem; color: #7a8580; font-weight: 600; font-size: 0.85rem;
    padding: 1.25rem; text-align: center;
}
.gp-camera-mark { position: relative; display: inline-flex; color: #6a7570; }
.gp-camera-plus {
    position: absolute; inset-block-start: -0.3rem; inset-inline-end: -0.35rem;
    display: inline-flex; color: #6a7570; line-height: 1;
}
/* Captured photo fills a clean landscape frame (cover-cropped to a nice area,
   matching the design deck). The FULL image is still stored + tap-to-open. */
.gp-cap-preview { display: block; width: 100%; aspect-ratio: 1.85 / 1; object-fit: cover; }
/* Once a photo is captured, drop the dashed/colored frame: the image sits in the
   white card with only a small radius and a hairline neutral edge — matching the
   design deck (no green border). */
.gp-cap-card.has-photo .gp-cap-drop {
    border: 1px solid var(--gp-border); border-radius: 8px; background: var(--gp-card);
    min-height: 0; padding: 0;
}

/* Confirm-entry button — icon + label centered together */
.gp-confirm-btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.45rem; }

/* Exit — search card + button */
.gp-exit-search-form { display: flex; flex-direction: column; gap: 0.8rem; }
.gp-search-btn {
    background: #c4cbc8; color: #fff; font-weight: 800; border: 0;
    transition: background 0.15s ease;
}
.gp-search-btn.is-ready { background: var(--gp-brand); }
.gp-search-btn.is-ready:hover { background: var(--gp-brand-2); color: #fff; }

.gp-vlist-heading { font-size: 1.05rem; font-weight: 800; margin-block: 1.4rem 0.7rem; color: var(--gp-brand-ink); }

/* Exit — inside-vehicle cards (green-bordered, boxed plate) */
.gp-exit-list { display: flex; flex-direction: column; gap: 0.7rem; }
/* Vehicle card — mirrors the Node app's gp-vitem exactly: the lucide LogIn
   icon at the start (RTL: right), entry time filling the middle, and the plate
   chip at the end (RTL: left). */
.gp-vcard {
    display: flex; align-items: center; gap: 0.7rem; padding: 0.55rem 0.85rem;
    background: var(--gp-card); border: 1.5px solid #b5e4c8;
    border-radius: 12px; text-decoration: none; color: var(--gp-brand-ink);
}
.gp-vcard-ico { flex: 0 0 auto; color: var(--gp-brand); display: inline-flex; }
.gp-vcard-meta {
    flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column;
    gap: 0.1rem; text-align: start;
}
.gp-vcard-meta-label { color: #94a3b8; font-size: 0.8125rem; font-weight: 500; }
.gp-vcard-meta-time { color: var(--gp-brand-ink); font-weight: 600; font-size: 0.875rem; }
.gp-vcard-plate {
    flex: 0 0 auto; min-width: 6.75rem; text-align: center; white-space: nowrap;
    padding: 0.4rem 0.75rem; background: #fff; border: 1px solid #e5e7eb;
    border-radius: 6px; font-weight: 600; letter-spacing: 0.03em; color: var(--gp-brand-ink);
}
.gp-lucide { vertical-align: -0.15em; }

/* Exit — detail */
.gp-exit-back {
    display: inline-flex; align-items: center; gap: 0.4rem; margin-block-end: 0.9rem;
    color: var(--gp-brand); font-weight: 700; text-decoration: none; font-size: 1rem;
}
.gp-cap-status { margin-inline-start: auto; }
.gp-plate-box {
    margin-block-start: 0.6rem; border: 2px dashed var(--gp-border); border-radius: 12px;
    background: var(--gp-input-bg); padding: 1rem; text-align: center;
    display: flex; flex-direction: column; gap: 0.35rem;
}
.gp-plate-box-label { color: var(--gp-muted); font-size: 0.8rem; }
.gp-plate-box-value { font-weight: 900; font-size: 1.8rem; letter-spacing: 0.05em; color: var(--gp-brand-ink); }

.gp-evi-stack { display: flex; flex-direction: column; gap: 0.7rem; margin-block-start: 0.6rem; }
.gp-evi-item {
    position: relative; display: block; border-radius: 12px; overflow: hidden;
    border: 1px solid var(--gp-border);
}
.gp-evi-item img { display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.gp-evi-badge {
    position: absolute; inset-block-start: 0.5rem; inset-inline-end: 0.5rem;
    background: rgba(255, 255, 255, 0.92); color: var(--gp-brand-ink);
    font-size: 0.72rem; font-weight: 700; padding: 0.15rem 0.55rem;
    border-radius: 999px; box-shadow: 0 1px 3px rgba(0,0,0,0.15);
}
.gp-log-row { display: flex; justify-content: space-between; align-items: center; padding-block: 0.35rem; }
.gp-log-row:not(:last-child) { border-block-end: 1px solid var(--gp-border); }

/* ============================ Back office shell ======================= */

.gp-bo-shell { display: grid; grid-template-columns: 260px 1fr; min-height: 100vh; min-height: 100dvh; }
.gp-bo-shell.is-collapsed { grid-template-columns: 72px 1fr; }

.gp-side {
    background: var(--gp-side-bg); color: #e6ebe8;
    display: flex; flex-direction: column; gap: 0.4rem;
    padding: 0.8rem 0.6rem; position: sticky; top: 0; height: 100vh; height: 100dvh; overflow-y: auto;
}
.gp-side-brand {
    display: flex; align-items: center; gap: 0.55rem; color: #fff;
    font-weight: 800; padding: 0.5rem 0.6rem 0.8rem; white-space: nowrap; overflow: hidden;
    border-block-end: 1px solid rgba(255,255,255,0.08);
}
.gp-side-brand-mark { display: inline-flex; color: #fff; flex: 0 0 auto; }
.gp-side-brand-text { flex: 1 1 auto; }
/* Close button — only shown in the mobile drawer. */
.gp-side-close {
    display: none; background: rgba(255,255,255,0.1); border: 0; color: #fff;
    width: 34px; height: 34px; border-radius: 9px; flex: 0 0 auto;
    align-items: center; justify-content: center; cursor: pointer;
}
.gp-side-close:hover { background: rgba(255,255,255,0.2); }
.gp-side-nav { display: flex; flex-direction: column; gap: 0.15rem; margin-block-start: 0.4rem; }
.gp-side-item {
    display: flex; align-items: center; gap: 0.7rem; padding: 0.55rem 0.7rem;
    color: #cfd8d2; text-decoration: none; border-radius: 9px; font-weight: 600;
    font-size: 0.9rem; white-space: nowrap; overflow: hidden;
}
.gp-side-item .gp-lucide { flex: 0 0 auto; }
.gp-side-item:hover { background: rgba(255,255,255,0.08); color: #fff; }
.gp-side-item.is-active { background: var(--gp-active); color: #fff; }
@supports (background: color-mix(in oklab, red, blue)) {
    .gp-side-item.is-active { background: color-mix(in oklab, var(--gp-brand) 55%, transparent); }
}
.gp-side-item--sub { padding-inline-start: 1.5rem; font-size: 0.86rem; }

.gp-side-group { display: flex; flex-direction: column; }
.gp-side-group-head {
    display: flex; align-items: center; gap: 0.6rem; width: 100%;
    padding: 0.55rem 0.7rem; background: transparent; border: 0; cursor: pointer;
    color: #9fb0a8; font-weight: 700; font-size: 0.9rem; border-radius: 9px;
    text-transform: lowercase;
}
.gp-side-group-head:hover { background: rgba(255,255,255,0.05); color: #fff; }
.gp-side-group-label { flex: 1 1 auto; text-align: start; }
.gp-side-group-head .gp-lucide { flex: 0 0 auto; }
.gp-side-chev { display: inline-flex; transition: transform 0.15s; margin-inline-start: auto; }
.gp-side-group-head[aria-expanded="true"] .gp-side-chev { transform: rotate(180deg); }

/* Collapsed icon rail (desktop) — hide all text, center icons. */
.is-collapsed .gp-side-brand-text,
.is-collapsed .gp-side-item-text,
.is-collapsed .gp-side-group-label,
.is-collapsed .gp-side-chev { display: none; }
.is-collapsed .gp-side-item,
.is-collapsed .gp-side-group-head,
.is-collapsed .gp-side-brand { justify-content: center; padding-inline: 0; }
.is-collapsed .gp-side-item--sub { padding-inline-start: 0; }

.gp-side-backdrop { display: none; }

.gp-bo-main { display: flex; flex-direction: column; min-width: 0; }
.gp-bo-header {
    position: sticky; top: 0; z-index: 6;
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.7rem 1.25rem; background: var(--gp-card);
    border-block-end: 1px solid var(--gp-border);
}
.gp-bo-header-spacer { flex: 1 1 auto; }
.gp-bo-header-actions { display: flex; align-items: center; gap: 0.5rem; }
/* Hamburger — a clean borderless ghost icon button (no framed box). */
.gp-bo-menu-btn {
    display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
    width: 40px; height: 40px; border-radius: 10px; padding: 0;
    background: transparent; border: 0; color: var(--gp-brand-ink);
    cursor: pointer; transition: background 0.15s ease, color 0.15s ease;
}
.gp-bo-menu-btn:hover, .gp-bo-menu-btn:focus-visible { background: var(--gp-input-bg); color: var(--gp-brand); }

/* Profile — borderless button with a soft-green avatar, name, and caret. */
.gp-bo-user-btn {
    display: inline-flex; align-items: center; gap: 0.5rem;
    padding-block: 0.25rem; padding-inline: 0.3rem 0.55rem; border-radius: 999px;
    background: transparent; border: 0; color: var(--gp-brand-ink);
    font-size: 0.88rem; font-weight: 600; cursor: pointer;
    transition: background 0.15s ease;
}
.gp-bo-user-btn:hover, .gp-bo-user-btn:focus-visible { background: var(--gp-input-bg); }
.gp-bo-avatar {
    display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
    width: 32px; height: 32px; border-radius: 999px;
    background: var(--gp-brand-soft); color: var(--gp-brand);
}
.gp-bo-user-caret { display: inline-flex; color: var(--gp-muted); }
.dropdown-item.gp-confirm-btn { gap: 0.5rem; }
.dropdown-item .gp-lucide { color: var(--gp-muted); }
.dropdown-item.text-danger .gp-lucide { color: var(--gp-danger); }
.gp-bo-content { padding: 1.5rem; flex: 1 1 auto; }

/* ============================ Page primitives ======================== */

.gp-vpage { display: flex; flex-direction: column; gap: 1.25rem; width: 100%; }
.gp-vpage--narrow { max-width: 760px; }
.gp-vpage-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; }
.gp-vpage-title { margin: 0; font-size: 1.5rem; font-weight: 900; letter-spacing: -0.01em; }

.gp-kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; }
.gp-kpi-grid--3 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.gp-kpi {
    --kpi-tint: var(--gp-brand);
    position: relative; overflow: hidden; padding: 1.1rem 1.15rem;
    background: var(--gp-card); border: 1px solid var(--gp-border); border-radius: 16px;
    display: flex; flex-direction: column; gap: 0.35rem;
}
.gp-kpi::before { content: ""; position: absolute; top: 0; bottom: 0; inset-inline-start: 0; width: 3px; background: var(--kpi-tint); }
/* Icon sits clean in the corner tinted by its category — no background chip. */
.gp-kpi-head {
    position: absolute; inset-block-start: 0.95rem; inset-inline-end: 1rem;
    display: grid; place-items: center; color: var(--kpi-tint);
}
.gp-kpi-value { font-size: 1.6rem; font-weight: 900; letter-spacing: -0.02em; padding-inline-end: 2.75rem; }
.gp-kpi-label { color: var(--gp-muted); font-size: 0.8rem; font-weight: 600; }
.gp-kpi--brand  { --kpi-tint: var(--gp-brand); }
.gp-kpi--muted  { --kpi-tint: #7a8580; }
.gp-kpi--warn   { --kpi-tint: #b17c1b; }
.gp-kpi--info   { --kpi-tint: #2563a8; }
.gp-kpi--accent { --kpi-tint: #1c8f5a; }

.gp-vpanel-row { display: grid; grid-template-columns: 2fr 1fr; gap: 1rem; }
.gp-vpanel {
    background: var(--gp-card); border: 1px solid var(--gp-border); border-radius: 16px;
    padding: 1.15rem 1.25rem; display: flex; flex-direction: column; gap: 1rem;
}
.gp-vpanel-head { display: flex; align-items: center; justify-content: space-between; padding-block-end: 0.6rem; border-block-end: 1px solid var(--gp-border); }
.gp-vpanel-title { margin: 0; font-size: 1.05rem; font-weight: 800; }
.gp-vpanel-empty { color: var(--gp-muted); padding: 2rem; text-align: center; }

/* Definite height so each bar's percentage height resolves (otherwise every bar
   collapsed to the 4px minimum). The bar is capped to leave room for the label. */
.gp-chart { display: flex; align-items: flex-end; gap: 0.5rem; height: 220px; }
.gp-chart-col { flex: 1 1 0; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: 0.35rem; min-width: 0; height: 100%; }
.gp-chart-bar {
    width: 100%; min-height: 4px; max-height: calc(100% - 1.3rem); border-radius: 8px 8px 0 0;
    background: linear-gradient(180deg, var(--gp-brand-2), var(--gp-brand));
}
.gp-chart-label { font-size: 0.78rem; color: var(--gp-muted); }

.gp-donut { display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; }
.gp-donut-ring {
    width: 170px; height: 170px; border-radius: 50%; flex: 0 0 auto;
    /* Fallback for browsers without conic-gradient: a solid brand ring. */
    background: var(--gp-brand);
    background: conic-gradient(var(--gp-brand) var(--on), var(--gp-input-bg) 0);
    display: grid; place-items: center;
}
.gp-donut-hole {
    width: 116px; height: 116px; border-radius: 50%; background: var(--gp-card);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.gp-donut-num { font-size: 2rem; font-weight: 900; }
.gp-donut-cap { font-size: 0.72rem; color: var(--gp-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.gp-donut-legend { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; min-width: 150px; }
.gp-donut-legend li { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.75rem; background: var(--gp-input-bg); border-radius: 8px; font-weight: 600; }
.gp-dot { width: 10px; height: 10px; border-radius: 50%; }
.gp-dot--on { background: var(--gp-brand); }
.gp-dot--off { background: var(--gp-input-bg); border: 1px solid var(--gp-border); }
.gp-donut-val { margin-inline-start: auto; font-weight: 900; }

/* Whole-row link (Records → vehicle detail): pointer + hover highlight. */
.gp-row-link { cursor: pointer; }
.gp-table tbody tr.gp-row-link:hover { background: rgba(22, 161, 99, 0.07); }

.gp-activity-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
.gp-activity-row {
    display: grid; grid-template-columns: auto auto 1fr; gap: 0.65rem; align-items: center;
    padding: 0.7rem 0.85rem; background: var(--gp-input-bg); border-radius: 10px;
    border-inline-start: 3px solid var(--gp-border);
}
.gp-activity-plate { font-weight: 800; font-size: 1.05rem; white-space: nowrap; }
/* Time sits at the row end (left in RTL); plate + status stay grouped at the start. */
.gp-activity-time { color: var(--gp-muted); font-size: 0.9rem; justify-self: end; white-space: nowrap; }

/* Filters + toolbar */
.gp-filters {
    display: flex; flex-wrap: wrap; align-items: end; gap: 0.85rem;
    background: var(--gp-card); border: 1px solid var(--gp-border);
    border-radius: 14px; padding: 1rem 1.1rem;
}
.gp-filter { display: flex; flex-direction: column; gap: 0.3rem; }
.gp-filter-label { font-size: 0.75rem; font-weight: 700; color: var(--gp-muted); letter-spacing: 0.01em; }
/* Single-search filter bar (Vehicles): keep the lone field a sensible width
   instead of stretching it full-width with the buttons floating far away. */
.gp-filters--single .gp-filter { flex: 0 1 24rem; }
.gp-filter-actions { display: flex; gap: 0.5rem; }
.gp-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.gp-toolbar-start, .gp-toolbar-end { display: flex; align-items: center; gap: 0.5rem; }
.gp-toolbar-search { min-width: 260px; background: var(--gp-input-bg); border: 1px solid var(--gp-border); border-radius: 10px; }
.gp-toolbar-search .form-control, .gp-toolbar-search .input-group-text { background: transparent; }

/* Tables */
.gp-table-wrap { background: var(--gp-card); border: 1px solid var(--gp-border); border-radius: 16px; overflow: hidden; }
/* Restore horizontal scroll on phones (the hidden overflow above killed
   Bootstrap's .table-responsive). Keeps the rounded card clip vertically. */
.gp-table-wrap.table-responsive { overflow-x: auto; }
/* Brand-green form switches/checkboxes (Bootstrap hard-codes #0d6efd). */
.form-check-input:checked { background-color: var(--gp-brand); border-color: var(--gp-brand); }
.form-check-input:focus { border-color: var(--gp-brand); box-shadow: 0 0 0 0.2rem rgba(22, 161, 99, 0.25); }
.gp-table { margin: 0; }
.gp-table thead th {
    background: var(--gp-input-bg); color: var(--gp-muted); font-weight: 700;
    font-size: 0.74rem; letter-spacing: 0.02em; padding-block: 0.75rem;
    border-block-end: 1px solid var(--gp-border);
}
.gp-table td { padding-block: 0.8rem; vertical-align: middle; }
/* Row-number (#) column: narrow, muted. */
.gp-num-col { width: 1%; white-space: nowrap; color: var(--gp-muted); font-variant-numeric: tabular-nums; }
.gp-table td, .gp-table th { font-variant-numeric: tabular-nums; }
.gp-table tbody tr:last-child td { border-block-end: 0; }
.gp-code { color: var(--gp-brand-ink); font-size: 0.8rem; }

/* Status pill with a leading dot for at-a-glance scanning. */
.gp-badge { display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.28rem 0.65rem; border-radius: 999px; font-size: 0.76rem; font-weight: 700; white-space: nowrap; }
.gp-badge-dot { width: 0.48rem; height: 0.48rem; border-radius: 50%; flex: none; }
.gp-badge--in { background: var(--gp-brand-soft); color: #0d7a4c; }
.gp-badge--in .gp-badge-dot { background: var(--gp-brand); }
.gp-badge--out { background: var(--gp-input-bg); color: var(--gp-muted); }
.gp-badge--out .gp-badge-dot { background: var(--gp-muted); }
.gp-badge--danger { background: #fdeceb; color: var(--gp-danger); }
.gp-badge--danger .gp-badge-dot { background: var(--gp-danger); }

/* Role pill, tinted per role for quick scanning. */
.gp-role { display: inline-flex; align-items: center; padding: 0.26rem 0.62rem; border-radius: 999px; font-size: 0.74rem; font-weight: 700; }
.gp-role--admin      { background: var(--gp-brand-soft); color: #0d7a4c; }
.gp-role--supervisor { background: #fbedd4; color: #90630f; }
.gp-role--guard      { background: var(--gp-input-bg); color: var(--gp-muted); }

/* Activity-log event pill (humanised, colour-toned by category). */
.gp-evt { display: inline-flex; align-items: center; padding: 0.24rem 0.62rem; border-radius: 999px; font-size: 0.74rem; font-weight: 700; white-space: nowrap; }
.gp-evt--in     { background: var(--gp-brand-soft); color: #0d7a4c; }
.gp-evt--out    { background: var(--gp-input-bg); color: var(--gp-muted); }
.gp-evt--danger { background: #fdeceb; color: var(--gp-danger); }
.gp-evt--warn   { background: #fbedd4; color: #90630f; }
.gp-evt--info   { background: #e8eefb; color: #2b579a; }

/* Record-count pill in the page header. */
.gp-count-pill { background: var(--gp-input-bg); color: var(--gp-muted); font-size: 0.8rem; font-weight: 700; padding: 0.3rem 0.7rem; border-radius: 999px; white-space: nowrap; }

/* Forms */
.gp-form-card { background: var(--gp-card); border: 1px solid var(--gp-border); border-radius: 16px; padding: 1.5rem; }
/* Backup settings card: icon tile + explanatory text. */
.gp-backup-head { display: flex; align-items: flex-start; gap: 0.9rem; line-height: 1.55; }
.gp-backup-ic { flex: none; width: 3rem; height: 3rem; border-radius: 12px; display: grid; place-items: center; background: var(--gp-brand-soft); color: var(--gp-brand); }
.gp-form-section { font-size: 0.95rem; font-weight: 800; color: var(--gp-brand-ink); margin-block-end: 0.75rem; }
.gp-account-avatar { font-size: 2.4rem; color: var(--gp-brand); }

/* Empty state */
.gp-empty { text-align: center; color: var(--gp-muted); padding: 3rem 1rem; }
.gp-empty .bi { font-size: 2rem; color: var(--gp-brand); }
.gp-empty .gp-lucide { color: var(--gp-brand); }
.gp-empty--lg { padding: 4rem 1rem; }

.gp-flash { border-radius: 12px; }

/* ============================ Responsive ============================= */

@media (max-width: 991.98px) {
    .gp-bo-shell, .gp-bo-shell.is-collapsed { grid-template-columns: 1fr; }
    .gp-side {
        position: fixed; top: 0; bottom: 0; inset-inline-start: 0; width: 280px; max-width: 82vw;
        z-index: 60; transform: translateX(-100%); transition: transform 0.25s ease;
    }
    [dir="rtl"] .gp-side { transform: translateX(100%); }
    .gp-bo-shell.is-drawer-open .gp-side { transform: translateX(0); box-shadow: 0 0 40px rgba(0,0,0,0.35); }
    .gp-side-close { display: inline-flex; } /* close (X) button visible in the drawer */
    .gp-bo-shell.is-drawer-open .gp-side-backdrop {
        display: block; position: fixed; inset: 0; z-index: 55; background: rgba(0,0,0,0.45);
    }
    /* On mobile the drawer is always full-width, so every collapsed-rail rule
       must be undone — not just the text hiding. Reverting `display` alone left
       the icon-rail GEOMETRY behind (centred items, zero inline padding), so
       the drawer showed labels crammed against centred icons. */
    .is-collapsed .gp-side-brand-text,
    .is-collapsed .gp-side-item-text,
    .is-collapsed .gp-side-group-label,
    .is-collapsed .gp-side-chev { display: revert; }
    .is-collapsed .gp-side-item,
    .is-collapsed .gp-side-group-head,
    .is-collapsed .gp-side-brand { justify-content: flex-start; padding-inline: revert; }
    .is-collapsed .gp-side-item--sub { padding-inline-start: revert; }
    .gp-vpanel-row { grid-template-columns: 1fr; }
}

@media (min-width: 992px) {
    /* Desktop: the menu button collapses to the icon rail, no drawer. */
    .gp-bo-menu-btn { display: inline-flex; }
}

@media (max-width: 575.98px) {
    .gp-kpi-grid { grid-template-columns: repeat(2, 1fr); }
    .gp-bo-content { padding: 1rem; }
    .gp-vpage-title { font-size: 1.25rem; }
    .gp-vpage-head { gap: 0.5rem; }
    /* Filters + toolbar stack and go full-width on phones. */
    .gp-filters, .gp-filter, .gp-filter-actions,
    .gp-toolbar, .gp-toolbar-start, .gp-toolbar-end { width: 100%; }
    .gp-filter, .gp-filter input, .gp-filter select { width: 100%; }
    .gp-toolbar-search { min-width: 0; width: 100%; }
    .gp-form-card { padding: 1.15rem; }
    .gp-donut { justify-content: center; }
    .gp-kpi-value { font-size: 1.4rem; }
}

/* Very small phones (≤360px: iPhone SE, older Android): single-column KPIs +
   capture tiles so nothing truncates; shrink the donut to fit. */
@media (max-width: 359.98px) {
    .gp-kpi-grid { grid-template-columns: 1fr; }
    .gp-donut-ring { width: 140px; height: 140px; }
    .gp-donut-hole { width: 96px; height: 96px; }
    .gp-donut-num { font-size: 1.6rem; }
    .gp-bo-content { padding: 0.85rem; }
}

/* Coarse-pointer (touch) devices: larger tap targets. */
@media (pointer: coarse) {
    .gp-side-item, .gp-side-group-head { padding-block: 0.7rem; }
    .btn { min-height: 42px; }
}

/* ============================ Print ================================= */

@media print {
    .gp-side, .gp-bo-header, .gp-print-hide, .gp-guard-bottomnav { display: none !important; }
    /* .is-collapsed must be listed explicitly: media queries add no specificity,
       so a bare `.gp-bo-shell` (0,1,0) loses to `.gp-bo-shell.is-collapsed`
       (0,2,0) and the report would print inside the 72px icon-rail column. */
    .gp-bo-shell, .gp-bo-shell.is-collapsed { grid-template-columns: 1fr; }
    .gp-bo-content { padding: 0; }
    /* Never clip a wide table at the page edge — there is no scrollbar on paper. */
    .gp-table-wrap { border: 0; overflow: visible; }
}

/* ==========================================================================
   Polish & accessibility layer
   ========================================================================== */

/* Consistent, visible keyboard focus everywhere (brand ring). */
a:focus-visible, button:focus-visible, .btn:focus-visible,
.form-control:focus-visible, .form-select:focus-visible,
.gp-side-item:focus-visible, .gp-side-group-head:focus-visible,
.gp-vcard:focus-visible, .gp-cap-photo:focus-within, .gp-evi-item:focus-visible,
.dropdown-item:focus-visible {
    outline: 2px solid var(--gp-brand);
    outline-offset: 2px;
    border-radius: 6px;
}

/* Skip-to-content link — appears on keyboard focus. */
.gp-skip {
    position: absolute; inset-inline-start: -999px; inset-block-start: 0.5rem;
    z-index: 200; background: var(--gp-brand); color: #fff;
    padding: 0.5rem 1rem; border-radius: 8px; font-weight: 700;
}
.gp-skip:focus { inset-inline-start: 0.5rem; color: #fff; }

/* Interactive polish: gentle transitions + hover feedback. */
.btn { transition: background 0.15s, border-color 0.15s, box-shadow 0.15s, transform 0.05s; }
.btn:active { transform: translateY(1px); }
.gp-vcard, .gp-kpi, .gp-cap-photo, .gp-evi-item, .gp-table tbody tr, .gp-side-item {
    transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease, border-color 0.15s ease;
}
.gp-vcard:hover { box-shadow: 0 2px 10px rgba(20,35,27,0.06); transform: translateY(-1px); }
.gp-kpi:hover { box-shadow: 0 4px 14px rgba(20,35,27,0.07); transform: translateY(-1px); }
.gp-evi-item:hover { border-color: var(--gp-brand); }
.gp-table tbody tr:hover { background: rgba(22,161,99,0.04); }

/* A form control in focus gets the brand ring, matching the design system. */
.form-control:focus, .form-select:focus {
    border-color: var(--gp-brand);
    box-shadow: 0 0 0 0.2rem rgba(22,161,99,0.2);
}

/* Submit buttons show a busy state (set by app.js on submit). */
.btn.is-loading { pointer-events: none; opacity: 0.75; }
.btn.is-loading::after {
    content: ""; display: inline-block; width: 0.9em; height: 0.9em;
    margin-inline-start: 0.5em; border: 2px solid currentColor;
    border-inline-end-color: transparent; border-radius: 50%;
    vertical-align: -0.15em; animation: gp-spin 0.6s linear infinite;
}
@keyframes gp-spin { to { transform: rotate(360deg); } }

/* Respect users who prefer reduced motion. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}

/* ---- Success modal (entry/exit confirmation — matches design deck) ---- */
.gp-success-modal {
    position: fixed; inset: 0; z-index: 100; display: grid; place-items: center;
    padding: 1.5rem; background: rgba(20, 35, 27, 0.35);
    animation: gp-fade-in 0.2s ease;
}
.gp-success-card {
    background: #fff; border-radius: 22px; padding: 2rem 2.5rem; text-align: center;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28); max-width: min(360px, 85vw);
    animation: gp-pop 0.25s ease;
}
.gp-success-ic {
    position: relative; display: inline-flex; color: var(--gp-brand-ink); line-height: 1;
}
/* Green disc with a white check, ringed in white to lift off the car icon. */
.gp-success-check {
    position: absolute; inset-block-end: -0.2rem; inset-inline-end: -0.35rem;
    display: grid; place-items: center; width: 1.55rem; height: 1.55rem;
    color: #fff; background: var(--gp-brand); border-radius: 50%;
    box-shadow: 0 0 0 3px #fff;
}
.gp-success-text {
    margin-block-start: 1rem; font-weight: 800; font-size: 1.15rem; color: var(--gp-brand-ink);
}
@keyframes gp-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes gp-pop { from { transform: scale(0.9); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* ---------- Two-factor authentication (TOTP) ---------- */
.gp-otp-heading { text-align:center; margin:0 0 0.35rem; font-weight:800; font-size:1.25rem; color:var(--gp-brand-ink); }
.gp-otp-sub     { text-align:center; color:var(--gp-muted); font-size:0.85rem; margin:0 0 1.25rem; }

/* Enrolment flow: numbered steps + QR + manual key + code entry */
.gp-otp-enrol      { display:flex; flex-direction:column; gap:1.25rem; }
.gp-otp-step       { display:flex; gap:0.85rem; align-items:flex-start; }
.gp-otp-step--form { margin:0; }
.gp-otp-step-num   {
    flex:none; width:28px; height:28px; border-radius:50%;
    background:var(--gp-brand); color:#fff;
    display:inline-flex; align-items:center; justify-content:center;
    font-weight:800; font-size:0.95rem; font-variant-numeric:tabular-nums;
    box-shadow:0 1px 2px rgba(0,0,0,0.15);
}
.gp-otp-step-body  { flex:1 1 auto; min-width:0; }
.gp-otp-step-title { font-weight:700; color:var(--gp-brand-ink); margin:0; }
.gp-otp-step-hint  { margin:0.15rem 0 0; }

.gp-otp-qr {
    align-self:center; padding:14px; background:#fff;
    border:1px solid var(--gp-border); border-radius:14px;
    box-shadow:0 4px 14px rgba(15,23,42,0.06);
    color:#0f172a;
}
.gp-otp-qr svg { display:block; width:220px; height:220px; image-rendering:pixelated; shape-rendering:crispEdges; }
.gp-otp-openlink {
    align-self:center; color:var(--gp-brand); font-weight:600;
    font-size:0.9rem; text-decoration:none; margin-top:-0.5rem;
}
.gp-otp-openlink:hover { text-decoration:underline; }

.gp-otp-manual         { border:1px dashed var(--gp-border); border-radius:10px; padding:0.65rem 0.9rem; }
.gp-otp-manual summary { cursor:pointer; font-weight:600; color:var(--gp-muted); font-size:0.9rem; list-style:none; }
.gp-otp-manual summary::-webkit-details-marker { display:none; }
.gp-otp-manual summary::before { content:"+ "; font-weight:700; color:var(--gp-brand); }
.gp-otp-manual[open] summary::before { content:"− "; }
/* ============================================================
   User edit — redesigned page (hero + panels + tiles)
   ============================================================ */
.gp-user-edit .gp-vpage-head { align-items:center; gap:0.5rem; }
.gp-user-backlink {
    display:inline-flex; align-items:center; gap:0.25rem;
    color:var(--gp-muted); font-size:0.85rem; font-weight:600;
    text-decoration:none; margin-bottom:0.75rem;
}
.gp-user-backlink:hover { color:var(--gp-brand); }
.gp-vpage-back {
    display:inline-flex; align-items:center; justify-content:center;
    width:36px; height:36px; border-radius:50%;
    color:var(--gp-brand-ink); background:transparent;
    border:1px solid var(--gp-border);
    text-decoration:none; transition:background 0.15s ease;
}
.gp-vpage-back:hover { background:var(--gp-brand-soft); color:var(--gp-brand); }

.gp-inline-alert {
    display:flex; align-items:center; gap:0.6rem;
    padding:0.75rem 1rem; border-radius:12px; font-weight:600;
    border:1px solid var(--gp-border); margin-bottom:1rem;
}
.gp-inline-alert--ok  { background:rgba(22,161,99,0.08);  color:#0e7c47; border-color:rgba(22,161,99,0.30); }
.gp-inline-alert--err { background:rgba(217,45,32,0.08);  color:#a92019; border-color:rgba(217,45,32,0.30); }


/* Compact user edit — single card with hair-rule subsections */
.gp-user-form   { display:flex; flex-direction:column; gap:0.85rem; }
.gp-user-card {
    background:var(--gp-card); border:1px solid var(--gp-border);
    border-radius:14px; padding:0.85rem 1.15rem 0.95rem;
    box-shadow:0 2px 8px rgba(15,23,42,0.03);
}
.gp-user-sec { padding:0.85rem 0; border-bottom:1px solid var(--gp-border); }
.gp-user-sec:last-of-type { border-bottom:none; padding-bottom:0.5rem; }
.gp-user-sec-title {
    display:inline-flex; align-items:center; gap:0.4rem;
    margin:0 0 0.75rem; font-size:0.95rem; font-weight:700;
    color:var(--gp-brand-ink);
}
.gp-user-sec-title svg { color:var(--gp-brand); }

/* Identity strip — role-tinted accent stripe + generous whitespace */
.gp-user-idbar {
    position:relative; overflow:hidden;
    display:flex; align-items:stretch; gap:0;
    border-radius:14px; background:var(--gp-card);
    border:1px solid var(--gp-border);
    box-shadow:0 4px 16px rgba(15,23,42,0.04);
}
.gp-user-idbar-stripe {
    flex:none; width:5px; align-self:stretch;
    background:linear-gradient(180deg, var(--gp-brand), var(--gp-brand-2));
}
.gp-user-idbar--admin      .gp-user-idbar-stripe { background:linear-gradient(180deg,#dc2626,#b91c1c); }
.gp-user-idbar--supervisor .gp-user-idbar-stripe { background:linear-gradient(180deg,#3b82f6,#1d4ed8); }
.gp-user-idbar-body  { padding:0.9rem 1.1rem; min-width:0; flex:1 1 auto; }
.gp-user-idbar-nameline {
    display:flex; align-items:center; gap:0.55rem; flex-wrap:wrap;
    line-height:1.1;
}
.gp-user-idbar-name {
    font-weight:800; font-size:1.15rem; color:var(--gp-brand-ink);
    letter-spacing:-0.01em;
}
.gp-user-idbar-selftag {
    padding:0.15rem 0.55rem; border-radius:999px;
    background:var(--gp-brand); color:#fff; font-size:0.7rem; font-weight:700;
    display:inline-flex; align-items:center; gap:0.28rem;
    box-shadow:0 2px 6px rgba(22,161,99,0.35);
}
.gp-user-idbar-inactive {
    padding:0.15rem 0.5rem; border-radius:999px;
    background:rgba(217,45,32,0.10); color:var(--gp-danger);
    font-size:0.7rem; font-weight:700;
    display:inline-flex; align-items:center; gap:0.25rem;
}

.gp-user-idbar-meta {
    display:flex; align-items:center; gap:1.1rem; flex-wrap:wrap;
    margin-top:0.5rem; padding-top:0.5rem;
    border-top:1px solid var(--gp-border);
    color:var(--gp-muted); font-size:0.82rem;
}
.gp-user-idbar-meta-item {
    display:inline-flex; align-items:center; gap:0.35rem;
}
.gp-user-idbar-meta-item svg      { color:var(--gp-muted); opacity:0.7; flex:none; }
.gp-user-idbar-meta-label         { color:var(--gp-muted); font-weight:600; }
.gp-user-idbar-meta-item strong   { color:var(--gp-brand-ink); font-weight:700; }
.gp-idbar-2fa-on  { color:#0e7c47 !important; }
.gp-idbar-2fa-off { color:#6b7280 !important; }


/* Compact readonly / disabled visuals */
.gp-user-form .form-control[readonly] {
    background:#f8fafc; color:var(--gp-brand-ink); font-weight:600;
    border-color:var(--gp-border); cursor:not-allowed;
}
.gp-user-form .form-select:disabled,
.gp-user-form .form-control:disabled {
    background:#f1f5f9; color:#64748b; cursor:not-allowed; opacity:0.95;
}
.gp-user-form .form-text { display:inline-flex; align-items:center; gap:0.3rem; }

/* Compact 2FA row — icon + status + inline action, matches form-select height */
.gp-2fa-row {
    display:flex; align-items:center; gap:0.55rem;
    padding-block:0.25rem; padding-inline:0.4rem 0.6rem; border-radius:8px; min-height:38px;
    border:1px solid var(--gp-border); background:var(--gp-input-bg);
}
.gp-2fa-row.is-on { background:rgba(22,161,99,0.08); border-color:rgba(22,161,99,0.30); }
.gp-2fa-row-ic {
    width:26px; height:26px; border-radius:6px; flex:none;
    display:inline-flex; align-items:center; justify-content:center;
    background:rgba(107,114,128,0.15); color:#4b5563;
}
.gp-2fa-row.is-on .gp-2fa-row-ic { background:rgba(22,161,99,0.20); color:#0e7c47; }
.gp-2fa-row-status { font-weight:700; color:var(--gp-brand-ink); }
.gp-2fa-row.is-on .gp-2fa-row-status { color:#0e7c47; }
.gp-2fa-row-disable summary { list-style:none; cursor:pointer; }
.gp-2fa-row-disable summary::-webkit-details-marker { display:none; }
.gp-2fa-disable-form { min-width:220px; }

/* Enrolment mini-panel appears under the row when mid-setup */
.gp-2fa-enrol {
    display:flex; flex-direction:column; gap:0.6rem;
    margin-top:0.65rem; padding:0.85rem; border-radius:10px;
    border:1px dashed var(--gp-border); background:#fbfcfc;
}
.gp-2fa-enrol-qr {
    align-self:center; padding:8px; background:#fff;
    border:1px solid var(--gp-border); border-radius:10px;
    color:#0f172a;
}
.gp-2fa-enrol-qr svg { display:block; width:160px; height:160px; image-rendering:pixelated; shape-rendering:crispEdges; }
.gp-2fa-enrol-form .gp-otp-input { max-width:150px; }


/* Active/inactive toggle — matches form-select height (~38px).
   State is driven by the checkbox itself (:has), NOT by a server-rendered
   class, so clicking it updates immediately. The .is-on/.is-off classes PHP
   still writes remain as the no-:has fallback for older engines. */
.gp-user-active-toggle {
    display:flex; align-items:center; gap:0.6rem; cursor:pointer;
    padding:0.375rem 0.75rem; border-radius:8px; min-height:38px;
    border:1px solid var(--gp-border); background:var(--gp-input-bg);
    font-weight:600; user-select:none; transition:all 0.15s ease;
}
.gp-user-active-toggle.is-on  { background:rgba(22,161,99,0.10); border-color:rgba(22,161,99,0.35); color:#0e7c47; }
.gp-user-active-toggle.is-off { background:rgba(107,114,128,0.10); color:#4b5563; }
.gp-user-active-toggle.is-locked { cursor:not-allowed; opacity:0.75; }
.gp-user-active-track {
    position:relative; width:38px; height:22px; border-radius:999px;
    background:rgba(0,0,0,0.15); transition:background 0.2s ease; flex:none;
}
.gp-user-active-thumb {
    position:absolute; top:2px; inset-inline-start:2px;
    width:18px; height:18px; border-radius:50%; background:#fff;
    box-shadow:0 1px 3px rgba(0,0,0,0.2);
    transition:inset-inline-start 0.2s ease;
}
.gp-user-active-toggle.is-on .gp-user-active-track { background:var(--gp-brand); }
.gp-user-active-toggle.is-on .gp-user-active-thumb { inset-inline-start:18px; }

/* Live state — wins over the server-rendered classes above. */
.gp-user-active-toggle:has(input:checked) {
    background:rgba(22,161,99,0.10); border-color:rgba(22,161,99,0.35); color:#0e7c47;
}
.gp-user-active-toggle:has(input:not(:checked)) {
    background:rgba(107,114,128,0.10); border-color:var(--gp-border); color:#4b5563;
}
.gp-user-active-toggle:has(input:checked) .gp-user-active-track { background:var(--gp-brand); }
.gp-user-active-toggle:has(input:checked) .gp-user-active-thumb { inset-inline-start:18px; }
.gp-user-active-toggle:has(input:not(:checked)) .gp-user-active-track { background:rgba(0,0,0,0.15); }
.gp-user-active-toggle:has(input:not(:checked)) .gp-user-active-thumb { inset-inline-start:2px; }
.gp-user-active-toggle:has(input:focus-visible) { outline:2px solid var(--gp-brand); outline-offset:2px; }
/* The label text is swapped by app.js, which also covers engines without :has. */




/* Action bar */
.gp-user-actionbar {
    display:flex; gap:0.5rem; justify-content:flex-end;
    padding-top:0.25rem;
}

@media (max-width: 640px) {
    .gp-user-idbar-meta  { font-size:0.8rem; }
    .gp-user-actionbar   { justify-content:stretch; flex-direction:column-reverse; }
    .gp-user-actionbar > * { width:100%; }
}

.gp-otp-secret         {
    display:block; margin-top:0.6rem; padding:0.65rem 0.75rem;
    background:#f8fafc; border-radius:8px;
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size:0.95rem; letter-spacing:0.08em; word-break:break-all;
    color:var(--gp-brand-ink);
}
