/* ============================================================
   Kulvio Design System — main.css
   Professional compliance platform (Chile Ley 19.628 / 21.719)
   ============================================================ */

/* --- Custom Properties (Design Tokens) --- */
:root {
  /* Primary — deep navy with teal accent */
  --color-primary: #1B3A5C;
  --color-primary-light: #EBF0F7;
  --color-primary-dark: #0F2440;
  --color-primary-hover: #264D73;
  --color-accent: #0EA5A0;
  --color-accent-light: #E6F7F7;
  --color-accent-hover: #0C8C88;

  /* Semantic */
  /* Verde, rojo y gris apagado, un tono más oscuro que en Kulvio para llegar a 4,5:1 (WCAG AA):
     el blanco sobre el verde y el rojo, y los dos como texto sobre su fondo claro y sobre el
     de la página (contraste y celular, 04-10-2026). El verde es el de los botones de PlanVital
     que Soluticket ya usaba (.btn-success); el rojo, el que Kulvio tenía al pasar el mouse. */
  --color-success: #0B7A45;
  --color-success-light: #ECFDF3;
  --color-danger: #C82333;
  --color-danger-light: #FEF2F2;
  --color-danger-hover: #A71D2A;
  --color-warning: #F59E0B;
  --color-warning-light: #FFFBEB;
  --color-warning-hover: #D97706;
  /* Ámbar oscuro para TEXTO sobre `--color-warning-light`: 6.8:1, cumple AA
     también a 12px (`--color-warning-hover` sobre tarjeta solo llega a 3.2:1).
     Es el par de contraste que `.badge-yellow` y `.status-badge--pending` ya
     usaban como literal. */
  --color-warning-text: #92400E;
  --color-info: #1B3A5C;
  --color-info-light: #EBF0F7;

  /* Neutrals */
  --color-bg: #F4F6F9;
  --color-bg-card: #FFFFFF;
  --color-bg-muted: #F0F2F5;
  --color-text: #1A1D26;
  --color-text-secondary: #5A6178;
  --color-text-muted: #676C7A;
  --color-border: #CDD2DB;
  --color-border-light: #E2E5EB;
  /* El borde de los campos: 3:1 con la tarjeta y con la página (WCAG 1.4.11). */
  --color-border-input: #858C9E;
  --color-row-hover: #F0F3F7;
  --color-row-stripe: #F8F9FB;

  /* Typography */
  --font-heading: 'Plus Jakarta Sans', system-ui, -apple-system, sans-serif;
  --font-body: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono: ui-monospace, 'Cascadia Code', 'Segoe UI Mono', monospace;
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 0.9375rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
  --text-3xl: 2rem;

  /* Spacing (8px grid) */
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
  --space-2xl: 3rem;

  /* Borders & Shadows */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-full: 9999px;
  --shadow-sm: 0 1px 2px rgba(15, 36, 64, 0.05);
  --shadow-md: 0 2px 6px rgba(15, 36, 64, 0.08), 0 1px 2px rgba(15, 36, 64, 0.04);
  --shadow-lg: 0 8px 24px rgba(15, 36, 64, 0.1), 0 2px 8px rgba(15, 36, 64, 0.06);

  /* Layout */
  --sidebar-width: 260px;
  --sidebar-collapsed-width: 64px;
  --navbar-height: 56px;
  --content-max-width: 1200px;

  /* Transitions */
  --transition: 150ms ease;
  --transition-smooth: 250ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-spring: 350ms cubic-bezier(0.34, 1.56, 0.64, 1);
}



/* --- Reduced Motion --- */
@media (prefers-reduced-motion: reduce) {
  /* Sin esperas tampoco: las entradas escalonadas (.kpi-card) y el retardo que oculta el menú del
     teléfono (contraste y celular, 04-10-2026). */
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
  }
}

/* --- Reset & Base --- */
*, *::before, *::after { box-sizing: border-box; }

/* La navbar es fija: compensa el anclaje (#contextual-help, #eipd, etc.)
   para que el salto no quede tapado bajo ella. */
html { scroll-padding-top: var(--navbar-height); }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0 0 var(--space-sm);
  line-height: 1.2;
  font-weight: 700;
  font-family: var(--font-heading);
  letter-spacing: -0.01em;
}
h1 { font-size: var(--text-3xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }
h4 { font-size: var(--text-lg); }

p { margin: 0 0 var(--space-md); }

a {
  color: var(--color-primary);
  text-decoration: none;
}
a:hover { text-decoration: underline; }

code, .mono {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

img { max-width: 100%; height: auto; }

/* --- App Layout (Sidebar + Main) --- */
.app-layout {
  /* flow-root: alto natural (el documento scrollea) + BFC para que el
     margin-top de .main-content no colapse y deje el contenido bajo la navbar. */
  display: flow-root;
  min-height: 100vh;
}

/* --- Navbar --- */
.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: 0 var(--space-lg);
  background: var(--color-bg-card);
  border-bottom: 1px solid var(--color-border-light);
  height: var(--navbar-height);
  z-index: 100;
  min-width: 0;
  box-shadow: 0 1px 3px rgba(15, 36, 64, 0.04);
}

.navbar-brand {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-weight: 800;
  font-size: var(--text-lg);
  font-family: var(--font-heading);
  color: var(--color-primary);
  width: calc(var(--sidebar-width) - var(--space-lg) * 2);
  flex-shrink: 0;
  letter-spacing: -0.02em;
}

.navbar-brand span { color: var(--color-text); font-weight: 400; font-size: var(--text-sm); }

.navbar-center {
  flex: 1;
  min-width: 0;
}

.navbar-org {
  display: inline-block;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  padding: var(--space-xs) var(--space-sm);
  background: var(--color-bg);
  border-radius: var(--radius-sm);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.navbar-actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.navbar-user {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

/* Hamburger toggle — hidden on desktop, shown ≤768px via the media query. */
.navbar-hamburger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  cursor: pointer;
  flex-shrink: 0;
}
.navbar-hamburger:hover { background: var(--color-bg); }

/* Off-canvas backdrop — only rendered (display:block) on mobile when open. */
.sidebar-backdrop { display: none; }

/* --- Sidebar --- */
.sidebar {
  position: fixed;
  top: var(--navbar-height);
  left: 0;
  bottom: 0;
  z-index: 90;
  background: var(--color-bg-card);
  border-right: 1px solid var(--color-border-light);
  padding: var(--space-md) 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: width var(--transition-smooth);
  width: var(--sidebar-width);
}

.sidebar-section {
  padding: var(--space-xs) var(--space-lg);
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
  margin-top: var(--space-lg);
}

.sidebar-section:first-child { margin-top: 0; }

.sidebar-nav { list-style: none; margin: 0; padding: 0; flex: 1; overflow-y: auto; }
.sidebar-nav::-webkit-scrollbar { width: 4px; }
.sidebar-nav::-webkit-scrollbar-track { background: transparent; }
.sidebar-nav::-webkit-scrollbar-thumb { background: var(--color-border-light); border-radius: 4px; }

.sidebar-footer {
  padding: var(--space-sm) var(--space-lg);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  border-top: 1px solid var(--color-border-light);
  text-align: center;
  flex-shrink: 0;
}

.sidebar-item a {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: 7px var(--space-lg);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  transition: all var(--transition-smooth);
  border-left: 3px solid transparent;
  text-decoration: none;
  position: relative;
}

.sidebar-item a:hover {
  background: var(--color-bg);
  color: var(--color-text);
  text-decoration: none;
}

.sidebar-item a:hover .sidebar-icon {
  color: var(--color-accent);
  transform: scale(1.08);
}

.sidebar-item--active a {
  color: var(--color-primary);
  background: var(--color-primary-light);
  border-left-color: var(--color-accent);
  font-weight: 600;
}

.sidebar-item--active a .sidebar-icon {
  color: var(--color-accent);
}

.sidebar-icon {
  width: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: all var(--transition-smooth);
  color: inherit;
}

.sidebar-icon svg {
  width: 18px;
  height: 18px;
}

.sidebar-group {
  list-style: none;
  margin: 0;
  padding: 0;
}
.sidebar-group-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-lg);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  cursor: pointer;
  transition: all var(--transition);
  border-left: 3px solid transparent;
  user-select: none;
}
.sidebar-group-toggle:hover {
  background: var(--color-bg);
  color: var(--color-text);
}
.sidebar-group--open > .sidebar-group-toggle {
  color: var(--color-text);
}
.sidebar-chevron {
  margin-left: auto;
  transition: transform 0.2s ease;
  flex-shrink: 0;
}
.sidebar-group--open > .sidebar-group-toggle > .sidebar-chevron {
  transform: rotate(90deg);
}
.sidebar-group-items {
  display: none;
  list-style: none;
  margin: 0;
  padding: 0;
}
.sidebar-group--open > .sidebar-group-items {
  display: block;
}
.sidebar-group-items > .sidebar-item {
  list-style: none;
}
.sidebar-group-items > .sidebar-item a {
  padding-left: calc(var(--space-lg) + 28px);
  font-size: var(--text-sm);
}

/* --- Sidebar Franjas (IA en 4 franjas, P3) --- */
/* Encabezado de franja: variante destacada de .sidebar-section que separa los
   4 grandes bloques (Inicio y Ruta · Núcleo PDP · Módulos · Configuración y Admin). */
.sidebar-franja {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-top: var(--space-xl);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--color-border-light);
  color: var(--color-text-secondary);
  font-size: 0.7rem;
}
.sidebar-franja:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}
/* Sub-encabezado dentro de una franja (Puesta en marcha, Inventario y riesgo,
   Derechos y titulares, Terceros, Gestión permanente, Configuración, etc.). */
.sidebar-subsection {
  padding: var(--space-xs) var(--space-lg);
  margin-top: var(--space-sm);
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-muted);
}

/* --- Insignias de navegación (Base / Módulo / estado ON·OFF) --- */
.nav-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.6rem;
  font-weight: 700;
  line-height: 1;
  padding: 2px 6px;
  border-radius: var(--radius-full);
  letter-spacing: 0.02em;
  text-transform: none;
}
/* Píldora "Base" — identifica el núcleo PDP (siempre incluido). */
.nav-badge--base {
  background: var(--color-accent-light);
  color: var(--color-accent-hover);
}
/* Píldora "Módulo" — identifica capacidades activables por plan. */
.nav-badge--module {
  background: var(--color-primary-light);
  color: var(--color-primary);
}
/* Estado por módulo: ● activo / ○ inactivo. */
.nav-badge--on {
  margin-left: auto;
  padding: 0;
  color: var(--color-success);
  font-size: 0.7rem;
}
.nav-badge--off {
  margin-left: auto;
  padding: 0;
  color: var(--color-text-muted);
  font-size: 0.7rem;
}
/* Cuando la insignia de estado vive en un .sidebar-group-toggle, el chevron va
   después: separar con margen para no pegar ● al chevron. */
.sidebar-group-toggle > .nav-badge--on,
.sidebar-group-toggle > .nav-badge--off {
  margin-left: auto;
  margin-right: var(--space-xs);
}
.sidebar-group-toggle > .nav-badge--on + .sidebar-chevron,
.sidebar-group-toggle > .nav-badge--off + .sidebar-chevron {
  margin-left: 0;
}

/* Entrada de módulo sin páginas propias (ISO 27001/27701) o módulo OFF:
   se muestra atenuada pero sigue presente y enlazable a Configuración › Módulos. */
.sidebar-item--module > a .nav-badge--on,
.sidebar-item--module > a .nav-badge--off {
  margin-left: auto;
}
.sidebar-item--module-off > a {
  color: var(--color-text-muted);
}
.sidebar-item--module-off > a .sidebar-icon {
  opacity: 0.6;
}
/* Hint "Activar módulo…" dentro de un grupo de módulo apagado. */
.sidebar-item--module-hint > a {
  color: var(--color-text-muted);
  font-style: italic;
}

/* --- Main Content --- */
.main-content {
  /* Offsets para no quedar bajo la navbar/sidebar fijos. Alto natural:
     el documento hace el scroll del contenido. */
  margin-top: var(--navbar-height);
  margin-left: var(--sidebar-width);
  padding: var(--space-xl);
  min-width: 0;
}

.page-header {
  margin-bottom: var(--space-xl);
}

.page-header h1 {
  font-size: var(--text-2xl);
  margin-bottom: var(--space-xs);
  font-family: var(--font-heading);
  letter-spacing: -0.02em;
}

.page-header p {
  color: var(--color-text-secondary);
  margin: 0;
}

/* --- Cards --- */
.card {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition-smooth), border-color var(--transition-smooth);
}

.card:hover {
  box-shadow: var(--shadow-md);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-md);
}

.card-title {
  font-size: var(--text-lg);
  font-weight: 700;
  font-family: var(--font-heading);
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: var(--space-md);
}

/* --- Buttons --- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  padding: 10px 20px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1;
  border: 1.5px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: all var(--transition-smooth);
  text-decoration: none;
  position: relative;
}

.btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.btn:disabled, .btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

.btn:active:not(:disabled) {
  transform: scale(0.97);
}

.btn svg { width: 16px; height: 16px; flex-shrink: 0; }
.btn-sm svg { width: 14px; height: 14px; }
.btn-lg svg { width: 18px; height: 18px; }

.btn-primary {
  background: var(--color-primary);
  color: #FFF;
  border-color: var(--color-primary);
  box-shadow: 0 1px 3px rgba(27, 58, 92, 0.25);
}
.btn-primary:hover { background: var(--color-primary-hover); border-color: var(--color-primary-hover); box-shadow: 0 2px 6px rgba(27, 58, 92, 0.3); }

.btn-secondary {
  background: transparent;
  color: var(--color-primary);
  border-color: var(--color-border);
}
.btn-secondary:hover { background: var(--color-primary-light); border-color: var(--color-primary); }

.btn-danger {
  background: transparent;
  color: var(--color-danger);
  border-color: var(--color-danger);
}
.btn-danger:hover { background: var(--color-danger-light); }

.btn-danger-solid {
  background: var(--color-danger);
  color: #FFF;
  border-color: var(--color-danger);
  box-shadow: 0 1px 3px rgba(220, 53, 69, 0.25);
}
.btn-danger-solid:hover { background: var(--color-danger-hover); border-color: var(--color-danger-hover); }

.btn-warning {
  background: var(--color-warning);
  color: var(--color-text);
  border-color: var(--color-warning);
}
.btn-warning:hover { background: var(--color-warning-hover); border-color: var(--color-warning-hover); }

.btn-ghost {
  background: transparent;
  color: var(--color-text-secondary);
  border-color: transparent;
}
.btn-ghost:hover { background: var(--color-bg); color: var(--color-text); }

.btn-sm { padding: 6px 12px; font-size: var(--text-xs); }
.btn-lg { padding: 14px 28px; font-size: var(--text-base); }
.btn-block { width: 100%; }

/* --- Forms --- */
.form-group {
  margin-bottom: var(--space-md);
}

.form-label {
  display: block;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text);
  margin-bottom: var(--space-xs);
}

.form-input {
  display: block;
  width: 100%;
  padding: 10px 12px;
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--color-text);
  background: var(--color-bg-card);
  border: 1.5px solid var(--color-border-input);
  border-radius: var(--radius-sm);
  transition: border-color var(--transition-smooth), box-shadow var(--transition-smooth);
}

.form-input:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(14, 165, 160, 0.12);
}

.form-input::placeholder { color: var(--color-text-muted); }

.form-input:disabled,
.form-input[readonly] {
  background: var(--color-bg-muted);
  color: var(--color-text-secondary);
  cursor: not-allowed;
}

.form-input--error {
  border-color: var(--color-danger);
}
.form-input--error:focus {
  /* Repone el borde rojo: `.form-input:focus` (misma especificidad 0,2,0) lo
     pintaría en color acento al enfocar un control en error. Al ir después en
     el archivo, esta declaración gana el desempate y el borde queda rojo. */
  border-color: var(--color-danger);
  box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.15);
}

/* Marca de error aplicada desde JS a los controles que no llevan .form-input y
   necesitan dibujar el borde rojo por su cuenta. Los campos de archivo NO la
   usan: tienen su propio estado (.file-field--error, ver «Campo de archivo»),
   porque el input real es transparente y el borde lo dibuja el disparador. Se
   acompaña siempre de aria-invalid en el elemento y del mensaje por toast: el
   borde rojo por sí solo no comunica nada a quien navega con lector de
   pantalla. */
.has-error {
  border: 1.5px solid var(--color-danger);
  border-radius: var(--radius-sm);
  padding: 6px;
}
.has-error:focus,
.has-error:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.15);
}

.form-error {
  font-size: var(--text-sm);
  color: var(--color-danger);
  margin-top: var(--space-xs);
}

.form-hint {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-top: var(--space-xs);
}

select.form-input {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%236B7280' viewBox='0 0 16 16'%3E%3Cpath d='M8 11L3 6h10z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 36px;
}

textarea.form-input {
  min-height: 100px;
  resize: vertical;
}

/* --- Searchable Select --- */
/* Lista con buscador (static/js/select-search.js), como el select2 de PlanVital. El <select>
   nativo queda en su lugar y define el tamaño; encima va el campo que se ve (.ss-trigger), y el
   panel (.ss-dropdown) se abre en la capa superior (popover), así ningún modal lo recorta. */
.ss-wrap {
  position: relative;
}

/* Invisible pero no display:none ni hidden: así se sigue enviando, conserva el tamaño que le
   dan las reglas de cada pantalla, el navegador puede mostrar su aviso de `required` y
   Playwright puede elegir una opción. Se oculta desde CSS y no con style: HTMX repone el style
   del servidor al aparear por id. */
.ss-wrap > select {
  opacity: 0;
  pointer-events: none;
}

