/* ════════════════════════════════════════════════════════════════════
   Reluxdent CRM — sistema visual
   Register: product. Acento: terracota. Light + dark.
   ════════════════════════════════════════════════════════════════════ */

/* ───────────────────────── Tokens (light) ───────────────────────── */
:root {
  /* Acento terracota — anti-cliché para dental estética */
  --acc-50:  oklch(0.97 0.012 40);
  --acc-100: oklch(0.94 0.025 40);
  --acc-200: oklch(0.88 0.045 40);
  --acc-300: oklch(0.78 0.085 40);
  --acc-400: oklch(0.66 0.115 40);
  --acc-500: oklch(0.55 0.130 40);  /* base */
  --acc-600: oklch(0.49 0.135 40);
  --acc-700: oklch(0.42 0.120 38);
  --acc-800: oklch(0.34 0.090 38);

  /* Neutros tintados hacia el acento (chroma 0.005) */
  --n-0:   oklch(0.995 0.003 40);
  --n-50:  oklch(0.985 0.004 40);
  --n-100: oklch(0.965 0.005 40);
  --n-200: oklch(0.935 0.006 40);
  --n-300: oklch(0.880 0.007 40);
  --n-400: oklch(0.760 0.008 40);
  --n-500: oklch(0.620 0.008 40);
  --n-600: oklch(0.490 0.009 40);
  --n-700: oklch(0.370 0.010 40);
  --n-800: oklch(0.250 0.010 40);
  --n-900: oklch(0.165 0.012 40);
  --n-950: oklch(0.110 0.014 40);

  /* Semánticos */
  --ok-500:   oklch(0.55 0.125 150);
  --ok-100:   oklch(0.95 0.025 150);
  --ok-700:   oklch(0.38 0.090 150);
  --warn-500: oklch(0.70 0.140 75);
  --warn-100: oklch(0.96 0.035 75);
  --warn-700: oklch(0.46 0.110 65);
  --err-500:  oklch(0.55 0.165 27);
  --err-100:  oklch(0.95 0.030 27);
  --err-700:  oklch(0.40 0.140 27);
  --info-500: oklch(0.55 0.110 235);
  --info-100: oklch(0.95 0.025 235);
  --info-700: oklch(0.38 0.090 235);

  /* v2.8 — verde del check de "cita completada" en el calendario. NO se
     redefine en oscuro, a propósito: la tarjeta de una cita se mantiene
     clara en los dos temas (igual que DONE_WASH en calendar.js), así que el
     verde tiene que ser el mismo en los dos para que el ✓ blanco de dentro
     siga leyéndose. Más saturado que el color pastel del doctor: es el único
     hecho del calendario que ya no puede cambiar. */
  --cal-done: oklch(0.50 0.145 150);

  /* Roles semánticos */
  --bg:         var(--n-50);
  --bg-elev:    var(--n-0);
  --bg-sunken:  var(--n-100);
  --surface:    var(--n-0);
  --surface-2:  var(--n-0);
  --border:     var(--n-200);
  --border-strong: var(--n-300);
  --text:       var(--n-900);
  --text-strong: var(--n-950);
  --text-muted: var(--n-600);
  --text-dim:   var(--n-500);
  --text-disabled: var(--n-400);
  --text-on-acc: var(--n-0);
  /* Alias histórico: una docena de reglas (editor de precios, cuenta del
     doctor, sedes) pide `--text-2` y nadie lo definía nunca, así que ese
     texto heredaba el color del padre en vez de atenuarse. Se define como
     lo que siempre quiso decir. Lo mismo con --radius y --leading-normal.
     No se agregan usos nuevos: los que quedan se van migrando. */
  --text-2: var(--text-muted);

  --acc:         var(--acc-500);
  --acc-hover:   var(--acc-600);
  --acc-active:  var(--acc-700);
  --acc-soft:    var(--acc-100);
  --acc-soft-2:  var(--acc-200);
  --acc-text:    var(--acc-700);

  --ok:    var(--ok-500);
  --warn:  var(--warn-500);
  --err:   var(--err-500);
  --info:  var(--info-500);
  --ok-bg:   var(--ok-100);
  --warn-bg: var(--warn-100);
  --err-bg:  var(--err-100);
  --info-bg: var(--info-100);

  /* Elevación (sólo light) */
  --shadow-xs: 0 1px 1px oklch(0.18 0.01 40 / 0.04);
  --shadow-sm: 0 1px 3px oklch(0.18 0.01 40 / 0.06), 0 1px 2px oklch(0.18 0.01 40 / 0.04);
  --shadow-md: 0 4px 12px oklch(0.18 0.01 40 / 0.07), 0 2px 4px oklch(0.18 0.01 40 / 0.04);
  --shadow-lg: 0 16px 40px oklch(0.18 0.01 40 / 0.12), 0 4px 12px oklch(0.18 0.01 40 / 0.06);
  --shadow-modal: 0 24px 64px oklch(0.18 0.01 40 / 0.20);

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

  --text-2xs: 0.625rem;    /* 10px */
  --text-xs:  0.6875rem;   /* 11px */
  --text-sm:  0.8125rem;   /* 13px */
  --text-base: 0.875rem;   /* 14px */
  --text-md:  0.9375rem;   /* 15px */
  --text-lg:  1.0625rem;   /* 17px */
  --text-xl:  1.25rem;     /* 20px */
  --text-2xl: 1.5rem;      /* 24px */
  --text-3xl: 1.875rem;    /* 30px */

  --leading-tight: 1.25;
  --leading-snug:  1.4;
  --leading-base:  1.55;
  --leading-normal: var(--leading-base);   /* alias histórico */
  --leading-relaxed: 1.7;

  --tracking-tight: -0.011em;
  --tracking-base:  0;
  --tracking-wide:  0.04em;
  --tracking-caps:  0.08em;

  /* Espaciado (base 4) */
  --space-1: 0.25rem;   /* 4 */
  --space-2: 0.5rem;    /* 8 */
  --space-3: 0.75rem;   /* 12 */
  --space-4: 1rem;      /* 16 */
  --space-5: 1.5rem;    /* 24 */
  --space-6: 2rem;      /* 32 */
  --space-7: 3rem;      /* 48 */
  --space-8: 4rem;      /* 64 */

  /* Radios */
  --r-xs:  4px;
  --r-sm:  6px;
  --r-md:  8px;
  --r-lg:  12px;
  --r-xl:  16px;
  --r-full: 9999px;
  --radius: var(--r-md);                   /* alias histórico */

  /* Motion */
  --dur-fast: 100ms;
  --dur-base: 160ms;
  --dur-slow: 240ms;
  --dur-trace: 600ms;
  --ease: cubic-bezier(0.22, 1, 0.36, 1); /* ease-out-quart */
  --ease-in: cubic-bezier(0.55, 0, 1, 0.45);
  --ease-trace: cubic-bezier(0.16, 1, 0.3, 1); /* ease-out-expo */

  /* v1.5 Marginalia — spacing rhythm:
     padding interno por jerarquía (compact dentro de grupos densos,
     generous solo en superficies primarias), gaps entre bloques
     semánticos (no entre filas). El padding ya no es uniforme. */
  --pad-compact: 12px;
  --pad-standard: 16px;
  --pad-generous: 24px;
  --gap-section: 32px;
  --gap-section-lg: 48px;

  /* Layout */
  --header-h: 56px;
  --nav-h:    44px;
  --max-w:    1480px;
  /* Shell v2 — sidebar: ancho expandido, contraído, y el ancho VIGENTE
     (--sb-cur) que consumen tanto .sidebar como el offset del overlay
     de paciente. body.sb-collapsed y el breakpoint móvil lo redefinen. */
  --sb-w:     232px;
  --sb-w-min: 64px;
  --sb-cur:   var(--sb-w);

  color-scheme: light;
}

/* ───────────────────────── Tokens (dark) ───────────────────────── */
[data-theme="dark"] {
  --bg:         var(--n-950);
  --bg-elev:    oklch(0.205 0.014 40);
  --bg-sunken:  oklch(0.085 0.014 40);
  --surface:    oklch(0.205 0.014 40);
  --surface-2:  oklch(0.245 0.014 40);
  --border:     oklch(0.295 0.012 40);
  --border-strong: oklch(0.365 0.014 40);
  --text:       oklch(0.94 0.006 40);
  --text-strong: oklch(0.985 0.005 40);
  --text-muted: oklch(0.70 0.008 40);
  --text-dim:   oklch(0.55 0.008 40);
  --text-disabled: oklch(0.40 0.008 40);
  --text-on-acc: oklch(0.13 0.014 40);

  --acc:         oklch(0.72 0.130 42);
  --acc-hover:   oklch(0.78 0.130 42);
  --acc-active:  oklch(0.84 0.115 42);
  --acc-soft:    oklch(0.32 0.060 40);
  --acc-soft-2:  oklch(0.38 0.075 40);
  --acc-text:    oklch(0.84 0.110 42);

  --ok-500:   oklch(0.74 0.120 150);
  --warn-500: oklch(0.80 0.130 80);
  --err-500:  oklch(0.70 0.155 27);
  --info-500: oklch(0.72 0.100 235);
  --ok-bg:    oklch(0.28 0.045 150);
  --warn-bg:  oklch(0.30 0.055 75);
  --err-bg:   oklch(0.30 0.065 27);
  --info-bg:  oklch(0.28 0.040 235);

  /* Los tokens -700 son "el semántico fuerte", pensados como TEXTO oscuro
     sobre el -bg claro. En dark nunca se redefinían, así que quedaban en su
     valor claro (L≈0.40) pintando texto sobre los -bg oscuros (L≈0.29): unos
     1.4:1, ilegible. Chips de estado, pills de plan, badges de presupuesto,
     fechas vencidas y el toast de error caían todos ahí. En dark "fuerte"
     significa más claro, así que el -700 sube por encima del -500. Única
     superficie que se invierte y necesita el valor oscuro a mano: el toast
     (ver .toast más abajo). */
  --ok-700:   oklch(0.82 0.105 150);
  --warn-700: oklch(0.86 0.110 80);
  --err-700:  oklch(0.79 0.140 27);
  --info-700: oklch(0.80 0.090 235);

  /* Sin shadows en dark: profundidad por surface lightness */
  --shadow-xs: 0 0 0 1px oklch(1 0 0 / 0.02);
  --shadow-sm: 0 0 0 1px oklch(1 0 0 / 0.03);
  --shadow-md: 0 0 0 1px oklch(1 0 0 / 0.04), 0 8px 24px oklch(0 0 0 / 0.35);
  --shadow-lg: 0 0 0 1px oklch(1 0 0 / 0.05), 0 20px 48px oklch(0 0 0 / 0.50);
  --shadow-modal: 0 0 0 1px oklch(1 0 0 / 0.06), 0 32px 80px oklch(0 0 0 / 0.65);

  color-scheme: dark;
}

/* ───────────────────────── Reset / base ───────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  /* Shell v2 — sidebar + columna principal. Los hijos fixed (modales,
     overlay, toast, login) no participan del flex. */
  display: flex;
  align-items: stretch;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-base);
  letter-spacing: var(--tracking-tight);
  font-feature-settings: "cv11", "ss01";
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  color: var(--text-strong);
}

p { margin: 0; }
a { color: inherit; text-decoration: none; }

input, select, textarea, button {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

::selection { background: var(--acc-soft-2); color: var(--text-strong); }

/* Scrollbars discretas, tintadas */
* { scrollbar-width: thin; scrollbar-color: var(--n-300) transparent; }
[data-theme="dark"] * { scrollbar-color: var(--border-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: color-mix(in oklch, var(--text-dim) 35%, transparent);
  border-radius: var(--r-full);
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover {
  background: color-mix(in oklch, var(--text-dim) 60%, transparent);
  background-clip: padding-box;
  border: 2px solid transparent;
}

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

/* Utilidades */
.muted { color: var(--text-muted); }
.hidden { display: none !important; }
.spacer { flex: 1; }

/* El `[hidden]` del user-agent es `display: none` con especificidad de
   selector de tipo, así que cualquier `.componente { display: flex }`
   propio le gana y el elemento marcado como oculto se sigue viendo. Ya
   había 27 reglas parche por toda la hoja arreglando el mismo caso uno
   por uno, y el que faltaba (el selector de alcance del listado) se le
   mostraba al admin. Se resuelve de una vez y para todos: si algo tiene
   el atributo `hidden`, no se dibuja. La forma de mostrar algo es
   quitarle el atributo, no ganarle en CSS. */
[hidden] { display: none !important; }

/* ───────────────────────── App shell ───────────────────────── */
.app-header {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  height: var(--header-h);
  padding: 0 var(--space-5);
  background: color-mix(in oklch, var(--bg) 85%, transparent);
  backdrop-filter: saturate(140%) blur(8px);
  -webkit-backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid var(--border);
}

.brand {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  min-width: 0;
}
.brand h1 {
  font-size: var(--text-md);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-strong);
  white-space: nowrap;
}
.brand h1::first-letter,
.brand h1 { /* preserve original casing; we add an accent dot */ }
.env-tag {
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--acc-text);
  background: var(--acc-soft);
  padding: 2px var(--space-2);
  border-radius: var(--r-full);
  border: 1px solid color-mix(in oklch, var(--acc) 25%, transparent);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.header-actions .muted {
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}

/* Theme toggle */
.theme-toggle {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.theme-toggle:hover {
  background: var(--bg-sunken);
  color: var(--text);
  border-color: var(--border-strong);
}
.theme-toggle svg { width: 16px; height: 16px; }
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: block; }
[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* ─────────────────── Avisos (campana + panel) ───────────────────
   v2.0 (ajustes f7). Vive junto al toggle de tema: misma caja de 32px,
   mismo peso visual, para que la barra siga siendo una línea de
   utilidades y no una barra de notificaciones. El punto del contador es
   lo único que se enciende — terracota sólo cuando hay algo urgente,
   siguiendo la regla del acento discreto. */
.notif-wrap { position: relative; display: inline-flex; }
.notif-btn {
  position: relative;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.notif-btn:hover { background: var(--bg-sunken); color: var(--text); border-color: var(--border-strong); }
.notif-btn[aria-expanded="true"] { background: var(--bg-sunken); color: var(--text-strong); border-color: var(--border-strong); }
.notif-btn svg { width: 16px; height: 16px; }
.notif-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--text-dim);
  color: var(--surface);
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.notif-btn.has-urgent .notif-badge { background: var(--acc); color: var(--text-on-acc); }
.notif-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: min(380px, calc(100vw - 32px));
  max-height: min(70vh, 560px);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  z-index: 300;
  overflow: hidden;
}
.notif-panel[hidden] { display: none; }
.notif-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3);
  border-bottom: 1px solid var(--border);
}
.notif-head-title {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-strong);
}
.notif-head-action {
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 3px;
}
.notif-head-action:hover { color: var(--acc-text); }
.notif-list { overflow-y: auto; }
.notif-empty {
  padding: var(--space-5) var(--space-4);
  text-align: center;
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-style: italic;
  line-height: var(--leading-relaxed);
}
.notif-item {
  padding: var(--space-3);
  border-bottom: 1px solid var(--border);
  border-left: 2px solid transparent;
}
.notif-item:last-child { border-bottom: none; }
.notif-item.sev-urgent { border-left-color: var(--acc); }
.notif-item.sev-warn   { border-left-color: var(--warn); }
.notif-item-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}
.notif-item-title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-strong);
}
.notif-item-when {
  font-size: var(--text-2xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.notif-item.sev-urgent .notif-item-when { color: var(--acc-text); }
.notif-item-detail {
  margin-top: 2px;
  font-size: var(--text-xs);
  color: var(--text-muted);
  line-height: var(--leading-normal);
}
.notif-item-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.notif-action {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 2px var(--space-2);
  font-size: var(--text-2xs);
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.notif-action:hover { background: var(--bg-sunken); color: var(--text-strong); border-color: var(--border-strong); }
.notif-action.primary { color: var(--acc-text); border-color: color-mix(in oklch, var(--acc) 30%, transparent); }
.notif-action.primary:hover { background: var(--acc-soft); }
.notif-action.notif-dismiss { margin-left: auto; }
.notif-foot {
  padding: var(--space-2) var(--space-3);
  border-top: 1px solid var(--border);
  background: var(--bg-sunken);
  font-size: var(--text-2xs);
  color: var(--text-dim);
}
/* Móvil: el panel deja de colgar del botón y se ancla al ancho del
   viewport (a 375px un dropdown de 380px se saldría de pantalla). */
@media (max-width: 640px) {
  .notif-wrap { position: static; }
  .notif-panel {
    left: var(--space-3);
    right: var(--space-3);
    width: auto;
    max-height: 75vh;
  }
}

/* ─────────────────── Sidebar (shell v2) ───────────────────
   Rail vertical crema-sumida: la misma metáfora del pill rail
   horizontal, girada 90°. El ítem activo se "levanta" del raíl
   (surface + shadow-xs) y lleva un nodo terracota al margen,
   como las ruling lines de la bitácora. La contracción es
   instantánea (doctrina: no se anima layout). */
.sidebar {
  position: sticky;
  top: 0;
  align-self: flex-start;
  height: 100vh;
  height: 100dvh;
  flex: 0 0 var(--sb-cur);
  width: var(--sb-cur);
  display: flex;
  flex-direction: column;
  background: var(--bg-sunken);
  border-right: 1px solid var(--border);
  z-index: 40;
  overflow: hidden;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--header-h);
  flex-shrink: 0;
  padding: 0 var(--space-3) 0 14px;
  border-bottom: 1px solid var(--border);
}
.sidebar-mark {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-sm);
}
/* Logo de marca (diente Reluxdent). El PNG trae su propia silueta con
   contornos dorados: sin caja de fondo. Un drop-shadow tenue lo despega
   del surface claro (el relleno crema es casi blanco); en dark luce solo. */
.sidebar-mark-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  filter: drop-shadow(0 1px 1px color-mix(in oklch, var(--text-strong) 22%, transparent));
}
[data-theme="dark"] .sidebar-mark-img { filter: none; }
.sidebar-brandname {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  min-width: 0;
}
.sidebar-title {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  color: var(--text-strong);
  white-space: nowrap;
}

.sidebar-nav {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-3) var(--space-2);
  overflow-y: auto;
  overflow-x: hidden;
}
.side-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: 36px;
  flex-shrink: 0;
  padding: 0 10px;
  background: transparent;
  border: none;
  border-radius: var(--r-md);
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.side-item svg { width: 17px; height: 17px; flex-shrink: 0; }
/* v2.0 f8 — el árbol del rol oculta secciones enteras del sidebar.
   `display:flex` de arriba gana sobre el [hidden] nativo: hay que
   apagarlo de forma explícita. */
.side-item[hidden] { display: none !important; }
.side-item:hover {
  color: var(--text);
  background: color-mix(in oklch, var(--surface) 55%, transparent);
}
.side-item.active {
  background: var(--surface);
  color: var(--text-strong);
  font-weight: 600;
  box-shadow: var(--shadow-xs);
}
/* Nodo marginalia: punto terracota al margen del ítem activo */
.side-item.active::before {
  content: "";
  position: absolute;
  left: -5px;
  top: 50%;
  transform: translateY(-50%);
  width: 5px;
  height: 5px;
  border-radius: var(--r-full);
  background: var(--acc);
}
.side-label {
  overflow: hidden;
  text-overflow: ellipsis;
}
/* v2.9 f1 — badge de no leídos del ítem de sidebar (WhatsApp). Mismo
   patrón visual que .notif-badge, reposicionado para un botón más ancho
   con label. .side-item ya es position:relative. */
.side-badge {
  position: absolute;
  top: 4px;
  right: 8px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--acc);
  color: var(--text-on-acc);
  font-size: 10px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
body.sb-collapsed .side-badge { top: 2px; right: 2px; }

.sidebar-foot {
  flex-shrink: 0;
  padding: var(--space-2);
  border-top: 1px solid var(--border);
}
.side-collapse { width: 100%; }
.side-collapse svg { transition: transform var(--dur-base) var(--ease); }

/* v2.3 — separador de grupo del sidebar. Marca dónde termina el
   consultorio y empieza otra línea de negocio (hoy, Perfect White). Es
   una línea con un rótulo pequeño encima, no un bloque: la separación
   tiene que leerse sin pesar más que los botones que separa. La posición
   la decide `order` desde applySidebarForRole(), no el DOM. */
.side-sep {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
  margin: var(--space-4) 4px var(--space-2);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-dim);
  white-space: nowrap;
}
.side-sep::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}
.side-sep[hidden] { display: none !important; }

/* Contraído — sólo desktop/tablet; en móvil el sidebar es drawer y
   siempre se muestra expandido. */
@media (min-width: 769px) {
  body.sb-collapsed { --sb-cur: var(--sb-w-min); }
  body.sb-collapsed .sidebar-brandname,
  body.sb-collapsed .side-label { display: none; }
  body.sb-collapsed .sidebar-brand { justify-content: center; padding: 0; }
  body.sb-collapsed .side-item { justify-content: center; padding: 0; }
  body.sb-collapsed .side-item.active::before { display: none; }
  body.sb-collapsed .side-collapse svg { transform: rotate(180deg); }
  /* Contraído no hay sitio para el rótulo: queda la línea sola, que es
     lo que hace falta para que los dos grupos se sigan leyendo. */
  body.sb-collapsed .side-sep { margin: var(--space-3) 10px; }
  body.sb-collapsed .side-sep > span { display: none; }
}

/* Columna principal */
.app-main {
  flex: 1 1 auto;
  min-width: 0;
}

.header-context {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Subnav (shell v2): la fila horizontal ahora navega SUBsecciones de la
   sección activa del sidebar. Conserva clases .nav-tab + traveling
   underline. */
.main-nav {
  position: sticky;
  top: var(--header-h);
  z-index: 25;
  display: flex;
  align-items: center;
  gap: var(--space-1);
  height: var(--nav-h);
  padding: 0 var(--space-5);
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
}
.subnav-tabs {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-1);
  height: 100%;
  min-width: 0;
}

.nav-tab {
  position: relative;
  flex-shrink: 0;
  background: transparent;
  border: none;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  border-radius: var(--r-sm);
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.nav-tab:hover { color: var(--text); background: var(--bg-sunken); }
.nav-tab.active {
  color: var(--text-strong);
  font-weight: 600;
}
.nav-tab.active::after {
  content: "";
  position: absolute;
  left: var(--space-3);
  right: var(--space-3);
  bottom: -1px;
  height: 2px;
  background: var(--acc);
  border-radius: var(--r-full) var(--r-full) 0 0;
}

.nav-spacer { flex: 1; }

.nav-counter {
  font-size: var(--text-sm);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  padding-right: var(--space-2);
}
.nav-counter strong {
  color: var(--text-strong);
  font-weight: 600;
}

/* Vistas */
.view {
  display: none;
  padding: var(--space-5) var(--space-5) var(--space-7);
  max-width: var(--max-w);
  margin: 0 auto;
}
.view.active { display: block; }

/* ───────────────────────── Toolbar ───────────────────────── */
.toolbar {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.toolbar-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.toolbar-row-sub {
  gap: var(--space-2);
  padding: var(--space-2) 0 0;
  border-top: 1px dashed var(--border);
}
.toolbar-spacer { flex: 1; }

/* Filtros: input inline con label flotante a la izquierda */
.field-inline {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 34px;
  padding: 0 var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  transition: border-color var(--dur-fast) var(--ease);
}
.field-inline:hover { border-color: var(--border-strong); }
.field-inline:focus-within {
  border-color: var(--acc);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--acc) 18%, transparent);
}
.field-inline-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}
.filter-date {
  height: 100%;
  background-color: transparent;
  background-image: none;
  border: none;
  padding: 0;
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--text);
  width: 132px;
  color-scheme: light;
}
.filter-date:focus { outline: none; box-shadow: none; }
[data-theme="dark"] .filter-date { color-scheme: dark; }

.filter-select {
  height: 100%;
  background-color: transparent;
  border: none;
  padding: 0 22px 0 0;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text);
  background-position: right 0 center;
  background-repeat: no-repeat;
  background-size: 12px;
  width: auto;
  min-width: 120px;
  color-scheme: light;
}
.filter-select:focus { outline: none; box-shadow: none; }
.filter-select.is-active { color: var(--acc-text); font-weight: 600; }
[data-theme="dark"] .filter-select { color-scheme: dark; }
[data-theme="dark"] .filter-select option {
  background-color: var(--surface);
  color: var(--text);
}
[data-theme="dark"] .filter-select.is-active { color: var(--acc); }

/* Patients view: separación leve del lado izquierdo en la fila de
   sub-filtros (el filtro DOCTOR queda muy pegado al borde sin esto). */
#view-patients .toolbar-row-sub { padding-left: var(--space-2); }

/* Dropdown multi-select (canal) */
.dropdown-multi { position: relative; }
.dropdown-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 34px;
  padding: 0 var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  cursor: pointer;
  font-size: var(--text-sm);
  color: var(--text);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.dropdown-trigger:hover { border-color: var(--border-strong); background: var(--bg-sunken); }
.dropdown-trigger[aria-expanded="true"] {
  border-color: var(--acc);
  background: var(--surface);
}
.dropdown-trigger-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.dropdown-trigger-value {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-strong);
}
.dropdown-trigger-value.is-active { color: var(--acc-text); }
[data-theme="dark"] .dropdown-trigger-value.is-active { color: var(--acc); }
.dropdown-trigger-chevron {
  color: var(--text-muted);
  transition: transform var(--dur-fast) var(--ease);
}
.dropdown-trigger[aria-expanded="true"] .dropdown-trigger-chevron { transform: rotate(180deg); }

.dropdown-panel {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  min-width: 200px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md);
  padding: var(--space-1);
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 320px;
  overflow-y: auto;
}
.dropdown-panel[hidden] { display: none; }
.dropdown-option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--r-sm);
  cursor: pointer;
  font-size: var(--text-sm);
  color: var(--text);
  user-select: none;
  transition: background var(--dur-fast) var(--ease);
}
.dropdown-option:hover { background: var(--bg-sunken); }
.dropdown-option input[type="checkbox"] {
  margin: 0;
  width: 14px;
  height: 14px;
}
.dropdown-option-label { flex: 1; }
.dropdown-divider {
  height: 1px;
  background: var(--border);
  margin: 2px 0;
}
.dropdown-action {
  background: transparent;
  border: none;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--acc-text);
  cursor: pointer;
  text-align: left;
  border-radius: var(--r-sm);
  transition: background var(--dur-fast) var(--ease);
}
.dropdown-action:hover { background: var(--bg-sunken); }
[data-theme="dark"] .dropdown-action { color: var(--acc); }

/* Botón link (limpiar filtros) */
.btn-link {
  background: transparent;
  border: none;
  padding: 0 var(--space-2);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 3px;
  transition: color var(--dur-fast) var(--ease), text-decoration-color var(--dur-fast) var(--ease);
}
.btn-link:hover { color: var(--text); text-decoration-color: var(--border-strong); }

/* ───────────────────────── Botones ───────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 34px;
  padding: 0 var(--space-3);
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1;
  letter-spacing: var(--tracking-tight);
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
  white-space: nowrap;
  user-select: none;
}
.btn:hover { background: var(--bg-sunken); border-color: var(--border-strong); }
.btn:active { transform: translateY(0.5px); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
/* `.btn` fija display:inline-flex, que le gana al `[hidden]` del user-agent;
   sin esto, un botón .btn con el atributo `hidden` (Eliminar de evolución /
   plan / pago cuando el registro es nuevo) se seguiría mostrando. */
.btn[hidden] { display: none; }

.btn-primary {
  background: var(--acc);
  color: var(--text-on-acc);
  border-color: color-mix(in oklch, var(--acc) 75%, var(--n-950));
  box-shadow: var(--shadow-xs), inset 0 1px 0 oklch(1 0 0 / 0.10);
  font-weight: 600;
}
.btn-primary:hover {
  background: var(--acc-hover);
  border-color: color-mix(in oklch, var(--acc-hover) 70%, var(--n-950));
}
.btn-primary:active { background: var(--acc-active); }

.btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--text-muted);
  height: 32px;
  padding: 0 var(--space-2);
}
.btn-ghost:hover { background: var(--bg-sunken); color: var(--text); border-color: transparent; }

.btn-danger {
  background: transparent;
  color: var(--err-700);
  border-color: color-mix(in oklch, var(--err) 30%, var(--border));
}
[data-theme="dark"] .btn-danger { color: var(--err); }
.btn-danger:hover {
  background: var(--err-bg);
  border-color: color-mix(in oklch, var(--err) 55%, transparent);
  color: var(--err);
}

/* Variante con tinte de acento — secundario que sigue siendo de "marca"
   sin gritar como el primario. Sólo lo usamos cuando hay un par
   primario/secundario que comparten contexto (ej. cargar antes/después). */
.btn-soft {
  background: var(--acc-soft);
  color: var(--acc-text);
  border-color: color-mix(in oklch, var(--acc) 22%, transparent);
  font-weight: 500;
}
[data-theme="dark"] .btn-soft { color: var(--acc); }
.btn-soft:hover {
  background: color-mix(in oklch, var(--acc) 18%, var(--surface));
  border-color: color-mix(in oklch, var(--acc) 40%, transparent);
}

/* Icon button (x, edit, etc.) */
.icon-btn {
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  color: var(--text-muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.icon-btn:hover { background: var(--bg-sunken); color: var(--text); }

/* Upload-label (label que actúa como btn con input file) */
.upload-label {
  display: inline-flex;
  cursor: pointer;
}
.upload-label input[type="file"] { position: absolute; opacity: 0; pointer-events: none; }

/* ───────────────────────── Pills / filters ───────────────────────── */
.filter-pills {
  display: inline-flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  padding: 3px;
  background: var(--bg-sunken);
  border-radius: var(--r-md);
  border: 1px solid var(--border);
}
.pill {
  background: transparent;
  border: none;
  padding: 5px var(--space-3);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-muted);
  border-radius: calc(var(--r-md) - 3px);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.pill:hover { color: var(--text); }
.pill.active {
  background: var(--surface);
  color: var(--text-strong);
  box-shadow: var(--shadow-xs);
}

.view-switcher {
  display: inline-flex;
  background: var(--bg-sunken);
  padding: 3px;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
}
.view-btn {
  background: transparent;
  border: none;
  padding: 5px var(--space-3);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-muted);
  border-radius: calc(var(--r-md) - 3px);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.view-btn:hover { color: var(--text); }
.view-btn.active {
  background: var(--surface);
  color: var(--text-strong);
  box-shadow: var(--shadow-xs);
}

/* ── Selector de período unificado (v2.0 fase 4) ───────────────────
   [Todo] ‹ mes año › [Mes | 01–07 | 08–14 …]. Reutilizado en bandeja,
   pacientes, tratamientos e ingresos. */
.period-picker {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.period-picker .pp-all {
  border: 1px solid var(--border);
  background-color: transparent;
}
.period-picker .pp-all.active {
  background: var(--surface);
  color: var(--text-strong);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-xs);
}
.period-picker .pp-nav {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}
.period-picker .pp-nav.pp-off { opacity: 0.5; }
.period-picker .pp-nav .btn-ghost { padding: 2px 8px; }
.period-picker .pp-label {
  font-size: var(--text-sm);
  color: var(--text-strong);
  min-width: 104px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.period-picker .pp-weeks {
  display: inline-flex;
  gap: var(--space-1);
  padding: 3px;
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.period-picker .pp-weeks .pill { font-variant-numeric: tabular-nums; }

/* Link "ficha →" dentro del chip de paciente del modal de cita */
.apt-open-profile { margin-left: var(--space-2); font-size: var(--text-xs); white-space: nowrap; }

/* ───────────────────────── Inputs ───────────────────────── */
.search-input,
input[type="text"],
input[type="email"],
input[type="number"],
input[type="tel"],
input[type="date"],
input[type="datetime-local"],
input[type="search"],
textarea,
select {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 0 var(--space-3);
  height: 34px;
  font-size: var(--text-sm);
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
  width: 100%;
}
textarea {
  padding: var(--space-2) var(--space-3);
  height: auto;
  resize: vertical;
  min-height: 60px;
  line-height: var(--leading-snug);
}
select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M2.5 4.5L6 8l3.5-3.5'/></svg>");
  background-repeat: no-repeat;
  background-position: right var(--space-2) center;
  background-size: 12px;
  padding-right: 28px;
}
[data-theme="dark"] select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path fill='none' stroke='%23fff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M2.5 4.5L6 8l3.5-3.5'/></svg>");
}

input:hover, textarea:hover, select:hover { border-color: var(--border-strong); }
input:focus, textarea:focus, select:focus {
  border-color: var(--acc);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--acc) 18%, transparent);
}
input:disabled, select:disabled, textarea:disabled {
  background: var(--bg-sunken);
  color: var(--text-disabled);
  cursor: not-allowed;
}
::placeholder { color: var(--text-dim); opacity: 1; }

.search-input {
  min-width: 240px;
  max-width: 320px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14'><circle cx='6' cy='6' r='4.25' fill='none' stroke='%23999' stroke-width='1.4'/><path d='M9.2 9.2L12 12' fill='none' stroke='%23999' stroke-width='1.4' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: var(--space-3) center;
  padding-left: 32px;
}

/* Checkbox */
.checkbox-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  cursor: pointer;
}
/* `display:inline-flex` gana sobre el [hidden] nativo del navegador. */
.checkbox-label[hidden] { display: none !important; }
input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  margin: 0;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--r-xs);
  background: var(--surface);
  cursor: pointer;
  position: relative;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
  flex-shrink: 0;
}
input[type="checkbox"]:hover { border-color: var(--acc); }
input[type="checkbox"]:checked {
  background: var(--acc);
  border-color: var(--acc);
}
input[type="checkbox"]:checked::after {
  content: "";
  position: absolute;
  left: 4px;
  top: 1px;
  width: 5px;
  height: 9px;
  border: solid var(--text-on-acc);
  border-width: 0 1.8px 1.8px 0;
  transform: rotate(45deg);
}

/* Form labels (col layout dentro de modales) */
.modal-body label,
.patient-form label,
form label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.modal-body label.checkbox-label,
form label.checkbox-label {
  flex-direction: row;
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--text-sm);
  font-weight: 400;
  color: var(--text);
}
.modal-body label > input,
.modal-body label > select,
.modal-body label > textarea,
.patient-form label > input,
.patient-form label > select,
.patient-form label > textarea {
  text-transform: none;
  letter-spacing: var(--tracking-tight);
  font-size: var(--text-sm);
  font-weight: 400;
  color: var(--text);
}

/* ═══════════════════════════════════════════════════════════════════
   VISTA: BANDEJA DE LEADS
   ═══════════════════════════════════════════════════════════════════ */

.grid-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: auto;
  max-height: calc(100vh - var(--header-h) - var(--nav-h) - 180px);
  box-shadow: var(--shadow-xs);
}
/* v1.5.4 — en viewports bajos (móvil horizontal, laptops cortas) el
   max-height calculado se vuelve casi cero y colapsa la grilla, escondiendo
   los registros tras el scroll interno. Liberamos la altura: la página
   entera scrollea y los leads vuelven a verse. */
@media (max-height: 600px) {
  .grid-wrap { max-height: none; }
}

.data-grid {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--text-sm);
}
.data-grid thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bg-elev);
  color: var(--text-muted);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  text-align: left;
  padding: var(--space-3) var(--space-3);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.data-grid tbody td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  color: var(--text);
}
.data-grid tbody tr:last-child td { border-bottom: none; }
.data-grid tbody tr {
  transition: background var(--dur-fast) var(--ease);
}
.data-grid tbody tr:hover { background: var(--bg-sunken); }

/* Column hints */
.col-date    { width: 80px; }

/* Chip neutro para fechas en celdas (bandeja de leads, mi panel, etc.) */
.date-chip {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 8px;
  border-radius: 999px;
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  white-space: nowrap;
}
.date-chip--time {
  background: color-mix(in oklch, var(--acc) 10%, var(--surface));
  border-color: color-mix(in oklch, var(--acc) 25%, var(--border));
  color: var(--acc-text, var(--text));
}
[data-theme="dark"] .date-chip--time { color: var(--acc); }
.col-name    { min-width: 180px; }
.col-phone   { width: 140px; }
.col-channel { width: 130px; }
.col-status  { width: 180px; }
.col-actions { width: 150px; text-align: right; }

/* Pacientes grid — anchos calibrados para sus columnas.
   v2.0 f9.5: "Documento" deja de ser columna (baja a la segunda línea de
   la identidad) y entra la de acciones rápidas. */
.col-patient    { min-width: 220px; }
.col-document   { width: 140px; }
.col-doctor     { width: 160px; }
.col-status     { width: 170px; }
.col-last-visit { width: 108px; }
.col-next-visit { width: 108px; }
.col-balance    { width: 120px; text-align: right; font-variant-numeric: tabular-nums; }
.col-quick      { width: 132px; }

