/* bryce.today — /game/ additions only.
   Loaded after /styles.css, which already provides the desk, the book, the
   parchment page, the ribbon tabs, buttons, fields, notes, the seal, the
   panel and every mobile-first layout rule. Nothing from there is repeated
   here; this file is only what the game pages need on top.

   Mobile-first like the shared sheet: no fixed widths, no hover-only
   affordances, 44px (2.75rem) minimum targets via --tap, and the one
   min-width query below only adds breathing room. */

/* ---- page frame ---------------------------------------------------------- */
/* The book and the site chrome cap themselves at 62rem; <main> has to agree
   so the status line above the book lines up with its left edge. */
.shell {
  width: 100%;
  max-width: 62rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}

/* No-JS note and the app-level status line both sit on the desk rather than
   on parchment, so they take the desk's light-on-dark treatment. */
.desk-note {
  margin: 0;
  min-height: 0;          /* shared .note reserves 1.5em; on the desk that
                             would leave a permanent gap above the book */
  color: var(--parchment);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

.noscript-note {
  width: 100%;
  max-width: 62rem;
  margin: 0;
  padding: 0.75rem 1rem;
  border: 1px solid var(--gold);
  border-radius: 0.25rem;
  background: rgba(0, 0, 0, 0.3);
  color: var(--parchment);
  font-size: 0.95rem;
}

/* ---- reveal gate -------------------------------------------------------- */
/* app.html keeps its content out of sight until GET /me resolves, so a signed
   -out visitor never sees a flash of the shell before the redirect. game.js
   adds .ready on success AND on the retry path, so the retry panel is always
   reachable — the page must never end up blank. Only the app page is gated;
   index.html and 404.html paint immediately. */
body[data-page='app'] .shell {
  opacity: 0;
  transition: opacity 0.18s ease;
}
body[data-page='app'].ready .shell { opacity: 1; }

/* ---- login mode ribbons ------------------------------------------------- */
/* The two login modes are plain buttons carrying aria-pressed, not ARIA tabs
   (no arrow-key tab semantics are implied). The shared sheet only paints the
   active state for aria-current / aria-selected, so the pressed state is
   mapped onto the same look here. */
.tab[aria-pressed='true'] {
  background: var(--parchment);
  color: var(--ink);
  box-shadow: 0 -2px 0 var(--gold) inset;
  font-weight: 600;
}

/* ---- title line --------------------------------------------------------- */
/* Heading on the left, wax seal on the right; wraps rather than shrinking. */
.title-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.6rem;
}
.title-row h1 { margin: 0; }

/* ---- identity block ----------------------------------------------------- */
/* Seal plus the "Signed in as" lines. Stacks on a narrow phone. */
.identity {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
}
.identity > div { flex: 1 1 14rem; min-width: 0; }
.identity p:last-child { margin-bottom: 0; }
/* The seal carries the account's first initial; Cinzel has caps only. */
.identity .seal { text-transform: uppercase; }

/* Names come from the API. Long ones break instead of pushing the page wide. */
.name { overflow-wrap: anywhere; }

/* ---- Admin badge -------------------------------------------------------- */
.stamp {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--gold);
  border-radius: 0.15rem;
  background: rgba(156, 124, 44, 0.14);
  color: var(--ink-soft);
  font-family: var(--display);
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: 0.15em;
}

/* ---- account record ----------------------------------------------------- */
/* Label / value rows on ruled parchment. Two columns once there is room, one
   column on a phone so a long value never forces a sideways scroll. */
.record { margin: 0; }
.record > div {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 1rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--rule);
}
.record > div:last-child { border-bottom: 0; }
.record dt {
  font-family: var(--display);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.record dd {
  margin: 0;
  overflow-wrap: anywhere;
}

/* ---- inline command name ------------------------------------------------ */
.cmd {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
  padding: 0.1em 0.35em;
  border: 1px solid var(--rule-strong);
  border-radius: 0.15rem;
  background: rgba(255, 255, 255, 0.4);
  white-space: nowrap;
}

/* ---- form footers ------------------------------------------------------- */
/* Submit button beside its "Saved" confirmation; wraps on a narrow screen so
   the button keeps its full tap target. */
.form-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

/* A hairline before a trailing action (the second Log out button). */
.rule-off {
  margin: 1.75rem 0 1.25rem;
  border: 0;
  border-top: 1px solid var(--rule);
}

.stack-gap { margin-top: 1.5rem; }

/* ---- retry panel -------------------------------------------------------- */
/* Shown when /me fails for any reason other than a definite 401/403. */
.retry-actions { margin-top: 1.25rem; }

@media (min-width: 34rem) {
  /* Enough width for the label column to sit beside its value. */
  .record > div { grid-template-columns: 9rem minmax(0, 1fr); align-items: baseline; }
}

@media (min-width: 48rem) {
  /* Matches the shared sheet's wide-screen active ribbon, which keys on
     aria-current / aria-selected only. Same breakpoint, same values. */
  .tab[aria-pressed='true'] {
    box-shadow: 0.15rem 0.15rem 0.4rem rgba(0, 0, 0, 0.3), -3px 0 0 var(--gold) inset;
    transform: translateX(0.25rem);
  }
}

/* ---- settings: cover and desk pickers ------------------------------------
   Swatch colours live here as classes because the strict CSP on these pages
   (default-src 'self') blocks inline style attributes. The values must match
   /theme.css — they are the same four covers and four desks. */
.option-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 1.25rem;
}

.option {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  /* styles.css sizes .option for the homepage's dropdown panel, where it is a
     full-width menu row. In here they are chips that wrap. */
  width: auto;
  min-height: var(--tap, 2.75rem);
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--rule-strong);
  border-radius: 0.2rem;
  background: rgba(255, 255, 255, 0.35);
  color: var(--ink-soft);
  font-family: var(--body);
  font-size: 0.95rem;
  cursor: pointer;
}
.option:hover, .option:focus-visible, .option:active { color: var(--ink); }
.option[aria-pressed='true'] {
  color: var(--ink);
  font-weight: 600;
  border-color: var(--gold);
  box-shadow: 0 0 0 1px var(--gold) inset;
}

.swatch {
  width: 1.05rem;
  height: 1.05rem;
  border-radius: 0.15rem;
  border: 1px solid var(--rule-strong);
  flex: 0 0 auto;
}

.sw-oxblood  { background: #5c2124; }
.sw-forest   { background: #22392c; }
.sw-midnight { background: #1e2a44; }
.sw-jet      { background: #241f1c; }
.sw-walnut   { background: #493628; }
.sw-oak      { background: #5c4326; }
.sw-mahogany { background: #4d2c23; }
.sw-ebony    { background: #2a2725; }
