/* ==========================================================================
   GestionaClubs — Design tokens + componentes base
   Compartido por la app de familias (/app), la del entrenador (/entrenador)
   y el panel del gestor (/panel).

   Tema oscuro por defecto; claro con <html data-theme="light">.

   Misma convención que el resto del ecosistema (variables CSS --bg-card,
   --accent…), de modo que los cuatro productos puedan unificarse: si
   sustituyes los valores de :root por los de otro, todo se reviste solo.

   EL ACENTO SALE DEL LOGO: el rojo oscuro #9e1116. Cada producto del
   ecosistema comparte esta misma hoja y solo cambia su acento —azul en
   GestionaPublica, verde en GestionaAccesos, rojo aquí—, de modo que los
   cuatro se ven hermanos sin confundirse.

   POR QUÉ EL ACENTO NO ES EXACTAMENTE EL COLOR DEL LOGO EN TEMA OSCURO.
   El #9e1116 sobre el azul oscuro del fondo da 2:1 de contraste: un enlace en
   ese rojo no se leería. Así que el tema oscuro usa un rojo más claro de la
   misma familia (#e5545b, 4,9:1) y el tema claro sí usa el rojo exacto del
   logo (7,7:1 sobre blanco). La marca es la misma; lo que cambia es cuánta luz
   hace falta para leerla. Es la misma regla que sigue GestionaPublica con su
   amarillo: el logotipo lleva --brand y todo lo demás, --accent.

   Y POR QUÉ «PELIGRO» YA NO ES ROJO. Con la marca en rojo, un botón de
   eliminar rojo y un botón primario rojo son el mismo botón: el rojo deja de
   significar nada. Los avisos bajan un escalón en la rampa del semáforo:

       marca = rojo · peligro = naranja · atención = amarillo

   Tres señales que se distinguen de un vistazo, que es para lo que están.

   El degradado de marca (--brand-grad) se reserva para la marca: el escudo
   del login, la cabecera de la app y poco más. Un degradado repetido en cada
   botón cansa la vista y deja de significar nada.
   ========================================================================== */

