/* Per-theme color custom properties (--bg, --accent, --panel-glass, etc.) are
   defined in themes.css, keyed by the data-theme attribute core/theme.ts sets on
   <html>. Only theme-independent constants live here. */
:root {
  --radius: 8px;
  --font: "Segoe UI", Roboto, system-ui, sans-serif;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--font);
}

body {
  background-image: var(--bg-image);
  background-size: auto;
  background-repeat: repeat;
  background-attachment: fixed;
}

html[data-bg-image="off"] body {
  background-image: none;
}

button {
  font-family: inherit;
  cursor: pointer;
}

button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

input,
select,
textarea {
  font-family: inherit;
  background: var(--bg-panel-alt);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 4px;
  padding: 6px 8px;
}

textarea {
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
}

.hidden {
  display: none !important;
}

.hint-text {
  color: var(--text-dim);
  font-size: 0.9em;
}

.settings-apply-warning {
  color: var(--danger);
  font-weight: 600;
  font-size: 0.9em;
}

.primary-button {
  background: var(--accent);
  color: #10121a;
  border: none;
  border-radius: var(--radius);
  padding: 10px 18px;
  font-weight: 600;
  font-size: 1em;
}

.primary-button:hover:not(:disabled) {
  filter: brightness(1.1);
}

.secondary-button {
  background: var(--bg-panel-alt);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px 14px;
  text-decoration: none;
}

.secondary-button:hover:not(:disabled) {
  border-color: var(--accent);
}

.danger-button {
  background: var(--danger);
  color: #2a0810;
  border: none;
  border-radius: var(--radius);
  padding: 8px 14px;
  font-weight: 600;
}

#app {
  height: 100vh;
  display: flex;
  flex-direction: column;
}

/* ---------------- Top bar ---------------- */

/* Three-column grid (rather than the old flex row) so #word-timer-group's
   "auto" middle column is truly centered across the WHOLE bar - the two
   flanking 1fr columns always size equally, regardless of how wide the game
   title/round indicator on the left are compared to the mute/volume/theme/
   settings controls on the right. A flex row with only flex:1 on the middle
   item centers it within the leftover space between its neighbors instead,
   which visibly drifts off-center whenever those neighbors aren't the same
   width (they never are here). */
#top-bar {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  width: 100%;
  max-width: 1820px;
  margin: 14px auto 0;
  padding: 10px 20px;
  box-sizing: border-box;
  background: var(--panel-glass);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.18);
}

#top-bar-left {
  display: flex;
  align-items: center;
  gap: 24px;
  min-width: 0;
}

/* Wordmark font - see fonts/Marimpa.{otf,ttf} and ui/logo.ts. Must be loaded
   via the page's own stylesheet (not referenced from inside the standalone
   SVG file) since an externally-referenced SVG resource (mask-image, <img
   src>, ...) renders in an isolated context that can't see the host page's
   @font-face rules - that mismatch is why an earlier CSS-mask-based version
   of this logo silently fell back to a generic font. */
@font-face {
  font-family: "Marimpa";
  src:
    url("/fonts/Marimpa.otf") format("opentype"),
    url("/fonts/Marimpa.ttf") format("truetype");
  font-display: swap;
}

/* Wordmark, built as a real inline <svg> by ui/logo.ts (not a background-image
   or CSS mask) so its <text> is part of the document and can use the
   @font-face above. `fill: currentColor` + `color: var(--accent)` re-themes it
   exactly like the plain-text title it replaced did. */
.logo {
  display: inline-block;
  fill: currentColor;
  color: var(--accent);
}

.logo-text {
  font-family: "Marimpa", "Segoe UI", sans-serif;
  font-size: 70px;
  letter-spacing: 0.07em;
}

.logo--topbar {
  height: 28px;
  width: auto;
  margin-bottom: -7px;
}

.logo--hero {
  width: min(400px, 100%);
  height: auto;
}

.top-bar-item {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

#word-timer-group {
  justify-self: center;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  min-width: 0;
}

#word-display {
  font-size: 1.3em;
  letter-spacing: 2px;
  font-weight: 600;
  white-space: pre;
}

#timer-display {
  font-weight: 600;
  min-width: 60px;
  transition: color 0.15s ease;
}

#timer-display.timer-low {
  color: var(--danger);
  font-weight: 800;
  animation: timer-low-pulse 1s ease-in-out infinite;
}

