/* ============================================
   INTELLIGENCE GALENUS — BRAND IDENTITY
   Single source of truth: tipografía, colores, radios, layout
   y mapeo a Bootstrap/Keen. Mismo archivo para los 3 proyectos.
   ============================================ */


/* ============================================
   TIPOGRAFÍA — FUENTES DE MARCA

   - Inter:    cuerpo de texto. Self-hosted, 4 pesos en
               static/igalenus/fonts/inter/. Paths relativas abajo
               (este archivo vive en core/static/core/css/, sube dos
               niveles a /static/ y entra a igalenus/fonts/).

   - New Hero: encabezados. Cargada vía Adobe Typekit con un <link>
               en el <head> de base_layout.html. Familia Typekit:
                 - 'new-hero-bold'      → weights 400 (Regular) y 700 (Bold)
                 - 'new-hero-hairline'  → weight 100 (Hairline)
   ============================================ */

@font-face {
  font-family: 'Inter';
  src: url('../../igalenus/fonts/inter/Inter_28pt-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Inter';
  src: url('../../igalenus/fonts/inter/Inter_28pt-Medium.ttf') format('truetype');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Inter';
  src: url('../../igalenus/fonts/inter/Inter_28pt-SemiBold.ttf') format('truetype');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Inter';
  src: url('../../igalenus/fonts/inter/Inter_28pt-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Aplicar Inter al cuerpo del documento.
   !important porque Keen también define body { font-family } y necesitamos ganarle. */
body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif !important;
}

/* JetBrains Mono — fuente monoespaciada para badges con cifras tabulares
   (componente inner-sidebar y futuros). Se carga desde Google Fonts en
   base_layout.html con weight 500. Variable disponible globalmente vía
   var(--ig-font-mono). */
:root {
  --ig-font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* New Hero (Adobe Fonts / Typekit) para encabezados de listados, Empresa y
     formularios. El kit se carga en el <head> de base_layout.html (ori8kco.css).
     Familia tal cual la entrega el kit: "new-hero". Cambiar la fuente de todos
     los encabezados = editar solo esta variable. */
  --ig-font-heading: 'new-hero', 'Inter', sans-serif;
}

/* Shells GBOOK: solo Inter (cuerpo), New Hero (títulos), JetBrains Mono (mono).
   Evita fugas de fuentes de Keen/Select2/Tagify/SweetAlert en listados, drawers y forms. */
.ig-records-shell,
.company-settings-page,
.gbook-form-shell,
.gbook-form-inputs-on-gray {
  font-family: 'Inter', sans-serif;
}

.ig-records-shell .select2-container,
.ig-records-shell .select2-dropdown,
.ig-records-shell .tagify,
.ig-records-shell .swal2-popup,
.company-settings-page .select2-container,
.company-settings-page .select2-dropdown,
.company-settings-page .tagify,
.company-settings-page .swal2-popup,
.gbook-form-shell .select2-container,
.gbook-form-shell .select2-dropdown,
.gbook-form-shell .tagify,
.gbook-form-inputs-on-gray .tagify {
  font-family: inherit;
}

/* TÍTULOS → New Hero (global). Todos los encabezados del proyecto.
   !important para ganarle a Keen/Bootstrap (h1 { font-family } y
   --bs-heading-font-family) y evitar que se cuele una 3ª fuente.
   Solo puede resolver a 'new-hero' (Typekit) o, si no carga, 'Inter'.
   .page-header__title se incluye explícito por si alguna vez NO es un <h*>. */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6,
.page-header__title {
  font-family: var(--ig-font-heading) !important;
}

.ig-records-shell .font-monospace,
.ig-records-shell .text-monospace,
.company-settings-page .font-monospace,
.company-settings-page .text-monospace,
.gbook-form-shell .font-monospace,
.gbook-form-shell .text-monospace,
.gbook-form-inputs-on-gray .font-monospace,
.gbook-form-inputs-on-gray .text-monospace {
  font-family: var(--ig-font-mono);
}


/* ============================================
   PALETA Y TOKENS — variables CSS
   ============================================ */

:root {
  /* ============================================
     PALETA OFICIAL IGALENUS
     Tokens crudos — única fuente de verdad de los colores de marca.
     Cualquier override de Bootstrap/Keen debe consumir estas variables,
     nunca volver a escribir los hex.
     ============================================ */

  /* Solemn Blue — fondos oscuros, hero secundario */
  --ig-solemn-blue: #010326;
  --ig-solemn-blue-rgb: 1, 3, 38;

  /* Immaculate White — superficies claras, texto sobre oscuros */
  --ig-immaculate-white: #FFFFFF;
  --ig-immaculate-white-rgb: 255, 255, 255;

  /* Page Bg — fondo de página / bg-body (solo tema claro; guía de marca) */
  --ig-page-bg: #F2F3F7;
  --ig-page-bg-rgb: 242, 243, 247;

  /* Surface Nivel 1 — cards, frames, modales / bg-light (solo tema claro) */
  --ig-surface-1: #FAFBFD;
  --ig-surface-1-rgb: 250, 251, 253;

  /* Innovation Blue — azul intenso, acento secundario */
  --ig-innovation-blue: #003AC9;
  --ig-innovation-blue-rgb: 0, 58, 201;

  /* Serene Sky — color PRIMARIO de marca */
  --ig-serene-sky: #066DF0;
  --ig-serene-sky-rgb: 6, 109, 240;

  /* Intimate Liliac — púrpura claro, acento */
  --ig-intimate-liliac: #8A23E5;
  --ig-intimate-liliac-rgb: 138, 35, 229;

  /* Friendly Purple — púrpura oscuro, acento principal */
  --ig-friendly-purple: #6000C6;
  --ig-friendly-purple-rgb: 96, 0, 198;

  /* Mustard — color WARNING de la plataforma. Sustituye al amarillo #F6C000
     de Keen (demasiado claro: texto e iconos warning se perdían sobre fondos
     claros). Tono mostaza quemado con suficiente contraste para texto. */
  --ig-mustard: #B5731A;
  --ig-mustard-rgb: 181, 115, 26;
  --ig-mustard-active: #9E6417;        /* hover/active de btn-warning (más oscuro) */
  --ig-mustard-light: #F7EFE2;         /* bg-light-warning — crema cálido */
  /* Variantes tema oscuro: un paso más brillante para no apagarse sobre Obsidiana */
  --ig-mustard-dark: #C9821D;
  --ig-mustard-dark-rgb: 201, 130, 29;
  --ig-mustard-dark-active: #D68E2A;
  --ig-mustard-dark-light: #2A2115;    /* bg-light-warning en oscuro — tinte tenue */

  /* Brand Gradient — órbita azul→púrpura (guía de marca), 120°:
     Innovation Blue → Serene Sky → Friendly Purple → Intimate Liliac.
     Uso: acentos, alertas destacadas, barras de progreso. Con texto
     encima → SIEMPRE texto blanco (contraste). No usar detrás de texto
     de cuerpo (gris/oscuro) — solo como fondo de acento. */
  --brand-gradient: linear-gradient(
    120deg,
    var(--ig-innovation-blue) 0%,
    var(--ig-serene-sky)      35%,
    var(--ig-friendly-purple) 70%,
    var(--ig-intimate-liliac) 100%
  );

  /* Variante tenue — fondos sutiles sin texto blanco encima */
  --brand-gradient-soft: linear-gradient(
    120deg,
    rgba(var(--ig-innovation-blue-rgb), 0.12) 0%,
    rgba(var(--ig-serene-sky-rgb),      0.10) 35%,
    rgba(var(--ig-friendly-purple-rgb), 0.10) 70%,
    rgba(var(--ig-intimate-liliac-rgb), 0.12) 100%
  );

  /* ============================================
     MAPEO A BOOTSTRAP / KEEN
     primary = Serene Sky (#066DF0)
     ============================================ */

  /* Primary */
  --bs-primary: var(--ig-serene-sky);
  --bs-primary-rgb: var(--ig-serene-sky-rgb);

  /* Acento púrpura */
  --bs-accent-purple: var(--ig-friendly-purple);
  --bs-accent-purple-rgb: var(--ig-friendly-purple-rgb);

  /* Fondo oscuro */
  --bs-bg-dark: var(--ig-solemn-blue);

  /* Keen theme */
  --kt-primary: var(--ig-serene-sky);
  --kt-primary-inverse: var(--ig-immaculate-white);

  /* Bootstrap — componentes activos */
  --bs-pagination-active-bg: var(--ig-serene-sky);
  --bs-component-active-bg: var(--ig-serene-sky);

  /* ============================================
     LAYOUT
     ============================================ */

  /* Ancho máximo del contenido principal (cualquier template que
     extienda base_layout.html). Customizable por proyecto. */
  --ig-content-max-width: 1400px;

  /* Espacio entre el topbar y el inicio del contenido.
     Aplica a todas las extensiones de base_layout.html. */
  --ig-content-padding-top: 1.5rem;
  /* Gutter horizontal global para evitar que el contenido se pegue a los bordes
     en pantallas medianas/chicas (apps/listados “extensiones”).
     Mínimo 1rem; escala con viewport en móvil/tablet. */
  --ig-content-padding-x: clamp(1rem, 3vw + 0.5rem, 1.5rem);

  /* ============================================
     RADIUS — escala unificada de redondeo
     Pill conserva 50vh (identidad de switch).
     Inputs y botones: 8px (md) base, 12px (lg) con rounded-4.
     Cards de sección (.rounded-5): 32px (xl) — radio mayor para diferenciar contenedor.
     Modales: 12px (lg).
     ============================================ */

  /* Tokens base */
  --ig-radius-sm: 0.375rem;   /* 6px  — detalles pequeños */
  --ig-radius-md: 0.5rem;     /* 8px  — inputs, botones tamaño base */
  --ig-radius-lg: 0.75rem;    /* 12px — inputs/botones rounded-4, modales */
  --ig-radius-xl: 2rem;       /* 32px — cards de sección (.rounded-5), más radio = jerarquía visual */

  /* Page header — título display (fluido, semibold, tono premium sin peso pesado) */
  --page-header-title-size-min: 1.875rem;   /* ~30px móvil */
  --page-header-title-size-max: 2.375rem;   /* ~38px desktop — más delgado que 3rem */
  --page-header-title-weight: 600;
  --page-header-title-tracking: -0.018em;
  --page-header-title-leading: 1.12;
  --ig-radius-pill: 50vh;     /* pill switcher (su identidad) */

  /* Cascada a Bootstrap — afecta utilities .rounded-* y componentes BS */
  --bs-border-radius-sm: var(--ig-radius-md);   /* uniformemos sm con md */
  --bs-border-radius: var(--ig-radius-md);
  --bs-border-radius-lg: var(--ig-radius-md);   /* uniformemos lg con md */
  --bs-border-radius-xl: var(--ig-radius-lg);   /* rounded-4 = 12px */
  --bs-border-radius-2xl: var(--ig-radius-xl);  /* rounded-5 — cards de sección */
  --bs-border-radius-pill: var(--ig-radius-pill);

  /* Cards default (sin clase rounded-X explícita): 8px discreto.
     Para cards de SECCIÓN (toolbars, tablas, paneles) usar el combo
     "card border-0 shadow-xs rounded-5" en HTML — ver estilos-gbook.md. */
  --bs-card-border-radius: var(--ig-radius-md);
  --bs-card-inner-border-radius: var(--ig-radius-md);

  /* Modales: el radio real lo manda `custom-modals.css` (tiene !important para
     ganarle a Keen). Aquí se apunta al MISMO token para que lo que derive de
     esta variable —p. ej. el inner-radius con que Bootstrap redondea header y
     footer— no se quede 4px corto y deje un escalón en las esquinas. */
  --bs-modal-border-radius: var(--ig-modal-radius, var(--ig-radius-lg));

  /* ============================================
     PALETA PIEDRA — extensión de marca para tema claro
     Capas tonales con sub-tono azulado derivado de Solemn Blue.
     Filosofía: "elevación por tono, no por sombra"
     (separación entre capas por 5–10 unidades de luminancia
     + 1px de Line, en lugar de drop-shadows pesados).
     Ver estilos-gbook.md § "Paleta Piedra".
     ============================================ */
  --ig-stone-l2:        #EBEDF2;  /* L2 Subtle  — headers de tabla, paneles anidados */
  --ig-stone-recess:    #E2E5EC;  /* L3 Recess  — capa más profunda (uso selectivo) */
  --ig-stone-line:      #DCDFE7;  /* Line       — bordes finos */
  --ig-stone-ink-soft:  #5C6170;  /* Ink soft   — texto secundario */
  --ig-stone-ink:       #15171D;  /* Ink        — texto primario */
  --ig-stone-ink-soft-rgb: 92, 97, 112;
  --ig-stone-ink-rgb:      21, 23, 29;

  /* Relleno de inputs — token propio, NO reusa L2.
     Los controles necesitan leerse como "hueco" un paso por debajo de la
     superficie, más marcado que el L2 que usan paneles anidados y headers de
     tabla embebidos. Si compartieran token, oscurecer el input arrastraría
     esas otras capas. Aquí solo se toca el valor de esta línea.
     Fallback = gray-200 → en tema OSCURO el input conserva el gris de Keen
     (#26272F) sin cambio alguno. */
  --ig-input-bg: var(--bs-gray-200, #f1f1f2);

  /* Obsidiana — equivalente Piedra para tema oscuro (mismo sub-tono Solemn Blue) */
  --ig-obsidian-bg:       #0E1015;  /* L0 Body oscuro — más oscuro que Surface */
  --ig-obsidian-bg-rgb:   14, 16, 21;
  --ig-obsidian-surface:  #16181F;  /* L1 Surface oscuro — cards, modales */
  --ig-obsidian-line:     #232631;  /* Line oscuro — bordes y separadores de fila */
}

/* bg-body, bg-light y escala de grises — solo tema claro.
   Tema oscuro conserva los valores de Keen/Bootstrap en el bundle.
   La paleta Piedra ripplea automáticamente a las utilidades Keen
   (bg-gray-200, border-gray-300, text-gray-600/900, text-muted). */
[data-bs-theme="light"] {
  --bs-body-bg: var(--ig-page-bg);
  --bs-body-bg-rgb: var(--ig-page-bg-rgb);
  --bs-light: var(--ig-surface-1);
  --bs-light-rgb: var(--ig-surface-1-rgb);

  /* Card / modal / list-group → L1 Surface (más claro que L0 body).
     Bootstrap 5.3 por defecto hace --bs-card-bg = --bs-body-bg, lo cual
     elimina la diferencia tonal entre body y card. La filosofía Piedra
     exige que la card flote sobre el body con ~5 unidades de luminancia
     más clara. Esta es la línea clave que hace que la "elevación por
     tono" funcione sin sombras. */
  --bs-card-bg: var(--ig-surface-1);
  --bs-modal-bg: var(--ig-surface-1);
  --bs-list-group-bg: var(--ig-surface-1);

  /* Remapeo escala de grises Keen → Piedra */
  --bs-gray-200: var(--ig-stone-l2);
  --bs-gray-300: var(--ig-stone-line);

  /* Relleno de inputs SOLO en claro — un paso por debajo de L2 y con menos
     sub-tono azul, para que el control se lea como hueco tallado y no como
     otra superficie. Oscuro no entra aquí: conserva gray-200 de Keen. */
  --ig-stone-input: #E4E6EA;
  --ig-input-bg: var(--ig-stone-input);
  --bs-gray-600: var(--ig-stone-ink-soft);
  --bs-gray-900: var(--ig-stone-ink);

  /* Texto secundario (text-muted, page-header__counter, etc.) → Ink soft */
  --bs-secondary-color: var(--ig-stone-ink-soft);

  /* Borde por defecto de Bootstrap → Line */
  --bs-border-color: var(--ig-stone-line);

  /* ============================================
     WARNING → Mustard (--ig-mustard)
     Keen compila btn-warning / bg-warning / badge-warning / text-warning /
     bg-light-warning consumiendo estas variables, así que el remapeo aquí
     propaga a todas las clases sin tocar el bundle. Va en el bloque de tema
     (no en :root) porque Keen define los valores dark dentro de
     [data-bs-theme=dark], que le gana a :root por especificidad.
     ============================================ */
  --bs-warning: var(--ig-mustard);
  --bs-warning-rgb: var(--ig-mustard-rgb);
  --bs-warning-active: var(--ig-mustard-active);
  --bs-warning-light: var(--ig-mustard-light);
  --bs-warning-inverse: var(--ig-immaculate-white);
  --bs-warning-clarity: rgba(var(--ig-mustard-rgb), 0.2);
  --bs-text-warning: var(--ig-mustard);
  /* Bootstrap 5.3 — alert-warning y variantes subtle */
  --bs-warning-text-emphasis: #6F470F;
  --bs-warning-bg-subtle: #F3E7D3;
  --bs-warning-border-subtle: #E3CBA4;
}

/* Keen/style.bundle puede definir .rounded-5 con valor fijo o sin variables;
   forzar el radio de marca (este archivo carga después del bundle en base_layout). */
.rounded-5 {
  border-radius: var(--ig-radius-xl) !important;
}

/* ============================================
   PALETA PIEDRA — overrides de utilidades Keen (tema claro)
   Las utilidades de Keen pueden estar compiladas con valores literales
   (no var()). Forzamos la paleta Piedra solo en tema claro; el dark
   keeps su escala neutra original.
   ============================================ */

[data-bs-theme="light"] .bg-gray-200 { background-color: var(--ig-stone-l2) !important; }
[data-bs-theme="light"] .border-gray-300 { border-color: var(--ig-stone-line) !important; }
[data-bs-theme="light"] .text-gray-600 { color: var(--ig-stone-ink-soft) !important; }
[data-bs-theme="light"] .text-gray-900 { color: var(--ig-stone-ink) !important; }

/* Force surface L1 sobre TODA .card / .modal-content (tema claro).
   Razón: Keen compila `.card { background-color: ... }` con literal en lugar
   de var(--bs-card-bg), así que override de la variable solo no funciona.
   Belt-and-suspenders: var override (más arriba) + regla forzada con !important. */
[data-bs-theme="light"] .card {
  --bs-card-bg: var(--ig-surface-1);
  background-color: var(--ig-surface-1) !important;
}
[data-bs-theme="light"] .modal-content { background-color: var(--ig-surface-1) !important; }
[data-bs-theme="light"] .list-group-item { background-color: var(--ig-surface-1) !important; }

/* ============================================
   PALETA OBSIDIANA — tema oscuro
   Equivalente Piedra para dark theme: misma filosofía de capas tonales,
   sub-tono azulado derivado de Solemn Blue, pero invertida.
   Surface L1 #16181F flota sobre body L0 (más oscuro) por ~5–8 unidades.
   ============================================ */

[data-bs-theme="dark"] {
  /* Body L0 — más oscuro que Surface, para que las cards floten visualmente */
  --bs-body-bg:       var(--ig-obsidian-bg);
  --bs-body-bg-rgb:   var(--ig-obsidian-bg-rgb);

  /* Surface L1 — cards, modales, list-groups */
  --bs-light:         var(--ig-obsidian-surface);
  --bs-card-bg:       var(--ig-obsidian-surface);
  --bs-modal-bg:      var(--ig-obsidian-surface);
  --bs-list-group-bg: var(--ig-obsidian-surface);

  /* Line — bordes y separadores */
  --bs-border-color:  var(--ig-obsidian-line);

  /* WARNING → Mustard, variante brillante para fondos Obsidiana
     (mismo remapeo que en tema claro; ver ese bloque para el porqué). */
  --bs-warning: var(--ig-mustard-dark);
  --bs-warning-rgb: var(--ig-mustard-dark-rgb);
  --bs-warning-active: var(--ig-mustard-dark-active);
  --bs-warning-light: var(--ig-mustard-dark-light);
  --bs-warning-inverse: var(--ig-immaculate-white);
  --bs-warning-clarity: rgba(var(--ig-mustard-dark-rgb), 0.2);
  --bs-text-warning: var(--ig-mustard-dark);
  /* Bootstrap 5.3 — alert-warning y variantes subtle (oscuro) */
  --bs-warning-text-emphasis: #E0AC5E;
  --bs-warning-bg-subtle: #281A06;
  --bs-warning-border-subtle: #79511A;
}

/* Force surface L1 en oscuro — mismo razonamiento que en claro:
   Keen no setea background-color en .card / .modal-content / .list-group-item,
   o lo compila con literal, así que override del var solo no basta. */
[data-bs-theme="dark"] body             { background-color: var(--ig-obsidian-bg) !important; }
[data-bs-theme="dark"] .bg-light        { background-color: var(--ig-obsidian-surface) !important; }
[data-bs-theme="dark"] .card {
  --bs-card-bg: var(--ig-obsidian-surface);
  background-color: var(--ig-obsidian-surface) !important;
}
[data-bs-theme="dark"] .modal-content   { background-color: var(--ig-obsidian-surface) !important; }
[data-bs-theme="dark"] .list-group-item { background-color: var(--ig-obsidian-surface) !important; }

/* Borde 1px Line en cards de tabla en oscuro (alongside shadow-xs original).
   Da un cierre visual al contorno además del contraste tonal body→surface. */
[data-bs-theme="dark"] .card.card-table.shadow-xs,
[data-bs-theme="dark"] .card.shadow-xs.rounded-5,
[data-bs-theme="dark"] .card.shadow-xs.rounded-4 {
  border: 1px solid var(--ig-obsidian-line) !important;
}

/* Separadores de fila sólidos en oscuro (paridad con tema claro).
   Sin esto, Keen muestra dashed con su gris neutro original. */
[data-bs-theme="dark"] .card.card-table .table.table-row-dashed > :not(caption) > * > * {
  border-bottom-style: solid !important;
  border-bottom-color: var(--ig-obsidian-line) !important;
}

/* ============================================
   PALETA PIEDRA — cards de sección (tema claro)
   Elevación por tono + 1px borde Line, en lugar de shadow-xs.
   Tema oscuro: shadow-xs original (no se toca).
   Aplica a cards que llevan el combo `card ... shadow-xs rounded-5`
   y a cards de tabla (`.card-table`) que pueden venir en rounded-4.
   ============================================ */

[data-bs-theme="light"] .card.card-table.shadow-xs,
[data-bs-theme="light"] .card.shadow-xs.rounded-5,
[data-bs-theme="light"] .card.shadow-xs.rounded-4 {
  box-shadow: none !important;
  border: 1px solid var(--ig-stone-line) !important;
}

/* Tabla: separadores entre filas sólidos (no dashed) en color Line.
   Más premium, más "piedra tallada" — menos artesanal que el dashed. */
[data-bs-theme="light"] .card.card-table .table.table-row-dashed > :not(caption) > * > * {
  border-bottom-style: solid !important;
  border-bottom-color: var(--ig-stone-line) !important;
}

/* ============================================
   BOTONES DE MARCA — overrides Bootstrap/Keen
   ============================================ */

/* Outline-primary usa Innovation Blue (acento secundario), distinto
   del primary Serene Sky. Da contraste a botones outline sin que se
   sientan "el mismo color" que el primary. */
.btn-outline-primary {
  --bs-btn-color: var(--ig-innovation-blue) !important;
  --bs-btn-border-color: var(--ig-innovation-blue) !important;
  --bs-btn-hover-bg: var(--ig-innovation-blue) !important;
  --bs-btn-hover-border-color: var(--ig-innovation-blue) !important;
  --bs-btn-focus-shadow-rgb: var(--ig-innovation-blue-rgb) !important;
  --bs-btn-active-bg: var(--ig-innovation-blue) !important;
  --bs-btn-active-border-color: var(--ig-innovation-blue) !important;
  --bs-btn-disabled-color: var(--ig-innovation-blue) !important;
  --bs-btn-disabled-border-color: var(--ig-innovation-blue) !important;
}

/* ============================================
   ANIMACIÓN DE CARGA DE PÁGINA (GLOBAL)
   ============================================ */

/* Estado inicial: oculto y muy ligeramente escalado (más cerca) */
.page-load-animation {
  opacity: 0;
  transform: scale(0.99);
  will-change: opacity, transform;
}

/* ============================================
   CONTENEDOR DE CONTENIDO (GLOBAL)
   Wrapper de {% block content %} en base_layout.html.
   - Ancho máximo centrado (header y footer mantienen full-width)
   - Padding superior: separa el contenido del topbar
   El !important en padding-top sobrescribe la regla inline
   .app-container { padding-top: 0 !important } de base_layout.html.
   ============================================ */

#kt_app_content_container {
  max-width: var(--ig-content-max-width);
  padding-top: var(--ig-content-padding-top) !important;
  margin-left: auto;
  margin-right: auto;
}

/* Extensiones de base_layout (excluye calendario — conserva su gutter en base-layout.css) */
#kt_app_content_container:not(:has(.calendar-page-root)) {
  padding-left: max(var(--ig-content-padding-x), env(safe-area-inset-left, 0px)) !important;
  padding-right: max(var(--ig-content-padding-x), env(safe-area-inset-right, 0px)) !important;
}

/* ============================================
   PAGE LINE TABS 2x (Keen — nav principal de página)
   Uso: 5+ secciones (perfil paciente, configuración empresa).
   Ver keen-bootstrap.md § "Line Tabs 2x".
   ============================================ */

.gbook-page-tabs-bar {
  flex-shrink: 0;
}

.gbook-page-tabs-bar__nav {
  min-width: 0;
}

.gbook-page-line-tabs.nav {
  flex-wrap: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  border-bottom: 1px solid var(--bs-border-color) !important;
}

.gbook-page-line-tabs .nav-item {
  flex-shrink: 0;
}

.gbook-page-line-tabs .nav-link {
  white-space: nowrap;
}

.gbook-page-line-tabs.nav-line-tabs-2x > .nav-item > .nav-link:not(.active) {
  color: var(--bs-gray-700);
}

.gbook-page-line-tabs.nav-line-tabs-2x > .nav-item > .nav-link:not(.active):hover {
  color: var(--bs-gray-800);
}

.gbook-page-line-tabs.nav-line-tabs-2x > .nav-item > .nav-link.active {
  color: var(--bs-primary);
}

.cs-card__body > .tab-content,
.patient-profile-card__body > .tab-content {
  border-top: 0 !important;
  margin-top: 0;
  padding-top: 0;
}

/* ============================================
   TABLAS EN CARDS
   Clase .card-table: marca semántica para cards que envuelven tablas.
   Altura = contenido (tabla + footer/paginación); sin min-height global
   para evitar hueco vacío con pocas filas. Estados vacíos: mensaje o
   skeleton dentro de la card, no forzar altura del contenedor.

   Listados Keen: alineación vertical homogénea sin repetir align-middle
   en cada plantilla (cabeceras ordenables + celdas mixtas).
   ============================================ */

.card.card-table .table-responsive .table th,
.card.card-table .table-responsive .table td {
  vertical-align: middle;
}

/* ============================================
   RECORDS SHELL (GLOBAL)
   Patrón reusable para vistas con:
   título + toolbar/búsqueda + tabla + footer/paginación.
   Objetivo: que solo la región de registros haga scroll.

   Nota: base_layout define #kt_app_content.app-content { overflow-y: auto }.
   Si el contenido mide más que el viewport, aparece scroll “de toda la página”.
   Cuando existe [data-scroll-shell], anclamos altura al área útil y movemos el
   scroll solo a .ig-records-shell__scroll (sin segundo scrollbar en app-content).
   ============================================ */

#kt_app_content.app-content:has([data-scroll-shell]) {
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* Tope de altura = viewport − header. Garantiza que el contenedor
     ocupe exactamente la pantalla y el scroll viva en .ig-records-shell__scroll,
     sin depender de la cadena flex de base_layout (el wrapper intermedio
     .d-flex.flex-column.flex-column-fluid no trae min-height:0). */
  max-height: calc(100vh - var(--bs-app-header-height, 70px));
  /* svh (alto con el chrome del navegador DESPLEGADO) en vez de dvh: es un valor
     ESTABLE que no se recalcula cuando la barra de direcciones se colapsa al
     hacer scroll. Con dvh, ese recálculo a mitad del gesto movía el layout en
     iPad/iOS y podía dejar el topbar fuera del área visible. En la app instalada
     no hay chrome, así que svh == dvh y no se pierde alto.
     --ig-chrome-top = header + safe-area superior (ver base-layout.css). Se deja
     fallback explícito porque este archivo es portable entre proyectos IGalenus
     y puede usarse sin base-layout.css, que es donde se define la variable. */
  max-height: calc(100svh - var(--ig-chrome-top, var(--bs-app-header-height, 70px)));
  overflow-y: hidden;
}

