/* ------------------------------------------------------------------
   Briya kiosk theme — colors and fonts follow the official Briya
   brand guidelines (Briya Blue #0084CB primary, Lexend Deca for
   student-facing UI with Calibri fallback for hosts without the font).
------------------------------------------------------------------ */
:root {
    /* Brand blues */
    --briya-blue:        #0084CB;  /* primary */
    --briya-blue-dark:   #006197;  /* hover / active / links */
    --briya-blue-medium: #00A2E4;
    --briya-blue-light:  #60C3EF;
    --briya-blue-tint:   #E8F4FB;  /* very light bg, key-press feedback */

    /* Warm accents — use sparingly */
    --briya-orange: #FBAA19;
    --briya-yellow: #FFC60B;
    --briya-green:  #AAD047;

    /* Neutrals */
    --briya-black:    #231F20;
    --briya-gray-65:  #77787B;
    --briya-gray-25:  #C7C8CA;
    --briya-white:    #FFFFFF;

    /* Semantic / surface */
    --surface-bg:    #F4F8FB;
    --surface-card:  #FFFFFF;
    --error-bg:      #FEE2E2;
    --error-text:    #B91C1C;
    --shadow-sm: 0 2px 4px rgba(35, 31, 32, 0.06);
    --shadow-md: 0 6px 20px rgba(35, 31, 32, 0.08);
    --shadow-lg: 0 12px 32px rgba(0, 97, 151, 0.18);
}

* { box-sizing: border-box; }
html, body {
    margin: 0; padding: 0;
    font-family: "Lexend Deca", "Calibri", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    background: var(--surface-bg);
    color: var(--briya-black);
    -webkit-touch-callout: none;
    overscroll-behavior: none;
}
/* Disable text selection on the kiosk side only (a student dragging across
   the screen shouldn't highlight UI text). The admin side stays selectable
   so staff can copy filenames, emails, API keys, and table cells. */
body.kiosk {
    -webkit-user-select: none;
            user-select: none;
}
/* Body grows with content + dynamic padding-bottom set by vkb.js so the
   page is scrollable past the keyboard. */

body.signing { touch-action: pan-y; -ms-touch-action: pan-y; }
body.signing .sig-wrap, body.signing #sigpad { touch-action: none; -ms-touch-action: none; overscroll-behavior: contain; }

/* Stop iOS/Android browsers from treating rapid taps on the kiosk's buttons
   and cards as a double-tap-to-zoom gesture. `manipulation` says "these are
   taps; don't wait 300ms for a possible zoom" so the keypad responds
   instantly and the page doesn't zoom in when a user taps fast. */
button, a, label, input[type="checkbox"], [role="button"],
.key, .text-link, .check-pill,
.tile, .step, .home-begin, .home-btn,
.teacher-card, .student-card,
.admin-nav a, .admin-card, .admin-tech-remove,
.admin-files-action, .admin-danger-btn,
.back-btn, .admin-btn, .admin-logout-btn,
.sig-expand-btn, .sig-baseline,
.primary, .secondary {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

body.kiosk { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; }

/* ------------------------------------------------------------------
   Topbar — Briya Blue background. Three-section grid: [Back][Logo][Admin].
   Logo stays centered regardless of which side-buttons are visible.
------------------------------------------------------------------ */
.topbar {
    display: grid;
    /* minmax(0,1fr) lets the side tracks shrink so the user-menu name ellipsizes
       instead of forcing horizontal overflow on the smallest phones. */
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    gap: clamp(8px, 1.6vmin, 24px);
    padding: clamp(8px, 1.2vh, 18px) clamp(14px, 2.2vmin, 36px);
    background: var(--briya-blue);
    color: var(--briya-white);
    box-shadow: 0 2px 0 var(--briya-blue-dark);
}

.topbar > .back-btn, .topbar > .topbar-spacer { justify-self: start; }
.topbar > .brand                             { justify-self: center; }
.topbar > .admin-btn                         { justify-self: end; }
.topbar-spacer                               { width: 1px; height: 1px; }

.brand { display: inline-flex; align-items: center; text-decoration: none; line-height: 0; }
.brand-logo {
    display: block;
    height: clamp(44px, 7vh, 110px);
    width: auto;
    max-width: 100%;
    object-fit: contain;
}

.back-btn, .admin-btn {
    display: inline-flex; align-items: center; justify-content: center;
    gap: clamp(4px, 0.8vmin, 10px);
    padding: clamp(8px, 1.2vmin, 16px) clamp(12px, 1.8vmin, 24px);
    /* vmin-based padding collapses on a phone, leaving these at ~38px tall.
       They're on every kiosk page and get tapped with a thumb, so floor the
       box at the 44px touch guideline instead of letting it scale away. */
    min-height: 44px; min-width: 44px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.55);
    background: transparent;
    color: var(--briya-white);
    text-decoration: none;
    font-family: inherit;
    font-size: clamp(13px, 1.8vmin, 20px);
    font-weight: 600;
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, transform 0.06s;
}
.back-btn:hover, .admin-btn:hover {
    background: rgba(255, 255, 255, 0.10);
}
.back-btn:active, .admin-btn:active {
    background: rgba(255, 255, 255, 0.20);
    border-color: var(--briya-white);
    transform: translateY(1px);
}
.back-btn svg, .admin-btn svg {
    width: clamp(16px, 2.2vmin, 24px);
    height: clamp(16px, 2.2vmin, 24px);
    flex-shrink: 0;
}

/* Admin button gets a touch more emphasis — filled-tint background + a faint
   shield-blue glow so it reads as the right-side primary action. */
.admin-btn {
    background: rgba(255, 255, 255, 0.10);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.18) inset;
}
.admin-btn:hover  { background: rgba(255, 255, 255, 0.18); }
.admin-btn:active { background: rgba(255, 255, 255, 0.28); }

/* On narrow screens, drop the text labels — icon-only pills. */
@media (max-width: 540px) {
    .back-btn .back-label,
    .admin-btn .admin-label { display: none; }
    .back-btn, .admin-btn   { padding: 10px 12px; }
}

.content {
    flex: 1; width: 100%; margin: 0 auto;
    padding: clamp(10px, 1.6vh, 36px) clamp(14px, 2vmin, 48px);
    max-width: min(94vw, 1600px);
    display: flex;
    flex-direction: column;
    /* Vertically center the page section. `safe center` is critical — when
       a page's content is taller than the viewport (long forms), the
       browser falls back to start-alignment so the top never gets clipped
       above the scroll position. */
    justify-content: center;
    justify-content: safe center;
}

h1 {
    font-size: clamp(24px, 3.6vmin, 56px);
    margin: 0 0 clamp(10px, 1.6vh, 24px);
    color: var(--briya-black); font-weight: 700;
    overflow-wrap: anywhere;
}
h2 {
    font-size: clamp(16px, 2.2vmin, 28px);
    margin: clamp(12px, 1.8vh, 28px) 0 clamp(6px, 1vh, 14px);
    color: var(--briya-black); font-weight: 600;
}
.subtitle { font-size: clamp(14px, 2vmin, 24px); color: var(--briya-gray-65); margin: 0 0 clamp(12px, 1.6vh, 24px); }
/* The negative pull is only meant to snug a subtitle up under its heading, so
   scope it to that exact adjacency. As a blanket rule it collided with anything
   else placed between the two — e.g. the SIS/Class line on the language page. */
h1 + .subtitle { margin-top: -10px; }
.muted    { color: var(--briya-gray-65); }

/* ------------------------------------------------------------------
   HOME — process roadmap with CTA
------------------------------------------------------------------ */
.subtitle-center { text-align: center; }

/* Home hero fills the .content area and distributes its three blocks
   (head, steps, CTA) with even vertical spacing instead of clustering
   them at the top. Result: header sits near the top, roadmap floats
   in the middle, "Begin Return" lands in the lower thumb-zone — same
   content the user already likes, just spread across the viewport. */
.home-hero {
    max-width: min(94vw, 1400px);
    margin: 0 auto;
    width: 100%;
    flex: 1;
    display: flex; flex-direction: column;
    justify-content: space-evenly;
    align-items: stretch;
    gap: clamp(16px, 3vh, 48px);  /* minimum breathing room; space-evenly adds the rest */
    padding: clamp(8px, 2vh, 36px) 0 clamp(12px, 2.4vh, 40px);
}
.home-head { text-align: center; margin-bottom: 0; }
.home-head h1 {
    font-size: clamp(24px, 4.2vh, 60px);
    margin: clamp(2px, 0.5vh, 10px) 0 clamp(4px, 0.8vh, 14px);
}
.home-head .subtitle {
    margin: 0;
    font-size: clamp(13px, 2vh, 26px);
}

.steps {
    list-style: none; padding: 0;
    margin: 0;                       /* spacing owned by .home-hero now */
    display: flex; align-items: stretch; justify-content: center;
    gap: clamp(4px, 0.8vh, 12px); flex-wrap: nowrap;
}
.step {
    flex: 1 1 0; min-width: 0; max-width: 240px;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(14px, 2vmin, 24px);
    padding: clamp(12px, 2.2vh, 30px) clamp(10px, 1.6vmin, 22px) clamp(10px, 1.8vh, 24px);
    text-align: center;
    box-shadow: var(--shadow-sm);
    transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}
.step-num {
    width: clamp(42px, 6vh, 76px);
    height: clamp(42px, 6vh, 76px);
    border-radius: 50%;
    background: linear-gradient(135deg, var(--briya-blue-medium), var(--briya-blue));
    color: var(--briya-white);
    font-size: clamp(18px, 2.8vh, 34px); font-weight: 700;
    display: flex; align-items: center; justify-content: center;
    margin: 0 auto clamp(6px, 1.2vh, 16px);
    box-shadow: 0 6px 14px rgba(0, 132, 203, 0.28);
}
.step-num svg { width: 50%; height: 50%; }
.step-title { font-size: clamp(14px, 2.1vh, 22px); font-weight: 700; color: var(--briya-black); margin-bottom: clamp(2px, 0.5vh, 6px); line-height: 1.2; }
.step-meta  { font-size: clamp(11px, 1.6vh, 18px); color: var(--briya-gray-65); line-height: 1.45; }
.step-done .step-num {
    background: linear-gradient(135deg, var(--briya-green), #7AB02C);
    box-shadow: 0 6px 14px rgba(170, 208, 71, 0.4);
}
.step-arrow {
    list-style: none;
    display: flex; align-items: center; justify-content: center;
    color: var(--briya-blue-light);
    flex: 0 0 auto; padding: 0 2px;
}
.step-arrow svg { width: clamp(18px, 2.6vh, 30px); height: clamp(18px, 2.6vh, 30px); }

.home-cta { display: flex; justify-content: center; margin-top: 0; }

/* ------------------------------------------------------------------
   HOME — task picker (contract device / contract hotspot / return).
   Three equal cards on a wide kiosk; they stack on a phone. Sized with
   the same clamp() vocabulary as .step so the two rows agree visually
   at every viewport.
------------------------------------------------------------------ */
.task-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(10px, 1.6vmin, 24px);
    width: 100%;
    max-width: 1180px;
    margin: 0 auto;
}
@media (max-width: 900px) { .task-grid { grid-template-columns: 1fr; } }

.task-card {
    position: relative;
    display: flex; flex-direction: column;
    gap: clamp(3px, 0.6vh, 8px);
    padding: clamp(16px, 2.6vh, 34px) clamp(16px, 2.2vmin, 30px) clamp(46px, 5vh, 62px);
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(14px, 2vmin, 24px);
    box-shadow: var(--shadow-sm);
    text-decoration: none;
    transition: transform 0.12s, box-shadow 0.12s, border-color 0.12s;
}
.task-card:active { transform: scale(0.985); box-shadow: var(--shadow-sm); }
@media (hover: hover) {
    .task-card:hover {
        border-color: var(--briya-blue-light);
        box-shadow: 0 12px 30px rgba(0, 97, 151, 0.16);
        transform: translateY(-2px);
    }
}

.task-badge {
    align-self: flex-start;
    font-size: clamp(10px, 1.2vh, 13px);
    font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    padding: 3px clamp(8px, 1vmin, 12px);
    border-radius: 999px;
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
}
.task-return .task-badge { background: rgba(170, 208, 71, 0.22); color: #5C7A18; }

.task-icon {
    width: clamp(40px, 5.4vh, 66px);
    height: clamp(40px, 5.4vh, 66px);
    border-radius: clamp(12px, 1.6vmin, 20px);
    margin: clamp(6px, 1.2vh, 16px) 0 clamp(4px, 0.8vh, 10px);
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, var(--briya-blue-medium), var(--briya-blue));
    color: var(--briya-white);
    box-shadow: 0 6px 14px rgba(0, 132, 203, 0.26);
}
.task-return .task-icon {
    background: linear-gradient(135deg, var(--briya-green), #7AB02C);
    box-shadow: 0 6px 14px rgba(170, 208, 71, 0.4);
}
.task-icon svg { width: 56%; height: 56%; }

.task-title {
    font-size: clamp(16px, 2.3vh, 26px); font-weight: 700;
    color: var(--briya-black); line-height: 1.22;
}
.task-meta {
    font-size: clamp(12px, 1.6vh, 18px);
    color: var(--briya-gray-65); line-height: 1.4;
}
.task-go {
    position: absolute;
    right: clamp(14px, 2vmin, 26px);
    bottom: clamp(14px, 1.8vh, 24px);
    width: clamp(30px, 3.8vh, 44px);
    height: clamp(30px, 3.8vh, 44px);
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
}
.task-return .task-go { background: rgba(170, 208, 71, 0.22); color: #5C7A18; }
.task-go svg { width: 58%; height: 58%; }

/* Site footer — currently only on the home page. */
.site-footer {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: clamp(6px, 1vmin, 14px);
    padding: clamp(8px, 1.4vh, 22px) clamp(16px, 2.4vmin, 36px);
    color: var(--briya-gray-65);
    font-size: clamp(11px, 1.4vh, 17px);
    text-align: center;
    background: transparent;
    border-top: 1px solid var(--briya-gray-25);
    flex-wrap: wrap;
}
.site-footer-sep { opacity: 0.6; }
.home-begin {
    display: inline-flex; align-items: center; gap: clamp(10px, 1.6vmin, 22px);
    background: linear-gradient(135deg, var(--briya-blue-medium), var(--briya-blue-dark));
    color: var(--briya-white);
    text-decoration: none; font-weight: 700;
    font-size: clamp(18px, 3.2vh, 40px);
    padding: clamp(12px, 2.4vh, 30px) clamp(32px, 5vmin, 72px);
    border-radius: 999px;
    box-shadow: 0 14px 36px rgba(0, 97, 151, 0.32);
    transition: transform 0.1s, box-shadow 0.1s;
}
.home-begin:active {
    transform: scale(0.98);
    box-shadow: 0 6px 18px rgba(0, 97, 151, 0.32);
}
.home-begin-arrow { width: clamp(20px, 2.8vh, 32px); height: clamp(20px, 2.8vh, 32px); }

/* ------------------------------------------------------------------
   LOOKUP — fully fluid sizing.
   Everything below uses clamp(min, vmin-based, max) so the keypad
   and input scale smoothly from a 375px phone to a 4K kiosk (and
   same size in portrait vs landscape, since vmin = min(vw, vh)).
------------------------------------------------------------------ */

/* Required-field star */
.req { color: var(--briya-orange); font-weight: 700; margin-left: 2px; }

/* Lookup container — sized to fit the viewport so users don't need to scroll.
   Vertical-sensitive clamps use vh; horizontal/font scale with vmin.
   `width: 100%` is critical here — inside a flex-column parent, auto margins
   would otherwise shrink the section to its content width, which (with the
   grid auto-fill children) collapses to a single column.
   Width capped at 880px so the input/keypad fit comfortably on the kiosk
   without stretching across very wide screens. The .teacher modifier
   overrides this to a wider cap for the photo-card grid. */
.lookup {
    max-width: min(94vw, 880px);
    width: 100%;
    margin: 0 auto;
    padding: clamp(4px, 0.8vh, 18px) 0;
}
.lookup h1 {
    font-size: clamp(22px, 3.4vh, 64px);
    margin-bottom: clamp(4px, 0.8vh, 18px);
    text-align: center;
}
.lookup .subtitle {
    font-size: clamp(13px, 2vh, 28px);
    margin: 0 0 clamp(10px, 1.4vh, 26px);
}

/* Compact the lookup header + footer link when the VKB is open. With the
   keyboard claiming ~48vh from the bottom and the topbar another ~95px
   from the top, the form has to live in a much thinner band — especially
   on phone landscape. Shrink the heading/subtitle so the input + Continue
   button stay comfortably above the keyboard on every viewport. */
body.vkb-open .lookup h1 {
    font-size: clamp(20px, 2.8vh, 40px);
    margin-bottom: clamp(3px, 0.6vh, 10px);
}
body.vkb-open .lookup .subtitle {
    font-size: clamp(13px, 1.8vh, 18px);
    margin-bottom: clamp(8px, 1.1vh, 14px);
}
body.vkb-open .lookup form { gap: clamp(8px, 1.1vh, 16px); }
body.vkb-open .text-link {
    margin-top: clamp(6px, 1vh, 14px);
    padding: clamp(6px, 1vh, 14px) clamp(14px, 2vmin, 28px);
    font-size: clamp(12px, 1.7vh, 18px);
}

/* Big search input — caret area; readonly in numeric mode, editable in ABC.
   Caps tuned so the placeholder ("FT25C001") and typical 6-7 digit SIS values
   always fit without overflow: ~64px max font on big screens, ~28px on phones.
   Margin-bottom is 0 because `.lookup form` now uses flex `gap` for spacing. */
.big-input {
    width: 100%;
    min-width: 0;
    font-size: clamp(28px, 4.5vh, 64px);
    text-align: center;
    padding: clamp(8px, 1.2vh, 20px) clamp(8px, 1.2vmin, 22px);
    border: 2px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.4vmin, 24px);
    background: var(--surface-card);
    margin-bottom: 0;
    letter-spacing: clamp(2px, 0.4vmin, 4px);
    color: var(--briya-black);
}
.big-input:focus { border-color: var(--briya-blue); outline: none; box-shadow: 0 0 0 4px var(--briya-blue-tint); }

/* Wrap that lets us pin a scan button to the right edge of .big-input.
   The input's right padding is bumped so its centered text doesn't slide
   under the button. The button is absolute-positioned so it never steals
   focus from the field — the user can still type or tap the keypad. */
.input-wrap { position: relative; width: 100%; }
.input-wrap .big-input { padding-right: clamp(60px, 9vh, 96px); }

/* Lookup autocomplete dropdown — sits below the input in normal flow
   (NOT absolute-positioned) so it pushes the Continue button down rather
   than overlapping it, and the VKB's ensureVisible() can scroll the whole
   stack into the visible band above the keyboard. */
.lookup-suggest {
    list-style: none;
    margin: 0;
    padding: 0;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.4vmin, 16px);
    box-shadow: var(--shadow-md);
    overflow: hidden;
    max-height: clamp(180px, 32vh, 360px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}
.lookup-suggest[hidden] { display: none; }
.lookup-suggest-item {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: clamp(10px, 1.4vh, 16px) clamp(14px, 2vmin, 20px);
    cursor: pointer;
    border-bottom: 1px solid var(--briya-gray-25);
    transition: background 0.1s ease;
}
.lookup-suggest-item:last-child { border-bottom: none; }
.lookup-suggest-item:hover,
.lookup-suggest-item:focus {
    background: var(--briya-blue-tint);
    outline: none;
}
.lookup-suggest-item:active { background: #DCF0FB; }
.lookup-suggest-name {
    font-size: clamp(15px, 2vh, 20px);
    font-weight: 700;
    color: var(--briya-black);
    line-height: 1.2;
}
.lookup-suggest-meta {
    font-size: clamp(12px, 1.5vh, 15px);
    color: var(--briya-gray-65);
    font-family: ui-monospace, Menlo, Consolas, monospace;
    letter-spacing: 0.5px;
}
/* Compact slightly when the VKB is open to match the rest of the
   vkb-open lookup overrides. */
body.vkb-open .lookup-suggest      { max-height: clamp(140px, 24vh, 280px); }
body.vkb-open .lookup-suggest-item { padding: clamp(8px, 1.1vh, 12px) clamp(12px, 1.8vmin, 18px); }

/* Fake blinking caret centered in the empty input — visual "ready for
   input" cue without forcing focus (real focus would pop the on-screen
   VKB and hide the keypad below). Vanishes the moment the input gets
   focus (the real OS caret takes over) or has any content (placeholder
   is no longer shown). Uses :has() which is supported in every browser
   the kiosk targets (Chrome 105+, Safari 15.4+, Firefox 121+).
   The placeholder is hidden while the fake caret is showing — the
   subtitle above the input already carries the "SIS / phone / Briya
   ID" hint, so the format example here was redundant when paired with
   a blinking cursor. */
.input-wrap:has(.big-input:placeholder-shown:not(:focus))::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 2px;
    height: clamp(28px, 4vh, 56px);
    background: var(--briya-blue);
    border-radius: 2px;
    pointer-events: none;
    animation: input-caret-blink 1.06s steps(2, start) infinite;
}
.input-wrap:has(.big-input:placeholder-shown:not(:focus)) .big-input::placeholder {
    color: transparent;
}
@keyframes input-caret-blink {
    50% { opacity: 0; }
}
.scan-btn {
    position: absolute;
    top: 50%;
    right: clamp(6px, 1vmin, 14px);
    transform: translateY(-50%);
    width: clamp(44px, 6.5vh, 68px);
    height: clamp(44px, 6.5vh, 68px);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
    border: 1px solid var(--briya-blue-light);
    border-radius: clamp(8px, 1.2vmin, 14px);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.scan-btn:hover, .scan-btn:focus-visible {
    background: var(--briya-blue);
    color: var(--briya-white);
    border-color: var(--briya-blue);
    outline: none;
}
.scan-btn svg { width: 62%; height: 62%; display: block; }

/* Full-screen scanner modal: viewfinder + reticle + cancel.
   z-index sits above .no-match-modal (1000) and the VKB. */
.scanner-modal {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.78);
    display: none;
    align-items: center;
    justify-content: center;
    padding: clamp(12px, 3vmin, 36px);
    z-index: 2000;
}
.scanner-modal.is-open { display: flex; }
body.scanner-open { overflow: hidden; }
.scanner-card {
    background: var(--surface-card);
    color: var(--briya-black);
    border-radius: 18px;
    padding: clamp(16px, 2.4vmin, 28px);
    max-width: min(640px, 96vw);
    width: 100%;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.32);
    text-align: center;
}
.scanner-title { margin: 0 0 6px; font-size: clamp(20px, 3vmin, 28px); }
.scanner-hint { margin: 0 0 14px; color: var(--briya-gray-65); font-size: clamp(13px, 1.8vmin, 16px); }
.scanner-stage {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    background: #000;
    border-radius: 12px;
    overflow: hidden;
    margin-bottom: 12px;
    min-height: 220px;
}
/* html5-qrcode injects a <video> (and a scan-region overlay) into the
   container. Force them to fill the stage so the framing matches our
   aspect-ratio box on every device. */
