/* SF Pro Display is loaded natively via the system font stack below
   (-apple-system / BlinkMacSystemFont). The previous @font-face rules
   pointed to /Document fonts/*.OTF which were never committed and 404'd
   on every page. Stack order keeps Apple devices on SF Pro and gives
   non-Apple a clean fallback. */

/* ===== RESET & BASE ===== */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
  font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

body {
  font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
}

input, button, textarea, select, optgroup {
  font-family: inherit;
  font-size: inherit;
}

/* ===== COLOR VARIABLES ===== */
:root {
  /* Brand — primary navy + verde BEPP */
  --primary-dark: #184d6c;
  --primary: #1d5c80;
  --primary-soft: #4A7A9A;
  --primary-light: #4A7A9A;
  /* alias — kept for legacy class consumers */
  --accent: #A4C634;
  --accent-hover: #8DB02A;
  --accent-soft: #D9E8A8;

  /* Sky family — capa azul suave y acogedora */
  --sky-soft: #E9F2F8;
  --sky: #88B2CE;
  --sky-deep: #7ed3f3;

  /* Surfaces & text — neutros blancos, feel paciente */
  --bg: #FFFFFF;
  --surface-alt: #F6F8FB;
  --card: #FFFFFF;
  --text: #1d5c80;
  --text-secondary: #7A8598;
  --text-light: #A8B2C1;
  --border: #E8ECF0;
  --border-light: #F3F5F8;

  /* Semánticos — tonos suavizados, menos clínicos */
  --success: #7FB77E;
  --warning: #E8A55C;
  --danger: #da392e;
  --info: #7FB3D5;

  /* ===== STATUS PALETTE — semánticos con variantes soft / strong =====
     Úsalos cuando necesites un tono específico (fondo suave de alerta,
     texto de alto contraste, borde de éxito, etc.). Evita hex sueltos. */
  --status-success: #7FB77E;
  --status-success-soft: #E8F5E9;
  --status-success-strong: #15803D;
  --status-warning: #E8A55C;
  --status-warning-soft: #FEF3C7;
  --status-warning-strong: #B45309;
  --status-danger: #da392e;
  --status-danger-soft: #FEE2E2;
  --status-danger-strong: #B91C1C;
  --status-info: #7FB3D5;
  --status-info-soft: #DBEAFE;
  --status-info-strong: #2563EB;

  /* ===== DATA PALETTE — categorías / módulos / charts =====
     Paleta neutral pensada para distinguir categorías no semánticas
     (especialidades, módulos, series de datos). Armonizada con BEPP. */
  --data-1: #2F7CA8;   /* navy-blue  */
  --data-2: #4C9F70;   /* green      */
  --data-3: #C59A42;   /* amber      */
  --data-4: #B85C5C;   /* red-brick  */
  --data-5: #7A5FB3;   /* violet     */
  --data-6: #C27AA8;   /* rose       */
  --data-7: #4BA3A8;   /* teal       */
  --data-8: #8A6A4A;   /* sepia      */
  --data-1-soft: #E5F0F6;
  --data-2-soft: #E8F3EC;
  --data-3-soft: #F6EEDB;
  --data-4-soft: #F6E3E3;
  --data-5-soft: #ECE6F5;
  --data-6-soft: #F4E4EE;
  --data-7-soft: #E3F1F2;
  --data-8-soft: #EFE8E0;

  /* ===== PROCEDURE TYPES — timeline event categories =====
     Tonos categóricos para tipos de evento clínico no cubiertos por
     primary/accent/sky/danger (que se usan para consulta/medicamento/
     enfermería/urgencias). Cada uno con variante -soft para fondo. */
  --proc-hospitalizacion: #6E56CF;
  --proc-hospitalizacion-soft: rgba(110, 86, 207, 0.10);
  --proc-quirurgico: #D97706;
  --proc-quirurgico-soft: rgba(217, 119, 6, 0.10);
  --proc-procedimiento: #0E7490;
  --proc-procedimiento-soft: rgba(14, 116, 144, 0.10);
  --proc-estudio: #7C3AED;
  --proc-estudio-soft: rgba(124, 58, 237, 0.10);

  /* ===== SUBSCRIPTION TIERS + PREMIUM =====
     3 tiers del paciente, monocromáticos, sin mezcla primary+accent.
       Esencial ($0)         — neutral, no premium
       Cuidado ($99)         — primary/azul, cuidado médico
       Cuidado Familia ($359)— violet (data-5), familiar premium
     --premium               — dorado mate, marca cualquier feature de paga
                               (independiente del tier requerido)               */
  --tier-esencial: var(--gray-500);
  --tier-esencial-soft: var(--gray-100);
  --tier-esencial-strong: var(--gray-600);

  --tier-cuidado: var(--primary);
  --tier-cuidado-soft: var(--sky-soft);
  --tier-cuidado-strong: var(--primary-dark);

  --tier-familia: var(--data-5);
  --tier-familia-soft: var(--data-5-soft);
  --tier-familia-strong: #5E4694;

  --premium: #B8893F;
  --premium-hover: #9C7332;
  --premium-strong: #8C6526;
  --premium-soft: #F2E8D2;

  /* ===== GRAY SCALE — neutrals for UI chrome ===== */
  --gray-50: #F9FAFB;
  --gray-100: #F3F5F8;
  --gray-200: #E8ECF0;
  --gray-300: #CBD5E1;
  --gray-400: #9CA3AF;
  --gray-500: #7A8598;
  --gray-600: #475569;
  --gray-700: #333333;
  --gray-800: #222222;
  --gray-900: #111111;
  --black: #000000;
  --white: #FFFFFF;

  --header-height: 64px;

  /* ===== BREAKPOINTS — esquema responsivo unificado =====
     CSS no permite var() dentro de @media, pero mantenemos estos tokens
     como fuente única de verdad. Cualquier media query del proyecto
     debe usar exclusivamente 640px (mobile) y 1024px (tablet).
       Mobile   ≤ 640px   — 1 columna, touch targets 44px, tipografía ↓
       Tablet   ≤ 1024px  — 2 columnas, grids reflow, nav compacto
       Desktop  > 1024px  — layout multi-columna completo                */
  --bp-mobile: 640px;
  --bp-tablet: 1024px;

  /* ===== RADIUS ===== */
  --radius-xs: 6px;
  /* dense badges, tight inputs */
  --radius-sm: 10px;
  /* inputs, small buttons */
  --radius-md: 14px;
  /* cards, buttons (standard) */
  --radius-lg: 20px;
  /* modals, form-views */
  --radius-xl: 36px;
  /* oversized (video frames) */
  --radius-full: 999px;
  /* pills, circles */
  --radius-pill: var(--radius-full);
  /* alias legacy — patterns.css usa --radius-pill en ~50 lugares */

  /* ===== SHADOW — tinte navy, difusas ===== */
  --shadow-xs: 0 2px 8px rgba(20, 40, 70, 0.05);
  --shadow-sm: 0 6px 20px rgba(20, 40, 70, 0.07);
  --shadow-md: 0 12px 32px rgba(20, 40, 70, 0.09);
  --shadow-lg: 0 24px 70px rgba(20, 40, 70, 0.14);
  --shadow-accent: 0 8px 22px rgba(160, 195, 52, 0.30);
  --shadow-primary: 0 8px 22px rgba(27, 73, 101, 0.22);
  --shadow-sky: 0 8px 22px rgba(127, 179, 213, 0.40);
  --shadow-data-1: 0 8px 22px rgba(47, 124, 168, 0.30);
  --shadow-data-2: 0 8px 22px rgba(76, 159, 112, 0.30);
  --shadow-data-3: 0 8px 22px rgba(197, 154, 66, 0.30);
  --shadow-data-4: 0 8px 22px rgba(184, 92, 92, 0.30);
  --shadow-data-5: 0 8px 22px rgba(122, 95, 179, 0.30);
  --shadow-data-6: 0 8px 22px rgba(194, 122, 168, 0.30);
  --shadow-data-7: 0 8px 22px rgba(75, 163, 168, 0.30);
  --shadow-data-8: 0 8px 22px rgba(138, 106, 74, 0.30);
  --shadow-tier-cuidado: var(--shadow-primary);
  --shadow-tier-familia: var(--shadow-data-5);
  --shadow-premium: 0 8px 22px rgba(184, 137, 63, 0.30);

  /* ===== ALPHA TINTS — tintes decorativos puntuales.
     No son elevación (para eso usar --shadow-*). Úsalos para backgrounds
     sutiles, focus rings, overlays semi-transparentes y gradientes. ===== */
  --primary-50: #f0f7ff;
  --primary-alpha-04: rgba(29, 92, 128, 0.04);
  --primary-alpha-06: rgba(29, 92, 128, 0.06);
  --primary-alpha-08: rgba(29, 92, 128, 0.08);
  --primary-alpha-12: rgba(29, 92, 128, 0.12);
  --primary-alpha-15: rgba(29, 92, 128, 0.15);
  --accent-alpha-10: rgba(164, 198, 52, 0.10);
  --accent-alpha-15: rgba(164, 198, 52, 0.15);
  --accent-alpha-25: rgba(164, 198, 52, 0.25);
  --accent-alpha-30: rgba(164, 198, 52, 0.30);
  --accent-alpha-85: rgba(164, 198, 52, 0.85);
  --sky-deep-alpha-35: rgba(126, 211, 243, 0.35);
  --danger-alpha-15: rgba(218, 57, 46, 0.15);
  --danger-alpha-45: rgba(218, 57, 46, 0.45);
  --danger-alpha-00: rgba(218, 57, 46, 0);
  --white-alpha-10: rgba(255, 255, 255, 0.10);
  --white-alpha-30: rgba(255, 255, 255, 0.30);
  --white-alpha-70: rgba(255, 255, 255, 0.70);
  --white-alpha-88: rgba(255, 255, 255, 0.88);
  --black-alpha-12: rgba(0, 0, 0, 0.12);
  --black-alpha-30: rgba(0, 0, 0, 0.30);
  --overlay-backdrop: rgba(20, 40, 70, 0.38);

  /* ===== SPACING — token name = px value.
     Fine-grained below 8px, step-of-4 through 24, widening for layout. ===== */
  --space-0: 0;
  --space-1: 1px;
  --space-2: 2px;
  --space-3: 3px;
  --space-4: 4px;
  --space-5: 5px;
  --space-6: 6px;
  --space-7: 7px;
  --space-8: 8px;
  --space-10: 10px;
  --space-12: 12px;
  --space-14: 14px;
  --space-16: 16px;
  --space-18: 18px;
  --space-20: 20px;
  --space-22: 22px;
  --space-24: 24px;
  --space-28: 28px;
  --space-32: 32px;
  --space-36: 36px;
  --space-40: 40px;
  --space-48: 48px;
  --space-56: 56px;
  --space-64: 64px;
  --space-72: 72px;
  --space-80: 80px;
  --space-96: 96px;
  --space-112: 112px;
  --space-128: 128px;

  /* ===== TYPOGRAPHY — font-size ===== */
  --font-3xs: 0.5625rem;
  /* 9px */
  --font-2xs: 0.625rem;
  /* 10px */
  --font-xs: 0.75rem;
  /* 12px */
  --font-sm: 0.875rem;
  /* 14px */
  --font-base: 1rem;
  /* 16px */
  --font-md: 1.125rem;
  /* 18px */
  --font-lg: 1.375rem;
  /* 22px */
  --font-xl: 1.75rem;
  /* 28px */
  --font-2xl: 2.25rem;
  /* 36px */
  --font-3xl: 2.8125rem;
  /* 45px */
  --font-4xl: 3.375rem;
  /* 54px */

  /* ===== LINE-HEIGHT ===== */
  --lh-tight: 1.15;
  --lh-snug: 1.3;
  --lh-normal: 1.5;
  --lh-loose: 1.7;

  /* ===== FONT WEIGHT ===== */
  --fw-light: 300;
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-extrabold: 800;
  --fw-black: 900;

  /* ===== LETTER SPACING ===== */
  --tracking-caps: 0.06em;   /* uppercase labels (sweep §D2) */
  --tracking-caps-sm: 0.04em;

  /* ===== LETTER SPACING ===== */
  --tracking-tighter: -0.02em;
  --tracking-tight: -0.01em;
  --tracking-normal: 0;
  --tracking-wide: 0.03em;
  --tracking-wider: 0.08em;

  /* ===== MOTION — duraciones + curvas =====
     Industria primero (memoria: industria_estandar): replican iOS HIG
     y Material por default. Spring snap es el cubic-bezier de Apple
     usado en bottom sheets / page transitions.
       --duration-fast   150ms — micro (hover, active, ripple)
       --duration-base   250ms — botones, fades, cards
       --duration-slow   350ms — entradas/salidas grandes (sheets)
       --duration-page-transition 240ms — slide entre pantallas (router)
       --duration-spring 280ms — snap de bottom sheet, swipe-back
     Curvas:
       --ease-out         estándar entrada (decelerate)
       --ease-in          estándar salida (accelerate)
       --ease-in-out      loops, pulsos
       --ease-ios-default curva default de iOS para todo
       --spring-snap      cierre/apertura de sheets, swipe-back commit
       --spring-bounce    micro overshoot para celebraciones (success toast) */
  --duration-fast: 150ms;
  --duration-base: 250ms;
  --duration-slow: 350ms;
  --duration-page-transition: 240ms;
  --duration-spring: 280ms;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in: cubic-bezier(0.7, 0, 0.84, 0);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-ios-default: cubic-bezier(0.25, 0.1, 0.25, 1);
  --spring-snap: cubic-bezier(0.32, 0.72, 0.30, 0.99);
  --spring-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* ===== SHADOW TOKENS =====
     Tint con --primary-dark (#184d6c) para que las sombras tengan un
     pigmento sutil de la marca, no negro plano. Snap a 3 tamaños:
       --shadow-sm   hover sutil de cards/links
       --shadow-md   cards elevadas, dropdowns
       --shadow-lg   modals, sheets, popovers
     Antes había hardcoded rgba en animations.css — sweep §4.2 + §3.2. */
  --shadow-sm: 0 1px 3px rgba(24, 77, 108, 0.06), 0 1px 2px rgba(24, 77, 108, 0.04);
  --shadow-md: 0 8px 24px rgba(24, 77, 108, 0.08), 0 2px 6px rgba(24, 77, 108, 0.04);
  --shadow-lg: 0 20px 48px rgba(24, 77, 108, 0.12), 0 4px 12px rgba(24, 77, 108, 0.06);
}

/* ===== BADGE SYSTEM =====
   Base + modifiers. Compose:
   <span class="bepp-badge bepp-badge--success">Active</span>
   <span class="bepp-badge bepp-badge--eyebrow">Coverage</span>
   <span class="bepp-badge bepp-badge--count">3</span>
*/
.bepp-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: 4px 10px;
  border-radius: 999px;
  font-size: var(--font-xs);
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  background: var(--border-light);
  color: var(--text-secondary);
}
.bepp-badge[hidden],
.bepp-badge--count[hidden],
.bepp-badge--dot[hidden] { display: none !important; }

/* Shape modifiers */
.bepp-badge--square {
  border-radius: 6px;
}

/* Eyebrow — small uppercase section label */
.bepp-badge--eyebrow {
  padding: 5px 14px;
  background: rgba(160, 195, 52, 0.12);
  color: var(--accent-hover);
  font-size: var(--font-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* Status / semantic */
.bepp-badge--success {
  background: var(--status-success-soft);
  color: var(--status-success-strong);
}

.bepp-badge--warning {
  background: var(--status-warning-soft);
  color: var(--status-warning-strong);
}

.bepp-badge--danger {
  background: var(--status-danger-soft);
  color: var(--danger);
}

.bepp-badge--info {
  background: var(--status-info-soft);
  color: var(--status-info-strong);
}

.bepp-badge--neutral {
  background: var(--border-light);
  color: var(--text-secondary);
}

/* On-dark — for hero / dark sections */
.bepp-badge--on-dark {
  background: rgba(255, 255, 255, 0.15);
  color: var(--white);
}

/* Tag — content pill (categories, filters) */
.bepp-badge--tag {
  padding: 5px 12px;
  font-size: var(--font-xs);
  font-weight: 600;
  border-radius: var(--radius-md);
  background: var(--border-light);
  color: var(--text);
}

/* Count — notification circle (pair with .bepp-badge--danger for red) */
.bepp-badge--count {
  width: 18px;
  height: 18px;
  min-width: 18px;
  padding: 0;
  font-size: var(--font-2xs);
  border-radius: 50%;
  background: var(--danger);
  color: var(--white);
}

/* Dot — solid status dot (no text) */
.bepp-badge--dot {
  width: 8px;
  height: 8px;
  min-width: 8px;
  padding: 0;
  border-radius: 50%;
}

/* Tag-accent — brand-colored chip with soft accent tint + border.
   Used for hero eyebrows with border, nav pills, feature highlights. */
.bepp-badge--tag-accent {
  padding: 6px 16px;
  border-radius: var(--radius-lg);
  background: rgba(160, 195, 52, 0.15);
  border: 1px solid rgba(160, 195, 52, 0.35);
  color: var(--accent-hover);
}

/* Compact — dense notification / protocol status badge.
   Compose with a semantic modifier (e.g. --success, --warning). */
.bepp-badge--compact {
  padding: 2px 8px;
  border-radius: 8px;
  font-size: var(--font-2xs);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

/* Micro — smallest inline badge (request/vital labels).
   Compose with a semantic modifier. */
.bepp-badge--micro {
  padding: 2px 6px;
  border-radius: var(--radius-xs);
  font-size: var(--font-3xs);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

/* Accent gradient — premium / featured callout pill (e.g. "TOP" chip). */
.bepp-badge--accent-gradient {
  padding: 4px 9px;
  font-size: var(--font-2xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: linear-gradient(135deg, var(--accent-hover), var(--accent));
  color: var(--white);
}

/* AI — gradient + shadow pill for AI-generated content indicators. */
.bepp-badge--ai {
  padding: 5px 14px;
  border-radius: var(--radius-full);
  font-size: var(--font-sm);
  font-weight: 800;
  gap: var(--space-6);
  background: linear-gradient(135deg, var(--primary-light), var(--accent));
  color: var(--white);
  box-shadow: 0 2px 8px rgba(27, 73, 101, 0.2);
}

/* Premium — pill dorado para marcar features de paga (genérico, sin tier).
   Análogo al badge de IA pero independiente: comunica "esto cuesta", no
   "esto es IA". Combina con icono de candado/star inline.
   Uso:  <span class="bepp-badge bepp-badge--premium">
           <svg class="bepp-icon-xs">…</svg> Premium
         </span>                                                              */
.bepp-badge--premium {
  padding: 5px 14px;
  border-radius: var(--radius-full);
  font-size: var(--font-2xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  gap: var(--space-6);
  background: linear-gradient(135deg, var(--premium), var(--premium-strong));
  color: var(--white);
  box-shadow: var(--shadow-premium);
}
/* Variante soft — para listas largas o filas densas donde el shadow distrae. */
.bepp-badge--premium-soft {
  padding: 4px 10px;
  border-radius: var(--radius-full);
  font-size: var(--font-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  gap: var(--space-4);
  background: var(--premium-soft);
  color: var(--premium-strong);
}

/* ===== BEPP TIER CHIP =====
   3 chips para diferenciar tier de suscripción del paciente.
       Esencial ($0) · Cuidado ($99) · Cuidado Familia ($359)
   Monocromático por tier (sin mezcla primary+accent).
   Uso:
     <span class="bepp-tier-chip bepp-tier-chip--cuidado">Cuidado</span>
     <span class="bepp-tier-chip bepp-tier-chip--familia bepp-tier-chip--solid">Familia</span>

   Variante "lock" — feature bloqueada, comunica el tier requerido:
     <span class="bepp-tier-chip bepp-tier-chip--cuidado bepp-tier-chip--lock">
       <svg class="bepp-icon-xs">…lock…</svg> Necesitas Cuidado
     </span>                                                                  */
.bepp-tier-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding: 4px 10px;
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-tight);
  border-radius: var(--radius-full);
  border: 1px solid transparent;
  line-height: 1.1;
  white-space: nowrap;
}
.bepp-tier-chip .icon,
.bepp-tier-chip .i { color: currentColor; }

.bepp-tier-chip--esencial {
  background: var(--tier-esencial-soft);
  color: var(--tier-esencial-strong);
  border-color: var(--tier-esencial-soft);
}
.bepp-tier-chip--cuidado {
  background: var(--tier-cuidado-soft);
  color: var(--tier-cuidado-strong);
  border-color: var(--tier-cuidado-soft);
}
.bepp-tier-chip--familia {
  background: var(--tier-familia-soft);
  color: var(--tier-familia-strong);
  border-color: var(--tier-familia-soft);
}

/* Variante sólida — header de plan, callout de upsell, badge en card hero. */
.bepp-tier-chip--solid.bepp-tier-chip--esencial {
  background: var(--tier-esencial);
  color: var(--white);
  border-color: var(--tier-esencial);
}
.bepp-tier-chip--solid.bepp-tier-chip--cuidado {
  background: var(--tier-cuidado);
  color: var(--white);
  border-color: var(--tier-cuidado);
}
.bepp-tier-chip--solid.bepp-tier-chip--familia {
  background: var(--tier-familia);
  color: var(--white);
  border-color: var(--tier-familia);
}

/* Variante "lock" — feature bloqueada por plan insuficiente. Mismo color
   del tier requerido + icono candado inline (lo aporta el HTML).            */
.bepp-tier-chip--lock {
  text-transform: uppercase;
  font-size: var(--font-2xs);
  letter-spacing: 0.04em;
}

/* ===== TIER GATING — badge + upsell (js/paciente-tier.js) =====
   Aplicado declarativamente a [data-bepp-gate] y [data-bepp-tier-chip].
   El badge inyectado (.bepp-gate-badge) marca la función como IA y/o de
   paga; cuando el tier no alcanza, la superficie toma .is-locked y al
   tocar abre el sheet de upsell (.bepp-tier-upsell).                     */
.bepp-gate-badge {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
}
/* En la Beppi bar el badge se ancla a la orilla derecha. */
.ph-beppi-bar .bepp-gate-badge { margin-left: auto; margin-right: var(--space-4); }
/* Posición por defecto del badge cuando el contenedor lo soporta. */
.bepp-gated { position: relative; }
.bepp-gated.is-locked { cursor: pointer; }
/* Atenúa el contenido bloqueado sin ocultarlo (sigue invitando al upsell).
   Excepto --nobadge (controles chicos) y --card (tiene su propio tratamiento). */
.bepp-gated.is-locked:not(.bepp-gated--nobadge):not(.bepp-gated--card) > :not(.bepp-gate-badge) { opacity: 0.62; }

/* Card mode (widgets bloqueados): contenido escondido en gris + aviso arriba.
   Sin blur (memoria: blur solo en scrims de modal). */
.bepp-gated--card.is-locked > :not(.bepp-gate-notice) {
  opacity: 0.34;
  filter: grayscale(1);
  pointer-events: none;
  user-select: none;
}
.bepp-gate-notice {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  margin-bottom: var(--space-14);
  padding: var(--space-10) var(--space-12);
  font-size: var(--font-xs);
  font-weight: var(--fw-medium);
  color: var(--premium-strong);
  background: var(--premium-soft);
  border-radius: var(--radius-md);
  line-height: var(--lh-snug);
}
.bepp-gate-notice .icon { width: 16px; height: 16px; flex-shrink: 0; color: var(--premium-strong); }
.bepp-gate-notice strong { font-weight: var(--fw-bold); }

/* CTA dorado del upsell — reutiliza tokens --premium (no inventa color). */
.btn-premium {
  background: linear-gradient(135deg, var(--premium), var(--premium-strong));
  color: var(--white);
  box-shadow: var(--shadow-premium);
}
.btn-premium:hover { background: linear-gradient(135deg, var(--premium-hover), var(--premium-strong)); transform: translateY(-1px); }
.btn-ghost {
  background: transparent;
  color: var(--text-secondary);
}
.btn-ghost:hover { background: var(--surface-alt); color: var(--primary-dark); }
.btn-block { display: flex; width: 100%; }
/* CTAs monocromáticos por tier (sin mezcla primary+accent). */
.btn-cuidado { background: var(--tier-cuidado); color: var(--white); }
.btn-cuidado:hover { background: var(--tier-cuidado-strong); transform: translateY(-1px); }
.btn-familia { background: var(--tier-familia); color: var(--white); }
.btn-familia:hover { background: var(--tier-familia-strong); transform: translateY(-1px); }

/* Upsell MODAL — centrado, con arte (PNG still) de Beppina + copy por gate.
   Monta sobre .modal-overlay (blur scrim + scroll lock vía :has()).        */
.bepp-tier-modal__card {
  position: relative;
  width: min(92vw, 380px);
  max-height: 88vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--card);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  padding: var(--space-24) var(--space-24) var(--space-20);
  text-align: center;
  transform: translateY(8px) scale(0.98);
  opacity: 0;
  transition: transform var(--duration-base, 250ms) var(--spring-snap, cubic-bezier(0.32,0.72,0.30,0.99)),
              opacity var(--duration-base, 250ms) var(--ease-out, ease);
}
.modal-overlay.bepp-tier-modal.active .bepp-tier-modal__card { transform: translateY(0) scale(1); opacity: 1; }
.bepp-tier-modal__close {
  position: absolute;
  top: var(--space-12);
  right: var(--space-12);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--surface-alt);
  color: var(--text-secondary);
  cursor: pointer;
}
.bepp-tier-modal__close .icon { width: 18px; height: 18px; }
.bepp-tier-modal__art {
  width: 120px;
  height: 120px;
  margin: var(--space-4) auto var(--space-12);
}
.bepp-tier-modal__art img { width: 100%; height: 100%; object-fit: contain; }
.bepp-tier-modal__eyebrow { margin-bottom: var(--space-10); }
.bepp-tier-modal__title {
  font-size: var(--font-lg);
  font-weight: var(--fw-bold);
  color: var(--primary-dark);
  margin: 0 0 var(--space-6);
  letter-spacing: var(--tracking-tight);
}
.bepp-tier-modal__desc {
  font-size: var(--font-sm);
  color: var(--text-secondary);
  line-height: var(--lh-normal);
  margin: 0 auto var(--space-16);
  max-width: 34ch;
}
.bepp-tier-modal__benefits {
  list-style: none;
  margin: 0 0 var(--space-16);
  padding: 0;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}
.bepp-tier-modal__benefits li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-8);
  font-size: var(--font-sm);
  color: var(--text);
}
.bepp-tier-modal__benefits .icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--accent);
  margin-top: 1px;
}
.bepp-tier-modal__plan {
  display: inline-flex;
  align-items: center;
  gap: var(--space-10);
  padding: var(--space-10) var(--space-16);
  border-radius: var(--radius-lg);
  background: var(--surface-alt);
  margin-bottom: var(--space-16);
}
.bepp-tier-modal__price {
  font-size: var(--font-md);
  font-weight: var(--fw-bold);
  color: var(--primary-dark);
}
.bepp-tier-modal__price small {
  font-size: var(--font-2xs);
  font-weight: var(--fw-medium);
  color: var(--text-secondary);
}
.bepp-tier-modal__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

