/* ============================================
   STYLE 6: FLOATING CARD - Login Page CSS
   Lingualab
   ============================================ */

:root {
  --bg-primary: #0a0f1a;
  --bg-secondary: #0f1729;
  --bg-deep: #0c1220;
  --bg-card: linear-gradient(145deg, #0f1729 0%, #0c1220 100%);
  /* One blue family. The gradient used to run blue -> sky -> cyan. */
  --accent-primary: #3b82f6;
  --accent-secondary: #60a5fa;
  --accent-tertiary: #93c5fd;
  --accent-gradient: linear-gradient(135deg, #2563eb 0%, #3b82f6 50%, #60a5fa 100%);
  --success: #10b981;
  --error: #ef4444;
  --warning: #f59e0b;
  --text-primary: #ffffff;
  --text-secondary: #9ca3af;
  --text-muted: #6b7280;
  --border-color: rgba(255, 255, 255, 0.06);
}

/* The login page is the FIRST screen anyone sees, so it has to match the app
   it opens. It carries its own complete token set (it does not load the shared
   app-settings stylesheet), so light mode is restated here in full. The class
   comes from js/app-settings.js, which index.html loads with the panel opted
   out - the theme is applied, no settings wheel appears on the login screen. */
.light-mode {
  --bg-primary: #f6f8fb;
  --bg-secondary: #ffffff;
  --bg-deep: #f2f6fc;
  --bg-card: linear-gradient(145deg, #ffffff 0%, #f7faff 100%);
  --accent-primary: #2563eb;
  --accent-secondary: #2563eb;
  --accent-tertiary: #1d4ed8;
  --accent-gradient: linear-gradient(135deg, #1d4ed8 0%, #2563eb 50%, #3b82f6 100%);
  --success: #15803d;
  --error: #b91c1c;
  --warning: #b45309;
  --text-primary: #0f172a;
  --text-secondary: #475569;
  --text-muted: #5b6b7f;
  --border-color: rgba(15, 23, 42, 0.10);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html, body {
  overflow-x: hidden;
  max-width: 100vw;
}

body {
  font-family: var(--ll-font);
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-primary);
  position: relative;
  overflow: hidden;
  padding: 20px;
}

/* Particle canvas */
#particles {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

/* Gradient overlay */
.gradient-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: 
    radial-gradient(ellipse at top left, rgba(59, 130, 246, 0.1) 0%, transparent 50%),
    radial-gradient(ellipse at bottom right, rgba(96, 165, 250, 0.1) 0%, transparent 50%);
  z-index: 1;
  pointer-events: none;
}

/* ============================================
   FLOATING CARD
   ============================================ */

.container {
  position: relative;
  z-index: 10;
  width: 100%;
  max-width: 420px;
}

.login-card {
  width: 100%;
  padding: 40px 32px;
  background: var(--bg-card);
  border-radius: 28px;
  border: 1px solid var(--border-color);
  box-shadow: 
    0 30px 60px rgba(0, 0, 0, 0.5),
    0 0 0 1px rgba(255, 255, 255, 0.05) inset,
    0 -20px 40px rgba(59, 130, 246, 0.08) inset;
  animation: cardFloat 6s ease-in-out infinite;
}

@keyframes cardFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}

/* ============================================
   LOGO SECTION
   ============================================ */

.logo-section {
  text-align: center;
  margin-bottom: 28px;
}

.logo-container {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 12px 20px;
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.15), rgba(96, 165, 250, 0.15));
  border-radius: 50px;
  margin-bottom: 16px;
  border: 1px solid rgba(59, 130, 246, 0.15);
}

.logo-icon {
  height: 60px;
  width: auto;
  border-radius: 12px;
}

.logo-text {
  font-size: 1rem;
  font-weight: 700;
  background: var(--accent-gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.welcome-text {
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 6px;
}

.subtitle-text {
  color: var(--text-muted);
  font-size: 0.85rem;
}

/* ============================================
   TABS
   ============================================ */

.tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 24px;
}

.tab {
  flex: 1;
  padding: 12px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  border-radius: 12px;
  transition: all 0.3s ease;
  position: relative;
}

.tab.active {
  color: var(--text-primary);
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.25), rgba(96, 165, 250, 0.25));
}