:root {
  /* El navegador pinta el lienzo con este color ANTES de aplicar la hoja de
     estilos. Sin él pinta blanco, y en tema oscuro se ve un fogonazo blanco
     en cada navegación —y el revés en claro—. También tiñe barras de scroll,
     controles nativos y campos de formulario. */
  color-scheme: dark;

  /* --- Superficies ---
     LAS MISMAS QUE GESTIONAFITNESS Y GESTIONAPUBLICA: azul oscuro de base en
     lugar del negro grisáceo. Es lo que hace que los cuatro productos se vean
     de la misma casa aunque cada uno lleve su acento.

     Y no son cuatro grises sueltos, es un sistema: las TARJETAS no tienen
     color propio, son blanco a muy baja opacidad sobre ese azul. Por eso se
     ven como el mismo material esté la tarjeta donde esté —sobre el fondo,
     dentro de un modal o dentro de otra tarjeta— y por eso aquí NO valen
     colores sólidos.

     La excepción: todo lo que tenga que TAPAR contenido al desplazarse
     —cabeceras fijas de tabla, barra superior, cajón, modales, desplegables—
     usa --bg-elev, que sí es opaco. Con una tarjeta translúcida se vería el
     contenido pasando por debajo. */
  --bg:            #111827;
  --bg-elev:       #18202e;
  --bg-card:       rgba(255, 255, 255, .055);
  --bg-card-hover: rgba(255, 255, 255, .09);
  --bg-input:      rgba(255, 255, 255, .075);
  --bg-overlay:    rgba(9, 14, 26, .72);

  /* --- Bordes y líneas ---
     También translúcidos: sobre el azul se funden solos y no hace falta
     recalcularlos cuando una tarjeta va encima de otra. */
  --border:        rgba(255, 255, 255, .11);
  --border-soft:   rgba(255, 255, 255, .04);
  --border-strong: rgba(255, 255, 255, .22);

  /* --- Texto --- */
  --text:          #f1f5f9;
  --text-soft:     #94a3b8;
  /* Un punto más claro que el gris de GestionaFitness: aquí lo llevan los
     avisos y la letra pequeña, y aquel se queda corto sobre el fondo nuevo. */
  --text-muted:    #7c8aa0;

  /* --- Marca (del logo) --- */
  --brand:         #9e1116;   /* el rojo exacto del logo */
  --brand-deep:    #7d0d11;
  --brand-light:   #e04b52;   /* el mismo rojo con luz, para fondos oscuros */
  --brand-grad:    linear-gradient(120deg, var(--brand-deep), var(--brand-light));

  /* El mismo degradado, pero para TEXTO sobre el azul oscuro. El extremo
     profundo del logo (#7d0d11) tiene sobre el fondo el mismo contraste que
     el propio fondo: en un titular grande la primera mitad de la palabra
     quedaría en blanco. Así que en oscuro el degradado se sube entero al rojo
     con luz y se abre hacia un rosa claro —es lo que hace GestionaFitness con
     su morado: tres tonos claros, no uno oscuro—, y en claro vuelve a ser el
     degradado del logotipo tal cual. */
  --brand-grad-text: linear-gradient(120deg, var(--brand-light), #ff9aa2);

  /* Sobre el azul oscuro hace falta un rojo con más luz o los enlaces no se
     leen. Ver la explicación de arriba. Este da 4,9:1 sobre el fondo y 4,5:1
     sobre una tarjeta, con el blanco encima a 3,7:1: pasa como texto y como
     relleno de botón sin irse al salmón. */
  --accent:        #e5545b;
  --accent-hover:  #ea666c;
  --accent-soft:   rgba(229, 84, 91, .16);
  --accent-text:   #ffffff;

  --info:          #3b82f6;
  --info-soft:     rgba(59, 130, 246, .14);
  /* Naranja y amarillo, no rojo: con la marca en rojo, un aviso rojo se
     confunde con un botón primario. */
  --warn:          #eab308;
  --warn-soft:     rgba(234, 179, 8, .15);
  --danger:        #f97316;
  --danger-soft:   rgba(249, 115, 22, .15);
  --purple:        #a855f7;
  --purple-soft:   rgba(168, 85, 247, .14);

  /* --- Paleta de series para gráficas ---
     Aquí el rojo NO es semántico: son series de datos, y una serie roja al
     lado de una naranja es solo eso. La primera es la de la marca. */
  --c1: #e5545b; --c2: #3b82f6; --c3: #eab308; --c4: #a855f7;
  --c5: #14b8a6; --c6: #22d3d8; --c7: #ec4899; --c8: #84cc16;

  /* --- Formas --- */
  --r-sm: 8px;
  --r:    12px;
  --r-lg: 16px;
  --r-xl: 22px;
  --r-pill: 999px;

  /* --- Sombras --- */
  --shadow-sm: 0 1px 2px rgba(0,0,0,.32);
  --shadow:    0 4px 16px rgba(0,0,0,.34);
  --shadow-lg: 0 18px 48px rgba(0,0,0,.48);

  /* --- Tipografía --- */
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

  /* --- Layout --- */
  --topbar-h: 62px;
  --tabbar-h: 64px;
  --maxw: 1440px;
}

html[data-theme="light"] {
  color-scheme: light;

  /* En claro sí son colores sólidos: sobre blanco, una tarjeta translúcida no
     se distinguiría del fondo. Mismos valores que el resto del ecosistema. */
  --bg:            #f8fafc;
  --bg-elev:       #ffffff;
  --bg-card:       #ffffff;
  --bg-card-hover: #f1f5f9;
  --bg-input:      #ffffff;
  --bg-overlay:    rgba(15, 23, 42, .45);

  --border:        #cbd5e1;
  --border-soft:   #e2e8f0;
  --border-strong: #94a3b8;

  --text:          #0f172a;
  --text-soft:     #475569;
  --text-muted:    #8593a5;

  --brand-grad-text: var(--brand-grad);

  /* Sobre blanco sí cabe el rojo exacto del logo: 7,6:1 de contraste. */
  --accent:        #9e1116;
  --accent-hover:  #7d0d11;
  --accent-soft:   rgba(158, 17, 22, .10);
  --accent-text:   #ffffff;

  --warn:          #ca8a04;
  --warn-soft:     rgba(202, 138, 4, .12);
  --danger:        #ea580c;
  --danger-soft:   rgba(234, 88, 12, .12);

  --shadow-sm: 0 1px 2px rgba(16, 24, 40, .06);
  --shadow:    0 4px 16px rgba(16, 24, 40, .08);
  --shadow-lg: 0 18px 48px rgba(16, 24, 40, .16);
}

/* ==========================================================================
   Reset
   ========================================================================== */

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

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

body { min-height: 100vh; }

h1, h2, h3, h4, h5 { margin: 0; font-weight: 650; letter-spacing: -.01em; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }
p  { margin: 0 0 .6rem; }
a  { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
hr { border: 0; border-top: 1px solid var(--border); margin: 1rem 0; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 99px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

/* ==========================================================================
   Utilidades
   ========================================================================== */

.gc-row     { display: flex; align-items: center; gap: 10px; }
.gc-row-b   { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.gc-col     { display: flex; flex-direction: column; gap: 10px; }
.gc-wrap    { flex-wrap: wrap; }
.gc-grow    { flex: 1 1 auto; min-width: 0; }
.gc-center  { text-align: center; }
.gc-right   { text-align: right; }
.gc-mt      { margin-top: 14px; }
.gc-mb      { margin-bottom: 14px; }
.gc-hide    { display: none !important; }
.gc-muted   { color: var(--text-muted); }
.gc-soft    { color: var(--text-soft); }
.gc-small   { font-size: .82rem; }
.gc-xs      { font-size: .74rem; }
.gc-bold    { font-weight: 650; }
.gc-num     { font-variant-numeric: tabular-nums; }
.gc-trunc   { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gc-scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Fila apagada: lo anulado sigue a la vista, pero deja de competir */
.gc-dim     { opacity: .5; }

.gc-ok    { color: var(--accent); }
.gc-err   { color: var(--danger); }
.gc-warnc { color: var(--warn); }
.gc-infoc { color: var(--info); }

/* Texto con el degradado de la marca. Solo para el nombre del producto. */
.gc-brand-text {
  background: var(--brand-grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-weight: 750;
}

/* Desplegable de formulario: para lo que casi nunca se toca y ocupa mucho.
   Con <details> nativo a propósito —abre y cierra sin JavaScript, el teclado
   ya funciona y los campos de dentro siguen en el formulario aunque esté
   cerrado, así que `GC.readForm` los lee igual. */
.gc-details {
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--bg-card); padding: 0 12px;
}
.gc-details > summary {
  cursor: pointer; padding: 11px 0; font-size: .84rem; font-weight: 600;
  color: var(--text-soft); list-style: none;
}
.gc-details > summary::-webkit-details-marker { display: none; }
.gc-details > summary::before { content: "▸ "; color: var(--text-muted); }
.gc-details[open] > summary::before { content: "▾ "; }
.gc-details > summary:hover { color: var(--text); }
.gc-details[open] > summary { border-bottom: 1px solid var(--border); }
.gc-details > :last-child { margin-bottom: 12px; }

/* ==========================================================================
   Botones
   ========================================================================== */

.gc-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 16px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--bg-card);
  color: var(--text);
  font-size: .9rem; font-weight: 600;
  cursor: pointer;
  transition: background .15s, border-color .15s, transform .06s, opacity .15s;
  white-space: nowrap;
  user-select: none;
}
.gc-btn:hover  { background: var(--bg-card-hover); border-color: var(--border-strong); text-decoration: none; }
.gc-btn:active { transform: translateY(1px); }
.gc-btn:disabled, .gc-btn[disabled] { opacity: .45; cursor: not-allowed; transform: none; }

.gc-btn.primary   { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.gc-btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.gc-btn.danger    { background: var(--danger); border-color: var(--danger); color: #fff; }
.gc-btn.danger:hover { filter: brightness(1.08); }
.gc-btn.ghost     { background: transparent; border-color: transparent; color: var(--text-soft); }
.gc-btn.ghost:hover { background: var(--bg-card-hover); color: var(--text); }
.gc-btn.outline   { background: transparent; }
.gc-btn.sm        { padding: 6px 11px; font-size: .8rem; }
.gc-btn.lg        { padding: 13px 22px; font-size: 1rem; }
.gc-btn.block     { width: 100%; }
.gc-btn.icon      { padding: 8px; width: 36px; height: 36px; }

/* ==========================================================================
   Formularios
   ========================================================================== */

.gc-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.gc-label { font-size: .78rem; font-weight: 600; color: var(--text-soft); letter-spacing: .01em; }
.gc-label .req { color: var(--danger); }

.gc-input, .gc-select, .gc-textarea {
  width: 100%;
  padding: 10px 12px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text);
  font-size: .92rem;
  transition: border-color .15s, box-shadow .15s;
  appearance: none;
}
.gc-textarea { min-height: 92px; resize: vertical; line-height: 1.55; }
.gc-select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%237c8aa0' stroke-width='2.5' stroke-linecap='round'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat: no-repeat;
  background-position: right 11px center;
  padding-right: 32px;
}
.gc-input:focus, .gc-select:focus, .gc-textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.gc-input::placeholder, .gc-textarea::placeholder { color: var(--text-muted); }
.gc-input:disabled, .gc-select:disabled, .gc-textarea:disabled { opacity: .55; cursor: not-allowed; }
.gc-input.invalid, .gc-select.invalid, .gc-textarea.invalid { border-color: var(--danger); }

.gc-hint { font-size: .74rem; color: var(--text-muted); }
.gc-err-msg { font-size: .74rem; color: var(--danger); }

.gc-grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 12px; }
.gc-grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 12px; }
.gc-grid-4 { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 12px; }
@media (max-width: 780px) {
  .gc-grid-2, .gc-grid-3, .gc-grid-4 { grid-template-columns: 1fr; }
}

/* checkbox / switch */
.gc-check { display: flex; align-items: flex-start; gap: 9px; cursor: pointer; font-size: .86rem; color: var(--text-soft); }
.gc-check input { width: 17px; height: 17px; accent-color: var(--accent); margin: 2px 0 0; flex: 0 0 auto; cursor: pointer; }

.gc-switch { position: relative; display: inline-block; width: 42px; height: 24px; flex: 0 0 auto; }
.gc-switch input { opacity: 0; width: 0; height: 0; }
.gc-switch span {
  position: absolute; inset: 0; cursor: pointer;
  background: var(--border-strong); border-radius: 99px; transition: background .18s;
}
.gc-switch span::before {
  content: ""; position: absolute; width: 18px; height: 18px; left: 3px; top: 3px;
  background: #fff; border-radius: 50%; transition: transform .18s;
}
.gc-switch input:checked + span { background: var(--accent); }
.gc-switch input:checked + span::before { transform: translateX(18px); }

/* ==========================================================================
   Tarjetas
   ========================================================================== */

.gc-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 16px;
}
.gc-card.pad-0 { padding: 0; }
.gc-card-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-bottom: 14px;
}
.gc-card-title { font-size: .95rem; font-weight: 650; }
.gc-card-sub   { font-size: .78rem; color: var(--text-muted); font-weight: 500; }

