/* Guess the Character — daily Stat Compare mode. Self-contained styles that
   reuse the site's existing color/type variables from styles.css.

   2026-08-28 redesign pass — token notes (reused, not invented):
   - Color: var(--teal)/--amber/--red/--line/--surface-2/--surface-3 from
     styles.css, same family the rest of the site already uses for
     match/partial/miss and role-adjacent signals.
   - The match/partial/miss system AND the 5-tier series-closeness system
     now share one visual component (.gc-chip) instead of two different
     "color the whole cell" treatments — a chip carries an icon (check /
     approx / x) plus a tier color, so "how close" reads from shape+icon
     first and color second (not color-only).
   - Row-height fix: every graded cell's text is clamped to 2 lines with
     ellipsis + a native title tooltip for the full value, and cells get a
     shared min-height. Verified against the roster's real worst cases
     (Rimuru Tempest / "That Time I Got Reincarnated as a Slime" at 39
     characters, Zenitsu Agatsuma's 3-part fighter-type combo) — uniform
     row height beat widening columns because the narrow/mobile width still
     needs a hard cap regardless of column width.

   2026-08-28 second pass — horizontal-scroll fix + two comparable layouts:
   - Playtest flagged the table required horizontal scrolling to see a
     guess's full row, and that Fighter Type text sometimes wrapped to two
     lines.
   - Two real, toggleable layouts now ship side by side so the user can
     compare live: "Table" (this same comparison table) and "Cards" (a
     card-per-guess layout with a wrapping row of small icon badges,
     modeled on playfootball.games' "Guess the Footballer" reference the
     user pointed at). See .gc-view-toggle / .gc-cards below.
   - Series closeness now renders via HSL hue interpolation (0% -> hue 0
     red, 100% -> hue 120 green) instead of the old fixed 5-bucket
     teal/amber/red color-mix blends, wired through a --hue custom
     property set inline by JS from data/series-closeness.js's continuous
     0-100 closeness() score (that module landed its continuous score in
     this same work session - see guess-character.js hueForSeriesScore()).

   2026-08-29 pass — Table rebuilt as two grouped rows per guess (Identity +
   Stats) with full header words/values everywhere, no truncation. The old
   table-layout:fixed/<colgroup>/single-row approach from the 2026-08-28
   pass above is gone, replaced entirely.

   2026-09-02 — Table removed. Cards is the only layout now, per
   instruction; there is no more toggle. Cards' own name column (a big
   source of the old Table's raison d'être - room for long text) was
   widened at the same time (--gc-grid-cols below) and the roster's
   handful of names that still didn't fit even at that width got a short
   "goes by" override (see guess-character.js's CARD_SHORT_NAMES) instead
   of taking room from the icon-only badge/stat columns. */

.gc-shell {
  width: min(1040px, 100%);
  display: grid;
  gap: 18px;
}

.gc-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: linear-gradient(120deg, color-mix(in srgb, var(--teal) 14%, transparent), var(--surface-2) 60%);
}

.gc-banner-info {
  min-width: 0;
}

.gc-puzzle-label {
  margin: 0;
  color: var(--text);
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1.05rem;
  letter-spacing: 0.02em;
}

.gc-date-label {
  margin: 2px 0 0;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 700;
}

.gc-guess-pill {
  flex: 0 0 auto;
  padding: 6px 12px;
  border: 1px solid var(--teal);
  border-radius: 999px;
  color: #102019;
  background: var(--teal);
  font-weight: 900;
  font-size: 0.8rem;
  white-space: nowrap;
}

.gc-guess-pill.is-over {
  border-color: var(--red);
  background: var(--red);
  color: #24100c;
}

.gc-play-area {
  display: grid;
  gap: 14px;
  /* Grid items default to min-width:auto (their own content's automatic
     minimum size), which can silently force the whole track wider than the
     viewport regardless of any responsive rules further down - found while
     verifying this pass's no-horizontal-overflow requirement: a long
     Fighter Type value (e.g. "Hand-to-hand, Elemental user") inside a grid
     item was blowing this section out past 264px even though every element
     inside it individually had min-width:0. min-width:0 here breaks that
     propagation at the source instead of only patching it deeper in the
     tree. Pre-existing bug, not introduced by this pass - fixed here since
     this pass's job was verifying overflow doesn't happen. */
  min-width: 0;
}

.gc-objective {
  margin: 0;
  color: var(--muted);
  font-size: 0.88rem;
  line-height: 1.45;
}

