@import url('fonts.css');

/* =====================================================================
   انت الزنيط — الأنماط الرئيسية
   ---------------------------------------------------------------------
   Mobile-first, and RTL-native rather than RTL-flipped: the layout is
   written with CSS logical properties (inline-start/inline-end, padding-
   inline, border-inline) so it is laid out for Arabic from the start and
   would mirror correctly if a LTR locale were ever added.

   No inline styles and no external requests anywhere — the strict CSP in
   Kernel.php depends on that.
   ===================================================================== */

/* ---- one rule the identity package is missing ----------------------
   The text-bearing SVGs carry no font of their own; they tag their <text>
   with a class and inherit it from the host document when inlined, and
   KHAIMA-VISUAL-IDENTITY/tokens.css supplies .h .b .n .t .lbl .d for that.
   It does not supply .wm — which is the class used by all SEVEN الخيمة
   logo assets (wordmark, wordmark-light, wordmark-gold, logo-primary,
   logo-primary-light, logo-horizontal, logo-horizontal-light). Without it
   the platform wordmark inherits the body face instead of the display one.

   Kept here rather than edited into tokens.css so the served package stays
   byte-identical to the delivered source. DELETE THIS BLOCK once the
   package ships the rule itself.
   -------------------------------------------------------------------- */
svg .wm { font-family: var(--kh-font-display); font-weight: 700; }

/* =====================================================================
   الخيمة component layer — the modifiers this product needs and the
   identity package does not ship.
   ---------------------------------------------------------------------
   The package ships .kh-btn, .kh-card, .kh-input and .kh-chip with their
   semantic variants, and nothing else: no sizes, no widths, no
   low-emphasis fill. This product has screens that need all three — a
   full-width primary action on a phone, a dense admin table, a status
   badge that must recede.

   These are EXTENSIONS, not a second system: they carry no colour, radius,
   shadow, spacing or font value of their own, only --kh-* tokens, and they
   are meaningless without the .kh-* base class beside them. If the package
   ever ships an equivalent, delete the rule here and keep the package's.

   Everything below is additive. No .kh-* class from the package is
   redefined and no --kh-* variable is overridden.
   ===================================================================== */

/* ---- buttons: size and width --------------------------------------- */
.kh-btn--block { display: flex; width: 100%; }

/* The primary action on a gameplay screen. 66px is a layout constant, not
   a taste: the one-viewport screens were measured around it. */
.kh-btn--lg { min-height: 66px; font-size: 18px; padding-inline: var(--kh-space-7); }

/* Secondary controls, chiefly in the admin. Deliberately 48px and not the
   42px the old .btn--sm used — that was below the platform's own floor. */
.kh-btn--sm { min-height: 48px; font-size: 13.5px; padding-inline: var(--kh-space-4); }

/* Low emphasis with a fill, between --ghost (no fill) and --primary. The
   pressed state is set explicitly because the package's .kh-btn:active
   drops a GOLD depth shadow, which belongs only to a gold button. */
.kh-btn--quiet {
  background: var(--kh-surface-dark);
  color: var(--kh-text-on-dark);
  border: 1px solid var(--kh-border-on-dark);
  box-shadow: none;
}
.kh-btn--quiet:active { box-shadow: none; }

/* ---- cards ---------------------------------------------------------- */
.kh-card--tight  { padding: var(--kh-space-3); }
.kh-card--accent { border-color: var(--kh-border-gold); }
.kh-card--danger { border-color: var(--kh-error); background: var(--kh-error-fill); }

/* ---- inputs --------------------------------------------------------- */
.kh-input--sm   { font-size: 13.5px; }
/* A two- or three-digit settings field. Numeric, so it takes the numeric
   face and an LTR isolate for the same reason .kh-ltr exists. */
.kh-input--tiny {
  width: 6em;
  text-align: center;
  direction: ltr;
  unicode-bidi: isolate;
  font-family: var(--kh-font-num);
}

/* ---- chips: two more shades of quiet -------------------------------- */
.kh-chip--quiet {
  background: var(--kh-surface-dark);
  color: var(--kh-text-on-dark-muted);
  border: 1px solid var(--kh-border-on-dark);
}
.kh-chip--muted {
  background: transparent;
  color: var(--kh-disabled-text);
  border: 1px solid var(--kh-border-on-dark);
}

/* ---- notifications --------------------------------------------------
   The package specifies these in prose — "full-width pill on the semantic
   fill with the matching 1px border" — but ships no class. Written to that
   description. The text tokens are the ON-DARK ones because the shell is
   still the legacy dark ground; that pairing is revisited in Phase 3 when
   the ground itself changes.
   -------------------------------------------------------------------- */
.kh-note {
  display: flex;
  align-items: center;
  gap: var(--kh-space-2);
  padding: var(--kh-space-3) var(--kh-space-4);
  border-radius: var(--kh-radius-pill);
  border: 1px solid var(--kh-border-on-dark);
  font-size: 13.5px;
  line-height: 1.5;
}
.kh-note--success { background: var(--kh-success-fill); border-color: var(--kh-success); color: var(--kh-success-text); }
.kh-note--error   { background: var(--kh-error-fill);   border-color: var(--kh-error);   color: var(--kh-error-text); }
.kh-note--info    { background: var(--kh-warning-fill); border-color: var(--kh-warning); color: var(--kh-warning-text); }

/* ---- the retired palette, now pointing at the identity --------------
   These names are the first game's, from before the platform had an
   identity of its own. Roughly two hundred declarations across this file
   and knowledge.css still read them, so rather than rewrite every one and
   risk the layout, each name now RESOLVES TO ITS الخيمة equivalent.

   Nothing here declares a colour any more: every value is a --kh-* token,
   so there is exactly one palette in the product and this block is a set of
   aliases on the way out. Delete a name here once nothing reads it.
   -------------------------------------------------------------------- */
