:root {
  --bg: #0f1117;
  --panel: #181b24;
  --panel-2: #20242f;
  --text: #f3f4f6;
  --muted: #9aa3b2;
  --border: rgba(255, 255, 255, 0.08);
  --in: #16a34a;
  --in-strong: #22c55e;
  --in-shadow: rgba(34, 197, 94, 0.45);
  --out: #b91c1c;
  --out-strong: #ef4444;
  --out-shadow: rgba(239, 68, 68, 0.45);
  /* Break (orange) — distinct from the green "clock in" affordance. */
  --break: #ea580c;
  --break-strong: #f97316;
  --break-shadow: rgba(249, 115, 22, 0.45);
  --error: #fca5a5;
  --error-bg: rgba(239, 68, 68, 0.12);
  /* The Ivy brand accents — pink script, green leaves. Used sparingly. */
  --brand-pink: #ec5b8a;
  --brand-green: #3dae6a;
  --accent-blue: #2563eb;
  --accent-blue-strong: #3b82f6;
  --accent-blue-shadow: rgba(59, 130, 246, 0.45);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  background: var(--bg);
  color: var(--text);
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  overflow: hidden;
}

/* ===== Selectable text utility =====
   The body disables selection so taps don't highlight buttons. These message
   elements opt back in so employees can long-press → Copy an error message
   to send to a manager. iOS shows its native copy popover for elements with
   -webkit-touch-callout: default + user-select: text. */
.error-banner,
.result-screen h1,
.result-screen .result-time,
.result-screen .result-info,
.result-screen .result-info li,
.result-screen .result-thanks,
.lightbox-meta,
.admin-login-screen .error-banner {
  user-select: text;
  -webkit-user-select: text;
  -webkit-touch-callout: default;
}

#app {
  height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
  padding: clamp(16px, 3vw, 32px);
  position: relative;
}

.screen {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.screen[hidden] { display: none; }

.location-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: clamp(13px, 1.3vw, 15px);
  color: var(--muted);
  cursor: pointer;
  font-family: inherit;
  transition: filter 120ms ease;
  /* Pin to the top-right of the viewport so it sits out of the keypad flow
     and never competes with IN/OUT for vertical space. */
  position: absolute;
  top: clamp(10px, 1.5vw, 18px);
  right: clamp(10px, 1.5vw, 18px);
  z-index: 5;
  margin: 0;
  max-width: calc(100vw - 36px);
}
.location-banner:hover { filter: brightness(1.15); }
.location-banner #locationName { color: var(--text); font-weight: 500; }
.location-pin { font-size: 1.1em; }

/* Top-right "Declare tips for today" button (standalone tip flow). Sits just
   BELOW the location pill (which keeps its top-right corner spot). */
.declare-tips-btn {
  position: absolute;
  top: clamp(54px, 7.5vw, 74px);
  right: clamp(10px, 1.5vw, 18px);
  z-index: 6;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 24px;
  border: none;
  border-radius: 999px;
  font-family: inherit;
  font-size: clamp(15px, 1.7vw, 20px);
  font-weight: 800;
  letter-spacing: 0.3px;
  color: #fff;
  background: linear-gradient(180deg, var(--accent-blue-strong), var(--accent-blue));
  box-shadow: 0 10px 28px var(--accent-blue-shadow);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: transform 80ms ease, filter 120ms ease, opacity 120ms ease;
}
.declare-tips-btn:hover { filter: brightness(1.06); }
.declare-tips-btn:active { transform: scale(0.97); }
.declare-tips-btn .declare-tips-icon {
  font-size: 1.15em;
  font-weight: 900;
  opacity: 0.95;
}
.declare-tips-btn:disabled,
.declare-tips-btn[disabled] {
  opacity: 0.4;
  filter: grayscale(0.4);
  pointer-events: none;
  box-shadow: none;
}
.location-change {
  font-size: 0.85em;
  color: var(--muted);
  border-left: 1px solid var(--border);
  padding-left: 10px;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ===== Admin password screen ===== */
.admin-screen { align-items: stretch; }
.admin-display {
  letter-spacing: 14px;
  font-size: clamp(40px, 6vw, 64px);
}
.admin-submit {
  color: var(--in-strong);
  font-weight: 700;
}

/* ===== Location setup screen ===== */
.location-screen {
  align-items: stretch;
  justify-content: flex-start;
  gap: 18px;
}
.location-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  width: min(900px, 95%);
  margin: 14px auto 0;
}
.location-btn {
  background: linear-gradient(180deg, #2b3142, #20242f);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: clamp(32px, 5vw, 56px) 18px;
  font-family: inherit;
  font-size: clamp(22px, 2.6vw, 30px);
  font-weight: 600;
  cursor: pointer;
  transition: transform 80ms ease, filter 120ms ease;
  text-align: center;
}
.location-btn:hover { filter: brightness(1.1); }
.location-btn:active { transform: scale(0.97); }
.location-btn[data-suggested="true"] {
  border-color: var(--in-strong);
  box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.15) inset;
}

