/* Kiosk System Style Sheet */

/* One font size for every drop-down, search box, input field, field label
   and stations-grid heading on every page. Change it here only. */
:root{
    --field-font-size:12px;
}

/* GENERAL */

html, body, input, button, select, textarea {
    font-family:Poppins, Arial, sans-serif;
}

/* ============================================================
   PAGE SHELL (Round 6)
   ------------------------------------------------------------
   Matches the admin system's shell exactly so both systems size
   their panels the same way: html/body take the viewport height,
   body is a flex column, the navbar keeps its natural height,
   and .main-content takes everything that's left - so panels
   always end flush at the bottom of the window instead of
   stopping wherever their content happens to stop. Anything that
   can outgrow its panel scrolls INSIDE the panel (.stations-scroll,
   .timeline-scroll, .reservation-scroll), never the page.
   ============================================================ */

html{
    height:100%;
}

body{
    /* margin was "3" - not a valid CSS length, so it was silently
       ignored and the default 8px applied, pushing the page ~11px
       past the window and adding a stray scrollbar.
       Sept 09 review: it then came back as margin:5px, which has the
       same problem in smaller form - a margin sits OUTSIDE
       box-sizing:border-box, so height:100% plus a margin is taller
       than the window, and body's overflow:hidden clips that strip
       instead of scrolling it. The inset comes from padding alone now,
       which border-box does account for. */
    margin:0;
    padding:5px;

    height:100%;
    box-sizing:border-box;

    display:flex;
    flex-direction:column;
    overflow:hidden;

    background-image: url("/static/tupclc_background.png");
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    background-attachment: fixed;
}

/* The login screen centres a single card and has no navbar/panel
   layout, so it opts out of the flex shell. */
body.login-body{
    display:block;
    overflow:auto;
}

.navbar{
    flex:0 0 auto;
}

/* ================= LOGIN PAGE ================= */

.login-body{
    background:#d9d9d9;
}

.login-container{
    width:400px;
    margin:100px auto;
    padding:30px;
    background:#e5e5e5;
    border:2px solid black;
    border-radius:20px;
}

.login-container h3{
    color:#c81d3a;
    margin:0;
}

.login-container h1{
    color:#c81d3a;
    margin-top:5px;
    margin-bottom:30px;
}

.login-container label{
    font-weight:bold;
}

.login-container input{
    width:100%;
    padding:12px;

    margin-top:10px;
    margin-bottom:20px;

    border:1px solid gray;
    border-radius:20px;

    box-sizing:border-box;
}

.login-btn{
    width:100%;
    padding:12px;

    background:#c81d3a;
    color:white;

    border:none;
    border-radius:20px;

    cursor:pointer;

    font-weight:bold;
}

/* FORGOT PASSWORD BUTTON */

.forgot-btn{
    width:100%;

    padding:12px;

    margin-top:10px;

    background:#444;
    color:white;

    border:none;
    border-radius:20px;

    cursor:pointer;

    font-weight:bold;
}

.forgot-btn:hover{
    background:#333;
}

/* PASSWORD BOX */

.password-box{
    position:relative;
}

.password-box input{
    width:100%;
    padding:5px;
    padding-right:45px;

    margin-top:10px;
    margin-bottom:20px;

    border:1px solid gray;
    border-radius:20px;

    box-sizing:border-box;
}

.eye{
    position:absolute;

    right:15px;
    top:50%;

    transform:translateY(-50%);

    cursor:pointer;

    font-size:16px;

    color:#555;
}

/* ================= DASHBOARD ================= */


.navbar{
    padding:20px;
    margin-bottom:-28px;
    display:flex;
    justify-content:space-between;
    align-items:center;
}

.navbar h2{
    color:#c81d3a;
    font-size:23px;
    margin-top:0px;
    margin-bottom:-20px;
}

.menu a{
    text-decoration:none;
    margin-left:20px;
    color:black;
    font-weight:bold;
}

.menu a:hover{
    color:#c81d3a;
}

.navbar-content h4,
.navbar-content h2 {
    margin: -9px -10px 0 0;
    margin-left: -7px;
}

.navbar-content h4 {
    margin-bottom: 0.2px;
}

h4 {
    font-size: 13px;
    font-weight: normal;
}

