/* Componentes del Design System de x-p, portados a HTML/CSS plano.

   Fuente: components/core/*.jsx y components/match/*.jsx del paquete de
   Claude Design (verificado 20/09/2026). Los .jsx llevan los estilos en
   línea; aquí son las mismas reglas convertidas en clases con prefijo
   `xb-`, para no chocar con las clases de la app antigua (.modal-*,
   .badge, .btn...), que no se tocan. Todo sale de tokens/*.css: nada de
   colores sueltos. Los px que no tienen token (15px del contador, 56px de
   la ficha, 520px del modal...) son los mismos valores que el .jsx.

   Estados comunes (README del sistema):
   - pressed: scale(var(--press-scale)) en var(--duration-fast).
   - seleccionado/activo: clase `.is-active` (o `.is-selected` en fichas).
   - deshabilitado: opacidad .4, cursor normal.
   - foco de teclado: outline 2px --surface-accent, offset 2px (aquí
     explícito, para que funcione también fuera de `.xb-screen`).

   Marcado (todo lo que no es obvio va comentado junto a cada componente).
   Los componentes fijan su propia fuente y color: se ven igual dentro y
   fuera de `.xb-screen`. */

.xb-btn:focus-visible,
.xb-icon-btn:focus-visible,
.xb-input:focus-visible,
.xb-segmented__item:focus-visible,
.xb-modal__close:focus-visible,
.xb-player-chip:focus-visible,
.xb-zone-legend__item:focus-visible {
  outline: 2px solid var(--surface-accent);
  outline-offset: 2px;
}

/* --- Button ---------------------------------------------------------------
   <button type="button" class="xb-btn xb-btn--primary">Entrar</button>
   Variantes: --primary (una por pantalla) | (ninguna = secundario) |
   --ghost | --danger | --success (empezar partido) | --live (rojo, partido
   en curso). Tamaños: (md, 44px) | --sm (36px) | --compact (36px, botonera).
   --block = ancho completo. `.is-active` = modo de anotación seleccionado. */
.xb-btn {
  font-family: var(--font-heading);
  letter-spacing: var(--tracking-label);
  min-height: var(--hit-target);
  padding: var(--space-4) var(--space-7);
  font-size: var(--text-base);
  background: var(--surface-raised);
  color: var(--text-body);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-sm);
  cursor: pointer;
  touch-action: manipulation;
  transition:
    background var(--duration-fast) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard);
}
.xb-btn:active:not(:disabled) { transform: scale(var(--press-scale)); }
.xb-btn:disabled { opacity: 0.4; cursor: default; }
.xb-btn--block { width: 100%; }

.xb-btn--primary {
  background: var(--surface-accent);
  border-color: var(--surface-accent);
  color: var(--text-inverse);
  font-weight: var(--weight-bold);
}
.xb-btn--ghost { background: transparent; }
.xb-btn--danger {
  background: transparent;
  border-color: var(--state-danger);
  color: var(--state-danger);
}
.xb-btn--success {
  background: var(--state-ok);
  border-color: var(--state-ok);
  color: var(--surface-page);
  font-weight: var(--weight-bold);
}
.xb-btn--live {
  background: var(--match-live);
  border-color: var(--match-live);
  color: var(--surface-page);
  font-weight: var(--weight-bold);
}

.xb-btn--sm {
  min-height: var(--hit-target-compact);
  font-size: var(--text-sm);
  padding: var(--space-3) var(--space-5);
}
.xb-btn--compact {
  min-height: var(--hit-target-compact);
  font-size: var(--text-xs);
  padding: 5px var(--space-3);
}

/* Después de las variantes: `.is-active` gana siempre. */
.xb-btn.is-active {
  background: var(--surface-accent);
  border-color: var(--surface-accent);
  color: var(--text-inverse);
  font-weight: var(--weight-bold);
}