:root {
  --bg:          var(--kh-bg-dark);
  --bg-elev:     var(--kh-brown);
  --surface:     var(--kh-surface-dark);
  --surface-2:   rgba(255, 253, 247, 0.11);
  --border:      var(--kh-border-on-dark);
  --border-2:    var(--kh-border-gold);

  --text:        var(--kh-text-on-dark);
  --text-dim:    var(--kh-text-on-dark-muted);
  --text-mute:   var(--kh-disabled-text);

  /* The old brand pair was a purple/pink gradient. The platform's colour is
     the tent: deep desert red, with gold as the action. */
  --brand-1:     var(--kh-red-light);
  --brand-2:     var(--kh-red-dark);
  --gold:        var(--kh-gold);
  --success:     var(--kh-success);
  --danger:      var(--kh-error);
  --info:        var(--kh-gold-bright);

  --grad-brand:  var(--kh-grad-header);
  --grad-gold:   var(--kh-grad-gold);
  --grad-danger: var(--kh-grad-danger);
  --grad-good:   var(--kh-grad-success);

  /* 16px is the identity's floor; the old --radius-sm was 10px. */
  --radius-sm:   var(--kh-radius-sm);
  --radius:      var(--kh-radius-md);
  --radius-lg:   var(--kh-radius-lg);
  --radius-pill: var(--kh-radius-pill);

  --shadow:      var(--kh-shadow-md);
  --shadow-lg:   var(--kh-shadow-lg);

  --tap:         56px;   /* minimum touch target */
  --page-pad:    18px;
  --max-w:       560px;  /* one phone — never wider than a comfortable column */

  --ease:        cubic-bezier(0.16, 1, 0.3, 1);
}

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

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
}

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

body {
  font-family: var(--kh-font-body);
  font-weight: 500;
  font-size: 17px;
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  /* Inside the tent at night: the cloth glows warm where the lamp hangs.
     Two grounds and no more — the deep brown and the red-lit corner — which
     is the identity's "at most two background colours per screen". The
     Amazigh weave goes on top as texture, in ::before below, because the
     pattern tile ships with an OPAQUE red field: used here it would carpet
     the page in solid diamonds instead of whispering under it. */
  background-image:
    radial-gradient(1100px 680px at 84% -10%, rgba(139, 38, 38, 0.55), transparent 64%),
    radial-gradient(760px 520px at 8% 2%,     rgba(212, 175, 55, 0.10), transparent 58%);
  background-attachment: fixed;
  min-height: 100dvh;
  overflow-x: hidden;
  /* Stop the double-tap zoom that makes a fast-paced party game feel broken. */
  touch-action: manipulation;
}

/* The weave. Fixed so it never scrolls against the content, inert so it can
   never eat a tap, and at 8% because the identity's ceiling for ornament is
   18% and this tile is high-contrast gold on red. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.08;
  background-image: url('../KHAIMA-VISUAL-IDENTITY/brand/patterns/pattern-amazigh-diamond.svg');
  background-size: 120px 120px;
  background-repeat: repeat;
}

img { max-width: 100%; height: auto; }

h1, h2, h3, h4 {
  margin: 0 0 0.4em;
  font-weight: 800;
  /* Arabic is a connected script: tracking pulls joined letters apart and
     costs legibility rather than buying tightness. Leave it alone. */
  letter-spacing: normal;
  /* Slightly more leading than a Latin heading needs — Arabic ascenders and
     the dots below the baseline want the room. */
  line-height: 1.35;
}

h1 { font-size: clamp(1.7rem, 6vw, 2.3rem); }
h2 { font-size: clamp(1.35rem, 4.6vw, 1.7rem); }
h3 { font-size: 1.15rem; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--info); text-decoration: none; }
a:hover, a:focus-visible { text-decoration: underline; }

/* Visible focus everywhere — the game is used one-handed and quickly. */
:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
  border-radius: 6px;
}

/* ---- layout -------------------------------------------------------- */
.page {
  width: 100%;
  max-width: var(--max-w);
  margin-inline: auto;
  padding: var(--page-pad);
  padding-bottom: calc(var(--page-pad) + env(safe-area-inset-bottom, 0px));
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

.page--center {
  justify-content: center;
  gap: 20px;
}

.stack      { display: flex; flex-direction: column; gap: 14px; }
.stack--sm  { gap: 8px; }
.stack--lg  { gap: 22px; }
.grow       { flex: 1 1 auto; }
.center     { text-align: center; }
.spacer     { flex: 1 1 auto; min-height: 8px; }

.row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.row--between { justify-content: space-between; }
.row--nowrap  { flex-wrap: nowrap; }

/* ---- brand --------------------------------------------------------- */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-weight: 800;
  font-size: 1.05rem;
  color: var(--text);
}
.brand:hover { text-decoration: none; }

/* The emblem is the mark now — a drawn tent, not an emoji in a tinted tile,
   so it needs no plate behind it. .brand__mark is kept for any caller that
   still passes the emoji. */
.brand__emblem {
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
}
.brand__name {
  font-family: var(--kh-font-display);
  font-weight: 700;
  letter-spacing: 0.2px;
}
.brand__mark {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: var(--kh-radius-sm);
  background: var(--kh-grad-panel);
  border: 1px solid var(--kh-border-gold);
  font-size: 20px;
}

.hero__title {
  font-size: clamp(2.1rem, 9vw, 3rem);
  background: linear-gradient(120deg, var(--kh-sand-light) 8%, var(--kh-gold-bright) 62%, var(--kh-gold) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  margin-bottom: 0.25em;
}

.hero__sub {
  color: var(--text-dim);
  font-size: 1.05rem;
  max-width: 34ch;
  margin-inline: auto;
}

/* ---- cards --------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px;
  box-shadow: var(--shadow);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}

.card--tight   { padding: 14px; }
.card--flat    { box-shadow: none; background: var(--surface); }
.card--accent  { border-color: rgba(251, 191, 36, 0.45); }
.card--danger  { border-color: rgba(251, 113, 133, 0.45); }
.card--success { border-color: rgba(52, 211, 153, 0.45); }

.card__label {
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  color: var(--text-mute);
  font-weight: 700;
  margin-bottom: 4px;
}

/* ---- buttons ------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--tap);
  padding: 12px 22px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: inherit;
  font-size: 1.05rem;
  font-weight: 700;
  color: #fff;
  background: var(--surface-2);
  cursor: pointer;
  text-align: center;
  transition: transform 0.14s var(--ease), filter 0.18s var(--ease), box-shadow 0.18s var(--ease);
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}

.btn:hover { text-decoration: none; filter: brightness(1.08); }
.btn:active { transform: scale(0.975); }

.btn[disabled], .btn[aria-disabled='true'] {
  opacity: 0.45;
  pointer-events: none;
}

.btn--block   { display: flex; width: 100%; }
.btn--primary { background: var(--grad-brand); box-shadow: 0 10px 26px rgba(124, 58, 237, 0.42); }
.btn--gold    { background: var(--grad-gold); color: #2a1a00; box-shadow: 0 10px 26px rgba(251, 191, 36, 0.35); }
.btn--danger  { background: var(--grad-danger); box-shadow: 0 10px 26px rgba(244, 63, 94, 0.32); }
.btn--success { background: var(--grad-good); box-shadow: 0 10px 26px rgba(16, 185, 129, 0.32); }
.btn--ghost   { background: transparent; border-color: var(--border-2); color: var(--text-dim); box-shadow: none; }
.btn--quiet   { background: var(--surface); border-color: var(--border); color: var(--text-dim); box-shadow: none; }

.btn--lg { min-height: 66px; font-size: 1.2rem; padding-inline: 28px; }
.btn--sm { min-height: 42px; font-size: 0.92rem; padding: 6px 16px; }

/* ---- forms --------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: 7px; }

.label {
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--text-dim);
}

.input, .textarea, .select {
  width: 100%;
  min-height: var(--tap);
  padding: 12px 16px;
  font-family: inherit;
  font-size: 1.05rem;
  font-weight: 500;
  color: var(--text);
  background: rgba(0, 0, 0, 0.28);
  border: 1.5px solid var(--border-2);
  border-radius: var(--radius);
  transition: border-color 0.18s var(--ease), background 0.18s var(--ease);
  /* Arabic input must read right-to-left even when the value is Latin. */
  text-align: start;
}

