/* ============================================
   GAME LAUNCHER
   Splash sequence, login screen, preloader bar.
   ============================================ */

/* --- Launcher Container --- */

#launcher {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: var(--bg-void);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Launcher-level toast notifications. The in-game #toast-container lives at body
   level (it used to be in the hidden game HUD), so the launcher needs its own
   visible container. Fixed bottom-center, ABOVE the launcher screens (z-index 1-10)
   AND the account modals + their shroud (z-index 199-200), all within #launcher's
   stacking context, so a success toast fired from the account modal is never hidden
   behind it. Toasts inside reuse .notification.toast; allow wrapping since launcher
   messages (e.g. a failed account-link) run longer than terse in-game toasts.
   pointer-events: none so it never blocks the screens behind it. */
#launcher-toast-container {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gui-gap-sm);
  max-width: min(90vw, 420px);
  pointer-events: none;
}

#launcher-toast-container:empty { display: none; }

#launcher-toast-container .notification.toast {
  white-space: normal;
  text-align: center;
}

#launcher.hidden {
  content-visibility: hidden;
  display: none;
}

/* --- Splash Phases --- */

.launcher-phase {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--fade-slow) ease-out;
  contain: layout style;
}

.launcher-phase.active {
  opacity: 1;
  pointer-events: auto;
}

/* --- Engine Splash (Pixel Arc Logo) --- */

.pa-logo {
  width: min(80vw, 490px);
  height: auto;
}

.pa-block,
.pa-text,
.pa-divider,
.pa-tagline-text {
  opacity: 0;
  transition:
    opacity 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94) var(--delay, 0ms),
    transform 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94) var(--delay, 0ms);
}

.pa-block {
  transform-box: fill-box;
  transform-origin: center;
  transform: scale3d(0, 0, 1);
  transition-timing-function:
    cubic-bezier(0.25, 0.46, 0.45, 0.94),
    cubic-bezier(0.34, 1.56, 0.64, 1);
  transition-duration: 150ms, 150ms;
}

.pa-text {
  transform: translate3d(0, 6px, 0);
}

.pa-text--tm {
  transform: none;
}

.pa-divider {
  transform-box: fill-box;
  transform-origin: top center;
  transform: scale3d(1, 0, 1);
  transition-duration: 250ms, 250ms;
}

.pa-tagline-text {
  transform: translate3d(12px, 0, 0);
}

/* Reveal state: .reveal on #engine-splash triggers all transitions */
#engine-splash.reveal .pa-block {
  opacity: 1;
  transform: scale3d(1, 1, 1);
}

#engine-splash.reveal .pa-text,
#engine-splash.reveal .pa-tagline-text {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

#engine-splash.reveal .pa-text--tm {
  transform: none;
}

#engine-splash.reveal .pa-divider {
  opacity: 1;
  transform: scale3d(1, 1, 1);
}

/* --- Game Splash (Sol Wilds Planet) --- */

.solwilds-logo {
  width: min(60vw, 400px);
  height: auto;
  transform: translate3d(-15px, 0, 0);
  transition: transform 1000ms ease-out;
}

.vl-band {
  opacity: 0;
  transform: translate3d(-40px, 0, 0);
  transition:
    opacity 250ms ease-out calc(var(--i, 0) * 60ms),
    transform 350ms cubic-bezier(0.25, 0.46, 0.45, 0.94) calc(var(--i, 0) * 60ms);
}

.vl-artifact {
  opacity: 0;
  transform: translate3d(-40px, 0, 0);
  transition:
    opacity 300ms ease-out calc(200ms + var(--i, 0) * 25ms),
    transform 350ms cubic-bezier(0.25, 0.46, 0.45, 0.94) calc(200ms + var(--i, 0) * 25ms);
}

#game-splash.reveal .solwilds-logo {
  transform: none;
}

#game-splash.reveal .vl-band {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

#game-splash.reveal .vl-artifact {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* --- Login Screen --- */

#login-screen {
  flex-direction: column;
}

.login-background {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center, var(--color-white-05) 0%, transparent 70%);
  pointer-events: none;
}

.login-content {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gui-gap-lg);
  z-index: 1;
  padding: var(--gui-padding);
}

.login-title {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 8vw, 4rem);
  font-weight: 700;
  letter-spacing: 0.15em;
  color: var(--text-primary);
}

.login-subtitle {
  font-family: var(--font-display);
  font-size: clamp(0.7rem, 1.8vw, 0.9rem);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-top: calc(-1 * var(--gui-gap));
}

/* --- Auth Forms --- */

.auth-form {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap-md);
  width: min(100%, 320px);
  margin-top: var(--gui-gap-lg);
}

.auth-form.hidden {
  display: none;
}

/* Sub-state wrapper divs inside the .auth-form screens group their elements, so those
   elements don't inherit the form's gap and would sit flush: the email screen's front
   door / consent gate / verify step, the recover screen's steps, and the MFA screen's
   factor-picker / TOTP section. Give each wrapper the same column gap. (.hidden is
   `display: none !important` in _utilities.css, so hiding a wrapper still wins over this
   `display: flex`.) Round 3 proposed `display: contents` to drop the wrappers from
   layout; round 4 reverted it because Safari has a long, still-present-in-2026 history of
   breaking keyboard focus / accessible names for interactive controls under
   `display: contents`, and these are the Safari-critical sign-in / recover / MFA forms. */