.gc-search-row {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.gc-combobox {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
}

.gc-suggestions {
  position: absolute;
  z-index: 5;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 320px;
  margin: 0;
  padding: 4px;
  list-style: none;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #101714;
  box-shadow: 0 14px 32px rgba(0, 0, 0, 0.4);
  overflow-y: auto;
}

.gc-suggestions[hidden] {
  display: none;
}

/* Stacked name-over-series, each line truncating on its own — a flex row
   with space-between used to squeeze the name down to near-zero width
   whenever the series name was long (e.g. "That Time I Got Reincarnated as
   a Slime"), and overflow-wrap:anywhere would then wrap it one letter per
   line. Full width per line + ellipsis avoids that entirely. */
.gc-suggestion {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 10px;
  border-radius: 5px;
  cursor: pointer;
  font-size: 0.88rem;
}

.gc-suggestion strong {
  display: block;
  overflow: hidden;
  color: var(--text);
  font-weight: 800;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.gc-suggestion span {
  display: block;
  overflow: hidden;
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 700;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.gc-suggestion:hover,
.gc-suggestion.is-active {
  background: rgba(60, 195, 160, 0.16);
}

.gc-suggestion-empty {
  padding: 10px;
  color: var(--muted);
  font-size: 0.84rem;
}

.gc-search-status {
  min-height: 16px;
  margin: -2px 0 0;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 700;
}

/* Legend — one bordered panel instead of two loose rows of colored
   squares. The chip previews are the literal .gc-chip component used in
   the cards below, so the key is never out of sync with what it explains
   and the page isn't teaching a second, separate color language. */
.gc-legend-panel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 18px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface-2);
}

.gc-legend-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}

.gc-legend-title {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 0.66rem;
  font-weight: 900;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.gc-legend-divider {
  flex: 0 0 auto;
  width: 1px;
  height: 18px;
  background: var(--line);
  opacity: 0.6;
}

.gc-legend-stats {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
}

.gc-legend-stat-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 700;
}

/* Icon system - every comparison glyph on this page (.gc-chip-icon,
   .gc-arrow-icon) renders an inline SVG (see iconSvg()/ICON_PATHS in
   guess-character.js, sourced from Lucide) sized to exactly fill its
   holder via this one rule, so check/approx/x and the up/down chevrons all
   share one stroke weight and proportion no matter which class wraps them. */
.gc-chip-icon svg,
.gc-arrow-icon svg,
.gc-icon-svg {
  display: block;
  width: 1em;
  height: 1em;
}

.gc-arrow-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  font-size: 0.7rem;
  line-height: 1;
}

.gc-arrow-icon.is-up {
  color: var(--amber);
}

.gc-arrow-icon.is-down {
  color: var(--blue);
}

.gc-arrow-icon.is-exact {
  color: var(--teal);
}

/* Table layout removed - Cards is the page's only comparison layout now
   (was previously toggleable; see .gc-cards further down). */

.gc-cell {
  min-height: 58px;
  color: var(--text);
  font-weight: 700;
  font-size: 0.76rem;
  line-height: 1.25;
}

/* Graded chip — the single shared component behind both grading systems
   (3-state match/partial/miss, and the 5-step series-closeness gradient).
   Icon carries the coarse "close or not" signal, tier color carries the
   fine-grained one, so this never relies on color alone. Text clamps to 2
   lines with ellipsis and a title tooltip holds the untruncated value -
   this, plus the shared min-height above, is what keeps every guess row a
   uniform height even for the roster's longest series names/tag combos. */
.gc-chip {
  display: inline-flex;
  max-width: 100%;
  align-items: flex-start;
  gap: 5px;
  padding: 4px 9px;
  border: 1px solid transparent;
  border-radius: 10px;
  font-size: 0.72rem;
  font-weight: 800;
  line-height: 1.25;
  text-align: left;
}

.gc-chip-icon {
  flex: 0 0 auto;
  margin-top: 0.1em;
  font-size: 0.68rem;
  line-height: 1;
}

/* Only used by the static legend key above the play area now (its example
   chips show real text - "Match"/"Partial"/"Exact"/etc.) - the actual guess
   list is Cards, which renders its chips icon-only with no .gc-chip-text at
   all (see .gc-chip-icon-only below). */