#kt_app_content_container:has([data-scroll-shell]) {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.ig-records-shell {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

/* Tab content bajo el page-header: ocupa el alto restante */
.ig-records-shell > .tab-content {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Bootstrap usa display:none/block en .tab-pane; forzamos flex en el activo */
.ig-records-shell .tab-pane.active {
  display: flex !important;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

/* Card de tabla dentro de cada tab (p. ej. Vínculos sin clases __*) */
.ig-records-shell .tab-pane.active > .card.card-table {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.ig-records-shell .tab-pane.active > .card.card-table > .card-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Tab Vínculos: .table-responsive directo bajo .card-body */
.ig-records-shell .tab-pane.active > .card.card-table > .card-body > .table-responsive {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.ig-records-shell__card,
.ig-records-shell__body,
.ig-records-shell__content {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.ig-records-shell__scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.ig-records-shell__footer {
  flex-shrink: 0;
}

/* Envoltorio intermedio "transparente": divs que existen por razones de
   estructura (vista lista/tablero, contenedor del partial que se reemplaza por
   AJAX) y que deben DEJAR PASAR la cadena flex hasta __card/__scroll. Sin esto
   el wrapper corta la cadena y la región de filas pierde su altura acotada.
   Sus otros hijos (pastillas de estatus, chips de filtros) no se comprimen. */
.ig-records-shell__pass {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.ig-records-shell__pass > :not(.ig-records-shell__card):not(.ig-records-shell__pass) {
  flex-shrink: 0;
}

/* Hub Pagos: métricas y filtros fijos; solo el acordeón/listado scrollea */
.ig-records-shell__body > .row,
.ig-records-shell__body > .alert {
  flex-shrink: 0;
}

.ig-records-shell__scroll .table thead th,
.ig-records-shell .tab-pane.active > .card.card-table > .card-body > .table-responsive .table thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  /* L1 Surface — mismo tono que el cuerpo de la card (evita halo al hacer scroll) */
  background-color: var(--bs-card-bg, var(--bs-light));
}

/* ============================================
   NÚMEROS TABULARES (Inter — sin segunda fuente)
   Inter incluye cifras tabulares; alinear columnas de expedientes, teléfonos,
   fechas y contadores sin JetBrains Mono ni ir plantilla por plantilla.
   Ref: font-variant-numeric: tabular-nums (SaaS moderno: Stripe, Vercel, etc.)
   Para fuera de .card.card-table usar la utilidad .gbook-tabular-nums
   ============================================ */

/* NÚMEROS → JetBrains Mono (global). Marcar con .gbook-tabular-nums cualquier
   elemento cuyo contenido sea 100% numérico (IGN, fechas, teléfonos, montos,
   contadores, etc.). El mono ya trae cifras de ancho fijo; tabular-nums se deja
   como refuerzo/fallback a Inter. Una sola variable controla la familia. */
.gbook-tabular-nums {
  font-family: var(--ig-font-mono);
  font-variant-numeric: tabular-nums;
}

/* Formularios shell: teléfonos y campos numéricos → JetBrains Mono */
.gbook-form-inputs-on-gray input[type="tel"],
.gbook-form-inputs-on-gray input[type="number"],
.gbook-form-shell input[type="tel"],
.gbook-form-shell input[type="number"] {
  font-family: var(--ig-font-mono);
  font-variant-numeric: tabular-nums;
}

/* Botón Cancelar en encabezados de formulario — mismo tono que inputs / panel anidado */
.gbook-form-btn-cancel {
  background-color: var(--bs-gray-200, #f1f1f2) !important;
  border: 1px solid var(--bs-gray-300, #e1e3ea) !important;
  color: var(--bs-gray-800, #3f4254) !important;
}

.gbook-form-btn-cancel:hover,
.gbook-form-btn-cancel:focus {
  background-color: var(--bs-gray-300, #e1e3ea) !important;
  border-color: var(--bs-gray-300, #e1e3ea) !important;
  color: var(--bs-gray-900, #181c32) !important;
}

[data-bs-theme="dark"] .gbook-form-btn-cancel {
  color: var(--bs-gray-800, #cdcdde) !important;
}

[data-bs-theme="dark"] .gbook-form-btn-cancel:hover,
[data-bs-theme="dark"] .gbook-form-btn-cancel:focus {
  color: var(--bs-gray-900, #f5f5f5) !important;
}

/* Encabezado de formulario: título | estado (centro) | acciones */
.gbook-form-page-header__status {
  max-width: 100%;
  /* Transición fina para que el cambio a "pill" (flash de notificación) se
     sienta como una alerta inline y no como un brinco. Padding/border-radius
     base reservan el espacio para evitar layout shift cuando aparece la pill. */
  transition: background-color 0.25s ease, padding 0.25s ease, border-radius 0.25s ease;
  padding: 0.2rem 0.75rem;
  border-radius: 99rem;
}

.gbook-form-page-header__status.is-flashing {
  padding: 0.35rem 1.1rem;
}

/* Listados en card-table: una sola regla cubre todas las tablas de listado */
.card.card-table .table-responsive .table {
  font-variant-numeric: tabular-nums;
}

/* Paginación numérica alineada (suele vivir dentro del mismo card) */
.card.card-table .pagination {
  font-variant-numeric: tabular-nums;
}


/* ============================================
   PAGE HEADER — eyebrow + título + greeting (listados premium)
   Calidez: greeting legible, eyebrow suave, sin gritar en mayúsculas.
   Exclusividad: Inter 28pt + OpenType (cv11, ss01, tnum, calt, case).
   Título: semibold fluido (no bold 700) — sensación editorial ligera.
   ============================================ */

.page-header {
  font-feature-settings: "cv11", "ss01", "tnum", "calt", "case";
  font-optical-sizing: auto;
}

/* Eyebrow / breadcrumb — discreto, sin uppercase agresivo */
.page-header__eyebrow {
  font-size: 0.8125rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--bs-secondary-color);
  line-height: 1.4;
}

.page-header__eyebrow .opacity-50 {
  opacity: 0.45 !important;
}

/* Título — tamaño fluido con clamp (viewport + tope más bajo que antes) */
.page-header__title {
  font-size: clamp(
    var(--page-header-title-size-min),
    1rem + 2.25vw,
    var(--page-header-title-size-max)
  );
  font-weight: var(--page-header-title-weight);
  line-height: var(--page-header-title-leading);
  letter-spacing: var(--page-header-title-tracking);
  color: var(--bs-emphasis-color);
  margin: 0;
}

/* Contador inline — escala con el título, peso ligero; cifras tabulares (Inter) */
.page-header__counter {
  font-size: clamp(0.9375rem, 0.85rem + 0.35vw, 1.0625rem);
  font-weight: 400;
  color: var(--bs-secondary-color);
  letter-spacing: 0.01em;
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
}

/* Greeting — conversacional */
.page-header__greeting {
  font-size: clamp(0.9375rem, 0.9rem + 0.15vw, 1rem);
  font-weight: 400;
  line-height: 1.55;
  color: color-mix(in srgb, var(--bs-body-color) 88%, var(--bs-secondary-color));
  margin: 0;
}

.page-header__greeting strong {
  font-weight: 500;
  color: var(--bs-emphasis-color);
}

/* Greeting en fila propia (debajo del título, ancho completo) */
.page-header__greeting-wrap .page-header__greeting {
  max-width: 58ch;
}

/* Greeting en una línea (tabs con textos largos — evita salto de layout) */
.page-header__greeting-wrap--single-line .page-header__greeting {
  max-width: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Greeting + búsqueda/acciones en la misma fila: una sola línea de texto */
.page-header__toolbar-row > .page-header__greeting,
.page-header > .d-flex.justify-content-between:has(> .page-header__greeting) > .page-header__greeting {
  flex: 1 1 auto;
  min-width: 0;
  max-width: none;
  white-space: nowrap;
}

.page-header__toolbar-row > .flex-shrink-0,
.page-header > .d-flex.justify-content-between:has(> .page-header__greeting) > .flex-shrink-0 {
  flex-shrink: 0;
}

@media (max-width: 991.98px) {
  .page-header__toolbar-row > .page-header__greeting,
  .page-header > .d-flex.justify-content-between:has(> .page-header__greeting) > .page-header__greeting {
    white-space: normal;
    flex: 1 1 100%;
  }
}

/* ============================================
   SIDEBAR — logo (layout dark-sidebar)
   Keen: border-bottom punteado en .app-sidebar-logo; sin separador visual.
   ============================================ */

[data-kt-app-layout="dark-sidebar"] .app-sidebar .app-sidebar-logo {
  border-bottom: none !important;
}

/* Toggle colapsar sidebar: icono iGAL sin caja btn-icon de Keen */
#kt_app_sidebar_toggle.app-sidebar-toggle--brand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none !important;
  background: transparent !important;
  box-shadow: none !important;
  width: auto;
  height: auto;
  min-width: 0;
  cursor: pointer;
}

#kt_app_sidebar_toggle.app-sidebar-toggle--brand:hover,
#kt_app_sidebar_toggle.app-sidebar-toggle--brand:focus,
#kt_app_sidebar_toggle.app-sidebar-toggle--brand:active,
#kt_app_sidebar_toggle.app-sidebar-toggle--brand.active {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}

#kt_app_sidebar_toggle .app-sidebar-toggle__icon {
  display: block;
  width: 1.875rem;
  height: 1.875rem;
  object-fit: contain;
}

/* ============================================
   TOPBAR — nombre del tenant + carril de alarmas
   ============================================ */

/* Keen aplica box-shadow inferior por defecto en .app-header (tema claro).
   Filosofía Piedra: separación por tono, no por sombra. */
#kt_app_header.app-header {
  box-shadow: none !important;
  /* Topbar con el MISMO fondo base (L0) que el contenido de las extensiones
     (bg-body / --bs-body-bg): #F2F3F7 en claro, Obsidian bg en oscuro. Look
     integrado, sin la banda blanca del header default de Keen. */
  --bs-app-header-base-bg-color: var(--bs-body-bg);
  background-color: var(--bs-body-bg) !important;
}

.app-header-tenant-left {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  transform: translateX(-50%);
  z-index: 1;
  /* Centrado sin invadir navbar derecha (avatar, theme, setup guide) */
  max-width: min(28rem, calc(100% - 13rem));
  width: auto;
  min-width: 0;
  overflow: hidden;
  justify-content: center;
  padding-left: 0 !important;
  padding-right: 0 !important;
}

.app-header-tenant-left > .d-flex {
  max-width: 100%;
  min-width: 0;
  overflow: hidden;
}

.app-header-tenant__name {
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--bs-emphasis-color);
  line-height: 1.25;
  font-feature-settings: "cv11", "ss01", "calt", "case";
  text-align: center;
  min-width: 0;
  flex: 1 1 auto;
  max-width: 100%;
}

/* Navbar derecha por encima del bloque centrado (clicks + legibilidad) */
#kt_app_header_wrapper > .app-navbar.ms-auto {
  position: relative;
  z-index: 2;
}

@media (max-width: 991.98px) {
  .app-header-tenant-left {
    max-width: min(22rem, calc(100% - 11rem));
  }

  .app-header-tenant__name {
    font-size: 1.15rem;
  }
}

.app-header-tenant-alarms:empty {
  display: none;
}

/* GbookHeaderFlash — oculto temporalmente (reactivar quitando display:none) */
.app-header-alarms-center {
  display: none !important;
}

.app-header-tenant-alarms:not(:empty) {
  display: flex;
}

/* GbookHeaderFlash — topbar (header-flash-alert.js + anime.js) */
.header-flash-alert {
  display: none;
  max-width: 100%;
}

.header-flash-alert.is-visible {
  display: block;
}

.header-flash-alert__inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.header-flash-alert__burst {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 1rem;
  height: 1rem;
  margin-left: -0.5rem;
  margin-top: -0.5rem;
  border-radius: 50%;
  background: var(--bs-primary);
  box-shadow: 0 0 12px rgba(var(--bs-primary-rgb), 0.55);
  pointer-events: none;
  z-index: 2;
  opacity: 0;
}

.header-flash-alert--warning .header-flash-alert__burst {
  background: var(--bs-warning);
  box-shadow: 0 0 12px rgba(var(--bs-warning-rgb), 0.5);
}

.header-flash-alert--success .header-flash-alert__burst {
  background: var(--bs-success);
  box-shadow: 0 0 12px rgba(var(--bs-success-rgb), 0.45);
}

.header-flash-alert__panel {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: stretch;
  gap: 0.15rem;
  min-height: 2.75rem;
  max-width: min(28rem, 58vw);
  transform: scaleX(0);
  transform-origin: center center;
  border-radius: var(--ig-radius-lg);
  background: linear-gradient(
    105deg,
    rgba(var(--bs-primary-rgb), 0.1) 0%,
    var(--bs-body-bg) 50%,
    rgba(var(--bs-accent-purple-rgb, 96, 0, 198), 0.06) 100%
  );
  border: 1px solid rgba(var(--bs-primary-rgb), 0.24);
  box-shadow: 0 2px 12px rgba(var(--bs-primary-rgb), 0.12);
  overflow: hidden;
}

.header-flash-alert--warning .header-flash-alert__panel {
  border-color: rgba(var(--bs-warning-rgb), 0.35);
}

.header-flash-alert--success .header-flash-alert__panel {
  border-color: rgba(var(--bs-success-rgb), 0.35);
}

.header-flash-alert__content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.35rem;
  min-width: 0;
  padding: 0.5rem 0.35rem 0.5rem 1rem;
}

.header-flash-alert__label {
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--bs-primary);
  line-height: 1;
  opacity: 0;
}

.header-flash-alert__message-row {
  display: flex;
  align-items: center;
  min-width: 0;
}

.header-flash-alert__text {
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--bs-emphasis-color);
  white-space: nowrap;
  text-decoration: none;
  opacity: 0;
}

.header-flash-alert__text:hover {
  color: var(--bs-emphasis-color);
}

.header-flash-alert__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
}

.header-flash-alert__action {
  white-space: nowrap;
  opacity: 0;
}

.header-flash-alert__prompt {
  display: none;
  align-items: center;
  gap: 0.35rem;
  width: 100%;
  min-width: min(16rem, 40vw);
}

.header-flash-alert--prompt .header-flash-alert__message-row {
  display: none;
}

.header-flash-alert--prompt .header-flash-alert__prompt {
  display: flex;
}

.header-flash-alert__input {
  flex: 1;
  min-width: 0;
  opacity: 0;
}

.header-flash-alert__close {
  flex-shrink: 0;
  align-self: center;
  width: 2.125rem !important;
  height: 2.125rem !important;
  margin-right: 0.15rem;
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .header-flash-alert__burst {
    display: none;
  }

  .header-flash-alert__panel {
    transform: none;
  }

  .header-flash-alert__label,
  .header-flash-alert__text,
  .header-flash-alert__action,
  .header-flash-alert__input,
  .header-flash-alert__close {
    opacity: 1;
  }
}

/* ============================================
   FORMULARIOS GBOOK — shell global (inputs + foco + secciones)
   Alcance por defecto: #kt_app_content (base_layout), drawers de calendario/paciente,
   modales Bootstrap y .gbook-form-shell opt-in.
   Ver core/static/core/estilos-gbook.md § Formularios en paneles.
   ============================================ */

/* Card sección: fondo vía clase Keen bg-light en HTML (var --bs-light = theme-aware) */
.card.gbook-form-section-card {
  --bs-card-bg: var(--bs-light, #f8f9fa);
  --bs-card-box-shadow: none;
  background-color: var(--bs-light, #f8f9fa) !important;
  border-color: var(--bs-gray-300, #e1e3ea) !important;
  box-shadow: none !important;
}

.gbook-form-section-card {
  background-color: var(--bs-light, #f8f9fa);
  border: 1px solid var(--bs-gray-300, #e1e3ea);
}

/* Panel anidado: clase Keen bg-gray-200 en HTML; inputs un tono más oscuro */
.gbook-form-nested-panel {
  border: 1px solid var(--bs-gray-300, #e1e3ea);
}

.gbook-form-nested-panel .form-control:not(.form-control-flush):not(.no-gbook-input),
.gbook-form-nested-panel .form-select:not(.no-gbook-input),
.gbook-form-nested-panel textarea.form-control:not(.no-gbook-input) {
  background-color: var(--bs-gray-300, #e1e3ea) !important;
  border-color: var(--bs-gray-300, #e1e3ea) !important;
}

/* --- Controles: fondo gray-200, borde gray-300, radio rounded-3 --- */
#kt_app_content .form-control:not(.form-control-flush):not(.no-gbook-input),
#kt_app_content .form-select:not(.no-gbook-input),
#kt_app_content textarea.form-control:not(.no-gbook-input),
#kt_modal_create_patient_inline .form-control,
#kt_modal_create_patient_inline .form-select,
#kt_modal_create_patient_inline textarea.form-control,
#kt_drawer_create_appointment .form-control,
#kt_drawer_create_appointment .form-select,
#kt_drawer_create_appointment textarea.form-control,
#kt_drawer_edit_appointment .form-control,
#kt_drawer_edit_appointment .form-select,
#kt_drawer_edit_appointment textarea.form-control,
#kt_drawer_create_time_block .form-control,
#kt_drawer_create_time_block .form-select,
.fc-appointment-form-popover .form-control,
.fc-appointment-form-popover .form-select,
.fc-appointment-form-popover textarea.form-control,
.fc-appointment-popover .form-control,
.fc-appointment-popover .form-select,
.fc-appointment-popover textarea.form-control,
#kt_modal_add_user .form-control,
#kt_modal_add_user .form-select,
.modal .form-control:not(.form-control-flush):not(.no-gbook-input),
.modal .form-select:not(.no-gbook-input),
.modal textarea.form-control:not(.no-gbook-input),
.gbook-form-shell .form-control:not(.form-control-flush):not(.no-gbook-input),
.gbook-form-shell .form-select:not(.no-gbook-input),
.gbook-form-shell textarea.form-control:not(.no-gbook-input),
.gbook-form-inputs-on-gray .form-control,
.gbook-form-inputs-on-gray .form-select,
.gbook-form-inputs-on-gray textarea.form-control {
  background-color: var(--ig-input-bg, var(--bs-gray-200, #f1f1f2)) !important;
  border-color: var(--bs-gray-300, #e1e3ea) !important;
  border-radius: var(--bs-border-radius-lg, 0.5rem) !important;
}

#kt_app_content .form-control:disabled,
#kt_app_content .form-select:disabled,
#kt_modal_create_patient_inline .form-control:disabled,
#kt_modal_create_patient_inline .form-select:disabled,
#kt_drawer_create_appointment .form-control:disabled,
#kt_drawer_create_appointment .form-select:disabled,
#kt_drawer_edit_appointment .form-control:disabled,
#kt_drawer_edit_appointment .form-select:disabled,
.fc-appointment-form-popover .form-control:disabled,
.fc-appointment-form-popover .form-select:disabled,
.fc-appointment-popover .form-control:disabled,
.fc-appointment-popover .form-select:disabled,
.gbook-form-shell .form-control:disabled,
.gbook-form-shell .form-select:disabled,
.gbook-form-inputs-on-gray .form-control:disabled,
.gbook-form-inputs-on-gray .form-select:disabled {
  background-color: var(--ig-input-bg, var(--bs-gray-200, #f1f1f2)) !important;
  opacity: 0.88;
}

/* Select2 / contenedor con borde en drawers */
#kt_drawer_create_appointment .drawer-select-border,
#kt_drawer_edit_appointment .drawer-select-border,
#kt_modal_create_patient_inline .drawer-select-border,
.fc-appointment-form-popover .drawer-select-border,
.gbook-form-shell .drawer-select-border {
  background-color: var(--ig-input-bg, var(--bs-gray-200, #f1f1f2)) !important;
  border-color: var(--bs-gray-300, #e1e3ea) !important;
}

/* --- Foco: borde azul sin anillo doble (todos los controles del shell) --- */
#kt_app_content .form-control:focus:not(.is-invalid):not(:disabled),
#kt_app_content .form-select:focus:not(.is-invalid):not(:disabled),
#kt_modal_create_patient_inline .form-control:focus:not(.is-invalid):not(:disabled),
#kt_modal_create_patient_inline .form-select:focus:not(.is-invalid):not(:disabled),
#kt_drawer_create_appointment .form-control:focus:not(.is-invalid):not(:disabled),
#kt_drawer_create_appointment .form-select:focus:not(.is-invalid):not(:disabled),
#kt_drawer_edit_appointment .form-control:focus:not(.is-invalid):not(:disabled),
#kt_drawer_edit_appointment .form-select:focus:not(.is-invalid):not(:disabled),
#kt_drawer_create_time_block .form-control:focus:not(.is-invalid):not(:disabled),
.fc-appointment-form-popover .form-control:focus:not(.is-invalid):not(:disabled),
.fc-appointment-form-popover .form-select:focus:not(.is-invalid):not(:disabled),
.fc-appointment-popover .form-control:focus:not(.is-invalid):not(:disabled),
.fc-appointment-popover .form-select:focus:not(.is-invalid):not(:disabled),
.fc-appointment-popover .focus-ring:focus:not(.is-invalid),
.fc-appointment-popover .focus-ring:focus-visible:not(.is-invalid),
#kt_modal_add_user .form-control:focus:not(.is-invalid):not(:disabled),
#kt_modal_add_user .form-select:focus:not(.is-invalid):not(:disabled),
.modal .form-control:focus:not(.is-invalid):not(:disabled),
.modal .form-select:focus:not(.is-invalid):not(:disabled),
.gbook-form-shell .form-control:focus:not(.is-invalid):not(:disabled),
.gbook-form-shell .form-select:focus:not(.is-invalid):not(:disabled),
.gbook-form-inputs-drawer-style .form-control:focus:not(.is-invalid):not(:disabled),
.gbook-form-inputs-drawer-style .form-select:focus:not(.is-invalid):not(:disabled),
#kt_app_content .focus-ring:focus:not(.is-invalid),
#kt_app_content .focus-ring:focus-visible:not(.is-invalid),
#kt_modal_add_user .focus-ring:focus:not(.is-invalid),
#kt_modal_add_user .focus-ring:focus-visible:not(.is-invalid),
.gbook-form-inputs-drawer-style .focus-ring:focus:not(.is-invalid),
.gbook-form-inputs-drawer-style .focus-ring:focus-visible:not(.is-invalid) {
  box-shadow: none !important;
  outline: none !important;
  border-color: #007bff !important;
}

#kt_app_content .form-control.is-invalid:focus,
#kt_app_content .form-select.is-invalid:focus,
#kt_modal_add_user .focus-ring.is-invalid:focus,
#kt_modal_add_user .focus-ring.is-invalid:focus-visible,
.gbook-form-inputs-drawer-style .focus-ring.is-invalid:focus,
.gbook-form-inputs-drawer-style .focus-ring.is-invalid:focus-visible,
.fc-appointment-popover .form-control.is-invalid:focus,
.fc-appointment-popover .form-select.is-invalid:focus,
.fc-appointment-popover .focus-ring.is-invalid:focus,
.fc-appointment-popover .focus-ring.is-invalid:focus-visible,
.gbook-form-shell .form-control.is-invalid:focus,
.gbook-form-shell .form-select.is-invalid:focus {
  box-shadow: none !important;
  outline: none !important;
  border-color: var(--bs-form-invalid-border-color, #dc3545) !important;
}

/* ============================================
   GBOOK DRAWER CHROME — header / footer
   Referencia canónica: #kt_drawer_create_appointment
   Ver core/static/core/estilos-gbook.md § Chrome de drawers.
   ============================================ */

/* Shell lateral: padding horizontal uniforme en formularios drawer */
#kt_drawer_create_appointment .drawer-appointment-shell,
#kt_drawer_create_appointment .drawer-appointment-content,
#kt_modal_create_patient_inline .drawer-patient-content,
#kt_drawer_create_time_block .drawer-time-block-content,
#kt_drawer_appointment .appointment-workspace-drawer__shell,
#kt_drawer_appointment_payments .appointment-pos-drawer__shell {
  box-sizing: border-box;
  padding-left: 2.25rem;
  padding-right: 2.25rem;
}

/* Header: py-2 compacto (0.5rem arriba/abajo) */
.gbook-drawer-header,
#kt_drawer_create_appointment .drawer-appointment-header,
#kt_drawer_create_appointment .drawer-appointment-patient-header,
#kt_modal_create_patient_inline .drawer-patient-header,
#kt_drawer_appointment .appointment-workspace-drawer__header,
#kt_drawer_appointment_payments .appointment-pos-drawer__header,
#kt_drawer_create_time_block .drawer-time-block-header {
  flex-shrink: 0;
  border-bottom: 1px solid var(--bs-border-color, #e1e3ea) !important;
  padding-top: 0.5rem !important;
  padding-bottom: 0.5rem !important;
  background: var(--bs-body-bg, #fff);
}

/* Título de una línea (Crear atención, Nuevo paciente, etc.) */
.gbook-drawer-header .gbook-drawer-title,
#kt_drawer_create_appointment .drawer-appointment-header h2,
#kt_modal_create_patient_inline .drawer-patient-header h2,
#kt_drawer_appointment .appointment-workspace-drawer__header h2,
#kt_drawer_appointment_payments .appointment-pos-drawer__header h2 {
  font-size: 0.95rem;
  line-height: 1.25;
}

/* Botón cerrar estándar en header drawer */
.gbook-drawer-header .gbook-drawer-close,
#kt_drawer_create_appointment .drawer-appointment-header .btn-icon,
#kt_modal_create_patient_inline .drawer-patient-header .btn-icon {
  width: 30px;
  height: 30px;
  min-width: 30px;
  min-height: 30px;
}

/* Footer: pt-3 pb-4 (1rem / 1.5rem) + sombra superior */
.gbook-drawer-footer,
#kt_drawer_create_appointment .drawer-appointment-footer,
#kt_drawer_create_appointment .drawer-appointment-patient-footer,
#kt_modal_create_patient_inline .drawer-patient-footer,
#kt_drawer_appointment .appointment-workspace-drawer__footer,
#kt_drawer_appointment_payments .appointment-pos-drawer__footer,
#kt_drawer_create_time_block .drawer-time-block-footer {
  flex-shrink: 0;
  border-top: 1px solid var(--bs-border-color, #e1e3ea) !important;
  padding-top: 1rem !important;
  padding-bottom: 1.5rem !important;
  background: var(--bs-body-bg, #fff);
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.04);
  z-index: 2;
}

/* Footer a ancho completo dentro del shell con padding 2.25rem */
.gbook-drawer-footer,
#kt_drawer_create_appointment .drawer-appointment-footer,
#kt_drawer_create_appointment .drawer-appointment-patient-footer,
#kt_modal_create_patient_inline .drawer-patient-footer,
#kt_drawer_appointment .appointment-workspace-drawer__footer,
#kt_drawer_appointment_payments .appointment-pos-drawer__footer,
#kt_drawer_create_time_block .drawer-time-block-footer {
  margin-left: -2.25rem;
  margin-right: -2.25rem;
  padding-left: 2.25rem;
  padding-right: 2.25rem;
}

/* intl-tel-input v29: ver core/static/core/css/intl-tel-input-gbook-theme.css
   (debe cargarse después del CDN intlTelInput.css en cada plantilla que lo use). */

/* =============================================================================
   SweetAlert2 — estilo "gbook-swal" GLOBAL (theme-aware)
   Popup discreto tipo Linear/Stripe: fondo del tema, 1px de borde, sin sombra.
   Se usa con customClass: { popup: 'gbook-swal' }. Canónico aquí (global);
   calendar.css conserva una copia idéntica para su propio contexto.
   ============================================================================= */
.swal2-popup.gbook-swal {
  background-color: var(--bs-body-bg) !important;
  color: var(--bs-body-color) !important;
  border: 1px solid var(--bs-border-color) !important;
  border-radius: 1rem !important;
  box-shadow: none !important;
  padding: 1.5rem 1.5rem 1.25rem !important;
  width: 22rem !important;
  max-width: calc(100vw - 2rem) !important;
}

/* Icono compacto */
.swal2-popup.gbook-swal .swal2-icon {
  width: 2.75rem !important;
  height: 2.75rem !important;
  margin: 0.25rem auto 0.75rem !important;
  border-width: 2px !important;
}

/* Variante warning (--bs-warning) */
.swal2-popup.gbook-swal .swal2-icon.swal2-warning {
  border-color: var(--bs-warning) !important;
  color: var(--bs-warning) !important;
  background-color: transparent !important;
}
.swal2-popup.gbook-swal .swal2-icon.swal2-warning .swal2-icon-content {
  color: var(--bs-warning) !important;
  font-size: 1.5rem !important;
  line-height: 1 !important;
  font-weight: 600 !important;
}

/* Ícono de éxito: un SOLO ícono Keen inyectado con iconHtml. Quitamos el
   anillo/relleno del contenedor nativo para que no se vea un círculo extra ni
   las piezas encimadas del success de SweetAlert. */
.swal2-popup.gbook-swal .swal2-icon.swal2-success {
  border: none !important;
  background-color: transparent !important;
  width: auto !important;
  height: auto !important;
  min-height: 0 !important;
}
.swal2-popup.gbook-swal .swal2-icon.swal2-success .swal2-icon-content {
  color: var(--bs-success) !important;
  font-size: 3rem !important;
  line-height: 1 !important;
}

/* Barra de progreso del timer con color de marca */
.swal2-popup.gbook-swal .swal2-timer-progress-bar {
  background-color: rgba(var(--bs-primary-rgb), 0.35) !important;
}

/* Tipografía del título y del cuerpo */
.swal2-popup.gbook-swal .swal2-title {
  color: var(--bs-body-color) !important;
  font-weight: 600 !important;
  font-size: 1rem !important;
  line-height: 1.35 !important;
  margin: 0 0 0.4rem !important;
  padding: 0 !important;
}
.swal2-popup.gbook-swal .swal2-html-container {
  color: var(--bs-secondary-color) !important;
  font-size: 0.8125rem !important;
  line-height: 1.5 !important;
  margin: 0 0 1.25rem !important;
  padding: 0 !important;
}

/* Acciones: centradas, mismo gap si hubiera 2 botones */
.swal2-popup.gbook-swal .swal2-actions {
  gap: 0.5rem !important;
  margin: 0 !important;
  width: 100% !important;
  justify-content: center !important;
}
.swal2-popup.gbook-swal .swal2-actions .swal2-styled {
  margin: 0 !important;
  min-width: 8rem !important;
}

/* Caso "un solo botón": ghost theme-aware */
.swal2-popup.gbook-swal .swal2-actions .swal2-styled:only-child {
  background-color: var(--bs-body-bg) !important;
  border: 1px solid var(--bs-gray-300) !important;
  color: var(--bs-body-color) !important;
  font-weight: 500 !important;
}
.swal2-popup.gbook-swal .swal2-actions .swal2-styled:only-child:hover {
  background-color: var(--bs-gray-100) !important;
  border-color: var(--bs-gray-400) !important;
  color: var(--bs-body-color) !important;
}
.swal2-popup.gbook-swal .swal2-actions .swal2-styled:only-child:focus,
.swal2-popup.gbook-swal .swal2-actions .swal2-styled:only-child:focus-visible {
  box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.2) !important;
  outline: none !important;
}

/* =============================================================================
   BOTÓN GHOST — .gbook-btn-ghost (GLOBAL, reutilizable)

   Acción secundaria que no debe competir con nada: sin fondo, sin borde, sin
   sombra. Solo texto Ink soft que se "enciende" al hover con un tinte mínimo
   de Ink. Es el lenguaje que ya usaban los botones de la nota clínica
   (.gcc-ai-ghostbtn en clinical-note-page.css); aquí queda extraído como clase
   global y theme-aware para poder aplicarlo en cualquier vista.

   Cuándo usarlo: acciones de apoyo dentro de un formulario o card — "Agregar
   otro día", "Seleccionar todos", toggles, atajos. NUNCA para la acción
   primaria de un panel (esa es btn-primary) ni para Cancelar/Guardar de un
   drawer, que conservan su par btn-light / btn-primary.

   Uso:
     <button type="button" class="btn btn-sm gbook-btn-ghost">Agregar otro día</button>
     <button type="button" class="btn btn-sm gbook-btn-ghost" aria-pressed="true">…</button>  ← toggle: + .active

   Variantes:
     .gbook-btn-ghost--primary   → texto primary (para el ghost que "sugiere" la acción esperada)
     .gbook-btn-ghost--danger    → hover en rojo (acciones destructivas suaves)
     .active                     → estado presionado de un toggle (tinte primary)

   Los colores salen de tokens Bootstrap/Keen, así que en tema oscuro se
   invierten solos (gray-600/gray-900 → Ink soft / Ink en claro; escala Keen en
   oscuro). Se usa !important en lo mínimo indispensable para vencer a .btn de
   Bootstrap sin tener que escribir selectores anidados en cada vista.
   ============================================================================= */
.gbook-btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border: 0 !important;
  background: transparent !important;
  padding: 0.45rem 0.75rem;
  border-radius: 0.7rem !important;
  color: var(--bs-gray-600);
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: none !important;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.gbook-btn-ghost:hover,
.gbook-btn-ghost:focus-visible {
  /* Tinte del 6% del Ink: suficiente para acusar recibo del hover sin dibujar
     un botón sólido. color-mix con fallback en rgba para navegadores viejos. */
  background: rgba(21, 23, 29, 0.06) !important;
  background: color-mix(in srgb, var(--bs-gray-900) 6%, transparent) !important;
  color: var(--bs-gray-900);
}

.gbook-btn-ghost:disabled,
.gbook-btn-ghost.disabled {
  opacity: 0.45;
  cursor: default;
  background: transparent !important;
  color: var(--bs-gray-600);
}

/* Toggle presionado */
.gbook-btn-ghost.active {
  background: rgba(var(--bs-primary-rgb), 0.1) !important;
  color: var(--bs-primary);
  font-weight: 600;
}

.gbook-btn-ghost.active:hover {
  background: rgba(var(--bs-primary-rgb), 0.16) !important;
  color: var(--bs-primary);
}

/* Variante primary: el ghost que insinúa la acción esperada del bloque */
.gbook-btn-ghost--primary {
  color: var(--bs-primary);
  font-weight: 600;
}

.gbook-btn-ghost--primary:hover,
.gbook-btn-ghost--primary:focus-visible {
  background: rgba(var(--bs-primary-rgb), 0.1) !important;
  color: var(--bs-primary);
}

/* Variante danger: neutro en reposo, rojo al hover */
.gbook-btn-ghost--danger:hover,
.gbook-btn-ghost--danger:focus-visible {
  background: rgba(var(--bs-danger-rgb), 0.1) !important;
  color: var(--bs-danger);
}

/* En tema oscuro el tinte de hover va en blanco (el Ink oscuro no se vería) */
[data-bs-theme="dark"] .gbook-btn-ghost:hover,
[data-bs-theme="dark"] .gbook-btn-ghost:focus-visible {
  background: rgba(255, 255, 255, 0.08) !important;
  color: var(--bs-body-color);
}