/* Utilidad: texto sólo para lectores de pantalla (encabezados de columnas
   que son visualmente evidentes, como la de acciones). */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ─────────────────────────────────────────────────────────────────────
   Listado de pacientes — fila (v2.0 f9.5)
   ───────────────────────────────────────────────────────────────────
   Densidad dentro de la celda, respiración entre filas. La identidad
   manda: nombre en dos pesos por encima de su línea de datos.
   ─────────────────────────────────────────────────────────────────── */
.data-grid-roomy tbody td { padding-top: 10px; padding-bottom: 10px; }
.pt-identity {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.pt-meta {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pt-star { margin-left: 6px; color: var(--acc); font-size: var(--text-xs); }
.pt-doctor {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}
/* El punto reusa el pastel del doctor del calendario: el mismo código de
   color en los tres lugares donde se lo identifica (agenda, inicio,
   listado). El anillo lo despega del fondo, que también es claro. */
.pt-doctor-dot {
  width: 9px; height: 9px;
  border-radius: var(--r-full);
  flex-shrink: 0;
  box-shadow: 0 0 0 1px oklch(0 0 0 / 0.10) inset;
}
.pt-none { color: var(--text-muted); font-style: italic; font-size: var(--text-xs); }
.pt-date {
  font-variant-numeric: tabular-nums;
  line-height: 1.3;
}
.pt-date-abs { display: block; }
.pt-date-rel {
  display: block;
  font-size: var(--text-2xs);
  color: var(--text-muted);
}
.pt-actions { text-align: right; }

/* Acciones rápidas: presentes pero calladas. En desktop bajan a la mitad
   de opacidad hasta que el puntero entra en la fila; en táctil (donde no
   hay hover que revele nada) se quedan siempre visibles. */
.quick-acts {
  display: inline-flex;
  gap: 2px;
  justify-content: flex-end;
}
.quick-act {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px; height: 30px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background-color: transparent;
  color: var(--text-muted);
  cursor: pointer;
  opacity: 0.55;
  transition: opacity var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease);
}
.patient-row:hover .quick-act,
.quick-act:focus-visible { opacity: 1; }
.quick-act:hover {
  color: var(--acc);
  border-color: color-mix(in oklch, var(--acc) 30%, var(--border));
  background-color: color-mix(in oklch, var(--acc) 8%, transparent);
}
.quick-act.is-on { opacity: 1; color: var(--acc); }
.quick-act[disabled],
.quick-act.is-disabled {
  opacity: 0.28;
  cursor: not-allowed;
}
.patient-row:hover .quick-act[disabled] { opacity: 0.28; }
@media (hover: none) {
  .quick-act { opacity: 1; }
}

/* Saldo pendiente: especificidad alta para ganar sobre el color genérico
   de .data-grid tbody td. Sin esto las clases JS quedan invisibles. */
#patients-grid tbody td.balance-pending {
  color: var(--err);
  font-weight: 600;
}
#patients-grid tbody td.balance-zero {
  color: var(--text-muted);
}

.patients-title {
  font-size: var(--text-lg);
  font-weight: 600;
  margin: 0 var(--space-3) 0 0;
  color: var(--text-strong);
}

/* Fila clickeable: toda la fila abre la ficha del paciente. Cursor +
   hover indican la interacción. El hover de .data-grid ya oscurece un
   poco; intensificamos con un fondo accent muy tenue + ring sutil al
   pasar por encima. */
#patients-grid tbody tr.patient-row { cursor: pointer; transition: background var(--dur-fast) var(--ease); }
#patients-grid tbody tr.patient-row:hover {
  background: color-mix(in oklch, var(--acc) 7%, var(--bg-sunken));
}
#patients-grid tbody tr.patient-row:hover .patient-row-name {
  color: var(--acc);
}
#patients-grid tbody tr.patient-row:active {
  background: color-mix(in oklch, var(--acc) 12%, var(--bg-sunken));
}
#patients-grid tbody tr.patient-row .patient-row-name {
  font-weight: 500;
  color: var(--text-strong);
}

/* Status chip en la grid de pacientes (badge compacto, una sola línea) */
.status-chip {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--r-full);
  font-size: 10px;
  line-height: 1.3;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 600;
  border: 1px solid var(--border);
  background: var(--bg-sunken);
  color: var(--text-muted);
  white-space: nowrap;
}
.status-chip.status-VALUATION_SCHEDULED { color: var(--acc); border-color: color-mix(in oklch, var(--acc) 30%, transparent); background: color-mix(in oklch, var(--acc) 8%, var(--bg-sunken)); }
.status-chip.status-VALUATION_DONE      { color: var(--info); border-color: color-mix(in oklch, var(--info) 30%, transparent); background: color-mix(in oklch, var(--info) 8%, var(--bg-sunken)); }
.status-chip.status-TREATMENT_ACCEPTED  { color: var(--ok); border-color: color-mix(in oklch, var(--ok) 30%, transparent); background: color-mix(in oklch, var(--ok) 8%, var(--bg-sunken)); }
.status-chip.status-TREATMENT_FINISHED  { color: var(--text-muted); border-color: var(--border); }
.status-chip.status-NOT_CONTINUED       { color: var(--err); border-color: color-mix(in oklch, var(--err) 30%, transparent); background: color-mix(in oklch, var(--err) 8%, var(--bg-sunken)); }

/* Inline edit cells */
.cell-select,
.cell-input {
  width: 100%;
  height: 28px;
  padding: 0 var(--space-2);
  font-size: var(--text-sm);
  background-color: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  color: var(--text);
  transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.cell-select {
  padding-right: 22px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'><path fill='none' stroke='%23999' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M2.5 4.5L6 8l3.5-3.5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 6px center;
  background-size: 10px;
}
[data-theme="dark"] .cell-select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'><path fill='none' stroke='%23bbb' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M2.5 4.5L6 8l3.5-3.5'/></svg>");
}
.cell-input { padding: 0 var(--space-2); }

/* Idle state: borde sutil para que el control sea reconocible sin hover (clave en dark) */
[data-theme="dark"] .cell-select,
[data-theme="dark"] .cell-input {
  background-color: color-mix(in oklch, var(--bg-elev) 60%, transparent);
  border-color: color-mix(in oklch, var(--border) 70%, transparent);
}

tr:hover .cell-select,
tr:hover .cell-input {
  background-color: var(--surface);
  border-color: var(--border);
}
[data-theme="dark"] tr:hover .cell-select,
[data-theme="dark"] tr:hover .cell-input {
  background-color: var(--surface-2);
  border-color: var(--border-strong);
}

.cell-select:hover, .cell-input:hover {
  background-color: var(--surface);
  border-color: var(--border-strong);
}
.cell-select:focus, .cell-input:focus {
  background-color: var(--surface);
  border-color: var(--acc);
  box-shadow: 0 0 0 2px color-mix(in oklch, var(--acc) 22%, transparent);
}
/* Disabled: completamente inerte. Sin chevron, sin borde, sin fondo,
   incluso bajo tr:hover o el idle state de dark mode (mayor especificidad
   con &:disabled[data-...] no aplica aquí; usamos selector duplicado). */
.cell-select:disabled,
.cell-input:disabled,
[data-theme="dark"] .cell-select:disabled,
[data-theme="dark"] .cell-input:disabled,
tr:hover .cell-select:disabled,
tr:hover .cell-input:disabled,
[data-theme="dark"] tr:hover .cell-select:disabled,
[data-theme="dark"] tr:hover .cell-input:disabled {
  background-color: transparent;
  background-image: none;
  border-color: transparent;
  color: var(--text-disabled);
  opacity: 0.45;
  cursor: not-allowed;
  padding-right: var(--space-2);
}

/* Native option popup respeta tema OS via color-scheme en :root; reforzamos en el control */
.cell-select { color-scheme: light; }
[data-theme="dark"] .cell-select { color-scheme: dark; }
[data-theme="dark"] select { color-scheme: dark; }

/* Nombre clickeable */
.name-link {
  font-weight: 500;
  color: var(--text-strong);
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 3px;
  transition: text-decoration-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.name-link:hover { text-decoration-color: var(--acc); color: var(--acc-text); }
.name-link.no-name { color: var(--text-dim); font-style: italic; font-weight: 400; }

.phone-link {
  color: var(--text);
  font-variant-numeric: tabular-nums;
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 3px;
  transition: text-decoration-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.phone-link:hover { text-decoration-color: var(--acc); color: var(--acc-text); }
.phone-empty { color: var(--text-dim); }

/* Status colors en select (gota de color sutil a la izquierda del valor) */
.status-select {
  font-weight: 500;
  padding-left: var(--space-3);
  position: relative;
}
.status-select.status-NEW_LEAD          { color: var(--info-700); }
.status-select.status-VALUATION_SCHEDULED { color: var(--warn-700); }
.status-select.status-VALUATION_DONE      { color: var(--info-700); }
.status-select.status-TREATMENT_ACCEPTED  { color: var(--ok-700); }
.status-select.status-TREATMENT_FINISHED  { color: var(--acc-text); }
.status-select.status-NOT_CONTINUED       { color: var(--err-700); }

[data-theme="dark"] .status-select.status-NEW_LEAD { color: var(--info-500); }
[data-theme="dark"] .status-select.status-VALUATION_SCHEDULED { color: var(--warn-500); }
[data-theme="dark"] .status-select.status-VALUATION_DONE { color: var(--info-500); }
[data-theme="dark"] .status-select.status-TREATMENT_ACCEPTED { color: var(--ok-500); }
[data-theme="dark"] .status-select.status-TREATMENT_FINISHED { color: var(--acc); }
[data-theme="dark"] .status-select.status-NOT_CONTINUED { color: var(--err-500); }

/* Channel chip-style coloring (sutil) */
.channel-select { font-weight: 500; }
.channel-select.channel-whatsapp  { color: oklch(0.50 0.13 150); }
.channel-select.channel-instagram { color: oklch(0.55 0.16 350); }
.channel-select.channel-facebook  { color: oklch(0.52 0.13 250); }
.channel-select.channel-tiktok    { color: oklch(0.45 0.04 290); }
.channel-select.channel-google    { color: oklch(0.55 0.13 60); }
.channel-select.channel-referido  { color: oklch(0.50 0.10 200); }
.channel-select.channel-otro      { color: var(--text-muted); }
.channel-select.channel-          { color: var(--text-dim); }

[data-theme="dark"] .channel-select.channel-whatsapp  { color: oklch(0.78 0.13 150); }
[data-theme="dark"] .channel-select.channel-instagram { color: oklch(0.78 0.14 350); }
[data-theme="dark"] .channel-select.channel-facebook  { color: oklch(0.76 0.12 250); }
[data-theme="dark"] .channel-select.channel-tiktok    { color: oklch(0.85 0.03 290); }
[data-theme="dark"] .channel-select.channel-google    { color: oklch(0.80 0.13 80); }
[data-theme="dark"] .channel-select.channel-referido  { color: oklch(0.76 0.10 200); }

/* Acciones de fila */
.row-action {
  background: transparent;
  border: 1px solid transparent;
  padding: 4px var(--space-2);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--text-muted);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.row-action:hover {
  background: var(--bg-sunken);
  color: var(--text);
  border-color: var(--border);
}
.row-action.del { color: var(--err-700); padding: 4px 8px; }
[data-theme="dark"] .row-action.del { color: var(--err); }
.row-action.del:hover {
  background: var(--err-bg);
  color: var(--err);
  border-color: color-mix(in oklch, var(--err) 35%, transparent);
}

/* Empty row */
.empty-row td {
  text-align: center;
  padding: var(--space-7) var(--space-4) !important;
  color: var(--text-muted);
  font-size: var(--text-sm);
  background: var(--bg);
}

/* Pagination */
.pagination {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-3) 0;
  margin-top: var(--space-2);
  flex-wrap: wrap;
}
.page-btn {
  min-width: 30px;
  height: 30px;
  padding: 0 var(--space-2);
  background: transparent;
  color: var(--text-muted);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.page-btn:hover:not(:disabled) {
  background: var(--bg-sunken);
  color: var(--text);
  border-color: var(--border);
}
.page-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.page-btn.active {
  background: var(--acc-soft);
  color: var(--acc-text);
  border-color: color-mix(in oklch, var(--acc) 30%, transparent);
}
.page-info {
  font-size: var(--text-xs);
  color: var(--text-muted);
  padding: 0 var(--space-2);
  font-variant-numeric: tabular-nums;
}
.page-info:last-child { margin-left: auto; }

/* ═══════════════════════════════════════════════════════════════════
   VISTA: CALENDARIO
   ═══════════════════════════════════════════════════════════════════ */

.cal-nav {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px;
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.cal-nav .btn-ghost { height: 28px; padding: 0 var(--space-2); }
.cal-period {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-strong);
  padding: 0 var(--space-3);
  min-width: 140px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ── Mini-calendario (datepick, v2.0 f4.1) ─────────────────────────
   Cualquier label de fecha marcado como trigger abre el popover para
   saltar directo a un día. El subrayado punteado es la señal. */
.datepick-trigger {
  cursor: pointer;
  border-radius: var(--r-sm);
  text-decoration: underline dotted color-mix(in oklch, currentColor 35%, transparent);
  text-underline-offset: 3px;
  transition: text-decoration-color var(--dur-fast) var(--ease);
}
.datepick-trigger:hover {
  text-decoration-color: color-mix(in oklch, currentColor 70%, transparent);
}
.datepick-trigger:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}
.rlx-datepick {
  position: fixed;
  z-index: 9995;
  width: 252px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
  padding: var(--space-3);
}
.rlx-datepick[hidden] { display: none; }
.dp-head { display: flex; align-items: center; gap: var(--space-1); margin-bottom: var(--space-2); }
.dp-head .btn-ghost { height: 26px; padding: 0 var(--space-2); }
.dp-label {
  flex: 1;
  text-align: center;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-strong);
}
.dp-dow { display: grid; grid-template-columns: repeat(7, 1fr); margin-bottom: 2px; }
.dp-dow span {
  text-align: center;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  color: var(--text-dim);
}
.dp-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.dp-day {
  aspect-ratio: 1;
  border: none;
  background: transparent;
  border-radius: var(--r-full);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  color: var(--text);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.dp-day:hover { background: var(--bg-sunken); }
.dp-day.other { color: var(--text-disabled); }
.dp-day.today { box-shadow: inset 0 0 0 1px var(--acc); }
.dp-day.selected { background: var(--acc); color: var(--text-on-acc); }
.dp-today { width: 100%; margin-top: var(--space-2); font-size: var(--text-xs); }

.cal-legend {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-4);
  font-size: var(--text-xs);
  color: var(--text-muted);
  padding: var(--space-2) 0;
}
.legend-item { display: inline-flex; align-items: center; gap: var(--space-2); }
.legend-sep { width: 1px; height: 14px; background: var(--border); }

.dot, .density-dot {
  width: 10px;
  height: 10px;
  border-radius: var(--r-full);
  display: inline-block;
}
.density-dot.empty  { background: var(--n-200); }
.density-dot.light  { background: color-mix(in oklch, var(--acc) 25%, var(--n-100)); }
.density-dot.medium { background: color-mix(in oklch, var(--acc) 55%, var(--n-100)); }
.density-dot.full   { background: var(--acc); }
.density-dot.over   { background: var(--err); }
[data-theme="dark"] .density-dot.empty { background: var(--n-700); }

.legend-swatch {
  width: 12px; height: 12px;
  border-radius: var(--r-xs);
}
.legend-stripe {
  width: 18px; height: 4px;
  border-radius: var(--r-full);
}
.stripe-valuation { background: var(--info); }
.stripe-treatment { background: var(--acc); }
.stripe-canceled  { background: var(--text-disabled); }

/* Month grid */
#calendar-container {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-xs);
}

.cal-month {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  grid-auto-rows: minmax(96px, 1fr);
}
.cal-dow {
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  background: var(--bg-elev);
  text-align: left;
}
.cal-day {
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  cursor: pointer;
  position: relative;
  transition: background var(--dur-fast) var(--ease);
  min-height: 96px;
}
.cal-day:hover { background: var(--bg-sunken); }
.cal-day:nth-child(7n+7) { border-right: none; }
.cal-day.other-month { background: var(--bg-sunken); }
.cal-day.other-month .cal-day-num { color: var(--text-disabled); }
.cal-day.today { background: var(--acc-soft); }
.cal-day.today .cal-day-num {
  background: var(--acc);
  color: var(--text-on-acc);
}
.cal-day-num {
  font-size: var(--text-sm);
  font-weight: 600;
  width: 24px;
  height: 24px;
  border-radius: var(--r-full);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-strong);
}
.cal-day-density { display: flex; flex-direction: column; gap: 2px; margin-top: auto; }
.cal-day-count { font-size: var(--text-lg); font-weight: 600; color: var(--text-strong); line-height: 1; font-variant-numeric: tabular-nums; }
.cal-day-label { font-size: var(--text-2xs); color: var(--text-muted); letter-spacing: var(--tracking-wide); }
.cal-day-bar {
  height: 3px;
  background: var(--n-200);
  border-radius: var(--r-full);
  overflow: hidden;
  margin-top: var(--space-1);
}
[data-theme="dark"] .cal-day-bar { background: var(--n-800); }
.cal-day-bar-fill {
  height: 100%;
  background: var(--acc);
  transition: width var(--dur-base) var(--ease);
}
.cal-day.density.empty .cal-day-bar-fill { background: var(--n-300); }
.cal-day.density.over .cal-day-bar-fill { background: var(--err); }

/* Week & Day — semana 8:00 a 18:00 visible sin scroll vertical */
.cal-week, .cal-day-view {
  display: flex;
  flex-direction: column;
}
.cal-week-header {
  display: grid;
  grid-template-columns: 60px repeat(7, 1fr);
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
}
.cal-week-header > div {
  padding: var(--space-2) var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-align: center;
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  border-right: 1px solid var(--border);
}
.cal-week-header > div:last-child { border-right: none; }
.wh-date {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: var(--r-full);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-strong);
  margin-top: 2px;
}
.wh-date.today { background: var(--acc); color: var(--text-on-acc); }

/* v2.1 2.2 — franja de bloqueos POR DOCTOR, entre el número del día y el
   inicio de las 08:00. Mismo grid que header/body para que cada celda
   quede alineada bajo su columna de día; sólo se agrega al DOM si hay
   al menos un bloqueo esa semana/día (ver renderBlockRow en calendar.js). */
.cal-week-blockrow, .cal-day-blockrow {
  display: grid;
  border-bottom: 1px solid var(--border);
  background: var(--bg-elev);
}
.cal-week-blockrow { grid-template-columns: 60px repeat(7, 1fr); }
.cal-day-blockrow  { grid-template-columns: 60px 1fr; }
.cal-blockrow-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 3px 4px;
  border-right: 1px solid var(--border);
  /* v2.1 aj3 — sin esto, un nombre largo de doctor no se recorta: empuja
     el ancho mínimo de ESTA celda de grid más allá de su columna (1fr),
     y como el header/body de arriba y abajo son grids APARTE que no
     cambian de ancho por esto, el resultado es que el chip queda
     "corrido" respecto de su columna del día. `min-width: 0` es el fix
     estándar para que la celda respete el ancho que le tocó y sea el
     texto (con su propio overflow/ellipsis) el que se recorte, no la
     grilla la que se deforme. */
  min-width: 0;
}
.cal-blockrow-cell:last-child { border-right: none; }
/* v2.1 aj2 — Javi: el chip de bloqueo por doctor se confundía con una cita
   real porque llevaba el color pastel del doctor. Ahora es SIEMPRE gris
   oscuro fijo (ni el color del doctor, ni distinto entre claro/oscuro) —
   nada más se le parece en el calendario. `--n-700`/`--n-50` son parte de
   la escala neutra base y no cambian con el tema (a diferencia de
   `--bg-sunken`/`--text-muted`, que sí se invierten en oscuro). */
.cal-blockrow-chip {
  display: flex;
  align-items: center;
  padding: 2px 6px;
  border-radius: var(--r-sm);
  font-size: var(--text-2xs);
  font-weight: 500;
  cursor: pointer;
  overflow: hidden;
  background: var(--n-700);
  color: var(--n-50);
}
.cal-blockrow-doc { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

.cal-week-body, .cal-day-body {
  display: grid;
  position: relative;
  overflow: visible;
}
.cal-week-body { grid-template-columns: 60px repeat(7, 1fr); }
.cal-day-body  { grid-template-columns: 60px 1fr; }

.cal-hour-col {
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--border);
}
.cal-hour-label {
  height: 56px; /* v1.5.4 — debe coincidir con SLOT_HEIGHT en calendar.js */
  padding: 2px var(--space-2);
  font-size: var(--text-2xs);
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
  text-align: right;
  border-top: 1px dashed var(--border);
}
.cal-hour-label:first-child { border-top: none; }
/* v1.5.4 — etiqueta de cierre 18:00 al pie del eje: altura cero (no
   desalinea con las columnas de día) y el texto se eleva sobre la línea
   inferior para quedar dentro de la ventana visible. */
.cal-hour-label-end {
  height: 0;
  border-top: none;
  transform: translateY(-0.95em);
}

.cal-day-col {
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--border);
  border-bottom: 1px dashed var(--border); /* v1.5.4 — cierra el eje en 18:00 */
  position: relative;
}
.cal-day-col:last-child { border-right: none; }
.cal-hour-col { border-bottom: 1px dashed var(--border); } /* cierre 18:00 */
.cal-hour-slot {
  height: 56px; /* v1.5.4 — debe coincidir con SLOT_HEIGHT en calendar.js */
  border-top: 1px dashed var(--border);
  position: relative;
  transition: background var(--dur-fast) var(--ease);
}
.cal-hour-slot:hover { background: var(--bg-sunken); }
.cal-hour-slot:first-child { border-top: none; }
/* v2.0 f8 — el doctor no agenda: el hueco libre no reacciona ni invita. */
.cal-hour-slot.is-static { cursor: default; }
.cal-hour-slot.is-static:hover { background: transparent; }

/* v2.0 f4 — la franja izquierda de tipo desaparece: el tipo va como
   badge de texto (val/tto) junto a la hora. El fondo sigue siendo el
   color del doctor. */
.cal-event-block {
  position: absolute;
  left: 4px;
  right: 4px;
  background: var(--info-bg);
  color: var(--info-700);
  border: 1px solid transparent;  /* el estado lo enciende (reservada/completada) */
  border-radius: var(--r-sm);
  padding: 3px 6px;
  font-size: var(--text-xs);
  font-weight: 500;
  overflow: hidden;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
  box-shadow: var(--shadow-xs);
}
.cal-event-block:hover {
  transform: translateX(1px);
  box-shadow: var(--shadow-sm);
  z-index: 5;
}
.cal-event-block.cal-event-treatment,
.cal-event-block[class*="treatment"] {
  background: var(--acc-soft);
  color: var(--acc-text);
}
[data-theme="dark"] .cal-event-block { color: var(--info-500); }
[data-theme="dark"] .cal-event-block.cal-event-treatment { color: var(--acc); }
.cal-event-block.canceled {
  background: var(--bg-sunken);
  color: var(--text-disabled);
  text-decoration: line-through;
}
/* v1.5.5 — bloqueo de franja: estilo "no disponible" tramado, neutro y sin
   acento. No representa a un paciente. */
.cal-event-block.type-block {
  background:
    repeating-linear-gradient(
      135deg,
      var(--bg-sunken) 0,
      var(--bg-sunken) 6px,
      color-mix(in oklch, var(--text-muted) 16%, var(--bg-sunken)) 6px,
      color-mix(in oklch, var(--text-muted) 16%, var(--bg-sunken)) 12px
    );
  color: var(--text-muted);
  box-shadow: none;
}
.cal-event-block.type-block .ev-title { font-style: italic; }
.cal-event-block.has-doctor { /* color override viene en línea de doctor */ }

/* v2.1 2.2 — bloqueo de SEDE completa (sin doctor asociado): banda que
   cruza los carriles de todos los doctores de la columna del día, en vez
   de vivir en el carril de uno solo. Mismo tramado "no disponible" que
   type-block; sólo cambia el ancho. z-index bajo: si alguna cita quedó
   agendada dentro del rango bloqueado, sigue siendo visible encima. */
.cal-event-block.is-sede-block {
  left: 0;
  right: 0;
  z-index: 1;
  pointer-events: auto;
}

/* v2.0 f9 — estados de la cita en el calendario. Son tres tratamientos
   distintos sobre el mismo bloque, y ninguno pierde el color del doctor:
     · reservada  → relleno atenuado + borde punteado. El espacio está
       sostenido pero nadie confirmó; el punteado es la convención de
       "provisional" y se lee incluso en blanco y negro.
     · completada → relleno pálido (lo calcula calendar.js con el color del
       doctor) + borde pleno de ese mismo color + check. Ya ocurrió, deja de
       competir con lo que viene, y sigue diciendo quién atendió.
     · cancelada  → neutra y tachada (regla anterior, sin cambios). */
.cal-event-block.is-reserved {
  /* v2.1 2.3 — antes bajaba la opacidad de TODO el bloque (relleno Y borde
     parejos); Javi pidió que el borde se lea al 100% y solo el relleno se
     atenúe. El relleno atenuado ahora lo pone `eventDoctorStyle()` inline
     (mismo mecanismo que "completada", con `color-mix(in oklab, …)`); acá
     solo queda el trazo punteado — sin `opacity` a nivel de bloque. */
  border-style: dashed;
  border-color: color-mix(in oklch, currentColor 55%, transparent);
  box-shadow: none;
}
/* Mezclas entre familias de tono distintas van en oklab: oklch interpola el
   tono por el arco corto y un azul mezclado con crema pasaría por el rosa. */
.cal-event-block.is-reserved:not(.has-doctor) {
  background: color-mix(in oklab, var(--info-bg) 55%, var(--surface));
}
.cal-event-block.is-done {
  box-shadow: none;
  border-color: color-mix(in oklch, currentColor 35%, transparent);
}
.cal-event-block.is-done:not(.has-doctor) {
  background: var(--bg-sunken);
  color: var(--text-muted);
  border-color: var(--border-strong);
}
.cal-event-block.is-done .ev-title { font-weight: 500; }

/* Marca de estado en la fila de la hora: monocroma (currentColor), de ancho
   fijo, legible sobre cualquier pastel de doctor y en los dos temas.

   v2.8 — es UNA pieza que crece con el estado, no cuatro señales sueltas:
   el mismo círculo se va llenando conforme la cita se vuelve más firme.
     · punteado y vacío  → reservada  (nada es firme todavía)
     · continuo y vacío  → agendada   (la franja ya es firme)
     · continuo con ✓    → el paciente confirmó que viene
     · verde con ✓ blanco → completada (ya ocurrió; es el único con color,
       porque es el único hecho que ya no puede cambiar)
   Antes completada y confirmada llevaban las dos un check y se confundían. */
.ev-mark {
  flex-shrink: 0;
  width: 12px; height: 12px;
  border-radius: var(--r-full);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 9px;
  font-weight: 700;
  line-height: 1;
  border: 1px solid color-mix(in oklch, currentColor 55%, transparent);
}
.ev-mark-done {
  background: var(--cal-done);
  border-color: var(--cal-done);
  color: var(--n-0);
}
.ev-mark-sched { /* el círculo base ya es esto: continuo y vacío */ }
.ev-mark-res   { border-style: dashed; }
.cal-week .ev-mark { width: 10px; height: 10px; font-size: 8px; }

/* Cuadritos de la leyenda para los estados de cita. */
.legend-box {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px; height: 11px;
  border-radius: var(--r-xs);
  border: 1px solid var(--border-strong);
  background: var(--bg-sunken);
  font-size: 8px;
  font-weight: 700;
  color: var(--text-muted);
  line-height: 1;
}
/* v2.8 — los cuadritos de estado pasan a círculos: en la tarjeta la marca es
   un círculo, y una leyenda que dibuja otra cosa explica otra cosa. */
.legend-box-res,
.legend-box-sched,
.legend-box-confirmed,
.legend-box-done {
  width: 12px; height: 12px;
  border-radius: var(--r-full);
  background: transparent;
  border-color: var(--text-muted);
}
.legend-box-res  { border-style: dashed; }
.legend-box-done {
  background: var(--cal-done);
  border-color: var(--cal-done);
  color: var(--n-0);
}

/* v2.0 f8 — cita de otro doctor en la vista del doctor: ocupa la franja
   real, conserva el color de su doctor (hay que poder distinguir de quién
   es) y muestra el nombre del paciente, pero baja de contraste y no abre
   nada. Lo que la separa de una cita propia es que no reacciona al hover
   ni al clic: es ocupación de la sede, no un paciente al que se entra. */
.cal-event-block.is-foreign {
  opacity: 0.62;
  cursor: default;
  box-shadow: none;
}
.cal-event-block.is-foreign:hover { transform: none; box-shadow: none; }

/* v1.5.5 — modal de cita en modo "bloqueo de franja": se ocultan el bloque de
   paciente, el ingreso y el estado (un bloqueo no es de un paciente ni tiene
   ingreso). El "Motivo" pasa a ser el motivo del bloqueo. */
#apt-modal[data-apt-mode="block"] .apt-patient-field,
#apt-modal[data-apt-mode="block"] #apt-new-patient-fields,
#apt-modal[data-apt-mode="block"] .apt-revenue-field,
#apt-modal[data-apt-mode="block"] .apt-status-field { display: none; }
/* v1.5.5 — contenido por niveles del bloque del calendario. Todas las líneas
   en una sola fila con elipsis y line-height apretado para que entren hasta
   cuatro (hora · nombre · título · tratamiento) en una cita de 1 h.
   Jerarquía: hora (pequeña/dim) → nombre (semibold) → título (secundario) →
   tratamiento·ingreso (secundario). */
.ev-time, .ev-title, .ev-subtitle {
  display: block;
  line-height: 1.18;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ev-time { font-size: var(--text-2xs); opacity: 0.72; font-variant-numeric: tabular-nums; }
.ev-title { font-weight: 600; }
.ev-subtitle { font-size: var(--text-2xs); opacity: 0.85; }
.ev-time-inline { flex-shrink: 0; opacity: 0.7; font-weight: 600; font-size: var(--text-2xs); font-variant-numeric: tabular-nums; }

/* v2.0 f4.1 — fila superior de la card: hora + badge (color de sede, texto
   val/tto). El nivel compacto (.ev-row) es una sola línea flex donde el
   nombre cede con ellipsis: nada se solapa nunca. */
.ev-top {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  line-height: 1.18;
}
.ev-top .ev-time { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-row {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  line-height: 1.15;
}
.ev-row .ev-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}
.cal-event-block.ev-sm { padding: 2px 5px; display: flex; align-items: center; }
.cal-event-block.ev-sm .ev-row { width: 100%; }
/* Carril compartido (2+ doctores): menos padding y tipografía un punto
   más chica para que la info primaria siga entrando. */
.cal-event-block.narrow { padding: 3px 4px; }
.cal-event-block.narrow .ev-title { font-size: var(--text-2xs); }
.ev-badge {
  flex-shrink: 0;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  line-height: 1;
  padding: 2px 4px;
  border-radius: var(--r-sm);
  border: 1px solid color-mix(in oklch, currentColor 45%, transparent);
}
.legend-badge { color: var(--text-muted); font-size: 9px; }

/* Tablet: columnas de semana angostas — compactar la card entera */
@media (max-width: 1280px) {
  .cal-week .cal-event-block { padding: 2px 4px; font-size: var(--text-2xs); }
  .cal-week .cal-event-block.narrow { padding: 2px 3px; }
  .cal-week .ev-badge { font-size: 7px; padding: 2px 3px; }
  .cal-week .ev-time, .cal-week .ev-time-inline { font-size: 9px; }
}

/* v2.0 f4 — popover táctil de detalle de cita (tablet/móvil, sin hover) */
.rlx-cal-popover {
  position: fixed;
  z-index: 9990;
  background: var(--n-900);
  color: var(--n-0);
  font-size: var(--text-xs);
  line-height: 1.5;
  padding: 10px 12px;
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md);
  font-family: var(--font-sans);
}
.rlx-cal-popover[hidden] { display: none; }
.cal-popover-text { white-space: pre-line; }
.rlx-cal-popover .cal-popover-open {
  margin-top: var(--space-2);
  width: 100%;
  font-size: var(--text-xs);
  padding: 5px 10px;
}
[data-theme="dark"] .rlx-cal-popover {
  background: var(--n-200);
  color: var(--n-900);
}

/* ═══════════════════════════════════════════════════════════════════
   VISTA: TABLA DE PRECIOS
   ═══════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════
   Tabla de precios — v1.1 · layout en 3 columnas
   sidebar (categorías) | main (tabs + lista) | detail (item seleccionado)
   ═══════════════════════════════════════════════════════════════════ */
.prices-layout {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr) 340px;
  gap: var(--space-5);
  align-items: start;
  position: relative;
  min-height: 60vh;
}

/* ── Sidebar (cuadro amarillo del wireframe) ── */
.prices-sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  position: sticky;
  top: calc(var(--header-h, 60px) + var(--nav-h, 48px) + var(--space-4));
}
.prices-sidebar-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-dim);
  padding: 0 var(--space-2) var(--space-1);
}
.prices-cat-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.prices-cat-row {
  display: flex;
  align-items: stretch;
  gap: 2px;
  position: relative;
}
.prices-cat-row .prices-cat-item { flex: 1; min-width: 0; }
.prices-cat-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  color: var(--text-muted);
  font: inherit;
  font-size: var(--text-base);
  text-align: left;
  cursor: pointer;
  position: relative;
  transition:
    background var(--dur-fast) var(--ease),
    color var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease);
}
.prices-cat-item:hover {
  background: var(--bg-sunken);
  color: var(--text-strong);
}
.prices-cat-item.is-active {
  background: var(--surface);
  color: var(--text-strong);
  border-color: var(--border);
  box-shadow: var(--shadow-sm);
}
.prices-cat-item.is-active::before {
  content: "";
  position: absolute;
  left: -1px; top: 8px; bottom: 8px;
  width: 3px;
  background: var(--acc);
  border-radius: 0 var(--r-xs) var(--r-xs) 0;
  animation: prices-cat-bar var(--dur-base) var(--ease);
}
@keyframes prices-cat-bar {
  from { transform: scaleY(0.2); opacity: 0; }
  to   { transform: scaleY(1); opacity: 1; }
}
.prices-cat-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.prices-cat-tally {
  font-size: var(--text-2xs);
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
  background: var(--bg-sunken);
  padding: 1px 6px;
  border-radius: var(--r-full);
  min-width: 18px;
  text-align: center;
}
.prices-cat-item.is-active .prices-cat-tally {
  background: var(--acc-soft);
  color: var(--acc-text);
}
[data-theme="dark"] .prices-cat-item.is-active .prices-cat-tally { color: var(--acc); }
/* Botón × para borrar categoría custom. Hidden hasta hover/focus en desktop,
   siempre visible (con menos prominencia) en móvil para que sea descubrible. */
.prices-cat-del {
  flex-shrink: 0;
  width: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  color: var(--text-dim);
  font-size: var(--text-md);
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.prices-cat-row:hover .prices-cat-del,
.prices-cat-del:focus-visible {
  opacity: 1;
}
.prices-cat-del:hover {
  color: var(--err-700, oklch(0.5 0.15 25));
  background: var(--bg-sunken);
  border-color: var(--border);
}
.prices-cat-add {
  margin-top: var(--space-2);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: var(--space-2) var(--space-3);
  background: transparent;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
  color: var(--text-muted);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.prices-cat-add:hover {
  color: var(--text-strong);
  border-color: var(--acc);
  background: var(--acc-soft);
}
.prices-cat-add span { font-weight: 600; }

/* ── Main (cuadros azul + verde del wireframe) ── */
.prices-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.prices-main-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--space-3);
}
.prices-main-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}
.prices-main-title h3 {
  font-size: var(--text-2xl);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--text-strong);
  margin: 0;
}
.prices-cat-meta {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.prices-subtabs {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-wrap: wrap;
  margin: 0 calc(var(--space-1) * -1);
}
.prices-subtab {
  position: relative;
  padding: var(--space-2) var(--space-3);
  background: transparent;
  border: none;
  border-radius: var(--r-sm);
  color: var(--text-muted);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.prices-subtab::after {
  content: "";
  position: absolute;
  left: var(--space-3); right: var(--space-3);
  bottom: -1px;
  height: 2px;
  background: var(--acc);
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--dur-base) var(--ease);
}
.prices-subtab:hover { color: var(--text-strong); background: var(--bg-sunken); }
.prices-subtab.is-active {
  color: var(--acc-text);
}
[data-theme="dark"] .prices-subtab.is-active { color: var(--acc); }
.prices-subtab.is-active::after { transform: scaleX(1); }
.prices-subtab-add {
  margin-left: auto;
  color: var(--text-dim);
  font-weight: 600;
  font-size: var(--text-md);
  padding: var(--space-2);
  min-width: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.prices-subtab-add::after { display: none; }
.prices-subtab-add:hover { color: var(--acc); }
/* Wrap de subcategorías custom (con su botón ×) para que ambos elementos
   se comporten como un solo bloque dentro del flex/wrap de tabs. */
.prices-subtab-wrap {
  display: inline-flex;
  align-items: center;
  gap: 0;
}
.prices-subtab-wrap .prices-subtab { padding-right: var(--space-2); }
.prices-subtab-del {
  flex-shrink: 0;
  width: 22px; height: 22px;
  margin-right: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  color: var(--text-dim);
  font-size: var(--text-sm);
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.prices-subtab-wrap:hover .prices-subtab-del,
.prices-subtab-del:focus-visible {
  opacity: 1;
}
.prices-subtab-del:hover {
  color: var(--err-700);
  background: var(--bg-sunken);
  border-color: var(--border);
}

/* En dispositivos sin hover (touch) mostramos los botones de eliminar
   discretamente para que sean descubribles sin depender del hover. */
@media (hover: none) {
  .prices-cat-del,
  .prices-subtab-del { opacity: 0.55; }
}

/* ── Lista de items (cuadro verde) ── */
.prices-list {
  display: flex;
  flex-direction: column;
  animation: prices-list-in var(--dur-base) var(--ease);
}
@keyframes prices-list-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.prices-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  padding: var(--space-3) var(--space-3);
  background: transparent;
  border: 1px solid transparent;
  border-bottom-color: var(--border);
  border-radius: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  position: relative;
  transition:
    background var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease),
    box-shadow var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease);
}
.prices-row:hover {
  background: var(--bg-sunken);
}
.prices-row.is-selected {
  background: var(--surface);
  border-color: var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
}
.prices-row.is-selected::before {
  content: "";
  position: absolute;
  left: 0; top: 8px; bottom: 8px;
  width: 3px;
  background: var(--acc);
  border-radius: 0 var(--r-xs) var(--r-xs) 0;
  animation: prices-cat-bar var(--dur-base) var(--ease);
}
.prices-row.is-inactive { opacity: 0.55; }
.prices-row-main {
  min-width: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.prices-row-name {
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--text-strong);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  line-height: var(--leading-snug);
}
.prices-row-sub {
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: var(--leading-snug);
}
.prices-row-price {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--acc-text);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  background: var(--acc-soft);
  padding: 3px var(--space-2);
  border-radius: var(--r-sm);
  border: 1px solid color-mix(in oklch, var(--acc) 22%, transparent);
  white-space: nowrap;
  flex-shrink: 0;
}
[data-theme="dark"] .prices-row-price { color: var(--acc); }
/* Producto de rango: el precio es un intervalo, así que pesa menos y se
   distingue del precio cerrado (que es un compromiso). */