.scanner-stage video {
    width: 100% !important;
    height: 100% !important;
    object-fit: cover !important;
    display: block;
}
.scanner-stage img { display: none; } /* hide the library's stock camera icon */
.scanner-status {
    min-height: 1.4em;
    margin: 0 0 12px;
    color: var(--briya-gray-65);
    font-size: clamp(13px, 1.8vmin, 16px);
}
.scanner-status.is-error {
    color: var(--error-text);
    background: var(--error-bg);
    padding: 10px 14px;
    border-radius: 10px;
}
.scanner-actions { display: flex; justify-content: center; }

.error { color: var(--error-text); background: var(--error-bg); padding: 12px 16px; border-radius: 12px; margin-bottom: 16px; font-weight: 500; }

/* No-match modal: shown on lookup/lookup-teacher when a search produces no
   results, offering "Retry" vs "Fill manually". Sits on top of the search
   form via a fixed overlay so the kiosk's chrome (topbar) stays in place. */
.no-match-modal {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.55);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(16px, 4vmin, 48px);
    z-index: 1000;
    animation: nm-fade 0.18s ease-out;
}
@keyframes nm-fade { from { opacity: 0; } to { opacity: 1; } }
.no-match-card {
    background: var(--surface-card, #fff);
    color: var(--briya-black, #111);
    border-radius: 18px;
    padding: clamp(20px, 3vmin, 36px);
    max-width: min(520px, 92vw);
    width: 100%;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28);
    text-align: center;
    animation: nm-rise 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
}
@keyframes nm-rise { from { transform: translateY(8px); } to { transform: translateY(0); } }
.no-match-card h2 { margin: 0 0 12px; font-size: clamp(20px, 3vmin, 28px); }
.no-match-card p { margin: 0 0 10px; line-height: 1.45; }
.no-match-prompt { color: var(--muted, #475569); }
.no-match-actions {
    display: flex;
    gap: 12px;
    justify-content: center;
    margin-top: clamp(14px, 2vmin, 22px);
    flex-wrap: wrap;
}
.no-match-actions .primary,
.no-match-actions .secondary {
    min-width: 160px;
}

/* Lookup + admin-login form: flex column with consistent gap instead of
   per-element margins, so spacing scales with one knob and doesn't fight
   the vh-based clamps on each child. */
.lookup form,
.admin-login form {
    display: flex;
    flex-direction: column;
    gap: clamp(10px, 1.4vh, 22px);
}

/* Numeric keypad grid — keys' vertical padding is vh-based so the 4-row
   keypad always fits the viewport without scrolling, even on phone portrait.
   margin-bottom dropped — parent form uses flex `gap`. */
.keypad {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(6px, 1vh, 22px);
}
/* When the on-screen virtual keyboard slides up (vkb.js adds .vkb-open to
   body), hide the numeric keypad so staff aren't looking at two stacked
   input affordances. VKB has its own number row + symbol toggle, so it
   handles all input on its own. The admin PIN page's input is
   readonly + data-vkb="off", so VKB never attaches there and the keypad
   stays visible — exactly what we want for PIN entry. */
body.vkb-open .keypad { display: none; }
.key {
    font-size: clamp(22px, 3.6vh, 72px);
    padding: clamp(10px, 1.8vh, 38px) 0;
    font-weight: 600;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.4vmin, 24px);
    box-shadow: var(--shadow-sm);
    color: var(--briya-black);
    font-family: inherit;
    transition: background 60ms, border-color 60ms, transform 60ms;
}
.key:active { background: var(--briya-blue-tint); border-color: var(--briya-blue); transform: translateY(1px); }
.key-secondary { background: #F3F4F6; color: var(--briya-gray-65); }

/* Lookup submit button — sized so the lookup page fits the viewport. */
.lookup form .primary {
    width: 100%;
    font-size: clamp(18px, 2.8vh, 48px);
    padding: clamp(10px, 1.8vh, 28px) clamp(20px, 3.5vmin, 64px);
    border-radius: clamp(10px, 1.4vmin, 24px);
    min-width: 0;
    margin-top: 0;
}

.text-link {
    display: block; text-align: center;
    margin: clamp(10px, 1.4vh, 28px) auto 0;
    font-size: clamp(14px, 2vh, 28px);
    color: var(--briya-blue-dark); text-decoration: none; font-weight: 500;
    padding: clamp(8px, 1.2vh, 22px) clamp(18px, 2.4vmin, 36px);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.4vmin, 20px);
    max-width: min(80vw, 640px);
    background: var(--surface-card);
}
.text-link:active { background: var(--briya-blue-tint); }

.primary, .secondary {
    /* inline-flex, not inline-block, so `min-height` centres the label instead
       of leaving it sitting against the top padding. */
    display: inline-flex; align-items: center; justify-content: center;
    font-size: clamp(16px, 2.1vmin, 26px);
    padding: clamp(10px, 1.8vh, 22px) clamp(16px, 2.4vmin, 32px);
    /* The vertical padding is vh-based, so on a phone held sideways (a ~375px
       TALL viewport) it collapses to its 10px minimum and these land at 38px —
       below the touch guideline, on Sign in, Continue, Back and Cancel at once.
       Width-only testing never sees it because the page is *wider* in
       landscape, not narrower. Floor the height instead. */
    min-height: 44px;
    border-radius: clamp(10px, 1.4vmin, 18px);
    text-decoration: none; border: none; cursor: pointer;
    min-width: clamp(140px, 20vmin, 240px);
    text-align: center;
    font-weight: 600; font-family: inherit;
}
.primary { background: var(--briya-blue); color: var(--briya-white); }
.primary:active { background: var(--briya-blue-dark); }
.primary:disabled { background: var(--briya-blue-dark); opacity: 0.6; }
.secondary { background: #E5E7EB; color: var(--briya-black); }
.secondary:active { background: var(--briya-gray-25); }
.full { display: block; }

button.primary, button.secondary { width: auto; }
/* `flex`, not `block`, so these keep the centring (and the 44px floor) that
   the base rule gives them. */
form .primary, form .secondary { display: flex; width: 100%; margin-top: 8px; }
.actions {
    display: flex; flex-wrap: wrap;
    gap: clamp(8px, 1.4vmin, 20px);
    justify-content: flex-end;
    margin-top: clamp(12px, 2vh, 28px);
}
.actions .primary, .actions .secondary {
    width: auto;
    min-width: clamp(140px, 20vmin, 240px);
    display: inline-block;
}

/* TEACHER list — floating rounded-square photo cards in a fully responsive grid. */

/* On the teacher page, use more horizontal real-estate than the keypad page. */
.lookup.teacher { max-width: min(96vw, 1600px); width: 100%; }
/* The form wrapping the grid must also take full width or the grid collapses
   to its natural single-card width inside an auto-sized form. */
.lookup.teacher #teacher-form { width: 100%; }
.lookup.teacher .teacher-grid { width: 100%; }

/* Shared filter-input style used by teacher lookup AND student disambiguation. */
.search-input {
    width: 100%;
    font-size: clamp(18px, 2.4vmin, 28px);
    padding: clamp(10px, 1.4vh, 18px) clamp(14px, 2vmin, 22px);
    border-radius: clamp(10px, 1.4vmin, 16px);
    border: 2px solid var(--briya-gray-25); background: var(--surface-card);
    margin-bottom: clamp(10px, 1.6vh, 22px);
    color: var(--briya-black);
    font-family: inherit;
}
.search-input:focus { border-color: var(--briya-blue); outline: none; box-shadow: 0 0 0 4px var(--briya-blue-tint); }

/* A device already set aside for this student. The list stays a choice — the
   reserved unit can be faulty or not on the cart — so this offers it up front
   and the rows below remain live. */
.pick-reserved {
    display: flex; flex-wrap: wrap; align-items: center;
    justify-content: space-between; gap: clamp(10px, 1.6vmin, 20px);
    padding: clamp(11px, 1.6vh, 18px) clamp(13px, 1.9vmin, 20px);
    margin: clamp(8px, 1.2vh, 14px) 0 clamp(4px, 0.6vh, 8px);
    background: #FFF8EC;
    border: 1px solid var(--briya-orange);
    border-radius: clamp(10px, 1.4vmin, 16px);
}
.pick-reserved-text {
    font-size: clamp(13px, 1.7vmin, 18px); color: var(--briya-black);
    min-width: 0; overflow-wrap: anywhere;
}
.pick-reserved-skip {
    width: auto; margin: 0; flex: 0 0 auto;
    min-height: 44px; display: inline-flex; align-items: center;
    text-decoration: none;
}
.pick-reserved-hint { margin: 0 0 clamp(6px, 1vh, 12px); font-size: clamp(12px, 1.5vmin, 16px); }

/* ── The one way to close a dialog ────────────────────────────────────────
   Every modal in the app closes by this X or by one of its own buttons, and
   by nothing else — no backdrop tap, no Escape. On a shared touch screen a
   stray tap beside the card is easy to make, and the dialogs here either hold
   half-typed input or say something that has to be read. Same corner, same
   size, every time, so there is never a question of how to get out.
   Full 44px: it is the only exit. */
.modal-close {
    position: absolute; top: 8px; right: 8px;
    width: 44px; height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0; border: none; border-radius: 999px;
    background: transparent; color: var(--briya-gray-65);
    font-size: 30px; line-height: 1; font-family: inherit;
    cursor: pointer;
    transition: background 0.1s, color 0.1s;
}
.modal-close:hover { background: var(--briya-blue-tint); color: var(--briya-blue-dark); }
.modal-close:focus-visible { outline: 3px solid var(--briya-blue); outline-offset: -2px; }
/* The cards need a positioning context, and room so the X never lands on the
   heading it sits beside. */
.admin-modal-card, .no-match-card, .scanner-card { position: relative; }
.admin-modal-card > h2:first-of-type,
.no-match-card > h2:first-of-type,
.scanner-card > .scanner-title { padding-right: 44px; }

/* ── Return flow: what is still out ───────────────────────────────────────
   Sits under the search box on the return flow's Find-your-record screen. The
   list is the common case; the search box is for the device that isn't on it. */
.return-shortlist { width: 100%; margin-top: clamp(14px, 2.2vh, 28px); }
.return-shortlist-heading {
    display: flex; align-items: center; gap: 10px;
    font-size: clamp(14px, 1.8vmin, 19px);
    text-transform: uppercase; letter-spacing: 0.6px;
    color: var(--briya-blue-dark);
    margin: 0 0 clamp(8px, 1.2vh, 14px);
}
.return-shortlist-count {
    background: var(--briya-blue-tint); color: var(--briya-blue-dark);
    border-radius: 999px; padding: 1px 10px;
    font-size: 0.8em; font-weight: 700;
}
.return-shortlist-list {
    list-style: none; margin: 0; padding: 0;
    display: flex; flex-direction: column; gap: clamp(6px, 1vmin, 12px);
    max-height: min(46vh, 560px);
    overflow-y: auto; overflow-x: hidden;
    scrollbar-width: thin;
    scrollbar-color: var(--briya-blue-light) transparent;
}
.return-shortlist-list li[hidden] { display: none; }
.return-shortlist-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: clamp(8px, 1.4vmin, 18px); flex-wrap: wrap;
    min-height: 44px;
    padding: clamp(10px, 1.5vh, 16px) clamp(12px, 1.8vmin, 18px);
    text-decoration: none; color: inherit;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.3vmin, 14px);
    box-shadow: var(--shadow-sm);
    transition: transform 0.1s, border-color 0.1s;
}
.return-shortlist-row:active { transform: scale(0.99); border-color: var(--briya-blue); }
.return-shortlist-row:focus-visible { outline: 3px solid var(--briya-blue); outline-offset: 2px; }
.return-shortlist-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.return-shortlist-name {
    font-weight: 700; color: var(--briya-black);
    font-size: clamp(14px, 1.8vmin, 19px); overflow-wrap: anywhere;
}
.return-shortlist-meta {
    color: var(--briya-gray-65); font-size: clamp(12px, 1.5vmin, 16px);
    overflow-wrap: anywhere;
}
.return-shortlist-device {
    display: flex; align-items: center; gap: 7px; flex: 0 0 auto;
}
.return-shortlist-owed {
    background: #FFF4E0; color: #7A4A00;
    border: 1px solid var(--briya-orange);
    padding: 2px 9px; border-radius: 999px;
    font-size: clamp(11px, 1.3vmin, 14px); font-weight: 700;
}

/* ── Browse by class ──────────────────────────────────────────────────────
   Classes are grouped under their campus. Unlike the teacher grid this scrolls
   as one list rather than per-group: a technician looking for "B1 FT (AM)"
   should not have to work out which of four nested scroll areas holds it. */
.class-pick #class-list {
    width: 100%;
    max-height: min(66vh, 860px);
    overflow-y: auto; overflow-x: hidden;
    scrollbar-width: thin;
    scrollbar-color: var(--briya-blue-light) transparent;
}
.class-group[hidden] { display: none; }
.class-group-heading {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px;
    font-size: clamp(14px, 1.8vmin, 19px);
    text-transform: uppercase; letter-spacing: 0.6px;
    color: var(--briya-blue-dark);
    margin: clamp(10px, 1.6vh, 20px) 0 clamp(6px, 0.9vh, 12px);
    padding-bottom: 6px;
    border-bottom: 2px solid var(--briya-blue-tint);
    position: sticky; top: 0; z-index: 1;
    background: var(--surface-bg);
}
.class-group-heading:first-child { margin-top: 0; }
.class-group-count {
    font-size: 0.72em; font-weight: 600; letter-spacing: 0.3px;
    color: var(--briya-gray-65); text-transform: none;
}
.class-grid {
    list-style: none; margin: 0; padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
    gap: clamp(8px, 1.3vmin, 18px);
}
.class-card {
    width: 100%;
    /* An anchor, not a button: the class list is addressable, so Back can come
       straight back to it. Links need their own reset. */
    text-decoration: none; color: inherit;
    display: flex; flex-direction: column; align-items: flex-start;
    gap: clamp(4px, 0.7vh, 9px);
    /* Floored at 44px like every other kiosk-facing control — the vmin clamp
       alone bottoms out on a phone held sideways. */
    min-height: 44px;
    padding: clamp(11px, 1.7vh, 18px) clamp(13px, 1.9vmin, 20px);
    text-align: left;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.4vmin, 16px);
    box-shadow: var(--shadow-md);
    cursor: pointer; font-family: inherit;
    transition: transform 0.1s, border-color 0.1s;
}
.class-card:active { transform: scale(0.99); border-color: var(--briya-blue); }
.class-card:focus-visible { outline: 3px solid var(--briya-blue); outline-offset: 2px; }
.class-card-name {
    font-size: clamp(15px, 1.9vmin, 21px); font-weight: 700;
    color: var(--briya-black); line-height: 1.25;
    overflow-wrap: anywhere;
}
.class-card-meta {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: clamp(5px, 0.9vmin, 10px);
    font-size: clamp(12px, 1.5vmin, 16px);
}
.class-card-total { color: var(--briya-gray-65); }
.class-card-need {
    background: #FFF4E0; color: #7A4A00;
    border: 1px solid var(--briya-orange);
    padding: 2px 9px; border-radius: 999px; font-weight: 700;
}
.class-card-done {
    background: var(--briya-blue-tint); color: var(--briya-blue-dark);
    border: 1px solid var(--briya-blue-light);
    padding: 2px 9px; border-radius: 999px; font-weight: 600;
}