#emailcode-frontdoor,
#emailcode-consent-gate,
#emailcode-verify-step,
#recover-code-step,
#recover-email-step,
#recover-setemail-step,
#recover-setemail-verify,
#mfa-totp-section {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap-md);
}

.auth-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.auth-label {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
  letter-spacing: 0.03em;
}

.auth-input {
  width: 100%;
  padding: var(--gui-padding) var(--gui-gap);
  background: var(--frame-inner);
  border: 1px solid var(--alpha-white-08);
  border-radius: 4px;
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  outline: none;
  transition: border-color var(--ui-transition);
}

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

.auth-input:focus {
  border-color: var(--accent);
}

.auth-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.auth-error {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--danger);
  min-height: 1.2em;
}

.auth-success {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--success);
  min-height: 1.2em;
}

.auth-hint {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
  line-height: 1.4;
}

.auth-checkbox {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
  cursor: pointer;
  line-height: 1.4;
}

.auth-checkbox input[type="checkbox"] {
  accent-color: var(--accent);
  margin-top: 2px;
  flex-shrink: 0;
}

.auth-divider {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
}

.auth-divider::before,
.auth-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border-default);
}

.launcher-btn--discord {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 8px 12px;
  background: oklch(55% 0.15 264);
  color: oklch(100% 0 0);
  border: none;
  border-radius: 4px;
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  font-weight: 600;
  cursor: pointer;
  transition: background 150ms ease;
}

.launcher-btn--discord:hover {
  background: oklch(48% 0.15 264);
}

.launcher-btn--discord:active {
  background: oklch(42% 0.15 264);
}

.discord-icon {
  flex-shrink: 0;
}

.launcher-btn--steam {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 8px 12px;
  background: oklch(35% 0.04 245);
  color: oklch(100% 0 0);
  border: none;
  border-radius: 4px;
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  font-weight: 600;
  cursor: pointer;
  transition: background 150ms ease;
}

.launcher-btn--steam:hover {
  background: oklch(40% 0.05 245);
}

.launcher-btn--steam:active {
  background: oklch(30% 0.04 245);
}

.steam-icon {
  flex-shrink: 0;
}

/* "Last used" badge: pins to the corner of the sign-in button for the device's
   last-used method (see applyLastUsedBadge in launcher.js). The three host buttons
   get position:relative so this absolute pill anchors to them; absolute removes it
   from the flex flow so it doesn't shift the centered button label. */
.launcher-btn--discord,
.launcher-btn--steam,
#emailcode-send-btn {
  position: relative;
}

.launcher-last-used-badge {
  position: absolute;
  top: -6px;
  right: 8px;
  padding: 1px 6px;
  background: var(--accent);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: var(--font-size-2xs);
  font-weight: 600;
  line-height: 1.5;
  border-radius: 999px;
  white-space: nowrap;
  pointer-events: none;
}

/* Provider-aware routing: the hint under the email field when the typed address
   belongs to a linked Discord/Steam login, plus the "primed" ring on the button it
   points at. Both are static (no animation, so no compositor cost). */
.auth-route-hint {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-primary);
  line-height: 1.4;
  padding: var(--space-2, 8px) var(--space-3, 12px);
  border-left: 2px solid var(--accent);
  background: var(--color-lapis-10);
  border-radius: 4px;
}

.launcher-btn--primed {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Character Select linking nudge: a quiet, persistent pointer to Account so
   players discover login-linking before an unlinked sign-in makes a duplicate. */
.charsel-link-tip {
  margin-top: var(--space-2, 8px);
  text-align: center;
  line-height: 1.4;
}

#turnstile-container {
  display: flex;
  justify-content: center;
}

.auth-switch {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-align: center;
}

.auth-link {
  background: none;
  border: none;
  color: var(--accent);
  font: inherit;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.auth-link:hover {
  color: var(--text-primary);
}

/* --- Server Status --- */

.server-status {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  margin-top: var(--gui-gap);
}

.status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-muted);
  flex-shrink: 0;
}

.server-status.online .status-dot { background: var(--success); }
.server-status.offline .status-dot { background: var(--danger); }
.server-status.maintenance .status-dot { background: var(--warning); }

.maintenance-banner {
  background: oklch(0.35 0.06 70);
  color: var(--text-primary);
  padding: var(--gui-padding) calc(var(--gui-padding) * 2);
  text-align: center;
  font: var(--font-size-sm) / 1.4 var(--font-sans);
  border-radius: 4px;
  margin-block-end: var(--gui-gap);
}
.maintenance-banner.hidden { display: none; }

/* --- Launcher Screens (Character Select, Creation) --- */

.launcher-screen {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: safe center;
  gap: var(--gui-gap-lg);
  z-index: 3;
  background: var(--bg-void);
  overflow-y: auto;
}

.launcher-screen.hidden {
  display: none;
}

.screen-title {
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 3vw, 1.6rem);
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-primary);
}

/* --- Character Select --- */