.ss-trigger {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  cursor: pointer;
  text-align: left;
  line-height: 1.5;
  user-select: none;
}

.ss-wrap > select:focus + .ss-trigger {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(14, 165, 160, 0.12);
}

.ss-trigger[aria-disabled="true"] {
  background: var(--color-bg-muted);
  color: var(--color-text-secondary);
  cursor: not-allowed;
}

.ss-trigger__value {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ss-trigger__chevron {
  flex-shrink: 0;
  color: var(--color-text-muted);
  transition: transform var(--transition);
  display: flex;
  align-items: center;
}

.ss-wrap--open .ss-trigger__chevron {
  transform: rotate(180deg);
}

.ss-wrap--open .ss-trigger {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(14, 165, 160, 0.12);
}

/* Sin popover (navegadores viejos) el panel es fijo igual; JS le pone top, left y width. */
.ss-dropdown {
  position: fixed;
  inset: auto;
  margin: 0;
  padding: 0;
  z-index: 1000;
  overflow: hidden;
  color: var(--color-text);
  background: var(--color-bg-card);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
}

.ss-wrap:not(.ss-wrap--open) .ss-dropdown {
  display: none;
}

.ss-search-wrap {
  padding: 6px;
}

.ss-search {
  display: block;
  width: 100%;
  padding: 6px 10px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--color-text);
  background: var(--color-bg-card);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-sm);
}

.ss-search::-webkit-search-cancel-button {
  appearance: none; /* sin la «×» de Chrome, como select2 */
}

.ss-search:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(14, 165, 160, 0.12);
}

.ss-options {
  position: relative; /* offsetTop de cada opción, para mantener la marcada a la vista */
  list-style: none;
  margin: 0;
  padding: 0 0 4px;
  max-height: min(240px, 40vh);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.ss-options::-webkit-scrollbar {
  width: 6px;
}

.ss-options::-webkit-scrollbar-track {
  background: transparent;
}

.ss-options::-webkit-scrollbar-thumb {
  background: var(--color-border);
  border-radius: 3px;
}

.ss-option {
  padding: 6px 12px;
  font-size: var(--text-sm);
  color: var(--color-text);
  cursor: pointer;
  overflow-wrap: anywhere;
}

.ss-option--selected {
  font-weight: 600;
}

/* La marcada (teclado o mouse) va en azul con letra blanca, como select2 en PlanVital; es el
   azul de las etiquetas de Soluticket (.event-label--blue), 8,4:1 con el blanco. */
.ss-option--highlighted {
  background: #1F4F8F;
  color: #fff;
}

.ss-option--disabled {
  color: var(--color-text-muted);
  cursor: not-allowed;
}

.ss-option--disabled.ss-option--highlighted {
  background: var(--color-bg-muted);
  color: var(--color-text-muted);
}

.ss-empty {
  margin: 0;
  padding: 6px 12px 10px;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* En el teléfono, 16 px: con menos, Safari agranda la página al enfocar el buscador. */
@media (max-width: 768px) {
  .ss-search {
    font-size: 16px;
  }
}

/* --- Form Sections (reusable layout for structured forms) --- */
.form-section {
  margin-bottom: var(--space-lg);
}

.form-section-header {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding-bottom: var(--space-sm);
  margin-bottom: var(--space-md);
  border-bottom: 2px solid var(--color-primary);
  font-weight: 600;
  font-size: var(--text-base);
  color: var(--color-text-primary);
}

.form-section-header svg {
  color: var(--color-accent);
  flex-shrink: 0;
}

.form-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
}

@media (max-width: 640px) {
  .form-grid-2 {
    grid-template-columns: 1fr;
  }
}

.form-group--full {
  grid-column: 1 / -1;
}

/* --- Completion Bar --- */
.form-completion {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-lg);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

.form-completion-bar {
  flex: 1;
  height: 8px;
  background: var(--color-border-light);
  border-radius: 4px;
  overflow: hidden;
}

.form-completion-fill {
  height: 100%;
  border-radius: 4px;
  transition: width 0.3s ease;
}

.form-completion--low .form-completion-fill {
  background: var(--color-warning);
}

.form-completion--mid .form-completion-fill {
  background: var(--color-accent);
}

.form-completion--full .form-completion-fill {
  background: var(--color-success);
}

/* --- Checkbox / Form Check --- */
.form-check {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  cursor: pointer;
  font-size: var(--text-sm);
  line-height: 1.4;
}

.form-check input[type="checkbox"] {
  margin-top: 2px;
  accent-color: var(--color-primary);
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  cursor: pointer;
}

.form-check-label {
  color: var(--color-text-secondary);
}

.form-check-label a {
  color: var(--color-primary);
  text-decoration: underline;
}

/* --- Tables --- */
/* .table-responsive es alias histórico de .table-wrapper: el código nuevo debe usar .table-wrapper. */
.table-wrapper,
.table-responsive { overflow-x: auto; }

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.table th, .table td {
  padding: 12px 16px;
  text-align: left;
  border-bottom: 1px solid var(--color-border-light);
}

.table th {
  background: var(--color-row-stripe);
  font-weight: 600;
  color: var(--color-text-secondary);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.table tbody tr:hover { background: var(--color-row-hover); }
.table tbody tr:nth-child(even) { background: var(--color-row-stripe); }
.table tbody tr:nth-child(even):hover { background: var(--color-row-hover); }

.table th[data-sort] {
  cursor: pointer;
  user-select: none;
}
.table th[data-sort]::after { content: " \2195"; opacity: 0.4; }

/* ── Tabs ── */
.tabs {
  display: flex;
  gap: 0;
  border-bottom: 2px solid var(--color-border);
  overflow-x: auto;
}

.tab {
  position: relative;
  padding: var(--space-sm) var(--space-lg);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text-muted);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s ease, background 0.15s ease;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
}

.tab:hover {
  color: var(--color-text);
  background: var(--color-bg-muted);
  text-decoration: none;
}

.tab--active {
  color: var(--color-primary);
  border-bottom-color: var(--color-primary);
  font-weight: 600;
}

.tab--active:hover {
  color: var(--color-primary);
}

.tab .badge {
  vertical-align: middle;
}

/* --- Alerts / Banners --- */
.alert {
  padding: var(--space-md) var(--space-md) var(--space-md) var(--space-lg);
  border-radius: var(--radius-sm);
  border-left: 4px solid;
  font-size: var(--text-sm);
  margin-bottom: var(--space-md);
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
}

/* `display: flex` en la clase le ganaría al comportamiento por defecto del
   atributo `hidden`, así que sin esta regla una alerta marcada como oculta se
   mostraría igual. Hoy ningún consumidor le pone `hidden` —el aviso de rechazo
   del constructor del widget terminó siendo condicional en Jinja, y el nodo
   solo existe si hay algo que decir—, pero la regla se queda: ocultar con
   `hidden` es lo natural, y que funcione evita tener que crear y destruir el
   nodo para lograrlo. */
.alert[hidden] {
  display: none;
}

.alert-info    { background: var(--color-info-light);    border-color: var(--color-info);    color: var(--color-primary-dark); }
.alert-success { background: var(--color-success-light); border-color: var(--color-success); }
.alert-warning { background: var(--color-warning-light); border-color: var(--color-warning); }
.alert-danger  { background: var(--color-danger-light);  border-color: var(--color-danger); }

.alert-dismiss {
  margin-left: auto;
  background: none;
  border: none;
  font-size: var(--text-lg);
  cursor: pointer;
  color: inherit;
  opacity: 0.6;
  line-height: 1;
}
.alert-dismiss:hover { opacity: 1; }

/* --- Badges --- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  font-size: var(--text-xs);
  font-weight: 500;
  border-radius: var(--radius-full);
  line-height: 1.5;
}

.badge-green   { background: var(--color-success-light); color: var(--color-success); }
.badge-yellow  { background: var(--color-warning-light); color: #92400E; }
.badge-orange  { background: #FFEDD5;                     color: #9A3412; }
.badge-red     { background: var(--color-danger-light);  color: var(--color-danger); }
.badge-blue    { background: var(--color-primary-light); color: var(--color-primary); }
.badge-gray    { background: var(--color-row-stripe);    color: var(--color-text-secondary); }

/* Semantic status badges (prefer these over color-named variants for module UIs) */
.badge-status--active   { background: var(--color-success-light); color: var(--color-success); }
.badge-status--pending  { background: var(--color-warning-light); color: #92400E; }
.badge-status--error    { background: var(--color-danger-light);  color: var(--color-danger); }
.badge-status--inactive { background: var(--color-row-stripe);    color: var(--color-text-secondary); }
.badge-status--info     { background: var(--color-primary-light); color: var(--color-primary); }

/* Rol de la actividad en el RAT (Responsable / Encargado). Antes ambos roles
   compartían .badge-blue, así que el badge ocupaba lugar sin distinguir nada.
   Llevan par propio y NO reutilizan la paleta semántica: en la misma fila del
   listado conviven el verde «DPO», el ámbar «Devuelto» y, en la columna
   contigua, los badges de estado (celeste «Activa», navy «En revisión»). Pintar
   el rol de verde o azul lo haría leer como estado. El color no es el único
   indicador: cada badge lleva escrito su rol.
   El rosa de Responsable NO es decorativo: se probó celeste y quedaba a 17
   puntos RGB de .badge-active («Activa»), que aparece en la columna de al lado
   — y Responsable+Activa es la combinación más frecuente del listado, así que
   los dos chips se leían como el mismo. El rosa no colisiona con ningún badge
   del sistema.
   A var(--text-xs) (12px) y font-weight 500 el texto es normal para WCAG y
   exige 4.5:1; ambos pares superan el mínimo (~6.8:1 y ~7.6:1). */
.badge-role--controller { background: #FCE7F3; color: #9D174D; }
.badge-role--processor  { background: #EDE9FE; color: #5B21B6; }

/* Indicador de ESTADO de campo obligatorio en labels de formulario. Dejó de ser
   un marcador neutro repetido (que se veía igual con el campo lleno o vacío) y
   ahora dice en cuál de los dos estados está: pendiente («Requerido», ámbar) o
   completo («Listo», verde con check). El estado lo aplica el JS del formulario
   leyendo el valor real del control.
   El ámbar es el MISMO par que .badge-yellow, para leerse como continuación del
   badge «N campos» del listado /rat. El verde es deliberadamente más suave:
   confirma sin competir, la atención se la debe llevar el ámbar.
   A 11px/400 el texto es normal para WCAG y exige 4.5:1; los dos pares cumplen.
   El color nunca es el único indicador: cada estado lleva su propio texto. */
.badge-required {
  background: var(--color-warning-light);
  color: #92400E; /* 4.5:1+ sobre --color-warning-light (par de .badge-yellow) */
  padding: 1px 6px;
  font-size: 0.6875rem;
  font-weight: 400;
  margin-left: var(--space-xs);
  vertical-align: middle;
}
.badge-required.is-complete {
  background: var(--color-success-light);
  /* Verde más oscuro que --color-success: ese queda en ~2.9:1 sobre
     --color-success-light y no alcanza el 4.5:1 exigido; este llega a ~5.2:1. */
  color: #047857;
}
.badge-required__done { display: none; align-items: center; gap: 3px; }
.badge-required.is-complete .badge-required__pending { display: none; }
.badge-required.is-complete .badge-required__done { display: inline-flex; }

/* --- Status Dots (Semaphores) --- */
.status-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.status-dot--green  { background: var(--color-success); }
.status-dot--yellow { background: var(--color-warning); }
.status-dot--red    { background: var(--color-danger); }
.status-dot--gray   { background: var(--color-text-muted); }

/* --- Toast Notifications --- */
.toast-container {
  position: fixed;
  top: calc(var(--navbar-height) + var(--space-md));
  right: var(--space-md);
  z-index: 300;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  pointer-events: none;
}

.toast {
  pointer-events: auto;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: var(--space-md) var(--space-lg);
  min-width: 300px;
  max-width: 420px;
  font-size: var(--text-sm);
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  animation: toast-in 200ms ease;
}

.toast--success { border-left: 4px solid var(--color-success); }
.toast--error   { border-left: 4px solid var(--color-danger); }
.toast--warning { border-left: 4px solid var(--color-warning); }
.toast--info    { border-left: 4px solid var(--color-primary); }

.toast-dismiss {
  margin-left: auto;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-muted);
  font-size: var(--text-base);
}

@keyframes toast-in {
  from { opacity: 0; transform: translateX(20px); }
  to   { opacity: 1; transform: translateX(0); }
}

.toast-out {
  animation: toast-out 200ms ease forwards;
}

@keyframes toast-out {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(20px); }
}

/* --- Tooltip --- */
.tooltip {
  position: relative;
  cursor: help;
}

.tooltip::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background: #1F2937;
  color: #FFF;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition);
  z-index: 50;
}

.tooltip:hover::after { opacity: 1; }

/* --- Auth Layout (split design) --- */
.auth-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: 100vh;
}

.auth-brand-panel {
  background: linear-gradient(135deg,
      var(--portal-color-dark, var(--color-primary-dark)) 0%,
      var(--portal-color, var(--color-primary)) 50%,
      color-mix(in srgb, var(--portal-color, #1E5A7E) 60%, #1a1a2e) 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-2xl);
  position: relative;
  overflow: hidden;
}

.auth-brand-panel::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 30% 20%, rgba(14, 165, 160, 0.2) 0%, transparent 50%),
    radial-gradient(circle at 70% 80%, rgba(14, 165, 160, 0.15) 0%, transparent 50%);
  pointer-events: none;
}

.auth-brand-panel::after {
  content: "";
  position: absolute;
  inset: 0;
  background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.04'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
  pointer-events: none;
}

.auth-brand-content {
  position: relative;
  z-index: 1;
  text-align: center;
  color: #FFF;
  animation: auth-brand-in 600ms ease;
}

@keyframes auth-brand-in {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}

.auth-brand-content h1 {
  font-size: 2.5rem;
  font-weight: 800;
  margin-bottom: var(--space-md);
  color: #FFF;
}

.auth-brand-content p {
  font-size: var(--text-lg);
  opacity: 0.85;
  max-width: 320px;
  line-height: 1.6;
}

.auth-brand-features {
  position: relative;
  z-index: 1;
  margin-top: var(--space-2xl);
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.auth-brand-feature {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  color: rgba(255, 255, 255, 0.85);
  font-size: var(--text-sm);
}

.auth-brand-feature-icon {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.auth-form-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-2xl);
  background: var(--color-bg);
}

.auth-card {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-2xl) var(--space-2xl) var(--space-xl);
  width: 100%;
  max-width: 420px;
  animation: auth-card-in 500ms cubic-bezier(0.4, 0, 0.2, 1);
}

@keyframes auth-card-in {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}

.auth-logo {
  text-align: center;
  margin-bottom: var(--space-xl);
}

.auth-logo h1 {
  font-size: var(--text-2xl);
  color: var(--color-primary);
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 800;
}

.auth-logo p {
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
  margin: var(--space-xs) 0 0;
}

.auth-divider {
  text-align: center;
  margin: var(--space-md) 0;
  position: relative;
}
.auth-divider::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--border-color);
}
.auth-divider span {
  background: var(--card-bg, white);
  padding: 0 var(--space-sm);
  position: relative;
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.auth-footer {
  text-align: center;
  margin-top: var(--space-lg);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.auth-security-badge {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  margin-top: var(--space-md);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.auth-security-badge svg {
  color: var(--color-accent);
}

@media (max-width: 768px) {
  .auth-layout { grid-template-columns: 1fr; }
  .auth-brand-panel { display: none; }
  .auth-form-panel { min-height: 100vh; }
}

/* --- OTP Input --- */
.otp-input {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: center;
  margin: var(--space-lg) 0 var(--space-xl);
}

.otp-input input {
  width: 44px;
  height: 52px;
  text-align: center;
  font-size: var(--text-xl);
  font-weight: 600;
  font-family: var(--font-mono);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg);
  color: var(--color-text);
  transition: border-color var(--transition), box-shadow var(--transition);
}

.otp-input input:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(14, 165, 160, 0.12);
}

.otp-separator {
  width: 12px;
  height: 2px;
  background: var(--color-border);
  border-radius: 1px;
  flex-shrink: 0;
}

/* --- OTP Footer (countdown + resend inline) --- */
.otp-footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  margin-top: var(--space-lg);
}

.otp-footer-sep {
  color: var(--color-muted);
  font-size: var(--text-sm);
}

.btn-link {
  background: none;
  border: none;
  color: var(--color-primary);
  cursor: pointer;
  padding: 0;
  font-family: inherit;
  font-size: inherit;
  text-decoration: none;
}

.btn-link:hover {
  text-decoration: underline;
}

/* --- Org Selector Cards --- */
.org-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.org-option {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-md);
  border: 2px solid var(--color-border-light);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: all var(--transition);
}

.org-option:hover {
  border-color: var(--color-primary);
  background: var(--color-primary-light);
}

.org-option input[type="radio"] {
  accent-color: var(--color-primary);
  width: 18px;
  height: 18px;
}

.org-option-info { flex: 1; }
.org-option-name { font-weight: 500; }
.org-option-role { font-size: var(--text-sm); color: var(--color-text-secondary); }

/* --- KPI Cards (Dashboard) --- */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-md);
  margin-bottom: var(--space-xl);
}

/* Nota aclaratoria bajo una grilla de KPIs: se pega a las tarjetas
   (la grilla ya aporta el margen inferior del bloque). */
.kpi-grid + .kpi-grid-note {
  margin-top: calc(var(--space-sm) - var(--space-xl));
  margin-bottom: var(--space-xl);
}

.kpi-card {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  transition: all var(--transition-smooth);
  position: relative;
  overflow: hidden;
}

.kpi-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}

.kpi-label {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  margin-bottom: var(--space-xs);
}