.textarea { min-height: 120px; padding-block: 12px; resize: vertical; line-height: 1.7; }

.select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-dim) 50%),
                    linear-gradient(135deg, var(--text-dim) 50%, transparent 50%);
  background-position: calc(0% + 18px) calc(50% + 2px), calc(0% + 24px) calc(50% + 2px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-inline-start: 42px;
}

.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--brand-2);
  background: rgba(0, 0, 0, 0.42);
}

.input::placeholder, .textarea::placeholder { color: var(--text-mute); }

.input--error, .textarea--error, .select--error { border-color: var(--danger); }

.hint  { font-size: 0.85rem; color: var(--text-mute); }
.error { font-size: 0.9rem; color: var(--danger); font-weight: 700; }

/* ---- flash messages ------------------------------------------------ */
.flash {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--border-2);
  background: var(--surface-2);
  font-weight: 700;
  font-size: 0.97rem;
}
.flash--success { border-color: rgba(52, 211, 153, 0.5); background: rgba(52, 211, 153, 0.12); }
.flash--error   { border-color: rgba(251, 113, 133, 0.5); background: rgba(251, 113, 133, 0.12); }
.flash--info    { border-color: rgba(56, 189, 248, 0.5);  background: rgba(56, 189, 248, 0.12); }

/* ---- pills & badges ------------------------------------------------ */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 13px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--text-dim);
}
.pill--gold    { background: rgba(251, 191, 36, 0.16); border-color: rgba(251, 191, 36, 0.4); color: var(--gold); }
.pill--success { background: rgba(52, 211, 153, 0.16); border-color: rgba(52, 211, 153, 0.4); color: var(--success); }
.pill--danger  { background: rgba(251, 113, 133, 0.16); border-color: rgba(251, 113, 133, 0.4); color: var(--danger); }
.pill--muted   { color: var(--text-mute); }

/* ---- progress ------------------------------------------------------ */
.progress {
  display: flex;
  gap: 5px;
  align-items: center;
}
.progress__seg {
  flex: 1 1 0;
  height: 5px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
}
.progress__seg--done   { background: var(--grad-brand); }
.progress__seg--active { background: var(--gold); }

.stage-label {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--text-mute);
  letter-spacing: 0.02em;
}

/* ---- the phone-passing screen -------------------------------------- */
.pass {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 34px 20px;
  text-align: center;
}

.pass__icon {
  font-size: 54px;
  line-height: 1;
  animation: float 2.6s ease-in-out infinite;
}

.pass__label { color: var(--text-dim); font-weight: 700; }

.pass__name {
  font-size: clamp(2.2rem, 11vw, 3.4rem);
  font-weight: 800;
  background: var(--grad-gold);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  margin: 0;
  overflow-wrap: anywhere;
}

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9px); }
}

/* ---- the secret word ----------------------------------------------- */
.secret {
  padding: 30px 20px;
  text-align: center;
  border-radius: var(--radius-lg);
  border: 1px solid rgba(251, 191, 36, 0.4);
  background: linear-gradient(160deg, rgba(251, 191, 36, 0.14), rgba(124, 58, 237, 0.12));
  animation: pop 0.42s var(--ease) both;
}

.secret__word {
  font-size: clamp(2rem, 10vw, 3rem);
  font-weight: 800;
  margin: 10px 0;
  overflow-wrap: anywhere;
}

.secret--outsider {
  border-color: rgba(244, 63, 94, 0.5);
  background: linear-gradient(160deg, rgba(244, 63, 94, 0.16), rgba(88, 28, 135, 0.2));
}

@keyframes pop {
  from { opacity: 0; transform: scale(0.94) translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* ---- player choice list -------------------------------------------- */
.choices { display: flex; flex-direction: column; gap: 10px; }

.choice {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--tap);
  padding: 12px 16px;
  border-radius: var(--radius);
  border: 1.5px solid var(--border-2);
  background: var(--surface);
  font-size: 1.1rem;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 0.16s var(--ease), background 0.16s var(--ease), transform 0.12s var(--ease);
  -webkit-tap-highlight-color: transparent;
}

.choice:active { transform: scale(0.985); }

.choice input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.choice__dot {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid var(--border-2);
  display: grid;
  place-items: center;
  transition: border-color 0.16s var(--ease);
}

.choice__dot::after {
  content: '';
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--grad-brand);
  transform: scale(0);
  transition: transform 0.18s var(--ease);
}

.choice:has(input:checked) {
  border-color: var(--brand-2);
  background: rgba(236, 72, 153, 0.14);
}
.choice:has(input:checked) .choice__dot { border-color: var(--brand-2); }
.choice:has(input:checked) .choice__dot::after { transform: scale(1); }
.choice:has(input:focus-visible) { outline: 3px solid var(--gold); outline-offset: 3px; }

.choice__name { flex: 1 1 auto; overflow-wrap: anywhere; }

/* ---- countdown ----------------------------------------------------- */
.countdown {
  display: grid;
  place-items: center;
  gap: 4px;
  margin-block: 8px;
}

.countdown__ring {
  position: relative;
  width: 168px;
  height: 168px;
  display: grid;
  place-items: center;
}

.countdown__svg { position: absolute; inset: 0; transform: rotate(-90deg); }

.countdown__track { fill: none; stroke: rgba(255, 255, 255, 0.10); stroke-width: 10; }

