/* Caerwyn Dusk is always played at dusk: bone-colored words on soot, ember for the
   places you stand, old blood for the fighting. Every theme keeps its words at WCAG AA
   (4.5 to 1) against every surface they sit on, and --edge keeps the outlines of fields
   at 3 to 1. Sizes are in rem, so the page grows with the reader's own text size. */
:root {
  --bg: #0d0b0a;
  --bg-glow: #1d1410;
  --panel: #16110e;
  --text: #ddd2bf;
  --muted: #95866f;
  --rule: #3a2e24;
  --edge: #76644f;
  --accent: #c89b5a;
  --combat: #d9584a;
  --npc: #8fb39f;
  --quest: #d8b24a;
  --say: #9fb0d8;
  --system: #a99a84;
  --shadow: rgba(200, 155, 90, 0.35);
  color-scheme: dark;
}

/* Other lights to read by: #theme parchment, ash, blood, or dusk to return. */
:root[data-theme='parchment'] {
  --bg: #efe6d2;
  --bg-glow: #f7f1e3;
  --panel: #e4d9c1;
  --text: #2b2118;
  --muted: #665848;
  --rule: #c7b899;
  --edge: #8a7759;
  --accent: #7a4a1e;
  --combat: #9c2a1f;
  --npc: #2f6b4a;
  --quest: #7a5000;
  --say: #2f4a7a;
  --system: #5a4c3c;
  --shadow: rgba(122, 74, 30, 0.2);
  color-scheme: light;
}
:root[data-theme='ash'] {
  --bg: #000000;
  --bg-glow: #0a0a0a;
  --panel: #111111;
  --text: #f2f2f2;
  --muted: #b0b0b0;
  --rule: #444444;
  --edge: #808080;
  --accent: #ffd27a;
  --combat: #ff6b5e;
  --npc: #9ee3b4;
  --quest: #ffe066;
  --say: #a9c4ff;
  --system: #d0d0d0;
  --shadow: rgba(255, 210, 122, 0.3);
}
:root[data-theme='blood'] {
  --bg: #130607;
  --bg-glow: #2a0d0f;
  --panel: #1e0a0c;
  --text: #e6cfc4;
  --muted: #9a7a70;
  --rule: #4a1f22;
  --edge: #8a5558;
  --accent: #d9534f;
  --combat: #ff5a4a;
  --npc: #c9a66b;
  --quest: #f0c050;
  --say: #c8a0a8;
  --system: #b08a80;
  --shadow: rgba(217, 83, 79, 0.35);
}

/* Author display rules (form is flex) would otherwise override the hidden attribute. */
[hidden] {
  display: none !important;
}

/* For screen readers only: in the page, read aloud, never seen. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 8px;
  top: -100px;
  z-index: 20;
  padding: 8px 12px;
  background: var(--panel);
  color: var(--accent);
  border: 1px solid var(--accent);
}
.skip-link:focus {
  top: 8px;
}

body {
  margin: 0;
  display: flex;
  flex-direction: column;
  height: 100vh;
  /* On phones the browser bar and keyboard come and go; dvh follows the visible area. */
  height: 100dvh;
  background: radial-gradient(ellipse at 50% 0%, var(--bg-glow) 0%, var(--bg) 70%) fixed, var(--bg);
  color: var(--text);
  font: 0.9375rem/1.6 ui-monospace, 'Cascadia Mono', 'DejaVu Sans Mono', monospace;
}

header {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
  justify-content: space-between;
  align-items: baseline;
  padding: 14px 16px 10px;
  border-bottom: 1px solid var(--rule);
}

h1 {
  margin: 0;
  font: 400 1.5rem/1 'Cormorant Garamond', 'EB Garamond', Garamond, 'Iowan Old Style', Georgia, serif;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  text-shadow: 0 0 12px var(--shadow);
}

#tools {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
#tools button {
  padding: 5px 10px;
  font-size: 0.75rem;
  border-color: var(--edge);
  color: var(--muted);
}
#tools button[aria-pressed='true'] {
  border-color: var(--accent);
  color: var(--accent);
}
#tools button:hover {
  color: var(--bg);
}

/* The map you have walked, beside the log on a wide screen and over it on a phone. */
#map {
  position: fixed;
  right: 16px;
  top: 70px;
  max-width: calc(100vw - 32px);
  max-height: 50vh;
  overflow: auto;
  padding: 10px 12px;
  border: 1px solid var(--rule);
  background: var(--panel);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  z-index: 5;
}
#map pre {
  margin: 0;
  font: 0.8125rem/1.25 ui-monospace, 'Cascadia Mono', 'DejaVu Sans Mono', monospace;
  color: var(--accent);
}

