/* Japifon Design System v1.1 — componentes
   Requiere japifon-tokens.css cargado antes. Solo usa tokens, nunca HEX.
   Prefijo: jp-  ·  Modificadores: jp-bloque--variante  ·  Partes: jp-bloque__parte
   Tema: data-theme="light|dark" en <html> o en cualquier contenedor.
   Sin JavaScript: dropdown usa <details>, modal usa <dialog>, tabs usan enlaces o botones con aria-selected.

   ÍNDICE
   01 Base            09 Tablas            17 Modal
   02 Layout          10 Badges            18 Toast
   03 Tipografía      11 Alertas           19 Progreso y spinner
   04 Links           12 Cards             20 Skeleton
   05 Botones         13 Navegación        21 Tooltip
   06 Formularios     14 Tabs y pills      22 List group
   07 Checks/radios   15 Breadcrumb        23 Empty state
   08 Input group     16 Paginación / Dropdown   24 Utilidades
   25 Panel            26 Datos (etiqueta-valor)   27 Canal             28 KPI y stats
   29 Zona de peligro  30 Gráficas (Chart.js, ver japifon-charts.js)
   31 Encabezado de página   32 Filtros   33 Acciones de agregado   34 Barra de acciones masivas   35 Acceso
*/

/* ============ 01 BASE ============ */
*, *::before, *::after { box-sizing: border-box; }
/* Sin esto, cualquier componente con display propio (flex, grid) ignora el atributo hidden */
[hidden] { display: none !important; }
/* La página va en surface-sunken: todo contenedor (tabla, panel, card) se eleva sobre ella */
body { margin: 0; font: 400 .875rem/1.25rem var(--font-sans); color: var(--text-primary); background: var(--surface-sunken);
  -webkit-font-smoothing: antialiased; }
:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
::selection { background: var(--primary-subtle); }
hr, .jp-divider { border: 0; border-top: 1px solid var(--border-divider); margin: var(--space-4) 0; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; animation: none !important; } }
/* Cortes de línea: títulos y textos cortos equilibrados; párrafos sin palabra huérfana al final */
h1, h2, h3, h4, .jp-display, .jp-h1, .jp-h2, .jp-h3, .jp-auth__title, .jp-auth__lead, .jp-auth__legal, .jp-empty__title, .jp-modal__title { text-wrap: balance; }
p, .jp-help, .jp-error, .jp-valid-msg, .jp-alert__body, .jp-toast__text { text-wrap: pretty; }

/* ============ 02 LAYOUT ============ */
.jp-container { width: 100%; max-width: 1200px; margin-inline: auto; padding-inline: var(--space-4); }
.jp-container--fluid { max-width: none; }
.jp-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--space-4); }
.jp-col-1{grid-column:span 1}.jp-col-2{grid-column:span 2}.jp-col-3{grid-column:span 3}.jp-col-4{grid-column:span 4}
.jp-col-5{grid-column:span 5}.jp-col-6{grid-column:span 6}.jp-col-7{grid-column:span 7}.jp-col-8{grid-column:span 8}
.jp-col-9{grid-column:span 9}.jp-col-10{grid-column:span 10}.jp-col-11{grid-column:span 11}.jp-col-12{grid-column:span 12}
/* Móvil primero: por debajo de 768px todas las columnas ocupan la fila completa */
@media (max-width: 767.98px) { .jp-grid > [class*="jp-col-"] { grid-column: span 12; } }
@media (min-width: 768px) {
  .jp-col-md-3{grid-column:span 3}.jp-col-md-4{grid-column:span 4}.jp-col-md-6{grid-column:span 6}
  .jp-col-md-8{grid-column:span 8}.jp-col-md-12{grid-column:span 12} }
@media (min-width: 1024px) {
  .jp-col-lg-3{grid-column:span 3}.jp-col-lg-4{grid-column:span 4}.jp-col-lg-6{grid-column:span 6}
  .jp-col-lg-8{grid-column:span 8}.jp-col-lg-9{grid-column:span 9} }
.jp-stack { display: flex; flex-direction: column; gap: var(--space-4); }
.jp-stack--sm { gap: var(--space-2); } .jp-stack--lg { gap: var(--space-6); }
.jp-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.jp-spread { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); }

/* ============ 03 TIPOGRAFÍA ============ */
.jp-display { font: 700 3rem/3.5rem var(--font-sans); letter-spacing: -.02em; }
.jp-h1 { font: 700 1.75rem/2.25rem var(--font-sans); letter-spacing: -.01em; }
.jp-h2 { font: 600 1.375rem/1.75rem var(--font-sans); }
.jp-h3 { font: 600 1.125rem/1.5rem var(--font-sans); }
.jp-body-lg { font: 400 1rem/1.5rem var(--font-sans); }
.jp-body { font: 400 .875rem/1.25rem var(--font-sans); }
.jp-caption { font: 400 .75rem/1rem var(--font-sans); color: var(--text-muted); }
.jp-overline { font: 600 .75rem/1rem var(--font-sans); letter-spacing: .04em; text-transform: uppercase; color: var(--text-secondary); }
.jp-mono, code, kbd { font-family: var(--font-mono); font-size: .8125rem; }
.jp-kbd, kbd { padding: 0 var(--space-1); border: 1px solid var(--border-component); border-bottom-width: 2px; border-radius: var(--radius-sm); }
.jp-num { font-variant-numeric: tabular-nums; }

/* ============ 04 LINKS (siempre subrayados, WCAG 1.4.1) ============ */
.jp-link { color: var(--link); text-decoration: var(--link-decoration); text-underline-offset: 2px; cursor: pointer; }
.jp-link:hover { color: var(--link-hover); }

/* ============ 05 BOTONES ============ */
.jp-btn {
  --_bg: transparent; --_fg: var(--text-primary); --_bd: transparent; --_ov: transparent;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: var(--control-h-md); padding: 0 var(--space-4); border-radius: var(--radius-md);
  border: 1.5px solid var(--_bd); background-color: var(--_bg); background-image: linear-gradient(var(--_ov), var(--_ov));
  color: var(--_fg); font: 600 .875rem/1 var(--font-sans); text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background-color var(--duration) var(--ease), border-color var(--duration) var(--ease); user-select: none;
}
.jp-btn--primary   { --_bg: var(--btn-primary-bg); --_fg: var(--btn-primary-fg); }
.jp-btn--primary:hover { --_ov: var(--state-darken-hover); } .jp-btn--primary:active { --_ov: var(--state-darken-pressed); }
.jp-btn--secondary { --_bg: var(--btn-secondary-bg); --_fg: var(--btn-secondary-fg); }
.jp-btn--secondary:hover { --_ov: var(--btn-secondary-overlay-hover); } .jp-btn--secondary:active { --_ov: var(--btn-secondary-overlay-pressed); }
.jp-btn--outline   { --_fg: var(--btn-outline-fg); --_bd: var(--btn-outline-border); }
.jp-btn--outline:hover, .jp-btn--ghost:hover { --_ov: var(--state-hover-surface); }
.jp-btn--ghost     { --_fg: var(--color-primary); }
.jp-btn--danger    { --_bg: var(--color-error-fill); --_fg: var(--color-on-error); }
.jp-btn--danger:hover { --_ov: var(--state-darken-hover); } .jp-btn--danger:active { --_ov: var(--state-darken-pressed); }
.jp-btn--link      { --_fg: var(--link); padding-inline: 0; text-decoration: underline; text-underline-offset: 2px; min-height: auto; }
.jp-btn--sm { min-height: var(--control-h-sm); padding: 0 var(--space-3); font-size: .75rem; }
.jp-btn--lg { min-height: var(--control-h-lg); padding: 0 var(--space-5); font-size: 1rem; }
.jp-btn--link.jp-btn--sm, .jp-btn--link.jp-btn--lg { padding-inline: 0; min-height: auto; }
.jp-btn--block { display: flex; width: 100%; }
.jp-btn--icon { padding: 0; width: var(--control-h-md); }
.jp-btn--icon.jp-btn--sm { width: var(--control-h-sm); }
.jp-btn:disabled, .jp-btn[aria-disabled="true"] {
  --_bg: var(--btn-disabled-bg); --_fg: var(--btn-disabled-fg); --_bd: var(--border-disabled); --_ov: transparent; cursor: not-allowed; }
.jp-btn--link:disabled { --_bg: transparent; --_bd: transparent; }
.jp-btn[aria-busy="true"] { cursor: progress; }
.jp-btn[aria-busy="true"]::before { content: ""; width: 1em; height: 1em; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent; animation: jp-spin .7s linear infinite; }
.jp-btn-group { display: inline-flex; }
.jp-btn-group > .jp-btn { border-radius: 0; }
.jp-btn-group > .jp-btn:first-child { border-radius: var(--radius-md) 0 0 var(--radius-md); }
.jp-btn-group > .jp-btn:last-child { border-radius: 0 var(--radius-md) var(--radius-md) 0; }
.jp-btn-group > .jp-btn + .jp-btn { margin-left: -1.5px; }
.jp-btn-group > .jp-btn[aria-pressed="true"] { --_bg: var(--primary-subtle); --_fg: var(--color-primary); --_bd: var(--color-primary); position: relative; z-index: 1; }