.tab.active::after {
  content: '';
  position: absolute;
  bottom: -4px;
  left: 50%;
  transform: translateX(-50%);
  width: 30px;
  height: 3px;
  background: var(--accent-gradient);
  border-radius: 2px;
}

.tab:hover:not(.active) {
  color: var(--text-secondary);
  background: var(--tint-surface, rgba(255, 255, 255, 0.03));
}

/* ============================================
   FORM SECTIONS
   ============================================ */

.form-section {
  display: none;
}

.form-section.active {
  display: block;
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ============================================
   FORM ELEMENTS
   ============================================ */

.form-group {
  margin-bottom: 16px;
}

.form-label {
  display: block;
  color: var(--text-secondary);
  font-size: 0.75rem;
  font-weight: 500;
  margin-bottom: 8px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.input-wrapper {
  position: relative;
}

.input-icon {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 1rem;
  opacity: 0.5;
}

.form-input {
  width: 100%;
  padding: 14px 14px 14px 42px;
  background: var(--tint-surface, rgba(255, 255, 255, 0.03));
  border: 2px solid var(--border-color);
  border-radius: 14px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.9rem;
  transition: all 0.3s ease;
}

.form-input:focus {
  outline: none;
  border-color: var(--accent-primary);
  background: rgba(59, 130, 246, 0.05);
  box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.08);
}

.form-input::placeholder {
  color: var(--text-muted);
}

.form-input.no-icon {
  padding-left: 14px;
}

/* Select styling */
.form-select {
  width: 100%;
  padding: 14px;
  background: var(--tint-surface, rgba(255, 255, 255, 0.03));
  border: 2px solid var(--border-color);
  border-radius: 14px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  transition: all 0.3s ease;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2'%3E%3Cpolyline points='6,9 12,15 18,9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 18px;
}

.form-select:focus {
  outline: none;
  border-color: var(--accent-primary);
  background-color: rgba(59, 130, 246, 0.05);
}

.form-select option {
  background: var(--bg-secondary, #0f1729);
  color: var(--text-primary);
}

/* Inline form groups */
.form-row {
  display: flex;
  gap: 10px;
}

.form-row .form-select-small {
  width: 100px;
}

.form-row .form-input {
  flex: 1;
}

/* ============================================
   OPTIONS ROW
   ============================================ */

.options-row {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 20px;
  margin-top: -8px;
}

.forgot-link {
  color: var(--accent-primary);
  font-size: 0.8rem;
  text-decoration: none;
  font-weight: 500;
  transition: color 0.3s;
}

.forgot-link:hover {
  color: var(--accent-secondary);
}

/* ============================================
   BUTTONS
   ============================================ */

.btn-submit {
  width: 100%;
  padding: 16px;
  background: var(--accent-gradient);
  border: none;
  border-radius: 14px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 10px 30px rgba(59, 130, 246, 0.25);
  position: relative;
  overflow: hidden;
}

.btn-submit::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
  transition: left 0.5s;
}

.btn-submit:hover {
  transform: translateY(-3px);
  box-shadow: 0 15px 40px rgba(59, 130, 246, 0.35);
}

.btn-submit:hover::before {
  left: 100%;
}

.btn-submit:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

/* ============================================
   DIVIDER
   ============================================ */

.divider {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 20px 0;
  color: var(--text-muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 1px;
}

.divider::before,
.divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
}

/* ============================================
   GOOGLE BUTTON
   ============================================ */

.btn-google {
  width: 100%;
  padding: 14px;
  background: var(--tint-surface, rgba(255, 255, 255, 0.03));
  border: 2px solid var(--border-color);
  border-radius: 14px;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  transition: all 0.3s ease;
}

.btn-google:hover {
  background: var(--tint-surface, rgba(255, 255, 255, 0.06));
  border-color: var(--tint-line-strong, rgba(255, 255, 255, 0.15));
  transform: translateY(-2px);
  color: var(--text-primary);
}

.btn-google svg {
  width: 20px;
  height: 20px;
}

/* Google is the MAIN way in (2026-09-28): bigger, bolder, first on both tabs. */
.btn-google.ll-google-btn {
  padding: 16px;
  font-size: 1rem;
  font-weight: 700;
  color: var(--text-primary);
  border-color: var(--accent-primary, #2563eb);
}
/* Google profile-completion form (built in main.js showGoogleCompleteForm).
   Header = the same tinted box as the email-verify panel; Cancel = a plain
   secondary button, full width, like "Use another account" there. */
.ll-gc-head {
  margin: 0 0 18px;
  padding: 14px 16px;
  border-radius: 10px;
  background: rgba(37, 99, 235, 0.08);
  border: 1px solid var(--border-color);
  color: var(--text-secondary);
  font-size: 0.95em;
  line-height: 1.5;
}
.ll-gc-title { font-weight: 600; color: var(--text-primary); margin-bottom: 4px; font-size: 1.05em; }
.ll-gc-tr { margin-top: 2px; font-size: 0.92em; }
.ll-gc-cancel {
  display: block;
  width: 100%;
  margin-top: 12px;
  padding: 12px 14px;
  border-radius: 14px;
  background: transparent;
  border: 1px solid var(--border-color);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 500;
  cursor: pointer;
}
.ll-gc-cancel:hover { border-color: var(--accent-primary, #2563eb); color: var(--text-primary); }
/* Google in the same liquid style as Sign In (1 Oct 2026): the G mark and the
   label side by side, above the button's moving highlight. */
.btn-submit.ll-google-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
.btn-submit.ll-google-btn svg {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  position: relative;
  z-index: 1;
}
.btn-submit.ll-google-btn[disabled] {
  opacity: 0.75;
  cursor: progress;
  transform: none;
}
.btn-google.ll-google-btn[disabled] {
  opacity: 0.75;
  cursor: progress;
  transform: none;
}
.ll-google-hint {
  margin: 8px 2px 0;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--text-muted);
  text-align: center;
}
/* "You opened Lingualab inside another app" (main.js llInAppGate). */
.ll-inapp {
  margin: 0 0 16px;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid var(--accent-primary, #2563eb);
  background: rgba(37, 99, 235, 0.08);
  color: var(--text-primary);
  font-size: 0.92rem;
  line-height: 1.5;
}
.ll-inapp strong { display: block; margin-bottom: 4px; }
.ll-inapp .ll-inapp-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.ll-inapp button, .ll-inapp a {
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid var(--accent-primary, #2563eb);
  background: var(--accent-primary, #2563eb);
  color: #ffffff;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

/* ============================================
   MESSAGES
   ============================================ */

.message {
  padding: 12px 16px;
  border-radius: 12px;
  font-size: 0.85rem;
  margin-bottom: 16px;
  display: none;
  animation: fadeIn 0.3s ease;
}

.message.error {
  display: block;
  background: rgba(239, 68, 68, 0.1);
  border: 1px solid rgba(239, 68, 68, 0.3);
  color: var(--text-error, #fca5a5);
}

.message.success {
  display: block;
  background: rgba(16, 185, 129, 0.1);
  border: 1px solid rgba(16, 185, 129, 0.3);
  color: var(--text-success, #6ee7b7);
}

/* ============================================
   FOOTER
   ============================================ */

.footer-text {
  text-align: center;
  margin-top: 20px;
  color: var(--text-muted);
  font-size: 0.75rem;
}

.footer-text a {
  color: var(--accent-primary);
  text-decoration: none;
}

.footer-text a:hover {
  text-decoration: underline;
}

/* ============================================
   LOADING SPINNER
   ============================================ */

.loading-spinner {
  display: inline-block;
  width: 18px;
  height: 18px;
  border: 2px solid var(--tint-line-strong, rgba(255,255,255,0.3));
  border-radius: 50%;
  border-top-color: white;
  animation: spin 0.8s linear infinite;
  margin-right: 8px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* ============================================
   TOS MODAL
   ============================================ */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
  padding: 20px;
}

.modal-overlay.open {
  opacity: 1;
  pointer-events: auto;
}

.modal-card {
  background: linear-gradient(145deg, var(--bg-secondary, #0f1729) 0%, var(--bg-deep, #0c1220) 100%);
  border-radius: 20px;
  padding: 28px;
  max-width: 700px;
  width: 100%;
  max-height: 85vh;
  overflow-y: auto;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.5);
  border: 1px solid var(--border-color);
  position: relative;
  animation: modalPop 0.25s ease;
}

@keyframes modalPop {
  from { transform: scale(0.95); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

.modal-close {
  position: absolute;
  top: 16px;
  right: 20px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: 1.8rem;
  cursor: pointer;
  transition: color 0.3s;
  line-height: 1;
}

.modal-close:hover {
  color: var(--text-primary);
}

.modal-muted {
  color: var(--text-secondary);
  font-size: 0.9rem;
  margin-bottom: 12px;
  line-height: 1.6;
}

.tos-content h2 {
  color: var(--text-primary);
  margin-bottom: 8px;
  font-size: 1.3rem;
}

.tos-content h3 {
  margin-top: 20px;
  font-size: 1rem;
  color: var(--text-primary);
}

.tos-content ul {
  margin-left: 20px;
  margin-top: 8px;
  line-height: 1.8;
}

/* Language toggle buttons */
.lang-toggle {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
}

.lang-btn {
  padding: 8px 16px;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 600;
  font-size: 0.85rem;
  transition: all 0.3s ease;
  font-family: inherit;
}

.lang-btn.active {
  border: 2px solid var(--accent-primary);
  background: var(--accent-gradient);
  color: white;
}

.lang-btn:not(.active) {
  border: 2px solid var(--border-color);
  background: transparent;
  color: var(--text-secondary);
}

.lang-btn:not(.active):hover {
  border-color: var(--accent-primary);
}

/* ============================================
   ANIMATED TEXT CYCLE
   ============================================ */

.text-cycle-wrapper {
  display: inline-block;
  position: relative;
  overflow: hidden;
  vertical-align: bottom;
  height: 1.4em;
  min-width: 6ch;
}

.text-cycle-word {
  display: inline-block;
  background: var(--accent-gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  font-weight: 700;
  white-space: nowrap;
  animation: cycleWordIn 0.45s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

.text-cycle-word.exit {
  animation: cycleWordOut 0.35s ease-in forwards;
  position: absolute;
  top: 0;
  left: 0;
}

@keyframes cycleWordIn {
  from { opacity: 0; transform: translateY(60%); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes cycleWordOut {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(-60%); }
}

/* ============================================
   LIQUID GLASS BUTTON
   ============================================ */

.btn-liquid {
  background: rgba(59, 130, 246, 0.25) !important;
  backdrop-filter: blur(16px) !important;
  -webkit-backdrop-filter: blur(16px) !important;
  border: 1px solid var(--tint-line-strong, rgba(255, 255, 255, 0.18)) !important;
  box-shadow:
    0 8px 32px rgba(59, 130, 246, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    inset 0 -1px 0 rgba(0, 0, 0, 0.15) !important;
}

.btn-liquid::before {
  content: '';
  position: absolute;
  top: -50%;
  left: -20%;
  width: 70%;
  height: 200%;
  background: radial-gradient(ellipse, rgba(255,255,255,0.22) 0%, transparent 65%);
  border-radius: 50%;
  animation: liquidBlob 4s ease-in-out infinite;
  pointer-events: none;
  z-index: 0;
}

.btn-liquid span, .btn-liquid {
  position: relative;
  z-index: 1;
}

@keyframes liquidBlob {
  0%   { transform: translate(0%,   0%)   scale(1);    }
  30%  { transform: translate(40%,  15%)  scale(1.15); }
  65%  { transform: translate(10%,  30%)  scale(0.9);  }
  100% { transform: translate(0%,   0%)   scale(1);    }
}

.btn-liquid:hover {
  background: rgba(59, 130, 246, 0.4) !important;
  border-color: var(--tint-line-strong, rgba(255, 255, 255, 0.3)) !important;
  box-shadow:
    0 14px 40px rgba(59, 130, 246, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.25),
    inset 0 -1px 0 rgba(0, 0, 0, 0.1) !important;
}

/* ============================================
   RESPONSIVE
   ============================================ */

@media (max-width: 480px) {
  body {
    padding: 12px;
    /* The Register and Google "complete profile" forms are taller than a phone
       viewport. The base `overflow:hidden` + vertical centering hid the bottom
       fields and the Complete Registration button with no way to scroll. Pin to
       the top and allow vertical scrolling so the whole form is reachable.
       (overflow-x stays hidden via the html,body rule.) */
    align-items: flex-start;
    overflow-y: auto;
  }

  .login-card {
    padding: 28px 20px;
    border-radius: 20px;
    animation: none;
  }
  
  .logo-container {
    padding: 10px 16px;
  }
  
  .logo-icon {
    height: 28px;
  }
  
  .logo-text {
    font-size: 0.9rem;
  }
  
  .welcome-text {
    font-size: 1.2rem;
  }
  
  .tab {
    padding: 10px 8px;
    font-size: 0.85rem;
  }
  
  .form-input,
  .form-select {
    padding: 12px;
    font-size: 0.85rem;
  }
  
  .form-input {
    padding-left: 38px;
  }
  
  .btn-submit {
    padding: 14px;
  }
  
  .modal-card {
    padding: 20px;
    border-radius: 16px;
  }
}

@media (max-width: 360px) {
  .form-row {
    flex-direction: column;
  }
  
  .form-row .form-select-small {
    width: 100%;
  }
}

/* ============================================
   LIGHT MODE - surfaces that were written for a dark card
   The rules above use white-on-black idioms: a heavy black drop shadow, a
   white inset highlight, and translucent-white fills for inputs and hover.
   On white paper the shadow reads as grime and the white fills are invisible.
   ============================================ */
.light-mode .login-card {
  box-shadow:
    0 24px 48px rgba(15, 23, 42, 0.10),
    0 2px 8px rgba(15, 23, 42, 0.04),
    0 0 0 1px rgba(15, 23, 42, 0.03) inset;
}
.light-mode .form-input,
.light-mode .form-select {
  background: #ffffff;
  border-color: #dbe3ef;
}
.light-mode .form-input:focus,
.light-mode .form-select:focus {
  background: #ffffff;
  border-color: var(--accent-primary);
  box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.12);
}
.light-mode .tab:hover:not(.active) {
  background: rgba(15, 23, 42, 0.04);
}
/* The seal tile behind the wordmark: a pale blue chip rather than a dark one. */
.light-mode .logo-container {
  background: linear-gradient(135deg, rgba(37, 99, 235, 0.08), rgba(96, 165, 250, 0.10));
  border-color: rgba(37, 99, 235, 0.16);
}

/* ============================================================
   LIGHT MODE - generated by tools/light-coverage.js findings
   Each rule mirrors a real one above and flips only its SURFACE,
   keeping the original alpha so translucent panels stay translucent
   and nothing about the layering changes. Dark is untouched.
   ============================================================ */
.light-mode .modal-overlay {
  background: rgba(246, 248, 251, 0.85);
}

/* ============================================================
   LOGIN HERO PHOTO
   ------------------------------------------------------------
   Full-bleed, and purely ADDITIVE. Nothing that was on this page moves: the
   .login-card stays centred exactly where it was, #particles keeps drifting,
   and .gradient-overlay stays. This slots in underneath all of them.

   Final stacking, bottom to top:
     body::before  -1   the photograph
     body::after   -1   a scrim over it, so the photo never competes with the card
     #particles     0   (unchanged)
     .gradient-overlay 1 (unchanged)
     .container    10   the login card (unchanged)

   Every visible word on this page lives inside .login-card, which has a solid
   --bg-card background, so no text ever sits on the photograph. The scrim is
   therefore about composition, not legibility - it keeps a bright sunset from
   pulling the eye off the form.

   image-set() lets the browser pick: AVIF 136 KB, WebP 203 KB, JPEG 277 KB.
   Below 760px the -sm pair is used instead (AVIF 50 KB), because a full-bleed
   background is cropped hard on a narrow screen and shipping the desktop file
   to a phone wastes bandwidth on the connection least able to spare it.

   Photo: free-tier Unsplash, Pang Yuhao. Fixed attachment is deliberately NOT
   used - it is a known jank source on mobile Safari.
   ============================================================ */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  background-color: var(--bg-primary);
  background-image: image-set(
    url('/img/login-hero.avif') type('image/avif'),
    url('/img/login-hero.webp') type('image/webp'),
    url('/img/login-hero.jpg')  type('image/jpeg')
  );
  background-image: -webkit-image-set(
    url('/img/login-hero.avif') type('image/avif'),
    url('/img/login-hero.webp') type('image/webp'),
    url('/img/login-hero.jpg')  type('image/jpeg')
  );
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  pointer-events: none;
}

/* The scrim. Dark theme sinks the photo so the card reads as the lit object;
   light theme lifts it instead, because the same veil that helps on navy
   turns a white card muddy. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(10, 15, 26, 0.42) 0%,
    rgba(10, 15, 26, 0.56) 55%,
    rgba(10, 15, 26, 0.72) 100%
  );
}

.light-mode body::after,
body.light-mode::after {
  /* Deliberately light. The card carries its own opaque gradient, so nothing
     here is load-bearing for legibility - this only stops the photograph
     competing with the form. Started at 0.62-0.88 and the picture washed out
     to almost nothing, which defeats the point of having one. */
  background: linear-gradient(
    180deg,
    rgba(246, 248, 251, 0.30) 0%,
    rgba(246, 248, 251, 0.42) 55%,
    rgba(246, 248, 251, 0.58) 100%
  );
}

@media (max-width: 760px) {
  body::before {
    background-image: image-set(
      url('/img/login-hero-sm.avif') type('image/avif'),
      url('/img/login-hero-sm.webp') type('image/webp'),
      url('/img/login-hero-sm.jpg')  type('image/jpeg')
    );
    background-image: -webkit-image-set(
      url('/img/login-hero-sm.avif') type('image/avif'),
      url('/img/login-hero-sm.webp') type('image/webp'),
      url('/img/login-hero-sm.jpg')  type('image/jpeg')
    );
  }
}

/* The "Can't sign in?" line. Slightly stronger than the terms line beneath
   it, because someone who is locked out needs to find it, but still quiet
   enough that it is not competing with the Sign In button. */
.footer-help {
  margin-bottom: 6px;
}
.footer-help a {
  font-weight: 600;
  text-decoration: none;
}
.footer-help a:hover {
  text-decoration: underline;
}

/* ============================================================
   HELP BUTTON (4 Oct 2026)
   A round chat-style button in the bottom-right corner, outside the card,
   like the help buttons on other websites. It opens a small "Need help?"
   panel with "Common questions" (only when the admin has published some for
   this page; js/faq.js unhides that row) and "Contact us". Both rows open the
   same dialogs as before. Above the card (z 10), below every dialog (1000).
   ============================================================ */
.help-fab {
  position: fixed;
  right: calc(18px + env(safe-area-inset-right, 0px));
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
}
.help-fab-btn {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  background: var(--accent-gradient);
  box-shadow: 0 10px 26px rgba(37, 99, 235, 0.42), 0 2px 6px rgba(0, 0, 0, 0.25);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.help-fab-btn:hover { transform: translateY(-2px); box-shadow: 0 14px 30px rgba(37, 99, 235, 0.5), 0 2px 6px rgba(0, 0, 0, 0.25); }
.help-fab-btn:focus-visible { outline: 3px solid var(--accent-tertiary); outline-offset: 3px; }
.help-fab-btn svg { width: 28px; height: 28px; }
.help-fab-btn .help-fab-x { display: none; }
.help-fab-btn[aria-expanded="true"] .help-fab-chat { display: none; }
.help-fab-btn[aria-expanded="true"] .help-fab-x { display: block; }

.help-panel {
  width: min(320px, calc(100vw - 36px));
  background: linear-gradient(145deg, var(--bg-secondary) 0%, var(--bg-deep) 100%);
  border: 1px solid var(--border-color);
  border-radius: 18px;
  box-shadow: 0 24px 50px rgba(0, 0, 0, 0.45);
  padding: 16px;
  color: var(--text-primary);
  transform-origin: bottom right;
  animation: helpPanelIn 0.18s ease;
}
@keyframes helpPanelIn { from { opacity: 0; transform: translateY(8px) scale(0.97); } to { opacity: 1; transform: none; } }
.help-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.help-panel-title { font-size: 1.05rem; font-weight: 700; margin: 0; }
.help-panel-sub { margin: 4px 0 12px; font-size: 0.88rem; color: var(--text-secondary); line-height: 1.45; }
.help-panel-close {
  width: 32px; height: 32px; border-radius: 50%; border: none; cursor: pointer;
  background: transparent; color: var(--text-secondary); font-size: 1.3rem; line-height: 1;
}
.help-panel-close:hover, .help-panel-close:focus-visible { background: var(--border-color); color: var(--text-primary); outline: none; }
.help-panel-rows { display: grid; gap: 8px; }
.help-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border-radius: 14px;
  border: 1px solid var(--border-color);
  color: var(--text-primary);
  text-decoration: none;
  background: rgba(59, 130, 246, 0.06);
  transition: background 0.15s ease, border-color 0.15s ease;
}
.help-row:hover, .help-row:focus-visible { background: rgba(59, 130, 246, 0.14); border-color: var(--accent-primary); outline: none; }
.help-row-icon {
  flex: 0 0 38px; width: 38px; height: 38px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-gradient); color: #ffffff;
}
.help-row-icon svg { width: 20px; height: 20px; }
.help-row-text { display: grid; gap: 1px; min-width: 0; }
.help-row-title { font-weight: 700; font-size: 0.95rem; }
.help-row-desc { font-size: 0.82rem; color: var(--text-secondary); line-height: 1.35; }
.help-row[hidden] { display: none; }
.light-mode .help-panel { box-shadow: 0 24px 50px rgba(15, 23, 42, 0.18); }
.light-mode .help-row { background: rgba(37, 99, 235, 0.05); }
.light-mode .help-row:hover, .light-mode .help-row:focus-visible { background: rgba(37, 99, 235, 0.10); }
/* Phones: the button must never sit on top of Sign In or Google (real phone
   windows are short, and a tap there would open help instead of signing in).
   It stays at the bottom of the PAGE, in a strip kept free under the card,
   and scrolls with it (body is position: relative). */
@media (max-width: 480px) {
  body { padding-bottom: 88px; }
  .help-fab { position: absolute; right: calc(14px + env(safe-area-inset-right, 0px)); bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
}
/* Only the button and the open panel take taps, never the empty space the
   wrapper spans beside the button while the panel is open. */
.help-fab { pointer-events: none; }
.help-fab > * { pointer-events: auto; }
/* A phone held sideways: the panel scrolls rather than pushing its title off
   the top of the screen. */
.help-panel { max-height: calc(100vh - 110px); max-height: calc(100dvh - 110px); overflow-y: auto; }
.help-panel-close:focus-visible { outline: 2px solid var(--accent-primary); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .help-panel { animation: none; }
  .help-fab-btn { transition: none; }
}