/* ===== Locked screen (device not authorized) ===== */
.locked-screen {
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 24px;
}
.locked-back-btn { margin-top: 4px; }
/* Waiting-for-approval (remote authorization) */
.waiting-body {
  width: min(440px, 96%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 28px 22px;
  text-align: center;
}
.waiting-spinner {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 4px solid var(--border);
  border-top-color: var(--in-strong, #22c55e);
  animation: spin 0.9s linear infinite;
}
.waiting-msg { font-size: clamp(16px, 2vw, 20px); margin: 0; line-height: 1.45; }
.locked-form {
  width: min(440px, 96%);
  display: flex;
  flex-direction: column;
  gap: 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 22px;
  text-align: center;
}
.locked-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-align: left;
}
.locked-field > span:first-child {
  font-size: 13px;
  color: var(--muted);
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.locked-field input[type="text"],
.locked-field input[type="password"] {
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 16px;
  font-family: inherit;
}
.locked-field small.hint {
  color: var(--muted);
  font-size: 12px;
  margin-top: 2px;
}
.locked-geo-status {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
}
.locked-geo-status .geo-label {
  font-size: 13px;
  color: var(--muted);
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  display: block;
  margin-bottom: 4px;
}
.locked-geo-status .geo-value {
  display: block;
  color: var(--text);
  font-size: 14px;
  margin-bottom: 8px;
}
.locked-geo-status.captured .geo-value {
  color: var(--in-strong);
  font-weight: 600;
}
.locked-geo-status.error .geo-value {
  color: var(--error);
}
.locked-geo-status .geo-btn {
  width: 100%;
  cursor: pointer;
}
.locked-geo-status .hint { margin-top: 6px; }

.brand { text-align: center; margin-bottom: 8px; }
.brand h1 {
  margin: 0;
  font-size: clamp(28px, 4vw, 44px);
  letter-spacing: 0.5px;
}
.brand .hint {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: clamp(13px, 1.4vw, 16px);
}

/* ===== The Ivy branding ===== */
.brand-logo {
  display: block;
  margin: 0 auto;
  height: clamp(64px, 9vh, 110px);
  width: auto;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
}
.brand-logo-small {
  height: clamp(72px, 9vw, 96px);
  margin-bottom: 4px;
}
.brand-with-logo { margin: 0 0 6px; }
.brand .tagline {
  margin: -2px 0 4px;
  color: var(--brand-pink);
  font-size: clamp(11px, 1.3vw, 14px);
  font-style: italic;
  letter-spacing: 2px;
  text-transform: uppercase;
}

/* ===== Keypad screen ===== */
.code-display {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 12px 18px;
  margin: 8px auto 12px;
  width: min(720px, 96%);
  text-align: center;
  font-size: clamp(44px, 6.5vw, 72px);
  font-weight: 700;
  letter-spacing: 14px;
  min-height: 76px;
  line-height: 1;
  transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
}
.code-display.pulse {
  transform: scale(1.04);
  border-color: var(--in-strong);
  box-shadow: 0 0 0 4px rgba(34, 197, 94, 0.18);
}

/* Bilingual contact note under the clock buttons — who to message about
   schedules or clock-in/out/break trouble. */
.keypad-help-note {
  width: min(900px, 95%);
  margin: 10px auto 0;
  text-align: center;
  font-size: clamp(11px, 1.2vw, 13px);
  line-height: 1.5;
  color: var(--muted);
}
.keypad-help-note strong {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* Status chip under the PIN: "Clocked in since 4:02 PM" / "On break since…" /
   "Not clocked in". Filled by the status preview after the 4th digit. */
.status-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: fit-content;
  max-width: min(720px, 96%);
  margin: -4px auto 10px;
  padding: 6px 16px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--muted);
  font-size: clamp(15px, 1.8vw, 19px);
  font-weight: 600;
  text-align: left;
}
/* Employee name to the left of the status lines, divided by a thin rule that
   picks up the chip's per-status color. */
.status-name {
  font-weight: 800;
  white-space: nowrap;
  padding-right: 12px;
  border-right: 2px solid currentColor;
  opacity: 0.92;
}
.status-lines {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.status-chip[data-status="in"] {
  color: var(--in-strong);
  border-color: rgba(34, 197, 94, 0.45);
  background: rgba(34, 197, 94, 0.08);
}
.status-chip[data-status="break"] {
  color: #f59e0b;
  border-color: rgba(245, 158, 11, 0.45);
  background: rgba(245, 158, 11, 0.08);
}
.status-chip[data-status="out"] {
  color: var(--muted);
}
/* Secondary lines under the primary status (e.g. "On break from X to Y"):
   smaller and dimmer, inheriting the chip's per-status color. */
.status-line-sub {
  font-size: 0.85em;
  font-weight: 500;
  opacity: 0.85;
}

.keypad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(10px, 1.5vh, 16px);
  width: min(720px, 96%);
  margin: 0 auto 12px;
}
.key {
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: clamp(14px, 2vh, 22px) 0;
  min-height: clamp(64px, 9vh, 96px);
  font-size: clamp(28px, 3.6vw, 42px);
  font-weight: 600;
  cursor: pointer;
  transition: transform 60ms ease, background 100ms ease, border-color 100ms ease;
  touch-action: manipulation;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.key:active {
  transform: scale(0.94);
  background: #353b4d;
  border-color: rgba(255, 255, 255, 0.18);
}
.key-util { font-size: clamp(18px, 2.2vw, 22px); color: var(--muted); }

.audio-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: var(--panel);
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  /* Sit in the top-left corner, mirror of the location pill. Out of the
     keypad's vertical flow so it doesn't push IN/OUT off-screen. */
  position: absolute;
  top: clamp(10px, 1.5vw, 18px);
  left: clamp(10px, 1.5vw, 18px);
  z-index: 5;
  margin: 0;
}
.audio-toggle[aria-pressed="true"] {
  color: var(--text);
  border-color: rgba(34, 197, 94, 0.5);
  background: rgba(34, 197, 94, 0.12);
}
.audio-toggle:active { transform: scale(0.96); }
.audio-toggle-label { display: none; }
@media (min-width: 700px) {
  .audio-toggle-label { display: inline; }
}

/* Yellow "?" help button — bottom-left of the keypad (mirror of the audio
   toggle's top-left). Always shows the "?"; the prompt text appears on wider
   screens. Out of the keypad's vertical flow so it never shifts IN/OUT. */
.help-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: #f5c518;
  color: #1a1205;
  border: 1px solid rgba(0, 0, 0, 0.25);
  border-radius: 999px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  position: absolute;
  bottom: clamp(10px, 1.5vw, 18px);
  left: clamp(10px, 1.5vw, 18px);
  z-index: 5;
  margin: 0;
  box-shadow: 0 4px 14px rgba(245, 197, 24, 0.35);
}
.help-toggle:active { transform: scale(0.96); }
.help-toggle-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.18);
  font-weight: 800;
}
.help-toggle-label { display: none; }
@media (min-width: 700px) {
  .help-toggle-label { display: inline; }
}