.kpi-value {
  font-size: var(--text-3xl);
  font-weight: 700;
}

/* --- Progress Steps (Wizard) --- */
.steps {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin-bottom: var(--space-xl);
}

.step {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.step-circle {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-sm);
  font-weight: 600;
  border: 2px solid var(--color-border);
  color: var(--color-text-secondary);
  background: var(--color-bg-card);
  flex-shrink: 0;
}

.step--done .step-circle {
  background: var(--color-success);
  border-color: var(--color-success);
  color: #FFF;
}

.step--active .step-circle {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.step-label {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

.step--active .step-label { color: var(--color-primary); font-weight: 500; }

.step-line {
  flex: 1;
  height: 2px;
  background: var(--color-border);
  min-width: 20px;
}
.step--done + .step-line { background: var(--color-success); }

/* --- Countdown Timer --- */
.countdown {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.countdown--expired {
  color: var(--color-danger);
}

/* --- SLA Timer Bar (ARSOPB, Brechas) --- */
.sla-timer {
  margin-bottom: var(--space-md);
}

.sla-bar {
  height: 8px;
  background: var(--color-border-light);
  border-radius: var(--radius-full);
  overflow: hidden;
  margin-bottom: var(--space-xs);
}

.sla-bar-fill {
  height: 100%;
  border-radius: var(--radius-full);
  transition: width 300ms ease, background-color 300ms ease;
}

.sla-bar--green .sla-bar-fill  { background: var(--color-success); }
.sla-bar--yellow .sla-bar-fill { background: var(--color-warning); }
.sla-bar--red .sla-bar-fill    { background: var(--color-danger); }

.sla-text {
  display: flex;
  justify-content: space-between;
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
}

.sla-text-remaining {
  font-family: var(--font-mono);
  font-weight: 600;
}

.sla-bar--yellow ~ .sla-text .sla-text-remaining { color: var(--color-warning); }
.sla-bar--red ~ .sla-text .sla-text-remaining    { color: var(--color-danger); }

.sla-paused {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--text-xs);
  color: var(--color-primary);
  font-weight: 500;
  margin-top: var(--space-xs);
}

/* --- Panic Button (Reportar Incidente) --- */
.btn-panic {
  background: var(--color-danger);
  color: #FFF;
  border-color: var(--color-danger);
  font-weight: 600;
  white-space: nowrap;
}
.btn-panic:hover { background: var(--color-danger-hover); border-color: var(--color-danger-hover); }

/* --- Context Switcher (Multi-Org) --- */
.org-switcher {
  position: relative;
}

.org-switcher-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-xs) var(--space-sm);
  background: var(--color-bg);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  transition: all var(--transition);
  font-family: var(--font-body);
}

.org-switcher-toggle:hover {
  border-color: var(--color-primary);
  color: var(--color-text);
}

.org-switcher-name {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
  color: var(--color-text);
}

.org-switcher-arrow {
  font-size: var(--text-xs);
  transition: transform var(--transition);
}

.org-switcher.is-open .org-switcher-arrow {
  transform: rotate(180deg);
}

.org-switcher-dropdown {
  position: absolute;
  top: calc(100% + var(--space-xs));
  left: 0;
  min-width: 260px;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  z-index: 150;
  padding: var(--space-xs) 0;
  display: none;
}

.org-switcher.is-open .org-switcher-dropdown {
  display: block;
}

.org-switcher-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-sm) var(--space-md);
  cursor: pointer;
  transition: background var(--transition);
  font-size: var(--text-sm);
  color: var(--color-text);
  border: none;
  background: none;
  width: 100%;
  text-align: left;
  font-family: var(--font-body);
}

.org-switcher-item:hover {
  background: var(--color-bg);
}

.org-switcher-item--active {
  background: var(--color-primary-light);
  color: var(--color-primary);
  font-weight: 500;
}

.org-switcher-item-role {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.org-switcher-divider {
  height: 1px;
  background: var(--color-border-light);
  margin: var(--space-xs) 0;
}

.org-switcher-item--create {
  color: var(--color-primary);
  font-weight: 500;
}

.org-switcher-item--create:hover {
  background: var(--color-primary-light);
}

/* --- Legal Tooltips (?) --- */
.tooltip-legal {
  --tooltip-shift-x: 0px;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--color-border-light);
  color: var(--color-text-secondary);
  font-size: 11px;
  font-weight: 700;
  cursor: help;
  vertical-align: middle;
  margin-left: var(--space-xs);
  flex-shrink: 0;
}

.tooltip-legal::before {
  content: "?";
}

.tooltip-legal-content {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(calc(-50% + var(--tooltip-shift-x)));
  background: var(--color-text);
  color: var(--color-bg-card);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: 400;
  line-height: 1.5;
  min-width: 220px;
  max-width: 320px;
  white-space: normal;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--transition), visibility var(--transition);
  z-index: 250;
  box-shadow: var(--shadow-lg);
}

.tooltip-legal-content::after {
  content: "";
  position: absolute;
  top: 100%;
  left: calc(50% - var(--tooltip-shift-x));
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--color-text);
}

/* Bias edge-constrained tooltips slightly right without changing the default pattern. */
.tooltip-legal--edge {
  --tooltip-shift-x: calc(var(--space-sm) + var(--space-xs));
}

.tooltip-legal:hover .tooltip-legal-content {
  opacity: 1;
  visibility: visible;
}

.tooltip-legal-ref {
  display: block;
  margin-top: var(--space-xs);
  font-size: 10px;
  opacity: 0.7;
  font-style: italic;
}

.form-label > .tooltip-legal,
.form-check-label > .tooltip-legal {
  vertical-align: middle;
  display: inline-flex;
}

/* --- Autosave Indicator (Wizard) --- */
.autosave {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-full);
  background: var(--color-bg);
}

.autosave--saving { color: var(--color-warning); }
.autosave--saved  { color: var(--color-success); }

.autosave-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

/* --- Table Toolbar (Search, Filter, Actions) --- */
.table-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-md);
  flex-wrap: wrap;
}

.table-search {
  flex: 1;
  min-width: 200px;
  max-width: 320px;
  position: relative;
}

.table-search input {
  width: 100%;
  padding: 8px 12px 8px 36px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg-card);
  color: var(--color-text);
  transition: border-color var(--transition);
}

.table-search input:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(14, 165, 160, 0.12);
}

.table-search-icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  pointer-events: none;
}

.table-actions {
  display: flex;
  gap: var(--space-xs);
  margin-left: auto;
}

.table-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: var(--space-md);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

.table-pagination-pages {
  display: flex;
  gap: 2px;
}

.table-pagination-btn {
  padding: 6px 10px;
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  background: var(--color-bg-card);
  color: var(--color-text-secondary);
  cursor: pointer;
  font-size: var(--text-sm);
  font-family: var(--font-body);
  transition: all var(--transition);
}

.table-pagination-btn:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.table-pagination-btn--active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #FFF;
}

/* --- Empty State --- */
.empty-state {
  text-align: center;
  padding: var(--space-2xl) var(--space-lg);
}

.empty-state-icon {
  font-size: 48px;
  color: var(--color-border);
  margin-bottom: var(--space-md);
}

.empty-state-title {
  font-size: var(--text-lg);
  font-weight: 600;
  margin-bottom: var(--space-xs);
}

.empty-state-description {
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
  max-width: 400px;
  margin: 0 auto var(--space-lg);
}

/* --- Activity Timeline --- */
.timeline {
  position: relative;
  padding-left: 24px;
}

.timeline::before {
  content: "";
  position: absolute;
  left: 7px;
  top: 4px;
  bottom: 4px;
  width: 2px;
  background: var(--color-border-light);
}

.timeline-item {
  position: relative;
  padding-bottom: var(--space-md);
}

.timeline-item:last-child { padding-bottom: 0; }

.timeline-dot {
  position: absolute;
  left: -20px;
  top: 4px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-bg-card);
  border: 2px solid var(--color-border);
}

.timeline-item--info .timeline-dot    { border-color: var(--color-primary); }
.timeline-item--success .timeline-dot { border-color: var(--color-success); }
.timeline-item--warning .timeline-dot { border-color: var(--color-warning); }
.timeline-item--danger .timeline-dot  { border-color: var(--color-danger); }

.timeline-content {
  font-size: var(--text-sm);
}

.timeline-time {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  margin-top: 2px;
}

/* --- Campo de archivo (macro _macros/file_field.html) ---
   Componente unico de adjuntos. Dos variantes: la compacta (boton «Adjuntar» +
   chip con el nombre) y la de arrastre (.file-field--dropzone), reservada a la
   evidencia de medidas de seguridad. Arrastrar y soltar funciona en las dos. */
.file-field {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
  min-width: 0;
}

/* El input se estira transparente sobre el disparador en vez de ocultarse con
   display:none: asi el clic y el foco por teclado funcionan sin JS, y el globo
   de la validacion nativa de un campo `required` aparece sobre el boton en vez
   de flotar fuera de sitio (con display:none el navegador ni siquiera puede
   enfocarlo y aborta el envio con «An invalid form control is not focusable»). */
.file-field__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}
.file-field__input:disabled { cursor: not-allowed; }

/* El aspecto del disparador lo dan `.btn.btn-secondary.btn-sm`, que el macro ya
   pone en el <label>: aca solo lo propio del componente. */
.file-field__trigger {
  position: relative;
  overflow: hidden;
  display: inline-flex;
}

/* El foco vive en el input, que es invisible: el anillo lo tiene que dibujar el
   disparador. Mismo anillo que `.btn:focus-visible`, porque el disparador se ve
   y se lee como un boton.
   Ademas de `:focus-visible` se contempla `:focus` a secas: tras un rechazo el
   JS devuelve el foco al input por codigo, y un `.focus()` programatico sobre
   un input de archivo no activa `:focus-visible`. El costo es que el input
   cubre el disparador (`.file-field__input`, arriba), asi que un clic del raton
   tambien lo enfoca y el anillo se dibuja en toda interaccion con raton. Se
   acepta ese anillo de mas a cambio de que el foco programatico se vea: un foco
   que no se ve deja al usuario sin saber donde quedo tras el rechazo. */
.file-field__trigger:has(.file-field__input:focus-visible),
.file-field__trigger:has(.file-field__input:focus) {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.file-field__trigger:has(.file-field__input:disabled) {
  opacity: 0.5;
  cursor: not-allowed;
}

.file-field__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  max-width: 100%;
  min-width: 0;
  padding: 2px var(--space-xs) 2px var(--space-sm);
  background: var(--color-primary-light);
  color: var(--color-primary);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}

.file-field__chip svg { flex-shrink: 0; }

/* El nombre lo elige el usuario y puede ser largo. Se recorta con elipsis en
   una sola linea —partirlo a mitad de palabra en tres o cuatro lineas estiraba
   la fila dentro de una celda estrecha— y el `title` (lo pone el JS, y el macro
   en el chip persistente) devuelve el nombre completo. El chip es flex, asi que
   el hijo se blockifica y admite elipsis.
   Sin tope propio de ancho: el chip ya trae `max-width:100%` y este hijo, al
   llevar `overflow:hidden`, tiene minimo automatico 0, asi que se recorta solo
   cuando el contenedor aprieta. Un tope duro en `ch` recortaba tambien en los
   formularios a ancho completo, donde el nombre cabia entero y el usuario tenia
   que apuntar con el raton para confirmar que habia elegido el archivo
   correcto. Los sitios estrechos (celdas de tabla) aprietan con
   `wrapper_style`. */
.file-field__chip-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: inherit;
}

/* El nombre enlazado (descarga del archivo guardado) hereda el color del chip y
   el proyecto quita el subrayado a todos los enlaces salvo en :hover, asi que
   sin esto se ve identico al nombre no enlazado y nada anuncia que se puede
   descargar. El subrayado es permanente a proposito: la afordancia no puede
   depender de pasar el raton por encima. */
.file-field__chip-name--link {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Tras un swap de HTMX hay plantillas que devuelven el foco a este enlace por
   codigo, y un `.focus()` programatico no activa la heuristica de
   `:focus-visible`: el destino quedaria sin ninguna senal visual. Por eso se
   estila tambien `:focus` a secas —mismo criterio que en `.file-field__trigger`—
   asumiendo que un clic con el raton sobre el enlace tambien dibuje el anillo. */
.file-field__chip-name:focus-visible,
.file-field__chip-name:focus {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* El chip persistente (archivo ya guardado en el servidor) y el de seleccion
   (archivo elegido, todavia sin subir) conviven en pantalla cuando se reemplaza
   un adjunto, y sus botones de quitar hacen cosas muy distintas: uno descarta la
   seleccion, el otro borra evidencia de cumplimiento de forma irreversible.
   Distinguirlos solo por el glifo de 14px no basta, asi que el persistente sale
   en gris neutro y el de seleccion se queda con el azul primario, que es el
   estado que pide accion. Este gris es, junto al tacho, el unico diferenciador:
   el chip persistente llevo ademas un rotulo «Guardado» y se quito, porque el
   estado en que ambos conviven dura segundos y el rotulo permanente pesaba mas
   que el caso que resolvia. Por eso el nombre accesible de cada boton de quitar
   tiene que seguir siendo distinto (ver el macro `_macros/file_field.html`). */
.file-field__chip--stored {
  background: var(--color-bg-muted);
  color: var(--color-text-secondary);
}

.file-field__chip-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 24px;
  padding: 0;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--color-text-secondary);
  cursor: pointer;
  transition: color var(--transition);
}
.file-field__chip-remove:hover { color: var(--color-danger); }
.file-field__chip-remove:focus-visible {
  outline: none;
  color: var(--color-danger);
  box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.15);
}

/* El JS muestra y esconde el chip con la propiedad `hidden`, y el display de
   autor de arriba le gana al del user-agent: sin esto, ocultarlo no tendria
   efecto. */
.file-field__chip[hidden] { display: none; }

/* En la variante de arrastre el area punteada ES el disparador: el borde, el
   padding y el texto de ayuda viven dentro del <label>, no en el contenedor.
   Con el boton suelto dentro del area, el bloque completo se resaltaba al pasar
   por encima y decia «haz clic», pero solo el boton respondia al clic. */
.file-field--dropzone {
  flex-direction: column;
  align-items: stretch;
}

.file-field--dropzone .file-field__trigger {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  /* Alto por defecto del area. Las llamadas que viven en una fila junto a otros
     controles lo ajustan con `--file-field-dropzone-padding` en `wrapper_style`
     (la propiedad se hereda del contenedor al disparador). */
  padding: var(--file-field-dropzone-padding, var(--space-xl) var(--space-lg));
  border: 2px dashed var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg);
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}

/* El disparador de esta variante no lleva las clases `.btn`, que son las que
   dimensionan el icono: sin esto el SVG sin `width`/`height` se dibuja al
   tamaño por defecto de un reemplazado (300x150). */
.file-field--dropzone .file-field__trigger svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

/* El `:not()` deja fuera el area rechazada: el hover de esta variante tiene mas
   especificidad que el estado de error (`.clase .clase :hover` contra
   `.clase .clase`), asi que sin la exclusion el borde rojo se repintaba de azul
   en cuanto el puntero tocaba el area, justo cuando el usuario va a reintentar.
   No se resuelve subiendo la especificidad del error porque entonces el error le
   ganaria tambien al resaltado de arrastre. */
.file-field--dropzone:not(.file-field--error) .file-field__trigger:hover {
  border-color: var(--color-primary);
  background: var(--color-primary-light);
}

/* El texto de ayuda va dentro del area, y su margen superior lo reemplaza el
   `gap` del disparador. */
.file-field--dropzone .form-hint {
  display: block;
  margin-top: 0;
}

/* Ayuda de la variante compacta: el <p> es hijo directo del contenedor, que es
   una fila flex, asi que sin esto quedaria en linea junto al boton en vez de
   debajo. Ocupando la fila completa baja a su propia linea, y el espacio lo da
   el `gap` del contenedor. */
.file-field > .form-hint {
  flex: 0 0 100%;
  margin: 0;
}

/* Estados del disparador, comunes a las dos variantes. Van al final del bloque
   porque el orden de aparicion es lo unico que los separa de las reglas de la
   variante de arrastre con las que empatan en especificidad (el resaltado de
   arrastre y el borde por defecto del area): a igual peso gana la ultima.
   El hover de esa variante pesa mas que estas dos y por eso se excluye a mano
   mas arriba, no por orden.
   El error lo pinta el JS junto con `aria-invalid` en el input y el mensaje por
   toast: el borde por si solo no comunica nada a quien navega con lector de
   pantalla. */
.file-field--error .file-field__trigger { border-color: var(--color-danger); }
.file-field--dragover .file-field__trigger {
  border-color: var(--color-primary);
  background: var(--color-primary-light);
}

/* --- Inline Editable Cell --- */
.cell-editable {
  position: relative;
  cursor: pointer;
  padding: 2px 4px;
  border-radius: var(--radius-sm);
  transition: background var(--transition);
}

.cell-editable:hover {
  background: var(--color-primary-light);
}

.cell-editable input,
.cell-editable select {
  width: 100%;
  padding: 4px 8px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-sm);
  background: var(--color-bg-card);
  color: var(--color-text);
  box-shadow: 0 0 0 3px rgba(14, 165, 160, 0.12);
}

/* --- Field History Icon (Audit Trail) --- */
.field-history {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  cursor: pointer;
  transition: all var(--transition);
  background: none;
  border: none;
  font-size: 12px;
  padding: 0;
  vertical-align: middle;
  margin-left: var(--space-xs);
}

.field-history:hover {
  background: var(--color-primary-light);
  color: var(--color-primary);
}