.prices-row-price.is-range {
  font-size: var(--text-sm);
  font-weight: 500;
  background: transparent;
  border-style: dashed;
}
.prices-detail-range-help {
  margin-top: calc(-1 * var(--space-2));
  font-size: var(--text-xs);
  color: var(--text-muted);
  line-height: var(--leading-normal);
}
/* Bloque de precio del modal: fijo o rango, nunca los dos. */
.price-range-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
}
.price-range-block > .form-row { margin: 0; }
.prices-row-add {
  margin-top: var(--space-3);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: var(--space-3);
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: var(--r-md);
  color: var(--text-dim);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.prices-row-add:hover {
  color: var(--text-strong);
  border-color: var(--acc);
  background: var(--acc-soft);
}
.prices-row-add span { font-weight: 600; }

.prices-empty {
  padding: var(--space-6) var(--space-4);
  text-align: center;
  color: var(--text-muted);
  font-size: var(--text-sm);
  background: var(--surface);
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-lg);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}
.prices-empty strong { color: var(--text-strong); font-weight: 600; }

/* ── Panel de detalle (cuadro rojo) ── */
.prices-detail {
  position: sticky;
  top: calc(var(--header-h, 60px) + var(--nav-h, 48px) + var(--space-4));
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--space-4);
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  animation: prices-detail-in var(--dur-base) var(--ease);
  min-height: 280px;
}
@keyframes prices-detail-in {
  from { opacity: 0; transform: translateX(6px); }
  to   { opacity: 1; transform: translateX(0); }
}
.prices-detail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.prices-detail-crumbs {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.prices-detail-crumbs .sep { color: var(--text-dim); }
.prices-detail-close {
  /* Sólo se muestra en breakpoint compacto */
  display: none;
}
.prices-detail-name {
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--text-strong);
  margin: 0;
  line-height: var(--leading-snug);
}
.prices-detail-subtitle {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin: 0;
  line-height: var(--leading-snug);
}
.prices-detail-price {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3);
  background: var(--acc-soft);
  border: 1px solid color-mix(in oklch, var(--acc) 22%, transparent);
  border-radius: var(--r-md);
}
.prices-detail-price-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--acc-text);
}
[data-theme="dark"] .prices-detail-price-label { color: var(--acc); }
.prices-detail-price-value {
  font-size: var(--text-xl);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.015em;
  color: var(--acc-text);
}
[data-theme="dark"] .prices-detail-price-value { color: var(--acc); }
.prices-detail-section {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.prices-detail-section-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-dim);
}
.prices-detail-desc {
  font-size: var(--text-sm);
  color: var(--text);
  line-height: var(--leading-base);
  margin: 0;
  white-space: pre-wrap;
}
.prices-detail-desc.is-muted { color: var(--text-dim); font-style: italic; }
.prices-detail-meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  font-size: var(--text-2xs);
  color: var(--text-dim);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border);
}
.prices-detail-updated {
  letter-spacing: 0;
  text-transform: none;
}
.prices-detail-actions {
  display: flex;
  gap: var(--space-2);
  margin-top: auto;
  padding-top: var(--space-3);
}
.prices-detail-actions .btn { flex: 1; }
.prices-detail-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-3);
  text-align: center;
  color: var(--text-dim);
  font-size: var(--text-sm);
  height: 100%;
}
.prices-detail-empty p { margin: 0; }
.prices-detail-empty-icon {
  width: 40px; height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--bg-sunken);
  color: var(--text-dim);
}
.prices-detail-empty-icon svg { width: 20px; height: 20px; }

.prices-inactive-tag {
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
  background: var(--bg-sunken);
  padding: 1px 6px;
  border-radius: var(--r-full);
  border: 1px solid var(--border);
}
.prices-active-tag {
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--acc-text);
  background: var(--acc-soft);
  padding: 1px 6px;
  border-radius: var(--r-full);
  border: 1px solid color-mix(in oklch, var(--acc) 22%, transparent);
}
[data-theme="dark"] .prices-active-tag { color: var(--acc); }

/* Backdrop del panel detalle — sólo se activa en breakpoint compacto */
.prices-detail-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: oklch(0.18 0.01 40 / 0.45);
  border: none;
  padding: 0;
  cursor: pointer;
  z-index: 49;
}

/* ═══════════════════════════════════════════════════════════════════
   VISTA: WHATSAPP — bandeja (v2.9 f1 · fase 1, sólo lectura)
   Dos columnas: lista de conversaciones | hilo. Mismo mecanismo de
   colapso a drawer que Precios (detail-open + backdrop), con una sola
   columna que se desliza en vez de tres.
   ═══════════════════════════════════════════════════════════════════ */
.wa-layout {
  display: grid;
  grid-template-columns: minmax(260px, 320px) minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
  position: relative;
  height: calc(100vh - var(--header-h, 60px) - var(--nav-h, 48px) - var(--space-4) * 2);
  min-height: 420px;
}

.wa-list-pane {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.wa-list {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.wa-conv-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
  padding: var(--space-3);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  text-align: left;
  font: inherit;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.wa-conv-row:hover { background: var(--bg-sunken); }
.wa-conv-row.is-active { background: var(--acc-soft); }
.wa-conv-row.has-unread .wa-conv-name { font-weight: 700; color: var(--text-strong); }
.wa-conv-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}
.wa-conv-name {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wa-conv-when {
  flex-shrink: 0;
  font-size: var(--text-2xs);
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.wa-conv-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.wa-conv-preview {
  font-size: var(--text-xs);
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}
.wa-conv-preview-empty { color: var(--text-dim); font-style: italic; }
.wa-conv-badge {
  flex-shrink: 0;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9px;
  background: var(--acc);
  color: var(--text-on-acc);
  font-size: 10px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.wa-conv-meta {
  display: flex;
  align-items: center;
  gap: 6px;
}
.wa-mode-tag {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  padding: 1px 6px;
  border-radius: var(--r-full);
  border: 1px solid var(--border);
  color: var(--text-muted);
  background: var(--bg-sunken);
}
.wa-mode-tag.is-human {
  color: var(--acc-text);
  background: var(--acc-soft);
  border-color: color-mix(in oklch, var(--acc) 22%, transparent);
}
[data-theme="dark"] .wa-mode-tag.is-human { color: var(--acc); }
.wa-review-tag {
  font-size: var(--text-2xs);
  font-weight: 600;
  padding: 1px 6px;
  border-radius: var(--r-full);
  color: var(--warn-700);
  background: var(--warn-bg);
  border: 1px solid color-mix(in oklch, var(--warn-500) 30%, transparent);
}

/* ── Hilo ── */
.wa-thread-pane {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.wa-thread {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}
.wa-thread-header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
}
.wa-thread-back {
  display: none; /* sólo en el breakpoint compacto */
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text-muted);
  cursor: pointer;
  font-size: var(--text-md);
  line-height: 1;
}
.wa-thread-head-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.wa-thread-name {
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--text-strong);
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wa-thread-patient {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.wa-thread-patient-name {
  align-self: flex-start;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--acc-text);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
[data-theme="dark"] .wa-thread-patient-name { color: var(--acc); }
.wa-thread-patient-empty {
  font-size: var(--text-sm);
  color: var(--text-dim);
  font-style: italic;
}
.wa-thread-patient-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-2xs);
  color: var(--text-muted);
}
.wa-thread-warn {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--warn-700);
  background: var(--warn-bg);
  border: 1px solid color-mix(in oklch, var(--warn-500) 30%, transparent);
  border-radius: var(--r-sm);
  padding: 3px 8px;
  display: inline-block;
}

.wa-thread-mode {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--border);
}
.wa-thread-mode-label {
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  font-size: var(--text-2xs);
  padding: 2px 8px;
  border-radius: var(--r-full);
  color: var(--text-muted);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
}
.wa-thread-mode.is-human .wa-thread-mode-label {
  color: var(--acc-text);
  background: var(--acc-soft);
  border-color: color-mix(in oklch, var(--acc) 22%, transparent);
}
[data-theme="dark"] .wa-thread-mode.is-human .wa-thread-mode-label { color: var(--acc); }
/* v2.10 — quién tiene el control (punto 11, multi-admin) */
.wa-thread-mode-controller {
  font-size: var(--text-xs);
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Tomar conversación / Volver a IA — pegado al borde derecho de la
   franja de modo, nunca compite en jerarquía con los botones grandes
   del composer que van debajo. */
.wa-mode-action {
  margin-left: auto;
  height: 28px;
  padding: 0 var(--space-3);
  font-size: var(--text-xs);
  flex-shrink: 0;
}

/* v2.10 — composer de texto (sólo HUMAN_ACTIVE) */
.wa-composer {
  display: flex;
  align-items: flex-end;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.wa-composer-input {
  flex: 1;
  min-height: 38px;
  max-height: 140px;
  padding: var(--space-2) var(--space-3);
  font: inherit;
  font-size: var(--text-sm);
  line-height: var(--leading-base);
  color: var(--text);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  resize: vertical;
}
.wa-composer-input:focus-visible {
  outline: none;
  border-color: var(--acc);
  box-shadow: 0 0 0 2px color-mix(in oklch, var(--acc) 22%, transparent);
}
.wa-composer-input:disabled { opacity: 0.6; cursor: not-allowed; }
.wa-composer-send { flex-shrink: 0; height: 38px; }
.wa-composer-error {
  margin: 0 var(--space-4) var(--space-3);
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-xs);
  color: var(--err-700);
  background: var(--warn-bg);
  border: 1px solid color-mix(in oklch, var(--err) 30%, transparent);
  border-radius: var(--r-sm);
}

.wa-thread-messages {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
}
.wa-msg {
  max-width: 72%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--r-lg);
  font-size: var(--text-sm);
  line-height: var(--leading-base);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.wa-msg.is-patient {
  align-self: flex-start;
  background: var(--bg-sunken);
  color: var(--text);
  border-bottom-left-radius: var(--r-xs);
}
.wa-msg.is-ai {
  align-self: flex-end;
  background: var(--acc-soft);
  color: var(--acc-text);
  border-bottom-right-radius: var(--r-xs);
}
[data-theme="dark"] .wa-msg.is-ai { color: var(--text); }
.wa-msg.is-human {
  align-self: flex-end;
  background: var(--acc);
  color: var(--text-on-acc);
  border-bottom-right-radius: var(--r-xs);
}
.wa-msg-tag {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  opacity: 0.7;
}
.wa-msg-text { white-space: pre-wrap; word-break: break-word; }
.wa-msg-audio-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  opacity: 0.8;
}
.wa-msg-audio-placeholder { font-style: italic; opacity: 0.8; }
.wa-msg-time {
  align-self: flex-end;
  font-size: 10px;
  opacity: 0.6;
  font-variant-numeric: tabular-nums;
}

.wa-empty {
  padding: var(--space-5) var(--space-4);
  text-align: center;
  color: var(--text-dim);
  font-size: var(--text-sm);
}
.wa-empty-err { color: var(--err-700); }
.wa-thread-empty { height: 100%; display: flex; align-items: center; justify-content: center; }

.wa-thread-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: oklch(0.18 0.01 40 / 0.45);
  border: none;
  padding: 0;
  cursor: pointer;
  z-index: 49;
}

/* ── Field help reutilizable (modales del módulo) ── */
.field-help {
  display: block;
  margin-top: 4px;
  font-size: var(--text-2xs);
  color: var(--text-dim);
  line-height: var(--leading-snug);
}
.modal-narrow { width: min(420px, 100%); }

/* ═══════════════════════════════════════════════════════════════════
   VISTA: DOCTORES
   ═══════════════════════════════════════════════════════════════════ */

.doctors-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--space-4);
}
.doctor-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-xs);
  display: flex;
  flex-direction: column;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.doctor-card:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}
.doctor-card.inactive { opacity: 0.65; }
.doctor-card-foot {
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  text-align: center;
  border-top: 1px solid var(--border);
}

.doctor-card-head {
  padding: var(--space-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* JS inyecta background:var(--c.bg);color:var(--c.text) — lo respetamos */
}
.doctor-card-title {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}
.doctor-avatar {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-full);
  font-size: var(--text-md);
  font-weight: 600;
  flex-shrink: 0;
}
.doctor-name { font-size: var(--text-md); font-weight: 600; line-height: 1.2; }
.doctor-specialty { font-size: var(--text-xs); opacity: 0.85; margin-top: 2px; }
.doctor-edit-btn {
  width: 30px; height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: oklch(1 0 0 / 0.15);
  border: 1px solid oklch(1 0 0 / 0.18);
  border-radius: var(--r-sm);
  cursor: pointer;
  flex-shrink: 0;
  transition: background var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.doctor-edit-btn:hover { background: oklch(1 0 0 / 0.28); }
.doctor-edit-btn:active { transform: translateY(0.5px); }

.doctor-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  padding: var(--space-3) var(--space-4);
  gap: var(--space-2);
  border-bottom: 1px solid var(--border);
}
.doctor-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.doctor-stat label {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.doctor-stat span {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}

.doctor-section {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
}
.doctor-section:last-child { border-bottom: none; }
.doctor-section-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-2);
}
.doctor-section-head h4 {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}

.doc-apt-row, .doc-patient-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-2);
  border-radius: var(--r-sm);
  cursor: pointer;
  font-size: var(--text-sm);
  transition: background var(--dur-fast) var(--ease);
}
.doc-apt-row:hover, .doc-patient-row:hover { background: var(--bg-sunken); }
.doc-apt-date { color: var(--text-muted); font-variant-numeric: tabular-nums; min-width: 90px; font-size: var(--text-xs); }
.doc-apt-patient, .doc-patient-name { color: var(--text); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-patient-meta { font-size: var(--text-xs); }
.doc-apt-type {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  padding: 2px var(--space-2);
  border-radius: var(--r-full);
  flex-shrink: 0;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  line-height: 1.4;
}
.doc-apt-type.type-treatment {
  background: var(--acc-soft);
  color: var(--acc-text);
  border-color: color-mix(in oklch, var(--acc) 22%, transparent);
}
.doc-apt-type.type-valuation {
  background: var(--info-bg);
  color: var(--info-700);
  border-color: color-mix(in oklch, var(--info) 22%, transparent);
}
.doc-apt-type.type-followup {
  background: var(--ok-bg);
  color: var(--ok-700);
  border-color: color-mix(in oklch, var(--ok) 22%, transparent);
}
[data-theme="dark"] .doc-apt-type.type-valuation { color: var(--info-500); }
[data-theme="dark"] .doc-apt-type.type-treatment { color: var(--acc); }
[data-theme="dark"] .doc-apt-type.type-followup  { color: var(--ok-500); }

.doc-empty-row {
  padding: var(--space-3);
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-align: center;
  font-style: italic;
}

/* Ficha modal: form a la izquierda + detalle a la derecha (modo edit)
   En modo view sólo se muestra el detalle, ocupando todo el ancho. */
.doctor-modal-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-5);
  padding: var(--space-5);
}
#doctor-modal[data-mode="view"] .doctor-modal-body,
#doctor-modal[data-mode="edit"] .doctor-modal-body {
  grid-template-columns: minmax(0, 1fr);
}
#doctor-modal[data-mode="view"] .doctor-form-pane { display: none; }
#doctor-modal[data-mode="edit"] .doctor-detail-pane { display: none; }
#doctor-modal[data-mode="view"] .doctor-detail-stats {
  grid-template-columns: repeat(4, 1fr);
}
.doctor-form-pane,
.doctor-detail-pane {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}
/* v2.0 f9.5 — el form son bloques: respiración entre ellos, densidad
   adentro (la doctrina de Marginalia aplicada al formulario más largo
   de la plataforma). */
.doctor-form-pane { gap: var(--space-4); }
.doctor-detail-pane {
  background: var(--bg-sunken);
  border-radius: var(--r-md);
  padding: var(--space-4);
  overflow-y: auto;
  max-height: 70vh;
}
.doctor-detail-empty {
  padding: var(--space-5) 0;
  text-align: center;
  font-size: var(--text-sm);
}
.doctor-detail-head {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--r-md);
  margin-bottom: var(--space-3);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.doctor-detail-identity { min-width: 0; }
.doctor-detail-name {
  font-size: var(--text-lg);
  font-weight: 600;
  line-height: 1.2;
}
.doctor-detail-specialty {
  font-size: var(--text-xs);
  opacity: 0.85;
  margin-top: 2px;
}
.doctor-detail-edit {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 30px;
  padding: 0 var(--space-3);
  background: oklch(1 0 0 / 0.18);
  border: 1px solid oklch(1 0 0 / 0.22);
  border-radius: var(--r-sm);
  cursor: pointer;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  flex-shrink: 0;
  transition: background var(--dur-fast) var(--ease);
}
.doctor-detail-edit:hover { background: oklch(1 0 0 / 0.30); }
.doctor-detail-stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  padding: var(--space-3);
  background: var(--surface);
  border-radius: var(--r-md);
  border: 1px solid var(--border);
}
.doctor-detail-section { margin-bottom: var(--space-4); }
.doctor-detail-section:last-child { margin-bottom: 0; }
.doctor-detail-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-2);
}
.doctor-detail-section-head h5 {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}

/* v2.1 — panel de actividad del doctor (admin-only). Reusa
   .doctor-detail-stats para los KPIs y .view-switcher para el rango de
   la bitácora: mismos componentes que ya existen en el resto de la app,
   nada nuevo que aprender visualmente. */
.doc-activity-section .view-switcher { flex-shrink: 0; }
.doc-activity-kpis { grid-template-columns: repeat(3, 1fr); margin-bottom: var(--space-3); }
.doc-activity-lastlogin {
  font-size: var(--text-xs);
  margin: 0 0 var(--space-3);
}
.doc-activity-timeline {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 280px;
  overflow-y: auto;
}
.doc-activity-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--r-sm);
  font-size: var(--text-xs);
}
.doc-activity-row:nth-child(odd) { background: var(--surface); }
.doc-activity-time {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
  min-width: 76px;
}
.doc-activity-action { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 768px) {
  .doctor-detail-section-head:has(.view-switcher) { flex-wrap: wrap; gap: var(--space-2); }
}

/* En móvil: una sola columna */
@media (max-width: 768px) {
  .doctor-modal-body { grid-template-columns: 1fr; gap: var(--space-4); padding: var(--space-4); }
  .doctor-detail-pane { max-height: none; }
}

/* Color picker (doctores) */
.color-picker {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-top: var(--space-1);
}
.color-swatch {
  width: 32px;
  height: 32px;
  border-radius: var(--r-full);
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
  padding: 0;
}
.color-swatch:hover { transform: scale(1.08); }
.color-swatch.selected {
  border-color: var(--text-strong);
  box-shadow: 0 0 0 2px var(--surface);
}

/* ═══════════════════════════════════════════════════════════════════
   VISTA: TRATAMIENTOS
   ═══════════════════════════════════════════════════════════════════ */

.tx-totals {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-xs);
}
.tx-total-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.tx-total-stat label {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.tx-total-stat span {
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.tx-total-stat span.paid { color: var(--ok-700); }
.tx-total-stat span.balance { color: var(--acc-text); }
[data-theme="dark"] .tx-total-stat span.paid { color: var(--ok-500); }

/* ═══════════════════════════════════════════════════════════════════
   VISTA: COTIZACIONES (v2.0 f6 — presupuestos globales)
   ═══════════════════════════════════════════════════════════════════ */
.quotes-container { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-4); }
.quote-card {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-xs);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.quote-card:hover { background: var(--bg-elev); }
.quote-status-SENT     { border-left-color: var(--info); }
.quote-status-ACCEPTED { border-left-color: var(--ok); }
.quote-status-REJECTED,
.quote-status-EXPIRED  { border-left-color: color-mix(in oklch, var(--text-muted) 40%, transparent); }
.quote-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.quote-patient { font-size: var(--text-sm); font-weight: 600; color: var(--text-strong); }
.quote-name { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; font-size: var(--text-sm); color: var(--text); }
.quote-dates { font-size: var(--text-2xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.quote-total { font-size: var(--text-base); font-weight: 600; color: var(--text-strong); font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (max-width: 640px) {
  .quote-card { grid-template-columns: 1fr auto; }
  .quote-card .row-action { grid-column: 1 / -1; justify-self: start; }
}

/* ═══════════════════════════════════════════════════════════════════
   VISTA: INGRESOS (v2.0 f6 — subsección propia)
   ═══════════════════════════════════════════════════════════════════ */
.income-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-xs);
}
.income-kpi { display: flex; flex-direction: column; gap: 2px; }
.income-kpi label { font-size: var(--text-2xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-muted); }
.income-kpi .value { font-size: var(--text-xl); font-weight: 600; color: var(--text-strong); font-variant-numeric: tabular-nums; line-height: 1.1; }

.income-methods { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-3); }
.income-methods:empty { display: none; margin: 0; }
.income-methods-title { font-size: var(--text-2xs); letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--text-muted); font-weight: 600; }
.income-method {
  display: grid;
  grid-template-columns: 120px 1fr 110px 44px;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-sm);
}
.im-label { color: var(--text); }
.im-bar { height: 8px; background: var(--bg-sunken); border-radius: var(--r-full); overflow: hidden; }
.im-bar-fill { display: block; height: 100%; background: var(--acc); border-radius: var(--r-full); }
.im-amount { text-align: right; color: var(--text-strong); font-variant-numeric: tabular-nums; }
.im-pct { text-align: right; color: var(--text-muted); font-variant-numeric: tabular-nums; }
/* Lo que no se pudo atribuir a un doctor o una sede se muestra aparte,
   apagado: es un pendiente de datos, no una categoría real. */
.income-method.is-unassigned .im-label { color: var(--text-dim); font-style: italic; }
.income-method.is-unassigned .im-bar-fill { background: var(--text-dim); }

.income-body {
  margin-top: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-xs);
  overflow: hidden;
}
.income-body .income-weeks { margin-top: 0; border-top: 0; padding: var(--space-1) var(--space-3); }
.income-body .empty-state { border: 0; }
.income-body .stats-footnote { padding: var(--space-3) var(--space-4); margin: 0; border-top: 1px solid var(--border); }
@media (max-width: 640px) {
  .income-method { grid-template-columns: 92px 1fr 52px; }
  .income-method .im-amount { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   VISTA: PACIENTES → RECORDATORIOS (v2.0 f7)
   ═══════════════════════════════════════════════════════════════════ */
.reminders-container { display: flex; flex-direction: column; gap: var(--space-4); margin-top: var(--space-4); }
.reminder-group { display: flex; flex-direction: column; gap: var(--space-2); }
.reminder-group-head {
  font-size: var(--text-2xs); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--text-muted); font-weight: 600;
  display: flex; align-items: center; gap: var(--space-2);
}
.reminder-group-head.is-overdue { color: var(--err-700); }
.reminder-group-head.is-today { color: var(--acc-text); }
[data-theme="dark"] .reminder-group-head.is-overdue { color: var(--err-500); }
.reminder-group-count {
  font-size: var(--text-2xs); font-weight: 600;
  background: var(--bg-sunken); color: var(--text-muted);
  border-radius: var(--r-full); padding: 0 6px;
}
.reminder-card {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-xs);
}
.reminder-card.is-done { opacity: 0.7; }
.reminder-main { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.reminder-top { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.reminder-patient { font-size: var(--text-sm); font-weight: 600; color: var(--text-strong); }
.reminder-kind {
  font-size: var(--text-2xs); font-weight: 600;
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  padding: 1px var(--space-2); border-radius: var(--r-full);
  background: var(--bg-sunken); color: var(--text-muted); border: 1px solid var(--border);
}
.reminder-kind.kind-APPOINTMENT { color: var(--info); border-color: color-mix(in oklch, var(--info) 30%, transparent); }
.reminder-kind.kind-FOLLOWUP { color: var(--acc-text); border-color: color-mix(in oklch, var(--acc) 25%, transparent); }
.reminder-note { font-size: var(--text-sm); color: var(--text-muted); overflow-wrap: anywhere; }
.reminder-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; white-space: nowrap; }
.reminder-date { font-size: var(--text-sm); color: var(--text); font-variant-numeric: tabular-nums; }
.reminder-rel { font-size: var(--text-2xs); color: var(--text-muted); }
.reminder-rel.is-overdue { color: var(--err-700); font-weight: 600; }
[data-theme="dark"] .reminder-rel.is-overdue { color: var(--err-500); }
.reminder-actions { display: flex; gap: var(--space-1); flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 720px) {
  .reminder-card { grid-template-columns: 1fr auto; }
  .reminder-actions { grid-column: 1 / -1; justify-content: flex-start; }
}

/* Fila rápida de fechas en el modal de recordatorio (reusa .fv-quick). */
.reminder-quick { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: calc(-1 * var(--space-1)) 0 var(--space-1); }
.reminder-quick-hint {
  font-size: var(--text-2xs); letter-spacing: var(--tracking-wide);
  text-transform: uppercase; color: var(--text-muted); margin-right: 2px;
}

/* Inicio — marca de recordatorio vencido. */
.home-row-time.is-overdue { color: var(--err-700); font-weight: 600; }
[data-theme="dark"] .home-row-time.is-overdue { color: var(--err-500); }

/* ═══════════════════════════════════════════════════════════════════
   VISTA: PACIENTES → SEGUIMIENTO + REFERIDOS (v2.0 f7)
   ═══════════════════════════════════════════════════════════════════ */
.subsection-kpi { font-size: var(--text-sm); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.subsection-kpi strong { color: var(--text-strong); font-weight: 600; }
.filter-pills-sm .pill { padding: 2px var(--space-2); font-size: var(--text-2xs); }

/* Seguimiento */
.followup-container { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-4); }
.followup-card {
  display: grid; grid-template-columns: 1fr auto auto; align-items: center;
  gap: var(--space-4); padding: var(--space-3) var(--space-4);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-xs);
}
.followup-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.followup-name { font-size: var(--text-sm); font-weight: 600; color: var(--text-strong); }
.followup-sub { font-size: var(--text-2xs); color: var(--text-muted); }
.followup-elapsed { font-size: var(--text-sm); color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.followup-elapsed.is-overdue { color: var(--acc-text); font-weight: 600; }
[data-theme="dark"] .followup-elapsed.is-overdue { color: var(--acc); }
.followup-actions { display: flex; gap: var(--space-1); flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 760px) {
  .followup-card { grid-template-columns: 1fr auto; }
  .followup-actions { grid-column: 1 / -1; justify-content: flex-start; }
}

/* Referidos */
.referrals-container { display: flex; flex-direction: column; gap: var(--space-3); margin-top: var(--space-4); }
.referral-group { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-xs); overflow: hidden; }
.referral-group-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-3) var(--space-4); background: var(--bg-elev);
  border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
.referral-referrer { display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; min-width: 0; }
.referral-referrer-name { font-size: var(--text-md); font-weight: 600; color: var(--text-strong); }
.referral-count {
  font-size: var(--text-2xs); font-weight: 600; letter-spacing: var(--tracking-wide);
  text-transform: uppercase; color: var(--acc-text); background: var(--acc-soft);
  border-radius: var(--r-full); padding: 1px var(--space-2);
}
[data-theme="dark"] .referral-count { color: var(--acc); }
.referral-group-actions { display: flex; gap: var(--space-1); flex-wrap: wrap; }
.referral-rows { display: flex; flex-direction: column; }
.referral-row {
  display: grid; grid-template-columns: 1fr auto auto auto; align-items: center;
  gap: var(--space-3); padding: var(--space-2) var(--space-4); border-top: 1px solid var(--border);
}
.referral-row:first-child { border-top: 0; }
.referral-row-name { font-size: var(--text-sm); color: var(--text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.referral-row-date { font-size: var(--text-2xs); color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (max-width: 640px) {
  .referral-row { grid-template-columns: 1fr auto; }
  .referral-row-date { display: none; }
}

.treatments-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-4);
}
.tx-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-xs);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.tx-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.tx-card.status-COMPLETED { opacity: 0.85; }
.tx-card.status-CANCELED { opacity: 0.65; }

.tx-card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: var(--space-3) var(--space-4);
  gap: var(--space-3);
  border-bottom: 1px solid var(--border);
}
.tx-card-patient { min-width: 0; flex: 1; }
.tx-card-patient-name {
  font-size: var(--text-xs);
  color: var(--text-muted);
  letter-spacing: var(--tracking-wide);
}
.tx-card-plan-name {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text-strong);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-top: 2px;
}
.tx-card-actions { display: flex; gap: var(--space-1); }

.status-pill {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  padding: 2px var(--space-2);
  border-radius: var(--r-full);
  border: 1px solid transparent;
}
.status-pill.status-ACTIVE    { background: var(--ok-bg); color: var(--ok-700); border-color: color-mix(in oklch, var(--ok) 30%, transparent); }
.status-pill.status-COMPLETED { background: var(--bg-sunken); color: var(--text-muted); border-color: var(--border); }
.status-pill.status-CANCELED  { background: var(--err-bg); color: var(--err-700); border-color: color-mix(in oklch, var(--err) 30%, transparent); }
[data-theme="dark"] .status-pill.status-ACTIVE { color: var(--ok-500); }
[data-theme="dark"] .status-pill.status-CANCELED { color: var(--err-500); }

/* v2.0 f6 — pills de estado del presupuesto (ciclo de vida). */
.status-pill.budget-pill-DRAFT    { background: var(--bg-sunken); color: var(--text-muted); border-color: var(--border); }
.status-pill.budget-pill-SENT     { background: var(--info-bg, color-mix(in oklch, var(--info) 14%, var(--surface))); color: var(--info); border-color: color-mix(in oklch, var(--info) 30%, transparent); }
.status-pill.budget-pill-ACCEPTED { background: var(--ok-bg); color: var(--ok-700); border-color: color-mix(in oklch, var(--ok) 30%, transparent); }
.status-pill.budget-pill-REJECTED { background: var(--err-bg); color: var(--err-700); border-color: color-mix(in oklch, var(--err) 30%, transparent); }
.status-pill.budget-pill-EXPIRED  { background: var(--bg-sunken); color: var(--text-muted); border-color: var(--border); }
.status-pill.budget-pill-direct   { background: var(--acc-soft); color: var(--acc-text); border-color: color-mix(in oklch, var(--acc) 25%, transparent); }
[data-theme="dark"] .status-pill.budget-pill-ACCEPTED { color: var(--ok-500); }
[data-theme="dark"] .status-pill.budget-pill-REJECTED { color: var(--err-500); }
[data-theme="dark"] .status-pill.budget-pill-direct   { color: var(--acc); }

/* Card de presupuesto (entidad): borde izquierdo teñido según estado. */
.budget-card.budget-status-ACCEPTED { border-left: 3px solid var(--ok); }
.budget-card.budget-status-SENT     { border-left: 3px solid var(--info); }
.budget-card.budget-status-REJECTED,
.budget-card.budget-status-EXPIRED  { border-left: 3px solid color-mix(in oklch, var(--text-muted) 40%, transparent); }
/* Metadatos del ciclo de vida del presupuesto, como badges pequeñas.
   Padding horizontal --space-4 para alinear con .plan-head y la cotización. */
.budget-meta {
  display: flex; flex-wrap: wrap; gap: var(--space-2);
  padding: var(--space-3) var(--space-4) 0;
  margin: 0;
}
.budget-date-badge {
  display: inline-flex; align-items: baseline; gap: var(--space-2);
  padding: 2px var(--space-2) 3px;
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  background: var(--bg-sunken);
  line-height: 1.3;
}
.budget-date-badge .bdb-label {
  font-size: var(--text-2xs); font-weight: 600;
  text-transform: uppercase; letter-spacing: var(--tracking-caps);
  color: var(--text-muted);
}
.budget-date-badge .bdb-date {
  font-size: var(--text-2xs); color: var(--text);
  font-variant-numeric: tabular-nums;
}
.budget-date-badge.budget-date-sent { border-color: color-mix(in oklch, var(--info) 30%, transparent); background: var(--info-bg, color-mix(in oklch, var(--info) 10%, var(--surface))); }
.budget-date-badge.budget-date-sent .bdb-label { color: var(--info); }
.budget-date-badge.budget-date-accepted { border-color: color-mix(in oklch, var(--ok) 30%, transparent); background: var(--ok-bg); }
.budget-date-badge.budget-date-accepted .bdb-label { color: var(--ok-700); }
.budget-date-badge.budget-date-rejected { border-color: color-mix(in oklch, var(--err) 30%, transparent); background: var(--err-bg); }
.budget-date-badge.budget-date-rejected .bdb-label { color: var(--err-700); }
[data-theme="dark"] .budget-date-badge.budget-date-accepted .bdb-label { color: var(--ok-500); }
[data-theme="dark"] .budget-date-badge.budget-date-rejected .bdb-label { color: var(--err-500); }
.budget-total {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: var(--space-2) var(--space-3); margin-top: var(--space-2);
  background: var(--bg-sunken); border-radius: var(--r-sm);
  font-size: var(--text-sm);
}
.budget-total strong { font-size: var(--text-base); color: var(--text-strong); font-variant-numeric: tabular-nums; }
.budget-linked-note {
  display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
  margin-top: var(--space-3); padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm); color: var(--text);
  background: var(--ok-bg); border-radius: var(--r-sm);
}
.budget-section-label {
  font-size: var(--text-2xs); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--text-muted); font-weight: 600;
  margin: var(--space-4) 0 var(--space-1);
}
.row-action.danger-text { color: var(--err-700); }
[data-theme="dark"] .row-action.danger-text { color: var(--err-500); }
.row-action.danger-text:hover { background: var(--err-bg); }

.tx-card-body {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4) var(--space-4);
}
.tx-card-services { display: flex; flex-direction: column; gap: var(--space-2); }
.tx-items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.tx-items li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  padding: 4px var(--space-2);
  font-size: var(--text-sm);
  border-radius: var(--r-sm);
}
.tx-items li:hover { background: var(--bg-sunken); }
.tx-item-name { color: var(--text); }
.tx-item-name small { color: var(--text-muted); font-weight: 500; }
.tx-item-price { color: var(--text-muted); font-variant-numeric: tabular-nums; font-weight: 500; }
.tx-items-empty { font-size: var(--text-xs); padding: var(--space-2); }