/* ===== FAMILY MEMBER COLOR =====
   Paleta categórica para miembros del plan Cuidado Familia. 7 colores
   curados, derivados de --data-* (se omite data-5 violet, reservado al
   chip del tier Familia para evitar confusión visual).
     1 navy · 2 green · 3 amber · 4 brick · 5 rose · 6 teal · 7 sepia
   Cada clase expone --member-color y --member-color-soft; los componentes
   (avatar, evento de calendario, fila compartida) consumen esas vars.
   Uso:
     <div class="member-avatar bepp-member-color--3">RA</div>
     .member-avatar { background: var(--member-color-soft); color: var(--member-color); } */
.bepp-member-color--1 { --member-color: var(--data-1); --member-color-soft: var(--data-1-soft); }
.bepp-member-color--2 { --member-color: var(--data-2); --member-color-soft: var(--data-2-soft); }
.bepp-member-color--3 { --member-color: var(--data-3); --member-color-soft: var(--data-3-soft); }
.bepp-member-color--4 { --member-color: var(--data-4); --member-color-soft: var(--data-4-soft); }
.bepp-member-color--5 { --member-color: var(--data-6); --member-color-soft: var(--data-6-soft); }
.bepp-member-color--6 { --member-color: var(--data-7); --member-color-soft: var(--data-7-soft); }
.bepp-member-color--7 { --member-color: var(--data-8); --member-color-soft: var(--data-8-soft); }

/* ===== BEPP LEVEL CHIP =====
   Sistema de 5 tiers progresivos para m&eacute;dicos.
   Uso: <span class="bepp-level-chip bepp-level-chip--destacado">Destacado</span>
   Tiers: nuevo → verificado → experimentado → destacado → elite.
   Monocrom&aacute;tico por familia (sin mezcla primary+accent).
*/
.bepp-level-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding: 4px 10px;
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-tight);
  border-radius: var(--radius-full);
  border: 1px solid transparent;
  line-height: 1.1;
  white-space: nowrap;
}
.bepp-level-chip .icon,
.bepp-level-chip .i { color: currentColor; }

.bepp-level-chip--nuevo {
  background: var(--sky-soft);
  color: var(--primary-dark);
  border-color: var(--sky-soft);
}
.bepp-level-chip--verificado {
  background: var(--status-info-soft);
  color: var(--status-info-strong);
  border-color: var(--status-info-soft);
}
.bepp-level-chip--experimentado {
  background: var(--accent-soft);
  color: var(--primary-dark);
  border-color: var(--accent-soft);
}
.bepp-level-chip--destacado {
  background: var(--status-warning-soft);
  color: var(--status-warning-strong);
  border-color: var(--status-warning-soft);
}
.bepp-level-chip--elite {
  background: var(--data-5-soft);
  color: var(--data-5);
  border-color: var(--data-5-soft);
}
.bepp-level-chip--verified {
  background: var(--status-success-soft);
  color: var(--status-success-strong);
  border-color: var(--status-success-soft);
}

/* ===== AVATAR SYSTEM =====
   Base handles shape + layout. Compose with a color variant;
   size/font-size/margins/status-dots stay page-local.
   <div class="bepp-avatar bepp-avatar--gradient-accent">DD</div>
   <div class="bepp-avatar bepp-avatar--gradient-primary" data-initials="AP"><img src="..."></div>

   Fallback: si el <img> falla (onerror="this.remove()") o no existe,
   las iniciales del data-initials quedan visibles automáticamente.
*/
.bepp-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  overflow: hidden;
  font-weight: 700;
  flex-shrink: 0;
  position: relative;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.bepp-avatar[data-initials]::before {
  content: attr(data-initials);
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 0.85em;
  letter-spacing: 0.04em;
}

.bepp-avatar>img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  position: relative;
  z-index: 1;
}

/* Tamaños del avatar — sin estos, un <img> con src 404 renderea con su
   tamaño intrínseco y rompe layout (page-wide H_SCROLL). */
.bepp-avatar--xs { width: 24px; height: 24px; font-size: var(--font-2xs); }
.bepp-avatar--sm { width: 32px; height: 32px; font-size: var(--font-xs); }
.bepp-avatar--md { width: 40px; height: 40px; font-size: var(--font-sm); }
.bepp-avatar--lg { width: 56px; height: 56px; font-size: var(--font-base); }
.bepp-avatar--xl { width: 80px; height: 80px; font-size: var(--font-lg); }

/* Accent gradient — for doctor avatars (initials on lime→green) */
.bepp-avatar--gradient-accent {
  background: linear-gradient(135deg, var(--accent), var(--accent-hover));
  color: var(--primary-dark);
}

/* Primary gradient — light→dark (patient avatars) */
.bepp-avatar--gradient-primary {
  background: linear-gradient(135deg, var(--primary-light), var(--primary));
  color: var(--white);
}

/* Primary gradient reversed — dark→light (family, testimonial) */
.bepp-avatar--gradient-primary-reversed {
  background: linear-gradient(135deg, var(--primary), var(--primary-light));
  color: var(--white);
}

/* Member — consume --member-color/--member-color-soft de la clase
   .bepp-member-color--N. Pareado con avatar de miembro Familia.            */
.bepp-avatar--member {
  background: var(--member-color-soft);
  color: var(--member-color);
}

/* ===== AVATAR FALLBACK — color determinista por id =====
   Paleta de 8 gradientes (sin primary/accent/sky) para avatares de
   pacientes/usuarios sin foto. La clase la asigna BeppAvatar.colorClass(id)
   en js/avatar-utils.js — mismo id ⇒ misma clase en toda la app.
   Texto blanco siempre. Compone con .bepp-avatar + data-initials.            */
:root {
  --avatar-c1: linear-gradient(135deg, #6E56CF, #9F86F0); /* violeta */
  --avatar-c2: linear-gradient(135deg, #D97706, #F4A24A); /* naranja */
  --avatar-c3: linear-gradient(135deg, #0E7490, #3DA9C0); /* teal */
  --avatar-c4: linear-gradient(135deg, #7C3AED, #A66EF6); /* púrpura */
  --avatar-c5: linear-gradient(135deg, #DB2777, #F472B6); /* rosa */
  --avatar-c6: linear-gradient(135deg, #4F46E5, #818CF8); /* índigo */
  --avatar-c7: linear-gradient(135deg, #B45309, #E8A55C); /* ámbar */
  --avatar-c8: linear-gradient(135deg, #047857, #34D399); /* esmeralda */
}
.bepp-avatar--c1 { background: var(--avatar-c1); color: var(--white); }
.bepp-avatar--c2 { background: var(--avatar-c2); color: var(--white); }
.bepp-avatar--c3 { background: var(--avatar-c3); color: var(--white); }
.bepp-avatar--c4 { background: var(--avatar-c4); color: var(--white); }
.bepp-avatar--c5 { background: var(--avatar-c5); color: var(--white); }
.bepp-avatar--c6 { background: var(--avatar-c6); color: var(--white); }
.bepp-avatar--c7 { background: var(--avatar-c7); color: var(--white); }
.bepp-avatar--c8 { background: var(--avatar-c8); color: var(--white); }

/* ===== SCROLLBAR ===== */
::-webkit-scrollbar {
  width: 5px;
  height: 5px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--text-light);
}

/* Paciente app: hide all scrollbars (mobile app feel) */
html:has(body.bepp-mobile-app),
body.bepp-mobile-app,
body.bepp-mobile-app * {
  scrollbar-width: none;
  -ms-overflow-style: none;
}

/* Paciente app: kill iOS tap highlight (gray overlay on every touch) */
body.bepp-mobile-app,
body.bepp-mobile-app * {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}
html:has(body.bepp-mobile-app)::-webkit-scrollbar,
body.bepp-mobile-app::-webkit-scrollbar,
body.bepp-mobile-app *::-webkit-scrollbar {
  width: 0;
  height: 0;
  display: none;
}

/* Regla global: solo scroll vertical en la app mobile, nunca horizontal */
html:has(body.bepp-mobile-app),
body.bepp-mobile-app {
  overflow-x: hidden;
  max-width: 100vw;
}
body.bepp-mobile-app .ph-main {
  overflow-x: hidden;
}

/* ============================================
   FIELD VALUE (read-only display)
   Renders a form-control value as static text
   keeping the same grid footprint as the input.
   ============================================ */
.field-value {
  display: block;
  padding: 8px 12px;
  min-height: 38px;
  font-size: var(--font-sm);
  color: var(--primary-dark);
  background: var(--bg-soft);
  border: 1px solid transparent;
  border-radius: var(--radius-sm, 10px);
  line-height: 1.4;
  word-break: break-word;
  white-space: pre-wrap;
}
.field-value.is-empty {
  color: var(--text-light);
  font-style: italic;
}

/* ============================================
   FORM CONTROLS — base BEPP (consumida por 138+ HTML)
   ============================================ */
.form-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  min-width: 0;
}

.form-label {
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-secondary);
  letter-spacing: var(--tracking-tight);
  line-height: var(--lh-snug);
}

.form-control {
  display: block;
  width: 100%;
  min-width: 0;
  font-family: inherit;
  font-size: var(--font-sm);
  color: var(--primary-dark);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-10) var(--space-12);
  line-height: var(--lh-snug);
  transition: border-color 160ms ease, box-shadow 160ms ease;
  appearance: none;
  -webkit-appearance: none;
}

.form-control::placeholder {
  color: var(--text-light);
}

.form-control:hover {
  border-color: var(--primary-alpha-15);
}

.form-control:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-alpha-15);
}

.form-control:disabled {
  background: var(--surface-alt);
  color: var(--text-light);
  cursor: not-allowed;
}

.form-control.is-invalid {
  border-color: var(--danger);
}
.form-control.is-invalid:focus {
  box-shadow: 0 0 0 3px var(--danger-alpha-15);
}

select.form-control {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%231D5C80' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat: no-repeat;
  background-position: right var(--space-12) center;
  padding-right: var(--space-32);
}

textarea.form-control {
  min-height: 96px;
  resize: vertical;
}

/* Read-only form-controls: visually identical to .field-value */
.form-control[readonly].form-control--readonly,
.form-control--readonly {
  background: var(--bg-soft);
  border-color: transparent;
  color: var(--primary-dark);
  cursor: default;
}
.form-control--readonly:focus {
  outline: none;
  box-shadow: none;
}

/* ============================================
   PATIENT TIMELINE (clinical events chronology)
   Vertical timeline grouped by month with
   per-event cards. Used in patient profile.
   ============================================ */
.patient-timeline {
  display: flex;
  flex-direction: column;
  gap: var(--space-24, 24px);
  margin-top: var(--space-16, 16px);
}

.patient-timeline-group {
  position: relative;
}

.patient-timeline-group-label {
  font-size: var(--font-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary);
  padding-bottom: var(--space-8, 8px);
  border-bottom: 1px solid var(--border-light);
  margin-bottom: var(--space-12, 12px);
}

.patient-timeline-track {
  position: relative;
  padding-left: 28px;
}
.patient-timeline-track::before {
  content: '';
  position: absolute;
  left: 10px;
  top: 6px;
  bottom: 6px;
  width: 2px;
  background: var(--border-light);
}

.patient-timeline-item {
  position: relative;
  margin-bottom: var(--space-12, 12px);
}

.patient-timeline-dot {
  position: absolute;
  left: -24px;
  top: 14px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--type-color, var(--primary));
  box-shadow: 0 0 0 3px var(--white), 0 0 0 4px var(--border-light);
}

.patient-timeline-card {
  background: var(--white);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-sm, 10px);
  padding: var(--space-12, 12px) var(--space-16, 16px);
  box-shadow: var(--shadow-xs, 0 1px 2px rgba(20, 40, 70, 0.04));
  transition: box-shadow 150ms var(--ease-out, ease), transform 150ms var(--ease-out, ease);
}
.patient-timeline-card:hover {
  box-shadow: var(--shadow-sm, 0 6px 20px rgba(20, 40, 70, 0.07));
  transform: translateY(-1px);
}

.patient-timeline-head {
  display: flex;
  align-items: center;
  gap: var(--space-8, 8px);
  margin-bottom: var(--space-4, 4px);
  flex-wrap: wrap;
}

.patient-timeline-type {
  font-size: var(--font-2xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--type-color, var(--primary));
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--type-bg, rgba(42, 111, 151, 0.08));
}

.patient-timeline-date {
  font-size: var(--font-xs);
  color: var(--text-secondary);
  margin-left: auto;
}

.patient-timeline-title {
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--primary-dark);
  margin: 0;
}

.patient-timeline-summary {
  font-size: var(--font-xs);
  color: var(--text-secondary);
  margin: var(--space-4, 4px) 0 var(--space-8, 8px);
  line-height: 1.5;
}

.patient-timeline-footer {
  display: flex;
  align-items: center;
  gap: var(--space-12, 12px);
  font-size: var(--font-xs);
  color: var(--text-light);
}

.patient-timeline-footer .btn-link {
  margin-left: auto;
  font-size: var(--font-xs);
  color: var(--primary);
  font-weight: 600;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
}
.patient-timeline-footer .btn-link:hover { color: var(--primary-dark); text-decoration: underline; }

.patient-timeline-link {
  margin-left: auto;
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--primary);
  text-decoration: none;
  white-space: nowrap;
}
.patient-timeline-link:hover { color: var(--primary-dark); text-decoration: underline; }
.patient-timeline-link:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 2px; }

/* Type color tokens for timeline events */
.pt-type-consulta       { --type-color: var(--primary);    --type-bg: rgba(42,111,151,0.10); }
.pt-type-hospitalizacion{ --type-color: var(--proc-hospitalizacion); --type-bg: var(--proc-hospitalizacion-soft); }
.pt-type-urgencias      { --type-color: var(--danger);     --type-bg: rgba(218,57,46,0.10); }
.pt-type-enfermeria     { --type-color: var(--sky);        --type-bg: rgba(136,178,206,0.15); }
.pt-type-quirurgico     { --type-color: var(--proc-quirurgico); --type-bg: var(--proc-quirurgico-soft); }
.pt-type-medicamento    { --type-color: var(--accent);     --type-bg: rgba(164,198,52,0.15); }
.pt-type-procedimiento  { --type-color: var(--proc-procedimiento); --type-bg: var(--proc-procedimiento-soft); }
.pt-type-estudio        { --type-color: var(--proc-estudio); --type-bg: var(--proc-estudio-soft); }
.pt-type-documento      { --type-color: var(--text-secondary); --type-bg: rgba(100,116,139,0.10); }

/* Actor color tokens for access-log timeline (paciente · privacidad · registro de accesos) */
.pt-actor-medico        { --type-color: var(--primary);  --type-bg: var(--primary-alpha-08); }
.pt-actor-familia       { --type-color: var(--data-6);   --type-bg: var(--data-6-soft); }
.pt-actor-self          { --type-color: var(--data-7);   --type-bg: var(--data-7-soft); }
.pt-actor-sistema       { --type-color: var(--data-5);   --type-bg: var(--data-5-soft); }

/* ============================================
   PATIENT TIMELINE · RICH variant
   Actor icon inside the dot + tinted cards.
   Used in paciente · privacidad · registro de accesos.
   ============================================ */