/* --- IconButton -----------------------------------------------------------
   <button type="button" class="xb-icon-btn" title="Plantilla" aria-label="Plantilla">👥</button>
   Siempre con title + aria-label: no hay etiqueta visible. Contador opcional:
   <span class="xb-icon-btn__badge">3</span> dentro del botón. */
.xb-icon-btn {
  position: relative;
  min-width: var(--hit-target-compact);
  min-height: var(--hit-target-compact);
  padding: var(--space-2) var(--space-4);
  font-size: 1.05rem;
  line-height: 1;
  font-family: var(--font-heading);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  color: var(--text-body);
  cursor: pointer;
  touch-action: manipulation;
  transition:
    background var(--duration-fast) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard);
}
.xb-icon-btn:active:not(:disabled) { transform: scale(var(--press-scale)); }
.xb-icon-btn:disabled { opacity: 0.4; cursor: default; }
.xb-icon-btn.is-active {
  border-color: var(--surface-accent);
  background: var(--surface-accent);
  color: var(--text-inverse);
}
.xb-icon-btn__badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 15px;
  padding: 0 3px;
  border-radius: var(--radius-pill);
  background: var(--surface-accent);
  color: var(--text-inverse);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  line-height: 15px;
  text-align: center;
}

/* --- Badge ----------------------------------------------------------------
   <span class="xb-badge xb-badge--live">En curso</span>
   Tonos: (neutral) | --live | --ready | --scheduled | --done | --warn.
   `--plain` = borde gris en vez del color del tono (outlined=false). */
.xb-badge {
  --_tone: var(--text-muted);
  display: inline-block;
  font-family: var(--font-heading);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-label);
  padding: var(--space-1) var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--_tone);
  color: var(--_tone);
  white-space: nowrap;
}
.xb-badge--live { --_tone: var(--match-live); }
.xb-badge--ready { --_tone: var(--match-ready); }
.xb-badge--scheduled { --_tone: var(--match-scheduled); }
.xb-badge--done { --_tone: var(--match-done); }
.xb-badge--warn { --_tone: var(--state-warn); }
.xb-badge--plain { border-color: var(--border-hairline); }

/* --- Card -----------------------------------------------------------------
   <section class="xb-card blueprint">
     <i class="corner tl"></i><i class="corner tr"></i>
     <i class="corner bl"></i><i class="corner br"></i>
     <header class="xb-card__header">
       <h2 class="xb-card__title">Quinteto en pista</h2>
       <button class="xb-btn xb-btn--sm">Cambio</button>   (acción opcional)
     </header>
     …contenido…
   </section>
   `.blueprint` y las cuatro esquinas vienen de tokens/base.css. */
.xb-card {
  background: var(--surface-card);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-7);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.xb-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
}
/* `.xb-card` delante: sube la especificidad para ganar a `.xb-screen h2`
   (tokens/base.css), como gana el estilo en línea del .jsx original. */
.xb-card .xb-card__title {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  font-size: var(--text-base);
  color: var(--text-muted);
}

/* --- Field + Input --------------------------------------------------------
   <label class="xb-field">Correo
     <input class="xb-input" type="email" placeholder="entrenador@club.es">
     <span class="xb-field__hint">Ayuda</span>        (o)
     <span class="xb-field__error">Error</span>
   </label> */
.xb-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.xb-field__hint { font-size: var(--text-sm); }
.xb-field__error { font-size: var(--text-sm); color: var(--state-danger); }
.xb-input {
  min-height: var(--hit-target);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  color: var(--text-body);
  font-family: var(--font-body);
  font-size: var(--text-md);
  padding: var(--space-4) var(--space-5);
}

/* --- SegmentedControl -----------------------------------------------------
   <div class="xb-segmented" role="group">
     <button type="button" class="xb-segmented__item is-active" aria-pressed="true" title="Vertical">▯</button>
     <button type="button" class="xb-segmented__item" aria-pressed="false" title="Horizontal">▭</button>
   </div>
   `xb-segmented--md` sube los botones a 44px (por defecto 36px). */
