/* ---------------------------------------------------------------------------------------------
 * Zaytun Player — presentation only. The output pane's line classes (room-title, combat, error,
 * status, echo, finish, scene) are set by ui.js as each line is rendered.
 *
 * Three things this file is trying to be, in order:
 *
 *   1. Readable. A game here is nothing but text, so the type, the measure and the contrast are
 *      the interface. Every colour pair below is at or above WCAG AA against its own background,
 *      computed rather than eyeballed.
 *   2. Usable on a phone. The transcript takes whatever height is left, the prompt stays put
 *      above the keyboard, and every control is big enough to hit.
 *   3. Self-contained. No fonts, no images, no network of any kind — the page has to work when
 *      opened straight off disk over file://, which is most of the point of this player.
 * ------------------------------------------------------------------------------------------- */

:root {
  color-scheme: dark light;

  --bg:      #0d1117;
  --panel:   #161b22;
  --text:    #e6edf3;
  --dim:     #9aa7b4;   /* was #6b7280, which came to 3.7:1 on the panel and failed AA */
  --accent:  #7fd7c4;
  --on-accent: #0d1117;
  --error:   #ff9d9d;
  --finish:  #f0c96b;
  --combat:  #e8b078;
  --scene:   #c9d3e0;
  --border:  #2a313a;
  --focus:   #7fd7c4;

  --radius: 10px;
  --gap: 0.75rem;
}

/* The light palette is a separate set of values rather than a filter, because a wash of
   inverted colours reads as a mistake. Anyone who has asked their system for light wants
   paper. */
@media (prefers-color-scheme: light) {
  :root {
    --bg:      #f7f6f3;
    --panel:   #ffffff;
    --text:    #1c2128;
    --dim:     #5a6672;
    --accent:  #0d6e5e;
    --on-accent: #ffffff;
    --error:   #b3261e;
    --finish:  #8a6100;
    --combat:  #9a5518;
    --scene:   #39424d;
    --border:  #d9dee4;
    --focus:   #0d6e5e;
  }
}

* { box-sizing: border-box; }

/* 100dvh rather than 100vh: on a phone the visual viewport shrinks when the keyboard opens and
   grows when the browser chrome retracts, and vh does not notice either. The vh line is the
   fallback for browsers without dvh. */
html { height: 100%; }
body {
  height: 100vh;
  height: 100dvh;
  margin: 0 auto;
  padding: 1rem;
  padding-left:  max(1rem, env(safe-area-inset-left));
  padding-right: max(1rem, env(safe-area-inset-right));
  padding-bottom: max(1rem, env(safe-area-inset-bottom));
  max-width: 48rem;
  display: flex;
  flex-direction: column;
  gap: var(--gap);

  background: var(--bg);
  color: var(--text);
  font-family: ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;
  font-size: clamp(0.95rem, 0.9rem + 0.25vw, 1.05rem);
  line-height: 1.6;
  -webkit-text-size-adjust: 100%;   /* stop iOS inflating text in landscape */
}

h1 {
  font-size: 1.1rem;
  color: var(--accent);
  margin: 0;
  letter-spacing: 0.02em;
}

#subtitle {
  color: var(--dim);
  font-size: 0.8rem;
  line-height: 1.5;
  margin: 0;
}

/* --- loading a game ------------------------------------------------------------------------ */

#loadBar {
  display: flex;
  flex-wrap: wrap;              /* on a narrow screen the status drops below the picker */
  gap: 0.5rem var(--gap);
  align-items: center;
}

#fileInput {
  color: var(--dim);
  font: inherit;
  font-size: 0.8rem;
  max-width: 100%;
}

/* The default file button is the one control that looks like it belongs to a different page. */
#fileInput::file-selector-button {
  font: inherit;
  font-size: 0.8rem;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.5rem 0.75rem;
  margin-right: 0.6rem;
  cursor: pointer;
  min-height: 2.5rem;
}
#fileInput::file-selector-button:hover { border-color: var(--accent); }

#status { color: var(--dim); font-size: 0.8rem; }

/* --- the transcript ------------------------------------------------------------------------ */

