.auth-main {
  padding: 56px 0 80px;
  position: relative;
  overflow: hidden;
}

.auth-wrap { display: flex; justify-content: center; }

/* =========================================================
   AMBIENT BACKGROUND (login / register)
   Extends the homepage hero's drifting-voxel motif (.floaty,
   defined in style.css) across the whole auth page rather than a
   one-off effect just for these two pages, plus a slow
   "breathing" glow centered behind the card (glow-breathe is
   defined once in style.css and shared with the home page's
   .page-glow). Purely decorative — aria-hidden, and switched off
   under prefers-reduced-motion via style.css's reduced-motion
   block, which style.css is always loaded before this file so
   the shared keyframe and reduced-motion rule are both in scope
   on every page that uses these classes.
   ========================================================= */
.auth-card { position: relative; z-index: 1; }

.auth-glow {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 640px;
  height: 640px;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgba(111, 217, 74, 0.14), transparent 70%);
  animation: glow-breathe 5s ease-in-out infinite;
  pointer-events: none;
}

.auth-floaty-1 { width: 20px; height: 20px; top: 10%; left: 8%; animation-delay: 0s; }
.auth-floaty-2 { width: 14px; height: 14px; top: 78%; left: 12%; animation-delay: 2s; background: linear-gradient(160deg, var(--gold), var(--gold-dark)); }
.auth-floaty-3 { width: 18px; height: 18px; top: 20%; right: 10%; animation-delay: 1s; }
.auth-floaty-4 { width: 16px; height: 16px; top: 70%; right: 6%; animation-delay: 3.5s; background: linear-gradient(160deg, var(--gold), var(--gold-dark)); }
.auth-floaty-5 { width: 12px; height: 12px; top: 45%; left: 3%; animation-delay: 2.7s; }
.auth-floaty-6 { width: 22px; height: 22px; top: 50%; right: 3%; animation-delay: 0.8s; }

/* narrower centered column for stacked cards that aren't a
   side-by-side row — used by the payment page. Doesn't carry
   .wrap's class (its max-width is narrower than .wrap's), so it
   needs its own matching horizontal padding — without this, pages
   using .narrow-wrap had NO horizontal margin at all on mobile,
   unlike every other page which gets .wrap's padding: 0 24px. */
.narrow-wrap { max-width: 640px; margin: 0 auto; padding: 0 24px; }

.narrow-wrap .auth-card { max-width: none; margin-bottom: 20px; }
.narrow-wrap .auth-card:last-child { margin-bottom: 0; }

.auth-card {
  width: 100%;
  max-width: 420px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
  padding: 32px;
}

.auth-card h1 {
  font-family: var(--font-display);
  font-size: 1.5rem;
  margin-bottom: 6px;
}

.auth-sub {
  color: var(--text-dim);
  font-size: 0.9rem;
  margin-bottom: 24px;
}

/* Shared by every form on an auth-card-style page (login,
   register, and now the profile/settings pages too) — add
   class="form-styled" to a <form> to get this look instead of
   repeating the same rules per-page. Excludes .radio-option and
   .checkbox-row so it doesn't stomp the flex layout those labels
   need (without this, a .checkbox-row's display:flex loses to this
   rule's higher specificity, and its voxel box falls back to plain
   inline baseline alignment against the label text instead of
   sitting centered with it). */
.form-styled label:not(.radio-option):not(.checkbox-row) {
  display: block;
  font-size: 0.85rem;
  font-weight: 500;
  margin: 16px 0 6px;
}

.form-styled label:not(.radio-option):not(.checkbox-row):first-of-type { margin-top: 0; }

.optional { color: var(--text-faint); font-weight: 400; }

.form-styled input[type="email"],
.form-styled input[type="password"],
.form-styled input[type="text"],
.form-styled input[type="number"],
.form-styled select {
  width: 100%;
  background: var(--panel-raised);
  border: 1px solid var(--panel-border);
  color: var(--text);
  padding: 10px 12px;
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-size: 0.95rem;
}

/* read-only display of the current profile values, shown until
   "Edit" is clicked */
.profile-view { margin-bottom: 4px; }

.profile-view-row {
  padding: 12px 0;
  border-bottom: 1px solid var(--panel-border);
}

.profile-view-row:last-child { border-bottom: none; }

.profile-view-label {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-faint);
  margin-bottom: 4px;
}

.profile-view-value {
  font-size: 0.95rem;
  color: var(--text);
  margin: 0;
}

.radio-group { display: flex; gap: 18px; margin-top: 4px; flex-wrap: wrap; }