.charsel-layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: var(--gui-gap-lg);
  width: min(100%, 640px);
}

@media (max-width: 600px) {
  .charsel-layout {
    grid-template-columns: 1fr;
  }
}

.charsel-preview {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap);
}

.charsel-preview-frame {
  aspect-ratio: 3 / 4;
  border: 1px dashed var(--border-default);
  border-radius: 4px;
  background: var(--frame-inner);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--gui-gap);
}

.preview-placeholder-icon {
  font-size: 3rem;
  opacity: 0.3;
  line-height: 1;
}

.preview-placeholder-label {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-align: center;
}

.charsel-preview-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: center;
}

.charsel-preview-info.hidden {
  display: none;
}

.charsel-preview-name {
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--text-primary);
}

.charsel-preview-meta {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
}

.charsel-preview-location {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
}

.charsel-preview-time {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-disabled);
}

.charsel-list-col {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap-lg);
}

.charsel-list {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap);
  max-height: 320px;
  overflow-y: auto;
}

.charsel-row {
  display: flex;
  align-items: center;
  gap: var(--gui-gap);
  padding: var(--gui-padding) var(--gui-gap);
  background: var(--frame-inner);
  border: 1px solid var(--alpha-white-08);
  border-radius: 4px;
  cursor: pointer;
  transition: border-color var(--ui-transition);
}

.charsel-row:hover,
.charsel-row.selected,
.charsel-row:focus-visible {
  border-color: var(--accent);
}

.charsel-row.selected {
  background: var(--color-white-05);
}

.charsel-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.charsel-name {
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--text-primary);
}

.charsel-meta {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
}

.charsel-detail {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-disabled);
}

.charsel-delete {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: var(--font-size-sm);
  cursor: pointer;
  padding: 4px;
  opacity: 0;
  transition: opacity var(--ui-transition), color var(--ui-transition);
}

.charsel-row:hover .charsel-delete,
.charsel-row:focus-within .charsel-delete,
.charsel-delete:focus-visible {
  opacity: 1;
}

.charsel-delete:hover,
.charsel-delete:focus-visible {
  color: var(--danger);
}

.charsel-row.charsel-deleted {
  opacity: 0.5;
  border-color: var(--color-white-05);
  cursor: default;
}

.charsel-row.charsel-deleted:hover {
  border-color: var(--color-white-05);
  background: none;
}

.charsel-row.charsel-deleted .charsel-name {
  text-decoration: line-through;
}

.charsel-restore {
  background: none;
  border: 1px solid var(--text-muted);
  color: var(--text-secondary);
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  padding: 0.2rem 0.6rem;
  border-radius: 3px;
  cursor: pointer;
  transition: color var(--fade-snappy) ease-out, border-color var(--fade-snappy) ease-out;
}

.charsel-restore:hover,
.charsel-restore:focus-visible {
  color: var(--success);
  border-color: var(--success);
}

.charsel-rename {
  background: none;
  border: 1px solid var(--text-muted);
  color: var(--text-secondary);
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  padding: 0.2rem 0.6rem;
  border-radius: 3px;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--ui-transition), color var(--fade-snappy) ease-out, border-color var(--fade-snappy) ease-out;
}

.charsel-row:hover .charsel-rename,
.charsel-row:focus-within .charsel-rename,
.charsel-rename:focus-visible {
  opacity: 1;
}

.charsel-rename:hover,
.charsel-rename:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
}

.charsel-empty {
  text-align: center;
  padding: var(--gui-gap-lg);
  color: var(--text-muted);
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
}

.charsel-actions {
  display: flex;
  gap: var(--gui-gap);
}

.charsel-actions .launcher-btn {
  flex: 1;
}

/* --- Character Creation --- */

.charcreate-layout {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: var(--gui-gap-lg);
  width: min(100%, 700px);
}

@media (max-width: 600px) {
  .charcreate-layout {
    grid-template-columns: 1fr;
  }

  .charcreate-preview {
    order: -1;
  }
}

.charcreate-preview {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap);
}

.charcreate-preview-frame {
  aspect-ratio: 3 / 4;
  border: 1px dashed var(--border-default);
  border-radius: 4px;
  background: var(--frame-inner);
  display: flex;
  align-items: center;
  justify-content: center;
}

.charcreate-sprite-wrap {
  position: relative;
  width: 192px;
  height: 256px;
}

.charcreate-sprite-preview {
  width: 192px;
  height: 256px;
  background-image: url('/sprites/human-male.svg');
  background-size: 500% 3400%;
  background-position-x: 0;
  background-position-y: calc(var(--preview-dir, 0) * 4 * 100% / 33);
  background-repeat: no-repeat;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  image-rendering: crisp-edges;
}

.charcreate-hair-preview {
  position: absolute;
  inset: 0;
  background-size: 500% 3400%;
  background-position-x: 0;
  background-position-y: calc(var(--preview-dir, 0) * 4 * 100% / 33);
  background-repeat: no-repeat;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  image-rendering: crisp-edges;
  pointer-events: none;
}

/* --- Rotation Controls --- */

.charcreate-rotate {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gui-gap);
}