@keyframes timer-low-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}

#top-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  justify-self: end;
}

#top-controls button {
  background: var(--bg-panel-alt);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 1em;
}

.icon-btn-img {
  display: block;
  height: 18px;
  width: 18px;
  object-fit: contain;
}

#volume-slider {
  width: 90px;
}

/* ---------------- Main 3-column layout ---------------- */

#game-layout {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: 230px 1fr 330px;
  gap: 16px;
  min-height: 0;
  width: 100%;
  max-width: 1820px;
  margin: 0 auto;
  padding: 14px 16px;
  box-sizing: border-box;
}

/* Floating glass panels: on wide viewports the grid above stops growing past its
   max-width, so this padding/gap is what pushes the leftover space to the outer
   edges of the window instead of stranding it between the columns and the canvas. */
#player-list,
#chat-panel {
  background: var(--panel-glass);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.18);
  /* Cap height instead of stretching to the full row (which tracks the tallest
     grid item / viewport height) - on a tall screen that made these columns grow
     far past their content with nothing to show, unrelated to the canvas size.
     Deliberately no explicit align-self: once max-height clamps a stretched grid
     item below the row's height, it's auto-aligned to the row's start (top) per
     the CSS Box Alignment spec - and #chat-panel still gets a definite height this
     way, which its internal `flex: 1` message area needs to fill correctly. */
  max-height: 1000px;
}

#player-list {
  overflow-y: auto;
  padding: 10px;
}

.player-badges {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.spectator-count-footer {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 0.85em;
  text-align: center;
}

.player-badge {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-panel-alt);
  border: 2px solid var(--player-color, var(--border));
  border-radius: 999px;
  padding: 6px 10px;
  font-size: 0.9em;
}

.player-badge.disconnected {
  opacity: 0.5;
}

.player-badge.is-you {
  box-shadow: 0 0 0 2px var(--accent);
}

.player-badge.guessed-correctly {
  background: color-mix(in srgb, var(--success) 20%, var(--bg-panel-alt));
}

.player-badge.is-drawing {
  background:
    linear-gradient(to right, transparent, color-mix(in srgb, var(--player-color, var(--border)) 50%, transparent)),
    var(--bg-panel-alt);
}

.player-color-swatch {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: none;
  padding: 0;
  flex: 0 0 auto;
}

.player-color-swatch--editable {
  cursor: pointer;
}

.player-color-swatch--editable:hover {
  box-shadow: 0 0 0 2px var(--accent);
}

.player-color-swatch--editable:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.player-name-wrap {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 1;
  min-width: 0;
}

.player-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.host-tag {
  color: var(--warning);
}

.spectator-tag,
.connection-tag {
  font-size: 0.8em;
  color: var(--text-dim);
}

.kick-button,
.transfer-host-button {
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-size: 0.85em;
  line-height: 1;
  padding: 2px 4px;
  flex: 0 0 auto;
}

.kick-button {
  margin-left: auto;
}

.kick-button:hover {
  color: var(--danger);
}

.transfer-host-button:hover {
  color: var(--warning);
}

.player-score {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.player-score--hidden {
  color: var(--text-dim);
  font-weight: 400;
}

#main-area {
  overflow-y: auto;
  padding: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  /* Same cap as the side columns (#player-list / #chat-panel) - without it this
     column stretches to the full row height on a tall screen while the canvas
     itself (capped by canvas-wrap's max-width/aspect-ratio) stays a fixed size,
     leaving it adrift in a lot of empty vertical space. */
  max-height: 1000px;
}

/* Auto-margin centering instead of `justify-content: center` - the latter
   clips overflowing content at the TOP when it's taller than the scrollable
   container (e.g. the CCC debug-mode grid showing every card at once), since
   it centers by pushing content equally past both edges regardless of
   scrollability. Auto margins degrade gracefully to top-aligned-and-scrollable
   once content overflows, while still centering short content. */
#main-area > * {
  margin-top: auto;
  margin-bottom: auto;
}

/* ---------------- Chat ---------------- */

#chat-panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

#chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.chat-message {
  font-size: 0.9em;
  line-height: 1.3;
  word-wrap: break-word;
}

.chat-message--system {
  color: var(--text-dim);
  font-style: italic;
}

.chat-message--announcement {
  color: var(--accent);
  font-weight: 700;
  text-align: center;
  margin: 4px 0;
}