/* --- Confirm Dialog (replaces native browser confirm) --- */
.confirm-dialog {
  border: none;
  border-radius: var(--radius-lg);
  background: var(--color-bg-card);
  box-shadow: var(--shadow-lg), 0 0 0 1px rgba(15, 36, 64, 0.05);
  padding: 0;
  max-width: 420px;
  width: calc(100% - 2 * var(--space-lg));
  font-family: var(--font-body);
  color: var(--color-text);
}

.confirm-dialog::backdrop {
  background: rgba(15, 36, 64, 0.35);
  backdrop-filter: blur(2px);
}

.confirm-dialog-body {
  padding: var(--space-xl) var(--space-xl) var(--space-lg);
  text-align: center;
}

.confirm-dialog-icon {
  width: 48px;
  height: 48px;
  margin: 0 auto var(--space-md);
  border-radius: var(--radius-full);
  background: var(--color-danger-light);
  display: flex;
  align-items: center;
  justify-content: center;
}

.confirm-dialog-icon svg {
  width: 24px;
  height: 24px;
  stroke: var(--color-danger);
}

.confirm-dialog-message {
  font-size: var(--text-base);
  line-height: 1.5;
  color: var(--color-text-secondary);
  margin: 0;
}

.confirm-dialog-actions {
  display: flex;
  gap: var(--space-sm);
  justify-content: flex-end;
  padding: var(--space-md) var(--space-xl);
  border-top: 1px solid var(--color-border-light);
}

/* --- Double Confirmation Page --- */
.confirm-destructive {
  text-align: center;
  padding: var(--space-md) 0;
}

.confirm-destructive-icon {
  font-size: 48px;
  color: var(--color-danger);
  margin-bottom: var(--space-md);
}

.confirm-destructive p {
  color: var(--color-text-secondary);
  margin-bottom: var(--space-lg);
}

.confirm-input {
  display: block;
  width: 100%;
  padding: 10px 12px;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  text-align: center;
  letter-spacing: 0.1em;
  border: 2px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  color: var(--color-text);
  margin-bottom: var(--space-md);
  transition: border-color var(--transition);
}

.confirm-input:focus {
  outline: none;
  border-color: var(--color-danger);
  box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.15);
}

/* --- Workflow Badges --- */
.badge-draft     { background: var(--color-row-stripe); color: var(--color-text-secondary); }
.badge-review    { background: var(--color-info-light); color: var(--color-primary); }
.badge-approved  { background: var(--color-success-light); color: var(--color-success); }
.badge-active    { background: #E0F2FE; color: #0369A1; }
.badge-expired   { background: var(--color-danger-light); color: var(--color-danger); }

/* --- Escalation Level Badges --- */
.escalation-level {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  font-size: var(--text-xs);
  font-weight: 600;
  border-radius: var(--radius-sm);
}

.escalation-l1 { background: var(--color-warning-light); color: #92400E; }
.escalation-l2 { background: #FED7AA; color: #9A3412; }
.escalation-l3 { background: var(--color-danger-light); color: var(--color-danger); }

/* --- Breach Severity Colors --- */
.severity-critical { color: var(--color-danger); }
.severity-high     { color: #EA580C; }
.severity-medium   { color: var(--color-warning); }
.severity-low      { color: var(--color-primary); }

/* --- KPI Card Variants --- */
.kpi-card--success { border-left: 3px solid var(--color-success); }
.kpi-card--warning { border-left: 3px solid var(--color-warning); }
.kpi-card--danger  { border-left: 3px solid var(--color-danger); }
.kpi-card--info    { border-left: 3px solid var(--color-primary); }

/* Tarjeta de total sobre una grilla de KPIs: vive fuera de la grilla y en su propia
   fila, para que no se lea como una categoría más que suma junto a las tarjetas de
   partición. Ancho acotado — estirada a todo el ancho se ve como una banda vacía. */
.kpi-card--total {
  max-width: 260px;
  margin-bottom: var(--space-lg);
}

.kpi-trend {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--text-xs);
  margin-top: var(--space-xs);
}

.kpi-trend--up   { color: var(--color-success); }
.kpi-trend--down { color: var(--color-danger); }
.kpi-trend--flat { color: var(--color-text-muted); }

/* --- Step Completeness Tags --- */
.step-tag {
  font-size: 10px;
  display: block;
  margin-top: 2px;
}

.step--complete .step-circle {
  background: var(--color-success);
  border-color: var(--color-success);
  color: #FFF;
}
.step--complete .step-tag { color: var(--color-success); }

.step--incomplete .step-tag { color: var(--color-warning); }

.step--alert .step-circle {
  border-color: var(--color-danger);
  color: var(--color-danger);
}
.step--alert .step-tag { color: var(--color-danger); }

/* --- Column Toggle (Show/Hide Columns) --- */
.column-toggle {
  position: relative;
}

.column-toggle-menu {
  position: absolute;
  top: calc(100% + var(--space-xs));
  right: 0;
  min-width: 200px;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  z-index: 50;
  padding: var(--space-sm) 0;
  display: none;
}

.column-toggle.is-open .column-toggle-menu {
  display: block;
}

.column-toggle-item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-xs) var(--space-md);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: background var(--transition);
}

.column-toggle-item:hover {
  background: var(--color-bg);
}

.column-toggle-item input[type="checkbox"] {
  accent-color: var(--color-primary);
}

/* --- Secure Inbox (Whistleblowing Chat) --- */
.chat-thread {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-md);
  max-height: 400px;
  overflow-y: auto;
}

.chat-message {
  max-width: 75%;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.chat-message--sent {
  align-self: flex-end;
  background: var(--color-primary);
  color: #FFF;
  border-bottom-right-radius: var(--radius-sm);
}

.chat-message--received {
  align-self: flex-start;
  background: var(--color-bg);
  color: var(--color-text);
  border-bottom-left-radius: var(--radius-sm);
}

.chat-message-time {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  margin-top: 4px;
}

.chat-message--sent .chat-message-time { color: rgba(255,255,255,0.7); }

.chat-input {
  display: flex;
  gap: var(--space-sm);
  padding: var(--space-md);
  border-top: 1px solid var(--color-border-light);
}

.chat-input textarea {
  flex: 1;
  padding: var(--space-sm) var(--space-md);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  resize: none;
  min-height: 40px;
  max-height: 120px;
  background: var(--color-bg-card);
  color: var(--color-text);
}

/* --- Risk Matrix (Heat Map for EIPD) --- */
.risk-matrix {
  display: grid;
  grid-template-columns: auto repeat(4, 1fr);
  gap: 3px;
  font-size: var(--text-xs);
}

.risk-matrix-header {
  padding: var(--space-xs) var(--space-sm);
  text-align: center;
  font-weight: 600;
  color: var(--color-text-secondary);
  font-size: 11px;
  line-height: 1.2;
}

.risk-matrix-label {
  display: flex;
  align-items: center;
  padding: var(--space-xs) var(--space-sm);
  font-weight: 500;
  color: var(--color-text-secondary);
  font-size: 11px;
  white-space: nowrap;
}

.risk-matrix-cell {
  padding: var(--space-xs) var(--space-sm);
  text-align: center;
  border-radius: var(--radius-sm);
  font-weight: 600;
  transition: all 0.15s ease;
  min-height: 48px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  position: relative;
}

.risk-matrix-cell:hover { opacity: 0.85; }

/* Inactive cells: subtle score, lower opacity */
.risk-matrix-cell:not(.risk-matrix-active) {
  opacity: 0.55;
}
.risk-matrix-cell:not(.risk-matrix-active):hover {
  opacity: 0.75;
}

.risk-matrix-cell.risk-matrix-active {
  opacity: 1;
  outline: 2px solid var(--color-text);
  outline-offset: -1px;
  font-weight: 700;
  z-index: 1;
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.08);
  transform: scale(1.04);
}

.risk-matrix-cell .risk-matrix-threats {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.5px;
  line-height: 1;
}

.risk-low      { background: #DCFCE7; color: #166534; }
.risk-moderate { background: #FEF9C3; color: #854D0E; }
.risk-high     { background: #FED7AA; color: #9A3412; }
.risk-critical { background: #FECACA; color: #991B1B; }

.risk-matrix-legend {
  display: flex;
  gap: var(--space-md);
  flex-wrap: wrap;
  margin-top: var(--space-sm);
}

.risk-matrix-legend-item {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: 11px;
  color: var(--color-text-secondary);
}

.risk-matrix-legend-item .legend-swatch {
  width: 12px;
  height: 12px;
  border-radius: 2px;
  flex-shrink: 0;
}

/* --- Pre-filled Field Indicator (EIPD auto-import) --- */
.field-imported {
  position: relative;
}

.field-imported::after {
  content: "\2193";
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 12px;
  color: var(--color-primary);
  background: var(--color-primary-light);
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* --- Certificate Expiry Badge --- */
.badge-expiry {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  font-size: var(--text-xs);
  font-weight: 500;
  border-radius: var(--radius-full);
}

.badge-expiry--ok      { background: var(--color-success-light); color: var(--color-success); }
.badge-expiry--warning { background: var(--color-warning-light); color: #92400E; }
.badge-expiry--expired { background: var(--color-danger-light); color: var(--color-danger); }

/* --- Toggle Switch (Security Checklist) --- */
.toggle-group {
  display: flex;
  gap: 2px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-light);
  overflow: hidden;
}

.toggle-option {
  padding: 6px 12px;
  font-size: var(--text-xs);
  font-weight: 500;
  cursor: pointer;
  transition: all var(--transition);
  background: var(--color-bg-card);
  color: var(--color-text-secondary);
  border: none;
  font-family: var(--font-body);
}

.toggle-option:hover { background: var(--color-bg); }
.toggle-option--active { background: var(--color-primary); color: #FFF; }
.toggle-option--partial { background: var(--color-warning-light); color: #92400E; }

/* --- Utilities --- */
.text-center { text-align: center; }
.text-right  { text-align: right; }
.text-muted   { color: var(--color-text-secondary); }
/* Enlace al archivo adjunto de un registro (respaldo de la base legal en el
   RAT, en el detalle y en el editor). El nombre de un archivo puede ser largo y
   sin espacios, asi que rompe por cualquier caracter en vez de desbordar su
   columna. */
.file-link {
  color: var(--color-primary);
  font-weight: 600;
  word-break: break-all;
}

.text-danger  { color: var(--color-danger); }
.text-success { color: var(--color-success); }
.text-warning { color: var(--color-warning); }
.text-accent  { color: var(--color-accent); }
.text-sm     { font-size: var(--text-sm); }
.text-xs     { font-size: var(--text-xs); }
.text-lg     { font-size: var(--text-lg); }
.font-mono   { font-family: var(--font-mono); }
.font-bold   { font-weight: 600; }
.font-heading { font-family: var(--font-heading); }

.mt-xs { margin-top: var(--space-xs); }
.mt-sm { margin-top: var(--space-sm); }
.mt-md { margin-top: var(--space-md); }
.mt-lg { margin-top: var(--space-lg); }
.mt-xl { margin-top: var(--space-xl); }
.mb-xs { margin-bottom: var(--space-xs); }
.mb-sm { margin-bottom: var(--space-sm); }
.mb-md { margin-bottom: var(--space-md); }
.mb-lg { margin-bottom: var(--space-lg); }
.mb-xl { margin-bottom: var(--space-xl); }
.ml-auto { margin-left: auto; }
.mr-md { margin-right: var(--space-md); }

.flex         { display: flex; }
.flex-col     { display: flex; flex-direction: column; }
.flex-wrap    { flex-wrap: wrap; }
.flex-1       { flex: 1; }
.items-center { align-items: center; }
.items-start  { align-items: flex-start; }
.justify-between { justify-content: space-between; }
.justify-center  { justify-content: center; }
.justify-end     { justify-content: flex-end; }
.gap-xs { gap: var(--space-xs); }
.gap-sm { gap: var(--space-sm); }
.gap-md { gap: var(--space-md); }
.gap-lg { gap: var(--space-lg); }
.nowrap { white-space: nowrap; }

.hidden { display: none !important; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --- Loading indicator (HTMX) --- */
.htmx-indicator {
  opacity: 0;
  transition: opacity 200ms ease-in;
}
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  opacity: 1;
}

/* Estado ocupado del control que pidió. HTMX pone .htmx-request en el elemento que
   hizo la petición: un botón con hx-post propio se ve ocupado y no recibe clics. En un
   formulario la clase va en el <form>, no en sus botones: ahí protege hx-disabled-elt
   (find button[type=submit]) y el guardia de app.js. */
.btn.htmx-request,
button.htmx-request {
  opacity: 0.65;
  pointer-events: none;
  cursor: progress;
}

.spinner {
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 2px solid var(--color-border);
  border-top-color: var(--color-accent);
  border-radius: 50%;
  animation: spin 600ms linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* --- HTMX Top Progress Bar --- */
.htmx-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--color-accent), var(--color-primary));
  z-index: 9999;
  transition: width 300ms ease;
  border-radius: 0 2px 2px 0;
  box-shadow: 0 0 8px rgba(14, 165, 160, 0.4);
}

/* --- Skeleton Loading --- */
.skeleton {
  background: linear-gradient(90deg, var(--color-bg-muted) 25%, var(--color-border-light) 50%, var(--color-bg-muted) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s ease infinite;
  border-radius: var(--radius-sm);
}

.skeleton-text {
  height: 14px;
  margin-bottom: var(--space-sm);
  border-radius: var(--radius-sm);
}

.skeleton-text:last-child { width: 60%; }

.skeleton-heading {
  height: 24px;
  width: 40%;
  margin-bottom: var(--space-md);
  border-radius: var(--radius-sm);
}

.skeleton-card {
  height: 100px;
  border-radius: var(--radius-md);
}

.skeleton-circle {
  width: 32px;
  height: 32px;
  border-radius: 50%;
}

@keyframes skeleton-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* --- Page Content Entrance --- */
.main-content > * {
  animation: content-in 350ms cubic-bezier(0.4, 0, 0.2, 1);
}

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

/* --- Staggered Entrance (for grids) --- */
.kpi-card { animation: card-in 400ms cubic-bezier(0.4, 0, 0.2, 1) backwards; }
.kpi-card:nth-child(1) { animation-delay: 50ms; }
.kpi-card:nth-child(2) { animation-delay: 100ms; }
.kpi-card:nth-child(3) { animation-delay: 150ms; }
.kpi-card:nth-child(4) { animation-delay: 200ms; }
.kpi-card:nth-child(5) { animation-delay: 250ms; }
.kpi-card:nth-child(6) { animation-delay: 300ms; }
.kpi-card:nth-child(7) { animation-delay: 350ms; }

/* La tarjeta de total está fuera de la grilla, así que su :nth-child cuenta entre los
   hijos de .main-content y no entre las tarjetas: le tocaría un delay mayor que el de
   la primera tarjeta de la grilla, y entraría después de una tarjeta que va más abajo.
   Va arriba de todo, entra primero. Doble clase para ganarle al :nth-child de arriba. */
.kpi-card.kpi-card--total { animation-delay: 0s; }

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

@keyframes pulse-soft {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

/* Despliegue del formulario «Enviar a borrador» en el detalle de una RAT activa
   (ver rat/detail.html + rat/_detail_actions.html). Al pulsar el botón el panel
   —oculto por defecto— se muestra con este fundido: entra en opacidad y un anillo
   de color que se desvanece (`outline` sólido -> transparente), para señalar
   que la acción abrió algo nuevo sin un parpadeo brusco. El color sale de las
   variables de diseño (`--color-warning`, la convención de «enviar a borrador»),
   no hardcodeado. La regla global de `prefers-reduced-motion` (arriba) reduce la
   duración a ~0 para quien lo pide: el panel aparece igual, pero sin animación.
   El estado final coincide con el reposo (opacidad 1, sin anillo), así que basta
   con la animación sin `animation-fill-mode`. Se usa `outline` y no `box-shadow`
   porque `.card` ya transiciona su sombra en :hover: animar la sombra la haría
   parpadear al terminar. El `outline` no está transicionado, así revierte limpio.

   Hay DOS casos y una animación para cada uno (el script en detail.html elige):
   - `.decision-flash` (oculto -> visible): fundido de entrada COMPLETO —opacidad
     + `translateY`— más el anillo que se desvanece. El panel aparece.
   - `.decision-flash--ring` (ya visible, p. ej. tras un error del POST y el
     usuario vuelve a pulsar): SOLO el anillo, sin tocar opacidad ni transform,
     porque repetir el movimiento de entrada sobre algo que ya estaba en pantalla
     se ve como un salto. Misma curva, duración y color. */
@keyframes decision-reveal {
  from { opacity: 0; transform: translateY(-4px); outline: 3px solid var(--color-warning); outline-offset: 2px; }
  to   { opacity: 1; transform: translateY(0);    outline: 3px solid transparent;          outline-offset: 2px; }
}
@keyframes decision-ring {
  from { outline: 3px solid var(--color-warning); outline-offset: 2px; }
  to   { outline: 3px solid transparent;          outline-offset: 2px; }
}
.decision-flash { animation: decision-reveal 1s ease-out; }
.decision-flash--ring { animation: decision-ring 1s ease-out; }

/* --- Responsive --- */
@media (max-width: 768px) {
  .navbar-hamburger { display: inline-flex; }

  /* Off-canvas sidebar: hidden off the left edge, slides in when the body
     carries .sidebar-mobile-open. z-index 95 keeps it under the fixed navbar
     (100) but over the content and the backdrop (94). */
  .sidebar {
    display: flex;
    transform: translateX(-100%);
    transition: transform var(--transition-smooth);
    box-shadow: var(--shadow-lg);
    z-index: 95;
  }
  body.sidebar-mobile-open .sidebar { transform: translateX(0); }

  .sidebar-backdrop {
    position: fixed;
    top: var(--navbar-height);
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(15, 36, 64, 0.45);
    z-index: 94;
  }
  body.sidebar-mobile-open .sidebar-backdrop { display: block; }
  /* Lock body scroll while the menu is open. */
  body.sidebar-mobile-open { overflow: hidden; }

  .navbar-brand { width: auto; }

  .main-content {
    /* Sin sidebar fijo: el contenido ocupa el ancho completo. La navbar fija
       full-width mantiene su margin-top de var(--navbar-height). */
    margin-left: 0;
    padding: var(--space-md);
  }

  .kpi-grid { grid-template-columns: 1fr 1fr; }
  .module-grid { grid-template-columns: 1fr 1fr; }
}


/* ---------------------------------------------------------------------------
   Dashboard: Module semaphore grid
   --------------------------------------------------------------------------- */

.module-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-md);
  padding: var(--space-md);
}

.module-card {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md);
  border-radius: var(--radius-md);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  text-decoration: none;
  color: inherit;
  transition: all var(--transition-smooth);
}

.module-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--color-border);
  transform: translateY(-1px);
  text-decoration: none;
}

.module-card--green  { border-left: 3px solid var(--color-success); }
.module-card--yellow { border-left: 3px solid var(--color-warning); }
.module-card--red    { border-left: 3px solid var(--color-danger); }

.module-indicator {
  flex-shrink: 0;
}

.module-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.module-name {
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--color-text);
}

.module-detail {
  font-size: 0.75rem;
  color: var(--color-text-secondary);
}


/* ---------------------------------------------------------------------------
   Dashboard: Timeline / Alerts
   --------------------------------------------------------------------------- */

.timeline-list {
  display: flex;
  flex-direction: column;
}

.timeline-item {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-border);
}