.patient-timeline--rich .patient-timeline-track { padding-left: 40px; }
.patient-timeline--rich .patient-timeline-track::before {
  left: 18px;
  top: 16px;
}
.patient-timeline--rich .patient-timeline-dot {
  width: 32px;
  height: 32px;
  left: -38px;
  top: 6px;
  display: grid;
  place-items: center;
  color: var(--white);
  box-shadow: 0 0 0 3px var(--white), 0 0 0 4px var(--type-bg, var(--border-light));
}
.patient-timeline--rich .patient-timeline-dot .icon {
  width: 16px;
  height: 16px;
  stroke-width: 2;
}
.patient-timeline--rich .patient-timeline-card {
  background: var(--type-bg, var(--white));
  border-color: transparent;
}

/* Variante: el dot alberga un avatar (foto/iniciales del usuario o entidad) */
.patient-timeline--rich .patient-timeline-dot--avatar {
  background: transparent;
  color: inherit;
  padding: 0;
}
.patient-timeline--rich .patient-timeline-dot--avatar .bepp-avatar {
  width: 100%;
  height: 100%;
  font-size: var(--font-xs);
}

/* Filter chips (reusable) */
.chip-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8, 8px);
  margin-bottom: var(--space-16, 16px);
}
.chip-filter {
  border: 1px solid var(--border-light);
  background: var(--white);
  color: var(--text-secondary);
  font-size: var(--font-xs);
  font-weight: 500;
  padding: 6px 12px;
  border-radius: 999px;
  cursor: pointer;
  transition: all 150ms var(--ease-out, ease);
}
.chip-filter:hover { border-color: var(--primary); color: var(--primary); }
.chip-filter.active {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--white);
}

/* ============================================
   PC-CHIP / PC-CHIPROW (reusable patient chips)
   Filtros horizontales del paciente — citas, mensajes, etc.
   --scroll = nowrap + scroll horizontal (default mobile)
   --wrap   = wrap a multilínea (cuando hay pocos chips o el contenedor lo permite)
   .is-active = highlight primary
   ============================================ */
.pc-chiprow {
  display: flex;
  gap: var(--space-6);
  flex-wrap: wrap;
}
.pc-chiprow--scroll {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  margin: 0 calc(var(--space-16) * -1);
  padding: 0 var(--space-16);
}
.pc-chiprow--scroll::-webkit-scrollbar { display: none; }
.pc-chiprow--wrap { flex-wrap: wrap; }

.pc-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
  min-height: 36px;
  padding: 0 var(--space-14);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  color: var(--text-secondary);
  font-family: inherit;
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out);
}
.pc-chip:active { transform: scale(0.97); }
.pc-chip.is-active {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--white);
}
.pc-chip .icon { color: currentColor; }
.pc-chip--mod.is-active {
  background: var(--primary-dark);
  border-color: var(--primary-dark);
}

/* ============================================
   ACTION BARS (lenguaje visual compartido)
   - .action-bar-sticky  : sticky al pie de un main scrollable (consulta + perfil)
   - .modal-footer       : pie de modal (.modal-content)
   - .section-edit-footer: pie inline dentro de un accordion en modo edición
   Todos comparten: borde superior punteado, fondo translúcido y
   botones alineados a la derecha. Sólo cambia el posicionamiento.
   ============================================ */

/* Wrapper del main que aloja un .action-bar-sticky al pie. Sólo deja
   espacio extra abajo para que el contenido no quede tapado por el bar. */
.main-content--with-action-bar {
  padding-bottom: var(--space-80);
  display: flex;
  flex-direction: column;
}
.action-bar-sticky,
.modal-footer,
.section-edit-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-8, 8px);
  padding: var(--space-12, 12px) var(--space-20, 20px);
  background: transparent;
  border-top: 1px dashed var(--border-light);
}

.action-bar-sticky {
  position: sticky;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 30;
  gap: var(--space-12, 12px);
  background: var(--card);
}
.action-bar-sticky .action-bar-status {
  font-size: var(--font-xs);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: var(--space-6);
}
.action-bar-sticky .action-bar-spacer { flex: 1; }

/* Variante inline: dentro de un accordion-body que ya tiene padding horizontal */
.section-edit-footer {
  padding: var(--space-12, 12px) 0 0;
  margin-top: var(--space-12, 12px);
}

/* ============================================
   SIDEBAR STICKY CTA (bottom of left sidebar)
   Contenedor del sidebar con CTA anclada al pie:
   área scrollable arriba + CTA fijo abajo con
   fade hacia el fondo. Usado en perfil paciente.
   ============================================ */
.sidebar-left--has-cta {
  display: flex;
  flex-direction: column;
}
.sidebar-left--has-cta .sidebar-left-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding-right: var(--space-10);
}
.sidebar-left--has-cta .sidebar-left-scroll::-webkit-scrollbar {
  width: 4px;
}
.sidebar-left--has-cta .sidebar-left-scroll::-webkit-scrollbar-thumb {
  border-radius: 2px;
}
.sidebar-left-cta {
  flex: 0 0 auto;
  padding: var(--space-12, 12px) 0 var(--space-4, 4px);
  border-top: 1px solid var(--border-light);
  margin-top: var(--space-12, 12px);
  position: sticky;
  bottom: 0;
  background: var(--card);
}

/* CTA primaria del sidebar (gradiente accent) */
.btn-sidebar-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  width: 100%;
  padding: 14px 16px;
  background: var(--accent);
  color: var(--white);
  font-weight: 700;
  font-size: var(--font-sm);
  letter-spacing: 0.02em;
  border-radius: var(--radius-md, 14px);
  border: none;
  cursor: pointer;
  text-decoration: none;
  transition: transform 150ms var(--ease-out, ease), box-shadow 150ms var(--ease-out, ease);
}
.btn-sidebar-cta:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}
.btn-sidebar-cta:active {
  transform: translateY(0);
}

/* CTA secundaria del sidebar (outline sobre blanco) */
.btn-sidebar-cta-alt {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-6);
  width: 100%;
  padding: 10px 14px;
  background: var(--white);
  color: var(--primary-dark);
  font-weight: 600;
  font-size: var(--font-xs);
  border-radius: var(--radius-md, 14px);
  border: 1px solid var(--border-light);
  cursor: pointer;
  text-decoration: none;
  transition: all 150ms var(--ease-out, ease);
}
.btn-sidebar-cta-alt:hover {
  border-color: var(--primary-light);
  background: var(--gray-50);
}

/* ============================================
   CONSULTA STATUS PILL (in-progress indicator)
   ============================================ */
.consulta-status-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
  font-size: var(--font-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent-dark);
  background: rgba(164, 198, 52, 0.14);
  padding: 4px 10px;
  border-radius: 999px;
}
.consulta-status-pill .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  animation: consulta-pulse 1.6s ease-in-out infinite;
}
.consulta-status-pill.is-live {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: var(--font-sm);
  padding: 8px 18px;
  gap: var(--space-10);
  background: var(--accent);
  color: var(--white);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
  z-index: 1;
}
.consulta-status-pill.is-live .dot {
  width: 10px;
  height: 10px;
  background: var(--white);
}
@keyframes consulta-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.55; transform: scale(0.85); }
}

/* ============================================
   SEGMENTED TOGGLE (used for privada/compartida)
   ============================================ */
.segmented {
  display: inline-flex;
  background: var(--bg-soft);
  padding: 4px;
  border-radius: 999px;
  border: 1px solid var(--border-light);
  gap: var(--space-2);
}
.segmented-option {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--text-secondary);
  padding: 6px 14px;
  border-radius: 999px;
  cursor: pointer;
  border: none;
  background: transparent;
  transition: all 150ms var(--ease-out, ease);
}
.segmented-option.active {
  background: var(--white);
  color: var(--primary-dark);
  box-shadow: var(--shadow-xs, 0 1px 2px rgba(20, 40, 70, 0.04));
}

/* ============================================
   BUTTONS (global primitive)
   Base .btn + variantes primary / accent / secondary / outline.
   .btn-sm para versión compacta (modal-footer, action-bar-sticky).
   La jerarquía primary NO lleva sombra en reposo — solo al hover.
   ============================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-6);
  padding: var(--space-10) var(--space-20);
  border: 1px solid transparent;
  border-radius: 10px;
  font-family: inherit;
  font-size: var(--font-sm);
  font-weight: var(--fw-semibold);
  line-height: 1.2;
  cursor: pointer;
  text-decoration: none;
  transition: background 150ms var(--ease-out, ease),
              border-color 150ms var(--ease-out, ease),
              color 150ms var(--ease-out, ease),
              box-shadow 200ms var(--ease-out, ease),
              transform 150ms var(--ease-out, ease);
}
.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--primary-alpha-15);
}
.btn-sm {
  padding: var(--space-8) var(--space-14);
  font-size: var(--font-xs);
  border-radius: 8px;
}

.btn-primary {
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
  color: var(--white);
}
.btn-primary:hover {
  box-shadow: var(--shadow-primary);
  transform: translateY(-1px);
}

.btn-accent {
  background: var(--accent);
  color: var(--white);
}
.btn-accent:hover {
  background: var(--accent-hover);
  transform: translateY(-1px);
}

.btn-danger {
  background: var(--danger);
  color: var(--white);
}
.btn-danger:hover {
  background: var(--danger);
  box-shadow: 0 4px 12px var(--danger-alpha-15);
  transform: translateY(-1px);
}

/* Secondary/outline comparten visual (border + texto sobre card).
   .btn-secondary = neutral explícito, .btn-outline = alias histórico. */
.btn-secondary,
.btn-outline {
  background: var(--card);
  border-color: var(--border);
  color: var(--text-secondary);
}
.btn-secondary:hover,
.btn-outline:hover {
  border-color: var(--primary);
  background: var(--primary-alpha-04);
  color: var(--primary);
}

/* ===== MODAL (global pattern) =====
   Usage:
   <div class="modal-overlay" id="myModal">
     <div class="modal-content">
       <div class="modal-header"><div class="modal-title">...</div><div class="modal-close">&times;</div></div>
       <div class="modal-body">...</div>
       <div class="modal-footer">...</div>
     </div>
   </div>
   Open: el.classList.add('active')   |  Close: el.classList.remove('active')
   Size variants on .modal-content: default (400) · .modal-md (560) · .modal-lg (760)
*/
body.is-modal-open { overflow: hidden; }

/* Auto body-scroll-lock cuando hay cualquier modal/sheet/drawer abierto.
   Usa :has() (Safari 15.4+, Chrome 105+, FF 121+ — universal en 2026).
   Cubre los selectores que actualmente abren overlays en el app:
     .modal-overlay.active        — modales globales (nuevoPaciente, etc.)
     .doctor-menu-overlay.is-open — hamburger nav del doctor
     .tpl-modal-overlay.is-open   — modal de plantillas en consulta
     .photo-modal-backdrop        — modal de foto en perfil/editar (sin clase active, siempre montado solo cuando se abre)
     .ob-country-modal:not(.hidden) — modal de país en onboarding
     .stats-drawer-backdrop[style*="opacity"][style*="1"] — drawer estadísticas (compatibilidad)
   Evita el patrón position:fixed en body (memory feedback_body_scroll_lock_pattern). */
html:has(.modal-overlay.active),
html:has(.doctor-menu-overlay.is-open),
html:has(.tpl-modal-overlay.is-open),
html:has(.ob-country-modal:not(.hidden)) {
  overflow: hidden;
}
html:has(.modal-overlay.active) body,
html:has(.doctor-menu-overlay.is-open) body,
html:has(.tpl-modal-overlay.is-open) body,
html:has(.ob-country-modal:not(.hidden)) body {
  overflow: hidden;
}

.modal-overlay {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  background: var(--overlay-backdrop);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  /* Centra el .modal-content en viewport — sin esto el modal cae en la
     esquina superior-izquierda porque .modal-content no tiene posicionamiento
     propio. */
  display: flex;
  justify-content: center;
  align-items: center;
  /* Above the fixed doctor header (z-index 1000000). Modals take over the
     whole screen and must cover the nav. */
  z-index: 1000001;
  /* Oculto por default: sin esto, cualquier .modal-overlay declarado en el
     HTML (sin .active) cubre la pantalla con el blur permanentemente y se
     ve como "fondo borroso que no se quita". .active lo activa abajo. */
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--duration-base, 250ms) var(--ease-out, ease),
              visibility var(--duration-base, 250ms) var(--ease-out, ease);
}
/* BeppModal.confirm/alert/prompt deben quedar SIEMPRE encima de cualquier
   sub-modal de aplicación (ej. tpl-modal-overlay = 10000001). Sin esto el
   confirm se monta detrás y los clicks acumulan instancias invisibles. */
.modal-overlay.bepp-modal {
  z-index: 100000010;
  display: flex;
  justify-content: center;
  align-items: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--duration-base, 250ms) var(--ease-out, ease),
              visibility var(--duration-base, 250ms) var(--ease-out, ease);
}
.modal-overlay.active {
  opacity: 1;
  visibility: visible;
}
.modal-content {
  background: var(--card);
  width: 90%;
  max-width: 400px;
  max-height: calc(100vh - var(--space-32));
  border-radius: 12px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
  opacity: 0;
  transform: translateY(8px) scale(0.98);
  transition: opacity var(--duration-base, 250ms) var(--ease-out, ease-out),
              transform var(--duration-base, 250ms) var(--ease-out, ease-out);
}
.modal-overlay.active .modal-content {
  opacity: 1;
  transform: translateY(0) scale(1);
}
.modal-content.modal-md { max-width: 560px; }
.modal-content.modal-lg { max-width: 760px; }
.modal-header {
  padding: var(--space-16) var(--space-20);
  border-bottom: 1px solid var(--border-light);
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}
.modal-title {
  font-weight: var(--fw-bold);
  font-size: var(--font-base);
  color: var(--text);
}
.modal-close {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--text-light);
  font-family: inherit;
  font-size: var(--font-md);
  line-height: 1;
  padding: var(--space-6);
  border-radius: var(--radius-xs);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 150ms var(--ease-out), background 150ms var(--ease-out);
}
.modal-close:hover { color: var(--text); background: var(--gray-50, var(--surface)); }
.modal-close:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.modal-body {
  padding: var(--space-20);
  display: flex;
  flex-direction: column;
  gap: var(--space-14);
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
}
.modal-form-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.modal-form-group label {
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-light);
}
.modal-form-group input,
.modal-form-group select,
.modal-form-group textarea {
  padding: var(--space-10);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: inherit;
  font-size: var(--font-sm);
}
.modal-form-group input.is-invalid,
.modal-form-group select.is-invalid,
.modal-form-group textarea.is-invalid {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px var(--danger-alpha-15);
}
/* Base visual (display, padding, border dashed, transparent) en el grupo
   .action-bar-sticky, .modal-footer, .section-edit-footer más arriba. */
.modal-flex-row { display: flex; gap: var(--space-12); }
.modal-flex-1 { flex: 1; }

/* Choice list inside modal (vertical stacked action cards) */
.modal-choice-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-10);
}
.modal-choice {
  display: flex;
  align-items: center;
  gap: var(--space-14);
  padding: var(--space-14) var(--space-16);
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--card);
  cursor: pointer;
  text-align: left;
  transition: border-color 150ms var(--ease-out, ease), background 150ms var(--ease-out, ease), transform 150ms var(--ease-out, ease);
  width: 100%;
  font-family: inherit;
  text-decoration: none;
  color: inherit;
}
.modal-choice:hover {
  border-color: var(--primary);
  background: var(--primary-50);
}
.modal-choice:active { transform: scale(0.99); }
.modal-choice-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--primary-50);
  color: var(--primary);
  flex-shrink: 0;
}
/* Paleta de acentos para chips e iconos (plantillas, categorías, etc.)
   Define --chip-color; los consumidores pueden usarlo como background. */
.acc-bg-blue   { --chip-color: var(--data-1); }
.acc-bg-green  { --chip-color: var(--data-2); }
.acc-bg-amber  { --chip-color: var(--data-3); }
.acc-bg-red    { --chip-color: var(--data-4); }
.acc-bg-purple { --chip-color: var(--data-5); }
.acc-bg-pink   { --chip-color: var(--data-6); }
.acc-bg-sky    { --chip-color: var(--sky); }
.acc-bg-grey   { --chip-color: var(--gray-200); }
.modal-choice-icon.acc-bg-blue,
.modal-choice-icon.acc-bg-green,
.modal-choice-icon.acc-bg-amber,
.modal-choice-icon.acc-bg-red,
.modal-choice-icon.acc-bg-purple,
.modal-choice-icon.acc-bg-pink,
.modal-choice-icon.acc-bg-sky {
  background: var(--chip-color);
  color: var(--white);
}
.modal-choice-icon.acc-bg-grey {
  background: var(--gray-100);
  color: var(--text-light);
}
.modal-choice.is-muted .modal-choice-icon { background: var(--gray-100); color: var(--text-light); }

/* Plantillas — variante "muted" para opciones secundarias (ej. "Consulta completa")
   y "ghost" para acciones de creación (ej. "Crear plantilla nueva"). La jerarquía
   visual la lleva la opción recomendada (.modal-choice-badge) en su título. */
.modal-choice--muted {
  opacity: 0.65;
}
.modal-choice--muted:hover { opacity: 1; }
.modal-choice--ghost {
  border-style: dashed;
  background: transparent;
}
.modal-choice--ghost .modal-choice-title { color: var(--text-light); }
.modal-choice--ghost:hover .modal-choice-title { color: var(--text); }

.modal-choice-badge {
  display: inline-block;
  margin-left: var(--space-8);
  padding: 2px var(--space-8);
  border-radius: 999px;
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  background: var(--primary-alpha-12);
  color: var(--primary);
  vertical-align: middle;
  letter-spacing: 0.01em;
}
/* Variante destructiva — acciones que descartan trabajo (salir sin guardar, etc.).
   La jerarquía solo aparece en :hover, igual que el patrón base. */
.modal-choice.is-danger:hover { border-color: var(--danger); background: var(--status-danger-soft); }
.modal-choice.is-danger .modal-choice-icon { background: var(--status-danger-soft); color: var(--danger); }
.modal-choice.is-danger:hover .modal-choice-title { color: var(--status-danger-strong); }
.modal-choice-text { flex: 1; display: flex; flex-direction: column; gap: var(--space-2); }
.modal-choice-title { font-size: var(--font-sm); font-weight: var(--fw-bold); color: var(--text); }
.modal-choice-sub { font-size: var(--font-xs); color: var(--text-light); line-height: 1.35; }
.modal-choice-chevron { color: var(--text-light); flex-shrink: 0; }

/* Modal back button — botón "← volver" para paneles secundarios dentro de un modal
   (p. ej. lista de borradores al volver a las opciones iniciales). */
.modal-back-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
  background: none;
  border: none;
  padding: var(--space-4) var(--space-6);
  margin: 0 0 0 calc(var(--space-6) * -1);
  font: inherit;
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-light);
  cursor: pointer;
  border-radius: var(--radius-xs);
  transition: color 150ms var(--ease-out, ease), background 150ms var(--ease-out, ease);
}
.modal-back-btn:hover { color: var(--primary); background: var(--primary-50); }
.modal-back-btn .icon { width: 14px; height: 14px; }

/* Panel secundario dentro del mismo .modal-content (p. ej. lista de borradores).
   Se muestra/oculta con el atributo data-panel en .modal-body. */
.modal-body[data-panel] > .modal-panel { display: none; }
.modal-body[data-panel="main"] > .modal-panel-main { display: flex; flex-direction: column; gap: var(--space-14); }
.modal-body[data-panel="drafts"] > .modal-panel-drafts { display: flex; flex-direction: column; gap: var(--space-14); }

/* ============================================
   Modal feedback panel — BeppModal.alert / .confirm
   Centered vertical layout: icon → title → message
   Sin inline styles; iconos del sprite.
   ============================================ */
.modal-feedback-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--space-36) var(--space-28) var(--space-20);
  gap: var(--space-8);
}
.modal-feedback-icon {
  width: 56px;
  height: 56px;
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-bottom: var(--space-4);
}
.modal-feedback-title {
  font-size: var(--font-md);
  font-weight: var(--fw-bold);
  color: var(--text);
  line-height: 1.3;
  margin: 0;
}
.modal-feedback-msg {
  font-size: var(--font-sm);
  color: var(--text-light);
  line-height: 1.5;
  margin: 0;
  max-width: 260px;
}
.modal-tone-success .modal-feedback-icon { background: var(--status-success-soft); color: var(--status-success-strong); }
.modal-tone-error   .modal-feedback-icon { background: var(--status-danger-soft);  color: var(--status-danger-strong); }
.modal-tone-warning .modal-feedback-icon { background: var(--status-warning-soft); color: var(--status-warning-strong); }
.modal-tone-info    .modal-feedback-icon { background: var(--status-info-soft);    color: var(--status-info-strong); }
/* Feedback modals: borde sólido, botones centrados */
.modal-feedback-panel + .modal-footer { border-top-style: solid; justify-content: center; }
.bepp-modal .modal-content { border-radius: 16px; max-width: 420px; }

/* Draft card — item de la lista de borradores. Mismo feel que .modal-choice
   pero con meta-row (fecha, plantilla) y badge de progreso. */