/* ============ 06 FORMULARIOS ============ */
.jp-form { display: flex; flex-direction: column; gap: var(--space-5); }
.jp-form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-4); }
.jp-fieldset { border: 1px solid var(--border-divider); border-radius: var(--radius-lg); padding: var(--space-4); margin: 0; }
.jp-fieldset > legend { padding: 0 var(--space-2); font: 600 .875rem/1.25rem var(--font-sans); }
.jp-field { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.jp-label { font: 600 .875rem/1.25rem var(--font-sans); color: var(--text-primary); }
.jp-label .jp-req { color: var(--color-error); margin-left: 2px; }
.jp-label .jp-opt { color: var(--text-muted); font-weight: 400; margin-left: var(--space-1); }
.jp-help { font: 400 .75rem/1rem var(--font-sans); color: var(--text-muted); }
.jp-error { font: 500 .75rem/1rem var(--font-sans); color: var(--color-error); }
.jp-valid-msg { font: 500 .75rem/1rem var(--font-sans); color: var(--color-success); }
.jp-counter { font: 400 .75rem/1rem var(--font-sans); color: var(--text-muted); text-align: right; font-variant-numeric: tabular-nums; }

.jp-input, .jp-select, .jp-textarea {
  width: 100%; min-height: var(--control-h-md); padding: var(--space-2) var(--space-3);
  border: 1px solid var(--input-border); border-radius: var(--radius-md);
  background: var(--surface-base); color: var(--text-primary);
  font: 400 .875rem/1.25rem var(--font-sans);
  transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
}
.jp-input::placeholder, .jp-textarea::placeholder { color: var(--input-placeholder); opacity: 1; }
.jp-input:hover, .jp-select:hover, .jp-textarea:hover { border-color: var(--text-secondary); }
.jp-input:focus-visible, .jp-select:focus-visible, .jp-textarea:focus-visible {
  outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 3px var(--primary-subtle), 0 0 0 1px var(--color-primary); }
.jp-textarea { min-height: 6rem; resize: vertical; }
.jp-select { appearance: none; padding-right: 2.25rem; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-secondary) 50%), linear-gradient(135deg, var(--text-secondary) 50%, transparent 50%);
  background-position: calc(100% - 16px) 55%, calc(100% - 11px) 55%; background-size: 5px 5px; background-repeat: no-repeat; }
.jp-input--sm, .jp-select.jp-input--sm { min-height: var(--control-h-sm); padding-block: var(--space-1); font-size: .75rem; }
.jp-input--lg, .jp-select.jp-input--lg { min-height: var(--control-h-lg); font-size: 1rem; }
.jp-input:disabled, .jp-select:disabled, .jp-textarea:disabled {
  background: var(--surface-disabled); color: var(--text-disabled); border-color: var(--border-disabled); cursor: not-allowed; }
.jp-input[readonly] { background: var(--surface-subtle); border-style: dashed; }
/* Validación: borde + mensaje de texto; nunca solo color */
.jp-field--error .jp-input, .jp-field--error .jp-select, .jp-field--error .jp-textarea,
.jp-input[aria-invalid="true"], .jp-select[aria-invalid="true"], .jp-textarea[aria-invalid="true"] {
  border-color: var(--input-border-error); box-shadow: inset 0 0 0 1px var(--input-border-error); }
.jp-field--error .jp-input:focus-visible, .jp-input[aria-invalid="true"]:focus-visible {
  box-shadow: inset 0 0 0 1px var(--color-error), 0 0 0 3px var(--error-subtle), 0 0 0 1px var(--color-error); }
.jp-field--valid .jp-input, .jp-field--valid .jp-select, .jp-field--valid .jp-textarea { border-color: var(--color-success); box-shadow: inset 0 0 0 1px var(--color-success); }
.jp-file { font: 400 .875rem/1.25rem var(--font-sans); color: var(--text-secondary); }
.jp-file::file-selector-button { margin-right: var(--space-3); min-height: var(--control-h-sm); padding: 0 var(--space-3);
  border: 1.5px solid var(--border-component); border-radius: var(--radius-md); background: transparent;
  color: var(--color-primary); font: 600 .75rem/1 var(--font-sans); cursor: pointer; }
.jp-range { width: 100%; accent-color: var(--color-control-checked); }

/* ============ 07 CHECKBOX · RADIO · SWITCH ============ */
.jp-check { display: inline-flex; align-items: flex-start; gap: var(--space-2); font: 400 .875rem/1.25rem var(--font-sans); cursor: pointer; }
.jp-check input { appearance: none; flex: none; margin: 2px 0 0; width: 1rem; height: 1rem;
  border: 1.5px solid var(--border-component); background: var(--surface-base); cursor: pointer; display: grid; place-content: center;
  transition: background-color var(--duration) var(--ease), border-color var(--duration) var(--ease); }
.jp-check input[type="checkbox"] { border-radius: var(--radius-sm); }
.jp-check input[type="radio"] { border-radius: 50%; }
.jp-check input:checked { background: var(--color-control-checked); border-color: var(--color-control-checked); }
.jp-check input[type="checkbox"]:checked::after { content: ""; width: .5rem; height: .28rem; margin-top: -2px;
  border: solid var(--color-on-control-checked); border-width: 0 0 2px 2px; transform: rotate(-45deg); }
.jp-check input[type="checkbox"]:indeterminate { background: var(--color-control-checked); border-color: var(--color-control-checked); }
.jp-check input[type="checkbox"]:indeterminate::after { content: ""; width: .5rem; height: 2px; background: var(--color-on-control-checked); }
.jp-check input[type="radio"]:checked::after { content: ""; width: .4rem; height: .4rem; border-radius: 50%; background: var(--color-on-control-checked); }
.jp-check input:disabled { background: var(--surface-disabled); border-color: var(--border-disabled); cursor: not-allowed; }
.jp-check:has(input:disabled) { color: var(--text-disabled); cursor: not-allowed; }
.jp-check input[aria-invalid="true"] { border-color: var(--input-border-error); box-shadow: inset 0 0 0 1px var(--input-border-error); }
.jp-check__hint { display: block; color: var(--text-muted); font-size: .75rem; line-height: 1rem; }
.jp-switch { display: inline-flex; align-items: center; gap: var(--space-2); font: 400 .875rem/1.25rem var(--font-sans); cursor: pointer; }
.jp-switch input { appearance: none; margin: 0; flex: none; position: relative; width: 2.25rem; height: 1.25rem; border-radius: var(--radius-pill);
  background: var(--surface-subtle); border: 1.5px solid var(--border-component); cursor: pointer;
  transition: background-color var(--duration) var(--ease), border-color var(--duration) var(--ease); }
.jp-switch input::after { content: ""; position: absolute; top: 1.5px; left: 2px; width: .875rem; height: .875rem; border-radius: 50%;
  background: var(--text-secondary); transition: transform var(--duration) var(--ease), background-color var(--duration) var(--ease); }
.jp-switch input:checked { background: var(--color-control-checked); border-color: var(--color-control-checked); }
.jp-switch input:checked::after { transform: translateX(1rem); background: var(--color-on-control-checked); }
.jp-switch input:disabled { background: var(--surface-disabled); border-color: var(--border-disabled); cursor: not-allowed; }
.jp-switch input:disabled::after { background: var(--text-disabled); }
.jp-switch:has(input:disabled) { color: var(--text-disabled); cursor: not-allowed; }
.jp-choice-group { display: flex; flex-direction: column; gap: var(--space-2); }
.jp-choice-group--inline { flex-direction: row; flex-wrap: wrap; gap: var(--space-4); }

/* ============ 08 INPUT GROUP ============ */
.jp-input-group { display: flex; align-items: stretch; width: 100%; }
.jp-input-group > .jp-input, .jp-input-group > .jp-select { flex: 1; min-width: 0; border-radius: 0; }
.jp-input-group > :first-child { border-top-left-radius: var(--radius-md); border-bottom-left-radius: var(--radius-md); }
.jp-input-group > :last-child { border-top-right-radius: var(--radius-md); border-bottom-right-radius: var(--radius-md); }
.jp-input-group > * + * { margin-left: -1px; }
.jp-input-group > .jp-btn { border-radius: 0; }
.jp-input-group > .jp-btn:last-child { border-radius: 0 var(--radius-md) var(--radius-md) 0; }
.jp-input-group > :focus-visible { position: relative; z-index: 1; }
.jp-addon { display: inline-flex; align-items: center; padding: 0 var(--space-3); border: 1px solid var(--input-border);
  background: var(--surface-subtle); color: var(--text-secondary); font: 500 .875rem/1 var(--font-sans); white-space: nowrap; }
.jp-search { position: relative; }
.jp-search > .jp-input { padding-left: 2.25rem; padding-right: 2.25rem; }
.jp-search > .jp-input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
/* Botón limpiar propio (el nativo cambia por navegador). Se oculta solo cuando el campo está vacío: requiere placeholder. */
.jp-search__clear { position: absolute; top: 50%; right: .25rem; transform: translateY(-50%); width: 1.75rem; height: 1.75rem; padding: 0; border: 0;
  border-radius: 50%; background: none; color: var(--text-secondary); font-size: 0; cursor: pointer; }