.countdown__bar {
  fill: none;
  stroke: var(--gold);
  stroke-width: 10;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.95s linear, stroke 0.3s var(--ease);
}

.countdown__num {
  position: relative;
  font-size: 4rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.countdown.is-urgent .countdown__bar { stroke: var(--danger); }
.countdown.is-urgent .countdown__num { color: var(--danger); animation: pulse 0.8s ease-in-out infinite; }

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.12); }
}

/* ---- reveal / drumroll --------------------------------------------- */
.reveal-name {
  font-size: clamp(2.3rem, 12vw, 3.6rem);
  font-weight: 800;
  text-align: center;
  background: var(--grad-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: pop 0.5s var(--ease) both;
  overflow-wrap: anywhere;
}
/* The outsider's unmasking sits on the danger card, whose red wash makes the
   gradient treatment above illegible. On that card the name is solid white —
   the highest-contrast thing on the screen, as the moment deserves. */
.kh-card--danger .reveal-name {
  background: none;
  -webkit-background-clip: initial;
  background-clip: initial;
  color: #fff;
}

.verdict {
  text-align: center;
  padding: 26px 18px;
  border-radius: var(--radius-lg);
  animation: pop 0.4s var(--ease) both;
}
.verdict--good { background: linear-gradient(160deg, rgba(16, 185, 129, 0.2), rgba(5, 150, 105, 0.08)); border: 1px solid rgba(52, 211, 153, 0.45); }
.verdict--bad  { background: linear-gradient(160deg, rgba(244, 63, 94, 0.2), rgba(185, 28, 28, 0.08)); border: 1px solid rgba(251, 113, 133, 0.45); }
.verdict__title { font-size: 1.9rem; margin-bottom: 6px; }
.verdict__sub   { color: var(--text-dim); margin: 0; }

/* ---- scoreboard ---------------------------------------------------- */
.score-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 15px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
}
.score-row--outsider { border-color: rgba(244, 63, 94, 0.45); background: rgba(244, 63, 94, 0.09); }
.score-row--winner   { border-color: rgba(251, 191, 36, 0.5);  background: rgba(251, 191, 36, 0.09); }

.score-row__name   { flex: 1 1 auto; font-weight: 700; overflow-wrap: anywhere; }
.score-row__points { font-weight: 800; font-size: 1.25rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.score-row__meta   { font-size: 0.82rem; color: var(--text-mute); font-weight: 500; }

.rank {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 12px;
  background: var(--surface-2);
  font-weight: 800;
  font-size: 0.95rem;
}
.rank--1 { background: var(--grad-gold); color: #2a1a00; }
.rank--2 { background: linear-gradient(135deg, #e2e8f0, #94a3b8); color: #1e293b; }
.rank--3 { background: linear-gradient(135deg, #d97706, #92400e); color: #fff7ed; }

/* ---- tables (admin) ------------------------------------------------ */
.table-wrap {
  /* Wide tables scroll inside their own box; the page never does. */
  overflow-x: auto;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
  white-space: nowrap;
}

.table th, .table td {
  padding: 12px 14px;
  text-align: start;
  border-bottom: 1px solid var(--border);
}

.table th {
  font-weight: 800;
  font-size: 0.85rem;
  color: var(--text-mute);
  background: rgba(0, 0, 0, 0.2);
  position: sticky;
  top: 0;
}

.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: rgba(255, 255, 255, 0.03); }
.table td.wrap { white-space: normal; min-width: 200px; }

/* ---- admin shell --------------------------------------------------- */
.admin { min-height: 100dvh; display: flex; flex-direction: column; }

.admin__bar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  background: rgba(10, 9, 22, 0.9);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}

.admin__body {
  width: 100%;
  max-width: 1080px;
  margin-inline: auto;
  padding: 18px 16px calc(28px + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  gap: 18px;
  flex: 1 1 auto;
}

.admin__nav {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: thin;
}

.admin__nav a {
  flex: 0 0 auto;
  padding: 9px 16px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 0.92rem;
  font-weight: 700;
  white-space: nowrap;
}
.admin__nav a:hover { text-decoration: none; color: var(--text); }
.admin__nav a.is-active {
  background: var(--kh-grad-gold);
  border-color: transparent;
  color: var(--kh-text-on-gold);
  font-family: var(--kh-font-display);
  font-weight: 700;
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
}

.stat {
  padding: 16px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
}
.stat__value { font-size: 1.9rem; font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat__label { font-size: 0.85rem; color: var(--text-mute); font-weight: 700; }

/* ---- misc ---------------------------------------------------------- */
.divider { height: 1px; background: var(--border); border: none; margin: 4px 0; }

.muted { color: var(--text-mute); }
.dim   { color: var(--text-dim); }
.small { font-size: 0.87rem; }
.bold  { font-weight: 800; }
.gold  { color: var(--gold); }
.danger-text { color: var(--danger); }
.success-text { color: var(--success); }

.empty {
  text-align: center;
  padding: 40px 20px;
  color: var(--text-mute);
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.name-rows { display: flex; flex-direction: column; gap: 10px; }

.name-row { display: flex; align-items: center; gap: 8px; }
.name-row .input { flex: 1 1 auto; }

.name-row__drop {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-mute);
  font-size: 20px;
  cursor: pointer;
  font-family: inherit;
}
.name-row__drop:hover { color: var(--danger); border-color: var(--danger); }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }

.chip {
  padding: 8px 15px;
  border-radius: var(--radius-pill);
  border: 1px dashed var(--border-2);
  background: transparent;
  color: var(--text-dim);
  font-family: inherit;
  font-size: 0.92rem;
  font-weight: 700;
  cursor: pointer;
}
.chip:hover { border-style: solid; border-color: var(--brand-2); color: var(--text); }

.detail-list { display: flex; flex-direction: column; gap: 2px; }

.detail {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 11px 0;
  border-bottom: 1px solid var(--border);
}
.detail:last-child { border-bottom: none; }
.detail__label { color: var(--text-mute); font-weight: 700; font-size: 0.92rem; }
.detail__value { font-weight: 700; text-align: end; overflow-wrap: anywhere; }

/* Vote tally bars. The width is applied by app.js through the CSSOM rather
   than an inline style attribute, which the CSP (style-src 'self') forbids.
   Without JavaScript the bar simply renders at its default width — the
   numbers next to it already carry the information. */
.tally {
  height: 8px;
  width: 100%;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  overflow: hidden;
}

.tally-bar {
  display: block;
  height: 100%;
  width: 100%;
  border-radius: var(--radius-pill);
  background: var(--grad-brand);
  transition: width 0.6s var(--ease);
}

/* Sits in the game header row rather than floating over it — as an overlay
   it clipped the stage name on narrow phones. */
.mute-toggle {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
  font-family: inherit;
}
.mute-toggle:hover { color: var(--text); border-color: var(--border-2); }

.game-header { margin-bottom: 6px; }

/* =====================================================================
   شاشة اللعب تسع الهاتف كاملًا — one viewport, no scrolling
   ---------------------------------------------------------------------
   Gameplay is played standing up, passing a phone around, often one-handed.
   A screen that scrolls hides the thing you are meant to tap next, so every
   in-game screen is pinned to exactly one viewport and its contents scale
   down to fit instead of pushing the page taller.

   The technique: `dvh` for every vertical measurement, so the boxes shrink
   as the viewport gets shorter, with a `clamp()` floor that never takes a
   touch target below a comfortable size. Nothing here changes the desktop
   or admin experience.
   ===================================================================== */

body.is-game {
  height: 100dvh;
  min-height: 0;
  overflow: hidden;
  /* Stops the iOS rubber-band drag, which reads as "the page scrolled". */
  overscroll-behavior: none;
}

.page--game {
  height: 100dvh;
  min-height: 0;
  gap: 0;
  padding-block: max(10px, env(safe-area-inset-top, 0px))
                 max(10px, env(safe-area-inset-bottom, 0px));
}

/* ---- the game's own ground -----------------------------------------
   A gameplay screen is the one place a game's colour takes over from the
   platform's, and even here the chrome above it — the kicker, the gold
   action — stays red and gold. The tint is deliberately gentle: these
   screens are read at speed in a lit room, and a full-strength gradient
   behind body text is a legibility problem, not a brand statement.

   Fixed, inert and behind everything, so it costs the layout nothing and
   the one-viewport rule is untouched.
   -------------------------------------------------------------------- */
.page--game[data-game]::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.42;
  background-image: var(--kh-game-grad);
}

/* The single flexible region, between the progress header and whatever the
   screen's own action is. It gives up space before the page ever does.
   The overflow rule is a safety valve for viewports shorter than anything
   currently sold — it is not the normal path, and it is asserted against in
   the layout test. */
.game-fit {
  min-height: 0;
  overflow-y: auto;
  /* Naming one axis is not enough. CSS Overflow §3 says that when overflow-y
     is not `visible`, a `visible` overflow-x takes the used value `auto` — so
     declaring only the vertical rule quietly makes this a horizontally
     scrollable box, and the first child ever wider than it becomes draggable
     into view. Gameplay moves on one axis only, so say so. */
  overflow-x: hidden;
  overscroll-behavior: contain;
  scrollbar-width: none;
  gap: clamp(8px, 1.8dvh, 16px);
}
.game-fit::-webkit-scrollbar { width: 0; height: 0; }

/* A screen's form owns the rest of the column, so the list inside it can
   give up height instead of pushing the submit button past the fold. */
.is-game .game-fit > form {
  flex: 1 1 auto;
  min-height: 0;
}

/* The only regions permitted to scroll are the ones whose length is set by
   how many people are playing. Everything else — titles, prompts, and every
   button — stays put, always on screen. */
.is-game .choices,
.is-game .scroll-region {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* Same reason as .game-fit above: vertical only, and horizontal pinned shut
     rather than left to the used-value rule. A ballot is the one list whose
     width is set by names somebody typed, so it is the likeliest to overflow
     one day. */
  overflow-x: hidden;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--border-2) transparent;
}
/* Fades the last few pixels so a row cut by the frame edge reads as "there
   is more below" rather than as a rendering fault. */
.is-game .choices,
.is-game .scroll-region {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 16px), transparent 100%);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 16px), transparent 100%);
  padding-block-end: 4px;
}
.is-game .choices::-webkit-scrollbar,
.is-game .scroll-region::-webkit-scrollbar { width: 4px; }
.is-game .choices::-webkit-scrollbar-thumb,
.is-game .scroll-region::-webkit-scrollbar-thumb {
  background: var(--border-2);
  border-radius: var(--radius-pill);
}