.timeline-item:last-child {
  border-bottom: none;
}

.timeline-item--critical {
  background: var(--color-danger-light);
}

.timeline-badge {
  flex-shrink: 0;
  width: 70px;
}

.timeline-content {
  flex: 1;
  min-width: 0;
}

.timeline-title {
  font-weight: 500;
  font-size: 0.875rem;
  color: var(--color-text);
}

.timeline-desc {
  font-size: 0.75rem;
  color: var(--color-text-secondary);
  margin-top: 2px;
}

.timeline-action {
  flex-shrink: 0;
}


/* ---------------------------------------------------------------------------
   Dashboard: Progress bar
   --------------------------------------------------------------------------- */

.progress-bar {
  height: 8px;
  background: var(--color-row-stripe);
  border-radius: 4px;
  overflow: hidden;
}

.progress-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--color-accent), var(--color-primary));
  border-radius: 4px;
  transition: width 0.3s ease;
}


/* ---------------------------------------------------------------------------
   Dashboard: Step line done state
   --------------------------------------------------------------------------- */

.step-line--done {
  background: var(--color-success) !important;
}

.step--done .step-circle {
  background: var(--color-success);
  color: white;
  border-color: var(--color-success);
}


/* ---------------------------------------------------------------------------
   Contextual Help — informational note at the bottom of each page
   --------------------------------------------------------------------------- */

.contextual-help {
  margin-top: var(--space-xl, 2rem);
  padding: var(--space-lg);
  background: var(--color-info-light);
  border: 1px solid rgba(14, 165, 160, 0.12);
  border-radius: var(--radius-md);
}

.contextual-help-header {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--color-primary-dark);
  margin-bottom: var(--space-md);
}

.contextual-help-header svg {
  flex-shrink: 0;
  color: var(--color-primary);
}

.contextual-help-items {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.contextual-help-item {
  font-size: var(--text-sm);
  color: var(--color-text);
  line-height: 1.5;
  padding-left: var(--space-md);
  position: relative;
}

.contextual-help-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.5em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-primary);
}

.contextual-help-ref {
  display: inline-block;
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--color-primary-dark);
  background: rgba(14, 165, 160, 0.1);
  padding: 1px 6px;
  border-radius: 3px;
  white-space: nowrap;
}

/* ── Per-page guide banner (D4) ── */
.page-guide {
  margin-bottom: var(--space-lg);
  padding: var(--space-lg);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-left: 4px solid var(--color-accent);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

.page-guide-zones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-lg);
}

.page-guide-zone {
  flex: 1 1 280px;
  min-width: 0;
}

.page-guide-heading {
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--color-primary-dark);
  margin: 0 0 var(--space-sm);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.page-guide-text {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  line-height: 1.55;
  margin: 0;
}

.page-guide-list {
  margin: 0;
  padding-left: var(--space-lg);
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.page-guide-list li {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  line-height: 1.5;
}

.page-guide-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  margin-top: var(--space-md);
  padding-top: var(--space-md);
  border-top: 1px solid var(--color-border-light);
}

.page-guide-effort {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--text-xs);
  font-weight: 600;
  padding: 4px 10px;
  border-radius: var(--radius-full);
  border: 1px solid transparent;
}

.page-guide-effort-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
}

/* Effort state is conveyed by the LABEL text; color is a redundant cue only. */
.page-guide-effort--instant {
  color: var(--color-accent-hover);
  background: var(--color-accent-light);
  border-color: var(--color-accent);
}

.page-guide-effort--human {
  color: var(--color-warning-hover);
  background: var(--color-warning-light);
  border-color: var(--color-warning);
}

.page-guide-effort--mixed {
  color: var(--color-primary-dark);
  background: var(--color-info-light);
  border-color: var(--color-primary);
}

.page-guide-help-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-primary);
  text-decoration: none;
}

/* Sin píldora de esfuerzo el enlace queda solo en el pie: `space-between` lo
   alinearía a la izquierda, así que el margen automático lo mantiene a la
   derecha como en el resto de las pantallas. */
.page-guide-help-link:only-child {
  margin-left: auto;
}

.page-guide-help-link:hover {
  color: var(--color-primary-hover);
  text-decoration: underline;
}

.page-guide-help-link svg {
  flex-shrink: 0;
}

/* ── Document content (rendered Markdown) ── */
.document-content h1 { font-size: 1.8em; margin: 1em 0 0.4em; }
.document-content h2 { font-size: 1.4em; margin: 0.9em 0 0.35em; border-bottom: 1px solid var(--color-border); padding-bottom: 0.25em; }
.document-content h3 { font-size: 1.2em; margin: 0.8em 0 0.3em; }
.document-content h4 { font-size: 1.05em; margin: 0.7em 0 0.25em; }
.document-content p { margin: 0 0 0.8em; }
.document-content ul,
.document-content ol { margin: 0 0 0.8em; padding-left: 1.8em; }
.document-content li { margin-bottom: 0.3em; }
.document-content blockquote {
  border-left: 3px solid var(--color-primary);
  padding: 0.5em 1em;
  margin: 0.8em 0;
  color: var(--color-text-muted);
  background: var(--color-bg-muted);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.document-content pre {
  background: var(--color-bg-muted);
  padding: var(--space-md);
  border-radius: var(--radius-sm);
  overflow-x: auto;
  margin: 0.8em 0;
}
.document-content code {
  background: var(--color-bg-muted);
  padding: 1px 4px;
  border-radius: 3px;
  font-size: 0.9em;
}
.document-content pre code {
  background: none;
  padding: 0;
}
.document-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 0.8em 0;
  font-size: var(--text-sm);
}
.document-content th,
.document-content td {
  border: 1px solid var(--color-border);
  padding: 0.5em 0.75em;
  text-align: left;
}
.document-content th {
  background: var(--color-bg-muted);
  font-weight: 600;
}
.document-content tr:hover td {
  background: rgba(0, 0, 0, 0.02);
}
.document-content hr {
  border: none;
  border-top: 1px solid var(--color-border);
  margin: 1.5em 0;
}
.document-content img {
  max-width: 100%;
  height: auto;
}
.document-content .wiki-link {
  color: var(--color-primary);
  font-weight: 500;
  text-decoration: none;
  border-bottom: 1px dashed var(--color-primary);
}
.document-content .wiki-link:hover {
  border-bottom-style: solid;
}
.document-content .wiki-link--broken {
  color: var(--color-danger);
  border-bottom-color: var(--color-danger);
  cursor: help;
}

/* ── Document template placeholders ── */
.doc-placeholder {
  display: inline-block;
  background: #fff3cd;
  color: #856404;
  border: 1px dashed #ffc107;
  border-radius: 4px;
  padding: 1px 8px;
  font-size: 0.85em;
  font-weight: 500;
  cursor: help;
  transition: background 0.15s, border-color 0.15s;
}
.doc-placeholder:hover {
  background: #ffe69c;
  border-color: #e0a800;
}
.doc-placeholder-banner {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-lg);
  background: #fff8e1;
  border-bottom: 1px solid #ffe082;
  color: #6d5a00;
  font-size: var(--text-sm);
}

/* ── Glossary ── */
.glossary-search { margin-bottom: var(--space-lg); }
.glossary-search .form-input {
  max-width: 400px;
  width: 100%;
}
.glossary-az-index {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-bottom: var(--space-lg);
}
.glossary-az-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--color-primary);
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}
.glossary-az-link:hover {
  background: var(--color-primary);
  color: #fff;
}
.glossary-letter-heading {
  font-size: var(--text-xl);
  font-weight: 700;
  font-family: var(--font-heading);
  color: var(--color-primary-dark);
  padding: var(--space-sm) 0;
  margin-top: var(--space-md);
  border-bottom: 2px solid var(--color-accent);
  margin-bottom: var(--space-sm);
}
.glossary-term-card {
  padding: var(--space-md);
  border-bottom: 1px solid var(--color-border-light);
}
.glossary-term-card:last-child { border-bottom: none; }
.glossary-term-name {
  font-weight: 600;
  font-size: var(--text-base);
  color: var(--color-text);
  margin-bottom: var(--space-xs);
}
.glossary-term-def {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  line-height: 1.5;
  margin-bottom: var(--space-xs);
}
.glossary-links-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-md);
  padding: var(--space-md);
}
.glossary-link-card {
  display: block;
  position: relative;
  padding: var(--space-md);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: var(--color-text);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.glossary-link-card:hover {
  border-color: var(--color-primary);
  box-shadow: 0 2px 8px rgba(14, 165, 160, 0.1);
}
.glossary-link-name {
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--color-primary);
  margin-bottom: var(--space-xs);
}
.glossary-link-desc {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  line-height: 1.4;
}
.glossary-external-icon {
  position: absolute;
  top: var(--space-sm);
  right: var(--space-sm);
  color: var(--color-text-muted);
}

/* --- Guide (Step-by-step compliance roadmap) --- */

/* Global progress */
.guide-global-progress {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin-bottom: var(--space-md);
  padding: var(--space-sm) var(--space-md);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
}
.guide-global-progress-text {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.guide-global-progress-bar {
  flex: 1;
  height: 8px;
  background: var(--color-bg-muted);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.guide-global-progress-fill {
  height: 100%;
  background: var(--color-accent);
  border-radius: var(--radius-full);
  transition: width var(--transition-smooth);
}

/* Progress track */
.guide-progress-bar {
  margin-bottom: var(--space-xl);
  overflow-x: auto;
  padding: var(--space-sm) 0;
}
.guide-progress-track {
  display: flex;
  align-items: center;
  gap: 0;
  min-width: max-content;
}
.guide-progress-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-full);
  background: var(--color-bg-card);
  border: 2px solid var(--color-border);
  font-weight: 700;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  flex-shrink: 0;
  cursor: pointer;
  padding: 0;
}
.guide-progress-dot:hover {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}
.guide-progress-dot--active {
  border-color: var(--color-accent);
  color: var(--color-accent);
  background: var(--color-accent-light);
}
.guide-progress-dot--done {
  background: var(--color-success);
  border-color: var(--color-success);
  color: #fff;
}
.guide-progress-dot--done:hover {
  background: var(--color-success);
  border-color: var(--color-success);
}
.guide-progress-number { line-height: 1; }
.guide-progress-line {
  flex: 1;
  min-width: 24px;
  height: 2px;
  background: var(--color-border-light);
  transition: background 0.15s;
}
.guide-progress-line--done {
  background: var(--color-success);
}

/* Phase card */
.guide-phase {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  margin-bottom: var(--space-lg);
  box-shadow: var(--shadow-sm);
}
.guide-phase-header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-md);
  cursor: pointer;
  user-select: none;
  margin-bottom: var(--space-lg);
  padding-bottom: var(--space-md);
  border-bottom: 1px solid var(--color-border-light);
}
.guide-phase--collapsed .guide-phase-header {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}
.guide-phase-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-md);
  background: var(--color-primary-light);
  color: var(--color-primary);
  flex-shrink: 0;
}
.guide-phase-info { flex: 1; min-width: 0; }
.guide-phase-label {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-accent);
  margin-bottom: var(--space-xs);
}
.guide-phase-title {
  font-size: var(--text-xl);
  font-weight: 700;
  font-family: var(--font-heading);
  color: var(--color-primary-dark);
  margin: 0 0 var(--space-xs) 0;
}
.guide-phase-subtitle {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  margin: 0;
}
.guide-phase--collapsed .guide-phase-subtitle { display: none; }
.guide-phase-meta {
  flex-shrink: 0;
  margin-top: var(--space-xs);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}
.guide-phase-badge {
  display: inline-block;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-text-muted);
  background: var(--color-bg-muted);
  padding: 2px 10px;
  border-radius: var(--radius-full);
  white-space: nowrap;
}
.guide-phase-badge--active {
  color: var(--color-accent);
  background: var(--color-accent-light);
}
.guide-phase-badge--done {
  color: var(--color-success);
  background: var(--color-success-light);
}
.guide-phase-time {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-text-muted);
  background: var(--color-bg-muted);
  padding: 4px 10px;
  border-radius: var(--radius-full);
}
.guide-phase-time svg { opacity: 0.7; }

/* Chevron */
.guide-phase-chevron {
  flex-shrink: 0;
  margin-top: var(--space-sm);
  color: var(--color-text-muted);
  transition: transform var(--transition-smooth);
}
.guide-phase--collapsed .guide-phase-chevron {
  transform: rotate(-90deg);
}

/* Accordion body */
.guide-steps-wrapper {
  max-height: 5000px;
  overflow: hidden;
  transition: max-height var(--transition-smooth), opacity var(--transition-smooth);
  opacity: 1;
}
.guide-phase--collapsed .guide-steps-wrapper {
  max-height: 0;
  opacity: 0;
}

/* Steps timeline */
.guide-steps { padding-left: var(--space-sm); }
.guide-step {
  display: flex;
  gap: var(--space-md);
  position: relative;
}
.guide-step-connector {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
  width: 20px;
}
.guide-step-dot {
  width: 10px;
  height: 10px;
  border-radius: var(--radius-full);
  background: var(--color-accent);
  border: 2px solid var(--color-bg-card);
  box-shadow: 0 0 0 2px var(--color-accent);
  flex-shrink: 0;
  margin-top: 6px;
  transition: background 0.15s, box-shadow 0.15s;
}
.guide-step--done .guide-step-dot {
  background: var(--color-success);
  box-shadow: 0 0 0 2px var(--color-success);
}
.guide-step-line {
  flex: 1;
  width: 2px;
  background: var(--color-border-light);
  margin: var(--space-xs) 0;
}
.guide-step-content {
  flex: 1;
  padding-bottom: var(--space-lg);
  min-width: 0;
}
.guide-step:last-child .guide-step-content { padding-bottom: 0; }
.guide-step-header {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
  margin-bottom: var(--space-xs);
}

/* Checkbox */
.guide-step-checkbox {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  flex-shrink: 0;
  cursor: pointer;
}
.guide-step-checkbox input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.guide-step-checkmark {
  width: 18px;
  height: 18px;
  border: 2px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-bg-card);
  transition: background 0.15s, border-color 0.15s;
  display: flex;
  align-items: center;
  justify-content: center;
}
.guide-step-checkbox input:checked + .guide-step-checkmark {
  background: var(--color-success);
  border-color: var(--color-success);
}
.guide-step-checkbox input:checked + .guide-step-checkmark::after {
  content: '';
  width: 5px;
  height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
  margin-top: -1px;
}
.guide-step-checkbox:hover .guide-step-checkmark {
  border-color: var(--color-accent);
}

.guide-step-title {
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-text);
  margin: 0;
  transition: color 0.15s;
}
.guide-step--done .guide-step-title {
  color: var(--color-text-muted);
  text-decoration: line-through;
  text-decoration-color: var(--color-border);
}
.guide-step-role {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-primary);
  background: var(--color-primary-light);
  padding: 2px 8px;
  border-radius: var(--radius-full);
  white-space: nowrap;
}
.guide-step-desc {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  line-height: 1.6;
  margin: 0 0 var(--space-sm) 0;
}
.guide-step--done .guide-step-desc { opacity: 0.6; }
.guide-step-tip {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  font-size: var(--text-sm);
  color: var(--color-accent-hover);
  background: var(--color-accent-light);
  border-left: 3px solid var(--color-accent);
  padding: var(--space-sm) var(--space-md);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  margin-bottom: var(--space-sm);
  line-height: 1.5;
}
.guide-step-tip svg {
  flex-shrink: 0;
  margin-top: 2px;
  opacity: 0.8;
}
.guide-step .btn { margin-top: var(--space-xs); }

/* Final CTA */
.guide-final {
  text-align: center;
  padding: var(--space-2xl) var(--space-lg);
  background: var(--color-bg-card);
  border: 2px solid var(--color-accent);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-lg);
}
.guide-final-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border-radius: var(--radius-full);
  background: var(--color-accent-light);
  color: var(--color-accent);
  margin-bottom: var(--space-md);
}
.guide-final h2 {
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  color: var(--color-primary-dark);
  margin: 0 0 var(--space-sm) 0;
}
.guide-final p {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  max-width: 600px;
  margin: 0 auto var(--space-lg) auto;
  line-height: 1.6;
}