.xb-segmented { display: flex; gap: var(--space-3); }
.xb-segmented__item {
  font-family: var(--font-heading);
  min-height: var(--hit-target-compact);
  padding: var(--space-1) var(--space-5);
  font-size: var(--text-base);
  line-height: 1;
  font-weight: var(--weight-semibold);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-sm);
  background: var(--surface-raised);
  color: var(--text-body);
  cursor: pointer;
  touch-action: manipulation;
}
.xb-segmented--md .xb-segmented__item { min-height: var(--hit-target); }
.xb-segmented__item.is-active {
  border-color: var(--surface-accent);
  background: var(--surface-accent);
  color: var(--text-inverse);
  font-weight: var(--weight-bold);
}

/* --- StatTable ------------------------------------------------------------
   <table class="xb-stat-table">
     <thead><tr><th class="is-left">Jugador</th><th title="Valoración FIBA">VAL</th></tr></thead>
     <tbody><tr>
       <td class="is-left is-text">#21 Aguado</td>
       <td><span class="xb-stat-mark xb-stat-mark--best">19</span></td>
     </tr></tbody>
   </table>
   Por defecto todo va a la derecha y en cifras (--font-num, tabular-nums).
   `.is-left` alinea a la izquierda; `.is-text` usa la fuente de cuerpo
   (nombres). Mejor/peor del equipo: `.xb-stat-mark--best` / `--worst`. */
.xb-stat-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--text-body);
}
.xb-stat-table th,
.xb-stat-table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border-width) solid var(--border-hairline);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.xb-stat-table th {
  font-family: var(--font-heading);
  font-weight: var(--weight-bold);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  background: var(--surface-raised);
}
.xb-stat-table td { font-family: var(--font-num); }
.xb-stat-table .is-left { text-align: left; }
.xb-stat-table td.is-text { font-family: var(--font-body); }
.xb-stat-mark {
  padding: 1px var(--space-3);
  font-weight: var(--weight-bold);
}
.xb-stat-mark--best { background: var(--stat-best-bg); color: var(--stat-best-ink); }
.xb-stat-mark--worst { background: var(--stat-worst-bg); color: var(--stat-worst-ink); }

/* --- Modal ----------------------------------------------------------------
   <div class="xb-modal-scrim">
     <div class="xb-modal" role="dialog" aria-modal="true" aria-labelledby="t">
       <header class="xb-modal__header">
         <h2 class="xb-modal__title" id="t">¿Ataque o defensa?</h2>
         <button type="button" class="xb-modal__close" aria-label="Cerrar">✕</button>
       </header>
       <p class="xb-modal__hint">Rebote de #21 Aguado</p>
       <div class="xb-modal__options">…botones xb-btn--block…</div>  (rejilla de 2 columnas iguales)
       …contenido…
       <div class="xb-modal__actions">…</div>
     </div>
   </div>
   Es el ÚNICO elemento con sombra del sistema. Cerrar al tocar el velo lo
   cablea cada pantalla (no hay JS aquí). */
.xb-modal-scrim {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: var(--scrim);
  display: grid;
  place-items: center;
  padding: var(--space-8);
}
/* Sin esto, el `hidden` del HTML no basta: `display: grid` de arriba gana
   por ser regla de autor (pesa más que el `[hidden]{display:none}` del user
   agent), así que el modal se vería siempre abierto en cuanto tuviera
   contenido. Mismo fallo que ya resuelve `.modal-overlay[hidden]` en el
   sistema antiguo (style.css) -- aquí faltaba, corregido 21/09/2026 al
   migrar los primeros modales reales (Novedades, Cuenta) a estas clases. */