.charcreate-rotate-btn {
  background: none;
  border: var(--border-hairline);
  border-radius: 4px;
  color: var(--text-secondary);
  font-size: 1.2rem;
  line-height: 1;
  padding: 2px 8px;
  cursor: pointer;
  transition: border-color var(--ui-transition), color var(--ui-transition);
}

.charcreate-rotate-btn:hover,
.charcreate-rotate-btn:focus-visible {
  border-color: var(--accent);
  color: var(--text-primary);
}

.charcreate-rotate-label {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  min-width: 5em;
  text-align: center;
}

.charcreate-gender-grid,
.charcreate-hairstyle-grid {
  display: flex;
  gap: var(--gui-gap);
  flex-wrap: wrap;
}

.gender-option,
.hairstyle-option {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border: var(--border-hairline);
  border-radius: 4px;
  background: var(--frame-inner);
  color: var(--text-secondary);
  font: var(--font-size-sm) var(--font-sans);
  cursor: pointer;
  transition: border-color var(--ui-transition), color var(--ui-transition);
}

.gender-option.selected,
.hairstyle-option.selected {
  border-color: var(--accent);
  color: var(--text-primary);
}

.gender-option input,
.hairstyle-option input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.charcreate-role-summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gui-gap);
}

.role-tag {
  font-family: var(--font-mono);
  font-size: var(--font-size-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 1px 6px;
  border-radius: 2px;
  background: var(--accent);
  color: var(--text-primary);
}

.role-weapon {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
}

.charcreate-options-col {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap-lg);
}

.charcreate-desc {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
  line-height: 1.5;
  margin-top: var(--gui-gap);
}

/* Tint swatch grid */
.charcreate-tint-grid {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}

.tint-swatch {
  width: 44px;
  height: 44px;
  padding: 8px;
  border-radius: 50%;
  border: 2px solid transparent;
  background: none;
  cursor: pointer;
  transition: border-color var(--ui-transition);
}
.tint-swatch:hover { border-color: var(--alpha-white-35); }
.tint-swatch.selected { border-color: var(--accent); }
.tint-swatch:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.tint-swatch-inner {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
}

/* Skin tone swatch colors — match --skin-* tokens from _tokens.css */
.skin-alabaster  { background: var(--skin-1); }
.skin-sandstone  { background: var(--skin-2); }
.skin-sienna     { background: var(--skin-3); }
.skin-clay       { background: var(--skin-4); }
.skin-umber      { background: var(--skin-5); }
.skin-peat       { background: var(--skin-6); }

/* Hair color swatch colors — match --hair-* tokens from _tokens.css */
.hair-black      { background: var(--hair-black); }
.hair-brown      { background: var(--hair-brown); }
.hair-auburn     { background: var(--hair-auburn); }
.hair-blonde     { background: var(--hair-blonde); }
.hair-gray       { background: var(--hair-gray); }
.hair-white      { background: var(--hair-white); }
.hair-red        { background: var(--hair-red); }
.hair-blue       { background: var(--hair-blue); }

.charcreate-section h3 {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-bottom: var(--gui-gap);
}

.charcreate-options {
  display: flex;
  gap: var(--gui-gap);
  flex-wrap: wrap;
}

.charcreate-option {
  flex: 1;
  min-width: 100px;
  padding: var(--gui-padding) var(--gui-gap);
  background: var(--frame-inner);
  border: 1px solid var(--alpha-white-08);
  border-radius: 4px;
  text-align: center;
  cursor: pointer;
  transition: border-color var(--ui-transition);
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  color: var(--text-primary);
}

.charcreate-option input[type="radio"] {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.charcreate-option.selected,
.charcreate-option:has(input:checked) {
  border-color: var(--accent);
  background: var(--color-white-05);
}

.charcreate-option.disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.charcreate-option small {
  display: block;
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  margin-top: 2px;
}

.name-status {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  min-height: 1.2em;
  margin-top: 2px;
  color: var(--text-muted);
}
.name-status.available { color: var(--success); }
.name-status.taken,
.name-status.reserved,
.name-status.inappropriate { color: var(--danger); }
.name-status.invalid { color: var(--warning); }
.name-status.checking { color: var(--text-muted); }

/* --- Step System --- */

.charcreate-steps {
  position: relative;
  min-height: 200px;
}

.charcreate-step {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap-lg);
  opacity: 0;
  transform: translate3d(0, 8px, 0);
  pointer-events: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  transition: opacity var(--fade-standard) ease-out, transform var(--fade-standard) ease-out;
}

.charcreate-step.step-active {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  pointer-events: auto;
  position: relative;
}

.charcreate-step-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  padding-top: var(--gui-gap);
}

.step-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--alpha-white-08);
  transition: background var(--fade-standard) ease-out;
}

.step-dot.active {
  background: var(--accent);
}

/* --- Class Cards --- */

.class-card-grid {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap);
}

.class-card {
  display: flex;
  gap: var(--gui-gap);
  padding: var(--gui-padding);
  background: var(--frame-inner);
  border: 1px solid var(--alpha-white-08);
  border-radius: 4px;
  cursor: pointer;
  transition: border-color var(--ui-transition), background var(--ui-transition);
}

.class-card:hover:not(.class-card--disabled) {
  border-color: var(--accent);
}