.jp-search__clear::before, .jp-search__clear::after { content: ""; position: absolute; top: 50%; left: 50%; width: .625rem; height: 1.5px;
  border-radius: 1px; background: currentColor; transform: translate(-50%, -50%) rotate(45deg); }
.jp-search__clear::after { transform: translate(-50%, -50%) rotate(-45deg); }
.jp-search__clear:hover { background: var(--state-hover-surface); color: var(--text-primary); }
.jp-search:has(> .jp-input:placeholder-shown) > .jp-search__clear { display: none; }
.jp-search__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.jp-search::before { content: ""; position: absolute; left: .85rem; top: 50%; width: .6rem; height: .6rem; margin-top: -.4rem;
  border: 2px solid var(--text-muted); border-radius: 50%; pointer-events: none; }
.jp-search::after { content: ""; position: absolute; left: 1.45rem; top: 50%; width: 2px; height: .35rem; margin-top: .1rem;
  background: var(--text-muted); transform: rotate(-45deg); pointer-events: none; }

/* ============ 09 TABLAS ============ */
.jp-table-wrap { position: relative; width: 100%; overflow-x: auto; border-radius: var(--radius-lg); background: var(--container-bg); border: 1px solid var(--container-border); box-shadow: var(--container-shadow); }
/* Escritorio: sin recorte, para que los menús de fila (⋯) no queden cortados. Tablas muy anchas: .jp-table-wrap--scroll */
@media (min-width: 768px) { .jp-table-wrap:not(.jp-table-wrap--scroll) { overflow: visible; } }
/* La franja del encabezado solo redondea sus esquinas cuando la tabla es lo primero del contenedor.
   Si arriba hay barra de filtros, conteo, título o la tabla vive en un panel, el encabezado queda recto. */
.jp-table-wrap:not(.jp-panel .jp-table-wrap) > .jp-table:first-child thead tr:first-child th:first-child { border-top-left-radius: calc(var(--radius-lg) - 1px); }
.jp-table-wrap:not(.jp-panel .jp-table-wrap) > .jp-table:first-child thead tr:first-child th:last-child { border-top-right-radius: calc(var(--radius-lg) - 1px); }
.jp-table { width: 100%; border-collapse: collapse; font: 400 .875rem/1.25rem var(--font-sans); color: var(--text-primary); }
.jp-table caption { caption-side: top; text-align: left; padding: var(--space-3) var(--space-4); font-weight: 600; }
/* Tabla tipo tarjeta: la tabla es un contenedor elevado. El encabezado lleva una franja tenue sobre el contenedor
   (--table-head-bg, relativa: funciona igual en panel, card o página) y texto en text-primary para que mande. */
.jp-table thead th { height: 3rem; text-align: left; vertical-align: middle; padding: var(--space-3) var(--space-5); border-bottom: 1px solid var(--border-divider);
  font: 600 .75rem/1rem var(--font-sans); letter-spacing: .06em; text-transform: uppercase; color: var(--text-primary); white-space: nowrap;
  background: var(--table-head-bg); }
.jp-table tbody th { text-align: left; font-weight: 600; }
.jp-table td { height: 4.25rem; padding: var(--space-3) var(--space-5); border-bottom: 1px solid var(--border-divider); vertical-align: middle; }
/* Columnas de apoyo (razón social, IDs, fechas): texto secundario para que el nombre mande */
.jp-table .jp-cell--muted { color: var(--text-secondary); }
.jp-table tbody tr:last-child td { border-bottom: 0; }
.jp-table .jp-num, .jp-table th.jp-num { text-align: right; font-variant-numeric: tabular-nums; }
.jp-table .jp-actions { text-align: right; white-space: nowrap; }
.jp-table--striped tbody tr:nth-child(even) { background: var(--state-hover-surface); }
.jp-table--hover tbody tr:hover { background: var(--state-hover-surface); }
.jp-table--bordered td, .jp-table--bordered th { border: 1px solid var(--border-divider); }
.jp-table--compact thead th { height: 2.25rem; padding: var(--space-1) var(--space-3); }
.jp-table--compact td { height: auto; padding: var(--space-2) var(--space-3); }
.jp-table--sticky thead th { position: sticky; top: 0; z-index: var(--z-sticky); box-shadow: 0 1px 0 var(--border-divider); }
.jp-table tbody tr[aria-selected="true"] { background: var(--primary-subtle); box-shadow: inset 3px 0 0 var(--color-primary); }
.jp-table th[aria-sort] { cursor: pointer; }
.jp-table th[aria-sort]::after { content: "↕"; margin-left: var(--space-1); color: var(--text-muted); }
.jp-table th[aria-sort="ascending"]::after { content: "↑"; color: var(--color-primary); }
.jp-table th[aria-sort="descending"]::after { content: "↓"; color: var(--color-primary); }
.jp-table td.jp-check-cell, .jp-table th.jp-check-cell { width: 1%; padding-right: 0; }
.jp-table__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-4) var(--space-5); border-top: 1px solid var(--border-divider); color: var(--text-muted); font-size: .8125rem; }
/* Encabezado propio de la tabla (título + acción) cuando la página tiene más de una tabla o la tabla vive dentro de otra vista.
   Si la tabla es el contenido único de la página, el título ya lo da jp-page-header: no repetirlo. */
.jp-table__header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border-divider); }
.jp-table__title { margin: 0; font: 600 1rem/1.5rem var(--font-sans); }

/* ============ 10 BADGES (con ícono o texto, WCAG 1.4.1) ============ */
.jp-badge { display: inline-flex; align-items: center; gap: var(--space-1); padding: .125rem var(--space-2); border-radius: var(--radius-pill);
  font: 600 .75rem/1rem var(--font-sans); white-space: nowrap; border: 1px solid transparent; }
.jp-badge--draft     { background: var(--badge-draft-bg);     color: var(--badge-draft-fg); }
.jp-badge--scheduled { background: var(--badge-scheduled-bg); color: var(--badge-scheduled-fg); }
.jp-badge--sent      { background: var(--badge-sent-bg);      color: var(--badge-sent-fg); }
.jp-badge--failed    { background: var(--badge-failed-bg);    color: var(--badge-failed-fg); }
.jp-badge--new       { background: var(--badge-new-bg);       color: var(--badge-new-fg); }
.jp-badge--warning   { background: var(--color-warning-fill); color: var(--color-on-warning); }
.jp-badge--outline   { background: transparent; color: var(--text-secondary); border-color: var(--border-component); }
/* Variante suave (tinte + borde + texto del rol): para estados en tablas densas, donde el sólido pesa demasiado.
   Solo sobre surface-base; el texto conserva ≥4.5:1 sobre el tinte. */
.jp-badge--soft { background: var(--_soft-bg); color: color-mix(in srgb, var(--_soft-fg) 72%, var(--text-primary)); border-color: color-mix(in srgb, var(--_soft-fg) 45%, transparent); }
.jp-badge--soft.jp-badge--sent      { --_soft-bg: var(--success-subtle); --_soft-fg: var(--color-success); }
.jp-badge--soft.jp-badge--failed    { --_soft-bg: var(--error-subtle);   --_soft-fg: var(--color-error); }
.jp-badge--soft.jp-badge--warning   { --_soft-bg: var(--warning-subtle); --_soft-fg: var(--color-warning); }
.jp-badge--soft.jp-badge--scheduled { --_soft-bg: var(--primary-subtle); --_soft-fg: var(--color-primary); }
.jp-badge--soft.jp-badge--new       { --_soft-bg: var(--accent-subtle);  --_soft-fg: var(--color-accent); }
.jp-badge--soft.jp-badge--draft     { --_soft-bg: var(--surface-subtle); --_soft-fg: var(--text-secondary); }
.jp-badge--count     { min-width: 1.25rem; justify-content: center; padding: 0 var(--space-1); background: var(--color-control-checked); color: var(--color-on-control-checked); }
.jp-dot { display: inline-block; width: .5rem; height: .5rem; border-radius: 50%; background: currentColor; }

/* ============ 11 ALERTAS (van sobre surface.base, no dentro de cards) ============ */
.jp-alert { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md); border-left: 4px solid; color: var(--text-primary); font: 400 .875rem/1.25rem var(--font-sans); }
.jp-alert__icon { flex: none; font-weight: 700; line-height: 1.25rem; }
.jp-alert__body { flex: 1; min-width: 0; }
.jp-alert__title { font-weight: 600; }
.jp-alert__close { position: relative; margin: -2px -4px 0 auto; flex: none; width: 1.5rem; height: 1.5rem; padding: 0; background: none; border: 0;
  color: var(--text-secondary); font-size: 0; cursor: pointer; border-radius: var(--radius-sm); }
