/* Base styles — reset, body, layout, buttons, flash, nav */

body::before {
  content: '';
  position: fixed;
  inset: 0;
  background-image: var(--theme-bg-image);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  opacity: 0.12;
  pointer-events: none;
  z-index: 0;
}

body::after {
  content: '';
  position: fixed;
  inset: 0;
  background: radial-gradient(ellipse at center, transparent 30%, rgba(0, 0, 0, 0.5) 100%);
  pointer-events: none;
  z-index: 9998;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 125%; }
@media (max-width: 768px) { html { font-size: 100%; } }
body { font-family: var(--theme-font); background: var(--theme-bg); color: var(--theme-text); min-height: 100vh; padding-top: env(safe-area-inset-top); }
a { color: var(--theme-accent); }

.container { position: relative; z-index: 1; max-width: 900px; margin: 0 auto; padding: 1rem; }
@media (min-width: 1400px) { .container { max-width: 1200px; } }
@media (max-width: 768px) {
  .container { padding: 0.5rem 0.6rem; }
  .app-nav-tokens-count { display: block; }
}

.btn { display: inline-block; padding: 0.5rem 1.2rem; border: 1px solid var(--theme-accent); background: transparent; color: var(--theme-accent); cursor: pointer; font-family: inherit; font-size: 0.9rem; text-decoration: none; }
.btn:hover { background: var(--theme-accent); color: var(--theme-bg); }
.btn-primary { background: var(--theme-accent); color: var(--theme-bg); }
.btn-primary:hover { background: #6a9480; }
.btn-danger { border-color: #6a3030; color: #8a4040; font-size: 0.72rem; padding: 0.35rem 0.8rem; }
.btn-danger:hover { background: #6a3030; color: #e0d4bc; }

.flash-notice { background: #1a3a2a; border: 1px solid var(--theme-accent); padding: 0.75rem 1rem; margin-bottom: 1rem; }
.flash-alert { background: #3a1a1a; border: 1px solid #a08080; color: #c8a0a0; padding: 0.75rem 1rem; margin-bottom: 1rem; }

h1, h2, h3 { color: #e8e8d4; font-weight: normal; letter-spacing: 0.05em; }

.app-nav { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 0.5rem 0.75rem; padding: 0.4rem 0 0.75rem; border-bottom: 1px solid #1e1810; margin-bottom: 0.75rem; font-size: 0.7rem; }
.app-nav-home { text-decoration: none; margin-right: auto; display: flex; align-items: center; }
.app-nav-home:hover { opacity: 0.8; }
.app-nav-icon { height: 1.6rem; width: auto; }
.app-nav-user { display: inline-flex; align-items: center; gap: 0.3rem; font-family: 'Lora', Georgia, serif; font-style: italic; color: #4a4030; max-width: 8rem; text-decoration: none; }
.app-nav-user-icon { width: 0.95em; height: 0.95em; flex-shrink: 0; opacity: 0.8; }
.app-nav-user-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-nav-user:hover { color: var(--theme-accent); }
.app-nav-tokens { color: #4a4030; font-size: 0.65rem; letter-spacing: 0.05em; max-width: 6rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-nav-signout { background: transparent; border: 1px solid #2a2318; color: #4a4030; padding: 0.2rem 0.4rem; cursor: pointer; font-family: 'Cinzel', serif; font-size: 0.6rem; letter-spacing: 0.1em; line-height: 1.2; }
.app-nav-signout:hover { color: var(--theme-accent); border-color: #3a3020; }
.app-nav-locale { background: transparent; border: 1px solid #2a2318; color: #4a4030; padding: 0.2rem 0.4rem; cursor: pointer; font-family: 'Cinzel', serif; font-size: 0.6rem; letter-spacing: 0.1em; line-height: 1.2; appearance: none; -webkit-appearance: none; }
.app-nav-locale:hover { color: var(--theme-accent); border-color: #3a3020; }

.token-banner { position: fixed; top: 1rem; left: 50%; transform: translateX(-50%); z-index: 9999; background: #2a1010; border: 1px solid #6a3030; padding: 0.75rem 2.5rem 0.75rem 1.25rem; font-family: 'Lora', Georgia, serif; font-size: 0.82rem; color: #c8a0a0; box-shadow: 0 4px 20px rgba(0,0,0,0.6); max-width: 480px; width: calc(100% - 2rem); }
.token-banner-text { display: block; }
.token-banner-close { position: absolute; top: 0.4rem; right: 0.6rem; background: none; border: none; color: #6a4040; font-size: 1.1rem; cursor: pointer; line-height: 1; padding: 0.2rem; }
.token-banner-close:hover { color: #c8a0a0; }

/* ── Loading overlay ── */
.loading-overlay[hidden] { display: none !important; }
.loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    repeating-conic-gradient(rgba(120, 90, 50, 0.03) 0% 25%, transparent 0% 50%) 0 0 / 4px 4px,
    radial-gradient(ellipse at 0% 0%, rgba(90, 60, 30, 0.15) 0%, transparent 50%),
    radial-gradient(ellipse at 100% 100%, rgba(90, 55, 25, 0.18) 0%, transparent 50%),
    radial-gradient(ellipse at 50% 40%, #efe3cd 0%, #e2d3b8 40%, #d4c4a4 80%);
  animation: overlayFadeIn 0.3s ease-out both;
}
@keyframes overlayFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
.loading-overlay-content { text-align: center; }
.loading-overlay-title {
  font-family: 'Cinzel', 'Palatino Linotype', serif;
  font-size: 2.2rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  color: #3a2a14;
  text-transform: uppercase;
  text-shadow: 0 1px 0 rgba(255, 245, 220, 0.5);
  margin-bottom: 1.5rem;
}
.loading-overlay-dots {
  display: flex;
  gap: 0.45rem;
  justify-content: center;
}
.loading-overlay-dots span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #8a7354;
  animation: loadPulse 1.4s ease-in-out infinite;
}
.loading-overlay-dots span:nth-child(2) { animation-delay: 0.2s; }
.loading-overlay-dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes loadPulse {
  0%, 80%, 100% { opacity: 0.2; transform: scale(0.8); }
  40% { opacity: 1; transform: scale(1); }
}

/* ── Site footer — legal links ── */
.site-footer {
  text-align: center;
  padding: 2rem 1rem 1.2rem;
  font-family: 'Lora', Georgia, serif;
  font-style: italic;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  position: relative;
  z-index: 1;
}

.site-footer a {
  color: #4a4030;
  text-decoration: none;
  opacity: 0.7;
  transition: opacity 0.3s ease;
}
.site-footer a:hover { opacity: 1; }

.site-footer-dot {
  display: inline-block;
  margin: 0 0.6em;
  color: #4a4030;
  opacity: 0.5;
  opacity: 0.25;
  font-style: normal;
}

/* Parchment pages (sign-in, legal) — warm tones */
body:has(.signin-screen) .site-footer a,
body:has(.legal-page) .site-footer a { color: #9a8568; }
body:has(.signin-screen) .site-footer-dot,
body:has(.legal-page) .site-footer-dot { color: #9a8568; }

/* Modal dialog — generic, driven by controllers/dialog_controller.js. Native
   <dialog> supplies Esc, focus trapping and the backdrop; this is only paint. */
/* margin: auto is what centres a modal dialog, and the global `* { margin: 0 }`
   reset above strips the UA default — without this it pins to the top-left. */
.app-dialog { border: 1px solid var(--border-color); background: var(--panel-bg, #14100c); color: var(--text-mid); padding: 0; max-width: min(30rem, calc(100vw - 2rem)); width: 100%; margin: auto; }
.app-dialog::backdrop { background: rgba(0, 0, 0, 0.65); }
.app-dialog-body { padding: 1rem 1.15rem 1.15rem; }
/* Re-acceptance popup (shared/_terms_reacceptance). It opens over every page,
   dark game screens and the parchment dashboard alike, and sits outside each
   page's own markup, so the page styles never reach it. It carries its own
   parchment look, the dashboard's, rather than inheriting the default theme,
   whose font is Courier. */
.terms-reaccept { margin: auto; padding: 0; width: 100%; max-width: min(32rem, calc(100vw - 2rem)); border: 1px solid rgba(138, 115, 84, 0.6); color: #3a2a14; background: radial-gradient(ellipse at 50% 30%, #efe3cd 0%, #e2d3b8 60%, #d4c4a4 100%); box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5); font-family: 'Lora', Georgia, serif; }
.terms-reaccept::backdrop { background: rgba(20, 14, 8, 0.72); }
.terms-reaccept-body { padding: 1.4rem 1.5rem 1.2rem; }
.terms-reaccept-title { font-family: 'Cinzel', 'Palatino Linotype', serif; font-size: 0.8rem; font-weight: normal; letter-spacing: 0.22em; text-transform: uppercase; text-align: center; color: #5a4a30; margin-bottom: 1rem; }
.terms-reaccept-text { font-size: 0.8rem; line-height: 1.6; margin-bottom: 1rem; }
.terms-reaccept a { color: #5a4a30; text-decoration: underline; text-underline-offset: 2px; }
.terms-reaccept a:hover { color: #3a2a14; }
.terms-reaccept a:focus-visible, .terms-reaccept input:focus-visible, .terms-reaccept-btn:focus-visible { outline: 1px solid #8a7354; outline-offset: 2px; }
.terms-reaccept-check { display: flex; align-items: flex-start; gap: 0.6rem; font-size: 0.8rem; line-height: 1.5; cursor: pointer; }
.terms-reaccept-check input { margin-top: 0.2rem; accent-color: #5a4a30; flex-shrink: 0; }
.terms-reaccept-actions { display: flex; justify-content: center; margin: 1.1rem 0 1rem; }
.terms-reaccept-btn { display: inline-block; font-family: 'Cinzel', serif; font-size: 0.7rem; letter-spacing: 0.1em; padding: 0.45rem 1rem; border: 1px solid #b5a382; background: transparent; color: #5a4a30; cursor: pointer; transition: background 0.2s ease, border-color 0.2s ease; }
.terms-reaccept a.terms-reaccept-btn { text-decoration: none; }
.terms-reaccept-btn:hover { background: rgba(138, 115, 84, 0.12); border-color: #8a7354; color: #3a2a14; }
.terms-reaccept-btn-primary { border-color: #8a7354; background: rgba(90, 74, 48, 0.12); color: #3a2a14; }
.terms-reaccept-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.terms-reaccept-leave { font-size: 0.72rem; font-style: italic; line-height: 1.5; color: #7a6548; border-top: 1px solid rgba(138, 115, 84, 0.3); padding-top: 0.9rem; margin-bottom: 0.8rem; }
.terms-reaccept-exits { display: flex; justify-content: center; gap: 0.6rem; flex-wrap: wrap; }
.terms-reaccept-exits form { display: inline; }
/* High contrast replaces the parchment only where high_contrast.css defines its
   palette, the game screen. Everywhere else the variables are unset, and the card
   would lose its background, so it keeps the parchment. */
body.hc-dark:has(.game-screen) .terms-reaccept, body.hc-light:has(.game-screen) .terms-reaccept { background: var(--panel-bg); color: var(--theme-text); border-color: var(--theme-accent); }
body.hc-dark:has(.game-screen) :is(.terms-reaccept-title, .terms-reaccept-leave, .terms-reaccept a, .terms-reaccept-btn), body.hc-light:has(.game-screen) :is(.terms-reaccept-title, .terms-reaccept-leave, .terms-reaccept a, .terms-reaccept-btn) { color: var(--theme-text); border-color: var(--theme-accent); }
.app-dialog-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 0.85rem; }
.app-dialog-title { font-family: 'Cinzel', serif; font-size: 0.78rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-muted); }
.app-dialog-close { background: transparent; border: 0; color: var(--text-muted); font-size: 1.4rem; line-height: 1; cursor: pointer; padding: 0 0.25rem; }
.app-dialog-close:hover { color: var(--theme-accent); }

/* Full-size image viewer — shared/_lightbox, driven by lightbox_controller.js.
   The same .app-dialog as every other modal, sized to its picture rather than to
   a column of text: no panel, no padding, the image on the backdrop with the
   close button laid over its corner where a thumb can reach it. */
.lightbox-trigger { display: block; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; background: none; color: inherit; line-height: 0; cursor: zoom-in; }
.lightbox-trigger:focus-visible { outline: 2px solid var(--theme-accent, currentColor); outline-offset: 2px; }
/* fit-content, not auto. A modal <dialog> is position: fixed with inset: 0, so an
   auto width stretches it across the whole viewport and the image sits at its
   left edge, with the close button stranded at the far right. Shrink-wrapping
   the dialog to its picture is what lets margin: auto centre it. */
.app-dialog.lightbox { width: fit-content; height: fit-content; max-width: calc(100vw - 1rem); max-height: calc(100vh - 1rem); max-height: calc(100dvh - 1rem); background: transparent; border: 0; overflow: visible; }
.lightbox-body { position: relative; width: fit-content; }
.lightbox-image { display: block; width: auto; height: auto; max-width: calc(100vw - 1rem); max-height: calc(100vh - 1rem); max-height: calc(100dvh - 1rem); object-fit: contain; border: 1px solid var(--border-color); cursor: zoom-out; }
/* The viewer's one optional button — today the NPC redraw. Bottom centre, over
   the picture, so it is where the eye already is without covering the face. */
.lightbox-action { position: absolute; bottom: 0.6rem; left: 50%; transform: translateX(-50%); z-index: 1; text-decoration: none; }
.lightbox-action[hidden] { display: none; }
.lightbox-close { position: absolute; top: 0.4rem; right: 0.4rem; z-index: 1; width: 2.25rem; height: 2.25rem; border-radius: 50%; background: rgba(0, 0, 0, 0.55); color: #f0ece4; }
