/* ============================================================
   CAPA UX v2 — PRUEBA AISLADA (negocio "Tema Test", id 11)
   ------------------------------------------------------------
   Qué es: tipografía, escala, densidad y microinteracciones del
   panel, resueltas SOLO en la capa de tokens (Capa 2). No toca
   ni un color de tema, ni el liquid glass, ni la estructura de
   Ónix. Los tres temas (Ónix, Cristal, Pétalo) comparten esta
   capa; Pétalo conserva cara propia (ver bloque 1b).

   Cómo se enciende: TODO cuelga de :root[data-ux="v2"], que pone
   admin.html solo cuando el JWT dice business_id === 11. Sin ese
   atributo este archivo es inerte aunque se cargue.

   Cómo se revierte: quitar el <link> de admin-ux.css y el script
   "CAPA UX v2" de admin.html. Los tokens viejos siguen intactos
   debajo, no se ha borrado nada.

   Cómo se extiende: cambiar la condición del script por una
   columna businesses.ux_version. La capa se propaga sola a los
   tres temas de cada negocio marcado.

   Se carga DESPUÉS de admin.css y de themes.css.
   ============================================================ */

/* ── 1. TOKENS ────────────────────────────────────────────────
   Propuesta B "Editorial": Fraunces en títulos, Manrope en
   interfaz y cifras. Fraunces ya lo importa themes.css, así que
   aquí no se vuelve a pedir (evita dos @font-face de la misma
   familia). Manrope, Urbanist y Petrona los inyecta el
   script de admin.html, y solo para este negocio. */
:root[data-ux="v2"] {
  /* --font-mono es el token que admin.css usa para body, botones e
     inputs: remapearlo cambia la cara de TODA la interfaz de una vez. */
  --font-mono:    'Manrope', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-disp:    'Fraunces', Georgia, 'Times New Roman', serif;
  --font-figures: 'Manrope', 'Segoe UI', system-ui, -apple-system, sans-serif;

  /* Motor de movimiento. --t ya lo usan 76 transiciones de admin.css:
     redefinirlo les cambia la curva a todas sin tocar una sola regla. */
  --ease-out:    cubic-bezier(.23, 1, .32, 1);
  --ease-in-out: cubic-bezier(.77, 0, .175, 1);
  --dur-press: 120ms;
  --dur-ui:    180ms;
  --dur-over:  240ms;
  --t: var(--dur-ui) var(--ease-out);

  /* Rejilla de 4 pt. Estaba en la propuesta desde el principio y se me quedó
     SIN DEFINIR: admin.css tiene --sp-xs/sm/md/lg/xl, no --sp-1..6. Un
     `var()` sin definir invalida la declaración entera y el navegador la tira
     sin decir nada, así que 24 reglas de espaciado de este archivo llevaban
     todo este tiempo sin hacer absolutamente nada. Se ve al medir —dos
     desplegables que debían tener 33 px de aire tenían 1— y no al leer. */
  --sp-1:  4px;
  --sp-2:  8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 22px;
  --sp-6: 30px;

  /* El 2px de --radius chocaba con el 9px del glass en la misma tarjeta. */
  --radius: 10px;

  --ux-ring:  0 0 0 3px rgba(var(--accent-rgb), .22);
  --ux-press: .97;
}

/* ── 1b. PÉTALO — cara propia, un tono más femenina ───────────
   Antes: Fraunces + Quicksand. Quicksand es redondeada pero algo
   infantil, y Fraunces es la misma serif que llevan los otros dos
   temas, así que Pétalo no se distinguía por tipografía.
   Ahora: Petrona (serif cálida, de trazo caligráfico) en títulos +
   Urbanist (geométrica de eje alto, más adulta que Quicksand) en
   interfaz y cifras. Sigue sin ser cursiva.

   Aquí antes había Bodoni Moda y fue un error: una didona basa toda
   su identidad en el contraste extremo entre el trazo grueso y el
   fino, y a 20 px en pantalla el fino cae por debajo del píxel. Se
   leía mal, que es justo lo contrario de lo que buscábamos. Petrona
   es variable, así que a 600 tiene cuerpo de verdad, y su contraste
   es moderado: aguanta el tamaño de título sobre fondo blush.
   Para volver a Quicksand: cambiar las dos últimas líneas. */
:root[data-ux="v2"][data-theme="petalo"] {
  --font-disp:    'Petrona', 'Fraunces', Georgia, serif;
  --font-mono:    'Urbanist', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-figures: 'Urbanist', 'Segoe UI', system-ui, -apple-system, sans-serif;
}

/* ── 2. BASE ──────────────────────────────────────────────────
   13 px de cuerpo con una monoespaciada era lo que obligaba a
   bajar todas las etiquetas a 9,6 px para que cupieran. */
:root[data-ux="v2"] body {
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0;
}
:root[data-ux="v2"] input,
:root[data-ux="v2"] select,
:root[data-ux="v2"] textarea { font-size: 14px; }

/* ── 3. FIN DE LA MÁQUINA DE ESCRIBIR ─────────────────────────
   93 reglas de admin.css combinan uppercase + letter-spacing de
   0.16em a 0.2em. Eso, y no la familia, es lo que producía el
   efecto "terminal". Se pasan a caja baja con tracking normal y
   a un tamaño que se lee al sol. */
:root[data-ux="v2"] :is(
  .field-label, .form-label, .detail-label, .cl-field label,
  .config-section-title, .cierre-sec-title, .cms-section-title, .fch-titulo,
  .cont-block-title, .hd-title, .tk-audit-title, .cms-label,
  .stat-card-label, .cl-stat-label, .cl-stat-box-label, .emp-super-label,
  .sidebar-nav a, .sidebar-section-label,
  .btn-admin, .btn-login, .btn-topbar, .btn-appt-action, .btn-free-slots,
  .btn-cerrar-caja, .cl-btn-primary, .cl-btn-save, .cl-btn-delete,
  .cl-btn-ver, .cl-btn-nueva-cita, .cl-btn-tag-add, .cl-back-btn,
  .cont-period-btn, .hist-period-btn, .cms-upload-btn, .day-toggle,
  .cl-tab, .cms-tab, .client-tabs-bar, .cl-table-header, .data-table,
  .view-title, .cl-page-title, .modal-title, .login-title, .login-sub,
  .day-view-title, .day-view-closed, .calendar-month-label,
  .add-slot-hint, .block-slot-label, .block-banner-reason,
  .time-label, .free-slots-empty, .cl-empty, .cl-next-label,
  .sched-day-name, .sched-off-label, .toggle-active, .cms-toggle,
  .emp-row--head, .evo-row--head, .hist-detail-key, .dots-item,
  .mw-etiqueta, .mw-lista-titulo, .ob-days, .ob-ideas,
  .reminder-panel-header, .senal-ajustes label, .susc-caja,
  .tk-act-label, .topbar-brand, .topbar-user, .topbar-owner-label,
  .hist-bkd-header, .modal-close, .paywall-marca, .sr-marca, .login-logo,
  .barber-legend, .se-empty, .kpi-value, .cm-stat-val, .cierre-step
) {
  text-transform: none;
  letter-spacing: 0.01em;
}

/* La regla suelta `label { text-transform: uppercase; font-size: 10px }` de
   admin.css alcanza a TODAS las etiquetas de formulario del panel (nombre,
   dirección, teléfono, horarios…). Es la que dejaba Configuración en
   mayúsculas a 10 px, que era el sitio donde más se notaba. */
:root[data-ux="v2"] label,
:root[data-ux="v2"] .config-label,
:root[data-ux="v2"] .ob-ideas-label,
:root[data-ux="v2"] .kpi-label,
:root[data-ux="v2"] .cms-section-label {
  text-transform: none;
  letter-spacing: 0.01em;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.35;
}
:root[data-ux="v2"] .config-hint { font-size: 12px; line-height: 1.45; }

/* Las que SÍ deben seguir en mayúsculas (iniciales de avatar, cabecera
   de días del calendario, insignias de estado): solo se les afloja el
   tracking, que a 0.2em separaba las letras de un modo antinatural. */
:root[data-ux="v2"] :is(
  .topbar-avatar-initial, .cl-avatar-sm, .cl-ficha-avatar,
  .cal-header-cell, .calendar-header-cell,
  .status-badge, .cl-tag, .cl-appt-badge, .appt-completed-badge,
  .appt-source-badge, .appt-barber-tag
) { letter-spacing: 0.05em; }

/* ── 4. ESCALA ────────────────────────────────────────────────
   Un solo salto de tamaños, en lugar de veinticinco valores rem
   sueltos entre 0.52 y 1.1. */

/* Títulos de vista y de modal — la serif hace el trabajo */
:root[data-ux="v2"] .view-title,
:root[data-ux="v2"] .cl-page-title,
:root[data-ux="v2"] .day-view-title { font-size: 20px; font-weight: 600; line-height: 1.2; }
/* El título del modal va también en la serif: en un panel donde cada modal es
   una tarea (cobrar, cerrar caja, crear cita), es lo que dice "esto es una
   pantalla nueva", no un bloque más del formulario. */
:root[data-ux="v2"] .modal-title,
:root[data-ux="v2"] .login-title    { font-family: var(--font-disp); font-size: 17px; font-weight: 600; }
:root[data-ux="v2"] .topbar-brand   { font-size: 14px; font-weight: 600; }

/* Etiquetas y microcopy */
:root[data-ux="v2"] :is(
  .field-label, .form-label, .detail-label, .cl-field label,
  .stat-card-label, .cl-stat-label, .cl-stat-box-label, .emp-super-label,
  .sidebar-section-label, .cms-label, .hist-detail-key,
  .barber-legend, .se-empty, .block-slot-label, .cl-next-label,
  .sched-off-label, .mw-etiqueta, .login-sub
) { font-size: 11.5px; font-weight: 500; line-height: 1.35; }

/* Cabeceras de sección */
:root[data-ux="v2"] :is(
  .config-section-title, .cierre-sec-title, .cms-section-title, .fch-titulo,
  .cont-block-title, .hd-title, .tk-audit-title, .mw-lista-titulo
) { font-size: 13px; font-weight: 600; }