/* Auto-tracked steps (computed from DB, not toggleable) */
.guide-step--auto .guide-step-checkmark {
  cursor: default;
}
.guide-step--auto .guide-step-checkbox:hover .guide-step-checkmark {
  border-color: var(--color-border);
}
.guide-step--auto.guide-step--done .guide-step-checkmark {
  background: var(--color-primary);
  border-color: var(--color-primary);
}
.guide-step-auto-tag {
  font-size: 10px;
  font-weight: 600;
  color: var(--color-primary);
  background: var(--color-primary-light);
  padding: 1px 6px;
  border-radius: var(--radius-full);
  white-space: nowrap;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* Guide breadcrumb */
.guide-breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin-bottom: var(--space-lg);
  font-size: var(--text-sm);
}
.guide-breadcrumb a {
  color: var(--color-primary);
  text-decoration: none;
  transition: color 0.15s;
}
.guide-breadcrumb a:hover {
  color: var(--color-primary-hover, var(--color-primary));
  text-decoration: underline;
}
.guide-breadcrumb-sep {
  color: var(--color-text-muted);
}
.guide-breadcrumb-current {
  color: var(--color-text-secondary);
  font-weight: 500;
}

/* Dashboard — Guide Progress */
.guide-dashboard-phases {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--space-sm);
  padding: 0 var(--space-md) var(--space-md);
}
.guide-dashboard-phase {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-light);
  text-decoration: none;
  color: inherit;
  transition: all var(--transition-smooth);
}
.guide-dashboard-phase:hover {
  box-shadow: var(--shadow-sm);
  border-color: var(--color-border);
  transform: translateY(-1px);
  text-decoration: none;
}
.guide-dashboard-phase--completed { border-left: 3px solid var(--color-success); }
.guide-dashboard-phase--active { border-left: 3px solid var(--color-warning); }
.guide-dashboard-phase--pending { border-left: 3px solid var(--color-border); }
.guide-dashboard-phase-header {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}
.guide-dashboard-phase-number {
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--color-text-muted);
  background: var(--color-bg);
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  flex-shrink: 0;
}
.guide-dashboard-phase--completed .guide-dashboard-phase-number {
  background: var(--color-success);
  color: white;
}
.guide-dashboard-phase-title {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.guide-dashboard-phase-bar {
  height: 4px;
  background: var(--color-border-light);
  border-radius: 2px;
  overflow: hidden;
}
.guide-dashboard-phase-fill {
  height: 100%;
  background: var(--color-success);
  border-radius: 2px;
  transition: width 0.3s ease;
}
.guide-dashboard-phase--active .guide-dashboard-phase-fill {
  background: var(--color-warning);
}
.guide-dashboard-phase-count {
  font-size: 10px;
  color: var(--color-text-muted);
  font-weight: 500;
}

/* Responsive */
@media (max-width: 640px) {
  .guide-phase-header { flex-direction: column; }
  .guide-phase-meta { align-self: flex-start; flex-direction: row; }
  .guide-step-header { flex-direction: row; align-items: center; }
  .guide-global-progress { flex-direction: column; align-items: stretch; }
}

/* --- Portal Layout (Vendor, standalone pages) --- */
.portal-layout {
  min-height: 100vh;
  background: var(--color-bg);
}

.portal-header {
  background: var(--color-bg-card);
  border-bottom: 1px solid var(--color-border-light);
  padding: var(--space-md) var(--space-xl);
  box-shadow: 0 1px 3px rgba(15, 36, 64, 0.04);
}

.portal-header-inner {
  max-width: 1024px;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.portal-brand {
  font-size: var(--text-xl);
  font-weight: 800;
  font-family: var(--font-heading);
  color: var(--color-primary);
}

.portal-main {
  max-width: 1024px;
  margin: 0 auto;
  padding: var(--space-xl);
  animation: content-in 350ms cubic-bezier(0.4, 0, 0.2, 1);
}

.portal-footer {
  text-align: center;
  padding: var(--space-lg);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
}

.portal-header-vendor {
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--color-primary);
  background: var(--color-primary-light);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  letter-spacing: 0.01em;
}

/* --- Vendor Portal Hero Banner --- */
.vendor-hero {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  padding: var(--space-xl);
  margin-bottom: var(--space-xl);
  background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-dark) 100%);
  border-radius: var(--radius-lg);
  color: #FFFFFF;
}

.vendor-hero-icon {
  flex-shrink: 0;
  width: 72px;
  height: 72px;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(4px);
  border: 2px solid rgba(255, 255, 255, 0.25);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  font-weight: 800;
  font-family: var(--font-heading);
  color: #FFFFFF;
  line-height: 1;
}

.vendor-hero-content {
  min-width: 0;
}

.vendor-hero-label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  opacity: 0.7;
  margin-bottom: var(--space-xs);
  font-weight: 600;
}

.vendor-hero-name {
  font-size: 28px;
  font-weight: 800;
  font-family: var(--font-heading);
  margin: 0 0 var(--space-sm);
  line-height: 1.2;
  color: #FFFFFF;
  overflow: hidden;
  text-overflow: ellipsis;
}

.vendor-hero-org {
  font-size: var(--text-sm);
  opacity: 0.85;
  margin-bottom: var(--space-xs);
}

.vendor-hero-org strong {
  color: #FFFFFF;
  font-weight: 700;
}

.vendor-hero-contact {
  font-size: var(--text-xs);
  opacity: 0.65;
}

@media (max-width: 600px) {
  .vendor-hero {
    flex-direction: column;
    text-align: center;
    padding: var(--space-lg);
  }
  .vendor-hero-name {
    font-size: 22px;
  }
  .vendor-hero-icon {
    width: 56px;
    height: 56px;
    font-size: 24px;
  }
}

/* ============================================================
   Error Pages
   ============================================================ */

.error-page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: var(--color-bg);
  padding: var(--space-xl);
}

.error-card {
  background: var(--color-bg-card);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: var(--space-2xl) var(--space-2xl) var(--space-xl);
  text-align: center;
  max-width: 480px;
  width: 100%;
  animation: auth-card-in 500ms cubic-bezier(0.4, 0, 0.2, 1);
}

.error-icon {
  margin-bottom: var(--space-md);
}

.error-icon svg {
  width: 64px;
  height: 64px;
  stroke-width: 1.5;
}

.error-card.error-403 .error-icon svg { color: var(--color-warning); }
.error-card.error-404 .error-icon svg { color: var(--color-text-muted); }
.error-card.error-429 .error-icon svg { color: var(--color-warning); }
.error-card.error-500 .error-icon svg { color: var(--color-danger); }

.error-code {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-muted);
  letter-spacing: 0.05em;
  margin-bottom: var(--space-xs);
}

.error-title {
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  font-weight: 700;
  color: var(--color-text);
  margin: 0 0 var(--space-sm);
}

.error-message {
  font-size: var(--text-base);
  color: var(--color-text-secondary);
  margin: 0 0 var(--space-lg);
  line-height: 1.5;
}

.error-detail {
  background: var(--color-bg-muted);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  padding: var(--space-sm) var(--space-md);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
  text-align: left;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  margin: 0 0 var(--space-lg);
}

.error-actions {
  display: flex;
  gap: var(--space-sm);
  justify-content: center;
}

.error-footer {
  margin-top: var(--space-xl);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-family: var(--font-body);
}

/* Inline error partial (for HTMX partial requests) */
.error-inline {
  display: flex;
  align-items: flex-start;
  gap: var(--space-md);
  padding: var(--space-lg);
  max-width: 480px;
  margin: var(--space-xl) auto;
  text-align: left;
}

.error-inline-icon svg {
  width: 32px;
  height: 32px;
  stroke-width: 1.5;
  flex-shrink: 0;
}

.error-inline.error-403 .error-inline-icon svg { color: var(--color-warning); }
.error-inline.error-404 .error-inline-icon svg { color: var(--color-text-muted); }
.error-inline.error-429 .error-inline-icon svg { color: var(--color-warning); }
.error-inline.error-500 .error-inline-icon svg { color: var(--color-danger); }

.error-inline-content strong {
  display: block;
  font-size: var(--text-base);
  color: var(--color-text);
  margin-bottom: var(--space-xs);
}

.error-inline-content p {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  margin: 0;
}

/* ══════════════════════════════════════════════════════════════
   RAT Page — Stats strip, panels, table enhancements
   ══════════════════════════════════════════════════════════════ */

/* ── Stats strip ── */
.rat-stats-strip {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  padding: var(--space-md) var(--space-lg);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-lg);
}

.rat-stat {
  display: flex;
  align-items: center;
  gap: 6px;
}

.rat-stat-value {
  font-size: var(--text-lg);
  font-weight: 700;
  font-family: var(--font-heading);
  color: var(--color-text);
  line-height: 1;
}

.rat-stat-label {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.rat-stat-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

.rat-stat-dot--draft   { background: var(--color-text-muted); }
.rat-stat-dot--review  { background: var(--color-info, #3B82F6); }
.rat-stat-dot--active  { background: var(--color-success); }

/* ── Collapsible panels ── */
.rat-panels {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
  margin-bottom: var(--space-lg);
}

/* Modificador para cuando solo se renderiza un panel (p. ej. al AUDITOR se le
   oculta el de plantillas sugeridas): ocupa el ancho completo en vez de dejar
   la mitad derecha de la grilla vacía. */
.rat-panels--single {
  grid-template-columns: 1fr;
}

.rat-panel {
  min-width: 0;
}

.rat-panel-details {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.rat-panel-summary {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md) var(--space-lg);
  cursor: pointer;
  user-select: none;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
  list-style: none;
  transition: background 0.15s ease;
}

.rat-panel-summary::-webkit-details-marker { display: none; }
.rat-panel-summary::marker { content: ""; }

.rat-panel-summary:hover {
  background: var(--color-row-stripe);
}

.rat-panel-summary svg:first-child {
  color: var(--color-text-muted);
  flex-shrink: 0;
}

.rat-panel-chevron {
  color: var(--color-text-muted);
  flex-shrink: 0;
  transition: transform 0.2s ease;
}

.rat-panel-details[open] .rat-panel-chevron {
  transform: rotate(180deg);
}

.rat-panel-body {
  padding: 0 var(--space-lg) var(--space-lg);
}

.rat-panel-body .alert:last-child {
  margin-bottom: 0;
}

/* ── Template list inside panel ── */
.rat-template-list {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.rat-template-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-sm) 0;
  border-bottom: 1px solid var(--color-border-light);
}

.rat-template-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.rat-template-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.rat-template-name {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex-wrap: wrap;
}

.rat-template-desc {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rat-template-actions {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex-shrink: 0;
}

/* ── Table enhancements ── */
.rat-table td {
  vertical-align: middle;
}

.rat-activity-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.rat-activity-name {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 2px;
}

.rat-activity-name strong {
  margin-right: 4px;
}

.rat-activity-meta {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.rat-categories {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
}

/* ── Empty state ── */
.rat-empty-state {
  text-align: center;
  padding: var(--space-2xl) var(--space-lg);
}

.rat-empty-icon {
  color: var(--color-text-muted);
  margin-bottom: var(--space-md);
  opacity: 0.5;
}

.rat-empty-title {
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--color-text);
  margin: 0 0 var(--space-xs);
}

.rat-empty-desc {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin: 0;
}

/* ── Responsive ── */
@media (max-width: 768px) {
  .rat-panels {
    grid-template-columns: 1fr;
  }

  .rat-stats-strip {
    flex-wrap: wrap;
    gap: var(--space-md);
  }
}


/* ===========================================================================
   Training Module
   =========================================================================== */

/* --- Callout (reusable info banner) --- */
.callout {
  padding: var(--space-md) var(--space-lg);
  border-radius: var(--radius-md);
  border-left: 4px solid var(--color-primary);
  background: #EEF2F7;
  font-size: var(--text-sm);
}

.callout-info  { border-left-color: var(--color-primary); background: #EEF2F7; }
.callout-success { border-left-color: var(--color-success); background: #ECFDF5; }
.callout-warning { border-left-color: var(--color-warning); background: #FFFBEB; }
.callout-danger  { border-left-color: var(--color-danger); background: #FEF2F2; }

/* Solo el <strong> que es HIJO DIRECTO del callout es el título y va en bloque.
   Con el selector descendente (`.callout strong`) también caía el énfasis dentro
   de un párrafo: una frase como "se heredan de <strong>Terceros</strong>. Si..."
   se partía en tres renglones y el punto quedaba huérfano al inicio de uno. */
.callout > strong { display: block; margin-bottom: var(--space-xs); }

/* --- Training card grid --- */
.training-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: var(--space-md);
}

.training-card {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-left: 4px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  display: flex;
  flex-direction: column;
  transition: all var(--transition-smooth);
  animation: card-in 400ms cubic-bezier(0.4, 0, 0.2, 1) backwards;
}

.training-card:nth-child(1) { animation-delay: 50ms; }
.training-card:nth-child(2) { animation-delay: 100ms; }
.training-card:nth-child(3) { animation-delay: 150ms; }
.training-card:nth-child(4) { animation-delay: 200ms; }
.training-card:nth-child(5) { animation-delay: 250ms; }
.training-card:nth-child(6) { animation-delay: 300ms; }

.training-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.training-card--completed { border-left-color: var(--color-success); }
.training-card--expired   { border-left-color: var(--color-warning); }
.training-card--failed    { border-left-color: var(--color-danger); }
.training-card--pending   { border-left-color: var(--color-primary); }

.training-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}

.training-card-title {
  font-weight: 700;
  font-size: var(--text-base);
  color: var(--color-text);
  line-height: 1.3;
}

.training-card-meta {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  margin-bottom: var(--space-sm);
}

.training-card-meta .meta-item {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.training-card-meta .meta-sep {
  color: var(--color-border);
}

.training-card-desc {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  line-height: 1.5;
  margin-bottom: var(--space-sm);
  flex: 1;
}

.training-card-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-top: auto;
  padding-top: var(--space-sm);
  border-top: 1px solid var(--color-border-light);
}

.training-card-score {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.training-card-score strong {
  color: var(--color-text);
}

/* --- Progress section --- */
.training-progress {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  padding: var(--space-lg);
}

.training-progress-ring {
  position: relative;
  width: 80px;
  height: 80px;
  flex-shrink: 0;
}

.training-progress-ring svg {
  transform: rotate(-90deg);
}

.training-progress-ring .ring-bg {
  fill: none;
  stroke: var(--color-border-light);
  stroke-width: 6;
}

.training-progress-ring .ring-fill {
  fill: none;
  stroke-width: 6;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.6s ease;
}

.training-progress-ring .ring-text {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--color-text);
}

.training-progress-details {
  flex: 1;
}

.training-progress-label {
  font-weight: 600;
  font-size: var(--text-base);
  margin-bottom: var(--space-xs);
}

.training-progress-stats {
  display: flex;
  gap: var(--space-lg);
  flex-wrap: wrap;
}

.training-stat {
  text-align: center;
}

.training-stat-value {
  font-size: var(--text-xl);
  font-weight: 700;
  line-height: 1;
}

.training-stat-value--success { color: var(--color-success); }
.training-stat-value--warning { color: var(--color-warning); }
.training-stat-value--danger  { color: var(--color-danger); }
.training-stat-value--muted   { color: var(--color-text-muted); }

.training-stat-label {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  margin-top: 2px;
}

/* --- Module detail metadata --- */
.training-meta-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-lg);
}

.training-meta-item {
  text-align: center;
}

.training-meta-value {
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--color-text);
}

.training-meta-label {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  margin-top: 2px;
}

/* --- Quiz styling --- */
.quiz-question {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  margin-bottom: var(--space-md);
  transition: border-color var(--transition-smooth);
}

.quiz-question:hover {
  border-color: var(--color-border);
}

.quiz-question-header {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-md);
}

.quiz-question-number {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-full);
  background: var(--color-primary);
  color: white;
  font-size: var(--text-xs);
  font-weight: 700;
  flex-shrink: 0;
}

.quiz-question-text {
  flex: 1;
  min-width: 0;
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--color-text);
  line-height: 1.4;
}

.quiz-question-points {
  flex-shrink: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-text-secondary);
  white-space: nowrap;
}

.quiz-option {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-xs);
  cursor: pointer;
  transition: all var(--transition-smooth);
  font-size: var(--text-sm);
}

.quiz-option:hover {
  background: var(--color-bg);
  border-color: var(--color-primary);
}

.quiz-option input[type="radio"] {
  accent-color: var(--color-primary);
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.quiz-option:has(input:checked) {
  background: #EEF2F7;
  border-color: var(--color-primary);
}

/* --- Quiz result --- */
.quiz-result-card {
  text-align: center;
  padding: var(--space-xl) var(--space-lg);
}

.quiz-result-icon {
  width: 64px;
  height: 64px;
  border-radius: var(--radius-full);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-md);
}

.quiz-result-icon--pass {
  background: #ECFDF5;
  color: var(--color-success);
}

.quiz-result-icon--fail {
  background: #FEF2F2;
  color: var(--color-danger);
}

.quiz-result-icon svg {
  width: 32px;
  height: 32px;
}

/* El veredicto del resultado del quiz es un <h2>: no por su tamaño, sino por la
   jerarquia de encabezados de la pantalla (h1 modulo -> h2 veredicto -> h3
   "Revision de Respuestas"), que lo mete una sola vez en el indice del
   documento. Por eso la regla declara TODO lo que el reset de h1..h6 le aporta
   —margen, interlineado, familia y tracking de titulos— y no solo lo que
   difiere: asi el bloque se ve igual que cuando era un div y sigue viendose
   igual si manana cambian los estilos de encabezado del producto. */