/* Help screen — reuses the break-confirm layout, amber palette. */
.help-screen .help-icon {
  color: #1a1205;
  background: #f5c518;
  box-shadow: 0 0 0 8px rgba(245, 197, 24, 0.12), 0 14px 40px rgba(0, 0, 0, 0.5);
  font-weight: 800;
}
.help-screen .help-body {
  color: var(--text);
  font-size: clamp(16px, 2vw, 22px);
  font-weight: 600;
  max-width: min(640px, 92%);
}

/* Small, unobtrusive "Privacy notice" link centered below the help note. */
.privacy-link {
  display: block;
  margin: 8px auto 0;
  padding: 4px 10px;
  background: none;
  border: none;
  color: var(--muted);
  font-family: inherit;
  font-size: clamp(11px, 1.2vw, 13px);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.privacy-link:active { color: var(--text); }

/* Privacy notice popup — a true overlay (over any screen), not a screen swap. */
.privacy-modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(12px, 3vw, 32px);
}
.privacy-modal[hidden] { display: none; }
.privacy-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.72);
  backdrop-filter: blur(2px);
}
.privacy-card {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: min(900px, 100%);
  height: min(92vh, 1100px);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.6);
  overflow: hidden;
}
.privacy-card-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
}
.privacy-card-head h2 {
  margin: 0;
  flex: 1;
  font-size: clamp(16px, 2vw, 22px);
  color: var(--text);
}
.privacy-lang { display: inline-flex; gap: 6px; }
.privacy-lang-btn {
  padding: 6px 12px;
  background: var(--bg);
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.privacy-lang-btn.active {
  color: var(--text);
  border-color: var(--in-strong);
  background: rgba(34, 197, 94, 0.12);
}
.privacy-close {
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.privacy-close:active { transform: scale(0.96); }
.privacy-frame {
  flex: 1;
  width: 100%;
  border: 0;
  background: #fff; /* PDFs render on white; avoids a dark flash before load */
}

.action-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  width: min(900px, 95%);
  margin: auto auto 0;
  padding-top: 6px;
  /* Make sure the buttons never get squeezed below their natural height. */
  flex-shrink: 0;
}
.action {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  border: none;
  border-radius: 20px;
  padding: clamp(20px, 3vh, 36px) 12px;
  color: white;
  font-family: inherit;
  cursor: pointer;
  text-align: left;
  transition: transform 80ms ease, box-shadow 200ms ease, filter 120ms ease;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.action:active { transform: scale(0.98); }
.action-icon {
  font-size: clamp(40px, 5vw, 64px);
  line-height: 1;
}
.action-label { display: flex; flex-direction: column; }
.action-title {
  font-size: clamp(28px, 3.4vw, 44px);
  font-weight: 800;
  letter-spacing: 1px;
}
.action-sub {
  font-size: clamp(13px, 1.4vw, 16px);
  opacity: 0.9;
  margin-top: 2px;
}
.action-in {
  background: linear-gradient(180deg, var(--in-strong), var(--in));
  box-shadow: 0 12px 30px var(--in-shadow);
}
.action-in:hover { filter: brightness(1.05); }
.action-out {
  background: linear-gradient(180deg, var(--out-strong), var(--out));
  box-shadow: 0 12px 30px var(--out-shadow);
}
.action-out:hover { filter: brightness(1.05); }
.action-break {
  background: linear-gradient(180deg, var(--break-strong), var(--break));
  box-shadow: 0 12px 30px var(--break-shadow);
}
.action-break:hover { filter: brightness(1.05); }
/* Keypad pre-tap hint: a clocked-in employee who's obviously still mid-shift
   (3h+ left) gets an ORANGE CLOCK OUT button — "this would be a break." Overrides
   the red .action-out; the .action-suggested ring still composes on top. */
.action-out.action-break-expected {
  background: linear-gradient(180deg, var(--break-strong), var(--break));
  box-shadow: 0 12px 30px var(--break-shadow);
}
/* The button matching the previewed status gets a ring; the other dims a touch.
   Purely advisory — both stay tappable. */
.action-suggested {
  outline: 3px solid rgba(255, 255, 255, 0.85);
  outline-offset: 3px;
}
.action-row:has(.action-suggested) .action:not(.action-suggested) {
  opacity: 0.55;
}

.error-banner {
  margin: 4px auto 10px;
  width: min(720px, 96%);
  text-align: center;
  color: #fef2f2;
  background: rgba(239, 68, 68, 0.22);
  border: 2px solid var(--out-strong);
  border-radius: 12px;
  padding: 14px 18px;
  font-size: clamp(16px, 2vw, 20px);
  font-weight: 600;
  letter-spacing: 0.3px;
  box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.10), 0 6px 24px rgba(239, 68, 68, 0.18);
  /* Allow employees to long-press and copy the message to send to a manager. */
  user-select: text;
  -webkit-user-select: text;
  -webkit-touch-callout: default;
  cursor: text;
}
.error-banner::before {
  content: "⚠ ";
  font-weight: 800;
  margin-right: 4px;
}

/* ===== Position picker ===== */
.position-screen {
  align-items: stretch;
  justify-content: flex-start;
  gap: 14px;
}
.position-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 14px;
  width: min(900px, 95%);
  margin: 10px auto 0;
}
.position-btn {
  background: linear-gradient(180deg, #2b3142, #20242f);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: clamp(20px, 3vw, 32px) 16px;
  font-family: inherit;
  font-size: clamp(20px, 2.4vw, 28px);
  font-weight: 600;
  cursor: pointer;
  transition: transform 80ms ease, filter 120ms ease;
  text-align: center;
}
.position-btn:hover { filter: brightness(1.08); }
.position-btn:active { transform: scale(0.97); }
.cancel-btn {
  display: block;
  margin: 20px auto 0;
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px 32px;
  font-family: inherit;
  font-size: 16px;
  cursor: pointer;
}
.cancel-btn:hover { color: var(--text); }

/* ===== Photo screen ===== */
.photo-screen { align-items: center; justify-content: center; gap: 16px; }
.video-wrap {
  position: relative;
  width: min(560px, 80vw);
  aspect-ratio: 4 / 3;
  background: black;
  border-radius: 18px;
  overflow: hidden;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.6);
}
#cameraVideo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scaleX(-1); /* mirror — feels natural to the person standing in front */
}
.face-guide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  fill: none;
  stroke: rgba(255, 255, 255, 0.55);
  stroke-width: 0.6;
  stroke-linecap: round;
  stroke-dasharray: 1.2 1.6;
  filter: drop-shadow(0 0 6px rgba(0, 0, 0, 0.55));
}