/* Botones y pestañas */
:root[data-ux="v2"] :is(
  .btn-admin, .btn-login, .btn-topbar, .btn-appt-action, .btn-free-slots,
  .btn-cerrar-caja, .cl-btn-primary, .cl-btn-save, .cl-btn-delete,
  .cl-btn-ver, .cl-btn-nueva-cita, .cl-btn-tag-add, .cl-back-btn,
  .cont-period-btn, .hist-period-btn, .cms-upload-btn, .day-toggle,
  .cl-tab, .cms-tab, .ob-day
) { font-size: 13px; font-weight: 500; }

/* Menú lateral */
:root[data-ux="v2"] .sidebar-nav a { font-size: 13px; font-weight: 500; }
:root[data-ux="v2"] .sidebar-nav .nav-web-cta { font-size: 12px; letter-spacing: 0.02em; }

/* Agenda: la hora y el "+ Añadir cita" son la referencia de lectura */
:root[data-ux="v2"] .time-label   { font-size: 11.5px; font-weight: 500; }
:root[data-ux="v2"] .add-slot-hint { font-size: 11.5px; font-weight: 500; }
:root[data-ux="v2"] .appt-service { font-size: 13.5px; font-weight: 600; }
:root[data-ux="v2"] .appt-client  { font-size: 12px; }

/* Cifras: la mono desaparece, pero las columnas de euros siguen
   alineadas gracias a tabular-nums (Manrope y Urbanist lo traen). */
:root[data-ux="v2"] :is(
  .figure, .amount, .stat-card-value, .cmp-val, .caja-exp-val,
  .denom-qty, .denom-sub, .denom-total, .ht-td.figure, .kpi-value,
  .cm-stat-val, .cont-line span:last-child
) {
  font-family: var(--font-figures);
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  letter-spacing: -0.005em;
  font-weight: 700;
}
:root[data-ux="v2"] .stat-card-value { font-size: 26px; line-height: 1.1; }
/* Los stat-card de texto (servicio top, profesional top) no son cifras. */
:root[data-ux="v2"] .stat-card-value--sm {
  font-family: var(--font-disp);
  font-weight: 600;
  font-size: 16px;
  font-variant-numeric: normal;
  letter-spacing: 0;
}

/* ── 5. DENSIDAD ──────────────────────────────────────────────
   El texto crece, así que las piezas que lo contienen necesitan
   algo más de aire. Solo se tocan los componentes que ya cambian
   de tamaño arriba; el resto de la retícula queda como estaba. */
:root[data-ux="v2"] .btn-admin        { padding: 9px 16px; }
:root[data-ux="v2"] .sidebar-nav a    { padding: 9px var(--sp-lg); }
:root[data-ux="v2"] .config-section-title { padding: 13px var(--sp-lg); }
:root[data-ux="v2"] .config-rows      { gap: 18px; }
:root[data-ux="v2"] .field-input      { padding: 10px 12px; }
:root[data-ux="v2"] .time-label       { width: 68px; }

/* ── 6. MICROINTERACCIONES ────────────────────────────────────
   Cada una con un motivo. Todas heredadas por los tres temas. */

/* 6.1 — Pulsación. Confirma que la interfaz oyó el toque antes de
   que conteste el servidor. 120 ms: por debajo se pierde. */
:root[data-ux="v2"] :is(
  .btn-admin, .btn-login, .btn-topbar, .btn-appt-action, .btn-free-slots,
  .btn-cerrar-caja, .cl-btn-primary, .cl-btn-save, .cl-btn-delete,
  .cl-btn-ver, .cl-btn-nueva-cita, .cl-btn-tag-add, .cl-back-btn,
  .cont-period-btn, .hist-period-btn, .cms-upload-btn, .day-toggle,
  .cl-tab, .cms-tab, .ob-day, .pal-opt, .modal-close
) {
  /* "all" animaba también lo que dispara relayout: se nombran las
     propiedades reales una por una. */
  transition: background var(--dur-ui) var(--ease-out),
              border-color var(--dur-ui) var(--ease-out),
              color var(--dur-ui) var(--ease-out),
              box-shadow var(--dur-ui) var(--ease-out),
              transform var(--dur-press) var(--ease-out);
}
:root[data-ux="v2"] :is(
  .btn-admin, .btn-login, .btn-topbar, .btn-appt-action, .btn-free-slots,
  .btn-cerrar-caja, .cl-btn-primary, .cl-btn-save, .cl-btn-delete,
  .cl-btn-ver, .cl-btn-nueva-cita, .cl-btn-tag-add, .cl-back-btn,
  .cont-period-btn, .hist-period-btn, .cms-upload-btn, .day-toggle,
  .cl-tab, .cms-tab, .ob-day, .pal-opt, .modal-close
):active { transform: scale(var(--ux-press)); }

:root[data-ux="v2"] .fab {
  transition: box-shadow var(--dur-ui) var(--ease-out),
              transform var(--dur-press) var(--ease-out);
}
:root[data-ux="v2"] .fab:active { transform: scale(.94); }

/* 6.2 — Foco. Antes solo cambiaba el color del borde y se perdía;
   ahora hay un anillo del acento del tema que no desplaza nada. */
:root[data-ux="v2"] :is(
  .field-input, .cmp-input, .denom-qty, .cl-input, .ob-input,
  input[type="text"], input[type="password"], input[type="number"],
  input[type="email"], input[type="tel"], input[type="date"],
  input[type="time"], select, textarea
) {
  transition: border-color var(--dur-ui) var(--ease-out),
              box-shadow var(--dur-ui) var(--ease-out);
}
:root[data-ux="v2"] :is(
  .field-input, .cmp-input, .denom-qty, .cl-input, .ob-input,
  input[type="text"], input[type="password"], input[type="number"],
  input[type="email"], input[type="tel"], input[type="date"],
  input[type="time"], select, textarea
):focus {
  border-color: var(--gold);
  box-shadow: var(--ux-ring);
  outline: none;
}

/* 6.3 — Tarjetas con relieve. 1 px de elevación y el borde al
   acento. Solo con ratón: en táctil el hover se dispara al tocar
   y deja la tarjeta "encendida" después de soltar. */
@media (hover: hover) and (pointer: fine) {
  :root[data-ux="v2"] :is(.stat-card, .se-section .hist-bkd-header, .cl-ficha-card) {
    transition: background var(--dur-ui) var(--ease-out),
                border-color var(--dur-ui) var(--ease-out),
                transform var(--dur-ui) var(--ease-out);
  }
  :root[data-ux="v2"] :is(.stat-card, .se-section .hist-bkd-header, .cl-ficha-card):hover {
    transform: translateY(-1px);
  }
}

/* 6.4 — Menú lateral. La barra de la izquierda y el fondo dejan de
   ser un salto seco; se nombran las propiedades en vez de "all". */
:root[data-ux="v2"] .sidebar-nav a {
  transition: background var(--dur-ui) var(--ease-out),
              color var(--dur-ui) var(--ease-out),
              border-left-color var(--dur-ui) var(--ease-out);
}

/* 6.5 — Hueco de agenda. "+ Añadir cita" estaba siempre visible y
   ensuciaba una agenda vacía; ahora aparece al pasar por encima.
   En táctil se queda visible: no hay hover que lo revele. */
@media (hover: hover) and (pointer: fine) {
  :root[data-ux="v2"] .add-slot-hint {
    opacity: 0;
    transform: translateX(-6px);
    transition: opacity var(--dur-ui) var(--ease-out),
                transform var(--dur-ui) var(--ease-out),
                color var(--dur-ui) var(--ease-out);
  }
  :root[data-ux="v2"] .time-slot:hover .add-slot-hint {
    opacity: 1;
    transform: translateX(0);
  }
}

/* 6.6 — Avisos. Ya usaban transition (bien: dos avisos seguidos se
   redirigen en vez de reiniciarse). Se les quita el "all" y se les
   pone la curva fuerte, manteniendo la dirección de entrada —
   entra por donde vive, abajo a la derecha. */
:root[data-ux="v2"] .toast {
  transition: opacity var(--dur-over) var(--ease-out),
              transform var(--dur-over) var(--ease-out);
}

/* 6.7 — Modales. Entran desde 0.97, nunca desde 0: nada en el mundo
   real aparece de la nada. El origen se queda en el centro porque un
   modal no cuelga de ningún disparador concreto. */
