* { box-sizing: border-box; }
:root {
  --bg: #f5f4f0;
  --card: #ffffff;
  --red: #ba1f1f;
  --red-dark: #951717;
  --text: #101014;
  --muted: #5e5e66;
  --line: #d9d9de;
  --yellow: #f6d40b;
  --green: #146b38; /* darker than a typical "success green" on purpose — #1a8f4c failed WCAG AA contrast (3.88:1) with white bold button text; this measures ~6.6:1 */
  --green-dark: #0d4d28;
  --yellow-dark: #c9a600;
  --shadow-sm: 0 1px 3px rgba(16, 16, 20, 0.08), 0 1px 2px rgba(16, 16, 20, 0.05);
  /* --shadow-card is the standard elevation for every card-like surface
     app-wide (headers, result cards, dialogs) — restrained on purpose;
     --shadow-md/--shadow-lg are kept only for the few spots that still
     want a stronger lift on hover/selection, not as a resting-state shadow. */
  --shadow-card: 0 2px 8px rgba(16, 16, 20, 0.1), 0 1px 2px rgba(16, 16, 20, 0.05);
  --shadow-md: 0 4px 14px rgba(16, 16, 20, 0.1), 0 1px 3px rgba(16, 16, 20, 0.06);
  --shadow-lg: 0 10px 26px rgba(16, 16, 20, 0.16), 0 2px 6px rgba(16, 16, 20, 0.08);
  --radius-card: 20px;
  --scan-accent: #8ee9ff;
  --scan-accent-strong: #17bbe3;
  --scan-surface: #091724;
}

/* html needs its own background too, not just body's — on a viewport
   taller than the body's content (e.g. a short page, or a rubber-band
   overscroll on mobile), the <html> canvas shows through underneath/
   beyond body, and without this it defaults to the browser's own white
   (or, in dark mode, near-black) — the "thin dark bar along the bottom
   edge" this was reported as. overflow-x hidden guards the same seam
   showing up horizontally if anything ever computes a hair wider than
   the viewport. */
html {
  background: var(--bg);
  margin: 0;
  overflow-x: hidden;
}
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
  /* Clip horizontal overflow without creating a scroll container that traps
     sticky Home and section navigation above a long enrollment form. */
  overflow-x: clip;
  -webkit-tap-highlight-color: transparent;
  /* CONFIRMED ROOT CAUSE of an intermittent mobile-WebKit test failure
     ("Clicking the checkbox did not change its state" on
     #sessions-live-toggle, admin-phase2-devices-sessions.spec.js): with
     no touch-action set and pinch-zoom still enabled (the viewport meta
     tag has no user-scalable=no), WebKit must wait to disambiguate a
     single tap from the start of a double-tap-to-zoom gesture before
     committing to a click — a real, variable delay (observed up to
     ~160ms in this app) between the tap and the resulting native
     checked-state change/'change' event. That's not just test timing —
     it's genuine input latency for every real touch user of this kiosk/
     admin app on iOS Safari. touch-action: manipulation tells the
     browser this page doesn't need that gesture recognition, so taps
     commit immediately; page-level pinch-zoom on non-interactive areas
     is unaffected. */
  touch-action: manipulation;
}

/* Keyboard-only focus indicator — visible and high-contrast, but doesn't
   draw an outline on a mouse/touch tap (only on real keyboard focus). */
:focus-visible {
  outline: 3px solid #1a56db;
  outline-offset: 2px;
  border-radius: 4px;
}
/* main.js/admin.js's showView()/focusHeading() move DOM focus to each new
   view's heading via a plain .focus() call — tabindex="-1" is the ONLY
   place this attribute is ever used in this app (confirmed: grep the
   codebase) — purely so a screen reader announces the view change, the
   same way a real page navigation would land focus near the top of new
   content. A heading is never part of the normal Tab order (tabindex=-1
   guarantees that), so a sighted keyboard user can never land here by
   tabbing — but Chromium/WebKit's own :focus-visible heuristic still
   treats a script-triggered .focus() as "visible", drawing the outline
   on every single view change regardless of input method. Suppressing it
   here is intentionally scoped to exactly that pattern, not a blanket
   focus-outline removal: every real interactive control (buttons, links,
   inputs, selects) keeps the outline above untouched. */
[tabindex="-1"]:focus-visible {
  outline: none;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

#app-shell {
  max-width: 900px;
  margin: 0 auto;
  padding: 20px;
  padding-left: max(20px, env(safe-area-inset-left, 0px));
  padding-right: max(20px, env(safe-area-inset-right, 0px));
  min-height: 100vh; /* fallback for browsers without dvh/svh support */
  min-height: 100dvh; /* correct on mobile Safari — 100vh includes the address bar area and causes layout jumps as it shows/hides */
  /* CONFIRMED on a real iPhone: on first load, dvh can report the LARGER
     value (as if the address bar is already collapsed) before it's
     actually settled, so a min-height:100dvh flex column ends up taller
     than what's really on screen — content pinned to the bottom via
     justify-content:space-between (see .view.active/.kiosk-home-footer)
     lands just below the visible area, with no scroll affordance on a
     kiosk to reveal it. svh (small viewport height) is always the
     SMALLEST possible value regardless of toolbar state, guaranteeing
     the layout fits what's actually visible right now, at the cost of a
     little unused space on the rarer occasions the toolbar is already
     collapsed. Last declaration wins in browsers that support it. */
  min-height: 100svh;
}

.view { display: none; }
.page-home-navigation { display: flex; align-items: center; gap: 12px; position: sticky; top: max(8px, env(safe-area-inset-top, 0px)); z-index: 8; min-height: 44px; margin-bottom: 12px; background: var(--bg); border-radius: 12px; }
.page-home-navigation[hidden] { display: none; }
.page-home-navigation > span { color: var(--muted); font-size: .875rem; }
.home-navigation-button { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 10px 18px; border: 1px solid var(--line); border-radius: 12px; background: #fff; color: var(--text); text-decoration: none; font: inherit; font-weight: 700; cursor: pointer; }
.home-navigation-button svg { width: 20px; height: 20px; }
.has-home-navigation .view.active { min-height: calc(100vh - 96px); min-height: calc(100svh - 96px); }
.admin-page .has-home-navigation .admin-tabs { top: calc(64px + env(safe-area-inset-top, 0px)); }
.view.active {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - 40px);
  min-height: calc(100dvh - 40px);
  min-height: calc(100svh - 40px);
  opacity: 1;
}
@keyframes atl-fade-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes scan-guide-pulse {
  0%, 100% { box-shadow: 0 0 0 1px rgba(142, 233, 255, .2), 0 0 24px rgba(23, 187, 227, .12); }
  50% { box-shadow: 0 0 0 1px rgba(142, 233, 255, .5), 0 0 34px rgba(23, 187, 227, .26); }
}

@keyframes scan-sweep {
  0% { transform: translateX(-130%) rotate(-9deg); }
  100% { transform: translateX(130%) rotate(-9deg); }
}

@keyframes scan-dot-breathe {
  0%, 100% { transform: scale(1); opacity: .95; box-shadow: 0 0 0 0 rgba(134, 236, 255, .55); }
  50% { transform: scale(1.14); opacity: 1; box-shadow: 0 0 0 7px rgba(134, 236, 255, .05); }
}

@keyframes staff-scan-guide-pulse {
  0%, 100% { box-shadow: 0 0 0 1px rgba(255, 255, 255, .18), 0 0 20px rgba(255, 255, 255, .1); }
  50% { box-shadow: 0 0 0 1px rgba(255, 255, 255, .42), 0 0 28px rgba(255, 255, 255, .22); }
}
@keyframes staff-scan-dot-pulse {
  0%, 100% { transform: scale(1); opacity: .95; box-shadow: 0 0 0 0 rgba(255, 255, 255, .5); }
  50% { transform: scale(1.14); opacity: 1; box-shadow: 0 0 0 7px rgba(255, 255, 255, .05); }
}

@keyframes enroll-faceid-ring-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes enroll-faceid-scanline {
  0% { transform: translateY(-120%); opacity: 0; }
  15% { opacity: .86; }
  50% { transform: translateY(8%); opacity: .95; }
  85% { opacity: .84; }
  100% { transform: translateY(132%); opacity: 0; }
}

@keyframes enroll-faceid-focus {
  0%, 100% {
    box-shadow: inset 0 0 0 1px rgba(164, 241, 255, .34), 0 0 0 1px rgba(62, 204, 242, .15), 0 0 24px rgba(35, 193, 229, .26);
  }
  50% {
    box-shadow: inset 0 0 0 1px rgba(164, 241, 255, .56), 0 0 0 1px rgba(109, 230, 255, .3), 0 0 36px rgba(35, 193, 229, .4);
  }
}

@keyframes enroll-faceid-node-glow {
  0%, 100% { opacity: .42; transform: scale(1); }
  50% { opacity: .82; transform: scale(1.1); }
}

.hero-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 16px 20px;
  text-align: center;
  margin-bottom: 16px;
  box-shadow: var(--shadow-card);
}
.chip {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 600;
  background: #fdeaea;
  color: var(--red-dark);
}
.chip-outline {
  background: transparent;
  border: 1.5px solid var(--line);
  color: var(--muted);
}
.on-site-line, .sync-line {
  margin: 8px 0 0;
  font-size: 0.88rem;
  color: var(--muted);
}
.on-site-line:empty, .sync-line:empty { display: none; margin: 0; }
.sync-warn { color: #91720b !important; font-weight: 600; }
.sync-warn::before { content: '⚠ '; }
.brand-row {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 12px;
}
.brand-row.with-actions { justify-content: space-between; }
.brand-logo {
  height: 34px;
  display: block;
}
.brand-logo-link {
  display: block;
  border: none;
  background: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
  line-height: 0;
}
.brand-left {
  font-weight: 700;
  color: var(--red);
  font-size: 1.1rem;
}
/* .hero-card is admin-only now (both kiosk screens have moved to
   .kiosk-page-header/.kiosk-page-title — see below) — same charcoal
   heading treatment as the kiosk redesign, not the old red. */
.hero-card h1 {
  margin: 8px 0 4px;
  font-size: clamp(1.4rem, 4.2vw, 1.9rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
}
.hero-card p { color: var(--muted); margin: 0 0 6px; font-size: 0.95rem; }

/* Every kiosk sub-screen shares .kiosk-topbar (Back pill + site .pill-chip
   — see further down) instead of its own header markup, so branding stays
   identical everywhere without a screen-specific rule set. */

/* Each screen's own heading, now plain text below the compact header
   rather than inside a card. */
.kiosk-page-title {
  margin: 18px 0 4px;
  font-size: clamp(1.4rem, 4vw, 1.9rem);
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.01em;
}
.kiosk-page-sub { margin: 0 0 18px; color: var(--muted); font-size: 0.98rem; }

/* Kiosk setup is a single form-driven task, not a dashboard — constrain
   it to a readable measure and centre it instead of letting the pairing
   code input and status text stretch across the full #app-shell width on
   a wide tablet/desktop. */
#view-kiosk-setup .kiosk-page-title,
#view-kiosk-setup .kiosk-page-sub,
#view-kiosk-setup .form-card {
  max-width: 480px;
  margin-left: auto;
  margin-right: auto;
}
#view-kiosk-setup .kiosk-page-title,
#view-kiosk-setup .kiosk-page-sub { width: 100%; }

/* Visitor form: heading/buttons come SECOND in the markup (so Tab/Enter
   reaches the fields before the submit button — see index.html's own
   comment on this) but sit visually FIRST at every width — the greeting
   coming before the form it introduces, both stacked on mobile and
   side-by-side above 820px. */
#view-visitor-form .kiosk-split-text { order: -1; }
/* Comfortable, easy-to-hit input heights for a kiosk (scoped here rather
   than the shared input/select/textarea rule, which admin — a mouse/
   keyboard back-office tool — doesn't need at this size). */
#view-visitor-form input {
  padding: 14px;
  min-height: 50px;
}
.visitor-field-card { display: flex; flex-direction: column; }
/* Label-above-value field styling — label as a small uppercase caption
   above the value, fields separated by a divider line, rather than each
   field being its own bordered box. */