.teacher-grid {
    list-style: none;
    padding: clamp(4px, 0.8vh, 12px) clamp(6px, 1vmin, 14px);
    margin: 0;
    display: grid;
    /* Phone default: 140px minimum gives 2 cards on narrow phones, 3 on wider ones.
       Tiered breakpoints below grow the minimum so iPad / desktop / 4K get
       proportionally larger and tappier cards. */
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: clamp(8px, 1.4vmin, 22px);
    /* On long rosters, scroll inside the grid so the header + search stay anchored. */
    max-height: min(72vh, 900px);
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-width: thin;
    scrollbar-color: var(--briya-blue-light) transparent;
}
.teacher-grid::-webkit-scrollbar { width: 8px; }
.teacher-grid::-webkit-scrollbar-track { background: transparent; }
.teacher-grid::-webkit-scrollbar-thumb {
    background: var(--briya-blue-light);
    border-radius: 999px;
}
.teacher-grid::-webkit-scrollbar-thumb:hover { background: var(--briya-blue); }
.teacher-grid > li { min-width: 0; }   /* let cards shrink within the grid track */

/* iPad portrait & up: larger card minimum so cards feel substantial. */
@media (min-width: 720px) {
    .teacher-grid { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }
}
/* Desktop / 4K: largest card minimum for a poster-grid feel. */
@media (min-width: 1400px) {
    .teacher-grid { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
}

.teacher-card {
    width: 100%;
    aspect-ratio: 1 / 1;
    position: relative;
    overflow: hidden;
    border: none;
    border-radius: clamp(16px, 2.4vmin, 28px);
    background: linear-gradient(135deg, var(--briya-blue-medium) 0%, var(--briya-blue-dark) 100%);
    color: var(--briya-white);
    cursor: pointer;
    padding: 0;
    font-family: inherit;
    box-shadow:
        0 8px 22px rgba(0, 97, 151, 0.22),
        0 1px 0 rgba(255, 255, 255, 0.18) inset;
    transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.teacher-card:active {
    transform: translateY(2px) scale(0.97);
    box-shadow:
        0 4px 12px rgba(0, 97, 151, 0.28),
        0 1px 0 rgba(255, 255, 255, 0.15) inset;
}

/* Big initials sit in the upper area as a clean fallback when no photo
   is uploaded yet. Photo overlay (if loaded) will cover them. */
.teacher-card-initials {
    position: absolute;
    inset: 0 0 30% 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: clamp(40px, 8vmin, 92px);
    font-weight: 700;
    color: rgba(255, 255, 255, 0.85);
    letter-spacing: 1px;
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.18);
    user-select: none;
    pointer-events: none;
}

/* Teacher photo — fills the card. If the file 404s, JS hides this <img>
   and the initials underneath remain visible. */
.teacher-card-photo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    z-index: 1;
}

/* Dark gradient overlay at the bottom 60% so the teacher name is readable
   over any photo. */
.teacher-card::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 65%;
    background: linear-gradient(
        to top,
        rgba(0, 0, 0, 0.78) 0%,
        rgba(0, 0, 0, 0.55) 40%,
        rgba(0, 0, 0, 0) 100%
    );
    z-index: 2;
    pointer-events: none;
}

.teacher-card-name {
    position: absolute;
    left: clamp(10px, 1.6vmin, 18px);
    right: clamp(10px, 1.6vmin, 18px);
    bottom: clamp(10px, 1.6vh, 18px);
    z-index: 3;
    color: var(--briya-white);
    font-size: clamp(13px, 1.9vmin, 20px);
    font-weight: 600;
    line-height: 1.2;
    text-align: left;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
    overflow-wrap: anywhere;
}

/* DISAMBIGUATE cards */
.disambiguate { width: 100%; max-width: min(96vw, 1600px); margin: 0 auto; }
.disambiguate .card-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: clamp(10px, 1.6vh, 22px);
    /* Internal scroll for long lists so the page outer-stays anchored. */
    max-height: min(70vh, 880px);
    overflow-y: auto;
    padding: clamp(4px, 0.8vh, 10px);
    /* Match the teacher grid's thin Briya-blue scrollbar. */
    scrollbar-width: thin;
    scrollbar-color: var(--briya-blue-light) transparent;
}
.disambiguate .card-grid::-webkit-scrollbar { width: 8px; }
.disambiguate .card-grid::-webkit-scrollbar-track { background: transparent; }
.disambiguate .card-grid::-webkit-scrollbar-thumb { background: var(--briya-blue-light); border-radius: 999px; }
.disambiguate .card-grid::-webkit-scrollbar-thumb:hover { background: var(--briya-blue); }
.student-empty {
    text-align: center;
    padding: clamp(16px, 3vh, 40px) clamp(12px, 2vmin, 24px);
    font-size: clamp(14px, 2vmin, 22px);
    color: var(--briya-gray-65);
}
.student-card {
    display: block; text-decoration: none; color: inherit;
    background: var(--surface-card); border: 1px solid var(--briya-gray-25);
    border-radius: clamp(12px, 1.8vmin, 22px);
    padding: clamp(14px, 2vh, 24px) clamp(16px, 2.2vmin, 26px);
    box-shadow: var(--shadow-md);
    transition: transform 0.1s, border-color 0.1s;
}
.student-card:active { transform: scale(0.98); border-color: var(--briya-blue); }
.student-name { font-size: clamp(18px, 2.4vmin, 28px); font-weight: 700; margin-bottom: clamp(2px, 0.6vh, 8px); color: var(--briya-black); word-break: break-word; }
.student-meta { font-size: clamp(13px, 1.7vmin, 18px); color: var(--briya-gray-65); margin-bottom: clamp(2px, 0.4vh, 6px); }
.student-devices { margin-top: clamp(6px, 1vh, 14px); display: flex; flex-wrap: wrap; gap: clamp(4px, 0.8vmin, 8px); }
.chip {
    background: var(--briya-blue-tint); color: var(--briya-blue-dark);
    padding: clamp(2px, 0.5vh, 6px) clamp(8px, 1.4vmin, 14px);
    border-radius: 999px;
    font-size: clamp(12px, 1.5vmin, 16px);
    font-weight: 500;
}

/* CONFIRM — vertical-sensitive clamps use vh so the form's tall stack
   compresses to fit short viewports without scrolling. */
.confirm h1 { word-break: break-word; overflow-wrap: anywhere; }
/* The student's SIS/Class line. Not scoped to .confirm — the language picker
   shows the same line, and while this lived under .confirm it rendered there
   with no layout and, crucially, no bottom margin. */
.meta-row {
    display: flex; flex-wrap: wrap;
    gap: clamp(10px, 1.4vmin, 24px);
    font-size: clamp(14px, 1.9vmin, 22px);
    color: var(--briya-gray-65);
    margin-bottom: clamp(8px, 1.4vh, 20px);
}
.confirm-form label {
    display: block;
    font-size: clamp(13px, 1.7vmin, 20px);
    color: var(--briya-black);
    margin-bottom: clamp(8px, 1.4vh, 18px);
    font-weight: 500;
}
.confirm-form input[type="text"],
.confirm-form input[type="date"],
.confirm-form select {
    display: block; width: 100%;
    font-size: clamp(15px, 2vmin, 24px);
    padding: clamp(8px, 1.2vh, 18px) clamp(12px, 1.6vmin, 22px);
    /* vh-based padding leaves these ~39px tall on a phone. These are the
       fields a technician taps into one-handed at a desk, so floor them. */
    min-height: 44px;
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.4vmin, 18px);
    margin-top: clamp(3px, 0.5vh, 8px);
    background: var(--surface-card); color: var(--briya-black);
    font-family: inherit;
}
.confirm-form input:focus, .confirm-form select:focus { border-color: var(--briya-blue); outline: none; box-shadow: 0 0 0 3px var(--briya-blue-tint); }

.field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(10px, 1.6vmin, 26px);
}
@media (max-width: 820px) { .field-row { grid-template-columns: 1fr; } }

.device-list {
    display: flex; flex-direction: column;
    gap: clamp(6px, 1vh, 14px);
    margin-bottom: clamp(4px, 0.8vh, 10px);
}
.device-line {
    display: flex; align-items: center;
    gap: clamp(10px, 1.6vmin, 22px);
    background: var(--surface-card);
    padding: clamp(8px, 1.4vh, 18px) clamp(12px, 1.8vmin, 24px);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.4vmin, 18px);
}
.device-line input[type="checkbox"] {
    width: clamp(22px, 2.8vmin, 36px);
    height: clamp(22px, 2.8vmin, 36px);
    accent-color: var(--briya-blue);
    flex-shrink: 0;
}
.device-info { display: flex; flex-direction: column; min-width: 0; }
.device-id   { font-weight: 700; font-size: clamp(15px, 2vmin, 24px); color: var(--briya-black); word-break: break-all; }
.device-desc { font-size: clamp(13px, 1.7vmin, 20px); color: var(--briya-gray-65); overflow-wrap: anywhere; }
.device-sn   { font-size: clamp(11px, 1.4vmin, 16px); color: var(--briya-gray-65); overflow-wrap: anywhere; }

.checkbox-row {
    display: flex; flex-wrap: wrap;
    gap: clamp(6px, 1vh, 14px);
    margin-bottom: clamp(4px, 0.8vh, 10px);
}
.check-pill {
    display: inline-flex; align-items: center;
    gap: clamp(6px, 1vmin, 12px);
    padding: clamp(6px, 1vh, 14px) clamp(12px, 1.8vmin, 24px);
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: 999px;
    font-size: clamp(14px, 1.8vmin, 20px);
    cursor: pointer;
    color: var(--briya-black);
}
.check-pill input {
    width: clamp(18px, 2.4vmin, 30px);
    height: clamp(18px, 2.4vmin, 30px);
    accent-color: var(--briya-blue);
    flex-shrink: 0;
}

/* ------------------------------------------------------------------
   CONTRACT (issue) FORM — shares .confirm-form; only the extras below
   are new. `.form-kicker` also labels the shared search pages so staff
   can see which task they're in mid-flow.
------------------------------------------------------------------ */
.form-kicker {
    margin: 0 0 clamp(2px, 0.5vh, 8px);
    text-align: center;
    font-size: clamp(11px, 1.4vh, 15px);
    font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--briya-blue-dark);
}

.inventory-hint { margin: 0 0 clamp(4px, 0.8vh, 10px); }

/* Inventory prefill rows are <button>s, not checkbox labels — reset the
   UA button styling so they read as the same cards as .device-line. */
.inventory-picker .device-pick {
    width: 100%;
    text-align: left;
    font: inherit;
    color: inherit;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}
.inventory-picker .device-pick.is-picked {
    border-color: var(--briya-blue);
    background: var(--briya-blue-tint);
    box-shadow: 0 0 0 2px var(--briya-blue-tint);
}

/* The issue form pairs several inputs with a barcode scan button. .input-wrap
   is styled for the big lookup field, so scope a compact variant to the form. */
.confirm-form .input-wrap { position: relative; display: block; width: 100%; }
.confirm-form .input-wrap input { width: 100%; padding-right: clamp(44px, 6vmin, 64px); }
.confirm-form .input-wrap .scan-btn {
    position: absolute;
    right: clamp(4px, 0.7vmin, 8px);
    top: 50%; transform: translateY(-50%);
    /* The scanner is a primary affordance on a touchscreen — a technician taps
       it holding a device in the other hand. 4.4vmin collapses to 34px on a
       phone, so floor it at the 44px guideline. */
    width: clamp(44px, 4.4vmin, 50px);
    height: clamp(44px, 4.4vmin, 50px);
    padding: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
    border: none;
    border-radius: clamp(8px, 1.1vmin, 13px);
    cursor: pointer;
}
.confirm-form .input-wrap .scan-btn svg { width: 58%; height: 58%; }

.sign-intro {
    margin: 0 auto clamp(4px, 0.8vh, 10px);
    max-width: 62ch; text-align: center;
    font-size: clamp(12px, 1.7vh, 18px);
    color: var(--briya-gray-65);
}

/* Language chip + "Change" link in the issue form's kicker line. */
.lang-chip {
    display: inline-block;
    margin-left: 8px; padding: 2px 10px;
    border-radius: 999px;
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
    letter-spacing: 0.04em;
}
.lang-change {
    /* Small text, but it changes which agreement a student signs — so give it
       a real tap box rather than the 12px-tall line the text alone produced. */
    display: inline-flex; align-items: center;
    min-height: 44px; padding: 0 10px;
    margin-left: 4px;
    color: var(--briya-blue);
    text-transform: none; letter-spacing: 0;
    font-weight: 600;
}

.notice {
    margin: clamp(6px, 1vh, 14px) auto;
    padding: clamp(10px, 1.4vh, 16px) clamp(12px, 1.8vmin, 22px);
    border-radius: clamp(10px, 1.4vmin, 16px);
    font-size: clamp(12px, 1.6vh, 17px);
    line-height: 1.5;
    max-width: 70ch;
}
.notice-warn {
    background: #FFF6E5;
    border: 1px solid #F0C475;
    color: #6B4A08;
}

.done-note { margin: clamp(4px, 0.8vh, 10px) 0; font-size: clamp(12px, 1.6vh, 17px); }

/* ------------------------------------------------------------------
   LANGUAGE PICKER — the one screen the student is asked to choose on,
   so both options are equal-weight and large enough to tap confidently.
------------------------------------------------------------------ */
.lang-pick {
    max-width: min(94vw, 900px);
    margin: 0 auto;
    width: 100%;
    text-align: center;
}
/* This page is centered, so its flex rows need centering too — text-align
   can't reach flex items. `.actions` normally right-aligns a Cancel/Continue
   pair, but here Cancel is alone and looked stranded off to one side. */
.lang-pick .meta-row,
.lang-pick .actions { justify-content: center; }
.lang-prompt { margin-bottom: clamp(12px, 2vh, 28px); }
.lang-prompt-es { color: var(--briya-gray-65); font-style: italic; }

.lang-form {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(12px, 2vmin, 26px);
    margin-bottom: clamp(14px, 2.4vh, 32px);
}
@media (max-width: 720px) { .lang-form { grid-template-columns: 1fr; } }

