:root {
  --bg: #fafaf9;
  --card: #ffffff;
  --border: #e4e2dd;
  --text: #1a1a18;
  --muted: #5f5e5a; /* darker for readable contrast (WCAG AA) */
  --accent: #1a1a18;
  --green: #1d9e75; /* buttons, outlines */
  --green-text: #13795b; /* green TEXT: AA contrast */
  --red: #c8322f; /* button red */
  --red-text: #b42318; /* error text: AA contrast on light backgrounds */
  --amber: #8a5a00; /* AA contrast for text */
}

* { box-sizing: border-box; }

/* No pull-to-refresh or overscroll glow (Chrome on Android) — a stray
   swipe must never reload the kiosk. */
html, body { overscroll-behavior: none; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, system-ui, sans-serif;
  font-size: 18px;
  line-height: 1.4;
  -webkit-tap-highlight-color: transparent;
  /* Kiosk: no long-press "Save Image / Share" menu on covers and no text
     getting selected by stray taps. Inputs stay selectable (below).
     (-webkit-touch-callout is Safari's; on Chrome the long-press menu is
     stopped in app.js — the "contextmenu" listener.) */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}
input, textarea { -webkit-user-select: text; user-select: text; -webkit-touch-callout: default; }
/* No double-tap-to-zoom delay on tappable things. */
button, .tile, a { touch-action: manipulation; }

/* 100dvh where supported: a Chrome tab's address bar comes and goes. */
.screen { display: none; padding: 24px 24px 72px; min-height: 100vh; min-height: 100dvh; } /* bottom room: the admin dot never covers content */
.screen.active { display: block; }
/* Boot note: fades in after 4 s only if no screen became active. */
.boot-note { max-width: 640px; margin: 48px auto; padding: 0 24px; font-size: 1.1rem; line-height: 1.5; opacity: 0; animation: boot-note-in 0.3s ease 4s forwards; }
body:has(.screen.active) .boot-note { display: none; }
@keyframes boot-note-in { to { opacity: 1; } }

.tiles {
  align-items: start; /* covers line up even when titles wrap differently */
  display: grid;
  /* Bigger covers for older eyes: 4 across on a 10–11" tablet in landscape, 3 portrait, 2 on a phone. */
  grid-template-columns: repeat(auto-fill, minmax(min(200px, calc(50% - 10px)), 1fr));
  gap: 20px;
  margin-bottom: 32px;
}
.tile {
  position: relative;
  display: block;
  width: 100%;
  font: inherit;
  color: inherit;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px;
  cursor: pointer;
  text-align: center;
  font-size: 21px;
  font-weight: 600;
  line-height: 1.25;
  overflow-wrap: anywhere; /* long one-word titles stay inside the tile */
}
/* pointer-events:none: a long press lands on the button, never on the
   image itself (Chrome's "Download image / Share / Lens" menu is a way out
   of the kiosk); no dragging the cover out either. */