.quiz-result-title {
  font-size: var(--text-xl);
  font-weight: 700;
  margin: 0 0 var(--space-xs);
  line-height: 1.6;
  font-family: var(--font-body);
  letter-spacing: normal;
}

.quiz-result-title--pass { color: var(--color-success); }
.quiz-result-title--fail { color: var(--color-danger); }

.quiz-result-score {
  font-size: var(--text-3xl);
  font-weight: 800;
  color: var(--color-text);
  line-height: 1;
  margin-bottom: var(--space-xs);
}

.quiz-result-detail {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* --- Answer review --- */
.answer-review {
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-bottom: var(--space-sm);
}

.answer-review-header {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border-light);
  font-weight: 600;
  font-size: var(--text-sm);
}

.answer-review-number {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: 700;
  flex-shrink: 0;
}

.answer-review-number--correct {
  background: #ECFDF5;
  color: var(--color-success);
}

.answer-review-number--wrong {
  background: #FEF2F2;
  color: var(--color-danger);
}

.answer-option {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-xs) var(--space-md);
  font-size: var(--text-sm);
  border-bottom: 1px solid var(--color-border-light);
}

.answer-option:last-child { border-bottom: none; }

.answer-option--correct {
  background: #ECFDF5;
  color: var(--color-success);
  font-weight: 500;
}

.answer-option--wrong {
  background: #FEF2F2;
  color: var(--color-danger);
}

.answer-option-icon {
  width: 18px;
  flex-shrink: 0;
  text-align: center;
  font-weight: 700;
}

/* --- Team dashboard table --- */
.team-progress-bar {
  height: 6px;
  background: var(--color-border-light);
  border-radius: 3px;
  overflow: hidden;
  min-width: 80px;
}

.team-progress-fill {
  height: 100%;
  border-radius: 3px;
  transition: width 0.4s ease;
}

/* --- Responsive --- */
@media (max-width: 768px) {
  .training-grid {
    grid-template-columns: 1fr;
  }

  .training-progress {
    flex-direction: column;
    text-align: center;
  }

  .training-progress-stats {
    justify-content: center;
  }

  .training-meta-grid {
    grid-template-columns: 1fr 1fr;
  }
}

/* --- Wizard Stepper (reusable N-step indicator) --- */
.wizard-stepper {
  display: flex;
  list-style: none;
  gap: 0;
  padding: 0;
  margin: 0 0 24px 0;
}

.wizard-step {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

.wizard-step-circle {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 2px solid var(--color-border);
  background: var(--color-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  color: inherit;
  z-index: 1;
}

.wizard-step-label {
  margin-top: 8px;
  text-align: center;
}

.wizard-step--current .wizard-step-circle {
  border-color: var(--color-primary);
  color: var(--color-primary);
  background: var(--color-primary-light);
}

.wizard-step--current {
  color: var(--color-primary);
  font-weight: 600;
}

.wizard-step--done .wizard-step-circle {
  background: var(--color-success);
  border-color: var(--color-success);
  color: #fff;
}

.wizard-step--done {
  color: var(--color-text);
}

.wizard-step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 15px;
  left: calc(50% + 16px);
  right: calc(-50% + 16px);
  height: 2px;
  background: var(--color-border);
  z-index: 0;
}

.wizard-step--done:not(:last-child)::after {
  background: var(--color-success);
}

/* El stepper de la Guía de Cumplimiento (wizard/_wizard_stepper.html) comparte
   las clases `.wizard-step*` de arriba, pero dibuja círculos de 20px en vez de
   32px: la línea conectora, centrada para 32px (`top:15px`), le quedaba 5px por
   debajo del centro. `.wizard-stepper-list` existe SOLO en ese template, así que
   este ajuste no alcanza al stepper del wizard de biometría.
   Atado al tamaño del círculo: 20px de alto ⇒ centro en 10px, línea de 2px ⇒ 9px. */
.wizard-stepper-list .wizard-step:not(:last-child)::after {
  top: 9px;
}
/* Cada paso navega a su pantalla. Se marca con subrayado —no solo con el
   cursor— para que se note que es accionable, y el foco de teclado tiene su
   propio contorno: el enlace envuelve círculo y etiqueta, así que sin esto el
   recuadro por defecto quedaría pegado al texto. */
.wizard-step-link:hover .wizard-step-label { text-decoration: underline; }
.wizard-step-link:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* --- Diff view (unified diff rendering for policy versioning) --- */
.diff-view {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 16px;
  overflow-x: auto;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: var(--text-sm);
  line-height: 1.6;
  white-space: pre;
}
.diff-view span { display: block; padding: 0 8px; }
.diff-add  { background: var(--color-success-light); color: var(--color-success); }
.diff-del  { background: var(--color-danger-light);  color: var(--color-danger); }
.diff-hunk { background: var(--color-row-stripe);    color: var(--color-text-secondary); font-weight: 600; }
.diff-ctx  { color: var(--color-text); }

/* ============================================================
   Capa de Orientación — Command palette (⌘K)
   ============================================================ */
.palette-trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  height: 34px;
  padding: 0 var(--space-sm) 0 var(--space-md);
  background: var(--color-bg-muted);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-full);
  color: var(--color-text-secondary);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}
.palette-trigger:hover {
  border-color: var(--color-border);
  background: var(--color-bg-card);
  color: var(--color-text);
}
.palette-trigger-text { line-height: 1; }
.palette-trigger-kbd {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
  color: var(--color-text-muted);
}
@media (max-width: 640px) {
  .palette-trigger-text, .palette-trigger-kbd { display: none; }
  .palette-trigger { padding: 0; width: 34px; justify-content: center; }
}

.command-palette {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: flex-start;
  justify-content: center;
}
.command-palette[hidden] { display: none; }
.command-palette-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 36, 64, 0.35);
  backdrop-filter: blur(2px);
}
.command-palette-box {
  position: relative;
  width: min(640px, calc(100vw - 2 * var(--space-md)));
  margin-top: 12vh;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  animation: palette-in var(--transition-smooth);
}
@keyframes palette-in {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.command-palette-input-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md);
  border-bottom: 1px solid var(--color-border-light);
}
.command-palette-search-icon { color: var(--color-text-muted); flex-shrink: 0; }
.command-palette-input {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--text-lg);
  color: var(--color-text);
}
.command-palette-esc {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
  cursor: pointer;
}
.command-palette-results { max-height: 52vh; overflow-y: auto; padding: var(--space-xs) 0; }
.palette-group { padding: var(--space-xs) 0; }
.palette-group-title {
  padding: var(--space-xs) var(--space-md);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.palette-item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  color: var(--color-text);
  text-decoration: none;
  cursor: pointer;
  border-left: 2px solid transparent;
}
.palette-item:hover,
.palette-item--active {
  background: var(--color-primary-light);
  border-left-color: var(--color-accent);
  text-decoration: none;
}
.palette-item-label { flex: 1; font-size: var(--text-base); }
.palette-item-meta { font-size: var(--text-xs); color: var(--color-text-muted); }
.palette-item-icon {
  width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  background: var(--color-accent-light);
  color: var(--color-accent);
  font-weight: 700;
  flex-shrink: 0;
}
.palette-item-badge {
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--color-text-secondary);
  background: var(--color-bg-muted);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
  flex-shrink: 0;
}
.palette-empty {
  padding: var(--space-xl) var(--space-md);
  text-align: center;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}
.command-palette-hint {
  display: flex;
  gap: var(--space-lg);
  padding: var(--space-sm) var(--space-md);
  border-top: 1px solid var(--color-border-light);
  background: var(--color-bg-muted);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.command-palette-hint kbd {
  font-family: var(--font-mono);
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: 4px;
  padding: 0 4px;
}

/* ============================================================
   Capa de Orientación — Centro de Atención (campana)
   ============================================================ */
.attention-wrap { position: relative; }
.attention-bell {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--color-text-secondary);
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.attention-bell:hover {
  background: var(--color-bg-muted);
  color: var(--color-text);
}
.attention-badge-slot { position: absolute; top: 2px; right: 2px; }
.attention-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  border-radius: var(--radius-full);
  background: var(--color-danger);
  color: #fff;
  font-size: 0.66rem;
  font-weight: 700;
  line-height: 1;
  box-shadow: 0 0 0 2px var(--color-bg-card);
}
.attention-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: min(380px, calc(100vw - 2 * var(--space-md)));
  max-height: 70vh;
  overflow-y: auto;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  z-index: 900;
  animation: palette-in var(--transition);
}
.attention-panel[hidden] { display: none; }
.attention-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-border-light);
}
.attention-panel-title { font-weight: 700; color: var(--color-text); font-size: var(--text-sm); }
.attention-panel-all { font-size: var(--text-xs); }
.attention-list { list-style: none; margin: 0; padding: 0; }
.attention-item { border-bottom: 1px solid var(--color-border-light); }
.attention-item:last-child { border-bottom: none; }
.attention-item > a {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  text-decoration: none;
  color: var(--color-text);
}
.attention-item > a:hover { background: var(--color-row-hover); text-decoration: none; }
.attention-item-main { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.attention-item-title {
  font-size: var(--text-sm);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.attention-item-context { font-size: var(--text-xs); color: var(--color-text-muted); }
.attention-sev {
  flex-shrink: 0;
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 2px 7px;
  border-radius: var(--radius-full);
  white-space: nowrap;
}
.attention-sev--vencido { background: var(--color-danger-light); color: var(--color-danger); }
.attention-sev--hoy { background: var(--color-warning-light); color: var(--color-warning-hover); }
.attention-sev--semana { background: var(--color-info-light); color: var(--color-info); }
.attention-item-badge {
  flex-shrink: 0;
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--color-text-secondary);
  background: var(--color-bg-muted);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
}
.attention-empty,
.attention-more {
  display: block;
  padding: var(--space-md);
  text-align: center;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.attention-more { border-top: 1px solid var(--color-border-light); font-weight: 600; }
.attention-list--page .attention-item > a { padding: var(--space-md); align-items: center; }
.attention-list--page .attention-item-title { font-size: var(--text-base); }

/* ==========================================================================
   Detalle de RAT — documento + panel de historial
   `rat/detail.html` reparte el ancho entre el documento (columna elástica) y
   el panel «Historial de cambios» (columna acotada). El panel acompaña al
   lector mientras recorre el documento, que es largo; por eso es sticky.
   ========================================================================== */
.rat-detail-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(280px, 28%, 420px);
  gap: var(--space-lg);
  align-items: start;
}

.rat-history-panel {
  position: sticky;
  top: calc(var(--navbar-height) + var(--space-lg));
  /* Con el documento tan largo, el historial de una actividad muy movida
     desbordaría la pantalla: hace su propio scroll en vez de estirar la página. */
  max-height: calc(100vh - var(--navbar-height) - var(--space-xl) * 2);
  overflow-y: auto;
}

.rat-history-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.rat-history-item {
  padding: var(--space-sm) 0;
  border-bottom: 1px solid var(--color-border-light);
}
.rat-history-item:last-child { border-bottom: none; }

.rat-history-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  justify-content: space-between;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.rat-history-who { font-weight: 600; overflow-wrap: anywhere; }

.rat-history-action {
  margin: 2px 0 0;
  font-size: var(--text-sm);
  font-weight: 600;
}

.rat-history-details {
  margin: 2px 0 0;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}

/* Motivo de la devolución u observación de quien validó: es lo que el lector
   tiene que corregir, así que se lee al nivel del texto normal, no atenuado
   como el detalle. */
.rat-history-note {
  margin: 2px 0 0;
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}

.rat-history-changes {
  list-style: none;
  margin: var(--space-xs) 0 0;
  padding: 0;
  font-size: var(--text-xs);
}
.rat-history-changes li {
  margin-top: 2px;
  overflow-wrap: anywhere;
}
.rat-history-field { font-weight: 600; }
/* El rojo y el verde quedan reservados para lo que exige atención (una brecha,
   un plazo vencido): pintar así cada campo editado hace ver un problema donde
   sólo hubo una edición. El contraste entre antes y después se da con peso y
   atenuación, no con color. */
.rat-history-old {
  color: var(--color-text-muted);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.rat-history-new { font-weight: 600; }

.rat-history-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-top: var(--space-md);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--color-border-light);
}

@media (max-width: 1100px) {
  .rat-detail-layout { grid-template-columns: 1fr; }
  /* En una sola columna el panel queda bajo el documento: fijarlo lo dejaría
     pegado a un espacio que ya no tiene al lado. */
  .rat-history-panel {
    position: static;
    max-height: none;
    overflow-y: visible;
  }
}

@media print {
  .rat-detail-layout { display: block; }
  .rat-history-panel { display: none; }
}

/* Contador de caracteres de los formularios de decision sobre una RAT
   (`wizard/_rat_approval_form.html`). Atenuado mientras hay margen: es una
   referencia, no una alerta. Al pasarse toma el rojo de error y peso, porque
   ahi si describe algo que va a impedir el envio. El color no viaja solo: el
   texto dice el numero y el bloqueo entrega su propio mensaje. */
.decision-char-count {
  margin: var(--space-xs) 0 0;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-align: right;
}
.decision-char-count--over {
  color: var(--color-danger);
  font-weight: 600;
}

/* ============================================================
   Editor del widget de consentimiento
   (`consent/_widget_create_form.html`, `_widget_edit_form.html`,
   `_widget_fields_builder.html`, `_widget_purposes_builder.html`
   + `widget-field-builder.js`)

   Una sola cáscara de dos columnas para TODO el formulario: a la izquierda el
   acordeón de cuatro secciones (identificación, campos, propósitos, dominios y
   apariencia) y a la derecha, pegada, la vista previa. Antes la previa vivía
   dentro del constructor de campos y se perdía de pantalla justo al llegar a
   los propósitos, que es lo que más cambia lo que ve el titular.

   La previa es la única pieza que carga peso visual: se presenta como la
   superficie del visitante —marco propio, barra teñida con el color elegido y
   `--shadow-lg`—. Todo lo demás se mantiene callado. Las transiciones quedan
   cubiertas por la regla global de `prefers-reduced-motion` del inicio del
   archivo.
   ============================================================ */

/* `#form-container` es hijo directo de `.main-content`, así que hereda su
   animación de entrada, y el keyframe `content-in` anima `transform`. Un
   ancestro con `transform` activo pasa a ser el contenedor de referencia de
   cualquier descendiente `position: fixed`: durante esos 350 ms la barra de la
   previa (`.wb-aside` bajo 1024px) se posicionaba contra el formulario —que
   mide varias pantallas de alto— en vez de contra la ventana, o sea nacía al
   final del documento, invisible, y «aparecía» un tercio de segundo después.
   La entrada se conserva, pero solo con opacidad: sin `transform` no hay
   contenedor de referencia. No se toca el keyframe global —el resto de la
   aplicación no tiene nada `fixed` dentro—; si el salto reaparece, mirar esta
   regla antes que el JS. */
.main-content > .wb-page {
  animation: content-in-fade 350ms cubic-bezier(0.4, 0, 0.2, 1);
}

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

.wb-shell {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: var(--space-lg);
}

/* Sin `align-items: start`: la columna derecha tiene que estirarse a lo alto de
   la fila para que la previa `sticky` tenga recorrido por donde acompañar. */
.wb-main {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  min-width: 0;
}

.wb-aside { min-width: 0; }

.wb-actions {
  display: flex;
  gap: var(--space-sm);
  justify-content: flex-end;
  margin-top: var(--space-lg);
}

/* --- Acordeón de secciones --- */
.wb-section {
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  background: var(--color-bg-card);
}

/* Regla lateral: reservada para UN solo significado —el error de validación—,
   que es el único que necesita gritar desde fuera de la sección cerrada. El
   dato sensible y el propósito obligatorio se resuelven en su propia etiqueta
   (`.wf-flag`), no repitiendo esta misma afordancia en tres niveles de
   anidación con tres colores distintos. */
.wb-section--error { box-shadow: inset 3px 0 0 0 var(--color-danger); }

/* La cabecera tiene fondo opaco al pasar el mouse y con la sección abierta, y
   ese fondo pinta encima del `inset` de la sección. Repetir la regla sobre la
   propia cabecera hace que la marca de error sobreviva a ambos estados. */
.wb-section--error > .wb-section__head > .wb-section__toggle {
  box-shadow: inset 3px 0 0 0 var(--color-danger);
}

.wb-section__head {
  margin: 0;
  font-size: var(--text-base);
}

.wb-section__toggle {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  width: 100%;
  padding: var(--space-sm) var(--space-md);
  border: none;
  border-radius: var(--radius-md);
  background: none;
  font-family: inherit;
  /* Son la navegación principal de la pantalla, no filas de una lista: nunca
     por debajo del cuerpo de texto. La sección abierta sube otro escalón, para
     que entre el `h1` de la página y el cuerpo haya un peldaño intermedio. */
  font-size: var(--text-base);
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
}
.wb-section__toggle:hover { background: var(--color-bg-muted); }
.wb-section--open .wb-section__toggle {
  background: var(--color-bg-muted);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}

.wb-section__chevron {
  flex-shrink: 0;
  color: var(--color-text-muted);
  transition: transform var(--transition);
}
.wb-section--open .wb-section__chevron { transform: rotate(90deg); }

.wb-section__title {
  flex-shrink: 0;
  font-family: var(--font-heading);
  font-weight: 600;
  /* Alto de línea fijo, holgado para el `--text-lg` de la sección abierta: el
     escalón de jerarquía se conserva, pero la cabecera mide lo mismo abierta y
     cerrada, así que el chevron no se corre bajo el cursor en cada clic. */
  line-height: 1.75rem;
}
.wb-section--open .wb-section__title {
  font-size: var(--text-lg);
  letter-spacing: -0.01em;
}