.is-game .stack     { gap: clamp(8px, 1.8dvh, 14px); }
.is-game .stack--sm { gap: clamp(4px, 1dvh, 8px); }
.is-game .stack--lg { gap: clamp(10px, 2.4dvh, 22px); }
.is-game .spacer    { min-height: 0; }
.is-game p          { margin-bottom: clamp(0.4em, 1.4dvh, 1em); }

/* Primary actions stay generous but yield a little on short screens. */
.is-game .btn--lg {
  min-height: clamp(52px, 8dvh, 66px);
  font-size: clamp(1.02rem, 2.4dvh, 1.2rem);
}
.is-game .btn { min-height: clamp(48px, 7.2dvh, 56px); }

/* ---- passing the phone --------------------------------------------- */
.is-game .pass {
  padding: clamp(10px, 3dvh, 34px) 16px;
  gap: clamp(6px, 1.5dvh, 12px);
}
.is-game .pass__icon { font-size: clamp(32px, 7dvh, 54px); }
.is-game .pass__name { font-size: clamp(1.9rem, 9vw, 3.4rem); }

/* ---- the secret, and the outsider ---------------------------------- */
.is-game .secret {
  padding: clamp(14px, 3.4dvh, 30px) 18px;
}
.is-game .secret__word {
  font-size: clamp(1.8rem, 9vw, 3rem);
  margin: clamp(4px, 1dvh, 10px) 0;
}

/* Phase 6: the outsider gets one line, and it owns the screen. Nothing
   else appears here — no note, no hint, no category. */
/* This is a moment, not a notice: the card takes the whole free column and
   centres the single line inside it, so the message is unmistakably the
   thing on screen. */
.secret--outsider {
  display: grid;
  place-items: center;
  padding: clamp(20px, 6dvh, 52px) 18px;
}
/* Outweighs the trailing spacer so the free column collects around the
   message rather than below it. */
.is-game .secret--outsider {
  flex: 8 1 auto;
  min-height: 0;
  gap: clamp(14px, 3.5dvh, 34px);
  align-content: center;
}

/* The category sits under the headline, clearly secondary to it. */
.secret__category {
  display: grid;
  justify-items: center;
  gap: 4px;
}
.secret__category-name {
  font-size: clamp(1.25rem, 5.6vw, 1.9rem);
  font-weight: 800;
  color: var(--gold);
}
/* Two classes on purpose: this must out-rank the generic `.is-game h2`
   size, including inside the short-phone block below. */