.chat-message--guess-correct .chat-text {
  color: var(--success);
}

.chat-message--guess-close .chat-text {
  color: var(--warning);
}

.chat-author {
  font-weight: 600;
}

#chat-form {
  display: flex;
  gap: 6px;
  padding: 10px;
  border-top: 1px solid var(--border);
}

#chat-input {
  flex: 1;
}

#chat-form button {
  background: var(--accent);
  color: #10121a;
  border: none;
  border-radius: 4px;
  padding: 6px 12px;
  font-weight: 600;
}

/* ---------------- Lobby select / join / waiting room ---------------- */

#lobby-select-screen {
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
}

.lobby-creation-disabled-banner {
  max-width: 460px;
  width: 100%;
  box-sizing: border-box;
  background: #fff3b0;
  border: 1px solid #b58f00;
  color: #4a3b00;
  border-radius: var(--radius);
  padding: 12px 16px;
  font-weight: 600;
  text-align: center;
}

.lobby-select-wrap,
.join-form-wrap {
  max-width: 460px;
  width: 100%;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
}

.join-in-progress-banner {
  border: 1px solid var(--warning);
  border-radius: var(--radius);
  padding: 10px 12px;
  margin: 12px 0;
}

.join-spectate-anon-button {
  width: 100%;
  margin-bottom: 16px;
}

.waiting-room {
  max-width: 960px;
  width: 100%;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
}

.lobby-top-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.lobby-top-left {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1 1 auto;
  min-width: 0;
}

.lobby-top-left p {
  margin: 0;
}

.lobby-start-btn {
  flex-shrink: 0;
  font-size: 1.15em;
  padding: 14px 30px;
}

.lobby-heading-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.lobby-heading-row h2 {
  margin: 0;
}

.lobby-code-label {
  color: var(--text-dim);
  font-size: 0.9em;
}

.lobby-code-display {
  font-family: monospace;
  font-size: 1.1em;
  letter-spacing: 0.12em;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 3px 10px;
  cursor: pointer;
  user-select: none;
  transition: filter 0.15s;
}

.lobby-code-display.blurred {
  filter: blur(6px);
}

.lobby-copy-btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 3px 10px;
  font-size: 0.85em;
  line-height: 1.4;
  white-space: nowrap;
  color: var(--text);
}

.lobby-copy-btn:hover {
  border-color: var(--accent);
}

.lobby-select-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
}

.lobby-select-wrap .join-form {
  width: 100%;
  align-items: center;
}

.lobby-code-input {
  text-align: center;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.join-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.field-label {
  font-size: 0.85em;
  color: var(--text-dim);
  margin-top: 8px;
}

.join-form input[type="text"] {
  width: 100%;
}

.color-grid {
  display: grid;
  grid-template-columns: repeat(6, 34px);
  justify-content: center;
  gap: 10px;
}

.color-grid-swatch {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  border: 2px solid transparent;
  padding: 0;
}

.color-swatch-button {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 2px solid transparent;
  padding: 0;
}

.color-grid-swatch.selected {
  border-color: var(--accent);
  transform: scale(1.12);
}

/* Shared "already taken / blocked" treatment for both the lobby color grid and
   the in-canvas color toolbar - a strikethrough reads as "blocked" at a glance,
   whereas plain dimming (the old .taken rule) looked like just a darker shade
   of the same color. Both swatch types already set the native disabled
   attribute, so this hooks :disabled directly instead of a manually-toggled
   class, and covers both places for free. */
.color-grid-swatch:disabled,
.color-swatch-button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  position: relative;
}

.color-grid-swatch:disabled::after,
.color-swatch-button:disabled::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(
    to top right,
    transparent calc(50% - 1.5px),
    var(--danger) calc(50% - 1.5px),
    var(--danger) calc(50% + 1.5px),
    transparent calc(50% + 1.5px)
  );
}

/* Lobby-only: taken colors get a stronger "blocked" treatment than the canvas
   toolbar's (a player picks their color once and stares at this grid, so it's
   worth being unambiguous) - a grayish overlay tint on the swatch itself, a
   thicker and more vivid stripe, and an inset ring so the block reads even at a
   glance without needing to notice the stripe. Deliberately NOT using `filter`
   or the shared base rule's `opacity` for the gray tint - both apply to the
   WHOLE element (box-shadow and ::after included), which was washing out the
   red ring/stripe right along with the swatch color, making the "blocked"
   signal barely visible. Overriding opacity back to 1 and tinting via a
   separate ::before layer keeps the red elements at full, undimmed strength. */