.jp-alert__close:hover { background: var(--state-hover-surface); color: var(--text-primary); }
.jp-alert--info    { background: var(--primary-subtle); border-color: var(--color-info); }
.jp-alert--info    :is(.jp-alert__title, .jp-alert__icon) { color: var(--color-info); }
.jp-alert--success { background: var(--success-subtle); border-color: var(--color-success); }
.jp-alert--success :is(.jp-alert__title, .jp-alert__icon) { color: var(--color-success); }
.jp-alert--warning { background: var(--warning-subtle); border-color: var(--color-warning); }
.jp-alert--warning :is(.jp-alert__title, .jp-alert__icon) { color: var(--color-warning); }
.jp-alert--error   { background: var(--error-subtle);   border-color: var(--color-error); }
.jp-alert--error   :is(.jp-alert__title, .jp-alert__icon) { color: var(--color-error); }
/* Dentro de superficies elevadas el tinte baja el contraste del color de rol (Dark): título e ícono pasan a text-primary; el estado lo siguen dando barra, ícono y palabra */
:is(.jp-card, .jp-modal, .jp-menu, .jp-list) .jp-alert :is(.jp-alert__title, .jp-alert__icon) { color: var(--text-primary); }

/* ============ 12 CARDS ============ */
.jp-card { background: var(--card-bg); border: 1px solid var(--card-border); border-radius: var(--radius-lg); padding: var(--space-4); box-shadow: var(--container-shadow); }
.jp-card:has(> .jp-card__header, > .jp-card__body) { padding: 0; }
.jp-card__header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border-divider); }
.jp-card__title { margin: 0; font: 600 1rem/1.5rem var(--font-sans); }
.jp-card__body { padding: var(--space-4); }
.jp-card__footer { display: flex; justify-content: flex-end; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-top: 1px solid var(--border-divider); }
.jp-card--interactive { cursor: pointer; transition: box-shadow var(--duration) var(--ease), border-color var(--duration) var(--ease); }
.jp-card--interactive:hover { border-color: var(--border-component); box-shadow: var(--shadow-sm); }
.jp-card--selected { border-color: var(--color-primary); box-shadow: inset 0 0 0 1px var(--color-primary); }

/* ============ 13 NAVEGACIÓN LATERAL ============ */
.jp-nav { display: flex; flex-direction: column; gap: 2px; }
.jp-nav__item { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3);
  border-left: 3px solid transparent; border-radius: 0 var(--radius-md) var(--radius-md) 0;
  color: var(--text-secondary); text-decoration: none; font: 500 .875rem/1.25rem var(--font-sans); }
.jp-nav__item:hover { background: var(--state-hover-surface); color: var(--text-primary); }
.jp-nav__item[aria-current="page"] { background: var(--sidebar-active-bg); border-left-color: var(--sidebar-active-indicator); color: var(--color-primary); font-weight: 600; }
.jp-nav__item .jp-badge { margin-left: auto; }
.jp-nav__section { padding: var(--space-3) var(--space-3) var(--space-1); }

/* ============ 14 TABS Y PILLS ============ */
.jp-tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--border-divider); overflow-x: auto; }
.jp-tab { padding: var(--space-2) var(--space-3); margin-bottom: -1px; border: 0; border-bottom: 2px solid transparent; background: none;
  color: var(--text-secondary); font: 500 .875rem/1.25rem var(--font-sans); text-decoration: none; white-space: nowrap; cursor: pointer; }
.jp-tab:hover { color: var(--text-primary); }
.jp-tab[aria-selected="true"], .jp-tab[aria-current="page"] { color: var(--color-primary); border-bottom-color: var(--color-primary); font-weight: 600; }
.jp-pills { display: inline-flex; gap: var(--space-1); padding: var(--space-1); border-radius: var(--radius-md); background: var(--surface-subtle); }
.jp-pill { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1); min-height: 1.75rem; padding: var(--space-1) var(--space-3); border: 0; border-radius: var(--radius-sm); background: none; color: var(--text-secondary);
  font: 500 .8125rem/1.25rem var(--font-sans); cursor: pointer; }
/* Activo: fondo base + borde de componente (≥3:1). En Dark raised = subtle, así que la sombra sola no distinguía el activo */
.jp-pill[aria-pressed="true"], .jp-pill[aria-selected="true"] { background: var(--surface-base); color: var(--text-primary); font-weight: 600; box-shadow: inset 0 0 0 1px var(--border-component); }

/* Pestañas de página: navegación interna de una entidad (cuenta, centro de costo, agente). Son enlaces con aria-current,
   cada una es una ruta. Hasta 7; si hay más secciones usar .jp-settings (navegación vertical). */
.jp-tabs--page { gap: var(--space-5); padding-inline: var(--space-1); scrollbar-width: none; }
.jp-tabs--page::-webkit-scrollbar { display: none; }
@media (max-width: 767.98px) { .jp-tabs--page { -webkit-mask-image: linear-gradient(90deg, #000 85%, transparent); mask-image: linear-gradient(90deg, #000 85%, transparent); } } /* tokens-allow: en una máscara solo cuenta el canal alfa; el negro es la convención y no pinta nada */
.jp-tabs--page .jp-tab { display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-3) 0; }
.jp-tabs--sticky { position: sticky; top: 0; z-index: var(--z-sticky); background: var(--surface-base); }
.jp-tab__count { display: inline-grid; place-items: center; min-width: 1.25rem; height: 1.25rem; padding: 0 .375rem; border-radius: var(--radius-pill);
  background: var(--surface-subtle); color: var(--text-secondary); font: 600 .75rem/1 var(--font-sans); font-variant-numeric: tabular-nums; }
.jp-tab[aria-current="page"] .jp-tab__count, .jp-tab[aria-selected="true"] .jp-tab__count { background: var(--primary-subtle); color: var(--color-primary); }
.jp-tab__alert { width: .5rem; height: .5rem; border-radius: 50%; background: var(--color-error); }

/* Encabezado de entidad: migas + identidad + metadatos + acciones, seguido de .jp-tabs--page */
.jp-entity { display: flex; flex-direction: column; gap: var(--space-3); }
.jp-entity__main { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3) var(--space-4); }
.jp-entity__id { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.jp-entity__name { margin: 0; font: 700 1.75rem/2.25rem var(--font-sans); letter-spacing: -.01em; }
.jp-entity__meta { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); margin: var(--space-1) 0 0; padding: 0; list-style: none;
  font: 400 .8125rem/1.25rem var(--font-sans); color: var(--text-secondary); }
.jp-entity__meta b { font-weight: 500; color: var(--text-primary); }

/* Configuración con muchas secciones: navegación vertical + contenido. En móvil la navegación pasa a fila deslizable. */
.jp-settings { display: grid; grid-template-columns: 13rem minmax(0, 1fr); gap: var(--space-6); align-items: start; }
.jp-settings > .jp-nav { position: sticky; top: var(--space-4); }
@media (max-width: 767.98px) {
  .jp-settings { grid-template-columns: 1fr; gap: var(--space-4); }
  .jp-settings > .jp-nav { position: static; flex-direction: row; overflow-x: auto; border-bottom: 1px solid var(--border-divider); scrollbar-width: none; }
  .jp-settings > .jp-nav .jp-nav__item { flex: none; border-left: 0; border-bottom: 2px solid transparent; border-radius: 0; white-space: nowrap; }
  .jp-settings > .jp-nav .jp-nav__item[aria-current="page"] { border-bottom-color: var(--sidebar-active-indicator); background: none; }
  .jp-settings > .jp-nav .jp-nav__section { display: none; }
}

/* ============ 15 BREADCRUMB ============ */
.jp-breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); list-style: none; margin: 0; padding: 0;
  font: 400 .8125rem/1.25rem var(--font-sans); color: var(--text-muted); }
.jp-breadcrumb li + li::before { content: "/"; margin-right: var(--space-2); color: var(--text-muted); }
.jp-breadcrumb a { color: var(--link); text-underline-offset: 2px; }
.jp-breadcrumb [aria-current="page"] { color: var(--text-primary); font-weight: 500; }

/* ============ 16 PAGINACIÓN Y DROPDOWN ============ */
.jp-pagination { display: flex; flex-wrap: wrap; gap: var(--space-1); list-style: none; margin: 0; padding: 0; }
.jp-page { display: inline-grid; place-items: center; min-width: var(--control-h-sm); height: var(--control-h-sm); padding: 0 var(--space-2);
  border: 1px solid var(--border-divider); border-radius: var(--radius-md); color: var(--text-secondary); background: var(--surface-base);
  font: 500 .8125rem/1 var(--font-sans); text-decoration: none; font-variant-numeric: tabular-nums; cursor: pointer; }
.jp-page:hover { background: var(--state-hover-surface); color: var(--text-primary); }
.jp-page[aria-current="page"] { background: var(--color-control-checked); border-color: var(--color-control-checked); color: var(--color-on-control-checked); }
.jp-page[aria-disabled="true"] { color: var(--text-disabled); pointer-events: none; }
/* Dropdown con <details>: <details class="jp-dropdown"><summary class="jp-btn jp-btn--outline">…</summary><div class="jp-menu">…</div></details> */
.jp-dropdown { position: relative; display: inline-block; }
.jp-dropdown > summary { list-style: none; }
.jp-dropdown > summary::-webkit-details-marker { display: none; }
.jp-dropdown > summary.jp-btn--icon::after { content: none; }
.jp-dropdown > summary::after { content: ""; width: .4rem; height: .4rem; margin-left: var(--space-1); border: solid currentColor;
  border-width: 0 1.5px 1.5px 0; transform: rotate(45deg) translateY(-2px); }