/* El resumen es información, no decoración: es lo que reemplaza al párrafo
   introductorio. Abierta la sección sobra, porque el estado ya está a la vista.

   Por eso el color es `--color-text-secondary` y no `--color-text-muted`: con
   la sección cerrada esta línea es lo único que comunica el estado, y a
   `--text-xs` el gris apagado se quedaba en 3.11:1 sobre la tarjeta y 2.94:1
   sobre el fondo del hover, bajo el mínimo AA de 4.5:1. El secundario da
   6.15:1 sobre la tarjeta y 5.48:1 sobre el hover. */
.wb-section__state {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
}
.wb-section--open .wb-section__state { display: none; }

.wb-section__alert {
  margin-left: auto;
  flex-shrink: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-danger);
}

.wb-section__panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-md);
  border-top: 1px solid var(--color-border-light);
}

.wb-section__panel .form-group { margin-bottom: 0; }

/* El selector de color no necesita el ancho completo de la columna. */
.wb-color {
  height: 38px;
  padding: 4px;
  max-width: 10rem;
}

.wf-builder__intro { margin: 0; }

.wf-builder__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

/* --- Lista de campos y de propósitos --- */
/* Núcleo y adicionales van en una sola secuencia: el titular también los ve
   así. Lo que los distingue es la afordancia (candado, ausencia de «Quitar»),
   no una caja aparte. */
.wf-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  background: var(--color-bg-card);
}

/* Sin `overflow: hidden`: recortaría la lista de sugerencias que se abre bajo
   la etiqueta. Las esquinas se redondean fila a fila. */
.wf-row:first-child .wf-row__summary {
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}
.wf-row:last-child .wf-row__summary {
  border-radius: 0 0 var(--radius-md) var(--radius-md);
}

.wf-row { position: relative; }
.wf-row + .wf-row { border-top: 1px solid var(--color-border-light); }
.wf-row--dragging { opacity: 0.5; }

/* El dato sensible NO lleva regla lateral: esa afordancia queda reservada al
   error de validación. Lo distingue el peso y el color de su etiqueta
   «Dato sensible» (`.wf-flag--warning`), dentro de la propia fila. */

.wf-row__summary {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
}

.wf-row--open .wf-row__summary { background: var(--color-row-hover); }

.wf-row__handle {
  display: inline-flex;
  color: var(--color-text-muted);
  cursor: grab;
  flex-shrink: 0;
}
.wf-row__handle:active { cursor: grabbing; }

.wf-row__move {
  display: inline-flex;
  flex-direction: column;
  flex-shrink: 0;
}

.wf-row__move-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 16px;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--color-text-muted);
  cursor: pointer;
}
.wf-row__move-btn:hover:not(:disabled) {
  background: var(--color-bg-muted);
  color: var(--color-text);
}
.wf-row__move-btn:disabled {
  opacity: 0.3;
  cursor: default;
}

.wf-row__toggle {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex: 1;
  min-width: 0;
  padding: var(--space-xs) var(--space-sm);
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  font-family: inherit;
  font-size: var(--text-sm);
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
}
.wf-row__toggle:hover { background: var(--color-bg-muted); }

.wf-row__lock {
  color: var(--color-text-muted);
  flex-shrink: 0;
}

.wf-row__label {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wf-row--off .wf-row__label {
  color: var(--color-text-muted);
  font-weight: 500;
}

.wf-chip {
  flex-shrink: 0;
  padding: 1px var(--space-sm);
  border-radius: var(--radius-full);
  background: var(--color-bg-muted);
  color: var(--color-text-secondary);
  font-size: var(--text-xs);
  white-space: nowrap;
}

/* Las etiquetas de estado de una fila (Necesario, Dato sensible) son la
   afordancia que reemplaza a la regla lateral: se separan de los metadatos
   apagados por peso, no por una franja de color en el borde de la fila. */
.wf-flag {
  flex-shrink: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-text-secondary);
  white-space: nowrap;
}
/* «Dato sensible» es la condición con más carga legal de la lista (Art. 16) y,
   retirada la regla lateral, quedó como único indicador: lleva fondo propio, no
   solo color de texto. En ámbar sobre la tarjeta daba 3.2:1 a 12px —bajo el
   4.5:1 que exige AA, y 12px en negrita no califica como texto grande—; el par
   `--color-warning-light` / `--color-warning-text` da 6.8:1 y además la separa
   de las otras tres marcas de un vistazo. Sin `display` propio: cualquier
   declaración de autor le ganaría al `[hidden]` con que el JS la oculta. */
.wf-flag--warning {
  padding: 1px var(--space-sm);
  border-radius: var(--radius-full);
  background: var(--color-warning-light);
  color: var(--color-warning-text);
}

.wf-row__active {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  flex-shrink: 0;
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
  cursor: pointer;
}
.wf-row__active input { accent-color: var(--color-primary); }

/* --- Fila expandida --- */
.wf-row__panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-md) var(--space-md) var(--space-lg) var(--space-xl);
  border-top: 1px dashed var(--color-border-light);
}

.wf-row__panel .form-group {
  position: relative;
  margin-bottom: 0;
}

.wf-row__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-md);
  align-items: start;
}

.wf-row__checks {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding-top: var(--space-lg);
}

.wf-static {
  margin: 0;
  padding: 8px 0;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

/* Advierte, no bloquea: el administrador decide y queda informado. */
.wf-sensitive-note {
  margin: 0;
  padding: var(--space-sm) var(--space-md);
  border-left: 3px solid var(--color-warning);
  border-radius: var(--radius-sm);
  background: var(--color-warning-light);
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
}

/* --- Editor de opciones --- */
.wf-options {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-xs);
}

.wf-options__list {
  list-style: none;
  margin: 0;
  padding: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.wf-option {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}
.wf-option .form-input { flex: 1; }

.wf-option__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--color-text-muted);
  cursor: pointer;
}
.wf-option__remove:hover:not(:disabled) {
  background: var(--color-danger-light);
  color: var(--color-danger);
}
.wf-option__remove:disabled {
  opacity: 0.3;
  cursor: default;
}

/* --- Sugerencias de campos ya usados --- */
.wf-suggest {
  position: absolute;
  z-index: 20;
  left: 0;
  right: 0;
  margin-top: 2px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-card);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}

.wf-suggest__head {
  margin: 0;
  padding: var(--space-xs) var(--space-sm);
  border-bottom: 1px solid var(--color-border-light);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.wf-suggest__list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 220px;
  overflow-y: auto;
}

.wf-suggest__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-xs) var(--space-sm);
  font-size: var(--text-sm);
  cursor: pointer;
}
.wf-suggest__item:hover,
.wf-suggest__item.is-active { background: var(--color-primary-light); }

.wf-suggest__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Estado vacío: una invitación, no un lamento --- */
.wf-empty {
  padding: var(--space-lg);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-md);
  text-align: center;
}
.wf-empty__text {
  margin: 0 0 var(--space-sm);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

/* --- Vista previa ---
   La única pieza de la pantalla que se presenta como superficie propia: es lo
   que va a ver el visitante, no otro panel del panel. Acompaña al formulario en
   las cuatro secciones, también mientras se editan los propósitos. */
.wf-preview {
  --wf-accent: var(--color-primary);
  position: sticky;
  top: calc(var(--navbar-height) + var(--space-md));
  /* 24px de gotera: es el sitio que necesita la sombra del marco (ver
     `.wf-preview__inner`), y el que mantiene alineados el rótulo y la previa. */
  padding: var(--space-lg);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-lg);
  background: var(--color-bg-muted);
}

.wf-preview__summary {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  font-weight: 600;
  list-style: none;
}

.wf-preview__summary::-webkit-details-marker {
  display: none;
}

.wf-preview__count {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 400;
  color: var(--color-text-muted);
}

/* El scroll vive aquí y no en el `<details>`, por dos razones. El rótulo
   «Vista previa» y su contador no se van con el desplazamiento; y el recorte
   que impone todo contenedor con scroll cae sobre este relleno en vez de caer a
   ras del marco, que es lo que mochaba la sombra `--shadow-lg`.
   El relleno está dimensionado contra esa sombra, no elegido a ojo:
   `--shadow-lg` es `0 8px 24px`, o sea 24px de desenfoque a los lados y arriba
   y 32px abajo, contando el desplazamiento vertical. De ahí 24px en tres lados
   (`--space-lg`) y 32px abajo (`--space-xl`); con los 16px anteriores el corte
   seguía ahí, tenue pero visible. Los márgenes negativos —del tamaño del
   relleno del panel, `--space-lg`— devuelven el ancho y el fondo que ese
   relleno le quita, de modo que la previa sigue alineada con el rótulo y con el
   borde del panel. */
.wf-preview__inner {
  max-height: calc(100vh - var(--navbar-height) - var(--space-2xl) - var(--space-xl) - var(--space-sm));
  overflow-y: auto;
  margin: var(--space-sm) calc(var(--space-lg) * -1) calc(var(--space-lg) * -1);
  padding: var(--space-lg) var(--space-lg) var(--space-xl);
}

.wf-preview__hint {
  margin: 0 0 var(--space-sm);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.wf-preview__frame {
  border-radius: var(--radius-md);
  background: var(--color-bg-card);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

/* La barra toma el color que el administrador eligió para su widget: es el
   gesto que convierte la previa en la superficie del visitante. */
.wf-preview__bar {
  display: block;
  height: 6px;
  background: var(--wf-accent);
}

.wf-preview__card {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-md);
  background: var(--color-bg-card);
}

/* Los controles de la vista previa están deshabilitados a propósito: deben
   verse como los verá el titular, no como un campo bloqueado del panel. */
.wf-preview__card .form-input:disabled {
  background: var(--color-bg-card);
  color: var(--color-text-secondary);
  cursor: default;
}

.wf-preview__company {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 700;
}

/* Subtítulo del formulario publicado, bajo el nombre de la empresa. La tarjeta
   separa sus bloques con `gap`, que aquí sería demasiado: el subtítulo pertenece
   al nombre, así que se le acerca cuando va detrás de él. */
.wf-preview__subtitle {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

.wf-preview__company + .wf-preview__subtitle {
  margin-top: calc(var(--space-xs) - var(--space-md));
}

.wf-preview__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

/* Campo que el formulario publicado NO mostrará: un tipo de opciones sin
   opciones utilizables se descarta entero en el SDK. La nota ocupa su lugar y
   dice qué falta. Va deliberadamente sin aspecto de control —borde punteado,
   fondo apagado, texto pequeño— para que no se confunda con un campo real. */
.wf-preview__omitted {
  margin: 0;
  padding: var(--space-sm);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg-muted);
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
}

.wf-preview__label {
  font-size: var(--text-sm);
  font-weight: 600;
}

/* Distintivos junto a la etiqueta en la vista previa: obligatoriedad y dato
   personal sensible. Reproducen los dos chips que el SDK publicado dibuja en el
   sitio del cliente (`.kulvio-cw-required` y `.kulvio-cw-sensitive` de
   `app/static/js/consent-widget.js`): fondo tenue con texto oscuro, sin iconos
   de alarma ni mayúsculas. NO son la marca ámbar de `.wf-sensitive-note` de la
   fila del constructor: aquella le dice al administrador «marcaste este campo
   como sensible», estas le muestran lo que verá su visitante.

   Orden fijo cuando conviven, el del SDK: «Necesario» y después «Dato
   sensible». Lo pone el marcado que arma `appendFieldCaption`. */
.wf-preview__label-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-xs);
}

/* «Necesario». Reemplaza al asterisco que llevaban las etiquetas: rojo pleno
   en cada campo necesario convertía el formulario en una pared de alarma y
   competía con los errores reales, que usan ese mismo color.

   El sistema de diseño no tiene el rojo oscuro del SDK (#991B1B sobre #FEF2F2,
   7.6:1), así que el chip usa el par más cercano: `--color-danger-hover` sobre
   `--color-danger-light`, 5.1:1, por encima del 4.5:1 exigido.
   `--color-danger` sobre ese mismo fondo se queda en 4.1:1 y no alcanza. */
.wf-preview__required {
  display: inline-block;
  padding: 0 var(--space-sm);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-full);
  background: var(--color-danger-light);
  color: var(--color-danger-hover);
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 1.5;
  white-space: nowrap;
}

/* «Dato sensible». El sistema de diseño no tiene el índigo del SDK, así que el
   chip usa el par informativo más cercano —navy sobre azul muy pálido—: 10.2:1
   de contraste, por encima del 4.5:1 exigido. */
.wf-preview__sensitive {
  display: inline-block;
  padding: 0 var(--space-sm);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-full);
  background: var(--color-info-light);
  color: var(--color-info);
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 1.5;
  white-space: nowrap;
}

.wf-preview__sensitive-note {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
}

.wf-preview__help {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.wf-preview__choices {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.wf-preview__choice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

.wf-preview__policy { padding-top: var(--space-xs); }

.wf-preview__purposes {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin: 0;
  padding: var(--space-sm);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
}

/* Texto informativo libre que escribe el administrador, entre los propósitos y
   la casilla de política: ocupa el lugar del recuadro automático que se retiró.
   Reproduce `.kulvio-cw-info-text` del SDK, `pre-line` incluido, que es lo que
   conserva sus saltos de línea sin interpretar el texto como marcado. */
.wf-preview__info-text {
  margin: 0;
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--color-text-secondary);
  white-space: pre-line;
}

.wf-preview__submit {
  padding: var(--space-sm) var(--space-md);
  border: none;
  border-radius: var(--radius-sm);
  background: var(--wf-accent);
  color: var(--color-bg-card);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  opacity: 1;
  cursor: default;
}

/* La descripción y el enlace del propósito, bajo su nombre en la vista previa.
   Ambos son hermanos de la casilla —no van dentro de su etiqueta—, así que la
   sangría izquierda es lo único que los mantiene asociados a ella: el SDK usa
   24px, que aquí es `--space-lg`. La misma regla alinea el enlace a la política
   de privacidad, que allá se sangra igual. */
.wf-preview__purpose-note {
  display: block;
  /* Es un `<p>`, no un `<span>`: hay que anular el margen propio del párrafo. */
  margin: 0 0 0 var(--space-lg);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.wf-preview__purpose-link {
  display: inline-block;
  margin: var(--space-xs) 0 0 var(--space-lg);
  font-size: var(--text-xs);
}

/* --- Constructor de propósitos ---
   Reutiliza la lista, las filas y los controles del constructor de campos: son
   el mismo mecanismo, y el administrador no tiene por qué aprenderlo dos
   veces. */
/* El propósito necesario tampoco lleva regla lateral —ver `.wb-section--error`:
   la regla es del error—. Lo dice su etiqueta «Necesario», que va con el peso
   suficiente para leerse sin abrir la fila. */

/* `display:flex` gana al `display:none` que el navegador aplica por [hidden]:
   los bloques que el JS oculta con ese atributo necesitan decirlo aquí. */
.wb-section__panel[hidden],
.wf-row__panel[hidden],
.wf-options[hidden],
.wf-options__list[hidden],
.wf-builder__actions[hidden],
.wf-preview__choices[hidden] { display: none; }

/* --- Foco visible en todo control del editor --- */
.wb-section__toggle:focus-visible,
.wf-row__toggle:focus-visible,
.wf-row__move-btn:focus-visible,
.wf-row__active:focus-within,
.wf-option__remove:focus-visible,
.wf-suggest__item:focus-visible,
.wf-preview__summary:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

@media (max-width: 1024px) {
  .wb-shell { grid-template-columns: minmax(0, 1fr); }

  /* La previa no desaparece: se recoge en una barra inferior fija que dice
     cuántos campos ve el titular, y se despliega sobre el contenido al tocarla.
     Arranca donde termina el menú lateral: entre 769px y 1024px el menú sigue
     siendo fijo y de 260px de ancho, y una barra a `left: 0` nace con su rótulo
     «Vista previa» tapado y media zona táctil muerta. Bajo 768px el menú pasa a
     off-canvas y la barra recupera el ancho completo (más abajo). */
  .wb-aside {
    position: fixed;
    left: var(--sidebar-width);
    right: 0;
    bottom: 0;
    z-index: 30;
  }
  .wf-preview {
    position: static;
    border-color: var(--color-border);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    background: var(--color-bg-card);
    box-shadow: var(--shadow-lg);
  }
  .wf-preview__inner { max-height: 60vh; }
  /* Bajo 1024px, la previa es plegable. El script alterna `open`, pero el cursor
     viene de aquí (no de estilo en línea) para indicar que es interactivo. */
  .wf-preview__summary {
    justify-content: space-between;
    cursor: pointer;
  }

  /* Sitio para la barra recogida. La barra es `fixed; bottom: 0`, así que lo
     que hay que despejar es el FINAL del documento —donde vive el botón de
     guardar—, no un hueco intermedio del formulario: `.wb-actions` va después
     de `.wb-shell`, fuera de `.wb-main`, y reservar en `.wb-main` dejaba el
     botón primario parcialmente cubierto al llegar al fondo. */
  .wb-actions {
    /* Alto de la barra recogida: el `summary` es una línea de `--text-sm`
       dentro del relleno vertical de `--space-lg` de `.wf-preview`. */
    --wb-preview-bar-height: 4.5rem;
    margin-bottom: calc(var(--wb-preview-bar-height) + var(--space-md));
  }
}

@media (max-width: 768px) {
  /* El menú lateral ya no ocupa la columna izquierda (pasa a off-canvas): la
     barra de la previa recupera el ancho completo de la pantalla. */
  .wb-aside { left: 0; }
}

@media (max-width: 640px) {
  .wf-row__grid { grid-template-columns: minmax(0, 1fr); }
  .wf-row__checks { padding-top: 0; }
  .wf-row__panel { padding-left: var(--space-md); }
  .wf-row__summary { flex-wrap: wrap; }
  .wb-section__toggle { flex-wrap: wrap; }
  .wb-section__alert { margin-left: 0; }
}