/* KPI */
.gc-kpi {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 15px 16px;
  display: flex; flex-direction: column; gap: 5px;
  position: relative; overflow: hidden;
}
.gc-kpi .k-top { display: flex; align-items: center; gap: 8px; }
.gc-kpi .k-ico {
  width: 30px; height: 30px; border-radius: var(--r-sm);
  display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent); flex: 0 0 auto;
}
.gc-kpi .k-label { font-size: .76rem; color: var(--text-muted); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.gc-kpi .k-value { font-size: 1.65rem; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.gc-kpi .k-foot  { font-size: .76rem; color: var(--text-muted); display: flex; align-items: center; gap: 5px; }
.gc-kpi.info   .k-ico { background: var(--info-soft);   color: var(--info); }
.gc-kpi.warn   .k-ico { background: var(--warn-soft);   color: var(--warn); }
.gc-kpi.danger .k-ico { background: var(--danger-soft); color: var(--danger); }
.gc-kpi.purple .k-ico { background: var(--purple-soft); color: var(--purple); }

.gc-delta { font-weight: 650; font-size: .76rem; }
.gc-delta.up   { color: var(--accent); }
.gc-delta.down { color: var(--danger); }
.gc-delta.flat { color: var(--text-muted); }

/* ==========================================================================
   Badges / chips
   ========================================================================== */

.gc-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: var(--r-pill);
  font-size: .72rem; font-weight: 650; letter-spacing: .01em;
  background: var(--bg-card-hover); color: var(--text-soft);
  border: 1px solid var(--border); white-space: nowrap;
}
.gc-badge.ok     { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.gc-badge.info   { background: var(--info-soft);   color: var(--info);   border-color: transparent; }
.gc-badge.warn   { background: var(--warn-soft);   color: var(--warn);   border-color: transparent; }
.gc-badge.danger { background: var(--danger-soft); color: var(--danger); border-color: transparent; }
.gc-badge.dot::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.gc-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px; border-radius: var(--r-pill);
  background: var(--bg-card); border: 1px solid var(--border);
  font-size: .82rem; font-weight: 600; color: var(--text-soft);
  cursor: pointer; white-space: nowrap; transition: all .15s;
}
.gc-chip:hover  { border-color: var(--border-strong); color: var(--text); }
.gc-chip.active { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }

/* Punto de color de un deporte o una categoría. El color lo pone el JS
   inline, porque sale del dato y no del tema. */
.gc-dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; background: var(--text-muted); }

