/* ============================================================
   Efoo's Egloo — main.css
   reset -> tokens -> base -> layout -> components -> utilities
   No webfonts, no external requests. System stacks only.
   ============================================================ */

/* ---------- reset ---------- */
*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body,
h1, h2, h3, h4,
p, ul, ol, figure, blockquote, dl, dd { margin: 0; }

ul[class], ol[class] { list-style: none; padding: 0; }

img, svg { max-width: 100%; display: block; }

a { color: inherit; }

button { font: inherit; color: inherit; }

/* ---------- tokens (complete light palette on bare :root) ---------- */
:root {
  --bg: #eef4f8;
  --panel: #ffffff;
  --ink: #16232e;
  --ink-soft: #4a5c6b;
  --frost: #c9dcea;
  --accent: #b3541e;
  --accent-hover: #8c3f14;

  --shadow: rgba(22, 35, 46, 0.28);
  --danger: #a3261f;
  --danger-wash: #fbeceb;

  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-display: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  --border: 3px;
  --radius: 4px;
  --gap: 1.25rem;
  --measure: 68ch;
}

/* dark via system preference, unless explicitly set to light */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0e1620;
    --panel: #17222e;
    --ink: #e6eef5;
    --ink-soft: #9fb2c2;
    --frost: #243543;
    --accent: #f0904a;
    --accent-hover: #ffab6d;
    --shadow: rgba(0, 0, 0, 0.55);
    --danger: #ff8a80;
    --danger-wash: #331b19;
  }
}

/* explicit dark always wins */
:root[data-theme="dark"] {
  --bg: #0e1620;
  --panel: #17222e;
  --ink: #e6eef5;
  --ink-soft: #9fb2c2;
  --frost: #243543;
  --accent: #f0904a;
  --accent-hover: #ffab6d;
  --shadow: rgba(0, 0, 0, 0.55);
  --danger: #ff8a80;
  --danger-wash: #331b19;
}

/* ---------- base ---------- */
body {
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink);
  /* CSS-generated tile — no binary asset, no request */
  background-color: var(--bg);
  background-image:
    repeating-linear-gradient(45deg,  var(--frost) 0 1px, transparent 1px 14px),
    repeating-linear-gradient(-45deg, var(--frost) 0 1px, transparent 1px 14px);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

h1, h2, h3 {
  font-family: var(--font-display);
  line-height: 1.25;
  letter-spacing: -0.01em;
}

h1 { font-size: 2rem; }
h2 { font-size: 1.5rem; }
h3 { font-size: 1.25rem; }

p, ul, ol { margin-block: 0.75em; }

a {
  color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 2px;
}
a:hover { color: var(--accent-hover); }

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

code, pre {
  font-family: var(--font-display);
  font-size: 0.9em;
}

pre {
  overflow-x: auto;
  padding: 0.75rem;
  border: var(--border) solid var(--frost);
  background: var(--panel);
}

/* ---------- layout ---------- */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--panel);
  color: var(--ink);
  padding: 0.6rem 1rem;
  border: var(--border) solid var(--accent);
  z-index: 10;
}
.skip:focus { left: 0.5rem; top: 0.5rem; }

.shell {
  width: 100%;
  max-width: 62rem;
  margin-inline: auto;
  padding: var(--gap);
}

/* The game layout needs the room; prose pages read better narrow. */
.shell-wide { max-width: 82rem; }

.gamenav {
  margin-bottom: 0.75rem;
}

.gamenav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  /* The reset only clears markers from ul[class]; this ul has none of its own. */
  list-style: none;
  padding: 0;
}

.gamenav a {
  display: block;
  padding: 0.4rem 0.9rem;
  border: var(--border) solid var(--ink);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: 3px 3px 0 var(--shadow);
  text-decoration: none;
  font-family: var(--font-display);
  font-size: 0.9rem;
  color: var(--ink);
}
.gamenav a:hover { border-color: var(--accent); color: var(--accent); }

.gamenav a[aria-current="page"] {
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: inset 0 -4px 0 var(--accent);
}


main { flex: 1 0 auto; }

.panel {
  background: var(--panel);
  border: var(--border) solid var(--ink);
  border-radius: var(--radius);
  box-shadow: 5px 5px 0 var(--shadow);
  padding: clamp(1rem, 4vw, 2rem);
}

.panel + .panel { margin-top: calc(var(--gap) * 1.5); }
/* ...but not inside the column grid, where gap already spaces them and the
   stacking margin would push the side columns out of alignment. */
.columns > .panel + .panel { margin-top: 0; }

.prose { max-width: var(--measure); }