.tx-card-finance {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-3);
  padding: var(--space-3);
  background: var(--bg-sunken);
  border-radius: var(--r-md);
  border: 1px solid var(--border);
}
.tx-stat { display: flex; flex-direction: column; gap: 2px; }
.tx-stat label {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.tx-stat .value {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}
.tx-stat .value.paid { color: var(--ok-700); }
.tx-stat .value.balance { color: var(--acc-text); }
.tx-stat .value.balance.zero { color: var(--text-muted); }
[data-theme="dark"] .tx-stat .value.paid { color: var(--ok-500); }

.tx-progress-wrap {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.tx-progress-label {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.tx-progress {
  height: 6px;
  background: var(--n-200);
  border-radius: var(--r-full);
  overflow: hidden;
}
[data-theme="dark"] .tx-progress { background: var(--n-800); }
.tx-progress-bar {
  height: 100%;
  background: var(--acc);
  border-radius: var(--r-full);
  transition: width var(--dur-slow) var(--ease);
}
.tx-progress-bar.full { background: var(--ok); }

.tx-last-payment {
  font-size: var(--text-xs);
  grid-column: 1 / -1;
}

/* ═══════════════════════════════════════════════════════════════════
   MODALES & PANELES
   ═══════════════════════════════════════════════════════════════════ */

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  background: color-mix(in oklch, var(--n-950) 55%, transparent);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  animation: backdrop-in var(--dur-base) var(--ease);
}
.modal-backdrop.open { display: flex; }

@keyframes backdrop-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.modal {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-modal);
  width: min(520px, 100%);
  max-height: calc(100vh - var(--space-7));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: modal-in var(--dur-base) var(--ease);
}
.modal-wide { width: min(820px, 100%); }

@keyframes modal-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border);
  background: var(--bg-elev);
}
.modal-header h3 {
  font-size: var(--text-lg);
  font-weight: 600;
}
.modal-body {
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  overflow-y: auto;
}
.modal-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border);
  margin-top: auto;
  padding: var(--space-3) 0 0;
}
/* v2.8 — aviso al principio de un modal: dice qué OTRA cosa se está tocando
   sin darse cuenta (hoy, que presupuesto y plan se guardan juntos). Filete de
   acento a la izquierda, tono de nota al margen: informa, no alarma — para
   eso están los tonos semánticos. */
.modal-hint {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  border-left: 2px solid var(--acc);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  background: color-mix(in oklab, var(--acc) 7%, transparent);
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--text-muted);
}
.modal-hint strong { color: var(--text-strong); font-weight: 600; }
.form-row {
  display: grid;
  /* minmax(0, 1fr) en vez de 1fr para que inputs con min-intrinsic-width grande
     (datetime-local) no fuercen overflow horizontal del row. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-3);
}
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3) var(--space-4);
}
.form-grid .span-2 { grid-column: span 2; }

/* Form grid de 4 columnas (ficha de paciente con muchos campos) */
.form-grid-2 { grid-template-columns: repeat(2, 1fr); }
.form-grid-3 { grid-template-columns: repeat(3, 1fr); }
.form-grid-3 .span-2 { grid-column: span 2; }
.form-grid-3 .span-3 { grid-column: span 3; }
.form-grid-4 { grid-template-columns: repeat(4, 1fr); }
.form-grid-4 .span-2 { grid-column: span 2; }
.form-grid-4 .span-3 { grid-column: span 3; }
.form-grid-4 .span-4 { grid-column: span 4; }

/* Form sections (fieldsets agrupando campos por dominio lógico) */
.form-section {
  border: none;
  padding: 0;
  margin: 0 0 var(--space-5);
}
.form-section legend {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 0 0 var(--space-2);
  margin-bottom: var(--space-3);
  border-bottom: 1px solid var(--border);
  width: 100%;
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}
.form-section legend .legend-hint {
  margin-left: auto;
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: none;
  color: var(--acc-text);
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in oklch, var(--acc) 12%, transparent);
  border: 1px solid color-mix(in oklch, var(--acc) 25%, transparent);
}
[data-theme="dark"] .form-section legend .legend-hint { color: var(--acc); }
.form-section.is-required legend { color: var(--text-strong); }
.form-section-note {
  margin: 0 0 var(--space-3);
  font-size: var(--text-xs);
  color: var(--text-muted);
  line-height: var(--leading-snug);
}

/* Input con suffix (ej. fecha de nacimiento + edad calculada) */
.input-with-suffix {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding-right: var(--space-3);
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.input-with-suffix:focus-within {
  border-color: var(--acc);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--acc) 18%, transparent);
}
.input-with-suffix > input {
  border: none;
  background: transparent;
  flex: 1;
  min-width: 0;
}
.input-with-suffix > input:focus { box-shadow: none; }
.input-suffix {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  padding-left: var(--space-2);
  border-left: 1px solid var(--border);
}
.form-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-3);
}
.saved-msg {
  font-size: var(--text-xs);
  color: var(--ok-700);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease);
}
.saved-msg.show { opacity: 1; }
[data-theme="dark"] .saved-msg { color: var(--ok-500); }

/* ═══════════════════════════════════════════════════════════════════
   PERFIL DE PACIENTE (OVERLAY)
   ═══════════════════════════════════════════════════════════════════ */

.overlay {
  /* Shell v2 — el overlay de paciente arranca en el borde derecho del
     sidebar: se comporta como página dentro del shell (el sidebar sigue
     visible y navegable). En móvil --sb-cur es 0 → pantalla completa. */
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: var(--sb-cur);
  z-index: 60;
  display: none;
  background: var(--bg);
  animation: overlay-in var(--dur-base) var(--ease);
}
.overlay.open { display: flex; }
@keyframes overlay-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

.overlay-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* min-width: 0 permite que hijos con overflow-x:auto (p.ej. .profile-tabs)
     scrolleen dentro del viewport en lugar de empujar el ancho del overlay. */
  min-width: 0;
}
.overlay-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--header-h);
  padding: 0 var(--space-5);
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
}
.overlay-header h2 {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text-strong);
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.overlay-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* ═════════════════════════════════════════════════════════════════════
   Contexto de la consulta (v2.0 f8 — ficha del doctor)
   ───────────────────────────────────────────────────────────────────────
   Nota al margen, no tarjeta: filete de acento a la izquierda sobre fondo
   hundido, entre el encabezado y las pestañas. Es lo primero que se lee y
   se pliega a una línea cuando ya se leyó.
   ═════════════════════════════════════════════════════════════════════ */
.patient-context {
  flex-shrink: 0;
  padding: var(--space-3) var(--space-5) var(--space-4);
  background: var(--bg-sunken);
  border-bottom: 1px solid var(--border);
  border-left: 2px solid var(--acc);
}
.patient-context-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: 0;
  background: transparent;
  border: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
  color: var(--text-muted);
}
.patient-context-title {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  flex-shrink: 0;
}
.patient-context-hint {
  flex: 1;
  min-width: 0;
  font-size: var(--text-xs);
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.patient-context-chevron {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
  transition: transform var(--dur-fast) var(--ease);
}
.patient-context.is-collapsed { padding-bottom: var(--space-3); }
.patient-context.is-collapsed .patient-context-chevron { transform: rotate(-90deg); }
.patient-context.is-collapsed .patient-context-body { display: none; }

.patient-context-body { padding-top: var(--space-2); }
.patient-context-text {
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--text-strong);
  white-space: pre-wrap;
  max-width: 78ch;
}
.patient-context-text.is-empty {
  color: var(--text-muted);
  font-style: italic;
}
.patient-context-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
  margin-top: var(--space-3);
}
.patient-context-bit {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--text-xs);
}
.patient-context-bit .k {
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
.patient-context-bit .v {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
@media (prefers-reduced-motion: reduce) {
  .patient-context-chevron { transition: none; }
}
@media (max-width: 768px) {
  .patient-context { padding-left: var(--space-4); padding-right: var(--space-4); }
  .patient-context-meta { gap: var(--space-2) var(--space-4); }
}

.profile-tabs {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0 var(--space-5);
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  overflow-x: auto;
  overflow-y: hidden;
  flex-shrink: 0;
}
.profile-tab {
  position: relative;
  background: transparent;
  border: none;
  padding: var(--space-3) var(--space-3);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.profile-tab:hover { color: var(--text); }
.profile-tab.active { color: var(--text-strong); font-weight: 600; }
.profile-tab.active::after {
  content: "";
  position: absolute;
  left: var(--space-3);
  right: var(--space-3);
  bottom: -1px;
  height: 2px;
  background: var(--acc);
  border-radius: var(--r-full) var(--r-full) 0 0;
}

.profile-body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-5);
}
.profile-pane { display: none; max-width: 960px; }
.profile-pane.active { display: block; }
.profile-pane[data-pane="info"],
.profile-pane[data-pane="docs"],
.profile-pane[data-pane="firstvisit"],
.profile-pane[data-pane="treatment"],
.profile-pane[data-pane="budget"],
.profile-pane[data-pane="gallery"],
.profile-pane[data-pane="appointments"] { max-width: 1240px; }

.patient-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Datos: form principal + panel lateral con marketing/embudo */
.patient-info-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 360px);
  gap: var(--space-5);
  align-items: start;
}
.patient-info-main {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}
.patient-info-side {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}
.side-section {
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--space-4);
  margin: 0;
}
.side-section legend {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 0;
  margin: 0 0 var(--space-3);
  border: none;
  width: auto;
}
.side-fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.side-fields label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.side-fields label > input,
.side-fields label > select,
.side-fields label > textarea {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  color: var(--text);
}
.pane-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}
.pane-header h3 {
  font-size: var(--text-lg);
  font-weight: 600;
}
.pane-header > div { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* Bitácora */
.visits-list { display: flex; flex-direction: column; gap: var(--space-3); }
.visit-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.visit-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-xs); }
/* Estados firmada / borrador: borde lateral discreto que ancla la
   diferencia sin gritar. SIGNED usa el verde de --ok; DRAFT mantiene
   el borde neutro pero suaviza el fondo. */
.visit-card.is-signed {
  border-left: 3px solid color-mix(in oklch, var(--ok) 65%, var(--border));
}
.visit-card.is-draft {
  background: color-mix(in oklch, var(--acc) 3%, var(--surface));
  border-left: 3px solid color-mix(in oklch, var(--acc) 45%, var(--border));
}
.visit-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--text-sm);
  flex-wrap: wrap;
}
.visit-head-left {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.visit-head-right {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}
.visit-head strong { color: var(--text-strong); }
.visit-head-doc { color: var(--text-muted); }
.visit-body {
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  white-space: pre-wrap;
  color: var(--text);
}
.visit-actions { display: flex; justify-content: flex-end; gap: var(--space-1); flex-wrap: wrap; }

/* Status badges (mismo lenguaje visual que .fv-status-badge para que
   el ojo reconozca el ciclo DRAFT → SIGNED en cualquier lugar). */
.cr-status-badge {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 10px;
  border-radius: 999px;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  border: 1px solid var(--border);
  background: var(--bg-sunken);
  color: var(--text-muted);
}
.cr-status-badge.cr-status-DRAFT {
  background: color-mix(in oklch, var(--acc) 10%, var(--surface));
  color: var(--acc-text);
  border-color: color-mix(in oklch, var(--acc) 25%, var(--border));
}
[data-theme="dark"] .cr-status-badge.cr-status-DRAFT { color: var(--acc); }
.cr-status-badge.cr-status-SIGNED {
  background: var(--ok-bg);
  color: var(--ok-700);
  border-color: color-mix(in oklch, var(--ok) 30%, var(--border));
}

/* Tag "Aclaración" — discreto, color neutro, sin competir con el badge
   de status. Se usa en aclaraciones para que el ojo entienda de un
   vistazo que esa entrada es una corrección a otra. */
.cr-amendment-tag {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 10px;
  border-radius: 999px;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  border: 1px dashed var(--border-strong);
  background: var(--bg-sunken);
  color: var(--text-muted);
}

/* Bloque de firma — meta + imagen de firma embebida. La imagen se
   recorta a una altura razonable para que no domine la tarjeta. */
.cr-signature-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  border-top: 1px dashed var(--border);
  background: color-mix(in oklch, var(--ok) 4%, var(--surface));
  border-radius: 0 0 var(--r-md) var(--r-md);
  margin: var(--space-2) calc(var(--space-4) * -1) calc(var(--space-2) * -1);
  padding-left: var(--space-4);
  padding-right: var(--space-4);
}
.cr-signature-meta {
  font-size: var(--text-xs);
  color: var(--text-muted);
  line-height: var(--leading-snug);
}
.cr-signature-meta strong { color: var(--text); }
.cr-signature-image {
  display: block;
  max-height: 70px;
  width: auto;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 4px 8px;
  align-self: flex-start;
}

/* Aclaraciones anidadas: contenedor indentado bajo la entrada padre,
   con un acento lateral que conecta visualmente padre con hijos. */
.visit-amendments {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding-left: var(--space-4);
  border-left: 2px solid color-mix(in oklch, var(--acc) 30%, var(--border));
}
.visit-card.is-amendment {
  padding: var(--space-3) var(--space-4);
  background: var(--bg-sunken);
}
.visit-card.is-amendment.is-signed {
  background: color-mix(in oklch, var(--ok) 4%, var(--bg-sunken));
}

/* Botón admin discreto (mismo lenguaje que .fv-admin-btn). Se separa
   visualmente del resto con borde dasheado y opacidad reducida para
   recordar que son acciones de "modo pruebas". */
.row-action.cr-admin-btn {
  border-style: dashed;
  opacity: 0.85;
}
.row-action.cr-admin-btn:hover { opacity: 1; }
.row-action.primary {
  background: var(--acc);
  color: var(--text-on-acc);
  border-color: var(--acc);
}
.row-action.primary:hover {
  background: var(--acc-hover);
  border-color: var(--acc-hover);
}

/* Galería */
.gallery-section { margin-bottom: var(--space-5); }
.gallery-section h4 {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--space-3);
  font-weight: 600;
}
.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-3);
}
/* empty-state a ancho completo dentro de la grilla de fotos */
.gallery-empty { grid-column: 1 / -1; }
/* contador junto al título de sección (Antes · 3 / Después · 2) */
.gallery-count {
  color: var(--text-muted);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
}
.photo-card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
  aspect-ratio: 1;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.photo-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.photo-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-del {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 22px;
  height: 22px;
  background: oklch(0.18 0.01 40 / 0.55);
  color: var(--n-0);
  border: none;
  border-radius: var(--r-full);
  cursor: pointer;
  font-size: 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.photo-card:hover .photo-del { opacity: 1; }
.photo-del:hover { background: var(--err); }
.photo-meta {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  padding: var(--space-2);
  background: linear-gradient(to top, oklch(0.18 0.01 40 / 0.65), transparent);
  font-size: var(--text-2xs);
  color: var(--n-0);
  font-variant-numeric: tabular-nums;
}

/* Documentos */
.doc-categories {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
}
@media (max-width: 1100px) {
  .doc-categories { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.doc-cat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.doc-cat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
}
.doc-cat-head h4 {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-strong);
}
.doc-list {
  padding: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 80px;
}
.doc-empty {
  padding: var(--space-3);
  text-align: center;
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-style: italic;
}
.doc-card {
  display: grid;
  grid-template-columns: 40px 1fr auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2);
  border-radius: var(--r-sm);
  transition: background var(--dur-fast) var(--ease);
}
.doc-card:hover { background: var(--bg-sunken); }
.doc-thumb {
  width: 40px;
  height: 40px;
  border-radius: var(--r-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
}
/* Thumbnail real cuando el documento es una imagen — mismo tamaño
   que .doc-thumb (40x40) pero con object-fit:cover para que no
   reviente la grilla del .doc-card. */
.doc-card > img {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: var(--bg-sunken);
  display: block;
}
.doc-thumb.pdf { background: var(--err-bg); color: var(--err-700); border-color: color-mix(in oklch, var(--err) 25%, transparent); }
.doc-thumb.missing { background: var(--warn-bg); color: var(--warn-700); border-color: color-mix(in oklch, var(--warn) 30%, transparent); }
[data-theme="dark"] .doc-thumb.pdf { color: var(--err-500); }
[data-theme="dark"] .doc-thumb.missing { color: var(--warn-500); }
.doc-thumb-icon { font-size: var(--text-2xs); }
.doc-card-meta { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.doc-card-name {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.doc-card-date { font-size: var(--text-2xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.doc-card-actions { display: flex; gap: var(--space-1); }
.doc-card-btn {
  background: transparent;
  border: 1px solid transparent;
  padding: 4px var(--space-2);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--text-muted);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}
.doc-card-btn:hover {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border);
}
.doc-card-btn.del { color: var(--err-700); }
[data-theme="dark"] .doc-card-btn.del { color: var(--err-500); }
.doc-card-btn.del:hover { background: var(--err-bg); color: var(--err); border-color: color-mix(in oklch, var(--err) 35%, transparent); }

/* Plans (pagos) */
.plans-list { display: flex; flex-direction: column; gap: var(--space-4); }
.plan-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.plan-card.status-COMPLETED { opacity: 0.85; }
.plan-card.status-CANCELED { opacity: 0.65; }

.plan-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  background: var(--bg-elev);
}
.plan-title { display: flex; align-items: baseline; gap: var(--space-3); min-width: 0; flex-wrap: wrap; }
.plan-title strong {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text-strong);
}
.plan-title small {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  padding: 2px var(--space-2);
  border-radius: var(--r-full);
  border: 1px solid transparent;
}
.plan-title small.status-ACTIVE { background: var(--ok-bg); color: var(--ok-700); border-color: color-mix(in oklch, var(--ok) 30%, transparent); }
.plan-title small.status-COMPLETED { background: var(--bg-sunken); color: var(--text-muted); border-color: var(--border); }
.plan-title small.status-CANCELED { background: var(--err-bg); color: var(--err-700); border-color: color-mix(in oklch, var(--err) 30%, transparent); }
[data-theme="dark"] .plan-title small.status-ACTIVE { color: var(--ok-500); }
[data-theme="dark"] .plan-title small.status-CANCELED { color: var(--err-500); }
.plan-head-actions { display: flex; gap: var(--space-1); flex-shrink: 0; }

.plan-summary {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--bg-sunken);
  border-bottom: 1px solid var(--border);
}
.plan-stat { display: flex; flex-direction: column; gap: 2px; }
.plan-stat label {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.plan-stat .value {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}
.plan-stat .value.paid { color: var(--ok-700); }
.plan-stat .value.balance { color: var(--acc-text); }
.plan-stat .value.balance.zero { color: var(--text-muted); }
[data-theme="dark"] .plan-stat .value.paid { color: var(--ok-500); }
.plan-progress {
  height: 6px;
  background: var(--n-200);
  border-radius: var(--r-full);
  overflow: hidden;
  margin-top: 4px;
}
[data-theme="dark"] .plan-progress { background: var(--n-800); }
.plan-progress-bar {
  height: 100%;
  background: var(--acc);
  border-radius: var(--r-full);
  transition: width var(--dur-slow) var(--ease);
}
.plan-progress-bar.full { background: var(--ok); }

.plan-items-readout {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
}
.plan-items-readout strong {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
  display: block;
  margin-bottom: var(--space-2);
}
.plan-items-readout ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.plan-items-readout li {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--text-sm);
  padding: 2px 0;
}
.plan-items-readout .val { color: var(--text-muted); font-variant-numeric: tabular-nums; font-weight: 500; }
.plan-items-readout small { color: var(--text-muted); font-weight: 500; }
.plan-notes {
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  background: var(--bg-elev);
  line-height: var(--leading-relaxed);
}

.payments-section { padding: var(--space-3) var(--space-4) var(--space-4); }
.payments-section-head { margin-bottom: var(--space-2); }
.payments-section-head h4 {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}
.payments-list { display: flex; flex-direction: column; gap: 2px; }
.payment-row {
  display: grid;
  grid-template-columns: 110px 110px minmax(100px, 150px) 1fr auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2);
  border-radius: var(--r-sm);
  font-size: var(--text-sm);
  transition: background var(--dur-fast) var(--ease);
}
.payment-row:hover { background: var(--bg-sunken); }
.pay-date { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.pay-amount { color: var(--text-strong); font-weight: 600; font-variant-numeric: tabular-nums; }
.pay-method { color: var(--text-muted); }
.pay-notes {
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pay-del {
  width: 24px; height: 24px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  cursor: pointer;
  color: var(--text-dim);
  font-size: var(--text-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.payment-row:hover .pay-del { opacity: 1; }
.pay-del:hover { background: var(--err-bg); color: var(--err); }
/* v2.0 (ajustes f7) — corregir un pago ya registrado necesita un botón
   visible: antes sólo respondía el clic sobre la fila, que nadie veía. */
.pay-actions { display: inline-flex; align-items: center; gap: 2px; justify-self: end; }
.pay-edit {
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  padding: 2px var(--space-2);
  font-size: var(--text-2xs);
  color: var(--text-dim);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.payment-row:hover .pay-edit,
.pay-edit:focus-visible { opacity: 1; }
.pay-edit:hover { background: var(--bg-sunken); color: var(--text-strong); border-color: var(--border); }
/* Doctor atribuido: el dato que explica el desglose de ingresos. */
.pay-doctor {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 0 4px;
  border-radius: var(--r-xs);
  background: var(--bg-sunken);
  color: var(--text-dim);
  font-size: var(--text-2xs);
}
.payment-row:hover .pay-doctor { background: var(--surface); }
.payments-empty { padding: var(--space-3); text-align: center; color: var(--text-muted); font-size: var(--text-xs); }
/* v2.0 f7 — mensajes de WhatsApp de una cita. Cada plantilla es un cuadro
   editable con su propio botón de copiar: se elige el que se va a enviar. */
.apt-message-text {
  width: 100%;
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  resize: vertical;
}
.msg-cards-context {
  margin: calc(-1 * var(--space-2)) 0 var(--space-3);
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.msg-cards { display: flex; flex-direction: column; gap: var(--space-3); }
.msg-card {
  padding: var(--space-3);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.msg-card-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.msg-card-title { font-size: var(--text-sm); font-weight: 600; color: var(--text-strong); }
.msg-card-hint {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.msg-card-copy { margin-left: auto; flex-shrink: 0; }
.msg-card .apt-message-text { min-height: 0; background: var(--surface); }
@media (max-width: 600px) {
  .msg-card-hint { display: none; }
}

/* v2.0 f7 — botones de la cabecera de pagos (recordar pago · + pago). */
.payments-head-actions { display: flex; gap: var(--space-1); flex-wrap: wrap; }

/* v2.0 f6 — chip de cita vinculada dentro de la celda de notas del pago. */
.pay-apt {
  display: inline-block; margin-right: var(--space-2);
  padding: 1px 6px; border-radius: var(--r-full);
  background: var(--bg-sunken); border: 1px solid var(--border);
  font-size: var(--text-2xs); color: var(--text-muted);
  vertical-align: baseline; font-variant-numeric: tabular-nums;
}

/* Plan modal (configurador) */
.plan-items-section { display: flex; flex-direction: column; gap: var(--space-3); }
.plan-items-head { display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap; }
.plan-items-head h4 {
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-strong);
}
.plan-item-picker {
  position: relative;
  display: flex;
  flex-direction: column;
}
.plan-items-list { display: flex; flex-direction: column; gap: 2px; }
.plan-items-list-head {
  display: grid;
  grid-template-columns: 20px 1fr 104px 56px 104px 104px 28px;
  gap: var(--space-2);
  padding: 0 var(--space-2);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.plan-items-list-head-num { text-align: right; }
.plan-item-row {
  display: grid;
  grid-template-columns: 20px 1fr 104px 56px 104px 104px 28px;
  gap: var(--space-2) var(--space-2);
  align-items: center;
  padding: var(--space-2);
  background: var(--bg-sunken);
  border-radius: var(--r-sm);
}
/* Asa de reordenado + nota de la línea (v2.0 ajustes f7). La nota ocupa
   una segunda fila alineada bajo el nombre: es un apunte del servicio,
   no una columna más de la tabla. */
.plan-item-grip {
  width: 20px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: var(--r-sm);
  color: var(--text-dim);
  cursor: grab;
  touch-action: none;      /* el arrastre táctil no debe hacer scroll */
  padding: 0;
}
.plan-item-grip:hover { color: var(--text); background: var(--surface); }
.plan-item-grip:focus-visible { outline: 2px solid var(--acc); outline-offset: 1px; }
.plan-item-row.is-dragging {
  cursor: grabbing;
  opacity: 0.9;
  box-shadow: var(--shadow-md);
  outline: 1px dashed color-mix(in oklch, var(--acc) 45%, transparent);
}
.plan-item-row.is-dragging .plan-item-grip { cursor: grabbing; }
.plan-item-note {
  grid-column: 2 / -1;
  height: 24px;
  background: transparent;
  border: 1px dashed var(--border);
  border-radius: var(--r-sm);
  font-size: var(--text-xs);
  color: var(--text-muted);
  padding: 0 var(--space-2);
}
.plan-item-note:focus {
  border-style: solid;
  border-color: var(--border-strong);
  background: var(--surface);
  color: var(--text);
}
.plan-item-price-fixed {
  font-size: var(--text-sm);
  text-align: right;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
/* Un producto de rango es el único con precio editable en el plan. */
.plan-item-row.has-range .plan-item-price {
  border-color: color-mix(in oklch, var(--acc) 35%, var(--border));
}
.plan-item-name {
  font-size: var(--text-sm);
  font-weight: 500;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.plan-item-name > .plan-item-unit {
  font-size: var(--text-2xs);
  font-weight: 400;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.plan-item-qty, .plan-item-price, .plan-item-discount {
  height: 28px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-size: var(--text-sm);
  padding: 0 var(--space-2);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.plan-item-discount {
  color: var(--err-700);
}
[data-theme="dark"] .plan-item-discount { color: var(--err); }
.plan-item-subtotal {
  font-size: var(--text-sm);
  font-weight: 600;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--text-strong);
}
.plan-item-remove {
  width: 24px; height: 24px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  cursor: pointer;
  color: var(--text-dim);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-sm);
}
.plan-item-remove:hover { background: var(--err-bg); color: var(--err); }
.plan-items-empty {
  padding: var(--space-3);
  text-align: center;
  font-size: var(--text-xs);
  color: var(--text-muted);
  background: var(--bg-sunken);
  border: 1px dashed var(--border);
  border-radius: var(--r-sm);
  font-style: italic;
}
.plan-items-foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: var(--space-3);
  background: var(--acc-soft);
  border: 1px solid color-mix(in oklch, var(--acc) 25%, transparent);
  border-radius: var(--r-sm);
}
.plan-items-foot span:first-child {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--acc-text);
  font-weight: 600;
}
.plan-items-total {
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--acc-text);
  font-variant-numeric: tabular-nums;
}
/* Picker (paciente / servicio en plan) */
.patient-picker { display: flex; flex-direction: column; gap: var(--space-2); position: relative; }
.picker-results, .plan-item-picker .picker-results, #plan-item-results {
  display: none;
  position: absolute;
  top: 100%;
  left: 0; right: 0;
  margin-top: 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md);
  max-height: 220px;
  overflow-y: auto;
  z-index: 100;
}
.picker-results.open, .plan-item-picker .picker-results.open, #plan-item-results.open { display: block; }
.pick-row {
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.pick-row:hover { background: var(--bg-sunken); }
.pick-name { font-size: var(--text-sm); font-weight: 500; color: var(--text-strong); }
/* Paso corto de precio dentro del picker: un producto de rango pide el
   valor del caso ANTES de entrar al presupuesto. */
.pick-range-tag {
  display: inline-block;
  margin-left: 4px;
  padding: 0 4px;
  border-radius: var(--r-xs);
  background: var(--acc-soft);
  color: var(--acc-text);
  font-size: 9px;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  font-weight: 600;
}
.pick-range-step { padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
.pick-range-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }
.pick-range-field {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
}
.pick-range-field input {
  height: 30px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  padding: 0 var(--space-2);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--text-strong);
  text-transform: none;
  letter-spacing: 0;
}
.pick-range-actions { display: flex; justify-content: flex-end; gap: var(--space-2); }
.pick-phone { font-size: var(--text-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.pick-meta { font-size: var(--text-xs); color: var(--text-muted); }

.picker-selected {
  padding: var(--space-2) var(--space-3);
  background: var(--acc-soft);
  border: 1px solid color-mix(in oklch, var(--acc) 25%, transparent);
  border-radius: var(--r-sm);
  font-size: var(--text-sm);
  color: var(--acc-text);
  display: none;
}
.picker-selected.set { display: block; }
.new-patient-fields { display: flex; flex-direction: column; gap: var(--space-3); }

/* Citas (apt-list) — single-row compacto en desktop, two-row en mobile.
   El botón Editar va siempre a la derecha del título, no debajo. */
.apt-list { display: flex; flex-direction: column; gap: var(--space-2); }
/* Agrupación de citas: Próximas / Historial (Fase B). */
.apt-group-head {
  display: flex; align-items: baseline; gap: var(--space-2);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
  margin: var(--space-3) 0 2px;
}
.apt-group-head:first-child { margin-top: 0; }
.apt-group-count {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  padding: 1px 7px;
  border-radius: var(--r-full);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  color: var(--text-muted);
}
.apt-row {
  display: grid;
  grid-template-columns: 110px minmax(0, 1fr) auto auto auto auto;
  grid-template-areas: "when title type doctor status edit";
  gap: var(--space-2) var(--space-3);
  align-items: center;
  padding: var(--space-2) var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  font-size: var(--text-sm);
  transition: border-color var(--dur-fast) var(--ease);
}
.apt-row:hover { border-color: var(--border-strong); }

.apt-when {
  grid-area: when;
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.apt-date {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-xs);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.apt-time {
  color: var(--text);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-2xs);
  font-weight: 500;
}
.apt-title {
  grid-area: title;
  font-weight: 500;
  color: var(--text-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.apt-edit-btn { grid-area: edit; }
.apt-doctor {
  grid-area: doctor;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  padding: 2px 8px;
  border-radius: var(--r-full);
  white-space: nowrap;
}
.apt-doctor.muted { background: var(--bg-sunken); color: var(--text-muted); font-style: italic; }
.apt-type {
  grid-area: type;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: var(--r-full);
  white-space: nowrap;
}
.apt-status-select { grid-area: status; min-width: 130px; }
.apt-type.type-treatment { background: var(--acc-soft); color: var(--acc-text); }
.apt-type.type-valuation { background: var(--info-bg); color: var(--info-700); }
/* v2.0 f9 — seguimiento: control post-tratamiento. Verde apagado, para que
   no se confunda con la valoración (azul) ni con el tratamiento (acento). */
.apt-type.type-followup  { background: var(--ok-bg); color: var(--ok-700); }
[data-theme="dark"] .apt-type.type-valuation { color: var(--info-500); }
[data-theme="dark"] .apt-type.type-followup  { color: var(--ok-500); }
.apt-status-select.status-RESERVED  { color: var(--warn-700); }
.apt-status-select.status-SCHEDULED { color: var(--info-700); }
.apt-status-select.status-COMPLETED { color: var(--ok-700); }
.apt-status-select.status-CANCELED  { color: var(--err-700); }
[data-theme="dark"] .apt-status-select.status-RESERVED  { color: var(--warn-500); }
[data-theme="dark"] .apt-status-select.status-SCHEDULED { color: var(--info-500); }
[data-theme="dark"] .apt-status-select.status-COMPLETED { color: var(--ok-500); }
[data-theme="dark"] .apt-status-select.status-CANCELED  { color: var(--err-500); }

/* Media viewer */
.media-modal-content {
  background: transparent;
  border: none;
  box-shadow: none;
  width: min(960px, 100%);
  max-height: 100vh;
}
.media-modal-content .media-close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  z-index: 2;
  background: oklch(0.18 0.01 40 / 0.55);
  color: var(--n-0);
  border: 1px solid oklch(1 0 0 / 0.15);
}
.media-modal-content .media-close:hover { background: oklch(0.18 0.01 40 / 0.8); }
#media-viewer img,
#media-viewer iframe {
  width: 100%;
  max-height: 80vh;
  object-fit: contain;
  border-radius: var(--r-md);
  display: block;
}
#media-viewer iframe { height: 80vh; background: var(--surface); border: 1px solid var(--border); }

/* ───────────────────────── Toast ───────────────────────── */
.toast {
  position: fixed;
  bottom: var(--space-5);
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  padding: var(--space-3) var(--space-4);
  background: var(--n-950);
  color: var(--n-0);
  border-radius: var(--r-md);
  font-size: var(--text-sm);
  font-weight: 500;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  pointer-events: none;
  z-index: 200;
  transition: opacity var(--dur-base) var(--ease), transform var(--dur-base) var(--ease);
  max-width: 90vw;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}
.toast.ok::before { content: "✓"; color: var(--ok-500); font-weight: 700; }
.toast.error { background: var(--err-700); }
/* El toast es la única superficie que se INVIERTE en dark: fondo claro y
   texto oscuro. Por eso sus colores semánticos van con el valor oscuro
   explícito y no con los tokens -700, que en dark son claros. */
[data-theme="dark"] .toast { background: var(--n-100); color: var(--n-950); box-shadow: var(--shadow-lg); }
[data-theme="dark"] .toast.ok::before { color: oklch(0.38 0.090 150); }
[data-theme="dark"] .toast.error { background: oklch(0.52 0.175 27); color: var(--n-0); }

/* ───────────────────────── Empty state genérico ───────────────────────── */
.empty-state {
  padding: var(--space-6) var(--space-4);
  text-align: center;
  color: var(--text-muted);
  font-size: var(--text-sm);
  background: var(--surface);
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-lg);
}

/* ═══════════════════════════════════════════════════════════════════
   AUTH — chip de usuario en el header + pantalla de login
   ═══════════════════════════════════════════════════════════════════ */

/* Lock UI mientras se resuelve la sesión y/o cuando no hay login.
   Evita el flicker de la bandeja de leads vacía antes de que arranque
   Supabase. El header permanece visible (logo + tema). */
body.app-locked .sidebar,
body.app-locked .app-header,
body.app-locked .main-nav,
body.app-locked .view { display: none !important; }

/* Loading screen — overlay mientras storage.js sincroniza con Supabase. */
.loading-screen {
  position: fixed;
  inset: 0;
  z-index: 220;     /* arriba del login screen (200) */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  background: color-mix(in oklch, var(--bg) 92%, transparent);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  animation: login-screen-in var(--dur-base) var(--ease);
}
.loading-screen[hidden] { display: none; }
.loading-card {
  width: min(360px, 100%);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  text-align: center;
}
.loading-spinner {
  width: 32px; height: 32px;
  border: 2.5px solid var(--border);
  border-top-color: var(--acc);
  border-radius: 50%;
  animation: loading-spin 700ms linear infinite;
}
@keyframes loading-spin {
  to { transform: rotate(360deg); }
}
.loading-title {
  margin: 0;
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text-strong);
  letter-spacing: -0.01em;
}
.loading-message {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-muted);
  min-height: 1.4em;
}


/* Chip de usuario: rol + nombre + ícono de logout. Click = sign out. */
.user-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 32px;
  padding: 0 var(--space-2) 0 var(--space-3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  color: var(--text-muted);
  font: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
  max-width: 240px;
  min-width: 0;
}
.user-chip:hover {
  background: var(--bg-sunken);
  color: var(--text);
  border-color: var(--border-strong);
}
.user-chip[hidden] { display: none; }
.user-chip-role {
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  font-size: var(--text-2xs);
  color: var(--acc-text);
  background: var(--acc-soft);
  padding: 2px 6px;
  border-radius: var(--r-full);
}
[data-theme="dark"] .user-chip-role { color: var(--acc); }
.user-chip-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.user-chip-icon {
  width: 14px; height: 14px;
  flex-shrink: 0;
  opacity: 0.7;
}
.user-chip:hover .user-chip-icon { opacity: 1; }

/* Login screen — overlay full-screen que tapa todo cuando no hay sesión. */
.login-screen {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  background: var(--bg);
  animation: login-screen-in var(--dur-base) var(--ease);
}
.login-screen[hidden] { display: none; }
@keyframes login-screen-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
.login-card {
  width: min(420px, 100%);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-lg);
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  animation: login-card-in var(--dur-slow) var(--ease);
}
@keyframes login-card-in {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* v2.0 f9.5 — la portada de la plataforma. Marca arriba (el mismo diente
   del sidebar y del favicon), nombre en dos pesos y una línea que dice
   qué es esto. Sin promesas ni tono de bienvenida. */
.login-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  text-align: center;
  padding-bottom: var(--space-2);
}
.login-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px; height: 52px;
  border-radius: var(--r-md);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
}
.login-mark img { width: 34px; height: 34px; object-fit: contain; }
.login-brand {
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--text-strong);
  margin: 0;
}
.login-brand span {
  font-weight: 500;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  font-size: var(--text-xs);
  color: var(--acc);
  margin-left: 4px;
  vertical-align: 2px;
}
.login-subtitle {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--text-sm);
}
.login-notice {
  padding: var(--space-2) var(--space-3);
  background: var(--info-bg, var(--bg-sunken));
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--text-2);
}
.login-notice[hidden] { display: none; }
.login-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.login-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.login-field-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-dim);
}
/* El input[type="password"] no está en el selector global de inputs;
   lo añadimos acá para mantener el mismo look. */
.login-field input[type="email"],
.login-field input[type="password"] {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 0 var(--space-3);
  height: 38px;
  font-size: var(--text-base);
  width: 100%;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.login-field input:focus {
  border-color: var(--acc);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--acc) 18%, transparent);
  outline: none;
}
.login-error {
  padding: var(--space-2) var(--space-3);
  background: var(--err-bg);
  color: var(--err-700);
  border: 1px solid color-mix(in oklch, var(--err) 30%, transparent);
  border-radius: var(--r-sm);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}