.countdown {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(140px, 18vw, 240px);
  font-weight: 800;
  color: white;
  text-shadow: 0 4px 30px rgba(0, 0, 0, 0.7);
  pointer-events: none;
  z-index: 2;
}
.flash {
  position: absolute;
  inset: 0;
  background: white;
  opacity: 0;
  pointer-events: none;
  transition: opacity 80ms ease-out;
}
.flash.fire { opacity: 0.9; transition: opacity 30ms ease-in; }
.photo-foot { color: var(--muted); }

/* ===== Working screen ===== */
.working-screen { align-items: center; justify-content: center; gap: 22px; }
.spinner {
  width: 84px;
  height: 84px;
  border: 6px solid rgba(255, 255, 255, 0.12);
  border-top-color: var(--in-strong);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ===== Result screen ===== */
.result-screen { align-items: center; justify-content: center; gap: 12px; }
.result-icon {
  width: 140px;
  height: 140px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 80px;
  font-weight: 800;
  background: var(--panel-2);
  color: var(--in-strong);
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5);
}
.result-screen[data-kind="error"] .result-icon {
  color: var(--out-strong);
  background: rgba(239, 68, 68, 0.18);
  box-shadow: 0 0 0 8px rgba(239, 68, 68, 0.10), 0 14px 40px rgba(239, 68, 68, 0.25);
}
.result-screen[data-kind="error"] h1 {
  color: var(--out-strong);
}
.result-screen[data-kind="error"] .result-time {
  color: #fef2f2;
  background: rgba(239, 68, 68, 0.16);
  border: 1px solid rgba(239, 68, 68, 0.35);
  border-radius: 12px;
  padding: 12px 18px;
  margin: 8px auto 0;
  font-size: clamp(17px, 2.2vw, 22px);
  font-weight: 500;
  max-width: min(720px, 92%);
  line-height: 1.4;
  /* Errors usually have actionable info — let employees long-press to copy. */
  user-select: text;
  -webkit-user-select: text;
  -webkit-touch-callout: default;
  cursor: text;
}
.result-screen h1 { font-size: clamp(34px, 4vw, 52px); margin: 6px 0 0; }
.result-screen .result-time { font-size: clamp(20px, 2.4vw, 26px); color: var(--muted); margin: 0; }
.result-screen .result-thanks {
  font-size: clamp(15px, 1.8vw, 19px);
  font-style: italic;
  color: var(--brand-pink);
  letter-spacing: 1px;
  margin: 0;
}
.result-info {
  list-style: none;
  padding: 0;
  margin: 4px 0 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  text-align: center;
  max-width: min(720px, 92%);
}
.result-info li {
  font-size: clamp(16px, 1.9vw, 20px);
  color: var(--text);
  margin: 0;
}
.result-info li.info-emphasis { color: var(--in-strong); font-weight: 600; }
/* Optional action on a result screen (e.g. "Declare tips" on the break screen).
   Tapping it cancels the auto-return so the employee can complete the flow. */
