@font-face {
    font-family: 'Geist';
    src: url("../fonts/geist/Geist-Variable.woff2") format("woff2");
    font-weight: 100 900; font-style: normal; font-display: swap;
}

:root {
    --bg: #ffffff;
    --bg-soft: #f9f9f9;
    --surface: #ffffff;
    --card-bg: #ffffff;

    --text: #333333;
    --muted: #666666;

    --line: #ebebeb;
    --border: #ebebeb;

    /* Marca: dorado del logo de Real Plata (oscurecido para leerse sobre blanco) */
    --brand: #8a6d1b;
    --accent: #8a6d1b;
    --brand-2: #6b5413;
    --accent-strong: #6b5413;
    --accent-dark: #6b5413;
    --brand-soft: #f7f0db;
    --accent-soft: #f7f0db;
    /* Franja superior y panel del login: grafito del logo con borde dorado. */
    --strip-from: #2f2f31;
    --strip-to: #3a3a3c;
    --strip-line: #b8962e;

    --success: #1a7f37;
    --success-soft: #dafbe1;
    --danger: #d1242f;
    --danger-soft: #ffebe9;
    --warning: #9a6700;
    --warning-soft: #fff8c5;
    --orange: #bc4c00;
    --orange-soft: #fff1e5;

    /* Categórico para gráficas (barra de saldo tipo "Almacenamiento"): validado
       aparte de --accent/--brand, que no cumple la banda de luminosidad OKLCH
       requerida para uso categórico. Ver skill dataviz, references/palette.md. */
    --viz-blue: #2a78d6;
    --viz-orange: #eb6834;
    --dark-badge-bg: rgba(31, 35, 40, 0.14);
    --dark-badge-fg: #1f2328;

    --shadow-card: none;
    --shadow-hover: 0 1px 1px 0 rgb(16 24 40 / 0.05), 0 3px 8px -2px rgb(16 24 40 / 0.10);
    --shadow-md: 0 0 0 1px rgb(16 24 40 / 0.05), 0 8px 16px -6px rgb(16 24 40 / 0.10), 0 24px 48px -12px rgb(16 24 40 / 0.14);

    --radius-xl: 12px;
    --radius-lg: 6px;
    --radius-kpi: 8px;
    --radius-pill: 999px;

    --focus-ring: rgba(138, 109, 27, 0.30);

    /* Sistema de diseño tomado de Reservas 2026 (plan en ~/proyectos/jyl/docs/RESTYLING_PLAN.md §1.2). */
    --texto-3: #737373;
    --borde-suave: #f1f1f1;
    --borde-fuerte: #d6d6d6;
    --borde-control: #8c8f97;
    --fondo-hover: #f5f5f5;
    --fondo-activo: #ebebeb;
    --fila-hover: #fcfcfc;
    --marco-fondo: #ffffff;
    --marco-hoja-borde: #ecedf0;
    --hoja-radio: 14px;
    --marco-aire: 12px;
    --radio-tarjeta: 8px;
    --radio-chip: 4px;
    --sombra-control: 0 1px 1px 0 rgb(16 24 40 / 0.04), 0 1px 3px -1px rgb(16 24 40 / 0.07);
    --alto-control: 32px;
    --alto-control-sm: 28px;
    --alto-fila: 36px;
    --alto-encabezado: 47px;
    --alto-franja: 44px;
    --fuente: 'Geist', ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
    --fuente-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    --anillo: var(--accent);
    --lat-hover: #faf2f2;
    --lat-activo: var(--accent-soft);
    --lat-raya: #e4e4e7;
    --duracion-rapida: 100ms;
    /* Relleno del botón primario y texto encima (2026-11-07). En claro es el
       dorado oscuro de marca con blanco (4.9:1; hover 7.2:1). */
    --boton-primario: var(--accent);
    --boton-primario-hover: var(--accent-dark);
    --texto-sobre-acento: #ffffff;
}

:root[data-theme="dark"] {
    --bg: #171717;
    --bg-soft: #1d1d1d;
    --surface: #171717;
    --card-bg: #171717;

    --text: #ebebeb;
    --muted: #b3b3b3;

    --line: rgba(255, 255, 255, 0.10);
    --border: rgba(255, 255, 255, 0.10);

    --brand: #d9b84a;
    --accent: #d9b84a;
    --brand-2: #ecd27a;
    --accent-strong: #ecd27a;
    --accent-dark: #ecd27a;
    --brand-soft: rgba(217, 184, 74, 0.16);
    --accent-soft: rgba(217, 184, 74, 0.16);

    --success: #3fb950;
    --success-soft: rgba(63, 185, 80, 0.16);
    --danger: #f85149;
    --danger-soft: rgba(248, 81, 73, 0.16);
    --warning: #d29922;
    --warning-soft: rgba(210, 153, 34, 0.16);
    --orange: #ff9542;
    --orange-soft: rgba(255, 149, 66, 0.16);

    --viz-blue: #3987e5;
    --viz-orange: #d95926;
    --dark-badge-bg: rgba(240, 246, 252, 0.16);
    --dark-badge-fg: #f0f6fc;

    --shadow-card: none;
    --shadow-hover: 0 1px 1px 0 rgb(0 0 0 / 0.30), 0 3px 8px -2px rgb(0 0 0 / 0.45);
    --shadow-md: 0 0 0 1px rgb(255 255 255 / 0.08), 0 8px 16px -6px rgb(0 0 0 / 0.50), 0 24px 48px -12px rgb(0 0 0 / 0.60);

    --focus-ring: rgba(244, 112, 103, 0.32);

    --texto-3: #8f8f8f;
    --borde-suave: #222222;
    --borde-fuerte: #484848;
    --borde-control: #6b6b6b;
    --fondo-hover: #222222;
    --fondo-activo: #262626;
    --fila-hover: #1b1b1b;
    --marco-fondo: #171717;
    --marco-hoja-borde: rgba(255, 255, 255, 0.10);
    --sombra-control: 0 1px 1px 0 rgb(0 0 0 / 0.30), 0 1px 3px -1px rgb(0 0 0 / 0.40);
    --lat-hover: rgba(217, 184, 74, 0.10);
    --lat-raya: rgba(255, 255, 255, 0.10);
    /* En oscuro, dorado suave poco saturado con texto oscuro (mismo criterio
       que JYL): #171717 sobre #c9b06a = 8.4:1. */
    --boton-primario: #c9b06a;
    --boton-primario-hover: #d6c084;
    --texto-sobre-acento: #171717;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

html {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    scrollbar-width: thin;
    scrollbar-color: var(--borde-fuerte) transparent;
}

body {
    font-family: var(--fuente);
    font-size: 13px;
    font-weight: 500;
    line-height: 1.5;
    margin: 0;
    color: var(--text);
    background: var(--bg);
    transition: background-color .2s ease, color .2s ease;
}

button, input, optgroup, select, textarea { font: inherit; }
code, kbd, samp, pre { font-family: var(--fuente-mono); }

a { color: var(--accent); }

:focus-visible { outline: 2px solid var(--anillo); outline-offset: 2px; }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--borde-fuerte); border-radius: 8px; }
::-webkit-scrollbar-thumb:hover { background: var(--texto-3); }

/* Franja de marca: grafito con línea roja del logo */
.brand-strip {
    position: relative;
    background: linear-gradient(120deg, var(--strip-from), var(--strip-to));
    border-bottom: 2px solid var(--strip-line);
    color: #fff;
}
header.topbar {
    position: relative;
    height: calc(var(--alto-encabezado) + env(safe-area-inset-top));
    padding: env(safe-area-inset-top) 16px 0 12px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.topbar-left { display: flex; align-items: center; gap: 0.9rem; }
.sidebar-toggle {
    background: transparent; border: 0; color: #eef1fa; cursor: pointer;
    width: 30px; height: 30px; border-radius: 6px;
    display: inline-flex; align-items: center; justify-content: center; font-size: 1.1rem;
}
.sidebar-toggle:hover { background: rgba(255, 255, 255, 0.14); }
.brand { display: flex; align-items: center; gap: 0.75rem; text-decoration: none; }
.brand img { height: 28px; width: auto; display: block; border-radius: 50%; background: #fff; }
.brand-nombre { color: #fff; font-weight: 600; font-size: 14px; letter-spacing: 0.2px; }
@media (max-width: 600px) { .brand-nombre { display: none; } }
header.topbar nav { display: flex; align-items: center; gap: 4px; }
header.topbar nav a, header.topbar nav > span {
    display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 8px; border-radius: 6px;
    color: #eef1fa; text-decoration: none; font-weight: 500; font-size: 13px;
}
header.topbar nav a:hover { background: rgba(255, 255, 255, 0.10); }

/* Toggle de tema (switch tipo iOS) */
.theme-switch {
    display: inline-flex; align-items: center; gap: 6px;
    background: transparent; border: 0; cursor: pointer; color: #eef1fa;
}
.theme-switch-track {
    width: 32px; height: 18px; border-radius: 999px;
    background: rgba(255, 255, 255, 0.28);
    position: relative; transition: background-color .2s ease;
}
.theme-switch-knob {
    position: absolute; top: 2px; left: 2px;
    width: 14px; height: 14px; border-radius: 50%;
    background: #ffffff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    transition: transform .2s ease;
}
:root[data-theme="dark"] .theme-switch-knob { transform: translateX(14px); }

.dashboard-shell { width: min(1200px, calc(100% - 32px)); margin: 28px auto 40px; }
.dashboard-shell.fluid { width: auto; margin: 0; padding: 16px 20px 24px; }

.card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radio-tarjeta);
    box-shadow: none;
    overflow: hidden;
    margin-bottom: 16px;
}
.card .card-header {
    background: var(--card-bg);
    border-bottom: 1px solid var(--border);
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    padding: 12px 16px;
}
.card .card-body { padding: 16px; }

/* .card tiene overflow:hidden (para los bordes redondeados) — sin este
   wrapper, una tabla más ancha que la card queda RECORTADA en vez de
   scrolleable en pantallas angostas (columnas de más simplemente invisibles,
   sin ninguna forma de llegar a ellas). */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll:not(.card .table-scroll) { border: 1px solid var(--border); border-radius: var(--radio-tarjeta); }

/* Grids (generic_list.html): encabezados y barra inferior congelados. El
   listado ocupa el alto de la ventana (menos el padding de .dashboard-shell),
   la tabla hace scroll dentro de su tarjeta (así el thead sticky se queda
   arriba) y la barra de paginación queda siempre visible abajo. */
.grid-congelado { display: flex; flex-direction: column; height: calc(100vh - 40px); height: calc(100dvh - 40px); min-height: 360px; }
.grid-congelado > .page-header, .grid-congelado > .seg-chips { flex: 0 0 auto; }
.grid-congelado > .card { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; margin-bottom: 0; }
.grid-congelado > .card > .table-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; overscroll-behavior: contain; }
.grid-congelado > .pagination-bar {
    flex: 0 0 auto; margin-top: 0; padding: 10px 2px 0;
    border-top: 1px solid var(--border); background: var(--bg);
}
/* En pantallas angostas el alto fijo estorba más de lo que ayuda: vuelve al
   scroll normal de la página (el thead sigue siendo sticky dentro de la tabla). */