.class-card.selected {
  border-color: var(--accent);
  background: var(--color-white-05);
}

.class-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.class-card--disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.class-card-icon {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  background: var(--alpha-white-08);
  flex-shrink: 0;
}

.class-card-body {
  flex: 1;
  min-width: 0;
}

.class-card-header {
  display: flex;
  align-items: center;
  gap: var(--gui-gap);
  margin-bottom: 2px;
}

.class-card-name {
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--text-primary);
}

.class-card-weapon {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
}

.class-card-desc {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
  line-height: 1.4;
  margin: 0;
}

.class-card-soon {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--font-size-2xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin-top: 2px;
}

/* --- Screen Transitions (char select ↔ creation) --- */

.launcher-screen {
  transition: opacity var(--fade-standard) ease-out, transform var(--fade-standard) ease-out;
}

.launcher-screen.screen-inactive {
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: opacity var(--fade-standard) ease-out, transform var(--fade-standard) ease-out, visibility 0s var(--fade-standard);
}

.launcher-screen.screen-exit-left {
  transform: translate3d(-30px, 0, 0);
  opacity: 0;
}

.launcher-screen.screen-enter-right {
  transform: translate3d(30px, 0, 0);
  opacity: 0;
}

.launcher-screen.screen-exit-right {
  transform: translate3d(30px, 0, 0);
  opacity: 0;
}

.launcher-screen.screen-enter-left {
  transform: translate3d(-30px, 0, 0);
  opacity: 0;
}

.charcreate-actions {
  display: flex;
  gap: var(--gui-gap);
}

.charcreate-actions .launcher-btn {
  flex: 1;
}

/* --- Buttons --- */

.launcher-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--gui-padding) var(--gui-gap-lg);
  border: 1px solid var(--alpha-white-08);
  border-radius: 4px;
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition:
    background var(--ui-transition),
    border-color var(--ui-transition),
    opacity var(--ui-transition);
  user-select: none;
}

.launcher-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.launcher-btn--primary {
  width: 100%;
  background: var(--accent);
  border-color: var(--accent);
  color: var(--text-primary);
}

.launcher-btn--primary:hover:not(:disabled) {
  background: var(--accent-dim);
}

.launcher-btn--secondary {
  background: transparent;
  color: var(--text-secondary);
}

.launcher-btn--secondary:hover:not(:disabled) {
  color: var(--text-primary);
  border-color: var(--text-muted);
}

/* --- Launcher Footer --- */

.launcher-footer {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: var(--gui-padding) var(--gui-gap-lg);
  display: flex;
  align-items: center;
  gap: var(--gui-gap);
  z-index: 2;
  contain: layout style;
}

.launcher-version {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  white-space: nowrap;
  flex-shrink: 0;
}

/* --- Preloader Progress Bar --- */

.launcher-progress {
  flex: 1;
  height: 3px;
  background: var(--color-white-05);
  border-radius: 2px;
  overflow: hidden;
}

.launcher-progress-bar {
  width: 100%;
  height: 100%;
  border-radius: 2px;
  background: var(--danger);
  transform: scale3d(0, 1, 1);
  transform-origin: left center;
  transition:
    transform var(--fade-standard) ease-out,
    background-color var(--ui-transition);
}

.launcher-progress-bar.progress-mid {
  background: var(--warning);
}

.launcher-progress-bar.progress-done {
  background: var(--success);
}

/* --- Entering World Transition --- */

#entering-world {
  position: absolute;
  inset: 0;
  background: var(--bg-void);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--fade-standard) ease-out;
  z-index: 10;
}

#entering-world.active {
  opacity: 1;
  pointer-events: auto;
}

.entering-text {
  font-family: var(--font-display);
  font-size: clamp(0.9rem, 2vw, 1.1rem);
  letter-spacing: 0.1em;
  color: var(--text-secondary);
}

.entering-stage {
  display: block;
  margin-top: 0.5rem;
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  color: var(--text-muted);
  min-height: 1.2em;
  text-align: center;
  transition: opacity var(--fade-quick) ease-out;
}

.entering-tip {
  display: block;
  margin-top: 1.5rem;
  font-family: var(--font-sans);
  font-size: var(--font-size-sm);
  color: var(--text-muted);
  font-style: italic;
  max-width: 400px;
  text-align: center;
  opacity: 0;
  transition: opacity 400ms ease-out;
}

.entering-tip.visible {
  opacity: 1;
}

/* --- Entering World Progress Bar --- */

.entering-progress {
  width: 100%;
  max-width: 280px;
  height: 3px;
  background: var(--color-white-05);
  border-radius: 2px;
  overflow: hidden;
  margin-top: 1.5rem;
}

.entering-progress-bar {
  width: 100%;
  height: 100%;
  border-radius: 2px;
  background: var(--danger);
  transform: scale3d(0, 1, 1);
  transform-origin: left center;
  transition: transform var(--fade-standard) ease-out, background-color var(--fade-standard) ease-out;
}

.entering-progress-bar.progress-mid {
  background: var(--warning);
}

.entering-progress-bar.progress-done {
  background: var(--success);
}

/* --- News Panel --- */