.result-action-btn {
  margin-top: 22px;
  padding: 16px 34px;
  font-size: clamp(18px, 2.1vw, 24px);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #fff;
  border: none;
  border-radius: 16px;
  cursor: pointer;
  background: linear-gradient(180deg, var(--break-strong), var(--break));
  box-shadow: 0 12px 30px var(--break-shadow);
}
.result-action-btn[hidden] { display: none; }
.result-action-btn:active { transform: translateY(1px); }
/* Break-started screen: render the clock-back-in time much larger than the
   "Please clock back in by" prompt so it reads at a glance from across the room.
   Used for both server (deferred) and non-server (immediate) breaks. */
.result-info li .break-return-time {
  display: block;
  margin-top: 6px;
  font-size: clamp(34px, 5.2vw, 56px);
  font-weight: 800;
  line-height: 1.1;
}
.result-info li.warn { color: var(--error); font-weight: 600; font-size: clamp(17px, 2vw, 22px); }
/* Big bold meal-break reminder on 6h+ shifts — the most prominent line on the
   clock-in success screen. */
.result-info li.meal-break {
  color: var(--in-strong);
  font-weight: 800;
  font-size: clamp(22px, 3.4vw, 34px);
  line-height: 1.25;
  margin-top: 8px;
}
/* Prominent "contact the office" notices (no scheduled shift / clocked in
   early / clocked in late) — much bigger and bolder than .warn. */
.result-info li.alert {
  color: var(--error);
  font-weight: 800;
  font-size: clamp(22px, 3.6vw, 36px);
  line-height: 1.3;
}
.result-info .number-red { color: var(--out-strong); font-weight: 800; }
/* Multi-role clock-in: "You are now clocked in as <role>" with the role itself
   highlighted in the accent color so it's the thing the eye lands on. */
.result-info li.result-position {
  font-size: clamp(18px, 2.4vw, 26px);
  font-weight: 700;
  color: var(--text);
}
.role-highlight {
  color: var(--in-strong);
  font-weight: 800;
}
.result-foot { color: var(--muted); margin-top: 14px; font-size: 14px; }

/* ===== Already-clocked-in screen ===== */
.already-in-screen {
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 20px;
}
.already-in-icon {
  color: #a5b4fc;
  background: rgba(99, 102, 241, 0.12);
  box-shadow: 0 0 0 8px rgba(99, 102, 241, 0.08), 0 14px 40px rgba(0, 0, 0, 0.5);
  font-size: 72px;
}
.already-in-screen h1 {
  font-size: clamp(28px, 3.4vw, 42px);
  margin: 6px 0 4px;
  color: var(--text);
  text-align: center;
  user-select: text;
  -webkit-user-select: text;
  -webkit-touch-callout: default;
}
.already-in-prefix {
  color: var(--muted);
  font-size: clamp(15px, 1.8vw, 19px);
  margin: 4px 0 0;
}
.already-in-duration {
  font-size: clamp(64px, 11vw, 128px);
  font-weight: 800;
  line-height: 1.05;
  margin: 4px 0;
  color: var(--in-strong);
  letter-spacing: -1px;
  text-shadow: 0 4px 30px rgba(34, 197, 94, 0.25);
  user-select: text;
  -webkit-user-select: text;
  -webkit-touch-callout: default;
}
.already-in-since {
  color: var(--muted);
  font-size: clamp(18px, 2.2vw, 24px);
  margin: 0 0 14px;
  font-style: italic;
  user-select: text;
  -webkit-user-select: text;
  -webkit-touch-callout: default;
}
/* Forgot-to-clock-out variant: same screen, error palette + a contact line.
   Shown when the open shift ended hours ago and was never closed. */