.radio-option {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.88rem;
  font-weight: 400;
  color: var(--text-dim);
  cursor: pointer;
  margin: 0;
}

/* The native radio input stays in the DOM (for click/keyboard/
   screen-reader support) but is visually hidden — .radio-box is
   what actually gets styled: an outlined square "slot", and a
   green square filling ~90% of it when selected. Same idea as a
   Minecraft inventory slot with an item in it. */
.radio-input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.radio-box {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  border: 2px solid var(--text-faint);
  border-radius: 2px;
  background: var(--panel-raised);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.15s ease;
}

.radio-input:checked + .radio-box { border-color: var(--text); }

.radio-input:checked + .radio-box::after {
  content: "";
  width: 90%;
  height: 90%;
  background: var(--gold);
  border-radius: 1px;
}

/* A locked-out option (e.g. VIP while MVP is already active, or
   Legacy Pass while one is already running — see pay.js's
   applyShopLocks()) — dims the option and swaps the cursor rather
   than just silently ignoring clicks on it. */
.radio-option:has(.radio-input:disabled),
.checkbox-row:has(.radio-input:disabled) {
  opacity: 0.4;
  cursor: not-allowed;
}

.radio-input:focus-visible + .radio-box {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

.field-hint {
  font-size: 0.78rem;
  color: var(--text-faint);
  margin-top: 5px;
}

/* Why an option is locked out (redstone — same "can't do this"
   color used for rejected/left status badges) vs. a positive
   heads-up about bonus time from an upgrade (emerald, same as
   .goal-meta .highlight elsewhere). */
.field-hint--locked { color: var(--redstone); }
.field-hint--upgrade { color: var(--emerald); }

/* Live password-strength checklist, populated and kept in sync by
   initPasswordChecklist() in utils.js — one rule per <li>, turning
   from a hollow dot to a checked emerald dot as it's satisfied. */
.password-checklist {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.password-checklist li {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 0.78rem;
  color: var(--text-faint);
  transition: color 0.15s ease;
}

.password-checklist li::before {
  content: "○";
  font-size: 0.65rem;
  color: var(--text-faint);
  transition: color 0.15s ease;
}

.password-checklist li.rule-passed {
  color: var(--text-dim);
}

.password-checklist li.rule-passed::before {
  content: "✓";
  font-size: 0.75rem;
  color: var(--emerald);
}

/* Soft, non-blocking heads-up (e.g. "someone else already has this
   real name") — distinct from .form-error, since this never stops
   the form from being submitted. */
.field-warning {
  font-size: 0.78rem;
  color: var(--gold);
  margin-top: 5px;
  min-height: 1em;
}

.checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 20px;
  font-size: 0.82rem;
  color: var(--text-dim);
  cursor: pointer;
}

.checkbox-row input { margin-top: 3px; }

/* Opt-in modifier for a checkbox styled with the same .radio-box
   "voxel slot" square used by the radio groups above (.radio-input/
   .radio-box don't actually care about the input's type — :checked
   matches a checkbox just as well as a radio, so the battlepass
   add-on reuses those same classes instead of a separate set).
   flex-start suits a native checkbox glyph sitting slightly above
   the baseline; this box wants to sit centered with its label like
   a radio option does. Doesn't touch plain .checkbox-row usage
   elsewhere (e.g. the registration consent checkbox). */
.checkbox-row--voxel { align-items: center; }

.form-error {
  color: #e77;
  font-size: 0.85rem;
  margin-top: 14px;
  min-height: 1em;
}

.form-success {
  color: var(--emerald);
  font-size: 0.85rem;
  margin-top: 14px;
  min-height: 1em;
}

/* stacks form cards vertically with breathing room between them —
   used on the settings page (change email / change password) */
.panel-stack {
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

.auth-card .btn-gold {
  width: 100%;
  margin-top: 22px;
  text-align: center;
}

.auth-switch {
  text-align: center;
  margin-top: 20px;
  font-size: 0.85rem;
  color: var(--text-dim);
}

.auth-switch a { color: var(--gold); font-weight: 500; }

.verify-notice {
  margin-top: 18px;
  padding: 14px;
  background: var(--panel-raised);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
  font-size: 0.85rem;
  color: var(--text-dim);
}

/* .btn-ghost itself lives in style.css now — it's used outside
   the auth pages too (ledger pagination, the profile Edit
   button). Just the extra top margin needed here, next to the
   verify-notice text. */
.verify-notice .btn-ghost { margin-top: 10px; }