.draft-card {
  display: flex;
  align-items: center;
  gap: var(--space-14);
  padding: var(--space-14) var(--space-16);
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--card);
  cursor: pointer;
  text-align: left;
  width: 100%;
  font-family: inherit;
  text-decoration: none;
  color: inherit;
  transition: border-color 150ms var(--ease-out, ease), background 150ms var(--ease-out, ease), transform 150ms var(--ease-out, ease);
}
.draft-card:hover { border-color: var(--primary); background: var(--primary-50); }
.draft-card:active { transform: scale(0.99); }
.draft-card-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--primary-50);
  color: var(--primary);
  flex-shrink: 0;
}
.draft-card-body { flex: 1; display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.draft-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-10);
}
.draft-card-name { font-size: var(--font-sm); font-weight: var(--fw-bold); color: var(--text); }
.draft-card-date { font-size: var(--font-xs); color: var(--text-light); flex-shrink: 0; }
.draft-card-meta {
  display: flex;
  align-items: center;
  gap: var(--space-10);
  font-size: var(--font-xs);
  color: var(--text-light);
  flex-wrap: wrap;
}
.draft-card-template {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
}
.draft-card-progress {
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-2) var(--space-8);
  border-radius: var(--radius-full);
  background: var(--primary-alpha-06);
  color: var(--primary);
  font-weight: var(--fw-semibold);
}
.draft-card-chevron { color: var(--text-light); flex-shrink: 0; }
.draft-card-empty {
  padding: var(--space-24) var(--space-16);
  text-align: center;
  color: var(--text-light);
  font-size: var(--font-sm);
  border: 1px dashed var(--border);
  border-radius: var(--radius-md);
}

/* Multi-step modal bodies: show only the active step based on data-step.
   - Modal "Orden de estudio" usa data-step en .modal-body (body-only, sin footer).
   - Modal "Nuevo paciente" usa data-step en .modal-content para poder coordinar
     .modal-body + .modal-footer (cada paso revela su par body+footer). */
.modal-body[data-step] > .estudio-step { display: none; }
.modal-body[data-step="choose"] > .step-choose,
.modal-body[data-step="form"] > .step-form { display: flex; flex-direction: column; gap: var(--space-14); }

.modal-content[data-step] .paciente-step,
.modal-content[data-step] > .modal-footer.paciente-footer { display: none; }
.modal-content[data-step="choose"] .step-choose,
.modal-content[data-step="bepp"] .step-bepp,
.modal-content[data-step="nuevo"] .step-nuevo { display: flex; flex-direction: column; gap: var(--space-14); }
.modal-content[data-step="bepp"] > .modal-footer.step-bepp,
.modal-content[data-step="nuevo"] > .modal-footer.step-nuevo { display: flex; flex-direction: row; }

/* Small inline pill showing the currently picked study type (with "Cambiar" action) */
.estudio-tipo-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-10);
  padding: var(--space-8) var(--space-12);
  border: 1px solid var(--border);
  background: var(--primary-50);
  border-radius: 999px;
  font-size: var(--font-sm);
  font-weight: var(--fw-semibold);
  color: var(--primary);
  width: fit-content;
}

/* Small text-style button used inside modals to go back a step or toggle mode */
.btn-link-sm {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  color: var(--primary);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
  align-self: flex-start;
}
.btn-link-sm:hover { color: var(--primary-dark, var(--primary)); }

.modal-hint-sm {
  font-size: var(--font-xs);
  color: var(--text-light);
  line-height: 1.4;
  margin: 0;
}

/* ===== NAME LINK ===== */
/* Inline anchor that wraps a person name (typically a patient) so it's
   clickable without changing the surrounding typography. */
.name-link {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  display: inline-block;
  padding: var(--space-4) 0;
  transition: color 150ms var(--ease-out, ease);
}
.name-link:hover {
  color: var(--primary);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
.name-link:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ===== HOVER BANNER =====
   Floating label that appears above an element on :hover / :focus-visible.
   Usage: add `bepp-hover-banner` and a `data-tooltip="Label"` attribute.
   Modifiers:
     .bepp-hover-banner--align-end   → banner's right edge anchors to the
       host's right edge (use when the host sits at a container's right
       border and the centered banner would clip).
     .bepp-hover-banner--align-start → mirror of the above, left-anchored.
     .bepp-hover-banner--below       → flip the banner below the host. */
.bepp-hover-banner { position: relative; }
/* Si la clase persiste pero `data-tooltip` no existe o es vacío (caso típico:
   un botón con `data-disabled-reason` que vuelve a estado habilitado y queda
   con la clase `bepp-hover-banner` sin texto), suprimir el frame del ::after/::before
   para no dibujar un tooltip vacío al hover. */
.bepp-hover-banner:not([data-tooltip])::after,
.bepp-hover-banner:not([data-tooltip])::before,
.bepp-hover-banner[data-tooltip=""]::after,
.bepp-hover-banner[data-tooltip=""]::before {
  content: none;
}
/* Lift the host above siblings while the tooltip is showing — fixes
   z-index trap inside dropdowns/menus where the next sibling's stacking
   context covered the tooltip. */
.bepp-hover-banner:hover,
.bepp-hover-banner:focus-visible,
.bepp-hover-banner:focus-within {
  z-index: 1000005;
}

.bepp-hover-banner::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  background: var(--text);
  color: var(--white);
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  line-height: 1;
  padding: 6px 10px;
  border-radius: 6px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 150ms var(--ease-out, ease), transform 150ms var(--ease-out, ease);
  z-index: 1000005;
  box-shadow: var(--shadow-md);
}

.bepp-hover-banner::before {
  content: '';
  position: absolute;
  bottom: calc(100% + 3px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  border: 5px solid transparent;
  border-top-color: var(--text);
  opacity: 0;
  pointer-events: none;
  transition: opacity 150ms var(--ease-out, ease), transform 150ms var(--ease-out, ease);
  z-index: 1000005;
}

.bepp-hover-banner:hover::after,
.bepp-hover-banner:hover::before,
.bepp-hover-banner:focus-visible::after,
.bepp-hover-banner:focus-visible::before {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* Right-anchored variant — banner extends leftward from the host's right edge. */
.bepp-hover-banner--align-end::after {
  left: auto;
  right: 0;
  transform: translateX(0) translateY(4px);
}
.bepp-hover-banner--align-end:hover::after,
.bepp-hover-banner--align-end:focus-visible::after {
  transform: translateX(0) translateY(0);
}

/* Left-anchored variant — banner extends rightward from the host's left edge. */
.bepp-hover-banner--align-start::after {
  left: 0;
  right: auto;
  transform: translateX(0) translateY(4px);
}
.bepp-hover-banner--align-start:hover::after,
.bepp-hover-banner--align-start:focus-visible::after {
  transform: translateX(0) translateY(0);
}

/* Multiline variant — wraps long tooltips (e.g. "Motivo: Control · Consultorio ..."). */
.bepp-hover-banner--multiline::after {
  white-space: normal;
  max-width: 220px;
  text-align: center;
  line-height: 1.35;
  padding: 8px 12px;
}

/* Side variants — banner sits LEFT or RIGHT of the host (no overlap with
   vertical sibling list items in dropdowns/menus). */
.bepp-hover-banner--left::after {
  bottom: auto;
  top: 50%;
  left: auto;
  right: calc(100% + 8px);
  transform: translateX(4px) translateY(-50%);
}
.bepp-hover-banner--left::before {
  bottom: auto;
  top: 50%;
  left: auto;
  right: calc(100% + 3px);
  border: 5px solid transparent;
  border-left-color: var(--text);
  border-top-color: transparent;
  transform: translateX(4px) translateY(-50%);
}
.bepp-hover-banner--left:hover::after,
.bepp-hover-banner--left:focus-visible::after,
.bepp-hover-banner--left:hover::before,
.bepp-hover-banner--left:focus-visible::before {
  transform: translateX(0) translateY(-50%);
}

.bepp-hover-banner--right::after {
  bottom: auto;
  top: 50%;
  left: calc(100% + 8px);
  transform: translateX(-4px) translateY(-50%);
}
.bepp-hover-banner--right::before {
  bottom: auto;
  top: 50%;
  left: calc(100% + 3px);
  border: 5px solid transparent;
  border-right-color: var(--text);
  border-top-color: transparent;
  transform: translateX(-4px) translateY(-50%);
}
.bepp-hover-banner--right:hover::after,
.bepp-hover-banner--right:focus-visible::after,
.bepp-hover-banner--right:hover::before,
.bepp-hover-banner--right:focus-visible::before {
  transform: translateX(0) translateY(-50%);
}

/* Below variant — banner + arrow flip under the host. */
.bepp-hover-banner--below::after {
  bottom: auto;
  top: calc(100% + 8px);
  transform: translateX(-50%) translateY(-4px);
}
.bepp-hover-banner--below::before {
  bottom: auto;
  top: calc(100% + 3px);
  border-top-color: transparent;
  border-bottom-color: var(--text);
  transform: translateX(-50%) translateY(-4px);
}
.bepp-hover-banner--below:hover::after,
.bepp-hover-banner--below:hover::before,
.bepp-hover-banner--below:focus-visible::after,
.bepp-hover-banner--below:focus-visible::before {
  transform: translateX(-50%) translateY(0);
}

/* Combos: cuando se mezclan --align-end + --below (o --align-start + --below),
   --below sobrescribía el `transform` de --align-end con translateX(-50%) y
   el tooltip salía ~50% offset a la izquierda del botón. Estos combos dejan el
   eje X fijo a la variante de alineación y solo cambian el eje Y para below. */
.bepp-hover-banner--align-end.bepp-hover-banner--below::after,
.bepp-hover-banner--align-end.bepp-hover-banner--below::before {
  transform: translateX(0) translateY(-4px);
}
.bepp-hover-banner--align-end.bepp-hover-banner--below::before {
  /* La flecha vive cerca del borde derecho (sobre el botón), no centrada. */
  left: auto;
  right: 12px;
}
.bepp-hover-banner--align-end.bepp-hover-banner--below:hover::after,
.bepp-hover-banner--align-end.bepp-hover-banner--below:hover::before,
.bepp-hover-banner--align-end.bepp-hover-banner--below:focus-visible::after,
.bepp-hover-banner--align-end.bepp-hover-banner--below:focus-visible::before {
  transform: translateX(0) translateY(0);
}

.bepp-hover-banner--align-start.bepp-hover-banner--below::after,
.bepp-hover-banner--align-start.bepp-hover-banner--below::before {
  transform: translateX(0) translateY(-4px);
}
.bepp-hover-banner--align-start.bepp-hover-banner--below::before {
  left: 12px;
  right: auto;
}
.bepp-hover-banner--align-start.bepp-hover-banner--below:hover::after,
.bepp-hover-banner--align-start.bepp-hover-banner--below:hover::before,
.bepp-hover-banner--align-start.bepp-hover-banner--below:focus-visible::after,
.bepp-hover-banner--align-start.bepp-hover-banner--below:focus-visible::before {
  transform: translateX(0) translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .bepp-hover-banner::after,
  .bepp-hover-banner::before { transition: opacity 150ms linear; }
  .bepp-hover-banner:hover::after,
  .bepp-hover-banner:hover::before,
  .bepp-hover-banner:focus-visible::after,
  .bepp-hover-banner:focus-visible::before { transform: translateX(-50%) translateY(0); }
  .bepp-hover-banner--align-end:hover::after,
  .bepp-hover-banner--align-end:focus-visible::after,
  .bepp-hover-banner--align-start:hover::after,
  .bepp-hover-banner--align-start:focus-visible::after { transform: translateX(0) translateY(0); }
}

/* =====================================================================
   BEPP PULL TO REFRESH — indicator visual

   JS en js/bepp-pull-refresh.js. El indicator es un círculo fixed top-center
   que se traduce/rota proporcional al pull. Tokens BEPP, sin hex hardcoded.
   ===================================================================== */
.bepp-pull-refresh-indicator {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + var(--space-8));
  left: 50%;
  transform: translateX(-50%) translateY(-100%);
  z-index: 1000050;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--card);
  box-shadow: var(--shadow-md);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--primary);
  opacity: 0;
  transition: transform var(--duration-base, 250ms) var(--ease-out, ease),
              opacity var(--duration-fast, 150ms) ease;
  pointer-events: none;
}
.bepp-pull-refresh-indicator.is-pulling {
  transition: opacity var(--duration-fast, 150ms) ease;
}
.bepp-pull-refresh-indicator.is-ready {
  color: var(--accent);
}
.bepp-pull-refresh-indicator .bepp-pull-refresh-spinner {
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform var(--duration-fast, 150ms) var(--ease-out, ease);
}
.bepp-pull-refresh-indicator.is-refreshing .bepp-pull-refresh-spinner svg {
  animation: bepp-pull-spin 0.9s linear infinite;
}
@keyframes bepp-pull-spin {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .bepp-pull-refresh-indicator,
  .bepp-pull-refresh-indicator .bepp-pull-refresh-spinner {
    transition: opacity var(--duration-fast, 150ms) ease;
  }
  .bepp-pull-refresh-indicator.is-refreshing .bepp-pull-refresh-spinner svg {
    animation: bepp-pull-spin 1.6s linear infinite;
  }
}

/* =====================================================================
   bepp-hover-banner — kill switch en touch / mobile (≤640px)

   Decisión 2026-05-25: en touch no hay hover sostenido — el tap deja el
   tooltip "stuck" hasta el siguiente tap (sticky-hover de iOS Safari) y
   tapa el contenido. Aplica a paciente (PWA mobile, regla §4.1) y doctor
   en mobile (regla §4.2.2-H). En desktop/tablet con mouse real (hover:hover)
   el tooltip sigue funcionando.

   Doble guarda: viewport ≤640px Y/O hover capability = none. Cubre PWA
   instalada en iPad (puede ser >640 con touch) y desktop angosto con mouse
   (<640 con hover real).
   ===================================================================== */
@media (max-width: 640px), (hover: none) {
  .bepp-hover-banner::after,
  .bepp-hover-banner::before,
  .bepp-hover-banner:hover::after,
  .bepp-hover-banner:hover::before,
  .bepp-hover-banner:focus-visible::after,
  .bepp-hover-banner:focus-visible::before,
  .bepp-hover-banner:focus-within::after,
  .bepp-hover-banner:focus-within::before {
    content: none !important;
    opacity: 0 !important;
    display: none !important;
  }
  /* No lift z-index si no hay tooltip que mostrar */
  .bepp-hover-banner:hover,
  .bepp-hover-banner:focus-visible,
  .bepp-hover-banner:focus-within {
    z-index: auto;
  }
}

/* =====================================================================
   BEPP CURSOR TOOLTIP — floating cursor-follow tooltip
   See js/bepp-cursor-tooltip.js. Single shared DOM node, position:fixed.
   ===================================================================== */
.bepp-ct {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000060;
  pointer-events: none;
  background: var(--text);
  color: var(--white);
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
  padding: var(--space-8) var(--space-12);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  white-space: normal;
  max-width: 280px;
  max-height: 200px;
  overflow: hidden;
  opacity: 0;
  transform: translateY(2px);
  transition: opacity 120ms var(--ease-out), transform 120ms var(--ease-out);
}
.bepp-ct.is-visible {
  opacity: 1;
  transform: translateY(0);
}
.bepp-ct.no-motion {
  transition: none;
}
.bepp-ct .ct-line {
  display: block;
}
.bepp-ct .ct-line + .ct-line {
  margin-top: var(--space-4);
}
.bepp-ct .ct-line strong {
  font-weight: var(--fw-bold);
  opacity: 0.85;
}
.bepp-ct .ct-shortcut {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  flex-wrap: wrap;
}
.bepp-ct .ct-shortcut-hint {
  display: block;
  margin-top: var(--space-4);
  font-size: var(--font-2xs);
  font-weight: var(--fw-regular);
  opacity: 0.7;
}
.bepp-ct kbd {
  display: inline-block;
  padding: 1px 6px;
  margin: 0 1px;
  background: var(--white-alpha-10);
  border: 1px solid var(--white-alpha-30);
  border-radius: 4px;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: var(--font-2xs);
  color: var(--white);
}

/* ============================================= */
/* ===== LAYOUT EDITOR — trigger + action bar ==== */
/* ============================================= */
/* Reusable pattern for any screen that exposes a rearrangeable/resizable
   widget grid. Consumed by doctor_home.html today; the bento-grid page
   adds its own editing outlines and gridstack-specific rules. */

.layout-edit-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-10) var(--space-16);
  background: var(--white);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-size: var(--font-sm);
  font-weight: var(--fw-medium);
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

.layout-edit-btn:hover {
  background: var(--surface-alt);
  border-color: var(--primary-soft);
  box-shadow: var(--shadow-sm);
}

.layout-edit-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.layout-edit-btn .icon {
  color: var(--primary);
}

/* Navbar variant — translucent look that sits on the primary gradient header */
.header .layout-edit-btn {
  padding: var(--space-6) var(--space-12);
  background: rgba(255, 255, 255, 0.1);
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.2);
  font-size: var(--font-xs);
}

.header .layout-edit-btn:hover {
  background: rgba(255, 255, 255, 0.2);
  border-color: rgba(255, 255, 255, 0.35);
  box-shadow: none;
}

.header .layout-edit-btn:focus-visible {
  outline-color: var(--white);
}

.header .layout-edit-btn .icon {
  color: var(--white);
}

/* Hide while editing — the action bar takes over */
body.layout-editing .layout-edit-btn { display: none; }

/* Hide on narrow viewports — layout editor is desktop-only for now */
@media (max-width: 1100px) {
  .layout-edit-btn { display: none; }
}

/* --- Floating action bar (Save/Cancel) --- */
.layout-editor-bar {
  position: fixed;
  bottom: var(--space-24);
  left: 50%;
  transform: translateX(-50%) translateY(100px);
  display: flex;
  align-items: center;
  gap: var(--space-20);
  padding: var(--space-12) var(--space-20);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-lg);
  z-index: 9500;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.25s cubic-bezier(0.22, 1, 0.36, 1);
}

body.layout-editing .layout-editor-bar {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
  pointer-events: auto;
}

.layout-editor-bar-text {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  font-size: var(--font-sm);
  color: var(--text-secondary);
}

.layout-editor-bar-text .icon {
  color: var(--primary);
}

.layout-editor-bar-actions {
  display: inline-flex;
  gap: var(--space-8);
}

/* ============================================= */
/* ===== WIDGET MANAGER — modal (show/hide) ===== */
/* ============================================= */
/* Two-column modal pattern: Visible | Hidden. Each row is a toggleable
   button that flips between columns when pressed. Lives inside the
   standard .modal-overlay / .modal-content shell. */

/* Cap the modal height and make body fill the remaining space so the
   column lists can scroll internally instead of the whole card growing
   past the viewport. Scoped to the widget manager modal so other
   .modal-lg usages (multi-step forms, etc.) keep their natural height. */
#widgetManagerModal .modal-content {
  max-height: 85vh;
  display: flex;
  flex-direction: column;
}
#widgetManagerModal .modal-body {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.widget-manager-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-16);
  min-height: 0;
  height: 100%;
}

.widget-manager-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-10);
  padding: var(--space-14);
  border: 1px solid var(--border-light);
  border-radius: 12px;
  background: var(--gray-50);
  min-height: 240px;
  min-width: 0;
  overflow: hidden;
}

/* Header stays put; only the list below scrolls */
.widget-manager-col-header {
  flex-shrink: 0;
}

.widget-manager-col-header {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  color: var(--text-light);
}

.widget-manager-col-header h4 {
  margin: 0;
  font-size: var(--font-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-light);
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
}

.widget-manager-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 20px;
  padding: 0 var(--space-6);
  border-radius: 999px;
  background: var(--white);
  border: 1px solid var(--border-light);
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  color: var(--text-secondary);
  letter-spacing: 0;
  text-transform: none;
}

.widget-manager-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  /* Breathing room so the last row's focus ring isn't clipped */
  padding-right: 2px;
}

.widget-manager-empty {
  padding: var(--space-16) var(--space-12);
  text-align: center;
  font-size: var(--font-xs);
  color: var(--text-light);
  line-height: 1.45;
}

.widget-manager-item {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-10) var(--space-12);
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--white);
  cursor: pointer;
  text-align: left;
  width: 100%;
  font-family: inherit;
  transition: border-color 150ms ease, background 150ms ease, transform 120ms ease, box-shadow 150ms ease;
}

.widget-manager-item:hover {
  border-color: var(--primary);
  box-shadow: var(--shadow-sm);
}

.widget-manager-item:active { transform: scale(0.99); }

.widget-manager-item:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.widget-manager-icon {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--primary-50);
  color: var(--primary);
  flex-shrink: 0;
}

.widget-manager-item:not(.is-on) .widget-manager-icon {
  background: var(--gray-100);
  color: var(--text-light);
}

.widget-manager-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.widget-manager-title {
  font-size: var(--font-sm);
  font-weight: var(--fw-semibold);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.widget-manager-cat {
  font-size: var(--font-xs);
  color: var(--text-light);
}

/* iOS-style switch genérico — uso global */
.bepp-switch {
  position: relative;
  width: 44px;
  height: 26px;
  border-radius: 999px;
  background: var(--gray-300);
  flex-shrink: 0;
  transition: background 160ms ease;
  border: 0;
  padding: 0;
  cursor: pointer;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
}

.bepp-switch-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--white);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
  transition: transform 200ms var(--ease-out);
  pointer-events: none;
}

.bepp-switch.is-on {
  background: var(--accent);
}

.bepp-switch.is-on .bepp-switch-knob {
  transform: translateX(18px);
}

.bepp-switch:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.bepp-switch[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Setting row — pattern para listas de ajustes con switch o chevron */
.bepp-setting-row {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-14) var(--space-16);
  border-bottom: 1px solid var(--border-light);
  /* Reset cuando se usa como <button> o <a>: hereda look uniforme */
  appearance: none;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--border-light);
  border-radius: 0;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