[data-theme="dark"] .login-error { color: oklch(0.90 0.05 27); }
.login-submit {
  margin-top: var(--space-2);
  height: 40px;
  font-size: var(--text-base);
}
.login-submit:disabled { opacity: 0.6; cursor: progress; }
.login-foot {
  margin: 0;
  text-align: center;
  font-size: var(--text-xs);
  color: var(--text-dim);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: center;
}
.login-help {
  margin: 0;
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
  color: var(--text-muted);
  max-width: 34ch;
}
.login-help[hidden] { display: none; }

/* Campo de contraseña con su revelador. El botón vive dentro del borde
   del input para que los dos se lean como un solo control. */
.login-pw {
  position: relative;
  display: flex;
  align-items: center;
}
.login-pw input { padding-right: 62px !important; }
.login-pw-toggle {
  position: absolute;
  right: 5px;
  height: 28px;
  padding: 0 var(--space-2);
  border: 0;
  border-radius: var(--r-sm);
  background-color: transparent;
  color: var(--text-muted);
  font-size: var(--text-xs);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.login-pw-toggle:hover {
  color: var(--acc);
  background-color: color-mix(in oklch, var(--acc) 8%, transparent);
}
.login-hint {
  font-size: var(--text-xs);
  color: var(--warn-700);
}
.login-hint[hidden] { display: none; }

/* ═══════════════════════════════════════════════════════════════════
   RESPONSIVE — tablet 1024px y móvil 480/768
   ═══════════════════════════════════════════════════════════════════ */

/* Tabla de precios: detalle como drawer a partir de ≤1200px (antes del breakpoint general
   de tablet — el layout 3-col se ve apretado bastante antes que el resto de las vistas). */
@media (max-width: 1200px) {
  .prices-layout {
    grid-template-columns: 200px minmax(0, 1fr);
  }
  .prices-detail {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: min(400px, 92vw);
    margin: 0;
    border-radius: var(--r-lg) 0 0 var(--r-lg);
    border-right: none;
    box-shadow: var(--shadow-lg);
    z-index: 50;
    overflow-y: auto;
    transform: translateX(100%);
    transition: transform var(--dur-base) var(--ease);
    animation: none;
  }
  .prices-layout.detail-open .prices-detail { transform: translateX(0); }
  .prices-layout.detail-open .prices-detail-backdrop { display: block; }
  .prices-detail-close { display: inline-flex; }
}

/* Bandeja de WhatsApp: el hilo pasa a drawer antes que el resto de las
   vistas — dos columnas ya se leen apretadas antes que las de tres. */
@media (max-width: 900px) {
  .wa-layout {
    grid-template-columns: 1fr;
    height: calc(100vh - var(--header-h, 60px) - var(--nav-h, 48px) - var(--space-3) * 2);
  }
  .wa-thread-pane {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: 100%;
    max-width: none;
    border-radius: 0;
    border: none;
    z-index: 50;
    transform: translateX(100%);
    transition: transform var(--dur-base) var(--ease);
  }
  .wa-layout.detail-open .wa-thread-pane { transform: translateX(0); }
  .wa-layout.detail-open .wa-thread-backdrop { display: block; }
  .wa-thread-back { display: inline-flex; }
}

/* Tablet (≤1024px): ajustes de densidad y nav */
@media (max-width: 1024px) {
  .view { padding: var(--space-4); }

  .doctor-stats { grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
  .plan-summary { grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
  .form-grid-4 { grid-template-columns: repeat(2, 1fr); }
  .form-grid-4 .span-3, .form-grid-4 .span-4 { grid-column: span 2; }

  /* Datos paciente: el panel lateral pasa debajo a partir de tablet */
  .patient-info-layout { grid-template-columns: minmax(0, 1fr); }
  .patient-info-side { position: static; }

  /* v2.2 — la Bandeja pasó a 7 columnas con celdas nombradas por clase
     (identity · city · channel · ad · status · date · actions), así que
     lo que se oculta en cada breakpoint se declara por clase junto al
     resto del bloque v2.2 y no por nth-child. */
}

/* Móvil (≤768px) */
@media (max-width: 768px) {
  :root { --header-h: 52px; --nav-h: 42px; }

  .app-header { padding: 0 var(--space-3); }
  .brand h1 { font-size: var(--text-sm); }
  .env-tag { display: none; }

  /* Chip de usuario en móvil: sólo el rol + ícono, sin email */
  .user-chip { padding: 0 6px; max-width: none; gap: 6px; }
  .user-chip-label { display: none; }

  /* Login en móvil: padding más ajustado, card ocupa casi toda la pantalla */
  .login-screen { padding: var(--space-3); }
  .login-card { padding: var(--space-5); }
  .header-actions #today-date { display: none; }

  .main-nav { padding: 0 var(--space-3); }
  .nav-counter { display: none; }

  .view { padding: var(--space-3) var(--space-3) var(--space-6); }

  .toolbar-row { gap: var(--space-2); }
  .toolbar-spacer { display: none; }
  .search-input { min-width: 0; flex: 1 1 100%; max-width: none; order: 99; }

  .filter-pills { width: 100%; overflow-x: auto; flex-wrap: nowrap; }
  .pill { flex-shrink: 0; }

  .grid-wrap { max-height: none; border-radius: var(--r-md); }
  .data-grid { table-layout: auto; }
  .data-grid thead th,
  .data-grid tbody td { padding: var(--space-2); font-size: var(--text-sm); }
  .empty-row td {
    text-align: left !important;
    padding: var(--space-5) var(--space-3) !important;
    position: sticky;
    left: 0;
    max-width: calc(100vw - var(--space-3) * 2);
  }
  /* Reset min-widths para que columnas restantes quepan en 390-768px */
  .col-name { min-width: 0; }
  .col-phone, .col-status, .col-actions { width: auto; }
  .leads-grid .col-lead-identity { min-width: 0; }
  .leads-grid .col-lead-status, .leads-grid .col-lead-actions { width: auto; }

  .cal-month { grid-auto-rows: minmax(64px, auto); }
  .cal-day { min-height: 64px; padding: 4px; }
  .cal-day-count { font-size: var(--text-md); }
  .cal-day-label { display: none; }
  .cal-week-header { grid-template-columns: 44px repeat(7, 1fr); }
  .cal-week-body { grid-template-columns: 44px repeat(7, 1fr); }
  .cal-week-blockrow { grid-template-columns: 44px repeat(7, 1fr); }
  .cal-hour-label { font-size: 9px; padding: 2px 4px; }

  .doctors-container,
  .treatments-container,
  .doc-categories { grid-template-columns: 1fr; }

  /* Tabla de precios en móvil:
     - sidebar: barra horizontal de pills (scroll-x)
     - main: ancho completo
     - detalle: bottom-sheet que se desliza desde abajo */
  .prices-layout {
    grid-template-columns: 1fr;
    gap: var(--space-3);
  }
  .prices-sidebar {
    position: static;
    flex-direction: row;
    gap: var(--space-2);
    overflow-x: auto;
    padding: var(--space-2) var(--space-3);
    margin: 0 calc(var(--space-3) * -1);
    scrollbar-width: thin;
    align-items: center;
  }
  .prices-sidebar-label { display: none; }
  .prices-cat-list {
    flex-direction: row;
    gap: var(--space-1);
    flex-wrap: nowrap;
  }
  .prices-cat-list li { flex-shrink: 0; }
  .prices-cat-item {
    flex-direction: row;
    padding: 6px var(--space-3);
    border-radius: var(--r-full);
    border: 1px solid var(--border);
    background: var(--surface);
    font-size: var(--text-sm);
    white-space: nowrap;
  }
  .prices-cat-item.is-active::before { display: none; }
  .prices-cat-item.is-active {
    background: var(--acc-soft);
    border-color: color-mix(in oklch, var(--acc) 28%, transparent);
    color: var(--acc-text);
    box-shadow: none;
  }
  [data-theme="dark"] .prices-cat-item.is-active { color: var(--acc); }
  .prices-cat-add {
    flex-shrink: 0;
    margin-top: 0;
    padding: 6px var(--space-3);
    border-radius: var(--r-full);
    font-size: var(--text-sm);
  }
  .prices-main-title h3 { font-size: var(--text-xl); }
  .prices-subtab { font-size: var(--text-xs); padding: 6px var(--space-2); }

  .prices-detail {
    position: fixed;
    top: auto;
    left: 0; right: 0; bottom: 0;
    width: 100%;
    max-width: none;
    max-height: 85vh;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    border: 1px solid var(--border);
    border-bottom: none;
    transform: translateY(100%);
  }
  .prices-layout.detail-open .prices-detail { transform: translateY(0); }

  .doctor-stats { grid-template-columns: repeat(4, 1fr); padding: var(--space-2); }
  .doctor-stat span { font-size: var(--text-sm); }

  .plan-summary { grid-template-columns: repeat(2, 1fr); }
  .tx-card-finance { grid-template-columns: repeat(2, 1fr); }
  .tx-progress-wrap { grid-column: 1 / -1; }

  .modal { width: 100%; max-height: calc(100vh - var(--space-3) * 2); border-radius: var(--r-lg); }
  .modal-wide { width: 100%; }
  .modal-backdrop { padding: var(--space-3); align-items: flex-end; }
  .modal { animation-name: modal-in-mobile; }
  @keyframes modal-in-mobile {
    from { opacity: 0; transform: translateY(40px); }
    to { opacity: 1; transform: translateY(0); }
  }

  .form-grid, .form-row { grid-template-columns: 1fr; }
  .form-grid .span-2, .form-grid .span-3, .form-grid .span-4 { grid-column: auto; }
  .form-grid-4, .form-grid-3, .form-grid-2 { grid-template-columns: 1fr; }

  .overlay-header { padding: 0 var(--space-3); height: 52px; }
  .overlay-header h2 { font-size: var(--text-sm); }
  .profile-tabs { padding: 0 var(--space-3); }
  .profile-body { padding: var(--space-3); }

  .payment-row { grid-template-columns: 1fr 100px auto; row-gap: 2px; }
  .payment-row .pay-method,
  .payment-row .pay-notes { grid-column: 1 / -1; font-size: var(--text-2xs); }
  .payment-row .pay-del,
  .payment-row .pay-edit { opacity: 1; }

  /* A 375px la fila de servicio se pliega en tres niveles: qué es, cuánto
     cuesta, y el apunte + subtotal. El asa de arrastre sigue a la izquierda
     (el reordenado táctil es el caso principal en tablet y móvil). */
  .plan-items-list-head { display: none; }
  .plan-item-row {
    grid-template-columns: 20px 1fr 56px 92px;
    grid-template-areas:
      "grip name  name rm"
      ".    price qty  disc"
      ".    note  note sub";
    row-gap: var(--space-2);
  }
  .plan-item-grip { grid-area: grip; }
  .plan-item-name { grid-area: name; }
  .plan-item-remove { grid-area: rm; justify-self: end; }
  .plan-item-price,
  .plan-item-price-fixed { grid-area: price; }
  .plan-item-qty { grid-area: qty; }
  .plan-item-discount { grid-area: disc; }
  .plan-item-note { grid-area: note; }
  .plan-item-subtotal { grid-area: sub; }

  /* Mobile: dos filas, Editar a la derecha junto al título.
     Usamos flex en lugar de grid para que type+doctor+status floten en
     la segunda fila sin colisionar con grid-areas. */
  .apt-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
  }
  .apt-when {
    flex-direction: row;
    gap: var(--space-2);
    align-items: baseline;
    order: 2;
    flex-basis: 100%;
  }
  .apt-time { font-size: var(--text-xs); color: var(--text-muted); }
  .apt-title { order: 1; flex: 1; min-width: 0; }
  .apt-edit-btn { order: 1; margin-left: auto; }
  .apt-type   { order: 3; }
  .apt-doctor { order: 3; }
  .apt-status-select { order: 3; margin-left: auto; min-width: 120px; max-width: 160px; }
}

/* Móvil chico (≤480px): solo lo esencial */
@media (max-width: 480px) {
  .btn { padding: 0 var(--space-2); font-size: var(--text-xs); }
  .btn-primary { padding: 0 var(--space-3); }
  /* En pantalla muy chica el chip pasa a ser sólo el ícono + rol abreviado */
  .user-chip-role { padding: 2px 4px; font-size: 9px; }
}

/* ═════════════════════════════════════════════════════════════════════
   Doctor modal — campos de auth (creación)
   ═════════════════════════════════════════════════════════════════════ */
/* ═════════════════════════════════════════════════════════════════════
   Disponibilidad del doctor (v2.0 f8)
   ───────────────────────────────────────────────────────────────────────
   Mismo contenedor que "Cuenta de acceso" para que el modal lea como una
   sola pila de bloques. Los toggles de día reusan .day-toggle del editor
   de sedes: el mismo gesto en los dos lugares donde se toca lo mismo.
   ═════════════════════════════════════════════════════════════════════ */
/* ═════════════════════════════════════════════════════════════════════
   Modal de doctor — bloques (v2.0 f9.5)
   ─────────────────────────────────────────────────────────────────────
   El formulario son cuatro asuntos distintos y ahora se ven como cuatro:
   identidad · contacto y color · disponibilidad · cuenta de acceso. Un
   solo patrón de bloque para los cuatro, con el rótulo en versalitas y
   una regla fina debajo: el cuaderno separa por línea, no por caja
   dentro de caja.
   ═══════════════════════════════════════════════════════════════════ */
.doctor-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-2);
}
.doctor-block[hidden] { display: none; }
.doctor-block-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--border);
}
.doctor-block-head h4 {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
/* Etiqueta de estado de la cuenta: nueva · sin cuenta · con acceso. */
.doctor-block-tag {
  flex-shrink: 0;
  padding: 2px 8px;
  border-radius: var(--r-full);
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
.doctor-block-tag[hidden] { display: none; }
.doctor-block-note {
  margin: 0;
  font-size: var(--text-xs);
  line-height: 1.5;
}
/* Un enlace dentro de la nota es parte de la frase: hereda su tamaño en
   vez de romper el renglón con el cuerpo del botón. */
.doctor-block-note .btn-link { font-size: inherit; vertical-align: baseline; }
.doctor-color-label { gap: var(--space-2); }

/* Credencial: una fila etiqueta + campo + acción. */
.doctor-cred {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.doctor-cred[hidden] { display: none; }
.doctor-cred > label {
  font-size: var(--text-xs);
  color: var(--text-2);
}
.doctor-cred-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.doctor-cred-row input[type="email"] {
  flex: 1;
  min-width: 200px;
}
.doctor-cred-row-static {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: 8px 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
}
.doctor-cred-static-label {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
.doctor-cred-static-value {
  font-size: var(--text-sm);
  color: var(--text);
  word-break: break-all;
}
.doctor-cred-msg {
  margin: 0;
  font-size: var(--text-xs);
  line-height: 1.45;
  color: var(--text-muted);
}
.doctor-cred-msg[hidden] { display: none; }
.doctor-cred-msg.ok  { color: var(--ok-700); }
.doctor-cred-msg.err { color: var(--err-700); }

/* Campo de contraseña con sus dos utilidades pegadas al borde derecho. */
.doctor-pw-field {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.doctor-pw-field input { flex: 1; min-width: 0; }
.doctor-pw-btn {
  flex-shrink: 0;
  height: 30px;
  padding: 0 var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background-color: var(--surface);
  color: var(--text-2);
  font-size: var(--text-xs);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.doctor-pw-btn:hover { border-color: var(--acc); color: var(--text-strong); }
.doctor-auth-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
}
.doctor-auth-actions[hidden] { display: none; }
.doctor-auth-self { display: flex; flex-direction: column; gap: var(--space-3); }
.doctor-auth-self[hidden] { display: none; }

.doctor-avail-hint { margin: 0; font-size: 12px; line-height: 1.45; }
.doctor-avail-list { display: flex; flex-direction: column; gap: 10px; }
.doctor-avail-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
/* Sede asignada pero sin días marcados: sigue visible, apagada. */
.doctor-avail-row.is-off { opacity: 0.66; }
.doctor-avail-sede {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1;
  min-width: 140px;
}
.doctor-avail-sede-name { font-size: var(--text-sm); font-weight: 500; color: var(--text-strong); }
.doctor-avail-sede-meta { font-size: var(--text-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.doctor-avail-hours {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}
.doctor-avail-hours input[type="time"] {
  width: 104px;
  padding: 5px 7px;
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}
.doctor-avail-dash { color: var(--text-muted); }
.doctor-avail-empty { margin: 0; font-size: var(--text-sm); }

/* Sedes y horario en el panel derecho de la ficha del doctor. */
.doc-sedes-list { display: flex; flex-direction: column; gap: 6px; }
.doc-sede-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 7px 0;
  border-bottom: 1px solid var(--border);
}
.doc-sede-row:last-child { border-bottom: none; }
.doc-sede-name { font-size: var(--text-sm); font-weight: 500; color: var(--text-strong); }
.doc-sede-hours { font-size: var(--text-xs); font-variant-numeric: tabular-nums; }

@media (max-width: 640px) {
  .doctor-avail-row { align-items: flex-start; }
  .doctor-avail-hours { width: 100%; }
  .doctor-avail-hours input[type="time"] { flex: 1; width: auto; }
}

.doctor-block-auth input[type="email"],
.doctor-block-auth input[type="password"],
.doctor-block-auth input[type="text"] {
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background-color: var(--surface);
  color: var(--text);
  font: inherit;
  transition: border-color var(--dur-fast) var(--ease);
}
.doctor-block-auth input:focus {
  outline: none;
  border-color: var(--acc);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--acc) 25%, transparent);
}
.doctor-block-auth label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--text-xs);
  color: var(--text-2);
}
.doctor-block-auth .doctor-cred-row label { display: contents; }
.doctor-auth-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.doctor-auth-block[hidden] { display: none; }
.doctor-auth-reset {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-3);
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: var(--r-sm);
}
.doctor-auth-reset[hidden] { display: none; }

/* ═════════════════════════════════════════════════════════════════════
   Profile modal — Mi perfil
   ═════════════════════════════════════════════════════════════════════ */
.modal-profile {
  max-width: 480px;
  width: 100%;
}
.profile-modal-body {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 18px 20px 20px;
}
.profile-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.profile-section-title {
  margin: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-2);
}
.profile-section label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--text-2);
}
.profile-section input {
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  transition: border-color var(--dur-fast) var(--ease);
}
.profile-section input:focus {
  outline: none;
  border-color: var(--acc);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--acc) 25%, transparent);
}
.profile-section-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 4px;
}
.profile-feedback {
  flex: 1;
  font-size: 12px;
  color: var(--text-2);
  min-height: 1em;
}
.profile-feedback.ok  { color: var(--ok); }
.profile-feedback.err { color: var(--err); }
.profile-meta {
  background: var(--surface);
  gap: 8px;
}
/* v2.0 f8 — puntero de "cuenta" a "perfil profesional" (sólo doctor). */
.profile-hint {
  margin: 0;
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--text-muted);
}
.profile-hint[hidden] { display: none; }
.profile-meta-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 2px 0;
}
.profile-meta-label {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-2);
}
.profile-meta-value {
  font-size: 13px;
  color: var(--text);
  font-feature-settings: 'tnum' 1;
}
.profile-logout {
  background: transparent;
  border: none;
  padding: 0;
  flex-direction: row;
  justify-content: flex-end;
}

@media (max-width: 520px) {
  .modal-profile { max-width: 95vw; }
  .profile-modal-body { padding: 14px; }
}

/* ═════════════════════════════════════════════════════════════════════
   Role-based visibility
   ───────────────────────────────────────────────────────────────────────
   Elementos marcados con [data-role-admin] sólo se muestran si el body
   tiene data-rlx-role="admin". Elementos con [data-role-doctor-only] son
   lo opuesto — visibles sólo para doctor. El body parte sin atributo
   para que NADA admin-only se filtre antes de cargar el profile.
   ═════════════════════════════════════════════════════════════════════ */
body:not([data-rlx-role="admin"]) [data-role-admin] { display: none !important; }
[data-role-doctor-only] { display: none !important; }
body[data-rlx-role="doctor"] [data-role-doctor-only] { display: revert !important; }

/* ═════════════════════════════════════════════════════════════════════
   Overlay mode (v1.3 — separación Leads ↔ Pacientes)
   ───────────────────────────────────────────────────────────────────────
   El overlay del paciente se abre en dos modos:
     · "lead" — ficha mínima: solo pestaña Datos con Identidad + Contacto
       + Marketing/embudo. Pensado para procesar volumen desde la Bandeja.
     · "full" — todas las pestañas y secciones clínicas. Desde la sección
       Pacientes.
   Elementos marcados con [data-mode="full"] se ocultan cuando el body
   tiene data-overlay-mode="lead". El atributo se setea en patient.js
   `open()` y se quita en `close()`.
   ═════════════════════════════════════════════════════════════════════ */
body[data-overlay-mode="lead"] [data-mode="full"] { display: none !important; }

/* ═════════════════════════════════════════════════════════════════════
   Appointment status badge (read-only para doctor en ficha paciente)
   ═════════════════════════════════════════════════════════════════════ */
.apt-status-badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: var(--surface-2);
  color: var(--text-2);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.apt-status-badge.status-RESERVED  { color: var(--warn-700); background: var(--warn-bg); border-color: color-mix(in oklch, var(--warn) 25%, var(--border)); }
[data-theme="dark"] .apt-status-badge.status-RESERVED { color: var(--warn-500); }
.apt-status-badge.status-SCHEDULED { color: var(--acc); background: color-mix(in oklch, var(--acc) 10%, transparent); border-color: color-mix(in oklch, var(--acc) 25%, var(--border)); }
.apt-status-badge.status-COMPLETED { color: var(--ok-700); background: var(--ok-bg); border-color: color-mix(in oklch, var(--ok) 25%, var(--border)); }
.apt-status-badge.status-CANCELED  { color: var(--err-700, var(--err)); background: var(--err-bg); border-color: color-mix(in oklch, var(--err) 25%, var(--border)); }

/* ═════════════════════════════════════════════════════════════════════
   Inicio del doctor (v2.0 f8)
   ───────────────────────────────────────────────────────────────────────
   Reusa el lenguaje del Inicio del admin (home-strip · home-block ·
   home-row): mismo registro de cuaderno, contenido distinto. Sólo se
   define acá lo que el doctor agrega — la columna de hoy destacada, los
   días agrupados de la semana y la barra de avance del tratamiento.
   ═════════════════════════════════════════════════════════════════════ */
.dochome-greeting { display: flex; flex-direction: column; gap: 2px; }
.dochome-sede {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
.dochome-sede.is-warning {
  color: var(--err-700, var(--err));
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
}

.dochome-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--gap-section);
  align-items: start;
}
/* La columna de hoy es la que se mira primero: filete de acento sobre el
   encabezado, en la dosis mínima que pide la regla del acento discreto. */
.dochome-block-today .home-block-head { border-bottom-color: var(--acc); }
.dochome-block-today .home-block-head h3 { color: var(--text-strong); }

.dochome-count {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* Filas sin paciente asociado: informan, no llevan a ningún lado. */
.home-row.is-static { cursor: default; }
.home-row.is-static:hover { background: transparent; }
.home-row[data-done="1"] .home-row-name,
.home-row[data-done="1"] .home-row-time { color: var(--text-muted); }
/* Reservada: la hora se tiñe de ámbar, el mismo color con el que la
   plataforma marca "sostenido pero sin confirmar". */
.home-row[data-res="1"] .home-row-time { color: var(--warn-700); }

.dochome-tag {
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: var(--r-sm);
  background: var(--bg-sunken);
  color: var(--text-muted);
}
.dochome-tag.is-done {
  color: var(--ok-700);
  background: var(--ok-bg);
}
/* v2.0 f9 — cita reservada: sostenida, sin confirmar. Borde punteado, el
   mismo código que usa la tarjeta del calendario. */
.dochome-tag.is-res {
  color: var(--warn-700);
  background: transparent;
  border: 1px dashed color-mix(in oklch, var(--warn) 45%, transparent);
}
[data-theme="dark"] .dochome-tag.is-done { color: var(--ok-500); }
[data-theme="dark"] .dochome-tag.is-res  { color: var(--warn-500); }

.dochome-day + .dochome-day { margin-top: var(--space-4); }
.dochome-day-head {
  padding: var(--space-2) 2px;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
.dochome-day-head::first-letter { text-transform: uppercase; }

/* Avance del tratamiento: porcentaje arriba, pasos hechos/total abajo.
   Los dos números viven en la columna izquierda, que es de ancho fijo,
   para que ninguno dependa del largo del nombre del plan. */
.dochome-pct {
  width: 44px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  font-variant-numeric: tabular-nums;
}
.dochome-pct-num { font-size: var(--text-sm); font-weight: 600; color: var(--text-strong); }
.dochome-pct-steps {
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--text-muted);
}
.dochome-bar {
  display: block;
  width: 56px;
  height: 4px;
  border-radius: var(--r-full);
  background: var(--bg-sunken);
  overflow: hidden;
}
.dochome-bar-fill {
  display: block;
  height: 100%;
  background: var(--info, var(--acc));
  border-radius: inherit;
}

@media (max-width: 1200px) {
  .dochome-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .dochome-block-today { grid-column: 1 / -1; }
}
@media (max-width: 768px) {
  .dochome-grid { grid-template-columns: 1fr; gap: var(--space-6); }
  .dochome-block-today { grid-column: auto; }
}

/* ═════════════════════════════════════════════════════════════════════
   First Visit — Diagnóstico inicial (Historia Clínica primera vez)
   ═════════════════════════════════════════════════════════════════════ */
.firstvisit-pane .pane-header { gap: var(--space-3); align-items: center; }
.firstvisit-header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
  flex-wrap: wrap;
}
.firstvisit-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-4);
}
.firstvisit-form[data-locked="true"] {
  /* Estado visual sutil: la HC firmada no se puede editar. Los inputs
     ya están disabled — esto agrega una capa de "esto es definitivo". */
  background: linear-gradient(to bottom, transparent, color-mix(in oklch, var(--bg-sunken) 35%, transparent));
  border-radius: var(--r-lg);
  padding: var(--space-3);
}

.fv-status-badge {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 10px;
  border-radius: 999px;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  border: 1px solid var(--border);
  background: var(--bg-sunken);
  color: var(--text-muted);
}
.fv-status-badge.fv-status-DRAFT {
  background: color-mix(in oklch, var(--acc) 10%, var(--surface));
  color: var(--acc-text);
  border-color: color-mix(in oklch, var(--acc) 25%, var(--border));
}
[data-theme="dark"] .fv-status-badge.fv-status-DRAFT { color: var(--acc); }
.fv-status-badge.fv-status-SIGNED {
  background: var(--ok-bg);
  color: var(--ok-700);
  border-color: color-mix(in oklch, var(--ok) 30%, var(--border));
}

.fv-banner {
  margin: var(--space-3) 0 0;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--r-md);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  border: 1px solid var(--border);
}
.fv-banner-info {
  background: color-mix(in oklch, var(--acc) 6%, var(--bg-sunken));
  border-color: color-mix(in oklch, var(--acc) 20%, var(--border));
  color: var(--text);
}
.fv-banner-signed {
  background: var(--ok-bg);
  border-color: color-mix(in oklch, var(--ok) 25%, var(--border));
  color: var(--text);
}

/* ── Odontograma v2 (SVG interactivo, fase 5) ────────────────────────
   Port del React-Odontogram-Modul: 32 dientes en 2 arcadas, plantillas
   SVG por capas. Paleta de herramientas arriba, resumen abajo. */
.odo2 { display: flex; flex-direction: column; gap: var(--space-3); position: relative; }
.odo2-loading, .odo2-error { font-size: var(--text-sm); padding: var(--space-4) 0; }
.odo2-palette {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.odo2-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  font-family: inherit;
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--text-muted);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.odo2-chip:hover { color: var(--text); background: var(--surface); }
.odo2-chip.active {
  background: var(--surface);
  color: var(--text-strong);
  border-color: var(--acc);
  box-shadow: 0 0 0 1px var(--acc);
}
.odo2-swatch {
  width: 9px;
  height: 9px;
  border-radius: var(--r-full);
  flex-shrink: 0;
}
.odo2-hint { font-size: var(--text-xs); margin: -4px 0 0; }
/* Chips de superficie (caries/obturación): etiqueta "caras" al costado. */
.odo2-chip-tag {
  font-size: var(--text-2xs); letter-spacing: var(--tracking-wide);
  text-transform: uppercase; color: var(--text-muted);
  padding: 1px 5px; border-radius: var(--r-full);
  background: color-mix(in oklch, var(--acc) 12%, transparent);
}
.odo2-chip.active .odo2-chip-tag { color: var(--acc); }
.odo2-tooth.is-picking { border-color: var(--acc); box-shadow: 0 0 0 1px var(--acc); }

/* Surface picker: popover anclado al diente con las 4 caras. */
.odo2-surfaces {
  position: absolute; z-index: 40; width: 208px;
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); box-shadow: var(--shadow-lg, 0 8px 24px oklch(0.2 0.02 40 / 0.18));
}
.odo2-surf-head { font-size: var(--text-xs); color: var(--text-muted); }
.odo2-surf-head strong { color: var(--text-strong); }
.odo2-surf-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.odo2-surf {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 9px; font-family: inherit; font-size: var(--text-xs); font-weight: 500;
  color: var(--text); background: var(--bg-sunken);
  border: 1px solid var(--border); border-radius: var(--r-sm); cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.odo2-surf:hover { background: var(--surface); border-color: color-mix(in oklch, var(--acc) 40%, var(--border)); }
.odo2-surf-abbr {
  width: 20px; height: 20px; flex-shrink: 0; display: inline-flex;
  align-items: center; justify-content: center; font-weight: 700;
  border-radius: var(--r-sm); background: var(--surface); border: 1px solid var(--border);
  font-variant-numeric: tabular-nums;
}
.odo2-surf-name { color: var(--text-muted); }
.odo2-surf.is-caries { border-color: var(--odo-caries, oklch(0.55 0.16 25)); }
.odo2-surf.is-caries .odo2-surf-abbr { background: oklch(0.55 0.16 25); color: oklch(0.98 0.01 25); border-color: transparent; }
.odo2-surf.is-caries .odo2-surf-name { color: var(--text); }
.odo2-surf.is-filled { border-color: oklch(0.58 0.10 235); }
.odo2-surf.is-filled .odo2-surf-abbr { background: oklch(0.58 0.10 235); color: oklch(0.98 0.01 235); border-color: transparent; }
.odo2-surf.is-filled .odo2-surf-name { color: var(--text); }
/* v2.0 f7.2 — fosa/fisura y fractura también se registran por cara. */
.odo2-surf.is-fissure { border-color: oklch(0.62 0.13 105); }
.odo2-surf.is-fissure .odo2-surf-abbr { background: oklch(0.62 0.13 105); color: oklch(0.24 0.05 105); border-color: transparent; }
.odo2-surf.is-fissure .odo2-surf-name { color: var(--text); }
.odo2-surf.is-fracture { border-color: oklch(0.60 0.13 55); }
.odo2-surf.is-fracture .odo2-surf-abbr { background: oklch(0.60 0.13 55); color: oklch(0.98 0.01 55); border-color: transparent; }
.odo2-surf.is-fracture .odo2-surf-name { color: var(--text); }
/* La oclusal cierra la retícula ocupando el ancho: arriba M/D, luego V/P
   (vestibular · palatina o lingual) y abajo la cara oclusal. */
.odo2-surf-wide { grid-column: 1 / -1; justify-content: center; }
.odo2-surf-done {
  align-self: flex-end; padding: 4px 14px; font-family: inherit; font-size: var(--text-xs); font-weight: 600;
  color: var(--acc-text); background: var(--acc-soft);
  border: 1px solid color-mix(in oklch, var(--acc) 25%, transparent); border-radius: var(--r-sm); cursor: pointer;
}
[data-theme="dark"] .odo2-surf-done { color: var(--acc); }
.odo2-chart {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow-x: auto;
}
.odo2-arch {
  display: flex;
  align-items: stretch;
  gap: 2px;
  min-width: 600px;
}
.odo2-mid {
  width: 1px;
  flex-shrink: 0;
  background: color-mix(in oklch, var(--acc) 30%, var(--border));
  margin: 0 3px;
}
.odo2-tooth {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: 3px 1px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.odo2-tooth:hover {
  background: var(--surface);
  border-color: color-mix(in oklch, var(--acc) 40%, var(--border));
}
.odo2-tooth:disabled { cursor: default; }
.odo2-tooth:disabled:hover { background: transparent; border-color: transparent; }
/* La arcada inferior muestra el número ARRIBA del diente (los números
   quedan hacia la línea de oclusión, como en la carta dental clásica). */
.odo2-lower .odo2-tooth { flex-direction: column-reverse; }
.odo2-svg { display: block; width: 100%; }
.odo2-svg svg { display: block; width: 100%; height: auto; }
.odo2-svg.mirror svg { transform: scaleX(-1); }
.odo2-svg.rot svg { transform: rotate(180deg); }
.odo2-svg.mirror.rot svg { transform: rotate(180deg) scaleX(-1); }
.odo2-num {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: var(--text-2xs);
  font-weight: 600;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.odo2-dot {
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
}
.odo2-summary {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.odo2-sum-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-variant-numeric: tabular-nums;
}
/* Dark: los SVG traen encía/hueso con colores propios claros — se
   atenúan levemente para no reventar sobre fondo oscuro. */
[data-theme="dark"] .odo2-chart { background: color-mix(in oklch, var(--n-800) 60%, var(--bg-sunken)); }
[data-theme="dark"] .odo2-svg svg { filter: brightness(0.88) saturate(0.92); }

/* ── Condiciones médicas (checklist HC, fase 5) ──────────────────── */
.fv-conditions-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 2px var(--space-4);
}
/* label.fv-cond debe ganarle al estilo de label de formulario
   (columna + mayúsculas + caps-spacing): acá es una fila de check. */
label.fv-cond {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-2);
  padding: 5px var(--space-2);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
label.fv-cond span {
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--text-sm);
  font-weight: 400;
  color: var(--text);
}
.fv-cond:hover { background: var(--bg-sunken); }
.fv-cond input[type="checkbox"] { accent-color: var(--acc); width: 15px; height: 15px; flex-shrink: 0; margin: 0; }
.fv-cond input[type="checkbox"]:disabled + span { color: var(--text-muted); }
.fv-cond:has(input:checked) span { color: var(--text-strong); font-weight: 500; }

/* ── HC guiada v2 (fase 5): chips, segmentadas, examen físico, ATM ────
   Reusan el lenguaje del odontograma (.odo2-chip) y de las pills. Los
   <label> de chip y segmentada llevan el input visualmente oculto pero
   accesible (focusable, en el a11y tree); ganan al estilo genérico
   `form label` (columna + mayúsculas) mediante clase propia. */
.fv-mt { margin-top: var(--space-4); }

/* Label estilo formulario para bloques que no pueden ser <label>. */
.fv-field-label, .fv-exam-label, .fv-quick-hint {
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.fv-field, .fv-subfield { display: flex; flex-direction: column; gap: var(--space-2); }
.fv-detail-line { width: 100%; }

/* Chips de inserción rápida (motivo). Borde punteado = acción de insertar. */
.fv-quick-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: var(--space-3); }
.fv-quick-hint { margin-right: 2px; }
.fv-quick {
  font-family: inherit;
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--acc-text);
  background: color-mix(in oklch, var(--acc) 8%, var(--surface));
  border: 1px dashed color-mix(in oklch, var(--acc) 35%, var(--border));
  border-radius: var(--r-full);
  padding: 4px 11px;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.fv-quick:hover {
  background: color-mix(in oklch, var(--acc) 16%, var(--surface));
  border-color: color-mix(in oklch, var(--acc) 50%, var(--border));
}
[data-theme="dark"] .fv-quick { color: var(--acc); }

/* Grupo de chips multi-selección (hábitos, antecedentes odontológicos). */
.fv-chip-group { display: flex; flex-wrap: wrap; gap: 6px; }
label.fv-chip {
  position: relative;
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  padding: 5px 12px;
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-muted);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
label.fv-chip > span, label.fv-seg-opt > span {
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--text-xs);
  font-weight: inherit;
  color: inherit;
}
/* input oculto pero accesible: cubre el control, transparente, focusable. */
.fv-chip > input, .fv-seg-opt > input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.fv-chip:hover { color: var(--text); background: var(--surface); }
.fv-chip:has(input:checked) {
  color: var(--acc-text);
  background: color-mix(in oklch, var(--acc) 12%, var(--surface));
  border-color: color-mix(in oklch, var(--acc) 45%, var(--border));
  font-weight: 600;
}
[data-theme="dark"] .fv-chip:has(input:checked) { color: var(--acc); }
.fv-chip:has(input:focus-visible) { outline: 2px solid var(--acc); outline-offset: 2px; }
.fv-chip:has(input:disabled) { cursor: default; }
.fv-chip:has(input:disabled):hover { color: var(--text-muted); background: var(--bg-sunken); }
.fv-chip:has(input:checked:disabled):hover {
  color: var(--acc-text);
  background: color-mix(in oklch, var(--acc) 12%, var(--surface));
}