.gc-chip-text {
  min-width: 0;
  /* Every real value here (series/fighter-type/coverage lists) has spaces
     to break on, so wrap on word boundaries first and only fall back to
     mid-word breaking if a single word genuinely can't fit - avoids
     confusing letter-salad breaks in a narrow chip. */
  overflow-wrap: break-word;
  word-break: normal;
}

.gc-chip.is-match {
  border-color: color-mix(in srgb, var(--teal) 55%, transparent);
  background: color-mix(in srgb, var(--teal) 20%, transparent);
  color: var(--teal);
}

.gc-chip.is-partial {
  border-color: color-mix(in srgb, var(--amber) 55%, transparent);
  background: color-mix(in srgb, var(--amber) 20%, transparent);
  color: var(--amber);
}

.gc-chip.is-miss {
  border-color: color-mix(in srgb, var(--red) 55%, transparent);
  background: color-mix(in srgb, var(--red) 20%, transparent);
  color: var(--red);
}

/* Series closeness — continuous HSL hue interpolation instead of 5 fixed
   color-mix blends. --hue is set inline per chip by JS (seriesHue() in
   guess-character.js): 0 = red (cold/unrelated), 120 = green (exact same
   series), everything between sweeps smoothly through orange/yellow, so a
   "warm" pair and a "lukewarm" pair read as visibly different shades
   instead of jumping between 5 flat buckets. Saturation/lightness are
   fixed so only hue carries the signal. */
.gc-chip.is-series-hue {
  border-color: hsl(var(--hue, 0) 60% 42% / 0.65);
  background: hsl(var(--hue, 0) 65% 38% / 0.24);
  color: hsl(var(--hue, 0) 78% 72%);
}

.gc-stat-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  white-space: nowrap;
}

.gc-stat-value {
  color: var(--text);
  font-weight: 800;
  white-space: nowrap;
}

.gc-cell.is-won .gc-stat-value {
  padding: 2px 7px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--teal) 22%, transparent);
  color: var(--teal);
}

/* ---------------------------------------------------------------------
   Card layout — 2026-08-28 third pass. Card vs Table playtest picked Cards
   as the layout to keep investing in; this pass fixes the three things
   flagged against it:

   1. Icon consistency — handled above via the shared .gc-chip-icon /
      .gc-arrow-icon SVG sizing rule.

   2. "A lot of open space on the right side" — the old badge row was a
      flex-wrap of fixed 56px circles, which almost never divides evenly
      into a card's real width, leaving a dead gap after the last badge
      each row. Fixed by making the call the other direction ("expand to
      fill" vs "shrink the card") explicit: each card is now a CSS Grid
      with fr-unit columns (--gc-grid-cols, defined once on .gc-cards and
      inherited by both the header and every card row), which by
      construction always occupies exactly 100% of the card's width — an
      fr column can't leave unclaimed space the way a wrapped row of
      fixed-width circles can. Shrinking the card instead was the other
      option on the table; expand-to-fill won because it also directly
      enables requirement 3 below (real column alignment needs real
      columns, not a wrapping flex row).

   3. Per-card abbreviated labels (SER/TYP/AGE/COV/POW/SPD/DUR/IQ/TMW/HAX)
      replaced by ONE shared header (#gcCardsHeader in the HTML) spelling
      out full words once, with every card's grid cells landing in the
      same columns beneath it - "this cell is Fighter Type" now comes from
      position, matching the header above, not repeated text.

   Below 640px - corrected 2026-08-29, see the max-width:639px block
   further down: Cards doesn't reflow into a stacked block layout. Since
   that correction also made the four categorical badges symbol-only (no
   repeated text, see .gc-chip-icon-only), the header/badge columns stay
   real, aligned grid columns all the way down to the narrowest tested
   width instead of needing an escape hatch.

   2026-09-02 - name column widened from 15fr to 34fr (badge/stat columns
   trimmed accordingly) once Table was removed and this became the only
   layout; see the file-header comment for why. */
.gc-cards {
  --gc-grid-cols: 34fr 8fr 8fr 6fr 8fr 6fr 6fr 6fr 6fr 6fr 6fr;
  display: grid;
  gap: 10px;
  /* Same grid-item min-width fix as .gc-play-area above - this is also a
     grid item of .gc-play-area. */
  min-width: 0;
}

.gc-cards[hidden] {
  display: none;
}

.gc-cards-header {
  display: grid;
  grid-template-columns: var(--gc-grid-cols);
  align-items: center;
  gap: 8px 10px;
  padding: 9px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-2);
}