:root[data-ux="v2"] .modal-overlay.open       { animation: ux-overlay-in var(--dur-over) var(--ease-out) both; }
:root[data-ux="v2"] .modal-overlay.open .modal { animation: ux-modal-in var(--dur-over) var(--ease-out) both; transform-origin: center; }
@keyframes ux-overlay-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes ux-modal-in {
  from { opacity: 0; transform: scale(.97) translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* 6.8 — Entrada escalonada al cambiar de vista. 45 ms entre bloques.
   Solo al navegar: nunca en algo que se repita cien veces al día.
   Se excluyen los elementos fijos, que con un transform vivo
   cambiarían de bloque contenedor mientras dura la animación. */
:root[data-ux="v2"] .view.active > *:not(.fab):not(.modal-overlay) {
  animation: ux-view-in 280ms var(--ease-out) both;
}
:root[data-ux="v2"] .view.active > *:nth-child(1) { animation-delay: 0ms; }
:root[data-ux="v2"] .view.active > *:nth-child(2) { animation-delay: 45ms; }
:root[data-ux="v2"] .view.active > *:nth-child(3) { animation-delay: 90ms; }
:root[data-ux="v2"] .view.active > *:nth-child(n+4) { animation-delay: 135ms; }
@keyframes ux-view-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* ── 7. EL COLOR DE CADA PERSONA ──────────────────────────────
   El color de un trabajador se usa en DOS sitios: la tarjeta de sus
   citas en la vista del día y su fila en el panel de trabajadores,
   que es donde se elige. Verlo en los dos cierra el círculo — eliges
   un color y lo reconoces al momento en la agenda, sin leer nombres.

   Antes el color era una barra de 4 px a la izquierda de la cita:
   para saber de quién era una hora había que fijarse.

   La receta es idéntica en los dos sitios, así que el tono entra por
   un token común (--tinte) y las reglas se escriben una vez. El valor
   guardado es SIEMPRE un pastel, pensado para fondo claro; sobre el
   negro de Ónix, a plena intensidad, sería un bloque de luz, así que
   allí se mezcla con la superficie y solo el filo queda saturado.
   Mismo dato, dos lecturas. */
:root[data-ux="v2"] .appt-block { --tinte: var(--appt-color); }   /* lo pone renderApptCard */
:root[data-ux="v2"] .vip-row    { --tinte: var(--wk-color);   }   /* lo pone loadVipView   */

/* Los tres temas: el pastel, tal cual (16-09-2026, Ian). Ónix también: disuelto
   en el negro salía marrón o gris azulado y no eran sus colores. */
:root[data-ux="v2"][data-theme="cristal"] :is(.appt-block, .vip-row),
:root[data-ux="v2"][data-theme="petalo"]  :is(.appt-block, .vip-row),
:root[data-ux="v2"][data-theme="onix"]    :is(.appt-block, .vip-row),
:root[data-ux="v2"]:not([data-theme])     :is(.appt-block, .vip-row) {
  background: var(--tinte, var(--card));
  border-color: color-mix(in srgb, var(--tinte, var(--hairline-mid)) 86%, #000);
}
/* El hover de la fila venía del cristal (--gl-bg-hover) y borraba el tinte.
   Sobre color, "encima del ratón" se dice aclarando, no cambiando de color. */
@media (hover: hover) and (pointer: fine) {
  :root[data-ux="v2"][data-theme="cristal"] .vip-row:hover,
  :root[data-ux="v2"][data-theme="petalo"]  .vip-row:hover,
  :root[data-ux="v2"][data-theme="onix"]    .vip-row:hover,
  :root[data-ux="v2"]:not([data-theme])     .vip-row:hover {
    background: color-mix(in srgb, var(--tinte, var(--card)) 78%, #fff);
  }
}
:root[data-ux="v2"][data-theme="cristal"] .appt-block,
:root[data-ux="v2"][data-theme="petalo"]  .appt-block,
:root[data-ux="v2"][data-theme="onix"]    .appt-block,
:root[data-ux="v2"]:not([data-theme])     .appt-block {
  border-left-color: color-mix(in srgb, var(--tinte, var(--hairline-mid)) 66%, #000);
}
/* Sobre un pastel, el texto tiene que ser tinta oscura, no el gris de
   la superficie clara: sobre naranja o lima ese gris se queda en 2:1. */
:root[data-ux="v2"][data-theme="cristal"] :is(.appt-block, .vip-row) :is(.appt-service, .appt-price, .vip-name),
:root[data-ux="v2"][data-theme="petalo"]  :is(.appt-block, .vip-row) :is(.appt-service, .appt-price, .vip-name),
:root[data-ux="v2"][data-theme="onix"]    :is(.appt-block, .vip-row) :is(.appt-service, .appt-price, .vip-name),
:root[data-ux="v2"]:not([data-theme])     :is(.appt-block, .vip-row) :is(.appt-service, .appt-price, .vip-name) { color: #23201E; }
:root[data-ux="v2"][data-theme="cristal"] :is(.appt-block, .vip-row) :is(.appt-time, .appt-client, .vip-user),
:root[data-ux="v2"][data-theme="petalo"]  :is(.appt-block, .vip-row) :is(.appt-time, .appt-client, .vip-user),
:root[data-ux="v2"][data-theme="onix"]    :is(.appt-block, .vip-row) :is(.appt-time, .appt-client, .vip-user),
:root[data-ux="v2"]:not([data-theme])     :is(.appt-block, .vip-row) :is(.appt-time, .appt-client, .vip-user) { color: rgba(35,32,30,.68); }
/* La etiqueta del trabajador iba del color del trabajador: sobre su propio
   color desaparecía. Pasa a pastilla blanca. */
:root[data-ux="v2"][data-theme="cristal"] .appt-block .appt-barber-tag,
:root[data-ux="v2"][data-theme="petalo"]  .appt-block .appt-barber-tag,
:root[data-ux="v2"][data-theme="onix"]    .appt-block .appt-barber-tag,
:root[data-ux="v2"]:not([data-theme])     .appt-block .appt-barber-tag {
  background: rgba(255,255,255,.7); border-color: rgba(35,32,30,.16); color: rgba(35,32,30,.78);
}
/* Distintivos y botones: sobre color necesitan superficie propia, o se leen
   como manchas. Blanco translúcido, que deja pasar el tono de debajo. */
:root[data-ux="v2"][data-theme="cristal"] :is(.appt-block, .vip-row) :is(.appt-source-badge, .btn-appt-action, .appt-pay-select),
:root[data-ux="v2"][data-theme="petalo"]  :is(.appt-block, .vip-row) :is(.appt-source-badge, .btn-appt-action, .appt-pay-select),
:root[data-ux="v2"][data-theme="onix"]    :is(.appt-block, .vip-row) :is(.appt-source-badge, .btn-appt-action, .appt-pay-select),
:root[data-ux="v2"]:not([data-theme])     :is(.appt-block, .vip-row) :is(.appt-source-badge, .btn-appt-action, .appt-pay-select) {
  background: rgba(255,255,255,.72); border-color: rgba(35,32,30,.16); color: rgba(35,32,30,.78);
}
:root[data-ux="v2"][data-theme="cristal"] :is(.appt-block, .vip-row) .btn-appt-action:hover,
:root[data-ux="v2"][data-theme="petalo"]  :is(.appt-block, .vip-row) .btn-appt-action:hover,
:root[data-ux="v2"][data-theme="onix"]    :is(.appt-block, .vip-row) .btn-appt-action:hover,
:root[data-ux="v2"]:not([data-theme])     :is(.appt-block, .vip-row) .btn-appt-action:hover {
  background: #fff; border-color: rgba(35,32,30,.34); color: #23201E;
}
/* "Eliminar" es la única acción sin vuelta atrás de la fila: mantiene su rojo
   en vez de disolverse con las demás. */
:root[data-ux="v2"][data-theme="cristal"] .vip-row .btn-appt-action.danger,
:root[data-ux="v2"][data-theme="petalo"]  .vip-row .btn-appt-action.danger,
:root[data-ux="v2"][data-theme="onix"]    .vip-row .btn-appt-action.danger,
:root[data-ux="v2"]:not([data-theme])     .vip-row .btn-appt-action.danger { color: #A33226; }
:root[data-ux="v2"][data-theme="cristal"] .vip-row .status-badge,
:root[data-ux="v2"][data-theme="petalo"]  .vip-row .status-badge,
:root[data-ux="v2"][data-theme="onix"]    .vip-row .status-badge,
:root[data-ux="v2"]:not([data-theme])     .vip-row .status-badge { background: rgba(255,255,255,.72); }
:root[data-ux="v2"][data-theme="cristal"] .appt-block .btn-appt-dots,
:root[data-ux="v2"][data-theme="petalo"]  .appt-block .btn-appt-dots,
:root[data-ux="v2"][data-theme="onix"]    .appt-block .btn-appt-dots,
:root[data-ux="v2"]:not([data-theme])     .appt-block .btn-appt-dots { color: rgba(35,32,30,.55); }
/* "Completada" iba en el verde de --bs-green, pensado para el fondo negro de
   Ónix. Sobre un pastel claro se queda en 2,4:1 — se ve el color, no se lee la
   palabra. Verde oscuro, que sigue diciendo "hecho" y además se lee. */
:root[data-ux="v2"][data-theme="cristal"] .appt-block .appt-completed-badge,
:root[data-ux="v2"][data-theme="petalo"]  .appt-block .appt-completed-badge,
:root[data-ux="v2"][data-theme="onix"]    .appt-block .appt-completed-badge,
:root[data-ux="v2"]:not([data-theme])     .appt-block .appt-completed-badge { color: #1B6E3C; }
/* «No presentado» va en rojo oscuro: sobre el pastel se lee (y no es «hecho»). */
:root[data-ux="v2"] .appt-block .appt-completed-badge.appt-noshow-badge { color: #A12A2A; border-color: #A12A2A; }
:root[data-ux="v2"] .appt-block .appt-venta { color: #23201E; border-color: rgba(35,32,30,.25); background: rgba(255,255,255,.55); }

/* En Ónix el resto de la fila va sobre superficie oscura; dentro del pastel,
   el texto del interruptor «También atiendo citas» también en tinta. */
:root[data-ux="v2"][data-theme="onix"] .vip-row .form-toggle,
:root[data-ux="v2"]:not([data-theme])  .vip-row .form-toggle { color: rgba(35,32,30,.85); }

/* Ónix, un 10 % menos de brillo (16-09-2026, Ian): el pastel a pleno deslumbra
   sobre negro. Mismo tono, mezclado con un 10 % de negro. El texto sigue en
   tinta oscura y por encima de 7:1 con el color más oscuro. */
:root[data-ux="v2"][data-theme="onix"] :is(.appt-block, .vip-row),
:root[data-ux="v2"]:not([data-theme])  :is(.appt-block, .vip-row) {
  background: color-mix(in srgb, var(--tinte, var(--card)) 90%, #000);
}
@media (hover: hover) and (pointer: fine) {
  :root[data-ux="v2"][data-theme="onix"] .vip-row:hover,
  :root[data-ux="v2"]:not([data-theme])  .vip-row:hover { background: var(--tinte, var(--card)); }
}

:root[data-ux="v2"] :is(.appt-block, .vip-row) {
  transition: background var(--dur-ui) var(--ease-out),
              border-color var(--dur-ui) var(--ease-out),
              box-shadow var(--dur-ui) var(--ease-out);
}

/* Paleta dentro del modal de editar trabajador. Antes vivía suelta en la
   fila del listado: diez círculos de colores flotando sin contenedor
   competían con el nombre y las acciones, y no dejaban sitio para nada
   más. Recogidos aquí caben también el nombre, el email y la contraseña. */
:root[data-ux="v2"] .wk-colors {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: var(--sp-1) 0;
}
:root[data-ux="v2"] .wk-dot {
  width: 22px; height: 22px; min-height: 0; aspect-ratio: 1;
  flex: none; padding: 0; border-radius: 50%; cursor: pointer;
  background: var(--c);
  border: 1px solid rgba(0,0,0,.14);
  transition: transform var(--dur-press) var(--ease-out),
              box-shadow var(--dur-ui) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  :root[data-ux="v2"] .wk-dot:hover { transform: scale(1.16); }
}
:root[data-ux="v2"] .wk-dot:active { transform: scale(1.02); }
/* El anillo se separa con un aro del color del FONDO del modal, no del
   canvas: dentro de un modal claro sobre Ónix, --canvas seria negro y
   el hueco saldria como una linea oscura alrededor del punto. */
:root[data-ux="v2"] .wk-dot.on { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--c); }
:root[data-ux="v2"] .wk-dot:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

/* ── Modal de trabajador y recuperación de contraseña ───────── */
/* .wk-hint y .wk-ok tienen su estilo BASE en admin.css: los comparte el
   modal de "he olvidado mi contraseña", que se ve fuera de esta capa.
   Aquí solo se ajustan a la escala nueva. */
:root[data-ux="v2"] .wk-hint { font-size: var(--fs-xs); }
:root[data-ux="v2"] .wk-ok-line   { color: var(--success); font-weight: 600; }
:root[data-ux="v2"] .wk-warn-line { color: #B4761E; font-weight: 600; }
:root[data-ux="v2"] .wk-link {
  background: none; border: none; padding: 0; cursor: pointer;
  font: inherit; color: var(--gold); text-decoration: underline;
  text-underline-offset: 2px;
  transition: opacity var(--dur-ui) var(--ease-out);
}
:root[data-ux="v2"] .wk-link:hover { opacity: .75; }
/* La contraseña es la única acción del modal que no se deshace: se separa
   del resto con una línea, para que no se pulse de paso. */
:root[data-ux="v2"] .wk-bloque {
  border-top: 1px solid var(--hairline);
  padding-top: var(--sp-4); margin-top: var(--sp-2);
}
:root[data-ux="v2"] .wk-pass-btns { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-3); }
:root[data-ux="v2"] .btn-admin:disabled {
  opacity: .45; cursor: not-allowed; transform: none;
}
:root[data-ux="v2"] .wk-ok { font-size: var(--fs-md); }
:root[data-ux="v2"] .login-olvido { font-size: var(--fs-xs); letter-spacing: 0.01em; }

/* ── 8. CLIENTES ──────────────────────────────────────────────
   Esta vista se quedó fuera de todo lo anterior por una sola línea de
   admin.css: `#view-clients { font-family: 'Courier Prime' }`, escrita
   a mano, que gana a cualquier token. Con eso resuelto, el resto es
   ponerla al mismo nivel que las demás. */
:root[data-ux="v2"] #view-clients { font-family: var(--font-mono); }

:root[data-ux="v2"] .cl-page-title {
  font-family: var(--font-disp);
  font-size: 20px; font-weight: 600; line-height: 1.2;
  margin-bottom: var(--sp-5);
}
/* Las cifras de cabecera eran las únicas del panel que seguían sin
   dígitos tabulares: en una columna de euros se notaba. */
:root[data-ux="v2"] .cl-stat-box-value {
  font-family: var(--font-figures);
  font-variant-numeric: tabular-nums lining-nums;
  font-weight: 700; font-size: 26px; line-height: 1.1;
}
:root[data-ux="v2"] .cl-stat-box-label { font-size: var(--fs-2xs); font-weight: 500; }
:root[data-ux="v2"] .cl-search-input {
  font-size: var(--fs-md); padding: 10px 14px; border-radius: var(--radius);
}
:root[data-ux="v2"] .cl-btn-primary { font-size: var(--fs-xs); padding: 10px 18px; }
:root[data-ux="v2"] .cl-table-header { font-size: var(--fs-2xs); font-weight: 500; }
:root[data-ux="v2"] .cl-client-name  { font-size: var(--fs-md); font-weight: 600; }
:root[data-ux="v2"] .cl-client-email { font-size: var(--fs-2xs); }
:root[data-ux="v2"] .cl-cell         { font-size: var(--fs-sm); }
:root[data-ux="v2"] .cl-btn-ver {
  font-size: var(--fs-xs); font-weight: 500; padding: 6px 13px;
  border-radius: var(--radius);
}
:root[data-ux="v2"] .cl-empty { font-size: var(--fs-md); }

/* ── La lista es UNA tarjeta, no siete ───────────────────────
   Cada cliente era su propia tarjeta: mismo borde, mismo radio y
   misma sombra repetidos siete veces, separados por 10 px de aire.
   Borde, relleno, radio y sombra son las cuatro cosas que dicen
   "objeto aparte"; gastadas en todas las filas por igual, no
   destaca ninguna y la lista se lee como un montón de cajas.
   Ahora el objeto es la lista y las filas se separan con una
   línea, que es lo que son: filas. */
:root[data-ux="v2"] #cl-list-rows {
  border: 1px solid var(--gl-border);
  border-radius: var(--gl-radius);
  background: var(--gl-bg);
  box-shadow: var(--gl-shadow-sm);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  overflow: hidden;
}
:root[data-ux="v2"] .cl-client-row {
  background: none;
  border: none;
  border-top: 1px solid var(--hairline);
  border-radius: 0;
  box-shadow: none;
  margin-bottom: 0;
  padding: 12px 18px;
  transition: background var(--dur-ui) var(--ease-out);
}
:root[data-ux="v2"] #cl-list-rows > .cl-client-row:first-child { border-top: none; }
@media (hover: hover) and (pointer: fine) {
  :root[data-ux="v2"] .cl-client-row:hover { background: var(--gl-bg-hover); transform: none; }
}
/* La cabecera deja de flotar: se alinea con el relleno de las filas. */
:root[data-ux="v2"] .cl-table-header { padding: 0 18px 8px; }

/* En MÓVIL vuelve a ser una tarjeta por cliente.
   En escritorio la fila funciona: es una línea, se lee de izquierda a
   derecha y la línea de separación basta. Apilada es otra cosa — cada
   cliente ocupa seis renglones de etiqueta y valor, y con solo un
   filete entre uno y otro no se ve dónde acaba uno y empieza el
   siguiente. Ahí el contenedor deja de ser el objeto y vuelve a serlo
   cada persona. */
@media (max-width: 800px) {
  :root[data-ux="v2"] #cl-list-rows {
    border: none; background: none; box-shadow: none;
    backdrop-filter: none; -webkit-backdrop-filter: none;
    overflow: visible;
    display: flex; flex-direction: column; gap: 10px;
  }
  :root[data-ux="v2"] .cl-client-row {
    border: 1px solid var(--gl-border);
    border-radius: var(--gl-radius);
    background: var(--gl-bg);
    box-shadow: var(--gl-shadow-sm);
    padding: 14px 16px;
  }
  :root[data-ux="v2"] #cl-list-rows > .cl-client-row:first-child { border-top: 1px solid var(--gl-border); }
}

/* Reparto de anchos. "Última visita" ahora lleva fecha Y estado, así que
   necesita sitio: con 1.2fr el distintivo saltaba de línea y esas filas
   quedaban más altas que las demás, dejando la lista dentada. El sitio
   sale de "Próxima cita", que casi siempre está vacía y ocupaba 120 px
   para enseñar un guion. Cabecera y filas comparten la misma retícula,
   así que se cambian a la vez o dejan de estar alineadas. */
@media (min-width: 801px) {
  :root[data-ux="v2"] .cl-table-header,
  :root[data-ux="v2"] .cl-client-row {
    grid-template-columns: 2fr 1.1fr 1.65fr 72px 88px 92px 104px;
  }
  :root[data-ux="v2"] .cl-cell--visita { flex-wrap: nowrap; }
}

/* Las cifras se alinean a la DERECHA, que es como se comparan dos
   números de distinto ancho. A la izquierda, "1" y "25€" parecían
   caer en sitios distintos de la columna.
   Solo en ancho de escritorio: por debajo de 800 px la fila se
   apila y cada celda ya lleva su etiqueta delante. */
@media (min-width: 801px) {
  :root[data-ux="v2"] .cl-table-header > span:nth-child(4),
  :root[data-ux="v2"] .cl-table-header > span:nth-child(5),
  :root[data-ux="v2"] .cl-client-row > :nth-child(4),
  :root[data-ux="v2"] .cl-client-row > :nth-child(5) { text-align: right; }
}

/* La inicial del cliente era un círculo gris con una letra tenue.
   Con el acento del tema detrás se convierte en una marca. */
:root[data-ux="v2"] .cl-avatar-sm {
  background: rgba(var(--accent-rgb), .12);
  border-color: rgba(var(--accent-rgb), .22);
  color: var(--gold);
  font-weight: 700;
}

/* Estado del cliente. Color SEMÁNTICO (bien / ojo / mal), aparte del
   acento del tema: si fuera del acento, en Pétalo "en riesgo" saldría
   rosa y no diría nada. Se define por tema porque los verdes y rojos
   que funcionan sobre el negro de Ónix no llegan a 3:1 en claro. */
:root[data-ux="v2"] .cl-cell--visita {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
:root[data-ux="v2"] .cl-estado {
  font-size: 10.5px; font-weight: 600; letter-spacing: .02em;
  padding: 2px 8px; border-radius: 999px; white-space: nowrap;
  border: 1px solid currentColor;
}
:root[data-ux="v2"] .cl-estado.is-activo { color: #4CAF7D; }
:root[data-ux="v2"] .cl-estado.is-tibio  { color: #E39A3C; }
:root[data-ux="v2"] .cl-estado.is-riesgo { color: #E05555; }
:root[data-ux="v2"] .cl-estado.is-nada   { color: var(--muted); }
:root[data-ux="v2"][data-theme="cristal"] .cl-estado.is-activo,
:root[data-ux="v2"][data-theme="petalo"]  .cl-estado.is-activo { color: #1B6E3C; }
:root[data-ux="v2"][data-theme="cristal"] .cl-estado.is-tibio,
:root[data-ux="v2"][data-theme="petalo"]  .cl-estado.is-tibio  { color: #9A5B0E; }
:root[data-ux="v2"][data-theme="cristal"] .cl-estado.is-riesgo,
:root[data-ux="v2"][data-theme="petalo"]  .cl-estado.is-riesgo { color: #B23030; }

/* Las cuatro cifras de arriba no son el asunto de esta pantalla: el
   asunto es la lista. Se quedan como resumen, con menos peso, para
   que la primera cosa que se mira sea a quién hay que llamar. */
:root[data-ux="v2"] .cl-stats-global { margin-bottom: 20px; gap: 10px; }
:root[data-ux="v2"] .cl-stat-box { padding: 12px 14px; }
:root[data-ux="v2"] .cl-stat-box-value { font-size: 20px; }
/* Los importes y el contador de visitas iban clavados al dorado de Ónix
   (#c9a84c), así que en Cristal salían dorados sobre azul y en Pétalo
   dorados sobre rosa. Pasan al acento del tema. Y la fecha de última
   visita deja de ir en verde: es un dato, no un estado — el verde ahí
   no significaba nada y encima se quedaba en 2,6:1 sobre blanco.
   (El semáforo de retención —Activo / en riesgo— sí es un estado y se
   queda con sus colores.) */
:root[data-ux="v2"] #view-clients { --cl-cifra: var(--gold); --cl-fecha: var(--body); }

/* ── 9. REPASO ────────────────────────────────────────────────
   Lo que quedó suelto tras la primera pasada, encontrado midiendo
   el panel ya pintado, no leyendo el CSS. */

/* 9.1 — El menú "···" de una cita aparecía de golpe: se le cambiaba
   el display y ya estaba. Un menú anclado a un botón tiene que
   crecer DESDE ese botón, no desde su propio centro, o parece que
   sale de otro sitio. Cuelga por arriba y a la derecha del "···",
   así que ese es su origen. Y nunca desde scale(0): nada en el
   mundo real aparece de la nada.
   Va con animación y no con transición a propósito: el display
   pasa de none a flex, y una transición sobre eso no arranca. */
:root[data-ux="v2"] .appt-dots-menu {
  transform-origin: bottom right;
  animation: ux-popover-in 160ms var(--ease-out) both;
  border-radius: var(--gl-radius-sm);
  overflow: hidden;
}
@keyframes ux-popover-in {
  from { opacity: 0; transform: scale(.96); }
  to   { opacity: 1; transform: none; }
}

/* 9.2 — Quedaban dos `transition: all` vivos. "all" anima también
   lo que dispara relayout, y en un conmutador que además cambia de
   borde eso es un frame perdido por pulsación. */
:root[data-ux="v2"] :is(.toggle-active, .client-tab) {
  transition: background var(--dur-ui) var(--ease-out),
              border-color var(--dur-ui) var(--ease-out),
              color var(--dur-ui) var(--ease-out);
}

/* 9.3 — Pulsación en los botones que son solo un icono. Estaban
   fuera de la lista de la primera pasada porque entonces eran
   emoji sueltos, no botones. */
:root[data-ux="v2"] :is(.btn-icon-del, .cms-img-delete) {
  transition: opacity var(--dur-ui) var(--ease-out),
              transform var(--dur-press) var(--ease-out);
}
:root[data-ux="v2"] :is(.btn-icon-del, .cms-img-delete):active { transform: scale(.92); }

/* 9.4 — Hover pegado en pantalla táctil. Las reglas :hover de las
   superficies grandes (día del calendario, hueco de agenda, fila de
   cliente…) vienen de admin.css SIN condición de puntero: al tocar
   una en el móvil se queda encendida hasta que tocas otra cosa, y
   parece seleccionada sin estarlo. Donde no hay ratón, se apagan. */
@media (hover: none) {
  :root[data-ux="v2"] .calendar-day:hover      { background: var(--card); }
  :root[data-ux="v2"] .calendar-day.closed:hover { background: var(--canvas); }
  :root[data-ux="v2"] .time-slot:hover         { background: var(--card); }
  :root[data-ux="v2"] .cl-client-row:hover     { background: none; border-color: transparent; }
  :root[data-ux="v2"] .stat-card:hover         { background: var(--gl-bg); border-color: var(--gl-border); transform: none; }
  :root[data-ux="v2"] .appt-block:hover        { box-shadow: none; }
  /* El "+ Añadir cita" se revela al pasar por encima: sin ratón no hay
     forma de revelarlo, así que en táctil vive siempre visible. */
  :root[data-ux="v2"] .add-slot-hint { opacity: 1; transform: none; }
}

/* En móvil la fila de cliente se apila y cada celda se pone su
   propia etiqueta delante con `content: attr(data-label)`. Esa
   etiqueta es un pseudoelemento, así que se escapó del barrido de
   mayúsculas de la primera pasada —que iba por clases— y era lo
   único del panel que seguía en versalitas espaciadas. */
@media (max-width: 800px) {
  :root[data-ux="v2"] .cl-client-row .cl-cell::before {
    text-transform: none;
    letter-spacing: 0.01em;
    font-size: 12px;
    font-weight: 500;
  }
}

/* ── 10. DEDOS, NO PUNTEROS ───────────────────────────────────
   Medido con el panel abierto en 360, 390 y 768 px. Un dedo tapa
   unos 9 mm de pantalla y no apunta al pixel: por debajo de ~44 px
   se falla el toque y se acaba pulsando lo de al lado.
   Va bajo (pointer: coarse) —no bajo un ancho— porque lo que manda
   no es el tamaño de la pantalla sino con qué se toca: una tableta
   de 1024 px se usa con el dedo igual que un móvil.
   Solo crece el AREA de toque; el dibujo se queda como está. */
@media (pointer: coarse) {
  /* El icono de WhatsApp de la lista de clientes medía 16×16. Es una
     de las acciones que más se usan y era el objetivo más pequeño de
     todo el panel. El margen negativo compensa el relleno, así que
     crece el área sin mover nada de sitio. */
  :root[data-ux="v2"] .cl-wa {
    padding: 12px;
    margin: -12px -12px -12px -4px;
  }
  /* Selectores de periodo (Hoy / Semana / Mes / Personalizar y las
     pestañas del histórico): 29 px de alto. */
  :root[data-ux="v2"] :is(.hist-period-btn, .cont-period-btn) {
    min-height: 44px;
    padding: 10px 14px;
  }
  /* Flechas de mes del calendario: 27 px de ancho. */
  :root[data-ux="v2"] .btn-cal-nav { min-width: 44px; }
  /* Botones de icono (borrar, editar) y el "···" de una cita. */
  :root[data-ux="v2"] :is(.btn-icon-del, .cms-img-delete, .btn-appt-dots) {
    min-width: 44px; min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
  }
  :root[data-ux="v2"] :is(.appt-pay-select, .btn-appt-action) { min-height: 44px; }
  /* El "+" para meter una segunda cita en un hueco ya ocupado se revela al
     pasar el ratón por encima. Sin ratón no hay forma de revelarlo, así que
     en táctil vive visible — y con área de dedo, que medía 22 px. */
  :root[data-ux="v2"] .time-slot.occupied .add-slot-secondary {
    display: flex;
    min-width: 44px; min-height: 44px;
    align-items: center; justify-content: center;
  }
  /* Círculos de color: los del tema en Configuración y los del
     trabajador en su modal. 26 y 22 px respectivamente. */
  :root[data-ux="v2"] .theme-dot { width: 36px; height: 36px; }
  :root[data-ux="v2"] .wk-dot    { width: 34px; height: 34px; }
  :root[data-ux="v2"] .wk-colors { gap: 12px; }
}

/* ── 11. EL HUECO LIBRE SE VE COMO UN HUECO ───────────────────
   Para meter una tercera cita a la trabajadora que estaba libre
   había un "+" de 22 px, en la esquina, con `display: none` hasta
   que pasabas el ratón por encima. Dos problemas de golpe: no se
   veía, y —peor— no había forma de imaginar que estaba ahí. Una
   acción que nadie sabe que existe no existe.

   Como lo resuelve una agenda de salón (Booksy y compañía): el
   tiempo libre de cada persona ES una casilla de la rejilla, visible
   y pulsable. Aquí no hay columna fija por trabajadora, así que el
   hueco se dibuja como una tarjeta más de la fila, del tamaño de las
   citas, con su color y borde discontinuo — que es como se dice
   "aquí todavía no hay nada".

   Y dice de QUIÉN es el hueco. Eso una rejilla por columnas no lo
   necesita, porque la columna ya lleva el nombre; aquí sí, y de paso
   contesta la pregunta que uno se hace de verdad: no "¿puedo meter
   otra?" sino "¿quién puede cogerla?". */
:root[data-ux="v2"] .appt-libre {
  display: flex;
  flex-direction: column;
  gap: 3px;
  align-items: flex-start;
  justify-content: center;
  min-height: 92px;
  padding: 10px 12px;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-ui, inherit);
  border: 1px dashed color-mix(in srgb, var(--tinte, var(--hairline-mid)) 62%, #000);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--tinte, var(--card)) 26%, transparent);
  color: var(--body);
  transition: background var(--dur-ui) var(--ease-out),
              border-color var(--dur-ui) var(--ease-out),
              transform var(--dur-press) var(--ease-out);
}
/* En una fila con varias tarjetas, el hueco ocupa lo mismo que una cita:
   si fuera más estrecho parecería un resto, no una plaza libre. */
:root[data-ux="v2"] .time-content.multi .appt-libre {
  flex: 0 0 min(88%, 320px);
  scroll-snap-align: start;
}
:root[data-ux="v2"] .time-content:not(.multi) .appt-libre { width: 100%; }
@media (hover: hover) and (pointer: fine) {
  :root[data-ux="v2"] .appt-libre:hover {
    background: color-mix(in srgb, var(--tinte, var(--card)) 52%, transparent);
    border-style: solid;
  }
}
:root[data-ux="v2"] .appt-libre:active { transform: scale(var(--ux-press)); }
:root[data-ux="v2"] .appt-libre:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
:root[data-ux="v2"] .appt-libre-mas {
  font-size: 20px; line-height: 1; font-weight: 400;
  color: color-mix(in srgb, var(--tinte, var(--muted)) 55%, #000);
}
:root[data-ux="v2"] .appt-libre-txt   { font-size: var(--fs-md); font-weight: 600; color: var(--ink); }
:root[data-ux="v2"] .appt-libre-quien { font-size: var(--fs-2xs); color: var(--muted); }
/* En Ónix el pastel del borde discontinuo se pierde contra el negro: el mismo
   tono, pero sin mezclarlo hacia el negro. */
:root[data-ux="v2"]:not([data-theme]) .appt-libre,
:root[data-ux="v2"][data-theme="onix"] .appt-libre {
  border-color: var(--tinte, var(--hairline-mid));
  background: color-mix(in srgb, var(--tinte, var(--card)) 6%, transparent);
}
:root[data-ux="v2"]:not([data-theme]) .appt-libre-mas,
:root[data-ux="v2"][data-theme="onix"] .appt-libre-mas { color: var(--tinte, var(--muted)); }
@media (hover: hover) and (pointer: fine) {
  :root[data-ux="v2"]:not([data-theme]) .appt-libre:hover,
  :root[data-ux="v2"][data-theme="onix"] .appt-libre:hover {
    background: color-mix(in srgb, var(--tinte, var(--card)) 12%, transparent);
  }
}
/* Sobre pastel, el texto en tinta oscura (misma regla que las citas). */
:root[data-ux="v2"][data-theme="cristal"] .appt-libre-txt,
:root[data-ux="v2"][data-theme="petalo"]  .appt-libre-txt { color: #23201E; }
:root[data-ux="v2"][data-theme="cristal"] .appt-libre-quien,
:root[data-ux="v2"][data-theme="petalo"]  .appt-libre-quien { color: rgba(35,32,30,.68); }

/* ── 12. FICHA DE RENDIMIENTO DE UN TRABAJADOR ────────────────
   Contesta "¿cómo aprovecha su tiempo?", no "¿cuánto factura?" —eso
   ya estaba en Negocio → Empleados. Por eso el primer bloque es la
   ocupación y los huecos sin vender, y el dinero viene después.
   Las barras son de ancho proporcional y sin eje: aquí no hace falta
   leer un valor exacto de la barra —el número está al lado—, hace
   falta ver de un vistazo cuál destaca. */
:root[data-ux="v2"] .modal--ancho { width: 720px; max-width: 96vw; }

/* ── El color de la persona, como SUPERFICIE ──────────────────
   El pastel pinta fondos y encima va tinta oscura, igual que en su
   tarjeta de la lista y en sus citas de la agenda. Es literalmente
   el mismo tono, sin oscurecer: si se retocara para poder escribir
   con él, dejaría de ser su color, que es justo lo que se pedía. */
:root[data-ux="v2"] #wkStatsModal .stat-card {
  background: var(--wk);
  border-color: color-mix(in srgb, var(--wk) 86%, #000);
}
:root[data-ux="v2"] #wkStatsModal .stat-card :is(.stat-card-value, .stat-card-value.gold) { color: #23201E; }
:root[data-ux="v2"] #wkStatsModal .stat-card .stat-card-label { color: rgba(35,32,30,.68); }
/* El botón del periodo elegido: relleno de su color, texto oscuro. En claro
   themes.css le pone texto blanco a todo .btn-admin.gold, y blanco sobre un
   pastel no se lee. */
:root[data-ux="v2"] #wkStatsModal .btn-admin.gold,
:root[data-ux="v2"] #wkStatsModal .btn-admin.gold:hover {
  background: var(--wk); border-color: color-mix(in srgb, var(--wk) 80%, #000);
  color: #23201E;
}
/* Bordes y foco: ahí sí hace falta la versión fuerte, porque una línea de
   1 px en pastel sobre blanco no se ve. */
:root[data-ux="v2"] #wkStatsModal :is(.wks-cust-campo input:focus, .wks-desple > summary:focus-visible) {
  border-color: var(--wk-fuerte); outline-color: var(--wk-fuerte);
}

/* En Ónix el pastel a plena intensidad sería un bloque de luz sobre el negro,
   igual que pasaba con las tarjetas de cita: se mezcla con la superficie. */
:root[data-ux="v2"]:not([data-theme]) #wkStatsModal .stat-card,
:root[data-ux="v2"][data-theme="onix"] #wkStatsModal .stat-card {
  background: color-mix(in srgb, var(--wk) 20%, var(--card));
  border-color: color-mix(in srgb, var(--wk) 34%, transparent);
}
:root[data-ux="v2"]:not([data-theme]) #wkStatsModal .stat-card :is(.stat-card-value, .stat-card-value.gold),
:root[data-ux="v2"][data-theme="onix"] #wkStatsModal .stat-card :is(.stat-card-value, .stat-card-value.gold) { color: var(--ink); }
:root[data-ux="v2"]:not([data-theme]) #wkStatsModal .stat-card .stat-card-label,
:root[data-ux="v2"][data-theme="onix"] #wkStatsModal .stat-card .stat-card-label { color: var(--muted); }
:root[data-ux="v2"]:not([data-theme]) #wkStatsModal .btn-admin.gold,
:root[data-ux="v2"][data-theme="onix"] #wkStatsModal .btn-admin.gold { color: #23201E; }

:root[data-ux="v2"] .wks-periodo {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  padding-bottom: var(--sp-4); margin-bottom: var(--sp-4);
  border-bottom: 1px solid var(--hairline);
}
:root[data-ux="v2"] .wks-rango {
  margin-left: auto; font-family: var(--font-figures);
  font-size: var(--fs-2xs); color: var(--muted);
  font-variant-numeric: tabular-nums;
}
/* Rango a medida. Aparece solo al pedirlo: tener dos campos de fecha
   siempre a la vista, para algo que se usa de vez en cuando, le roba
   sitio a las cifras, que es a lo que se viene. */
/* `display: flex` gana al atributo `hidden`, que solo aporta un
   `display: none` de hoja de usuario: sin esta línea los campos de fecha se
   veían SIEMPRE, aunque el JS los diera por ocultos. */
:root[data-ux="v2"] .wks-custom[hidden] { display: none; }
:root[data-ux="v2"] .wks-custom {
  display: flex; align-items: flex-end; gap: var(--sp-3); flex-wrap: wrap;
  padding-bottom: var(--sp-4); margin-top: calc(var(--sp-4) * -1 + 4px); margin-bottom: var(--sp-4);
  border-bottom: 1px solid var(--hairline);
}
:root[data-ux="v2"] .wks-cust-campo {
  display: flex; flex-direction: column; gap: 5px;
  font-size: var(--fs-xs); color: var(--muted);
}
:root[data-ux="v2"] .wks-cust-campo input {
  font-family: var(--font-figures);
  border: 1px solid var(--hairline-mid); border-radius: var(--radius);
  background: var(--surface); color: var(--ink);
  padding: 8px 10px; outline: none;
}
:root[data-ux="v2"] .wks-cust-campo input:focus {
  border-color: var(--gold); box-shadow: var(--ux-ring);
}

:root[data-ux="v2"] :is(.wks-cargando, .wks-vacio) {
  padding: var(--sp-5) 0; text-align: center;
  font-size: var(--fs-md); color: var(--muted);
}
:root[data-ux="v2"] .wks-bloque { margin-bottom: var(--sp-5); }
/* Dos desplegables cerrados son dos titulos seguidos: sin aire y sin linea
   entre ellos se leen como uno solo con dos renglones. Cada uno con su franja
   y separacion generosa, que es lo unico que dice "esto es otra cosa". */
:root[data-ux="v2"] .wks-desple {
  padding: var(--sp-4) 0;
  border-top: 1px solid var(--hairline);
  margin-bottom: 0;
}
/* El primero se despega de las tarjetas: pegado a ellas parecia el pie de la
   ultima, no el principio de otra cosa. */
:root[data-ux="v2"] .wks-desple:first-of-type { margin-top: var(--sp-3); }
:root[data-ux="v2"] .wks-desple + .wks-desple { margin-top: 0; }
:root[data-ux="v2"] .wks-desple:last-child { border-bottom: 1px solid var(--hairline); }
/* Abierto, el contenido necesita respirar respecto a su propio titulo. */
:root[data-ux="v2"] .wks-desple[open] > summary { margin-bottom: var(--sp-3); }
:root[data-ux="v2"] .wks-titulo {
  font-family: var(--font-disp); font-size: var(--fs-lg); font-weight: 600;
  color: var(--ink); margin-bottom: var(--sp-3);
}
/* Rejilla propia y explícita. La primera versión se apoyaba en una clase
   del prototipo que NO existe en el panel, así que ponía las columnas sobre
   un contenedor que no era grid y las tarjetas salían una debajo de otra. */
:root[data-ux="v2"] .wks-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-2);
}
/* La cabecera son SEIS cuadrados y tienen que leerse como seis, no como
   "cuatro y dos que sobran": tres y tres en escritorio, dos y dos y dos en
   el movil. Por eso van con un numero fijo de columnas y no con auto-fit,
   que reparte segun quepa y rompe la figura. */
:root[data-ux="v2"] .wks-cards--6 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 620px) {
  :root[data-ux="v2"] .wks-cards--6 { grid-template-columns: repeat(2, 1fr); }
}
/* La nota va DEBAJO de las cifras, no encima: se lee cuando una de ellas
   sorprende, no antes de haberlas visto. */
:root[data-ux="v2"] .wks-nota {
  font-size: var(--fs-2xs); color: var(--muted); line-height: 1.5;
  margin-top: var(--sp-2); max-width: 62ch;
}

/* Servicios, ordenados por frecuencia */
:root[data-ux="v2"] .wks-lista { display: flex; flex-direction: column; }
:root[data-ux="v2"] .wks-fila {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(60px, 1fr) 44px 78px;
  gap: var(--sp-3); align-items: center;
  padding: 9px 0; border-bottom: 1px solid var(--hairline);
}
:root[data-ux="v2"] .wks-fila:last-child { border-bottom: none; }
:root[data-ux="v2"] .wks-fila-n {
  font-size: var(--fs-sm); color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
:root[data-ux="v2"] .wks-barra {
  height: 6px; border-radius: 3px;
  background: rgba(128,128,128,.20); overflow: hidden;
}
:root[data-ux="v2"] .wks-barra i {
  display: block; height: 100%; border-radius: 3px;
  background: var(--gold);
  /* scaleX y no width: el ancho recalcula la maqueta en cada fotograma. */
  transform-origin: left; transform: scaleX(var(--v, 0));
}
:root[data-ux="v2"] :is(.wks-fila-v, .wks-fila-e) {
  font-family: var(--font-figures); font-variant-numeric: tabular-nums lining-nums;
  font-size: var(--fs-sm); text-align: right; white-space: nowrap;
}
:root[data-ux="v2"] .wks-fila-v { font-weight: 600; color: var(--ink); }
:root[data-ux="v2"] .wks-fila-e { color: var(--muted); }

/* Su jornada, como línea de tiempo. Antes era una lista de horas: correcta y
   muda — para saber qué día entra antes había que leer y comparar siete pares
   de cifras. Dibujados contra una MISMA regla, la forma de la semana se ve sin
   leer ninguna: el hueco blanco del mediodía es el descanso, y un día más
   corto se nota porque su barra empieza después o acaba antes. */
/* La escala va ENCIMA de las barras y en la misma retícula que las filas, para
   que cada hora caiga justo sobre el canto que nombra. Antes solo decía la
   primera y la última, y las dos que importan —a la que para y a la que
   vuelve— había que ir a buscarlas a una columna de texto a la derecha. */
:root[data-ux="v2"] .wks-jor-escala {
  display: grid; grid-template-columns: 40px 1fr; gap: 6px;
  margin-bottom: 4px;
}
:root[data-ux="v2"] .wks-jor-esc-pista { position: relative; height: 15px; }
:root[data-ux="v2"] .wks-jor-esc-pista i {
  position: absolute; top: 0; font-style: normal;
  font-family: var(--font-figures); font-size: 10.5px; color: var(--muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
:root[data-ux="v2"] .wks-jornada { display: flex; flex-direction: column; gap: 5px; }
:root[data-ux="v2"] .wks-jor-fila {
  display: grid; grid-template-columns: 40px 1fr;
  gap: 6px; align-items: center;
}
:root[data-ux="v2"] .wks-jor-dia {
  font-size: var(--fs-xs); font-weight: 600; color: var(--body);
}
:root[data-ux="v2"] .wks-jor-pista {
  position: relative; height: 20px; border-radius: 5px;
  background: rgba(128,128,128,.14);
}
:root[data-ux="v2"] .wks-jor-tramo {
  position: absolute; top: 0; bottom: 0; border-radius: 5px;
  background: var(--gold);
}
/* El descanso se dibuja QUITANDO, no pintando otro color encima: es un hueco
   en la jornada, y así es como se lee. */
:root[data-ux="v2"] .wks-jor-comida {
  position: absolute; top: 0; bottom: 0;
  background: var(--card);
  border-left: 1px solid rgba(128,128,128,.25);
  border-right: 1px solid rgba(128,128,128,.25);
}
/* Un día libre lo dice la pista vacía, con la palabra dentro: sin la columna
   de la derecha, si no, sería una fila en blanco sin explicación. */
:root[data-ux="v2"] .wks-jor-pista.vacia {
  display: flex; align-items: center; justify-content: center;
}
:root[data-ux="v2"] .wks-jor-pista.vacia em {
  font-style: normal; font-size: var(--fs-2xs); color: var(--muted);
}
:root[data-ux="v2"] .wks-jor-fila.es-libre .wks-jor-dia { color: var(--muted); }
:root[data-ux="v2"] .wks-jor-fila.es-libre .wks-jor-pista { background: rgba(128,128,128,.07); }

/* Desplegable de servicios. Cerrado por defecto: la lista es larga y no es lo
   que se viene a mirar; el número al lado ya dice cuántos hace. */
:root[data-ux="v2"] .wks-desple > summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: var(--sp-2);
}
:root[data-ux="v2"] .wks-desple > summary::-webkit-details-marker { display: none; }
/* El chevron se dibuja, no se escribe: el carácter '⌄' sale como una uve
   suelta en la mayoría de las fuentes de interfaz. */
:root[data-ux="v2"] .wks-desple > summary::after {
  content: ''; margin-left: auto; flex: none;
  width: 8px; height: 8px; margin-bottom: 3px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(45deg); transform-origin: center;
  transition: transform var(--dur-ui) var(--ease-out);
}
:root[data-ux="v2"] .wks-desple[open] > summary::after { transform: rotate(225deg); margin-bottom: -3px; }
:root[data-ux="v2"] .wks-desple > summary:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 6px; }
:root[data-ux="v2"] .wks-cuenta {
  font-family: var(--font-ui); font-size: var(--fs-2xs); font-weight: 500;
  color: var(--muted); letter-spacing: 0;
}
/* Separación con margen y no con el `gap` del summary: el espacio literal entre
   los dos <span> es un nodo en blanco, que un contenedor flex descarta, y el
   contador acababa pegado al título ("Servicios que hace11"). */
:root[data-ux="v2"] .wks-desple > summary .wks-cuenta { margin-left: 7px; }

/* La fila del trabajador es pulsable: tiene que parecerlo. */
:root[data-ux="v2"] .vip-row[role="button"] { cursor: pointer; }
:root[data-ux="v2"] .vip-row[role="button"]:focus-visible {
  outline: 2px solid var(--gold); outline-offset: 2px;
}

@media (max-width: 560px) {
  :root[data-ux="v2"] .wks-fila {
    grid-template-columns: minmax(0, 1fr) 40px 70px;
  }
  /* En móvil se cae la barra, no el número: la barra era la ayuda visual,
     el dato es la cifra. */
  :root[data-ux="v2"] .wks-barra { display: none; }
  /* En móvil la barra se lleva todo el ancho que sobra. */
  :root[data-ux="v2"] .wks-jor-fila,
  :root[data-ux="v2"] .wks-jor-escala { grid-template-columns: 34px 1fr; }
}

/* ── 9. MOVIMIENTO REDUCIDO ───────────────────────────────────
   Menos movimiento y más suave, no cero: se conservan las
   transiciones de color y opacidad, que ayudan a entender el
   cambio de estado; se retira todo lo que se desplaza. */
@media (prefers-reduced-motion: reduce) {
  :root[data-ux="v2"] .view.active > *,
  :root[data-ux="v2"] .appt-dots-menu,
  :root[data-ux="v2"] .modal-overlay.open .modal { animation: none; }
  :root[data-ux="v2"] .modal-overlay.open { animation: ux-overlay-in 120ms linear both; }
  :root[data-ux="v2"] .add-slot-hint { opacity: 1; transform: none; }
  :root[data-ux="v2"] :is(.stat-card, .se-section .hist-bkd-header, .cl-ficha-card):hover { transform: none; }
  :root[data-ux="v2"] *:active { transform: none !important; }
}

/* ── CHROME ANTIGUA, SIN color-mix() (22-09-2026) ────────────────────────
   color-mix() existe desde Chrome 111. La tablet de The Barber Sevilla lleva
   una anterior y no veía los colores de la agenda, del equipo ni de los
   fichajes: parecía que los cambios del panel no le llegaban. Como esas reglas
   llevan var(), el navegador viejo no las descarta al leerlas sino al
   aplicarlas, y la propiedad se queda VACÍA: una regla de repuesto justo
   antes no sirve. Este bloque solo lo leen los navegadores sin color-mix().
   Los colores en RGB los pone el guion del final de admin.html
   (--tinte-rgb y --tinte-osc, un 65 % más oscuro) y wksAplicarColor
   (--accent-rgb y --wk-fuerte, en la ficha de estadísticas de cada uno). */
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  :root[data-ux="v2"]:not([data-theme]) :is(.appt-block, .vip-row) {
    border-color: rgb(var(--tinte-osc, 110, 110, 110));
    background: rgb(var(--tinte-rgb, 180, 180, 180));
  }
  :root[data-ux="v2"]:not([data-theme]) .appt-block { border-left-color: rgb(var(--tinte-osc, 110, 110, 110)); }
  :root[data-ux="v2"] .appt-libre {
    border: 1px dashed rgb(var(--tinte-osc, 110, 110, 110));
    background: rgba(var(--tinte-rgb, 180, 180, 180), 0.26);
  }
  :root[data-ux="v2"] .appt-libre-mas { color: rgb(var(--tinte-osc, 110, 110, 110)); }
  :root[data-ux="v2"][data-theme="onix"] .appt-libre { background: rgba(var(--tinte-rgb, 180, 180, 180), 0.06); }
  :root[data-ux="v2"][data-theme="onix"] .appt-libre-mas { color: rgb(var(--tinte-rgb, 180, 180, 180)); }
  :root[data-ux="v2"] #wkStatsModal .stat-card { border-color: var(--wk-fuerte); }
  :root[data-ux="v2"][data-theme="onix"] #wkStatsModal .stat-card {
    background: rgba(var(--accent-rgb), 0.2);
    border-color: rgba(var(--accent-rgb), 0.34);
  }
  .fch-persona, .fch-total, .fch-fila { border-left: 3px solid rgb(var(--tinte-rgb, 180, 180, 180)); }
  .fch-persona.dentro { background: rgba(var(--tinte-rgb, 180, 180, 180), 0.16); }
  .fch-total { background: rgba(var(--tinte-rgb, 180, 180, 180), 0.14); }
  .fch-fila.abierta { border-color: rgba(230, 126, 34, 0.4); border-left-color: rgb(var(--tinte-rgb, 180, 180, 180)); }
}

/* ── SE LEE SIN FORZAR LA VISTA (22-09-2026, Ian) ────────────────────────
   Las horas de «Nueva cita» estaban a 0.62rem —9,9 px— y las ocupadas al 35 %
   de opacidad: en la tablet del local (10", 1280×800 a 1 píxel por punto) había
   que acercarse a la pantalla para leerlas. No era cosa del navegador viejo:
   medido igual en una Chrome de hoy. Aquí se sube el tamaño, el peso y el
   contraste de lo que se lee al apuntar una cita y al abrir el día. Las horas
   llevan cifras de ancho fijo, que es lo que hace que una columna de horas se
   lea de un vistazo. */
:root[data-ux="v2"] .manual-slot-btn {
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.02em;
  padding: 9px 12px;
  min-width: 64px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
/* Ocupada: sigue tachada y apagada, pero legible (antes 0.35). */
:root[data-ux="v2"] .manual-slot-btn.occupied { opacity: 0.55; }
:root[data-ux="v2"] .manual-slot-btn.selected {
  font-weight: 700;
  /* La elegida va sobre el color del tema: su texto es el del lienzo, no la
     tinta. Sin esta línea, el color de arriba ganaba por especificidad y
     quedaba tinta oscura sobre azul (2,7:1). */
  color: var(--canvas);
}
/* Con las horas más grandes caben menos por pantalla: la caja crece un poco
   para que sigan viéndose tres filas sin desplazar. */
:root[data-ux="v2"] .manual-slots-grid { max-height: 232px; }
:root[data-ux="v2"] .slots-hint { font-size: 13px; letter-spacing: 0.02em; }

/* Las etiquetas de los campos dentro de una ventana: 11.5 px era el tamaño de
   una nota al pie para algo que hay que leer mientras se apunta una cita. */
:root[data-ux="v2"] .modal-overlay .field-label,
:root[data-ux="v2"] .modal-overlay .form-label,
:root[data-ux="v2"] .modal-overlay .cl-field label { font-size: 12.5px; }
/* La apertura del día: el texto de ayuda y las filas de cifras. */
:root[data-ux="v2"] .modal-overlay .empty-note { font-size: 12.5px; line-height: 1.5; }
:root[data-ux="v2"] .modal-overlay .cmp-row { font-size: 13.5px; }
:root[data-ux="v2"] .modal-overlay .cmp-val { font-variant-numeric: tabular-nums; }

/* La escala de tamaños del panel. Estaba SIN DEFINIR: dos docenas de reglas
   pedían var(--fs-sm) y compañía, el navegador las descartaba y esos textos
   se quedaban con el tamaño que heredaran (la ficha de un cliente, a 11 px).
   Se define aquí, con el mismo suelo de 12,5 px del bloque de abajo. */
:root[data-ux="v2"] {
  --fs-2xs: 12.5px;
  --fs-xs: 13px;
  --fs-sm: 13.5px;
  --fs-md: 14.5px;
  --fs-lg: 16.5px;
}

/* ── NADA POR DEBAJO DE 12 px (22-09-2026, Ian) ──────────────────────────
   Después de arreglar «Nueva cita» se midió el panel entero en las cuatro
   medidas (móvil 390, tablet 800 y 1280, PC 1512): quedaban 551 textos por
   debajo de 12 px, y los que más se leen estaban entre los peores —la hora de
   cada cita a 10,9 px, la columna de horas a 11,5, las tablas a 10,4 y las
   etiquetas de origen a 8,8—. En una tablet a un píxel por punto, a medio
   metro, eso es forzar la vista todo el día.

   Aquí se sube el suelo: 12,5 px para etiquetas y distintivos, 13 px para lo
   que se lee como dato (horas, tablas, números del calendario). No se toca el
   alto de las filas ni la retícula: solo el tamaño, el peso donde hacía falta
   y las cifras de ancho fijo donde hay columnas de números. */
html:root[data-ux="v2"] .appt-source-badge,
html:root[data-ux="v2"] .appt-barber-tag,
html:root[data-ux="v2"] .appt-completed-badge,
html:root[data-ux="v2"] .status-badge,
html:root[data-ux="v2"] .reminder-badge,
html:root[data-ux="v2"] .cl-estado,
html:root[data-ux="v2"] .toggle-active,
html:root[data-ux="v2"] .svc-foto-vacia { font-size: 12px; letter-spacing: 0.04em; }

html:root[data-ux="v2"] .config-label,
html:root[data-ux="v2"] .empty-note,
html:root[data-ux="v2"] .stat-card-label,
html:root[data-ux="v2"] .cl-stat-box-label,
html:root[data-ux="v2"] .cl-stat-label,
html:root[data-ux="v2"] .barber-legend-item,
html:root[data-ux="v2"] .fch-persona-e,
html:root[data-ux="v2"] .vip-user,
html:root[data-ux="v2"] .topbar-user,
html:root[data-ux="v2"] .topbar-owner-label,
html:root[data-ux="v2"] .cal-header-cell,
html:root[data-ux="v2"] .sr-duration { font-size: 12.5px; }

/* Datos que se leen de un vistazo: hora de la cita, columna de horas, celdas
   de las tablas y números del calendario. Con cifras de ancho fijo. */
html:root[data-ux="v2"] .appt-time,
html:root[data-ux="v2"] .time-label,
html:root[data-ux="v2"] .day-number,
html:root[data-ux="v2"] .day-count,
html:root[data-ux="v2"] .day-occ-pct,
html:root[data-ux="v2"] .ht-td,
html:root[data-ux="v2"] .ht-th,
html:root[data-ux="v2"] .cl-cell { font-size: 13px; font-variant-numeric: tabular-nums; }
html:root[data-ux="v2"] .btn-cal-nav { font-size: 13px; }

/* Para el dedo: el acceso a la web propia se quedaba en 32 px de alto. */
html:root[data-ux="v2"] .sidebar-nav .nav-web-cta { min-height: 40px; display: flex; align-items: center; justify-content: center; }
html:root[data-ux="v2"] .susc-estado { font-size: 12.5px; }

/* Para el dedo, en pantallas táctiles: los botones de la barra de arriba
   («Ver web», «Salir») se quedaban en 32 px de alto, y los enlaces sueltos
   dentro de un texto en 23. La recomendación es 40. */
@media (max-width: 1024px) {
  html:root[data-ux="v2"] .btn-topbar { min-height: 40px; padding-inline: 14px; }
  html:root[data-ux="v2"] .config-row a[href^="http"] { display: inline-block; padding-block: 8px; }
}

/* Los tres que seguían pequeños solo en pantalla estrecha: el aviso de citas
   «Sin asignar» (0,52 rem = 8,3 px), los botones Ayer/Hoy/Mañana de la vista
   del día, y los enlaces sueltos de Configuración, que no llegaban a 24 px de
   alto para el dedo. Llevan #id o van dentro de una media query, así que hace
   falta ganar en peso, no en orden. */
@media (max-width: 1024px) {
  html:root[data-ux="v2"] #unassignedBadge,
  html:root[data-ux="v2"] .reminder-badge { font-size: 12px; padding: 6px 10px; }
  html:root[data-ux="v2"] #view-day .view-actions .btn-admin { font-size: 13px; min-height: 42px; }
  html:root[data-ux="v2"] .config-value a[href^="http"],
  html:root[data-ux="v2"] .config-row a[href^="http"],
  html:root[data-ux="v2"] .config-section a[href^="http"] { display: inline-block; padding-block: 9px; }
}
/* El rótulo del mes bajaba a 0,66 rem (10,6 px) en el móvil. */
html:root[data-ux="v2"] .calendar-month-label { font-size: clamp(0.82rem, 2.7vw, 0.9rem); }

/* ── EL COLOR DE ATENCIÓN (25-09-2026) ───────────────────────────────────────
   El naranja está RESERVADO para el sistema: ya no se puede asignar a un
   trabajador (salió de COLORES_TRABAJADOR en server.js y en admin.html). Su
   trabajo es uno solo: que algo que pide atención se vea a un metro, en la
   tablet, sin buscarlo. Hoy lo usa la primera visita de alguien; habrá más.

   Va como color SÓLIDO y no translúcido a propósito: el chip se pinta encima de
   la tarjeta de la cita, que ya lleva el color pastel del profesional. Un chip
   translúcido dejaría pasar ese tono y se convertiría en otra mancha más — que
   es justo lo que pasaba cuando compartía clase con el chip de origen.

   Un solo juego de valores para los tres temas: el relleno es claro y el texto
   marrón oscuro (7:1), así que se lee igual sobre ónix que sobre cristal. */
:root {
  --atencion: #FFD3B0;
  --atencion-texto: #5A3410;
  --atencion-linea: rgba(90,52,16,.34);
}
.chip-atencion {
  display: inline-block;
  padding: 2px 7px;
  margin-right: 4px;
  border-radius: 6px;
  border: 1px solid var(--atencion-linea);
  background: var(--atencion);
  color: var(--atencion-texto);
  font-size: var(--fs-2xs, 12px);
  font-weight: 700;
  letter-spacing: .02em;
  white-space: nowrap;
  vertical-align: baseline;
}
/* Dentro de la tarjeta de la cita, el resto de chips se vuelven blanco
   translúcido (ver más arriba). Este NO: se queda con su naranja, que es su
   única razón de existir. */
:root[data-ux="v2"] :is(.appt-block, .vip-row) .chip-atencion {
  background: var(--atencion);
  border-color: var(--atencion-linea);
  color: var(--atencion-texto);
}
/* La sección de la apertura del día: una banda naranja a la izquierda, del mismo
   color, para que se distinga de «Citas hoy» sin gritar. */
.atencion-sec {
  border-left: 3px solid var(--atencion);
  padding-left: 10px;
}