/* Segmentada de selección única (Normal/Hallazgo, Angle, pronóstico, ATM). */
.fv-seg {
  display: inline-flex;
  max-width: 100%;
  padding: 3px;
  gap: 2px;
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
label.fv-seg-opt {
  position: relative;
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  padding: 4px 13px;
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-muted);
  border-radius: var(--r-sm);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.fv-seg-opt:hover { color: var(--text); }
.fv-seg-opt:has(input:checked) {
  background: var(--surface);
  color: var(--text-strong);
  font-weight: 600;
  box-shadow: var(--shadow-xs);
}
.fv-seg-opt:has(input:focus-visible) { outline: 2px solid var(--acc); outline-offset: 2px; }
.fv-seg-opt:has(input:disabled) { cursor: default; }

/* Examen físico: fila label · segmentada · detalle (revelado). */
.fv-exam-list { display: flex; flex-direction: column; }
.fv-exam-row {
  display: grid;
  grid-template-columns: 172px 1fr;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border);
}
.fv-exam-row:first-child { padding-top: 0; }
.fv-exam-row:last-child { border-bottom: 0; padding-bottom: 0; }
.fv-exam-controls { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); }
.fv-exam-angle { display: inline-flex; align-items: center; gap: var(--space-2); }
.fv-detail { grid-column: 1 / -1; }
.fv-detail > textarea { width: 100%; }
/* El detalle se revela sólo si hay hallazgo o ya hay texto (HC legacy). */
.fv-exam-row:not(:has(input[value="FINDING"]:checked)):not(:has(.fv-detail textarea:not(:placeholder-shown))) .fv-detail {
  display: none;
}

/* ATM. */
.fv-atm-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--space-4);
  align-items: start;
}
.fv-atm-opening { max-width: 128px; }

@media (max-width: 640px) {
  .odo2-chart { padding: var(--space-2); }
  .odo2-arch { min-width: 520px; }
  .fv-conditions-grid { grid-template-columns: 1fr; }
  .fv-exam-row { grid-template-columns: 1fr; gap: var(--space-2); }
  .fv-atm-grid { grid-template-columns: 1fr; }
  .fv-seg { width: 100%; }
  .fv-seg-opt { flex: 1; }
}

/* ── Signature modal ─────────────────────────────────────────────── */
.modal.modal-sign { max-width: 680px; width: 100%; }
.modal-sign .modal-intro {
  margin: 0 0 var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: var(--leading-snug);
}
.modal-sign .sign-label {
  display: block;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--space-2);
}
/* La firma se renderiza siempre sobre fondo blanco con trazo oscuro,
   independientemente del tema. Esto garantiza legibilidad de la firma en
   pantalla y consistencia con la imagen que se compone en el PDF. */
.sign-canvas-wrap {
  position: relative;
  background: #ffffff;
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--r-md);
  overflow: hidden;
}
.sign-canvas {
  display: block;
  width: 100%;
  height: 180px;
  touch-action: none;          /* impide scroll mientras se firma */
  cursor: crosshair;
  background: #ffffff;
  color-scheme: light;         /* evita que el UA oscurezca el canvas en dark */
}
.sign-clear-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  padding: 4px 10px;
  font-size: var(--text-xs);
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid #d0d0d0;
  border-radius: var(--r-sm);
  color: #444;
  cursor: pointer;
}
.sign-clear-btn:hover { color: #111; border-color: #888; background: #fff; }
.sign-disclaimer {
  margin-top: var(--space-2);
  font-size: var(--text-2xs);
  color: var(--text-muted);
  line-height: var(--leading-snug);
}

/* ───────────────────────── Animaciones ligeras ───────────────────────── */
.view.active { animation: view-in var(--dur-base) var(--ease); }
@keyframes view-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ═══════════════════════════════════════════════════════════════════
   Consentimientos informados (v1.2 Fase 5)
   ──────────────────────────────────────────────────────────────────
   Tres bloques de estilos:
   1) Listado de consents dentro de la card del TreatmentPlan.
   2) Documento "impreso" en el modal de preview — fondo blanco
      siempre para que el documento se lea como un papel físico,
      independiente del theme.
   3) Modal de doble firma (canvases lado a lado).
   ═══════════════════════════════════════════════════════════════════ */

/* — Listado en la card del plan — */
/* Alineado con .payments-section y .plan-notes (mismo padding horizontal del
   card). Sin esto el bloque queda pegado al borde izquierdo del plan-card,
   desalineado respecto al resto del contenido. */
.consents-section {
  padding: var(--space-3) var(--space-4);
  border-top: 1px dashed var(--border);
}
.consents-section-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-2);
}
.consents-section-head h4 {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0;
}
.consents-list {
  display: flex; flex-direction: column; gap: 4px;
}
.consents-empty {
  font-size: var(--text-xs);
  color: var(--text-muted);
  padding: var(--space-2) 0;
}
.consent-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--bg-sunken);
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  cursor: pointer;
  font-size: var(--text-sm);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.consent-row:hover { border-color: var(--border-strong); background: var(--bg-elev); }
.consent-row-name { color: var(--text); font-weight: 500; }
.consent-row-date { font-size: var(--text-xs); }

/* ═══ Ficha v2 (fase 5/6) — Tratamiento (servicios + avance) · bitácora
   anidada · Presupuesto. Reusan .plan-card / .plan-progress / .visits-list;
   la barra de avance clínico va en --info para distinguirla de la financiera
   (terracota). ═══ */
.treatment-card .plan-head-actions,
.budget-card .plan-head-actions { flex-wrap: wrap; justify-content: flex-end; }

.svc-progress {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  background: var(--bg-sunken);
}
.svc-progress-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3);
}
.svc-progress-label {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.svc-progress-count {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}
.plan-progress-bar.clinical { background: var(--info); }
.plan-progress-bar.clinical.full { background: var(--ok); }

/* Checklist de servicios del plan (toggle "hecho"). */
.svc-list {
  display: flex; flex-direction: column;
  padding: var(--space-2) var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--border);
}
.svc-row {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 6px var(--space-2);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.svc-row:hover { background: var(--bg-sunken); }
.svc-row > input[type="checkbox"] {
  accent-color: var(--info); width: 16px; height: 16px; flex-shrink: 0; margin: 0; cursor: pointer;
}
.svc-name { flex: 1; min-width: 0; font-size: var(--text-sm); color: var(--text); }
/* Apunte de la línea (ej. el diente). Va pegado al nombre en el
   seguimiento, la cotización y el presupuesto: es parte del servicio. */
.svc-note {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 0 5px;
  border-radius: var(--r-xs);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: var(--text-2xs);
  font-weight: 500;
  vertical-align: 1px;
}
.plan-items-readout .svc-note { background: var(--surface); }
.svc-name small { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.svc-row.done .svc-name {
  color: var(--text-muted);
  text-decoration: line-through;
  text-decoration-color: color-mix(in oklch, var(--text-muted) 50%, transparent);
}
.svc-done-at { font-size: var(--text-2xs); color: var(--text-muted); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.svc-empty { padding: var(--space-2); font-size: var(--text-xs); }

/* Bitácora anidada dentro del plan (y en la card General "sin plan"). */
.bitacora-section {
  padding: var(--space-3) var(--space-4) var(--space-4);
  border-top: 1px dashed var(--border);
}
.bitacora-section-head { margin-bottom: var(--space-2); }
.bitacora-section-head h4 {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0;
}
.bitacora-empty { font-size: var(--text-xs); color: var(--text-muted); padding: var(--space-2) 0; }
.treatment-card .visits-list { gap: var(--space-2); }
.general-card { border-style: dashed; }

/* Checklist "servicios realizados" en el modal de evolución. */
.record-services-block { display: flex; flex-direction: column; gap: var(--space-2); }
.record-services { display: flex; flex-direction: column; gap: 2px; }
.record-services-hint { font-size: var(--text-xs); padding: var(--space-1) 0; }
.record-svc { padding: 4px var(--space-2); }
/* Checklist de evolución: componentes agrupados bajo su paquete. */
.record-svc-group { padding: var(--space-1) 0; }
.record-svc-group + .record-svc-group { border-top: 1px dashed var(--border); margin-top: 2px; }
.record-svc-group-name {
  font-size: var(--text-2xs); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--text-muted);
  padding: var(--space-1) var(--space-2) 2px;
}
.record-svc-comp { padding-left: var(--space-4); }

/* ── Seguimiento por componentes (paquetes) en el tab Tratamiento ─────── */
.svc-pkg {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  margin: 4px 0;
  overflow: hidden;
}
.svc-pkg-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3);
  padding: 6px var(--space-3);
  background: var(--bg-sunken);
  border-bottom: 1px solid var(--border);
}
.svc-pkg-name { font-size: var(--text-sm); font-weight: 600; color: var(--text-strong); }
.svc-pkg-name small { font-weight: 400; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.svc-pkg-count {
  font-size: var(--text-2xs); font-weight: 600; color: var(--text-muted);
  font-variant-numeric: tabular-nums; flex-shrink: 0;
}
.svc-pkg.done .svc-pkg-count { color: var(--ok); }
.svc-pkg-comps { display: flex; flex-direction: column; padding: 2px var(--space-2) 4px; }
.svc-row.comp { padding-left: var(--space-2); }

/* Componente multi-etapa (placa protectora): nombre + segmentada de etapas. */
.svc-comp-staged {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3);
  padding: 6px var(--space-2);
}
.svc-comp-name { font-size: var(--text-sm); color: var(--text); flex-shrink: 0; }
.svc-comp-staged.done .svc-comp-name { color: var(--text-muted); }
.svc-stage-seg {
  display: inline-flex; padding: 3px; gap: 2px;
  background: var(--bg-sunken); border: 1px solid var(--border); border-radius: var(--r-md);
}
.svc-stage-opt {
  padding: 3px 11px; font-size: var(--text-xs); font-weight: 500;
  color: var(--text-muted); background: transparent; border: 0;
  border-radius: var(--r-sm); cursor: pointer; white-space: nowrap;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.svc-stage-opt:hover { color: var(--text); }
.svc-stage-opt.is-active {
  background: var(--surface); color: var(--text-strong); font-weight: 600; box-shadow: var(--shadow-xs);
}
.svc-stage-opt.is-past { color: color-mix(in oklch, var(--info) 80%, var(--text-muted)); }
.svc-stage-opt.is-active.is-done { color: var(--ok); }

/* ── Editor de composición en el modal de precios ─────────────────────── */
.price-comp-block {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3); margin: var(--space-1) 0;
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--bg-sunken);
}
.price-comp-headline { display: flex; flex-direction: column; gap: 2px; }
.price-comp-title {
  font-size: var(--text-2xs); letter-spacing: var(--tracking-caps);
  text-transform: uppercase; color: var(--text-muted); font-weight: 600;
}
.price-comp-quick { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.price-comp-quick-label { font-size: var(--text-xs); }
.chip-add {
  font-size: var(--text-xs); font-weight: 500; color: var(--acc-text);
  background: var(--acc-soft); border: 1px solid color-mix(in oklch, var(--acc) 22%, transparent);
  border-radius: var(--r-full, 999px); padding: 3px 10px; cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.chip-add:hover { background: color-mix(in oklch, var(--acc) 18%, var(--surface)); }
[data-theme="dark"] .chip-add { color: var(--acc); }
.price-comp-list { display: flex; flex-direction: column; gap: var(--space-2); }
.price-comp-empty { font-size: var(--text-xs); padding: 2px 0; }
.price-comp-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center; gap: var(--space-2) var(--space-3);
  padding: var(--space-2); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-sm);
}
.price-comp-row > input.price-comp-name { margin: 0; }
.price-comp-staged-toggle {
  display: inline-flex; align-items: center; gap: 6px; margin: 0;
  font-size: var(--text-xs); color: var(--text-muted); white-space: nowrap; cursor: pointer;
}
.price-comp-staged-toggle input { width: 15px; height: 15px; accent-color: var(--acc); margin: 0; cursor: pointer; }
.price-comp-del {
  width: 26px; height: 26px; flex-shrink: 0; display: inline-flex;
  align-items: center; justify-content: center; font-size: 18px; line-height: 1;
  color: var(--text-muted); background: transparent; border: 1px solid var(--border);
  border-radius: var(--r-sm); cursor: pointer;
}
.price-comp-del:hover { color: var(--danger, var(--acc)); border-color: currentColor; }
.price-comp-stages { grid-column: 1 / -1; margin: 0; }
.price-comp-stages-help { grid-column: 1 / -1; font-size: var(--text-2xs); margin-top: -2px; }
.btn-sm { padding: 4px 12px; font-size: var(--text-xs); align-self: flex-start; }

/* Composición en el panel de detalle del servicio (solo lectura). */
.prices-comp-detail-list { list-style: none; margin: var(--space-1) 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.prices-comp-item { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); font-size: var(--text-sm); }
.prices-comp-item-name { color: var(--text); }
.prices-comp-item-stages { font-size: var(--text-xs); color: var(--text-muted); text-align: right; }

@media (max-width: 640px) {
  .price-comp-row { grid-template-columns: 1fr auto; }
  .price-comp-staged-toggle { grid-column: 1; }
  .svc-comp-staged { align-items: flex-start; }
}

@media (max-width: 640px) {
  .plan-summary { grid-template-columns: 1fr 1fr; }
  /* En móvil el head del plan apila: título arriba, acciones abajo (evita
     que los botones se encimen con el nombre largo del plan). */
  .plan-head { flex-direction: column; align-items: stretch; gap: var(--space-2); }
  .plan-head-actions { justify-content: flex-start; flex-wrap: wrap; }
}

/* — Modal preview — ancho extra para que el documento se vea casi a tamaño real — */
.modal.modal-consent-preview {
  max-width: 980px;
  width: 100%;
}
.modal-consent-preview .modal-body {
  background: var(--bg-sunken);
  padding: var(--space-5);
  max-height: 78vh;
  overflow-y: auto;
}
.consent-preview-body {
  display: flex;
  justify-content: center;
}
.consent-preview-admin {
  display: inline-flex;
  gap: var(--space-2);
}

/* — Documento renderizado: simula la hoja impresa — */
.consent-document {
  background: #ffffff;
  color: #1a1a1a;
  width: 100%;
  max-width: 820px;
  padding: 40px 48px 32px;
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md, 0 4px 20px rgba(0,0,0,0.12));
  font-family: 'Inter Variable', 'Inter', system-ui, -apple-system, sans-serif;
  font-feature-settings: "tnum" 0;   /* sólo el header del CRM usa tabular-nums; el documento es prosa */
  line-height: 1.45;
  font-size: 11.5px;
}
.consent-header {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-4);
  padding-bottom: 16px;
  margin-bottom: 16px;
  border-bottom: 1px solid #e5e0d8;
}
.consent-header-brand {
  display: flex;
  align-items: center;
  gap: 12px;
}
.consent-logo {
  width: 64px;
  height: 64px;
  object-fit: contain;
  display: block;
}
.consent-header-brand-text { line-height: 1.1; }
.consent-brand-name {
  font-size: 22px;
  font-weight: 600;
  color: #2c2620;
  letter-spacing: 0.02em;
}
.consent-brand-tagline {
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #8a7e6e;
  margin-top: 2px;
}
.consent-header-title {
  text-align: right;
  font-size: 11px;
  color: #b25030;          /* terracota print-safe */
  line-height: 1.35;
  font-weight: 600;
}
.consent-header-subtitle { font-weight: 600; }
.consent-header-version  { font-weight: 500; opacity: 0.9; margin-top: 2px; }

/* Tabla de metadatos arriba */
.consent-meta-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 16px;
  font-size: 10.5px;
}
.consent-meta-table th {
  background: #faf7f2;
  color: #7a6a55;
  font-weight: 600;
  text-align: left;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-size: 9px;
  padding: 8px 10px;
  border: 1px solid #e5e0d8;
}
.consent-meta-table td {
  padding: 10px;
  border: 1px solid #e5e0d8;
  vertical-align: middle;
  height: 28px;
}

.consent-paragraph {
  margin: 0 0 10px;
  text-align: justify;
}
.consent-section-h {
  text-align: center;
  margin: 18px 0 10px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #2c2620;
}

.consent-fillin {
  border: 1px solid #e5e0d8;
  padding: 12px 14px;
  margin: 6px 0 12px;
  min-height: 30px;
  background: #fbf9f5;
  border-radius: 3px;
}
.consent-defbox {
  background: #fbf9f5;
  border: 1px solid #e5e0d8;
  padding: 10px 12px;
  margin: 6px 0 8px;
  border-radius: 3px;
}
.consent-defbox strong { color: #2c2620; }
.consent-options-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 14px;
}
.consent-option {
  flex: 1 1 auto;
  padding: 8px 12px;
  border: 1px solid #e5e0d8;
  border-radius: 3px;
  font-weight: 500;
  min-width: 180px;
}

.consent-risks-table {
  width: 100%;
  border-collapse: collapse;
  margin: 6px 0 14px;
  font-size: 10.5px;
}
.consent-risks-table th, .consent-risks-table td {
  border: 1px solid #e5e0d8;
  padding: 8px 10px;
  vertical-align: top;
}
.consent-risks-table th {
  background: #faf7f2;
  text-align: left;
  font-size: 9.5px;
  letter-spacing: 0.05em;
  color: #7a6a55;
  text-transform: uppercase;
}
.consent-risks-label {
  text-align: center !important;
  font-weight: 700;
  background: #fbf9f5;
  width: 25%;
}
.consent-risks-table ol {
  margin: 0;
  padding-left: 18px;
}
.consent-risks-subhead {
  font-weight: 700;
  margin-bottom: 4px;
  background: #faf7f2;
  padding: 4px 8px;
  border-radius: 3px;
  display: inline-block;
}

.consent-alt-table {
  width: 100%;
  border-collapse: collapse;
  margin: 6px 0 14px;
}
.consent-alt-table th, .consent-alt-table td {
  border: 1px solid #e5e0d8;
  padding: 12px;
  vertical-align: top;
}
.consent-alt-label {
  background: #fbf9f5;
  width: 28%;
  font-size: 10px;
  letter-spacing: 0.05em;
  color: #2c2620;
  font-weight: 700;
  text-transform: uppercase;
}
.consent-alt-value {
  min-height: 50px;
  font-size: 11px;
}

.consent-bullets {
  margin: 0 0 12px;
  padding-left: 22px;
}
.consent-bullets li { margin-bottom: 2px; }

/* Tabla de firmas */
.consent-sig-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 22px;
}
.consent-sig-table th {
  background: #faf7f2;
  color: #7a6a55;
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 8px 10px;
  border: 1px solid #e5e0d8;
  text-align: center;
  font-weight: 600;
}
.consent-sig-table td {
  border: 1px solid #e5e0d8;
  padding: 12px;
  vertical-align: bottom;
  width: 50%;
  text-align: center;
  height: 130px;
}
.consent-sig-img {
  max-height: 70px;
  max-width: 80%;
  display: block;
  margin: 0 auto;
}
.consent-sig-placeholder {
  color: #b8b0a3;
  font-style: italic;
  font-size: 10.5px;
  padding-top: 28px;
  padding-bottom: 12px;
}
.consent-sig-line {
  margin-top: 4px;
  border-top: 1px solid #2c2620;
  padding-top: 4px;
  font-weight: 700;
  font-size: 11px;
}
.consent-sig-cc {
  margin-top: 4px;
  font-size: 10px;
  color: #2c2620;
  font-weight: 700;
  text-align: left;
}

.consent-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 18px;
  padding: 10px 14px;
  background: #1a1a1a;
  color: #ffffff;
  font-size: 9.5px;
  border-radius: 3px;
}

.consent-signed-note {
  font-size: 10px;
  color: #6e6052;
  margin-top: 10px;
  text-align: center;
  font-style: italic;
}

/* — Modal create — bloque de checkboxes — */
.consent-options-block {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: var(--space-2);
  margin-bottom: var(--space-3);
}

/* Spacing entre fields del modal de create. Cada label directo del form
   queda separado del anterior; sin esto, los textareas de "Otras
   alternativas" se pegan contra los checkboxes de arriba. */
#consent-create-form > label,
#consent-create-form > .form-row,
#consent-create-form > #consent-template-fields > label,
#consent-create-form > #consent-template-fields > .consent-options-block {
  margin-bottom: var(--space-3);
}
#consent-create-form > label:last-of-type,
#consent-create-form > #consent-template-fields > label:last-of-type {
  margin-bottom: 0;
}

/* — Modal sign (doble firma) — */
.modal.modal-consent-sign {
  max-width: 920px;
  width: 100%;
}
.consent-sign-readouts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
  padding: var(--space-3);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  margin-bottom: var(--space-4);
  font-size: var(--text-sm);
}
.consent-sign-readouts > div { display: flex; flex-direction: column; gap: 2px; }
.consent-sign-canvases {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}
.consent-sign-canvas-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

@media (max-width: 768px) {
  .consent-sign-canvases { grid-template-columns: 1fr; }
  .consent-document { padding: 24px 16px; font-size: 11px; }
  .consent-header { grid-template-columns: 1fr; text-align: left; }
  .consent-header-title { text-align: left; }
}

/* ═══════════════════════════════════════════════════════════════════
   Modal de motivo obligatorio (Fase 7 — audit log)
   ═══════════════════════════════════════════════════════════════════ */
.modal.modal-audit-reason {
  max-width: 540px;
  width: 100%;
}
.audit-reason-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-top: var(--space-3);
}
.audit-reason-label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}
#audit-reason-textarea {
  width: 100%;
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-sm);
  resize: vertical;
  min-height: 100px;
}
#audit-reason-textarea:focus {
  outline: none;
  border-color: var(--acc);
  box-shadow: 0 0 0 2px color-mix(in oklch, var(--acc) 25%, transparent);
}
.audit-reason-counter {
  align-self: flex-end;
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 2px;
}

/* ═══════════════════════════════════════════════════════════════════
   v1.4 — Componentes nuevos (destacados, calendario, embudo)
   ═══════════════════════════════════════════════════════════════════ */

/* ── Destacados (aj3) — botón de estrella en la Bandeja ────────────── */
.col-star { width: 36px; padding-left: var(--space-2) !important; padding-right: 0 !important; }
.cell-star { padding-left: var(--space-2) !important; padding-right: 0 !important; text-align: center; }
.star-btn {
  background: transparent;
  border: 0;
  padding: 4px;
  cursor: pointer;
  color: var(--text-disabled);
  border-radius: var(--r-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.star-btn svg {
  display: block;
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linejoin: round;
  stroke-linecap: round;
  transition: fill var(--dur-fast) var(--ease);
}
.star-btn:hover { color: var(--acc); background: var(--bg-sunken); }
.star-btn:active { transform: scale(0.92); }
.star-btn.is-starred { color: var(--acc); }
.star-btn.is-starred svg { fill: currentColor; }
.star-btn.is-starred:hover { color: var(--acc-hover); background: var(--acc-soft); }

/* Pill "Destacados" en la barra de filtros */
.pill.pill-star {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.pill.pill-star svg { color: var(--acc); }
.pill.pill-star.active svg { color: currentColor; }

/* ── Estado INACTIVE (aj4) ────────────────────────────────────────── */
.status-chip.status-INACTIVE {
  color: var(--text-muted);
  border-color: var(--border-strong);
  background: var(--bg-sunken);
  font-style: italic;
}
.status-select.status-INACTIVE { color: var(--text-muted); font-style: italic; }
[data-theme="dark"] .status-select.status-INACTIVE { color: var(--text-dim); }

/* ── Calendario: tratamiento + ingreso en bloques (aj1) ───────────── */
.cal-event-block .ev-treatment {
  font-size: var(--text-2xs);
  line-height: 1.18;
  opacity: 0.85;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 500;
}
.cal-event-block .ev-revenue {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  margin-left: 2px;
}

/* El tooltip flotante propio del calendario se retiró en v2.2: hacía lo
   mismo que `.rlx-tip`, que ahora sirve a toda la plataforma. Las
   tarjetas declaran `data-tip` como cualquier otro elemento. */

/* ═══════════════════════════════════════════════════════════════════
   v1.4 — Drawer hamburguesa + responsive sistemático
   Desktop sigue tal cual. <=768px usa drawer. <=640px usa cards.
   ═══════════════════════════════════════════════════════════════════ */

/* Botón hamburguesa (oculto en desktop) */
.nav-hamburger {
  display: none;
  width: 36px;
  height: 36px;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text);
  cursor: pointer;
  padding: 0;
  margin-right: var(--space-2);
}
.nav-hamburger svg { width: 18px; height: 18px; }
.nav-hamburger:hover { background: var(--bg-sunken); }

/* Backdrop del drawer */
.nav-drawer-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  z-index: 70;
  animation: fadeIn 0.18s ease;
}
.nav-drawer-backdrop.open { display: block; }
@keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }

/* ═════════ <=768px — Sidebar como drawer + ajustes de toolbar ═════════ */
@media (max-width: 768px) {
  /* Shell v2 — el sidebar sale del flujo y se vuelve drawer deslizante.
     La subnav (.main-nav) se queda como fila horizontal scrolleable. */
  :root { --sb-cur: 0px; }

  .nav-hamburger { display: inline-flex; }

  .sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    height: 100vh; height: 100dvh;
    width: min(272px, 82vw);
    transform: translateX(-100%);
    transition: transform 0.24s var(--ease);
    z-index: 80;
    background: var(--bg-elev);
    box-shadow: none;
  }
  body.nav-drawer-open .sidebar {
    transform: translateX(0);
    box-shadow: var(--shadow-lg);
  }
  /* En drawer no tiene sentido contraer */
  .sidebar-foot { display: none; }
  .side-item { height: 42px; font-size: var(--text-md); }

  /* Drawer abierto → no scroll del body */
  body.nav-drawer-open { overflow: hidden; }

  /* Toolbar más compacta en mobile */
  .toolbar { padding-left: 0; padding-right: 0; }
  .toolbar-row { padding: 0 var(--space-3); }
  .toolbar-row-sub { padding-left: var(--space-3); padding-right: var(--space-3); }

  /* Search input ancho completo (ya estaba en orden 99) */
  .search-input {
    height: 38px;
    font-size: var(--text-md); /* 15px evita zoom en iOS */
  }

  /* Botón "+ Nuevo lead" más compacto */
  .toolbar .btn-primary { white-space: nowrap; }

  /* Inputs y selects: target táctil mínimo 36px */
  input[type="text"], input[type="email"], input[type="number"],
  input[type="tel"], input[type="date"], input[type="datetime-local"],
  input[type="password"], select, textarea {
    font-size: var(--text-md); /* 15px = no zoom auto en iOS */
    min-height: 36px;
  }
  /* Botones primarios y secundarios — target 38px mínimo */
  .btn { min-height: 38px; }
}

/* ═════════ <=640px — Cards en lugar de tabla ═════════ */
@media (max-width: 640px) {
  /* Bandeja de Leads: cada fila se convierte en una card vertical.
     Las columnas individuales se reorganizan en bloques etiquetados.
     Esto reemplaza las reglas previas que ocultaban columnas — perder
     información en móvil era el bug principal. */
  /* v2.2 — la card de lead con la fila editable: identidad arriba
     (nombre + teléfono, que son dos campos escribibles), ubicación a su
     derecha, y abajo canal · estado · ingreso. La pauta se queda fuera de
     la card: en móvil se consulta y se corrige desde la ficha. */
  #leads-grid { display: block; border: 0; }
  #leads-grid thead { display: none; }
  #leads-grid tbody { display: block; }
  #leads-grid tr:not(.empty-row) {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "identity city"
      "channel  status"
      "date     actions";
    gap: 8px 10px;
    align-items: center;
    padding: var(--space-3);
    margin-bottom: var(--space-3);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-xs);
  }
  #leads-grid tbody tr:not(.empty-row) > td { display: block; padding: 0; border: 0; min-width: 0; }
  #leads-grid .lead-identity { grid-area: identity; }
  #leads-grid .lead-city     { grid-area: city; max-width: 8rem; }
  #leads-grid .lead-channel  { grid-area: channel; display: block; }
  #leads-grid .lead-ad       { display: none; }
  #leads-grid .lead-status   { grid-area: status; }
  #leads-grid .lead-date     { grid-area: date; }
  #leads-grid .lead-actions  { grid-area: actions; text-align: right; }

  /* En card, los campos se ven como campos: sin hover que revele el borde,
     el dedo no sabe dónde puede escribir. */
  #leads-grid .cell-input { border-color: var(--border); background: var(--bg-sunken); }
  #leads-grid .cell-name { font-size: var(--text-md); }
  #leads-grid .cell-select { width: 100%; font-size: var(--text-xs); }
  #leads-grid .quick-act { opacity: 1; }
  #leads-grid .empty-row td { text-align: center !important; padding: var(--space-5) var(--space-3) !important; }
  #leads-grid .empty-row { background: transparent; border: 0; }

  /* Pacientes: misma técnica. v2.0 f9.5 — la fila es una tarjeta de
     cuatro renglones: identidad (que ya trae el documento adentro),
     estado + doctor, agenda, y al pie saldo + acciones rápidas. */
  #patients-grid { display: block; border: 0; }
  #patients-grid thead { display: none; }
  #patients-grid tbody { display: block; }
  #patients-grid tr.patient-row {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "name name"
      "status doctor"
      "lastvisit nextvisit"
      "balance actions";
    gap: 6px 12px;
    padding: var(--space-3);
    margin-bottom: var(--space-3);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-xs);
  }
  #patients-grid tr.patient-row > td { display: block; padding: 0; border: 0; min-width: 0; }
  /* La identidad conserva sus dos renglones: el `display:block` de arriba
     desarmaba el flex y el documento se pegaba al nombre en la misma
     línea, salvo cuando era largo y wrapeaba solo. */
  #patients-grid tr.patient-row > td:nth-child(1) {
    grid-area: name;
    display: flex;
    flex-direction: column;
    gap: 2px;
  }
  #patients-grid tr.patient-row .patient-row-name { font-weight: 600; font-size: var(--text-md); }
  #patients-grid tr.patient-row > td:nth-child(2) { grid-area: doctor; font-size: var(--text-xs); color: var(--text-muted); text-align: right; }
  #patients-grid tr.patient-row > td:nth-child(2) .pt-doctor { justify-content: flex-end; }
  #patients-grid tr.patient-row > td:nth-child(3) { grid-area: status; }
  #patients-grid tr.patient-row > td:nth-child(4),
  #patients-grid tr.patient-row > td:nth-child(5) {
    font-size: var(--text-xs);
    color: var(--text-muted);
  }
  #patients-grid tr.patient-row > td:nth-child(4) { grid-area: lastvisit; }
  #patients-grid tr.patient-row > td:nth-child(4)::before { content: "Última: "; }
  #patients-grid tr.patient-row > td:nth-child(5) { grid-area: nextvisit; text-align: right; }
  #patients-grid tr.patient-row > td:nth-child(5)::before { content: "Próxima: "; }
  /* En la tarjeta las dos líneas de fecha vuelven a una sola: el renglón
     ya está rotulado y no hay ancho para apilar. */
  #patients-grid tr.patient-row .pt-date-abs,
  #patients-grid tr.patient-row .pt-date-rel { display: inline; }
  #patients-grid tr.patient-row .pt-date-rel::before { content: " · "; }
  #patients-grid tr.patient-row > td:nth-child(6) { grid-area: balance; font-weight: 600; font-size: var(--text-sm); align-self: center; }
  #patients-grid tr.patient-row > td:nth-child(7) { grid-area: actions; text-align: right; }
  #patients-grid .empty-state { text-align: center; padding: var(--space-5) var(--space-3); }

  /* Patient overlay header: compactar botones */
  .overlay-actions { gap: var(--space-1) !important; flex-wrap: wrap; }
  .overlay-actions .btn { padding: 0 var(--space-2); font-size: var(--text-xs); min-height: 32px; }
  /* En móvil el "Exportar expediente" satura el header. El usuario puede
     hacerlo desde la pestaña Documentos. */
  #patient-dossier-btn { display: none; }

  /* Profile tabs scrollables horizontal con indicador visual */
  .profile-tabs { overflow-x: auto; flex-wrap: nowrap; scroll-snap-type: x mandatory; }
  .profile-tab { flex-shrink: 0; scroll-snap-align: start; padding: var(--space-2) var(--space-3); }

  /* Calendario en móvil: forzar vista día por default es una decisión
     de UX que reside en JS. Acá solo dejamos los bloques angostos
     legibles y la legenda en horizontal scroll. */
  .cal-legend { overflow-x: auto; flex-wrap: nowrap; }
  .cal-legend .legend-item { flex-shrink: 0; }
  /* v1.5.5 — la vista semana mide 36 + 7×80 = 596px y no cabe en un móvil
     vertical. #calendar-container tenía overflow:hidden, lo que recortaba los
     últimos días sin permitir scroll. Acá habilitamos scroll horizontal y
     fijamos un ancho mínimo en .cal-week para que header y body (mismo grid
     dentro del flex column) queden alineados y se desplacen juntos. */
  #calendar-container { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .cal-week { min-width: 596px; }
  .cal-week-header,
  .cal-week-body,
  .cal-week-blockrow { grid-template-columns: 36px repeat(7, minmax(80px, 1fr)); }
  /* En móvil el día único en cal-day-view ocupa toda la pantalla */
  .cal-day-view { min-width: 0; }
  .cal-day-view .cal-day-col { min-width: 0; }
  .cal-blockrow-chip { font-size: 9px; }
  .view-switcher .view-btn { padding: 6px 10px; font-size: var(--text-xs); }

  /* Modales en móvil — sticky footer + scroll interno seguro */
  .modal {
    max-height: calc(100dvh - var(--space-3) * 2);
    display: flex;
    flex-direction: column;
  }
  .modal-body {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .modal-actions {
    position: sticky;
    bottom: 0;
    background: var(--surface);
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
    margin-top: var(--space-3);
  }

  /* Toolbar-row-sub también scrolleable cuando hay muchos filtros */
  .toolbar-row-sub {
    overflow-x: auto;
    flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch;
  }
  .toolbar-row-sub > * { flex-shrink: 0; }
}

/* ═════════ H-SCROLL — Navs horizontales mobile-native (aj1-aj4) ═════════
   Patrón unificado para .profile-tabs, .filter-pills, .cal-legend y
   .toolbar-row-sub en móvil:

   - Scrollbar nativa oculta (estética tipo iOS / Material).
   - Momentum touch + touch-action: pan-x para no robar el scroll vertical.
   - Snap proximity para que cada chip caiga limpio.
   - Fade lateral via mask-image, toggleado por JS según overflow real
     (RLX.ui.initHScroll en app.js agrega .h-scroll-active /
     .is-overflow-start / .is-overflow-end). El fade aparece SOLO cuando
     hay contenido fuera del viewport en esa dirección, así no se atenúan
     bordes inútilmente.
*/
@media (max-width: 768px) {
  .profile-tabs,
  .filter-pills,
  .cal-legend,
  .toolbar-row-sub {
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-x;
    scroll-snap-type: x proximity;
    scroll-padding-inline: var(--space-2);
  }
  .profile-tabs::-webkit-scrollbar,
  .filter-pills::-webkit-scrollbar,
  .cal-legend::-webkit-scrollbar,
  .toolbar-row-sub::-webkit-scrollbar { display: none; height: 0; width: 0; }

  .profile-tab,
  .filter-pills > .pill,
  .cal-legend > .legend-item,
  .toolbar-row-sub > * { scroll-snap-align: start; }

  /* Fade lateral según overflow (toggled por JS, ver app.js). Usamos black
     como color de máscara: lo que importa es la opacidad de la rampa, no
     el color. */
  .h-scroll-active.is-overflow-start.is-overflow-end {
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 22px, #000 calc(100% - 22px), transparent 100%);
            mask-image: linear-gradient(to right, transparent 0, #000 22px, #000 calc(100% - 22px), transparent 100%);
  }
  .h-scroll-active.is-overflow-start:not(.is-overflow-end) {
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 22px, #000 100%);
            mask-image: linear-gradient(to right, transparent 0, #000 22px, #000 100%);
  }
  .h-scroll-active:not(.is-overflow-start).is-overflow-end {
    -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 22px), transparent 100%);
            mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 22px), transparent 100%);
  }
}