.color-grid-swatch:disabled {
  opacity: 1;
  box-shadow: inset 0 0 0 3px #ff2d3a;
}

.color-grid-swatch:disabled::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: rgba(35, 35, 35, 0.65);
}

.color-grid-swatch:disabled::after {
  background: linear-gradient(
    to top right,
    transparent calc(50% - 3px),
    #ff2d3a calc(50% - 3px),
    #ff2d3a calc(50% + 3px),
    transparent calc(50% + 3px)
  );
}

.form-error {
  color: var(--danger);
  font-size: 0.9em;
}

.reclaim-row {
  margin: 4px 0;
}

.lobby-settings-grid {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 16px 0;
  width: 100%;
  text-align: left;
}

.lobby-settings-columns {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}

.lobby-settings-column {
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex: 1 1 0;
  min-width: 0;
}

.lobby-settings-box {
  flex: 1 1 0;
  min-width: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 14px 14px;
}

/* Inside a column, a box should size to its own content (stacked vertically),
   not stretch to share the column's height evenly the way `flex: 1 1 0`
   does for boxes sitting side by side in a row. */
.lobby-settings-column > .lobby-settings-box {
  flex: 0 0 auto;
}

.lobby-settings-box legend {
  font-size: 0.85em;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0 4px;
}

.field-note {
  margin: 6px 0 0;
  font-size: 0.8em;
  color: var(--text-dim);
  font-style: italic;
}

.lobby-presets-row {
  display: flex;
  gap: 10px;
  margin-top: 4px;
}

.lobby-presets-row input[type="text"],
.lobby-presets-row select {
  flex: 1 1 0;
  min-width: 0;
}

/* ---------------- Announcements / word selection ---------------- */

.announcement-wrap,
.word-selection-waiting {
  text-align: center;
  max-width: 600px;
}

.word-selection-wrap {
  text-align: center;
  /* Wide enough that 3 word-option boxes stay on one row even when a word or
     two run long - a tight max-width here was forcing the third box onto its
     own row well before #main-area itself ran out of room. */
  max-width: 960px;
}

.word-selection-wrap h2 {
  font-size: 1.9em;
  margin: 0 0 6px;
}

.turn-result-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin: 16px 0;
}

.turn-result-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: var(--bg-panel-alt);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 16px;
  min-width: 110px;
  animation: pop-in 0.3s ease-out;
}

.turn-result-name {
  font-weight: 700;
}

.turn-result-tag {
  font-size: 0.75em;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.turn-result-points {
  font-size: 1.1em;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.word-selection-scoring-info {
  font-size: 1.05em;
  line-height: 1.5;
  margin: 10px 0 26px;
}

.word-options-row {
  display: flex;
  gap: 14px;
  justify-content: center;
  margin: 0 0 30px;
  flex-wrap: wrap;
}

.word-option {
  background: var(--bg-panel);
  color: var(--text);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  padding: 24px 18px;
  min-width: 175px;
  /* Capped so a long word/phrase wraps onto further lines WITHIN the box
     instead of growing the box - three uncapped boxes only needed one
     moderately long word to blow past the row's available width and get
     pushed onto its own line, which is the "two rows" bug this is fixing.
     Sized to still fit 3-across at #main-area's narrowest common width
     (~616px at a 1280px-wide window) even with the longest real word-list
     entries (e.g. "Social media influencer"). */
  max-width: 190px;
  transition: transform 0.15s ease, border-color 0.15s ease;
}

.word-option:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}

.word-option--easy {
  border-color: var(--success);
}

.word-option--moderate {
  border-color: var(--warning);
}

.word-option--difficult {
  border-color: var(--danger);
}

.word-option-difficulty {
  font-size: 0.9em;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 10px;
}

.word-option-word {
  font-size: 1.55em;
  font-weight: 700;
  color: var(--text);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  overflow-wrap: break-word;
  word-break: break-word;
}

.word-option-multiplier {
  font-size: 0.9em;
  color: var(--text-dim);
  margin-top: 12px;
}

.word-selection-redraw-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin: 0 0 30px;
}

.word-selection-redraw-block .secondary-button {
  font-size: 1.05em;
  padding: 10px 18px;
}

