/* BLACKGLASS base styles: design tokens and shared components.
   Used by every page (landing, game, sign-in, account, admin). */

:root {
  color-scheme: dark;

  --bg: #0a0b0c;
  --bg-raised: #101214;
  --panel: #14171a;
  --panel-2: #1a1e21;
  --line: #262b2f;
  --line-strong: #394046;

  --text: #d8d4cb;
  --text-strong: #efebe2;
  --muted: #8d8a83;
  --faint: #5c5a55;

  --accent: #9fb7aa;        /* pale verdigris */
  --accent-strong: #c3d8cc;
  --warn: #c79a5b;
  --danger: #c0645a;
  --ok: #8fb08a;
  --violet: #9587b3;

  /* editing (BG-161; the desktop Builder uses the same names and values): every editable control on a lighter inset
     surface with an outline you can see (3 : 1), bright values, an accent ring on focus, what is chosen on --selected */
  --field: #262c33;
  --field-hover: #2d343c;
  --field-border: #5a6672;
  --field-border-hover: #7d8a96;
  --value: #f2f4f5;
  --placeholder: #8c97a2;
  --selected: #1e3d46;
  --ring: #6cc4d8;
  --on-ring: #0b1215;

  --font-serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, "Times New Roman", serif;
  --font-mono: "Cascadia Mono", "SF Mono", Menlo, Consolas, "DejaVu Sans Mono", "Liberation Mono", ui-monospace, monospace;
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  --radius: 3px;
  --gap: 1rem;
  --measure: 38rem;
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--story-font, var(--font-serif));
  font-size: calc(var(--story-size, 19px) * 0.9);
  line-height: 1.6;
  min-height: 100vh;
  /* Notched phones: the viewport covers the whole screen (viewport-fit=cover in layout.php), so keep
     content out of the notch, rounded corners and home indicator. Zero everywhere else. The game
     screen applies these to its own shell instead (game.css). */
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

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

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

h1, h2, h3 {
  font-family: var(--font-mono);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-strong);
  line-height: 1.3;
}
h1 { font-size: 1.25rem; }
h2 { font-size: 1rem; }
h3 { font-size: 0.875rem; color: var(--muted); }

p { margin: 0 0 1em; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

.muted { color: var(--muted); }
.faint { color: var(--faint); }
.mono  { font-family: var(--font-mono); }
.small { font-size: 0.875rem; }

/* Page frame used by sign-in, account and admin pages */
.page { max-width: 64rem; margin: 0 auto; padding: 1.5rem 1rem 4rem; }
.page-narrow { max-width: 30rem; }

.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.75rem 1rem; border-bottom: 1px solid var(--line);
  font-family: var(--font-mono); font-size: 0.8125rem; letter-spacing: 0.06em;
}
.topbar a { color: var(--muted); text-decoration: none; }
.topbar a:hover { color: var(--text-strong); }
.wordmark {
  font-family: var(--font-mono); letter-spacing: 0.35em; text-transform: uppercase;
  color: var(--text-strong) !important; font-size: 0.875rem;
}

.stack > * + * { margin-top: var(--gap); }
.row { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; }

/* Panels */
.panel {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.25rem;
}
.panel > h2:first-child, .panel > h3:first-child { margin-top: 0; }

/* Buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5em;
  font-family: var(--font-mono); font-size: 0.8125rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text); background: transparent;
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  padding: 0.6rem 1rem; min-height: 2.5rem; cursor: pointer; text-decoration: none;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.btn:hover { border-color: var(--accent); color: var(--text-strong); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.btn-primary { border-color: var(--accent); color: var(--accent-strong); }
.btn-primary:hover { background: rgba(159, 183, 170, 0.08); }
.btn-danger { border-color: rgba(192, 100, 90, 0.6); color: var(--danger); }
.btn-danger:hover { border-color: var(--danger); background: rgba(192, 100, 90, 0.08); color: #e38b80; }
.btn-quiet { border-color: transparent; color: var(--muted); padding-left: 0.5rem; padding-right: 0.5rem; }
.btn-quiet:hover { border-color: var(--line); }
.btn-small { min-height: 2rem; padding: 0.35rem 0.7rem; font-size: 0.75rem; }

/* Forms */
.field { display: flex; flex-direction: column; gap: 0.35rem; }
.field label, .label {
  font-family: var(--font-mono); font-size: 0.75rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted);
}
.input, input[type="email"], input[type="text"], input[type="search"], textarea, select {
  font: inherit; font-family: var(--font-mono); font-size: 1rem;
  color: var(--text-strong); background: var(--bg-raised);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  padding: 0.6rem 0.75rem; width: 100%;
}
textarea { min-height: 12rem; line-height: 1.5; resize: vertical; }
.input:focus, input:focus, textarea:focus, select:focus { border-color: var(--accent); outline: none; }
.input-code { font-size: 1.5rem; letter-spacing: 0.5em; text-align: center; }
.check { display: flex; gap: 0.6rem; align-items: flex-start; font-size: 0.9375rem; }
.check input { margin-top: 0.3rem; accent-color: var(--accent); }
.hint { font-size: 0.875rem; color: var(--muted); }

/* Notices */
.notice {
  border: 1px solid var(--line-strong); border-left-width: 3px; border-radius: var(--radius);
  padding: 0.75rem 1rem; background: var(--bg-raised); font-size: 0.9375rem;
}
.notice-ok { border-left-color: var(--ok); }
.notice-error { border-left-color: var(--danger); }
.notice-warn { border-left-color: var(--warn); }

/* Tables (admin, account) */
.table-wrap { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: 0.8125rem; }
.table th, .table td { text-align: left; padding: 0.55rem 0.75rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.table th { color: var(--muted); font-weight: 400; letter-spacing: 0.08em; text-transform: uppercase; font-size: 0.6875rem; }
.table tr:hover td { background: var(--bg-raised); }

.tag {
  display: inline-block; font-family: var(--font-mono); font-size: 0.6875rem; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 0.1rem 0.45rem; border: 1px solid var(--line-strong);
  border-radius: 2px; color: var(--muted);
}
.tag-ok { border-color: rgba(143, 176, 138, 0.5); color: var(--ok); }
.tag-warn { border-color: rgba(199, 154, 91, 0.5); color: var(--warn); }
.tag-danger { border-color: rgba(192, 100, 90, 0.5); color: var(--danger); }

/* A Fragment finished by every character it defines (Jake, 2026-09-28: "Once a fragment has been
   finished by all characters, it should be marked as Complete") — landing.php beside the title,
   account.php beside each Fragment row. Black-glass-and-green, like the done-shard mark
   (_done-shard.php) that already means "finished" on this site, but a chip of its own so it reads
   as a property of the Fragment, not of one Journey. A one-off gentle shimmer when it first
   appears, not a repeating pulse like the other chips here: this marks something finished once, not
   an ongoing state. Reduced motion (above) flattens it to its resting look. */
.fragment-all-complete {
  display: inline-block; vertical-align: middle; margin-left: 0.4rem; padding: 0.05rem 0.45rem;
  font-family: var(--font-mono); font-size: 0.625rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: #5fd07a; background: #0b0d0f; border: 1px solid #56666b; border-radius: 2px;
  animation: fragment-all-complete-shimmer 2.6s ease-in-out 0.2s 1 both;
}
@keyframes fragment-all-complete-shimmer {
  0% { box-shadow: none; }
  40% { box-shadow: 0 0 8px 1px rgba(95, 208, 122, 0.55); }
  100% { box-shadow: none; }
}

dl.facts { display: grid; grid-template-columns: max-content 1fr; gap: 0.4rem 1.25rem; margin: 0; font-size: 0.9375rem; }
dl.facts dt { font-family: var(--font-mono); font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); padding-top: 0.2rem; }
dl.facts dd { margin: 0; }

