/* Durak — card table UI. No framework, plain modern CSS.

   Karten-Styling (Issue #17) liegt pro Theme in einer eigenen Datei, das
   klassische in /static/theme-classic.css. app.css haelt Layout, Flaechen
   und die Tokens --card-w/--card-ratio, mit denen auch der Tisch misst. */

:root {
  --felt-1: #2e7d52;
  --felt-2: #1b5e3c;
  --felt-3: #123f2a;
  --ink: #f4f6f5;
  --ink-dim: #b9c8c1;
  --panel: rgba(9, 32, 21, 0.78);
  --panel-line: rgba(255, 255, 255, 0.14);
  --gold: #f2c14e;
  --danger: #e0524c;
  --accent: #4fa3e3;
  --card-w: clamp(52px, 7vw, 86px);
  --card-ratio: 1.42;
  --radius: 12px;
  --shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
}

* { box-sizing: border-box; }

/* hidden muss gegen Display-Vorgaben gewinnen koennen (z. B. .btn mit
   display:inline-block verdeckt sonst das Legen-Button-Attribut hidden,
   Issue #38). */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color: var(--ink);
  background:
    radial-gradient(ellipse at 50% 35%, var(--felt-1) 0%, var(--felt-2) 55%, var(--felt-3) 100%);
  background-attachment: fixed;
  display: flex;
  flex-direction: column;
  /* Issue #84: dvh ist die sichtbare Hoehe (die URL-Leiste der Mobilbrowser
     zaehlt nicht mit). Die vh-Zeile steht zuerst und bleibt der Fallback
     fuer Browser ohne dvh, die moderne gewinnt als spaetere Declaration. */
  min-height: 100vh;
  min-height: 100dvh;
}

/* Issue #89: Weisse Streifen unterm Rand beim Scrollen. Auf Geraeten ohne
   praezisen Zeiger faehrt die URL-Leiste ein und aus, die sichtbare Hoehe
   wechselt also mitten im Scrollen. Ein am Viewport festgenagelter Hintergrund
   (background-attachment: fixed) kann da nicht hinterhermalen, und weil seine
   Box an der grossen Viewport-Hoehe haengt, laeuft sie ausserdem vom Inhalt
   weg: unten bleibt ungestrichene - weisse - Flaeche stehen. Darum wandert der
   Hintergrund auf diesen Geraeten mit, die Box folgt dem Inhalt statt dem
   Viewport, und die Flaeche hinter dem Koerper ist dunkel grundiert statt
   weiss. Desktop mit Maus behaelt den festgenagelten Verlauf. */
@media (hover: none), (pointer: coarse) {
  html { background: var(--felt-3); }
  body {
    background-attachment: scroll;
    height: auto;
  }
}

h1, h2, h3 { margin: 0 0 0.5rem; font-weight: 700; letter-spacing: 0.01em; }
a { color: var(--gold); }
main { flex: 1; width: 100%; max-width: 1100px; margin: 0 auto; padding: 1rem; }

/* ---------- generic surfaces ---------- */

.panel {
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: var(--radius);
  padding: 1rem 1.2rem;
  box-shadow: var(--shadow);
  margin-bottom: 1rem;
}

.hint { color: var(--ink-dim); font-size: 0.9rem; }

/* ---------- buttons & forms ---------- */

.btn {
  display: inline-block;
  padding: 0.55rem 1.1rem;
  border-radius: 999px;
  border: 1px solid var(--panel-line);
  background: linear-gradient(180deg, #3f8a63, #2c6d4a);
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--shadow);
  transition: transform 0.08s ease, filter 0.15s ease;
}
.btn:hover { filter: brightness(1.12); }
.btn:active { transform: scale(0.97); }
.btn:disabled, .btn[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  filter: grayscale(0.6);
}