.launcher-news {
  width: 100%;
  max-width: 360px;
  margin-top: var(--gui-gap);
}

.charsel-news {
  margin-top: 0;
}

.news-scroll {
  max-height: 180px;
  overflow-y: auto;
}

.news-view-all {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-decoration: none;
  padding-top: var(--gui-padding-sm);
  text-align: right;
}

.news-view-all:hover,
.news-view-all:focus-visible {
  color: var(--accent);
}

.news-loading {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  padding: var(--gui-padding-sm) 0;
}

.news-item {
  padding: var(--gui-padding-sm) 0;
  border-bottom: 1px solid var(--alpha-white-05);
}

.news-item:last-child {
  border-bottom: none;
}

.news-header {
  display: flex;
  align-items: baseline;
  gap: var(--gui-gap-sm);
  margin-bottom: 2px;
}

.news-badge {
  font-family: var(--font-mono);
  font-size: var(--font-size-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 1px 5px;
  border-radius: 2px;
  flex-shrink: 0;
}

.news-badge--patch { background: var(--info); color: var(--text-on-fill); }
.news-badge--latest { background: var(--accent); color: var(--text-on-fill); }
.news-badge--announcement { background: var(--accent); color: var(--text-on-fill); }
.news-badge--maintenance { background: var(--warning); color: var(--text-on-fill); }
.news-badge--legal { background: var(--accent); color: var(--text-on-fill); }
.news-badge--legal-new { background: var(--danger, oklch(0.65 0.18 25)); color: oklch(1 0 0); }

.news-title {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  font-weight: 600;
  color: var(--text-primary);
}

.news-date {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  color: var(--text-muted);
  margin-left: auto;
  flex-shrink: 0;
}

.news-body {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
  line-height: 1.4;
}

.news-change-group {
  margin-top: 4px;
}

.news-change-type {
  font-family: var(--font-mono);
  font-size: var(--font-size-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin-bottom: 2px;
}

.news-change-type--added { color: var(--success); }
.news-change-type--fixed { color: var(--info); }
.news-change-type--changed { color: var(--warning); }

.news-change-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.news-change-list li {
  font-family: var(--font-sans);
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
  line-height: 1.4;
  padding-left: 8px;
  position: relative;
}

.news-change-list li::before {
  content: '·';
  position: absolute;
  left: 0;
  color: var(--text-muted);
}

.news-item--current .news-badge--patch {
  background: var(--accent);
  color: var(--text-on-fill);
}

.news-item:not(.news-item--current):not(.news-item--expanded) .news-body {
  display: none;
}

.news-item:not(.news-item--current) .news-header {
  cursor: pointer;
}

.news-item:not(.news-item--current) .news-header:hover .news-title,
.news-item:not(.news-item--current) .news-header:focus-visible .news-title {
  color: var(--accent);
}

.news-item:not(.news-item--current) .news-header:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

/* --- Footer Links --- */

.launcher-footer-links {
  display: flex;
  align-items: center;
  gap: var(--gui-gap-sm);
  flex-shrink: 0;
}

.footer-link {
  font-family: var(--font-sans);
  font-size: 0.65rem;
  color: var(--text-muted);
  text-decoration: none;
  transition: color var(--ui-transition);
}

.footer-link:hover,
.footer-link:focus-visible {
  color: var(--text-secondary);
}

.footer-sep {
  color: var(--text-muted);
  font-size: 0.65rem;
  opacity: 0.5;
}

/* --- Launcher Modal Infrastructure --- */

/* Launcher modals open with show()/close() + a sibling #launcher-modal-shroud,
   NOT showModal(), mirroring the in-game #settings-menu pattern. showModal()'s
   top-layer centering mis-anchors to top-left on Safari, and its indefinite
   intrinsic height collapses the flex body to just the header on WebKit. The
   manual centering here + #launcher-account-modal's explicit height below fix
   both. See docs/architecture/visual-state-refactor.md §3.2 (sessions 280, 447). */
.launcher-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  margin: 0;
  translate: -50% -50% 0;
  z-index: 200;
  pointer-events: auto;
  border: var(--border-hairline);
  border-radius: 8px;
  padding: 0;
  background: var(--bg-panel);
  color: inherit;
  width: 90%;
  max-width: 440px;
  max-height: 85vh;
  box-shadow: 0 8px 32px oklch(0% 0 0 / 0.5);
  opacity: 0;
  scale: 0.95;
  /* `overlay` keeps a top-layer element in the top layer through its exit fade. The
     show()-mode modals never enter the top layer, so it's inert for them, but the
     recovery + passkey dialogs that share this class still open via showModal(): without
     it, the dialog drops out of the top layer instantly on close and fades behind its own
     ::backdrop (which DOES transition overlay). Keep it so their close stays clean. */
  transition: opacity var(--fade-standard) ease-out, scale var(--fade-standard) ease-out,
    overlay var(--fade-standard) ease-out allow-discrete,
    display var(--fade-standard) ease-out allow-discrete;
}

.launcher-modal[open] {
  display: flex;
  flex-direction: column;
  opacity: 1;
  scale: 1;
}

/* Entry reveal: showLauncherModal adds .modal-entering, opens with show(), then
   removes it on the next frame so the modal fades + scales in (matches settings). */
.launcher-modal[open].modal-entering {
  opacity: 0;
  scale: 0.95;
}

/* recovery-code-dialog still carries .launcher-modal but opens via showModal() (its
   recovery-ack flow the show() migration hasn't reached yet). showModal() renders the
   top-layer ::backdrop, so keep it for THAT dim. It is inert for the show()-mode modals
   above (::backdrop renders only for showModal), which use the #launcher-modal-shroud
   below instead. (The passkey-prompt-dialog moved to .show() in session 603, so it's no
   longer in this group.) */
.launcher-modal::backdrop {
  background: oklch(0% 0 0 / 0.6);
  opacity: 0;
  transition: opacity var(--fade-standard) ease-out,
    overlay var(--fade-standard) ease-out allow-discrete,
    display var(--fade-standard) ease-out allow-discrete;
}

.launcher-modal[open]::backdrop {
  opacity: 1;
}

/* Backdrop dim for the show()-mode modals — a sibling div, not ::backdrop, since show()
   has no top-layer backdrop. Matches the #settings-shroud / #dialogue-shroud pattern. */
#launcher-modal-shroud {
  position: fixed;
  inset: 0;
  background: oklch(0% 0 0 / 0.6);
  z-index: 199;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  cursor: pointer;
  transition: opacity var(--fade-standard) ease-out, visibility var(--fade-standard) ease-out;
}

