/* LUSKI Arcade — Dialogue Box component (support FAQ as RPG dialogue).
 *
 * One piece of a 4-piece game-UI library (nav bar, item-card, dialogue-box,
 * quest-log). Every colour, font and radius below comes from
 * arcade/tokens.css (--arc-*) — nothing here is a hand-picked value, because
 * that token file is the only thing keeping four separately-built pieces
 * looking like one system.
 *
 * Class vocabulary is prefixed `dlg-` so this component can sit on the same
 * page as the other three without any class collisions.
 *
 * Markup contract (see dialogue-box.html):
 *   .dlg                              root
 *   .dlg-window                       portrait + speech row
 *   .dlg-portrait                     circular placeholder slot (no photo yet)
 *   .dlg-speech / .dlg-speech-text    the line that gets replaced on click
 *   .dlg-choices                      up to 4 .dlg-choice buttons
 *   .dlg-choice[data-answer]          state classes: is-active, is-visited
 *
 * Accessibility:
 *   - .dlg-speech-text carries aria-live/aria-atomic in the markup so a
 *     screen reader announces the new answer the moment a choice is picked.
 *   - Each choice is a real <button>, so Tab/Enter/Space work with no extra
 *     script, and gets a visible :focus-visible ring built only from
 *     --arc-accent (no invented colour).
 *   - "Visited" is never colour-only: the marker glyph itself changes
 *     (▸︎ -> ✓) and a visually-hidden status span announces "Answered.".
 */

.dlg-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.dlg {
  width: 100%;
  max-width: 640px;
  font-family: var(--arc-font-body);
  color: var(--arc-ink);
}

/* ── window: portrait + speech ─────────────────────────────────────────── */

.dlg-window {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  background: linear-gradient(180deg, var(--arc-chrome-2) 0%, var(--arc-chrome-1) 100%);
  border: 1px solid var(--arc-border-chrome-strong);
  border-radius: var(--arc-radius);
  padding: 16px;
}

/* Shadow is derived from the site's own near-black --arc-bg via color-mix
   rather than a hard-coded rgba(0,0,0,..) value, so even this stays token-only.
   @supports guards browsers without color-mix; the window still reads fine
   with just its border and no drop shadow. */
@supports (color: color-mix(in srgb, red 50%, transparent)) {
  .dlg-window {
    box-shadow: 0 10px 28px color-mix(in srgb, var(--arc-bg) 55%, transparent);
  }
}

/* Circular portrait slot. Deliberately not a photo yet — a bordered ring
   with a dashed inner edge and a wrench glyph, so it reads as "art pending"
   rather than a finished, empty-looking avatar. The required HTML comment
   marking this slot for future AI-generated art lives in dialogue-box.html,
   directly above the .dlg-portrait element (this is a CSS file, so an HTML
   comment cannot live here). */