.lang-card {
    position: relative;
    display: flex; flex-direction: column; align-items: center;
    gap: clamp(3px, 0.6vh, 8px);
    padding: clamp(20px, 3.4vh, 44px) clamp(16px, 2.2vmin, 30px) clamp(44px, 5vh, 60px);
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(14px, 2vmin, 24px);
    box-shadow: var(--shadow-sm);
    font: inherit; color: inherit; cursor: pointer;
    -webkit-appearance: none; appearance: none;
    transition: transform 0.12s, box-shadow 0.12s, border-color 0.12s;
}
.lang-card:active { transform: scale(0.985); }
@media (hover: hover) {
    .lang-card:hover {
        border-color: var(--briya-blue-light);
        box-shadow: 0 12px 30px rgba(0, 97, 151, 0.16);
        transform: translateY(-2px);
    }
}
.lang-flag {
    width: clamp(46px, 6.4vh, 78px);
    height: clamp(46px, 6.4vh, 78px);
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, var(--briya-blue-medium), var(--briya-blue));
    color: var(--briya-white);
    font-size: clamp(16px, 2.4vh, 28px); font-weight: 700; letter-spacing: 0.06em;
    box-shadow: 0 6px 14px rgba(0, 132, 203, 0.28);
    margin-bottom: clamp(4px, 0.8vh, 10px);
}
.lang-es .lang-flag {
    background: linear-gradient(135deg, var(--briya-green), #7AB02C);
    box-shadow: 0 6px 14px rgba(170, 208, 71, 0.4);
}
.lang-name { font-size: clamp(19px, 2.8vh, 32px); font-weight: 700; color: var(--briya-black); }
.lang-sub  { font-size: clamp(12px, 1.6vh, 18px); color: var(--briya-gray-65); }
.lang-go {
    position: absolute;
    right: clamp(14px, 2vmin, 26px);
    bottom: clamp(14px, 1.8vh, 24px);
    width: clamp(30px, 3.8vh, 44px);
    height: clamp(30px, 3.8vh, 44px);
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
}
.lang-es .lang-go { background: rgba(170, 208, 71, 0.22); color: #5C7A18; }
.lang-go svg { width: 58%; height: 58%; }

/* SIGNATURE */
.sign .sig-wrap {
    position: relative;
    background: var(--surface-card);
    border: 2px dashed var(--briya-blue-light);
    border-radius: clamp(12px, 1.8vmin, 24px);
    margin: clamp(10px, 1.6vh, 22px) 0;
    padding: clamp(6px, 1vh, 14px);
    height: clamp(180px, 38vh, 440px);
}
#sigpad { width: 100%; height: 100%; touch-action: none; }
/* Bottom-left of the signature area — now a real Clear button. The "×"
   glyph still reads like the paper-form "sign here" indicator the user
   recognized, but tapping it now clears the canvas. */
.sig-baseline {
    position: absolute;
    left: clamp(14px, 2vmin, 28px);
    bottom: clamp(14px, 2vmin, 28px);
    display: inline-flex; align-items: center;
    gap: clamp(6px, 1vmin, 12px);
    padding: clamp(6px, 1vmin, 14px) clamp(10px, 1.4vmin, 20px);
    min-height: 44px;   /* student-facing: Clear must be an easy, deliberate tap */
    background: transparent;
    border: 1px solid transparent;
    border-radius: clamp(8px, 1.2vmin, 16px);
    color: var(--briya-gray-65);
    font-size: clamp(14px, 1.9vmin, 22px);
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    transition: background 0.1s, color 0.1s, border-color 0.1s;
}
.sig-baseline:hover { color: var(--briya-blue-dark); }
.sig-baseline:active {
    background: var(--briya-blue-tint);
    border-color: var(--briya-blue);
    color: var(--briya-blue-dark);
}
.sig-baseline-x     { font-size: clamp(22px, 2.8vmin, 38px); line-height: 1; }
.sig-baseline-label { letter-spacing: 0.3px; }
.sig-help     { color: var(--briya-gray-65); font-size: clamp(13px, 1.8vmin, 20px); }
.status       { margin-top: clamp(10px, 1.4vmin, 18px); font-size: clamp(15px, 2vmin, 22px); }
.status.error { color: var(--error-text); }

/* Expand-to-fullscreen button overlaying the top-right of the sig-wrap. */
.sig-expand-btn {
    position: absolute;
    top: clamp(8px, 1.2vmin, 18px);
    right: clamp(8px, 1.2vmin, 18px);
    z-index: 2;
    /* The signature page is the one screen a STUDENT touches, so its controls
       get the full 44px floor — 4.8vmin collapsed to 36px on a phone. */
    width: clamp(44px, 4.8vmin, 60px);
    height: clamp(44px, 4.8vmin, 60px);
    border-radius: 50%;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    color: var(--briya-blue-dark);
    display: inline-flex; align-items: center; justify-content: center;
    cursor: pointer;
    box-shadow: var(--shadow-sm);
    transition: background 0.1s, transform 0.05s;
}
.sig-expand-btn:active {
    background: var(--briya-blue-tint);
    transform: scale(0.96);
    border-color: var(--briya-blue);
}
.sig-expand-btn svg { width: 58%; height: 58%; }
.sig-expand-btn .sig-icon-close { display: none; }

/* Hint that only appears inside fullscreen mode. */
.sig-fs-hint { display: none; }
/* Rotate-your-device overlay, only shown inside fullscreen + portrait phone. */
.sig-rotate-prompt { display: none; }

/* Fullscreen mode — sig-wrap covers the entire viewport. The page underneath
   is explicitly hidden so the student sees ONLY the signature surface, the
   close X, and a small hint. The captured signature is preserved across
   the expand/collapse toggle (see resize() in sign.html). */
.sig-wrap.sig-fullscreen {
    /* `inset: 0` anchors to all four viewport edges, and `100dvh` uses the
       DYNAMIC viewport height — both work around Android Chrome's quirk
       where `100vh` reports the URL-bar-hidden height, leaving a strip of
       page background visible below the panel when the URL bar is showing. */
    position: fixed;
    inset: 0;
    width: 100dvw;
    height: 100dvh;
    margin: 0;
    border-radius: 0;
    border: none;
    padding: clamp(72px, 9vmin, 120px) clamp(20px, 3vmin, 48px) clamp(20px, 3vmin, 40px);
    z-index: 9000;
    background: var(--surface-card);
    box-shadow: none;
}
.sig-wrap.sig-fullscreen .sig-icon-expand { display: none; }
.sig-wrap.sig-fullscreen .sig-icon-close  { display: block; }
/* Make the close X very prominent and obvious to tap. */
.sig-wrap.sig-fullscreen .sig-expand-btn {
    width: clamp(56px, 7.4vmin, 96px);
    height: clamp(56px, 7.4vmin, 96px);
    top: clamp(16px, 2.4vmin, 32px);
    right: clamp(16px, 2.4vmin, 32px);
    background: var(--briya-blue);
    color: var(--briya-white);
    border-color: var(--briya-blue);
    box-shadow: 0 6px 16px rgba(0, 97, 151, 0.32);
}
.sig-wrap.sig-fullscreen .sig-expand-btn svg { width: 50%; height: 50%; }
.sig-wrap.sig-fullscreen .sig-fs-hint {
    display: block;
    position: absolute;
    top: clamp(22px, 3vmin, 44px);
    left: clamp(24px, 3vmin, 48px);
    max-width: calc(100% - clamp(100px, 13vmin, 180px));
    color: var(--briya-gray-65);
    font-size: clamp(14px, 2vmin, 24px);
    font-weight: 500;
    line-height: 1.3;
    pointer-events: none;
}
.sig-wrap.sig-fullscreen .sig-baseline {
    bottom: clamp(28px, 3.6vmin, 56px);
    left: clamp(28px, 3.6vmin, 56px);
    font-size: clamp(28px, 4vmin, 56px);
}

/* When fullscreen is open, fully hide everything else on the page so nothing
   can be tapped or seen behind the signature surface. The sig-wrap itself
   is a fixed-positioned element overlaying the viewport, so it stays visible. */
body.sig-fs-open {
    overflow: hidden;
}
body.sig-fs-open .topbar,
body.sig-fs-open .site-footer {
    visibility: hidden;
}
body.sig-fs-open .sign > h1,
body.sig-fs-open .sign > .subtitle,
body.sig-fs-open .sign > .sig-help,
body.sig-fs-open .sign > .actions,
body.sig-fs-open .sign > .status {
    visibility: hidden;
}

/* Phone-in-portrait + fullscreen-signing → show the "rotate to landscape"
   overlay covering the entire sig-wrap, blocking signing until the device
   is rotated. iPad / desktop / phone-landscape are unaffected. */
@media (orientation: portrait) and (max-width: 640px) {
    .sig-wrap.sig-fullscreen .sig-rotate-prompt {
        display: flex;
        position: absolute;
        inset: 0;
        z-index: 4;
        background: var(--surface-card);
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 18px;
        padding: 32px 24px;
        text-align: center;
        color: var(--briya-blue-dark);
    }
    .sig-wrap.sig-fullscreen .sig-rotate-prompt svg { width: 96px; height: 96px; color: var(--briya-blue); }
    .sig-wrap.sig-fullscreen .sig-rotate-prompt h2 { font-size: 24px; margin: 0; color: var(--briya-black); }
    .sig-wrap.sig-fullscreen .sig-rotate-prompt p  { font-size: 16px; margin: 0; color: var(--briya-gray-65); max-width: 280px; }
    /* While the prompt covers the canvas the hint/baseline-clear would
       just sit awkwardly behind it — hide them too. */
    .sig-wrap.sig-fullscreen .sig-fs-hint,
    .sig-wrap.sig-fullscreen .sig-baseline {
        visibility: hidden;
    }
}

/* Landscape phones / very short screens — squeeze the fullscreen padding so
   the canvas claims as much real estate as possible. */
@media (orientation: landscape) and (max-height: 480px) {
    .sig-wrap.sig-fullscreen {
        padding: 64px 10px 10px;
    }
    .sig-wrap.sig-fullscreen .sig-expand-btn {
        width: 48px; height: 48px;
        top: 10px; right: 10px;
    }
    .sig-wrap.sig-fullscreen .sig-fs-hint {
        top: 18px; left: 14px;
        font-size: 13px;
    }
}

/* REVIEW — per-device confirmation. Vertical-sensitive sizing uses vh so
   the whole review stack fits in one viewport. */
.review { max-width: min(94vw, 900px); margin: 0 auto; }
.review-head h1 { text-align: center; margin-bottom: clamp(4px, 0.8vh, 12px); word-break: break-word; }
.review-head .subtitle { margin: 0 0 clamp(10px, 1.6vh, 22px); }

.review-progress {
    list-style: none; padding: 0;
    margin: 0 0 clamp(14px, 2vh, 28px);
    display: flex; justify-content: center;
    gap: clamp(6px, 1vh, 14px);
    flex-wrap: wrap;
}
.review-progress li {
    width: clamp(32px, 4.4vmin, 54px);
    height: clamp(32px, 4.4vmin, 54px);
    border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--surface-card); border: 1px solid var(--briya-gray-25);
    color: var(--briya-gray-65); font-weight: 700;
    font-size: clamp(13px, 1.8vmin, 20px);
}
.review-progress li.current {
    background: var(--briya-blue); color: var(--briya-white);
    border-color: var(--briya-blue);
    box-shadow: 0 4px 10px rgba(0, 132, 203, 0.3);
}
.review-progress li.done {
    background: var(--briya-green); color: var(--briya-black);
    border-color: var(--briya-green);
}

.review-meta {
    background: var(--surface-card); border: 1px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.4vmin, 18px);
    padding: clamp(8px, 1.4vh, 18px) clamp(14px, 2vmin, 26px);
    margin-bottom: clamp(10px, 1.6vh, 22px);
    display: flex; flex-direction: column;
    gap: clamp(2px, 0.6vh, 8px);
    font-size: clamp(13px, 1.7vmin, 20px);
    word-break: break-word;
}
.review-meta strong { font-weight: 700; }
.review-meta .muted { font-size: clamp(10px, 1.3vmin, 14px); text-transform: uppercase; letter-spacing: 0.4px; }

.review-device-card {
    background: linear-gradient(135deg, #FFFFFF 0%, var(--briya-blue-tint) 100%);
    border: 2px solid var(--briya-blue);
    border-radius: clamp(14px, 2vmin, 24px);
    padding: clamp(12px, 2vh, 26px) clamp(18px, 2.4vmin, 32px);
    margin-bottom: clamp(12px, 2vh, 26px);
    box-shadow: var(--shadow-md);
}
.review-device-row {
    display: flex; align-items: center;
    gap: clamp(8px, 1.2vmin, 16px);
    flex-wrap: wrap;
    margin-bottom: clamp(2px, 0.6vh, 8px);
}
.review-device-id   { font-size: clamp(22px, 3.2vmin, 44px); font-weight: 800; color: var(--briya-black); letter-spacing: 0.5px; word-break: break-all; }
.review-device-meta { font-size: clamp(14px, 1.9vmin, 22px); color: var(--briya-blue-dark); font-weight: 500; overflow-wrap: anywhere; }
.review-device-sn   { font-size: clamp(11px, 1.5vmin, 16px); color: var(--briya-gray-65); margin-top: clamp(1px, 0.4vh, 5px); overflow-wrap: anywhere; }

.review-form h2 { margin-top: clamp(4px, 0.8vh, 12px); }
.review-form label { display: block; font-size: clamp(13px, 1.7vmin, 20px); color: var(--briya-black); margin-bottom: clamp(8px, 1.4vh, 18px); font-weight: 500; }
.review-form input[type="text"] {
    display: block; width: 100%;
    font-size: clamp(15px, 2vmin, 24px);
    padding: clamp(8px, 1.2vh, 16px) clamp(12px, 1.6vmin, 22px);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.4vmin, 18px);
    margin-top: clamp(3px, 0.5vh, 8px);
    background: var(--surface-card); color: var(--briya-black);
    font-family: inherit;
}
.review-form input:focus { border-color: var(--briya-blue); outline: none; box-shadow: 0 0 0 3px var(--briya-blue-tint); }

/* DONE — vh-based vertical clamps so the receipt-saved page fits any viewport. */
.done {
    text-align: center;
    padding-top: clamp(14px, 3vh, 48px);
    max-width: min(94vw, 800px);
    margin: 0 auto;
}
.done h1 {
    font-size: clamp(26px, 4.4vmin, 64px);
    margin: clamp(8px, 1.4vh, 22px) 0 clamp(6px, 1.2vh, 18px);
}
.done .check-bubble {
    width: clamp(72px, 12vh, 160px);
    height: clamp(72px, 12vh, 160px);
    line-height: clamp(72px, 12vh, 160px);
    font-size: clamp(48px, 8vh, 108px);
    margin: 0 auto clamp(10px, 1.6vh, 24px);
}
.done .done-label {
    font-size: clamp(14px, 2vmin, 24px);
    color: var(--briya-gray-65);
    margin: clamp(10px, 1.6vh, 22px) 0 0;
}
.done .done-file {
    margin: clamp(8px, 1.2vh, 16px) 0 clamp(14px, 2vh, 28px);
}
.done code {
    display: inline-block;
    background: var(--briya-blue-tint); color: var(--briya-blue-dark);
    padding: clamp(6px, 1vh, 14px) clamp(12px, 1.8vmin, 24px);
    border-radius: clamp(8px, 1.2vmin, 16px);
    font-size: clamp(12px, 1.7vmin, 20px);
    font-family: "Consolas", "Menlo", monospace;
    word-break: break-all;
    max-width: 90%;
}
.done .done-actions { margin: clamp(6px, 1.2vh, 18px) 0 clamp(14px, 2.4vh, 32px); }
.done-countdown {
    color: var(--briya-gray-65);
    margin: clamp(12px, 2vh, 26px) 0 clamp(8px, 1.2vh, 16px);
    font-size: clamp(13px, 1.9vmin, 22px);
}

.filename-list {
    list-style: none; padding: 0;
    margin: clamp(10px, 1.6vh, 24px) auto clamp(14px, 2.2vh, 28px);
    max-width: min(94vw, 640px);
    display: flex; flex-direction: column;
    gap: clamp(6px, 1vh, 14px);
}
.filename-list li a {
    display: block;
    padding: clamp(8px, 1.4vh, 18px) clamp(14px, 2vmin, 28px);
    background: var(--briya-blue-tint); color: var(--briya-blue-dark);
    border: 1px solid var(--briya-blue-light);
    border-radius: clamp(10px, 1.4vmin, 18px);
    text-decoration: none; font-weight: 500;
    transition: background 0.1s;
}
.filename-list li a:active { background: var(--briya-blue-light); }
.filename-list code { background: transparent; padding: 0; color: inherit; font-size: clamp(12px, 1.7vmin, 18px); word-break: break-all; }
.check-bubble {
    width: 120px; height: 120px; border-radius: 50%;
    background: var(--briya-green); color: var(--briya-black);
    font-size: 80px; line-height: 120px;
    margin: 0 auto 20px;
    box-shadow: var(--shadow-lg);
    font-weight: 700;
}
.done code {
    background: var(--briya-blue-tint); color: var(--briya-blue-dark);
    padding: 6px 12px; border-radius: 8px; font-size: 16px;
    font-family: "Consolas", "Menlo", monospace;
}

/* ------------------------------------------------------------------
   Virtual on-screen keyboard — modern light theme.
   - Soft blue-tinted gradient background with a glass-like top border
   - Crisp white keys with subtle paper-like shadows
   - Briya Blue accent on press (inverted: blue bg, white text)
   - Action keys (Enter, mode-toggle, ⌫) on a Briya Blue gradient pill
   - Shift-on lights up in Briya Yellow with a glow
------------------------------------------------------------------ */
.vkb {
    position: fixed; left: 0; right: 0; bottom: 0;
    background:
        linear-gradient(180deg, rgba(247, 251, 254, 0.96) 0%, rgba(232, 244, 251, 0.96) 100%);
    backdrop-filter: blur(24px) saturate(140%);
    -webkit-backdrop-filter: blur(24px) saturate(140%);
    color: var(--briya-black);
    border-top: 1px solid rgba(96, 195, 239, 0.35);
    box-shadow:
        0 -1px 0 rgba(255, 255, 255, 0.6) inset,
        0 -12px 36px rgba(0, 97, 151, 0.14);
    transform: translateY(100%);
    transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
    z-index: 1000;
    padding: 8px 10px calc(10px + env(safe-area-inset-bottom));
    user-select: none; -webkit-user-select: none;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
    max-height: 48vh;
    display: flex; flex-direction: column;
}
.vkb.is-open { transform: translateY(0); }

.vkb-bar {
    display: flex; justify-content: space-between; align-items: center;
    padding: 4px 10px 10px;
    flex: 0 0 auto;
    border-bottom: 1px solid rgba(199, 200, 202, 0.35);
    margin-bottom: 6px;
}
.vkb-mode {
    font-size: 11px;
    font-weight: 700;
    color: var(--briya-blue-dark);
    text-transform: uppercase;
    letter-spacing: 0.7px;
}
.vkb-close {
    background: linear-gradient(180deg, var(--briya-blue) 0%, var(--briya-blue-dark) 100%);
    color: var(--briya-white);
    border: none;
    border-radius: 999px;
    padding: 9px 22px;
    font-size: 14px; font-weight: 700;
    letter-spacing: 0.2px;
    cursor: pointer;
    font-family: inherit;
    box-shadow:
        0 4px 12px rgba(0, 132, 203, 0.42),
        0 1px 0 rgba(255, 255, 255, 0.25) inset;
    transition: transform 80ms, box-shadow 80ms, filter 80ms;
}
.vkb-close:active {
    transform: scale(0.96);
    box-shadow: 0 2px 6px rgba(0, 132, 203, 0.4);
    filter: brightness(0.95);
}