#launcher-modal-shroud.visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.launcher-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--gui-padding) var(--gui-padding) 0;
}

.launcher-modal-header h2 {
  margin: 0;
  font: var(--font-size-lg) var(--font-display);
  color: var(--text-primary);
  letter-spacing: 0.04em;
}

.launcher-modal-close {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 1.4rem;
  cursor: pointer;
  padding: 4px 8px;
  line-height: 1;
  transition: color var(--ui-transition);
}

.launcher-modal-close:hover,
.launcher-modal-close:focus-visible {
  color: var(--text-primary);
}

.launcher-modal-body {
  padding: var(--gui-padding);
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}

/* The account modal is content-heavy (email, linked logins, security). Give it an
   explicit height so its flex body has a definite size to scroll within: on WebKit a
   flex:1 child of a fit-content dialog collapses to zero. (visual-state-refactor §3.2) */
#launcher-account-modal {
  height: 85vh;
}

/* The small modals (delete-confirm, rename) size to their short content; their body
   must NOT be flex:1 or it collapses on WebKit (no definite parent height to fill). */
.launcher-modal--sm .launcher-modal-body {
  flex: 0 0 auto;
}

/* --- Account Panel Sections --- */

.account-section {
  margin-bottom: var(--gui-gap-lg);
  padding-bottom: var(--gui-gap-lg);
  border-bottom: var(--border-hairline);
}

.account-section:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.account-section h3 {
  margin: 0 0 var(--gui-gap-sm);
  font: 600 var(--font-size-sm) / 1.3 var(--font-sans);
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* The account modal reuses .settings-hint, which is styled for the in-game settings
   tab where it sits indented under a toggle. As a standalone section paragraph here,
   reset that indent and give it bottom spacing (mirrors .settings-section > .settings-hint). */
.account-section > .settings-hint {
  margin-left: 0;
  margin-bottom: var(--gui-gap-sm);
}

/* Space the top-level action buttons so they don't jam against the text above or each
   other. Scoped to direct children so the .account-stepup flex group (own gap) is untouched. */
.account-section > .launcher-btn {
  margin-top: var(--gui-gap-sm);
}

.account-email {
  margin: 0;
  font: var(--font-size-sm) var(--font-mono);
  color: var(--text-primary);
  word-break: break-all;
}

.account-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.account-form .launcher-label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font: var(--font-size-xs) var(--font-sans);
  color: var(--text-muted);
}

.account-success {
  margin: 0;
  font: var(--font-size-xs) var(--font-sans);
  color: var(--success);
}

.account-success.hidden {
  display: none;
}

.account-section--danger h3 {
  color: var(--danger);
}

.account-delete-confirm {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.account-delete-confirm.hidden {
  display: none;
}

.account-delete-warning {
  margin: 0;
  font: var(--font-size-xs) var(--font-sans);
  color: var(--text-secondary);
}

.account-delete-actions {
  display: flex;
  gap: 8px;
}

.launcher-btn--danger {
  background: var(--danger);
  color: var(--text-primary);
  border: 1px solid oklch(0.55 0.18 25);
  font: var(--font-size-sm) var(--font-sans);
  padding: 6px 14px;
  border-radius: 4px;
  cursor: pointer;
  transition: opacity var(--ui-transition);
}

.launcher-btn--danger:hover {
  opacity: 0.85;
}

.launcher-btn--danger:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* --- Settings Account Tab --- */

.settings-input {
  background: var(--frame-inner);
  border: var(--border-hairline);
  color: var(--text-primary);
  font: var(--font-size-sm) var(--font-display);
  padding: 6px 10px;
  width: 100%;
  max-width: 260px;
}

.settings-input:focus {
  border-color: var(--accent);
  outline: none;
}

.settings-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* --- prefers-reduced-motion --- */

@media (prefers-reduced-motion: reduce) {
  .pa-block,
  .pa-text,
  .pa-divider,
  .pa-tagline-text,
  .solwilds-logo,
  .vl-band,
  .vl-artifact,
  .launcher-phase,
  #entering-world,
  .launcher-progress-bar,
  .launcher-screen,
  .charcreate-step {
    transition-duration: 0ms !important;
    transition-delay: 0ms !important;
  }

  .entering-progress-bar {
    transition: none;
  }
}

/* --- MFA Enrollment UI --- */

.mfa-qr-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap);
  align-items: center;
}