button.bepp-setting-row:focus-visible,
a.bepp-setting-row:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
  background: var(--sky-soft);
}

@media (hover: hover) {
  button.bepp-setting-row:hover,
  a.bepp-setting-row:hover {
    background: var(--sky-soft);
  }
}

button.bepp-setting-row:active,
a.bepp-setting-row:active {
  background: var(--sky-soft);
}

.bepp-setting-row:last-child { border-bottom: 0; }

.bepp-setting-row-icon {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  background: var(--sky-soft);
  color: var(--primary-dark);
  flex-shrink: 0;
}

.bepp-setting-row-icon .icon { width: 18px; height: 18px; }

.bepp-setting-row-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.bepp-setting-row-title {
  font-size: var(--font-sm);
  font-weight: var(--fw-semibold);
  color: var(--primary-dark);
}

.bepp-setting-row-desc {
  font-size: var(--font-xs);
  color: var(--text-soft);
}

/* iOS-style switch (legacy: usado en widget manager) */
.widget-manager-switch {
  position: relative;
  width: 34px;
  height: 20px;
  border-radius: 999px;
  background: var(--gray-200);
  flex-shrink: 0;
  transition: background 160ms ease;
}

.widget-manager-switch-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--white);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
  transition: transform 160ms cubic-bezier(0.22, 1, 0.36, 1);
}

.widget-manager-item.is-on .widget-manager-switch {
  background: var(--primary);
}

.widget-manager-item.is-on .widget-manager-switch-knob {
  transform: translateX(14px);
}

@media (max-width: 640px) {
  /* On narrow screens, stack columns and let the modal body scroll as
     one so the user doesn't juggle two independent scroll areas. */
  .widget-manager-columns { grid-template-columns: 1fr; height: auto; }
  .widget-manager-col { min-height: 0; overflow: visible; }
  .widget-manager-list { overflow-y: visible; flex: none; }
  #widgetManagerModal .modal-body { overflow-y: auto; }
}

/* =====================================================================
   TABS — global component
   Reusable tab navigation pattern. Previously lived per-page in
   doctor_consulta.css / doctor_expediente_clinico.css. Canonical home
   is now here. Page-level overrides should be rare; prefer extending
   the global tokens.
   Mark-up:
     <nav class="tab-nav" role="tablist">
       <button class="tab-btn active" onclick="switchTab(event,'t1')">…</button>
       <button class="tab-btn" onclick="switchTab(event,'t2')">…</button>
     </nav>
     <section id="t1" class="tab-content active">…</section>
     <section id="t2" class="tab-content">…</section>
   ===================================================================== */
.tab-nav {
  display: flex;
  flex-wrap: wrap;
  background: var(--card);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-bottom: var(--space-20);
  box-shadow: var(--shadow-xs);
  gap: var(--space-2);
  border: 1px solid var(--border-light);
}

.tab-btn {
  padding: var(--space-10) var(--space-18);
  border: none;
  background: transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--font-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-secondary);
  white-space: nowrap;
  transition: background var(--duration-base, 240ms) var(--ease-spring, cubic-bezier(.34,1.56,.64,1)),
              color var(--duration-base, 240ms) var(--ease-out, ease),
              box-shadow var(--duration-base, 240ms) var(--ease-out, ease),
              transform var(--duration-quick, 150ms) var(--ease-out, ease);
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  min-height: 44px; /* touch target */
}
.tab-btn .icon {
  width: 16px;
  height: 16px;
}

.tab-btn:hover {
  background: var(--surface-alt);
  color: var(--text);
}

.tab-btn.active {
  background: var(--primary);
  color: var(--white);
  box-shadow: var(--shadow-sm);
}

.tab-btn .badge {
  background: rgba(255, 255, 255, 0.22);
  padding: var(--space-1) var(--space-6);
  border-radius: var(--radius-full);
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
}

.tab-btn .tab-btn-ai-badge {
  background: linear-gradient(135deg, var(--primary-light), var(--accent));
  color: var(--white);
  padding: 2px var(--space-8);
  border-radius: var(--radius-full);
  font-size: var(--font-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.tab-content {
  display: none;
  animation: tabContentFade 220ms ease-out;
}

.tab-content.active {
  display: block;
}

@keyframes tabContentFade {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (max-width: 640px) {
  .tab-nav {
    overflow-x: auto;
    flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .tab-nav::-webkit-scrollbar { display: none; }
  .tab-btn { padding: var(--space-10) var(--space-14); font-size: var(--font-xs); }
}

/* =====================================================================
   DATA TABLE — .bepp-table
   Tabla de datos reutilizable (directorio de pacientes, facturación,
   rewards). Soporta: checkbox bulk, columnas sortable, filas clickables,
   avatares y chips embebidos. Fondo de card, hover suave, sticky header.
   ===================================================================== */
.bepp-table-wrapper {
  background: var(--card);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xs);
  /* `overflow: visible` para que `position: sticky` del thead se ancle
     a la ventana (debajo del header global) en vez de al contenedor. */
  overflow: visible;
}

.bepp-table-scroll {
  /* Mismo principio: dejar el flujo libre para sticky vertical.
     El no-horizontal-scroll del body (regla global) clipea horizontalmente. */
  overflow: visible;
  -webkit-overflow-scrolling: touch;
}

.bepp-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--font-sm);
  color: var(--text);
}

/* Sticky header thead: queda anclado debajo del doctor-header global. */
.bepp-table thead {
  position: sticky;
  top: var(--header-height, 64px);
  z-index: 10;
  /* Sin background: rectangular detrás de las th rompía el rounded corner del
     wrapper. Cada th ya pinta su propio bg con border-radius en las esquinas. */
}
.bepp-table thead th {
  position: sticky;
  top: var(--header-height, 64px);
  z-index: 10;
  background: var(--card);
  color: var(--text-secondary);
  font-weight: var(--fw-semibold);
  font-size: var(--font-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  text-align: left;
  padding: var(--space-12) var(--space-14);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 var(--border);
  white-space: nowrap;
  user-select: none;
}
/* Redondear las esquinas exteriores del thead para que no escapen del
   card cuando el wrapper usa border-radius + overflow:visible (sticky).
   El primer th puede ser un checkbox con display:none (selection mode off)
   — por eso también redondeamos el th que viene después del check. */
.bepp-table thead tr:first-child > th:first-child,
.bepp-table thead tr:first-child > th.bepp-table__check + th {
  border-top-left-radius: var(--radius-md);
}
.bepp-table thead tr:first-child > th:last-child {
  border-top-right-radius: var(--radius-md);
}

.bepp-table thead th.is-sortable {
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
}

.bepp-table thead th.is-sortable:hover {
  color: var(--primary);
  background: var(--primary-alpha-04);
}

.bepp-table thead th.is-sorted {
  color: var(--primary);
}

.bepp-table-th-inner {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
}

.bepp-table-sort-icon {
  display: inline-flex;
  width: 12px;
  height: 12px;
  opacity: 0;
  transition: opacity 0.15s, transform 0.15s;
}

.bepp-table thead th.is-sortable:hover .bepp-table-sort-icon,
.bepp-table thead th.is-sorted .bepp-table-sort-icon {
  opacity: 1;
}

.bepp-table thead th.is-sorted-desc .bepp-table-sort-icon {
  transform: rotate(180deg);
}

.bepp-table tbody td {
  padding: var(--space-12) var(--space-14);
  border-bottom: 1px solid var(--border-light);
  vertical-align: middle;
}

.bepp-table tbody tr:last-child td {
  border-bottom: 0;
}

.bepp-table tbody tr.is-clickable {
  cursor: pointer;
  transition: background var(--duration-quick, 150ms) var(--ease-out, ease),
              box-shadow var(--duration-quick, 150ms) var(--ease-out, ease);
}

.bepp-table tbody tr.is-clickable:hover {
  background: var(--primary-alpha-04);
  box-shadow: inset 3px 0 0 var(--primary);
}

.bepp-table tbody tr.is-selected {
  background: var(--primary-alpha-06);
}

.bepp-table tbody tr.is-selected:hover {
  background: var(--primary-alpha-12);
}

.bepp-table__check {
  width: 36px;
  padding-right: 0;
  text-align: center;
}

.bepp-table__check input[type="checkbox"] {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--primary);
}

.bepp-table__cell--primary {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  min-width: 220px;
}

.bepp-table__cell--meta {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.bepp-table__name {
  font-weight: var(--fw-semibold);
  color: var(--text);
  line-height: var(--lh-snug);
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
}

.bepp-table__sub {
  font-size: var(--font-xs);
  color: var(--text-secondary);
  line-height: var(--lh-snug);
}

.bepp-table__actions {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  justify-content: flex-end;
  width: 100%;
}

.bepp-table__icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-xs);
  border: 0;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

.bepp-table__icon-btn:hover {
  background: var(--primary-alpha-06);
  color: var(--primary);
}

.bepp-table__icon-btn.is-active {
  color: var(--warning);
}

.bepp-table-empty {
  padding: var(--space-48) var(--space-24);
  text-align: center;
  color: var(--text-secondary);
}

.bepp-table-empty-icon {
  display: inline-flex;
  width: 48px;
  height: 48px;
  color: var(--text-light);
  margin-bottom: var(--space-12);
}

.bepp-table-empty-title {
  font-size: var(--font-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
  margin-bottom: var(--space-4);
}

/* =====================================================================
   BOTTOM SHEET GLOBAL — .bepp-sheet
   Drawer mobile-first anclado al pie. Backdrop + panel con grabber,
   header opcional (título + close), body scrolleable, footer opcional
   con safe-area. Body scroll lock vía .is-sheet-open en html/body
   (sólo overflow hidden — nunca position:fixed; rompe safe-area canvas).
   El helper js/bepp-sheet.js maneja apertura/cierre, Esc, y scroll lock.

   Estructura mínima:
     <div class="bepp-sheet" id="miSheet" hidden role="dialog" aria-modal="true">
       <div class="bepp-sheet__backdrop" data-sheet-close></div>
       <div class="bepp-sheet__panel">
         <div class="bepp-sheet__grabber" aria-hidden="true"></div>
         <header class="bepp-sheet__header">
           <h3 class="bepp-sheet__title">Compartir</h3>
           <button class="bepp-sheet__close" type="button" data-sheet-close
                   aria-label="Cerrar"><svg class="icon"><use href="#x"/></svg></button>
         </header>
         <div class="bepp-sheet__body">…</div>
         <footer class="bepp-sheet__footer">
           <div class="bepp-sheet__footer-row">…</div>
         </footer>
       </div>
     </div>

   Trigger:  <button data-sheet-open="miSheet">Abrir</button>
   API JS:   BeppSheet.open(el) | BeppSheet.close(el)
   Variantes en wrapper: --tall (92vh), --full (100lvh, sin border-radius).
   Variante header centrado: .bepp-sheet__header--centered (sin close button).
   ===================================================================== */
.bepp-sheet[hidden],
.bepp-sheet[aria-hidden="true"]:not(.is-open):not(.is-closing) { display: none; }

.bepp-sheet {
  position: fixed;
  inset: 0;
  z-index: 1000002;
  display: block;
}

html.is-sheet-open,
body.is-sheet-open {
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: none;
}

.bepp-sheet__backdrop {
  position: absolute;
  inset: 0;
  background: var(--overlay-backdrop);
  opacity: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity var(--duration-base) var(--ease-out);
}

.bepp-sheet.is-open .bepp-sheet__backdrop { opacity: 1; }

.bepp-sheet.is-closing .bepp-sheet__backdrop {
  opacity: 0;
  transition-duration: 180ms;
  transition-timing-function: var(--ease-in);
}

.bepp-sheet__panel {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  max-height: 85vh;
  background: var(--card);
  border-top-left-radius: var(--radius-lg);
  border-top-right-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  transform: translateY(100%);
  transition: transform var(--duration-slow) var(--ease-out);
}

/* Bg-extension abajo del panel: cubre el gap cuando rubber-band lo jala
   hacia arriba (industria-iOS — ej. Apple Maps). Se extiende muy debajo
   del viewport para que ningún rebote/overshoot/drag deje ver el fondo.
   pointer-events:none para no interferir con backdrop taps. */
.bepp-sheet__panel::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 100vh;
  background: var(--card);
  pointer-events: none;
}

.bepp-sheet.is-open .bepp-sheet__panel { transform: translateY(0); }

.bepp-sheet.is-closing .bepp-sheet__panel {
  transform: translateY(100%);
  transition-duration: 200ms;
  transition-timing-function: var(--ease-in);
}

.bepp-sheet--tall .bepp-sheet__panel { max-height: 92vh; }
.bepp-sheet--full .bepp-sheet__panel {
  max-height: 100lvh;
  height: 100lvh;
  border-radius: 0;
}

.bepp-sheet__grabber {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 28px;
  padding: var(--space-10) 0 var(--space-4);
  cursor: grab;
  touch-action: none;
  flex-shrink: 0;
}
.bepp-sheet__grabber::before {
  content: '';
  width: 40px;
  height: 4px;
  border-radius: var(--radius-full);
  background: var(--border);
}
.bepp-sheet__grabber:active { cursor: grabbing; }

.bepp-sheet__header { touch-action: none; }

.bepp-sheet__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  padding: var(--space-10) var(--space-20) var(--space-10);
  flex-shrink: 0;
}

.bepp-sheet__header--centered {
  flex-direction: column;
  text-align: center;
  align-items: stretch;
  gap: var(--space-4);
  padding-top: var(--space-12);
}

.bepp-sheet__title,
.bepp-sheet__header h2,
.bepp-sheet__header h3 {
  font-size: var(--font-md);
  font-weight: var(--fw-bold);
  color: var(--primary-dark);
  letter-spacing: var(--tracking-tight);
  line-height: var(--lh-snug);
  min-width: 0;
}

.bepp-sheet__sub,
.bepp-sheet__header p {
  font-size: var(--font-xs);
  color: var(--text-secondary);
  line-height: var(--lh-snug);
}

.bepp-sheet__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  background: transparent;
  border: 0;
  border-radius: var(--radius-full);
  color: var(--text-secondary);
  cursor: pointer;
  flex-shrink: 0;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}

.bepp-sheet__close .icon { width: 20px; height: 20px; }

@media (hover: hover) {
  .bepp-sheet__close:hover {
    background: var(--surface-alt);
    color: var(--primary-dark);
  }
}

.bepp-sheet__body {
  padding: var(--space-12) var(--space-20) var(--space-20);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
  flex: 1 1 auto;
  min-height: 0;
}

.bepp-sheet__footer {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  padding: var(--space-12) var(--space-20) calc(var(--space-16) + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--border-light);
  background: var(--card);
  flex-shrink: 0;
}

.bepp-sheet__footer-row {
  display: flex;
  gap: var(--space-8);
  align-items: stretch;
}

.bepp-sheet__footer-row > * { flex: 1 1 0; }

@media (prefers-reduced-motion: reduce) {
  .bepp-sheet__backdrop,
  .bepp-sheet__panel {
    transition: none !important;
  }
}

/* =====================================================================
   BULK ACTION BAR — .bulk-bar
   Barra flotante que aparece cuando hay selección múltiple en una tabla.
   Se ancla al pie de la página con transform para la animación de entrada.
   ===================================================================== */
.bulk-bar {
  position: fixed;
  left: 50%;
  bottom: var(--space-24);
  transform: translateX(-50%) translateY(calc(100% + var(--space-24) + 8px));
  display: flex;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-10) var(--space-12) var(--space-10) var(--space-16);
  background: var(--primary-dark);
  color: var(--white);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-lg);
  z-index: 50;
  max-width: calc(100vw - var(--space-32));
  transition: transform 0.25s cubic-bezier(0.2, 0.9, 0.3, 1.2), visibility 0s linear 0.25s;
  pointer-events: none;
  visibility: hidden;
}

.bulk-bar.is-open {
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
  visibility: visible;
  transition: transform 0.25s cubic-bezier(0.2, 0.9, 0.3, 1.2), visibility 0s;
}

.bulk-bar-count {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  font-size: var(--font-sm);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}

.bulk-bar-count strong {
  font-weight: var(--fw-bold);
}

.bulk-bar-divider {
  width: 1px;
  height: 24px;
  background: var(--white-alpha-70);
  opacity: 0.3;
}

.bulk-bar-actions {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
}

.bulk-bar-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-8) var(--space-14);
  background: transparent;
  border: 0;
  border-radius: var(--radius-full);
  color: var(--white);
  font-family: inherit;
  font-size: var(--font-sm);
  font-weight: var(--fw-medium);
  cursor: pointer;
  transition: background 0.15s;
  white-space: nowrap;
}

.bulk-bar-btn:hover {
  background: var(--white-alpha-70);
  color: var(--primary-dark);
}

.bulk-bar-btn--danger:hover {
  background: var(--status-danger);
  color: var(--white);
}

.bulk-bar-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: transparent;
  border: 0;
  border-radius: var(--radius-full);
  color: var(--white);
  cursor: pointer;
  transition: background 0.15s;
}

.bulk-bar-close:hover {
  background: var(--white-alpha-70);
  color: var(--primary-dark);
}

@media (max-width: 640px) {
  .bulk-bar {
    left: var(--space-12);
    right: var(--space-12);
    bottom: var(--space-12);
    transform: translateY(calc(100% + var(--space-12) + 8px));
    border-radius: var(--radius-md);
    flex-wrap: wrap;
    justify-content: space-between;
  }
  .bulk-bar.is-open {
    transform: translateY(0);
  }
  .bulk-bar-actions {
    flex-wrap: wrap;
  }
}

/* "Seleccionar todos" affordance dentro del bulk-bar */
.bulk-bar-selectall {
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-6) var(--space-12);
  background: var(--white-alpha-30);
  color: var(--white);
  border: 0;
  border-radius: var(--radius-full);
  font-family: inherit;
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: background var(--duration-quick, 150ms) var(--ease-out, ease);
  white-space: nowrap;
}
.bulk-bar-selectall:hover { background: var(--white); color: var(--primary-dark); }
.bulk-bar-selectall.is-active { background: var(--white); color: var(--primary-dark); }

/* Kbd hints en bulk-bar */
.bulk-kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: var(--space-4);
  padding: 0 var(--space-6);
  min-width: 18px;
  height: 18px;
  background: var(--white-alpha-30);
  color: var(--white);
  border-radius: var(--radius-xs);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--font-2xs);
  font-weight: var(--fw-bold);
  line-height: 1;
}

/* =====================================================================
   ROW CONTEXT MENU — .row-context-menu
   Popover invocado por right-click en filas de tablas. Posicionado en
   coordenadas del cursor. Estilo BEPP: card + border-light + shadow-md.
   ===================================================================== */
.row-context-menu {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000010;
  min-width: 220px;
  padding: var(--space-6);
  background: var(--card);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  opacity: 0;
  transform: scale(.96);
  transform-origin: top left;
  transition: opacity var(--duration-quick, 150ms) var(--ease-out, ease),
              transform var(--duration-quick, 150ms) var(--ease-out, ease);
  pointer-events: none;
}
.row-context-menu.is-open {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}
.row-context-menu[hidden] { display: none; }

.row-context-item {
  display: flex;
  align-items: center;
  gap: var(--space-10);
  width: 100%;
  padding: var(--space-8) var(--space-12);
  background: transparent;
  border: 0;
  border-radius: var(--radius-xs);
  color: var(--text);
  font-family: inherit;
  font-size: var(--font-sm);
  font-weight: var(--fw-medium);
  text-align: left;
  cursor: pointer;
  transition: background var(--duration-quick, 150ms) var(--ease-out, ease),
              color var(--duration-quick, 150ms) var(--ease-out, ease);
}
.row-context-item:hover,
.row-context-item:focus-visible {
  background: var(--primary-alpha-06);
  color: var(--primary);
  outline: none;
}
.row-context-item .icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}
.row-context-item.is-danger:hover,
.row-context-item.is-danger:focus-visible {
  background: var(--status-danger-soft);
  color: var(--status-danger-strong);
}
.row-context-sep {
  height: 1px;
  margin: var(--space-4) 0;
  background: var(--border-light);
}

@media (prefers-reduced-motion: reduce) {
  .row-context-menu { transition: opacity var(--duration-fast, 100ms) linear; transform: none; }
  .row-context-menu.is-open { transform: none; }
}

/* =====================================================================
   TOAST GLOBAL — .bepp-toast
   Notificación efímera, una sola línea, verde accent. Anclada al pie
   centro, encima del dock y la safe-area. Encima de modales.
   Estructura mínima:
     <div class="bepp-toast" role="status" aria-live="polite">
       <svg class="icon"><use href="#check-circle"/></svg>
       <span class="bepp-toast__msg">Listo. Se guardó tu cambio.</span>
       <button class="bepp-toast__action" type="button">Deshacer</button>
     </div>
   Contrato JS:  el.classList.add('is-visible')   →  mostrar
                 setTimeout(() => el.classList.remove('is-visible'), 2500)
   Variantes: --error · --info · --neutral (azul). Default = accent.
   ===================================================================== */