.word-selection-redraw-status {
  font-size: 0.95em;
  margin: 0;
}

.word-selection-active-cccs {
  padding-top: 22px;
  border-top: 1px solid var(--border);
}

.word-selection-ccc-label {
  color: var(--danger);
  font-weight: 600;
  font-size: 1.1em;
  text-shadow: 0 0 8px rgba(255, 45, 58, 0.35);
  margin: 0 0 12px;
}

.word-selection-ccc-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
}

.word-selection-ccc-list li {
  color: var(--danger);
  font-weight: 500;
  font-size: 1.05em;
  text-shadow: 0 0 6px rgba(255, 45, 58, 0.3);
}

/* ---------------- Canvas ---------------- */

.canvas-view {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: 100%;
}

.canvas-wrap {
  position: relative;
  width: 100%;
  max-width: 1100px;
  aspect-ratio: 1100 / 750;
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
  overflow: hidden;
}

.ccc-blindness-overlay {
  position: absolute;
  inset: 0;
  background: #000;
  opacity: 0;
  pointer-events: none;
  border-radius: 4px;
}

.drawing-canvas {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 4px;
}

.canvas-toolbar {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px;
  width: 100%;
  max-width: 1100px;
}

.toolbar-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.tool-button {
  background: var(--bg-panel-alt);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 6px 10px;
}

.tool-button.active {
  border-color: var(--accent);
  background: var(--accent-dim);
}

.toolbar-label {
  color: var(--text-dim);
  font-size: 0.85em;
  margin-right: 4px;
}

.brush-size-button {
  background: var(--bg-panel-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.brush-size-button.active {
  border-color: var(--accent);
}

.brush-size-dot {
  background: var(--text);
  border-radius: 50%;
  display: inline-block;
}

.color-row {
  gap: 4px;
}

.color-swatch-button {
  border: 2px solid var(--border);
}

.color-swatch-button.active {
  border-color: var(--accent);
  transform: scale(1.15);
}

/* ---------------- Victory ---------------- */

.victory-wrap {
  max-width: 600px;
  width: 100%;
  text-align: center;
}

.achievement-list,
.reveal-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 12px 0 20px;
}

.achievement-card {
  background: var(--bg-panel);
  border: 1px solid var(--warning);
  border-radius: var(--radius);
  padding: 12px;
  animation: pop-in 0.3s ease-out;
}

.achievement-title {
  font-weight: 700;
  color: var(--warning);
}

.achievement-desc {
  font-size: 0.85em;
  color: var(--text-dim);
}

.reveal-row {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 16px;
  animation: pop-in 0.3s ease-out;
  transition: background-color 0.4s, border-color 0.4s, opacity 0.4s;
}

/* All rank slots render immediately when the reveal begins; each one just
   looks "not yet revealed" until its own victory:reveal arrives and fills it
   in place - the transition above is what makes that fill-in read as a
   moment rather than an abrupt content swap. */
.reveal-row--pending {
  opacity: 0.55;
  border-style: dashed;
}

.reveal-row--pending .reveal-name,
.reveal-row--pending .reveal-score {
  color: var(--text-dim);
}

.reveal-row.reveal-winner {
  border-color: var(--warning);
  box-shadow: 0 0 12px rgba(217, 164, 65, 0.4);
}

.reveal-rank {
  font-weight: 700;
  min-width: 32px;
}

.reveal-name {
  flex: 1;
  text-align: left;
  font-weight: 600;
}

.reveal-score {
  font-variant-numeric: tabular-nums;
}

.victory-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
}

.vote-row {
  display: flex;
  gap: 12px;
  justify-content: center;
}

.vote-button {
  background: rgba(76, 217, 100, 0.18);
  border: 1px solid rgba(76, 217, 100, 0.4);
  color: var(--text);
  border-radius: var(--radius);
  padding: 8px 16px;
  font-weight: 600;
  transition: background-color 0.2s, border-color 0.2s, transform 0.15s;
}

.vote-button:hover {
  background: rgba(76, 217, 100, 0.3);
}

.vote-button--voted {
  background: rgba(76, 217, 100, 0.75);
  border-color: rgba(76, 217, 100, 0.9);
  color: #0a1a0d;
  transform: scale(1.04);
}