@media (max-width: 640px) {
    .grid-congelado { height: auto; min-height: 0; }
    .grid-congelado > .card > .table-scroll { max-height: 70vh; }
}

table { width: 100%; border-collapse: separate; border-spacing: 0; background: var(--card-bg); font-size: 13px; }
thead th {
    position: sticky; top: 0; z-index: 2;
    height: 36px;
    padding: 0 8px;
    background: var(--card-bg);
    color: var(--text);
    font-size: 13px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    border-bottom: 1px solid var(--border);
    border-right: 1px solid var(--borde-suave);
    white-space: nowrap;
}
th, td { padding: 0 8px; text-align: left; vertical-align: middle; }
/* Columnas numéricas/de dinero (ej. Valor en el listado de Compras): a la
   derecha, encabezado incluido, con dígitos de ancho fijo para que los
   montos queden alineados por unidades/decimales. */
th.col-num, td.col-num { text-align: right; font-variant-numeric: tabular-nums; }

/* Líneas verticales suaves entre columnas (StaffListView.lineas_verticales,
   ej. Servicios y productos): borde izquierdo de cada celda salvo la
   primera, en el color de línea del tema atenuado al 55% — se ven en claro
   y en oscuro sin competir con los datos. Con ">" para no tocar la tabla
   anidada del árbol ni la fila de detalle (colspan). */
.tabla-lineas-verticales > thead > tr > th + th,
.tabla-lineas-verticales > tbody > tr:not(.fila-arbol) > td + td {
    border-left: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}

.texto-tenue { color: var(--muted); }

/* Grid anidado tipo árbol (generic_list.html con url_filas_anidadas +
   static/js/arbol_filas.js): un <tbody class="grupo-arbol"> por registro =
   su fila + una fila de detalle colapsada. Las franjas alternas pasan a ser
   por grupo (nth-of-type del tbody), porque la fila de detalle rompería el
   nth-child de las filas. */
/* Ojo: selectores con ">" — con descendiente (espacio) alcanzarían también
   las celdas de la tabla anidada que vive dentro de la fila de detalle. */
.tabla-arbol > tbody > tr:nth-child(even) > td { background: transparent; }
.tabla-arbol > tbody.grupo-arbol:nth-of-type(even) > tr.fila-principal > td { background: var(--bg-soft); }
.tabla-arbol > tbody > tr.fila-principal:hover > td { background: var(--accent-soft); }
.tabla-arbol > tbody > tr.fila-arbol:hover > td { background: transparent; }
.tabla-arbol .col-arbol { width: 36px; padding-right: 0; }
.btn-arbol {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; padding: 0;
    border: 0; background: transparent; cursor: pointer;
    font-size: 17px; line-height: 1;
}
.btn-arbol:disabled { cursor: progress; opacity: 0.6; }
.tabla-arbol > .grupo-arbol.arbol-abierto > tr.fila-principal > td { border-bottom-color: transparent; }
.tabla-arbol > tbody > tr.fila-arbol > td { height: auto; padding: 0; border-bottom: 0; background: transparent; }
.tabla-arbol > .grupo-arbol.arbol-abierto > tr.fila-arbol > td { border-bottom: 1px solid var(--line); }
/* Acordeón lento: animar grid-template-rows 0fr -> 1fr anima la altura real
   del contenido (cargado por AJAX) sin tener que medirla en JS. */
.arbol-panel {
    display: grid; grid-template-rows: 0fr;
    transition: grid-template-rows 0.6s ease-in-out;
}
.arbol-panel.abierto { grid-template-rows: 1fr; }
.arbol-panel-interno { overflow: hidden; min-height: 0; }
.arbol-panel .arbol-contenido {
    margin: 2px 16px 0 48px;
    padding: 0 0 18px;   /* separación entre el detalle y el siguiente registro */
    opacity: 0; transition: opacity 0.6s ease-in-out;
}
.arbol-panel.abierto .arbol-contenido { opacity: 1; }
.tabla-anidada {
    border-collapse: separate; border-spacing: 0;   /* para que tome el radio */
    border: 1px solid var(--line); border-left: 3px solid var(--accent);
    border-radius: var(--radius-lg); overflow: hidden;
}
.tabla-anidada thead th { border-bottom: 1px solid var(--line); }
.tabla-anidada thead th { position: static; font-size: 10px; padding: 0.45rem 0.7rem; }
.tabla-anidada tbody td { height: auto; padding: 0.45rem 0.7rem; font-size: 13.5px; }
.tabla-anidada tbody tr:nth-child(even) td { background: var(--bg-soft); }
.tabla-anidada tbody tr:last-child td { border-bottom: 0; }
.tabla-anidada-nota { margin: 8px 0 0; font-size: 13.5px; }
tbody td {
    height: var(--alto-fila); color: var(--muted); font-size: 13px;
    border-bottom: 1px solid var(--borde-suave); border-right: 1px solid var(--borde-suave);
}
thead tr > th:last-child, tbody tr > td:last-child { border-right: 0; }
tbody tr:nth-child(even) td { background: transparent; }
tbody tr:hover td { background: var(--fila-hover); }

/* Columnas booleanas sí/no de los listados (get_attr en club_extras.py) */
.bool-icon-true { color: var(--success); }
.bool-icon-false { color: var(--danger); }

/* Tabla con columnas ordenables al clic (ej. "Reservas registradas" del
   dashboard de Staff) — el ícono indica la dirección actual, mismo patrón de
   rotación que .sidebar-caret. */
.sortable-table th[data-sort] { cursor: pointer; user-select: none; }
.sortable-table th[data-sort]:hover { color: var(--text); }
.sortable-table .sort-icon {
    font-size: 0.7rem; margin-left: 4px; color: var(--texto-3); opacity: 0;
    transition: transform 0.15s ease, opacity var(--duracion-rapida);
}
.sortable-table th:hover .sort-icon { opacity: 1; }
.sortable-table th.sort-asc .sort-icon { transform: rotate(180deg); }
.sortable-table th.sort-asc .sort-icon,
.sortable-table th.sort-desc .sort-icon { opacity: 1; color: var(--text); }
/* En generic_list.html el ordenamiento es un link real (recarga con
   ?ordenar=campo), no un listener JS — se resetea el estilo de <a> para que
   se vea igual que el resto de los encabezados. */
.sortable-table th[data-sort] a { color: inherit; text-decoration: none; }

/* Buscador del toolbar de cada listado de Staff (generic_list.html). El
   selector repite el patrón form input:not(...):not(...) de arriba (mismo
   nivel de especificidad + la clase .search-form) porque si no, esa regla
   genérica (width: 100%) le gana a esta y el input ocupa toda la fila,
   empujando el botón de la lupa a una línea aparte. */
.search-form { display: flex; flex-wrap: nowrap; align-items: center; gap: 4px; }
form.search-form input[type="search"]:not([type="checkbox"]):not([type="radio"]) {
    width: 220px;
    height: var(--alto-control);
    flex: 0 0 auto;
}

/* Barra de paginación (generic_list.html): página anterior/siguiente a la
   izquierda, total de registros + selector de filas por página a la derecha. */
.pagination-bar { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; margin-top: 12px; font-size: 13px; color: var(--muted); }
.por-pagina-form { display: flex; align-items: center; gap: 6px; }
.por-pagina-form select { width: auto; }