.is-game .secret__outsider,
.secret__outsider {
  margin: 0;
  font-size: clamp(2.5rem, 14vw, 4.6rem);
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: normal;
  color: #fff;
  text-shadow: 0 0 30px rgba(244, 63, 94, 0.55), 0 2px 12px rgba(0, 0, 0, 0.5);
}

/* The single focal question on a screen that also carries a list — sized to
   be read across a table without stealing the list's height. */
.is-game .turn-ask {
  margin: 0;
  text-align: center;
  font-size: clamp(1.2rem, 5vw, 1.6rem);
  line-height: 1.4;
  color: var(--text);
  text-wrap: balance;
}

/* ---- choosing a player --------------------------------------------- */
.is-game .choices {
  gap: clamp(6px, 1.3dvh, 10px);
  /* The list is a flex child that gives up height to whatever else is on the
     screen. Without a floor it can be squeezed to nothing, and a ballot with
     no visible names is not a cosmetic problem — it is an unplayable screen.
     Two full-size cards always survive; the rest scroll. */
  min-height: clamp(132px, 24dvh, 320px);
}
.is-game .choice {
  min-height: clamp(46px, 7.2dvh, 56px);
  padding: clamp(6px, 1.2dvh, 12px) 14px;
  font-size: clamp(1rem, 2.2dvh, 1.1rem);
}
.is-game .choice__dot { width: clamp(20px, 3dvh, 24px); height: clamp(20px, 3dvh, 24px); }

/* ---- the countdown -------------------------------------------------- */
.is-game .countdown { margin-block: clamp(2px, 0.8dvh, 8px); }
.is-game .countdown__ring {
  width: clamp(112px, 21dvh, 168px);
  height: clamp(112px, 21dvh, 168px);
}

/* Which round of the match this is, in the game header. */
.stage-label--round {
  color: var(--gold);
  font-weight: 800;
}

/* Position number in the final standings. */
.rank {
  display: inline-grid;
  place-items: center;
  min-width: 22px;
  height: 22px;
  margin-inline-end: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-2);
  font-size: 0.78rem;
  font-weight: 800;
  color: var(--text-dim);
}

/* ---- the result scoreboard ------------------------------------------ */
.is-game .score-row {
  padding: clamp(7px, 1.5dvh, 13px) 14px;
  gap: 10px;
}
.is-game .scroll-region {
  gap: clamp(5px, 1.1dvh, 10px);
  /* Never let the flexbox squeeze the scores out of existence — a result
     screen with no visible scores would be worse than one that scrolls. */
  min-height: clamp(92px, 14dvh, 220px);
}

/* The verdict banner is the loudest thing on the result screen; it does not
   also need to be the tallest. */
.is-game .verdict { padding: clamp(14px, 2.4dvh, 24px) 16px; }
.is-game .verdict__title { margin-bottom: 0.25em; }
.is-game .result-heading h1 { margin-bottom: 0; }

/* The match facts are label/value pairs, so on a phone they belong in two
   columns rather than a stack of full-width rows: same information, roughly
   half the height, and easier to scan. */
.is-game .detail-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px 14px;
}
.is-game .detail {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  padding: clamp(4px, 0.9dvh, 9px) 0;
}
.is-game .detail__label { font-size: 0.84rem; }
.is-game .detail__value { text-align: end; font-size: 0.96rem; }
/* A long final guess reads better across the full width. */
.is-game .detail:last-child:nth-child(odd) { grid-column: 1 / -1; }

/* ---- short phones ---------------------------------------------------
   An iPhone SE or a 640px-tall Android has roughly 200px less to work with
   than a modern flagship. Rather than let anything fall off the bottom, the
   decorative layer steps back: the emoji loses its reserved block, the
   supporting sentences shrink, and the headline gives up a size. Nothing
   interactive is touched. */
@media (max-height: 730px) {
  .is-game h1 { font-size: clamp(1.2rem, 4.6vw, 1.5rem); margin-bottom: 0.2em; }
  .is-game h2 { font-size: clamp(1.1rem, 4.2vw, 1.35rem); }
  /* The one heading that does not step back on a small screen. */
  .is-game .secret__outsider { font-size: clamp(2.2rem, 12.5vw, 3.4rem); }
  .is-game .pass { padding: 6px 12px; gap: 4px; }
  .is-game .pass__icon { font-size: 26px; animation: none; }
  .is-game .pass__name { font-size: clamp(1.5rem, 7.5vw, 2.1rem); }
  .is-game .pass__label { font-size: 0.9rem; }
  .is-game .small { font-size: 0.82rem; }
  .is-game .secret { padding: 12px 14px; }
  .is-game .verdict { padding: 12px 14px; }
  .is-game .stack--lg { gap: 8px; }
  .is-game .game-header { margin-bottom: 2px; }

  /* On the result screen the page heading only repeats what the verdict
     banner underneath already announces, so it steps aside on a short
     phone to keep the buttons on screen. */
  .is-game .result-heading { display: none; }
  .is-game .result-actions .btn:not(.btn--lg) { min-height: 44px; font-size: 0.9rem; }
  .is-game .result-actions { gap: 8px; }
  .is-game .card--tight { padding: 8px 12px; }
  .is-game .card { padding: 12px 14px; }
  .is-game .card__label { font-size: 0.8rem; }
  .is-game .scroll-region { min-height: clamp(88px, 16dvh, 260px); }
}

/* ---- accessibility & motion ---------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* Larger phones and tablets get a little more breathing room. */
@media (min-width: 480px) {
  :root { --page-pad: 24px; }
  body { font-size: 18px; }
}