/* Dialog */
dialog.dialog {
  background: var(--panel); color: var(--text); border: 1px solid var(--line-strong); border-radius: var(--radius);
  padding: 1.5rem; max-width: min(34rem, calc(100vw - 2rem));
}
dialog.dialog::backdrop { background: rgba(0, 0, 0, 0.7); }
dialog.dialog h2 { margin-top: 0; }
.dialog-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: flex-end; margin-top: 1.25rem; }
.dialog-close { position: absolute; top: 0.6rem; right: 0.7rem; background: none; border: 0; color: var(--muted); font-size: 1.6rem; line-height: 1; cursor: pointer; padding: 0.2rem 0.4rem; }
.dialog-close:hover { color: var(--text-strong); }

/* "Install as an app" instructions for iPhone and iPad (js/shell/pwa.js), styled like the About dialog. */
dialog.install-dialog { width: min(30rem, calc(100vw - 1.5rem)); max-width: none; max-height: calc(100dvh - 1.5rem); overflow-y: auto; padding: 1.5rem 1.6rem 1.1rem; position: relative; }
.install-dialog h2 { font-family: var(--font-mono); font-size: 0.95rem; font-weight: 400; letter-spacing: 0.22em; text-transform: uppercase; color: var(--text-strong); margin: 0 2rem 1.1rem 0; }
.install-dialog p { font-size: 0.975rem; line-height: 1.65; margin: 0 0 0.95rem; }
.install-steps { margin: 0 0 1.1rem; padding-left: 1.4rem; font-size: 0.975rem; line-height: 1.65; }
.install-steps li + li { margin-top: 0.35rem; }
.install-steps strong { color: var(--text-strong); font-weight: 600; }
.install-share { vertical-align: -0.2em; color: var(--accent); margin: 0 0.1rem; }
.install-dialog .hint { margin-bottom: 0; }

/* A newer release while this page is open (js/shell/pwa.js showUpdateNotice): quiet, bottom centre. */
.update-notice {
  position: fixed; left: 50%; bottom: calc(1rem + env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 50;
  display: flex; align-items: center; gap: 0.6rem; max-width: calc(100vw - 2rem); box-sizing: border-box;
  padding: 0.5rem 0.6rem 0.5rem 0.9rem; background: var(--panel-2); border: 1px solid var(--line-strong); border-radius: var(--radius);
  font-size: 0.875rem; color: var(--text); box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
}
.update-notice .update-dismiss { background: none; border: 0; color: var(--muted); font-size: 1.1rem; cursor: pointer; padding: 0 0.25rem; }
.update-notice .update-dismiss:hover { color: var(--text-strong); }

/* Anonymous analytics consent prompt (public/js/shell/analytics.js): a quiet bar at the foot of
   the page, not a modal wall. Shown once; the choice is then kept in localStorage (and, once
   signed in, on the account too), so it does not come back. */
.consent-bar {
  position: fixed; left: 1rem; right: 1rem; bottom: calc(1rem + env(safe-area-inset-bottom)); z-index: 40;
  max-width: 30rem; margin: 0 auto; box-sizing: border-box; padding: 0.7rem 1rem;
  border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--panel-2);
  color: var(--text); font-size: 0.9375rem; display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 0.6rem 1rem; box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
}
.consent-bar p { margin: 0; }
.consent-bar .row { display: flex; gap: 0.6rem; }

@media (max-width: 40rem) {
  dl.facts { grid-template-columns: 1fr; }
  dl.facts dd { margin-bottom: 0.5rem; }
}

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

/* ---- the game keeps its own colours (Jake, 2026-09-29) ------------------------------------------
   :root declares color-scheme: dark (and layout.php a matching meta and darkreader-lock), so the
   browsers' automatic dark modes and Dark Reader leave the page alone. Forced colours (Windows High
   Contrast, Firefox's "override colours") are an accessibility setting and still restyle text and
   controls, but the artwork keeps its true colours: the place pictures, map, sprites and every canvas,
   the header picture, the black-glass marks and the Journey-complete display. */
@media (forced-colors: active) {
  canvas, img, svg, video, picture,
  figure.place-art, .landing-hero, .series-title .glass,
  .done-shard, .journey-lcd, .journey-lcd * {
    forced-color-adjust: none;
  }
}