/* ==========================================================================
   LISTA DE ACCIONES (menu-list)
   --------------------------------------------------------------------------
   Filas pulsables dentro de una tarjeta o un modal: el menú de la cuenta en
   la topbar, el de acciones de un socio, los ajustes de la app.

   Vive aquí y no en app.css porque lo usan LAS TRES aplicaciones. Un
   <button> sin estas reglas se queda con el estilo por defecto del navegador
   y el texto acaba siendo ilegible sobre la tarjeta.
   ========================================================================== */

.menu-list {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--r); overflow: hidden;
}
.menu-list + .menu-list { margin-top: 14px; }
.menu-item {
  display: flex; align-items: center; gap: 13px; width: 100%;
  padding: 14px; background: none; border: 0; cursor: pointer;
  color: var(--text); font-size: .89rem; font-family: inherit;
  text-align: left; transition: background .14s;
}
.menu-item + .menu-item { border-top: 1px solid var(--border-soft); }
.menu-item:hover { background: var(--bg-card-hover); }
.menu-item .mi-ic { width: 24px; display: grid; place-items: center; flex: 0 0 auto; color: var(--text-muted); }
.menu-item .mi-label { flex: 1 1 auto; font-weight: 550; }
.menu-item .mi-value { font-size: .8rem; color: var(--text-muted); }
.menu-item .mi-arrow { color: var(--text-muted); display: grid; place-items: center; }
.menu-item.danger { color: var(--danger); }
.menu-item.danger .mi-ic, .menu-item.danger .mi-arrow { color: var(--danger); opacity: .7; }