@keyframes pop-in {
  from {
    opacity: 0;
    transform: translateY(6px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* ---------------- Settings modal ---------------- */

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}

#settings-modal {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  width: min(640px, 92vw);
  max-height: 88vh;
  overflow-y: auto;
  padding: 20px;
}

.settings-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.close-button {
  background: transparent;
  border: none;
  color: var(--text);
  font-size: 1.2em;
}

.settings-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.settings-section {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 14px;
}

.settings-section legend {
  color: var(--accent);
  font-weight: 600;
  padding: 0 6px;
}

.settings-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 4px 0;
  font-size: 0.9em;
}

.settings-field input {
  width: 100px;
}

.achievement-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 0;
  font-size: 0.9em;
}

.achievement-field input[type="number"] {
  width: 80px;
}

.settings-collapsible {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 14px;
}

.settings-collapsible > summary {
  color: var(--accent);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.settings-collapsible > summary::-webkit-details-marker {
  display: none;
}

.settings-collapsible > summary::before {
  content: "▶";
  display: inline-block;
  width: 1em;
  font-size: 0.75em;
  transition: transform 0.15s ease;
}

.settings-collapsible[open] > summary::before {
  transform: rotate(90deg);
}

.settings-collapsible-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 8px;
}

.settings-host-controls {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.settings-presets-heading {
  margin: 4px 0 0;
  font-size: 0.85em;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.preset-row {
  display: flex;
  gap: 8px;
}

.preset-row input,
.preset-row select {
  flex: 1;
}

.danger-row {
  display: flex;
  gap: 10px;
  margin-top: 6px;
}

/* ---------------- How to Play ---------------- */

#how-to-play-modal {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  width: min(640px, 92vw);
  max-height: 88vh;
  overflow-y: auto;
  padding: 20px;
}

.how-to-play-body {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* ---------------- Change Your Color ---------------- */

#color-picker-modal {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  width: min(420px, 92vw);
  max-height: 88vh;
  overflow-y: auto;
  padding: 20px;
}

#color-picker-modal .color-grid {
  margin-top: 4px;
}

.how-to-play-section h3 {
  color: var(--accent);
  margin: 0 0 6px;
}

.how-to-play-section p {
  margin: 0 0 8px;
  line-height: 1.4;
}

.how-to-play-achievement-list {
  margin: 0;
  padding-left: 20px;
  line-height: 1.5;
}

/* "About This Game" is a top-level heading alongside "How to Play" itself
   (which is the modal's own title), so it gets a rule above it to separate it
   from the gameplay sections rather than reading as another subsection. */
.how-to-play-section--top {
  border-top: 1px solid var(--border);
  padding-top: 16px;
}

.how-to-play-section--top h2 {
  color: var(--accent);
  margin: 0 0 6px;
  font-size: 1.25em;
}

.how-to-play-section--top p {
  margin: 0 0 8px;
  line-height: 1.4;
}

.how-to-play-ping {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 8px;
}

.how-to-play-ping-result {
  font-weight: 600;
  color: var(--accent);
}

.how-to-play-ping-result--error {
  color: var(--danger);
  font-weight: 400;
}

.how-to-play-inline-link,
.how-to-play-inline-link:visited {
  color: var(--text);
  text-decoration: underline;
}

.lobby-select-heading {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.lobby-select-heading h1 {
  margin: 10px 0 10px 0;
  /* Gives the h1 a definite width to resolve against - without this, it's a
     flex item sized by fit-content (align-items: center overrides the default
     stretch), and the logo svg's own `width: min(400px, 100%)` can't resolve
     its 100% against a shrink-to-fit ancestor, so the browser falls back to
     some other (much smaller) width instead of the intended 400px cap. */
  width: 100%;
  text-align: center;
}

.lobby-select-tagline {
  margin: 10px 0px 25px 0px;
  color: var(--text-dim);
}

/* ---------------- Theme picker ---------------- */

#theme-modal {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  width: min(520px, 92vw);
  max-height: 88vh;
  overflow-y: auto;
  padding: 20px;
}

.theme-color-hint {
  font-style: italic;
  color: var(--text-dim);
  font-size: 0.9em;
  text-align: center;
  margin: 0 0 16px;
}

.theme-section h3 {
  color: var(--text-dim);
  font-size: 0.85em;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 16px 0 8px;
}

.theme-section:first-of-type h3 {
  margin-top: 0;
}

.theme-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 10px;
}

.theme-swatch {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  border: 2px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 8px;
}