.already-in-contact {
  color: var(--out-strong);
  font-weight: 800;
  font-size: clamp(18px, 2.4vw, 28px);
  margin: 0 0 14px;
  text-align: center;
  max-width: min(640px, 92%);
}
.already-in-screen.stale .already-in-icon {
  color: var(--error);
  background: var(--error-bg);
  box-shadow: 0 0 0 8px rgba(239, 68, 68, 0.10), 0 14px 40px rgba(0, 0, 0, 0.5);
}
.already-in-screen.stale h1 { color: var(--out-strong); }
.already-in-screen.stale .already-in-duration {
  color: var(--out-strong);
  text-shadow: 0 4px 30px rgba(239, 68, 68, 0.25);
}
/* Plain "wrong button" block alert: amber icon, neutral readable body (the
   fixed "contact the office if there's a mistake" message lives in
   .already-in-contact, which the stale variant styles red — override here). */
.already-in-screen.alert .already-in-icon {
  color: #f5c518;
  background: rgba(245, 197, 24, 0.12);
  box-shadow: 0 0 0 8px rgba(245, 197, 24, 0.08), 0 14px 40px rgba(0, 0, 0, 0.5);
}
.already-in-screen.alert .already-in-contact {
  color: var(--text);
  font-weight: 700;
  font-size: clamp(19px, 2.4vw, 28px);
}

/* ===== No-scheduled-shift alert (must acknowledge) ===== */
/* Reuses the break-confirm layout but in the error palette, so a clock-in
   with no matching schedule is unmissable and blocks until OK is tapped. */
.no-schedule-screen .no-schedule-icon {
  color: var(--error);
  background: var(--error-bg);
  box-shadow: 0 0 0 8px rgba(239, 68, 68, 0.10), 0 14px 40px rgba(0, 0, 0, 0.5);
}
.no-schedule-screen h1 { color: var(--out-strong); }
.no-schedule-screen .no-schedule-body {
  color: var(--text);
  background: var(--error-bg);
  border-color: rgba(239, 68, 68, 0.30);
  font-size: clamp(16px, 2vw, 22px);
  font-weight: 600;
}
/* "You are now clocked in as <role>" line on the no-schedule screen, plus the
   muted change-role button beneath the acknowledge button. */
.no-schedule-role {
  margin: 2px 0 6px;
  font-size: clamp(16px, 2vw, 22px);
  font-weight: 700;
  color: var(--text);
  text-align: center;
}
.no-schedule-change-role { margin-top: 10px; }
.no-schedule-screen .no-schedule-phone {
  font-style: normal;
  font-weight: 800;
  color: var(--text);
  font-size: clamp(18px, 2.2vw, 26px);
  margin: 0 0 18px;
}

/* ===== Sling-schedule banner on the off-schedule (late/early) clock-in screens ===== */
.schedule-confirm-label {
  margin: 0 0 2px;
  color: var(--muted);
  font-size: clamp(14px, 1.7vw, 18px);
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.schedule-confirm-window {
  margin: 0 0 10px;
  font-size: clamp(40px, 7vw, 72px);
  font-weight: 800;
  line-height: 1.05;
  color: var(--in-strong);
  letter-spacing: -1px;
  text-shadow: 0 4px 30px rgba(34, 197, 94, 0.2);
}
.break-choice-sched-note {
  margin: 0 0 14px;
  color: var(--muted);
  font-size: clamp(15px, 1.9vw, 20px);
  line-height: 1.4;
  text-align: center;
  max-width: min(640px, 92%);
}

/* ===== Break-return-by box on the clock-out result screen ===== */
.break-return-box {
  margin: 8px auto 0;
  padding: 14px 18px;
  background: rgba(236, 91, 138, 0.08);
  border: 1px solid rgba(236, 91, 138, 0.35);
  border-radius: 14px;
  text-align: center;
  max-width: min(720px, 92%);
  width: 100%;
  box-sizing: border-box;
}
.break-return-prefix {
  margin: 0 0 4px;
  color: var(--brand-pink);
  font-size: clamp(13px, 1.5vw, 17px);
  font-style: italic;
  letter-spacing: 0.5px;
}
.break-return-time {
  margin: 0;
  font-size: clamp(56px, 10vw, 112px);
  font-weight: 800;
  line-height: 1.05;
  color: var(--in-strong);
  letter-spacing: -1px;
  text-shadow: 0 4px 30px rgba(34, 197, 94, 0.25);
  user-select: text;
  -webkit-user-select: text;
  -webkit-touch-callout: default;
}

/* ===== Break confirmation screen (short break < 30 min) ===== */
.break-confirm-screen {
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 24px 18px;
}
.break-confirm-icon {
  color: #fbbf24;
  background: rgba(251, 191, 36, 0.14);
  box-shadow: 0 0 0 8px rgba(251, 191, 36, 0.10), 0 14px 40px rgba(0, 0, 0, 0.5);
  font-size: 72px;
}
.break-confirm-screen h1 {
  font-size: clamp(24px, 3vw, 36px);
  margin: 6px 0 0;
  text-align: center;
}
.break-confirm-duration {
  font-size: clamp(72px, 13vw, 144px);
  font-weight: 800;
  line-height: 1;
  margin: 4px 0 4px;
  color: var(--out-strong);
  letter-spacing: -1px;
  text-shadow: 0 4px 30px rgba(239, 68, 68, 0.3);
}
.break-confirm-since {
  color: var(--muted);
  font-size: clamp(15px, 1.8vw, 20px);
  margin: 0 0 12px;
  font-style: italic;
}
.break-confirm-warn {
  color: var(--text);
  background: rgba(99, 102, 241, 0.10);
  border: 1px solid rgba(99, 102, 241, 0.30);
  border-radius: 10px;
  padding: 10px 14px;
  margin: 0 0 18px;
  font-size: clamp(13px, 1.6vw, 17px);
  max-width: min(560px, 92%);
  text-align: center;
}
.break-confirm-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  width: min(720px, 96%);
  margin-top: 6px;
}
/* The cancel button is intentionally RED (safer choice) and clock-in-anyway
   is GREEN — opposite of the usual kiosk green=action/red=stop convention,
   because here red = "don't proceed". */