.bepp-toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--space-96) + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%) translateY(140%);
  z-index: 1000003;
  display: inline-flex;
  align-items: center;
  gap: var(--space-10);
  padding: var(--space-10) var(--space-18);
  background: var(--accent-alpha-85);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
  color: var(--white);
  border-radius: var(--radius-full);
  font-size: var(--font-sm);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  box-shadow: var(--shadow-md);
  max-width: calc(100vw - var(--space-32));
  white-space: nowrap;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  transition: transform var(--duration-base) var(--ease-spring, cubic-bezier(.34,1.56,.64,1)),
              opacity var(--duration-quick) var(--ease-out);
}

.bepp-toast.is-visible {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
  pointer-events: auto;
}

.bepp-toast[hidden] { display: none; }

.bepp-toast .icon {
  width: 18px;
  height: 18px;
  color: var(--white);
  flex-shrink: 0;
}

.bepp-toast__msg {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.bepp-toast__action {
  display: inline-flex;
  align-items: center;
  padding: var(--space-4) var(--space-12);
  margin-left: var(--space-4);
  background: var(--white-alpha-70);
  border: 0;
  border-radius: var(--radius-full);
  color: var(--accent);
  font-family: inherit;
  font-size: var(--font-xs);
  font-weight: var(--fw-bold);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out);
  flex-shrink: 0;
}

@media (hover: hover) {
  .bepp-toast__action:hover { background: var(--white); }
}

.bepp-toast--error   { background: var(--status-danger-strong); }
.bepp-toast--error   .bepp-toast__action { color: var(--status-danger-strong); }

.bepp-toast--info    { background: var(--info); }
.bepp-toast--info    .bepp-toast__action { color: var(--info); }

.bepp-toast--neutral { background: var(--primary-dark); }
.bepp-toast--neutral .bepp-toast__action { color: var(--primary-dark); }

@media (prefers-reduced-motion: reduce) {
  .bepp-toast {
    transition: opacity var(--duration-fast) linear;
    transform: translateX(-50%);
  }
  .bepp-toast.is-visible { transform: translateX(-50%); }
}

/* =====================================================================
   WIZARD GLOBAL — .bepp-wizard
   Indicador de progreso para flujos multi-paso. Dos variantes:

   1. TRAIL  (default) — círculos con icono + nombres + conectores.
              Pensado para sub-flujos navegables (cada paso es un <a>).
              Estructura:
     <ol class="bepp-wizard bepp-wizard--trail" aria-label="Paso 1 de 5">
       <li class="bepp-wizard__step is-current" aria-current="step">
         <a class="bepp-wizard__link" href="...">
           <span class="bepp-wizard__circle">
             <svg class="icon"><use href="#user-circle"/></svg>
           </span>
           <span class="bepp-wizard__name">Ficha</span>
         </a>
       </li>
       <li class="bepp-wizard__connector" aria-hidden="true"></li>
       <li class="bepp-wizard__step">…</li>
     </ol>

   2. DOTS — pills minimalistas dentro de un sheet/wizard lineal.
             Estructura:
     <div class="bepp-wizard bepp-wizard--dots" role="progressbar">
       <span class="bepp-wizard__dot is-done"></span>
       <span class="bepp-wizard__dot is-active"></span>
       <span class="bepp-wizard__dot"></span>
     </div>

   Estados (en .bepp-wizard__step):
     · default       → vacío (gris)
     · is-progress   → en progreso (amarillo warning)
     · is-done       → completo (verde accent)
     · is-current    → paso actual (azul primary, escala 1.18)
   Los estados son combinables (e.g. is-current.is-done).
   ===================================================================== */
.bepp-wizard {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* ----- TRAIL ----- */
.bepp-wizard--trail {
  padding: 0 var(--space-8) var(--space-32);
}

.bepp-wizard__step {
  display: inline-flex;
  flex-shrink: 0;
}

.bepp-wizard__link {
  position: relative;
  display: inline-flex;
  text-decoration: none;
  color: inherit;
  border-radius: var(--radius-full);
  -webkit-tap-highlight-color: transparent;
  cursor: pointer;
}

.bepp-wizard__link:focus-visible {
  outline: 2px solid var(--primary-alpha-15);
  outline-offset: 4px;
}

.bepp-wizard__circle {
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-full);
  background: var(--card);
  border: 1.5px solid var(--border);
  color: var(--text-light);
  transition: background var(--duration-base) var(--ease-out),
              border-color var(--duration-base) var(--ease-out),
              color var(--duration-base) var(--ease-out),
              transform var(--duration-base) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out);
}

.bepp-wizard__circle .icon {
  width: 14px;
  height: 14px;
}

.bepp-wizard__name {
  position: absolute;
  top: calc(100% + var(--space-14));
  left: 50%;
  transform: translateX(-50%);
  font-size: var(--font-2xs);
  font-weight: var(--fw-semibold);
  color: var(--text-light);
  white-space: nowrap;
  letter-spacing: var(--tracking-tight);
  line-height: 1;
}

.bepp-wizard__connector {
  flex: 1;
  height: 2px;
  background: var(--gray-300);
  max-width: var(--space-32);
  min-width: var(--space-12);
  margin: 0 var(--space-6);
  list-style: none;
  transition: background var(--duration-base) var(--ease-out);
}

.bepp-wizard__connector.is-done {
  background: var(--accent);
}

/* Estados del trail */
.bepp-wizard__step.is-progress .bepp-wizard__circle {
  background: var(--status-warning-soft);
  border-color: transparent;
  color: var(--status-warning-strong);
}
.bepp-wizard__step.is-progress .bepp-wizard__name {
  color: var(--status-warning-strong);
}

.bepp-wizard__step.is-done .bepp-wizard__circle {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--white);
}
.bepp-wizard__step.is-done .bepp-wizard__name {
  color: var(--accent-hover);
}

.bepp-wizard__step.is-current .bepp-wizard__circle {
  background: var(--primary);
  border: 3px solid var(--white);
  outline: 1.5px solid var(--primary);
  color: var(--white);
  transform: scale(1.18);
  box-shadow: var(--shadow-md);
}
.bepp-wizard__step.is-current .bepp-wizard__name {
  color: var(--primary-dark);
  font-weight: var(--fw-bold);
}

.bepp-wizard__step.is-current.is-done .bepp-wizard__circle {
  background: var(--accent);
  outline-color: var(--accent);
}

.bepp-wizard__step.is-current.is-progress .bepp-wizard__circle {
  background: var(--status-warning-strong);
  outline-color: var(--status-warning-strong);
}

/* ----- DOTS ----- */
.bepp-wizard--dots {
  gap: var(--space-6);
  margin-top: var(--space-10);
}

.bepp-wizard__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--border);
  transition: width var(--duration-base) var(--ease-out),
              background var(--duration-base) var(--ease-out);
}

.bepp-wizard__dot.is-done {
  background: var(--accent);
}

.bepp-wizard__dot.is-active {
  width: 20px;
  border-radius: 3px;
  background: var(--primary);
}

@media (prefers-reduced-motion: reduce) {
  .bepp-wizard__circle,
  .bepp-wizard__dot { transition: none; }
  .bepp-wizard__step.is-current .bepp-wizard__circle { transform: none; }
}

/* =====================================================================
   MOBILE FORM CONTROLS — prevent iOS auto-zoom on focus
   iOS Safari hace zoom automático al enfocar un input con font-size < 16px.
   Forzamos --font-base (16px) en controles de formulario sólo en móvil
   para eliminar ese zoom sin tocar el meta viewport (preserva el gesto
   de pinch-zoom del usuario, importante para accesibilidad).
   ===================================================================== */
@media (max-width: 640px) {
  input,
  select,
  textarea,
  .modal-form-group input,
  .modal-form-group select,
  .modal-form-group textarea {
    font-size: var(--font-base);
  }
}

/* =====================================================================
   AI BULLETS — lista de hallazgos IA con icono + color semántico
   Uso: <ul class="ai-bullets"> con <li class="ai-bullet ai-bullet--info">
   Variantes: --info, --success, --warning, --danger, --accent
   ===================================================================== */
.ai-bullets {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-10) var(--space-20);
}
@media (max-width: 640px) {
  .ai-bullets { grid-template-columns: 1fr; }
}
.ai-bullet {
  display: flex;
  align-items: flex-start;
  gap: var(--space-12);
}
.ai-bullet-icon {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--status-info-soft);
  color: var(--status-info-strong);
}
.ai-bullet-body {
  font-size: var(--font-sm);
  color: var(--text);
  line-height: 1.45;
  padding-top: var(--space-4);
}
.ai-bullet-body strong {
  color: var(--text);
  font-weight: var(--fw-semibold);
}
.ai-bullet--info    .ai-bullet-icon { background: var(--status-info-soft);    color: var(--status-info-strong); }
.ai-bullet--success .ai-bullet-icon { background: var(--status-success-soft); color: var(--status-success-strong); }
.ai-bullet--warning .ai-bullet-icon { background: var(--status-warning-soft); color: var(--status-warning-strong); }
.ai-bullet--danger  .ai-bullet-icon { background: var(--status-danger-soft);  color: var(--status-danger-strong); }
.ai-bullet--accent  .ai-bullet-icon { background: var(--accent-soft);         color: var(--primary-dark); }

/* ============================================================
   CLINICAL CONTEXT CARD (.ctx-*)
   Shared patient clinical-context pattern used by doctor_chat,
   doctor_paciente_perfil y doctor_consulta.
   Compone: mini-card identidad, secciones, chips, listas, timeline,
   permisos, accesos rápidos, signos vitales compactos.
   ============================================================ */

.ctx-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-18);
}

.ctx-patient {
  text-align: center;
  padding: var(--space-16) var(--space-8);
  background: linear-gradient(135deg, var(--sky-soft) 0%, var(--card) 100%);
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
}
.ctx-patient-avatar {
  width: 96px;
  height: 96px;
  margin: 0 auto var(--space-12);
  font-size: var(--font-xl);
  border: none;
}
.ctx-patient-name {
  margin: 0;
  font-size: var(--font-sm);
  font-weight: var(--fw-bold);
  color: var(--primary-dark);
}
.ctx-patient-meta {
  font-size: var(--font-xs);
  color: var(--text-secondary);
  margin-top: 2px;
}
.ctx-patient-cta {
  display: inline-block;
  margin-top: var(--space-12);
  font-size: var(--font-xs);
  font-weight: var(--fw-bold);
  color: var(--primary);
  text-decoration: none;
  padding: var(--space-6) var(--space-12);
  border-radius: var(--radius-sm);
  background: var(--card);
  border: 1px solid var(--border);
  transition: all 0.15s;
}
.ctx-patient-cta:hover {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--white);
}

.ctx-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

/* Quick actions row: 3 iconos lado a lado con tooltips.
   Usado en la ficha del paciente (BEPPFichaPaciente). */
.ctx-actions--icons {
  flex-direction: row;
  gap: var(--space-8);
}
.ctx-icon-btn {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding: 0;
  border-radius: var(--radius-md);
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
  text-decoration: none;
}
.ctx-icon-btn:hover {
  background: var(--primary-alpha-10);
  border-color: var(--primary-alpha-30);
  color: var(--primary);
}
.ctx-icon-btn:active { transform: scale(0.97); }
.ctx-icon-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* Chip "+N" para truncación con tooltip listando los restantes.
   Neutral en color, distingue por punteado para sugerir interactividad. */
.ctx-chip--more {
  background: transparent;
  color: var(--text-secondary);
  border: 1px dashed var(--border);
  cursor: help;
}
.ctx-chip--more:hover {
  background: var(--surface);
  color: var(--text);
}

/* Estado vacío de una sección clínica — chip neutro y tenue. */
.ctx-chip--empty {
  background: transparent;
  color: var(--text-tertiary);
  font-weight: var(--fw-regular);
  font-style: italic;
  padding-inline: 0;
}

/* Chip que combina texto + bepp-badge embebido (ej. "IMC 25.9 [Normal]"). */
.ctx-chip--with-badge {
  gap: var(--space-6);
}
.ctx-chip--with-badge .bepp-badge {
  margin-left: var(--space-2);
}

/* Variant compact: ficha sin scroll interno. Reemplaza .sidebar-left--has-cta. */
.sidebar-left--compact {
  overflow: visible;
}

/* ============================================
   FICHA COLLAPSE — toggle compartido consulta/perfil
   El sidebar (`.sidebar-left`) y todo lo offseteado por
   `--sidebar-width` (main-content, action-bar-sticky,
   breadcrumb) reflowa en sincronía vía transición del
   token. Estado vive en `html[data-ficha="collapsed"]`,
   persistido por `js/doctor-ficha-paciente.js`.
   ============================================ */
.sidebar-left,
.main-content,
.action-bar-sticky,
.bepp-breadcrumb:has(+ .app) {
  transition: width var(--duration-base, 250ms) var(--ease-out, ease),
              margin-left var(--duration-base, 250ms) var(--ease-out, ease),
              max-width var(--duration-base, 250ms) var(--ease-out, ease),
              left var(--duration-base, 250ms) var(--ease-out, ease),
              padding-left var(--duration-base, 250ms) var(--ease-out, ease);
}

/* Botón pegado al borde derecho del sidebar; viaja con `--sidebar-width`.
   Cuando se colapsa, queda anclado al borde izquierdo del viewport como
   un handle "abrir ficha". */
.ficha-toggle {
  position: fixed;
  top: calc(var(--header-height, 64px) + var(--space-12));
  /* Cabalga el borde derecho del sidebar cuando está abierto (translateX -50%
     pone su centro sobre el edge). Cuando colapsa, `max()` evita que se vaya
     off-screen — fuerza un mínimo de 12px (la mitad de su ancho) para que el
     botón entero quede visible al borde izquierdo del viewport. */
  left: max(12px, var(--sidebar-width, 300px));
  transform: translateX(-50%);
  z-index: 110;
  width: 24px;
  height: 36px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--card);
  color: var(--text-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: left var(--duration-base, 250ms) var(--ease-out, ease),
              background var(--duration-fast, 150ms) var(--ease-out, ease),
              color var(--duration-fast, 150ms) var(--ease-out, ease),
              box-shadow var(--duration-fast, 150ms) var(--ease-out, ease);
}
.ficha-toggle:hover {
  background: var(--surface-alt, var(--card));
  color: var(--text);
  box-shadow: var(--shadow-md);
}
.ficha-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.ficha-toggle .icon {
  width: 14px;
  height: 14px;
  transition: transform var(--duration-base, 250ms) var(--ease-out, ease);
}
html[data-ficha="collapsed"] .ficha-toggle .icon {
  transform: rotate(180deg);
}

/* Colapso solo aplica desde tablet en adelante.
   Mobile (≤640px) ya re-acomoda el sidebar como strip horizontal. */
@media (min-width: 641px) {
  html[data-ficha="collapsed"] {
    --sidebar-width: 0px;
  }
  html[data-ficha="collapsed"] .sidebar-left {
    width: 0;
    padding-left: 0;
    padding-right: 0;
    border-right-width: 0;
    overflow: hidden;
    pointer-events: none;
  }
  html[data-ficha="collapsed"] .sidebar-left > * {
    opacity: 0;
    transition: opacity var(--duration-fast, 150ms) var(--ease-out, ease);
  }
  html[data-ficha="collapsed"] .main-content {
    margin-left: 0;
    max-width: 100vw;
  }
  html[data-ficha="collapsed"] .action-bar-sticky {
    left: 0;
  }
  html[data-ficha="collapsed"] .bepp-breadcrumb:has(+ .app) {
    padding-left: var(--space-24);
  }
}

/* Mobile: ocultar toggle — el sidebar ahí es strip/sticky, colapsar no aplica. */
@media (max-width: 640px) {
  .ficha-toggle { display: none; }
}

.ctx-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}
.ctx-section-title {
  font-size: var(--font-xs);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  color: var(--text-secondary);
  margin: 0;
}

.ctx-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
}
.ctx-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-10);
  border-radius: var(--radius-full);
  background: var(--border-light);
  color: var(--text);
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
}
/* ─── Paleta clínica canónica ────────────────────────────
   Alergias  = rojo   (danger)
   Diagnósticos = ámbar (warning)
   Medicamentos = azul  (info)
   Aplica en ctx-chip, ai-chip y cualquier badge clínico. */
.ctx-chip--danger,
.ctx-chip--alergia {
  background: var(--status-danger-soft);
  color: var(--status-danger-strong);
}
.ctx-chip--warning,
.ctx-chip--dx {
  background: var(--status-warning-soft);
  color: var(--status-warning-strong);
}
.ctx-chip--info,
.ctx-chip--med {
  background: var(--status-info-soft);
  color: var(--status-info-strong);
}

/* === Alergia chip canónico (cross-app) ===
   Alergia = peligro, siempre rojo. Reusable en lectura, perfil paciente,
   contexto sidebar, etc. Mismos tokens que ctx-chip--danger. */
.bepp-alergia-chip,
.lectura-alergia-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-10);
  border-radius: var(--radius-full);
  background: var(--status-danger-soft);
  color: var(--status-danger-strong);
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  line-height: 1.2;
}
.bepp-alergia-chip .icon,
.lectura-alergia-chip .icon { color: var(--status-danger); }

.ctx-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}
.ctx-list li {
  display: flex;
  gap: var(--space-10);
  align-items: flex-start;
  padding: var(--space-8) var(--space-10);
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
}
.ctx-list-icon {
  color: var(--primary);
  margin-top: 2px;
  flex-shrink: 0;
}
.ctx-list-icon--med { color: var(--status-info-strong); }
.ctx-list-title {
  font-size: var(--font-xs);
  font-weight: var(--fw-bold);
  color: var(--primary-dark);
}
.ctx-list-meta {
  font-size: var(--font-xs);
  color: var(--text-secondary);
  margin-top: 2px;
}
.ctx-tag-new {
  display: inline-block;
  margin-left: 4px;
  padding: 1px 6px;
  font-size: var(--font-3xs);
  font-weight: var(--fw-bold);
  background: var(--accent);
  color: var(--primary-dark);
  border-radius: var(--radius-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

.ctx-timeline {
  display: flex;
  flex-direction: column;
  gap: var(--space-10);
  position: relative;
  padding-left: var(--space-16);
}
.ctx-timeline::before {
  content: '';
  position: absolute;
  left: 5px;
  top: 6px;
  bottom: 6px;
  width: 2px;
  background: var(--border);
}
.ctx-timeline-item {
  display: flex;
  gap: var(--space-10);
  position: relative;
}
.ctx-timeline-dot {
  position: absolute;
  left: -14px;
  top: 4px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--card);
  border: 2px solid var(--primary);
}
.ctx-timeline-dot--next {
  border-color: var(--accent);
  background: var(--accent);
}

.ctx-permission {
  display: flex;
  align-items: center;
  gap: var(--space-10);
  padding: var(--space-10);
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
}
.ctx-permission > div { flex: 1; min-width: 0; }
.ctx-permission .icon { color: var(--primary); flex-shrink: 0; }
.ctx-permission--pending .icon { color: var(--status-warning-strong); }

.ctx-quick {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-8);
}
.ctx-quick-item {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-10);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  color: var(--text);
  text-decoration: none;
  transition: all 0.15s;
}
.ctx-quick-item:hover {
  border-color: var(--primary-light);
  background: var(--sky-soft);
  color: var(--primary);
}
.ctx-quick-item .icon { color: var(--primary); flex-shrink: 0; }

/* Vitals — compact value/unit grid using the ctx-list visual language */
.ctx-vitals {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.ctx-vitals li {
  display: flex;
  align-items: center;
  gap: var(--space-10);
  padding: var(--space-6) var(--space-10);
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
}
.ctx-vitals .ctx-list-icon { margin-top: 0; }
.ctx-vital-label {
  flex: 1;
  font-size: var(--font-xs);
  color: var(--text-secondary);
}
.ctx-vital-value {
  font-size: var(--font-xs);
  font-weight: var(--fw-bold);
  color: var(--primary-dark);
}
.ctx-vital-unit {
  font-size: var(--font-3xs);
  color: var(--text-secondary);
  font-weight: var(--fw-semibold);
  margin-left: 2px;
}

/* Notas internas — editable inline en sidebar */
.ctx-notes {
  width: 100%;
  min-height: 72px;
  padding: var(--space-10);
  font-family: inherit;
  font-size: var(--font-xs);
  color: var(--text);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  resize: vertical;
  transition: border-color 0.15s, background 0.15s;
}
.ctx-notes:focus {
  outline: none;
  border-color: var(--primary-light);
  background: var(--card);
}

/* Accordion-style section (para "Nuevos vitales") */
.ctx-accordion-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-8) var(--space-10);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  user-select: none;
  transition: background 150ms var(--ease-out, ease), border-color 150ms var(--ease-out, ease);
}
.ctx-accordion-header:hover {
  background: var(--primary-alpha-04);
  border-color: var(--primary);
}
.ctx-accordion-header .ctx-section-title { flex: 1; }
.ctx-accordion-chevron {
  transition: transform 0.2s;
  color: var(--text-secondary);
}
.ctx-accordion-header[aria-expanded="true"] .ctx-accordion-chevron { transform: rotate(180deg); }
.ctx-accordion-body {
  padding: var(--space-10) 0 0;
  display: none;
}
.ctx-accordion-body.is-open { display: block; }
.ctx-accordion-tag {
  font-size: var(--font-3xs);
  font-weight: var(--fw-bold);
  color: var(--primary);
  background: var(--sky-soft);
  padding: 2px var(--space-6);
  border-radius: var(--radius-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

/* Mobile: compact the sidebar context stack */
@media (max-width: 768px) {
  .ctx-stack { gap: var(--space-14); }
  .ctx-quick { grid-template-columns: 1fr; }
}

/* ============================================= */
/* ===== DM CHANNEL — status pill + horario ===== */
/* Shared widget para el canal de chat con pacientes.
   Se usa en doctor_home (widget DMs) y doctor_perfil_medico
   (chat con pacientes). Mantener el mismo markup y JS (bepp_dm_config). */
/* ============================================= */
.dm-status-bar {
  padding: var(--space-12) var(--space-20);
  background: var(--bg);
  border-bottom: var(--space-1) solid var(--border-light);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-10);
  flex-wrap: wrap;
}

.dm-status-pill {
  font-size: var(--font-xs);
  font-weight: var(--fw-bold);
  padding: var(--space-4) var(--space-10);
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.dm-status-pill.active { background: var(--status-success-soft); color: var(--status-success-strong); }
.dm-status-pill.muted  { background: var(--status-danger-soft); color: var(--danger); }
.dm-status-pill.scheduled { background: var(--status-warning-soft); color: var(--status-warning-strong); cursor: pointer; }

.dm-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}

/* Trigger de luna + hover menu para cambiar modo del canal */
.dm-mode-trigger {
  position: relative;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--text-secondary);
  transition: background 0.15s, color 0.15s;
}