.foot {
  border-top: var(--border) solid var(--frost);
  margin-top: calc(var(--gap) * 2);
  padding-block: 1rem;
  color: var(--ink-soft);
  font-size: 0.875rem;
}

/* ---------- components ---------- */
.lede {
  font-size: 1.125rem;
  color: var(--ink-soft);
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--gap);
  margin: 0;
}

/* Four classes: a fixed 2x2 reads as a balanced set. auto-fit gave 3 + 1,
   which left the fourth stranded on its own row. */
.cards-classes {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (max-width: 44rem) {
  .cards-classes { grid-template-columns: minmax(0, 1fr); }
}

/* Cards are columns so the button can sit at the bottom of each, keeping the
   choices aligned no matter how long a blurb runs. */
.cards-classes .card {
  display: flex;
  flex-direction: column;
}
.cards-classes .card .statline { margin-bottom: 0.75rem; }
.cards-classes .card > p:last-child { margin-top: auto; }

.card {
  border: var(--border) solid var(--frost);
  border-radius: var(--radius);
  padding: 1rem;
  background: var(--panel);
}
.card h3 { margin-bottom: 0.25rem; }
.card p { margin-block: 0.4rem; }

.thumb {
  aspect-ratio: 16 / 9;
  display: grid;
  place-items: center;
  border: var(--border) dashed var(--frost);
  border-radius: var(--radius);
  color: var(--ink-soft);
  font-family: var(--font-display);
  font-size: 0.8rem;
  margin-bottom: 0.75rem;
}

.tag {
  display: inline-block;
  font-family: var(--font-display);
  font-size: 0.75rem;
  padding: 0.1rem 0.4rem;
  border: 2px solid var(--frost);
  border-radius: var(--radius);
  color: var(--ink-soft);
}

/* badge wall — scrolls in its own container, never the body */
.badge-wall {
  overflow-x: auto;
  padding-bottom: 0.5rem;
}
.badge-wall ul {
  display: flex;
  gap: 0.5rem;
  margin: 0;
  min-width: max-content;
}
.badge-wall img {
  width: 88px;
  height: 31px;
  image-rendering: pixelated;
  border: 2px solid var(--frost);
}

.posts { margin: 0; }
.posts li {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: baseline;
  padding-block: 0.6rem;
  border-bottom: 2px solid var(--frost);
}
.posts time {
  font-family: var(--font-display);
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.linklist { margin: 0; }
.linklist li { padding-block: 0.35rem; }

.btn-quiet {
  box-shadow: none;
  border-color: var(--frost);
  font-size: 0.85rem;
  padding: 0.35rem 0.7rem;
}
.btn-quiet:hover { border-color: var(--accent); }

.btn-danger {
  border-color: var(--danger);
  color: var(--danger);
}
.btn-danger:hover { border-color: var(--danger); color: var(--danger); background: var(--danger-wash); }

/* settings */
.choices {
  border: var(--border) solid var(--frost);
  border-radius: var(--radius);
  padding: 0.75rem 1rem 1rem;
  margin: 0 0 1rem;
}
.choices legend {
  font-family: var(--font-display);
  font-size: 0.85rem;
  padding-inline: 0.4rem;
}
.choice { margin: 0.5rem 0; }
.choice label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: inherit;
  font-size: 1rem;
  margin: 0;
  cursor: pointer;
}
.choice input[type="radio"] {
  width: 1.1rem;
  height: 1.1rem;
  accent-color: var(--accent);
  margin: 0;
}
.choice .hint { margin-left: 1.6rem; }

.rule {
  border: 0;
  border-top: var(--border) solid var(--frost);
  margin: 1.75rem 0 1.25rem;
}

/* ---------- utilities ---------- */
.center { text-align: center; }
.stack > * + * { margin-top: 0.75rem; }
.muted { color: var(--ink-soft); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ============================================================
   Game components — modules, stat blocks, forms, portraits
   ============================================================ */

/* Three columns: character | location | announcements.
   Source order is location, character, announcements (main content first for
   screen readers and for a no-CSS render); explicit grid-column puts them in
   the sketched visual order. */
.columns {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr) minmax(0, 15rem);
  gap: var(--gap);
  align-items: start;
}

.col-main      { grid-column: 2; grid-row: 1; min-width: 0; }
.col-character { grid-column: 1; grid-row: 1; }
.col-announce  { grid-column: 3; grid-row: 1; }

/* Two columns: drop announcements below the main content. */
@media (max-width: 68rem) {
  .columns { grid-template-columns: minmax(0, 14rem) minmax(0, 1fr); }
  .col-main      { grid-column: 2; grid-row: 1; }
  .col-character { grid-column: 1; grid-row: 1; }
  .col-announce  { grid-column: 1 / -1; grid-row: 2; }
}

/* One column: character, then location, then announcements. */
@media (max-width: 46rem) {
  .columns { grid-template-columns: minmax(0, 1fr); }
  .col-character { grid-column: 1; grid-row: 1; }
  .col-main      { grid-column: 1; grid-row: 2; }
  .col-announce  { grid-column: 1; grid-row: 3; }
}

/* place tiles */
.places {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
  gap: var(--gap);
  margin: 0.75rem 0 0;
}

.place p { margin: 0.35rem 0 0; }

.place a,
.place .place-shut {
  display: block;
  text-decoration: none;
  border: var(--border) solid var(--frost);
  border-radius: var(--radius);
  background: var(--panel);
  padding: 0.4rem;
}
.place a:hover {
  border-color: var(--accent);
  box-shadow: 3px 3px 0 var(--shadow);
}

.tile {
  image-rendering: pixelated;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  border-radius: 2px;
}

.place-name {
  display: block;
  font-family: var(--font-display);
  font-size: 0.85rem;
  font-weight: 700;
  margin-top: 0.35rem;
  overflow-wrap: anywhere;
}

.place-blurb {
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.place-locked .tile { filter: grayscale(1); opacity: 0.55; }
.place-locked .place-name { color: var(--ink-soft); text-decoration: line-through; }

/* announcements */
.announcements { margin: 0.5rem 0 0; }
.announcements li + li {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 2px solid var(--frost);
}
.announcement h3 { font-size: 0.95rem; margin: 0; }
.announcement p { margin: 0.3rem 0 0; font-size: 0.9rem; }
.announcement .stamp {
  font-family: var(--font-display);
  font-size: 0.75rem;
  color: var(--ink-soft);
}

.portrait {
  image-rendering: pixelated;
  border: var(--border) solid var(--frost);
  border-radius: var(--radius);
  width: 96px;
  height: 96px;
}
.portrait-lg { width: 120px; height: 120px; }

/* stat block — two columns, label and value */
.statline {
  display: grid;
  grid-template-columns: auto auto;
  gap: 0.15rem 0.75rem;
  justify-content: start;
  margin: 0.75rem 0 0;
  font-family: var(--font-display);
  font-size: 0.9rem;
}
.statline dt { color: var(--ink-soft); }
.statline dd { margin: 0; font-weight: 700; }

.statline-block {
  grid-template-columns: 1fr auto;
  justify-content: stretch;
  gap: 0.25rem 1rem;
}
.statline-block dt,
.statline-block dd {
  border-bottom: 2px solid var(--frost);
  padding-block: 0.2rem;
}

/* forms */
label {
  display: block;
  font-family: var(--font-display);
  font-size: 0.85rem;
  margin-bottom: 0.25rem;
}

input[type="text"],
input[type="email"],
textarea {
  width: 100%;
  max-width: 32rem;
  font: inherit;
  color: var(--ink);
  background: var(--panel);
  border: var(--border) solid var(--frost);
  border-radius: var(--radius);
  padding: 0.45rem 0.6rem;
}
textarea { max-width: 44rem; resize: vertical; }

input:focus-visible,
textarea:focus-visible { border-color: var(--accent); }

.hint {
  display: block;
  font-size: 0.8rem;
  color: var(--ink-soft);
  margin-top: 0.25rem;
  max-width: 44rem;
}

button {
  font-family: var(--font-display);
  font-size: 0.9rem;
  padding: 0.45rem 0.9rem;
  color: var(--ink);
  background: var(--panel);
  border: var(--border) solid var(--ink);
  border-radius: var(--radius);
  box-shadow: 3px 3px 0 var(--shadow);
  cursor: pointer;
}
button:hover { border-color: var(--accent); color: var(--accent); }
button:active { box-shadow: 1px 1px 0 var(--shadow); transform: translate(2px, 2px); }

.formerror,
.formok {
  border: var(--border) solid var(--accent);
  border-radius: var(--radius);
  padding: 0.6rem 0.8rem;
  margin-block: 0.75rem;
  font-size: 0.95rem;
}
.formok { border-color: var(--frost); }

.reveal {
  border: var(--border) solid var(--frost);
  border-radius: var(--radius);
  padding: 0.6rem 0.8rem;
  margin-block: 1rem;
}
.reveal summary {
  font-family: var(--font-display);
  font-size: 0.9rem;
  cursor: pointer;
}
.reveal[open] summary { margin-bottom: 0.5rem; }

.cards .card button { margin-top: 0.5rem; }

/* The player's name is the Character panel's heading. Sized down from a
   default h2 because it sits in a narrow column, and allowed to break
   anywhere -- a name is user-supplied and can be a single long token. */
.charname {
  font-size: 1.15rem;
  margin: 0;
  overflow-wrap: anywhere;
}

/* Quest is a stacked label-and-value pair rather than a two-column stat row:
   the value is prose and would squeeze against the label. */
.quest-block {
  grid-template-columns: minmax(0, 1fr);
  gap: 0.1rem;
  margin-top: 0.75rem;
  padding-top: 0.6rem;
  border-top: 2px solid var(--frost);
}
.quest-block dt { color: var(--ink-soft); }
.quest {
  font-weight: 700;
  overflow-wrap: anywhere;
}

/* inventory */
.items {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.75rem;
  margin: 0.75rem 0 0;
}

.item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas:
    "icon name qty"
    "icon kind kind"
    "blurb blurb blurb";
  gap: 0.15rem 0.6rem;
  align-items: center;
  border: var(--border) solid var(--frost);
  border-radius: var(--radius);
  background: var(--panel);
  padding: 0.6rem;
}

.item-icon {
  grid-area: icon;
  image-rendering: pixelated;
  width: 48px;
  height: 48px;
  border: 2px solid var(--frost);
  border-radius: 2px;
}

.item-name {
  grid-area: name;
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.item-qty {
  grid-area: qty;
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--accent);
}

.item .tag { grid-area: kind; justify-self: start; }

.item-blurb {
  grid-area: blurb;
  font-size: 0.82rem;
  color: var(--ink-soft);
  margin-top: 0.35rem;
}

/* The reset zeroes heading margins. Restore spacing above any heading that
   follows content, but not one that opens a panel -- the panel's own padding
   already handles that case. */
.panel h2:not(:first-child),
.panel h3:not(:first-child) {
  margin-top: 1.5rem;
}
.panel .rule + h2 { margin-top: 1rem; }

/* ---------- admin ---------- */
.adminlist { margin: 0.75rem 0 0; }
.adminlist li + li {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 2px solid var(--frost);
}
.adminrow p { margin: 0.25rem 0; }

.inline-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.4rem;
}
.inline-form label { margin: 0; }