.tile img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 8px; margin-bottom: 10px; pointer-events: none; -webkit-user-drag: none; user-select: none; }
/* Selected: thick green outline + check badge — visible even on dark covers. */
.tile.selected { outline: 4px solid var(--green); outline-offset: -2px; background: #eaf7f2; }
.tile-check {
  display: none; position: absolute; top: 6px; right: 6px; width: 44px; height: 44px; border-radius: 50%;
  background: var(--green); color: #fff; font-size: 26px; line-height: 44px; box-shadow: 0 1px 4px rgba(0,0,0,.3);
}
.tile.selected .tile-check { display: block; }
.tile:focus-visible { outline: 3px solid #2563eb; outline-offset: 2px; }
.tiles-empty { color: var(--muted); font-size: 20px; grid-column: 1 / -1; text-align: center; }
.album-hint { color: var(--amber); background: #fdf3e3; border-radius: 8px; padding: 12px 14px; margin: 0 0 12px; font-size: 21px; font-weight: 600; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Stays in view at the bottom while scrolling a long album list. */
.email-form-wrap {
  /* Full-width bar (so covers scrolling underneath are hidden cleanly),
     contents centered at up to 680px. */
  margin: 0 -24px; position: sticky; bottom: 0; z-index: 5;
  background: var(--bg); border-top: 1px solid var(--border);
  padding: 12px max(16px, calc((100% - 680px) / 2)) 16px;
  box-shadow: 0 -6px 16px rgba(0,0,0,0.06);
}
.email-form { display: flex; gap: 12px; }
.email-form input {
  flex: 1; min-width: 0; /* lets the field shrink so Save never gets pushed off narrow screens */ padding: 18px; font-size: 23px; border-radius: 10px; border: 2px solid #8d8b85;
}
.btn {
  padding: 18px 30px; font-size: 22px; font-weight: 600; border-radius: 10px; border: none; min-height: 60px;
  background: var(--accent); color: #fff; cursor: pointer;
}
.btn.secondary { background: transparent; color: var(--text); border: 1px solid var(--border); }


.admin-unlock {
  position: fixed; bottom: 10px; right: 10px; width: 44px; height: 44px; z-index: 6;
  border-radius: 50%; background: var(--border); border: none; opacity: 0.5;
}
/* Something needs a look: a thin amber ring only the brother would notice —
   not a bright red dot that invites fans to tap it. */
.admin-unlock.attention { box-shadow: inset 0 0 0 3px #d39b3a; opacity: 0.8; }
.admin-unlock.hidden-dot { display: none; }

.intro-copy { max-width: 640px; margin: 0 auto 24px; text-align: center; color: var(--text); font-size: 23px; line-height: 1.35; }

.confirmation { max-width: 560px; margin: 60px auto; text-align: center; }
.confirmation .check {
  width: 76px; height: 76px; border-radius: 50%; background: var(--green); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 40px; margin: 0 auto 16px;
}
.confirmation h2 { font-size: 32px; margin: 0 0 12px; }
.confirmation p { color: var(--text); font-size: 21px; line-height: 1.5; margin: 0 0 24px; overflow-wrap: anywhere; }
.confirmation strong { color: var(--text); }
.confirmation h2:focus { outline: none; } /* focused only so screen readers announce it */
.confirmation p.confirmation-lookfor { font-weight: 600; margin-top: -8px; }
.confirmation p.confirmation-contact { color: var(--muted); font-size: 19px; margin-top: -12px; }

.pin-pad { max-width: 280px; margin: 80px auto; text-align: center; }
.pin-dots { display: flex; justify-content: center; gap: 12px; margin-bottom: 24px; }
.pin-dots span { display: inline-block; width: 14px; height: 14px; border-radius: 50%; border: 2px solid #8d8b85; }
.pin-label { color: var(--muted); text-align: center; min-height: 1.5em; }
.pin-dots.shake { animation: shake 0.35s; }
@keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-8px); } 75% { transform: translateX(8px); } }
.pin-dots span.filled { background: var(--text); }
.pin-keys { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.pin-keys button { padding: 20px; font-size: 20px; border-radius: 8px; border: 1px solid var(--border); background: var(--card); }

.feed-row { display: flex; justify-content: space-between; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--border); }
.feed-main { min-width: 0; }
/* Which albums were chosen that hour — wraps rather than overflowing. */
.feed-titles { display: block; color: var(--muted); font-size: 15px; margin-top: 2px; overflow-wrap: anywhere; }
.feed-row > .status { flex: none; margin-left: 12px; }
.feed-row .status.synced { color: var(--green-text); font-weight: 600; }
.feed-row .status.pending { color: var(--red-text); font-weight: 600; }
/* Waiting on the server (it emails them by itself): normal, not an alarm. */
.feed-row .status.held { color: var(--amber); font-weight: 600; }
/* Left to the server (the tablet doesn't know how it ended): neutral. */
.feed-row .status.neutral { color: var(--muted); font-weight: 600; }
.muted-text { color: var(--muted); font-size: 14px; }

.banner { padding: 12px; border-radius: 8px; margin-bottom: 16px; display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.banner.offline { background: #fdf3e3; color: var(--amber); }
.banner.reauth { background: #fdeceb; color: var(--red-text); }
/* A calm note (the server holds a sign-up for a reason that needs nothing
   from anyone here — a domain re-check, an address the email service won't
   take, a mailbox's daily cap): neutral grey, not a "coloured banner". */
.banner.info { background: #f1f0ed; color: var(--muted); border: 1px solid var(--border); }
/* Lost sign-ups: loud, and the list under the text. */
.banner.lost-banner { display: block; border: 2px solid var(--red-text); font-weight: 600; }
.banner.lost-banner[hidden] { display: none; }
.lost-banner ul { margin: 8px 0 12px; padding-left: 20px; font-weight: 400; }
.lost-banner p { margin: 0 0 8px; }
.lost-banner p[hidden], .lost-banner button[hidden] { display: none; }
.lost-banner .link-btn { color: inherit; font-weight: 400; font-size: 16px; margin: 0; padding: 12px 4px; } /* small on purpose: see renderLostBanner */
.tab-warning { display: block; font-weight: 600; }
.tab-warning[hidden] { display: none; }
.storage-status { color: var(--green-text); font-size: 15px; font-weight: 600; }
.storage-status.storage-bad { color: var(--amber); }

.totals { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 16px 0; }
.totals .card { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 16px; }
.totals .num { font-size: 28px; font-weight: 600; }
.totals .label { color: var(--muted); font-size: 13px; }

/* --- Email check + confirm pop-up --- */
.email-form input.invalid { border-color: var(--red); outline: none; box-shadow: 0 0 0 3px #fdeceb; }
.email-form input.just-fixed { border-color: var(--green); outline: 2px solid var(--green); box-shadow: 0 0 0 5px #e1f5ee; }
.email-error { color: var(--red-text); font-size: 20px; font-weight: 600; margin: 8px 0 0; }

/* "This kiosk has moved": covers everything, can't be closed. */
.moved-screen { position: fixed; inset: 0; z-index: 100; background: var(--bg); overflow: auto; overscroll-behavior: contain; padding: 32px 24px; }
.moved-screen[hidden] { display: none; }
.moved-card { max-width: 640px; margin: 40px auto; text-align: center; }
.moved-card h1 { font-size: 34px; line-height: 1.25; color: var(--red-text); margin: 0 0 16px; }
.moved-card h1:focus { outline: none; }
.moved-card p { font-size: 23px; line-height: 1.45; margin: 0 0 20px; }
.moved-unsent-count { font-weight: 700; background: #fdeceb; color: var(--red-text); border-radius: 10px; padding: 14px 16px; }
.moved-unsent-list { text-align: left; font-size: 20px; line-height: 1.5; padding-left: 28px; overflow-wrap: anywhere; }
.moved-reveal { margin: 24px 0; }
.moved-reveal label { display: block; font-size: 20px; margin-bottom: 8px; }
.moved-pin-row { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.moved-pin-row input { width: 160px; padding: 14px; font-size: 26px; text-align: center; letter-spacing: 8px; border-radius: 10px; border: 2px solid #8d8b85; }
.moved-addresses { margin: 24px 0; padding: 16px; border: 2px solid var(--border); border-radius: 12px; background: var(--card); }

.modal-backdrop {
  position: fixed; inset: 0; background: rgba(26, 26, 24, 0.55);
  display: flex; align-items: center; justify-content: center; padding: 24px; z-index: 50;
}
.modal-backdrop[hidden] { display: none; }
.modal {
  background: var(--card); border-radius: 16px; padding: 28px 24px 24px;
  width: 100%; max-width: 600px; text-align: center; box-shadow: 0 12px 40px rgba(0,0,0,0.25);
}
.modal h2 { font-size: 30px; margin: 0 0 4px; }
.modal-sub { color: var(--text); font-size: 20px; margin: 4px 0 20px; }
.modal-email {
  font-size: clamp(24px, 6.5vw, 34px); font-weight: 700; line-height: 1.25; margin: 0 0 20px;
  padding: 16px; background: var(--bg); border-radius: 10px;
  overflow-wrap: anywhere; /* long addresses wrap instead of overflowing */
}
.modal-suggest { font-size: 21px; margin: -8px 0 20px; color: var(--amber); }
.link-btn { background: none; border: none; padding: 10px 4px; margin: -10px 0; font: inherit; font-weight: 700; color: var(--amber); text-decoration: underline; cursor: pointer; } /* ~40px tap target */
/* Whole row is the tap target (it's a <label>). */
.modal-optin {
  display: flex; align-items: center; gap: 14px; margin: -4px 0 20px;
  padding: 14px; border-radius: 10px; border: 2px solid var(--border); background: var(--bg);
  font-size: 19px; line-height: 1.35; text-align: left; cursor: pointer;
}
.modal-optin:has(input:checked) { border-color: var(--green); background: #eaf7f2; }
.modal-optin input { flex: none; width: 32px; height: 32px; margin: 0; accent-color: var(--green); }
.modal-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.modal-actions .btn { padding: 22px 18px; font-size: 26px; font-weight: 700; }
.btn-red { background: var(--red); }
.btn-green { background: var(--green); }
.btn:disabled { opacity: 0.6; }

/* --- Login form (kiosk setup / re-auth) --- */
.login-form label { display: block; text-align: left; font-size: 14px; color: var(--muted); margin: 8px 0 4px; }
/* 16px+ so Safari doesn't zoom in when the field is focused. */
.login-form input { width: 100%; padding: 12px; font-size: 17px; margin-bottom: 8px; border-radius: 8px; border: 1px solid #bdbab3; }
.login-error { color: var(--red-text); }
.homescreen-hint { text-align: left; font-size: 14px; background: #fdf3e3; color: var(--amber); padding: 10px 12px; border-radius: 8px; }

.privacy-note { color: var(--muted); font-size: 16px; margin: 10px 0 0; text-align: center; }
/* Narrower screens (a 10–11" tablet in portrait is ~600–640 px wide): the
   privacy line wraps to two lines right where the admin dot sits (bottom
   right) — keep the text clear of it on both sides (centred). */
@media (max-width: 820px) { .privacy-note { padding: 0 52px; } }
.privacy-note .privacy-link { color: var(--muted); font-weight: 600; }
/* The in-app privacy panel: the text scrolls, Close stays in view. */
.privacy-modal { max-width: 720px; max-height: calc(100vh - 48px); max-height: calc(100dvh - 48px); display: flex; flex-direction: column; text-align: left; padding: 0; overflow: hidden; }
.privacy-body { overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; padding: 24px 24px 8px; font-size: 19px; line-height: 1.5; }
.privacy-body h2 { text-align: center; }
.privacy-body h3 { font-size: 22px; margin: 24px 0 6px; }
.privacy-body p { margin: 0 0 12px; overflow-wrap: anywhere; }
.privacy-body ul { margin: 0 0 12px; padding-left: 1.2em; }
.privacy-body li { margin: 0 0 10px; overflow-wrap: anywhere; }
.privacy-body .privacy-updated { color: var(--muted); text-align: center; }
.privacy-close { margin: 12px 24px 24px; font-size: 22px; padding: 16px; }

/* --- Device settings: choices --- */
.storage-note { color: var(--amber); font-size: 14px; font-weight: 600; text-align: left; }
.setting-group { text-align: left; border: 1px solid var(--border); border-radius: 10px; margin: 20px 0 0; padding: 10px 14px 6px; }
.setting-group legend { font-size: 15px; font-weight: 600; padding: 0 4px; }
.setting-choice { display: flex; align-items: center; gap: 10px; min-height: 44px; font-size: 16px; cursor: pointer; }
.setting-choice input { flex: none; width: 24px; height: 24px; margin: 0; accent-color: var(--accent); }
.setting-help { color: var(--muted); font-size: 13px; margin: 4px 0; }

/* --- Private on-screen keyboard for the fan email field ---
   Lives inside the sticky email bar, under the field and Save, so it can
   never cover either. Keys are big and plain; no key ever takes focus from
   the field on a tap (see app.js). */
.fan-keyboard { margin: 12px 0 0; display: flex; flex-direction: column; gap: 6px; touch-action: manipulation; -webkit-user-select: none; user-select: none; }
.fan-keyboard[hidden] { display: none; }
.osk-row { display: flex; gap: 6px; }
.osk-key {
  flex: 1 1 0; min-width: 0; height: clamp(44px, 7vh, 60px); padding: 0;
  font: inherit; font-size: 22px; font-weight: 600; line-height: 1; color: var(--text);
  background: var(--card); border: 1px solid #bdbab3; border-radius: 8px; box-shadow: 0 1px 0 #bdbab3;
  cursor: pointer; touch-action: manipulation; white-space: nowrap; overflow: hidden;
}
@supports (height: 1dvh) { .osk-key { height: clamp(44px, 7dvh, 60px); } }
.osk-key:active, .osk-key.pressed { background: #e4e2dd; }
.osk-key:focus-visible { outline: 3px solid #2563eb; outline-offset: 1px; }
.osk-key.wide { flex-grow: 2; }
.osk-key.symbol { background: #f1f0ec; }
/* Shortcut keys share the row by the length of their text, so "@hotmail.com" is never cut off. */
.osk-row.shortcuts { flex-wrap: wrap; } /* two rows on a narrow (portrait) screen rather than tiny text */
.osk-row.shortcuts .osk-key { flex: 1 1 auto; min-width: 52px; padding: 0 4px; font-size: 16px; background: #f1f0ec; }
.osk-key.osk-backspace { font-size: 26px; background: #f1f0ec; }
.osk-key.osk-save { background: var(--accent); color: #fff; border-color: var(--accent); box-shadow: none; }
.osk-key.osk-hide { font-size: 16px; color: var(--muted); background: transparent; }

/* --- App-only on Android (see "App-only on Android" in app.js) --- */
.app-only .moved-card h1 { color: var(--text); }
.moved-card .moved-card .app-only-small, .app-only-small { color: var(--muted); font-size: 16px; line-height: 1.4; margin: 8px 0 16px; }
#app-only-override-box { margin-top: 36px; }
.install-first[hidden], .login-form[hidden] { display: none; }
.install-first { text-align: left; }
.install-first h2 { font-size: 24px; margin: 0 0 12px; }
.install-first ol { font-size: 18px; line-height: 1.45; padding-left: 24px; }
.install-first ol li { margin-bottom: 10px; }
.install-first .link-btn { font-size: 15px; margin: 8px 0 0; }
/* The tab is being used anyway (PIN override / set up in a tab): always in view, never dismissable. */
.override-banner { position: sticky; top: 0; z-index: 7; margin: 0; padding: 10px 16px; background: #fdf3e3; color: var(--amber); border-bottom: 2px solid #d39b3a; font-size: 16px; font-weight: 700; text-align: center; }
.override-banner[hidden] { display: none; }
/* The "kiosk has moved" PIN box: a text box shown as dots (not a password field — no save prompts). */
.masked-digits { -webkit-text-security: disc; }
.storage-space { color: var(--amber); font-size: 15px; font-weight: 600; }
.storage-space[hidden] { display: none; }