@media print {
  body { background: #fff; color: #000; }
  .btn, .admin__bar, .admin__nav, .mute-toggle { display: none !important; }
}

/* =====================================================================
   لوحة الألعاب — the platform dashboard
   ---------------------------------------------------------------------
   Square cards on a fixed two-column grid. There is one game today; the
   layout is built so the second and third drop in without a redesign.
   ===================================================================== */

.dash-bar { margin-bottom: 2px; }

.game-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.game-card {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  /* Square, so the grid reads as a wall of tiles rather than a list. */
  aspect-ratio: 1 / 1;
  padding: 14px 12px;
  /* 2px gold at 55% — the identity's game-card rule. */
  border: 2px solid var(--kh-border-gold);
  border-radius: var(--kh-radius-lg);
  /* The game's own gradient, from its data-game attribute and nowhere else.
     A card with no game (an empty slot) falls back to the platform panel. */
  background: var(--kh-game-grad, var(--kh-grad-panel));
  box-shadow: var(--kh-shadow-md);
  color: var(--kh-text-on-dark);
  text-align: center;
  transition: transform 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease;
}
/* The weave, inside the card, under the words. */
.game-card::before {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0.10;
  pointer-events: none;
  background-image: url('../KHAIMA-VISUAL-IDENTITY/brand/patterns/pattern-amazigh-diamond.svg');
  background-size: 120px 120px;
}
.game-card > * { position: relative; }
a.game-card:hover, a.game-card:focus-visible {
  text-decoration: none;
  border-color: var(--kh-gold);
  transform: translateY(-2px);
  box-shadow: var(--kh-shadow-lg);
}
a.game-card:active { transform: scale(0.985); }

/* ---- a card that is a button --------------------------------------
   One game is entered by POST rather than followed as a link, so its
   card is a <button> inside a <form>. Everything above is written for
   an anchor and stays exactly as it is; these rules only give the
   button the same starting point and the same behaviour.

   The form is the grid item and the button fills it, rather than the
   form using display:contents — which removes the element from the
   accessibility tree in some browsers, and a form is not a wrapper
   that should disappear. */
.game-card-form { display: block; }

button.game-card {
  /* A button brings a font, a background, a border and a text
     alignment of its own; .game-card already states the last three, so
     only the font and the box need saying. */
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  font: inherit;
  cursor: pointer;
}

button.game-card:hover, button.game-card:focus-visible {
  border-color: var(--kh-gold);
  transform: translateY(-2px);
  box-shadow: var(--kh-shadow-lg);
}
button.game-card:active { transform: scale(0.985); }

.game-card__emoji { font-size: clamp(26px, 7.5vw, 38px); line-height: 1; }
.game-card__title {
  font-family: var(--kh-font-display);
  font-weight: 700;
  font-size: 1.06rem;
  overflow-wrap: anywhere;
}
.game-card__sub   { font-size: 0.78rem; color: var(--kh-text-on-dark-muted); }
/* Gold, because on a game card the action is the platform speaking, not the
   game — the same reason the kicker above it stays gold. */
.game-card__action {
  margin-top: 4px;
  padding: 5px 16px;
  border-radius: var(--kh-radius-pill);
  background: var(--kh-grad-gold);
  font-family: var(--kh-font-display);
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--kh-text-on-gold);
}

/* A card with nothing behind it yet must not look tappable. */
.game-card--soon {
  border-style: dashed;
  border-color: var(--kh-border-on-dark);
  background: var(--kh-surface-dark);
  color: var(--kh-text-on-dark-muted);
  box-shadow: none;
}
.game-card--soon::before { opacity: 0.04; }
.game-card--soon .game-card__emoji { filter: grayscale(1); opacity: 0.55; }

.dash-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 18px;
  font-size: 0.87rem;
}
.dash-links a { color: var(--text-mute); }

/* =====================================================================
   عدد الأدوار — the segmented rounds picker
   ===================================================================== */

.segmented {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.segment { flex: 1 1 auto; position: relative; }
/* The input covers its own label rather than collapsing to a zero-size box
   somewhere else on the page: the tap target is the whole segment, and the
   focus ring lands where the control actually is. */
.segment input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.segment span {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  font-weight: 700;
  color: var(--text-dim);
  white-space: nowrap;
  cursor: pointer;
}
.segment input:checked + span {
  border-color: transparent;
  background: var(--grad-brand);
  color: #fff;
}
.segment input:focus-visible + span { outline: 3px solid var(--gold); outline-offset: 3px; }

/* =====================================================================
   خصم النقاط — the wrong-answer checklist
   ---------------------------------------------------------------------
   The same row as the ballot, with a box instead of a dot: one control the
   whole game over, so nobody has to learn a second one.
   ===================================================================== */

.choice__box {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border: 2px solid var(--border-2);
  border-radius: 7px;
  position: relative;
}
.choice__box::after {
  content: '✓';
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 0.9rem;
  font-weight: 900;
  color: #fff;
  transform: scale(0);
  transition: transform 0.12s ease;
}
.choice--check:has(input:checked) .choice__box {
  border-color: var(--danger);
  background: var(--danger);
}
.choice--check:has(input:checked) .choice__box::after { transform: scale(1); }
.choice--check:has(input:checked) { border-color: rgba(251, 113, 133, 0.55); }
.is-game .choice__box { width: clamp(20px, 3dvh, 24px); height: clamp(20px, 3dvh, 24px); }

/* =====================================================================
   قائمة الكلمات في التخمين الأخير
   ---------------------------------------------------------------------
   Every word in the category, as buttons. Tapping one IS the answer, so
   they are sized as touch targets first and text second, and the frame
   scrolls internally like the ballot does.
   ===================================================================== */

.word-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 8px;
  align-content: start;
}
.word-option {
  min-height: 48px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  font-family: inherit;
  font-size: 0.98rem;
  font-weight: 700;
  color: var(--text);
  cursor: pointer;
  overflow-wrap: anywhere;
}
.word-option:hover, .word-option:focus-visible {
  border-color: var(--brand-2);
  background: var(--surface);
}
.word-option:active { transform: scale(0.97); }
.is-game .word-grid { min-height: clamp(120px, 26dvh, 340px); }
.is-game .word-option { min-height: clamp(42px, 6.4dvh, 52px); font-size: clamp(0.9rem, 2dvh, 1rem); }

/* The countdown shares the screen with the word list now, so it gives up
   most of its height rather than owning the column. */
.is-game .countdown--inline .countdown__ring {
  width: clamp(76px, 13dvh, 112px);
  height: clamp(76px, 13dvh, 112px);
}
.countdown--inline .countdown__num { font-size: clamp(1.4rem, 5dvh, 2.2rem); }

/* =====================================================================
   إنهاء الجولة — the end-round control and its confirmation
   ---------------------------------------------------------------------
   It sits in the progress header, where it costs no height at all: in the
   page flow it took ~30px from every gameplay screen, and a twelve-player
   ballot has none to give.
   ===================================================================== */

.end-round__open {
  flex: 0 0 auto;
  padding: 3px 10px;
  border: 1px dashed var(--border-2);
  border-radius: var(--radius-pill);
  background: transparent;
  font-family: inherit;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--text-mute);
  white-space: nowrap;
  cursor: pointer;
}
.end-round__open:hover { color: var(--danger); border-color: var(--danger); }

/* The wrong-answer screen puts both buttons on one row; each half must fill
   its share, including the one wrapped in its own form. */