/* ==========================================================================
   Tablas
   ========================================================================== */

.gc-table { width: 100%; border-collapse: collapse; font-size: .87rem; }
.gc-table thead th {
  text-align: left; padding: 10px 12px;
  font-size: .72rem; font-weight: 650; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  background: var(--bg-elev);
  position: sticky; top: 0; z-index: 2;
  white-space: nowrap;
}
/* Cabeceras que ordenan al pulsarlas. Misma señal que en GestionaFitness: la
   columna activa se pinta en el color de acento y lleva su flecha. */
.gc-table thead th.sortable { cursor: pointer; user-select: none; transition: color .14s; }
.gc-table thead th.sortable:hover { color: var(--text-soft); }
.gc-table thead th.sorted { color: var(--accent); }
.gc-table tbody td { padding: 11px 12px; border-bottom: 1px solid var(--border-soft); vertical-align: middle; }
.gc-table tbody tr:hover td { background: var(--bg-card-hover); }
.gc-table tbody tr.clickable { cursor: pointer; }
.gc-table td.num, .gc-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.gc-table .empty td { text-align: center; color: var(--text-muted); padding: 34px 12px; }
.gc-table tfoot td { padding: 11px 12px; font-weight: 650; border-top: 1px solid var(--border); }

.gc-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent);
  display: grid; place-items: center;
  font-size: .74rem; font-weight: 700; flex: 0 0 auto;
  text-transform: uppercase; overflow: hidden;
}
.gc-avatar.lg { width: 54px; height: 54px; font-size: 1.15rem; }
.gc-avatar img { width: 100%; height: 100%; object-fit: cover; }