/* ═════════ <=480px — Reducción extrema ═════════ */
@media (max-width: 480px) {
  .app-header { padding: 0 var(--space-2); gap: var(--space-2); }
  .brand h1 { font-size: var(--text-xs); }

  /* Overlay header en móvil chico: ocultar título largo cuando los
     botones lo aprietan; el nombre del paciente queda visible solo en
     el form. */
  .overlay-header h2 { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   v1.5 — MARGINALIA
   "El cuaderno con margen". Extensión del north star v1.0 (El Cuaderno
   de Operación): mantenemos la densidad dentro de cada bloque semántico
   y la respiración aparece entre bloques. Motion como rastro temporal —
   el sistema deja marcas sutiles de lo que pasó sin decorar.

   Decisiones duras que NO se rompen:
   - OKLCH-only · acento terracota ≤10% del píxel · Inter Variable única.
   - Sin gradientes en headers, sin paper-texture, sin hand-drawn.
   - Toda animación respeta prefers-reduced-motion.
   ═══════════════════════════════════════════════════════════════════ */

/* ─── M1 · Spacing rhythm aplicado ─────────────────────────────────
   Mantenemos densidad DENTRO de cada bloque semántico (form-section,
   card, tabla) y aumentamos respiración ENTRE bloques. Spacing
   rhythm sin padding decorativo: el gap separa, el padding cohesiona.
*/
.form-section + .form-section { margin-top: var(--gap-section); }

/* Panes principales del paciente: respiración entre fieldsets y secciones */
.patient-info-main > .form-section + .form-section { margin-top: var(--gap-section); }
.patient-info-aside .side-section + .side-section { margin-top: var(--space-5); }

/* Toolbars y secciones top-level del view */
.view > .toolbar + .grid-wrap,
.view > .toolbar + .doctors-container,
.view > .toolbar + .treatments-container { margin-top: var(--space-5); }

@media (max-width: 768px) {
  .form-section + .form-section { margin-top: var(--space-5); }
  .patient-info-main > .form-section + .form-section { margin-top: var(--space-5); }
}

/* ─── M2 · View Transitions ────────────────────────────────────────
   activateView() en app.js dispara document.startViewTransition() en
   navegadores con soporte. CSS define el cross-fade + slide sutil. */
::view-transition-old(root) {
  animation: rlx-vt-out 160ms var(--ease-trace) both;
}
::view-transition-new(root) {
  animation: rlx-vt-in 200ms var(--ease-trace) both;
}
@keyframes rlx-vt-out {
  to { opacity: 0; transform: translateY(-6px); }
}
@keyframes rlx-vt-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ─── M3 · Traveling underline ─────────────────────────────────────
   Indicador único por nav que se desplaza entre tabs. Reemplaza el
   ::after del tab activo en desktop. JS: RLX.ui.travelingIndicator.
   IMPORTANTE: .main-nav ya es position: sticky con top: --header-h
   (línea 342). NO override a relative — sticky ya es contexto de
   posicionamiento válido para el .nav-indicator absoluto, y forzar
   relative dispararía el top: --header-h como offset, creando un
   hueco de 56px arriba del nav. .profile-tabs sí necesita relative
   porque originalmente es static. */
.profile-tabs {
  position: relative;
}
.nav-indicator {
  position: absolute;
  bottom: 0;
  left: 0;
  height: 2px;
  width: 0;
  background: var(--acc);
  border-radius: var(--r-full) var(--r-full) 0 0;
  pointer-events: none;
  opacity: 0;
  transform: translateX(0);
  transition:
    transform 240ms var(--ease-trace),
    width 240ms var(--ease-trace),
    opacity 160ms var(--ease);
  z-index: 1;
}
.nav-indicator.is-visible { opacity: 1; }

/* Al activar el indicador móvil, ocultamos el ::after del tab activo
   sólo si el indicador está visible (fallback a ::after si JS falla). */
.main-nav.has-traveling-indicator .nav-tab.active::after,
.subnav-tabs.has-traveling-indicator .nav-tab.active::after,
.profile-tabs.has-traveling-indicator .profile-tab.active::after {
  display: none;
}

/* ─── M4 · Save trace ──────────────────────────────────────────────
   Un trazo terracota recorre el borde superior de la superficie
   guardada en 600ms y se desvanece. JS: RLX.ui.trace(el).
   Cero impacto de layout (todo es ::before posicionado absoluto). */
.rlx-trace-host { position: relative; }
.rlx-trace-host > .rlx-trace {
  position: absolute;
  top: -1px;
  left: 0;
  right: 0;
  height: 2px;
  pointer-events: none;
  background: linear-gradient(
    to right,
    transparent 0%,
    transparent 28%,
    var(--acc) 50%,
    transparent 72%,
    transparent 100%
  );
  background-size: 250% 100%;
  background-position: 100% 0;
  border-radius: var(--r-full);
  animation: rlx-trace-run var(--dur-trace) var(--ease-trace) forwards;
}
@keyframes rlx-trace-run {
  0%   { background-position: 110% 0; opacity: 1; }
  85%  { opacity: 1; }
  100% { background-position: -10% 0; opacity: 0; }
}

/* ─── M5 · Status chip pulse ───────────────────────────────────────
   Al cambiar el embudo (select en Bandeja), el select pulsa una vez.
   240ms total, ease-out-quart, no genera layout shift. */
@keyframes rlx-chip-pulse {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.045); }
  100% { transform: scale(1); }
}
.cell-select.is-just-changed,
.status-chip.is-just-changed {
  animation: rlx-chip-pulse 240ms var(--ease) 1;
  transform-origin: center center;
}

/* ─── M6 · Ruling lines en bitácora clínica ────────────────────────
   Cada entrada de bitácora se ancla a un nodo coloreado a la izquierda
   (marginalia literal). El color del nodo comunica el estado en lugar
   del side-stripe banned por DESIGN.md. */
[data-pane="visits"] .visits-list .visit-card {
  position: relative;
  padding-left: var(--space-5);
}
[data-pane="visits"] .visits-list .visit-card::before {
  content: "";
  position: absolute;
  left: 8px;
  top: 22px;
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: var(--acc);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--acc) 12%, transparent);
  transition: background var(--dur-fast) var(--ease);
}
[data-pane="visits"] .visits-list .visit-card.is-signed::before {
  background: var(--ok);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--ok) 14%, transparent);
}
[data-pane="visits"] .visits-list .visit-card.is-draft::before {
  background: var(--acc);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--acc) 14%, transparent);
}
/* v1.5 — Removemos los border-left 3px de is-signed/is-draft (violaban
   "La Regla de No Side-stripes"). El estado vive ahora en el nodo. */
.visit-card.is-signed { border-left: 1px solid var(--border); }
.visit-card.is-draft { border-left: 1px solid var(--border); }

/* ─── M7 · Headline editorial ──────────────────────────────────────
   Un solo grado de jerarquía editorial para titulares ≥17px. Misma
   familia (Inter Variable), peso 700, tracking más cerrado. Aplicado
   sólo a h2 del overlay y h3 del modal — los anclas grandes donde el
   ojo busca contexto. NO aplico a legend (labels en mayúscula con
   tracking se romperían). */
.modal-header h3,
.overlay-header h2 {
  font-weight: 700;
  letter-spacing: -0.018em;
  line-height: 1.18;
}
.overlay-header h2 {
  font-size: 1.0625rem;
}

/* ─── Card mobile polish — ocultar "Última: —" vacíos ──────────── */
@media (max-width: 640px) {
  #patients-grid tr.patient-row > td.is-empty { display: none; }
}

/* ─── Reduced motion guardrail (M2-M5) ─────────────────────────────
   Cualquier animación nueva se neutraliza a casi nada si el usuario
   prefiere reduced motion. View Transitions se desactivan desde JS. */
@media (prefers-reduced-motion: reduce) {
  .nav-indicator { transition: none !important; }
  .rlx-trace-host > .rlx-trace { animation-duration: 0.001ms !important; }
  .cell-select.is-just-changed,
  .status-chip.is-just-changed { animation: none !important; }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none !important; }
}

/* ═════════ Safe area iOS (notch) ═════════ */
@supports (padding: env(safe-area-inset-bottom)) {
  @media (max-width: 768px) {
    body { padding-bottom: env(safe-area-inset-bottom); }
    .modal-actions { padding-bottom: max(var(--space-3), env(safe-area-inset-bottom)); }
  }
}

/* ═══════════════════════════════════════════════════════════════════
   v1.5.2 — SORTING POR COLUMNA + SKELETONS
   ═══════════════════════════════════════════════════════════════════ */

/* Headers ordenables (sección Pacientes). El indicador comunica estado
   (columna activa + dirección), no decora: solo aparece donde aplica. */
.data-grid thead th.sortable {
  cursor: pointer;
  user-select: none;
}
.data-grid thead th.sortable:hover { color: var(--text); }
.data-grid thead th.sortable[aria-sort]::after {
  content: '';
  display: inline-block;
  margin-left: 6px;
  vertical-align: middle;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
}
.data-grid thead th.sortable[aria-sort="ascending"]::after {
  border-bottom: 5px solid var(--acc);
}
.data-grid thead th.sortable[aria-sort="descending"]::after {
  border-top: 5px solid var(--acc);
}

/* Skeletons — solo donde hay carga async real (blobs de galería y
   documentos bajando de Storage). Pulso sutil de opacidad como rastro
   de "esto está llegando"; reduced-motion lo congela abajo. */
.rlx-skeleton {
  background: var(--n-200);
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 8px);
  animation: rlxSkeletonPulse 1.4s ease-in-out infinite;
  pointer-events: none;
}
.photo-card.rlx-skeleton { min-height: 120px; }
.doc-card.rlx-skeleton { min-height: 140px; }
@keyframes rlxSkeletonPulse {
  0%, 100% { opacity: 0.5; }
  50%      { opacity: 0.85; }
}
@media (prefers-reduced-motion: reduce) {
  .rlx-skeleton { animation: none; opacity: 0.6; }
}

/* ═════════════════════════════════════════════════════════════════════
   v1.5.3 — ciudad en bandeja + estadísticas de leads + ingresos por período
   ═════════════════════════════════════════════════════════════════════ */

/* Columna ciudad en la grid de la Bandeja */
.col-city { width: 110px; }
#leads-grid .city-cell {
  color: var(--text-muted);
  max-width: 140px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cell-empty { color: var(--text-disabled); }

/* Panel de contenido de subsección (estadísticas · ingresos · cruces).
   Superficie hermana de la grid: densidad adentro, respiración afuera. */
.stats-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-xs);
  padding: var(--pad-standard);
}
.stats-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.stats-period { display: inline-flex; align-items: center; gap: var(--space-1); }
.period-btn {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-elev);
  color: var(--text-muted);
  font-size: var(--text-md);
  line-height: 1;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.period-btn:hover:not(:disabled) {
  background: var(--bg-sunken);
  color: var(--text);
  border-color: var(--border-strong);
}
.period-btn:disabled { opacity: 0.45; cursor: default; }
.stats-period-label {
  min-width: 124px;
  text-align: center;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-strong);
}
.stats-headline {
  margin-left: auto;
  font-size: var(--text-sm);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.stats-headline strong { color: var(--text-strong); font-weight: 600; }

/* v1.5.4 — maestro-detalle: lista de buckets (selector) | detalle cruzado.
   El maestro es angosto y scrollea; el detalle ocupa el resto con dos
   rankings (ciudades + pautas) del bucket elegido. */
.stats-cross {
  display: grid;
  grid-template-columns: minmax(190px, 260px) minmax(0, 1fr);
  gap: var(--space-5);
  margin-top: var(--space-4);
  align-items: start;
}
.stats-master { border-right: 1px solid var(--border); padding-right: var(--space-4); }
.stats-detail-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--border);
  min-height: 24px;
}
.stats-detail-title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-strong);
}
.stats-detail-count {
  font-size: var(--text-sm);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.stats-detail-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-5);
}
/* v2.0 f7 — KPIs de conversión de la subsección Estadísticas. */
.stats-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  padding: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-xs);
}
.stats-kpi { display: flex; flex-direction: column; gap: 2px; }
.stats-kpi label { font-size: var(--text-2xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-muted); }
.stats-kpi .value { font-size: var(--text-xl); font-weight: 600; color: var(--text-strong); font-variant-numeric: tabular-nums; line-height: 1.1; }
.stats-kpi .value small { font-size: var(--text-sm); font-weight: 500; color: var(--acc-text); }
[data-theme="dark"] .stats-kpi .value small { color: var(--acc); }
/* La subsección apila sus paneles con aire entre ellos. */
#view-stats .stats-panel + .stats-panel { margin-top: var(--space-4); }
/* v1.5.4 — apartado del cruce pauta × ciudad, separado del bloque de arriba. */
.stats-section {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
}
.stats-section-title {
  margin: 0 0 var(--space-3);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-strong);
}
.stats-section .stats-cross { margin-top: 0; }
.stats-block-title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
.stats-rows {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 272px;
  overflow-y: auto;
  scrollbar-width: thin;
}

/* Fila de dato: etiqueta + barra normalizada al máximo + conteo.
   La barra es dato, no decoración: acc-soft-2 es tinta diluida. */
.stat-row {
  display: grid;
  grid-template-columns: minmax(56px, 40%) 1fr auto;
  gap: var(--space-2);
  align-items: center;
  font-size: var(--text-sm);
  padding: 2px 0;
}
.stat-row-label {
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.stat-row-bar {
  height: 8px;
  background: var(--bg-sunken);
  border-radius: var(--r-full);
  overflow: hidden;
}
.stat-row-fill {
  display: block;
  height: 100%;
  background: var(--acc-soft-2);
  border-radius: inherit;
}
.stat-row-count {
  min-width: 24px;
  text-align: right;
  font-weight: 600;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}
.stat-row.is-current .stat-row-label { color: var(--acc-text); font-weight: 600; }
.stat-row.is-muted .stat-row-label,
.stat-row.is-muted .stat-row-count { color: var(--text-dim); font-weight: 400; }
.stat-row.is-muted .stat-row-fill { background: var(--border); }

/* Fila-botón del maestro: clicable, con hover y estado seleccionado. */
.stat-row-btn {
  width: 100%;
  border: 0;
  background: transparent;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  padding: 3px var(--space-2);
  border-radius: var(--r-sm);
  transition: background var(--dur-fast) var(--ease);
}
.stat-row-btn:hover { background: var(--bg-sunken); }
.stat-row-btn.is-selected { background: var(--acc-soft); }
.stat-row-btn.is-selected .stat-row-label { color: var(--acc-text); font-weight: 600; }
[data-theme="dark"] .stat-row-btn.is-selected .stat-row-label { color: var(--acc); }
.stat-row-btn:focus-visible { outline: 2px solid var(--acc); outline-offset: -2px; }
.stats-empty { font-size: var(--text-sm); color: var(--text-dim); padding: var(--space-2) 0; }
.stats-footnote { margin: var(--space-3) 0 0; font-size: var(--text-xs); color: var(--text-dim); }

/* Ingresos por período: semanas como filas de registro, días plegados
   dentro de cada semana (details nativo, sin marker del navegador). */
.income-weeks {
  margin-top: var(--space-3);
  border-top: 1px solid var(--border);
}
.income-week { border-bottom: 1px solid var(--border); }
.income-week summary {
  display: grid;
  grid-template-columns: 1fr auto minmax(96px, auto) 12px;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-2) var(--space-1);
  font-size: var(--text-sm);
  cursor: pointer;
  list-style: none;
}
.income-week summary::-webkit-details-marker { display: none; }
.income-week summary:hover { background: var(--bg-sunken); }
.income-week.is-empty {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-1);
  font-size: var(--text-sm);
  color: var(--text-dim);
}
.income-week-label { color: var(--text); font-variant-numeric: tabular-nums; }
.income-week-label em {
  font-style: normal;
  color: var(--acc-text);
  font-size: var(--text-xs);
}
.income-week.is-empty .income-week-label,
.income-week.is-empty .income-week-count { color: var(--text-dim); }
.income-week-count {
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}
.income-week-total {
  text-align: right;
  font-weight: 600;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}
.income-week-chevron {
  color: var(--text-dim);
  transition: transform var(--dur-base) var(--ease);
}
.income-week[open] .income-week-chevron { transform: rotate(180deg); }
.income-days { padding: 0 var(--space-1) var(--space-2) var(--space-4); }
.income-day {
  display: grid;
  grid-template-columns: 1fr auto minmax(96px, auto);
  gap: var(--space-3);
  padding: 2px calc(12px + var(--space-3)) 2px 0;
  font-size: var(--text-sm);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.income-day strong {
  text-align: right;
  font-weight: 500;
  color: var(--text);
}

/* v1.5.4 — pagos individuales por día: paciente · monto, clicable a su ficha */
.income-day-group { margin-bottom: var(--space-2); }
.income-day-group:last-child { margin-bottom: 0; }
.income-payments {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin: 2px 0 0 var(--space-3);
}
.income-payment {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-3);
  align-items: center;
  width: 100%;
  border: 0;
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
  padding: 3px calc(12px + var(--space-3)) 3px var(--space-2);
  border-radius: var(--r-sm);
  color: var(--text-muted);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.income-payment:hover { background: var(--bg-sunken); color: var(--text); }
.income-payment:focus-visible { outline: 2px solid var(--acc); outline-offset: -2px; }
.income-pay-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.income-pay-amount {
  text-align: right;
  font-weight: 500;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* Responsive: maestro y detalle apilan en móvil; el headline baja de
   línea cuando no cabe junto al período. El maestro acota su alto para no
   empujar el detalle fuera de pantalla. */
@media (max-width: 768px) {
  .stats-cross { grid-template-columns: 1fr; gap: var(--space-4); }
  .stats-master {
    border-right: 0;
    padding-right: 0;
    border-bottom: 1px solid var(--border);
    padding-bottom: var(--space-3);
  }
  .stats-master-rows { max-height: 200px; }
  .stats-headline { margin-left: 0; flex-basis: 100%; }
}
/* En pantallas muy angostas los dos rankings también apilan. */
@media (max-width: 520px) {
  .stats-detail-cols { grid-template-columns: 1fr; gap: var(--space-4); }
}

@media (prefers-reduced-motion: reduce) {
  .period-btn,
  .income-week-chevron { transition: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   Shell v2 — Inicio (resumen del día)
   Registro, no dashboard: una línea de datos entre filetes, dos
   columnas de listas densas. Sin cards de KPI, sin gradientes.
   ═══════════════════════════════════════════════════════════════════ */
.home-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
.home-date {
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--text-strong);
}
.home-date::first-letter { text-transform: uppercase; }
.home-quick { display: flex; gap: var(--space-2); }

.home-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-7);
  padding: var(--space-4) 2px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--gap-section);
}
.home-stat { display: flex; flex-direction: column; gap: 2px; }
.home-stat .k {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}
.home-stat .v {
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}
.home-stat .v .unit {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-muted);
  margin-left: 4px;
}

.home-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: var(--gap-section);
  align-items: start;
}
.home-block-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--border-strong);
}
.home-block-head h3 {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.home-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: 10px 2px;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  font: inherit;
  text-align: left;
  color: var(--text);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.home-row:hover { background: var(--bg-sunken); }
.home-row-time {
  flex-shrink: 0;
  width: 46px;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}
.home-row-main { flex: 1; min-width: 0; }
.home-row-name {
  display: block;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.home-row-sub {
  display: block;
  font-size: var(--text-xs);
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.home-row-meta {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.home-doctor-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  flex-shrink: 0;
}
.home-empty {
  padding: var(--space-4) 2px;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

@media (max-width: 1024px) {
  .home-grid { grid-template-columns: 1fr; gap: var(--space-6); }
}
@media (max-width: 768px) {
  .home-quick { width: 100%; }
  .home-quick .btn { flex: 1; }
  .home-strip { gap: var(--space-3) var(--space-5); }
  .home-stat .v { font-size: var(--text-lg); }
}

/* ═══════════════════════════════════════════════════════════════════
   Sedes — v2.0 fase 2 (clínica → sedes)
   ═══════════════════════════════════════════════════════════════════ */
.sedes-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: var(--space-4);
}
.sede-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-xs);
  padding: var(--space-4);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.sede-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.sede-card.inactive { opacity: 0.6; }
/* v2.0 f8 — para el doctor la sede es ficha, no editor: sin afordancia. */
.sedes-container.is-readonly .sede-card { cursor: default; }
.sedes-container.is-readonly .sede-card:hover {
  border-color: var(--border);
  box-shadow: var(--shadow-xs);
}
.sede-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}
.sede-card-head h3 { font-size: var(--text-md); }
.sede-inactive-tag {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-dim);
}
.sede-card-meta {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin-top: 2px;
}
.sede-card-doctors {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.sede-doctor-line {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  min-width: 0;
}
.sede-doctor-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  flex-shrink: 0;
  margin-top: 5px;
}
.sede-doctor-info { min-width: 0; flex: 1; }
.sede-doctor-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-width: 0;
}
.sede-doctor-name {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sede-doctor-hours {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  min-width: 0;
  margin-top: 1px;
}

/* Chips de días (lectura, cards de sede): L M X J V S D */
.day-chips { display: inline-flex; gap: 2px; flex-shrink: 0; }
.day-chip {
  width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-sm);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--text-disabled);
  background: var(--bg-sunken);
}
.day-chip.on {
  color: var(--acc-text);
  background: var(--acc-soft);
}
.sede-card-empty, .sede-schedule-empty {
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.sedes-empty {
  padding: var(--space-6) var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  color: var(--text-muted);
  font-size: var(--text-sm);
}

/* Editor de franjas en el modal de sede */
.sede-schedule-section {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: flex-start;
}
.sede-schedule-head h4 { font-size: var(--text-base); }
.sede-schedule-hint { display: block; font-size: var(--text-xs); margin-top: 2px; }
.sede-schedule-list {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
/* Fila del editor: doctor · días (toggles) · horas · quitar */
.sede-horario-row {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) auto auto 30px;
  gap: var(--space-2);
  align-items: center;
}
.sede-horario-row select,
.sede-horario-row input { height: 34px; }
.sede-horario-times {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}
.sede-horario-times input[type="time"] { width: 112px; }
.sede-horario-dash { color: var(--text-dim); }
.sede-horario-del { color: var(--text-muted); }
.sede-horario-del:hover { color: var(--err); }

/* Toggles de día (edición): mismos chips, clickeables */
.day-toggles { display: inline-flex; gap: 3px; }
.day-toggle {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background-color: transparent;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-dim);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.day-toggle:hover { border-color: var(--border-strong); color: var(--text); }
.day-toggle.on {
  background: var(--acc-soft);
  border-color: color-mix(in oklch, var(--acc) 40%, var(--border));
  color: var(--acc-text);
}

@media (max-width: 768px) {
  .sede-horario-row {
    grid-template-columns: minmax(0, 1fr) 30px;
    grid-auto-rows: auto;
    row-gap: var(--space-2);
    padding-bottom: var(--space-2);
    border-bottom: 1px dashed var(--border);
  }
  .sede-horario-row select[data-field="doctorId"] { grid-column: 1 / 2; grid-row: 1; }
  .sede-horario-row .sede-horario-del { grid-column: 2; grid-row: 1; }
  .sede-horario-row .day-toggles,
  .sede-horario-row .sede-horario-times { grid-column: 1 / -1; }
}

/* ═══════════════════════════════════════════════════════════════════
   DISPONIBILIDAD (agenda → disponibilidad, v2.0 fase 3)
   Timeline 08:00–18:00 por sede × doctor. Celda libre = hueco
   agendable; cita = bloque superpuesto; fuera de franja = apagado.
   ═══════════════════════════════════════════════════════════════════ */
.availability-container {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.avail-hint { font-size: var(--text-xs); color: var(--text-dim); }

/* Tira de días de la semana en la toolbar (f4.1) */
.avail-days { display: flex; gap: 4px; }
.avail-day-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  min-width: 44px;
  padding: 4px 8px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-sunken);
  cursor: pointer;
  font-family: inherit;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.avail-day-chip:hover { background: var(--surface); }
.adc-dow {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--text-dim);
  line-height: 1.2;
}
.adc-num {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.avail-day-chip.active {
  background: var(--acc-soft);
  border-color: color-mix(in oklch, var(--acc) 45%, var(--border));
}
.avail-day-chip.active .adc-num { color: var(--acc-text); }
.avail-day-chip.today .adc-dow { color: var(--acc); font-weight: 700; }

.avail-sede {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-xs);
  padding: var(--space-4);
}
.avail-sede-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  min-width: 0;
}
.avail-sede-swatch {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  flex-shrink: 0;
  align-self: center;
}
.avail-sede-head h3 { font-size: var(--text-md); }
.avail-sede-meta {
  font-size: var(--text-xs);
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.avail-sede-sum {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.avail-empty {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.avail-grid {
  margin-top: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.avail-row {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: var(--space-3);
  align-items: center;
}
.avail-row-scale { margin-bottom: calc(-1 * var(--space-1)); }
.avail-doctor {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}
.avail-doctor-txt {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.25;
}
.avail-doctor-name {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.avail-doctor-free {
  font-size: var(--text-2xs);
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.avail-scale {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
}
.avail-scale span {
  font-size: var(--text-2xs);
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  padding-left: 2px;
}

/* Track por segmentos: la base es "fuera de franja" (tramado); encima
   van los segmentos de franja (surface), los libres (tinte verde suave,
   clickeables con snap a 30 min), las pills de cita y el marcador de
   hora actual. */
.avail-track {
  position: relative;
  height: 48px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
  background: repeating-linear-gradient(
    135deg,
    var(--bg-sunken) 0,
    var(--bg-sunken) 6px,
    transparent 6px,
    transparent 12px
  );
}
.avail-seg { position: absolute; top: 0; bottom: 0; }
.avail-seg.in-franja { background: var(--surface); }
.avail-seg.free { background: color-mix(in oklch, var(--ok) 11%, var(--surface)); }
.avail-seg.free.clickable { cursor: pointer; transition: background var(--dur-fast) var(--ease); }
.avail-seg.free.clickable:hover { background: color-mix(in oklch, var(--ok) 22%, var(--surface)); }
[data-theme="dark"] .avail-seg.free { background: color-mix(in oklch, var(--ok) 16%, var(--surface)); }
[data-theme="dark"] .avail-seg.free.clickable:hover { background: color-mix(in oklch, var(--ok) 28%, var(--surface)); }
.avail-ticks {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: linear-gradient(to right, var(--border) 1px, transparent 1px);
  background-size: 10% 100%;
  opacity: 0.65;
}
.avail-apt {
  position: absolute;
  top: 7px;
  bottom: 7px;
  z-index: 2;
  border: 1px solid color-mix(in oklch, var(--info) 30%, transparent);
  background: var(--info-bg);
  color: var(--info-700);
  border-radius: var(--r-full);
  padding: 0 10px;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  box-shadow: var(--shadow-xs);
}
[data-theme="dark"] .avail-apt { color: var(--info-500); }
/* v2.0 f9 — reservada: ocupa la franja pero sin confirmar. Mismo punteado
   que la tarjeta del calendario. */
.avail-apt.is-reserved {
  border-style: dashed;
  border-color: color-mix(in oklch, var(--warn) 55%, transparent);
  background: color-mix(in oklab, var(--warn-bg) 45%, var(--surface));
  color: var(--warn-700);
  box-shadow: none;
}
[data-theme="dark"] .avail-apt.is-reserved { color: var(--warn-500); }
.avail-apt.type-block {
  background: repeating-linear-gradient(
    135deg,
    var(--bg-sunken) 0,
    var(--bg-sunken) 6px,
    color-mix(in oklch, var(--text-muted) 16%, var(--bg-sunken)) 6px,
    color-mix(in oklch, var(--text-muted) 16%, var(--bg-sunken)) 12px
  );
  color: var(--text-muted);
  border-color: var(--border);
  font-style: italic;
  box-shadow: none;
}
.avail-apt.other-sede {
  background: var(--bg-sunken);
  color: var(--text-muted);
  border-color: var(--border);
  opacity: 0.75;
}
.avail-now {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  z-index: 3;
  background: var(--acc);
  pointer-events: none;
}
.avail-now::before {
  content: "";
  position: absolute;
  top: 0;
  left: -2px;
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: var(--acc);
}
/* Burbuja de hover con la hora propuesta (solo dispositivos con hover) */
.avail-cursor {
  position: fixed;
  z-index: 9990;
  transform: translateX(-50%);
  background: var(--n-900);
  color: var(--n-0);
  font-size: var(--text-2xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  padding: 3px 8px;
  border-radius: var(--r-full);
  pointer-events: none;
  box-shadow: var(--shadow-sm);
  white-space: nowrap;
}
.avail-cursor[hidden] { display: none; }
[data-theme="dark"] .avail-cursor { background: var(--n-200); color: var(--n-900); }

@media (max-width: 900px) {
  .avail-days { overflow-x: auto; scrollbar-width: none; max-width: 100%; }
  .avail-days::-webkit-scrollbar { display: none; }
  .avail-day-chip { min-width: 40px; padding: 3px 6px; }
}
@media (max-width: 640px) {
  .avail-row { grid-template-columns: 1fr; gap: 4px; }
  .avail-row-scale .avail-doctor { display: none; }
  .avail-track { height: 44px; }
  .avail-hint { display: none; }
  .avail-sede-meta { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   MODAL DE CITA (v2.0 f9)
   ═══════════════════════════════════════════════════════════════════
   El formulario deja de ser una pila plana de campos y se lee como tres
   bloques: quién · qué · cuándo y dónde. Cada bloque es una superficie
   propia (crema sumida, borde 1px) con un rótulo caps arriba, igual que
   los fieldsets de la ficha de paciente pero más compactos: el modal es
   un flujo corto, no un formulario largo.

   Tipo y estado se resuelven con un control segmentado y no con un select:
   son 3-4 opciones que se eligen en un clic y que conviene ver de una
   (el estado, además, es lo que más se escanea de una cita). */

.modal-apt { width: min(580px, 100%); }
.modal-apt .modal-body { gap: var(--space-3); }
/* La barra de acciones queda anclada al pie del modal: en una laptop de
   768px de alto el formulario no entra completo, y "Guardar cita" no puede
   depender de que el usuario descubra que hay scroll. */
.modal-apt .modal-actions {
  position: sticky;
  bottom: 0;
  z-index: 2;
  margin: 0 calc(var(--space-5) * -1) 0;
  padding: var(--space-3) var(--space-5) var(--space-2);
  background: var(--surface);
}

.apt-block {
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--pad-compact);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.apt-block-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}
.apt-block-title {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
/* Los controles dentro de un bloque van sobre `surface` para separarse del
   fondo sumido (si no, el campo se disuelve en la superficie del bloque). */
.apt-block input,
.apt-block select { background-color: var(--surface); }

/* Campo con rótulo propio para controles que no son <input> (segmentados). */
.apt-field { display: flex; flex-direction: column; gap: var(--space-1); }
.apt-field-label {
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.apt-revenue-field input { max-width: 240px; font-variant-numeric: tabular-nums; }
#apt-place-row.is-single { grid-template-columns: minmax(0, 1fr); }

/* ── Control segmentado ─────────────────────────────────────────────
   Radios reales (el form sigue leyendo form.type.value) con la etiqueta
   como superficie clickeable. Misma gramática que las pills de filtro: el
   raíl contiene, y la opción activa se "levanta" con sombra. */
.seg {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 3px;
  padding: 3px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.seg input {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}
.seg label {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 5px;
  min-width: 0;
  height: 30px;
  padding: 0 var(--space-2);
  border-radius: var(--r-sm);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.seg label:hover { color: var(--text-strong); background: var(--bg-sunken); }
.seg input:checked + label {
  background: var(--bg-sunken);
  color: var(--text-strong);
  font-weight: 600;
  box-shadow: var(--shadow-xs);
}
.seg input:focus-visible + label {
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--acc) 18%, transparent);
}
.seg input:disabled + label { cursor: default; opacity: 0.55; }
.seg input:disabled + label:hover { background: transparent; color: var(--text-muted); }
.seg input:disabled:checked + label { opacity: 1; background: var(--bg-sunken); }

/* Punto de estado: mismo vocabulario que el calendario — punteado es
   "provisional", relleno es "en firme". El color semántico aparece sólo en
   la opción activa; las demás quedan en gris para no pintar un semáforo. */
.seg-dot {
  flex-shrink: 0;
  width: 8px; height: 8px;
  border-radius: var(--r-full);
  border: 1.5px solid currentColor;
  background: currentColor;
  opacity: 0.45;
}
.seg input:checked + label .seg-dot { opacity: 1; }
.seg-status input:checked + label[data-value="RESERVED"]  { color: var(--warn-700); }
.seg-status input:checked + label[data-value="SCHEDULED"] { color: var(--info-700); }
.seg-status input:checked + label[data-value="COMPLETED"] { color: var(--ok-700); }
.seg-status input:checked + label[data-value="CANCELED"]  { color: var(--err-700); }
.seg-status label[data-value="RESERVED"] .seg-dot { background: transparent; border-style: dashed; }
[data-theme="dark"] .seg-status input:checked + label[data-value="RESERVED"]  { color: var(--warn-500); }
[data-theme="dark"] .seg-status input:checked + label[data-value="SCHEDULED"] { color: var(--info-500); }
[data-theme="dark"] .seg-status input:checked + label[data-value="COMPLETED"] { color: var(--ok-500); }
[data-theme="dark"] .seg-status input:checked + label[data-value="CANCELED"]  { color: var(--err-500); }

/* ── Picker de paciente ────────────────────────────────────────────── */
.apt-pick-bar {
  position: relative;
  display: flex;
  gap: var(--space-2);
}
.apt-pick-bar .apt-pick-search { flex: 1; min-width: 0; }
.apt-pick-bar .btn { flex-shrink: 0; height: 34px; }
.pick-row-apt {
  flex-direction: row;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}
.pick-row-apt .pick-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-empty { color: var(--text-muted); cursor: default; }
.pick-empty:hover { background: transparent; }

/* Paciente elegido: tarjeta con nombre + teléfono a la izquierda, estado de
   embudo y accesos a la derecha. Reemplaza la línea de texto suelta. */
#apt-patient-selected.picker-selected {
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
  background: var(--surface);
  border: 1px solid color-mix(in oklch, var(--acc) 30%, var(--border));
  border-radius: var(--r-md);
  color: var(--text);
}
#apt-patient-selected.set {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.apt-pc-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.apt-pc-name {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.apt-pc-meta {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.apt-pc-chip { flex-shrink: 0; }
#apt-patient-selected .apt-open-profile { flex-shrink: 0; font-size: var(--text-xs); }
.apt-pc-clear {
  flex-shrink: 0;
  width: 26px; height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-muted);
  font-size: var(--text-md);
  line-height: 1;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.apt-pc-clear:hover { background: var(--bg-sunken); color: var(--text-strong); }

/* Alta rápida de paciente dentro del picker. Borde punteado = "esto todavía
   no existe", el mismo código visual que la cita reservada. */
#apt-new-patient-fields {
  padding: var(--space-3);
  background: var(--surface);
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
}
#apt-new-patient-fields.hidden { display: none; }
.apt-new-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.apt-new-title {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
.apt-new-hint {
  margin: var(--space-2) 0 0;
  font-size: var(--text-2xs);
  color: var(--text-dim);
  line-height: var(--leading-snug);
}

/* Sólo lectura (doctor): el formulario se lee, no se toca. */
#apt-modal[data-readonly="true"] .apt-pick-bar,
#apt-modal[data-readonly="true"] .apt-pc-clear { display: none; }

/* Móvil: el segmentado de cuatro opciones no cabe en una fila de 375px. */
@media (max-width: 560px) {
  .apt-block { padding: var(--space-2); }
  .seg { grid-auto-flow: row; grid-auto-columns: auto; grid-template-columns: 1fr 1fr; }
  .seg label { justify-content: flex-start; }
  .apt-pick-bar { flex-wrap: wrap; }
  .apt-pick-bar .apt-pick-search { flex: 1 1 100%; }
  .apt-pick-bar .btn { width: 100%; }
  #apt-patient-selected.set { flex-wrap: wrap; }
  .apt-pc-main { flex: 1 1 100%; }
  .apt-revenue-field input { max-width: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   REPARTO DE INGRESOS + CIERRES (v2.1.4, fase 8.2)
   ───────────────────────────────────────────────────────────────────
   Pantalla de plata: la legibilidad del número manda sobre todo lo
   demás. Cifras tabulares, columnas alineadas a la derecha, y el acento
   terracota reservado para UNA cosa — el bruto, que es la cifra de la
   que cuelgan las otras. Las dos columnas derivadas (bolsa del
   consultorio y colchón) se distinguen por peso y por un tinte neutro,
   no por color: si todo grita, nada se lee.
   ═══════════════════════════════════════════════════════════════════ */

.payout-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-5);
  max-width: 1240px;
}

.payout-range { display: flex; gap: var(--space-3); align-items: center; }
.payout-range input[type="date"] { min-width: 9.5rem; }

.payout-block {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--space-4) var(--space-5) var(--space-5);
}
.payout-block-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.payout-block-head h3 {
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  font-weight: 600;
}
.payout-period {
  font-size: var(--text-sm);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* ── La cadena bruto → comisión → neto → doctores + consultorio ──── */
.payout-chain {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
  padding-bottom: var(--space-4);
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--border);
}
.payout-step { display: flex; flex-direction: column; gap: 2px; }
.payout-step .k {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}
.payout-step .v {
  font-size: 1.0625rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-strong);
}
.payout-step.is-lead .v { color: var(--acc-text); font-size: 1.25rem; }
.payout-op {
  font-size: var(--text-sm);
  color: var(--text-disabled);
  padding-bottom: 0.2rem;
}
.payout-step-meta {
  margin-left: auto;
  align-self: flex-end;
  font-size: var(--text-xs);
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* ── Tabla de reparto ────────────────────────────────────────────── */
/* Wrapper con scroll propio: 11 columnas de dinero (v2.8 sumó Ajustes) no
   entran en tablet y el body de la app nunca debe desplazarse en horizontal. */
.payout-table-wrap { overflow-x: auto; }
.payout-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
}
.payout-table th,
.payout-table td {
  padding: var(--space-2);
  text-align: left;
  white-space: nowrap;
}
.payout-table th:first-child,
.payout-table td:first-child { padding-left: 0; }
/* La última columna (colchón) conserva su aire: lleva fondo tintado y
   pegarlo al borde de la tarjeta lo hace ver cortado. */
.payout-table th:last-child,
.payout-table td:last-child  { padding-right: var(--space-3); }
.payout-table thead th {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  font-weight: 600;
  border-bottom: 1px solid var(--border-strong);
}
.payout-table .num { text-align: right; }
.payout-table tbody th { font-weight: 600; color: var(--text-strong); }
.payout-table tbody tr + tr th,
.payout-table tbody tr + tr td { border-top: 1px solid var(--border); }
.payout-table tbody td { color: var(--text); }
/* Las dos columnas derivadas se tintan con un velo del PROPIO color de
   texto, no con --bg-sunken: en oscuro ese token (L 0.085) es mucho más
   oscuro que la tarjeta (L 0.205) y las columnas se leían como agujeros
   negros. Mezclado contra el texto, el velo oscurece en claro y aclara en
   oscuro — el mismo gesto en los dos temas, sin una regla por tema. */
.payout-table .is-pot { font-weight: 600; background: color-mix(in oklab, var(--text) 5%, transparent); }
.payout-table .is-cushion { font-weight: 700; color: var(--text-strong); background: color-mix(in oklab, var(--text) 9%, transparent); }
.payout-table .is-neg { color: var(--err-700); }
.payout-table tfoot th,
.payout-table tfoot td {
  border-top: 2px solid var(--border-strong);
  font-weight: 700;
  color: var(--text-strong);
}
/* Los gastos comunes se escriben en la propia celda: es una tabla de
   trabajo, no un informe. Un modal para esto sería una capa de más. */
.payout-table input.payout-exp {
  width: 6.25rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
  padding: 3px var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background-color: transparent;
  color: var(--text);
}
.payout-table input.payout-exp:focus {
  outline: none;
  border-color: var(--acc);
  box-shadow: 0 0 0 3px var(--acc-soft);
}

/* ── Columna de ajustes (v2.8) ─────────────────────────────────────
   Las otras tres columnas de la tabla son gastos y siempre restan; esta
   puede sumar, así que el signo tiene que verse SIEMPRE, también cuando
   el valor es cero. Por eso es un botón con estado y no un guion que
   alguien teclea: un "−" escrito a mano desaparece al reformatear el
   campo, y un ajuste con el signo cambiado descuadra el cierre entero. */
.payout-adj {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
}
.payout-sign {
  flex-shrink: 0;
  width: 1.5rem; height: 1.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
/* Verde = entra al colchón, rojo = sale. Es la misma gramática que ya usa
   la tabla para un cuadre negativo. Van ANTES de :hover y :focus-visible: con
   la misma especificidad gana la última regla, así que al revés el botón se
   quedaba sin estados visibles. */
.payout-sign.is-plus  { color: var(--ok-700);  border-color: color-mix(in oklab, var(--ok-700) 45%, transparent); }
.payout-sign.is-minus { color: var(--err-700); border-color: color-mix(in oklab, var(--err-700) 45%, transparent); }
/* El hover tiñe el fondo y deja el trazo en manos del signo. */
.payout-sign:hover { background: color-mix(in oklab, var(--text) 8%, transparent); }
.payout-sign:focus-visible {
  outline: none;
  border-color: var(--acc);
  box-shadow: 0 0 0 3px var(--acc-soft);
}
.payout-table input.payout-adj-amount { width: 4.75rem; }
.payout-table td.is-adj { white-space: normal; }
.payout-table input.payout-adj-note {
  display: block;
  width: 100%;
  margin-top: 4px;
  text-align: right;
  font-size: var(--text-xs);
  padding: 2px var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background-color: transparent;
  color: var(--text-muted);
}
.payout-table input.payout-adj-note:hover { border-color: var(--border); }
.payout-table input.payout-adj-note:focus {
  outline: none;
  color: var(--text);
  border-color: var(--acc);
  box-shadow: 0 0 0 3px var(--acc-soft);
}
.payout-table input.payout-adj-note::placeholder { color: var(--text-dim); }
/* Sólo lectura (doctor, y tabla de un cierre guardado). */
.payout-adj-note-ro {
  display: block;
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-weight: 400;
}
/* Los motivos, bajo la tabla del cierre: texto plano, no un tooltip. Un
   cierre se relee meses después y ahí el hover no existe. */
.payout-adj-list {
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.payout-adj-list .payout-adj-amt { font-variant-numeric: tabular-nums; color: var(--text); }
/* El mismo botón, en miniatura, dentro del pie explicativo. */
.payout-sign-inline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.1rem; height: 1.1rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  font-weight: 700;
  line-height: 1;
  vertical-align: -2px;
}

/* ── Avisos ──────────────────────────────────────────────────────── */
.payout-alert,
.payout-note {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--text);
}
.payout-alert { border-color: var(--warn-700); background: var(--warn-bg); color: var(--warn-700); }
.payout-note  { color: var(--text-muted); background: color-mix(in oklab, var(--text) 4%, transparent); }
.payout-missing-list { margin: var(--space-2) 0 0; padding-left: var(--space-4); }
.payout-missing-list li { margin-top: 2px; font-variant-numeric: tabular-nums; }
.payout-missing { color: var(--text-muted); font-size: var(--text-xs); }

/* ── Cierres guardados ───────────────────────────────────────────── */
.payout-status {
  display: inline-block;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 2px var(--space-2);
  border-radius: var(--r-full);
  border: 1px solid var(--border-strong);
  color: var(--text-muted);
}
.payout-status.is-closed { border-color: var(--ok-700); color: var(--ok-700); background: var(--ok-bg); }

.payout-closing {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  margin-bottom: var(--space-3);
  overflow: hidden;
}
.payout-closing-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  flex-wrap: wrap;
}
.payout-closing-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: inherit;
  font: inherit;
  text-align: left;
}
.payout-closing-period { font-weight: 600; color: var(--text-strong); font-variant-numeric: tabular-nums; }
.payout-closing-label { font-size: var(--text-sm); color: var(--text-dim); }
/* De qué sede es el cierre. Va junto al período porque un cierre
   congelado tiene que decir sobre qué se hizo, no sólo cuándo. */
.payout-closing-sede { font-size: var(--text-xs); color: var(--text-muted); }
.payout-closing-total {
  margin-left: auto;
  font-size: var(--text-sm);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.payout-closing-actions { display: flex; gap: var(--space-1); }
.payout-closing-body { padding: 0 var(--space-4) var(--space-4); border-top: 1px solid var(--border); }
.payout-closing-meta {
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.payout-closing.is-closed { border-color: var(--border-strong); }

/* ── Configuración de porcentajes ────────────────────────────────── */
.payout-config { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-4); }
.payout-config label { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--text-sm); }
.payout-config input { width: 7rem; }
.payout-config-derived { font-size: var(--text-sm); color: var(--text-muted); padding-bottom: var(--space-2); }

/* ═══ Vista previa del reparto dentro del modal de pago ═══════════ */
.payment-split {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
  background: color-mix(in oklab, var(--text) 4%, transparent);
}
.payment-split:empty { display: none; }
.pay-split-label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}
.pay-split-bit { display: flex; gap: var(--space-1); align-items: baseline; font-size: var(--text-sm); }
.pay-split-bit .k { color: var(--text-muted); }
.pay-split-bit .v { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text-strong); }

/* ═══ Ingresos en Inicio, con el ojo ══════════════════════════════ */
.home-income {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--space-4);
  margin-bottom: var(--space-5);
}
.home-income-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.home-income-head h3 {
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  font-weight: 600;
}
.home-income-actions { margin-left: auto; display: flex; align-items: center; gap: var(--space-2); }
.home-income-figs { display: flex; flex-wrap: wrap; gap: var(--space-6); }
.home-income-fig { display: flex; flex-direction: column; gap: 2px; }
.home-income-fig .k {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}
.home-income-fig .v {
  font-size: 1.375rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-strong);
}
.home-income-fig.is-lead .v { color: var(--acc-text); }
.home-income-fig.is-meta .v { font-size: 1rem; color: var(--text-muted); }
/* Con las cifras ocultas el bloque baja de intensidad: sin números que
   leer, el acento no tiene qué destacar. */
.home-income.is-hidden .home-income-fig .v { color: var(--text-disabled); letter-spacing: 0.1em; }

.home-income-panel {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5);
}
.home-income-chain { display: flex; flex-direction: column; gap: var(--space-1); min-width: 16rem; }
.home-income-line {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}
.home-income-line .k { color: var(--text-muted); }
.home-income-line .v { font-weight: 600; color: var(--text); }
.home-income-line.is-lead .k,
.home-income-line.is-lead .v { color: var(--text-strong); font-weight: 700; }
.home-income-table {
  border-collapse: collapse;
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}
.home-income-table th,
.home-income-table td { padding: var(--space-1) var(--space-3); text-align: left; white-space: nowrap; }
.home-income-table .num { text-align: right; }
.home-income-table thead th {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  border-bottom: 1px solid var(--border);
}
.home-income-table tbody th { font-weight: 500; color: var(--text); }
.home-income-foot { flex: 1 1 100%; font-size: var(--text-xs); color: var(--text-muted); }
/* El enlace va dentro de una frase: sin el padding del btn-link, el punto
   final quedaba separado de la palabra. */