/* white-space: normal (not nowrap+ellipsis) so a two-word label ("Fighter
   Type", "Age Stage") wraps onto its natural word break instead of getting
   cut off - widening the name column (see .gc-cards below) left these
   columns real but modest width, and at that width nowrap+ellipsis was
   truncating words like "Durability"/"Teamwork" that a reader familiar
   with the game needs spelled out, not "DURABI…"/"TEAMW…". */
.gc-cards-header-cell {
  color: var(--muted);
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.03em;
  line-height: 1.15;
  text-align: center;
  text-transform: uppercase;
  white-space: normal;
}

.gc-cards-header-cell.gc-cards-header-name {
  text-align: left;
}

.gc-cards-empty {
  margin: 0;
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  color: var(--muted);
  font-weight: 700;
  text-align: center;
}

.gc-cards-list {
  display: grid;
  gap: 10px;
}

.gc-guess-card {
  display: grid;
  grid-template-columns: var(--gc-grid-cols);
  align-items: center;
  gap: 8px 10px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.22);
}

.gc-grid-cell {
  min-width: 0;
}

.gc-guess-card-name-cell {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.gc-guess-card-name-cell .portrait {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  font-size: 0.66rem;
}

.gc-guess-card-name-wrap {
  min-width: 0;
}

.gc-guess-card-name {
  margin: 0;
  overflow: hidden;
  color: var(--text);
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 900;
  line-height: 1.15;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Categorical cells (Series/Fighter Type/Age Stage/Coverage) reuse the
   .gc-chip component's color/tier language, rendered SYMBOL-ONLY (icon +
   tier color, no repeated text) - see .gc-chip-icon-only below. */
.gc-guess-card .gc-chip {
  max-width: 100%;
}

/* Cards-only icon chip: the shared #gcCardsHeader row already spells out
   "Series"/"Fighter Type"/"Age Stage"/"Coverage" once, so a per-card badge
   repeating the guessed character's raw value underneath added no new
   information and was the actual source of the wrapping/overflow playtest
   kept re-finding (a short word like "Adult" wrapping to two lines is a
   symptom of unnecessary text in a small grid cell, not a font-sizing bug).
   Fixed to a small, uniform, fixed-size square holding only the check/
   approx/x (or hue-colored) icon - a shape this size can never wrap, and a
   grid of many of them can never overflow the way variable-length text
   could. The untruncated value is still reachable via the native `title`
   tooltip. */
.gc-chip.gc-chip-icon-only {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  gap: 0;
}

.gc-chip.gc-chip-icon-only .gc-chip-icon {
  margin: 0;
  font-size: 0.82rem;
}

/* Shared centering for every badge cell in a card's grid row - both the
   symbol-only categorical badges above and the numeric stat cells below
   sit centered under their shared header label rather than left-aligned
   inside a wide fr column. */
.gc-badge-grid-cell,
.gc-stat-grid-cell {
  display: flex;
  justify-content: center;
}

.gc-stat-grid-cell.is-won .gc-stat-value {
  padding: 2px 7px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--teal) 22%, transparent);
  color: var(--teal);
}

/* Mid-range width - smaller padding/type scale so the 11-column grid stays
   comfortable right above the stacked breakpoint instead of feeling
   squeezed. */
@media (max-width: 900px) {
  .gc-cards-header {
    padding: 7px 10px;
  }

  .gc-cards-header-cell {
    font-size: 0.56rem;
  }

  .gc-guess-card {
    padding: 8px 10px;
  }

  .gc-guess-card-name {
    font-size: 0.92rem;
  }
}

/* Correction, 2026-08-29: below 640px, Cards no longer falls back to a
   stacked data-label layout - the user explicitly does not want that
   (Cards should stay Cards at every real width, mobile included). That
   fallback existed to solve a text-overflow problem (long Fighter
   Type/Series values refusing to wrap in a narrow column) which no longer
   exists now that those four fields render as a single small fixed-size
   icon (see .gc-chip-icon-only above) instead of text - there is nothing
   left that can wrap or blow out a column's width.
   Approach: the 11-column single-row grid (name + 10 badges sharing one
   fr-based column set with the header) still works fine down to ~640px,
   but below that the name column's fr-share becomes too little (guess
   names need real characters, badges only need a small fixed square) if
   both stay on the same row. Rather than fight that with ever-smaller fr
   weights, both the header and every card switch to a TWO-ROW grid here:
   row 1 is the name (or, in the header, the "Guess" label) spanning the
   full width; row 2 is the 10 badge columns, now weighted evenly since
   every one of them holds equivalent-sized content (one icon, or one
   short number + icon) instead of competing with variable-length text.
   Because every badge is the same small fixed size regardless of which
   character was guessed, this 10-equal-column row can shrink safely all
   the way down to the smallest tested width (264px) without overflowing -
   confirmed via document.documentElement.scrollWidth/clientWidth, not
   just visual inspection, using the roster's actual worst-case long values
   (Zenitsu Agatsuma's 3-part Fighter Type combo, Rimuru Tempest's
   39-character series name) precisely to prove those long values no longer
   matter once they're not rendered as text. */