/* ==========================================================================
   Modal
   ========================================================================== */

.gc-modal {
  position: fixed; inset: 0; z-index: 900;
  background: var(--bg-overlay);
  backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  animation: gcFade .16s ease;
}
.gc-modal-box {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  width: 100%; max-width: 560px;
  max-height: calc(100vh - 40px);
  display: flex; flex-direction: column;
  animation: gcPop .18s cubic-bezier(.2,.9,.3,1.1);
}
.gc-modal-box.wide  { max-width: 900px; }
.gc-modal-box.xwide { max-width: 1120px; }
.gc-modal-box.slim  { max-width: 420px; }
.gc-modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 16px 18px; border-bottom: 1px solid var(--border); flex: 0 0 auto;
}
.gc-modal-body { padding: 18px; overflow-y: auto; flex: 1 1 auto; }
.gc-modal-foot {
  display: flex; align-items: center; justify-content: flex-end; gap: 10px;
  padding: 14px 18px; border-top: 1px solid var(--border); flex: 0 0 auto;
}
.gc-x {
  background: none; border: 0; color: var(--text-muted); cursor: pointer;
  font-size: 1.35rem; line-height: 1; padding: 4px 8px; border-radius: var(--r-sm);
}
.gc-x:hover { background: var(--bg-card-hover); color: var(--text); }

@keyframes gcFade { from { opacity: 0 } to { opacity: 1 } }
@keyframes gcPop  { from { opacity: 0; transform: translateY(10px) scale(.985) } to { opacity: 1; transform: none } }
@keyframes gcSlideUp { from { transform: translateY(100%) } to { transform: none } }

/* Hoja inferior (móvil / PWA) */
@media (max-width: 640px) {
  .gc-modal { padding: 0; align-items: flex-end; }
  .gc-modal-box {
    max-width: 100%; border-radius: var(--r-xl) var(--r-xl) 0 0;
    max-height: 92vh; animation: gcSlideUp .22s cubic-bezier(.2,.9,.3,1);
  }
}

/* ==========================================================================
   Toasts
   ========================================================================== */