.btn {
    display: inline-flex; align-items: center; gap: 6px;
    height: var(--alto-control);
    padding: 0 12px;
    border-radius: 6px;
    background: var(--boton-primario);
    color: var(--texto-sobre-acento);
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    font-size: 13px;
    font-weight: 500;
    box-shadow: var(--sombra-control);
    transition: background-color var(--duracion-rapida);
}
.btn:hover { background: var(--boton-primario-hover); color: var(--texto-sobre-acento); }
.btn-danger { background: var(--danger); }
.btn-danger:hover { background: color-mix(in srgb, var(--danger) 85%, #000); }
.btn-secondary { background: var(--card-bg); color: var(--text); border-color: var(--border); }
.btn-secondary:hover { background: var(--fondo-hover); color: var(--text); }
.btn-secondary:active { background: var(--fondo-activo); }
.btn.disabled { opacity: 0.45; cursor: not-allowed; pointer-events: none; }
/* Botones de exportación (ícono + texto, color suave según el formato) —
   reemplazan a un .icon-btn genérico en encabezados que ya tienen otro botón
   con texto al lado (ej. "Volver"), para que se lean como acciones y no
   como iconos sueltos. */
.btn-export-excel, .btn-export-pdf { background: var(--card-bg); color: var(--text); border-color: var(--border); }
.btn-export-excel:hover, .btn-export-pdf:hover { background: var(--fondo-hover); color: var(--text); }
.btn-export-excel:active, .btn-export-pdf:active { background: var(--fondo-activo); }
/* Solo el ícono lleva el color del formato. Doble clase para ganarle a la
   lista de excepciones de íconos del final del archivo (se revisa en el Paso 5). */
.btn.btn-export-excel .bi { color: var(--success); }
.btn.btn-export-pdf .bi { color: var(--danger); }
/* Verde de marca de WhatsApp: intencional, no es un token del sistema de
   diseño porque identifica el servicio, no un estado semántico de la app. */
.btn-whatsapp { background: #25d366; color: #08341c; }
.btn-whatsapp:hover { background: #1fb855; color: #08341c; }

.icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: var(--alto-control-sm); height: var(--alto-control-sm);
    border-radius: 6px;
    background: transparent;
    border: 1px solid transparent;
    text-decoration: none;
    cursor: pointer;
    font-size: 14px;
    color: var(--muted);
}
.icon-btn:hover { background: var(--fondo-hover); color: var(--text); border-color: transparent; }
.actions { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
/* Celda de botones de una grilla (<td class="actions">): sigue siendo celda
   de tabla, no flex — con display:flex el <td> deja de medirse como columna
   y en tablas anchas (Usuarios) los botones se apilaban e invadían la fila
   de abajo. Una sola línea siempre; el gap lo da el margen. */
td.actions { display: table-cell; white-space: nowrap; width: 1%; }
td.actions > * + * { margin-left: 4px; }
/* Grillas con más columnas de las que caben: las celdas no parten el texto,
   la tabla se ensancha y .table-scroll da el scroll
   horizontal. Selectores con ">" para no alcanzar la tabla anidada del árbol. */
.table-scroll > table.sortable-table > tbody > tr > td { white-space: nowrap; }
/* Excepción: un texto largo (más de 40 caracteres, generic_list.html) parte en
   varias líneas dentro de un ancho acotado, para que la columna no estire la
   tabla (pedido del usuario, 2026-11-09). Lo corto sigue en una sola línea. */
.texto-largo {
    display: block; min-width: 14rem; max-width: 28rem;
    white-space: normal; overflow-wrap: anywhere; line-height: 1.35;
}

/* La columna de botones queda fija a la derecha mientras se desplaza el
   resto. Necesita fondo propio (si no, se ve lo que pasa por debajo); la
   cebra/hover de la fila le ganan por especificidad y lo siguen pintando.
   El <th> vacío de esa columna se fija igual para que el header no se corra. */
.table-scroll td.actions,
.table-scroll > table > thead > tr > th:last-child:empty { position: sticky; right: 0; }
.table-scroll td.actions { z-index: 1; background: var(--card-bg); }
.table-scroll tbody tr:hover td.actions { background: var(--fila-hover); }
.table-scroll > table > thead > tr > th:last-child:empty { z-index: 3; }
/* Sombra de "hay columnas debajo" solo cuando la tabla de verdad desborda
   (clase .con-scroll que pone static/js/table_scroll.js). */
.table-scroll.con-scroll td.actions,
.table-scroll.con-scroll > table > thead > tr > th:last-child:empty {
    box-shadow: inset 1px 0 0 var(--border), -8px 0 8px -8px rgba(0, 0, 0, 0.25);
}

/* Botón de refresh junto a un <select> de catálogo (RefreshableSelect,
   club/forms.py + static/js/refreshable_select.js) — repuebla las opciones
   sin recargar la página. */
.refreshable-select { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; }
.refreshable-select select { flex: 1; min-width: 0; }
.refreshable-select .btn-refrescar-select { flex: 0 0 auto; }
.refreshable-select .btn-refrescar-select i.girando { animation: processing-spin 0.6s linear infinite; }
/* Dentro de un formulario, a todo el ancho de la columna como el resto de
   los campos (el widget es un <span> para no romper el <p> de form.as_p). */
.form-grid .refreshable-select { display: flex; width: 100%; }

form p, form .campo { margin: 0 0 12px; }
/* Combinador de hijo directo (>): apunta solo a la etiqueta principal de cada
   campo (ej. "Grupos:"), NO a las etiquetas por-opción que Django genera dentro
   de CheckboxSelectMultiple/RadioSelect (esas quedan anidadas más profundo,
   dentro de un <div id="id_campo">, nunca como hijas directas del <p>). */
form p > label, form .campo > label {
    display: block;
    font-size: 12px;
    line-height: 16px;
    font-weight: 600;
    margin-bottom: 4px;
    color: var(--muted);
}
form input:not([type="checkbox"]):not([type="radio"]), form select, form textarea {
    width: 100%;
    min-height: var(--alto-control);
    padding: 6px 8px;
    font-size: 13px;
    border: 1px solid var(--borde-control);
    border-radius: 6px;
    background: var(--card-bg);
    color: var(--text);
    transition: border-color 0.1s ease, box-shadow 0.1s ease;
}
form textarea { min-height: 72px; }
form input:not([type="checkbox"]):not([type="radio"]), form select { line-height: 18px; }
form input:not([type="checkbox"]):not([type="radio"]):focus, form select:focus, form textarea:focus {
    border-color: var(--anillo);
    box-shadow: inset 0 0 0 1px var(--anillo);
    outline: none;
}
::placeholder { color: var(--texto-3); opacity: 1; }
form input[readonly] {
    background: var(--bg-soft);
    color: var(--muted);
    border-color: var(--border);
    cursor: not-allowed;
}
form input[type="checkbox"], form input[type="radio"] { width: auto; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); width: 16px; height: 16px; }
/* Flecha propia de los select (appearance: none). */
form select:not([multiple]) {
    appearance: none; padding-right: 28px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23666666' stroke-width='1.6' d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 8px center;
}
:root[data-theme="dark"] form select:not([multiple]) {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23b3b3b3' stroke-width='1.6' d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
}

/* Layout de 2 columnas para formularios en escritorio (envolver los <p> de
   `form.as_p`, o los renderizados campo a campo, en <div class="form-grid">).
   Campos donde no tiene sentido compartir fila con otro (textarea, grupos de
   checkbox/radio, archivos, o cualquier <p>/bloque marcado a mano con
   .form-grid-full) ocupan las 2 columnas completas. Por debajo de 700px
   (mobile) vuelve a 1 columna, igual que el resto de los grids del sistema
   (ver .kpi-grid). */
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 24px; }
.form-grid > p:has(textarea),
.form-grid > p:has(input[type="checkbox"]),
.form-grid > p:has(input[type="file"]),
.form-grid > p:has(select[multiple]),
.form-grid > .campo:has(textarea),
.form-grid > .campo:has(input[type="checkbox"]),
.form-grid > .campo:has(input[type="file"]),
.form-grid > .campo:has(select[multiple]),
.form-grid .form-grid-full {
    grid-column: 1 / -1;
}
@media (max-width: 700px) { .form-grid { grid-template-columns: 1fr; } }

/* Selector de fecha con formato largo (ej. "Domingo 30 de agosto 2026"): el
   <input> real (data-input) queda invisible pero SIGUE ocupando el mismo
   rectángulo que el <label> (position: absolute; inset: 0) — a propósito, no
   display:none: Flatpickr en modo "wrap" (ver flatpickr_init.js) calcula
   dónde dibujar el calendario según la posición/tamaño de ese input, y con
   display:none le queda un rectángulo de 0x0 en (0,0) y el calendario
   termina flotando en la esquina superior izquierda de la página en vez de
   debajo del <span data-toggle> (bug real encontrado al verificar con
   Playwright antes de este ajuste). pointer-events: none porque el click ya
   lo captura el <span> (visualmente encima, mismo <label>). */
.fecha-picker { position: relative; display: inline-flex; align-items: center; cursor: pointer; }
.fecha-picker input { position: absolute; inset: 0; opacity: 0; pointer-events: none; padding: 0; border: 0; }

/* --- Desplegables con búsqueda (Tom Select, static/js/selects_init.js) ---
   Portado de jyl. Pedido del usuario (2026-11-09): escribir para filtrar,
   efecto acordeón al abrir y lista más clara, con línea de división entre
   opciones. Mismas medidas que los campos (--alto-control, --borde-control,
   foco --anillo). La lista vive en <body> y se ensancha para textos largos
   (mínimo el campo, máximo lo que fija selects_init.js). */
.ts-wrapper { width: 100%; --ts-pr-caret: 28px; }
.ts-wrapper .ts-control,
.ts-wrapper.single.input-active .ts-control {
    min-height: var(--alto-control); padding: 6px 30px 6px 8px; align-items: center; gap: 4px;
    border: 1px solid var(--borde-control); border-radius: 6px;
    background: var(--card-bg); color: var(--text); font-size: 13px; line-height: 18px; box-shadow: none;
    transition: border-color 0.1s ease, box-shadow 0.1s ease;
}
.ts-wrapper.focus .ts-control { border-color: var(--anillo); box-shadow: inset 0 0 0 1px var(--anillo); }
/* Un solo valor: todo en una línea; el valor largo se recorta con "…". */
.ts-wrapper.single .ts-control { flex-wrap: nowrap; }
.ts-wrapper.single .ts-control > .item { flex: 0 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.ts-wrapper.single.has-items .ts-control > input { flex: 1 1 0; min-width: 0; width: 0; }
.ts-wrapper.single.ts-escribiendo .ts-control > .item { display: none; }
.ts-wrapper.single.ts-escribiendo .ts-control > input { flex: 1 1 auto; width: auto; }
.ts-wrapper .ts-control > input { color: var(--text); font-size: 13px; min-width: 4rem; }
.ts-wrapper .ts-control > input::placeholder { color: var(--texto-3); }
/* Flecha que gira al abrir (como el acordeón del menú). */
.ts-wrapper .ts-control::after {
    content: "\f282"; font-family: "bootstrap-icons"; position: absolute; right: 10px; top: 50%;
    margin-top: -7px; font-size: 12px; line-height: 14px; color: var(--muted);
    transition: transform 0.2s ease; pointer-events: none;
}
.ts-wrapper.dropdown-active .ts-control::after { transform: rotate(180deg); color: var(--accent); }
.ts-wrapper.disabled .ts-control { background: var(--bg-soft); color: var(--muted); border-color: var(--border); opacity: 1; cursor: not-allowed; }
.plugin-clear_button .clear-button { color: var(--muted); font-size: 16px; line-height: 1; }
.plugin-clear_button .clear-button:hover { color: var(--danger); }
.plugin-clear_button.focus.has-items .clear-button, .plugin-clear_button:not(.disabled):hover.has-items .clear-button { opacity: 1; }
/* Varios valores: cada uno como chip. */
.ts-wrapper.multi .ts-control, .ts-wrapper.multi.has-items .ts-control { padding: 3px 30px 3px 4px; }
.ts-wrapper.multi .ts-control > div {
    display: inline-flex; align-items: center; margin: 1px; padding: 1px 2px 1px 6px;
    border: 0; border-radius: var(--radio-chip); background: var(--fondo-activo); color: var(--text); font-size: 12px;
}
.ts-wrapper.multi .ts-control > div.active { background: var(--accent-soft); color: var(--text); }
.ts-wrapper.plugin-remove_button .item .remove { border-left: 0; padding: 0 4px; margin-left: 2px; color: var(--muted); border-radius: 3px; }
.ts-wrapper.plugin-remove_button .item .remove:hover { background: transparent; color: var(--danger); }
/* Lista desplegable: filas con línea de división, más aire y texto completo. */
.ts-dropdown {
    z-index: 7900; margin-top: 4px; padding: 0; overflow: hidden;
    width: max-content !important;  /* Tom Select fija el ancho del campo al recolocarla */
    border: 1px solid var(--border); border-radius: var(--radio-tarjeta);
    background: var(--card-bg); color: var(--text); box-shadow: var(--shadow-md); font-size: 13px;
}
.ts-dropdown .ts-dropdown-content { max-height: 320px; scrollbar-width: thin; }
/* Cuadro "Buscar…" arriba de la lista (plugin dropdown_input): autofind al expandir. */
.ts-dropdown .dropdown-input-wrap {
    position: relative; padding: 8px; background: var(--bg-soft); border-bottom: 1px solid var(--border);
}
.ts-dropdown .dropdown-input-wrap::before {
    content: "\f52a"; font-family: "bootstrap-icons"; position: absolute; left: 18px; top: 50%;
    transform: translateY(-50%); font-size: 12px; color: var(--muted); pointer-events: none;
}
.ts-dropdown .dropdown-input {
    width: 100%; height: 30px; padding: 4px 8px 4px 28px; box-sizing: border-box;
    border: 1px solid var(--borde-control); border-radius: 6px; box-shadow: none;
    background: var(--card-bg); color: var(--text); font-size: 13px;
}
.ts-dropdown .dropdown-input:focus { outline: none; border-color: var(--anillo); box-shadow: inset 0 0 0 1px var(--anillo); }
.ts-dropdown .dropdown-input::placeholder { color: var(--texto-3); }
/* El campo cerrado ya no se escribe: solo muestra el valor y abre la lista. */
.ts-wrapper.plugin-dropdown_input .ts-control { cursor: pointer; }
.ts-wrapper.plugin-dropdown_input .items-placeholder { border: 0; box-shadow: none; background: transparent; color: var(--texto-3); font-size: 13px; }
.ts-wrapper.plugin-dropdown_input.has-items .items-placeholder { display: none !important; }
.ts-dropdown .option, .ts-dropdown .no-results, .ts-dropdown .create {
    padding: 8px 12px; line-height: 18px; white-space: normal; overflow-wrap: anywhere;
}
.ts-dropdown .option { cursor: pointer; border-bottom: 1px solid var(--border); }
.ts-dropdown .option:last-child { border-bottom: 0; }
.ts-dropdown .active { background: var(--fondo-hover); color: var(--text); }
.ts-dropdown .option.selected {
    position: relative; padding-right: 32px; color: var(--accent); font-weight: 600;
    box-shadow: inset 3px 0 0 var(--accent); background: var(--accent-soft);
}
.ts-dropdown .option.selected.active { background: color-mix(in srgb, var(--accent) 16%, var(--card-bg)); }
.ts-dropdown .option.selected::after {
    content: "\f272"; font-family: "bootstrap-icons"; position: absolute; right: 12px; top: 50%;
    transform: translateY(-50%); font-weight: normal;
}
.ts-dropdown .highlight { background: color-mix(in srgb, var(--accent) 20%, transparent); color: inherit; border-radius: 2px; }
.ts-dropdown .no-results { color: var(--muted); }
/* Acordeón: la lista se despliega de arriba hacia abajo. */
.ts-dropdown.ts-acordeon { animation: ts-acordeon 0.24s cubic-bezier(0.2, 0.8, 0.2, 1); }
@keyframes ts-acordeon {
    from { clip-path: inset(0 0 100% 0 round 8px); opacity: 0.4; transform: translateY(-4px); }
    to { clip-path: inset(0 0 0 0 round 8px); opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .ts-dropdown.ts-acordeon { animation: none; }
    .ts-wrapper .ts-control::after { transition: none; }
}
/* Celdas de tablas de edición (tarjetones): el campo no ensancha la columna. */
td .ts-wrapper { min-width: 9rem; }

/* Flatpickr (selectores de fecha/fecha-hora, ver flatpickr_init.js): apenas lo
   necesario para que el popup del calendario respete el tema claro/oscuro de
   la app en vez de quedarse con el blanco fijo de su tema por default —
   reusa los mismos tokens que el resto de foxlima.css, sin theme aparte de
   Flatpickr. */
.flatpickr-calendar {
    background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radio-tarjeta);
    box-shadow: var(--shadow-md); font-family: inherit;
}
.flatpickr-calendar.arrowTop::before,
.flatpickr-calendar.arrowTop::after { border-bottom-color: var(--border); }
.flatpickr-months .flatpickr-month,
.flatpickr-current-month,
.flatpickr-weekdays { background: var(--card-bg); color: var(--text); fill: var(--text); }
.flatpickr-weekday { color: var(--muted); }
span.flatpickr-weekday { background: var(--card-bg); }
.flatpickr-day { color: var(--text); border-radius: 6px; }
.flatpickr-day.flatpickr-disabled,
.flatpickr-day.flatpickr-disabled:hover { color: var(--muted); opacity: 0.4; }
.flatpickr-day.prevMonthDay, .flatpickr-day.nextMonthDay { color: var(--muted); }
.flatpickr-day:hover, .flatpickr-day.today:hover { background: var(--bg-soft); border-color: var(--bg-soft); }
.flatpickr-day.today { border-color: var(--accent); }
.flatpickr-day.selected, .flatpickr-day.selected:hover {
    background: var(--boton-primario); border-color: var(--boton-primario); color: var(--texto-sobre-acento);
}
.flatpickr-current-month input.cur-year { color: var(--text); }
.flatpickr-current-month .flatpickr-monthDropdown-months { background: var(--card-bg); color: var(--text); }
.numInputWrapper span.arrowUp:after { border-bottom-color: var(--text); }
.numInputWrapper span.arrowDown:after { border-top-color: var(--text); }
.flatpickr-time input, .flatpickr-time .flatpickr-am-pm {
    color: var(--text); background: var(--card-bg);
}
.flatpickr-time .numInputWrapper:hover, .flatpickr-time input:hover,
.flatpickr-am-pm:hover, .flatpickr-am-pm:focus { background: var(--bg-soft); }

/* Grupos del formulario de Usuario: una opción por tarjeta, texto arriba y
   checkbox abajo (el campo se comporta como selección única, ver JS en
   usuario_form.html + validación server-side en forms.py). */
#id_groups { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 4px; }
#id_groups > div {
    border: 1px solid var(--border);
    border-radius: var(--radio-tarjeta);
    padding: 10px 14px;
    background: var(--card-bg);
}
#id_groups label {
    display: flex; flex-direction: column-reverse; align-items: flex-start; gap: 8px;
    font-weight: 600; cursor: pointer;
}

form ul.errorlist { color: var(--danger); font-size: 12px; margin: 4px 0 0; padding-left: 0; list-style: none; }
form ul.errorlist li::before { content: "\f333"; font-family: "bootstrap-icons"; margin-right: 4px; vertical-align: -1px; } /* bi-exclamation-circle */
.non-field-errors { margin-bottom: 14px; }
/* El ícono lo pone .non-field-errors::before (ver Mensajes): sin el de la lista. */
.non-field-errors ul.errorlist { margin: 0; color: inherit; font-size: inherit; }
.non-field-errors ul.errorlist li::before { content: none; }

.page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; min-height: 32px; gap: 1rem; flex-wrap: wrap; }
.page-header h1 { font-size: 20px; line-height: 24px; font-weight: 600; letter-spacing: -0.01em; margin: 0; }