select {
  font: inherit;
  font-family: var(--font-display);
  font-size: 0.85rem;
  color: var(--ink);
  background: var(--panel);
  border: var(--border) solid var(--frost);
  border-radius: var(--radius);
  padding: 0.3rem 0.5rem;
}
select:focus-visible { border-color: var(--accent); }

.messages { margin: 0.75rem 0 0; }
.messages li + li {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 2px solid var(--frost);
}
.message-unread { border-left: 4px solid var(--accent); padding-left: 0.75rem; }
.message-body { white-space: pre-wrap; overflow-wrap: anywhere; }

.invite-code {
  font-size: 1.2rem;
  letter-spacing: 0.02em;
}
.invite-code code {
  display: inline-block;
  padding: 0.4rem 0.7rem;
  border: var(--border) solid var(--accent);
  border-radius: var(--radius);
  background: var(--panel);
}

.choice input[type="checkbox"] {
  width: 1.1rem;
  height: 1.1rem;
  accent-color: var(--accent);
  margin: 0;
}

/* ---------- content editor ---------- */
.cgroup {
  border: var(--border) solid var(--frost);
  border-radius: var(--radius);
  margin-top: 0.75rem;
  background: var(--panel);
}
.cgroup > summary {
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 700;
  padding: 0.6rem 0.8rem;
  cursor: pointer;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}