#gc-toasts {
  position: fixed; z-index: 1000; bottom: 20px; right: 20px;
  display: flex; flex-direction: column; gap: 9px; pointer-events: none;
  max-width: min(380px, calc(100vw - 32px));
}
.gc-toast {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 15px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-muted);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-lg);
  font-size: .87rem;
  animation: gcToastIn .2s cubic-bezier(.2,.9,.3,1.1);
  pointer-events: auto;
}
.gc-toast.success { border-left-color: var(--accent); }
.gc-toast.error   { border-left-color: var(--danger); }
.gc-toast.warning { border-left-color: var(--warn); }
.gc-toast.info    { border-left-color: var(--info); }
.gc-toast.out     { animation: gcToastOut .18s ease forwards; }
.gc-toast .t-ico  { flex: 0 0 auto; }
@keyframes gcToastIn  { from { opacity: 0; transform: translateX(24px) } to { opacity: 1; transform: none } }
@keyframes gcToastOut { to { opacity: 0; transform: translateX(24px) } }
@media (max-width: 640px) {
  #gc-toasts { bottom: calc(var(--tabbar-h) + 14px); left: 12px; right: 12px; max-width: none; }
}

/* ==========================================================================
   Barra de progreso / ocupación
   ========================================================================== */

.gc-bar { height: 7px; background: var(--border-soft); border-radius: 99px; overflow: hidden; }
.gc-bar > i { display: block; height: 100%; background: var(--accent); border-radius: 99px; transition: width .35s ease; }
.gc-bar > i.warn   { background: var(--warn); }
.gc-bar > i.danger { background: var(--danger); }
.gc-bar > i.info   { background: var(--info); }

/* ==========================================================================
   Estados vacíos / carga
   ========================================================================== */

.gc-empty { text-align: center; padding: 42px 20px; color: var(--text-muted); }
.gc-empty .e-ico { margin-bottom: 10px; opacity: .5; display: flex; justify-content: center; }
.gc-empty .e-title { font-weight: 650; color: var(--text-soft); margin-bottom: 4px; }

.gc-skel {
  background: linear-gradient(90deg, var(--bg-card) 25%, var(--bg-card-hover) 37%, var(--bg-card) 63%);
  background-size: 400% 100%;
  animation: gcShimmer 1.2s ease-in-out infinite;
  border-radius: var(--r-sm);
}
@keyframes gcShimmer { 0% { background-position: 100% 0 } 100% { background-position: 0 0 } }

.gc-spin {
  width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--border-strong); border-top-color: var(--accent);
  animation: gcSpin .7s linear infinite; flex: 0 0 auto;
}
@keyframes gcSpin { to { transform: rotate(360deg) } }

#gc-loader {
  position: fixed; inset: 0; z-index: 1100;
  background: var(--bg-overlay); backdrop-filter: blur(2px);
  display: grid; place-items: center;
}
#gc-loader .gc-spin { width: 34px; height: 34px; border-width: 3px; }

/* ==========================================================================
   Tabs
   ========================================================================== */

.gc-tabs { display: flex; gap: 3px; border-bottom: 1px solid var(--border); overflow-x: auto; }
.gc-tab {
  padding: 10px 15px; background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--text-muted); font-size: .87rem; font-weight: 600; cursor: pointer;
  white-space: nowrap; transition: color .15s, border-color .15s;
}
.gc-tab:hover  { color: var(--text-soft); }
.gc-tab.active { color: var(--accent); border-bottom-color: var(--accent); }