.dlg-portrait {
  position: relative;
  flex: 0 0 auto;
  width: clamp(52px, 16vw, 84px);
  height: clamp(52px, 16vw, 84px);
  border-radius: 50%;
  border: 2px solid var(--arc-accent);
  background: radial-gradient(circle at 35% 30%, var(--arc-chrome-1) 0%, var(--arc-chrome-2) 60%, var(--arc-chrome-1) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* Placeholder-only ring, shown while no portrait art exists yet (see the
   dlg-portrait--pending modifier below). Once real art is in place, the
   circle's own border carries the frame instead. */
.dlg-portrait--pending::after {
  content: '';
  position: absolute;
  inset: 5px;
  border-radius: 50%;
  border: 1px dashed var(--arc-border-chrome-strong);
  pointer-events: none;
}

.dlg-portrait-icon {
  position: relative;
  z-index: 1;
  width: 44%;
  height: 44%;
  color: var(--arc-ink-solid-dim);
}

.dlg-portrait-img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  display: block;
}

.dlg-speech {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  background: var(--arc-chrome-2);
  border: 1px solid var(--arc-border-chrome-strong);
  border-radius: var(--arc-radius);
  padding: 12px 14px;
  /* Fixed-ish minimum height so the choice list beneath doesn't jump around
     as the visitor picks answers of different lengths. */
  min-height: 4.6em;
  box-sizing: border-box;
}

/* Speaker name, shown once above the line -- optional: pages that haven't
   adopted a named character yet simply omit this element and .dlg-speech's
   own justify-content:center keeps a lone .dlg-speech-text vertically
   centred exactly as before. */
.dlg-speech-name {
  margin: 0;
  color: var(--arc-accent);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.dlg-speech-text {
  margin: 0;
  color: var(--arc-ink-solid);
  font-size: 15px;
  line-height: 1.5;
  animation: dlg-text-in .3s var(--arc-ease);
}

@keyframes dlg-text-in {
  from { opacity: 0; transform: translateY(3px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Real numbers/amounts Torque references (a $ figure, a %, a km count, a
   day/month/year count) — wrapped at render time by dialogue-box.js, never
   hand-authored in the source copy. Highlighter-swipe: a flat accent fill
   grows in from the left via background-size, same shape as a highlighter
   pen stroke landing on the word. */
.dlg-num {
  background-image: linear-gradient(90deg, color-mix(in srgb, var(--arc-accent) 32%, transparent), color-mix(in srgb, var(--arc-accent) 32%, transparent));
  background-repeat: no-repeat;
  background-size: 0% 100%;
  color: inherit;
  font-weight: 700;
  padding: 0 1px;
  border-radius: 2px;
  animation: dlg-num-sweep .5s var(--arc-ease) forwards;
  animation-delay: .12s;
}

@keyframes dlg-num-sweep {
  to { background-size: 100% 100%; }
}

/* Typewriter caret, appended after the in-progress text and removed once
   the answer finishes revealing (see renderAnswer in dialogue-box.js). */
.dlg-caret {
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 1px;
  vertical-align: text-bottom;
  background: var(--arc-accent);
  animation: dlg-caret-blink 1s step-end infinite;
}

@keyframes dlg-caret-blink {
  50% { opacity: 0; }
}

/* ── choices ────────────────────────────────────────────────────────────── */

.dlg-choices {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 14px;
}

/* The [hidden] content attribute only maps to display:none via the browser's
   UA stylesheet, which author CSS always outranks regardless of selector
   specificity -- the plain `display: flex` above was silently cancelling it
   out, so every topic panel rendered fully expanded at once, all the time,
   on every page using this component (found via a direct computed-style
   check during real mobile-viewport testing; every prior check in this
   loop had only confirmed the RIGHT content was reachable via text
   matching, never that the WRONG content was actually hidden). Restated
   explicitly here so a hidden panel is actually hidden again. */
.dlg-choices[hidden] {
  display: none;
}

.dlg-choice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  text-align: left;
  font: inherit;
  font-size: 14px;
  line-height: 1.45;
  color: var(--arc-ink-solid);
  background: var(--arc-chrome-2);
  border: 1px solid var(--arc-border-chrome-strong);
  border-radius: var(--arc-radius);
  padding: 10px 14px;
  cursor: pointer;
}

.dlg-choice:hover {
  border-color: var(--arc-accent);
  background: var(--arc-chrome-1);
}

.dlg-choice-marker {
  flex: 0 0 auto;
  width: 1em;
  line-height: 1.45;
  font-weight: 700;
  color: var(--arc-ink-solid-dim);
}

.dlg-choice-marker::before {
  content: '\25B8\FE0E'; /* ▸︎ */
}

.dlg-choice-text {
  flex: 1 1 auto;
}

/* Currently-shown answer: neutral->accent border pop, distinct from "visited". */
.dlg-choice.is-active {
  border-color: var(--arc-accent);
  background: var(--arc-chrome-1);
}

.dlg-choice.is-active .dlg-choice-text {
  font-weight: 600;
}

/* Already-answered: marker glyph swaps to a check (never colour-only) and
   the question text dims so the list visually settles as it's worked through. */
.dlg-choice.is-visited .dlg-choice-marker::before {
  content: '\2713'; /* ✓ */
}

.dlg-choice.is-visited .dlg-choice-marker {
  /* --arc-good directly on --arc-chrome-2 is still under the 3:1 non-text
     WCAG floor, making the ✓ glyph nearly invisible. Darken it via color-mix
     (same technique as the .dlg-window shadow above) so it stays recognizably
     "good"-green but clears a solid margin against chrome -- no new token,
     no hue change, just enough lightness drop to make the glyph legible. */
  color: color-mix(in srgb, var(--arc-good) 55%, black);
}

.dlg-choice.is-visited:not(.is-active) .dlg-choice-text {
  color: var(--arc-ink-solid-dim);
}

/* ── focus (keyboard only, built only from --arc-accent) ──────────────────── */

/* ── topics — the level above a question list, for a FAQ too big for one
   flat set of choices to stay legible (see dialogue-box.js's two-level
   flow). Same visual language as .dlg-choice by design: a topic is still
   "a thing you pick", it just leads to more choices instead of an answer. */

.dlg-topic {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  color: var(--arc-ink-solid);
  background: var(--arc-chrome-2);
  border: 1px solid var(--arc-border-chrome-strong);
  border-radius: var(--arc-radius);
  padding: 12px 14px;
  cursor: pointer;
}

.dlg-topic:hover {
  border-color: var(--arc-accent);
  background: var(--arc-chrome-1);
}

.dlg-topic-marker {
  flex: 0 0 auto;
  color: var(--arc-ink-solid-dim);
}

.dlg-topic-marker::before {
  content: '\25B8\FE0E'; /* ▸︎, matches .dlg-choice-marker's unanswered glyph */
}

/* A topic already opened once reads the same way an answered question does
   -- settled, not demanding another look -- without implying its questions
   were "answered" the way a real choice is. */
.dlg-topic.is-visited .dlg-topic-marker::before {
  content: '\2022'; /* middle dot, deliberately distinct from ✓ (answered) and ▸︎ (unopened) */
}

.dlg-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--arc-ink-solid-dim);
  background: none;
  border: none;
  padding: 4px 2px;
  margin-bottom: 10px;
  cursor: pointer;
}

.dlg-back:hover {
  color: var(--arc-accent);
}

.dlg-topic-heading {
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--arc-ink-solid-dim);
  font-weight: 700;
  margin: 0 0 10px;
}

/* ── motion & small viewports ─────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .dlg-speech-text {
    animation: none;
  }
  .dlg-choice, .dlg-topic {
    transition: none;
  }
}

@media (max-width: 360px) {
  .dlg-window {
    padding: 12px;
    gap: 10px;
  }
  .dlg-speech {
    padding: 10px 12px;
  }
  .dlg-speech-text {
    font-size: 14px;
  }
  .dlg-choice {
    padding: 9px 11px;
    font-size: 13px;
  }
}