.jp-menu { position: absolute; z-index: var(--z-dropdown); top: calc(100% + var(--space-1)); left: 0; min-width: 12rem; padding: var(--space-1);
  background: var(--surface-raised); border: 1px solid var(--border-divider); border-radius: var(--radius-md); box-shadow: var(--shadow-md); }
.jp-menu--end { left: auto; right: 0; }
.jp-menu__item { display: flex; align-items: center; gap: var(--space-2); width: 100%; padding: var(--space-2) var(--space-3); border: 0;
  border-radius: var(--radius-sm); background: none; color: var(--text-primary); font: 400 .875rem/1.25rem var(--font-sans);
  text-align: left; text-decoration: none; cursor: pointer; }
.jp-menu__item:hover, .jp-menu__item:focus-visible { background: var(--state-hover-surface); outline-offset: -2px; }
.jp-menu__item--danger { color: var(--color-error); }
.jp-menu__sep { height: 1px; margin: var(--space-1) 0; background: var(--border-divider); }

/* ============ 17 MODAL (<dialog class="jp-modal">, abrir con dialog.showModal()) ============ */
.jp-modal { width: min(560px, calc(100vw - 2rem)); max-height: calc(100vh - 4rem); padding: 0; border: 1px solid var(--border-divider);
  border-radius: var(--radius-lg); background: var(--surface-raised); color: var(--text-primary); box-shadow: var(--shadow-lg); }
.jp-modal::backdrop { background: var(--backdrop); }
.jp-modal--sm { width: min(400px, calc(100vw - 2rem)); } .jp-modal--lg { width: min(800px, calc(100vw - 2rem)); }
.jp-modal__header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-4) var(--space-5) var(--space-2); }
.jp-modal__title { margin: 0; font: 600 1.125rem/1.5rem var(--font-sans); }
.jp-modal__body { padding: var(--space-2) var(--space-5) var(--space-4); color: var(--text-secondary); overflow: auto; }
.jp-modal__footer { display: flex; justify-content: flex-end; gap: var(--space-2); padding: var(--space-3) var(--space-5) var(--space-5); }
.jp-close { position: relative; flex: none; display: inline-block; width: var(--control-h-sm); height: var(--control-h-sm); padding: 0; border: 0;
  border-radius: var(--radius-md); background: none; color: var(--text-secondary); font-size: 0; cursor: pointer; }
/* La X se dibuja con dos trazos centrados: el glifo × de la fuente queda descentrado. El texto del botón se oculta (font-size 0) y el nombre va en aria-label. */
:is(.jp-close, .jp-alert__close, .jp-chip__remove)::before, :is(.jp-close, .jp-alert__close, .jp-chip__remove)::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: .875rem; height: 1.5px; border-radius: 1px; background: currentColor;
  transform: translate(-50%, -50%) rotate(45deg); }
:is(.jp-close, .jp-alert__close, .jp-chip__remove)::after { transform: translate(-50%, -50%) rotate(-45deg); }
.jp-alert__close::before, .jp-alert__close::after { width: .75rem; }
.jp-chip__remove::before, .jp-chip__remove::after { width: .5625rem; }
.jp-close:hover { background: var(--state-hover-surface); color: var(--text-primary); }

/* ============ 18 TOAST ============ */
.jp-toast-region { position: fixed; z-index: var(--z-toast); right: var(--space-4); bottom: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.jp-toast { --_accent: var(--color-primary); display: flex; align-items: flex-start; gap: var(--space-3); width: min(380px, calc(100vw - 2rem));
  padding: var(--space-3) var(--space-2) var(--space-3) var(--space-4); border: 1px solid var(--border-divider); border-left: 4px solid var(--_accent);
  border-radius: var(--radius-md); background: var(--surface-raised); color: var(--text-primary); box-shadow: var(--shadow-lg);
  font: 400 .875rem/1.25rem var(--font-sans); }
.jp-toast--success { --_accent: var(--color-success); } .jp-toast--warning { --_accent: var(--color-warning); } .jp-toast--error { --_accent: var(--color-error); }
.jp-toast__icon { flex: none; width: 1.25rem; height: 1.25rem; color: var(--_accent); }
.jp-toast__body { flex: 1; min-width: 0; }
.jp-toast__title { font-weight: 600; }
.jp-toast__text { color: var(--text-secondary); }
.jp-toast__action { margin-top: var(--space-2); }
.jp-toast .jp-close { width: 1.75rem; height: 1.75rem; margin-top: -.25rem; }

/* ============ 19 PROGRESO Y SPINNER (la barra usa el color de texto del rol: ≥3:1 contra el riel) ============ */
.jp-progress { width: 100%; height: .5rem; border-radius: var(--radius-pill); background: var(--surface-subtle); overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--border-divider); }
.jp-progress__bar { height: 100%; border-radius: inherit; background: var(--color-primary); transition: width var(--duration) var(--ease); }
.jp-progress__bar--success { background: var(--color-success); } .jp-progress__bar--warning { background: var(--color-warning); }
.jp-progress__bar--error { background: var(--color-error); }
.jp-spinner { display: inline-block; width: 1.25rem; height: 1.25rem; border-radius: 50%; border: 2px solid var(--border-divider);
  border-top-color: var(--color-primary); animation: jp-spin .7s linear infinite; }
.jp-spinner--lg { width: 2rem; height: 2rem; border-width: 3px; }
@keyframes jp-spin { to { transform: rotate(360deg); } }

/* ============ 20 SKELETON ============ */
.jp-skeleton { display: block; height: 1rem; border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--surface-subtle) 25%, var(--state-hover-surface) 50%, var(--surface-subtle) 75%);
  background-size: 200% 100%; animation: jp-shimmer 1.4s ease-in-out infinite; }
@keyframes jp-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* ============ 21 TOOLTIP (solo para información adicional, no esencial) ============ */
.jp-tooltip { position: relative; display: inline-flex; vertical-align: middle; }
.jp-tooltip__content { position: absolute; z-index: var(--z-tooltip); bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%);
  width: max-content; max-width: 16rem; padding: var(--space-2) var(--space-3); border-radius: var(--radius-md);
  background: var(--surface-inverse); color: var(--surface-base); box-shadow: var(--shadow-md);
  font: 500 .75rem/1rem var(--font-sans); text-align: left; text-transform: none; letter-spacing: 0; white-space: normal;
  pointer-events: none; opacity: 0; transition: opacity var(--duration) var(--ease); }
/* Flecha que apunta al disparador: es lo que lo distingue de un toast o una etiqueta */
.jp-tooltip__content::after { content: ""; position: absolute; top: 100%; left: 50%; margin-left: -6px;
  border: 6px solid transparent; border-top-color: var(--surface-inverse); }
.jp-tooltip--bottom .jp-tooltip__content { bottom: auto; top: calc(100% + 8px); }
.jp-tooltip--bottom .jp-tooltip__content::after { top: auto; bottom: 100%; border-top-color: transparent; border-bottom-color: var(--surface-inverse); }
/* Disparador de ayuda: ícono (i) en círculo, nunca un «?» suelto */
.jp-info { display: inline-grid; place-items: center; width: 1.5rem; height: 1.5rem; padding: 0; border: 0; border-radius: 50%;
  background: none; color: var(--text-muted); cursor: help; }
.jp-info svg { width: 1rem; height: 1rem; }
.jp-info:hover { color: var(--text-primary); }
.jp-tooltip:hover .jp-tooltip__content, .jp-tooltip:focus-within .jp-tooltip__content { opacity: 1; }