.xb-modal-scrim[hidden] {
  display: none;
}
.xb-modal {
  width: min(520px, 100%);
  max-height: 86vh;
  overflow-y: auto;
  background: var(--surface-card);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-8);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  color: var(--text-body);
  font-family: var(--font-body);
}
.xb-modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  /* Arrastre por cabecera (01-core.js, genérico para cualquier modal de la
     app, viejo o migrado -- ver comentario junto a `.modal-header` en
     style.css): mismo cursor y bloqueo de gestos táctiles/selección que su
     equivalente antiguo, para que no cambie de comportamiento al migrar un
     modal a estas clases. */
  cursor: grab;
  touch-action: none;
  user-select: none;
}
.xb-modal__header:active { cursor: grabbing; }
/* Variantes anchas (21/09/2026), adición propia de XBasket: el modal del
   sistema es de 520px, pero dos modales de la app no caben ahí.
   `--wide` (640px): formularios con varias columnas, como "Generar propuesta
   de planificación". `--table` (hasta 1100px): tablas de muchas columnas,
   como el box score de "Estadísticas" de un partido. */
.xb-modal--wide { width: min(640px, 100%); }
.xb-modal--table { width: min(1100px, 100%); }

/* Igual que `.xb-card__title`: `.xb-modal` delante para ganar a `.xb-screen h2`. */
.xb-modal .xb-modal__title {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  font-size: var(--text-lg);
  color: var(--text-body);
}
.xb-modal__close {
  min-height: var(--hit-target-compact);
  min-width: var(--hit-target-compact);
  background: transparent;
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
}
.xb-modal__hint { margin: 0; font-size: var(--text-sm); color: var(--text-muted); }
.xb-modal__options {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
}
.xb-modal__actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

/* --- AlertBar -------------------------------------------------------------
   <div class="xb-alert xb-alert--danger" role="status">
     <span aria-hidden="true">🚩</span>
     <span class="xb-alert__text">BONUS — 5 faltas de equipo en el C3</span>
     <span class="xb-alert__action"><button class="xb-btn xb-btn--sm">Reintentar</button></span>  (opcional)
   </div>
   Tonos e icono por defecto: --info ℹ | --warn ⚠ | --danger 🚩 | --ok ✓ |
   --offline ⛔. Va SIEMPRE dentro del flujo, nunca flotante: en pista el
   anotador no puede perseguir un mensaje que se va solo. */
.xb-alert {
  --_tone: var(--state-info);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-5);
  background: var(--surface-raised);
  border: var(--border-width) solid var(--border-hairline);
  border-left: 3px solid var(--_tone);
  border-radius: var(--radius-sm);
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-label);
  color: var(--_tone);
}
.xb-alert--warn { --_tone: var(--state-warn); }
.xb-alert--danger { --_tone: var(--state-danger); }
.xb-alert--ok { --_tone: var(--state-ok); }
.xb-alert--offline { --_tone: var(--state-danger); }
.xb-alert__text { color: var(--text-body); }
.xb-alert__action { margin-left: auto; }

/* --- PlayerChip -----------------------------------------------------------
   <button type="button" class="xb-player-chip is-selected">
     <span class="xb-player-chip__dorsal">21</span>
     <span class="xb-player-chip__name">Aguado</span>
     <span class="xb-player-chip__stats">14 pts · <span class="xb-player-chip__fouls">2F</span> · 26′</span>
   </button>
   Estados: `.is-selected` | `.is-entra` (verde sólido) | `.is-sale` (rojo
   sólido) | `.is-bench` (jugador en banquillo, opacidad .8).
   Faltas: `.is-warn` en __fouls con 3 (ámbar, negrita) | `.is-limit` con 4+
   (rojo, negrita). Con entra/sale las faltas heredan el color de la ficha. */