.mfa-qr {
  width: 200px;
  height: 200px;
  border-radius: 4px;
  background: var(--alpha-white-08);
}

.mfa-secret {
  display: inline-block;
  padding: 2px 6px;
  font: var(--font-size-xs) / 1.4 var(--font-mono);
  background: var(--alpha-white-08);
  border-radius: 2px;
  user-select: all;
  word-break: break-all;
}

.mfa-codes-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap);
  align-items: center;
}

.mfa-codes-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 4px 12px;
  font: var(--font-size-sm) / 1.5 var(--font-mono);
  padding: var(--gui-padding);
  background: var(--alpha-white-05);
  border-radius: 4px;
  user-select: all;
}

.mfa-code {
  padding: 2px 4px;
  letter-spacing: 0.05em;
}

.mfa-ack-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font: var(--font-size-xs) / 1.4 var(--font-sans);
  color: var(--text-secondary);
  cursor: pointer;
}

/* --- Delete Confirm Modal --- */

.launcher-modal--sm {
  max-width: 380px;
}

/* --- Post-login "Create a passkey" enrollment prompt --- */

/* The post-login passkey prompt shares .launcher-modal for the centered card look,
   but opens via plain show() (out of the top layer so the OS "Save passkey" sheet
   anchors by the toolbar, not over the card). It is a gentle auto-appearing
   suggestion, not a blocking action: no #launcher-modal-shroud full-screen dim (that
   read as "everything went gray") and no scale-pop entrance. Pin scale:1 so it opens
   cleanly; the panel background + box-shadow give it enough presence on their own. */
#passkey-prompt-dialog,
#passkey-prompt-dialog[open] {
  scale: 1;
}

.passkey-prompt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gui-gap);
  text-align: center;
}

.passkey-prompt-icon {
  color: var(--accent);
}

.passkey-prompt-actions {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap);
  width: 100%;
  margin-top: var(--gui-gap);
}

/* Recovery-email prompt: same non-blocking auto-suggestion shape as the passkey
   prompt (opens via show(), no shroud, no scale-pop). Pin scale:1. */
#recovery-email-prompt-dialog,
#recovery-email-prompt-dialog[open] {
  scale: 1;
}

.recovery-email-prompt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gui-gap);
  text-align: center;
}

.recovery-email-prompt-icon {
  color: var(--accent);
}

.recovery-email-prompt .auth-field {
  width: 100%;
  text-align: left;
}

#recovery-email-prompt-code-wrap {
  width: 100%;
}

.recovery-email-prompt-actions {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap);
  width: 100%;
  margin-top: var(--gui-gap);
}

.delete-confirm-actions,
.rename-actions {
  display: flex;
  gap: var(--gui-gap);
  justify-content: flex-end;
  margin-top: var(--gui-gap);
}

/* --- Currently Playing Badge --- */
/* A live in-world session exists elsewhere for this character. Same pill
   design as .launcher-last-used-badge (Simon's call), but in-flow beside
   the name like the flagged badge below, so the two coexist cleanly. */

.charsel-playing-badge {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: var(--font-size-2xs);
  font-weight: 600;
  line-height: 1.5;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--text-primary);
  margin-left: var(--gui-gap);
  vertical-align: middle;
  white-space: nowrap;
}

/* --- Flagged Character Badge --- */

.charsel-flagged-badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--font-size-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 1px 5px;
  border-radius: 2px;
  background: var(--danger);
  color: var(--text-on-fill);
  margin-left: var(--gui-gap);
  vertical-align: middle;
}

/* --- Character Select Sprite Preview --- */

.charsel-sprite-wrap {
  position: relative;
  width: 96px;
  height: 128px;
  margin: 0 auto;
  image-rendering: pixelated;
}

.charsel-sprite-preview,
.charsel-hair-preview {
  position: absolute;
  inset: 0;
  background-size: 500% 3400%;
  background-position: 0 0;
  image-rendering: pixelated;
}

.charsel-hair-preview {
  pointer-events: none;
}

/* Linked Logins (account modal) — the account's login methods + link/unlink. */
.account-identities {
  list-style: none;
  margin: 0 0 var(--space-3, 12px);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2, 8px);
}

.account-identity {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3, 12px);
}

.account-identity-name {
  font-size: 0.95rem;
}

.account-identity-unlink {
  flex: 0 0 auto;
}

.account-stepup {
  display: flex;
  flex-direction: column;
  gap: var(--space-2, 8px);
  margin-top: var(--gui-gap);
  padding-top: var(--gui-gap);
  border-top: var(--border-hairline);
}