/* ============ 22 LIST GROUP ============ */
.jp-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--border-divider); border-radius: var(--radius-lg); background: var(--surface-raised); overflow: hidden; }
.jp-list__item { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border-divider); }
.jp-list__item:last-child { border-bottom: 0; }
.jp-list__item--action { cursor: pointer; } .jp-list__item--action:hover { background: var(--state-hover-surface); }
.jp-list--flush { border: 0; border-radius: 0; background: none; }
.jp-list--flush > .jp-list__item { padding-inline: var(--space-5); }
.jp-list__info { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.jp-list__title { font: 500 .875rem/1.25rem var(--font-sans); }
.jp-list__sub { font: 400 .75rem/1rem var(--font-sans); color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jp-list__actions { flex: none; display: flex; justify-content: flex-end; gap: var(--space-1); min-width: 6rem; } /* ranura fija: las columnas no bailan entre filas */
.jp-list__meta { margin-left: auto; color: var(--text-muted); font-size: .75rem; font-variant-numeric: tabular-nums; }

/* ============ 23 EMPTY STATE ============ */
.jp-empty { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); padding: var(--space-7) var(--space-4); text-align: center; color: var(--text-secondary); }
.jp-empty__title { margin: 0; color: var(--text-primary); font: 600 1rem/1.5rem var(--font-sans); }

/* ============ 25 PANEL (contenedor de listados: header + filtros + cuerpo) ============ */
.jp-panel { border-radius: var(--radius-lg); background: var(--container-bg); border: 1px solid var(--container-border); box-shadow: var(--container-shadow); }
/* Una tabla dentro de un panel no repite tarjeta */
.jp-panel .jp-table-wrap { box-shadow: none; }
.jp-panel > :first-child { border-top-left-radius: inherit; border-top-right-radius: inherit; }
.jp-panel > :last-child { border-bottom-left-radius: inherit; border-bottom-right-radius: inherit; }
.jp-panel__header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border-divider); }
.jp-panel__title { margin: 0; font: 600 1rem/1.5rem var(--font-sans); }
.jp-panel__subtitle { margin: 0; font: 400 .8125rem/1.25rem var(--font-sans); color: var(--text-secondary); }
.jp-panel__filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-3); padding: var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--border-divider); background: transparent; }
.jp-panel__filters > .jp-field { flex: 1 1 180px; }
.jp-panel__body { padding: var(--space-4) var(--space-5); }
.jp-panel__body--flush { padding: 0; }
.jp-panel__body--flush > .jp-table-wrap { border: 0; border-radius: 0; }
.jp-panel__footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-3) var(--space-5); border-top: 1px solid var(--border-divider); color: var(--text-muted); font-size: .75rem; }
.jp-avatar { flex: none; display: inline-grid; place-items: center; width: 2rem; height: 2rem; border-radius: 50%;
  background: var(--primary-subtle); color: var(--color-primary); font: 600 .75rem/1 var(--font-sans); text-transform: uppercase; }
.jp-avatar--muted { background: var(--surface-subtle); color: var(--text-secondary); }
.jp-avatar--lg { width: 3rem; height: 3rem; font-size: 1rem; }

/* ============ 26 DATOS (rejilla etiqueta-valor). La ficha de una entidad es jp-entity + jp-tabs--page; esto es su contenido ============ */
.jp-details { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); margin: 0 -1px -1px 0; }
.jp-details__field { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-4) var(--space-5); min-width: 0;
  border-right: 1px solid var(--border-divider); border-bottom: 1px solid var(--border-divider); }
.jp-details__label { font: 600 .75rem/1rem var(--font-sans); letter-spacing: .04em; text-transform: uppercase; color: var(--text-secondary); }
.jp-details__value { margin: 0; font: 400 .875rem/1.25rem var(--font-sans); overflow-wrap: anywhere; }
.jp-panel > .jp-details { overflow: hidden; }

.jp-panel .jp-table :is(th, td):first-child { padding-left: var(--space-5); }
.jp-panel .jp-table :is(th, td):last-child { padding-right: var(--space-5); }
.jp-panel .jp-table tr.jp-table__group th { padding: var(--space-4) var(--space-4) var(--space-2); background: transparent; border-bottom: 1px solid var(--border-divider);
  font: 600 .75rem/1rem var(--font-sans); letter-spacing: .04em; text-transform: uppercase; color: var(--text-primary); }

/* ============ 27 TABLA DE ACTIVACIÓN (canales y servicios; sustituye a las tarjetas de canal) ============ */
/* Una fila por servicio, agrupadas por familia. Estado siempre con punto + palabra. El switch solo cuando activar es
   inmediato y reversible; si requiere configuración, botón «Activar» que abre el flujo. */
.jp-table tr.jp-table__group th { padding: var(--space-2) var(--space-4); background: transparent; border-bottom: 1px solid var(--border-divider);
  font: 600 .75rem/1rem var(--font-sans); letter-spacing: .04em; text-transform: uppercase; color: var(--text-secondary); }
.jp-service { display: flex; align-items: center; gap: var(--space-3); min-width: 12rem; }
.jp-service__icon { flex: none; display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border-radius: var(--radius-md);
  background: var(--surface-subtle); color: var(--text-secondary); font: 700 .75rem/1 var(--font-sans); }
.jp-service__name { display: block; font: 600 .875rem/1.25rem var(--font-sans); }
.jp-service__desc { display: block; font: 400 .75rem/1rem var(--font-sans); color: var(--text-muted); }
tr:has(.jp-status--on) .jp-service__icon { background: var(--primary-subtle); color: var(--color-primary); }
.jp-status { display: inline-flex; align-items: center; gap: var(--space-2); font: 500 .8125rem/1.25rem var(--font-sans); color: var(--text-secondary); white-space: nowrap; }
.jp-status::before { content: ""; flex: none; width: .5rem; height: .5rem; border-radius: 50%; background: currentColor; }
.jp-status--on { color: var(--color-success); }
.jp-status--off { color: var(--text-secondary); }
.jp-status--error { color: var(--color-error); }
.jp-status--pending { color: var(--color-warning); }
.jp-status--locked::before { width: .5rem; height: .5rem; border-radius: 1px; background: none; box-shadow: inset 0 0 0 1.5px currentColor; }
/* Bloqueado por plan: texto en muted (no disabled): la fila sigue siendo informativa y el CTA de plan es accionable */
tr.is-locked .jp-service__name, tr.is-locked .jp-service__icon { color: var(--text-muted); }
.jp-table .jp-switch { vertical-align: middle; }

/* Tabla apilada en móvil: cada fila se vuelve bloque con etiqueta (data-label en cada td) */
@media (max-width: 767.98px) {
  .jp-table--stack thead { display: none; }
  .jp-table--stack, .jp-table--stack tbody, .jp-table--stack tr, .jp-table--stack td, .jp-table--stack th { display: block; width: 100%; }
  .jp-table--stack tbody tr { padding: var(--space-3) var(--space-5); border-bottom: 1px solid var(--border-divider); }
  .jp-table--stack tbody tr.jp-table__group { padding: 0; }
  .jp-table--stack td { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-1) 0; border: 0; text-align: right; }
  .jp-table--stack td[data-label]::before { content: attr(data-label); flex: none; font: 600 .75rem/1rem var(--font-sans); letter-spacing: .04em;
    text-transform: uppercase; color: var(--text-secondary); text-align: left; }
  .jp-table--stack td:first-child { justify-content: flex-start; text-align: left; padding-bottom: var(--space-2); }
  .jp-table--stack td.jp-actions { justify-content: flex-end; }
  .jp-panel .jp-table--stack tbody :is(th, td), .jp-panel .jp-table--stack tbody :is(th, td):is(:first-child, :last-child) { padding-left: 0; padding-right: 0; }
}

/* ============ 28 KPI Y STATS ============ */
.jp-kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-4); }
.jp-kpi { position: relative; display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-4) var(--space-5);
  background: var(--container-bg); box-shadow: var(--container-shadow); border: 1px solid var(--container-border); border-radius: var(--radius-lg); min-width: 0; }
.jp-kpi__label { font: 600 .75rem/1rem var(--font-sans); letter-spacing: .04em; text-transform: uppercase; color: var(--text-secondary); }
.jp-kpi__value { font: 700 1.75rem/2.25rem var(--font-sans); font-variant-numeric: tabular-nums; white-space: nowrap; }
.jp-kpi__sub { font: 400 .75rem/1rem var(--font-sans); color: var(--text-muted); }
.jp-kpi__delta--up { color: var(--color-success); font-weight: 600; } .jp-kpi__delta--down { color: var(--color-error); font-weight: 600; }
/* KPI enlazado: toda la tarjeta es clicable, el enlace va en el label */
.jp-kpi__link { color: inherit; text-decoration: none; }
.jp-kpi__link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.jp-kpi:has(.jp-kpi__link):hover { border-color: var(--border-component); box-shadow: var(--shadow-sm); }
.jp-kpi:has(.jp-kpi__link:focus-visible) { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.jp-kpi__link:focus-visible { outline: none; }
.jp-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); background: var(--container-bg); box-shadow: var(--container-shadow);
  border: 1px solid var(--border-divider); border-radius: var(--radius-lg); overflow: hidden; }
.jp-stats > * { margin: 0 -1px -1px 0; }
.jp-stats__item { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); padding: var(--space-3) var(--space-2); text-align: center;
  border-right: 1px solid var(--border-divider); border-bottom: 1px solid var(--border-divider); }
.jp-stats__value { font: 700 1.375rem/1.75rem var(--font-sans); font-variant-numeric: tabular-nums; }
.jp-stats__label { font: 600 .75rem/1rem var(--font-sans); letter-spacing: .04em; text-transform: uppercase; color: var(--text-secondary); }
.jp-stats__value--primary { color: var(--color-primary); } .jp-stats__value--success { color: var(--color-success); }
.jp-stats__value--warning { color: var(--color-warning); } .jp-stats__value--error { color: var(--color-error); }

/* ============ 29 ZONA DE PELIGRO (acciones destructivas de una entidad) ============ */
.jp-danger-zone { padding: var(--space-5); border: 1px solid var(--border-error); border-left-width: 4px; border-radius: var(--radius-lg); background: var(--error-subtle); }
.jp-danger-zone__title { margin: 0; font: 600 1rem/1.5rem var(--font-sans); color: var(--color-error); }
.jp-danger-zone__action { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-4);
  margin-top: var(--space-3); padding: var(--space-4); background: var(--surface-base); border: 1px solid var(--border-divider); border-radius: var(--radius-md); }