.visitor-field {
  margin: 0;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.visitor-field:first-child { padding-top: 4px; }
.visitor-field:last-child { border-bottom: none; padding-bottom: 4px; }
.visitor-field input {
  display: block;
  width: 100%;
  margin-top: 4px;
  padding: 2px 0;
  border: none;
  border-radius: 0;
  font-size: 1rem;
  font-weight: 500;
  text-transform: none;
  letter-spacing: normal;
  color: var(--text);
  min-height: 0;
}
.visitor-field input::placeholder { color: #b8b8bd; }

/* ===== Kiosk home =====
   Three groups in a full-height flex column (#view-home.active,
   justify-content:space-between): a top group (header, headcount chips,
   greeting, weather card), a middle group (the two actions), and a
   footer. Every other kiosk sub-screen keeps its own compact
   .kiosk-topbar + .kiosk-footer-bar pattern below, unaffected. */
.kiosk-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 22px;
}
.kiosk-brand-row { display: flex; align-items: center; gap: 10px; min-width: 0; }
.kiosk-brand-row .brand-logo { height: 30px; flex-shrink: 0; }
.kiosk-brand-name { font-weight: 700; font-size: 0.95rem; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Home screen only: the logo image already contains the "Active
   Tunnelling" wordmark, so it's shown alone (no separate text label). */
#view-home .kiosk-brand-row .brand-logo { height: 34px; }

/* Generic pill-shaped badge — the current-site indicator in every kiosk
   screen's top bar. */
.pill-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 40px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0 16px;
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  flex-shrink: 0;
  box-shadow: var(--shadow-sm);
}
.pill-chip::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green);
  flex-shrink: 0;
}
.site-selector {
  min-height: 44px;
  max-width: 65%;
  min-width: 0;
  gap: 8px;
  cursor: pointer;
}
.site-selector-label { overflow: hidden; text-overflow: ellipsis; }
.site-selector svg { width: 20px; height: 20px; flex-shrink: 0; }
.site-selector:hover { border-color: #92929b; }
.site-selector:active { background: #eeedf0; }

/* Generic pill-shaped button — back controls, Cancel, the visitors link,
   "Use a PIN instead", and the visitor form's Sign in button all share
   this base, varying only by color via the modifier classes below. */
.pill-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: none;
  border-radius: 999px;
  padding: 14px 22px;
  font-size: 0.98rem;
  font-weight: 600;
  font-family: inherit;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 100ms ease, box-shadow 100ms ease, border-color 120ms ease;
}
.pill-btn svg { width: 20px; height: 20px; flex-shrink: 0; }
.pill-btn-chevron { width: 16px !important; height: 16px !important; opacity: 0.5; }
.pill-btn:active { transform: scale(0.97); }
.pill-btn-light { background: #fff; border: 1.5px solid var(--line); color: var(--text); }
@media (hover: hover) {
  .pill-btn-light:hover { border-color: #c7c7cc; }
}
.pill-btn-muted { background: #eceaea; border: none; color: var(--text); box-shadow: none; }
@media (hover: hover) {
  .pill-btn-muted:hover { background: #e2e0e0; }
}
.pill-btn-black { background: linear-gradient(165deg, #27272c, #18181b); color: #fff; }

#view-home.active { justify-content: space-between; }
.kiosk-home-top { display: flex; flex-direction: column; gap: 20px; }
.kiosk-home-footer { display: flex; flex-direction: column; gap: 14px; }

/* 2. Headcount chips */
.kiosk-headcount-row { display: flex; gap: 8px; }
.kiosk-headcount-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 34px;
  padding: 0 14px;
  border: none;
  border-radius: 999px;
  background: rgba(28, 28, 30, 0.06);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  /* #6e6e73 (as elsewhere) measures only 4.1:1 once blended against this
     chip's own tinted fill (effectively #e8e7e3, darker than the plain
     page background) — an axe-core "serious" WCAG AA failure (needs
     4.5:1). --muted passes at 5.19:1 on this specific background. */
  color: var(--muted);
  white-space: nowrap;
  cursor: pointer;
}
.kiosk-headcount-chip svg { width: 16px; height: 16px; flex-shrink: 0; }
.kiosk-headcount-number { font-size: 16px; font-weight: 700; color: #1c1c1e; }
@media (hover: hover) {
  .kiosk-headcount-chip:hover { background: rgba(28, 28, 30, 0.1); }
}

/* 3. Greeting */
.kiosk-intro { text-align: left; }
.kiosk-intro h1 {
  margin: 0;
  font-size: 40px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: var(--text);
}
.kiosk-intro-clock {
  margin-top: 6px;
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 17px;
}
.kiosk-intro-clock .kiosk-clock-time { font-weight: 700; color: #1c1c1e; }
.kiosk-intro-clock .kiosk-clock-date { font-weight: 400; color: #6e6e73; }
.kiosk-intro .sync-line { margin-top: 8px; text-align: left; }

/* 4. Weather card — 14px below the date specifically (not the top
   group's general 20px gap, which .kiosk-home-top's own gap already
   provides between the other rows above it). */
.kiosk-weather-card {
  align-items: center;
  gap: 14px;
  margin-top: -6px;
  background: #fff;
  border-radius: 22px;
  padding: 14px 16px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 6px 18px rgba(0, 0, 0, 0.05);
}
.kiosk-weather-icon { width: 44px; height: 44px; flex-shrink: 0; }
.kiosk-weather-icon svg { width: 100%; height: 100%; display: block; }
.kiosk-weather-now { display: flex; flex-direction: column; gap: 2px; flex-shrink: 0; }
.kiosk-weather-temp-row { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.kiosk-weather-temp { font-size: 28px; font-weight: 700; color: #1c1c1e; line-height: 1; }
.kiosk-weather-hilo { font-size: 13px; color: #6e6e73; white-space: nowrap; }
.kiosk-weather-desc { font-size: 14px; color: #6e6e73; }
.kiosk-weather-divider { width: 1px; height: 40px; background: rgba(28, 28, 30, 0.08); flex-shrink: 0; }
.kiosk-weather-forecast { display: flex; flex: 1; justify-content: space-evenly; gap: 8px; min-width: 0; }
.kiosk-weather-forecast-col { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.kiosk-weather-forecast-hour { font-size: 12px; color: #6e6e73; }
.kiosk-weather-forecast-icon { width: 22px; height: 22px; display: block; }
.kiosk-weather-forecast-icon svg { width: 100%; height: 100%; display: block; }
.kiosk-weather-forecast-temp { font-size: 14px; font-weight: 700; color: #1c1c1e; }

/* Middle group: the two actions */
.kiosk-choices { display: flex; flex-direction: column; gap: 12px; }
.staff-choices { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: stretch; }
@media (max-width: 900px) {
  .staff-choices { grid-template-columns: 1fr; }
}

/* The two primary action cards — deliberately neutral (charcoal / white),
   not colour-coded green/red: before either is tapped, signing in and
   signing out are equally valid, everyday choices, not a "safe" option
   and a "danger" option. Colour is reserved for actual status afterwards
   (see .result-icon / .status-badge on the confirmation screens). Same
   fixed size/radius/padding for both — only the fill, text colour and
   shadow tell them apart. */
.action-card {
  border: 1.5px solid transparent;
  border-radius: 28px;
  padding: 20px 24px;
  height: 160px;
  cursor: pointer;
  font-family: inherit;
  display: flex;
  flex-direction: column;
  /* space-between: the icon sits at the top, title/subtitle at the
     bottom, with the card's fixed height giving them room between. */
  justify-content: space-between;
  align-items: flex-start;
  text-align: left;
  transition: transform 150ms cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 150ms ease, border-color 150ms ease;
}
.action-card-icon {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.action-card-icon svg { width: 24px; height: 24px; }
.action-card-text { display: flex; flex-direction: column; gap: 4px; }
.action-card-title { font-size: 30px; font-weight: 700; letter-spacing: -0.01em; }
.action-card-desc { font-size: 15px; font-weight: 500; line-height: 1.35; }

.action-card.clock-in {
  background: linear-gradient(165deg, #27272c, #18181b);
  border-color: #18181b;
  color: #fff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 14px 36px rgba(0, 0, 0, 0.18);
}
.action-card.clock-in .action-card-icon { background: rgba(255, 255, 255, 0.12); color: #fff; }
.action-card.clock-in .action-card-desc { color: rgba(255, 255, 255, 0.62); }

.action-card.clock-out {
  background: #ffffff;
  border-color: var(--line);
  color: #1c1c1e;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 14px 36px rgba(0, 0, 0, 0.06);
}
.action-card.clock-out .action-card-icon { background: rgba(28, 28, 30, 0.06); color: #1c1c1e; }
.action-card.clock-out .action-card-desc { color: #6e6e73; }

.action-card:active { transform: scale(0.98) translateY(1px); }
@media (hover: hover) {
  .action-card:hover { transform: translateY(-2px); }
  .action-card.clock-out:hover { border-color: #c7c7cc; }
}

/* 7. Visitors/deliveries — full-width pill below the two cards. */
.pill-btn-visitor-full {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: 56px;
  padding: 0 18px 0 16px;
  border: none;
  border-radius: 999px;
  background: rgba(28, 28, 30, 0.06);
  font-family: inherit;
  font-size: 17px;
  font-weight: 700;
  color: #1c1c1e;
  cursor: pointer;
}
.pill-btn-visitor-full .icon { display: flex; color: #6e6e73; flex-shrink: 0; }
.pill-btn-visitor-full .pill-btn-chevron { margin-left: auto; color: #6e6e73; opacity: 1; width: 16px !important; height: 16px !important; }
@media (hover: hover) {
  .pill-btn-visitor-full:hover { background: rgba(28, 28, 30, 0.1); }
}

/* Bottom bar shared by every OTHER kiosk sub-screen (not home — see
   .kiosk-home-footer above): the clock/date on the left, context-
   specific secondary links/notes on the right. margin-top:auto (this is
   the last child of a flex column, .view.active) pushes it to the
   bottom of the screen's own height without position:fixed, so it can
   never overlap scrolled content on a short viewport. */
.kiosk-footer-bar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: auto;
  padding-top: 20px;
}
.kiosk-clock-block { line-height: 1; }
.kiosk-clock-time {
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.kiosk-clock-date { margin-top: 3px; font-size: 0.8rem; color: var(--muted); font-weight: 500; }
/* Context-specific note in the right side of a sub-screen's footer bar
   (privacy note, "forgotten your PIN?", consent text). */
.kiosk-footer-note { font-size: 0.8rem; color: var(--muted); text-align: right; max-width: 46ch; }

/* 8. Home's own footer: one centred row of links (the clock/date moved
   up under the greeting, so this footer no longer needs the two-column
   .kiosk-footer-bar layout the other screens use).
   #aeaeb2 (as requested) measures 2:1 against the #f5f4f0 background at
   this font size — an axe-core "serious" WCAG AA failure (needs 4.5:1);
   #6e6e73 is effectively the lightest gray that still passes here, so
   it's reused rather than a paler tone that would fail for anyone with
   low vision. */
.kiosk-footer-links {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 22px;
  font-size: 13px;
  color: #6e6e73;
  padding-bottom: max(4px, env(safe-area-inset-bottom, 0px));
}
.kiosk-footer-links a { color: inherit; text-decoration: none; padding: 10px 2px; margin: -10px -2px; }
.kiosk-footer-links a:hover, .kiosk-footer-links a:active { color: var(--text); }

/* Short viewports (small phones, e.g. 320x568): the default sizes above
   can overflow a short screen. Shrinking here (well above the 44px
   touch-target minimum) keeps the whole home screen visible without
   scrolling. */
@media (max-height: 700px) {
  .kiosk-topbar { margin-bottom: 12px; }
  .kiosk-home-top { gap: 14px; }
  .kiosk-choices { gap: 8px; }
  .staff-choices { gap: 8px; }
  .kiosk-footer-bar { padding-top: 10px; }
}
@media (max-height: 600px) {
  .kiosk-intro h1 { font-size: 32px; }
  .sync-line { font-size: 0.78rem; }
  .kiosk-clock-time { font-size: 1.05rem; }
}

/* Top-anchored on short/phone viewports (header, then the site grid, in
   one continuous flow). On a taller viewport the small header + a handful
   of site cards otherwise leaves a large empty void below them — centering
   the whole block vertically there reads as a balanced, deliberate layout
   instead of content stranded at the top of a mostly-empty screen. */
#view-site.active { padding-top: 6vh; }
@media (min-height: 760px) {
  #view-site.active { padding-top: 0; justify-content: center; }
}

.site-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
.site-card {
  position: relative;
  border: 1.5px solid var(--line);
  background: #fff;
  border-radius: var(--radius-card);
  padding: 20px 14px;
  min-height: 140px;
  font-size: 1.05rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  text-align: center;
  color: var(--text);
  box-shadow: var(--shadow-sm);
  opacity: 0;
  animation: atl-pop-in 320ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
  animation-delay: var(--pop-delay, 0ms);
  transition: transform 150ms cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 150ms ease, border-color 150ms ease;
}
/* One restrained, neutral treatment for every card — no per-card accent
   rotation. A row of same-coloured "stickers" read as more decorative
   than informative; the selected state (below) is what actually needs
   to stand out. */
.site-icon-badge {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: #f0f0f2;
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.site-icon-badge svg { width: 24px; height: 24px; }
.site-name { line-height: 1.25; }
.site-check {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--text);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  font-weight: 700;
  opacity: 0;
  transform: scale(0.4);
  transition: opacity 150ms ease, transform 150ms ease;
}
.site-card:active { transform: scale(0.97); }
@media (hover: hover) {
  .site-card:hover { border-color: #c7c7cc; transform: translateY(-2px); box-shadow: var(--shadow-card); }
}
.site-card.selected { border-color: var(--text); background: #f6f6f7; box-shadow: var(--shadow-card); }
.site-card.selected .site-icon-badge { background: var(--text); color: #fff; }
.site-card.selected .site-check { opacity: 1; transform: scale(1); }

#btn-site-continue {
  margin-top: 18px;
  opacity: 0.5;
  transform: translateY(8px);
  transition: opacity 220ms ease, transform 220ms ease;
}
#btn-site-continue.visible { opacity: 1; transform: translateY(0); }

/* The PIN alternative is always visible and has a full-size touch target. */
.scan-pin-fallback { text-align: center; margin: 16px 0 0; }
.scan-pin-fallback .pill-btn { width: 100%; min-height: 56px; white-space: normal; line-height: 1.4; border: 2px solid #9caabb; background: #fff; color: #263e59; }
.pin-photo-notice { max-width: 440px; margin: 0 auto; padding: 16px 18px; border: 1px solid #cbd7e3; border-radius: 14px; background: #edf3f8; color: #263e59; font-size: .98rem; line-height: 1.55; }
.kiosk-weather-location { margin-top: 2px; color: #526074; font-size: .8rem; line-height: 1.3; }
.pin-footer-note p { margin: 0; }
.pin-privacy-link { display: inline-block; min-height: 44px; margin-top: 4px; padding: 10px 0; border: 0; border-radius: 4px; background: transparent; box-shadow: none; color: #263e59; font: inherit; line-height: 1.45; text-align: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.pin-privacy-link:hover { color: #102945; }
.pin-privacy-link:focus-visible { outline: 3px solid #234c80; outline-offset: 4px; }

/* PIN sign-in (#view-staff-pin) — dots left-align with the rest of the
   left column's text/controls. */
.pin-dots {
  display: flex;
  justify-content: flex-start;
  gap: 18px;
  margin: 4px 0;
}
.pin-dot {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2.5px solid var(--line);
  background: transparent;
  transition: background 120ms ease, border-color 120ms ease;
}
.pin-dot.filled { background: var(--text); border-color: var(--text); }
.pin-keypad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  max-width: 248px;
  /* CONFIRMED ROOT CAUSE of keys rendering at ~36-41px instead of the
     intended size (measured directly on the live site: grid-template-
     columns resolved to "36px 36px 36px" despite max-width:320px above):
     this is a flex item (.view.active is display:flex) with horizontal
     auto margins for centering — but an auto margin on a flex item's
     cross axis is resolved as flex ALIGNMENT, which overrides
     align-items:stretch and leaves the item at its own intrinsic
     (max-content) width instead of filling up to max-width. Explicit
     width:100% restores the intended "stretch up to max-width" sizing;
     the auto margins then correctly compute to 0 instead of centering a
     shrunk box. */
  width: 100%;
  margin: 24px auto 0;
}
.pin-key {
  aspect-ratio: 1 / 1;
  min-height: 64px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  background: #fff;
  font-size: 1.9rem;
  font-weight: 600;
  color: var(--text);
  font-family: inherit;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: border-color 120ms ease, transform 100ms ease;
}
.pin-key:active { transform: scale(0.94); }
@media (hover: hover) {
  .pin-key:hover { border-color: #c7c7cc; }
}
.pin-key-backspace { font-size: 1.5rem; color: var(--muted); }

/* Keeps the keypad comfortably tappable (well above the ~44px touch-target
   floor) without overflowing a short phone in landscape or a small phone
   overall, alongside the header/title/dots/error text also on screen. */
@media (max-height: 700px) {
  .pin-dots { margin: 16px 0 6px; }
  .pin-keypad { max-width: 216px; gap: 12px; margin-top: 14px; }
  .pin-key { min-height: 56px; font-size: 1.6rem; }
}

/* ===== Split layout: sub-screens with a heading/controls column beside a
   camera/keypad/form column (staff scan, PIN, visitor form). Stacked
   (text first, then media) below 820px; side by side above it, matching
   the top bar's same breakpoint as the home screen's own layout switch. */
.kiosk-split {
  display: flex;
  flex-direction: column;
  gap: 28px;
  flex: 1;
  min-height: 0;
}
.kiosk-split-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
}
.kiosk-split-text .kiosk-page-title { margin: 0; }
.kiosk-split-text .kiosk-page-sub { margin: 0; }
.kiosk-split-media { min-width: 0; }
@media (min-width: 820px) {
  .kiosk-split { flex-direction: row; align-items: center; gap: 48px; }
  .kiosk-split-text { flex: 0 0 42%; gap: 18px; }
  .kiosk-split-media { flex: 1; }
}

.footer-link {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  text-align: center;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(transparent, var(--bg) 40%);
}
.footer-link a {
  display: inline-block;
  /* Was color: var(--muted) at opacity: 0.75 — that combination measured
     3.34:1 against the page background under axe-core (WCAG AA needs
     4.5:1 for this text size). Full-opacity var(--muted), the same as
     every other secondary/subtitle text in the app, already passes. */
  color: var(--muted);
  font-size: 0.8rem;
  text-decoration: none;
  /* The visible text stays small on purpose (this is a secondary, rarely
     used link) but the actual tappable area still needs to clear a real
     touch target — padding does that without inflating the text itself. */
  padding: 14px 10px;
  margin: -14px -10px;
  min-height: 44px;
  box-sizing: border-box;
}
.footer-link a:hover, .footer-link a:active { color: var(--text); }
/* keep page content from being hidden behind the fixed footer bar — only
   #view-login and #view-site still use .footer-link; #view-home now ends
   with .kiosk-footer-bar (in-flow, via margin-top:auto), which needs no
   such clearance. */
#view-login, #view-site { padding-bottom: 44px; }

/* Short viewports: a fixed-position footer can't adapt to how tall the
   content above it happens to be — and that height genuinely varies with
   real data (e.g. the on-site-summary line's text length). Rather than
   trying to precisely budget pixels so everything always juuust fits
   (fragile — breaks again the next time any content on this screen
   changes), the footer stops being fixed here and simply becomes the
   last thing on the page, the way a normal footer behaves — guaranteeing
   it can never overlap anything, instead of merely making overlap less
   likely. This must come after the base .footer-link/padding-bottom
   rules above (same selector specificity — later wins), not before. */
@media (max-height: 700px) {
  .footer-link { position: static; background: none; margin-top: 12px; }
  #view-login, #view-site { padding-bottom: 0; }
}

/* Small, secondary, dismissible — installation is a nice-to-have offered
   quietly alongside the main actions, not a full-width bold banner
   competing with Sign in/Sign out for attention. */
.install-banner-row {
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 14px;
}
.install-banner {
  width: auto;
  padding: 8px 16px;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  background: #fff;
  color: var(--text);
  font-weight: 600;
  font-size: 0.85rem;
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.install-banner svg { width: 18px; height: 18px; flex-shrink: 0; }
.install-hint {
  margin: 0;
  padding: 8px 14px;
  border-radius: 999px;
  background: #eef2ff;
  color: #33396b;
  font-size: 0.82rem;
  text-align: center;
}
.install-dismiss {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--muted);
  font-size: 0.9rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
@media (hover: hover) {
  .install-dismiss:hover { background: #e6e6ea; color: var(--text); }
}
/* Buttons */
.btn-red, .btn-yellow, .btn-black, .btn-light, .btn-green {
  border: none;
  border-radius: 14px;
  padding: 14px 18px;
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 100ms ease, opacity 100ms ease, box-shadow 100ms ease;
}
button:active:not(:disabled) { transform: scale(0.97); box-shadow: none; }
.btn-red { background: linear-gradient(155deg, var(--red), var(--red-dark)); color: #fff; }
.btn-yellow { background: linear-gradient(155deg, var(--yellow), var(--yellow-dark)); color: var(--text); }
.btn-black { background: linear-gradient(165deg, #27272c, #18181b); color: #fff; }
.btn-light { background: #fff; color: var(--text); border: 1.5px solid var(--line); box-shadow: none; }
.btn-light:active:not(:disabled) { background: #f6f6f8; }
.btn-green { background: linear-gradient(155deg, #1c8449, var(--green)); color: #fff; }
button:disabled {
  background: #e2e2e6 !important;
  color: #9a9aa2 !important;
  cursor: not-allowed;
  box-shadow: none !important;
  border-color: transparent !important;
}
button.small { padding: 10px 14px; font-size: 0.9rem; }
.btn-block { width: 100%; }
.btn-icon { display: inline-flex; vertical-align: -3px; margin-right: 2px; }
.btn-icon svg { width: 16px; height: 16px; }

/* Admin is a back-office tool, used mostly with a mouse/keyboard on a
   desktop or office tablet — not a walk-up public touchscreen, so its
   buttons don't need the kiosk's oversized touch-target padding. Scoped
   to body.admin-page, which never contains a .kiosk-btn, so this can't
   affect the kiosk screens at all. */
body.admin-page .btn-red,
body.admin-page .btn-yellow,
body.admin-page .btn-black,
body.admin-page .btn-light,
body.admin-page .btn-green {
  padding: 11px 16px;
  font-size: 0.92rem;
}

/* Camera frames follow their container, including narrow tablet columns.
   The guide is an overlay; the live preview itself is never circle-cropped. */
.scan-wrap {
  position: relative;
  width: 100%;
  margin: 0 auto 14px;
  overflow: hidden;
  border: 1px solid #9fb9cd;
  border-radius: 24px;
  background: linear-gradient(180deg, #eaf0f8 0%, #dfe8f1 100%);
  box-shadow: 0 12px 30px rgba(18, 34, 52, .12);
}
.camera-preview {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  max-height: 440px;
  overflow: hidden;
  background: radial-gradient(circle at 20% 14%, #2a4562 0%, #0b1928 62%, #08131f 100%);
}
.camera-preview::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(circle at 50% 6%, rgba(133, 224, 255, .35), transparent 45%), radial-gradient(circle at 50% 115%, rgba(24, 80, 117, .3), transparent 58%);
}
.camera-preview::after {
  content: '';
  position: absolute;
  z-index: 1;
  pointer-events: none;
  top: -24%;
  bottom: -24%;
  left: -28%;
  width: 48%;
  background: linear-gradient(90deg, rgba(255,255,255,0), rgba(147,228,255,.06) 25%, rgba(157,235,255,.34) 50%, rgba(147,228,255,.06) 75%, rgba(255,255,255,0));
  transform: translateX(-130%) rotate(-9deg);
  animation: scan-sweep 3.2s ease-in-out infinite;
  opacity: 0;
}
.scan-wrap video {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scaleX(-1);
  display: block;
}
.scan-guide {
  position: absolute;
  z-index: 2;
  inset: 12% 27% 15%;
  border: 2px solid rgba(169, 236, 255, .92);
  border-radius: 38px;
  box-shadow: 0 0 0 600px rgba(8, 17, 29, .34);
  pointer-events: none;
}
.scan-guide::before {
  content: '';
  position: absolute;
  inset: -8px;
  border-radius: inherit;
  border: 1px solid rgba(178, 240, 255, .6);
  animation: scan-guide-pulse 2.2s ease-in-out infinite;
}
.scan-guide::after {
  content: '';
  position: absolute;
  inset: 12px;
  border-radius: inherit;
  border: 1px solid rgba(211, 247, 255, .38);
}
.scan-hud {
  position: absolute;
  z-index: 3;
  top: 12px;
  left: 12px;
  right: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  pointer-events: none;
}
.scan-hud-pill {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 4px 11px;
  border-radius: 999px;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #e0f7ff;
  background: rgba(7, 20, 31, .54);
  border: 1px solid rgba(157, 232, 255, .36);
  backdrop-filter: blur(6px);
}
.scan-hud-pulse {
  width: 10px;
  height: 10px;
  border-radius: 999px;
  background: #89ebff;
  animation: scan-dot-breathe 1.6s ease-in-out infinite;
}
.scan-status {
  position: relative;
  min-height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 14px 18px;
  background: #fff;
  color: #273343;
  text-align: center;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.4;
  border-top: 1px solid #dfe4eb;
}
.scan-status.scan-status-error { color: #8e2020; background: #fff2f2; }
.scan-status.scan-status-success { color: #125a31; background: #e9f6ef; }
.scan-status.scan-status-connection { color: #694908; background: #fff5d9; }
.scan-wrap-error .scan-guide { opacity: .35; }
.scan-state-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 10px auto 0;
  min-height: 28px;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid #c9d6e4;
  background: #f0f5fb;
  color: #38506a;
  font-size: .78rem;
  font-weight: 650;
  letter-spacing: .01em;
}
/* Dev-only diagnostic (Phase 1.5 SFace test mode) — never shown to ordinary
   workers; see index.html's own comment on #scan-dev-diagnostics. */
.scan-dev-diagnostics {
  margin: 10px auto 0;
  padding: 6px 10px;
  max-width: 100%;
  border-radius: 8px;
  background: #1a1a1a;
  color: #7dffb0;
  font: 11px/1.4 ui-monospace, monospace;
  text-align: center;
  word-break: break-word;
}
#view-staff-scan .camera-preview::after,
.enrollment-capture .scan-wrap[data-capture-state="ready"] .camera-preview::after {
  opacity: .95;
}
#view-staff-scan .scan-status {
  background: linear-gradient(180deg, #1c1c1f 0%, #0e0e0f 100%);
  color: #f2f2f3;
  border-top-color: #2c2c2f;
}
#view-staff-scan .scan-status.scan-status-error { color: #f8d8d8; background: linear-gradient(180deg, #612627 0%, #4d2021 100%); border-top-color: #884143; }
#view-staff-scan .scan-status.scan-status-success { color: #cff6dd; background: linear-gradient(180deg, #165330 0%, #124628 100%); border-top-color: #2d6f4a; }
#view-staff-scan .scan-status.scan-status-connection { color: #ffe8b1; background: linear-gradient(180deg, #5d4518 0%, #4d3a15 100%); border-top-color: #8a6a25; }
#view-staff-scan .scan-state-chip {
  background: linear-gradient(180deg, #1c1c1f 0%, #0e0e0f 100%);
  border-color: #3a3a3d;
  color: #eef0f3;
}
#view-staff-scan .scan-wrap[data-scan-state="starting"] .scan-state-chip { color: #eef0f3; border-color: #4a4a4d; }
#view-staff-scan .scan-wrap[data-scan-state="align"] .scan-guide {
  border-color: rgba(254, 221, 146, .94);
  box-shadow: 0 0 0 520px rgba(0, 0, 0, .68), 0 0 20px rgba(255, 212, 112, .2);
}
#view-staff-scan .scan-wrap[data-scan-state="align"] .scan-state-chip {
  color: #ffe8b0;
  border-color: #7a6133;
}
#view-staff-scan .scan-wrap[data-scan-state="locking"] .scan-guide {
  border-color: rgba(255, 255, 255, .98);
}
#view-staff-scan .scan-wrap[data-scan-state="locking"] .scan-guide::before {
  animation-duration: 1s;
}
#view-staff-scan .scan-wrap[data-scan-state="locking"] .scan-state-chip {
  color: #f2f2f3;
  border-color: #5a5a5d;
}
#view-staff-scan .scan-wrap[data-scan-state="verified"] .scan-guide {
  border-color: rgba(138, 246, 185, .98);
}
#view-staff-scan .scan-wrap[data-scan-state="verified"] .scan-state-chip {
  color: #c6f9d8;
  border-color: #3e7f57;
}
#view-staff-scan .scan-wrap[data-scan-state="error"] .scan-hud-pulse {
  background: #ff968f;
  box-shadow: 0 0 0 0 rgba(255, 122, 112, .35);
}
.camera-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  background: #edf1f5;
  color: #46566a;
  font-size: .95rem;
}
.camera-placeholder svg { width: 44px; height: 44px; }
.scan-wrap[data-capture-state="ready"] .camera-placeholder,
.scan-wrap[data-capture-state="complete"] .camera-placeholder { display: none; }
.scan-wrap[data-capture-state]:is([data-capture-state="idle"], [data-capture-state="starting"], [data-capture-state="paused"], [data-capture-state="error"]) .scan-guide,
.scan-wrap[data-capture-state]:is([data-capture-state="idle"], [data-capture-state="starting"], [data-capture-state="paused"], [data-capture-state="error"]) .enroll-faceid-ring,
.scan-wrap[data-capture-state]:is([data-capture-state="idle"], [data-capture-state="starting"], [data-capture-state="paused"], [data-capture-state="error"]) .enroll-faceid-scanline,
.scan-wrap[data-capture-state]:is([data-capture-state="idle"], [data-capture-state="starting"], [data-capture-state="paused"], [data-capture-state="error"]) .enroll-faceid-complete {
  visibility: hidden;
}
.scan-wrap[data-capture-state]:is([data-capture-state="idle"], [data-capture-state="starting"], [data-capture-state="paused"], [data-capture-state="error"]) video { visibility: hidden; }
.scan-empty-state {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 10px;
  border-radius: 18px;
  background: #fff;
  border: 1px solid var(--line);
  aspect-ratio: 4 / 3;
  margin: 0 auto 14px;
  padding: 28px;
}
.scan-empty-icon {
  width: 56px; height: 56px; border-radius: 50%;
  background: #edf1f5; color: #46566a;
  display: flex; align-items: center; justify-content: center;
}
.scan-empty-icon svg { width: 28px; height: 28px; }
.scan-empty-title { margin: 4px 0 0; font-weight: 650; font-size: 1.1rem; }
.scan-empty-desc { margin: 0; color: var(--muted); font-size: .95rem; max-width: 32ch; }

.tech-details {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 10px 14px;
  margin: 12px 0;
  font-size: 0.85rem;
}
.tech-details summary { cursor: pointer; font-weight: 700; color: var(--muted); }
.tech-details pre {
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 0.75rem;
  background: #f6f6f8;
  border-radius: 10px;
  padding: 10px;
  margin: 10px 0;
  max-height: 240px;
  overflow-y: auto;
}

.result-card {
  background: #fff;
  border-radius: var(--radius-card);
  padding: 26px 24px;
  text-align: center;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-card);
  opacity: 1;
}
@keyframes atl-pop-in {
  from { opacity: 0; transform: scale(0.92); }
  to { opacity: 1; transform: scale(1); }
}
.result-card.match { border-color: var(--green); }
.result-card.out { border-color: var(--red-dark); }
.result-icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 14px;
  opacity: 1;
}
.result-icon svg { width: 32px; height: 32px; }
.result-icon.in { background: #e4f6ec; color: var(--green); }
.result-icon.out { background: #fdeaea; color: var(--red-dark); }
.result-card h2 { margin: 0 0 6px; }
.result-card .status-badge {
  display: inline-block;
  padding: 4px 14px;
  border-radius: 999px;
  font-weight: 700;
  margin-bottom: 10px;
  /* Visual emphasis via CSS, not by writing "CLOCK IN" into the actual
     text content — some screen readers spell out all-caps text letter by
     letter instead of reading it as a word, and the underlying text
     should stay normal sentence case regardless of how it's styled. */
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.status-badge.in { background: #e4f6ec; color: var(--green); }
.status-badge.out { background: #fdeaea; color: var(--red); }
.status-badge.neutral { background: #eef1f4; color: var(--ink); }

/* Forms (visitor / admin) */
.form-card {
  background: #fff;
  border-radius: var(--radius-card);
  padding: 18px;
  margin-bottom: 14px;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}
.form-card h2, .form-card h3 { margin-top: 0; }
#panel-access h2 { font-size: 1.17em; }
.access-invite-option { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }
.access-invite-option h3 { margin-bottom: 8px; font-size: 1rem; }
.setup-account-email { overflow-wrap: anywhere; font-weight: 600; }
#view-setup .form-card, #view-recovery .form-card { max-width: 540px; margin-left: auto; margin-right: auto; }
#btn-setup-login { margin-top: 14px; }
.step-label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text);
  margin: 18px 0 8px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.step-label:first-of-type { margin-top: 4px; padding-top: 0; border-top: none; }
.consent-box {
  background: #fff8e6;
  border: 1px solid #f0deac;
  border-radius: 12px;
  padding: 12px 14px;
  font-weight: 500 !important;
  font-size: 0.9rem !important;
  display: flex !important;
  /* flex-start, not center: center vertically centers the checkbox/radio
     against the FULL height of the label text, which looks fine for a
     one-line label but puts the input next to the middle line of a
     wrapped multi-line one (confirmed on a real device — the Yes/No
     credential options here wrap to 2-3 lines). The 3px margin-top on
     the input below lines its center up with the first line's cap
     height instead of its top edge. */
  align-items: flex-start;
  gap: 10px;
}
.consent-box input[type='checkbox'], .consent-box input[type='radio'] { margin-top: 3px; }

/* Deliberately understated — the PIN opt-out link on the enrollment
   form (see admin.html Step 2) shouldn't look like a real button
   competing with the actual Yes/No choice, just a quiet "here if you
   need it" affordance. */
.link-btn {
  background: none;
  border: none;
  box-shadow: none;
  padding: 0;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: underline;
  cursor: pointer;
}
.link-btn:active:not(:disabled) { opacity: 0.6; }
label { display: block; margin-bottom: 12px; font-weight: 600; font-size: 0.95rem; }
/* Plain native checkboxes (13px, unstyled) are hard to hit accurately on
   a tablet — every checkbox in the app is a consent/toggle the admin
   taps deliberately, so size and brand-color them like the rest of the
   touch targets here instead of leaving browser defaults. */
input[type='checkbox'], input[type='radio'] {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  margin: 0;
  accent-color: var(--red);
  cursor: pointer;
}
input, select, textarea {
  width: 100%;
  margin-top: 6px;
  padding: 12px;
  border-radius: 10px;
  border: 1px solid var(--line);
  font-size: 1rem;
  font-family: inherit;
}
.toggle-row { display: flex; gap: 10px; }
.toggle-row button { flex: 1; transition: background 120ms ease, color 120ms ease; }
.toggle-row button.selected { background: var(--red-dark); color: #fff; }
.toggle-row button.selected.in { background: var(--green); color: #fff; }
.toggle-row button.selected.out { background: var(--red); color: #fff; }

.chip-select-label {
  margin: 0 0 10px;
  font-weight: 600;
  font-size: 0.92rem;
  color: var(--text);
}
.chip-select {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 10px;
}
.chip-option {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px 10px;
  border-radius: 14px;
  border: 2px solid var(--line);
  background: #fff;
  color: var(--text);
  font-weight: 600;
  font-size: 1rem;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease, color 120ms ease, transform 120ms ease;
}
.chip-icon { font-size: 1.3rem; display: flex; }
.chip-icon svg { width: 20px; height: 20px; }
.chip-option:active { transform: scale(0.97); }
@media (hover: hover) {
  .chip-option:not(.selected):hover { border-color: #c7c7cc; }
}
.chip-option.selected {
  border-color: var(--text);
  background: var(--text);
  color: #fff;
}

.field-hint {
  min-height: 1.2em;
  color: var(--red-dark);
  font-weight: 600;
  font-size: 0.88rem;
  margin: -4px 0 0;
}
#caps-lock-hint.field-hint { color: #91720b; margin-bottom: 8px; }
.field-hint.field-hint-success { color: #1f6b3a; }

.password-field { position: relative; display: block; }
.password-field input { padding-right: 64px; }
.password-toggle {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  color: var(--muted);
  font-weight: 700;
  font-size: 0.85rem;
  padding: 6px 10px;
  cursor: pointer;
  min-height: 32px;
}

/* Sign-out: pick your name from who's currently in, instead of retyping
   the whole form you already filled in on the way in. */
.person-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 14px;
}
.person-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  width: 100%;
  text-align: left;
  background: #fff;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-card);
  padding: 14px 16px;
  cursor: pointer;
  font-family: inherit;
  box-shadow: var(--shadow-sm);
  transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}
.person-row-name { font-size: 1.05rem; font-weight: 700; color: var(--text); }
.person-row-sub { font-size: 0.85rem; color: var(--muted); }
.person-row:active { transform: scale(0.98); }
@media (hover: hover) {
  .person-row:hover { border-color: #c7c7cc; box-shadow: var(--shadow-card); }
}
/* Plain, non-interactive variant for the read-only "who's on site" list
   (#onsite-modal-overlay) — same card look, but no pointer/hover/active
   affordance, since tapping a row here does nothing (deliberately: no
   sign-out from this view). */
.person-row.readonly { cursor: default; }
.person-row.onsite-phone-row { display: block; color: var(--text); font-size: 1.1rem; font-weight: 700; text-decoration: none; }
.person-row.readonly:active { transform: none; }
@media (hover: hover) {
  .person-row.readonly:hover { border-color: var(--line); box-shadow: var(--shadow-sm); }
}

.sticky-bar {
  position: sticky;
  bottom: 0;
  display: flex;
  gap: 10px;
  align-items: center;
  background: var(--bg);
  padding: 10px 0 calc(10px + env(safe-area-inset-bottom, 0px));
  margin-top: auto;
}
.sticky-bar .btn-block {
  width: auto;
  flex: 1;
}

/* Admin navigation — a plain-flex icon+label tab bar that scrolls
   horizontally on narrow screens (kept reachable via a sticky top position
   so the active tab is never lost while scrolling a long table) and
   becomes a real left sidebar once there's room, via .admin-layout below.
   Deliberately its own component (not a restyle of the generic
   .toggle-row utility, which is still used for several unrelated button
   rows elsewhere in admin.html/admin.js). */
body.admin-page #app-shell { max-width: 900px; }
@media (min-width: 900px) {
  body.admin-page #app-shell { max-width: 1180px; }
  /* The wider shell above is meant for the tabbed admin dashboard
     (.admin-layout) only — the sign-in screen is a single centered card
     and would look stretched and hard to scan at 1180px. */
  body.admin-page #view-login .hero-card,
  body.admin-page #view-login .form-card {
    max-width: 440px;
    margin-left: auto;
    margin-right: auto;
  }
}

.admin-layout {
  display: flex;
  flex-direction: column;
  gap: 14px;
  flex: 1;
}
@media (min-width: 900px) {
  .admin-layout { flex-direction: row; align-items: flex-start; gap: 24px; }
}

.admin-tabs {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  position: sticky;
  top: 0;
  z-index: 5;
  background: linear-gradient(var(--bg), var(--bg) 70%, transparent);
  padding: 4px 2px 10px;
  margin: 0 -2px;
  /* Fades the last visible tab's trailing edge so a horizontally-scrollable
     bar reads as "more to the right" rather than looking like the full,
     final set of tabs — mask-image degrades harmlessly to a hard edge on
     browsers that don't support it (still scrollable either way). */
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), rgba(0, 0, 0, 0.25));
  mask-image: linear-gradient(to right, #000 calc(100% - 28px), rgba(0, 0, 0, 0.25));
}
.admin-tabs::-webkit-scrollbar { display: none; }
@media (min-width: 900px) {
  .admin-tabs { -webkit-mask-image: none; mask-image: none; }
}
@media (min-width: 900px) {
  .admin-tabs {
    flex-direction: column;
    flex: 0 0 210px;
    position: sticky;
    top: 16px;
    background: none;
    padding: 0;
    overflow-x: visible;
  }
}

.admin-tab-btn {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 9px;
  border: 1.5px solid var(--line);
  background: #fff;
  color: var(--muted);
  border-radius: 12px;
  padding: 10px 14px;
  font-weight: 700;
  font-size: 0.85rem;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
  box-shadow: var(--shadow-sm);
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease, transform 100ms ease;
}
.admin-tab-btn svg { width: 17px; height: 17px; flex-shrink: 0; }
.admin-tab-btn:active { transform: scale(0.97); }
@media (hover: hover) {
  .admin-tab-btn:hover { border-color: #c7c7cc; color: var(--text); }
}
.admin-tab-btn.selected { background: var(--text); border-color: var(--text); color: #fff; }
.admin-tab-btn .tab-sub { opacity: 0.7; font-weight: 600; }
@media (min-width: 900px) {
  .admin-tab-btn { width: 100%; }
}

.admin-content { min-width: 0; flex: 1; }

/* Home and horizontal navigation stay in flow; separate sticky bars obscured staff controls. */
.admin-page .page-home-navigation { position: static; }
@media (max-width: 899px) { .admin-page .admin-tabs { position: static; } }

/* Staff panel sub-tabs (Enrolled staff / Add staff) — kept visually
   lighter than .admin-tab-btn so they read as a level below the main
   admin nav, not a sibling of it. Splitting these apart means opening
   the Staff tab no longer starts the camera + face-api.js detection
   loop unconditionally — that only happens once "Add staff" is
   actually selected, which is what was causing the reported lag when
   an admin just wanted to glance at the roster. */
.sub-tabs { display: flex; gap: 8px; margin-bottom: 14px; }
.sub-tab-btn {
  flex: 0 0 auto;
  border: 1.5px solid var(--line);
  background: #fff;
  color: var(--muted);
  border-radius: 10px;
  padding: 8px 14px;
  font-weight: 700;
  font-size: 0.88rem;
  cursor: pointer;
}
.sub-tab-btn:active { transform: scale(0.97); }
@media (hover: hover) {
  .sub-tab-btn:hover { border-color: #c7c7cc; color: var(--text); }
}
.sub-tab-btn.selected { background: var(--text); border-color: var(--text); color: #fff; }

/* On-site list / dashboard */
.roster-table { width: 100%; min-width: 560px; border-collapse: collapse; background: #fff; border-radius: 14px; overflow: hidden; box-shadow: var(--shadow-sm); }
.roster-table th, .roster-table td { text-align: left; padding: 11px 12px; border-bottom: 1px solid var(--line); font-size: 0.92rem; }
.roster-table th { background: #f6f6f8; font-weight: 700; text-transform: uppercase; font-size: 0.72rem; letter-spacing: 0.03em; color: var(--muted); white-space: nowrap; }
.roster-table tbody tr:hover { background: #fafafc; }
.roster-table tbody tr:last-child td { border-bottom: none; }
/* Every loading/empty/error placeholder row in this app uses a single
   colspan cell spanning the whole table (a real data row never sets
   colspan) — styling that pattern generically gives every table a
   consistent, calmer "nothing to show yet" look without needing a class
   on each one individually. */
.roster-table td[colspan] {
  text-align: center;
  color: var(--muted);
  padding: 22px 12px;
  font-size: 0.9rem;
}
.roster-table tr.long-open { background: #fff8e6; }
.roster-table tr.long-open td:first-child { border-left: 3px solid #b8860b; }
.duration-warning { color: #91720b; font-weight: 700; }
.duration-warning::before { content: '⚠ '; }

.roster-headline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}
.headcount-badge {
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--text);
}
.roster-site-picker { margin-bottom: 0; flex: 1; min-width: 180px; }

.warning-box {
  background: #fff4e0;
  border: 1px solid #e8b94e;
  border-radius: 14px;
  padding: 12px 16px;
  margin-bottom: 14px;
  font-size: 0.9rem;
}
.warning-box strong { color: #8a5a00; display: block; margin-bottom: 6px; }

/* Phase 2 shadow data — visually distinct from .warning-box (amber,
   "something needs attention") since this isn't a warning, it's a
   standing reminder that the whole panel is inert/non-authoritative. */
.shadow-banner {
  background: #eaf1ff;
  border: 1px solid #a9c4f5;
  border-radius: 14px;
  padding: 12px 16px;
  margin-bottom: 14px;
  font-size: 0.9rem;
}
.shadow-banner strong { color: #2a4a8f; display: block; margin-bottom: 4px; }
.pill.shadow { background: #eaf1ff; color: #2a4a8f; }
.pill.pending { background: #f0f0f0; color: #555; }
.pill.revoked { background: #ffe0e0; color: #a02020; }
@media print {
  /* Muster print view: only the muster panel's content is meant to be
     printed during an incident — everything else (nav, other tabs, the
     shadow-data banner itself, action buttons) is noise on a printed
     sign-in sheet. */
  body.printing-muster .no-print {
    display: none !important;
  }
}

.roster-table tr.needs-attention { background: #fff4e0; }

/* Offline muster snapshot warning — deliberately loud (not just another
   .warning-box) since this is a safety-critical "the data on screen may
   not reflect who is actually on site right now" state, and must be
   impossible to miss during a real emergency. Left visible in print
   output on purpose (no .no-print class) — a printed muster taken while
   offline must carry this warning too. */
.offline-banner {
  background: #7a1414;
  color: #fff;
  border-radius: 14px;
  padding: 14px 18px;
  margin-bottom: 14px;
  font-size: 1rem;
  font-weight: 700;
  text-align: center;
}

.pairing-code {
  font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
  font-size: 1.1rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  background: #f6f6f8;
  border-radius: 8px;
  padding: 2px 8px;
  display: inline-block;
}
.roster-table td button + button { margin-left: 6px; }
.pill { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: 0.78rem; font-weight: 700; }
.pill.employee { background: #e8edff; color: #3b4fb0; }
.pill.visitor { background: #fff4d9; color: #806300; }
.pill.lorry { background: #ffe6d9; color: #b0521f; }
/* Active/inactive record status (sites, staff) — kept distinct from
   .pill.employee above (that one marks a roster row's PERSON TYPE, not
   a record's active/inactive status; reusing it here was a coincidence,
   not a shared meaning). */
.pill.active-status { background: #e4f6ec; color: var(--green); }
.pill.inactive-status { background: #f0f0f0; color: #555; }

.toast {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--text);
  color: #fff;
  padding: 12px 20px;
  border-radius: 12px;
  font-weight: 600;
}
.toast.hidden { display: none; }
.muted { color: var(--muted); font-size: 0.85rem; }

.sync-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
  margin-bottom: 14px;
}
.sync-stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: #f6f6f8;
  border-radius: 12px;
  padding: 12px 14px;
}
.sync-stat-label { font-size: 0.78rem; color: var(--muted); font-weight: 600; }
.sync-stat-value { font-size: 1.15rem; font-weight: 700; color: var(--text); }

/* Discard is a one-way, unrecoverable action (the record was never saved
   to the server) — visually distinct from the ordinary btn-light Retry
   next to it, on purpose, so the two are never confused at a glance. */
.btn-discard {
  background: #fdeaea;
  color: var(--red-dark);
  border: 1.5px solid #f3c6c6;
  border-radius: 10px;
  font-weight: 700;
  cursor: pointer;
  padding: 8px 14px;
}
.btn-discard:hover { background: var(--red); color: #fff; border-color: var(--red); }

/* .edit-time-overlay/.edit-time-box (app/admin.js's manual time-
   correction modal) share these rules but are deliberately NOT also
   named .modal-overlay/.modal-box — an existing test
   (admin-sync.spec.js) locates the discard-confirmation modal via the
   bare `.modal-box` selector on the assumption exactly one exists at a
   time; the edit-time modal is permanently present in the DOM (just
   display:none), which would make that a two-element match. */
.modal-overlay, .edit-time-overlay {
  position: fixed;
  inset: 0;
  background: rgba(16, 16, 20, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  z-index: 1000;
}
.modal-box, .edit-time-box {
  background: #fff;
  border-radius: var(--radius-card);
  padding: 22px;
  max-width: 440px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: var(--shadow-md);
}
.modal-box h3, .edit-time-box h3 { margin-top: 0; }
/* Section divider inside the read-only "who's on site" modal (see
   #onsite-modal-overlay), when both staff and visitors are shown
   together — same eyebrow-label treatment as .kiosk-site-label. */
.onsite-modal-section-label {
  margin: 4px 0 -2px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.onsite-modal-section-label:first-child { margin-top: 0; }

/* People on site: the list and contact detail share one bounded dialog. */
#onsite-modal-overlay { padding: 20px; background: rgba(20,22,28,.44); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.modal-box.onsite-modal-box { display: flex; flex-direction: column; gap: 18px; width: 100%; max-width: 600px; max-height: calc(100vh - 40px); max-height: calc(100dvh - 40px); padding: 26px; overflow: hidden; border: 1px solid rgba(255,255,255,.8); border-radius: 28px; box-shadow: 0 24px 80px rgba(16,16,20,.22); }
.onsite-modal-header { display: grid; grid-template-columns: minmax(0, 1fr); gap: 5px; flex-shrink: 0; }
.onsite-modal-header h3 { margin: 2px 0 0; font-size: 1.65rem; font-weight: 700; line-height: 1.18; letter-spacing: -.035em; overflow-wrap: anywhere; }
.onsite-context { margin: 0; color: var(--muted); font-size: .82rem; line-height: 1.45; overflow-wrap: anywhere; }
#btn-onsite-modal-back { display: inline-flex; align-items: center; justify-content: center; justify-self: start; gap: 5px; min-width: 44px; min-height: 44px; margin: 0 0 7px; padding: 10px 12px; border: 0; border-radius: 13px; background: #f0f1f4; color: #3b3e48; font: inherit; font-size: .85rem; font-weight: 650; cursor: pointer; }
#btn-onsite-modal-back[hidden] { display: none; }
#btn-onsite-modal-back svg { width: 18px; height: 18px; }
.onsite-modal-box #onsite-modal-body { display: flex; flex-direction: column; gap: 10px; min-height: 0; margin: -3px; padding: 3px; overflow-y: auto; overscroll-behavior: contain; scrollbar-gutter: stable; }
.onsite-modal-box .onsite-modal-section-label { margin: 14px 4px 2px; color: #666773; font-size: .7rem; font-weight: 700; letter-spacing: .1em; }
.onsite-modal-box .onsite-modal-section-label:first-child { margin-top: 0; }
.person-row.onsite-person-button { display: flex; flex-direction: row; align-items: center; gap: 14px; width: 100%; min-height: 80px; padding: 15px 17px; margin: 0; flex-shrink: 0; border: 1px solid #e4e5e9; border-radius: 18px; background: #fafafb; box-shadow: none; font: inherit; text-align: left; }
button.onsite-person-button { cursor: pointer; }
.onsite-avatar, .staff-detail-avatar { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 46px; height: 46px; border-radius: 15px; background: #e9edf3; color: #40506b; font-size: .96rem; font-weight: 700; letter-spacing: -.03em; }
.onsite-person-text { display: flex; flex-direction: column; gap: 5px; min-width: 0; flex: 1; }
.onsite-person-text .person-row-name { font-size: 1rem; line-height: 1.3; letter-spacing: -.015em; overflow-wrap: anywhere; }
.onsite-person-text .person-row-sub { color: var(--muted); font-size: .78rem; line-height: 1.4; overflow-wrap: anywhere; }
.onsite-chevron { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; flex: 0 0 18px; color: #737987; font-size: 26px; line-height: 1; }
@media (hover: hover) {
  button.onsite-person-button:hover { background: #f4f6f9; border-color: #bfc7d4; box-shadow: none; }
  .person-row.onsite-person-button.readonly:hover { border-color: #e4e5e9; box-shadow: none; }
}
.staff-detail-hero { display: flex; flex-direction: column; align-items: center; padding: 16px 12px 20px; text-align: center; }
.staff-detail-avatar { width: 82px; height: 82px; margin-bottom: 16px; border-radius: 26px; background: linear-gradient(145deg, #e9edf4, #dfe6f0); font-size: 1.75rem; }
.staff-detail-name { margin: 0 0 9px; font-size: clamp(1.55rem, 4.5vw, 2rem); line-height: 1.16; font-weight: 700; letter-spacing: -.04em; overflow-wrap: anywhere; }
.staff-detail-status { display: inline-flex; align-items: center; gap: 7px; margin: 0; padding: 6px 11px; border-radius: 999px; background: #edf4ef; color: #276542; font-size: .76rem; font-weight: 600; line-height: 1.4; }
.staff-detail-status::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.staff-detail-fields { margin: 0; padding: 0 18px; border: 1px solid #e3e5e9; border-radius: 18px; background: #fafafb; }
.staff-detail-fields > div { display: grid; grid-template-columns: minmax(80px, .7fr) minmax(0, 1.6fr); align-items: baseline; gap: 14px; padding: 16px 0; }
.staff-detail-fields > div + div { border-top: 1px solid #e5e6eb; }
.staff-detail-fields dt { color: var(--muted); font-size: .8rem; line-height: 1.5; }
.staff-detail-fields dd { min-width: 0; margin: 0; color: #252832; font-size: .92rem; font-weight: 600; line-height: 1.5; overflow-wrap: anywhere; }
.staff-phone-link { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 48px; padding: 11px 16px; border: 1px solid #c9d5e3; border-radius: 13px; background: #edf3fa; color: #234d80; font-size: 1rem; font-weight: 650; line-height: 1.4; text-decoration: none; overflow-wrap: anywhere; }
.staff-phone-link svg { width: 19px; height: 19px; flex-shrink: 0; }
.staff-phone-link:hover { background: #e1ecf8; border-color: #9eb6d3; text-decoration: underline; }
.onsite-notice { margin: 4px 0; padding: 14px 16px; border: 1px solid #e2e5eb; border-radius: 14px; background: #f4f6f9; color: #535d6d; font-size: .82rem; line-height: 1.55; overflow-wrap: anywhere; }
#btn-onsite-modal-close { flex-shrink: 0; min-height: 48px; margin: 0; border: 1px solid #dedfe5; border-radius: 14px; background: #f0f1f4; color: #383c46; font-weight: 650; }
@media (max-width: 640px) {
  #onsite-modal-overlay { padding: 12px; }
  .modal-box.onsite-modal-box { max-height: calc(100vh - 24px); max-height: calc(100dvh - 24px); gap: 16px; padding: 20px; border-radius: 24px; }
  .onsite-modal-header h3 { font-size: 1.45rem; }
  .person-row.onsite-person-button { min-height: 76px; gap: 11px; padding: 13px; }
  .onsite-avatar { width: 42px; height: 42px; border-radius: 13px; }
  .staff-detail-hero { padding-top: 10px; }
  .staff-detail-fields { padding: 0 14px; }
  .staff-detail-fields > div { grid-template-columns: 1fr; gap: 5px; padding: 13px 0; }
  .staff-phone-link { width: 100%; }
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

#idle-modal-overlay .modal-box > button { margin-top: 12px; }
.modal-summary {
  width: 100%;
  border-collapse: collapse;
  margin: 12px 0;
  font-size: 0.9rem;
}
.modal-summary th {
  text-align: left;
  color: var(--muted);
  font-weight: 600;
  padding: 4px 10px 4px 0;
  vertical-align: top;
  white-space: nowrap;
}
.modal-summary td { padding: 4px 0; word-break: break-word; }

/* Tablet check-in and staff registration */
/* Enrollment controls belong on the preview, where people expect to tap. */
.enrollment-capture { scroll-margin-top: 76px; }
.enrollment-capture .camera-preview { background: #172130; }
.enrollment-capture .camera-placeholder { background: #edf2f7; color: #263e59; gap: 18px; padding: 32px; text-align: center; }
.enrollment-capture .camera-placeholder svg { width: 66px; height: 66px; padding: 15px; border-radius: 20px; background: #fff; box-shadow: 0 5px 18px #263e5914; }
.enrollment-capture .camera-placeholder span { font-size: 1.12rem; font-weight: 700; }
.camera-start-surface { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2; border: 0; border-radius: inherit; background: transparent; cursor: pointer; color: #263e59; }
.camera-start-surface:focus-visible { outline: 3px solid #234c80; outline-offset: -6px; }
.camera-start-surface[hidden], .camera-stop-control[hidden] { display: none; }
.camera-stop-control { position: absolute; right: 12px; top: 12px; z-index: 2; border: 1px solid #ffffff60; border-radius: 999px; background: #172130e8; color: white; padding: 10px 16px; min-height: 44px; font-weight: 600; }
.capture-steps { display: none; position: absolute; z-index: 2; bottom: 14px; left: 50%; transform: translateX(-50%); gap: 7px; padding: 8px 10px; background: rgba(7, 17, 27, .62); border: 1px solid rgba(166, 220, 241, .34); border-radius: 999px; backdrop-filter: blur(8px); }
.capture-steps span { display: block; width: 12px; height: 12px; border: 1px solid rgba(221, 241, 249, .6); border-radius: 999px; color: transparent; font-size: 0; background: rgba(255, 255, 255, .16); box-shadow: inset 0 1px 2px rgba(8, 17, 29, .4); }
.capture-steps .captured { border-color: transparent; background: linear-gradient(180deg, #9af1ff, #19bde5); box-shadow: 0 0 12px rgba(137, 236, 255, .9); }
.scan-wrap[data-capture-state="ready"] .capture-steps { display: flex; }
.scan-wrap[data-capture-state="complete"] .camera-start-surface { inset: 12px 12px auto auto; width: auto; height: auto; min-height: 44px; padding: 10px 14px; border: 1px solid #c2d5ca; border-radius: 999px; background: white; font-weight: 600; }
button { font-family: inherit; }
.section-eyebrow { margin: 0 0 8px; color: #556274; font-size: .78rem; font-weight: 750; letter-spacing: .09em; text-transform: uppercase; }
.result-topbar .brand-logo { height: 52px; width: auto; max-width: 34%; object-fit: contain; }
.identity-conflict { padding: 28px; border: 2px solid #c13b3b; border-radius: 20px; background: #fff4f3; color: #55211f; }
.identity-conflict[hidden] { display: none; }
.identity-conflict h2 { margin-top: 0; }
.identity-conflict p { line-height: 1.6; }
.identity-error-icon { display: grid; place-items: center; width: 44px; height: 44px; margin-bottom: 16px; border-radius: 50%; background: #ae2525; color: #fff; font-size: 28px; font-weight: 800; }
#view-staff-scan .kiosk-split { width: 100%; max-width: 620px; margin: 8px auto 24px; flex: 0 0 auto; flex-direction: column; gap: 20px; }
#view-staff-scan .kiosk-split-text { flex: initial; align-items: center; text-align: center; gap: 8px; }
#view-staff-scan .kiosk-split-text .kiosk-page-title { font-size: clamp(1.8rem, 3vw, 2.4rem); }
#view-staff-scan .kiosk-split-media { width: 100%; }
#view-staff-scan .scan-wrap {
  --staff-scan-video-zoom: 1;
  --staff-scan-video-pan-x: 0px;
  --staff-scan-video-pan-y: 0px;
  --staff-scan-guide-size: min(66%, 244px);
  --staff-scan-guide-center-y: 54%;
}
#view-staff-scan .scan-wrap video {
  transform: translate(var(--staff-scan-video-pan-x), var(--staff-scan-video-pan-y)) scaleX(-1) scale(var(--staff-scan-video-zoom));
  transform-origin: center center;
  transition: transform 180ms cubic-bezier(.18, .78, .22, 1);
  will-change: transform;
}
#view-staff-scan .camera-preview {
  background: radial-gradient(circle at 50% 16%, #1e1e21 0%, #0a0a0b 60%, #050505 100%);
}
#view-staff-scan .camera-preview::before {
  background: radial-gradient(circle at 50% 8%, rgba(255, 255, 255, .1), transparent 46%), radial-gradient(circle at 50% 118%, rgba(255, 255, 255, .04), transparent 60%);
}
#view-staff-scan .camera-preview::after {
  background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.05) 25%, rgba(255,255,255,.2) 50%, rgba(255,255,255,.05) 75%, rgba(255,255,255,0));
}
#view-staff-scan .scan-guide {
  inset: auto;
  top: var(--staff-scan-guide-center-y);
  left: 50%;
  /* Height derives from width via aspect-ratio, not a second percentage,
     so the guide stays a true circle instead of an ellipse. */
  width: var(--staff-scan-guide-size);
  height: auto;
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border-color: rgba(255, 255, 255, .82);
  box-shadow: 0 0 0 520px rgba(0, 0, 0, .68);
}
#view-staff-scan .scan-guide::before {
  inset: -9px;
  border-radius: 50%;
  border-color: rgba(255, 255, 255, .4);
  animation-name: staff-scan-guide-pulse;
}
#view-staff-scan .scan-guide::after {
  inset: 14px;
  border-radius: 50%;
  border-color: rgba(255, 255, 255, .18);
}
#view-staff-scan .scan-hud-pill {
  color: #f4f4f5;
  background: rgba(12, 12, 13, .6);
  border-color: rgba(255, 255, 255, .26);
}
#view-staff-scan .scan-hud-pulse {
  background: #f4f4f5;
  animation-name: staff-scan-dot-pulse;
}
#view-staff-scan #btn-staff-cancel { padding: 8px 18px; min-height: 44px; background: transparent; color: #526074; font-size: .9rem; }
#view-staff-scan .kiosk-footer-bar { margin-top: auto; padding-top: 12px; }
#view-staff-scan .scan-pin-fallback { margin: 16px auto 0; text-align: center; }
#view-staff-result.active { opacity: 1; }
.staff-confirm-panel { width: min(100%, 600px); margin: auto; border: 1px solid #d7dee6; border-radius: 24px; background: #fff; box-shadow: 0 10px 32px rgba(25,40,60,.07); overflow: hidden; }
#view-staff-result .result-card { border: 0; border-radius: 0; padding: 30px 28px 18px; box-shadow: none; opacity: 1; }
#view-staff-result .result-icon { width: 76px; height: 76px; margin: 22px auto 18px; background: #edf1f6; color: #40546b; opacity: 1; }
#staff-result-name { font-size: clamp(1.8rem, 4vw, 2.5rem); line-height: 1.15; overflow-wrap: anywhere; }
#staff-result-badge { margin: 14px 0 4px; }
#staff-result-sub { font-size: 1rem; line-height: 1.5; }
.pin-audit-camera { width: min(100%, 360px); margin: 20px auto 0; padding: 0 0 14px; overflow: hidden; border: 1px solid #cbd4df; border-radius: 16px; background: #f4f7fa; }
.pin-audit-camera[hidden], #btn-pin-audit-retry[hidden] { display: none; }
#pin-audit-video { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: contain; background: #172130; }
#pin-audit-camera-status { margin: 12px 16px 0; color: #33445a; font-size: .95rem; line-height: 1.5; }
#btn-pin-audit-retry { min-height: 44px; margin-top: 12px; }
#pin-privacy-modal-overlay { padding: 16px; }
#pin-privacy-modal-overlay[hidden] { display: none; }
#pin-privacy-modal-overlay .pin-privacy-notice { display: flex; flex-direction: column; width: min(100%, 680px); max-width: 680px; max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); padding: clamp(20px, 4vw, 32px); text-align: left; overflow: hidden; }
#pin-privacy-title { flex: 0 0 auto; margin: 0 0 20px; color: #172130; font-size: clamp(1.15rem, 3vw, 1.45rem); line-height: 1.4; overflow-wrap: anywhere; }
.pin-privacy-body { min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 2px 8px 2px 2px; }
.pin-privacy-body section + section { margin-top: 22px; }
.pin-privacy-body h3 { margin: 0 0 8px; font-size: 1rem; line-height: 1.5; color: #172130; }
.pin-privacy-body p { margin: 0; color: #3f4b5a; font-size: 1rem; line-height: 1.65; }
.pin-privacy-body:focus-visible { outline: 2px solid #234c80; outline-offset: -2px; }
#btn-pin-privacy-close { flex: 0 0 auto; min-height: 48px; margin-top: 24px; }
.history-row-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.audit-photo-action { white-space: nowrap; }
.audit-photo-overlay { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; padding: 16px; z-index: 1000; background: rgba(16, 24, 34, .62); }
.audit-photo-overlay[hidden], #audit-photo-figure[hidden] { display: none; }
.audit-photo-box { width: min(100%, 720px); max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); overflow-y: auto; padding: clamp(20px, 4vw, 32px); border-radius: 20px; background: #fff; box-shadow: var(--shadow-md); }
#audit-photo-title { margin: 0 0 12px; font-size: 1.5rem; line-height: 1.3; }
#audit-photo-context { margin: 0 0 12px; line-height: 1.5; overflow-wrap: anywhere; }
.audit-photo-guidance { margin: 0 0 18px; color: #526074; font-size: .95rem; line-height: 1.5; }
#audit-photo-status { color: #33445a; line-height: 1.5; }
#audit-photo-figure { margin: 0; }
#audit-photo-image { display: block; width: 100%; max-height: 56vh; max-height: 56dvh; object-fit: contain; border-radius: 12px; background: #172130; }
#audit-photo-figure figcaption { margin: 10px 0 0; color: #526074; font-size: .9rem; }
#btn-audit-photo-close { min-height: 48px; margin-top: 20px; }

/* Home dashboard: ATL surfaces, with attendance first and local weather below. */
#app-shell.home-dashboard-shell { --home-top-space: max(24px, env(safe-area-inset-top, 0px)); max-width: 1180px; padding-top: var(--home-top-space); }
#view-home.active { justify-content: flex-start; gap: 24px; min-height: calc(100vh - var(--home-top-space, 24px) - 20px); min-height: calc(100svh - var(--home-top-space, 24px) - 20px); }
#view-home .kiosk-home-top { gap: 22px; }
#view-home .kiosk-topbar { margin-bottom: 0; }
#view-home .kiosk-brand-row .brand-logo { height: 40px; width: auto; }
.home-intro-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(330px, 420px); align-items: start; gap: 20px; }
#view-home .kiosk-intro h1 { font-size: clamp(28px, 3vw, 36px); line-height: 1.12; }
#view-home .kiosk-intro-clock { margin-top: 8px; }
#view-home .sync-line:empty { display: none; }
.home-dashboard.kiosk-choices { display: block; }
.home-presence-card { appearance: none; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-rows: auto auto; align-content: center; align-items: center; align-self: start; gap: 6px 18px; width: 100%; min-width: 0; min-height: 88px; padding: 18px 20px; border: 1px solid #dedee3; border-radius: 22px; background: #fafafa; color: var(--text); box-shadow: 0 2px 4px rgba(16,16,20,.025); font: inherit; text-align: left; cursor: pointer; transition: transform 160ms ease, border-color 160ms ease, box-shadow 160ms ease; }
.home-presence-heading { grid-column: 2; grid-row: 1; font-size: .88rem; line-height: 1.35; color: #414149; font-weight: 650; }
.home-presence-total { grid-column: 1; grid-row: 1 / 3; display: block; margin: 0; font-size: 36px; font-weight: 650; letter-spacing: -.055em; line-height: 1; font-variant-numeric: tabular-nums; }
.home-presence-breakdown { grid-column: 2; grid-row: 2; display: flex; flex-wrap: wrap; gap: 3px 12px; margin: 0; color: var(--muted); font-size: .75rem; line-height: 1.5; }
.home-presence-breakdown > span { display: inline-flex; gap: 4px; min-width: 0; }
.home-presence-breakdown strong { color: inherit; font-size: inherit; font-weight: 500; font-variant-numeric: tabular-nums; }
.home-presence-action { grid-column: 3; grid-row: 1 / 3; display: flex; flex-direction: column; align-items: flex-end; gap: 8px; color: #51515a; font-size: .8rem; font-weight: 600; white-space: nowrap; }
.home-presence-action svg { width: 19px; height: 19px; }
.home-presence-card:active { transform: scale(.985); }
@media (hover: hover) {
  .home-presence-card:hover { border-color: #bfc0c9; background: #fff; }
}
#view-home .staff-choices { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-areas: 'signin signout' 'visitors visitors'; gap: 18px; min-width: 0; }
#view-home .action-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: 1fr auto; align-items: end; height: auto; min-height: 292px; padding: 32px; border-radius: 28px; gap: 28px 18px; }
#view-home .action-card-text { grid-column: 1; grid-row: 2; min-width: 0; gap: 8px; }
#view-home .action-card-title { font-size: clamp(44px, 5vw, 58px); font-weight: 700; line-height: 1.06; letter-spacing: -.045em; }
#view-home .action-card-desc { font-size: 1rem; line-height: 1.4; }
#view-home .action-card-icon { grid-column: 1; grid-row: 1; align-self: start; width: 64px; height: 64px; border-radius: 20px; }
#view-home .action-card-icon svg { width: 34px; height: 34px; }
#view-home .action-card-arrow { grid-column: 2; grid-row: 2; align-self: center; width: 26px; height: 26px; color: #7b7b83; }
#view-home .action-card.clock-in { grid-area: signin; color: #fff; background: linear-gradient(145deg, #2c2d32, #191a1e); border-color: #292b2f; box-shadow: 0 3px 6px rgba(16,16,20,.05), 0 12px 26px rgba(16,16,20,.11); }
#view-home .action-card.clock-in .action-card-icon { color: #fff; background: rgba(255,255,255,.1); }
#view-home .action-card.clock-in .action-card-desc { color: #dedfe3; }
#view-home .action-card.clock-in .action-card-arrow { color: #c6c7cd; }
#view-home .action-card.clock-out, #view-home .action-card.visitor-action { background: #fff; color: var(--text); border-color: #dedee3; box-shadow: 0 2px 4px rgba(16,16,20,.03), 0 10px 24px rgba(16,16,20,.035); }
#view-home .action-card.clock-out { grid-area: signout; }
#view-home .action-card.clock-out .action-card-icon, #view-home .action-card.visitor-action .action-card-icon { color: #34343d; background: #f1f1f4; }
#view-home .action-card.clock-out .action-card-desc, #view-home .action-card.visitor-action .action-card-desc { color: var(--muted); }
#view-home .action-card.visitor-action { grid-area: visitors; display: flex; flex-direction: row; justify-content: flex-start; align-items: center; gap: 16px; min-height: 108px; padding: 22px 24px; border-radius: 22px; }
#view-home .action-card.visitor-action .action-card-text { flex: 1; gap: 5px; }
#view-home .action-card.visitor-action .action-card-title { font-size: clamp(22px, 2.4vw, 28px); letter-spacing: -.035em; line-height: 1.15; }
#view-home .action-card.visitor-action .action-card-desc { font-size: .85rem; }
#view-home .action-card.visitor-action .action-card-icon { align-self: center; width: 44px; height: 44px; border-radius: 14px; }
#view-home .action-card.visitor-action .action-card-icon svg { width: 24px; height: 24px; }
#view-home .action-card.visitor-action .action-card-arrow { flex: 0 0 18px; width: 18px; height: 18px; }
#view-home .kiosk-weather-card { display: grid; grid-template-columns: minmax(160px, .85fr) minmax(150px, .8fr) minmax(290px, 1.6fr); align-items: center; gap: 12px 20px; margin: 0; padding: 16px 22px 12px; border: 1px solid var(--line); border-radius: var(--radius-card); box-shadow: var(--shadow-card); }
.home-weather-conditions { display: flex; align-items: center; gap: 12px; min-width: 0; }
#view-home .kiosk-weather-now { min-width: 0; flex-shrink: 1; gap: 4px; }
#view-home .kiosk-weather-temp-row { flex-wrap: wrap; gap: 6px 8px; }
#view-home .kiosk-weather-temp { font-size: 28px; color: #1c1c1e; }
#view-home .kiosk-weather-desc { font-size: .85rem; line-height: 1.35; color: var(--muted); }
#view-home .kiosk-weather-location { color: #526074; font-size: .8rem; line-height: 1.3; }
#view-home .kiosk-weather-hilo { font-size: .75rem; color: var(--muted); }
#view-home .kiosk-weather-forecast { align-self: stretch; align-items: center; gap: 16px; padding: 0 16px; border-left: 1px solid #e4e5e8; border-right: 1px solid #e4e5e8; }
#view-home .kiosk-weather-forecast-hour { font-size: .72rem; color: var(--muted); }
#view-home .kiosk-weather-forecast-col { gap: 6px; }

@keyframes weather-icon-breathe { 0%, 100% { transform: scale(1) translateY(0); } 50% { transform: scale(1.06) translateY(-1px); } }
@keyframes weather-forecast-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-2px); } }
#view-home .kiosk-weather-icon { width: 56px; height: 56px; }
#view-home .kiosk-weather-forecast-icon { width: 28px; height: 28px; }
#view-home .kiosk-weather-icon svg, #view-home .kiosk-weather-forecast-icon svg { overflow: visible; filter: drop-shadow(0 3px 3px rgba(64, 86, 105, .2)); }
#view-home .weather-sun circle, #view-home .weather-partly-cloudy circle { animation: weather-icon-breathe 4s ease-in-out infinite; transform-origin: center; }
#view-home .weather-sun g { animation: weather-sun-rays 12s linear infinite; transform-origin: center; }
#view-home .weather-moon, #view-home .weather-partly-cloudy-night path:first-child { animation: weather-moon-float 5s ease-in-out infinite; transform-origin: center; }
#view-home .weather-partly-cloudy path, #view-home .weather-partly-cloudy-night path:last-child, #view-home .weather-cloud path, #view-home .weather-rain path:first-child, #view-home .weather-snow path:first-child, #view-home .weather-thunderstorm path:first-child { animation: weather-cloud-drift 5s ease-in-out infinite; transform-origin: center; }
#view-home .weather-rain g, #view-home .weather-snow g { animation: weather-precipitation-fall 2.4s ease-in-out infinite; }
#view-home .weather-fog g { animation: weather-fog-slide 4s ease-in-out infinite; }
#view-home .weather-thunderstorm path:last-child { animation: weather-lightning-flicker 3.5s ease-in-out infinite; }
#view-home .kiosk-weather-forecast-icon svg { animation: weather-forecast-float 3.6s ease-in-out infinite; }
#view-home .kiosk-weather-forecast-col:nth-child(2) .kiosk-weather-forecast-icon svg { animation-delay: .4s; }
#view-home .kiosk-weather-forecast-col:nth-child(3) .kiosk-weather-forecast-icon svg { animation-delay: .8s; }
@keyframes weather-sun-rays { to { transform: rotate(360deg); } }
@keyframes weather-moon-float { 0%, 100% { transform: translate(0, 0) rotate(-1deg); } 50% { transform: translate(0, -1px) rotate(1deg); } }
@keyframes weather-cloud-drift { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(1px); } }
@keyframes weather-precipitation-fall { 0%, 100% { transform: translateY(-1px); opacity: .78; } 50% { transform: translateY(1px); opacity: 1; } }
@keyframes weather-fog-slide { 0%, 100% { transform: translateX(-1px); opacity: .78; } 50% { transform: translateX(1px); opacity: 1; } }
@keyframes weather-lightning-flicker { 0%, 82%, 100% { opacity: .92; } 85% { opacity: .2; } 88% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { #view-home .kiosk-weather-icon svg, #view-home .kiosk-weather-forecast-icon svg, #view-home .kiosk-weather-icon svg *, #view-home .kiosk-weather-forecast-icon svg * { animation: none !important; } }
.home-wind-panel { min-width: 0; }
.home-wind-heading { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 10px; }
.home-wind-label { font-size: .8rem; color: var(--muted); }
.home-wind-value { color: var(--text); font-size: 1.55rem; line-height: 1.15; font-weight: 750; font-variant-numeric: tabular-nums; }
.home-wind-status { display: flex; align-items: center; gap: 7px; margin: 8px 0 12px; font-size: .88rem; font-weight: 700; line-height: 1.4; color: #465469; }
.home-wind-status::before { content: ''; width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; background: currentColor; }
.kiosk-weather-card[data-wind-state="below"] .home-wind-status { color: var(--green); font-size: 1rem; }
.kiosk-weather-card[data-wind-state="restricted"] .home-wind-status { color: #915500; }
.kiosk-weather-card[data-wind-state="stop"] .home-wind-status { color: var(--red-dark); }
.home-wind-gauge { position: relative; height: 7px; margin: 0 7px; border-radius: 7px; background: linear-gradient(to right, #1f9d55 0% 34.5%, #fff 34.5% 35.5%, #d68b17 35.5% 69.5%, #fff 69.5% 70.5%, #bd5252 70.5% 100%); }
.home-wind-marker { position: absolute; left: 0; top: 50%; width: 16px; height: 16px; border: 3px solid #fff; border-radius: 50%; background: #20242a; box-shadow: 0 0 0 1px #20242a; transform: translate(-50%, -50%); }
.home-wind-marker[hidden] { display: none; }
.home-wind-limits { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 11px; color: var(--muted); font-size: .7rem; line-height: 1.5; }
.home-wind-limits span { display: flex; flex-wrap: wrap; gap: 2px 6px; }
.home-wind-limits strong { color: #3e4752; font-size: .76rem; white-space: nowrap; }
.home-wind-basis { margin: 8px 0 0; color: var(--muted); font-size: .72rem; line-height: 1.45; }
.kiosk-weather-card:is([data-wind-state="below"], [data-wind-state="restricted"], [data-wind-state="stop"]) .home-wind-basis { display: none; }
.home-weather-footnote { grid-column: 1 / -1; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 16px; padding-top: 8px; border-top: 1px solid #ebebee; color: var(--muted); font-size: .7rem; line-height: 1.5; }
.home-weather-footnote p { margin: 0; }
.home-weather-footnote p:first-child { display: flex; flex-wrap: wrap; gap: 2px 12px; }
#view-home .kiosk-home-footer { margin-top: auto; }
#view-home .kiosk-footer-links a { min-height: 44px; display: inline-flex; align-items: center; }
@media (max-width: 940px) {
  #view-home .kiosk-weather-card { grid-template-columns: 1fr 1fr; }
  #view-home .kiosk-weather-forecast { border-right: 0; }
  .home-wind-panel { grid-column: 1 / -1; padding-top: 16px; border-top: 1px solid #e4e5e8; }
  .home-wind-heading { float: left; margin-right: 20px; }
  .home-wind-status { margin-top: 3px; }
  .home-wind-gauge { clear: both; }
  .home-wind-limits { font-size: .76rem; }
}
@media (min-width: 700px) and (max-height: 900px) {
  #view-home.active { gap: 16px; }
  #view-home .kiosk-home-top { gap: 14px; }
  #view-home .kiosk-intro h1 { font-size: 30px; }
  #view-home .staff-choices { gap: 16px; }
  #view-home .action-card { min-height: 272px; padding: 28px 30px; gap: 24px 18px; }
  #view-home .action-card-title { font-size: clamp(44px, 4.6vw, 54px); }
  #view-home .action-card.visitor-action { min-height: 100px; padding: 20px 24px; gap: 16px; }
  #view-home .action-card.visitor-action .action-card-title { font-size: 24px; }
  .home-presence-card { min-height: 88px; padding: 18px 20px; }
  #view-home .kiosk-weather-card { padding: 14px 20px 10px; gap: 10px 18px; }
  .home-weather-footnote { padding-top: 10px; }
}
@media (max-width: 699px) {
  #view-home.active { gap: 20px; }
  .home-intro-row { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  #view-home .kiosk-home-top { gap: 20px; }
  #view-home .kiosk-brand-row .brand-logo { height: 34px; }
  #view-home .kiosk-intro-clock { flex-wrap: wrap; gap: 4px 8px; }
  #view-home .staff-choices { grid-template-columns: minmax(0, 1fr); grid-template-areas: 'signin' 'signout' 'visitors'; gap: 14px; }
  #view-home .action-card { min-height: 192px; padding: 24px; gap: 18px; border-radius: 24px; }
  #view-home .action-card-title { font-size: clamp(40px, 10vw, 48px); }
  #view-home .action-card-desc { font-size: .9rem; }
  #view-home .action-card-icon { width: 46px; height: 46px; border-radius: 15px; }
  #view-home .action-card-icon svg { width: 26px; height: 26px; }
  #view-home .action-card-arrow { width: 22px; height: 22px; }
  #view-home .action-card.visitor-action { min-height: 104px; padding: 20px; gap: 14px; }
  #view-home .action-card.visitor-action .action-card-title { font-size: 22px; }
  .home-presence-card { min-height: 82px; gap: 5px 12px; padding: 16px 18px; border-radius: 20px; }
  .home-presence-total { font-size: 32px; }
  .home-presence-breakdown { gap: 2px 10px; font-size: .75rem; }
  .home-presence-action { font-size: .75rem; }
  #view-home .kiosk-weather-card { padding: 20px 18px 16px; gap: 16px 10px; grid-template-columns: 1fr 1fr; }
  .home-weather-conditions { flex-direction: column; align-items: flex-start; gap: 8px; }
  #view-home .kiosk-weather-temp { font-size: 26px; }
  #view-home .kiosk-weather-forecast { gap: 10px; padding: 0 0 0 12px; }
  .home-wind-heading { float: none; margin: 0; }
  .home-wind-status { margin: 10px 0 14px; }
  .home-wind-value { font-size: 1.5rem; }
  .home-wind-limits { font-size: .7rem; }
  .home-weather-footnote { font-size: .7rem; }
}
/* Short landscape screens (e.g. 10-11" Android tablets): fit the whole home screen in one view, no scrolling. */
@media (min-width: 700px) and (max-height: 820px) {
  #app-shell.home-dashboard-shell { --home-top-space: max(10px, env(safe-area-inset-top, 0px)); padding-bottom: 10px; }
  #view-home.active { gap: 10px; height: calc(100svh - var(--home-top-space, 10px) - 10px); min-height: 0; }
  #view-home .kiosk-home-top { gap: 8px; }
  #view-home .kiosk-brand-row .brand-logo { height: 30px; }
  .home-intro-row { gap: 12px; }
  #view-home .kiosk-intro h1 { font-size: 24px; }
  #view-home .kiosk-intro-clock { margin-top: 2px; }
  .home-presence-card { min-height: 0; padding: 8px 14px; gap: 2px 12px; border-radius: 16px; }
  .home-presence-total { font-size: 28px; }
  .home-dashboard.kiosk-choices { display: block; flex: 0 0 auto; }
  #view-home .staff-choices { grid-template-rows: auto auto; gap: 10px; }
  #view-home .action-card { min-height: clamp(150px, 32svh, 240px); padding: 16px 22px; gap: 8px 14px; border-radius: 22px; }
  #view-home .action-card-icon { width: 44px; height: 44px; border-radius: 14px; }
  #view-home .action-card-icon svg { width: 24px; height: 24px; }
  #view-home .action-card-title { font-size: clamp(32px, 4.4vw, 42px); }
  #view-home .action-card-desc { font-size: .85rem; }
  #view-home .action-card.visitor-action { min-height: 0; padding: 10px 18px; border-radius: 18px; }
  #view-home .action-card.visitor-action .action-card-title { font-size: 20px; }
  #view-home .action-card.visitor-action .action-card-icon { width: 36px; height: 36px; border-radius: 12px; }
  #view-home .action-card.visitor-action .action-card-icon svg { width: 20px; height: 20px; }
  #view-home .kiosk-weather-card { grid-template-columns: minmax(140px, .8fr) minmax(120px, .7fr) minmax(230px, 1.5fr); padding: 8px 16px 6px; gap: 4px 14px; }
  #view-home .kiosk-weather-forecast { border-right: 1px solid #e4e5e8; }
  #view-home .kiosk-weather-icon { width: 38px; height: 38px; }
  #view-home .kiosk-weather-forecast-icon { width: 22px; height: 22px; }
  #view-home .kiosk-weather-temp { font-size: 22px; }
  #view-home .kiosk-weather-desc, #view-home .kiosk-weather-location { font-size: .75rem; line-height: 1.25; }
  .home-wind-panel { grid-column: auto; padding-top: 0; border-top: 0; }
  .home-wind-heading { float: none; margin: 0; }
  .home-wind-value { font-size: 1.2rem; }
  .home-wind-status { margin: 3px 0 6px; font-size: .8rem; }
  .home-wind-limits { margin-top: 5px; font-size: .68rem; }
  .home-wind-basis, .home-weather-footnote p:first-child { display: none; }
  .home-weather-footnote { padding-top: 4px; font-size: .66rem; line-height: 1.3; }
  #view-home .kiosk-footer-links a { min-height: 32px; }
}
.staff-confirm-actions { position: static; flex-direction: column-reverse; gap: 10px; padding: 8px 28px 28px; background: #fff; }
.staff-confirm-actions button { width: 100%; min-height: 54px; }
.staff-confirm-actions #btn-staff-confirm { width: 100%; flex: none; }
.staff-confirm-actions #btn-staff-again { border-color: transparent; background: transparent; box-shadow: none; color: #4b5868; }
.result-topbar { margin-bottom: 24px; }
.enrollment-heading { margin: 8px 0 16px; }
.enrollment-outcome[hidden], #enroll-form[hidden], .enrollment-outcome-check[hidden] { display: none; }
.enrollment-outcome { max-width: 720px; padding: clamp(24px, 5vw, 44px); border: 1px solid #b6d8c6; background: #f4fbf7; }
.enrollment-outcome-icon { width: 64px; height: 64px; display: grid; place-items: center; margin-bottom: 24px; border-radius: 50%; background: #dcefe3; color: #17673d; font-size: 2.2rem; font-weight: 700; }
.enrollment-outcome h2 { margin: 8px 0 12px; font-size: clamp(1.5rem, 4vw, 2rem); line-height: 1.2; overflow-wrap: anywhere; }
.enrollment-outcome p { line-height: 1.6; }
.enrollment-outcome[data-outcome="uncertain"] { background: #fffbf1; border-color: #e0cc9d; }
.enrollment-outcome[data-outcome="uncertain"] .enrollment-outcome-icon { background: #f3e7c8; color: #785710; }
.enrollment-outcome-check { display: flex; align-items: flex-start; gap: 12px; padding: 16px; border: 1px solid #dfd3b7; border-radius: 12px; background: #fff; margin: 24px 0; }
.enrollment-outcome-check input { flex-shrink: 0; width: 22px; height: 22px; margin: 2px 0 0; }
.enrollment-outcome-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 24px; }
.enrollment-outcome-actions button { min-height: 48px; flex: 1 1 220px; }
.enrollment-heading h2 { margin: 0 0 8px; font-size: 1.6rem; letter-spacing: -.035em; }
.enrollment-heading > p:last-child { margin: 0; }
.enrollment-grid { display: grid; gap: 20px; align-items: start; }
.enrollment-grid .form-card { margin: 0; padding: 20px; border-radius: 18px; box-shadow: none; min-width: 0; }
.enrollment-grid h3 { display: flex; align-items: center; gap: 10px; margin: 0 0 18px; font-size: 1.1rem; }
.step-number { display: inline-flex; width: 28px; height: 28px; align-items: center; justify-content: center; border-radius: 8px; background: #edf0f4; color: #47566a; font-size: .85rem; }
.enrollment-fields { display: grid; gap: 0 14px; }
.label-optional { font-size: .8rem; color: #657083; font-weight: 400; }
.enrollment-consent { border-top: 1px solid #e4e7ec; margin-top: 10px; padding-top: 20px; }
.enrollment-consent h4 { margin: 0 0 8px; font-size: 1rem; }
.enrollment-consent > p { font-size: .9rem; line-height: 1.5; margin: 0 0 14px; }
.enrollment-consent .consent-box { background: #f6f8fb; border-color: #d9e0e9; padding: 14px; margin-bottom: 6px; font-size: .9rem !important; line-height: 1.5; }
.enrollment-consent .consent-box:has(input:checked) { border-color: #596d86; background: #edf2f8; }
.enrollment-consent input[type="radio"] { flex-shrink: 0; width: 20px; height: 20px; accent-color: #283d58; }
.enrollment-consent .link-btn { margin: 4px 0; padding: 10px 0; min-height: 44px; font-size: .85rem; }
.capture-instruction { margin: -8px 0 16px; color: #5d6878; font-size: .92rem; line-height: 1.5; }
.enrollment-capture .scan-wrap {
  margin-bottom: 14px;
  --enroll-faceid-size: min(66%, 176px);
  --enroll-faceid-center-y: 62%;
  --enroll-video-zoom: 1;
  --enroll-video-pan-x: 0px;
  --enroll-video-pan-y: 0px;
}
.enrollment-capture .camera-preview {
  max-height: 310px;
  background: radial-gradient(circle at 50% 20%, #121926 0%, #05080f 58%, #020307 100%);
}
.enrollment-capture .camera-preview::before {
  background: radial-gradient(circle at 50% 50%, rgba(122, 198, 255, .14) 0%, rgba(122, 198, 255, .03) 40%, rgba(5, 9, 16, .86) 66%, rgba(2, 3, 8, .95) 100%);
}
.enrollment-capture .camera-preview::after { display: none; }
.enrollment-capture .scan-wrap video {
  clip-path: circle(calc(var(--enroll-faceid-size) / 2) at 50% var(--enroll-faceid-center-y));
  transform: translate(var(--enroll-video-pan-x), var(--enroll-video-pan-y)) scaleX(-1) scale(var(--enroll-video-zoom));
  transform-origin: center center;
  transition: transform 180ms cubic-bezier(.18, .78, .22, 1);
  will-change: transform;
}
.enrollment-capture .scan-hud {
  z-index: 7;
}
.enrollment-capture .scan-hud-pill {
  color: #d8ffe9;
  background: rgba(6, 13, 10, .62);
  border-color: rgba(99, 255, 173, .48);
}
.enrollment-capture .scan-hud-pulse {
  background: #54f7b0;
  box-shadow: 0 0 0 0 rgba(84, 247, 176, .35);
}
.enrollment-capture .enroll-faceid-ring {
  position: absolute;
  z-index: 4;
  top: var(--enroll-faceid-center-y);
  left: 50%;
  width: calc(var(--enroll-faceid-size) + 56px);
  height: calc(var(--enroll-faceid-size) + 56px);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  pointer-events: none;
}
.enrollment-capture .enroll-faceid-ring span {
  position: absolute;
  top: 0;
  left: 0;
  width: 4px;
  height: 12px;
  border-radius: 999px;
  background: rgba(114, 158, 134, .25);
  opacity: .95;
  transform: translate(-50%, -50%);
  transform-origin: center center;
  transition: background-color 140ms ease, box-shadow 140ms ease, opacity 140ms ease;
}
.enrollment-capture .enroll-faceid-ring span.filled {
  background: #62ffb5;
  opacity: 1;
  box-shadow: 0 0 7px rgba(98, 255, 181, .65);
}
.enrollment-capture .scan-wrap[data-capture-state="complete"] .enroll-faceid-ring span {
  background: #62ffb5;
  opacity: 1;
  box-shadow: 0 0 7px rgba(98, 255, 181, .72);
}
.enrollment-capture .scan-guide {
  inset: auto;
  top: var(--enroll-faceid-center-y);
  left: 50%;
  width: var(--enroll-faceid-size);
  height: var(--enroll-faceid-size);
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border: 0;
  box-shadow: 0 0 0 400px rgba(2, 5, 10, .84);
  animation: none;
  z-index: 3;
}
.enrollment-capture .scan-guide::before {
  display: none;
}
.enrollment-capture .scan-guide::after {
  display: none;
}
.enroll-faceid-scanline {
  position: absolute;
  z-index: 5;
  inset: auto;
  top: var(--enroll-faceid-center-y);
  left: 50%;
  width: var(--enroll-faceid-size);
  height: var(--enroll-faceid-size);
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
}
.enroll-faceid-scanline::before {
  content: '';
  position: absolute;
  left: 10%;
  right: 10%;
  top: 0;
  height: 30%;
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(146, 233, 255, 0), rgba(146, 233, 255, .82), rgba(146, 233, 255, 0));
  animation: enroll-faceid-scanline 2.6s cubic-bezier(.4, 0, .2, 1) infinite;
}
.enrollment-capture .scan-wrap[data-capture-state="ready"] .enroll-faceid-scanline { opacity: 1; }
.enrollment-capture .scan-wrap[data-capture-state="error"] .scan-hud-pulse { background: #ff9d95; box-shadow: 0 0 0 0 rgba(255, 122, 112, .35); }
.enrollment-capture .scan-wrap[data-capture-state="complete"] .scan-hud-pulse { background: #6bf7ba; box-shadow: 0 0 0 0 rgba(84, 247, 176, .3); }
.enrollment-capture .enroll-faceid-complete {
  position: absolute;
  z-index: 6;
  left: 50%;
  bottom: 16px;
  transform: translate(-50%, 8px) scale(.96);
  opacity: 0;
  min-height: 30px;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid rgba(109, 255, 183, .55);
  background: rgba(6, 20, 13, .7);
  color: #bcffd9;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  transition: opacity 180ms ease, transform 180ms ease;
  pointer-events: none;
}
.enrollment-capture .scan-wrap[data-capture-state="complete"] .enroll-faceid-complete {
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
}
.enrollment-capture .camera-stop-control,
.enrollment-capture .scan-wrap[data-capture-state="complete"] .camera-start-surface {
  z-index: 8;
}
.enrollment-capture .scan-status { font-size: .88rem; min-height: 52px; padding: 12px; }
.capture-progress-row { display: flex; justify-content: space-between; gap: 12px; font-size: .86rem; color: #2c435a; }
.capture-progress { height: 8px; margin: 10px 0 16px; border-radius: 999px; overflow: hidden; background: linear-gradient(180deg, #e6edf5, #d5e1ec); border: 1px solid #c2d2e2; }
.capture-progress > span { display: block; height: 100%; width: var(--capture-progress, 0%); background: linear-gradient(90deg, #74e4ff 0%, #18bde5 45%, #0c95bf 100%); box-shadow: 0 0 14px rgba(23, 187, 227, .6); transition: width 200ms ease; }
.enrollment-capture .capture-steps {
  display: none !important;
  position: absolute;
  z-index: 3;
  bottom: 18px;
  left: 50%;
  transform: translateX(-50%);
  gap: 10px;
  padding: 8px 14px;
  background: rgba(8, 19, 31, .44);
  border: 1px solid rgba(151, 227, 255, .35);
  border-radius: 999px;
  backdrop-filter: blur(6px);
}
.enrollment-capture .capture-steps span {
  width: 10px;
  height: 10px;
  border: 1px solid rgba(174, 233, 255, .55);
  border-radius: 999px;
  color: transparent;
  font-size: 0;
  background: rgba(208, 243, 255, .18);
  box-shadow: none;
  opacity: .42;
  animation: enroll-faceid-node-glow 1.9s ease-in-out infinite;
}
.enrollment-capture .capture-steps span:nth-child(2) { animation-delay: .08s; }
.enrollment-capture .capture-steps span:nth-child(3) { animation-delay: .16s; }
.enrollment-capture .capture-steps span:nth-child(4) { animation-delay: .24s; }
.enrollment-capture .capture-steps span:nth-child(5) { animation-delay: .32s; }
.enrollment-capture .capture-steps span:nth-child(6) { animation-delay: .4s; }
.enrollment-capture .capture-steps .captured {
  border-color: rgba(132, 252, 194, .95);
  background: radial-gradient(circle at 35% 30%, #ceffe8 0%, #4af3ad 55%, #1ebf79 100%);
  box-shadow: 0 0 10px rgba(72, 244, 169, .7);
  opacity: 1;
  animation: none;
}
.enrollment-capture .scan-wrap[data-capture-state="ready"] .capture-steps { display: flex; }
.enrollment-save { border-top: 1px solid #e4e7ec; margin-top: 16px; padding-top: 14px; }
.enrollment-save #enroll-error:empty { display: none; }
.enrollment-review { padding: 16px; margin-bottom: 16px; border: 1px solid #d2dae6; border-radius: 12px; background: #f3f6fa; }
.enrollment-review[hidden] { display: none; }
.enrollment-review.is-error { border: 2px solid #c13b3b; background: #fff4f3; color: #55211f; }
.enrollment-review.is-error h4::before { content: '!'; display: inline-grid; place-items: center; width: 28px; height: 28px; margin-right: 8px; border-radius: 50%; background: #ae2525; color: #fff; font-weight: 800; }
.enrollment-capture.has-review-error #emp-face-section { display: none !important; }
.staff-contact { display: block; overflow-wrap: anywhere; }
.enrollment-save button[hidden] { display: none; }
#enroll-signin[hidden] { display: none; }
#enroll-signin button { margin-top: 12px; }
#enroll-signin label { overflow-wrap: anywhere; }
#enroll-signin-error { margin-top: 12px; }
#enroll-signin-error:empty { display: none; }
.enrollment-review h4 { margin: 0 0 10px; }
.enrollment-review p { font-size: .9rem; line-height: 1.5; }
.enrollment-review > button { margin-top: 10px; }
.enrollment-save #save-hint { margin: 0 0 12px; font-size: .88rem; line-height: 1.5; }
.enrollment-grid button { min-height: 46px; }
.enrollment-grid label { font-size: .9rem; }
#view-admin > .hero-card { text-align: left; padding: 20px 24px; border-radius: 16px; box-shadow: none; }
#view-admin > .hero-card h1 { font-size: 1.3rem; margin: 0 0 4px; letter-spacing: -.03em; }
#view-admin .brand-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 20px; margin: 0; }
#admin-access-label { margin: 0; font-size: .9rem; }
#view-admin .admin-tabs .admin-tab-btn { box-shadow: none; }
@media (min-width: 700px) {
  .enrollment-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); }
  #view-staff-scan .kiosk-split { max-width: 580px; }
}
@media (min-width: 1100px) { .enrollment-fields { grid-template-columns: 1fr 1fr; } }
@media (max-width: 699px) {
  #view-admin > .hero-card { padding: 16px; }
  #view-admin .brand-row { grid-template-columns: minmax(0, 1fr) auto; gap: 12px; }
  #view-admin .brand-logo-link { display: none; }
  .enrollment-grid .form-card { padding: 20px; }
  .staff-confirm-actions { padding: 8px 20px 20px; }
  #view-staff-result .result-card { padding: 24px 20px 12px; }
}
@media (min-width: 820px) and (max-height: 900px) {
  #view-staff-scan .kiosk-split { max-width: 620px; margin-top: 0; }
  #view-staff-scan .kiosk-split-text { align-items: center; text-align: center; }
  #view-staff-scan .camera-preview { max-height: 400px; }
  .enrollment-capture .camera-preview { max-height: 230px; }
}

/* Concise enrolment help and an unmistakable primary roster action. */
.enrollment-phone-field { min-width: 0; }
.enrollment-phone-field > label { margin-bottom: 4px; }
.enrollment-privacy-details { margin: 0 0 14px; color: #606a79; font-size: .78rem; line-height: 1.45; }
.enrollment-privacy-details summary { cursor: pointer; min-height: 32px; display: list-item; padding: 6px 0; color: #46566b; text-decoration: underline; text-underline-offset: 3px; }
.enrollment-privacy-details p { margin: 4px 0 0; }
.enrollment-field-error { display: block; margin: 6px 0 0; color: #a82323; font-size: .8rem; font-weight: 500; line-height: 1.4; }
.enrollment-field-error[hidden] { display: none; }
.enrollment-grid #emp-company { text-transform: uppercase; letter-spacing: .03em; }
.enrollment-grid [aria-invalid="true"] { border-color: #bd3333; }
.roster-actions { display: flex; align-items: center; gap: 10px; }
.roster-actions .roster-clock-out { min-height: 44px; white-space: nowrap; }
.roster-actions .roster-edit-time { min-height: 44px; border-color: transparent; background: transparent; box-shadow: none; color: #535b68; white-space: nowrap; }
.roster-actions .roster-edit-time:hover { background: #f0f1f4; }

/* Every screen after Home: one slim top row (Home, Back, site chip) instead of two stacked bars. */
#app-shell { position: relative; }
#app-shell.has-home-navigation .page-home-navigation { position: absolute; top: 20px; left: max(20px, env(safe-area-inset-left, 0px)); z-index: 8; margin: 0; min-height: 44px; }
.page-home-navigation > span { display: none; }
#app-shell.has-home-navigation .kiosk-topbar { padding-left: 128px; min-height: 44px; margin-bottom: 8px; }
/* Admin pages have their own header with the logo: keep Home above it, in flow. */
.admin-page #app-shell.has-home-navigation .page-home-navigation { position: static; margin: 0 0 12px; }
.has-home-navigation .view.active { min-height: calc(100svh - 40px); }
/* Face scan: chip over the camera, clear Cancel and PIN buttons. */
#view-staff-scan .scan-state-chip { position: absolute; left: 14px; bottom: 64px; z-index: 3; margin: 0; }
#view-staff-scan #btn-staff-cancel { min-height: 48px; padding: 10px 24px; border: 1px solid #c9d0d9; background: #fff; font-size: 1rem; font-weight: 600; color: #34404f; }
#view-staff-scan .scan-pin-fallback { margin-top: 2px; }
#view-staff-scan .scan-pin-fallback .pill-btn { width: auto; min-height: 44px; padding: 8px 22px; font-size: .95rem; }

/* MatePad-class landscape tablets (about 1280x776 or 960x560): one slim top row and
   side-by-side layouts so no kiosk screen needs scrolling. */
@media (min-width: 820px) and (max-height: 820px) {

  #view-staff-scan .kiosk-split { flex-direction: row; align-items: center; max-width: none; margin: 0; gap: 32px; flex: 1 1 auto; }
  #view-staff-scan .kiosk-split-text { flex: 0 0 30%; align-items: flex-start; text-align: left; gap: 10px; }
  #view-staff-scan .kiosk-split-media { flex: 1; display: flex; flex-direction: column; align-items: center; }
  #view-staff-scan .scan-wrap { max-width: 680px; margin-bottom: 8px; --staff-scan-guide-size: min(60%, 300px); }
  #view-staff-scan .camera-preview { aspect-ratio: auto; height: clamp(200px, calc(100svh - 290px), 500px); max-height: none; }
  #view-staff-scan .scan-state-chip { position: absolute; left: 14px; bottom: 64px; z-index: 3; margin: 0; }
  #view-staff-scan .kiosk-split-text .kiosk-page-title { font-size: 2.6rem; }
  #view-staff-scan .kiosk-split-text .kiosk-page-sub { font-size: 1.15rem; line-height: 1.4; }
  #view-staff-scan #btn-staff-cancel { min-height: 48px; padding: 10px 24px; border: 1px solid #c9d0d9; background: #fff; font-size: 1rem; font-weight: 600; color: #34404f; }
  #view-staff-scan .scan-pin-fallback { margin-top: 2px; }
  #view-staff-scan .scan-pin-fallback .pill-btn { min-height: 44px; padding: 8px 22px; font-size: .95rem; }
  #view-staff-scan .kiosk-footer-bar { padding-top: 6px; }
  .kiosk-footer-bar { padding-top: 6px; }

  #view-staff-pin .kiosk-split, #view-visitor-form .kiosk-split { gap: 32px; }
  #view-staff-pin .pin-keypad { max-width: 236px; gap: 10px; margin-top: 8px; }
  #view-staff-pin .pin-key { min-height: 56px; font-size: 1.6rem; }
  #view-staff-pin .pin-photo-notice { margin: 0 0 6px; padding: 10px 14px; font-size: .85rem; }
  #view-staff-pin .pin-dots { margin: 12px 0 4px; }
  .visitor-field { padding: 4px 16px; }
  #view-visitor-form .kiosk-split-text { gap: 10px; }

  #view-kiosk-setup.active { flex-direction: row; flex-wrap: wrap; align-content: flex-start; column-gap: 20px; }
  #view-kiosk-setup > .kiosk-topbar, #view-kiosk-setup .kiosk-page-title, #view-kiosk-setup .kiosk-page-sub, #view-kiosk-setup > .footer-link { flex: 0 0 100%; }
  #view-kiosk-setup .kiosk-page-title, #view-kiosk-setup .kiosk-page-sub { max-width: none; margin: 0 0 6px; }
  #view-kiosk-setup .form-card { flex: 1 1 calc(50% - 10px); max-width: none; margin: 0 0 12px; padding: 16px 18px; }

  #view-staff-result.active .staff-confirm-panel { margin: 0 auto; }
  #view-staff-result .result-card { padding: 18px 24px 8px; }
  .staff-confirm-actions { padding: 6px 24px 18px; gap: 6px; }
  .staff-confirm-actions button { min-height: 50px; }
}

/* Home on a MatePad-height screen: spread the groups over the height instead of leaving a gap at the bottom. */
@media (min-width: 820px) and (min-height: 700px) and (max-height: 820px) {
  #view-home.active { justify-content: space-between; }
  #view-home .kiosk-home-footer { margin-top: 0; }
  #view-home .kiosk-weather-card { padding: 12px 20px 8px; gap: 6px 18px; }
  #view-home .kiosk-weather-icon { width: 52px; height: 52px; }
  #view-home .kiosk-weather-temp { font-size: 32px; }
  #view-home .kiosk-weather-desc, #view-home .kiosk-weather-location { font-size: .85rem; }
  #view-home .kiosk-weather-forecast-icon { width: 30px; height: 30px; }
  #view-home .kiosk-weather-forecast-hour { font-size: .8rem; }
  #view-home .kiosk-weather-forecast-temp { font-size: 1rem; }
  .home-wind-value { font-size: 1.5rem; }
  .home-wind-status { font-size: .9rem; margin: 4px 0 8px; }
  .home-wind-limits { font-size: .78rem; }
  .home-weather-footnote { font-size: .74rem; }
  #view-home .action-card-title { font-size: clamp(44px, 4.6vw, 54px); }
}

/* Portrait tablets: a taller camera so the face fills the guide. */
@media (min-width: 700px) and (orientation: portrait) {
  #view-staff-scan .kiosk-split { max-width: 680px; }
  #view-staff-scan .camera-preview { aspect-ratio: 4 / 5; max-height: 62svh; }
}

/* Staff scan: corner brackets instead of a circular target. The colour tells the story:
   white while searching, amber when the face needs adjusting, green once identified. */
#view-staff-scan .scan-wrap .scan-guide {
  --b: rgba(255, 255, 255, .92);
  --t: 5px;
  --l: 44px;
  inset: 9% 20%;
  top: 9%;
  left: 20%;
  width: auto;
  height: auto;
  aspect-ratio: auto;
  transform: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background:
    linear-gradient(var(--b), var(--b)) top left / var(--l) var(--t) no-repeat,
    linear-gradient(var(--b), var(--b)) top left / var(--t) var(--l) no-repeat,
    linear-gradient(var(--b), var(--b)) top right / var(--l) var(--t) no-repeat,
    linear-gradient(var(--b), var(--b)) top right / var(--t) var(--l) no-repeat,
    linear-gradient(var(--b), var(--b)) bottom left / var(--l) var(--t) no-repeat,
    linear-gradient(var(--b), var(--b)) bottom left / var(--t) var(--l) no-repeat,
    linear-gradient(var(--b), var(--b)) bottom right / var(--l) var(--t) no-repeat,
    linear-gradient(var(--b), var(--b)) bottom right / var(--t) var(--l) no-repeat;
  transition: --b 200ms ease;
  filter: drop-shadow(0 0 6px rgba(0, 0, 0, .55));
}
#view-staff-scan .scan-wrap .scan-guide::before,
#view-staff-scan .scan-wrap .scan-guide::after { display: none; }
#view-staff-scan .scan-wrap[data-scan-state="align"] .scan-guide { --b: rgba(254, 214, 120, .98); box-shadow: none; }
#view-staff-scan .scan-wrap[data-scan-state="locking"] .scan-guide { --b: rgba(255, 255, 255, 1); box-shadow: none; animation: staff-bracket-pulse 1s ease-in-out infinite; }
#view-staff-scan .scan-wrap[data-scan-state="verified"] .scan-guide { --b: rgba(110, 240, 165, 1); box-shadow: none; }
#view-staff-scan .scan-wrap[data-scan-state="error"] .scan-guide { --b: rgba(255, 140, 130, .95); box-shadow: none; }
@keyframes staff-bracket-pulse { 50% { transform: scale(1.03); } }
@media (prefers-reduced-motion: reduce) { #view-staff-scan .scan-wrap[data-scan-state="locking"] .scan-guide { animation: none; } }
@media (min-width: 700px) and (orientation: portrait) { #view-staff-scan .scan-wrap .scan-guide { inset: 9% 14%; top: 9%; left: 14%; } }

/* Access tab: site agents with one or more sites, global administrators */
.access-role, .access-sites { border: 1px solid var(--line); border-radius: 14px; padding: 10px 14px 12px; margin: 0 0 14px; }
.access-role legend, .access-sites legend { padding: 0 6px; font-weight: 700; }
.access-role { display: flex; flex-wrap: wrap; gap: 8px 22px; }
.access-site-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 6px 16px; }
.access-choice { display: flex; align-items: center; gap: 8px; min-height: 40px; font-weight: 600; cursor: pointer; }
.access-choice input { width: 20px; height: 20px; margin: 0; accent-color: var(--red); }
.access-sites-cell { min-width: 180px; }
.access-chip { display: inline-flex; align-items: center; gap: 4px; margin: 2px 6px 2px 0; padding: 3px 4px 3px 10px; border: 1px solid var(--line); border-radius: 999px; background: #fff; font-size: 0.85rem; font-weight: 600; white-space: nowrap; }
.access-chip-remove { width: 26px; height: 26px; border: 0; border-radius: 50%; background: #f1f1f3; color: var(--text); font-size: 1rem; line-height: 1; cursor: pointer; }
.access-chip-remove:hover { background: #fdecec; color: #a4161a; }
.access-owner { display: inline-block; margin-left: 4px; padding: 1px 8px; border-radius: 999px; background: #fdecec; color: #a4161a; font-size: .75rem; font-weight: 700; vertical-align: 1px; }
.access-actions { position: relative; width: 64px; }
.access-action-menu { position: relative; width: 42px; }
.access-action-toggle { display: grid; place-items: center; width: 42px; height: 42px; border: 1px solid var(--line); border-radius: 12px; background: #fff; color: var(--text); font-size: 1.45rem; font-weight: 800; line-height: 1; cursor: pointer; list-style: none; }
.access-action-toggle::-webkit-details-marker { display: none; }
.access-action-toggle:hover, .access-action-toggle:focus-visible, .access-action-menu[open] .access-action-toggle { background: #f1f1f3; border-color: #b9b9bf; }
.access-action-panel { position: fixed; z-index: 50; top: 0; left: 0; width: max-content; min-width: 190px; padding: 6px; border: 1px solid var(--line); border-radius: 12px; background: #fff; box-shadow: 0 12px 30px rgba(0, 0, 0, .16); }
.access-menu-item { display: block; width: 100%; min-height: 42px; padding: 9px 11px; border: 0; border-radius: 8px; background: transparent; color: var(--text); text-align: left; font: inherit; font-weight: 700; cursor: pointer; }
.access-action-panel .access-menu-item + .access-menu-item { margin: 2px 0 0; }
.access-menu-item:hover, .access-menu-item:focus-visible { background: #f1f1f3; }
.access-menu-danger { color: #a4161a; }
.access-menu-danger:hover, .access-menu-danger:focus-visible { background: #fdecec; }

/* ===== New starter induction (app/induction.js) ===== */
body.induction-open { overflow: hidden; }
.induction-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--bg);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: max(12px, env(safe-area-inset-top, 0px)) 16px max(24px, env(safe-area-inset-bottom, 0px));
}
.induction-overlay[hidden] { display: none; }
.induction-top {
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: 920px;
  margin: 0 auto 10px;
}
.induction-logo { height: 34px; width: auto; flex-shrink: 0; }
.induction-top-copy { flex: 1; min-width: 0; }
.induction-top-copy h1 { margin: 0; font-size: 1.15rem; line-height: 1.2; }
.induction-top-copy p { margin: 2px 0 0; font-size: 0.85rem; overflow-wrap: anywhere; }
.induction-progress {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  max-width: 920px;
  margin: 0 auto 12px;
  padding: 0;
  list-style: none;
  counter-reset: induction-step;
}
.induction-progress[hidden] { display: none; }
.induction-progress li {
  counter-increment: induction-step;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--muted);
  padding-top: 8px;
  border-top: 4px solid var(--line);
}
.induction-progress li::before { content: counter(induction-step) ". "; }
.induction-progress li.done { border-top-color: var(--green); color: var(--text); }
.induction-progress li.current { border-top-color: var(--red); color: var(--text); }
.induction-body { max-width: 920px; margin: 0 auto; }
.induction-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
  padding: 20px;
}
.induction-card h2 { margin: 0 0 8px; font-size: 1.35rem; }
.induction-card h2:focus { outline: none; }
.induction-ref { font-size: 0.85rem; font-weight: 600; margin-left: 6px; }
.induction-section {
  margin: 22px 0 10px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: 1rem;
}
.induction-section .muted { font-weight: 500; font-size: 0.85rem; margin-left: 6px; }
.induction-fields {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 0 16px;
}
.induction-field.wide { grid-column: 1 / -1; }
.induction-hint { display: block; font-weight: 500; font-size: 0.82rem; margin-top: 2px; }
.induction-field[aria-invalid='true'], .induction-field input[aria-invalid='true'], .induction-field select[aria-invalid='true'] { border-color: var(--red); }
.induction-choice { border: 0; padding: 0; margin: 8px 0 0; display: grid; gap: 10px; }
.induction-choice legend { font-weight: 700; margin-bottom: 8px; padding: 0; }
.induction-choice .consent-box { margin: 0; }
.induction-confirm { margin: 14px 0 0; }
.induction-confirm[hidden] { display: none !important; }
.induction-nav {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
.induction-nav button { min-width: 140px; min-height: 48px; }
.induction-error:empty { display: none; }
.induction-error { margin: 14px 0 0; }

.induction-lead { margin: 0 0 12px; }
.induction-slide {
  margin: 0;
  background: #111;
  border-radius: 14px;
  overflow: hidden;
  position: relative;
  touch-action: pan-y;
  user-select: none;
}
.induction-slide img { display: block; width: 100%; aspect-ratio: 16 / 9; max-height: calc(100vh - 290px); max-height: calc(100dvh - 290px); min-height: 180px; object-fit: contain; background: #fff; }
.induction-slide figcaption {
  position: absolute;
  right: 10px;
  bottom: 10px;
  background: rgba(16, 16, 20, 0.78);
  color: #fff;
  font-size: 0.8rem;
  font-weight: 700;
  border-radius: 999px;
  padding: 4px 10px;
}
.induction-slide-controls { display: flex; justify-content: space-between; gap: 12px; margin-top: 12px; }
.induction-slide-controls button { flex: 1; min-height: 48px; }

.induction-questions { list-style: none; margin: 14px 0 0; padding: 0; }
.induction-question { padding: 14px 0; border-top: 1px solid var(--line); }
.induction-question fieldset { border: 0; margin: 0; padding: 0; }
.induction-question legend { font-weight: 600; padding: 0; margin-bottom: 8px; }
.induction-yesno { display: flex; gap: 10px; }
.induction-yesno label { margin: 0; flex: 0 1 140px; }
.induction-yesno input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.induction-yesno span {
  display: block;
  text-align: center;
  padding: 11px 0;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: #fff;
  font-weight: 700;
  cursor: pointer;
}
.induction-yesno input:checked + span { background: var(--text); border-color: var(--text); color: #fff; }
.induction-yesno input:focus-visible + span { outline: 3px solid var(--scan-accent-strong); outline-offset: 2px; }
.induction-details { margin: 10px 0 0; font-weight: 500; font-size: 0.9rem; }
.induction-details[hidden] { display: none; }
.induction-question input[type='number'] { max-width: 160px; }

.induction-rules { margin: 10px 0 0; padding-left: 26px; line-height: 1.45; }
.induction-rules li { margin-bottom: 4px; }
.induction-sign { margin-top: 16px; }
.induction-sign > span { display: block; font-weight: 600; margin-bottom: 6px; }
.signature-pad {
  display: block;
  width: 100%;
  height: 170px;
  border: 1.5px dashed #9a9aa3;
  border-radius: 12px;
  background: #fff linear-gradient(to top, transparent 38px, var(--line) 38px, var(--line) 39px, transparent 39px);
  touch-action: none;
  cursor: crosshair;
}
.induction-sign .link-btn { margin-top: 8px; }
.induction-handback {
  text-align: center;
  background: #fff8e6;
  border: 1px solid #f0deac;
  border-radius: 14px;
  padding: 18px;
}
.induction-handback p { margin: 0; font-size: 1.05rem; font-weight: 600; }
.induction-done { text-align: center; }
.induction-done .enrollment-outcome-icon { margin: 0 auto 10px; }
.induction-leave { z-index: 1010; }
.induction-leave[hidden] { display: none; }
.induction-dialog[hidden] { display: none; }
.site-location-find { display: flex; gap: 8px; align-items: stretch; }
.site-location-find button { margin-top: 6px; flex-shrink: 0; }
.site-weather-place { display: block; font-weight: 600; }
.induction-delete-warning { background: #fdeaea; color: var(--red-dark); border-radius: 10px; padding: 10px 12px; font-size: 0.9rem; font-weight: 600; }
#induction-delete-confirm:not(:disabled) { background: var(--red); }

.induction-panel-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.induction-panel-head h2 { margin-bottom: 4px; }
.induction-site-filter { max-width: 360px; }
.induction-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.pill.induction-status { background: #e4f6ec; color: var(--green); margin-left: 6px; }

@media (max-width: 600px) {
  .induction-card { padding: 16px; }
  .induction-progress li { font-size: 0.7rem; }
  .induction-nav button { min-width: 0; flex: 1; }
  .induction-logo { height: 28px; }
}

/* Staff not seen for 30 days (On Site Now) */
.unseen-staff h2 { margin: 0 0 4px; font-size: 1.1rem; }
.unseen-staff > p { margin: 0 0 12px; font-size: 0.92rem; }
.unseen-staff-list { list-style: none; margin: 0; padding: 0; }
.unseen-staff-list li { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 0; border-top: 1px solid var(--line); }
.unseen-staff-who { min-width: 0; flex: 1 1 220px; }
.unseen-staff-who strong { display: block; }
.unseen-staff-who span { display: block; color: var(--muted); font-size: 0.88rem; }
.unseen-staff-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.staff-left-note { display: block; color: var(--muted); font-size: 0.85rem; margin-top: 4px; }
#staff-delete-confirm:not(:disabled) { background: var(--red); }
.staff-actions { width: 64px; }

/* Access page: levels, site dropdown, compact site lists */
.access-role { flex-direction: column; gap: 4px; }
.access-level { align-items: flex-start; padding: 6px 0; }
.access-level input { margin-top: 2px; }
.access-level span { display: flex; flex-direction: column; }
.access-level small { color: var(--muted); font-weight: 500; font-size: 0.85rem; }
.site-picker { border: 1px solid var(--line); border-radius: 12px; background: #fff; }
.site-picker-toggle { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 46px; padding: 0 14px; font-weight: 700; cursor: pointer; list-style: none; }
.site-picker-toggle::-webkit-details-marker { display: none; }
.site-picker-toggle::after { content: ''; width: 8px; height: 8px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); margin-top: -4px; transition: transform .15s; }
.site-picker[open] .site-picker-toggle::after { transform: rotate(-135deg); margin-top: 4px; }
.site-picker-panel { padding: 10px 14px 12px; border-top: 1px solid var(--line); }
.site-picker-panel input[type=search] { width: 100%; margin: 0 0 8px; }
.site-picker-tools { display: flex; gap: 8px; margin: 0 0 8px; }
.site-picker .access-site-list { max-height: 260px; overflow-y: auto; }
.access-choice[hidden] { display: none; }
.access-chip[hidden] { display: none; }
.access-more { margin: 2px 0; padding: 3px 10px; border: 0; border-radius: 999px; background: #f1f1f3; color: var(--text); font: inherit; font-size: 0.85rem; font-weight: 700; cursor: pointer; white-space: nowrap; }
.access-more:hover, .access-more:focus-visible { background: #e4e4e8; }

/* Tablets (Admin → Sites) */
.tablet-add { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; gap: 10px; align-items: end; }
.tablet-add label { margin: 0; }
@media (max-width: 640px) { .tablet-add { grid-template-columns: 1fr; } }
.tablet-code-value { margin: 14px 0; text-align: center; font-size: 2.2rem; font-weight: 800; letter-spacing: .12em; font-variant-numeric: tabular-nums; }
.tablet-modes-title { margin-top: 20px; }
.tablet-site-modes { display: grid; gap: 6px; }
.tablet-site-mode { display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto; gap: 12px; align-items: center; padding: 8px 0; border-top: 1px solid var(--line); }
.tablet-site-name { font-weight: 700; }