/* Banner modo demo */
.gc-demo-flag {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: var(--r-pill);
  background: var(--warn-soft); color: var(--warn);
  font-size: .68rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ==========================================================================
   ELEGIR UN COLOR O UN EMOJI
   --------------------------------------------------------------------------
   Un DESPLEGABLE, no una rejilla suelta: treinta muestras dentro de un
   formulario se comen la pantalla y empujan hacia abajo lo que de verdad se
   está rellenando. Cerrado ocupa una línea y dice qué hay elegido; abierto
   enseña la paleta entera.

   Paleta cerrada y con NOMBRES, en lugar de la rueda cromática del navegador:
   «Granate» se recuerda, «#8e1b2e» no. Y ese es justo el problema que tiene un
   selector libre.
   ========================================================================== */

.gc-swatches { display: block; }

/* --- El campo cerrado --- */

.sw-trigger {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 9px 11px;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--bg-input); color: var(--text);
  font-family: inherit; font-size: .87rem; text-align: left;
  cursor: pointer; transition: border-color .14s, background .14s;
}
.sw-trigger:hover { border-color: var(--border-strong); }
.sw-trigger[aria-expanded="true"] {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.sw-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-caret { color: var(--text-muted); display: inline-flex; flex: 0 0 auto; transition: transform .14s; }
.sw-trigger[aria-expanded="true"] .sw-caret { transform: rotate(180deg); }

/* La muestra del campo cerrado */
.sw-chip {
  width: 22px; height: 22px; flex: 0 0 auto;
  border-radius: 6px;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .22);
}
.sw-chip.is-emoji,
.sw-chip.is-none {
  display: grid; place-items: center;
  background: var(--bg-card);
  box-shadow: inset 0 0 0 1px var(--border);
  color: var(--text-muted);
  font-size: 1rem; line-height: 1;
}

/* --- El panel desplegado ---
   Cuelga de <body> en `position: fixed`: el cuerpo de un modal lleva
   `overflow-y: auto` y lo cortaría por abajo justo cuando el campo está al
   final del formulario, que es donde suele estar. */

.sw-pop {
  position: fixed; z-index: 3000;
  width: 268px; padding: 9px;
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);
  border-radius: var(--r);
  box-shadow: var(--shadow-lg);
  animation: swIn .12s ease-out;
}
.sw-pop.is-emoji { width: 300px; }

@keyframes swIn { from { opacity: 0; transform: translateY(-4px); } }

.sw-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 6px;
}
.sw-pop.is-emoji .sw-grid { grid-template-columns: repeat(8, 1fr); }

.sw {
  aspect-ratio: 1;
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--r-sm);
  cursor: pointer;
  position: relative;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .18);
  transition: transform .1s, border-color .1s;
}
.sw:hover { transform: scale(1.14); z-index: 1; }
.sw.on { border-color: var(--text); }
/* Marca de elegido: un punto blanco con reborde, legible sobre cualquier
   color de la paleta, incluidos el arena y el negro. */
.sw.on::after {
  content: '';
  position: absolute; inset: 0; margin: auto;
  width: 7px; height: 7px; border-radius: 50%;
  background: #fff; box-shadow: 0 0 0 1.5px rgba(0, 0, 0, .45);
}

/* El emoji se dibuja solo: ni fondo de color ni punto encima, que lo taparía */
.sw-e {
  background: var(--bg-card);
  box-shadow: inset 0 0 0 1px var(--border);
  font-size: 1.05rem; line-height: 1;
  display: grid; place-items: center;
}
.sw-e.on { background: var(--accent-soft); border-color: var(--accent); }
.sw-e.on::after { display: none; }

/* Filas sueltas de arriba: «ninguno» y el color que ya estaba puesto */
.sw-row {
  display: flex; align-items: center; gap: 9px;
  width: 100%; padding: 7px 8px; margin-bottom: 6px;
  border: 1px solid transparent; border-radius: var(--r-sm);
  background: var(--bg-card); color: var(--text-soft);
  font-family: inherit; font-size: .8rem; text-align: left;
  cursor: pointer; transition: all .12s;
}
.sw-row:hover { background: var(--bg-card-hover); color: var(--text); }
.sw-row.on { border-color: var(--accent); color: var(--text); }

/* El pie dice cómo se llama la muestra que se está señalando, antes de
   elegirla: así se sabe qué es «ese verde» sin tener que probarlo. */
.sw-foot {
  margin-top: 9px; padding-top: 8px;
  border-top: 1px solid var(--border-soft);
  font-size: .74rem; font-weight: 600; color: var(--text-soft);
  min-height: 1.15em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