.dm-mode-trigger:hover,
.dm-mode-trigger:focus-within {
  background: var(--border-light);
  color: var(--primary);
  outline: none;
}

.dm-mode-menu {
  position: absolute;
  top: calc(100% + var(--space-4));
  right: 0;
  background: var(--card);
  border: var(--space-1) solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 160px;
  opacity: 0;
  transform: translateY(calc(-1 * var(--space-4)));
  pointer-events: none;
  transition: opacity 0.15s, transform 0.15s;
  z-index: 50;
}

.dm-mode-trigger:hover .dm-mode-menu,
.dm-mode-trigger:focus-within .dm-mode-menu {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.dm-mode-option {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-6) var(--space-10);
  font-size: var(--font-xs);
  font-weight: var(--fw-semibold);
  color: var(--text);
  background: transparent;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: background 0.15s, color 0.15s;
}

.dm-mode-option:hover { background: var(--border-light); }

.dm-mode-option.active {
  background: var(--primary);
  color: var(--white);
}

/* Puente invisible entre el icono luna y el menú: cubre el gap de 4px
   para que al bajar el cursor al menú, el hover no se rompa. */
.dm-mode-trigger::after {
  content: '';
  position: absolute;
  top: 100%;
  right: 0;
  width: 160px;
  height: var(--space-6);
}

.dm-schedule-panel {
  padding: var(--space-12) var(--space-20);
  background: var(--status-warning-soft);
  border-bottom: var(--space-1) solid var(--status-warning-soft);
  font-size: var(--font-xs);
  display: none;
}

.dm-schedule-panel.open { display: block; }

.dm-schedule-subtitle {
  font-size: var(--font-xs);
  color: var(--text-secondary);
  margin-top: var(--space-2);
}

.dm-schedule-row {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  margin-top: var(--space-6);
}

.dm-schedule-row label { color: var(--text-secondary); font-size: var(--font-xs); }

.dm-time-input {
  padding: var(--space-4) var(--space-8);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: inherit;
  font-size: var(--font-xs);
}

.dm-days {
  display: flex;
  gap: var(--space-4);
  margin-top: var(--space-6);
}

.dm-day {
  width: 26px;
  height: 26px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--card);
  font-size: var(--font-xs);
  font-weight: var(--fw-bold);
  cursor: pointer;
  font-family: inherit;
  color: var(--text-secondary);
  transition: border-color 150ms var(--ease-out, ease), color 150ms var(--ease-out, ease);
}

.dm-day:not(.active):hover {
  border-color: var(--primary);
  color: var(--primary);
}

.dm-day.active {
  background: var(--primary);
  color: var(--white);
  border-color: var(--primary);
}

.dm-schedule-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: var(--space-10);
}

.dm-schedule-save-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-6) var(--space-12);
  border-radius: 6px;
  border: 1px solid var(--primary);
  background: var(--primary);
  color: var(--white);
  font-family: inherit;
  font-size: var(--font-xs);
  font-weight: var(--fw-bold);
  cursor: pointer;
  transition: filter 0.15s ease;
}

.dm-schedule-save-btn:hover { filter: brightness(1.05); }
/* ============================================================
   GLOBAL PRIMITIVES — BANNER / EMPTY STATE / SKELETON
   Memoria: maximum global, minimum local. Estos componentes
   se consumen desde cualquier pantalla del app paciente.
   ============================================================ */

/* ===== BANNER (notification) =====
   Stack en TOP, fixed. Respeta safe-area-inset-top (notch).
   Variantes por tipo: success/info/warning/error.
   API JS: BeppBanner.show({type,title,message,action,duration}).
   Coexiste con .bepp-toast (single-line bottom confirmation existente). */
.bepp-banner-stack {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + var(--space-12));
  left: 50%;
  transform: translateX(-50%);
  width: min(440px, calc(100% - var(--space-24) * 2));
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  z-index: 9999;
  pointer-events: none;
}

.bepp-banner {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: var(--space-12);
  padding: var(--space-12) var(--space-14);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  opacity: 0;
  transform: translateY(-110%) scale(0.96);
  transition: opacity var(--duration-base) var(--ease-out),
              transform var(--duration-spring) var(--spring-snap);
  will-change: transform, opacity;
}

.bepp-banner.is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.bepp-banner.is-leaving {
  opacity: 0;
  transform: translateY(-120%) scale(0.96);
}

.bepp-banner__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-full);
  flex-shrink: 0;
  background: var(--gray-100);
  color: var(--text-secondary);
}
.bepp-banner__icon .icon {
  width: 18px;
  height: 18px;
}

.bepp-banner__body {
  flex: 1;
  min-width: 0;
}
.bepp-banner__title {
  font-size: var(--font-sm);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  color: var(--text);
}
.bepp-banner__msg {
  font-size: var(--font-xs);
  line-height: var(--lh-normal);
  color: var(--text-secondary);
  margin-top: var(--space-2);
}

.bepp-banner__action {
  appearance: none;
  border: 0;
  background: transparent;
  font-family: inherit;
  font-size: var(--font-sm);
  font-weight: var(--fw-semibold);
  color: var(--primary);
  padding: var(--space-4) var(--space-8);
  margin: calc(var(--space-4) * -1) calc(var(--space-4) * -1) calc(var(--space-4) * -1) 0;
  cursor: pointer;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
  transition: background var(--duration-fast) var(--ease-out);
}
@media (hover: hover) {
  .bepp-banner__action:hover { background: var(--primary-alpha-08); }
}

/* Variantes */
.bepp-banner--success .bepp-banner__icon { background: var(--status-success-soft); color: var(--status-success-strong); }
.bepp-banner--info    .bepp-banner__icon { background: var(--status-info-soft);    color: var(--status-info-strong); }
.bepp-banner--warning .bepp-banner__icon { background: var(--status-warning-soft); color: var(--status-warning-strong); }
.bepp-banner--error   .bepp-banner__icon { background: var(--status-danger-soft);  color: var(--status-danger-strong); }

.bepp-banner--success { border-color: var(--status-success-soft); }
.bepp-banner--info    { border-color: var(--status-info-soft); }
.bepp-banner--warning { border-color: var(--status-warning-soft); }
.bepp-banner--error   { border-color: var(--status-danger-soft); }

/* ===== EMPTY STATE =====
   Componente unificado para "sin datos". Variantes:
     base       — bloque dentro de card
     .is-screen — toma toda la pantalla (vh - dock)
     .is-compact — versión chiquita para inline */
.bepp-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--space-32) var(--space-20);
  gap: var(--space-12);
}

.bepp-empty__illus {
  width: 72px;
  height: 72px;
  border-radius: var(--radius-full);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--sky-soft);
  color: var(--primary);
  margin-bottom: var(--space-4);
}
.bepp-empty__illus .icon {
  width: 32px;
  height: 32px;
}

.bepp-empty__title {
  font-size: var(--font-md);
  font-weight: var(--fw-semibold);
  color: var(--text);
  line-height: var(--lh-snug);
}

.bepp-empty__msg {
  font-size: var(--font-sm);
  color: var(--text-secondary);
  line-height: var(--lh-normal);
  max-width: 36ch;
}

.bepp-empty__actions {
  display: flex;
  gap: var(--space-8);
  margin-top: var(--space-8);
  flex-wrap: wrap;
  justify-content: center;
}

.bepp-empty.is-screen {
  min-height: calc(100vh - 220px);
  justify-content: center;
}

.bepp-empty.is-compact {
  padding: var(--space-16) var(--space-12);
  gap: var(--space-8);
}
.bepp-empty.is-compact .bepp-empty__illus {
  width: 48px;
  height: 48px;
}
.bepp-empty.is-compact .bepp-empty__illus .icon {
  width: 22px;
  height: 22px;
}
.bepp-empty.is-compact .bepp-empty__title { font-size: var(--font-sm); }
.bepp-empty.is-compact .bepp-empty__msg   { font-size: var(--font-xs); }

/* Tints alternativos */
.bepp-empty--accent .bepp-empty__illus { background: var(--accent-alpha-15); color: var(--accent-hover); }
.bepp-empty--neutral .bepp-empty__illus { background: var(--gray-100); color: var(--text-secondary); }

/* ===== SKELETON =====
   Reusa la animación .shimmer (ya existente en animations.css).
   Composición: combina .bepp-skel-line + .bepp-skel-circle dentro
   de helpers .bepp-skel-card-* segun la card que estés simulando. */
.bepp-skel {
  background: linear-gradient(
    90deg,
    var(--gray-100) 0%,
    var(--gray-200) 50%,
    var(--gray-100) 100%
  );
  background-size: 200% 100%;
  animation: bepp-shimmer 1.8s linear infinite;
  border-radius: var(--radius-sm);
}

.bepp-skel-line {
  height: 12px;
  width: 100%;
  border-radius: var(--radius-xs);
}
.bepp-skel-line--sm { height: 10px; width: 50%; }
.bepp-skel-line--lg { height: 16px; width: 70%; }
.bepp-skel-line--title { height: 18px; width: 60%; }

.bepp-skel-circle {
  border-radius: var(--radius-full);
  width: 40px;
  height: 40px;
  flex-shrink: 0;
}
.bepp-skel-circle--lg { width: 56px; height: 56px; }
.bepp-skel-circle--sm { width: 28px; height: 28px; }

.bepp-skel-block {
  border-radius: var(--radius-md);
  width: 100%;
  height: 80px;
}

/* Helpers de cards comunes (cita / receta / estudio / producto) */
.bepp-skel-card {
  display: flex;
  align-items: flex-start;
  gap: var(--space-12);
  padding: var(--space-16);
  background: var(--card);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
}
.bepp-skel-card__main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

/* =====================================================================
   Atributo [hidden] siempre gana sobre reglas de autor.
   Sin esto, selectores con display:flex/grid de mayor especificidad
   anulan al atributo y dejan elementos zombi visibles en el DOM.
   ===================================================================== */
[hidden] { display: none !important; }

/* =====================================================================
   BEPP TOUR — spotlight onboarding overlay
   Uso: window.BeppTour.start([{selector,title,body,side}], {id:'home-welcome'})
   Vive en js/bepp-tour.js. Inyecta su DOM en body al primer start().
   ===================================================================== */
.bepp-tour-root {
  position: fixed;
  inset: 0;
  z-index: 2000000;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--duration-base, 250ms) var(--ease-out, ease),
              visibility var(--duration-base, 250ms) var(--ease-out, ease);
}
.bepp-tour-root.is-visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
.bepp-tour-scrim {
  position: absolute;
  inset: 0;
  background: transparent;
  /* Default: transparente. El dark cover lo provee el box-shadow del spot
     (evita doble-dark que dimeaba al elemento highlighted). */
  cursor: pointer;
}
/* Cuando NO hay spot (centered coachmark con selector:null), el scrim
   debe darle dark al fondo, ya que el spot está oculto. */
.bepp-tour-root.no-spot .bepp-tour-scrim {
  background: rgba(13, 43, 62, 0.65);
}
.bepp-tour-spot {
  position: fixed;
  border-radius: var(--radius-md);
  pointer-events: none;
  opacity: 0;
  /* box-shadow gigante = scrim oscuro alrededor del target. No usa el
     token --overlay-backdrop (0.38 alpha = muy claro para spotlight); aquí
     necesitamos contraste fuerte entre área highlighted y el resto. */
  box-shadow: 0 0 0 9999px rgba(13, 43, 62, 0.65),
              0 0 0 2px var(--accent),
              0 0 24px 4px var(--accent-alpha-30);
  transition: top var(--duration-base, 250ms) var(--ease-out, ease),
              left var(--duration-base, 250ms) var(--ease-out, ease),
              width var(--duration-base, 250ms) var(--ease-out, ease),
              height var(--duration-base, 250ms) var(--ease-out, ease),
              opacity var(--duration-fast, 150ms) ease;
}
.bepp-tour-bubble {
  position: fixed;
  width: 320px;
  max-width: calc(100vw - 24px);
  background: var(--card);
  color: var(--text);
  border-radius: var(--radius-lg);
  padding: var(--space-20);
  box-shadow: 0 12px 32px rgba(13, 43, 62, 0.18);
  transition: top var(--duration-base, 250ms) var(--ease-out, ease),
              left var(--duration-base, 250ms) var(--ease-out, ease);
}
.bepp-tour-arrow {
  position: absolute;
  width: 16px;
  height: 16px;
  background: var(--card);
  transform: rotate(45deg);
}
.bepp-tour-progress {
  font-size: var(--font-xs);
  color: var(--text-secondary);
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  margin-bottom: var(--space-6);
}
.bepp-tour-title {
  font-size: var(--font-md);
  font-weight: 700;
  color: var(--text);
  margin: 0 0 var(--space-8) 0;
  line-height: 1.3;
}
.bepp-tour-body {
  font-size: var(--font-sm);
  color: var(--text-secondary);
  line-height: 1.45;
  margin-bottom: var(--space-16);
}
.bepp-tour-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
}
.bepp-tour-actions-right {
  display: flex;
  gap: var(--space-8);
  align-items: center;
}
.bepp-tour-btn {
  border: none;
  background: transparent;
  font-family: inherit;
  font-size: var(--font-sm);
  font-weight: 600;
  padding: var(--space-8) var(--space-14);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--duration-fast, 150ms) ease,
              color var(--duration-fast, 150ms) ease;
}
.bepp-tour-btn--ghost {
  color: var(--text-secondary);
}
.bepp-tour-btn--ghost:hover {
  background: var(--primary-alpha-06);
  color: var(--text);
}
.bepp-tour-btn--primary {
  background: var(--primary);
  color: var(--white);
}
.bepp-tour-btn--primary:hover {
  background: var(--primary-dark);
}

/* ============================================
   Autocomplete (BeppAutocomplete) — predictive
   autofill panel para inputs con catálogos.
   Markup: <input data-autocomplete="catalog:cie10">
   ============================================ */
.bepp-ac-panel {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px var(--shadow-md, var(--primary-alpha-10));
  max-height: 320px;
  overflow-y: auto;
  padding: var(--space-4);
  font-size: var(--font-sm);
}
.bepp-ac-panel[hidden] { display: none; }
.bepp-ac-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  padding: var(--space-8) var(--space-10);
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text);
  line-height: 1.35;
}
.bepp-ac-item:hover,
.bepp-ac-item.is-active {
  background: var(--primary-alpha-08, var(--surface));
  color: var(--primary-dark, var(--text));
}
.bepp-ac-item-label {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bepp-ac-item-label mark {
  background: var(--primary-alpha-20, transparent);
  color: inherit;
  font-weight: var(--fw-semibold);
  padding: 0;
}
.bepp-ac-item-meta {
  font-size: var(--font-xs);
  color: var(--text-light);
  font-variant-numeric: tabular-nums;
}
.bepp-ac-empty {
  padding: var(--space-10) var(--space-12);
  font-size: var(--font-xs);
  color: var(--text-light);
  font-style: italic;
}

/* ===================================================================
   Form invalid state (aria-invalid="true")
   =================================================================== */
.form-control[aria-invalid="true"],
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"] {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px var(--danger-alpha-15);
}
.form-control[aria-invalid="true"]:focus,
input[aria-invalid="true"]:focus,
select[aria-invalid="true"]:focus,
textarea[aria-invalid="true"]:focus {
  outline: none;
  border-color: var(--danger);
  box-shadow: 0 0 0 3px var(--danger-alpha-15);
}

/* ===================================================================
   D1 — Tabular numerals on numeric surfaces (KPIs, tables, times)
   Locks digit width so numbers don't dance when values change.
   =================================================================== */
.stats-kpi-value,
.stats-kpi-delta,
.balance-kpi,
.welcome-chip-value,
.embajador-hero-amount,
.embajador-kpi-value,
.embajador-hero-amount-cents,
.receta-amount,
.receta-paper-folio-value,
.bepp-table td.is-num,
.bepp-table .pacientes-col-meta,
.timestamp,
time,
.dm-time,
.inbox-time,
.agenda-event-time,
.review-stars,
.reviews-summary-card-meta strong,
.reviews-dist-count,
.bepp-badge--count,
.badge-count-red,
.badge-count {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}

/* ===================================================================
   D2 — Tracking-caps on uppercase labels
   Applied via class .label-caps OR auto on common label hooks.
   =================================================================== */
.label-caps,
.stats-kpi-label,
.embajador-kpi-label,
.receta-section-label,
.receta-paper-section-label,
.welcome-chip-label,
.pane-title,
.vacuna-stat-label,
.vacuna-table th {
  letter-spacing: var(--tracking-caps);
}

/* ===================================================================
   D3 — Medium-weight (500) baseline for nav-like UI
   Reserves bold (700) for headlines + KPIs only.
   =================================================================== */
.nav-item,
.tab-btn,
.bepp-table thead th,
.pacientes-chip,
.inbox-tab,
.consultorio-option,
.action-option-title,
.bepp-breadcrumb__item:not(.is-current),
.consulta-tab-btn {
  font-weight: var(--fw-medium);
}

/* ===================================================================
   D5 — Ghost/outline variant for non-dominant CTAs
   Use to demote secondary buttons that were primary-blue solid.
   =================================================================== */
.btn-ghost,
.btn.is-ghost {
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid var(--border);
  font-weight: var(--fw-medium);
  transition: background var(--duration-quick, 150ms) var(--ease-out, ease),
              color var(--duration-quick, 150ms) var(--ease-out, ease),
              border-color var(--duration-quick, 150ms) var(--ease-out, ease);
}
.btn-ghost:hover,
.btn.is-ghost:hover {
  background: var(--surface-alt);
  color: var(--text);
  border-color: var(--border-strong, var(--border));
}

/* ===================================================================
   C7 — Theme + density + fontScale infrastructure
   Set via JS on <html> via:
     data-theme="light|dark|auto"
     data-density="comfortable|compact"
     data-font-scale="0.9|1|1.1|1.25"
   Tokens cascade into existing variables — no per-page changes needed.
   =================================================================== */
:root {
  --font-scale: 1;
  --density-pad: 1;     /* 1 = comfortable, 0.78 = compact */
}
html[data-font-scale="0.9"]  { --font-scale: 0.9; }
html[data-font-scale="1"]    { --font-scale: 1; }
html[data-font-scale="1.1"]  { --font-scale: 1.1; }
html[data-font-scale="1.25"] { --font-scale: 1.25; }
html[data-density="compact"] { --density-pad: 0.78; }

/* Apply scale to root font-size so all rem-based tokens follow. */
html { font-size: calc(16px * var(--font-scale, 1)); }

/* Density: nudge spacing scale on common surfaces. */
html[data-density="compact"] {
  --space-12: 9px;
  --space-16: 12px;
  --space-20: 15px;
  --space-24: 18px;
}

/* Smooth focus ring baseline (Linear/Stripe-style)
   Applies to keyboard focus only (:focus-visible), pixelated outlines
   replaced with a soft box-shadow that animates in/out.
   =================================================================== */
:where(button, a, input, select, textarea, [tabindex]):focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--primary-alpha-15);
  transition: box-shadow var(--duration-quick, 150ms) var(--ease-out, ease);
  border-radius: var(--radius-sm);
}
/* Avoid double-rings on form fields that already paint focus via
   border-color + their own box-shadow. */
.form-control:focus-visible,
input.form-control:focus-visible,
select.form-control:focus-visible,
textarea.form-control:focus-visible {
  box-shadow: 0 0 0 3px var(--primary-alpha-15);
}

/* =====================================================================
   BEPP CMDK — Command palette (Linear/Raycast style, doctor app)
   Container reuses .modal-overlay so :has() body-scroll-lock applies.
   ===================================================================== */