.penalty-actions { flex: 0 0 auto; align-items: stretch; }
.penalty-actions > * { flex: 1 1 0; min-width: 0; }
.penalty-actions form { display: flex; }

.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(4, 3, 12, 0.78);
}
.modal[hidden] { display: none; }
.modal__panel {
  width: min(420px, 100%);
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 22px;
  border: 1px solid var(--border-2);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
  text-align: center;
}
.modal__title { margin: 0; font-size: 1.25rem; }
.modal__body  { margin: 0; color: var(--text-dim); }
.modal__confirm { flex: 1 1 auto; display: flex; }
.modal__confirm .btn { width: 100%; }

/* ---------------------------------------------------------------------
   فحص الصوت — the audio check's log.

   Monospaced digits and a fixed height, because this is read as a list of
   observations rather than as prose: the eye should be able to run down
   the left edge and find the one ❌ among twenty ✅.
   --------------------------------------------------------------------- */
.ac-log {
  max-height: 55vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 0.85rem;
  line-height: 1.45;
}
.ac-row {
  display: grid;
  grid-template-columns: 1.4rem 1fr auto;
  gap: 8px;
  align-items: baseline;
  padding: 4px 6px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.03);
}
.ac-row--bad { background: rgba(220, 60, 60, 0.14); }
.ac-row--ok  { background: rgba(60, 190, 120, 0.10); }
.ac-text { word-break: break-word; }
.ac-ms {
  font-variant-numeric: tabular-nums;
  opacity: 0.55;
  font-size: 0.78rem;
  direction: ltr;
}

/* =====================================================================
   منصور و عادل — the platform's brand characters
   ---------------------------------------------------------------------
   Static images. No rig, no animation, no controller, no selection. They
   support the message and never become it: the hierarchy is الخيمة, then
   the interface, then the character.

   Every rule here exists to keep a guideline:
     * height-constrained with width:auto     — proportions are locked
     * bottom-anchored, inline side           — never centred behind content
     * pointer-events:none                    — never eats a tap
     * z-index below the content              — never covers a control
     * no filter, no blend, no non-uniform scale — the art is not ours to edit
     * hidden when the viewport is short      — the one-screen rule wins
   ===================================================================== */
.kh-figure {
  position: fixed;
  bottom: 0;
  z-index: 0;
  /* Height drives, width follows. `max-width: none` is the load-bearing
     part: the global `img { max-width: 100% }` clamps the width while the
     height is held, and the figure comes out squashed — measured at 390x300
     against a 379x1200 source. Non-uniform scaling is one of the things the
     identity forbids outright, so the clamp has to be lifted here. */
  width: auto;
  max-width: none;
  pointer-events: none;
  user-select: none;
  /* The only treatment the identity permits, so the figure sits on the
     ground instead of floating on it. */
  filter: drop-shadow(0 12px 26px rgba(0, 0, 0, 0.45));
}
.kh-figure--end   { inset-inline-end: 0; }
.kh-figure--start { inset-inline-start: 0; }

/* Sizes are heights. The full figure never goes below 90px WIDE, and these
   renders are roughly 1:3, so 300px of height is the floor for a web crop. */
.kh-figure--sm.kh-figure--web { height: 300px; }
.kh-figure--md.kh-figure--web { height: 380px; }
.kh-figure--lg.kh-figure--web { height: 460px; }
.kh-figure--sm.kh-figure--bust { height: 84px; }
.kh-figure--md.kh-figure--bust { height: 110px; }
.kh-figure--lg.kh-figure--bust { height: 150px; }

/* The content always wins. Anything in the page flow sits above the figure,
   so a character can never cover a headline, a score, a timer or a button.

   The figure itself is excluded, and that exclusion is load-bearing: this
   selector is more specific than `.kh-figure`, so without :not() it turned
   the figure's `position: fixed` back into `relative`, dropped it into the
   flow, and let it stretch to the column width while its height was held —
   which is exactly the non-uniform scaling the identity forbids. It rendered
   at 512x300 against a 379x1200 source until this was fixed. */
.page > *:not(.kh-figure) { position: relative; z-index: 1; }

/* A short phone in landscape, or a small screen with a long form: the
   decoration goes before the layout does. */
@media (max-height: 700px) {
  .kh-figure--web { height: 250px; opacity: 0.9; }
}
@media (max-height: 600px) {
  .kh-figure { display: none; }
}

/* On a narrow phone the figure must not eat the column. Reduce the HEIGHT —
   the width follows it — rather than clamping the width, which is what
   distorts a replaced element. */
@media (max-width: 420px) {
  .kh-figure--web { height: 240px; }
}

/* Gameplay is one viewport with no scrolling anywhere. A character is
   welcome on a result screen only while it costs the layout nothing, so
   it is opt-in per screen and never global. */
.is-game .kh-figure { opacity: 0.85; }

@media (prefers-reduced-motion: reduce) {
  .kh-figure { filter: none; }
}

/* The emblem used as a hero mark, on the two screens that introduce the
   platform rather than sit inside it. */
.brand__lockup {
  width: clamp(84px, 26vw, 116px);
  height: auto;
  margin-inline: auto;
  display: block;
}


/* =====================================================================
   Tap targets — the identity's floor is 48x48 and these were under it
   ---------------------------------------------------------------------
   Measured, not guessed: a browser pass over every screen reported the
   dashboard's footer links at 23px tall, the setup screens' remove-player
   button at 44px, and the admin menu at 44px. None of them were reachable
   comfortably with a thumb, and all three are used constantly.
   ===================================================================== */
.dash-links a {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding-inline: var(--kh-space-3);
}

.name-row__drop {
  min-width: 48px;
  min-height: 48px;
}

.admin__nav a {
  min-height: 48px;
  display: inline-flex;
  align-items: center;
}

/* The form controls on the setup screens were coming out at 46px because a
   local height beat the component's own minimum. */
.kh-input,
.input, .textarea, .select {
  min-height: 48px;
}

/* The brand in the admin bar is a link; give it the same floor. */
a.brand { min-height: 48px; display: inline-flex; align-items: center; }

/* The remaining sub-48px targets a browser pass found: inline text links in
   the admin lists and under the auth forms, and the bare checkboxes, which
   never had a class and so were never part of the input component. */
a.small,
.center.small.muted,
.dash-links a,
.detail a {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
}

/* A native checkbox is 13x13 and cannot be resized by the component layer,
   so it gets a real target of its own. */
input[type="checkbox"] {
  width: 26px;
  height: 26px;
  margin: 11px;
  accent-color: var(--kh-gold);
  cursor: pointer;
}