.badge {
    display: inline-flex; align-items: center; gap: 4px;
    height: 20px;
    padding: 0 6px;
    border-radius: var(--radio-chip);
    font-size: 12px;
    line-height: 16px;
    font-weight: 500;
    white-space: nowrap;
}
.badge-success { background: var(--success-soft); color: var(--success); }
.badge-danger  { background: var(--danger-soft);  color: var(--danger); }
.badge-warning { background: var(--warning-soft); color: var(--warning); }
.badge-orange  { background: var(--orange-soft);  color: var(--orange); }
.badge-accent  { background: var(--accent-soft);  color: var(--accent-dark); }
.badge-neutral { background: #ededed; color: #525252; }
:root[data-theme="dark"] .badge-neutral { background: #383838; color: #b3b3b3; }
.badge-dark { background: var(--dark-badge-bg); color: var(--dark-badge-fg); }

/* --- Miniatura de foto en listados + modal de zoom --- */
.foto-thumb {
    width: 36px; height: 36px; border-radius: 50%; object-fit: cover;
    border: 1px solid var(--border); cursor: pointer; display: block;
    transition: transform 0.15s ease;
}
.foto-thumb:hover { transform: scale(1.08); }
.foto-thumb-empty {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; border-radius: 50%;
    background: var(--bg-soft); border: 1px solid var(--border); color: var(--muted);
    cursor: default; font-size: 16px;
}

.foto-modal {
    display: none; position: fixed; inset: 0; z-index: 8000;
    background: rgba(0, 0, 0, 0.78);
    align-items: center; justify-content: center;
}
.foto-modal.open { display: flex; }
.foto-modal img {
    max-width: min(90vw, 720px); max-height: 85vh;
    border-radius: var(--radio-tarjeta);
    box-shadow: var(--shadow-md);
}
.foto-modal-close {
    position: absolute; top: 20px; right: 28px;
    color: #fff; font-size: 1.6rem; cursor: pointer; opacity: 0.85;
}
.foto-modal-close:hover { opacity: 1; }

.info-modal {
    display: none; position: fixed; inset: 0; z-index: 8000;
    background: rgba(0, 0, 0, 0.36);
    align-items: center; justify-content: center;
}
.info-modal.open { display: flex; }
.info-modal-panel {
    width: min(90vw, 560px); max-height: 80vh; overflow-y: auto;
    background: var(--card-bg); border: 0;
    border-radius: var(--radius-xl); box-shadow: var(--shadow-md);
}
.info-modal-header {
    display: flex; align-items: center; justify-content: space-between;
    padding: 24px 24px 16px; border-bottom: 0;
}
.info-modal-header h2 { margin: 0; font-size: 16px; line-height: 20px; font-weight: 600; }
.info-modal-close { color: var(--muted); cursor: pointer; }
.info-modal-close:hover { color: var(--text); }
.info-modal-body { padding: 0 24px 24px; }
.info-modal-body h3 { font-size: 0.85rem; color: var(--muted); text-transform: uppercase; margin: 14px 0 6px; }
.info-modal-body h3:first-child { margin-top: 0; }
.info-modal-body ul { margin: 0 0 4px; padding-left: 1.2rem; }
.info-modal-body li { font-size: 0.9rem; margin-bottom: 4px; }

.messages { list-style: none; margin: 0 0 16px; padding: 0; }
.messages li, .non-field-errors {
    position: relative; display: block;
    padding: 12px 16px 12px 42px; border-radius: var(--radio-tarjeta); margin-bottom: 8px; font-size: 13px; line-height: 20px;
    background: var(--accent-soft); color: var(--text);
}
/* Ícono por tipo de mensaje (no depende solo del color). Va en posición
   absoluta y no con flex: algunos mensajes traen <strong> dentro del texto
   (csrf_failure.html) y con flex cada trozo se volvía una columna. */
.messages li::before, .non-field-errors::before { position: absolute; left: 16px; top: 12px; font-family: "bootstrap-icons"; font-size: 16px; line-height: 20px; }
.messages li::before { content: "\f431"; color: var(--accent); }          /* bi-info-circle */
.messages li.success::before { content: "\f26b"; color: var(--success); } /* bi-check-circle */
.messages li.warning::before { content: "\f33b"; color: var(--warning); } /* bi-exclamation-triangle */
.messages li.error::before, .non-field-errors::before { content: "\f333"; color: var(--danger); } /* bi-exclamation-circle */
.messages li.info { background: var(--accent-soft); }
.messages li.success { background: var(--success-soft); }
.messages li.warning { background: var(--warning-soft); }
.messages li.error, .non-field-errors { background: var(--danger-soft); }

.kpi-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-bottom: 20px; }
@media (max-width: 900px) { .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.kpi {
    padding: 12px 16px; border-radius: var(--radius-kpi); background: var(--card-bg);
    border: 1px solid var(--border); box-shadow: none;
}
.kpi .kpi-value { font-size: 24px; font-weight: 600; }

.kpi .kpi-label { font-size: 12px; font-weight: 600; color: var(--muted); }

/* Switch "Resumen" de la vista Mes (calendario_servicio.html/
   calendario_instructor.html) — patrón checkbox-hack: el track/thumb son
   ::before/::after de un <span> hermano del <input>, sin JS de animación,
   solo el onchange que ya reenvía el form (mismo criterio que el resto de
   controles del header del calendario). */
.switch-toggle {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 13px; font-weight: 600; color: var(--text); cursor: pointer; user-select: none;
}
.switch-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track {
    position: relative; width: 34px; height: 20px; border-radius: var(--radius-pill);
    background: var(--border); transition: background 0.15s ease; flex-shrink: 0;
}
.switch-track::after {
    content: ''; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
    border-radius: 50%; background: #fff; box-shadow: var(--shadow-hover);
    transition: transform 0.15s ease;
}
.switch-toggle input:checked + .switch-track { background: var(--accent); }
.switch-toggle input:checked + .switch-track::after { transform: translateX(14px); }
.switch-toggle input:focus-visible + .switch-track { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Mi cuenta > Notificaciones por correo: interruptor general destacado +
   una caja por tipo de notificación (grilla que se acomoda al ancho, 1
   columna en móvil). Dentro de cada caja, una fila por opción con el texto
   a la izquierda y el switch alineado a la derecha. */
.notif-ayuda { font-size: 12px; color: var(--muted); font-weight: 400; }
.notif-general {
    display: flex; align-items: center; gap: 14px;
    padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--radius-xl);
    background: var(--accent-soft);
}
.notif-general-icono {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    border-radius: 50%; background: var(--boton-primario); color: var(--texto-sobre-acento);
}
.notif-general-icono { width: 36px; height: 36px; font-size: 17px; }
.notif-general-texto { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.notif-general-texto strong { font-size: 14px; color: var(--text); }

.notif-general .switch-toggle { position: relative; }

/* --- Login: foto a pantalla completa (2026-11-07) ---
   La foto cubre toda la pantalla y la tarjeta queda encima, a la derecha.
   .login-side ya no es el contenedor posicionado: su ::before (foto) y su
   ::after (velo) se anclan a .login-shell. */
.login-shell {
    position: relative; overflow: hidden; isolation: isolate;
    min-height: 100vh; display: grid; grid-template-columns: 1.1fr 1fr;
    background: var(--bg);
}
.login-side {
    position: static;
    display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start; color: #fff;
    padding: 64px 56px 56px;
}
/* Foto: la del login de Scriptcase (montañas y lago, sin vehículo; ver
   static/img/login/CREDITOS.md), 1920 × 1080. Entra en blanco y negro y en 6 s
   pasa a color, una sola vez, sin blur ni zoom (se ve distorsionado). Al cambiar
   la foto, cámbiale el nombre: Cloudflare guarda /static/ en caché y el url() no
   lleva versión. */
.login-side::before {
    content: ''; position: absolute; inset: -24px; z-index: -2;
    /* AVIF (253 KB) con WebP (331 KB) de respaldo; sin image-set(), el WebP. */
    background: url("../img/login/fondo_v1.webp") 50% 60% / cover no-repeat #2f2f31;
    background-image: image-set(url("../img/login/fondo_v1.avif") type("image/avif"),
                                url("../img/login/fondo_v1.webp") type("image/webp"));
    animation: login-foto 6s ease-out 0.3s both;
}
/* Velo: oscuro arriba a la izquierda (para leer el título sobre el cielo) y,
   hacia la derecha, un fundido suave al color de fondo que no pasa del 45 %:
   la foto se sigue viendo detrás de la tarjeta. */
.login-side::after {
    content: ''; position: absolute; inset: 0; z-index: -1;
    background:
        linear-gradient(to right, transparent 40%, color-mix(in srgb, var(--bg) 18%, transparent) 60%,
            color-mix(in srgb, var(--bg) 35%, transparent) 80%, color-mix(in srgb, var(--bg) 45%, transparent) 100%),
        linear-gradient(to bottom, rgba(16, 16, 18, 0.75) 0%, rgba(16, 16, 18, 0.35) 28%, rgba(16, 16, 18, 0) 52%);
    animation: login-velo 6s ease-out 0.3s both;
}
.login-main { position: relative; }
@media (max-width: 860px) {
    .login-shell { grid-template-columns: 1fr; }
    .login-side { padding: 0; }
    .login-side h1, .login-side p { display: none; }
    .login-side::after { background: color-mix(in srgb, var(--bg) 40%, transparent); }
}
@keyframes login-foto {
    from { filter: grayscale(1) brightness(1.05) contrast(1.05); }
    to { filter: grayscale(0) brightness(1.05) contrast(1.05); }
}
@keyframes login-velo {
    from { opacity: 1; }
    to { opacity: 0.85; }
}
.login-side h1 { font-size: 2.1rem; line-height: 1.15; margin: 0 0 10px; max-width: 460px; }
.login-side h1::before {
    content: ''; display: block; width: 56px; height: 4px; border-radius: 2px; margin-bottom: 16px;
    background: linear-gradient(90deg, #8a6d1b, #d9b84a);
}
.login-side p { max-width: 420px; margin: 0; font-weight: 600; opacity: 0.95; }
.login-side h1, .login-side p { text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9), 0 0 22px rgba(0, 0, 0, 0.6); }
.login-side h1, .login-side p { animation: login-texto 0.9s ease-out 0.6s both; }
@keyframes login-texto {
    from { opacity: 0; transform: translateY(-12px); }
    to { opacity: 1; transform: none; }
}
.login-main { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 24px; }
.login-main-logo {
    height: 120px; width: auto; max-width: 100%; display: block; margin-bottom: 18px;
    animation: login-logo 0.8s ease-out 0.15s both;
}
@keyframes login-logo {
    from { opacity: 0; transform: translateY(-10px) scale(0.98); }
    to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .login-side::before { animation: none; filter: none; }
    .login-side::after { animation: none; opacity: 0.85; }
    .login-side h1, .login-side p, .login-main-logo { animation: none; }
}
/* Tarjeta de vidrio esmerilado (26 % de fondo): lo de atrás se desenfoca y se
   aclara (tema claro) u oscurece (tema oscuro) para que el texto se lea. */
.login-card {
    width: 100%; max-width: 380px; padding: 32px;
    border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
    border-radius: var(--radius-xl); box-shadow: var(--shadow-md);
    background: color-mix(in srgb, var(--card-bg) 26%, transparent);
    -webkit-backdrop-filter: blur(16px) saturate(1.2) brightness(1.9);
    backdrop-filter: blur(16px) saturate(1.2) brightness(1.9);
}
:root[data-theme="dark"] .login-card {
    -webkit-backdrop-filter: blur(16px) saturate(1.1) brightness(0.6);
    backdrop-filter: blur(16px) saturate(1.1) brightness(0.6);
}
.login-card h1 { font-size: 20px; line-height: 24px; font-weight: 700; margin: 0 0 6px; }
.login-card .sub { color: var(--text); font-weight: 500; font-size: 0.9rem; margin-bottom: 24px; }
.login-card label { color: var(--text); font-weight: 600; }
.login-card h1, .login-card .sub, .login-card label, .login-card a {
    text-shadow: 0 0 6px color-mix(in srgb, var(--card-bg) 85%, transparent),
                 0 1px 1px color-mix(in srgb, var(--card-bg) 60%, transparent);
}
.login-card .btn { width: 100%; justify-content: center; height: 36px; margin-top: 8px; }
.login-signup {
    margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--border);
    text-align: center;
}
.login-signup p { color: var(--muted); font-size: 13px; margin: 0 0 10px; }
.login-website { margin-top: 4px; text-align: center; }
.login-olvide { margin: -4px 0 4px; text-align: right; font-size: 0.85rem; }
.login-olvide a, .login-website a { color: var(--accent); font-weight: 500; text-decoration: none; }
.login-olvide a:hover, .login-olvide a:focus-visible,
.login-website a:hover, .login-website a:focus-visible { text-decoration: underline; }
.login-card h1 .bi { color: var(--accent); }
/* Elegir / cambiar de rol (templates/club/auth/elegir_rol.html): una
   tarjeta-botón por cuenta de la persona (mismo correo, distinto rol). */
.rol-opciones { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.rol-opcion {
    display: flex; align-items: center; gap: 14px; width: 100%; padding: 12px 14px;
    background: var(--surface); color: var(--text); text-align: left; font: inherit;
    border: 1px solid var(--border); border-radius: var(--radio-tarjeta); cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}
.rol-opcion:hover { border-color: var(--borde-fuerte); background: var(--fondo-hover); }
.rol-opcion > .bi:first-child { font-size: 1.4rem; color: var(--accent); }
.rol-opcion-texto { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.rol-opcion-texto small { color: var(--muted); font-size: 0.8rem; }
.rol-opcion-flecha { color: var(--muted); }
.rol-opcion-actual { cursor: default; background: var(--bg-soft); }
.rol-opcion-actual:hover { border-color: var(--border); background: var(--bg-soft); }
.rol-opcion-actual .rol-opcion-flecha { visibility: hidden; }
/* Campo de contraseña con botón de mostrar/ocultar (ojito) — reusado en el
   login y en el alta de Usuario (password1/password2), no solo en .login-card. */
.password-field { position: relative; display: block; }
.password-field input { padding-right: 2.4rem; }
.password-toggle {
    position: absolute; top: 50%; right: 0.6rem; transform: translateY(-50%);
    background: none; border: none; padding: 4px; cursor: pointer;
    color: var(--muted); display: flex; align-items: center;
}
.password-toggle:hover { color: var(--text); }

/* Checklist en vivo de reglas de contraseña (alta de Usuario). */
.password-checklist { margin: 6px 0 0; display: flex; flex-direction: column; gap: 4px; }
.regla {
    display: flex; align-items: center; gap: 6px;
    font-size: 0.82rem; color: var(--muted); margin: 0;
}
.regla.regla-ok { color: var(--success); }
.regla-nota { font-size: 0.78rem; color: var(--muted); margin: 2px 0 0; }

/* --- Shell del portal de Staff (header + sidebar + área de trabajo) --- */
.app-shell {
    display: flex; flex-direction: column;
    /* dvh (viewport visible real) en vez de vh (viewport "máximo" con la
       barra de Safari oculta): en iOS, cuando aparece una barra del sistema
       arriba (ej. el aviso "Volver a WhatsApp" al abrir un link desde el
       chat), vh no se achica pero el área visible sí — con solo vh, la
       franja superior del shell (topbar) queda tapada/recortada. */
    height: 100vh; height: 100dvh;
}
.app-body { flex: 1; min-height: 0; display: flex; background: var(--marco-fondo); }

/* --- Menú lateral de Staff (acordeón, colapsable) --- */
.staff-sidebar {
    width: 256px; flex-shrink: 0;
    background: var(--marco-fondo); border-right: 0; padding: 12px 12px 16px;
    overflow-y: auto; overflow-x: hidden;
    transition: width 0.18s ease;
}
.staff-sidebar.collapsed { width: 56px; padding: 12px 8px; }
.sidebar-group-btn {
    width: 100%; background: transparent; border: 0; cursor: pointer;
    display: flex; align-items: center; gap: 8px;
    height: 40px; padding: 0 9px; border-radius: 8px;
    font-weight: 450; font-size: 14px; color: var(--text); text-align: left;
}
.sidebar-group-btn .bi { font-size: 18px; color: var(--text); }
.sidebar-group-btn:hover { background: var(--lat-hover); }
.sidebar-group.open > .sidebar-group-btn { font-weight: 500; }
.sidebar-group-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-caret { font-size: 0.7rem; color: var(--muted); opacity: 0; transition: transform 0.18s ease, opacity var(--duracion-rapida); }
.sidebar-group-btn:hover .sidebar-caret,
.sidebar-group-btn:focus-visible .sidebar-caret,
.sidebar-group.open .sidebar-caret { opacity: 1; }
.sidebar-group.open .sidebar-caret { transform: rotate(180deg); }
.sidebar-group-btn:focus-visible, .sidebar-group-items a:focus-visible { outline: 2px solid var(--text); outline-offset: 1px; }
/* Acordeón suave con altura real (no un max-height "adivinado" que hace que
   un submenú corto termine de revelarse mucho antes de que acabe la
   transición, y se sienta brusco/entrecortado) — técnica de grid con fila
   0fr -> 1fr: el track de la grilla sí anima entre fracciones, a diferencia
   de height/max-height que no puede animar hacia/desde "auto". El contenido
   real vive en .sidebar-group-items-inner, con overflow:hidden y min-height:0
   (si no, una grilla no deja encoger su contenido por debajo de su alto
   natural y el "0fr" no cierra del todo). */
.sidebar-group-items {
    display: grid; grid-template-rows: 0fr; opacity: 0;
    transition: grid-template-rows 0.28s ease, opacity 0.22s ease;
}
.sidebar-group.open .sidebar-group-items { grid-template-rows: 1fr; opacity: 1; }
.sidebar-group-items-inner { overflow: hidden; min-height: 0; padding: 2px 0 4px; }
.sidebar-group-items a {
    position: relative; display: flex; align-items: center; gap: 8px;
    height: 32px; padding: 0 10px; margin-left: 26px; border-radius: 8px;
    font-size: 13px; font-weight: 450; color: var(--text); text-decoration: none;
}
/* "L" que une cada subítem con su grupo (Reservas, submenú del sidebar). */
.sidebar-group-items a::before {
    content: ''; position: absolute; left: -9px; top: -16px;
    width: 8px; height: 32px; border-radius: 0; background: none;
    border-left: 1px solid var(--lat-raya); border-bottom: 1px solid var(--lat-raya);
    border-bottom-left-radius: 7px; pointer-events: none;
}
.sidebar-group-items-inner > a:first-child::before { top: -2px; height: 18px; }
.sidebar-group-items a:hover { background: var(--lat-hover); }
.sidebar-group-items a:hover::before { background: none; }
.sidebar-group-items a.activo { background: var(--lat-activo); font-weight: 500; }
.staff-sidebar.collapsed .sidebar-group-btn { justify-content: center; padding: 0; }
.staff-sidebar.collapsed .sidebar-group-label,
.staff-sidebar.collapsed .sidebar-caret,
.staff-sidebar.collapsed .sidebar-group-items { display: none; }

/* --- Responsive móvil (portal de Staff): el menú ya arranca cerrado por
   defecto (ver home.html, restoreSidebar) — acá además se ocultan el toggle
   de tema y los indicadores de la barra superior, que no entran cómodos en
   una pantalla angosta. --- */
@media (max-width: 768px) {
    .theme-switch { display: none; }
    /* En desktop, colapsado deja una franja de 56px con solo los íconos
       (modo "rail"). En móvil esa franja sigue robándole ancho a la vista
       activa, así que colapsado acá se oculta del todo (íconos incluidos). */
    .staff-sidebar.collapsed { width: 0; padding: 0; border-right: 0; }
}

/* --- Área de trabajo: barra de pestañas + contenido --- */
.main-area {
    flex: 1; min-width: 0; display: flex; flex-direction: column;
    margin: 0 var(--marco-aire) var(--marco-aire) 0;
    border: 1px solid var(--marco-hoja-borde); border-radius: var(--hoja-radio);
    overflow: hidden; background: var(--card-bg);
}
.tabs-bar {
    display: flex; align-items: stretch; gap: 2px; height: var(--alto-franja); flex-shrink: 0;
    padding: 0 8px; background: var(--card-bg); border-bottom: 1px solid var(--border);
    overflow-x: auto;
}
.tab {
    position: relative; display: flex; align-items: center; gap: 8px; padding: 0 10px; font-size: 13px; font-weight: 500;
    color: var(--muted); border-right: 0; cursor: pointer; white-space: nowrap;
    background: transparent;
}
/* Sin pestañas abiertas (inicio) la franja no ocupa lugar. */
.tabs-bar:empty { display: none; }
.tab:hover { color: var(--text); }
.tab.active { background: transparent; color: var(--accent); }
.tab.active::after {
    content: ''; position: absolute; left: 8px; right: 8px; bottom: -1px;
    height: 2px; border-radius: 2px 2px 0 0; background: var(--accent);
}
.tab .tab-close {
    display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px;
    border-radius: 4px; color: var(--muted); font-weight: 400; opacity: 1;
}
.tab .tab-close:hover { background: var(--fondo-hover); color: var(--text); }
.tabs-viewport { position: relative; flex: 1; min-height: 0; background: var(--card-bg); }
.tab-pane { position: absolute; inset: 0; display: none; }
.tab-pane.active { display: block; }
.tab-pane iframe { width: 100%; height: 100%; border: 0; display: block; background: var(--card-bg); }
.tab-empty { display: block; height: 100%; overflow-y: auto; padding: 24px 32px; color: var(--text); }
/* Inicio con el Dashboard de viajes en un iframe (core/staff/home.html). */
.tab-empty.tab-empty-dashboard { padding: 0; overflow: hidden; }
.tab-empty-dashboard iframe { flex: 1; width: 100%; height: 100%; border: 0; display: block; background: var(--card-bg); }
/* En móvil la hoja ocupa todo el ancho, sin filo ni esquinas (va después de
   .main-area para ganarle). */
@media (max-width: 768px) { .main-area { margin: 0; border: 0; border-radius: 0; } }

/* --- Dashboard básico (home del portal de Staff, estado sin pestañas) --- */
.dashboard { max-width: 1100px; margin: 0 auto; }
.dashboard h2 { margin: 0 0 16px; font-size: 1.3rem; display: flex; align-items: center; gap: 8px; }
/* Título del dashboard + etiqueta del período filtrado (clic = abre filtros). */
.dashboard-titulo { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.dashboard-titulo h2 { margin: 0; }

.panel-lateral-caja h3 { margin: 0 0 8px; font-size: 1.1rem; display: flex; align-items: center; gap: 8px; }

/* --- Overlay de "procesando" al enviar un formulario (evita doble envío,
   ver base_embed.html/base.html) — mismo patrón que shared/DESIGN_SYSTEM.md
   sección "Overlay de procesamiento a pantalla completa". */
.processing-overlay {
    position: fixed; inset: 0; z-index: 9000;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
    background: rgba(0, 0, 0, 0.4); backdrop-filter: blur(1px);
}
.processing-spinner {
    width: 32px; height: 32px; border-radius: 50%;
    border: 3px solid var(--borde-fuerte); border-top-color: var(--accent);
    animation: processing-spin 0.8s linear infinite;
}
.processing-overlay span {
    background: var(--card-bg); color: var(--text);
    padding: 6px 16px; border-radius: var(--radius-pill); font-size: 0.9rem; box-shadow: var(--shadow-md);
}
@keyframes processing-spin { to { transform: rotate(360deg); } }

/* --- Drawer / panel lateral (Ver/Editar/Nuevo/Borrar sin reemplazar toda la
   página) — ver shared/DESIGN_SYSTEM.md sección 18 y
   static/js/panel_lateral.js. z-index por debajo de los modales genuinos
   (.foto-modal en 8000) para que esos sigan abriéndose por encima de un
   panel ya abierto, y por debajo de .processing-overlay (9000) para que un
   spinner de guardado se siga viendo. */
.panel-lateral { position: fixed; inset: 0; z-index: 7800; }
.panel-lateral[hidden] { display: none; }
.panel-lateral-fondo {
    position: absolute; inset: 0;
    background: rgba(0, 0, 0, 0.05);
    cursor: pointer;
}
.panel-lateral-caja {
    position: absolute; top: 0; right: 0; height: 100%;
    width: 50%; max-width: 720px; min-width: min(100%, 420px);
    background: var(--card-bg);
    border-left: 1px solid var(--border);
    box-shadow: var(--shadow-md);
    display: flex; flex-direction: column;
    overflow-y: auto;
    padding: 24px;
    transform: translateX(100%);
    transition: transform 0.25s ease, width 0.25s ease, max-width 0.25s ease;
}
.panel-lateral.abierto .panel-lateral-caja { transform: translateX(0); }
/* Vista expandida (botón junto a la X, 2026-10-10): el panel ocupa todo el
   ancho del área de trabajo. La preferencia se recuerda por navegador
   (localStorage 'realplata_panel_modo', ver panel_lateral.js). */
.panel-lateral.expandido .panel-lateral-caja { width: 100%; max-width: 100%; }
/* Botones de la esquina: modos (normal/expandido) + cerrar, congelados arriba
   al hacer scroll igual que antes lo estaba solo la X. */
.panel-lateral-acciones {
    position: sticky; top: 16px; align-self: flex-end; z-index: 2; margin-bottom: -12px;
    display: flex; align-items: center; gap: 10px;
}
.panel-lateral-modos { display: flex; gap: 4px; }
.panel-lateral-modos .icon-btn[aria-pressed="true"] {
    background: var(--accent-soft); border-color: var(--accent);
}
@media (max-width: 768px) {
    .panel-lateral-caja,
    .panel-lateral.expandido .panel-lateral-caja { width: 100%; max-width: none; min-width: 0; }
    .panel-lateral-modos { display: none; }
}
/* Título de la vista actual, congelado al hacer scroll dentro del panel —
   ver shared/DESIGN_SYSTEM.md sección 18 para la explicación del margen/top
   negativos (escapan el padding de .panel-lateral-caja). */
#panel-lateral-body > .page-header:first-child {
    position: sticky; top: -24px;
    margin: -24px -24px 0;
    padding: 24px 140px 16px 24px; /* derecha: deja libres los 3 botones de la esquina */
    background: var(--card-bg);
    z-index: 1;
}
@media (max-width: 768px) {
    #panel-lateral-body > .page-header:first-child { padding-right: 56px; } /* solo la X */
}

/* --- Íconos en azul de marca (2026-10-10) ---
   A pedido del usuario, todos los íconos de contorno (Bootstrap Icons) del
   aplicativo van en el azul del tema (--accent, se adapta a claro/oscuro).
   Va al final del archivo para ganarle a reglas de una sola clase anteriores.
   Excepciones: el ícono toma el color de su contenedor cuando ese color ya
   comunica algo (badges, mensajes, encabezados de alerta, botones de
   exportar) o el fondo es azul/de color (botón primario, franja de marca,
   panel del login, círculos de Mi cuenta) — ahí un ícono azul no se vería. */
/* Restyling Paso 5 (2026-11-07): los íconos siguen el color del texto, como
   en Reservas; se quitó la regla heredada "íconos en color de marca". */
.bi { color: inherit; }
/* Booleanos sí/no de los listados: conservan su verde/rojo semántico. */
.bi.bool-icon-true { color: var(--success); }
.bi.bool-icon-false { color: var(--danger); }

/* --- Leyendas de ayuda de los formularios (2026-10-11) ---
   Todo `.helptext` (los help_text de Django y los que pintan los templates):
   texto gris debajo del campo, con una bombilla en ::before (Django genera el
   <span> y no se le puede insertar un <i>). Sin caja de color (Paso 4 del plan). */
.helptext {
    display: block;
    margin: 4px 0 0; padding: 0;
    background: none; border: 0;
    color: var(--muted); font-size: 12px; font-weight: 400; line-height: 1.45;
}
.helptext::before {
    content: "\f46b"; font-family: "bootstrap-icons"; font-weight: normal;
    font-size: 13px; line-height: 1.45; flex-shrink: 0;
}

.helptext::before { display: none; }
.helptext:empty { display: none; }

/* --- Real Plata: ítems del menú todavía no migrados (se usan en Scriptcase) --- */
.sidebar-item-pendiente {
    display: flex; align-items: center; gap: 8px;
    height: 32px; padding: 0 10px; margin-left: 26px; font-size: 13px;
    color: var(--muted); opacity: 0.7; cursor: not-allowed;
}
.sidebar-item-pendiente::before {
    content: ''; width: 5px; height: 5px; border-radius: 50%;
    border: 1px solid var(--muted); flex-shrink: 0;
}
.sidebar-item-pendiente small, .lista-bienvenida small {
    font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.4px;
    border: 1px solid var(--line); border-radius: var(--radius-pill); padding: 0 6px; margin-left: 4px;
}
.staff-sidebar.collapsed .sidebar-item-pendiente { display: none; }
.cards-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; margin-top: 16px; }
.lista-bienvenida { list-style: none; margin: 0; padding: 0; }
.lista-bienvenida li { padding: 3px 0; font-size: 0.9rem; }

/* --- Pestañas internas de una ficha (ej. ficha del piloto) --- */
.pestanas { display: flex; flex-wrap: wrap; gap: 0; margin: 16px 0 0 -8px; border-bottom: 1px solid var(--border); }
.pestana {
    position: relative; background: transparent; border: 0; border-radius: 6px; margin: 0;
    padding: 6px 8px; font-size: 13px; color: var(--muted); cursor: pointer; font-weight: 500;
}
.pestana::after {
    content: ''; position: absolute; left: 8px; right: 8px; bottom: -1px;
    height: 2px; border-radius: 2px 2px 0 0; background: transparent;
}
.pestana:hover { color: var(--text); background: transparent; }
.pestana:hover::after { background: var(--border); }
.pestana.activa { color: var(--accent); background: transparent; margin-bottom: 0; }
.pestana.activa::after { background: var(--accent); }
.pestana-cuenta { font-size: 0.72rem; color: var(--muted); font-weight: 500; margin-left: 2px; }
.panel-pestana { border-top-left-radius: 0; margin-top: 0; }

.detalle-seccion { font-size: 0.9rem; margin: 18px 0 8px; color: var(--accent); }
.detalle-seccion:first-child { margin-top: 0; }
.detalle-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px 24px; font-size: 13px; }

/* .campo: contenedor de un campo de formulario como <div> (no <p>): un grupo
   de casillas o radios genera un <div> y el navegador cierra el <p> que lo
   contiene, separando el grupo de su etiqueta. Ver core/staff/_campos.html. */
.campo .helptext { display: block; }
.campo > div[id^="id_"] label { font-weight: 400; display: inline-flex; align-items: center; gap: 6px; margin-right: 14px; }
.campo > div[id^="id_"] > div { display: inline-block; }

/* Filtro de período (desde/hasta + atajos) arriba de un informe (Real Plata). */
.filtro-periodo { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; }
.filtro-periodo label { display: flex; flex-direction: column; gap: 4px; font-weight: 600; }
.filtro-periodo input { width: 170px; }

.fila-subtotal td { background: var(--bg-soft) !important; border-top: 1px solid var(--line); }

/* --- Filtro por segmentos de los grids (core/segmentos.py), portado de jyl --- */
/* Botón del toolbar y chips de filtros activos. */
.seg-boton { position: relative; }
.seg-boton.activo { color: var(--accent); background: var(--accent-soft); }
.seg-cuenta {
    display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 4px;
    border-radius: var(--radius-pill); background: var(--boton-primario); color: var(--texto-sobre-acento);
    font-size: 10px; font-weight: 600; line-height: 1;
}
.seg-boton .seg-cuenta { position: absolute; top: -5px; right: -5px; }
.seg-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 10px; }
.seg-chip {
    display: inline-flex; align-items: center; gap: 4px; padding: 3px 6px 3px 10px; border-radius: var(--radius-pill);
    background: var(--accent-soft); color: var(--text); font-size: 12px; text-decoration: none; max-width: 100%;
}
.seg-chip strong { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.seg-chip .bi { color: var(--muted); }
.seg-chip:hover .bi { color: var(--danger); }
.seg-limpiar { font-size: 12px; color: var(--accent); margin-left: 4px; }

/* Panel izquierdo. */
.seg-fondo { position: fixed; inset: 0; z-index: 7000; background: rgba(0, 0, 0, 0); transition: background 0.2s ease; }
.seg-fondo.abierto { background: rgba(0, 0, 0, 0.25); }
.seg-panel {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 7010; width: min(340px, 100%);
    background: var(--card-bg); border-right: 1px solid var(--border); box-shadow: var(--shadow-md);
    transform: translateX(-100%); transition: transform 0.22s ease;
}
.seg-panel.abierto { transform: none; }
.seg-form { display: flex; flex-direction: column; height: 100%; }
.seg-cabeza { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 16px 16px 8px; }
.seg-cabeza h2 { margin: 0; font-size: 16px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
.seg-cuerpo { flex: 1; overflow-y: auto; padding: 0 8px 8px; }
.seg-grupo { border-bottom: 1px solid var(--borde-suave); padding: 2px 0; }
.seg-grupo > summary {
    display: flex; align-items: center; gap: 6px; padding: 9px 8px; border-radius: 6px; cursor: pointer;
    font-size: 13px; font-weight: 600; list-style: none;
}
.seg-grupo > summary::-webkit-details-marker { display: none; }
.seg-grupo > summary::after { content: "\f282"; font-family: "bootstrap-icons"; margin-left: auto; font-size: 11px; color: var(--muted); transition: transform 0.18s ease; }
.seg-grupo[open] > summary::after { transform: rotate(180deg); }
.seg-grupo > summary:hover { background: var(--fondo-hover); }
form input.seg-buscar:not([type="checkbox"]):not([type="radio"]),
.seg-buscar { width: calc(100% - 16px); margin: 2px 8px 6px; min-height: 30px; padding: 4px 8px; font-size: 12px; border: 1px solid var(--borde-control); border-radius: 6px; background: var(--card-bg); color: var(--text); }
.seg-lista { list-style: none; margin: 0; padding: 0 0 6px; }
.seg-lista label { display: grid; grid-template-columns: 16px minmax(0, 1fr) auto; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 6px; cursor: pointer; font-size: 13px; }
.seg-lista label:hover { background: var(--fondo-hover); }
/* Badges estilo Tailwind con tonos variados (pedido del usuario, 2026-11-10):
   nombre del segmento, y en cada opción su nombre (tono claro: 100/800) y su
   cantidad de registros (tono sólido: 600/blanco). Los tonos se alternan con
   :nth-child para distinguir una opción de la siguiente. */
:root {
    --seg-t1-bg: #dbeafe; --seg-t1-fg: #1e40af; --seg-t1-solido: #2563eb; --seg-t1-borde: rgba(37, 99, 235, .25);
    --seg-t2-bg: #d1fae5; --seg-t2-fg: #065f46; --seg-t2-solido: #059669; --seg-t2-borde: rgba(5, 150, 105, .25);
    --seg-t3-bg: #fef3c7; --seg-t3-fg: #92400e; --seg-t3-solido: #d97706; --seg-t3-borde: rgba(217, 119, 6, .25);
    --seg-t4-bg: #ffe4e6; --seg-t4-fg: #9f1239; --seg-t4-solido: #e11d48; --seg-t4-borde: rgba(225, 29, 72, .25);
    --seg-t5-bg: #ede9fe; --seg-t5-fg: #5b21b6; --seg-t5-solido: #7c3aed; --seg-t5-borde: rgba(124, 58, 237, .25);
    --seg-t6-bg: #cffafe; --seg-t6-fg: #155e75; --seg-t6-solido: #0891b2; --seg-t6-borde: rgba(8, 145, 178, .25);
    --seg-t7-bg: #ffedd5; --seg-t7-fg: #9a3412; --seg-t7-solido: #ea580c; --seg-t7-borde: rgba(234, 88, 12, .25);
    --seg-t8-bg: #e0e7ff; --seg-t8-fg: #3730a3; --seg-t8-solido: #4f46e5; --seg-t8-borde: rgba(79, 70, 229, .25);
}
:root[data-theme="dark"] {
    --seg-t1-bg: rgba(59, 130, 246, .16); --seg-t1-fg: #93c5fd; --seg-t1-solido: #3b82f6; --seg-t1-borde: rgba(147, 197, 253, .3);
    --seg-t2-bg: rgba(16, 185, 129, .16); --seg-t2-fg: #6ee7b7; --seg-t2-solido: #10b981; --seg-t2-borde: rgba(110, 231, 183, .3);
    --seg-t3-bg: rgba(245, 158, 11, .16); --seg-t3-fg: #fcd34d; --seg-t3-solido: #d97706; --seg-t3-borde: rgba(252, 211, 77, .3);
    --seg-t4-bg: rgba(244, 63, 94, .16); --seg-t4-fg: #fda4af; --seg-t4-solido: #e11d48; --seg-t4-borde: rgba(253, 164, 175, .3);
    --seg-t5-bg: rgba(139, 92, 246, .16); --seg-t5-fg: #c4b5fd; --seg-t5-solido: #7c3aed; --seg-t5-borde: rgba(196, 181, 253, .3);
    --seg-t6-bg: rgba(6, 182, 212, .16); --seg-t6-fg: #67e8f9; --seg-t6-solido: #0891b2; --seg-t6-borde: rgba(103, 232, 249, .3);
    --seg-t7-bg: rgba(249, 115, 22, .16); --seg-t7-fg: #fdba74; --seg-t7-solido: #ea580c; --seg-t7-borde: rgba(253, 186, 116, .3);
    --seg-t8-bg: rgba(99, 102, 241, .16); --seg-t8-fg: #a5b4fc; --seg-t8-solido: #4f46e5; --seg-t8-borde: rgba(165, 180, 252, .3);
}
.seg-grupo:nth-of-type(8n+1) { --seg-bg: var(--seg-t1-bg); --seg-fg: var(--seg-t1-fg); --seg-solido: var(--seg-t1-solido); --seg-borde: var(--seg-t1-borde); }
.seg-grupo:nth-of-type(8n+2) { --seg-bg: var(--seg-t2-bg); --seg-fg: var(--seg-t2-fg); --seg-solido: var(--seg-t2-solido); --seg-borde: var(--seg-t2-borde); }
.seg-grupo:nth-of-type(8n+3) { --seg-bg: var(--seg-t3-bg); --seg-fg: var(--seg-t3-fg); --seg-solido: var(--seg-t3-solido); --seg-borde: var(--seg-t3-borde); }
.seg-grupo:nth-of-type(8n+4) { --seg-bg: var(--seg-t4-bg); --seg-fg: var(--seg-t4-fg); --seg-solido: var(--seg-t4-solido); --seg-borde: var(--seg-t4-borde); }
.seg-grupo:nth-of-type(8n+5) { --seg-bg: var(--seg-t5-bg); --seg-fg: var(--seg-t5-fg); --seg-solido: var(--seg-t5-solido); --seg-borde: var(--seg-t5-borde); }
.seg-grupo:nth-of-type(8n+6) { --seg-bg: var(--seg-t6-bg); --seg-fg: var(--seg-t6-fg); --seg-solido: var(--seg-t6-solido); --seg-borde: var(--seg-t6-borde); }
.seg-grupo:nth-of-type(8n+7) { --seg-bg: var(--seg-t7-bg); --seg-fg: var(--seg-t7-fg); --seg-solido: var(--seg-t7-solido); --seg-borde: var(--seg-t7-borde); }
.seg-grupo:nth-of-type(8n+8) { --seg-bg: var(--seg-t8-bg); --seg-fg: var(--seg-t8-fg); --seg-solido: var(--seg-t8-solido); --seg-borde: var(--seg-t8-borde); }
/* Opciones de cada segmento: solo fondo gris (pedido del usuario, 2026-11-10);
   los colores quedan para el nombre del segmento. */
:root { --seg-gris-bg: #f3f4f6; --seg-gris-fg: #374151; --seg-gris-borde: #e5e7eb; --seg-gris-num: #e5e7eb; --seg-gris-anillo: #6b7280; }
:root[data-theme="dark"] { --seg-gris-bg: rgba(255, 255, 255, .07); --seg-gris-fg: #d1d5db; --seg-gris-borde: rgba(255, 255, 255, .12); --seg-gris-num: rgba(255, 255, 255, .12); --seg-gris-anillo: #9ca3af; }
.seg-lista li { --seg-bg: var(--seg-gris-bg); --seg-fg: var(--seg-gris-fg); --seg-borde: var(--seg-gris-borde); --seg-solido: var(--seg-gris-anillo); }
.seg-titulo, .seg-etq {
    display: inline-block; max-width: 100%; padding: 2px 9px; border-radius: var(--radius-pill);
    background: var(--seg-bg); color: var(--seg-fg); box-shadow: inset 0 0 0 1px var(--seg-borde);
    font-size: 12px; font-weight: 600; line-height: 1.5; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.seg-titulo { font-size: 12.5px; }
.seg-etq { justify-self: start; font-weight: 500; }
.seg-num {
    min-width: 26px; padding: 1px 8px; border-radius: var(--radius-pill); text-align: center;
    background: var(--seg-gris-num); color: var(--seg-gris-fg); font-size: 11px; font-weight: 600; line-height: 1.6;
    font-variant-numeric: tabular-nums;
}
/* Opción elegida: anillo del mismo tono para que se note. */
.seg-lista label:has(input:checked) .seg-etq { box-shadow: inset 0 0 0 1.5px var(--seg-solido); }
.seg-vacio { padding: 5px 8px; color: var(--muted); font-size: 12px; }
.seg-ver-todos { margin: 0 8px 8px; padding: 2px 0; border: 0; background: none; color: var(--accent); font: inherit; font-size: 12px; font-weight: 500; cursor: pointer; }
.seg-fechas { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 2px 8px 10px; }
.seg-fechas .campo { margin: 0; }
.seg-fechas label { font-size: 12px; color: var(--muted); font-weight: 600; display: block; margin-bottom: 4px; }
.seg-fechas input { width: 100%; min-height: var(--alto-control); padding: 6px 8px; font-size: 13px; border: 1px solid var(--borde-control); border-radius: 6px; background: var(--card-bg); color: var(--text); }
.seg-pie { display: flex; gap: 8px; padding: 12px 16px 16px; border-top: 1px solid var(--border); }
.seg-pie .btn { flex: 1; justify-content: center; }
@media (prefers-reduced-motion: reduce) { .seg-panel, .seg-fondo, .seg-grupo > summary::after { transition: none; } }