#output {
  flex: 1 1 auto;               /* takes whatever height is left, on any screen */
  min-height: 8rem;             /* ...but never collapses to nothing beside a tall keyboard */
  overflow-y: auto;
  overflow-x: auto;             /* wide preformatted text scrolls in here, never on the page */
  overscroll-behavior: contain; /* scrolling to the end does not then drag the page */

  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  white-space: pre-wrap;        /* the games align things with spaces; keep them */
  overflow-wrap: break-word;    /* a long word wraps rather than widening the box */
}

#output p { margin: 0 0 0.7rem 0; }
#output p:last-child { margin-bottom: 0; }

#output .room-title { color: var(--accent); font-weight: 700; }
#output .echo       { color: var(--dim); }
#output .error      { color: var(--error); }
#output .finish     { color: var(--finish); font-weight: 700; }
#output .combat     { color: var(--combat); }
#output .status     { color: var(--accent); }

/* Narrative scenes: set apart from ordinary room text by a rule and a little air, so an intro
   or a cutscene reads as its own thing rather than as another paragraph of description. */
#output p.scene {
  border-left: 2px solid var(--border);
  padding-left: 0.9rem;
  margin-left: 0.15rem;
  color: var(--scene);
}

/* --- the prompt ---------------------------------------------------------------------------- */

#cmdForm { display: flex; gap: 0.5rem; }

#cmd {
  flex: 1 1 auto;
  min-width: 0;                 /* lets the field shrink instead of pushing the button off */
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  font-family: inherit;
  font-size: 1rem;              /* 16px or more, or iOS zooms the page on focus */
  padding: 0.7rem 0.85rem;
  border-radius: var(--radius);
  min-height: 2.75rem;          /* 44px: the smallest thing a finger reliably hits */
}
#cmd::placeholder { color: var(--dim); opacity: 1; }
#cmd:disabled { opacity: 0.6; }

button {
  background: var(--accent);
  color: var(--on-accent);
  border: 1px solid transparent;
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 700;
  padding: 0.7rem 1.1rem;
  border-radius: var(--radius);
  cursor: pointer;
  min-height: 2.75rem;
  touch-action: manipulation;   /* no 300ms wait for a double-tap that is not coming */
}
button:hover { filter: brightness(1.08); }
button:active { transform: translateY(1px); }

button.secondary {
  background: transparent;
  color: var(--dim);
  border-color: var(--border);
  font-weight: 400;
}
button.secondary:hover { color: var(--text); border-color: var(--accent); }

#toolbar { display: flex; gap: 0.5rem; flex-wrap: wrap; }

#saveArea {
  display: none;                /* ui.js turns this on */
  width: 100%;
  min-height: 6rem;
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-family: inherit;
  font-size: 0.8rem;
  padding: 0.6rem;
  resize: vertical;
}

/* --- focus, motion, and the things people set for themselves -------------------------------- */

/* Visible focus on everything, and never removed. :focus-visible keeps it off a mouse click
   while keeping it on for the keyboard, which is who needs it. */
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
#cmd:focus-visible { outline-offset: 0; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
  button:active { transform: none; }
  #output { scroll-behavior: auto; }
}

@media (prefers-contrast: more) {
  :root { --dim: var(--text); --border: var(--text); }
}

/* --- small screens -------------------------------------------------------------------------- */

@media (max-width: 30rem) {
  body { padding: 0.6rem; gap: 0.5rem; }
  /* Once a game is running, the paragraph explaining what this page is has done its job, and
     on a small screen the transcript is what the room is for. It is taken out of the layout
     rather than out of the page: `display: none` would drop it from the accessibility tree
     too, and a screen reader user has as much right to re-read it as anyone. The file picker
     stays visible either way — you may want a different game. */
  body.playing #subtitle {
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap;
  }
  #output { padding: 0.75rem; border-radius: 8px; }
  h1 { font-size: 1rem; }
  #subtitle { font-size: 0.75rem; }
  /* Full-width buttons in the toolbar are easier to hit than a row of small ones. */
  #toolbar button { flex: 1 1 8rem; }
}

/* A short landscape phone: the header is the first thing worth giving up for transcript. */
@media (max-height: 26rem) and (orientation: landscape) {
  #subtitle { display: none; }
  body { gap: 0.4rem; padding-top: 0.5rem; }
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap;
}