@media (max-width: 639px) {
  .gc-cards-header,
  .gc-guess-card {
    grid-template-columns: repeat(10, minmax(0, 1fr));
    grid-template-rows: auto auto;
    gap: 6px 4px;
  }

  .gc-cards-header {
    padding: 7px 8px;
    /* No longer visually hidden - it stays a real, visible second row of
       short labels above the badges, since the badges themselves are now
       small enough that the header comfortably fits alongside them at
       every tested width instead of needing to be dropped. */
  }

  .gc-cards-header-name,
  .gc-guess-card-name-cell {
    grid-column: 1 / -1;
  }

  .gc-cards-header-name {
    text-align: left;
  }

  .gc-guess-card {
    padding: 8px 8px 10px;
  }

  .gc-guess-card-name-cell {
    padding-bottom: 6px;
    margin-bottom: 2px;
    border-bottom: 1px solid color-mix(in srgb, var(--line) 40%, transparent);
  }

  .gc-guess-card-name-cell .portrait {
    width: 26px;
    height: 26px;
    font-size: 0.56rem;
  }

  .gc-guess-card-name {
    font-size: 0.86rem;
  }

  .gc-cards-header-cell {
    font-size: 0.52rem;
    text-align: center;
    white-space: normal;
    line-height: 1.1;
    /* At this width a single-word label ("Coverage", "Durability",
       "Teamwork") is wider than its ~30px column and has no space to break
       on, so normal wrapping alone still truncates it with an ellipsis
       (from the base rule's overflow:hidden/text-overflow:ellipsis).
       overflow-wrap:anywhere lets it break mid-word onto a 2nd/3rd line
       instead, so the full label is still fully present (just stacked),
       not silently cut off - the column's grid track itself never grows
       for this since text-based grid items floor to 0 automatic minimum
       size once overflow isn't visible (same mechanism .gc-cards-header
       already relied on at 900px). */
    overflow-wrap: anywhere;
  }

  .gc-chip.gc-chip-icon-only {
    width: 22px;
    height: 22px;
  }

  .gc-chip.gc-chip-icon-only .gc-chip-icon {
    font-size: 0.68rem;
  }

  .gc-stat-cell {
    gap: 0;
  }

  .gc-stat-value {
    font-size: 0.7rem;
  }

  .gc-arrow-icon {
    width: 11px;
    height: 11px;
    font-size: 0.56rem;
  }
}

.gc-result-panel {
  display: grid;
  justify-items: center;
  gap: 14px;
  padding: 22px;
  border: 1.5px solid rgba(240, 184, 75, 0.5);
  border-radius: 14px;
  background: #1a2621;
  text-align: center;
}

.gc-result-panel[hidden] {
  display: none;
}

.gc-result-kicker {
  margin: 0;
  color: var(--muted);
  font-size: 0.88rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.gc-result-headline {
  margin: 0;
  color: var(--text);
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(2.4rem, 6vw, 3.4rem);
  line-height: 1;
}

.gc-reveal-card {
  width: min(320px, 100%);
  cursor: default;
}

.gc-reveal-card:hover {
  transform: none;
}

.gc-result-actions {
  display: flex;
  gap: 10px;
}

.gc-share-status {
  min-height: 18px;
  margin: 0;
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 800;
}

.gc-share-preview {
  width: min(360px, 100%);
  margin: 0;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #101714;
  color: var(--text);
  font-size: 0.9rem;
  line-height: 1.4;
  white-space: pre-wrap;
  text-align: left;
}

.gc-footer {
  margin-top: 6px;
}

.gc-dev-panel-body {
  display: grid;
  gap: 10px;
  margin-top: 10px;
}

@media (max-width: 640px) {
  .gc-search-row {
    flex-direction: column;
  }

  .gc-search-row .primary-button {
    width: 100%;
  }
}