.break-confirm-cancel .action-title,
.break-confirm-yes .action-title { letter-spacing: 0.5px; }

/* Early-clock-in blocked screen: single full-width OK button, and the contact
   line shouldn't be italicized like the break "since" line. */
.early-blocked-actions { grid-template-columns: 1fr; }
.early-blocked-ok { justify-content: center; }
.early-blocked-screen .break-confirm-since { font-style: normal; }

/* ===== Break choice screen (server clock-out, mid-shift) ===== */
.break-choice-screen {
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 24px 18px;
}
.break-choice-screen h1 {
  font-size: clamp(26px, 3.4vw, 40px);
  margin: 0;
  text-align: center;
}
.break-choice-sub {
  color: var(--muted);
  font-size: clamp(15px, 1.8vw, 20px);
  margin: 0 0 14px;
  text-align: center;
}
/* Off-schedule (late/early) info screens: this notice replaces the action
   buttons, so it reads as the main message — larger, brighter, and weightier
   than the usual muted sub. */
.break-choice-sub.off-schedule-notice {
  color: var(--text);
  font-size: clamp(22px, 3.2vw, 34px);
  font-weight: 700;
  line-height: 1.35;
  max-width: min(720px, 92%);
  margin: 10px auto 0;
}
.break-choice-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  width: min(760px, 96%);
}
/* The grid `display` above outranks the bare `hidden` attribute, so the
   buttonless off-schedule info screen needs this explicit override to drop the
   action buttons (same reason .screen[hidden] exists). */
.break-choice-actions[hidden] { display: none; }
/* Smart-default layout for the break-vs-done choice: stack the buttons so the
   RECOMMENDED action is the full prominent primary, and the alternative sits
   below it as a smaller, de-emphasized "escape hatch" (always tappable — the
   employee can override the recommendation). */
.break-choice-actions.smart {
  grid-template-columns: 1fr;
  gap: 12px;
  max-width: min(560px, 96%);
}
.break-choice-actions.smart .break-choice-secondary {
  padding: 14px 12px;
  gap: 12px;
  background: transparent;
  box-shadow: none;
  border: 2px solid rgba(255, 255, 255, 0.22);
  color: var(--muted);
}
.break-choice-actions.smart .break-choice-secondary .action-icon {
  font-size: clamp(20px, 2.4vw, 28px);
}
.break-choice-actions.smart .break-choice-secondary .action-title {
  font-size: clamp(17px, 1.9vw, 22px);
  letter-spacing: 0.5px;
}
.break-choice-actions.smart .break-choice-secondary:hover {
  filter: none;
  border-color: rgba(255, 255, 255, 0.45);
}
.break-choice-cancel {
  margin-top: 18px;
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: clamp(15px, 1.8vw, 19px);
  text-decoration: underline;
  padding: 10px 16px;
  cursor: pointer;
}

/* ===== Language picker (first clock-in only) ===== */
.language-screen h1 { letter-spacing: 0.5px; }
.language-screen .break-choice-sub { line-height: 1.5; }
.language-screen .action-icon { font-size: clamp(28px, 4vw, 44px); }

/* Build-version badge — tiny + faint, fixed in the corner so we can confirm at
   a glance which kiosk build an iPad is running. Non-interactive. */
.kiosk-version {
  position: fixed;
  right: 10px;
  bottom: 8px;
  z-index: 9999;
  font-size: 20px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: #ffffff;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
  pointer-events: none;
  user-select: none;
}

/* Tip wizard: step indicator above the title (server two-step flow). */
.tip-step {
  margin: 0 0 4px;
  font-size: clamp(13px, 1.6vw, 16px);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--in-strong);
}
/* Suggestion note under the amount (step 2 prefill: "Suggested from your
   $412.50 card tips × 55%"). */