.theme-swatch.active {
  box-shadow: 0 0 0 2px var(--accent);
}

.theme-swatch-dot {
  width: 22px;
  height: 22px;
  border-radius: 50%;
}

.theme-swatch-label {
  font-size: 0.8em;
  font-weight: 600;
}

.theme-bg-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  font-size: 0.9em;
}

/* ---------------- Session-replaced banner ---------------- */

.session-banner {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 10px 20px;
  background: var(--danger);
  color: #2a0810;
  font-weight: 600;
  text-align: center;
}

.session-banner .primary-button {
  flex: 0 0 auto;
}

/* ---------------- Chaos Canvas Cards ---------------- */

.ccc-wrap {
  text-align: center;
  max-width: 900px;
  width: 100%;
}

/* Light gray + a doubled black glow reads fine over a dark theme's background
   (image included) - var(--text-dim) alone wasn't legible against it - but the
   same combination disappears on a light theme, so both colors come from
   theme-provided custom properties (see themes.css) instead of being fixed
   like .ccc-card's colors below, which are deliberately theme-independent. */
.ccc-current-inventory {
  margin-bottom: 12px;
  color: var(--ccc-kicker-color);
  text-shadow:
    0 0 15px var(--ccc-kicker-shadow-color),
    0 0 15px var(--ccc-kicker-shadow-color);
}

.ccc-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 28px;
  margin: 20px 0;
}

/* Fixed width, matching .ccc-option-kicker's own max-width below - without
   this, an option with no fixed width shrink-wraps to whichever child is
   wider (a short kicker vs. the 220px card, or a long kicker up to its own
   250px max-width), so options end up different widths depending purely on
   their own kicker's text length. Since .ccc-grid's `gap` sits between these
   option boxes rather than between the cards themselves, that per-option
   width variance visibly threw off the spacing *between cards* - a card next
   to a wide-kicker option reads noticeably further away than one next to a
   narrow-kicker option, even though every gap is nominally the same 28px. A
   uniform width means every option is identical regardless of its own
   kicker's content, so the cards end up evenly spaced no matter what. */
.ccc-option {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  width: 250px;
}

/* A true FIXED height (not just a min-height floor) for exactly 3 wrapped
   lines, bottom-aligned, so a short kicker ("Pick up Monochrome I") and a long
   one ("Replace Crossing the Line with Claustrophobia II") both leave their
   card starting at the same Y position - a min-height alone only guarantees
   *short* kickers get padded up to match, but a kicker whose text genuinely
   wraps past that floor (e.g. a family-vs-family "Replace X with Y" combining
   two long card names) still grows taller than its neighbors and pushes just
   that one card down, drifting it out of alignment with the rest of the row.
   overflow: hidden is a safety net for the rare combination even 3 lines
   can't fit, clipping rather than misaligning. */
.ccc-option-kicker {
  font-size: 0.8em;
  line-height: 1.3;
  color: var(--ccc-kicker-color);
  text-shadow:
    0 0 15px var(--ccc-kicker-shadow-color),
    0 0 15px var(--ccc-kicker-shadow-color);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  /* 220px of actual text width, same as before - the extra 30px (matching the
     15px horizontal padding on each side below) is purely so the glow has
     room to render before overflow: hidden clips it; without that padding the
     15px blur was getting cut off flush against the text's own edges. */
  max-width: 250px;
  height: calc(1.3em * 3);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  text-align: center;
  padding: 0 15px 12px;
}

/* The leading "Replace"/"Upgrade"/"Pick up" of a kicker - same treatment as
   the rest of the kicker text, but bold with a red glow instead of the
   surrounding text's neutral one, so the action itself stands out from the
   card names around it. */
.ccc-option-kicker-action {
  font-weight: 700;
  text-shadow:
    0 0 15px var(--ccc-kicker-action-shadow-color),
    0 0 15px var(--ccc-kicker-action-shadow-color);
}

/* Deliberately fixed (theme-independent) dark-red colors - these cards are meant
   to look the same menacing way regardless of the site's current light/dark theme. */