.cgroup[open] > summary { border-bottom: 2px solid var(--frost); }

.cfields { margin: 0; padding: 0 0.8rem 0.8rem; }
.cfield + .cfield {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 2px solid var(--frost);
}
.cfield label {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}
.cfield input[type="text"],
.cfield textarea { max-width: 100%; }
.cfield .hint code { font-size: 0.9em; }
.cfield .inline-form { margin-top: 0.5rem; }

/* ---------- view-as banner ---------- */
/* Loud on purpose: an impersonation session must never be mistaken for a
   normal one. Full width, above everything, in the danger colour. */
.viewing {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 0.6rem 1rem;
  background: var(--danger-wash);
  border-bottom: var(--border) solid var(--danger);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: 0.9rem;
}
.viewing p { margin: 0; }
.viewing form { margin: 0; }

/* ---------- log ---------- */
.loglist { margin: 0.75rem 0 0; }
.loglist li + li {
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 2px solid var(--frost);
}
.logrow p { margin: 0.15rem 0; }
.logdetail {
  font-size: 0.88rem;
  color: var(--ink-soft);
  overflow-wrap: anywhere;
}

/* Narrow numeric inputs in the inspector's stat row. */
.inline-form input[size] { width: auto; min-width: 4.5rem; }
.inline-form span { display: flex; align-items: center; gap: 0.35rem; }