/* Searching the scrollback: what matches is lit, the rest fades. */
#find {
  padding: 8px 0 4px;
  align-items: center;
  flex-wrap: wrap;
}
#find input {
  min-width: 0;
}
#find button {
  padding: 9px 10px;
}
#find-count {
  color: var(--muted);
  font-size: 0.8125rem;
}
#log.searching .entry {
  opacity: 0.5;
}
#log.searching .entry.hit {
  opacity: 1;
}
#log .entry.hit mark {
  background: var(--accent);
  color: var(--bg);
}

#clock {
  color: var(--muted);
  font-size: 0.8125rem;
  font-style: italic;
}

main {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
  padding: 0 16px;
  box-sizing: border-box;
}
main:focus {
  outline: none;
}

#log {
  flex: 1;
  min-height: 6rem;
  overflow-y: auto;
  padding: 14px 0;
  scrollbar-color: var(--rule) transparent;
}

.entry {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin-bottom: 10px;
}

.entry.room {
  border-left: 2px solid var(--accent);
  padding: 2px 0 2px 12px;
}
.entry.room .room-title {
  margin: 0;
  font: 600 1.0625rem/1.8 'Cormorant Garamond', 'EB Garamond', Garamond, 'Iowan Old Style', Georgia, serif;
  letter-spacing: 0.08em;
  color: var(--accent);
}
.entry.room.pvp { border-left-color: var(--combat); }
.entry.room .warning { color: var(--combat); font-weight: bold; }
.entry.room .sky { color: var(--muted); font-style: italic; margin-top: 4px; }

/* The things in a room, as buttons. A tap finishes the command waiting in the command
   line, or names the thing there for a command button. */
.chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  white-space: normal;
}
.chips-label {
  color: var(--muted);
  font-size: 0.8125rem;
  margin-right: 2px;
}
.chip {
  padding: 4px 10px;
  font-size: 0.875rem;
  border-radius: 14px;
  border-color: var(--edge);
  color: var(--text);
}
.chip.enemy { color: var(--combat); border-color: var(--combat); }
.chip.npc { color: var(--npc); border-color: var(--npc); }
.chip.player { color: var(--say); border-color: var(--say); }
.chip.item { color: var(--quest); border-color: var(--edge); }
.chip.exit { color: var(--accent); border-color: var(--edge); }
.chip:hover { background: var(--panel); color: inherit; }
.chip:disabled {
  opacity: 0.6;
  cursor: default;
}

/* On a touch screen the things in a room are as easy to hit as the pad. */
@media (pointer: coarse) {
  .chip {
    min-height: 44px;
    min-width: 44px;
  }
}
.entry.chat { color: var(--say); font-style: italic; }
.entry.combat { color: var(--combat); }
.entry.npc { color: var(--npc); }
.entry.quest { color: var(--quest); font-weight: bold; }
.entry.say { color: var(--say); }
.entry.system { color: var(--system); font-style: italic; }
.entry.error, .entry.echo { color: var(--muted); }

#status {
  flex: none;
  padding: 6px 0;
  border-top: 1px solid var(--rule);
  color: var(--muted);
}

form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 8px 0 16px;
}

/* A field is its label above its input; the forms line fields up and wrap them. */
.field {
  flex: 1;
  min-width: 10rem;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-self: flex-end;
}
label {
  color: var(--muted);
  font-size: 0.8125rem;
}
#command label {
  flex: none;
}

input,
select {
  flex: 1;
  min-width: 8.75rem;
  padding: 9px 10px;
  font: inherit;
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--edge);
  outline: none;
}

input:focus,
select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent);
}

button {
  padding: 9px 16px;
  font: inherit;
  letter-spacing: 0.05em;
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
  cursor: pointer;
}

button:hover {
  background: var(--accent);
  color: var(--bg);
}

/* Where the keyboard is, always plain to see. */
button:focus-visible,
a:focus-visible,
#log:focus-visible,
input[type='checkbox']:focus-visible,
input[type='range']:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The pad: the compass of ways out on the left, Up beside North and Down beside South,
   and across a rule the commands. Every button is at least 44 pixels, and grows with the
   reader's text size. */