.vkb-keys {
    display: flex; flex-direction: column; gap: 6px;
    flex: 1 1 auto; min-height: 0;
    max-width: 980px; width: 100%;
    margin: 0 auto;
}
.vkb-row { display: flex; gap: 6px; justify-content: center; }
.vkb-row-mid    { padding: 0 4%; }       /* indents the asdfghjkl row */
.vkb-row-bottom { padding: 0; }
.vkb-row-num    { justify-content: center; }

/* Character keys — crisp white "paper" tiles with a layered shadow. */
.vkb-key {
    flex: 1 1 0;
    min-width: 0;
    height: clamp(38px, 6.6vh, 56px);
    background: linear-gradient(180deg, #FFFFFF 0%, #F6F9FC 100%);
    color: var(--briya-black);
    border: 1px solid rgba(199, 200, 202, 0.5);
    border-radius: 13px;
    font-size: clamp(16px, 2.4vh, 22px); font-weight: 600;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    padding: 0 4px;
    font-family: inherit;
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.9) inset,
        0 1px 2px rgba(35, 31, 32, 0.06),
        0 2px 6px rgba(35, 31, 32, 0.05);
    transition:
        background 100ms ease,
        color 100ms ease,
        border-color 100ms ease,
        transform 80ms ease,
        box-shadow 100ms ease;
}
.vkb-key:active {
    background: linear-gradient(180deg, var(--briya-blue) 0%, var(--briya-blue-dark) 100%);
    border-color: var(--briya-blue-dark);
    color: var(--briya-white);
    transform: translateY(1px) scale(0.97);
    box-shadow:
        0 0 0 3px rgba(0, 132, 203, 0.22),
        0 1px 0 rgba(255, 255, 255, 0.15) inset;
}

/* Modifier keys (shift, backspace) — subtle blue tint to distinguish from
   the alphabet without dominating the visual weight. */
.vkb-key-mod {
    flex: 1.5 1 0;
    background: linear-gradient(180deg, #EDF4F9 0%, #DEEBF3 100%);
    color: var(--briya-blue-dark);
    border-color: rgba(96, 195, 239, 0.45);
    font-size: clamp(15px, 2.2vh, 20px);
    font-weight: 700;
}
.vkb-key-mod.is-on {
    background: linear-gradient(135deg, var(--briya-yellow) 0%, var(--briya-orange) 100%);
    color: var(--briya-black);
    border-color: var(--briya-orange);
    box-shadow:
        0 0 0 2px rgba(251, 170, 25, 0.35),
        0 4px 12px rgba(251, 170, 25, 0.40),
        0 1px 0 rgba(255, 255, 255, 0.5) inset;
}

/* Action keys (123, ABC, Enter) — pop with the brand blue gradient pill. */
.vkb-key-action {
    flex: 1.6 1 0;
    background: linear-gradient(180deg, var(--briya-blue-medium) 0%, var(--briya-blue) 100%);
    color: var(--briya-white);
    border: 1px solid var(--briya-blue);
    font-size: clamp(13px, 1.9vh, 17px);
    font-weight: 700;
    letter-spacing: 0.3px;
    box-shadow:
        0 2px 8px rgba(0, 132, 203, 0.30),
        0 1px 0 rgba(255, 255, 255, 0.25) inset;
}
.vkb-key-action:active {
    background: linear-gradient(180deg, var(--briya-blue) 0%, var(--briya-blue-dark) 100%);
    border-color: var(--briya-blue-dark);
    color: var(--briya-white);
    transform: translateY(1px) scale(0.97);
    box-shadow: 0 0 0 3px rgba(0, 97, 151, 0.30);
}
.vkb-key-space  { flex: 5 1 0; }

/* Numeric pad: chunkier keys for the dedicated number layout. */
.vkb-row-num .vkb-key {
    height: clamp(48px, 8.2vh, 68px);
    font-size: clamp(22px, 3.2vh, 30px);
    max-width: 150px;
    border-radius: 16px;
}
.vkb-row-num .vkb-key-action {
    font-size: clamp(15px, 2vh, 19px);
}

/* Focused input gets a clean ring while the keyboard is open, AND a
   scroll-margin-bottom equal to the keyboard's height so any external
   call to scrollIntoView (browser default focus-scroll, anchor jumps,
   etc.) also keeps the input clear of the keyboard. */
body.vkb-open input:focus,
body.vkb-open textarea:focus {
    outline: 3px solid var(--briya-blue);
    outline-offset: 2px;
    box-shadow: 0 0 0 4px var(--briya-blue-tint);
    scroll-margin-top: 88px;
    scroll-margin-bottom: calc(var(--vkb-height, 50vh) + 32px);
}

/* ------------------------------------------------------------------
   ADMIN DASHBOARD
   Two-tier PIN-protected admin UI. Distinct from the kiosk look:
   compact topbar, side-by-side nav, data tables, settings toggles.
------------------------------------------------------------------ */
body.admin {
    background: var(--surface-bg);
    color: var(--briya-black);
    min-height: 100vh;
    display: flex; flex-direction: column;
}

/* 3-column grid: nav left · brand center · actions right.
   The middle column is `auto` so the logo is always dead-center
   regardless of how wide nav or actions are. The 1fr columns flank
   it symmetrically so the brand stays centered even on the admin
   login page (where nav + actions don't render and both side
   columns are empty). */
.admin-topbar {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: clamp(8px, 1.6vmin, 24px);
    padding: clamp(8px, 1.2vh, 18px) clamp(14px, 2.2vmin, 36px);
    background: var(--briya-blue);
    color: var(--briya-white);
    box-shadow: 0 2px 0 var(--briya-blue-dark);
}
.admin-topbar > .admin-brand   { grid-column: 2; justify-self: center; }
.admin-topbar > .admin-nav     { grid-column: 1; justify-self: start; }
.admin-topbar > .admin-actions { grid-column: 3; justify-self: end; }

.admin-brand {
    display: inline-flex; align-items: center; gap: 12px;
    color: white; text-decoration: none;
}
/* Logo intentionally inherits the base .brand-logo size from the kiosk-side
   topbar so the brand has the same presence everywhere in the app. */
.admin-nav {
    display: flex; gap: clamp(4px, 0.8vmin, 12px);
}
.admin-nav a {
    color: var(--briya-white); text-decoration: none;
    padding: clamp(6px, 1vh, 12px) clamp(12px, 1.6vmin, 22px);
    border-radius: 999px;
    font-size: clamp(13px, 1.7vmin, 17px);
    font-weight: 600;
    border: 1px solid transparent;
    transition: background 0.1s, border-color 0.1s;
    /* "Files & Data" was wrapping to three lines and stretching the topbar
       whenever the grid's side track got tight. A nav label should never
       wrap — let the row scroll instead (it already does at ≤900px). */
    white-space: nowrap;
    /* Admin is usable from a tablet, so keep the nav pills thumb-sized. */
    display: inline-flex; align-items: center; min-height: 40px;
}
.admin-nav a:hover { background: rgba(255, 255, 255, 0.12); }
.admin-nav a.is-active {
    background: rgba(255, 255, 255, 0.18);
    border-color: rgba(255, 255, 255, 0.45);
}
.admin-actions { display: inline-flex; align-items: center; gap: 12px; }
.admin-level {
    font-size: clamp(11px, 1.4vmin, 14px);
    font-weight: 700;
    letter-spacing: 1px; text-transform: uppercase;
    padding: 5px 12px; border-radius: 999px;
}
.admin-level-admin  { background: rgba(255, 255, 255, 0.15); color: white; }
.admin-level-super  { background: var(--briya-yellow); color: var(--briya-black); }
.admin-logout-form { margin: 0; }
.admin-logout-btn {
    background: transparent;
    color: var(--briya-white);
    border: 1px solid rgba(255, 255, 255, 0.55);
    border-radius: 999px;
    padding: 7px 16px;
    font-size: 13px; font-weight: 600;
    cursor: pointer; font-family: inherit;
}
.admin-logout-btn:hover { background: rgba(255, 255, 255, 0.12); }

.admin-content {
    flex: 1;
    width: 100%;
    max-width: min(96vw, 1500px);
    margin: 0 auto;
    padding: clamp(18px, 2.4vh, 36px) clamp(16px, 2.2vmin, 36px);
    /* Flex items default to min-width:auto (= min-content), which lets a wide
       child like the 14-column Returns table push this column WIDER than the
       viewport, overflowing the whole page. Allow it to shrink so the table
       scrolls inside .admin-table-wrap instead. */
    min-width: 0;
}

/* Flash banners */
.admin-flash-stack { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }
.admin-flash {
    padding: 12px 18px; border-radius: 10px;
    font-size: 15px;
    border: 1px solid transparent;
}
.admin-flash-ok    { background: #DEF7E6; border-color: var(--briya-green); color: #1A5C2A; }
.admin-flash-error { background: var(--error-bg); border-color: var(--error-text); color: var(--error-text); }
.admin-flash-message { background: var(--briya-blue-tint); border-color: var(--briya-blue-light); color: var(--briya-blue-dark); }

/* ------------------------------------------------------------------
   ADMIN DASHBOARD
   Stacks four sections inside .admin-content:
     1. .admin-welcome  — greeting + current date/time
     2. .admin-section "At a glance" — KPI tiles (returns today, etc.)
     3. .admin-section "Manage" — navigation cards
     4. .admin-section "Kiosk status" — live integration pills
------------------------------------------------------------------ */

.admin-dashboard {
    display: flex; flex-direction: column;
    gap: clamp(20px, 2.6vh, 36px);
}

/* Welcome strip — Briya-Blue gradient slab with the greeting + date. */
.admin-welcome {
    background: linear-gradient(135deg, var(--briya-blue) 0%, var(--briya-blue-dark) 100%);
    color: var(--briya-white);
    border-radius: 18px;
    padding: clamp(18px, 2.6vh, 32px) clamp(20px, 2.8vmin, 36px);
    box-shadow: var(--shadow-md);
}
.admin-welcome h1 {
    margin: 0;
    font-size: clamp(22px, 2.8vmin, 34px);
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--briya-white);  /* override the global h1 rule (black) */
}
.admin-welcome-meta {
    margin: 6px 0 0;
    color: rgba(255, 255, 255, 0.86);
    font-size: clamp(13px, 1.7vmin, 16px);
    font-weight: 500;
}
.admin-welcome-sep { margin: 0 8px; color: rgba(255, 255, 255, 0.55); }

/* Generic section + small-caps section title used across the dashboard. */
.admin-section { display: flex; flex-direction: column; gap: clamp(10px, 1.4vh, 18px); }
.admin-section-title {
    margin: 0;
    font-size: clamp(11px, 1.3vmin, 13px);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--briya-gray-65);
}

/* KPI tiles. Grid auto-fills so 4 tiles wrap to 2x2 on tablets and 1x4
   on phones without any media-query gymnastics. */
.admin-kpi-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: clamp(10px, 1.4vmin, 18px);
}
.admin-kpi {
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: 14px;
    padding: clamp(16px, 2vh, 22px) clamp(16px, 2vmin, 22px);
    box-shadow: var(--shadow-sm);
    display: flex; flex-direction: column; gap: 6px;
}
.admin-kpi-value {
    font-size: clamp(28px, 4vmin, 44px);
    font-weight: 700;
    color: var(--briya-black);
    line-height: 1.05;
    letter-spacing: -0.01em;
}
.admin-kpi-value-icon { display: inline-flex; align-items: center; }
.admin-kpi-value-icon svg { width: 1em; height: 1em; }
.admin-kpi-label {
    font-size: clamp(12px, 1.6vmin, 14px);
    font-weight: 600;
    color: var(--briya-gray-65);
    line-height: 1.35;
}
.admin-kpi-sublabel {
    display: block;
    font-size: clamp(11px, 1.4vmin, 12px);
    font-weight: 500;
    color: var(--briya-gray-65);
    margin-top: 2px;
    opacity: 0.85;
}
/* Per-site breakdown inside a count tile (Returns today / Active students /
   Devices on file): one row per site, name left + count right. Same site_order
   across all three tiles keeps the rows aligned tile-to-tile. */