.xb-player-chip {
  min-height: 56px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  padding: var(--space-3) var(--space-2);
  /* Fuente de cuerpo explícita: un <button> no hereda la del contenedor, y
     en el .jsx original el nombre acababa en la fuente por defecto del
     navegador. Aquí va en Barlow, como el resto del texto pequeño. */
  font-family: var(--font-body);
  background: var(--surface-card);
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-md);
  color: var(--text-body);
  cursor: pointer;
  touch-action: manipulation;
}
.xb-player-chip.is-selected {
  background: var(--surface-accent-soft);
  border-color: var(--surface-accent);
}
.xb-player-chip.is-entra { background: var(--state-ok); border-color: var(--state-ok); }
.xb-player-chip.is-sale { background: var(--state-danger); border-color: var(--state-danger); }
.xb-player-chip.is-bench { opacity: 0.8; }
.xb-player-chip__dorsal {
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-body);
}
.xb-player-chip__name {
  font-size: var(--text-2xs);
  color: var(--text-muted);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.xb-player-chip__stats {
  font-family: var(--font-num);
  font-size: var(--text-2xs);
  margin-top: var(--space-1);
  color: var(--text-muted);
}
.xb-player-chip__fouls { font-weight: var(--weight-regular); color: var(--text-muted); }
.xb-player-chip__fouls.is-warn { color: var(--foul-warn); font-weight: var(--weight-bold); }
.xb-player-chip__fouls.is-limit { color: var(--foul-limit); font-weight: var(--weight-bold); }
.xb-player-chip.is-entra .xb-player-chip__dorsal,
.xb-player-chip.is-entra .xb-player-chip__name,
.xb-player-chip.is-entra .xb-player-chip__stats,
.xb-player-chip.is-entra .xb-player-chip__fouls,
.xb-player-chip.is-sale .xb-player-chip__dorsal,
.xb-player-chip.is-sale .xb-player-chip__name,
.xb-player-chip.is-sale .xb-player-chip__stats,
.xb-player-chip.is-sale .xb-player-chip__fouls {
  color: var(--surface-page);
}

/* --- ZoneLegend -----------------------------------------------------------
   <div class="xb-zone-legend">
     <button type="button" class="xb-zone-legend__item is-active">
       <span class="xb-zone-legend__swatch xb-zone-legend__swatch--codo"></span>Codo
     </button> …
   </div>
   Orden canónico (del aro hacia fuera): aro, pintura, codo, tlibre, media,
   fondo, arriba-llave, ala, esquina, fuera-rango. El color del cuadrito
   sale de --zona-*; no se elige a mano. Como leyenda pasiva, usar <span> en
   vez de <button> (sin cursor de mano). */
.xb-zone-legend { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.xb-zone-legend__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  min-height: var(--hit-target-compact);
  background: transparent;
  border: var(--border-width) solid var(--border-hairline);
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--text-body);
  cursor: pointer;
}
span.xb-zone-legend__item { cursor: default; }
.xb-zone-legend__item.is-active {
  background: var(--surface-raised);
  border-color: var(--surface-accent);
}
.xb-zone-legend__swatch {
  width: 12px;
  height: 12px;
  background: var(--zona-aro);
  opacity: var(--zona-opacity);
}
.xb-zone-legend__swatch--aro { background: var(--zona-aro); }
.xb-zone-legend__swatch--pintura { background: var(--zona-pintura); }
.xb-zone-legend__swatch--codo { background: var(--zona-codo); }
.xb-zone-legend__swatch--tlibre { background: var(--zona-tlibre); }
.xb-zone-legend__swatch--media { background: var(--zona-media); }
.xb-zone-legend__swatch--fondo { background: var(--zona-fondo); }
.xb-zone-legend__swatch--arriba-llave { background: var(--zona-arriba-llave); }
.xb-zone-legend__swatch--ala { background: var(--zona-ala); }
.xb-zone-legend__swatch--esquina { background: var(--zona-esquina); }
.xb-zone-legend__swatch--fuera-rango {
  background: var(--zona-fuera-rango);
  opacity: var(--zona-opacity-fuera);
}