#pad {
  flex: none;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding-top: 8px;
}

#pad button {
  min-width: 0;
  min-height: 44px;
  padding: 2px 4px;
  font-size: 0.8125rem;
  letter-spacing: 0;
  white-space: nowrap;
}

#compass {
  flex: none;
  display: grid;
  grid-template-columns: repeat(3, max(44px, 2.75rem));
  grid-template-rows: repeat(3, max(44px, 2.75rem));
  grid-template-areas:
    '. north up'
    'west . east'
    '. south down';
  gap: 4px;
}
#compass .north { grid-area: north; }
#compass .south { grid-area: south; }
#compass .east { grid-area: east; }
#compass .west { grid-area: west; }
#compass .up { grid-area: up; }
#compass .down { grid-area: down; }
#compass button {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
#compass .updown {
  font-size: 0.75rem;
}
/* The arrows are drawn, not typed: a triangle pointing the way. */
#compass .way:not(.updown)::before {
  content: '';
  width: 1.125rem;
  height: 0.875rem;
  background: currentColor;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  forced-color-adjust: none;
}
#compass .east::before { transform: rotate(90deg); }
#compass .south::before { transform: rotate(180deg); }
#compass .west::before { transform: rotate(270deg); }
/* Ways the room last shown does not have: dimmed with a broken outline, still pressable;
   the game says so in words if the way is shut. */
#compass .shut {
  color: var(--muted);
  border-color: var(--edge);
  border-style: dashed;
}
#compass .shut:hover {
  color: var(--bg);
}
@media (forced-colors: active) {
  #compass .way:not(.updown)::before { background: ButtonText; }
}

#commands {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
  gap: 4px;
  padding-left: 8px;
  border-left: 1px solid var(--rule);
}

#command {
  flex: none;
}

/* The Reading window. */
dialog {
  max-width: min(36rem, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  overflow: auto;
  padding: 16px 20px;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--edge);
}
dialog::backdrop {
  background: rgba(5, 4, 3, 0.72);
}
dialog form {
  display: block;
  padding: 0;
}
dialog h2 {
  margin: 0 0 12px;
  font: 600 1.25rem/1.3 'Cormorant Garamond', 'EB Garamond', Garamond, Georgia, serif;
  color: var(--accent);
}
dialog h3 {
  margin: 16px 0 4px;
  font-size: 1rem;
  color: var(--accent);
}
dialog fieldset {
  margin: 0 0 12px;
  border: 1px solid var(--rule);
}
dialog legend {
  color: var(--accent);
  padding: 0 4px;
}
dialog .check {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  margin: 6px 0;
}
dialog .check input {
  flex: none;
  min-width: 0;
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.2rem;
}
dialog .check label,
dialog .field label {
  color: var(--text);
  font-size: 0.875rem;
}
dialog .field {
  margin: 8px 0;
}
dialog dl {
  margin: 0 0 12px;
  font-size: 0.875rem;
}
dialog dt {
  color: var(--accent);
}
dialog dd {
  margin: 0 0 4px 1rem;
  color: var(--text);
}

@media (max-width: 600px) {
  body {
    font-size: 0.875rem;
  }
  header {
    padding: 10px 12px 8px;
  }
  h1 {
    font-size: 1.125rem;
  }
  #clock {
    display: none;
  }
  #map {
    right: 12px;
    top: 52px;
  }
  main {
    padding: 0 12px;
  }
  #pad button {
    font-size: 0.75rem;
  }
  #commands {
    grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));
  }
  /* Large enough to stop mobile browsers zooming in on focus. */
  input {
    font-size: 1rem;
  }
}

/* A short phone screen: the commands keep to about the compass's height and scroll
   within it, the half row showing that there is more, so the log keeps its room. */
@media (max-width: 600px) and (max-height: 760px) {
  #commands {
    max-height: calc(3.5 * max(44px, 2.75rem) + 12px);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-color: var(--rule) transparent;
  }
}

/* Very narrow, or zoomed far in: a narrower margin, so the commands keep two columns. */
@media (max-width: 360px) {
  main {
    padding: 0 8px;
  }
  #pad {
    gap: 6px;
  }
  #commands {
    padding-left: 6px;
  }
}

button.quiet {
  border-color: var(--edge);
  color: var(--muted);
}

#auth-error {
  width: 100%;
  margin: 0;
  color: var(--combat);
}

/* Nothing in the page moves on its own, and nothing ever will for a player who asks. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}