.admin-kpi-sites {
    list-style: none;
    margin: clamp(8px, 1.2vh, 14px) 0 0;
    padding: clamp(8px, 1.2vh, 14px) 0 0;
    border-top: 1px solid var(--briya-gray-25);
    display: flex; flex-direction: column;
    gap: clamp(3px, 0.6vh, 6px);
}
.admin-kpi-site {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 10px;
    font-size: clamp(12px, 1.5vmin, 14px);
    line-height: 1.3;
}
.admin-kpi-site-name {
    color: var(--briya-gray-65);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.admin-kpi-site-num {
    color: var(--briya-black);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.admin-kpi.is-ok      .admin-kpi-value { color: var(--briya-blue-dark); }
.admin-kpi.is-warn    .admin-kpi-value { color: #B45309; }   /* amber-700 */
.admin-kpi.is-warn    { background: #FFFBEB; border-color: #FCD34D; }
.admin-kpi.is-error   .admin-kpi-value { color: var(--error-text); }
.admin-kpi.is-error   { background: var(--error-bg); border-color: var(--error-text); }

/* Issue-side tiles get the brand accent so the eye can separate "went out"
   from "came back" without reading the labels. */
.admin-kpi.is-accent  .admin-kpi-value { color: var(--briya-blue); }

/* Tiles that link into the matching Files & Data tab. */
a.admin-kpi.is-link { text-decoration: none; color: inherit; transition: transform 0.12s, box-shadow 0.12s, border-color 0.12s; }
@media (hover: hover) {
    a.admin-kpi.is-link:hover {
        border-color: var(--briya-blue-light);
        box-shadow: 0 10px 26px rgba(0, 97, 151, 0.14);
        transform: translateY(-2px);
    }
}

/* ------------------------------------------------------------------
   ACTIVITY STRIP — issued vs returned per day for the last fortnight.
   Two bars per day rather than a stacked total: the useful question is
   whether devices are flowing out or coming back, and a stack hides that.
------------------------------------------------------------------ */
.admin-activity {
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: 14px;
    padding: clamp(14px, 2vh, 22px) clamp(14px, 2vmin, 22px);
    box-shadow: var(--shadow-sm);
}
.admin-activity-legend {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: clamp(10px, 2vmin, 22px);
    margin-bottom: clamp(10px, 1.6vh, 18px);
    font-size: clamp(12px, 1.5vh, 15px);
}
.admin-activity-key { display: inline-flex; align-items: center; gap: 7px; color: var(--briya-gray-65); }
.admin-activity-key strong { color: var(--briya-black); }
.admin-activity-key i { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }
.admin-activity-key i.is-issued   { background: var(--briya-blue); }
.admin-activity-key i.is-returned { background: var(--briya-green); }
.admin-activity-total { margin-left: auto; font-size: 0.92em; }

.admin-activity-chart {
    list-style: none; margin: 0; padding: 0;
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: clamp(3px, 0.8vmin, 10px);
    height: clamp(90px, 14vh, 150px);
}
.admin-activity-day {
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column; align-items: center; gap: 5px;
    height: 100%;
}
.admin-activity-bars {
    flex: 1; width: 100%;
    display: flex; align-items: flex-end; justify-content: center;
    gap: 2px;
    /* A hairline baseline so empty days read as "zero", not "missing". */
    border-bottom: 2px solid var(--briya-gray-25);
    padding-bottom: 1px;
}
.admin-activity-bar {
    width: 42%; max-width: 16px;
    border-radius: 3px 3px 0 0;
    /* Keep a sliver visible at zero so the day still has a footprint. */
    min-height: 2px;
}
.admin-activity-bar.is-issued   { background: var(--briya-blue); }
.admin-activity-bar.is-returned { background: var(--briya-green); }
.admin-activity-tick {
    font-size: clamp(9px, 1.2vh, 12px);
    color: var(--briya-gray-65);
    font-variant-numeric: tabular-nums;
}
.admin-activity-day.is-today .admin-activity-tick {
    color: var(--briya-blue-dark); font-weight: 700;
}
.admin-activity-empty { margin: clamp(8px, 1.2vh, 14px) 0 0; }

/* Manage cards — circular tinted icon chip + tighter heading. */
.admin-card-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: clamp(12px, 1.6vmin, 22px);
}
.admin-card {
    display: flex; flex-direction: column;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: 16px;
    padding: clamp(18px, 2.2vh, 26px);
    text-decoration: none;
    color: var(--briya-black);
    box-shadow: var(--shadow-sm);
    transition: transform 0.1s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.admin-card:hover {
    transform: translateY(-2px);
    border-color: var(--briya-blue);
    box-shadow: var(--shadow-md);
}
.admin-card-icon {
    width: clamp(40px, 5vh, 52px); height: clamp(40px, 5vh, 52px);
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
    border-radius: 12px;
    margin-bottom: clamp(10px, 1.4vh, 16px);
}
.admin-card-icon svg { width: 60%; height: 60%; display: block; }
.admin-card h3 { margin: 0 0 6px; font-size: clamp(16px, 2vmin, 19px); color: var(--briya-black); font-weight: 700; }
.admin-card p  { margin: 0; font-size: clamp(13px, 1.6vmin, 14px); color: var(--briya-gray-65); line-height: 1.5; }

/* Kiosk status pills — dot + label. */
.admin-status-row {
    display: flex; gap: 10px; flex-wrap: wrap;
}
.admin-status-pill {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 8px 16px; border-radius: 999px;
    font-size: 13px; font-weight: 600;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    color: var(--briya-gray-65);
}
.admin-status-dot {
    display: inline-block;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--briya-gray-25);
}
/* ------------------------------------------------------------------
   ADMIN RECORD TABS — one per kiosk task (issue laptop / issue hotspot /
   return). All three tables render server-side and switching just toggles
   a class, so there's no reload and no lost filter or selection state.
------------------------------------------------------------------ */
.admin-tabs {
    display: flex; flex-wrap: wrap;
    gap: clamp(6px, 1vmin, 12px);
    margin: 0 0 clamp(14px, 2vh, 24px);
    border-bottom: 2px solid var(--briya-gray-25);
    padding-bottom: 0;
}
.admin-tab {
    display: inline-flex; align-items: center;
    gap: clamp(6px, 1vmin, 10px);
    padding: clamp(9px, 1.4vh, 14px) clamp(12px, 1.8vmin, 22px);
    border: 2px solid transparent;
    border-bottom: none;
    border-radius: clamp(8px, 1.2vmin, 12px) clamp(8px, 1.2vmin, 12px) 0 0;
    background: transparent;
    font: inherit;
    font-size: clamp(12px, 1.6vh, 16px);
    font-weight: 600;
    color: var(--briya-gray-65);
    cursor: pointer;
    margin-bottom: -2px;          /* sit on the container's border */
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.admin-tab:hover { color: var(--briya-blue-dark); background: var(--briya-blue-tint); }
.admin-tab.is-active {
    background: var(--surface-card);
    color: var(--briya-blue-dark);
    border-color: var(--briya-gray-25);
    border-bottom: 2px solid var(--surface-card);
}
.admin-tab-icon { width: 18px; height: 18px; flex: 0 0 auto; }
.admin-tab-icon svg { width: 100%; height: 100%; }
.admin-tab-count {
    min-width: 22px; padding: 1px 7px;
    border-radius: 999px;
    background: var(--briya-gray-25);
    color: var(--briya-black);
    font-size: 0.8em; font-weight: 700;
}
.admin-tab.is-active .admin-tab-count {
    background: var(--briya-blue); color: var(--briya-white);
}
@media (max-width: 760px) {
    .admin-tab-label { display: none; }   /* icon + count only on small screens */
    .admin-tab { padding-left: 14px; padding-right: 14px; }
}

.admin-tab-panel { display: none; }
.admin-tab-panel.is-active { display: block; }
.admin-tab-blurb { margin: 0 0 clamp(8px, 1.2vh, 16px); font-size: clamp(11px, 1.4vh, 14px); }

/* Agreement-template readiness list on the admin Files & Data page. Makes the
   "which of the four PDFs have actually been supplied" question answerable at
   a glance, since a missing one silently falls back to the generated page. */
.admin-template-status {
    margin: 0 0 clamp(12px, 1.8vh, 22px);
    padding: clamp(12px, 1.6vh, 20px) clamp(14px, 2vmin, 24px);
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.4vmin, 16px);
}
.admin-template-status h3 {
    margin: 0 0 10px;
    font-size: clamp(13px, 1.6vh, 16px);
    text-transform: uppercase; letter-spacing: 0.07em;
    color: var(--briya-gray-65);
}
.admin-template-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.admin-template-list li {
    display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px;
    font-size: clamp(12px, 1.5vh, 15px); line-height: 1.5;
}
.admin-template-dot {
    width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; align-self: center;
}
.admin-template-list .is-ready   .admin-template-dot { background: var(--briya-green); box-shadow: 0 0 0 3px rgba(170,208,71,0.25); }
.admin-template-list .is-missing .admin-template-dot { background: #E8A317; box-shadow: 0 0 0 3px rgba(232,163,23,0.22); }
.admin-template-list code { word-break: break-all; }

.admin-status-pill.is-on  { background: var(--briya-blue-tint); color: var(--briya-blue-dark); border-color: var(--briya-blue-light); }
.admin-status-pill.is-on  .admin-status-dot { background: var(--briya-blue); box-shadow: 0 0 0 3px rgba(0,132,203,0.18); }
.admin-status-pill.is-off { background: #FCFCFD; }
.admin-status-pill-link { color: var(--briya-blue); margin-left: 8px; font-weight: 500; text-decoration: none; }

/* Generic admin panel */
.admin-panel { background: transparent; }
.admin-panel h1 { font-size: clamp(22px, 2.8vmin, 36px); }
.admin-panel h2 { margin-top: clamp(18px, 2.4vh, 30px); }
.admin-form     { display: flex; flex-direction: column; gap: 14px; margin-bottom: 22px; }
.admin-form-actions {
    display: flex; flex-wrap: wrap;
    gap: clamp(8px, 1.4vmin, 14px);
    justify-content: flex-end;
    margin-top: clamp(14px, 2vh, 26px);
}
.admin-form-actions > * { flex: 0 1 auto; }

/* Login PIN keypad inherits the kiosk's .keypad / .key / .big-input styles. */
.admin-login { max-width: min(94vw, 480px); margin: clamp(20px, 4vh, 60px) auto; text-align: center; }
.admin-login h1 { font-size: clamp(24px, 3.2vmin, 40px); }
.admin-login .big-input { letter-spacing: 18px; font-size: clamp(40px, 6vh, 72px); }

/* Technicians */
.admin-tech-add { display: grid; grid-template-columns: 1fr 1fr auto; gap: 12px; align-items: end; }
.admin-tech-add label { display: flex; flex-direction: column; font-size: 14px; color: var(--briya-gray-65); }
.admin-tech-add input {
    margin-top: 4px;
    padding: 12px 14px; font-size: 16px;
    border: 1px solid var(--briya-gray-25); border-radius: 10px;
    background: var(--surface-card); color: var(--briya-black);
    font-family: inherit;
}
.admin-tech-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.admin-tech-item {
    display: grid;
    /* name · email-form · (role button, super view only) · remove — the role
       column is `auto` and collapses to 0 when absent for non-supers. */
    grid-template-columns: minmax(150px, 1.2fr) minmax(190px, 1.8fr) auto auto;
    gap: 12px;
    align-items: center;
    padding: 12px 16px;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: 10px;
    font-size: 16px;
}
.admin-tech-name { font-weight: 500; }
.admin-tech-email-form { display: flex; gap: 8px; align-items: center; margin: 0; }
.admin-tech-email-label { flex: 1; display: block; margin: 0; }
.admin-tech-email-form input[type="email"] {
    width: 100%;
    padding: 10px 12px; font-size: 15px;
    border: 1px solid var(--briya-gray-25); border-radius: 10px;
    background: var(--surface-card); color: var(--briya-black);
    font-family: inherit;
}
.admin-tech-email-form input[type="email"]:focus {
    border-color: var(--briya-blue);
    outline: none;
    box-shadow: 0 0 0 3px var(--briya-blue-tint);
}
.admin-tech-save {
    background: var(--briya-blue);
    color: #fff;
    border: 1px solid var(--briya-blue-dark);
    padding: 8px 16px;
    border-radius: 999px;
    font-size: 13px; font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    flex-shrink: 0;
}
.admin-tech-save:hover { background: var(--briya-blue-dark); }
.admin-tech-remove-form { margin: 0; }
.admin-tech-remove {
    background: transparent;
    color: var(--error-text);
    border: 1px solid var(--error-text);
    padding: 6px 14px;
    border-radius: 999px;
    font-size: 13px; font-weight: 600;
    cursor: pointer;
    font-family: inherit;
}
.admin-tech-remove:hover { background: var(--error-bg); }

/* Receipt-recipient presets — managed in Settings, picked on the kiosk
   confirm screen. Mirrors the technician add/remove pattern. */
.admin-recipients {
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: 16px;
    padding: clamp(16px, 2.2vh, 26px);
    margin-bottom: clamp(16px, 2.2vh, 26px);
    box-shadow: var(--shadow-sm);
}
.admin-recipients h2 { margin: 0 0 6px; }
.admin-recipients .muted { margin: 0 0 14px; }
.admin-preset-list {
    list-style: none; padding: 0; margin: 0 0 16px;
    display: flex; flex-direction: column; gap: 8px;
}
.admin-preset-row {
    display: grid;
    grid-template-columns: minmax(120px, 1fr) minmax(0, 2fr) auto;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    background: var(--surface-bg);
    border: 1px solid var(--briya-gray-25);
    border-radius: 12px;
}
.admin-preset-name { font-weight: 600; color: var(--briya-black); }
.admin-preset-email { color: var(--briya-gray-65); font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 14px; word-break: break-all; }
.admin-preset-remove-form { margin: 0; }
.admin-preset-add {
    display: grid; grid-template-columns: 1fr 1fr auto; gap: 12px; align-items: end;
    margin: 0;
}
.admin-preset-add label { display: flex; flex-direction: column; font-size: 14px; color: var(--briya-gray-65); }
.admin-preset-add input {
    margin-top: 4px;
    padding: 10px 12px; font-size: 15px;
    border: 1px solid var(--briya-gray-25); border-radius: 10px;
    background: var(--surface-card);
}
.admin-preset-add input:focus { border-color: var(--briya-blue); outline: none; box-shadow: 0 0 0 3px var(--briya-blue-tint); }
@media (max-width: 540px) {
    .admin-preset-add { grid-template-columns: 1fr; align-items: stretch; }
    .admin-preset-row { grid-template-columns: 1fr auto; }
    .admin-preset-row .admin-preset-email { grid-column: 1 / -1; }
}

/* Screen-reader-only label text. */
.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Settings toggles */
.admin-fieldset {
    border: 1px solid var(--briya-gray-25);
    border-radius: 14px;
    padding: clamp(14px, 1.8vh, 22px);
    margin: 0 0 16px;
    background: var(--surface-card);
}
.admin-fieldset legend {
    padding: 0 8px;
    font-weight: 700;
    color: var(--briya-blue-dark);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-size: 13px;
}
.admin-super { border-left: 3px solid var(--briya-yellow); }
.admin-fieldset label {
    display: block;
    font-size: 14px;
    color: var(--briya-gray-65);
    margin: 10px 0;
}
.admin-fieldset label input[type="text"],
.admin-fieldset label input[type="email"],
.admin-fieldset label input[type="url"],
.admin-fieldset label input[type="password"] {
    display: block; width: 100%;
    margin-top: 6px;
    padding: 10px 14px; font-size: 15px;
    border: 1px solid var(--briya-gray-25); border-radius: 10px;
    background: white; color: var(--briya-black);
    font-family: inherit;
}
.admin-fieldset small { display: block; margin-top: 4px; font-size: 12px; }
.admin-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 720px) { .admin-field-row { grid-template-columns: 1fr; } }

/* Toggle row — flexbox-based so the inline <span> slider gets a real box. */
.admin-toggle {
    display: flex;
    align-items: flex-start;
    gap: clamp(12px, 1.6vmin, 20px);
    padding: 10px 0;
    cursor: pointer;
}
/* Visually hide the real checkbox but keep it focusable / accessible. */
.admin-toggle input[type="checkbox"] {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
}
.admin-toggle-slider {
    display: inline-block;
    flex: 0 0 auto;
    width: 52px; height: 30px;
    background: var(--briya-gray-25);
    border-radius: 999px;
    position: relative;
    transition: background 0.18s;
    margin-top: 2px;
}
.admin-toggle-slider::after {
    content: "";
    position: absolute; top: 3px; left: 3px;
    width: 24px; height: 24px;
    background: white;
    border-radius: 50%;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
    transition: transform 0.18s;
}
.admin-toggle input[type="checkbox"]:checked + .admin-toggle-slider {
    background: var(--briya-blue);
}
.admin-toggle input[type="checkbox"]:checked + .admin-toggle-slider::after {
    transform: translateX(22px);
}
.admin-toggle input[type="checkbox"]:focus-visible + .admin-toggle-slider {
    box-shadow: 0 0 0 3px var(--briya-blue-tint);
}
.admin-toggle-text {
    flex: 1 1 0;
    min-width: 0;
    color: var(--briya-black);
    font-size: 14px;
    line-height: 1.4;
}
.admin-toggle-text strong { display: block; margin-bottom: 2px; font-size: 15px; }
.admin-toggle-text small  { display: block; color: var(--briya-gray-65); font-weight: 400; }

/* Import preview tables + stats */
.admin-stats-row {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 12px;
    margin: 14px 0 24px;
}
.admin-stat {
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: 12px;
    padding: 14px 16px;
    text-align: center;
}
.admin-stat-num { display: block; font-size: 28px; font-weight: 800; color: var(--briya-blue-dark); }
.admin-stat-label { display: block; font-size: 12px; color: var(--briya-gray-65); text-transform: uppercase; letter-spacing: 0.5px; margin-top: 2px; }
.admin-stat-warn .admin-stat-num { color: var(--briya-orange); }
.admin-warn {
    background: #FFF4E0;
    border: 1px solid var(--briya-orange);
    color: #7A4A00;
    padding: 12px 16px; border-radius: 10px;
    font-size: 14px;
    margin: 14px 0;
}

/* Wide tables scroll horizontally INSIDE this wrap on small screens instead of
   forcing the whole page wide. Momentum scroll + a thin scrollbar make the
   horizontal scroll smooth and discoverable on touch devices. */
.admin-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: var(--briya-blue-light) transparent;
}
.admin-table-wrap::-webkit-scrollbar { height: 8px; }
.admin-table-wrap::-webkit-scrollbar-track { background: transparent; }
.admin-table-wrap::-webkit-scrollbar-thumb { background: var(--briya-blue-light); border-radius: 999px; }
.admin-table {
    width: 100%; border-collapse: collapse;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: 10px;
    overflow: hidden;
    font-size: 14px;
}
.admin-table th,
.admin-table td { padding: 10px 14px; text-align: left; border-bottom: 1px solid var(--briya-gray-25); vertical-align: top; }
.admin-table thead th { background: var(--briya-blue-tint); color: var(--briya-blue-dark); font-weight: 700; font-size: 12px; text-transform: uppercase; letter-spacing: 0.4px; }
.admin-table tr:last-child td { border-bottom: none; }
.admin-table code { background: var(--briya-blue-tint); padding: 2px 6px; border-radius: 4px; font-size: 13px; color: var(--briya-blue-dark); }
.admin-row-warn { background: #FFFAF0; }

.admin-import-actions { margin: 14px 0 22px; }
.admin-import-template {
    display: inline-flex; align-items: center; gap: 8px;
    text-decoration: none;
}
/* File-upload drop zone for /admin/import.
   The native <input type="file"> is visually hidden but layered over the
   whole label so any tap still opens the OS file picker. JS in import.html
   adds .is-dragover on drag and .is-filled once a file is chosen. */
.admin-file-drop {
    position: relative;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: clamp(10px, 1.4vh, 16px);
    padding: clamp(24px, 3.4vh, 40px) clamp(20px, 2.6vmin, 32px);
    border: 2px dashed var(--briya-blue-light);
    border-radius: 16px;
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
    text-align: center;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.admin-file-drop:hover,
.admin-file-drop:focus-within {
    border-color: var(--briya-blue);
    background: #DCF0FB;
    box-shadow: 0 0 0 4px rgba(0,132,203,0.10);
}
.admin-file-drop.is-dragover {
    border-color: var(--briya-blue);
    background: #C9E7F7;
    box-shadow: 0 0 0 6px rgba(0,132,203,0.18);
}
.admin-file-drop.is-filled {
    border-style: solid;
    border-color: var(--briya-blue);
    background: var(--surface-card);
}
/* Hide the native control but keep it fully clickable + keyboard-accessible. */
.admin-file-drop input[type="file"] {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    opacity: 0;
    cursor: pointer;
}
.admin-file-drop-icon {
    width: clamp(40px, 5vh, 56px); height: clamp(40px, 5vh, 56px);
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--briya-white);
    border: 1px solid var(--briya-blue-light);
    border-radius: 999px;
    color: var(--briya-blue-dark);
    box-shadow: var(--shadow-sm);
}
.admin-file-drop-icon svg { width: 60%; height: 60%; display: block; }
.admin-file-drop-text { display: flex; flex-direction: column; gap: 2px; line-height: 1.35; }
.admin-file-drop-primary   { font-size: clamp(15px, 2vmin, 18px); font-weight: 700; color: var(--briya-blue-dark); }
.admin-file-drop-secondary { font-size: clamp(13px, 1.7vmin, 15px); font-weight: 500; color: var(--briya-blue-dark); opacity: 0.85; }
.admin-file-drop-hint      { font-size: clamp(11px, 1.4vmin, 13px); color: var(--briya-gray-65); margin-top: 4px; }
.admin-file-drop-filename {
    display: none;
    max-width: 100%;
    padding: 8px 14px;
    border-radius: 999px;
    background: var(--briya-blue);
    color: var(--briya-white);
    font-size: 13px; font-weight: 600;
    word-break: break-all;
    box-shadow: var(--shadow-sm);
}
.admin-file-drop.is-filled .admin-file-drop-filename { display: inline-block; }
.admin-file-drop.is-filled .admin-file-drop-primary::before { content: "Selected: "; opacity: 0.7; font-weight: 500; }

/* Export cards — sit below the import section. */
.admin-export-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: clamp(10px, 1.4vmin, 18px);
    margin: 14px 0 22px;
}
/* Single-card variant: cap width so a lone export card doesn't span the
   whole panel like an oversized hero. */
.admin-export-grid-single {
    grid-template-columns: minmax(280px, 480px);
    justify-content: start;
}
.admin-export-card {
    display: grid;
    grid-template-columns: 48px 1fr 24px;
    gap: 16px;
    align-items: center;
    padding: clamp(14px, 1.8vh, 22px) clamp(16px, 2vmin, 24px);
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: 14px;
    text-decoration: none;
    color: var(--briya-black);
    box-shadow: var(--shadow-sm);
    transition: transform 0.1s, border-color 0.1s, box-shadow 0.1s;
}
.admin-export-card:hover {
    transform: translateY(-2px);
    border-color: var(--briya-blue);
    box-shadow: var(--shadow-md);
}
.admin-export-card.is-empty {
    opacity: 0.6;
    cursor: not-allowed;
}
.admin-export-card.is-empty:hover { transform: none; border-color: var(--briya-gray-25); box-shadow: var(--shadow-sm); }
.admin-export-icon { width: 40px; height: 40px; color: var(--briya-blue); }
.admin-export-icon svg { width: 100%; height: 100%; }
.admin-export-title { font-size: 16px; font-weight: 700; color: var(--briya-black); margin-bottom: 2px; }
.admin-export-meta  { font-size: 13px; color: var(--briya-gray-65); line-height: 1.4; }
.admin-export-arrow { width: 22px; height: 22px; color: var(--briya-blue); justify-self: end; }
.admin-export-arrow svg { width: 100%; height: 100%; transform: rotate(180deg); }

/* ------------------------------------------------------------------
   ADMIN — responsive breakpoints
   The clamp() values above scale fluidly. Below, only the LAYOUT switches:
     - ≤800px: nav wraps to its own scrollable second row of the topbar
     - ≤600px: role pill + sign-out get compact, brand logo shrinks
     - ≤540px: technician add-form stacks input above the Add button
     - ≤420px: dashboard cards + status pills tighten up
------------------------------------------------------------------ */
@media (max-width: 900px) {
    /* Tight phones / portrait tablets / split-screen browser windows:
       the 3-column grid runs out of room, so collapse to a single
       centered column. Logo on top, nav (horizontally scrollable),
       then actions. Each row stays full-width so nothing collides. */
    .admin-topbar {
        grid-template-columns: 1fr;
        row-gap: 8px;
    }
    .admin-topbar > .admin-brand   { grid-column: 1; justify-self: center; }
    .admin-topbar > .admin-nav     { grid-column: 1; justify-self: stretch; }
    .admin-topbar > .admin-actions { grid-column: 1; justify-self: end; }
    .admin-nav {
        gap: 6px;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        padding-bottom: 2px;
    }
    .admin-nav::-webkit-scrollbar { display: none; }
    .admin-nav a   { flex: 0 0 auto; white-space: nowrap; }
}

@media (max-width: 600px) {
    /* Brand logo intentionally matches the kiosk-side size at every width
       — the base .brand-logo clamp already shrinks to 44px at this range. */
    .admin-level             { font-size: 10px; padding: 4px 10px; }
    .admin-logout-btn        { padding: 6px 12px; font-size: 12px; }
    .admin-content           { padding: clamp(12px, 1.8vh, 24px) clamp(12px, 2vmin, 22px); }
    .admin-panel h1          { font-size: clamp(20px, 5vw, 28px); }
}

/* Stack the technician rows before the multi-column layout can overflow
   (the super-admin view has 4 columns: name, email, role, remove). */
@media (max-width: 820px) {
    .admin-tech-item { grid-template-columns: 1fr; gap: 8px; }
    .admin-tech-email-form { width: 100%; }
    .admin-tech-remove-form,
    .admin-tech-role-form { align-self: flex-start; }
}

@media (max-width: 540px) {
    .admin-tech-add { grid-template-columns: 1fr; align-items: stretch; }
    .admin-tech-add button { width: 100%; }
    .admin-tech-item {
        grid-template-columns: 1fr;
        gap: 8px;
    }
    .admin-tech-name { font-size: 17px; }
    .admin-tech-email-form { width: 100%; }
    .admin-tech-remove-form { align-self: flex-start; }
    .admin-toggle {
        gap: 12px;
    }
    .admin-toggle-slider { width: 46px; height: 26px; }
    .admin-toggle-slider::after { width: 20px; height: 20px; }
    .admin-toggle input[type="checkbox"]:checked + .admin-toggle-slider::after {
        transform: translateX(20px);
    }
}

@media (max-width: 420px) {
    .admin-card-grid { grid-template-columns: 1fr; gap: 12px; }
    .admin-kpi-grid  { grid-template-columns: repeat(2, 1fr); }
    .admin-card h3   { font-size: 18px; }
    .admin-card p    { font-size: 13px; }
    .admin-status-pill { font-size: 12px; padding: 6px 12px; }
    .admin-export-grid { grid-template-columns: 1fr; }
}

/* Returns log — analytics table + toolbar on the Files & Data page */
.admin-returns-toolbar {
    display: flex; flex-wrap: wrap; gap: 12px;
    align-items: center; justify-content: space-between;
    margin: 14px 0;
}
.admin-returns-filter {
    flex: 1 1 260px; min-width: 0;
    padding: 10px 14px; font-size: 15px;
    border: 1px solid var(--briya-gray-25); border-radius: 10px;
    background: var(--surface-card); color: var(--briya-black);
    font-family: inherit;
}
.admin-returns-filter:focus {
    border-color: var(--briya-blue); outline: none;
    box-shadow: 0 0 0 3px var(--briya-blue-tint);
}
.admin-returns-toolbar .primary { flex: 0 0 auto; width: auto; margin: 0; }
.admin-returns-count { margin: 0 0 10px; font-size: 13px; }

/* Needs Returned tab: state filter chips + the Owed/Out badge.
   Full 44px targets here — this table is tens of rows, not hundreds, and the
   chips are the primary control on the panel. */
.admin-statechips { display: flex; flex-wrap: wrap; gap: 8px; flex: 0 0 auto; }
.admin-statechip {
    display: inline-flex; align-items: center; gap: 7px;
    min-height: 44px; padding: 8px 16px;
    border: 1px solid var(--briya-gray-25); border-radius: 999px;
    background: var(--surface-card); color: var(--briya-gray-65);
    font-family: inherit; font-size: 14px; font-weight: 600;
    cursor: pointer;
    transition: background 0.1s, border-color 0.1s, color 0.1s;
}
.admin-statechip span {
    font-size: 12px; font-weight: 700;
    padding: 1px 8px; border-radius: 999px;
    background: var(--briya-gray-10, #F1F2F4);
}
.admin-statechip:hover { border-color: var(--briya-blue-light); }
.admin-statechip.is-active {
    background: var(--briya-blue-tint); color: var(--briya-blue-dark);
    border-color: var(--briya-blue-light);
}
.admin-statechip.is-active span { background: var(--briya-white); }
.admin-statepill {
    display: inline-block; white-space: nowrap;
    padding: 3px 10px; border-radius: 999px;
    font-size: 12px; font-weight: 700;
}
.admin-statepill.is-owed { background: #FFF4E0; color: #7A4A00; border: 1px solid var(--briya-orange); }
.admin-statepill.is-out  { background: var(--briya-blue-tint); color: var(--briya-blue-dark); border: 1px solid var(--briya-blue-light); }
/* Destructive-ish, so it reads as the quieter of the two row actions. */
.admin-settle-btn {
    background: var(--surface-card); color: var(--briya-gray-65);
    border-color: var(--briya-gray-25);
}
.admin-settle-btn:hover { border-color: var(--briya-orange); color: #7A4A00; }
@media (max-width: 720px) {
    .admin-returns-toolbar .admin-statechips { width: 100%; }
    .admin-statechip { flex: 1 1 auto; justify-content: center; }
}
.admin-returns-empty { color: var(--briya-gray-65); padding: 12px 0; }
/* Font scales down a touch on smaller viewports so the 13-column table fits
   as many screens as possible; .admin-table-wrap still scrolls horizontally on
   the narrowest devices. */
.admin-returns-table { font-size: clamp(11px, 1.55vw, 13px); }
/* Every header + cell is centered and stays on one line. Compact padding keeps
   the table as narrow as possible without wrapping any cell text. */
.admin-returns-table th,
.admin-returns-table td {
    white-space: nowrap;
    text-align: center;
    vertical-align: middle;
    padding: 8px clamp(6px, 0.9vw, 12px);
}
/* Sortable headers reserve a right-side slot for the ⇅/▲/▼ arrow; mirror it on
   the left so the centered label doesn't drift off-center. */
.admin-returns-table th.admin-sortable,
#outstanding-table th.admin-sortable { padding-left: 22px; }
/* Center the per-row Receipt actions (Download / Delete) within their cell. */
.admin-returns-table .admin-files-col-actions { justify-content: center; text-align: center; }
.admin-returns-table code {
    background: var(--briya-blue-tint); color: var(--briya-blue-dark);
    padding: 2px 6px; border-radius: 4px;
    font-size: 0.92em;
}
/* Click-to-sort headers: a faint ⇅ hint until sorted, then ▲ asc / ▼ desc. */
.admin-sortable {
    cursor: pointer;
    user-select: none; -webkit-user-select: none;
    position: relative;
    padding-right: 22px !important;
    white-space: nowrap;
}
.admin-sortable:hover { background: var(--briya-blue-light); color: var(--briya-white); }
.admin-sortable:focus-visible { outline: 2px solid var(--briya-blue-dark); outline-offset: -2px; }
.admin-sortable::after {
    content: "\2195";          /* ⇅ */
    position: absolute; right: 7px; top: 50%; transform: translateY(-50%);
    font-size: 11px; opacity: 0.4;
}
.admin-sortable.is-sorted-asc::after  { content: "\25B2"; opacity: 1; }  /* ▲ */
.admin-sortable.is-sorted-desc::after { content: "\25BC"; opacity: 1; }  /* ▼ */

/* Returns & receipts — small-screen layout. The 14-column table itself
   scrolls horizontally inside .admin-table-wrap; here we stack the toolbar
   and bulk actions full-width and tighten the table so more columns fit. */
@media (max-width: 640px) {
    .admin-returns-toolbar { flex-direction: column; align-items: stretch; }
    .admin-returns-toolbar .admin-returns-filter { flex: 1 1 auto; }
    .admin-returns-toolbar .primary { width: 100%; }
    .admin-files-bulk { flex-direction: column; align-items: stretch; }
    .admin-files-bulk .primary,
    .admin-files-bulk .admin-danger-btn { width: 100%; }
    .admin-returns-table th,
    .admin-returns-table td { padding: 6px 7px; }
    /* Shrink the sort-arrow slot so the tighter cells don't waste width. */
    .admin-returns-table .admin-sortable { padding-right: 18px !important; }
    .admin-returns-table th.admin-sortable { padding-left: 18px; }
}

/* Files page — stored signed PDFs */
.admin-files-check { width: 1%; white-space: nowrap; text-align: center; }
.admin-files-check input[type="checkbox"] {
    /* Unlike the kiosk's device rows, this checkbox has no wrapping <label>,
       so the box IS the tap target. 18px was fiddly on a tablet; the extra
       padding widens the hit area without changing the visual size much. */
    width: 22px; height: 22px;
    margin: 9px 6px;
    accent-color: var(--briya-blue);
    cursor: pointer; vertical-align: middle;
}
.admin-files-bulk {
    display: flex; flex-wrap: wrap; gap: 12px;
    align-items: center;
    margin: 18px 0 22px;
}
.admin-files-table { font-size: 14px; }
.admin-files-name code {
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
    padding: 3px 9px;
    border-radius: 6px;
    font-size: 13px;
    word-break: break-all;
}
.admin-files-col-meta    { white-space: nowrap; color: var(--briya-gray-65); font-size: 13px; }
.admin-files-col-actions {
    white-space: nowrap;
    text-align: right;
    display: flex; gap: 8px; justify-content: flex-end;
    flex-wrap: wrap;
}
.admin-files-action {
    /* Deliberately below the 44px touch guideline: these sit in dense table
       rows, and a 44px control would nearly double the row height across
       hundreds of records. 34px is a workable compromise for what is a
       desk-and-mouse task; the kiosk's own controls are all full-size. */
    display: inline-flex; align-items: center; min-height: 34px;
    padding: 6px 14px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    font-family: inherit;
    transition: background 0.1s, border-color 0.1s, color 0.1s;
}
.admin-files-download {
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
    border-color: var(--briya-blue-light);
}
.admin-files-download:hover { background: var(--briya-blue-light); color: var(--briya-white); }
.admin-files-delete {
    background: transparent;
    color: var(--error-text);
    border-color: var(--error-text);
}
.admin-files-delete:hover { background: var(--error-bg); }

.admin-danger-btn {
    background: transparent;
    color: var(--error-text);
    border: 1px solid var(--error-text);
    border-radius: 999px;
    padding: 10px 18px;
    font-size: 14px; font-weight: 600;
    cursor: pointer;
    font-family: inherit;
}
.admin-danger-btn:hover { background: var(--error-bg); }

/* On narrow phones, hide the meta cols and stack actions */
@media (max-width: 540px) {
    .admin-files-col-meta { display: none; }
    .admin-files-table th:first-child,
    .admin-files-table td:first-child { padding-right: 0; }
}

/* Delivery log on done page */
.done-delivery {
    margin: 14px auto;
    max-width: min(92vw, 640px);
    text-align: left;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: 12px;
    padding: 10px 16px;
    font-size: 13px;
}
.done-delivery summary { cursor: pointer; font-weight: 600; color: var(--briya-blue-dark); }
.done-delivery ul { margin: 8px 0 4px; padding-left: 18px; }
.done-delivery .delivery-ok   { color: #1A5C2A; }
.done-delivery .delivery-fail { color: var(--error-text); }

/* ------------------------------------------------------------------
   Responsive layout — only the LAYOUT switches live here now. All size /
   padding / font-size scaling is handled by the clamp(min, vmin|vh, max)
   rules above, so we don't fight them with fixed-pixel overrides.
------------------------------------------------------------------ */
@media (max-width: 900px) {
    /* Stack action buttons full-width on small screens. */
    .actions { flex-direction: column-reverse; align-items: stretch; }
    .actions .primary, .actions .secondary { width: 100%; min-width: 0; }
}

@media (max-width: 720px) {
    /* iPad portrait & phones: wrap roadmap to a 2x2 grid, hide arrows.
       Vertical spacing is still owned by .home-hero's space-evenly; only
       horizontal centering is set here via auto margins. */
    .steps {
        display: grid; grid-template-columns: 1fr 1fr;
        gap: clamp(8px, 1.4vh, 16px);
        max-width: 520px;
        margin-left: auto; margin-right: auto;
    }
    .step { max-width: none; }
    .step-arrow { display: none; }
}

@media (max-width: 600px) {
    /* The vkb takes a bigger share on very narrow viewports so its keys
       stay readable. */
    .vkb { max-height: 50vh; }
}

@media (max-width: 420px) {
    /* Narrow phones: stack roadmap into a single column. */
    .steps { grid-template-columns: 1fr; max-width: 320px; }
}

@media (max-height: 500px) and (orientation: landscape) {
    /* Landscape phones / very short screens. The earlier 65vh value
       gave the keyboard more vertical room for tappable keys but
       buried the form on /lookup (a 375-tall viewport left ~36px
       between topbar and keyboard). Cap at the smaller of 55vh
       (≈206px on 375h) and 240px so the focused input always has
       breathing room above the keys, and ensureVisible() doesn't
       have to fight to keep it visible. */
    .vkb { max-height: min(55vh, 240px); }
}

/* Content max-width uses fluid clamp() — no fixed-pixel override needed here. */

/* ── Signed-in technician identity chip (kiosk + admin topbars) ───────────── */
.tech-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px 5px 8px;
    border-radius: 999px;
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
    font-size: .82rem;
    font-weight: 600;
    line-height: 1;
    max-width: 32vw;
}
.tech-chip svg { width: 17px; height: 17px; flex: none; }
.tech-chip .tech-chip-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
@media (max-width: 560px) {
    /* Tight screens: keep the icon, let the name ellipsize harder. */
    .tech-chip { max-width: 40vw; font-size: .78rem; }
}

/* Personalized greeting on the home hero. */
.home-greeting {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    align-self: center;
    margin: 0 0 clamp(6px, 1.2vh, 14px);
    padding: 6px 16px;
    border-radius: 999px;
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
    font-weight: 700;
    font-size: clamp(14px, 1.9vmin, 18px);
}

/* Topbar user menu — click the signed-in name for a dropdown (Admin / Sign out). */
.user-menu { position: relative; display: inline-block; }
.user-menu-trigger {
    display: inline-flex; align-items: center; gap: 7px;
    border: none; cursor: pointer; font: inherit;
    background: var(--briya-white); color: var(--briya-blue-dark);
    border-radius: 999px; padding: 6px 12px; font-size: .85rem; font-weight: 600;
    min-height: 40px;   /* the topbar's only menu — reachable on a tablet */
}
.user-menu-trigger > svg { width: 16px; height: 16px; flex: none; }
.user-menu-trigger .caret { transition: transform .2s ease; opacity: .8; }
.user-menu.open .user-menu-trigger .caret { transform: rotate(180deg); }
.user-menu-name { max-width: 30vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-menu-panel {
    position: absolute; top: calc(100% + 8px); right: 0; min-width: 224px;
    background: var(--briya-white); color: var(--briya-black);
    border-radius: 12px; box-shadow: 0 12px 34px rgba(0, 20, 40, .24);
    padding: 6px; z-index: 1000; text-align: left;
    opacity: 0; visibility: hidden; transform: translateY(-6px);
    transition: opacity .15s ease, transform .15s ease, visibility .15s ease;
}
.user-menu.open .user-menu-panel { opacity: 1; visibility: visible; transform: none; }
.user-menu-head {
    padding: 9px 12px 7px; margin-bottom: 4px; font-size: .74rem; line-height: 1.35;
    color: var(--briya-gray-65); border-bottom: 1px solid var(--briya-blue-tint); word-break: break-all;
}
.user-menu-head strong { display: block; color: var(--briya-black); font-size: .82rem; }
.user-menu-item {
    display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box;
    padding: 10px 12px; border: none; background: none; border-radius: 8px; cursor: pointer;
    font: inherit; font-size: .9rem; color: var(--briya-black); text-align: left; text-decoration: none;
    min-height: 42px;   /* "Sign out" sits next to "Admin" — don't mis-tap it */
}
.user-menu-item:hover, .user-menu-item:focus { background: var(--briya-blue-tint); outline: none; }
.user-menu-item > svg { width: 17px; height: 17px; flex: none; color: var(--briya-blue-dark); }
.user-menu-item.danger { color: #9B1C1C; }
.user-menu-item.danger > svg { color: #9B1C1C; }
.user-menu-item.danger:hover, .user-menu-item.danger:focus { background: #FCE8E8; }
.user-menu form { margin: 0; }

/* Account-type badge + promote/demote control on the Technicians page. */
.admin-role-badge {
    display: inline-block;
    margin-left: 8px;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .4px;
    vertical-align: middle;
}
.admin-role-super   { background: var(--briya-blue-tint); color: var(--briya-blue-dark); }
.admin-role-regular { background: #ECEEF1; color: var(--briya-gray-65); }
.admin-tech-role {
    border: 1px solid var(--briya-gray-25);
    background: var(--briya-white);
    color: var(--briya-blue-dark);
    border-radius: 8px;
    padding: 7px 12px;
    font-size: .85rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}
.admin-tech-role:hover { background: var(--briya-blue-tint); }
.admin-tech-promote { border-color: var(--briya-blue); }
.admin-tech-role-note { font-size: .8rem; white-space: nowrap; }

/* --- Asset picker -------------------------------------------------------
   Choosing which physical device is being handed over. The list can be 694
   rows, so it scrolls in its own box rather than growing the page, and the
   rows are laid out as a grid so identifiers line up down the column instead
   of wandering with the model name's width. */
.pick-search {
    display: flex; align-items: stretch;
    gap: clamp(8px, 1.2vmin, 14px);
    margin-bottom: clamp(8px, 1.2vh, 16px);
}
.pick-search input[type="text"] {
    /* Styled here rather than inherited: the kiosk's field styling is scoped to
       `.confirm-form`, so without this the scan box renders as a bare browser
       input with 1px of padding. */
    flex: 1 1 auto; min-width: 0;
    min-height: 44px;
    font-size: clamp(15px, 2vmin, 24px);
    padding: clamp(8px, 1.2vh, 18px) clamp(12px, 1.6vmin, 22px);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.4vmin, 18px);
    background: var(--surface-card); color: var(--briya-black);
    font-family: inherit;
}
.pick-search input[type="text"]:focus {
    border-color: var(--briya-blue); outline: none;
    box-shadow: 0 0 0 3px var(--briya-blue-tint);
}
.pick-search .scan-btn { flex: 0 0 auto; }
/* `form .primary` makes every button in a form full width, which is right for
   stacked forms and wrong inside this row — it ate the whole line and squeezed
   the scan box to 8px. */
.pick-search .pick-go {
    flex: 0 0 auto; width: auto; margin-top: 0;
    min-height: 44px; white-space: nowrap;
}

.pick-count { margin: 0 0 clamp(6px, 0.8vh, 10px); }

.pick-list {
    list-style: none; margin: 0 0 clamp(8px, 1.2vh, 16px); padding: 0;
    display: flex; flex-direction: column;
    gap: clamp(6px, 0.9vh, 12px);
    /* Bounded so the Back action stays reachable without scrolling past
       hundreds of rows; the box scrolls, the page doesn't. */
    max-height: min(52vh, 560px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}
.pick-item {
    display: grid;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
    align-items: center;
    gap: clamp(8px, 1.4vmin, 20px);
    width: 100%;
    min-height: 44px;
    text-align: left;
    background: var(--surface-card);
    color: var(--briya-black);
    padding: clamp(8px, 1.3vh, 16px) clamp(12px, 1.8vmin, 22px);
    border: 1px solid var(--briya-gray-25);
    border-radius: clamp(10px, 1.4vmin, 18px);
    cursor: pointer;
}
.pick-item:hover, .pick-item:focus-visible {
    border-color: var(--briya-blue);
    background: var(--briya-blue-tint);
}
.pick-id {
    font-weight: 700;
    font-size: clamp(15px, 2vmin, 22px);
    word-break: break-all;
}
.pick-desc {
    font-size: clamp(13px, 1.7vmin, 19px);
    color: var(--briya-gray-65);
    overflow-wrap: anywhere;
}
.pick-type-tag {
    font-size: clamp(11px, 1.4vmin, 15px);
    color: var(--briya-gray-65);
    white-space: nowrap;
}
.pick-more { margin: 0 0 clamp(8px, 1.2vh, 14px); }

@media (max-width: 520px) {
    /* Three columns don't fit a phone; stack and drop the type onto its own
       line rather than letting the identifier wrap mid-serial. */
    .pick-item { grid-template-columns: minmax(0, 1fr); gap: 2px; }
    .pick-search { flex-wrap: wrap; }
    .pick-search input[type="text"] { flex: 1 1 100%; }
    .pick-go { flex: 1 1 auto; }
}

/* --- Technician site permissions ---------------------------------------- */
.admin-tech-sites {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 6px; border: 0; margin: 0; padding: 0;
}
.admin-site-pill {
    display: inline-flex; align-items: center; gap: 5px;
    min-height: 34px; padding: 4px 10px;
    border: 1px solid var(--briya-gray-25);
    border-radius: 999px;
    font-size: 13px; font-weight: 600;
    color: var(--briya-gray-65);
    cursor: pointer;
}
.admin-site-pill.is-on {
    border-color: var(--briya-blue);
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
}
.admin-site-pill input { width: 16px; height: 16px; accent-color: var(--briya-blue); }
.admin-tech-sites-readonly { font-size: 13px; }

/* --- Import preview: reconciliation + conflict warning ------------------- */
.admin-scroll-list {
    /* These lists can be hundreds of rows (31 outstanding debts on day one),
       so they scroll in place rather than burying the commit button. */
    max-height: min(40vh, 380px);
    overflow-y: auto;
}
.admin-import-commit { margin-top: 24px; }
.admin-deactivate-opt {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 12px 14px; margin-bottom: 14px;
    border: 1px solid var(--briya-orange);
    border-radius: 10px;
    background: #FFF8EC;
    font-size: 14px; line-height: 1.45;
}
.admin-deactivate-opt input { width: 18px; height: 18px; margin-top: 2px; flex: 0 0 auto; }

.admin-modal {
    position: fixed; inset: 0; z-index: 60;
    display: flex; align-items: center; justify-content: center;
    padding: 20px;
    background: rgba(35, 31, 32, 0.55);
}
.admin-modal[hidden] { display: none; }
.admin-modal-card {
    background: var(--briya-white);
    border-radius: 14px;
    padding: clamp(18px, 3vmin, 28px);
    width: min(640px, 100%);
    max-height: 86vh; overflow-y: auto;
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.28);
}
.admin-modal-card h2 { margin-top: 0; }
.admin-modal-field { display: block; margin: 16px 0; font-size: 14px; color: var(--briya-gray-65); }
.admin-modal-field input {
    display: block; width: 100%; margin-top: 6px;
    min-height: 44px; padding: 10px 14px; font-size: 15px;
    border: 1px solid var(--briya-gray-25); border-radius: 10px;
    background: var(--briya-white); color: var(--briya-black);
    font-family: inherit;
}
.admin-modal-field input:focus {
    border-color: var(--briya-blue); outline: none;
    box-shadow: 0 0 0 3px var(--briya-blue-tint);
}

/* --- Landscape phones and dense admin rows -------------------------------
   Everything below was found by measuring real device viewports in BOTH
   orientations. A phone in landscape is a ~375px-tall viewport, so every
   `vh`-based clamp in this file sits at its minimum at once — a class of
   problem that width-only testing cannot see. */

/* The lookup page's "can't find them?" escape hatch, and the admin table
   filter: both land just under the guideline. */
.text-link { display: inline-flex; align-items: center; min-height: 44px; }
.admin-returns-filter { min-height: 44px; }

/* The technician roster is eight rows, not hundreds, so these can have the
   full target without the row-height cost that keeps the document tables
   compact. */
.admin-tech-email-form input { min-height: 44px; }
.admin-tech-save { min-height: 44px; }

/* Status pills in the admin tables link to the filtered view. They sit in
   dense rows where a 44px control would double the row height across hundreds
   of records, so they get a usable 34px rather than the full target — the same
   trade-off already made for the per-row Download/Delete actions. */
.admin-status-pill-link { display: inline-flex; align-items: center; min-height: 34px; }

/* The technician roster row is a flex line of name + email + site pills +
   actions. On a landscape phone it ran ~8px past the viewport once the
   scrollbar appeared, so let it wrap and let each part shrink. */
@media (max-width: 900px) {
    .admin-tech-item { flex-wrap: wrap; }
    .admin-tech-item > * { min-width: 0; }
    .admin-tech-email-form { flex: 1 1 220px; }
    .admin-tech-sites-form { flex: 1 1 100%; }

    /* "Add technician" is name + email + button on one grid row. It already
       collapsed below 540px, but a landscape phone is ~667px wide — wide
       enough to keep three columns, too narrow to fit them once the button
       hits its 140px minimum. It ran 8px past the edge. */
    .admin-tech-add { grid-template-columns: 1fr; }
}

/* --- Topbar: stop the user menu sitting on the logo ----------------------
   The topbar is a 3-column grid and the side tracks are minmax(0,1fr), but the
   user-menu button itself never shrank: a flex item defaults to min-width:auto,
   so it kept its full intrinsic width and spilled out of its track to the LEFT,
   landing on top of the brand. The track was doing its job; the button wasn't.
   This is overlap, not overflow, which is why the page still measured as
   fitting. */
.topbar-actions { min-width: 0; }
.user-menu { min-width: 0; max-width: 100%; }
.user-menu-trigger { min-width: 0; max-width: 100%; }
.user-menu-name { min-width: 0; }

@media (max-width: 620px) {
    /* On a phone, drop the name and keep the avatar + caret. Nothing is lost:
       the signed-in name is on the page below, and in the menu panel itself. */
    .user-menu-name { display: none; }
    .user-menu-trigger { gap: 4px; }
    /* Give the brand the room that frees up, but not so much that it crowds
       the menu again. */
    .brand-logo { height: clamp(34px, 5vh, 52px); }
}

/* --- Home roadmap: one card of rows on a phone ---------------------------
   Four full cards stacked ran ~360px — a whole phone screen before the three
   task buttons, which are the actual point of the page. Same four steps, same
   words, ~150px, as a single card of compact rows. */
@media (max-width: 620px) {
    .steps {
        display: grid; grid-template-columns: 1fr; gap: 0;
        max-width: 460px; margin-left: auto; margin-right: auto;
        background: var(--surface-card);
        border: 1px solid var(--briya-gray-25);
        border-radius: clamp(14px, 2vmin, 24px);
        box-shadow: var(--shadow-sm);
        padding: clamp(4px, 0.8vh, 8px) 0;
    }
    .step {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        grid-template-rows: auto auto;
        align-items: center;
        column-gap: clamp(10px, 3vmin, 14px);
        background: none; border: 0; box-shadow: none; border-radius: 0;
        padding: clamp(7px, 1.2vh, 11px) clamp(12px, 4vmin, 18px);
        text-align: left; max-width: none;
    }
    /* The hidden arrows are still in the DOM between steps, so this is what
       puts a rule between consecutive rows. */
    .step-arrow + .step { border-top: 1px solid var(--briya-gray-25); }
    .step-num {
        grid-column: 1; grid-row: 1 / span 2;
        width: clamp(28px, 8vmin, 34px); height: clamp(28px, 8vmin, 34px);
        margin: 0; font-size: clamp(14px, 3.6vmin, 17px);
        box-shadow: none;
    }
    .step-title { grid-column: 2; grid-row: 1; margin-bottom: 0;
                  font-size: clamp(14px, 3.8vmin, 16px); }
    .step-meta  { grid-column: 2; grid-row: 2;
                  font-size: clamp(11px, 3.2vmin, 13px); line-height: 1.3; }
}

/* The brand is the tappable home link; shrinking the logo for phones took it
   under the touch target, so floor the link rather than the image. */
.brand { min-height: 44px; }

/* Same as .brand: the admin logo is a home link, so it needs the target. */
.admin-brand { min-height: 44px; display: inline-flex; align-items: center; }

/* --- Asset picker: device-type filter -----------------------------------
   The list is sorted by type, so with 421 Chromebooks ahead of 272 laptops
   every row above the render cap was a Chromebook — the laptops were in stock
   and completely unreachable by browsing. These jump straight to a type. */
.pick-types {
    display: flex; flex-wrap: wrap; gap: 8px;
    margin: 0 0 clamp(8px, 1.2vh, 14px);
}
.pick-type {
    display: inline-flex; align-items: center; gap: 7px;
    min-height: 44px; padding: 6px 15px;
    border: 1px solid var(--briya-gray-25);
    border-radius: 999px;
    background: var(--surface-card);
    color: var(--briya-black);
    font-family: inherit; font-size: clamp(14px, 1.8vmin, 17px); font-weight: 600;
    cursor: pointer;
}
.pick-type span {
    font-variant-numeric: tabular-nums;
    font-weight: 700; font-size: .85em;
    color: var(--briya-gray-65);
}
.pick-type.is-on {
    background: var(--briya-blue); border-color: var(--briya-blue);
    color: var(--briya-white);
}
.pick-type.is-on span { color: rgba(255, 255, 255, .82); }
.pick-empty { list-style: none; padding: 18px 4px; color: var(--briya-gray-65); }

/* --- Asset picker: pager -------------------------------------------------
   Typing and scanning are the fast paths, but browsing has to be able to
   reach everything too — the render cap alone left the rest of the stock
   findable only by guessing what to type. */
.pick-pager {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 6px;
    margin: 0 0 clamp(8px, 1.2vh, 14px);
}
.pick-pager[hidden] { display: none; }
.pick-page {
    min-width: 44px; min-height: 44px;
    padding: 0 12px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--briya-gray-25);
    border-radius: 10px;
    background: var(--surface-card);
    color: var(--briya-black);
    font-family: inherit; font-size: clamp(14px, 1.8vmin, 17px); font-weight: 600;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}
.pick-page:hover:not(:disabled), .pick-page:focus-visible {
    border-color: var(--briya-blue); background: var(--briya-blue-tint);
}
.pick-page.is-on {
    background: var(--briya-blue); border-color: var(--briya-blue);
    color: var(--briya-white);
}
.pick-page:disabled { opacity: .4; cursor: default; }
.pick-page-step { font-size: 20px; line-height: 1; padding: 0 10px; }
.pick-gap { padding: 0 2px; color: var(--briya-gray-65); }

/* --- "still owes equipment" refusal -------------------------------------- */
.owes-list { list-style: none; padding: 0; margin: 0 0 clamp(10px, 1.6vh, 18px); display: grid; gap: 8px; }
.owes-list li {
    display: grid; gap: 2px;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-left: 4px solid var(--briya-orange);
    border-radius: 10px;
    padding: clamp(10px, 1.4vh, 14px) clamp(12px, 2vmin, 18px);
    text-align: left;
}
.owes-id   { font-weight: 700; font-size: clamp(15px, 2vmin, 20px); word-break: break-all; }
.owes-desc { font-size: clamp(13px, 1.7vmin, 17px); color: var(--briya-gray-65); }
.owes-meta { font-size: clamp(11px, 1.4vmin, 14px); color: var(--briya-gray-65); }
.owes-override { margin-top: clamp(12px, 2vh, 20px); }
.owes-override a { font-size: clamp(13px, 1.6vmin, 16px); color: var(--briya-gray-65); }

/* --- "which sheet is this?" chooser -------------------------------------- */
.admin-kind-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 14px; margin-bottom: 24px;
}
.admin-kind {
    display: flex; flex-direction: column; gap: 8px;
    background: var(--surface-card);
    border: 1px solid var(--briya-gray-25);
    border-radius: 10px;
    padding: 16px 18px;
    margin: 0;
}
.admin-kind h2 { margin: 0; font-size: 16px; }
.admin-kind p { margin: 0; font-size: 14px; color: var(--briya-gray-65); }
.admin-kind .admin-kind-score { font-size: 12.5px; }
.admin-kind .primary { margin-top: auto; width: 100%; }
.admin-kind-headers { display: flex; flex-wrap: wrap; gap: 6px; }
.admin-kind-headers code {
    background: var(--surface-2, #F3F6F9);
    border: 1px solid var(--briya-gray-25);
    border-radius: 4px; padding: 2px 7px; font-size: 12.5px;
}
.scroll-x { overflow-x: auto; }

/* --- Pre-filled sheet downloads ------------------------------------------ */
.admin-download-intro { margin-bottom: 10px; }
.admin-download-row { display: flex; flex-wrap: wrap; gap: 10px; }
.admin-download-row .admin-import-template {
    display: inline-flex; align-items: center; gap: 8px; min-height: 44px;
}
.admin-download-count {
    font-variant-numeric: tabular-nums;
    background: var(--briya-blue-tint);
    color: var(--briya-blue-dark);
    border-radius: 999px;
    padding: 1px 9px;
    font-size: .85em; font-weight: 700;
}
.admin-download-blank { margin-top: 8px; font-size: 13px; }
.admin-download-blank a { margin: 0 2px; }

/* --- Picker: reserved stock, shown rather than hidden --------------------
   A device that's spoken for still appears, greyed and named. Omitting it
   sends a technician hunting for a laptop that is on the shelf with somebody
   else's name on it. */
.pick-item { grid-template-columns: minmax(0, auto) minmax(0, 1fr) minmax(0, auto) minmax(0, auto); }
.pick-site {
    font-size: clamp(11px, 1.4vmin, 15px);
    color: var(--briya-gray-65);
    white-space: nowrap;
    border: 1px solid var(--briya-gray-25);
    border-radius: 999px;
    padding: 1px 9px;
}
.pick-item.is-taken {
    background: var(--surface-2, #F3F6F9);
    border-style: dashed;
    cursor: not-allowed;
    opacity: .72;
}
.pick-item.is-taken .pick-id { color: var(--briya-gray-65); }
.pick-item.is-taken:hover { border-color: var(--briya-gray-25); background: var(--surface-2, #F3F6F9); }

/* A reserved row is not for the student in front of you, but it is not a dead
   end either: the one person it IS for is named on it, and the row offers to go
   and sign for them. Still visibly set apart — dashed, muted — so it is never
   mistaken for the device you are handing over right now. */
.pick-item.is-signable {
    grid-template-columns: minmax(0, auto) minmax(0, 1fr) minmax(0, auto) minmax(0, auto) minmax(0, auto);
    cursor: pointer;
    text-decoration: none;
    color: inherit;
    opacity: .9;
}
.pick-item.is-signable:hover,
.pick-item.is-signable:focus-visible {
    border-color: var(--briya-orange);
    background: #FFFBF3;
    opacity: 1;
}
.pick-signfor {
    white-space: nowrap;
    font-size: clamp(11px, 1.4vmin, 15px);
    font-weight: 700;
    color: #7A4A00;
    background: #FFF4E0;
    border: 1px solid var(--briya-orange);
    border-radius: 999px;
    padding: 3px 11px;
}
@media (max-width: 620px) {
    .pick-item.is-signable { grid-template-columns: minmax(0, 1fr); }
}
.pick-desc em { font-style: normal; color: var(--briya-orange); font-weight: 600; }

@media (max-width: 620px) {
    .pick-item { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}