/* Servers' "expected tips" line — slightly more prominent than a muted hint so
   it actually registers, but still secondary to the title + amount display. */
.tip-note {
  margin: -2px auto 10px;
  width: min(720px, 96%);
  text-align: center;
  font-size: clamp(15px, 1.9vw, 21px);
  font-weight: 600;
  color: var(--text);
}

/* (The old server-flow confirmation equation + .tip-confirm-mode styles were
   removed with the two-step tip flow — the declaration is now a single step.) */

/* ===== Timesheet-edit approval + signature ===== */
.edit-approve-screen,
.edit-sign-screen {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 28px 26px;
  max-width: 760px;
  margin: 0 auto;
  width: 100%;
  max-height: 100vh;
  overflow-y: auto;
}
.edit-approve-screen h1,
.edit-sign-screen h1 {
  font-size: 30px;
}
.edit-approve-screen .hint,
.edit-sign-screen .hint {
  font-size: 18px;
  line-height: 1.4;
}
.edit-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow-y: auto;
  max-height: 40vh;
}
.edit-list-compact {
  max-height: 24vh;
  gap: 8px;
}
.edit-row {
  background: var(--panel-2, #20242f);
  border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
  border-left: 4px solid var(--break-strong, #f97316);
  border-radius: 10px;
  padding: 14px 18px;
}
.edit-row-main {
  font-size: 22px;
  font-weight: 700;
  color: var(--text, #f3f4f6);
}
.edit-row-by {
  font-size: 18px;
  line-height: 1.4;
  color: #cbd5e1;
  margin-top: 5px;
}
.edit-list-compact .edit-row { padding: 10px 14px; }
.edit-list-compact .edit-row-main { font-size: 18px; }
.edit-list-compact .edit-row-by { font-size: 15px; }

/* Full-day timesheet view (grouped by day) on the approval + signature screens.
   Each day lists every clock-in/out; corrected punches are highlighted. */
.edit-day {
  background: var(--panel-2, #20242f);
  border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
  border-radius: 10px;
  padding: 12px 16px;
  text-align: left;
}
.edit-day-head {
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #9aa3b2;
  margin-bottom: 8px;
}
.edit-day-note {
  font-size: 16px;
  line-height: 1.4;
  color: #fbbf24;
  margin-bottom: 8px;
}
.edit-punch {
  padding: 7px 10px;
  border-radius: 8px;
  border-left: 4px solid transparent;
}
.edit-punch + .edit-punch { margin-top: 4px; }
.edit-punch-main {
  font-size: 21px;
  font-weight: 700;
  color: var(--text, #f3f4f6);
  display: flex;
  align-items: center;
  gap: 10px;
}
.edit-punch-changed {
  background: rgba(249, 115, 22, 0.12);
  border-left-color: var(--break-strong, #f97316);
}
.edit-corrected-badge {
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #fff;
  background: var(--break-strong, #f97316);
  padding: 2px 8px;
  border-radius: 999px;
}
.edit-punch-reason {
  font-size: 17px;
  line-height: 1.4;
  color: #cbd5e1;
  margin-top: 4px;
}
.edit-list-compact .edit-day { padding: 10px 12px; }
.edit-list-compact .edit-day-head { font-size: 13px; }
.edit-list-compact .edit-punch-main { font-size: 17px; }
.edit-list-compact .edit-punch-reason { font-size: 14px; }
.edit-ack-statement {
  font-size: 20px;
  line-height: 1.55;
  font-weight: 500;
  color: var(--text, #f3f4f6);
  background: rgba(255, 255, 255, 0.06);
  border-radius: 10px;
  padding: 18px 20px;
  margin: 0;
}
.edit-ack-statement-sm {
  font-size: 16px;
  line-height: 1.5;
  font-weight: 400;
  color: #cbd5e1;
  padding: 14px 16px;
}
.edit-sign-fields {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 28px;
}
.edit-field {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.edit-field-label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--muted, #9aa3b2);
}
.edit-field-val {
  font-size: 18px;
  font-weight: 600;
  color: var(--text, #f3f4f6);
}
.edit-actions {
  display: flex;
  gap: 14px;
  margin-top: auto;
}
.edit-btn {
  flex: 1;
  padding: 20px;
  font-size: 20px;
  font-weight: 700;
  border-radius: 14px;
  border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
  cursor: pointer;
  font-family: inherit;
}
.edit-btn-primary {
  background: var(--in, #16a34a);
  color: #fff;
  border-color: var(--in-strong, #22c55e);
}
.edit-btn-secondary {
  background: var(--panel-2, #20242f);
  color: var(--muted, #9aa3b2);
}
.signature-wrap {
  position: relative;
  background: #fff;
  border-radius: 12px;
  padding: 8px;
}
.signature-pad {
  width: 100%;
  height: 240px;
  display: block;
  touch-action: none; /* let our pointer handlers own the gesture */
  border-radius: 8px;
}
.signature-name {
  position: absolute;
  left: 18px;
  bottom: 10px;
  font-size: 14px;
  color: #94a3b8;
  pointer-events: none;
}