.navbar-content {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.navbar-logo img {
    width: 50px;
    height: 50px;
    margin-top: -7px;
    object-fit: contain;
}

.main-content{
    display:flex;
    gap:20px;
    padding:20px;

    align-items:stretch; /* left panel now matches the right panel's height */

    /* Round 6: fills whatever the navbar leaves, so both panels end
       flush at the bottom of the window. min-height/min-width:0 let
       them shrink far enough for their inner scroll areas to engage
       instead of overflowing the page. */
    flex:1 1 auto;
    min-height:0;
    min-width:0;
    box-sizing:border-box;
}

/* LEFT PANEL - AVAILABILITY STATUS */

.left-panel{
    flex:1 1 auto; /* grows/shrinks with the right panel and the window, so both panels end flush at the bottom of the window */

    /* Round 6: part of the shared height chain (see PAGE SHELL). */
    display:flex;
    min-height:0;
    min-width:0;
}

.status-card{
    background:#e5e5e5;

    border:2px solid black;
    border-radius:20px;

    padding:18px;

    overflow:hidden;

    /* Round 6: fills its panel in both directions. The height used to
       be written in by setAvailabilityPanelHeight() in dashboard.html
       (now deleted); flex:1 1 auto is what keeps the card full width
       even when its contents are small - the same fix Round 5 applied
       to the More Information page's card. */
    flex:1 1 auto;
    height:100%;
    min-height:0;
    min-width:0;
    box-sizing:border-box;
    display:flex;
    flex-direction:column;
}

.status-card h1{
    color:#c81d3a;
    margin-top:-10px;
    margin-bottom:0px;
    font-size:27px;
}

/* LEFT PANEL - TOP STATUS */

.top-status{
    display:flex;
    flex-wrap:wrap; /* .status-right takes a full line of its own, below the Location dropdown */
    justify-content:space-between;
    align-items:flex-start;
    margin-bottom:10px;

    flex:0 0 auto; /* stays fixed height - only .stations-scroll grows/scrolls */
}

.status-left{
    flex:1 1 100%; /* full first line; the status pills sit on the line below */
    align-self:flex-start ;
    min-width:0; /* lets the Location dropdown shrink to this column instead of overflowing it */
    box-sizing:border-box;
    padding-right:6px; /* same right gutter as .status-right, so the Location dropdown and the pills end at exactly the same edge */
}

.date-time{
    margin:-7px 0 10px 0;
    font-size:15px;
    font-weight:semibold;
}

.location-label{
    display:block;
    margin-top:-5px;
    margin-bottom:5px;
    font-size:13px;
}

.location-select{
    height:30px;
    display:block;
    width:100%; /* fills .status-left exactly (was a fixed 570px + 20px margin that spilled past it and under the counts) */
    max-width:100%;
    padding:5px 10px;
    border:1px solid #ccc;
    border-radius:999px;
    margin-top:-5px;
    margin-right:0;
    background:white;
    font:100% Poppins, Arial, sans-serif;
    font-size:13px;
    line-height:30px;
    box-sizing:border-box;
}

/* Bug fix (Flowchart K1): Location used to be an open .location-select
   dropdown here - now it's a locked, read-only display plus a small
   password-gated Settings button (see #kiosk-settings-overlay). */
.location-display-row{
    display:flex;
    align-items:center;
    gap:8px;
    margin-top:-5px;
}

.location-display{
    font-size:13px;
    font-weight:bold;
    color:#000000;
}

.kiosk-settings-btn{
    width:24px;
    height:24px;
    line-height:20px;
    padding:0;
    border:2px solid #000000;
    border-radius:50%;
    background:white;
    font-size:13px;
    text-align:center;
    cursor:pointer;
}

.kiosk-settings-btn:hover{
    background:#f2f2f2;
}

.kiosk-settings-note{
    font-size:12.5px;
    color:#555;
    margin-top:0;
}

.kiosk-settings-error{
    color:#c81d3a;
    font-size:12.5px;
    font-weight:bold;
    margin:6px 0 0 0;
}

.kiosk-settings-box{
    max-width:420px;
}

/* ============================================================
   LEARNING STATION MAP POP-UP
   ------------------------------------------------------------
   Reuses .modal-overlay / .modal-box / .modal-header for the
   backdrop and card shape; only the image sizing is new.
   ============================================================ */

/* The box shrink-wraps the picture and is capped to the visible screen
   (dvh = real height on phones, excluding the browser toolbar), so the whole
   modal always fits the window and the body never needs a scrollbar.

   Fixed chrome around the image (keep in sync with .modal-box / .modal-header):
     border 2+2 + padding 22+22 = 48px wide
     border 4 + padding 44 + header ~46 + image top margin 12 = ~106px tall
   The extra ~54px of height leaves a small gutter above/below the modal. */
.modal-box.station-map-box{
    width:fit-content;
    max-width:96vw;
    max-height:96vh;
    max-height:96dvh;
    display:flex;
    flex-direction:column;
    overflow:hidden;
}

.station-map-box .modal-scroll-content{
    display:flex;
    align-items:center;
    justify-content:center;
    min-height:0;
    overflow:hidden; /* image is sized to fit, nothing to scroll */
}

.station-map-image{
    display:block;
    width:auto;
    height:auto;
    margin:12px auto 0;
    max-width:calc(96vw - 48px);
    max-height:calc(100vh - 160px);
    max-height:calc(100dvh - 160px);
    object-fit:contain;
    border-radius:12px;
}

.status-right{
    font-size:13px;
    line-height:normal;

    /* Colour-coded pills, always on their own line BELOW the Location
       dropdown. Four equal columns that together fill the full width,
       so the row lines up with the station/seat tiles underneath. */
    flex:0 0 100%;
    width:100%;
    box-sizing:border-box;
    margin:10px 0 0;
    padding-right:6px; /* same gutter .stations-scroll keeps for its scrollbar, so the right edges line up */
    display:grid;
    grid-template-columns:repeat(4,minmax(0,1fr));
    gap:6px;
}

/* 2 x 2 grid (still filling the full width) - switched on by
   StationsView.renderStatusSummary() only when a label would not fit
   inside its pill in the 4-across row (see fitStatusPills in
   stations-view.js). */
.status-right.is-2x2{
    grid-template-columns:repeat(2,minmax(0,1fr));
}

.status-right p{
    margin:0;
    padding:4px 10px;
    border:1.5px solid #000;
    border-radius:999px;
    font-size:11px;
    font-weight:700;
    text-align:center;
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
    background:#fff;
    background-origin:border-box;
}

.status-right p:nth-child(1){ background:linear-gradient(135deg, #004f3b, #2e7251); border-color:transparent; color:#fff; }  /* Vacant */
.status-right p:nth-child(2){ background:linear-gradient(135deg, #800000, #ad253b); border-color:transparent; color:#fff; }  /* Occupied */
.status-right p:nth-child(3){ background:linear-gradient(135deg, #393939, #4b4b4b); border-color:transparent; color:#fff; }  /* Closed */
.status-right p:nth-child(4){ background:linear-gradient(135deg, #241a7d, #372aac); border-color:transparent; color:#fff; }  /* Total */

/* LEFT PANEL - STATIONS GRID */

/* Scrollable region between .top-status and .buttons: takes up
   whatever vertical space is left in the (now height-bound)
   .status-card, and scrolls internally once the station cards don't
   fit, instead of growing the card past the panel's height. Mirrors
   .modal-scroll-content's scrollbar treatment for a consistent look. */
.stations-scroll{
    flex:1 1 auto;
    min-height:0; /* required so a flex child can actually shrink and scroll instead of overflowing */
    overflow-y:auto;

    padding-right:6px; /* keeps the scrollbar from overlapping the last column of cards */

    container-type:inline-size; /* the .stations column count below follows THIS width (the card), not the window - the card is narrow on a side-by-side desktop layout too */

    scrollbar-width:thin;
    scrollbar-color:#bbb transparent;
}

.stations-scroll::-webkit-scrollbar{
    width:8px;
}

.stations-scroll::-webkit-scrollbar-track{
    background:transparent;
}

.stations-scroll::-webkit-scrollbar-thumb{
    background:#bbb;
    border-radius:20px;
}

.stations-scroll::-webkit-scrollbar-thumb:hover{
    background:#999;
}

.stations{
    display:grid;

    /* The column count lives in --station-cols so .station-section can use the
       very same number (see below). minmax(0,..) para hindi palawakin ng oras sa
       tile ang column. */
    --station-cols:5;
    grid-template-columns:repeat(var(--station-cols),minmax(0,1fr));

    gap:10px;

    padding-bottom:20px; /* breathing room at the end of the scroll, so the last row of tiles isn't flush against the buttons / card edge */
}

/* Fewer, bigger columns as the card gets narrower, so every tile (name,
   status, time, minutes remaining) stays readable on a phone:
   wide = 5 columns -> medium = 4 columns -> narrow / mobile = 2 columns. */
@container (max-width:620px){
    .stations{
        --station-cols:4;
        gap:8px;
    }
    .station{
        min-height:90px; /* was 120px */
    }
}

@container (max-width:440px){
    .stations{
        --station-cols:2; /* mobile: 2 columns (was 3) */
        gap:6px;
    }
    .station{
        min-height:48px; /* was 64px, originally 100px */
        padding:3px 6px;
        font-size:13px;
        border-radius:8px;
    }
    .station-label{
        font-size:12px;
        margin:0 0 1px;
    }
    .station .station-time,
    .station .station-remaining{
        margin-top:0;
        font-size:0.62rem;
        line-height:1.1;
    }
}

/* Tracking page only (body.tracking-page): once the card is 900px wide or
   more, a 6th column (the maximum), so the tiles don't stretch huge. Everything narrower keeps the
   5 -> 4 -> 3 steps above. */
@container (min-width:900px){
    .tracking-page .stations{
        --station-cols:6;
    }
}

/* FALLBACK - old Android WebView (Chrome < 105) has no container queries, so
   the @container rules above never apply and the grid would stay at 5 columns.
   There, follow the viewport instead and keep the grid at 4 columns. Browsers
   that DO support container queries skip this block entirely. */
@supports not (container-type:inline-size){
    .stations{
        --station-cols:4;
        gap:6px;
    }
    .station{
        min-height:70px;
        padding:4px 6px;
        font-size:13px;
        border-radius:8px;
    }
    .station-label{
        font-size:12px;
        margin:0 0 1px;
    }
    .station .station-time,
    .station .station-remaining{
        margin-top:0;
        font-size:0.62rem;
        line-height:1.1;
    }
}

/* Pamagat ng grupo sa station grid ("Individual Stations" / "Group Tables").
   Sumasaklaw sa buong hanay ng grid. */
/* One section per group (Individual Stations / each table), built by
   StationsView.renderStationTiles(). It spans the whole .stations grid and
   uses the same column count (--station-cols, inherited from .stations), so
   the tiles line up exactly as before. This used to be
   "grid-template-columns:subgrid", but subgrid needs Chrome/WebView 117+;
   older Android WebViews dropped the rule and showed one column. */
.station-section{
    grid-column:1 / -1;
    display:grid;
    grid-template-columns:repeat(var(--station-cols,5),minmax(0,1fr));
    gap:inherit;
    align-content:start;
}

.station-section:not(:first-child){
    margin-top:12px;
}

/* The heading stays pinned at the top of the scrolling stations area for as
   long as its own section is on screen; at the end of the section the next
   section's heading takes over. Solid background so tiles never show through. */
.station-group-heading{
    grid-column:1 / -1;
    position:sticky;
    top:0;
    z-index:5;
    /* Solid grey "mask" around the rounded box: the 4px ring fills the corner
       notches and the strip below covers the full 10px grid gap, so nothing
       scrolling underneath shows through the heading. */
    box-shadow:0 0 0 4px #e5e5e5, 0 10px 0 0 #e5e5e5;
    margin:0;
    box-sizing:border-box;
    padding:6px 14px;

    /* Light-red label box. Kept full width (not shrink-to-fit) so the sticky
       heading still hides the tiles scrolling underneath it. */
    background:#fdecee;
    border:1px solid #c81d3a;
    border-radius:8px;

    font-size:13px;
    line-height:1.2;
    font-weight:bold;
    text-transform:uppercase;
    letter-spacing:2px;
    color:#c81d3a;
}

/* Icon before the heading text: monitor for "Individual Stations", group of
   people for tables (a table heading is the one that has the seats info). The
   icon is a mask painted in the text colour, so it scales with font-size. */
.station-group-heading::before{
    content:"";
    display:inline-block;
    width:1.15em;
    height:1.15em;
    margin-right:10px;
    vertical-align:-0.2em;
    background-color:currentColor;
    -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='3' width='20' height='14' rx='2'/%3E%3Cpath d='M8 21h8M12 17v4'/%3E%3C/svg%3E") center/contain no-repeat;
    mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='3' width='20' height='14' rx='2'/%3E%3Cpath d='M8 21h8M12 17v4'/%3E%3C/svg%3E") center/contain no-repeat;
}

.station-group-heading.is-table::before{
    -webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='9' cy='7' r='4'/%3E%3Cpath d='M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75'/%3E%3C/svg%3E");
    mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='9' cy='7' r='4'/%3E%3Cpath d='M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75'/%3E%3C/svg%3E");
}

/* "2 of 4 seats occupied" sa tabi ng pangalan ng table */
.station-group-info{
    margin-left:10px;
    font-size:12px;
    font-weight:normal;
    text-transform:none;
    letter-spacing:normal;
    color:#555;
}

.station{
    min-height:110px; /* was 155px */
    padding:8px 10px;

    border-radius:10px;

    color:white;
    font-weight:bold;

    display:flex;
    flex-direction:column;
    justify-content:center;
    align-items:center;
}

.password-box{
    position:relative;
}

.password-box h4{
    transform:translateY(-50%); 
    font-size:16px;
    margin-top:10px;
    font-weight:medium;
    color:#000000;
}

.vacant{
    background:linear-gradient(135deg, #004f3b, #2e7251);
}

.occupied{
    background:linear-gradient(135deg, #800000, #ad253b);
}


.closed{
    background:linear-gradient(135deg, #393939, #4b4b4b);
}

/* BUTTONS */


.buttons{
    margin-top:10px;
    margin-bottom:-5px;

    display:flex;
    justify-content:flex-end;

    gap:5px;

    flex:0 0 auto; /* stays pinned at the bottom of .status-card, below the scrollable grid */
}

.clear-btn{
    border: none;
    height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 5px;
    cursor: pointer;
    background: transparent;
    font-weight: bold   ;
}

.gray-btn{
    border: none;
    height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 18px;
    border-radius: 20px;
    cursor: pointer;
    color: white;
    font-weight: normal;
}

.red-btn{
    border: none;
    height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 18px;
    border-radius: 20px;
    cursor: pointer;
    color: white;
    font-weight: bold;
}

.gray-btn{
    background:#444;
}

.red-btn{
    background:#c81d3a;
}

/* SCHEDULE APPOINTMENT MODAL */

.modal-box h1{
    color:#c81d3a;
    margin-top:-10px;
    margin-bottom:-10px;
    font-size:27px;
}
.password-box-personal,
.password-box-appointment {
    position:relative;
}

.password-box-personal h4,
.password-box-appointment h4 { 
    transform:translateY(-50%); 
    font-size:16px;
    font-weight:bold;
    margin-top:12px;
    margin-bottom:-15px;
    font-weight:medium;
    color:#000000;
}

.password-box-appointment h5 {
    font-size:11.5px;
    font-weight:normal;
    margin-top:2px;
    margin-bottom:0px;
    color:#000000;
}

.form-input{
    width:100%;
    padding:0px 7px 0px 10px;
    height:30px;

    margin-top:0px;
    margin-bottom:5px;

    border:2px solid #000000;
    border-radius:20px;

    box-sizing:border-box;
    font-size: 13px;
}

.form-dropdown{
    width:100%;
    padding:0px 6px 0px 7px;
    height:30px;

    margin-top:0px;
    margin-bottom:5px;

    border:2px solid #000000;
    border-radius:20px;

    box-sizing:border-box;
    font-size: 13px;
}

.appointment-label{
    font-size:13px;
    margin-top:-20px;
    margin-bottom:-10px;
    color:#000000;
}

/* =========================================================
   RIGHT PANEL (merged from right-panel.css)
   ========================================================= */

/* RIGHT PANEL */

.right-panel{
    flex:0 0 460px; /* fixed size - won't grow/shrink with the availability panel or zoom level */
    width:460px;
    max-width:460px;
    display:flex;
    flex-direction:column;
    gap:10px; /* tighter spacing between the stacked cards (was 20px) */
    box-sizing:border-box;

    /* Round 6: lets the tab panel below shrink so the reservation form
       scrolls inside the panel, instead of the panel growing past the
       bottom of the window. */
    min-height:0;
}

.card{
    background:#e5e5e5;
    border:2px solid black;
    border-radius:20px;
    padding:20px;
    overflow:hidden;
}

.card h2{
    color:#c81d3a;
    margin-top:-10px;
    margin-bottom:-5px;
    font-size:27px;
}

/* QR Code Verification card - ang compact na itsura nito ay nasa KIOSK
   PANEL RESTRUCTURE section sa ibaba. */
.qr-verify-card{
    display:flex;
    flex-direction:column;
    min-height:0;
}

.qrstatus{
    color:#888;
    font-size:45px;
    font-weight:bold;
    text-align:center;
    margin:-5px 0px -14px 0px;
}

.qrstatus-verified{
    color:#2e8b57;
}

.qrstatus-invalid{
    color:#c81d3a;
}

.qrstatus-expired{
    color:#c79a3b;
}

.qrstatus-signedout{
    color:#3b6ec7;
}

.qr-scan-input{
    width:100%;
    padding:7px 14px;

    margin-top:20px;
    margin-bottom:-5px;

    border:2px solid #000000;
    border-radius:20px;

    box-sizing:border-box;
    font-size:12px;
    text-align:center;
}

/* Shown instead of .qr-scan-input when Kiosk Settings -> QR Scan
   Method is "Device Camera" (see applyQrScanMode()/startCameraQrScan()). */
.qr-camera-view{
    margin-top:20px;
}

.qr-camera-video{
    width:100%;
    max-width:100%;
    aspect-ratio:4/3;
    object-fit:cover;
    border:2px solid #000000;
    border-radius:20px;
    background:#000;
}

.qr-camera-error{
    margin:10px 0 0;
    font-size:12px;
    color:#c81d3a;
    text-align:center;
}

/* ================= MANAGE STATIONS ================= */

.manage-container{
    margin:20px;

    padding:20px;

    background:#e5e5e5;

    border:2px solid black;
    border-radius:20px;
}

.manage-header{
    display:flex;

    justify-content:space-between;
    align-items:center;

    margin-bottom:20px;
}

.manage-header h1{
    color:#c81d3a;

    margin:0;

    font-size:35px;
}

.manage-controls{
    display:flex;

    align-items:center;

    gap:10px;
}

.station-table{
    width:100%;

    border-collapse:collapse;
}

.station-table th{
    text-align:left;

    padding:10px;

    border-bottom:2px solid #bbb;

    font-size:16px;
}

.station-table td{
    padding:10px;

    border-bottom:1px solid #ccc;

    font-size:16px;
}

.vacant-text{
    color:#2e8b57;
    font-weight:bold;
}

.occupied-text{
    color:#c81d3a;
    font-weight:bold;
}


.open-text{
    color:#2e8b57;
}

.table-buttons{
    text-align:right;
}

.table-btn{
    padding:6px 14px;

    min-width:auto;

    font-size:12px;

    margin-left:5px;
}

.small-btn{
    padding:8px 15px;

    min-width:auto;

    font-size:12px;
}

.add-button-container{
    display:flex;

    justify-content:flex-end;

    margin-top:15px;
}

.add-btn{
    padding:8px 18px;

    min-width:auto;

    font-size:12px;
}

.active{
    color:#c81d3a !important;
}

/* TAB LINKS */

.tab-link{
    flex:1;

    text-decoration:none;
}

/* Note: confirmation messages now use the browser's built-in
   alert()/confirm() dialogs (see dashboard.html script), so no
   custom banner/pop-up styling is needed here. The classes below
   are kept only in case other UI reuses these status colors. */

.confirmation-success{
    background:#d9f2e3;
    color:#1e7e34;
    border:2px solid #2e8b57;
}

.confirmation-error{
    background:#fbdde2;
    color:#a71d2a;
    border:2px solid #c81d3a;
}

.confirmation-pending{
    background:#fbf1d3;
    color:#8a6d1d;
    border:2px solid #c79a3b;
}

/* =========================================================
   TIMELINE AVAILABILITY VIEW (Learning Stations Availability
   Status page). Added below without changing any rule above.
   ========================================================= */

/* Pill-style date input to match the mockup */
.date-pill{
    height:34px;
    padding:0 14px;
    border:2px solid #000000;
    border-radius:20px;
    background:white;
    font:600 13px Poppins, Arial, sans-serif;
    box-sizing:border-box;
}

/* Pill-style location dropdown (kiosk header) */
.location-pill{
    height:34px;
    padding:0 14px;
    min-width:320px;
    border:2px solid #000000;
    border-radius:20px;
    background:white;
    font:13px Poppins, Arial, sans-serif;
    box-sizing:border-box;
}

/* Pill-style primary action button */
.pill-btn{
    height:34px;
    padding:0 18px;
    border:2px solid #000000;
    border-radius:20px;
    background:white;
    color:#000;
    font:600 13px Poppins, Arial, sans-serif;
    cursor:pointer;
}

.pill-btn:hover{
    background:#f0f0f0;
}

/* Quick counts row above the timeline */
.status-summary{
    display:flex;
    gap:20px;
    margin:10px 2px 6px;
    font-size:13px;
    font-weight:bold;
    color:#333;
}

/* Weekend / after-hours notice */
.closed-notice{
    padding:14px 16px;
    margin:10px 0;
    background:#444;
    color:white;
    border-radius:12px;
    font-weight:bold;
    text-align:center;
}

/* Variant shown INSIDE .timeline-scroll (in place of the grid) so the
   prev/next day arrows keep flanking a full-size timeline box even on
   a day the Learning Commons is closed. Toggled via display:flex/none
   in JS, not display:block, so it can center its text. */
.closed-notice.timeline-message{
    height:100%;
    min-height:220px;
    margin:0;
    border-radius:0; /* the rounded corners already come from .timeline-scroll */
    align-items:center;
    justify-content:center;
    box-sizing:border-box;
}

/* Outer row: left arrow | scrollable grid | right arrow */
.timeline-outer{
    display:flex;
    align-items:stretch;
    gap:6px;
    margin-top:6px;

    flex:1 1 auto;   /* grow/shrink to fill whatever space is left in .status-card */
    min-height:0;    /* required so this flex child can actually shrink instead of overflowing the card */
    min-width:0;     /* same, sideways - lets the row shrink instead of forcing the card wide */
}

.scroll-btn{
    flex:0 0 auto;
    width:32px;
    border:none;
    background:transparent;
    color:#444;
    font-size:26px;
    font-weight:bold;
    cursor:pointer;
    align-self:center;
}

.scroll-btn:hover{
    color:#c81d3a;
}

/* Scrollable container that holds the CSS grid timeline.
   This is the ONLY element that scrolls - the page itself never does.
   Both axes scroll here: drag right for more stations, drag down for
   more of the day, independent of how big the browser window is. */
.timeline-scroll{
    flex:1 1 auto;
    min-height:0; /* required so this flex child can actually shrink and scroll instead of overflowing */
    min-width:0;  /* same, sideways - the grid inside can be wider than this box without stretching it */
    overflow-x:auto;
    overflow-y:auto;
    border-radius:12px;
    background:#f7f7f7;
    border:1px solid #d0d0d0;

    scrollbar-width:thin;
    scrollbar-color:#bbb #f0f0f0;
}

.timeline-scroll::-webkit-scrollbar{
    width:10px;
    height:10px;
}

.timeline-scroll::-webkit-scrollbar-track{
    background:#f0f0f0;
}

.timeline-scroll::-webkit-scrollbar-thumb{
    background:#bbb;
    border-radius:20px;
}

.timeline-scroll::-webkit-scrollbar-thumb:hover{
    background:#999;
}

.timeline-scroll::-webkit-scrollbar-corner{
    background:#f0f0f0;
}

/* The grid itself: column 1 = time labels, columns 2..N = stations */
.timeline-grid{
    position:relative;
    display:grid;
    min-width:max-content;
}

.tl-corner{
    position:sticky;
    left:0;
    z-index:3;
    background:#f7f7f7;
}

/* Station name header cells */
.tl-station-header{
    position:sticky;
    top:0;
    z-index:2;
    display:flex;
    align-items:center;
    justify-content:center;
    font-weight:bold;
    font-size:13px;
    color:#222;
    background:#f7f7f7;
    border-bottom:2px solid #ccc;
    padding:4px;
    box-sizing:border-box;
}

/* Time-of-day labels along the left edge */
.tl-time-label{
    position:sticky;
    left:0;
    z-index:1;
    background:#f7f7f7;
    font-size:12px;
    font-weight:600;
    color:#333;
    transform:translateY(-50%);
    padding-left:6px;
    box-sizing:border-box;
    white-space:nowrap;
}

/* Full-width horizontal hour line, sits behind the appointment blocks */
.tl-gridline{
    border-top:1px solid #d5d5d5;
    height:0;
    align-self:start;
}

/* Appointment block (reserved / occupied) */
.tl-block{
    margin:2px 4px;
    border-radius:8px;
    color:white;
    font-weight:bold;
    display:flex;
    flex-direction:column;
    align-items:center;
    justify-content:center;
    text-align:center;
    padding:6px 4px;
    box-sizing:border-box;
    overflow:hidden;
    z-index:1;
}


.tl-block.occupied{
    background:#c81d3a;
}

.tl-block.vacant{
    background:#2e8b57;
}

.tl-block.closed{
    background:#444;
}

.tl-block-status{
    font-size:12px;
    line-height:1.2;
}

.tl-block-time{
    font-size:10px;
    font-weight:normal;
    margin-top:2px;
    line-height:1.2;
}

/* =========================================================
   RESERVE AN APPOINTMENT BUTTON + SCHEDULING MODAL
   Added below without changing any rule above. The scheduling
   form now opens in a pop-up overlay instead of living directly
   in the right panel.
   ========================================================= */

.reserve-btn-container{
    display:flex;
    justify-content:center;
}

.reserve-btn{
    width:100%;
    padding:14px;
    font-size:15px;
    border-radius:20px;
    margin-bottom:0px;
}

/* Full-screen dimmed backdrop, hidden until .active is toggled on */
.modal-overlay{
    display:none;

    position:fixed;
    top:0;
    left:0;
    right:0;
    bottom:0;

    background:rgba(0,0,0,0.5);

    align-items:center;
    justify-content:center;

    z-index:1000;
}

.modal-overlay.active{
    display:flex;

    /* Entrance animation: backdrop fades in, box fades/scales in. */
    animation:overlay-fade-in 0.2s ease-out;
}

/* Exit animation. JS adds this class instead of immediately removing
   ".active", then removes both once the animation finishes - see
   closeModalOverlay() above. */
.modal-overlay.closing{
    display:flex;
    animation:overlay-fade-out 0.18s ease-in forwards;
}

@keyframes overlay-fade-in{
    from{ background:rgba(0,0,0,0); }
    to{ background:rgba(0,0,0,0.5); }
}

@keyframes overlay-fade-out{
    from{ background:rgba(0,0,0,0.5); }
    to{ background:rgba(0,0,0,0); }
}

/* Modal box motion (same as the admin system): entrance = zoom OUT (starts a
   little larger and settles to normal size), exit = zoom IN (grows slightly
   while fading). Both scale from the exact centre and use a fast-start /
   slow-end curve (cubic-bezier(0.22,1,0.36,1)), so there is no bounce. */
.modal-overlay.active .modal-box,
.modal-overlay.active .processing-box{
    transform-origin:center center;
    animation:overlay-zoom-out-in 0.3s cubic-bezier(0.22,1,0.36,1);
}

.modal-overlay.closing .modal-box,
.modal-overlay.closing .processing-box{
    transform-origin:center center;
    animation:overlay-zoom-in-out 0.24s cubic-bezier(0.22,1,0.36,1) forwards;
}

@keyframes overlay-zoom-out-in{
    from{
        opacity:0;
        transform:scale(1.06);
    }
    to{
        opacity:1;
        transform:scale(1);
    }
}

@keyframes overlay-zoom-in-out{
    from{
        opacity:1;
        transform:scale(1);
    }
    to{
        opacity:0;
        transform:scale(1.06);
    }
}

/* The scheduling form card itself, centered inside the overlay */
.modal-box{
    position:relative;

    width:420px;
    max-width:90vw;
    max-height:85vh;

    overflow-y:auto;

    background:#e5e5e5;
    border:2px solid black;
    border-radius:20px;

    padding:22px 22px;

    scrollbar-width:thin;
    scrollbar-color:#bbb transparent;
}

@keyframes modal-pop-in{
    from{
        opacity:0;
        transform:translateY(-10px) scale(0.98);
    }
    to{
        opacity:1;
        transform:translateY(0) scale(1);
    }
}

@media (prefers-reduced-motion: reduce){
    .modal-overlay.closing .modal-box,
    .modal-overlay.closing .processing-box{ animation:none; }
}

.modal-header{
    display:flex;
    justify-content:space-between;
    align-items:flex-start;
    flex:0 0 auto;

    padding:0 0 2px 0;
}

/* Scrollable region below the header. .modal-box now scrolls itself,
   so this just keeps the content's own spacing consistent. */
.modal-scroll-content{
    flex:1 1 auto;

    padding:0;

    scrollbar-width:thin;
    scrollbar-color:#bbb transparent;
}

.modal-scroll-content::-webkit-scrollbar{
    width:8px;
}

.modal-scroll-content::-webkit-scrollbar-track{
    background:transparent;
}

.modal-scroll-content::-webkit-scrollbar-thumb{
    background:#bbb;
    border-radius:20px;
}

.modal-scroll-content::-webkit-scrollbar-thumb:hover{
    background:#999;
}

/* Close (x) button, upper right of every overlay/modal box. */
.modal-close-btn{
    position:absolute;
    top:12px;
    right:12px;

    width:28px;
    height:28px;

    display:flex;
    align-items:center;
    justify-content:center;

    background:transparent;
    border:none;
    border-radius:50%;

    color:#444;
    font-size:18px;
    font-weight:bold;
    line-height:1;

    cursor:pointer;

    transition:background 0.2s ease, color 0.2s ease;
}

.modal-close-btn:hover{
    background:rgba(0,0,0,0.08);
    color:#c81d3a;
}

.modal-close-btn:focus-visible{
    outline:2px solid #c81d3a;
    outline-offset:2px;
}

/* SCHEDULE APPOINTMENT MODAL — RESERVATION TYPE TABS */

.reservation-tabs{
    display:flex;
    gap:10px;

    margin-top:2px;
    margin-bottom:8px;
}

.reservation-tab-btn{
    flex:1;

    display:flex;
    align-items:center;
    justify-content:center;

    border:2px solid #000000;
    background:#ffffff;
    border-radius:20px;

    padding:5px 6px;

    font-size:12.5px;
    font-weight:bold;
    text-align:center;
    color:#000000;
    white-space:nowrap; /* keep "Individual Reservation" / "Group Reservation" on one line */

    cursor:pointer;

    transition:background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}

.reservation-tab-btn:hover{
    background:#f2f2f2;
}

.reservation-tab-btn.active{
    background:#c81d3a;
    border-color:#000000;
    color:#ffffff !important;
}

.reservation-tab-btn.active:hover{
    background:#a8172f;
}

.reservation-tab-btn:active{
    transform:scale(0.98);
}

.reservation-tab-panel{
    display:none !important;
}

.reservation-tab-panel.active{
    display:block !important;
}

/* The Reservation tab's embedded form card - was a centered pop-up
   (.modal-box) up to 640px wide; now lives inline in the 400px-wide
   right panel, capped in height so it never grows past the window. */
.reservation-embed-card{
    display:flex;
    flex-direction:column;
    padding:15px 18px 18px;

    /* Round 6: was max-height:calc(100vh - 220px) - a guess at "the
       window minus the navbar and tabs" that was too generous on a
       short window, so the bottom of the form (Date, Station No.,
       Start/End Time, Clear Data / Done) ended up below the visible
       area with the page unable to scroll to it. It now simply fills
       the tab panel and lets .reservation-scroll-content scroll. */
    flex:1 1 auto;
    min-height:0;
}

.reservation-scroll-content{
    flex:1 1 auto;
    min-height:0;
    overflow-y:auto;

    padding-right:6px;

    scrollbar-width:thin;
    scrollbar-color:#bbb transparent;
}

.reservation-scroll-content::-webkit-scrollbar{
    width:8px;
}

.reservation-scroll-content::-webkit-scrollbar-track{
    background:transparent;
}

.reservation-scroll-content::-webkit-scrollbar-thumb{
    background:#bbb;
    border-radius:20px;
}

.reservation-scroll-content::-webkit-scrollbar-thumb:hover{
    background:#999;
}

/* Read-only Location field on both reservation forms (Flowchart K1 -
   Location now always matches the kiosk's locked setting). */
.locked-field{
    background:#e0e0e0;
    color:#555;
    cursor:not-allowed;
}

/* GROUP RESERVATION — STATION CHECKBOX LIST */

.group-station-checklist{
    display:grid;
    /* 3 columns, not 5 - this now lives in the 400px-wide right panel
       (embedded in the Reservation tab) instead of a 640px-wide
       pop-up, where 5 columns had more room to breathe. */
    grid-template-columns:repeat(3, 1fr);
    gap:8px;

    margin-top:5px;
    margin-bottom:6px;
    padding:10px;

    border:2px solid #000000;
    border-radius:14px;

    box-sizing:border-box;
    min-height:44px;
}

.group-station-hint{
    margin:0px 0 4px;
    font-size:12.5px;
    color:#555;
}

.group-station-checkbox{
    display:flex;
    flex-direction:column;
    align-items:center;
    justify-content:center;
    gap:4px;

    padding:10px 4px;

    border:1.5px solid #2e8b57;
    border-radius:12px;

    font-size:11.5px;
    font-weight:bold;
    text-align:center;
    color:#000000;
    background:#eefaf3;

    cursor:pointer;
    user-select:none;

    box-sizing:border-box;
    transition:background 0.15s ease, border-color 0.15s ease;
}

.group-station-checkbox:hover:not(.is-disabled){
    background:#dcf3e6;
}

.group-station-checkbox input[type="checkbox"]{
    accent-color:#c81d3a;
    cursor:pointer;
    margin:0;
    width:16px;
    height:16px;
}

.group-station-checkbox.is-disabled{
    border-color:#c81d3a;
    color:#a33;
    background:#fbeaea;
    cursor:not-allowed;
    opacity:0.75;
}

.group-station-checkbox.is-locked{
    border-color:#bbb;
    color:#999;
    background:#f2f2f2;
    cursor:not-allowed;
    opacity:0.6;
}

.group-station-checkbox.is-disabled input[type="checkbox"],
.group-station-checkbox.is-locked input[type="checkbox"]{
    cursor:not-allowed;
}
/* ============================================================
   PROCESSING NOTICE (Round 6)
   ------------------------------------------------------------
   Covers the screen from the moment the student confirms their
   appointment details until the server answers, so the kiosk
   never looks frozen while the reservation is being saved and
   the confirmation email sent. Reuses .modal-overlay for the
   dimmed backdrop; only the box and spinner are new.
   ============================================================ */

.processing-box{
    background:#e5e5e5;

    border:2px solid black;
    border-radius:20px;

    padding:16px 28px 24px 28px;

    max-width:440px;
    text-align:center;
}

.processing-spinner{
    width:46px;
    height:46px;

    margin:0 auto 18px;

    border:5px solid #cfcfcf;
    border-top-color:#c81d3a;
    border-radius:50%;

    animation:processing-spin 0.9s linear infinite;
}

@keyframes processing-spin{
    to{ transform:rotate(360deg); }
}

.processing-box h1{
    color:#c81d3a;
    margin:0;
    padding:0 0 10px;
    font-size:24px;
}

.processing-box p{
    margin:0;
    font-size:14px;
    line-height:1.45;
    color:#333;
}

/* Respects a reduced-motion preference - the notice still shows,
   it just doesn't spin. */
@media (prefers-reduced-motion: reduce){
    .processing-spinner{ animation:none; }
    .processing-box{ animation:none; }
}

/* ============================================================
   RESERVATION CONFIRMATION & APPOINTMENT RESULT POP-UPS
   ------------------------------------------------------------
   Replace the old window.confirm() prompt and the chain of
   window.alert() boxes used to report a submission's outcome.
   Both reuse .modal-overlay for the dimmed backdrop and
   .processing-box for the card shape/animation, matching the
   processing notice above.
   ============================================================ */

.confirm-box,
.result-box{
    position:relative;

    max-width:480px;
    padding:14px 18px;
}

.confirm-box .modal-header,
.result-box .modal-header{
    /* justify-content (not text-align) positions the heading, since
       the h1 is a shrink-wrapped flex item here. No extra side padding -
       centering needs to use the box's full width, or it visually
       skews off-center. The close (x) button is absolutely positioned
       relative to the box itself, so it doesn't need row clearance. */
    justify-content:flex-start;
}

/* Invalid/alert-style result pop-ups (missing fields, invalid email,
   invalid date/time) keep the old centered heading; genuine
   confirmations - the Confirm Reservation modal and success results
   like "Appointment Confirmed!" - use the left-aligned heading above. */
.result-box.is-error .modal-header{
    justify-content:center;
}

.confirm-box h1,
.result-box h1{
    margin:0;
    padding:0 0 4px;
}

.confirm-message,
.result-message{
    margin:0;
    font-size:14px;
    line-height:1.5;
    color:#333;
    text-align:left;

    /* Preserves the \n line breaks already built into the
       confirmation/result text instead of collapsing them. */
    white-space:pre-line;
}

.confirm-buttons,
.result-buttons{
    justify-content:flex-end;
    margin-top:14px;
}

.confirm-buttons .clear-btn{
    border:2px solid #444;
    border-radius:20px;
    padding:6px 14px;
    color:#444;
}

.confirm-buttons .clear-btn:hover{
    background:#f2f2f2;
}

.result-icon{
    width:46px;
    height:46px;
    margin:0 auto 14px;

    display:flex;
    align-items:center;
    justify-content:center;

    border-radius:50%;
    font-size:24px;
    font-weight:bold;
    color:#ffffff;

    animation:modal-pop-in 0.15s ease-out;
}

.result-icon.is-success{
    background:#2e9e4f;
}

.result-icon.is-error{
    background:#c81d3a;
}

@media (prefers-reduced-motion: reduce){
    .result-icon{ animation:none; }
}
/* ------------------------------------------------------------
   Holiday notice under the reservation Date field (Sept 09 review).
   The server refuses holiday bookings; this is the immediate
   feedback the student gets the moment they pick the date.
   ------------------------------------------------------------ */
.holiday-notice{
    margin:4px 2px 0;
    font-size:12px;
    font-weight:bold;
    line-height:1.35;
    color:#c81d3a;
}

.form-dropdown.is-holiday{
    border-color:#c81d3a;
}

/* ------------------------------------------------------------
   WALK-IN CHECK-IN (Flowchart K1) - scan hints/errors and the
   shared scan widget's per-tab slot, plus the Group Check-in
   scanned-members list and first-time-user GSFE prompt.
   ------------------------------------------------------------ */
.scan-hint{
    margin:4px 0;
    font-size:12.5px;
    color:#555;
}

.scan-error{
    margin:4px 0;
    font-size:12.5px;
    font-weight:bold;
    color:#c81d3a;
}

.scan-slot{
    min-height:4px;
}

.group-members-list{
    display:flex;
    flex-direction:column;
    gap:6px;
    margin:5px 0 6px;
}

.group-member-row{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:8px;

    padding:8px 12px;
    border:1.5px solid #2e8b57;
    border-radius:12px;
    background:#eefaf3;

    font-size:12.5px;
    font-weight:bold;
    color:#000000;
}

.group-gsfe-prompt{
    margin:6px 0;
    padding:10px;
    border:1.5px solid #c81d3a;
    border-radius:12px;
    background:#fbeaea;
}

/* ------------------------------------------------------------
   QR tab scroll wrappers (Sept 09 review)
   ------------------------------------------------------------
   .opening-scroll-content and .qr-scroll-content existed in the
   markup but had no CSS rules at all, so they were inert: their
   cards could not shrink and a few pixels of each were clipped by
   the card's overflow:hidden with no way to scroll to them (worse
   as the browser is zoomed in). Same treatment as the Reservation
   tab's .reservation-scroll-content.
   ------------------------------------------------------------ */
.opening-scroll-content,
.qr-scroll-content{
    flex:1 1 auto;
    min-height:0;
    overflow-y:auto;

    scrollbar-width:thin;
    scrollbar-color:#bbb transparent;
}

.opening-scroll-content::-webkit-scrollbar,
.qr-scroll-content::-webkit-scrollbar{
    width:8px;
}

.opening-scroll-content::-webkit-scrollbar-track,
.qr-scroll-content::-webkit-scrollbar-track{
    background:transparent;
}

.opening-scroll-content::-webkit-scrollbar-thumb,
.qr-scroll-content::-webkit-scrollbar-thumb{
    background:#bbb;
    border-radius:20px;
}

/* ============================================================
   RESPONSIVE (portrait tablet / phone)
   ------------------------------------------------------------
   Everything above assumes a landscape kiosk touchscreen: a fixed
   viewport height with NO page scroll (body{overflow:hidden}),
   where .left-panel/.right-panel sit side by side and anything
   that outgrows them scrolls in its own internal scroll area
   instead. That works on a physical kiosk, but breaks on a
   narrower/portrait screen - .right-panel's fixed 460px width
   alone pushes content off the right edge of a phone.

   Below 899px, this section switches the page over to a normal
   scrolling page instead: panels stack vertically, and the
   internal scroll areas hand their scrolling to the page itself
   (min-height/overflow reset to their natural/auto values) so nothing
   is clipped or hidden behind a tiny fixed-height box.
   ============================================================ */
@media (max-width:899px){
    body{
        height:auto;
        min-height:100%;
        overflow:auto;
    }
    .main-content{
        flex-direction:column;
        min-height:auto;
    }
    .left-panel{
        /* Same fix as the admin dashboard's copy of this rule: base
           .left-panel is flex:1 1 auto (flex-grow:1), sized to grow
           against .right-panel in the desktop ROW layout. After
           .main-content stacks them in a column, that flex-grow makes
           .left-panel (and .status-card/.stations-scroll flexed
           inside it) balloon to fill the column's leftover height
           instead of just fitting its own content, leaving empty
           space below the station grid. */
        flex:0 0 auto;
        min-height:auto;
    }
    .status-card{
        height:auto;
        min-height:0;
        overflow:visible;
    }
    .stations-scroll{
        overflow-y:visible;
        min-height:0;
    }
    .right-panel{
        flex:1 1 auto;
        width:100%;
        max-width:100%;
        min-height:auto;
    }

    /* Persistent header + buttons while the page scrolls (mobile view):
       the navbar stays pinned to the top of the screen and the Station
       Map / Learn More buttons stay pinned to the bottom of the screen
       for as long as the Availability Status card is on screen. Both
       get a solid background so the station tiles never show through. */
    .navbar{
        position:sticky;
        top:0;
        z-index:100; /* above the cards, below the pop-ups (z-index:1000) */
        margin-bottom:0;
        padding-bottom:12px;
        background:#f5f5f5;
        border-radius:0 0 16px 16px;
        box-shadow:0 2px 8px rgba(0,0,0,.18);
    }
    .main-content{
        padding-top:14px;
    }
    .status-card > .buttons{
        position:sticky;
        bottom:0;
        z-index:50;
        margin:0 0 -10px; /* pulls the row down into the card's bottom padding: less empty space under the buttons */
        padding:10px 0 2px;
        background:#e5e5e5; /* same grey as .status-card */
        box-shadow:0 -6px 8px -6px rgba(0,0,0,.25);
    }
    /* A little room under the last panel so its bottom edge and rounded
       border are never cut off by the screen edge / browser toolbar.
       (.dashboard-body prefix = beats the later phone .main-content padding) */
    .dashboard-body .main-content{
        padding-bottom:calc(8px + env(safe-area-inset-bottom, 0px));
    }

    /* KIOSK + TRACKING PAGES (mobile): fixed full-screen shell. The page
       itself never scrolls, so the navbar, the Availability Status
       heading / date-time / location / pills / buttons all stay put.
         - Only the stations grid (.stations-scroll) scrolls inside the card.
         - On the kiosk page the QR Verification / check-in panels sit
           below the Availability Status card inside .main-content, which
           is the one outer scroller: when the stations grid has reached
           its end, the swipe carries on into .main-content, which scrolls
           the Availability Status card away and brings the panels into
           view (and back again on the way up). On the tracking page there
           is nothing below the card, so .main-content never scrolls. */
    body:is(.tracking-page,.kiosk-page){
        height:100vh;
        height:100dvh; /* real visible height on phones (excludes the browser toolbar) */
        min-height:0;
        overflow:hidden;
    }
    /* Nothing scrolls under the navbar, so it needs no fill or shadow -
       it just sits on the page background. */
    :is(.tracking-page,.kiosk-page) .navbar{
        position:static;
        background:none;
        box-shadow:none;
        border-radius:0;
    }
    :is(.tracking-page,.kiosk-page) .main-content{
        flex:1 1 auto;
        min-height:0;
        overflow-y:auto; /* the outer scroller: only moves once the stations grid has reached its end */
        overscroll-behavior-y:contain; /* don't drag the browser's own pull-to-refresh / page bounce along */
    }
    :is(.tracking-page,.kiosk-page) .left-panel{
        flex:0 0 auto;
        height:100%; /* the Availability Status card is exactly one screen tall (below the navbar) */
        min-height:0;
    }
    :is(.tracking-page,.kiosk-page) .status-card{
        height:100%;
        overflow:hidden;
    }
    :is(.tracking-page,.kiosk-page) .stations-scroll{
        overflow-y:auto;
        min-height:0;
    }
    :is(.tracking-page,.kiosk-page) .right-panel{
        flex:0 0 auto; /* keep its full height instead of being squeezed into the scroller */
    }
    .qr-verify-card,
    .reservation-embed-card{
        min-height:auto;
    }
    .reservation-scroll-content,
    .qr-scroll-content,
    .opening-scroll-content{
        overflow-y:visible;
        min-height:0;
    }
}

@media (max-width:480px){
    .navbar-content h2{
        font-size:18px;
    }
    .main-content{
        padding:10px;
        gap:12px;
    }
    /* .stations / .station / .station-label sizing now follows the card
       width (see @container rules next to .stations): 3 readable columns
       on mobile instead of 5 tiny ones. */
    .station-group-heading{
        font-size:11px;
        letter-spacing:1.5px;
        padding:4px 10px;
    }
    .station-section:not(:first-child){
        margin-top:6px;
    }
    .group-station-checklist{
        grid-template-columns:repeat(2,1fr);
    }
    /* The pills already sit on their own line below the date/Location
       at every width (base .top-status / .status-right rules), so there
       is no phone-only override here. A flex-direction:column on
       .top-status used to live here; with the wrapping layout it pushed
       the pills sideways out of the card, so it was removed. */
}

/* ============================================================
   KIOSK PANEL RESTRUCTURE (updated mockups p.1-7)
   ------------------------------------------------------------
   Iisang QR Code Verification card sa taas, at sa ibaba ang
   Individual/Group Check-in: idle ("Scan your TUPC Student ID QR
   Code to Begin"), ang form, ang Group Table message, at ang
   "Thank You" notice ng sign-out. Dati: dalawang top-level tab
   ("QR Verification" / "Check-in").
   ============================================================ */

/* Ang hidden attribute ay hindi dapat natatalo ng display ng mga class. */
[hidden]{
    display:none !important;
}

/* ---- QR Code Verification card (compact) ---- */
.qr-verify-card{
    flex:0 0 auto;
    padding:16px 18px 18px;
}

.qr-verify-card .qr-scan-input{
    margin-top:14px;
    margin-bottom:0;
}

.qr-verify-card .qr-camera-view{
    margin-top:12px;
}

.scan-message{
    margin:8px 0 0;
    text-align:center;
    font-size:12.5px;
    font-weight:bold;
    color:#555;
}

.scan-message.is-error{
    color:#c81d3a;
}

/* ---- Check-in card ---- */
.reservation-scroll-content{
    display:flex;
    flex-direction:column;
}

.checkin-idle,
.checkin-message{
    flex:1 1 auto;
    display:flex;
    flex-direction:column;
    align-items:center;
    justify-content:center;
    text-align:center;
    gap:10px;
    padding:14px 6px 8px;
}

.checkin-icon{
    width:84px;
    height:84px;
    flex:0 0 auto;
}

.checkin-idle-title,
.checkin-message-text{
    margin:0;
    font-size:18px;
    font-weight:bold;
    line-height:1.3;
    color:#000000;
}

.checkin-idle-hours{
    margin:10px 0 0;
    font-size:13px;
    line-height:1.5;
    color:#000000;
}

.checkin-message-eta{
    margin:0;
    font-size:13px;
    color:#000000;
}

.checkin-message-icon{
    display:inline-flex;
}

.checkin-message .buttons{
    align-self:flex-end;
    margin-top:12px;
}

/* Sign-out notice: puso para sa "Thank You", babala para sa overtime. */
#checkin-notice .notice-icon-overtime{
    display:none;
}

#checkin-notice.is-overtime .notice-icon-thanks{
    display:none;
}

#checkin-notice.is-overtime .notice-icon-overtime{
    display:inline-flex;
}

/* ---- Individual / Group forms ---- */
.checkin-form{
    flex:0 0 auto;
}

.checkin-grid{
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:6px 10px;
}

.checkin-grid .span-2{
    grid-column:1 / -1;
}

.checkin-grid .field{
    min-width:0;
}

.field-label{
    display:block;
    margin:0 0 2px 4px;
    font-size:13px;
    color:#000000;
}

.checkin-form .form-input,
.checkin-form .form-dropdown{
    margin-bottom:0;
}

.checkin-subheading{
    margin:12px 0 2px;
    font-size:15px;
    font-weight:bold;
    color:#000000;
}

.checkin-form .group-gsfe-prompt .form-input{
    margin-bottom:6px;
}

.group-member-remove{
    flex:0 0 auto;
    width:22px;
    height:22px;
    padding:0;
    border:none;
    border-radius:50%;
    background:#c81d3a;
    color:#ffffff;
    font-size:15px;
    font-weight:bold;
    line-height:1;
    cursor:pointer;
}

.group-member-remove:hover{
    background:#a8172f;
}

/* ---- Oras at "minutes remaining" sa occupied na station tile (p.1) ---- */
.station-time,
.station-remaining{
    margin-top:4px;
    text-align:center;
    font-size:0.7rem;
    font-weight:normal;
    line-height:1.25;
}

.station-remaining.is-finished{
    font-weight:bold;
}

.station-short{
    display:none;
}

/* Dati, sa phone (limang maliliit na tile bawat hanay) "33 min" lang ang
   ipinapakita. Tatlong malalaking tile na ang bawat hanay sa mobile (tingnan
   ang @container sa tabi ng .stations), kaya buo na ulit ang oras at
   "minutes remaining"; hindi na ginagamit ang .station-short. */

/* ---- About the Learning Commons (p.3) ---- */
/* Mas mataas ang specificity kaysa sa .modal-box.station-map-box (width:auto),
   na nagpapalapad sa About hanggang sa haba ng intro text. */
.modal-box.about-box{
    width:min(580px, 94vw);

    /* Fit the visible screen (phones / short windows): the box is never
       taller than the screen, the heading + close (x) stay pinned at the
       top of the box, and only the content below them scrolls. The plain
       vh line is the fallback for browsers without dvh (dvh = the real
       visible height, excluding the mobile browser toolbar). */
    /* .modal-box is content-box, so max-height must leave room for the
       box's own padding (22px x 2) + border (2px x 2) = 48px, plus a
       24px margin of screen around it. */
    max-height:calc(100vh - 72px);
    max-height:calc(100dvh - 72px);
    max-width:calc(100vw - 72px); /* same allowance sideways: never wider than the screen */
    display:flex;
    flex-direction:column;
    overflow:hidden; /* the scrolling happens in .modal-scroll-content below */
}

.about-box .modal-header{
    padding-right:34px; /* keeps a long heading clear of the close (x) button */
}

.about-box .modal-scroll-content{
    display:block;
    flex:1 1 auto;
    min-height:0; /* required so this flex child can shrink and scroll instead of overflowing the box */
    overflow-y:auto;
    padding-right:4px; /* keeps the scrollbar off the text */
}

@media (max-width:480px){
    .modal-box.about-box{
        padding:16px 14px;
        /* padding is 16px x 2 here, so 36px (with border) + 24px margin */
        max-height:calc(100vh - 60px);
        max-height:calc(100dvh - 60px);
        max-width:calc(100vw - 60px);
    }
    /* Smaller heading on phones so it takes less of the (pinned) header. */
    .about-box .modal-header h1{
        font-size:22px;
        line-height:1.2;
    }
}

.about-intro{
    margin:8px 0 0;
    font-size:13px;
    line-height:1.45;
    color:#000000;
}

.about-heading{
    margin:14px 0 6px;
    font-size:16px;
    font-weight:bold;
    color:#c81d3a;
}

.about-steps{
    list-style:none;
    counter-reset:about-step;
    margin:0;
    padding:0;
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:6px 10px;
}

.about-steps li{
    counter-increment:about-step;
    display:flex;
    align-items:center;
    gap:8px;
    padding:6px 10px;
    border:2px solid #000000;
    border-radius:14px;
    background:#ffffff;
    font-size:12px;
    line-height:1.3;
    color:#000000;
}

.about-steps li::before{
    content:counter(about-step);
    flex:0 0 auto;
    width:22px;
    height:22px;
    display:flex;
    align-items:center;
    justify-content:center;
    border:2px solid #000000;
    border-radius:50%;
    background:#e5e5e5;
    font-size:12px;
    font-weight:bold;
}

.about-note{
    margin:10px 0 0;
    font-size:12px;
    color:#000000;
}

.about-people{
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:8px;
}

.about-person{
    display:flex;
    align-items:center;
    gap:8px;
    padding:8px 10px;
    border-radius:14px;
    background:#3a3a3a;
    color:#ffffff;
}

.about-avatar{
    position:relative;
    flex:0 0 40px;
    width:40px;
    height:40px;
    display:flex;
    align-items:center;
    justify-content:center;
    border-radius:50%;
    overflow:hidden;
    background:#c81d3a;
    font-size:13px;
    font-weight:bold;
    color:#ffffff;
}

.about-avatar::before{
    content:attr(data-initials);
}

.about-avatar img{
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
    object-fit:cover;
}

.about-person-info{
    display:flex;
    flex-direction:column;
    min-width:0;
    font-size:11px;
    line-height:1.25;
}

.about-person-info strong{
    font-size:12.5px;
}

.about-footer{
    margin:12px 0 0;
    font-size:11.5px;
    line-height:1.4;
    color:#333333;
}

@media (max-width:560px){
    .about-steps,
    .about-people{
        grid-template-columns:1fr;
    }
}

/* Phone width: isang column ang form (Location/Station, Student ID/Program). */
@media (max-width:480px){
    .checkin-grid{
        grid-template-columns:1fr;
    }
}

/* =========================================================
   ADMIN-SYSTEM LOOK, APPLIED TO THE KIOSK AND TRACKING PAGES
   (kept last so it wins over every per-element rule above;
   !important is used where an earlier, more specific rule would
   otherwise win - same approach as the admin stylesheet)
   Covers: button styles + hover/press animations, dropdown and
   text box styling, the Individual / Group reservation tabs, and
   the date fields. The station tile colours, location dropdown,
   group headings (with icons) and Vacant / Occupied / Closed /
   Total pills were updated in place above.
   ========================================================= */

/* ---------- Buttons: hover / press animation ---------- */
.gray-btn,
.red-btn,
.login-btn,
.forgot-btn,
.clear-btn,
.pill-btn,
.reservation-tab-btn,
.kiosk-settings-btn{
    transition:background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease,
               box-shadow 0.15s ease, transform 0.1s ease, filter 0.15s ease;
}

.gray-btn:active:not(:disabled),
.red-btn:active:not(:disabled),
.login-btn:active:not(:disabled),
.forgot-btn:active:not(:disabled),
.pill-btn:active:not(:disabled),
.clear-btn:active:not(:disabled){
    transform:translateY(0) scale(0.97);
    box-shadow:none;
}

/* ---------- Buttons: white, bold, 2px #0f172b border, 30px pill ---------- */
button{
    border-radius:999px;
}

.gray-btn,
.red-btn,
.login-btn,
.forgot-btn,
.clear-btn,
.pill-btn,
.reservation-tab-btn{
    background:#ffffff;
    color:#0f172b !important;
    border:2px solid #0f172b !important;
    font-weight:700;
    letter-spacing:normal;

    box-sizing:border-box !important;
    height:30px !important;
    min-height:30px !important;
    padding:0 12px !important;
    display:inline-flex !important;
    align-items:center !important;
    justify-content:center !important;
    font-family:Poppins, Arial, sans-serif;
    font-size:10px !important;
    line-height:1 !important;
    border-radius:999px !important;
}

.kiosk-settings-btn{
    border:2px solid #0f172b !important;
    color:#0f172b;
}

@media (hover:hover){
    .gray-btn:hover:not(:disabled),
    .red-btn:hover:not(:disabled),
    .login-btn:hover:not(:disabled),
    .forgot-btn:hover:not(:disabled),
    .clear-btn:hover:not(:disabled),
    .pill-btn:hover:not(:disabled),
    .reservation-tab-btn:hover:not(:disabled){
        background:#f2f2f2;
    }
}

/* ---------- Active reservation tab: same red gradient as the Occupied tiles / pill ---------- */
.reservation-tab-btn.active,
.reservation-tab-btn.active:hover:not(:disabled){
    background:linear-gradient(135deg, #800000, #ad253b) !important;
    border-color:transparent !important;
    background-origin:border-box !important;
    background-clip:border-box !important;
    color:#ffffff !important;
    outline:none;
}

@media (hover:hover){
    .reservation-tab-btn.active:hover:not(:disabled){
        filter:brightness(1.15);
    }
}

/* Phone width: the tabs may wrap onto two lines, so they keep a 30px
   minimum instead of a fixed height. */
@media (max-width:480px){
    .reservation-tab-btn{
        height:auto !important;
        padding:6px 10px !important;
        white-space:normal !important;
    }
}

/* ---------- Dropdowns ---------- */
select,
select:hover,
select:focus,
select:focus-visible,
select:active,
.form-dropdown,
.location-select,
.location-pill{
    box-sizing:border-box !important;
    height:30px !important;
    min-height:30px !important;
    padding-top:0 !important;
    padding-bottom:0 !important;
    padding-left:10px !important;
    padding-right:10px !important;

    background-color:#ffffff;
    border:2px solid #0f172b !important;
    border-radius:999px !important;

    color:#0f172b !important;
    font-family:Poppins, Arial, sans-serif !important;
    font-size:var(--field-font-size) !important;
    font-weight:700 !important;
    line-height:normal;
    letter-spacing:normal !important;
    outline:none;
    box-shadow:none;
}

/* Holiday cue on the date-dependent dropdown stays red */
.form-dropdown.is-holiday{
    border-color:#c81d3a !important;
    color:#c81d3a !important;
}

/* ---------- Text boxes: same pill as the dropdowns ---------- */
.form-input,
.qr-scan-input,
:is(.overlay-box, .modal-box) :is(
    input[type="text"],
    input[type="password"],
    input[type="number"],
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input:not([type])
){
    box-sizing:border-box !important;
    width:100%;
    max-width:100%;
    height:30px !important;
    min-height:30px !important;
    padding:0 14px !important;

    background-color:#ffffff;
    border:2px solid #0f172b !important;
    border-radius:999px !important;

    color:#0f172b !important;
    font-family:Poppins, Arial, sans-serif !important;
    font-size:var(--field-font-size) !important;
    font-weight:700 !important;
    line-height:1 !important;
    letter-spacing:normal !important;
}

.form-input:is(:hover, :focus, :focus-visible, :active),
.qr-scan-input:is(:hover, :focus, :focus-visible, :active),
:is(.overlay-box, .modal-box) :is(
    input[type="text"],
    input[type="password"],
    input[type="number"],
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input:not([type])
):is(:hover, :focus, :focus-visible, :active){
    outline:none !important;
    box-shadow:none !important;
    border-color:#0f172b !important;
}

/* The scan box keeps its centred text */
.qr-scan-input{
    text-align:center;
}

/* Read-only fields (Location, Name, ...) keep their grey "locked" look */
.form-input.locked-field,
.locked-field{
    background-color:#e0e0e0 !important;
    color:#555555 !important;
    cursor:not-allowed;
}

/* Multi-line box: same border and text, softer corner (a 30px pill can't
   hold several lines). */
:is(.overlay-box, .modal-box) textarea{
    box-sizing:border-box;
    border:2px solid #0f172b !important;
    border-radius:14px;
    padding:8px 14px;
    background-color:#ffffff;
    color:#0f172b;
    font-family:Poppins, Arial, sans-serif;
    font-size:var(--field-font-size);
    font-weight:700;
    letter-spacing:normal;
}

:is(.overlay-box, .modal-box) textarea:is(:hover, :focus, :focus-visible, :active){
    outline:none;
    box-shadow:none;
    border-color:#0f172b !important;
}

/* ---------- Date / time fields = dropdown look ---------- */
input[type="date"],
input[type="month"],
input[type="week"],
input[type="time"],
input[type="datetime-local"],
input.date-pill,
.date-pill{
    box-sizing:border-box !important;
    height:30px !important;
    min-height:30px !important;
    padding:0 10px !important;

    background:#ffffff !important;
    border:2px solid #0f172b !important;
    border-radius:999px !important;

    color:#0f172b !important;
    font-family:Poppins, Arial, sans-serif !important;
    font-size:var(--field-font-size) !important;
    font-weight:700 !important;
    line-height:1 !important;
    letter-spacing:normal !important;

    color-scheme:light;
}

input[type="date"]:is(:hover, :focus, :focus-visible, :active),
input[type="month"]:is(:hover, :focus, :focus-visible),
input[type="week"]:is(:hover, :focus, :focus-visible),
input[type="time"]:is(:hover, :focus, :focus-visible),
input[type="datetime-local"]:is(:hover, :focus, :focus-visible),
.date-pill:is(:hover, :focus, :focus-visible){
    outline:none !important;
    box-shadow:none !important;
    border-color:#0f172b !important;
}

input[type="date"]::-webkit-datetime-edit,
input[type="month"]::-webkit-datetime-edit,
input[type="week"]::-webkit-datetime-edit,
input[type="time"]::-webkit-datetime-edit,
input[type="datetime-local"]::-webkit-datetime-edit,
input[type="date"]::-webkit-datetime-edit-fields-wrapper,
input[type="time"]::-webkit-datetime-edit-fields-wrapper,
input[type="datetime-local"]::-webkit-datetime-edit-fields-wrapper,
input[type="date"]::-webkit-datetime-edit-text,
input[type="time"]::-webkit-datetime-edit-text,
input[type="datetime-local"]::-webkit-datetime-edit-text{
    padding:0;
    color:#0f172b;
    font-family:Poppins, Arial, sans-serif;
    font-size:var(--field-font-size);
    font-weight:700;
}

input[type="date"]::-webkit-calendar-picker-indicator,
input[type="month"]::-webkit-calendar-picker-indicator,
input[type="week"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator{
    cursor:pointer;
    opacity:0.8;
}

input[type="date"]::-webkit-calendar-picker-indicator:hover,
input[type="month"]::-webkit-calendar-picker-indicator:hover,
input[type="week"]::-webkit-calendar-picker-indicator:hover,
input[type="time"]::-webkit-calendar-picker-indicator:hover,
input[type="datetime-local"]::-webkit-calendar-picker-indicator:hover{
    opacity:1;
}


/* =========================================================
   BOLD FIELDS + ONE FONT SIZE ON EVERY PAGE (kept last so it wins)
   Same block as the admin system. Everything below is bold and uses
   var(--field-font-size) (set at the top of this file), so the size is
   identical on all pages and at every screen width (it also overrides the
   phone / container-query sizes set earlier for the station tiles and
   group headings).
   - Drop-downs, search boxes, date / time fields and every other input
     field and text area.
   - Field labels: Location, Date, etc.
   - Stations grid titles: Station 1, Station 2, Seat 1, Seat 2, the
     group headings (Individual Stations / Table 1 ...) and the
     column headers of the availability timeline.
   Buttons are not touched. !important is used because several
   page-specific rules above are more specific or use !important.
   ========================================================= */
select,
textarea,
input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="image"]):not([type="range"]):not([type="color"]){
    font-family:Poppins, Arial, sans-serif !important;
    font-size:var(--field-font-size) !important;
    font-weight:700 !important;
}

/* Text typed into a field and the hint shown inside it */
input::placeholder,
textarea::placeholder{
    font-weight:700;
    opacity:0.6;
}

/* The "Choose File" picker's own label text */
input[type="file"]::file-selector-button{
    font-family:Poppins, Arial, sans-serif;
    font-size:var(--field-font-size);
    font-weight:700;
}

/* Field labels */
label,
.location-label,
.location-display,
.field-label,
.login-container label{
    font-size:var(--field-font-size) !important;
    font-weight:700 !important;
}

/* Stations grid titles (Station 1, Seat 1, ...), group headings and the
   timeline's column headers */
.station-label,
.station-group-heading,
.station-group-info,
.tl-station-header{
    font-size:var(--field-font-size) !important;
    font-weight:700 !important;
}

@media (max-width:480px){
    .station-group-heading{
        font-size:var(--field-font-size) !important;
    }
}

/* =========================================================
   BUTTON ICONS (same as the admin system)
   Usage: <svg class="btn-icon" aria-hidden="true"><use href="#i-NAME"/></svg>Label
   The sprite (<symbol id="i-NAME">) sits at the top of <body>.
   Stroke follows the button's text colour, so it also turns white on
   the active reservation tab.
   ========================================================= */
.btn-icon{
    width:1.3em;
    height:1.3em;
    flex:0 0 auto;
    margin-right:6px;
    fill:none;
    stroke:currentColor;
    stroke-width:2;
    stroke-linecap:round;
    stroke-linejoin:round;
    vertical-align:middle;
    pointer-events:none;
}


/* =========================================================
   PERSISTENT CANCEL / DONE (Individual + Study Table check-in)
   The button row stays pinned to the bottom of the check-in card while
   the form scrolls, and sits at the bottom even when the form is short.
   The row has a solid card background (no shadow) so the fields never
   show through, and its bottom spacing matches the Availability Status
   card's buttons.
   ========================================================= */

/* The visible form fills the scroll area, so the button row can be pushed
   to the bottom with margin-top:auto. (:not([hidden]) keeps the hidden
   attribute working - the panels are shown/hidden by script.) */
.reservation-scroll-content > .checkin-form:not([hidden]),
#group-form-body:not([hidden]){
    display:flex;
    flex-direction:column;
    flex:1 0 auto;
}

.checkin-form > .buttons,
#group-form-body > .buttons{
    position:sticky;
    bottom:0;
    z-index:5;
    margin:auto 0 0; /* auto top = bottom of the card when the form is short */
    padding:10px 0 0;
    background:#e5e5e5; /* same grey as .card, so the fields never show through */
}

/* Bottom spacing patterned on the Availability Status card's buttons: there the
   card has 18px padding and the row is pulled 5px into it (margin-bottom:-5px),
   leaving 13px under the buttons. Same 13px here. */
.reservation-embed-card{
    padding-bottom:13px;
}

/* Stacked (tablet / phone) layout: the page scrolls instead of the card, and
   .card's overflow:hidden would stop the row from sticking - let it stick to
   the bottom of the screen for as long as the form is on screen. */
@media (max-width:899px){
    .reservation-embed-card{
        overflow:visible;
        padding-bottom:10px; /* Availability Status buttons leave 10px here (18px padding, -10px margin, 2px padding) */
    }
}


/* =========================================================
   CAMERA MODE: while the camera waits for a scan, the check-in panel is
   hidden and only the Individual / Study Table tabs remain (see
   syncCameraLayout() in index.html) - the card shrinks to just the tabs.
   ========================================================= */
.reservation-embed-card.is-camera-idle{
    flex:0 0 auto;
}

.reservation-embed-card.is-camera-idle .reservation-tabs{
    margin-bottom:0;
}


/* =========================================================
   CAMERA VIEWFINDER FILLS THE COLUMN (Device Camera scan method)
   The right column (QR Code Verification + check-in panel) is exactly as
   tall as the Availability Status panel. While the camera is live, the
   QR Code Verification card takes all the height the check-in panel
   doesn't need, and the viewfinder stretches to fill it (it used to be a
   fixed 4:3 box). Classes are set by syncCameraLayout() in index.html:
     .is-camera-live  on .qr-verify-card   (camera visible)
     .camera-mode     on <body>            (Device Camera selected)
   ========================================================= */
.qr-verify-card.is-camera-live{
    flex:1 1 0;
    min-height:240px;
}

.qr-verify-card.is-camera-live .qr-scroll-content{
    display:flex;
    flex-direction:column;
}

.qr-verify-card.is-camera-live #scan-widget,
.qr-verify-card.is-camera-live .qr-camera-view{
    flex:1 1 auto;
    min-height:0;
    display:flex;
    flex-direction:column;
}

.qr-verify-card.is-camera-live .qr-camera-video{
    flex:1 1 0;
    min-height:0;
    width:100%;
    height:100%;
    aspect-ratio:auto; /* was 4/3 - now follows the available height (object-fit:cover crops, no stretching) */
}

/* Stacked layout (tablet / phone): the column sits below the Availability
   Status panel, which is exactly one screen tall - give the column that same
   minimum height so the viewfinder lines up with it. */
@media (max-width:899px){
    body.camera-mode .right-panel{
        min-height:100%;
    }
}
/* ============================================================
   LOCATION PILL + SETTINGS BUTTON (Availability Status)
   ------------------------------------------------------------
   Same look and spacing as the admin system's Location dropdown:
   a 30px pill (border / font come from the shared dropdown rule
   above via .location-pill), sitting directly under the
   "Location:" label with the same -5px offsets. The read-only
   location name fills the row and the Kiosk Settings button sits
   right beside it, the same 30px height as the pill.
   Kept last so it wins.
   ============================================================ */
.location-display-row{
    display:flex;
    align-items:center;
    gap:8px;
    margin-top:-5px;     /* same offset as the admin .location-select */
    margin-right:0;
}

.location-display-row .location-pill{
    flex:1 1 auto;
    min-width:0;         /* cancels the old 320px minimum so it can shrink beside the button */
    margin:0;
    padding-left:13px !important; /* a native <select> insets its text ~3px beyond its padding; 10px + 3px makes the text start exactly where the Tracking page dropdown's text does */
    display:flex;
    align-items:center;  /* a span has no native vertical centring like a <select> */
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
}

.location-display-row .kiosk-settings-btn{
    flex:0 0 30px;
    width:30px;
    height:30px;
    padding:0;
    display:inline-flex;
    align-items:center;
    justify-content:center;
    font-size:0;
    line-height:1;
}

.location-display-row .kiosk-settings-btn .btn-icon{
    width:16px;
    height:16px;
    margin:0;
}
/* =========================================================
   KIOSK MODALS = ADMIN SYSTEM MODALS (kept last so it wins)
   Same layout as the admin .overlay-box / .overlay-header /
   .overlay-body / .overlay-buttons, so the kiosk and the /tracking
   page (which share this stylesheet) look like the admin modals.
     .modal-box / .processing-box  -> .overlay-box
     .modal-header                 -> .overlay-header
     .modal-scroll-content         -> .overlay-body
     .modal-buttons / .buttons     -> .overlay-buttons
   1. Edge padding = the panels' 20px. The box itself has no padding;
      the header, body and button row carry it, so the scrollbar
      stays inside the rounded corners.
   2. Subtitle (.modal-header > p): bordered box, no fill, bold text,
      info icon in front.
   3. Element spacing copied from the admin modals (title -> subtitle
      -> fields -> buttons).
   ========================================================= */

/* ---- 1. Box, header, body, button row ---- */
.modal-overlay .modal-box,
.modal-overlay .modal-box.card,
.modal-overlay .processing-box.confirm-box,
.modal-overlay .processing-box.result-box{
    display:flex;
    flex-direction:column;
    overflow:hidden;
    padding:0;
    max-height:85vh;
    max-height:85dvh;
}

/* Processing notice has no header: plain 20px panel padding all round */
.modal-overlay .processing-box:not(.confirm-box):not(.result-box){
    padding:20px;
}

/* Tall boxes keep their own size rules (they are declared above) */
.modal-overlay .modal-box.station-map-box{ max-height:96vh; max-height:96dvh; }
.modal-overlay .modal-box.about-box{
    max-height:calc(100vh - 72px);
    max-height:calc(100dvh - 72px);
}

.modal-overlay .modal-box > .modal-header,
.modal-overlay .processing-box > .modal-header{
    display:block;
    flex:0 0 auto;
    padding:15px 50px 4px 20px;      /* right room for the (x) button */
    text-align:left;
    background:inherit;
}

.modal-overlay .modal-box > .modal-header > h1,
.modal-overlay .processing-box > .modal-header > h1{
    margin:0;
    padding:0;
    font-size:27px;
    line-height:1;
}

/* Invalid / alert result pop-ups keep the centred heading */
.modal-overlay .result-box.is-error > .modal-header{
    padding:15px 50px 4px;
    text-align:center;
}

.modal-overlay .modal-box > .modal-scroll-content{
    flex:1 1 auto;
    min-height:0;
    overflow-y:auto;
    margin-right:4px;                /* keeps the scrollbar off the border */
    padding:0 16px 6px 20px;         /* 16px + 4px margin = 20px on the right */
}

/* No button row under it -> normal bottom edge padding */
.modal-overlay .modal-box > .modal-scroll-content:last-child{
    padding-bottom:20px;
}

/* Bottom buttons: pinned row, 5px apart, 20px right / 15px bottom edge */
.modal-overlay .modal-box > .buttons,
.modal-overlay .processing-box > .buttons{
    flex:0 0 auto;
    justify-content:flex-end;
    gap:5px;
    margin:0;
    padding:4px 20px 15px;
    background:inherit;
}

/* Confirm / result: message sits in the body position */
.modal-overlay .processing-box > .confirm-message,
.modal-overlay .processing-box > .result-message{
    margin:8px 0 0;
    padding:0 20px 6px;
}

.modal-overlay .processing-box.result-box > .result-icon{
    margin:20px auto 4px;
}

.modal-overlay .processing-box.result-box > .result-icon + .modal-header{
    padding-top:8px;
}

/* ---- 2. Subtitle: info icon, border, no background, bold ---- */
.modal-overlay .modal-header > p{
    display:flex;
    align-items:flex-start;
    gap:8px;

    box-sizing:border-box;
    margin:6px -30px 6px 0;          /* pulls back over the (x) room so the right edge lines up with the body's 20px edge */
    padding:8px 14px;

    background:transparent;
    border:2px solid #000000;
    border-radius:12px;

    color:#333333;
    font-size:12.5px;
    font-weight:bold;
    line-height:1.4;
    text-align:left;
}

.modal-overlay .modal-header > p::before{
    content:"";
    flex:0 0 auto;
    width:14px;
    height:14px;
    margin-top:1.75px;               /* centres the icon on the first line of text */
    background-color:currentColor;
    -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4'/%3E%3Cpath d='M12 8h.01'/%3E%3C/svg%3E") center/contain no-repeat;
    mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4'/%3E%3Cpath d='M12 8h.01'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* About the Learning Commons: its intro paragraph is the subtitle */
.modal-overlay .about-box .about-intro{
    display:flex;
    align-items:flex-start;
    gap:8px;
    box-sizing:border-box;
    margin:6px 0 6px;
    padding:8px 14px;
    background:transparent;
    border:2px solid #000000;
    border-radius:12px;
    color:#333333;
    font-size:12.5px;
    font-weight:bold;
    line-height:1.4;
    text-align:left;
}

.modal-overlay .about-box .about-intro::before{
    content:"";
    flex:0 0 auto;
    width:14px;
    height:14px;
    margin-top:1.75px;
    background-color:currentColor;
    -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4'/%3E%3Cpath d='M12 8h.01'/%3E%3C/svg%3E") center/contain no-repeat;
    mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4'/%3E%3Cpath d='M12 8h.01'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* ---- 3. Element spacing inside the modal (Kiosk Settings form) ---- */
/* Label directly above its field: label margin-bottom 5px + field
   margin-top -5px = no gap; 10px between field groups. */
.modal-overlay .modal-box .appointment-label{
    display:block;
    margin:10px 0 5px;
    font-size:var(--field-font-size);
    font-weight:700;
}

.modal-overlay .modal-box .modal-scroll-content > .appointment-label:first-child{
    margin-top:0;
}

.modal-overlay .modal-box .form-input,
.modal-overlay .modal-box .form-dropdown{
    display:block;
    margin-top:-5px;
    margin-bottom:0;
}

/* Helper text under a field */
.modal-overlay .modal-box .kiosk-settings-note{
    margin:6px 0 0;
    line-height:1.4;
}

/* Error line (same as the admin .overlay-status) */
.modal-overlay .modal-box .kiosk-settings-error{
    min-height:1.2em;
    margin:8px 0 0;
    font-size:12.5px;
}

@media (max-width:480px){
    .modal-overlay .about-box > .modal-header > h1{
        font-size:22px;
        line-height:1.2;
    }
}

/* =========================================================
   DROPDOWN ARROW POSITION = ADMIN SYSTEM (kept last so it wins)
   The browser's built-in arrow sits flush against the right edge and
   can't be padded, so every <select> draws its own chevron, exactly as
   in the admin system: 12px chevron, 14px from the right edge, 34px
   right padding so long text never runs under it, 14px left padding.
   The extra selectors (select.form-dropdown / select.location-select)
   are needed because the shared dropdown rule above sets 10px padding
   on those classes with !important.
   ========================================================= */
select,
select:hover,
select:focus,
select:focus-visible,
select:active,
select.form-dropdown,
select.location-select{
    -webkit-appearance:none !important;
    -moz-appearance:none !important;
    appearance:none !important;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%230f172b' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") !important;
    background-repeat:no-repeat !important;
    background-position:right 14px center !important;
    background-size:12px 12px !important;
    padding-left:14px !important;
    padding-right:34px !important;
    padding-top:0 !important;
    padding-bottom:0 !important;
    line-height:normal !important;
    text-overflow:ellipsis;
    vertical-align:middle;
}

/* The read-only Location pill on the kiosk is a <span>: its text now
   starts at the same 14px as the dropdown text. */
.location-display-row .location-pill{
    padding-left:14px !important;
}

/* =========================================================
   ON-SCREEN KEYBOARD MODE (tablet / phone, stacked layout)
   ---------------------------------------------------------
   While a check-in field (e.g. GSFE Email) is focused, index.html's
   "KEYBOARD-AWARE LAYOUT" script puts .keyboard-open on <body>:
     - the QR Code Verification card is hidden, so the check-in form
       (with the focused field) gets all the room above the keyboard;
     - the page shell is sized to the VISIBLE area (--vvh / --vvt come
       from window.visualViewport) instead of 100dvh, which does not
       shrink for the keyboard in most Android browsers / WebViews.
   The QR card comes back as soon as the field loses focus / the
   keyboard is dismissed.
   ========================================================= */
@media (max-width:899px){
    body.kiosk-page.keyboard-open{
        position:fixed;
        top:var(--vvt, 0px);
        left:0;
        right:0;
        height:var(--vvh, 100dvh);
        min-height:0;
    }
    body.keyboard-open .qr-verify-card{
        display:none;
    }
    body.keyboard-open .right-panel{
        min-height:0; /* beats body.camera-mode .right-panel{min-height:100%} */
    }
    body.keyboard-open .reservation-embed-card input,
    body.keyboard-open .reservation-embed-card select{
        scroll-margin:12px 0; /* a little air around the field when it is scrolled into view */
    }
}

/* "Scan Next Member" (Study Table check-in, Device Camera mode) */
.group-scan-next-btn{
    align-self:flex-end; /* right side of the form */
    margin:6px 0 2px;
}

/* Tapping the "camera stopped responding" message restarts the camera */
.qr-camera-error{
    cursor:pointer;
}

/* Camera still starting (waiting for page load / permission / first frame): show a calm
   grey placeholder with a label instead of an empty black box. */
.qr-camera-view{
    position:relative;
}
.qr-camera-view.is-starting .qr-camera-video{
    background:#d0d0d0;
}
.qr-camera-view.is-starting::after{
    content:"Starting camera\2026";
    position:absolute;
    inset:2px;
    display:flex;
    align-items:center;
    justify-content:center;
    font-size:14px;
    font-weight:bold;
    color:#555;
    pointer-events:none;
}
/* Scan box is display-only: filled by the QR reader, never typed into */
.qr-scan-input[readonly]{
    cursor:default;
    caret-color:transparent;
    user-select:none;
    -webkit-user-select:none;
}

/* =========================================================
   STUDY TABLE (GROUP) CHECK-IN LAYOUT
   ========================================================= */

/* Purpose + Table share one row. The label sits 2px above the field,
   exactly like Location (.field-label margin + .checkin-form fields have
   no bottom margin). */
.group-top-grid{
    margin-bottom:6px;
}
.group-top-grid .field-label{
    margin:0 0 2px 4px;
}
.group-top-grid .form-dropdown{
    margin:0;
}

/* "Scanned Members": same look as the stations-grid group heading
   (.station-group-heading) - light-red box, red uppercase bold text,
   group icon in front. Not sticky: it scrolls with the form. */
.checkin-members-heading{
    box-sizing:border-box;
    margin:8px 0 0;
    padding:6px 14px;

    background:#fdecee;
    border:1px solid #c81d3a;
    border-radius:8px;

    font-size:var(--field-font-size);
    line-height:1.2;
    font-weight:700;
    text-transform:uppercase;
    letter-spacing:2px;
    color:#c81d3a;
}

.checkin-members-heading::before{
    content:"";
    display:inline-block;
    width:1.15em;
    height:1.15em;
    margin-right:10px;
    vertical-align:-0.2em;
    background-color:currentColor;
    -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='9' cy='7' r='4'/%3E%3Cpath d='M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75'/%3E%3C/svg%3E") center/contain no-repeat;
    mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='9' cy='7' r='4'/%3E%3Cpath d='M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* Very narrow screens: stack Purpose and Table */
@media (max-width:480px){
    .group-top-grid{
        grid-template-columns:1fr;
    }
}

/* GSFE email prompt (Study Table check-in): Cancel + Add to Group,
   right-aligned, 5px apart (same as every other button row). */
.group-gsfe-actions{
    display:flex;
    justify-content:flex-end;
    align-items:center;
    gap:5px;
}

.checkin-form .group-gsfe-prompt .field-label{
    margin:0 0 2px 4px;
}

.checkin-form .group-gsfe-prompt .form-input{
    margin:0 0 8px;
}

.group-gsfe-actions .gray-btn,
.group-gsfe-actions .clear-btn{
    margin:0;
}

/* =========================================================
   SIGN-OUT / OVERTIME NOTICE: Close button
   Same spot and behaviour as Cancel / Done during check-in: the button
   row is pinned to the bottom-right of the card (stays visible while
   the card scrolls), with the same solid card background and spacing.
   The icon + message stay centred in the space above it.
   ========================================================= */
#checkin-notice{
    padding:0;
    gap:0;
    justify-content:flex-start;
    align-items:stretch;
    flex:1 0 auto;
}

#checkin-notice .checkin-notice-body{
    flex:1 0 auto;
    display:flex;
    flex-direction:column;
    align-items:center;
    justify-content:center;
    gap:10px;
    padding:14px 6px 8px;
    text-align:center;
}

#checkin-notice > .buttons{
    position:sticky;
    bottom:0;
    z-index:5;
    align-self:stretch;
    justify-content:flex-end;
    margin:auto 0 0;
    padding:10px 0 0;
    background:#e5e5e5;
}

/* =========================================================
   SELECT PLACEHOLDER = GRAY
   The Station No. / Table / Purpose dropdowns are "required", so they are
   :invalid exactly while the "Select ..." placeholder is showing. The
   options inside the opened list keep the normal dark text.
   ========================================================= */
select.form-dropdown:required:invalid{
    color:#6b7280 !important;
}
select.form-dropdown option{
    color:#0f172b;
}
select.form-dropdown option[value=""]{
    color:#6b7280;
}

/* =========================================================
   GSFE EMAIL BOX: name only, domain shown beside it
   ========================================================= */
.email-field{
    display:flex;
    align-items:center;
    gap:8px;
}

.email-field .form-input{
    flex:1 1 auto;
    width:auto;
    min-width:0;
}

.email-field .form-input::placeholder{
    color:#6b7280;
    font-weight:700;
}

.email-suffix{
    flex:0 0 auto;
    font-size:var(--field-font-size);
    font-weight:700;
    color:#0f172b;
    white-space:nowrap;
}

/* Stored email on some other domain: shown in full, no suffix */
.email-field.no-suffix .email-suffix{
    display:none;
}

@media (max-width:480px){
    .email-field{
        flex-wrap:wrap;
        gap:2px 8px;
    }
    .email-field .form-input{
        flex:1 1 100%;
    }
}

/* =========================================================
   STUDY TABLE GSFE EMAIL PROMPT: input box + domain text on one
   middle line. The 8px gap used to be the input's own bottom margin,
   which pushed the box up and left the domain text sitting lower
   than the box's middle. The gap now belongs to the row instead.
   ========================================================= */
.checkin-form .group-gsfe-prompt .email-field{
    align-items:center;
    margin:0 0 8px;
}

.checkin-form .group-gsfe-prompt .email-field .form-input{
    margin:0;
}

.group-gsfe-prompt .email-suffix{
    display:flex;
    align-items:center;
    height:30px;          /* same height as the input box, text centred in it */
    line-height:1;
}

/* =========================================================
   DEVICE CAMERA MODE: viewfinder that fits its panel
   - Camera mode shows the same panels as the hardware scanner; the
     "Tap to Scan Student ID QR Code" button opens the viewfinder.
   - While the viewfinder is open the details under the tabs are hidden
     (.is-camera-idle collapses the check-in card to its tabs) and the
     QR Code Verification card (.is-camera-live) takes all the remaining
     height of the right-hand panel, so the viewfinder fits it exactly:
     the card's own scrolling is switched off, so no scrollbars appear.
   ========================================================= */
.qr-verify-card.is-camera-live .qr-scroll-content{
    overflow:hidden;
}

.qr-camera-close{
    flex:0 0 auto;
    align-self:flex-end;
    margin:8px 0 0;
}

/* ---- "Tap to Scan Student ID QR Code" (Device Camera mode) ----
   Same pill as the other fields, black text, camera icon in front. */
.qr-scan-tap{
    display:flex;
    align-items:center;
    justify-content:center;
    gap:0; /* the icon's own 6px right margin (.btn-icon) is the spacing, like every other button */

    box-sizing:border-box;
    width:100%;
    max-width:100%;
    height:30px;
    margin:14px 0 0;
    padding:0 14px;

    background:#ffffff;
    border:2px solid #0f172b;
    border-radius:999px;

    color:#000000;
    font-family:Poppins, Arial, sans-serif;
    font-size:var(--field-font-size);
    font-weight:700;
    line-height:1;
    text-align:center;

    cursor:pointer;
    user-select:none;
    -webkit-user-select:none;
    -webkit-tap-highlight-color:transparent;
}

.qr-scan-tap:active{
    background:#ececec;
}

.qr-scan-tap .btn-icon{
    flex:0 0 auto;
    color:#000000;
}

.qr-scan-tap[hidden]{
    display:none !important;
}

/* The button styles (.clear-btn etc.) force display:inline-flex !important,
   which overrode the hidden attribute - so a "hidden" button was still shown.
   Close Camera / Scan Next Member now really disappear when hidden. */
.gray-btn[hidden],
.red-btn[hidden],
.clear-btn[hidden],
.pill-btn[hidden]{
    display:none !important;
}

/* ---- Viewfinder: keep its full border (incl. the right edge) inside the card.
   The video was 100% wide PLUS its 2px border, so the right border was pushed
   past the card edge and clipped. */
#scan-widget,
.qr-camera-view{
    box-sizing:border-box;
    width:100%;
    max-width:100%;
    min-width:0;
}

.qr-camera-video{
    box-sizing:border-box;
    display:block;
    width:100%;
    max-width:100%;
}

/* =========================================================
   CHECK-IN NOTE (Individual + Study Table)
   - Styled like the pop-up info panel (.modal-header > p): bordered, no
     fill, bold text, info icon in front.
   - Persistent: the note and Cancel / Done share one footer that is pinned
     to the bottom of the card (solid card background so the fields never
     show through), exactly like the Cancel / Done row was on its own.
   ========================================================= */
.checkin-footer{
    position:sticky;
    bottom:0;
    z-index:5;
    margin:auto 0 0;      /* auto top = bottom of the card when the form is short */
    padding:10px 0 0;
    background:#e5e5e5;
}

.checkin-footer > .buttons{
    position:static;
    margin:0;
    padding:0;
    background:none;
}

.checkin-note{
    display:flex;
    align-items:flex-start;
    gap:8px;

    box-sizing:border-box;
    margin:0 0 8px;
    padding:8px 14px;

    background:transparent;
    border:2px solid #000000;
    border-radius:12px;

    color:#333333;
    font-size:12.5px;
    font-weight:bold;
    line-height:1.4;
    text-align:left;
}

.checkin-note::before{
    content:"";
    flex:0 0 auto;
    width:14px;
    height:14px;
    margin-top:1.75px;               /* centres the icon on the first line of text */
    background-color:currentColor;
    -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4'/%3E%3Cpath d='M12 8h.01'/%3E%3C/svg%3E") center/contain no-repeat;
    mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4'/%3E%3Cpath d='M12 8h.01'/%3E%3C/svg%3E") center/contain no-repeat;
}

.checkin-note-text{
    min-width:0;
}

/* Kiosk Settings: QR Scan Method / Camera to Use as tabs (same tab look as the
   Individual / Study Table tabs); the active tab is the method in use. */
.settings-tabs{
    margin:0 0 6px;
}

/* Admin password pop-up (opens over Kiosk Settings when Save is pressed) */
.kiosk-password-box{
    max-width:360px;
}

/* =========================================================
   ALERT + CONFIRMATION POP-UPS = ADMIN "ARE YOU SURE ..." POP-UPS
   Pattern of the admin system's confirmation pop-ups (.overlay-box.confirm-box,
   e.g. "Close Learning Station"):
     1. a white icon on a red circle at the top centre
     2. the title right below it, centred, red
     3. the message centred below the title: plain text, no box
     4. round (x) at the top right; buttons bottom right (gray Cancel / OK,
        red action), 5px apart
   Applies to:
     - alert pop-ups (missing information, invalid email, check-in failed,
       connection error, closed / closing soon ...) = .result-box.is-admin-alert
     - other confirmations (e.g. Cancel Check-in)   = .confirm-box.is-admin-alert
   NOT applied (kept as they were): the check-in details pop-ups -
   "Confirm Check-in" / "Confirm Group Check-in" and "Check-in Confirmed!".
   ========================================================= */
.modal-overlay .processing-box.is-admin-alert{
    box-sizing:border-box;
    width:420px;
    max-width:90vw;
    padding:0;

    background:#e5e5e5;
    border:2px solid #000000;
    border-radius:20px;

    text-align:center;
}

/* 1. Icon: white on a red circle, top centre (admin .confirm-icon) */
.confirm-box .confirm-icon{
    display:none;
}

.modal-overlay .processing-box.is-admin-alert > .confirm-icon,
.modal-overlay .processing-box.is-admin-alert > .result-icon{
    flex:0 0 auto;
    box-sizing:border-box;
    width:60px;
    height:60px;
    margin:26px auto 0;
    display:flex;
    align-items:center;
    justify-content:center;
    background:#c81d3a;
    color:#ffffff;
    border-radius:50%;
    font-size:0;                    /* the icon is an svg, not a text glyph */
    animation:none;                 /* no pop-in animation, like the admin icon */
}

.modal-overlay .processing-box.is-admin-alert > .confirm-icon .btn-icon,
.modal-overlay .processing-box.is-admin-alert > .result-icon .btn-icon{
    width:28px;
    height:28px;
    min-width:0;
    min-height:0;
    margin:0;
    vertical-align:baseline;
}

/* 2. Title right below the icon, centred (equal left / right padding) */
.modal-overlay .processing-box.is-admin-alert > .modal-header,
.modal-overlay .processing-box.is-admin-alert.result-box > .result-icon + .modal-header,
.modal-overlay .result-box.is-error.is-admin-alert > .modal-header{
    display:block;
    padding:12px 20px 4px;
    text-align:center;
}

.modal-overlay .processing-box.is-admin-alert > .modal-header > h1{
    margin:0;
    padding:0;
    color:#c81d3a;
    font-size:27px;
    line-height:1;
    text-align:center;
}

/* 3. Message: plain centred text */
/* Spacing as in the admin "Close Learning Station" pop-up: title -> message 8px
   (the title's 4px bottom padding + 4px), message -> buttons 14px (4 + 6 + 4 in the
   admin header / body / button row). */
.modal-overlay .processing-box.is-admin-alert > .confirm-message,
.modal-overlay .processing-box.is-admin-alert > .result-message{
    margin:4px 0 0;
    padding:0 20px 10px;
    font-size:14px;
    font-weight:700;
    line-height:1.4;
    color:#333333;
    text-align:center;
    white-space:pre-line;
}

/* 4. (x) and buttons */
.modal-overlay .processing-box.is-admin-alert > .modal-close-btn,
.modal-overlay .processing-box.is-admin-alert .modal-header > .modal-close-btn{
    color:#393939;
}

.modal-overlay .processing-box.is-admin-alert > .modal-close-btn:hover,
.modal-overlay .processing-box.is-admin-alert .modal-header > .modal-close-btn:hover{
    color:#c81d3a;
}

.modal-overlay .processing-box.is-admin-alert > .buttons{
    justify-content:flex-end;
    gap:5px;
    margin:0;
    padding:4px 20px 15px;
}

/* =========================================================
   "CHECK-IN CONFIRMED" + "PROCESSING YOUR CHECK-IN" POP-UPS
   Same admin confirmation pattern as the alert pop-ups above:
   white icon on a red circle at the top centre, red centred title, centred
   message. (Confirmed: a check in the circle - to make that circle green
   instead, set .result-icon.is-success's colour on the .is-admin-alert rule.)
   Processing: a plain (static) white icon in the red circle; no buttons.
   ========================================================= */
#processing-overlay .processing-box{
    box-sizing:border-box;
    width:420px;
    max-width:90vw;
    padding:0 20px 20px;

    background:#e5e5e5;
    border:2px solid #000000;
    border-radius:20px;

    text-align:center;
}

#processing-overlay .processing-spinner{
    position:relative;
    box-sizing:border-box;
    display:flex;
    align-items:center;
    justify-content:center;
    width:60px;
    height:60px;
    margin:26px auto 0;
    border:none;
    border-radius:50%;
    background:#c81d3a;
    color:#ffffff;
    animation:none;                 /* no animation: a plain icon, like the admin pop-ups */
}

#processing-overlay .processing-spinner .btn-icon{
    width:28px;
    height:28px;
    min-width:0;
    min-height:0;
    margin:0;
    vertical-align:baseline;
}

#processing-overlay .processing-box h1{
    margin:12px 0 0;
    padding:0;
    color:#c81d3a;
    font-size:27px;
    line-height:1;
    text-align:center;
}

#processing-overlay .processing-box p{
    margin:8px 0 0;
    font-size:14px;
    font-weight:700;
    line-height:1.4;
    color:#333333;
    text-align:center;
}