.btn-primary { background: linear-gradient(180deg, #f6d27a, #d9a52f); color: #3a2c05; }
.btn-danger  { background: linear-gradient(180deg, #ef7a75, #c53e38); }
.btn-ghost   { background: transparent; }

label { display: block; margin: 0.45rem 0 0.15rem; color: var(--ink-dim); font-size: 0.88rem; }
input[type="text"], input[type="number"],
input[type="email"], input[type="password"], select {
  width: 100%;
  max-width: 260px;
  padding: 0.5rem 0.7rem;
  border-radius: 8px;
  border: 1px solid var(--panel-line);
  background: rgba(0, 0, 0, 0.35);
  color: var(--ink);
  font: inherit;
}
input[type="checkbox"] { accent-color: var(--gold); }
form.inline { display: flex; flex-wrap: wrap; gap: 0.6rem 1rem; align-items: flex-end; }
fieldset { border: 1px solid var(--panel-line); border-radius: 8px; margin: 0 0 0.8rem; padding: 0.4rem 0.8rem 0.7rem; }
legend { color: var(--ink-dim); font-size: 0.85rem; padding: 0 0.4rem; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 0.4rem 1.2rem; margin: 0.4rem 0; }
.form-grid .hint { font-size: 0.8rem; }
label.check { display: flex; align-items: center; gap: 0.45rem; margin-top: 0.5rem; color: var(--ink); }

/* ---------- login / lobby ---------- */

/* Issue #84: der Abstand vom oberen Rand traegt das Layout der Login-Seite,
   darum auch hier vh-Fallback zuerst, dvh als ueberschreibende Zeile. */
.auth-wrap {
  max-width: 420px;
  margin: 8vh auto 0;
  margin: 8dvh auto 0;
}

.round-list { list-style: none; margin: 0; padding: 0; }
.round-list li {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem;
  padding: 0.6rem 0.2rem;
  border-bottom: 1px dashed var(--panel-line);
}
.round-list .meta { color: var(--ink-dim); font-size: 0.88rem; }
.round-list .spacer { flex: 1; }
.code-pill {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  letter-spacing: 0.08em;
  background: rgba(0, 0, 0, 0.4);
  border-radius: 6px;
  padding: 0.1rem 0.45rem;
}

/* ---------- archive (Issue #29: abgeschlossene Runden) ---------- */

/* Ein Eintrag pro Runde: oben Name + Code + "Ansehen", darunter die
   Meta-Zeilen (Datum, Teilnehmer, Endstand). Eigene Liste statt
   .round-list, damit die Lobby-Grid-Regeln hier nicht greifen. */
.archive-list { list-style: none; margin: 0; padding: 0; }
.archive-list li {
  padding: 0.6rem 0.2rem;
  border-bottom: 1px dashed var(--panel-line);
}
.archive-list .archive-line {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem;
}
.archive-list .archive-line .spacer { flex: 1; }
.archive-list .meta { color: var(--ink-dim); font-size: 0.88rem; }
.archive-list .archive-standings { color: var(--ink); }
.archive-list a.btn { text-decoration: none; }

@media (max-width: 600px) {
  .archive-list .archive-line .btn { width: 100%; min-height: 44px; }
}

/* Admin-Bereich (Issue #22): Status-Marker in den Listen. */
.badge {
  border: 1px solid var(--panel-line);
  border-radius: 999px;
  padding: 0.1rem 0.5rem;
  font-size: 0.78rem;
  color: var(--ink-dim);
}
.badge.banned {
  border-color: transparent;
  background: var(--danger);
  color: #fff;
}

/* ---------- game table ---------- */

.game { display: flex; flex-direction: column; gap: 0.8rem; }

.topbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.8rem;
}
.topbar .stage {
  margin-left: auto;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: 999px;
  padding: 0.3rem 0.9rem;
  font-weight: 600;
  color: var(--gold);
}

/* opponent chips */
.opponents { display: flex; flex-wrap: wrap; gap: 0.8rem; }

.opponent {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: var(--radius);
  padding: 0.5rem 0.8rem;
  min-width: 130px;
}
.opponent .opp-name { font-weight: 700; display: flex; gap: 0.4rem; align-items: center; }
.opponent .role {
  font-size: 0.7rem; font-weight: 700; text-transform: uppercase;
  border-radius: 999px; padding: 0.05rem 0.5rem;
  background: rgba(0, 0, 0, 0.4);
}
.opponent .role.attacker { color: var(--gold); }
.opponent .role.defender { color: var(--accent); }
.opponent .role.bot { color: var(--ink-dim); }

/* Bot-Kennzeichnung (#26): gleiches Badge an jedem Sitz - Gegnerzeile,
   Rund-Lobby und eigenem Sitz. Deutsch wie der Rest (i18n folgt spaeter). */
.bot-badge {
  background: rgba(0, 0, 0, 0.4);
  border-radius: 999px;
  color: var(--ink-dim);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 0.05rem 0.5rem;
  text-transform: uppercase;
}

.opp-cards { display: flex; align-items: center; margin-top: 0.35rem; }
.count-badge {
  margin-left: 0.5rem;
  background: rgba(0, 0, 0, 0.55);
  border-radius: 999px;
  padding: 0.05rem 0.5rem;
  font-size: 0.85rem;
  font-weight: 700;
}
.opponent.out { opacity: 0.6; }
.out-badge { color: var(--ink-dim); font-size: 0.85rem; font-style: italic; }

.opponent.has-turn {
  border-color: var(--gold);
  box-shadow: 0 0 0 2px var(--gold), 0 0 18px rgba(242, 193, 78, 0.45);
  animation: pulse 1.6s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 2px var(--gold), 0 0 10px rgba(242, 193, 78, 0.35); }
  50%      { box-shadow: 0 0 0 2px var(--gold), 0 0 22px rgba(242, 193, 78, 0.65); }
}

/* middle zone: slots + stock */
.table-zone {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: flex-start;
  justify-content: center;
  min-height: calc(var(--card-w) * var(--card-ratio) + 2rem);
}

.slots { display: flex; flex-wrap: wrap; gap: 0.9rem; justify-content: center; flex: 1; }

.slot { position: relative; display: flex; align-items: center; }

.donations { display: flex; gap: 0.4rem; align-items: center; }
.donations .label { color: var(--ink-dim); font-size: 0.85rem; }

/* stock pile top-right */
.stock {
  position: relative;
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.stock .pile { position: relative; width: var(--card-w); }
.stock .stock-count {
  background: rgba(0, 0, 0, 0.55);
  border: 1px solid var(--panel-line);
  border-radius: 999px;
  padding: 0.15rem 0.6rem;
  font-weight: 700;
}
/* Issue #86: kurzes Wort zum Stapel - die Zahl allein liest sich nicht. */
.stock .stock-label { color: var(--ink-dim); font-weight: 700; }
.stock .trump-label { color: var(--gold); font-weight: 700; }
.stock .stock-count.empty { opacity: 0.4; }

/* actions */
.actions { display: flex; flex-wrap: wrap; gap: 0.6rem; justify-content: center; }

/* result banner */
.result-banner {
  text-align: center;
  background: var(--panel);
  border: 1px solid var(--gold);
  border-radius: var(--radius);
  padding: 1rem;
}
.result-banner .headline { color: var(--gold); font-size: 1.3rem; font-weight: 800; }
.score-table { margin: 0.6rem auto; border-collapse: collapse; }
.score-table td, .score-table th { padding: 0.2rem 0.9rem; text-align: left; }
.score-table .durak { color: var(--danger); font-weight: 700; }

/* Leaderboard (issue #31): Zahlen rechtsbuendig, damit die Spalten
   untereinander stehen; die Tabelle selbst nutzt .score-table. */
.board-table { width: 100%; }
.board-table th, .board-table td { padding: 0.3rem 0.6rem; }
.board-table td.num, .board-table th.num { text-align: right; }

/* mini log */
.log { color: var(--ink-dim); font-size: 0.85rem; }
.log summary { cursor: pointer; color: var(--ink); }
.log ul { margin: 0.4rem 0 0; padding-left: 1.1rem; max-height: 8rem; overflow-y: auto; }

/* ---------- flash / toasts ---------- */

#flash {
  position: fixed;
  top: 0.8rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  pointer-events: none;
  width: max(320px, min(90vw, 480px));
}
.toast {
  background: rgba(20, 20, 20, 0.92);
  border: 1px solid var(--panel-line);
  border-left: 4px solid var(--gold);
  color: var(--ink);
  border-radius: 8px;
  padding: 0.55rem 0.9rem;
  box-shadow: var(--shadow);
  animation: toast-in 0.25s ease-out, toast-out 0.4s ease-in 3.6s forwards;
}
.toast.error { border-left-color: var(--danger); }
.toast.ok { border-left-color: var(--felt-1); }
@keyframes toast-in  { from { opacity: 0; transform: translateY(-8px); } }
@keyframes toast-out { to   { opacity: 0; transform: translateY(-8px); } }

/* ---------- turn timer chip ---------- */

/* app.js counts down against data-deadline (unix seconds from the server,
   the single authority). The hourglass stays, only the digits update. */
.turn-timer {
  margin-left: auto;
  padding: 0.05rem 0.5rem;
  border: 1px solid var(--panel-line);
  border-radius: 999px;
  background: rgba(20, 20, 20, 0.45);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.turn-timer.urgent {
  color: var(--danger);
  border-color: var(--danger);
}

/* Issue #87: abgelaufene Frist. app.js haelt die letzten Sekunden wie
   bisher (urgent) und zeigt statt der Ziffern den kataloguebersetzten
   Ablauf-Text, sobald der Server selbst spielt (autoAct in internal/round).
   Der Chip bleibt dunkel grundiert, nur Rand und Text heben sich ab - der
   Spieler sieht den Umschaltmoment, bevor der neue Snapshot eintrifft. */
.turn-timer.expired {
  color: var(--ink);
  border-color: var(--danger);
  background: rgba(120, 30, 28, 0.85);
  font-weight: 700;
}

/* htmx request feedback */
.htmx-requesting { opacity: 0.7; transition: opacity 0.2s; }

/* ---------- responsive ---------- */

@media (max-width: 640px) {
  :root { --card-w: 15vw; }
  .stock { margin-left: 0; order: -1; }
  .topbar .stage { margin-left: 0; }
  /* Leaderboard: sieben Spalten brauchen auf dem Phone weniger Luft. */
  .board-table { font-size: 0.85rem; }
  .board-table th, .board-table td { padding: 0.25rem 0.4rem; }
}

/* ---------- identity + hint toggle ---------- */

.me-pill {
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid var(--panel-line);
  border-radius: 999px;
  padding: 0.25rem 0.8rem;
  font-size: 0.92rem;
}
.me-pill strong { color: var(--gold); }

.hints-toggle,
.theme-toggle,
.lang-toggle {
  background: none;
  border: 1px solid var(--panel-line);
  border-radius: 999px;
  color: var(--ink-dim);
  cursor: pointer;
  font: inherit;
  font-size: 0.85rem;
  padding: 0.25rem 0.7rem;
}
.hints-toggle:hover,
.theme-toggle:hover,
.lang-toggle:hover { color: var(--ink); border-color: var(--gold); }

/* "Hinweise: Aus" - hide the golden highlight, keep everything else. */
body.no-hints .opponent.has-turn { box-shadow: none; }

/* Site head (issue #15): the language switch shares the page's top row with
   the user bar and stays at the right edge - it is the only language control
   and must be within reach on every page, login included. The table topbar
   (#20) keeps its own two controls. */
.site-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  padding: 4px 0 10px;
}
.site-head .userbar { flex: 1 1 auto; padding: 0; }
.site-head form { margin: 0; }
/* Ohne Benutzerleiste (Login, Registrierung) rueckt der Umschalter allein an
   den rechten Rand - der Klickort bleibt auf jeder Seite derselbe. */
.site-head .lang-switch { margin-left: auto; }

/* User bar (page head): signed-in name, profile link, sign-out. */
.userbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 4px 0 10px;
  color: var(--ink-dim);
  font-size: 0.9rem;
}.userbar strong { color: var(--gold); }
.userbar form { margin: 0; }
.userlink {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--ink-dim);
  cursor: pointer;
  text-decoration: underline;
}
.userlink:hover { color: var(--danger); }