.jp-danger-zone__action p { margin: var(--space-1) 0 0; font-size: .8125rem; color: var(--text-secondary); }

/* ============ 30 GRÁFICAS (contenedor para Chart.js; colores en japifon-charts.js) ============ */
.jp-chart-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--space-4); }
.jp-chart-card { display: flex; flex-direction: column; border-radius: var(--radius-lg); min-width: 0; background: var(--container-bg); border: 1px solid var(--container-border); box-shadow: var(--container-shadow); }
.jp-chart-card__header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-4);
  padding: var(--space-3) var(--space-5); border-bottom: 1px solid var(--border-divider); background: var(--surface-sunken); border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
.jp-chart-card__subtitle { margin: 0; font: 400 .75rem/1rem var(--font-sans); color: var(--text-secondary); }
.jp-chart-card__summary { display: flex; flex-direction: column; align-items: flex-end; }
.jp-chart-card__summary .jp-kpi__sub { text-align: right; }
.jp-chart-card__title { margin: 0; font: 600 1rem/1.5rem var(--font-sans); }
.jp-chart-card__total { font: 700 1.375rem/1.75rem var(--font-sans); font-variant-numeric: tabular-nums; }
.jp-chart-card__body { position: relative; height: 240px; padding: var(--space-4) var(--space-4) var(--space-3); }
.jp-chart-card__body--sm { height: 180px; } .jp-chart-card__body--lg { height: 320px; }
.jp-chart-card__body canvas { max-width: 100%; }
.jp-legend { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); padding: var(--space-3) var(--space-5); border-top: 1px solid var(--border-divider); font: 400 .75rem/1rem var(--font-sans); color: var(--text-secondary); }
.jp-legend__item { display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-2); margin: calc(var(--space-1) * -1) calc(var(--space-2) * -1);
  border: 0; border-radius: var(--radius-sm); background: none; color: inherit; font: inherit; cursor: pointer; }
.jp-legend__item:hover { background: var(--state-hover-surface); color: var(--text-primary); }
/* Serie oculta: tachado + muestra vacía (no solo atenuado) */
.jp-legend__item[aria-pressed="false"] { text-decoration: line-through; }
.jp-legend__item[aria-pressed="false"] .jp-legend__swatch { background: none; box-shadow: inset 0 0 0 1.5px var(--_c, var(--chart-data-1)); }
/* --_c no se declara en ningún CSS: japifon-charts.js lo setea inline en cada
   ítem con el color de su serie. Por eso el uso lleva fallback. */
.jp-legend__swatch { width: .625rem; height: .625rem; border-radius: 2px; background: var(--_c, var(--chart-data-1)); }

/* ============ 31 ENCABEZADO DE PÁGINA (título + la única acción primaria de la vista) ============ */
.jp-page-header { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-3) var(--space-4); margin-bottom: var(--space-5); }
.jp-page-header__title { margin: 0; font: 700 1.75rem/2.25rem var(--font-sans); letter-spacing: -.01em; }
.jp-page-header__subtitle { margin: var(--space-1) 0 0; font: 400 .875rem/1.25rem var(--font-sans); color: var(--text-secondary); }
.jp-page-header__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.jp-icon { flex: none; width: 1rem; height: 1rem; }
.jp-btn--sm .jp-icon { width: .875rem; height: .875rem; }

/* ============ 32 FILTROS ============ */
/* Barra: búsqueda + filtros rápidos + «Más filtros» + limpiar. Filtra al cambiar; «Aplicar» solo si la consulta es costosa. */
.jp-filter-bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.jp-filter-bar > .jp-search { flex: 0 1 20rem; min-width: 12rem; }
/* Resultado de la búsqueda/filtros: siempre visible al final de la barra cuando hay consulta activa */
.jp-results { font: 400 .8125rem/1.25rem var(--font-sans); color: var(--text-secondary); white-space: nowrap; font-variant-numeric: tabular-nums; }
.jp-results b { color: var(--text-primary); font-weight: 600; }
/* La barra dentro de un panel ocupa la fila de filtros; el header del panel queda solo para título y acción */
.jp-panel__filters > .jp-filter-bar { flex: 1; }
.jp-filter-bar > .jp-quick-filters { flex: 1 1 0; min-width: 0; }
/* Tabla sin resultados */
.jp-table td.jp-table__empty { padding: var(--space-7) var(--space-4); text-align: center; color: var(--text-secondary); }
.jp-table__empty b { display: block; margin-bottom: var(--space-1); color: var(--text-primary); font-weight: 600; }
.jp-filter-bar > .jp-select { width: auto; flex: 0 1 auto; }
.jp-filter-bar__end { display: flex; align-items: center; gap: var(--space-2); margin-left: auto; }
/* Botón de filtro (abre un menú con opciones) */
.jp-filter { position: relative; display: inline-block; }
.jp-filter > summary { list-style: none; display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--control-h-sm);
  padding: 0 var(--space-3); border: 1px dashed var(--border-component); border-radius: var(--radius-pill); background: var(--surface-base);
  color: var(--text-secondary); font: 500 .8125rem/1 var(--font-sans); cursor: pointer; white-space: nowrap; }
.jp-filter > summary::-webkit-details-marker { display: none; }
.jp-filter > summary:hover { background: var(--state-hover-surface); color: var(--text-primary); }
/* Con valor: borde sólido + tinte + valor visible (no solo color) */
.jp-filter--active > summary { border-style: solid; border-color: var(--color-primary); background: var(--primary-subtle); color: var(--color-primary); font-weight: 600; }
.jp-filter__value { padding-left: var(--space-2); border-left: 1px solid currentColor; font-weight: 600; }
.jp-filter__count { display: inline-grid; place-items: center; min-width: 1.125rem; height: 1.125rem; padding: 0 .25rem; border-radius: var(--radius-pill);
  background: var(--color-control-checked); color: var(--color-on-control-checked); font: 600 .75rem/1 var(--font-sans); }
.jp-filter__panel { position: absolute; z-index: var(--z-dropdown); top: calc(100% + var(--space-1)); left: 0; width: 16rem; max-width: calc(100vw - 2rem);
  background: var(--surface-raised); border: 1px solid var(--border-divider); border-radius: var(--radius-md); box-shadow: var(--shadow-md); }
.jp-filter__panel--end { left: auto; right: 0; }
.jp-filter__body { display: flex; flex-direction: column; gap: var(--space-2); max-height: 16rem; overflow: auto; padding: var(--space-3); }
.jp-filter__footer { display: flex; justify-content: space-between; gap: var(--space-2); padding: var(--space-2) var(--space-3); border-top: 1px solid var(--border-divider); }
/* Filtro con muchas opciones (operadores, países, remitentes): búsqueda dentro del menú, seleccionados fijos arriba,
   conteo de visibles y «Seleccionar visibles». Hasta ~1,000 opciones en cliente (japifon-ui.js); más, búsqueda en servidor. */
.jp-filter__panel--wide { width: 20rem; }
.jp-filter__search { padding: var(--space-3) var(--space-3) 0; }
.jp-filter__meta { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: var(--space-2) var(--space-3) 0;
  font: 400 .75rem/1rem var(--font-sans); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.jp-filter__group { display: flex; flex-direction: column; gap: var(--space-2); }
.jp-filter__group + .jp-filter__group { padding-top: var(--space-2); border-top: 1px solid var(--border-divider); }
.jp-filter__group:empty, .jp-filter__group-label:has(+ .jp-filter__group:empty) { display: none; }
.jp-filter__group-label { font: 600 .75rem/1rem var(--font-sans); letter-spacing: .04em; text-transform: uppercase; color: var(--text-secondary); }
.jp-filter__empty { padding: var(--space-3) 0; text-align: center; font: 400 .8125rem/1.25rem var(--font-sans); color: var(--text-secondary); }
.jp-filter__more { color: var(--text-secondary); font-weight: 500; }

/* Filtros aplicados: chips removibles + «Limpiar todo» */
.jp-chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.jp-chip { display: inline-flex; align-items: center; gap: var(--space-1); min-height: 1.75rem; padding: 0 var(--space-1) 0 var(--space-3);
  border: 1px solid var(--border-component); border-radius: var(--radius-pill); background: var(--surface-subtle);
  color: var(--text-primary); font: 500 .8125rem/1 var(--font-sans); white-space: nowrap; }
.jp-chip__key { color: var(--text-secondary); font-weight: 400; }
.jp-chip__remove { position: relative; display: inline-block; width: 1.5rem; height: 1.5rem; border: 0; border-radius: 50%;
  background: none; color: var(--text-secondary); font: 400 1rem/1 var(--font-sans);
  /* Después del shorthand, no antes: `font` resetea font-size, y con el orden
     inverso el glifo del botón volvía a verse detrás de la X de ::before/::after. */
  font-size: 0; cursor: pointer; }
.jp-chip__remove:hover { background: var(--state-hover-surface); color: var(--text-primary); }
/* Filtro rápido segmentado con conteo (estado de la lista) */
.jp-quick-filters { display: flex; gap: var(--space-1); overflow-x: auto; }
.jp-quick-filter { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--control-h-sm); padding: 0 var(--space-3);
  border: 1px solid transparent; border-radius: var(--radius-pill); background: none; color: var(--text-secondary);
  font: 500 .8125rem/1 var(--font-sans); white-space: nowrap; cursor: pointer; }