.ccc-card {
  width: 220px;
  min-height: 300px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 16px;
  border-radius: 14px;
  border: 2px solid #7a1020;
  background: linear-gradient(160deg, #2a0509 0%, #4a0a12 60%, #2a0509 100%);
  color: #f5dede;
  cursor: pointer;
  text-align: left;
  box-shadow: 0 0 14px 2px rgba(200, 20, 40, 0.55), inset 0 0 20px rgba(200, 20, 40, 0.15);
  animation: ccc-glow 2.4s ease-in-out infinite;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.ccc-card:hover:not(:disabled):not(.ccc-card--selected) {
  transform: translateY(-3px);
}

.ccc-card--selected {
  transform: scale(1.06);
  border-color: #ff5a6e;
  box-shadow: 0 0 26px 6px rgba(255, 60, 80, 0.85), inset 0 0 24px rgba(255, 60, 80, 0.25);
}

.ccc-card--unavailable {
  cursor: not-allowed;
  opacity: 0.35;
  animation: none;
  box-shadow: none;
}

.ccc-card-name {
  font-weight: 700;
  font-size: 1.05em;
  color: #ff8a95;
  text-shadow: 0 0 8px rgba(255, 40, 60, 0.6);
}

.ccc-card-desc {
  font-size: 0.85em;
  line-height: 1.35;
  color: #f0d8da;
  flex: 1;
}

.ccc-card-bonus {
  font-weight: 700;
  font-size: 0.9em;
  color: #ffd166;
  text-align: right;
}

.ccc-card-placeholder {
  margin: auto;
  font-size: 0.85em;
  color: #c9a3a8;
  text-align: center;
}

@keyframes ccc-glow {
  0%,
  100% {
    box-shadow: 0 0 14px 2px rgba(200, 20, 40, 0.55), inset 0 0 20px rgba(200, 20, 40, 0.15);
  }
  50% {
    box-shadow: 0 0 26px 8px rgba(230, 30, 50, 0.85), inset 0 0 26px rgba(230, 30, 50, 0.25);
  }
}

.ccc-confirm-button {
  margin: 8px auto 16px;
  display: block;
  font-size: 1.1em;
  padding: 14px 32px;
}

.ccc-actions-row {
  display: flex;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
}

.ccc-active-status {
  font-size: 0.85em;
  color: var(--danger);
  font-weight: 600;
  margin-bottom: 6px;
  text-align: center;
}

/* Hoverable CCC name - reveals a small card-styled tooltip (name/level/effect/
   bonus) so a card mentioned in passing (the canvas "Active: ..." line, the
   word-selection screen's active-card list) doesn't need its full description
   spelled out inline every time. `position: fixed` (viewport-relative, not
   anchored to `.ccc-name-hover`) because cccTooltip.ts computes `top`/`left`
   itself on each show - flipping above/below and clamping horizontally based
   on actual space available, rather than a fixed CSS offset that could get
   clipped by (or grow the scrollHeight of) a scrolling ancestor like
   #main-area. show/hide is also JS-driven (not a :hover/:focus rule) so the
   position can be recomputed at the moment it's needed. */
.ccc-name-hover {
  position: relative;
  cursor: help;
  border-bottom: 1px dotted currentColor;
}

.ccc-tooltip {
  display: none;
  position: fixed;
  z-index: 60;
  width: 220px;
  padding: 12px 14px;
  border-radius: 12px;
  border: 2px solid #7a1020;
  background: linear-gradient(160deg, #2a0509 0%, #4a0a12 60%, #2a0509 100%);
  color: #f5dede;
  text-align: left;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5), 0 0 14px 2px rgba(200, 20, 40, 0.55);
  cursor: default;
  pointer-events: none;
}

.ccc-tooltip-name {
  font-weight: 700;
  font-size: 1.05em;
  color: #ff8a95;
  text-shadow: 0 0 8px rgba(255, 40, 60, 0.6);
  margin-bottom: 2px;
}

.ccc-tooltip-level {
  font-size: 0.75em;
  color: #c9a3a8;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 6px;
}

.ccc-tooltip-desc {
  font-size: 0.85em;
  line-height: 1.35;
  color: #f0d8da;
  margin-bottom: 8px;
}

.ccc-tooltip-bonus {
  font-weight: 700;
  font-size: 0.85em;
  color: #ffd166;
}

/* ---------------- Toasts ---------------- */

#toast-container {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 200;
}

.toast {
  background: var(--bg-panel-alt);
  border: 1px solid var(--accent);
  color: var(--text);
  padding: 10px 18px;
  border-radius: var(--radius);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.toast-success {
  border-color: var(--success);
}

.toast-error {
  border-color: var(--danger);
}

.toast-visible {
  opacity: 1;
}