.cmdk-overlay {
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding-top: 18vh;
  padding-left: var(--space-16);
  padding-right: var(--space-16);
  z-index: 1000;
}
.cmdk-overlay.active {
  display: flex;
}
.cmdk-panel {
  width: 100%;
  max-width: 640px;
  background: var(--card);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transform: scale(0.96);
  transition:
    opacity var(--duration-base, 250ms) var(--ease-out, ease),
    transform var(--duration-base, 250ms) var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1));
}
.cmdk-overlay.cmdk-in .cmdk-panel {
  opacity: 1;
  transform: scale(1);
}
.cmdk-input-wrap {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-14) var(--space-16);
  border-bottom: 1px solid var(--border-light);
}
.cmdk-input-wrap .cmdk-icon {
  width: 18px;
  height: 18px;
  color: var(--text-secondary);
  flex-shrink: 0;
}
.cmdk-input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  font-size: var(--font-base);
  color: var(--text);
  padding: var(--space-4) 0;
}
.cmdk-input::placeholder {
  color: var(--text-light);
}
.cmdk-list {
  max-height: 50vh;
  overflow-y: auto;
  padding: var(--space-6) 0;
}
.cmdk-section-header {
  padding: var(--space-8) var(--space-16) var(--space-4);
  font-size: var(--font-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-light);
}
.cmdk-item {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-10) var(--space-16);
  cursor: pointer;
  border-left: 3px solid transparent;
  transition: background var(--duration-fast, 150ms) var(--ease-out, ease);
}
.cmdk-item.is-selected {
  background: var(--primary-alpha-08);
  border-left-color: var(--primary);
}
.cmdk-item .cmdk-icon {
  width: 18px;
  height: 18px;
  color: var(--text-secondary);
  flex-shrink: 0;
}
.cmdk-item.is-selected .cmdk-icon {
  color: var(--primary);
}
.cmdk-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  flex-shrink: 0;
  font-size: var(--font-2xs);
}
.cmdk-item-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.cmdk-item-label {
  font-size: var(--font-sm);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cmdk-item-sub {
  font-size: var(--font-xs);
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cmdk-go-hint {
  display: inline-flex;
  gap: var(--space-3);
  flex-shrink: 0;
  opacity: 0.6;
}
.cmdk-empty {
  padding: var(--space-32) var(--space-16);
  text-align: center;
}
.cmdk-empty-title {
  font-size: var(--font-sm);
  color: var(--text);
  margin-bottom: var(--space-4);
}
.cmdk-empty-sub {
  font-size: var(--font-xs);
  color: var(--text-secondary);
}
.cmdk-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-16);
  padding: var(--space-8) var(--space-16);
  border-top: 1px solid var(--border-light);
  font-size: var(--font-2xs);
  color: var(--text-secondary);
  background: var(--primary-alpha-04);
}
.cmdk-footer span {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
}
.cmdk-kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 var(--space-4);
  font-family: inherit;
  font-size: var(--font-3xs);
  font-weight: 500;
  color: var(--text-secondary);
  background: var(--card);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-sm);
}
.cmdk-kbd--esc {
  margin-left: auto;
}

/* ===================================================================
   BEPP DATEPICKER
   Popover replacement for native <input type="date">.
   Tokens-only. Trigger button mirrors form-control sizing.
   =================================================================== */

/* Hide the native date input that we replace */
input[data-bepp-picker="1"] {
  display: none !important;
}

/* Trigger button — looks like a form-control */
.bepp-dp-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  width: 100%;
  min-height: 40px;
  padding: 0 var(--space-12);
  background: var(--card);
  color: var(--text);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
  font: inherit;
  font-size: var(--font-sm);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
  font-variant-numeric: tabular-nums;
}
.bepp-dp-trigger.is-empty .bepp-dp-trigger-label {
  color: var(--text-light);
}
.bepp-dp-trigger:hover:not(:disabled) {
  border-color: var(--primary-alpha-15);
}
.bepp-dp-trigger[aria-expanded="true"] {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-alpha-15);
}
.bepp-dp-trigger:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.bepp-dp-trigger-label {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bepp-dp-trigger-icon {
  width: 16px; height: 16px;
  flex: 0 0 auto;
  color: var(--text-secondary);
}

/* Popover */
.bepp-dp-popover {
  position: absolute;
  z-index: 1000050;
  width: 300px;
  background: var(--card);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: var(--space-8);
  font-size: var(--font-sm);
  color: var(--text);
  font-variant-numeric: tabular-nums;
  animation: beppDpIn var(--duration-base) var(--ease-spring, var(--ease-out));
  transform-origin: top left;
}
.bepp-dp-popover.no-anim { animation: none; }
@keyframes beppDpIn {
  from { opacity: 0; transform: translateY(-4px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .bepp-dp-popover { animation: none; }
}

/* Presets row */
.bepp-dp-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: var(--space-8);
}
.bepp-dp-preset {
  flex: 1 1 auto;
  min-width: 0;
  padding: 6px 8px;
  font-size: var(--font-xs);
  background: var(--primary-alpha-04);
  color: var(--text-secondary);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.bepp-dp-preset:hover {
  background: var(--primary-alpha-08);
  color: var(--primary);
}

/* Header */
.bepp-dp-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  margin-bottom: 6px;
}
.bepp-dp-title {
  flex: 1 1 auto;
  padding: 6px 8px;
  background: transparent;
  border: 0;
  border-radius: var(--radius-md);
  font-weight: 600;
  font-size: var(--font-sm);
  color: var(--text);
  cursor: pointer;
  text-transform: capitalize;
  transition: background var(--duration-fast) var(--ease-out);
}
.bepp-dp-title:hover { background: var(--primary-alpha-06); color: var(--primary); }
.bepp-dp-nav {
  flex: 0 0 auto;
  width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent;
  border: 0;
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.bepp-dp-nav svg { width: 14px; height: 14px; }
.bepp-dp-nav:hover { background: var(--primary-alpha-06); color: var(--primary); }

/* Day-of-week header */
.bepp-dp-dow {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  margin-bottom: 4px;
}
.bepp-dp-dow span {
  text-align: center;
  font-size: var(--font-xs);
  color: var(--text-light);
  font-weight: 500;
  padding: 4px 0;
}

/* Day grid */
.bepp-dp-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}
.bepp-dp-day {
  width: 36px; height: 36px;
  margin: 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--text);
  border: 0;
  border-radius: var(--radius-md);
  font-size: var(--font-sm);
  cursor: pointer;
  font-variant-numeric: tabular-nums;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.bepp-dp-day.is-out { color: var(--text-light); }
.bepp-dp-day.is-disabled { color: var(--text-light); cursor: not-allowed; opacity: 0.45; }
.bepp-dp-day:hover:not(.is-disabled):not(.is-selected) {
  background: var(--primary-alpha-08);
  color: var(--primary);
}
.bepp-dp-day.is-today:not(.is-selected) {
  box-shadow: inset 0 0 0 1.5px var(--primary);
  color: var(--primary);
}
.bepp-dp-day.is-in-range {
  background: var(--primary-alpha-08);
  color: var(--primary);
  border-radius: 0;
}
.bepp-dp-day.is-selected {
  background: var(--primary);
  color: var(--white);
  box-shadow: none;
}
.bepp-dp-day.is-range-start { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.bepp-dp-day.is-range-end   { border-top-left-radius: 0;  border-bottom-left-radius: 0; }

/* Months grid */
.bepp-dp-months,
.bepp-dp-years {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  padding: 4px 0;
}
.bepp-dp-month,
.bepp-dp-year {
  padding: 12px 0;
  background: transparent;
  border: 0;
  border-radius: var(--radius-md);
  color: var(--text);
  cursor: pointer;
  font-size: var(--font-sm);
  text-transform: capitalize;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.bepp-dp-month:hover,
.bepp-dp-year:hover {
  background: var(--primary-alpha-08);
  color: var(--primary);
}
.bepp-dp-month.is-selected,
.bepp-dp-year.is-selected {
  background: var(--primary);
  color: var(--white);
}

/* Footer */
.bepp-dp-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  margin-top: var(--space-8);
  padding-top: var(--space-8);
  border-top: 1px solid var(--border-light);
  font-size: var(--font-xs);
}
.bepp-dp-summary {
  flex: 1 1 auto;
  color: var(--text-secondary);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bepp-dp-summary strong { color: var(--text); font-weight: 600; }
.bepp-dp-summary-muted { color: var(--text-light); }
.bepp-dp-clear {
  flex: 0 0 auto;
  padding: 4px 10px;
  background: transparent;
  border: 0;
  color: var(--text-secondary);
  font-size: var(--font-xs);
  cursor: pointer;
  border-radius: var(--radius-md);
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.bepp-dp-clear:hover { background: var(--primary-alpha-08); color: var(--primary); }

/* ===================================================================
   BEPP UNDO STACK — bottom-right vertical stack of undo toasts
   =================================================================== */
.bepp-undo-stack {
  position: fixed;
  right: var(--space-20);
  bottom: calc(var(--space-20) + env(safe-area-inset-bottom, 0px));
  z-index: 1000003;
  display: flex;
  flex-direction: column-reverse;
  gap: var(--space-8);
  pointer-events: none;
}
.bepp-undo-stack .bepp-undo-toast {
  position: relative;
  left: auto;
  bottom: auto;
  transform: translateY(140%);
  pointer-events: auto;
}
.bepp-undo-stack .bepp-undo-toast.is-visible {
  transform: translateY(0);
}

/* ===================================================================
   THEME — DARK (global tokens)
   Las pantallas de auth/index del doctor NO cargan _doctor_header.css,
   así que los overrides de tokens de dark mode viven aquí también.
   Mantener sincronizado con el bloque idéntico en _doctor_header.css.
   =================================================================== */
html[data-theme="dark"] {
  --bg: #0e1620;
  --bg-deep: #0a1219;
  --surface: #131c27;
  --surface-alt: #1a2533;
  --card: #1a2533;
  --text: #e8eef4;
  --text-secondary: #a8b5c4;
  --text-light: #6e7d8d;
  --border: #2b3848;
  --border-light: #243040;
  --primary: #4fa3d8;
  --primary-light: #6fb3e0;
  --primary-dark: #2a7bb5;
  --primary-soft: #1a4660;
  --primary-alpha-04: rgba(79, 163, 216, 0.06);
  --primary-alpha-06: rgba(79, 163, 216, 0.10);
  --primary-alpha-08: rgba(79, 163, 216, 0.14);
  --primary-alpha-12: rgba(79, 163, 216, 0.18);
  --primary-alpha-15: rgba(79, 163, 216, 0.22);
  --shadow-xs: 0 2px 8px rgba(0, 0, 0, 0.25);
  --shadow-sm: 0 4px 12px rgba(0, 0, 0, 0.28);
  --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.35);
  --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.45);
  --gray-50: #1a2533;
  --gray-100: #243040;
  --gray-200: #2b3848;
  --gray-300: #344256;
  --gray-400: #6e7d8d;
  --white-alpha-70: rgba(26, 37, 51, 0.70);
  --white-alpha-88: rgba(26, 37, 51, 0.88);
  --sky-soft: var(--primary-soft);
  /* Status tokens — pastel soft colours must invert in dark mode */
  --status-success-soft: #0d2318;
  --status-success-strong: #5dc87e;
  --status-warning-soft: #2d1f09;
  --status-warning-strong: #d97706;
  --status-danger-soft: #2d1311;
  --status-danger-strong: #e5534b;
  --status-info-soft: #0f1e2e;
  --status-info-strong: #4d8fcc;
  --danger: #e5534b;
  --success: #5dc87e;
  --warning: #f0b070;
  /* Soft / pastel palette — light-mode pastels must invert in dark */
  --accent-soft: #1e2e0a;
  --data-5: #9878d0;
  --data-5-soft: #1e1530;
  --data-5-strong: #a08de0;
  --data-1-soft: #0f1e2e;
  --data-2-soft: #0d2218;
  --data-3-soft: #2d1e0a;
  --data-4-soft: #2d1010;
  --data-6-soft: #2d1526;
  --data-7-soft: #0d2728;
  --data-8-soft: #1e1208;
  --premium-soft: #2a1f0a;
  --premium-strong: #e0b870;
  --tier-familia-strong: #a08de0;
  --primary-50: var(--primary-alpha-08);
}
html[data-theme="dark"] body { background: var(--bg); color: var(--text); }
html[data-theme="dark"] .card { background: var(--card); border-color: var(--border-light); }

/* Componentes globales con bg/color hardcodeado a --white que no cambian
   con los tokens (porque --white sigue siendo blanco en dark, intencionalmente
   para textos sobre primary/accent). Acá cambiamos bg pero NO el color. */
html[data-theme="dark"] .chip-filter {
  background: var(--card);
  border-color: var(--border);
}
html[data-theme="dark"] .chip-filter:hover {
  border-color: var(--primary);
  color: var(--primary);
}
html[data-theme="dark"] .chip-filter.active {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--white);
}
html[data-theme="dark"] .segmented-option.active {
  background: var(--surface-alt);
  color: var(--text);
}

/* card-header-btn: usado en card headers de varias pantallas del doctor.
   Vivía sólo en doctor_home.css y por eso pages/agenda/documentos/perfil_resenas
   caían al estilo default UA (gris claro). Movida a global. */
.card-header-btn {
  background: none;
  border: none;
  color: var(--text-light);
  cursor: pointer;
  font-size: var(--font-sm);
  padding: var(--space-4) var(--space-8);
  border-radius: var(--radius-xs);
  transition: background 150ms var(--ease-out), color 150ms var(--ease-out);
}
.card-header-btn:hover {
  background: var(--bg);
  color: var(--text-secondary);
}
html[data-theme="dark"] .card-header-btn:hover {
  background: var(--surface-alt);
  color: var(--text);
}

/* btn-sm.outline / btn-sm.primary: usados en migrar_dictado.html sin la clase
   .btn-outline/.btn-primary esperada. Aliases hasta arreglar el HTML. */
.btn-sm.outline {
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  cursor: pointer;
  font-family: inherit;
  font-weight: var(--fw-semibold);
}
.btn-sm.outline:hover {
  border-color: var(--primary);
  background: var(--primary-alpha-04);
  color: var(--primary);
}
.btn-sm.primary {
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
  color: var(--white);
  border: 1px solid transparent;
  cursor: pointer;
  font-family: inherit;
  font-weight: var(--fw-semibold);
}
.btn-sm.primary:hover {
  box-shadow: var(--shadow-primary);
  transform: translateY(-1px);
}

/* ===== Dark mode — overrides para componentes que hardcodean var(--white)
   --white se mantiene blanco real (intencional: texto sobre primary/accent),
   por eso estos componentes necesitan override explícito en dark.
   Detectados por tools/doctor-smoke (DARK_MODE_HEX_LEAK). =================== */

/* Familia 1 — form inputs (afecta onboarding, settings, modal cita home,
   sheet justificante, firma-pin de receta, withdrawBank de embajador) */
html[data-theme="dark"] input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]),
html[data-theme="dark"] textarea,
html[data-theme="dark"] select {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border);
}
html[data-theme="dark"] input::placeholder,
html[data-theme="dark"] textarea::placeholder {
  color: var(--text-light);
}

/* Familia 2 — botón outline (debería ser transparente, no blanco) */
html[data-theme="dark"] .btn-outline,
html[data-theme="dark"] .btn.btn-outline {
  background: transparent;
  color: var(--text);
  border-color: var(--border);
}
html[data-theme="dark"] .btn-outline:hover,
html[data-theme="dark"] .btn.btn-outline:hover {
  background: var(--surface-alt);
  border-color: var(--primary);
  color: var(--primary);
}

/* Familia 3 — settings rows */
html[data-theme="dark"] .settings-row,
html[data-theme="dark"] .settings-row--toggle,
html[data-theme="dark"] .settings-row--readonly {
  background: var(--card);
  border-color: var(--border-light);
}

/* Familia 4 — hero del dictado (consulta_dictado, paciente_dictado,
   migrar_dictado) */
html[data-theme="dark"] .dx-hero,
html[data-theme="dark"] .dx-hero.pdic-hero {
  background: var(--card);
  border-color: var(--border-light);
}

/* Familia 5 — papel de receta */
html[data-theme="dark"] .receta-paper,
html[data-theme="dark"] .receta-paper-qr-box {
  background: var(--card);
  border-color: var(--border-light);
}

/* Familia 6 — cards de migrar dictado */
html[data-theme="dark"] .mg-progress-card,
html[data-theme="dark"] .mg-queue {
  background: var(--card);
  border-color: var(--border-light);
}

/* Familia 7 — layout editor bar (home) */
html[data-theme="dark"] #layoutEditorBar {
  background: var(--card);
  border-color: var(--border-light);
}

/* Familia 8 — input withdrawBank cubierto por familia 1 (input genérico) */

/* Familia 9 — sidebar secondary CTA button + widget count badge */
html[data-theme="dark"] .btn-sidebar-cta-alt {
  background: var(--surface);
  border-color: var(--border);
}
html[data-theme="dark"] .widget-manager-count {
  background: var(--surface);
  border-color: var(--border);
}

/* Familia 10 — patient timeline cards */
html[data-theme="dark"] .patient-timeline-card {
  background: var(--card);
  border-color: var(--border);
}

/* Familia 11 — widget manager items (layout editor) */
html[data-theme="dark"] .widget-manager-item {
  background: var(--card);
}

/* Familia 12 — layout edit button */
html[data-theme="dark"] .layout-edit-btn {
  background: var(--surface);
  border-color: var(--border);
}

/* Familia 13 — empty state illustration circle
   Default variant usa --sky-soft (→ dark: --primary-soft #1a4660) como fondo
   e icono --primary (#4fa3d8). Ambos son azules → el ícono se pierde.
   Fix: card + border para definir el círculo; el icono sigue siendo --primary. */
html[data-theme="dark"] .bepp-empty__illus {
  background: var(--card);
  border: 1px solid var(--border);
}
html[data-theme="dark"] .bepp-empty--accent .bepp-empty__illus {
  background: var(--accent-alpha-15);
  border-color: transparent;
}

/* Utility: margen inferior estándar (--space-12). Usar en lugar de inline
   style="margin-bottom: var(--space-12)". */
.has-margin-bottom { margin-bottom: var(--space-12); }

/* ===== Tap targets en touch devices (mobile + tablet)
   Doctor es desktop-first, pero queremos que eventualmente sirva en iPad +
   mobile. Bumpea hit-area a ≥36px en componentes de tamaño chip/btn-sm que
   históricamente quedaban <30px en touch. ============================= */
@media (hover: none) and (pointer: coarse), (max-width: 768px) {
  .chip-filter,
  .pacientes-chip,
  .demo-chip,
  .dm-mode-option,
  .stats-chip,
  .filter-chip,
  .composer-quick .quick-btn,
  .agenda-view-switch-btn,
  .receta-tab-btn,
  .edit-tab,
  .empty-state-inline__action,
  .review-reply-btn,
  .docs-alert-link,
  .docs-quote-btn,
  .card-header-btn,
  /* Tabs específicos del bento home/agenda widget */
  #tabDay, #tabWeek, #tabMonth {
    min-height: 36px;
    padding-top: var(--space-8);
    padding-bottom: var(--space-8);
  }
  /* Botones-ícono compactos */
  .task-delete,
  .bepp-table__icon-btn,
  .pane-collapse-btn,
  #dndTrigger,
  #patientFilterBtn {
    min-width: 36px;
    min-height: 36px;
  }
  /* Botones de tamaño compacto (sm) */
  .btn-sm,
  .btn.btn-primary,
  .btn.btn-outline,
  .btn.btn-secondary {
    min-height: 36px;
  }
}

/* Familia 9 — onboarding del doctor (cards y bullets que hardcodean
   var(--white) por estética del wizard) */
html[data-theme="dark"] .ob-svc-block,
html[data-theme="dark"] .ob-close-bullets li,
html[data-theme="dark"] .ob-chip,
html[data-theme="dark"] .ob-blood-cell,
html[data-theme="dark"] .ob-btn-secondary {
  background: var(--card);
  border-color: var(--border-light);
  color: var(--text);
}
html[data-theme="dark"] .ob-btn-secondary {
  color: var(--primary);
}

/* =====================================================================
   BeppTour mobile (≤640px) — bottom-sheet override

   Decision 2026-05-11: el tour bubble en mobile NO flota apuntando al
   target con arrow (rompe el viewport, tapa el elemento highlighted).
   En su lugar, anclar al BOTTOM como sheet con safe-area-inset-bottom.
   - Sin arrow (no apunta a target)
   - Botones 44px (tap target)
   - Padding más cómodo, font más legible
   - `!important` porque bepp-tour.js setea `top/left/transform`
     inline al posicionar el bubble (ver positionBubble en
     js/bepp-tour.js:88-90, 149-150).
   ===================================================================== */
@media (max-width: 640px) {
  .bepp-tour-bubble {
    top: auto !important;
    left: var(--space-12) !important;
    right: var(--space-12);
    bottom: max(var(--space-16), env(safe-area-inset-bottom));
    transform: none !important;
    width: auto;
    max-width: none;
    padding: var(--space-16);
    border-radius: var(--radius-lg);
  }
  .bepp-tour-arrow {
    display: none !important;
  }

  /* Title + body más legibles en mobile */
  .bepp-tour-title {
    font-size: var(--font-lg);
    margin-bottom: var(--space-10);
  }
  .bepp-tour-body {
    font-size: var(--font-base);
    line-height: 1.5;
    margin-bottom: var(--space-20);
  }
  .bepp-tour-progress {
    margin-bottom: var(--space-8);
  }

  /* Botones: 44px tap target, padding cómodo */
  .bepp-tour-btn {
    min-height: 44px;
    padding: var(--space-10) var(--space-16);
    font-size: var(--font-sm);
  }
  .bepp-tour-actions {
    gap: var(--space-10);
  }
  .bepp-tour-actions-right {
    gap: var(--space-8);
  }
}