.jp-quick-filter:hover { background: var(--state-hover-surface); color: var(--text-primary); }
.jp-quick-filter[aria-pressed="true"] { border-color: var(--color-primary); background: var(--primary-subtle); color: var(--color-primary); font-weight: 600; }
.jp-quick-filter__count { font-variant-numeric: tabular-nums; color: var(--text-muted); font-weight: 500; }
.jp-quick-filter[aria-pressed="true"] .jp-quick-filter__count { color: inherit; }
/* Rango de fechas: dos campos + atajos */
.jp-date-range { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.jp-date-range > .jp-input { width: auto; flex: 1 1 9rem; }
/* Móvil: la barra se pliega en «Filtros» */
.jp-filter-toggle { display: none; }
@media (max-width: 767.98px) {
  .jp-filter-bar > .jp-search { flex-basis: 100%; }
  .jp-filter-bar > :not(.jp-search):not(.jp-filter-toggle):not(.jp-filter-bar__end) { display: none; }
  .jp-filter-bar.is-open > * { display: revert; }
  .jp-filter-toggle { display: inline-flex; }
}

/* ============ 33 ACCIONES DE AGREGADO ============ */
/* Crear la entidad principal: botón primario con + en el encabezado (una por vista).
   Agregar dentro de un bloque (fila, destinatario, variable): outline/ghost o las piezas de abajo. */
.jp-split { display: inline-flex; position: relative; }
.jp-split > .jp-btn:first-child { border-radius: var(--radius-md) 0 0 var(--radius-md); }
.jp-split > .jp-dropdown > summary.jp-btn { border-radius: 0 var(--radius-md) var(--radius-md) 0; padding: 0 var(--space-2);
  border-left: 1px solid var(--state-lighten-pressed); }
.jp-split > .jp-dropdown > summary.jp-btn::after { margin-left: 0; }
/* Fila «+ Agregar …» al final de una lista o tabla */
.jp-add-row { display: flex; align-items: center; justify-content: center; gap: var(--space-2); width: 100%; min-height: var(--control-h-md);
  padding: 0 var(--space-4); border: 1px dashed var(--border-component); border-radius: var(--radius-md); background: none;
  color: var(--color-primary); font: 600 .875rem/1 var(--font-sans); cursor: pointer; }
.jp-add-row:hover { border-style: solid; border-color: var(--color-primary); background: var(--primary-subtle); }
.jp-add-row:disabled { color: var(--text-disabled); border-color: var(--border-disabled); background: none; cursor: not-allowed; }
/* Tarjeta «+ Agregar» dentro de una rejilla (canales, integraciones, plantillas) */
.jp-add-card { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2); min-height: 9rem;
  padding: var(--space-5) var(--space-4); border: 1.5px dashed var(--border-component); border-radius: var(--radius-lg); background: none;
  color: var(--color-primary); font: 600 .875rem/1.25rem var(--font-sans); text-align: center; text-decoration: none; cursor: pointer; }
.jp-add-card:hover { border-style: solid; border-color: var(--color-primary); background: var(--primary-subtle); }
.jp-add-card__icon { display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border-radius: 50%; background: var(--primary-subtle); }
.jp-add-card__hint { font: 400 .75rem/1rem var(--font-sans); color: var(--text-muted); }
/* Campos repetibles (destinatarios, variables, headers de webhook) */
.jp-repeater { display: flex; flex-direction: column; gap: var(--space-2); }
.jp-repeater__row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; gap: var(--space-2); align-items: center; }
.jp-repeater__row--1 { grid-template-columns: minmax(0, 1fr) auto; }
.jp-repeater__head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) var(--control-h-md); gap: var(--space-2); }
@media (max-width: 479.98px) { .jp-repeater__row { grid-template-columns: minmax(0, 1fr) auto; } .jp-repeater__row > :nth-child(2) { grid-column: 1; } .jp-repeater__head { display: none; } }

/* ============ 34 BARRA DE ACCIONES MASIVAS (aparece al seleccionar filas) ============ */
.jp-bulk-bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md); background: var(--surface-inverse); color: var(--surface-base); box-shadow: var(--shadow-md); }
.jp-bulk-bar__count { font: 600 .875rem/1.25rem var(--font-sans); font-variant-numeric: tabular-nums; }
.jp-bulk-bar__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); margin-left: auto; }
.jp-bulk-bar .jp-btn { --_fg: var(--surface-base); --_bd: transparent; }
.jp-bulk-bar .jp-btn:hover { --_ov: var(--state-lighten-hover); }
[data-theme="dark"] .jp-bulk-bar .jp-btn:hover, .jp-bulk-bar[data-inverse="dark"] .jp-btn:hover { --_ov: var(--state-darken-hover); }
.jp-bulk-bar .jp-close { color: inherit; }
.jp-bulk-bar--sticky { position: sticky; bottom: var(--space-4); z-index: var(--z-sticky); }

/* ============ 35 ACCESO (login, verificación, recuperar) ============ */
.jp-auth { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: var(--space-6) var(--space-4); background: var(--surface-sunken); }
.jp-auth__box { width: min(26rem, 100%); display: flex; flex-direction: column; gap: var(--space-5); }
.jp-auth__card { display: flex; flex-direction: column; gap: var(--space-5); padding: var(--space-7) var(--space-6) var(--space-6);
  background: var(--surface-raised); border: 1px solid var(--border-divider); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); }
.jp-auth__logo { display: block; height: 2.25rem; width: auto; margin: 0 auto; }
.jp-auth__head { text-align: center; }
.jp-auth__title { margin: 0; font: 700 1.5rem/2rem var(--font-sans); letter-spacing: -.01em; }
.jp-auth__lead { margin: var(--space-2) 0 0; font: 400 .9375rem/1.375rem var(--font-sans); color: var(--text-secondary); }
.jp-auth__lead b { color: var(--text-primary); font-weight: 600; overflow-wrap: anywhere; }
.jp-auth__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); }
.jp-auth__legal { display: flex; flex-direction: column; gap: var(--space-1); margin: 0; text-align: center; font: 400 .75rem/1rem var(--font-sans); color: var(--text-muted); }
/* Código de un solo uso: un campo (pega y autocompleta el SMS/correo), dígitos espaciados */
.jp-otp { text-align: center; font: 600 1.5rem/1 var(--font-mono); letter-spacing: .5em; padding-left: .5em; font-variant-numeric: tabular-nums; }
.jp-otp::placeholder { letter-spacing: .5em; }
.jp-auth__resend { display: flex; justify-content: center; gap: var(--space-2); font: 400 .8125rem/1.25rem var(--font-sans); color: var(--text-secondary); }

/* ============ 24 UTILIDADES ============ */
.jp-text-primary { color: var(--text-primary) !important; } .jp-text-secondary { color: var(--text-secondary) !important; }
.jp-text-muted { color: var(--text-muted) !important; } .jp-text-brand { color: var(--color-primary) !important; }
.jp-text-success { color: var(--color-success) !important; } .jp-text-warning { color: var(--color-warning) !important; }
.jp-text-error { color: var(--color-error) !important; }
.jp-bg-base { background: var(--surface-base) !important; } .jp-bg-raised { background: var(--surface-raised) !important; }
.jp-bg-subtle { background: var(--surface-subtle) !important; } .jp-bg-sunken { background: var(--surface-sunken) !important; }
.jp-text-left { text-align: left !important; } .jp-text-center { text-align: center !important; } .jp-text-right { text-align: right !important; }
.jp-fw-400 { font-weight: 400 !important; } .jp-fw-600 { font-weight: 600 !important; } .jp-fw-700 { font-weight: 700 !important; }
.jp-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jp-w-100 { width: 100% !important; }
.jp-d-none { display: none !important; } .jp-d-flex { display: flex !important; } .jp-d-grid { display: grid !important; } .jp-d-block { display: block !important; }
.jp-gap-1 { gap: var(--space-1) !important; } .jp-gap-2 { gap: var(--space-2) !important; } .jp-gap-3 { gap: var(--space-3) !important; } .jp-gap-4 { gap: var(--space-4) !important; }
.jp-m-0 { margin: 0 !important; } .jp-mt-2 { margin-top: var(--space-2) !important; } .jp-mt-4 { margin-top: var(--space-4) !important; } .jp-mb-2 { margin-bottom: var(--space-2) !important; } .jp-mb-4 { margin-bottom: var(--space-4) !important; }
.jp-p-0 { padding: 0 !important; } .jp-p-2 { padding: var(--space-2) !important; } .jp-p-4 { padding: var(--space-4) !important; } .jp-p-6 { padding: var(--space-6) !important; }
.jp-rounded { border-radius: var(--radius-md) !important; } .jp-rounded-lg { border-radius: var(--radius-lg) !important; } .jp-shadow { box-shadow: var(--shadow-md) !important; }
.jp-sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
@media (max-width: 767.98px) { .jp-d-md-none { display: none !important; } }