.home-income-foot .btn-link { padding: 0; font-size: inherit; vertical-align: baseline; }

/* El ojo: dos SVG superpuestos, se muestra el que toca. */
.home-eye .eye-off { display: none; }
.home-eye[aria-pressed="true"] .eye-open { display: none; }
.home-eye[aria-pressed="true"] .eye-off  { display: block; }

/* ── Responsive ──────────────────────────────────────────────────── */
@media (max-width: 1024px) {
  .payout-body { padding: var(--space-4); }
  .payout-chain { gap: var(--space-2); }
  .payout-step .v { font-size: 1rem; }
  .payout-step.is-lead .v { font-size: 1.125rem; }
}
@media (max-width: 640px) {
  .payout-body { padding: var(--space-3); gap: var(--space-4); }
  .payout-block { padding: var(--space-3); }
  .payout-range { flex-wrap: wrap; width: 100%; }
  .payout-range input[type="date"] { min-width: 0; flex: 1 1 8rem; }
  /* En móvil los operadores de la cadena estorban: las etiquetas ya
     dicen qué es cada cifra, y sin ellos entran dos por fila. */
  .payout-op { display: none; }
  .payout-chain { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
  .payout-step-meta { grid-column: 1 / -1; margin-left: 0; }
  .payout-closing-head { gap: var(--space-2); }
  .payout-closing-total { margin-left: 0; flex: 1 1 100%; }
  .home-income-figs { gap: var(--space-4); }
  .home-income-fig .v { font-size: 1.125rem; }
  .payout-table input.payout-exp { width: 5.5rem; }
  .payout-table input.payout-adj-amount { width: 4.25rem; }
}

/* ═════════════════════════════════════════════════════════════════════
   v2.2 — ajustes de operación
   Tooltips propios · confirmación de citas · menú del perfil y Ajustes ·
   Bandeja editable · filtros con conteo · seguimiento · fondo del colchón
   ═════════════════════════════════════════════════════════════════════ */

/* ── Tooltips propios ─────────────────────────────────────────────────
   Reemplazan al title="" nativo, que tarda ~1s en aparecer y lo pinta el
   sistema operativo con su tipografía y su color, fuera del sistema
   visual. Un solo nodo, posicionado contra el viewport por app.js. */
.rlx-tip {
  position: fixed;
  z-index: 900;
  max-width: 22rem;
  padding: 5px var(--space-2);
  border-radius: var(--r-sm);
  background: var(--n-900);
  color: var(--n-50);
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: var(--leading-snug);
  letter-spacing: 0;
  text-transform: none;
  white-space: pre-line;
  pointer-events: none;
  box-shadow: var(--shadow-md);
  opacity: 0;
  transform: translateY(3px);
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.rlx-tip.below { transform: translateY(-3px); }
.rlx-tip.is-visible { opacity: 1; transform: translateY(0); }
[data-theme="dark"] .rlx-tip {
  background: var(--n-200);
  color: var(--n-950);
}
@media (prefers-reduced-motion: reduce) {
  .rlx-tip { transition: none; transform: none; }
}

/* ── Segmentado: icono + texto ────────────────────────────────────────
   El tipo de cita se leía como cuatro palabras sueltas; con icono se
   reconoce de un golpe y aguanta el ancho de tablet. */
.seg-icon {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  opacity: 0.6;
  transition: opacity var(--dur-fast) var(--ease);
}
.seg input:checked + label .seg-icon { opacity: 1; }
.seg-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Tablet estrecha: el icono sostiene la identidad y el texto cede. */
@media (max-width: 900px) {
  .seg-type label { padding: 0 var(--space-1); }
}

/* Selector de tema (menú del perfil y preferencias). Botones normales en
   vez de radios porque el estado lo maneja JS y se repinta entero. */
.seg-theme {
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}
.seg-btn {
  border: 0;
  background: transparent;
  padding: 5px var(--space-3);
  border-radius: var(--r-sm);
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.seg-btn:hover { color: var(--text-strong); }
.seg-btn.is-on { background: var(--surface); color: var(--text-strong); font-weight: 600; box-shadow: var(--shadow-xs); }

/* ── Confirmación de la cita ──────────────────────────────────────────
   Marca en la tarjeta del calendario: el mismo círculo de `.ev-mark`, con
   el trazo al color pleno y el ✓ dentro. Lo que lo separa de completada es
   que aquél va relleno de verde: acá el hecho todavía puede cambiar.
   v2.8 — se fue el filete del borde izquierdo que además llevaba la card
   confirmada. Marcaba el mismo hecho dos veces y, con el check de
   completada al lado, terminaba leyéndose como un estado más. */
.ev-mark-confirmed {
  border-color: currentColor;
  font-size: 8px;
  opacity: 0.9;
}

/* Control de confirmación en el modal de cita */
.apt-confirm-box { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.apt-confirm-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 5px var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.apt-confirm-toggle:hover { border-color: var(--border-strong); color: var(--text-strong); }
.apt-confirm-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px; height: 16px;
  border-radius: var(--r-full);
  border: 1.5px solid currentColor;
  font-size: 10px;
  line-height: 1;
  opacity: 0.35;
  transition: opacity var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.apt-confirm-toggle.is-on {
  color: var(--ok-700);
  border-color: color-mix(in oklch, var(--ok) 40%, transparent);
  background: color-mix(in oklch, var(--ok) 8%, var(--surface));
}
.apt-confirm-toggle.is-on .apt-confirm-check { opacity: 1; background: color-mix(in oklch, var(--ok) 16%, transparent); }
.apt-confirm-when { font-size: var(--text-xs); color: var(--text-dim); }
[data-theme="dark"] .apt-confirm-toggle.is-on { color: var(--ok-500); }
/* En modo bloqueo no hay paciente que confirme (igual que el estado). */
#apt-modal[data-apt-mode="block"] .apt-confirm-field { display: none; }

/* Atajos a la ficha desde la tarjeta del paciente del modal */
.apt-pc-jumps { display: inline-flex; gap: 2px; flex-shrink: 0; }
.apt-pc-jump {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px; height: 30px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  color: var(--text-muted);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.apt-pc-jump:hover {
  color: var(--acc);
  border-color: color-mix(in oklch, var(--acc) 30%, var(--border));
  background-color: color-mix(in oklch, var(--acc) 8%, transparent);
}
/* Al doctor el modal le llega en lectura, pero la ficha del compañero de
   sede sí la puede abrir: los atajos siguen vivos. */
#apt-modal[data-readonly="true"] .apt-pc-jump { pointer-events: auto; }

/* ── Panel de avisos: la respuesta del paciente ───────────────────────
   Fila propia, separada de las acciones: no es "una acción más", es el
   resultado de haber mandado el mensaje, y las tres son excluyentes. */
.notif-reply {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px dashed var(--border);
}
.notif-reply-label {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--text-dim);
}
.notif-reply-btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  padding: 2px var(--space-3);
  font-size: var(--text-2xs);
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.notif-reply-btn.tone-ok:hover     { color: var(--ok-700);   border-color: color-mix(in oklch, var(--ok) 40%, transparent);   background: color-mix(in oklch, var(--ok) 10%, transparent); }
.notif-reply-btn.tone-warn:hover   { color: var(--warn-700); border-color: color-mix(in oklch, var(--warn) 45%, transparent); background: color-mix(in oklch, var(--warn) 12%, transparent); }
.notif-reply-btn.tone-danger:hover { color: var(--err-700);  border-color: color-mix(in oklch, var(--err) 40%, transparent);  background: color-mix(in oklch, var(--err) 10%, transparent); }
[data-theme="dark"] .notif-reply-btn.tone-ok:hover     { color: var(--ok-500); }
[data-theme="dark"] .notif-reply-btn.tone-warn:hover   { color: var(--warn-500); }
[data-theme="dark"] .notif-reply-btn.tone-danger:hover { color: var(--err-500); }

/* Etiqueta "confirmada" en las listas de Inicio */
.dochome-tag.is-ok { color: var(--ok-700); border-color: color-mix(in oklch, var(--ok) 32%, transparent); }
[data-theme="dark"] .dochome-tag.is-ok { color: var(--ok-500); }

/* ── Menú del perfil ──────────────────────────────────────────────── */
.user-wrap { position: relative; display: inline-flex; }
.user-chip[aria-expanded="true"] { background: var(--bg-sunken); }
.user-chip-icon { transition: transform var(--dur-base) var(--ease); }
.user-chip[aria-expanded="true"] .user-chip-icon { transform: rotate(180deg); }
.user-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: min(300px, calc(100vw - 32px));
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  z-index: 300;
  overflow: hidden;
}
.user-menu-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-3);
  border-bottom: 1px solid var(--border);
  background: var(--bg-sunken);
}
.user-menu-name { font-size: var(--text-base); font-weight: 600; color: var(--text-strong); }
.user-menu-sub { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.user-menu-mail {
  flex: 1;
  min-width: 0;
  font-size: var(--text-xs);
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.user-menu-role {
  flex-shrink: 0;
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--acc-text);
  background: var(--acc-soft);
  border-radius: var(--r-xs);
  padding: 1px 5px;
}
.user-menu-list { padding: var(--space-1); }
.user-menu-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  text-align: left;
  color: var(--text);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.user-menu-item:hover { background: var(--bg-sunken); color: var(--text-strong); }
.user-menu-icon {
  display: inline-flex;
  flex-shrink: 0;
  width: 18px; height: 18px;
  color: var(--text-muted);
}
.user-menu-item:hover .user-menu-icon { color: var(--acc); }
.user-menu-icon svg { width: 100%; height: 100%; }
.user-menu-text { display: flex; flex-direction: column; min-width: 0; }
.user-menu-label { font-size: var(--text-base); font-weight: 500; }
.user-menu-hint {
  font-size: var(--text-xs);
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.user-menu-foot {
  padding: var(--space-2) var(--space-1) var(--space-1);
  border-top: 1px solid var(--border);
}
.user-menu-theme {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 0 var(--space-3) var(--space-2);
}
.user-menu-theme-label { font-size: var(--text-sm); color: var(--text-muted); }
.user-menu-item.is-signout { color: var(--err-700); }
.user-menu-item.is-signout:hover { background: var(--err-bg); }
.user-menu-item.is-signout svg { width: 18px; height: 18px; flex-shrink: 0; }
[data-theme="dark"] .user-menu-item.is-signout { color: var(--err-500); }
@media (max-width: 640px) {
  .user-wrap { position: static; }
  .user-menu { left: var(--space-3); right: var(--space-3); width: auto; }
}

/* ── Sección Ajustes ──────────────────────────────────────────────── */
.set-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: 720px;
}
.set-head { display: flex; flex-direction: column; gap: var(--space-1); }
.set-title {
  margin: 0;
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  color: var(--text-strong);
}
.set-lede { margin: 0; font-size: var(--text-base); color: var(--text-muted); line-height: var(--leading-base); }
.set-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--pad-standard);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-xs);
}
.set-card-title {
  margin: 0;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--text-muted);
}
.set-card-lede { margin: calc(var(--space-2) * -1) 0 0; font-size: var(--text-sm); color: var(--text-dim); line-height: var(--leading-base); }
.set-card-actions { display: flex; align-items: center; gap: var(--space-3); }
.set-card-actions .spacer { flex: 1; }
.set-card-actions .profile-feedback { flex: 1; }
.set-field { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--text-sm); color: var(--text-muted); }
.set-field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-3); }
.set-field-narrow { max-width: 15rem; }
.set-field-unit { font-size: var(--text-xs); color: var(--text-dim); }
.set-note {
  margin: 0;
  padding-left: var(--space-3);
  border-left: 2px solid var(--border);
  font-size: var(--text-sm);
  color: var(--text-dim);
  line-height: var(--leading-base);
}
.set-card-danger { border-color: color-mix(in oklch, var(--err) 20%, var(--border)); }

/* v2.12 — Ajustes → Administradores */
.admins-list { display: flex; flex-direction: column; gap: 2px; }
.admins-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2);
  border-radius: var(--r-sm);
  font-size: var(--text-sm);
}
.admins-row:hover { background: var(--bg-sunken); }
.admins-row-name  { color: var(--text); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.admins-row-email { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-xs); }
.admins-row-role {
  font-size: 10px;
  font-weight: 500;
  padding: 2px var(--space-2);
  border-radius: var(--r-full);
  flex-shrink: 0;
  background: var(--acc-soft);
  color: var(--acc-text);
  border: 1px solid color-mix(in oklch, var(--acc) 22%, transparent);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}
/* Contraseña temporal del panel de éxito: mismo texto que
   .doctor-cred-static-value, con una caja para que se lea de un vistazo
   y quepa completa aunque el generador use 16+ caracteres. */
.admin-success-password {
  flex: 1;
  min-width: 0;
  font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
  padding: var(--space-2);
  background: var(--bg-sunken);
  border-radius: var(--r-sm);
}
.set-toggles { display: flex; flex-direction: column; gap: var(--space-1); }
.set-toggle {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.set-toggle:hover { background: var(--bg-sunken); }
.set-toggle input { margin-top: 3px; flex-shrink: 0; accent-color: var(--acc); }
.set-toggle-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.set-toggle-label { font-size: var(--text-base); color: var(--text); }
.set-toggle-hint { font-size: var(--text-xs); color: var(--text-dim); line-height: var(--leading-snug); }
/* La ficha de cuenta reusa las clases del viejo modal de perfil. */
#view-set-account .profile-meta-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
#view-set-account .profile-meta-row + .profile-meta-row { margin-top: var(--space-2); padding-top: var(--space-2); border-top: 1px solid var(--border); }
.payout-chain-demo { opacity: 0.9; }

/* ── Filtros con punto y conteo ───────────────────────────────────────
   Un filtro que dice "12" es información antes de pulsarlo; seis palabras
   sueltas no eran nada. El punto reusa el color del chip de estado de la
   fila, así que el filtro y el resultado hablan el mismo idioma. */
.filter-pills-rich { gap: 2px; }
.pill-rich {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px var(--space-2) 5px var(--space-3);
}
.pill-dot {
  width: 7px; height: 7px;
  flex-shrink: 0;
  border-radius: var(--r-full);
  background: currentColor;
  opacity: 0.5;
}
.pill-rich.active .pill-dot { opacity: 1; }
/* El punto toma el color del estado al que apunta el filtro. Mismas
   variables que .status-chip: una sola verdad de color por estado. */
.pill-dot.status-NEW_LEAD            { color: var(--info-700); }
.pill-dot.status-VALUATION_SCHEDULED { color: var(--acc); }
.pill-dot.status-VALUATION_DONE      { color: var(--info); }
.pill-dot.status-TREATMENT_ACCEPTED  { color: var(--ok); }
.pill-dot.status-TREATMENT_FINISHED  { color: var(--text-muted); }
.pill-dot.status-NOT_CONTINUED       { color: var(--err); }
.pill-dot.status-INACTIVE            { color: var(--warn-700); }
[data-theme="dark"] .pill-dot.status-NEW_LEAD { color: var(--info-500); }
[data-theme="dark"] .pill-dot.status-INACTIVE { color: var(--warn-500); }
.pill-label { white-space: nowrap; }
.pill-count {
  flex-shrink: 0;
  min-width: 1.35rem;
  padding: 0 5px;
  border-radius: var(--r-full);
  /* `--border` y no `--bg-sunken`: el contenedor de pills YA es sunken y
     el contador desaparecería dentro de él. */
  background: var(--border);
  font-size: var(--text-2xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.45;
  text-align: center;
  color: var(--text-dim);
}
.pill-rich.active .pill-count { background: var(--acc-soft); color: var(--acc-text); }
.pill-rich.is-empty { opacity: 0.5; }
.pill-rich.is-empty:hover { opacity: 1; }
.pill-star-icon { display: inline-flex; flex-shrink: 0; color: var(--acc); opacity: 0.55; }
.pill-rich.active .pill-star-icon { opacity: 1; }
[data-theme="dark"] .pill-rich.active .pill-count { background: color-mix(in oklch, var(--acc) 22%, transparent); color: var(--acc-200); }

/* ── Bandeja: fila editable ───────────────────────────────────────────
   Todo lo que se diligencia de un lead se escribe sin abrir la ficha. Los
   campos de texto parecen texto hasta que se les pasa por encima: la fila
   no engorda ni se lee como un formulario. */
.leads-grid .col-lead-identity { min-width: 200px; }
.leads-grid .col-lead-city     { width: 130px; }
.leads-grid .col-lead-channel  { width: 132px; }
.leads-grid .col-lead-ad       { width: 160px; }
.leads-grid .col-lead-status   { width: 172px; }
.leads-grid .col-lead-date     { width: 132px; }
.leads-grid .col-lead-actions  { width: 168px; }

.lead-identity { display: flex; align-items: center; gap: 6px; min-width: 0; }
.lead-fields { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
/* La estrella es una MARCA, no un botón: se enciende y se apaga desde el
   grupo de acciones, igual que en el listado de Pacientes. Ponerle un
   click propio duplicaría el gesto en dos sitios de la misma fila. */
.lead-star { flex-shrink: 0; margin-left: 0; line-height: 1; }
.lead-actions { text-align: right; }

/* Campo que parece texto. El borde aparece con hover/foco: hasta entonces
   la fila se lee como una tabla, no como cincuenta inputs apilados. */
.cell-input {
  width: 100%;
  min-width: 0;
  padding: 3px var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: transparent;
  font-family: inherit;
  font-size: var(--text-sm);
  color: var(--text);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.cell-input::placeholder { color: var(--text-disabled); }
tr:hover .cell-input { border-color: color-mix(in oklch, var(--border) 70%, transparent); }
.cell-input:hover { border-color: var(--border); }
.cell-input:focus {
  outline: none;
  border-color: var(--acc);
  background: var(--surface);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--acc) 14%, transparent);
}
/* Rastro del guardado (M4 · Marginalia). En un campo de texto el pulso de
   escala de `.cell-select` se lee como un tic; lo que hace falta acá es el
   acuse de recibo de que lo escrito quedó guardado, y eso es el acento
   apareciendo y desvaneciéndose en el borde. */
@keyframes rlx-cell-saved {
  0%   { border-color: var(--acc); background: color-mix(in oklch, var(--acc) 10%, transparent); }
  100% { border-color: transparent; background: transparent; }
}
.cell-input.is-just-changed { animation: rlx-cell-saved var(--dur-trace) var(--ease-trace) 1; }
@media (prefers-reduced-motion: reduce) {
  .cell-input.is-just-changed { animation: none; }
}
.cell-name { font-weight: 600; font-size: var(--text-base); color: var(--text-strong); }
.cell-phone { font-size: var(--text-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.cell-date { font-variant-numeric: tabular-nums; font-size: var(--text-xs); }
/* El icono nativo del datepicker sólo aparece al pasar por la fila: si no,
   cincuenta calendarios compiten con el resto de la tabla. */
.cell-date::-webkit-calendar-picker-indicator { opacity: 0; cursor: pointer; }
tr:hover .cell-date::-webkit-calendar-picker-indicator,
.cell-date:focus::-webkit-calendar-picker-indicator { opacity: 0.5; }
[data-theme="dark"] .cell-date::-webkit-calendar-picker-indicator { filter: invert(1); }

/* Acciones de la fila: aparecen al pasar por encima, como en Pacientes. */
.data-grid tbody tr:hover .quick-act { opacity: 1; }
.quick-act.is-danger:hover {
  color: var(--err);
  border-color: color-mix(in oklch, var(--err) 30%, var(--border));
  background-color: color-mix(in oklch, var(--err) 8%, transparent);
}
a.quick-act { text-decoration: none; }
span.quick-act { cursor: default; }

/* ── Seguimiento en la ficha ──────────────────────────────────────── */
.pf-wrap { display: flex; flex-direction: column; gap: var(--space-4); max-width: 720px; }
.pf-toggle {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.pf-toggle:hover { border-color: var(--border-strong); }
.pf-switch.is-on .pf-toggle {
  border-color: color-mix(in oklch, var(--ok) 35%, transparent);
  background: color-mix(in oklch, var(--ok) 5%, var(--surface));
}
.pf-toggle-track {
  flex-shrink: 0;
  position: relative;
  width: 36px; height: 20px;
  margin-top: 2px;
  border-radius: var(--r-full);
  background: var(--n-300);
  transition: background var(--dur-base) var(--ease);
}
[data-theme="dark"] .pf-toggle-track { background: var(--n-700); }
.pf-toggle-knob {
  position: absolute;
  top: 2px; left: 2px;
  width: 16px; height: 16px;
  border-radius: var(--r-full);
  background: var(--n-0);
  box-shadow: var(--shadow-xs);
  transition: transform var(--dur-base) var(--ease);
}
.pf-switch.is-on .pf-toggle-track { background: var(--ok); }
.pf-switch.is-on .pf-toggle-knob { transform: translateX(16px); }
.pf-toggle-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pf-toggle-title { font-size: var(--text-md); font-weight: 600; color: var(--text-strong); }
.pf-toggle-hint { font-size: var(--text-sm); color: var(--text-muted); line-height: var(--leading-snug); }
.pf-auto {
  margin: 0;
  padding-left: var(--space-3);
  border-left: 2px solid color-mix(in oklch, var(--acc) 40%, transparent);
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: var(--leading-base);
}
.pf-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-3); }
.pf-field { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--text-sm); color: var(--text-muted); }
.pf-readout-label {
  font-size: var(--text-2xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--text-dim);
}
.pf-readout-value { font-size: var(--text-base); color: var(--text-strong); }
.pf-readout-value.is-overdue { color: var(--err-700); font-weight: 600; }
[data-theme="dark"] .pf-readout-value.is-overdue { color: var(--err-500); }
.pf-note-field { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--text-sm); color: var(--text-muted); }
.pf-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.pf-history { display: flex; flex-direction: column; gap: var(--space-1); }
.pf-history-title {
  margin: 0 0 var(--space-1);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--text-muted);
}
.pf-history-row {
  display: grid;
  grid-template-columns: 8rem 1fr auto;
  gap: var(--space-3);
  align-items: baseline;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border);
  font-size: var(--text-sm);
}
.pf-history-date { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.pf-history-note { color: var(--text); min-width: 0; }
.pf-history-status { font-size: var(--text-xs); color: var(--text-dim); }
.pf-history-row.is-done { opacity: 0.55; }
.pf-history-row.is-done .pf-history-status { color: var(--ok-700); }
[data-theme="dark"] .pf-history-row.is-done .pf-history-status { color: var(--ok-500); }
.followup-interval { color: var(--text-dim); }
.followup-note { margin-top: 2px; font-size: var(--text-xs); color: var(--text-dim); }
.row-action.is-danger:hover { color: var(--err); border-color: color-mix(in oklch, var(--err) 35%, transparent); }
.prices-followup-tag {
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: var(--r-xs);
  background: color-mix(in oklch, var(--ok) 12%, transparent);
  color: var(--ok-700);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}
[data-theme="dark"] .prices-followup-tag { color: var(--ok-500); }

/* ── Porcentajes por pago ─────────────────────────────────────────── */
.payment-rates {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-sunken);
}
.payment-rates > summary {
  cursor: pointer;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text-muted);
  list-style: none;
}
.payment-rates > summary::-webkit-details-marker { display: none; }
.payment-rates > summary::before {
  content: "\25B8";
  display: inline-block;
  margin-right: 6px;
  font-size: 9px;
  color: var(--text-dim);
  transition: transform var(--dur-fast) var(--ease);
}
.payment-rates[open] > summary::before { transform: rotate(90deg); }
.payment-rates[open] > summary { margin-bottom: var(--space-2); color: var(--text-strong); }
.payment-rates.is-custom { border-color: color-mix(in oklch, var(--warn) 45%, transparent); }
.payment-rates-badge {
  margin-left: var(--space-2);
  padding: 1px 6px;
  border-radius: var(--r-full);
  background: var(--warn-bg);
  color: var(--warn-700);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}
[data-theme="dark"] .payment-rates-badge { color: var(--warn-500); background: color-mix(in oklch, var(--warn) 18%, transparent); }
.payment-rates-foot { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-2); }
.payment-rates-foot .field-help { flex: 1; }

/* ── Reparto: arrastre y fondo del colchón ────────────────────────── */
.payout-carry {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-3);
  border: 1px dashed var(--border);
  border-radius: var(--r-md);
  background: var(--bg-sunken);
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.payout-carry:empty { display: none; }
.payout-carry-lead strong { color: var(--text-strong); font-variant-numeric: tabular-nums; }
.payout-carry-bit { display: inline-flex; gap: var(--space-2); align-items: baseline; }
.payout-carry-bit .k { font-size: var(--text-xs); color: var(--text-dim); }
.payout-carry-bit .v { font-variant-numeric: tabular-nums; color: var(--text); }
.payout-carry-sum { margin-left: auto; color: var(--text-dim); }
.payout-carry-sum strong { color: var(--acc-text); font-variant-numeric: tabular-nums; }

.payout-fund-docs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin-bottom: var(--space-3);
}
.payout-fund-doc { display: flex; flex-direction: column; gap: 1px; }
.payout-fund-doc .k { font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: var(--tracking-caps); color: var(--text-dim); }
.payout-fund-doc .v { font-size: var(--text-lg); font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text-strong); }
.payout-fund-doc .v.is-neg { color: var(--err-700); }
[data-theme="dark"] .payout-fund-doc .v.is-neg { color: var(--err-500); }
.payout-fund-table tr.is-draft { opacity: 0.6; }
.payout-fund-table tr.is-live { font-style: italic; }
.payout-fund-table tr.is-live .is-cushion { font-style: normal; color: var(--acc-text); }
.payout-status.is-live { color: var(--text-dim); border-color: var(--border); }

.payout-block-slim { padding: var(--space-3) var(--pad-standard); }
.payout-rates-line {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.payout-rates-bit { display: inline-flex; gap: var(--space-2); align-items: baseline; }
.payout-rates-bit .k { font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: var(--tracking-caps); color: var(--text-dim); }
.payout-rates-bit .v { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text-strong); }
.payout-rates-note { margin-left: auto; font-size: var(--text-xs); color: var(--text-dim); }

/* ── Responsive de lo nuevo ───────────────────────────────────────── */
@media (max-width: 1024px) {
  /* Tablet: la pauta cede antes que nada — es el dato que menos se
     consulta de un vistazo y el que más ancho pide. */
  .leads-grid .col-lead-ad,
  .leads-grid .lead-ad { display: none; }
  .payout-carry-sum, .payout-rates-note { margin-left: 0; flex: 1 1 100%; }
}
@media (max-width: 768px) {
  .leads-grid .col-lead-channel,
  .leads-grid .lead-channel { display: none; }
  .set-page { max-width: none; }
}
@media (max-width: 640px) {
  .pf-history-row { grid-template-columns: 1fr auto; }
  .pf-history-date { grid-column: 1 / -1; }
  .payout-fund-docs { gap: var(--space-2) var(--space-4); }
}

/* Pregunta del seguimiento al pie del plan terminado (v2.2). Aparece
   donde se toma la decisión —con el tratamiento delante— y no cinco
   pantallas más allá. */
.plan-followup {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  margin-top: var(--space-3);
  padding: var(--space-3);
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
  background: var(--bg-sunken);
  font-size: var(--text-sm);
  color: var(--text-muted);
}
.plan-followup.is-on {
  border-style: solid;
  border-color: color-mix(in oklch, var(--ok) 35%, transparent);
  background: color-mix(in oklch, var(--ok) 6%, var(--surface));
}
.plan-followup-text { flex: 1; min-width: 12rem; line-height: var(--leading-snug); }
.plan-followup-text strong { color: var(--text-strong); }
.plan-followup-link { flex-shrink: 0; }
