/* =====================================================================
   Panel de licencias de MarkSite
   =====================================================================

   Hereda el lenguaje visual de marksitelab.html —Archivo ancho para los
   titulares, IBM Plex Mono para los datos, rojo #E30D18 como única señal,
   reglas de 1px y esquinas recortadas— pero traducido a un instrumento de
   trabajo: denso, tabla-primero, sin grano, sin barridos y sin animaciones
   de entrada. Aquí no se viene a mirar, se viene a resolver.

   Dos decisiones que conviene entender antes de tocar nada:

   1. El mono deja de ser un acento y pasa a ser el sustrato. Todo dato
      —tokens, dominios, versiones, fechas, recuentos, estados— va en IBM
      Plex Mono. Es lo que convierte una tabla en una lectura de aparato.

   2. El rojo NO significa «malo». Significa «esto es lo que hay que mirar»,
      igual que en la web. El estado de una licencia se codifica con un
      cuadro y una palabra, nunca con el color a solas: una tabla de
      doscientas licencias activas tiene que estar tranquila para que las
      cuatro con problemas salten a la vista.

   Índice
     1. Fuentes
     2. Tokens
     3. Base
     4. Estructura
     5. Tipografía
     6. Botones
     7. Formularios
     8. Tablas
     9. Estado y píldoras
    10. Tarjetas y paneles
    11. Pulso y gráfica
    12. Avisos, paginación y varios
   ===================================================================== */


/* ============================================================
   1. FUENTES — auto-alojadas, sin CDN, para poder cerrar la CSP
   ============================================================ */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 100% 125%;
  font-display: swap;
  src: url("../fonts/archivo-400-800-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 100% 125%;
  font-display: swap;
  src: url("../fonts/archivo-400-800-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Rubik";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/rubik-300-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Rubik";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/rubik-300-700-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/plex-mono-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/plex-mono-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/plex-mono-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/plex-mono-500-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
    U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
    U+2C60-2C7F, U+A720-A7FF;
}


/* ============================================================
   2. TOKENS
   ============================================================ */

:root {
  /* ---- Rojo de marca, intacto, con su rampa ---- */
  --red-400: #ff4438;
  --red-500: #e30d18;
  --red-600: #b00a12;
  --red-rgb: 227, 13, 24;

  /* ---- Ámbar: el único color que se añade a la paleta.
         Hace falta porque «caduca pronto» y «bloqueada» son dos cosas
         distintas y no pueden compartir el rojo. ---- */
  --amber-400: #f5a524;
  --amber-600: #a86a00;

  /* ---- Escala de grises heredada ---- */
  --ink-900: #08080a;
  --ink-800: #0b0b0d;
  --ink-700: #141416;
  --ink-600: #1b1b1f;
  --ink-500: #26262b;
  --line-700: #2a2a2e;
  --line-600: #3b3b42;

  --paper-100: #ffffff;
  --paper-200: #f7f7f5;
  --paper-300: #f2f2ef;
  --paper-400: #e4e4de;
  --paper-500: #d3d3cb;
  --paper-dim: #a5a59d;

  /* ---- Tipografía ---- */
  --font-display: "Archivo", "Rubik", system-ui, sans-serif;
  --font-body: "Rubik", system-ui, -apple-system, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Consolas, monospace;

  --fs-h1: 1.5rem;
  --fs-h2: 1.0625rem;
  --fs-body: 0.9375rem;
  --fs-sm: 0.8125rem;
  --fs-xs: 0.75rem;
  --fs-label: 0.6875rem;

  --tr-display: -0.025em;
  --tr-label: 0.16em;

  /* ---- Espaciado: escala corta, densa ---- */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;

  --r-1: 2px;
  --r-2: 3px;
  --r-pill: 999px;
  --cut: 10px;
  --cut-path: polygon(0 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% 100%, 0 100%);

  --rail-w: 216px;
  --topbar-h: 56px;
  --maxw: 1440px;

  --t-press: 120ms;
  --t-hover: 160ms;
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
}

/* ---- Tema oscuro: es el de la web, sin tocar ---- */
:root,
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: var(--ink-800);
  --bg-sunken: var(--ink-900);
  --surface: var(--ink-700);
  --surface-2: var(--ink-600);
  --surface-3: var(--ink-500);
  --border: var(--line-700);
  --border-strong: var(--line-600);

  --text: var(--paper-300);
  --text-2: var(--paper-dim);
  --text-3: #6f6f68;

  --signal: var(--red-500);
  --signal-text: var(--red-400);
  --signal-soft: rgba(227, 13, 24, 0.14);
  --on-signal: #ffffff;

  --warn: var(--amber-400);
  --warn-soft: rgba(245, 165, 36, 0.14);

  --focus: var(--red-400);
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.55), 0 8px 22px -16px rgba(0, 0, 0, 0.9);
  --shadow-2: 0 2px 5px rgba(0, 0, 0, 0.5), 0 22px 46px -26px rgba(0, 0, 0, 0.95);
  --row-hover: rgba(255, 255, 255, 0.032);
  --stripe: rgba(255, 255, 255, 0.014);
}

/* ---- Tema claro ----
   No es blanco puro: el fondo es el #F2F2EF que en la web era el color del
   texto. Invertir el papel de esa pareja mantiene la familia en vez de
   inventar una paleta nueva. Las superficies suben hacia el blanco, igual
   que en oscuro suben hacia el gris claro.
   El rojo baja a --red-600 para el texto pequeño: #E30D18 sobre blanco se
   queda en 4,4:1 y a 13px eso se lee mal. ---- */
:root[data-theme="light"] {
  color-scheme: light;

  --bg: var(--paper-300);
  --bg-sunken: var(--paper-400);
  --surface: var(--paper-100);
  --surface-2: var(--paper-200);
  --surface-3: var(--paper-400);
  --border: var(--paper-400);
  --border-strong: var(--paper-500);

  --text: var(--ink-800);
  --text-2: #5a5a55;
  --text-3: #83837c;

  --signal: var(--red-500);
  --signal-text: var(--red-600);
  --signal-soft: rgba(227, 13, 24, 0.09);
  --on-signal: #ffffff;

  --warn: var(--amber-600);
  --warn-soft: rgba(168, 106, 0, 0.11);

  --focus: var(--red-600);
  --shadow-1: 0 1px 2px rgba(11, 11, 13, 0.06), 0 6px 16px -12px rgba(11, 11, 13, 0.28);
  --shadow-2: 0 2px 5px rgba(11, 11, 13, 0.07), 0 18px 40px -24px rgba(11, 11, 13, 0.3);
  --row-hover: rgba(11, 11, 13, 0.028);
  --stripe: rgba(11, 11, 13, 0.012);
}


/* ============================================================
   3. BASE
   ============================================================ */

*,
*::before,
*::after {
  box-sizing: border-box;
}

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

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

h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 600;
}

p {
  margin: 0;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}

img,
svg {
  display: block;
  max-width: 100%;
}

hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: var(--s-5) 0;
}

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

::selection {
  background: var(--signal);
  color: var(--on-signal);
}

.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;
}

.skip {
  position: fixed;
  top: var(--s-3);
  left: var(--s-3);
  z-index: 200;
  transform: translateY(-200%);
  background: var(--signal);
  color: var(--on-signal);
  padding: var(--s-2) var(--s-4);
  font-size: var(--fs-sm);
  font-weight: 500;
  border-radius: var(--r-2);
  transition: transform var(--t-hover) var(--ease-out);
}

.skip:focus-visible {
  transform: translateY(0);
}


/* ============================================================
   4. ESTRUCTURA — raíl fijo a la izquierda y columna de trabajo
   ============================================================ */

.shell {
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr);
  min-height: 100vh;
}

/* ---- Raíl ---- */

.rail {
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  padding: var(--s-4) var(--s-3);
  background: var(--bg-sunken);
  border-right: 1px solid var(--border);
  overflow-y: auto;
}

.brand {
  display: flex;
  align-items: baseline;
  gap: 0;
  padding: var(--s-2) var(--s-3) 0;
  font-family: var(--font-display);
  font-stretch: 125%;
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: -0.02em;
  color: var(--text);
  white-space: nowrap;
}

.brand__accent {
  color: var(--signal);
}

.brand__sub {
  display: block;
  padding: 0 var(--s-3) 0;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--text-3);
}

/* Etiqueta de sección del raíl: la regla de 1px de la web, en pequeño. */
.rail__label {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: 0 var(--s-3);
  margin-bottom: var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--text-3);
}

.rail__label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}

.rail__nav {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.rail__link {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-2);
  font-size: var(--fs-sm);
  color: var(--text-2);
  transition: background-color var(--t-hover) ease, color var(--t-hover) ease;
}

.rail__link .icon {
  width: 15px;
  height: 15px;
  flex: none;
  opacity: 0.75;
}

.rail__link:hover {
  background: var(--row-hover);
  color: var(--text);
}

.rail__link[aria-current="page"] {
  background: var(--surface);
  color: var(--text);
  font-weight: 500;
}

.rail__link[aria-current="page"]::before {
  content: "";
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 2px;
  background: var(--signal);
  border-radius: var(--r-pill);
}

.rail__link[aria-current="page"] .icon {
  opacity: 1;
  color: var(--signal);
}

.rail__count {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-3);
}

.rail__foot {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding-top: var(--s-4);
  border-top: 1px solid var(--border);
}

.rail__user {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: 0 var(--s-3);
  min-width: 0;
}

.avatar {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex: none;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--text-2);
}

.rail__user-name {
  min-width: 0;
  font-size: var(--fs-sm);
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rail__user-role {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-3);
}

.rail__actions {
  display: flex;
  gap: var(--s-2);
  padding: 0 var(--s-3);
}

/* ---- Columna de trabajo ---- */

.main {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: var(--s-4);
  min-height: var(--topbar-h);
  padding: var(--s-2) var(--s-5);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  border-bottom: 1px solid var(--border);
}

.topbar__title {
  font-family: var(--font-display);
  font-stretch: 112%;
  font-weight: 700;
  font-size: var(--fs-h1);
  letter-spacing: var(--tr-display);
  line-height: 1.1;
}

.topbar__spacer {
  flex: 1;
}

.topbar__tools {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

.page {
  flex: 1;
  width: 100%;
  max-width: var(--maxw);
  padding: var(--s-5);
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}

.page__head {
  display: flex;
  align-items: flex-end;
  gap: var(--s-4);
  flex-wrap: wrap;
}

.page__head .prose {
  color: var(--text-2);
  font-size: var(--fs-sm);
  max-width: 68ch;
}

/* Rejillas reutilizables */
.grid {
  display: grid;
  gap: var(--s-4);
}

.grid--2 {
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}

.grid--3 {
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

.grid--split {
  grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr);
  align-items: start;
}

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


/* ============================================================
   5. TIPOGRAFÍA
   ============================================================ */

.mono {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
}

.num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.label {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--text-3);
}

.muted {
  color: var(--text-2);
}

.dim {
  color: var(--text-3);
}

.small {
  font-size: var(--fs-sm);
}

.tiny {
  font-size: var(--fs-xs);
}

.link {
  color: var(--text);
  border-bottom: 1px solid var(--border-strong);
  transition: color var(--t-hover) ease, border-color var(--t-hover) ease;
}

.link:hover {
  color: var(--signal-text);
  border-bottom-color: var(--signal);
}

.link--quiet {
  border-bottom-color: transparent;
}

.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}


/* ============================================================
   6. BOTONES
   ============================================================ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  padding: 0.44rem 0.8rem;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1.35;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--t-hover) ease, border-color var(--t-hover) ease,
    color var(--t-hover) ease, transform var(--t-press) var(--ease-out);
}

.btn:hover {
  border-color: var(--border-strong);
  background: var(--surface-2);
}

.btn:active {
  transform: scale(0.98);
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

.btn .icon {
  width: 14px;
  height: 14px;
  flex: none;
}

.btn--primary {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--on-signal);
}

.btn--primary:hover {
  background: var(--red-400);
  border-color: var(--red-400);
  color: #fff;
}

.btn--primary:active {
  background: var(--red-600);
  border-color: var(--red-600);
}

.btn--ghost {
  background: transparent;
}

.btn--ghost:hover {
  background: var(--row-hover);
}

/* Destructivo: rojo solo en el borde y el texto, nunca relleno. Un botón
   rojo macizo al lado de otros invita a pulsarlo por costumbre. */
.btn--danger {
  background: transparent;
  color: var(--signal-text);
  border-color: color-mix(in srgb, var(--signal) 45%, transparent);
}

.btn--danger:hover {
  background: var(--signal-soft);
  border-color: var(--signal);
  color: var(--signal-text);
}

.btn--sm {
  padding: 0.25rem 0.5rem;
  font-size: var(--fs-xs);
}

.btn--icon {
  padding: 0.38rem;
  width: 30px;
  height: 30px;
}

.btn--block {
  width: 100%;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  align-items: center;
}

.btn-row--end {
  justify-content: flex-end;
}


/* ============================================================
   7. FORMULARIOS
   ============================================================ */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  min-width: 0;
}

.field > label,
.field__label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--text-3);
}

.field__hint {
  font-size: var(--fs-xs);
  color: var(--text-3);
  line-height: 1.45;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="number"],
input[type="date"],
select,
textarea {
  width: 100%;
  padding: 0.42rem 0.6rem;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  color: var(--text);
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  transition: border-color var(--t-hover) ease, background-color var(--t-hover) ease;
}

input[type="date"],
input[type="number"],
input[type="search"] {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

textarea {
  min-height: 76px;
  resize: vertical;
  line-height: 1.5;
}

input:hover,
select:hover,
textarea:hover {
  border-color: var(--border-strong);
}

input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--signal);
  background: var(--surface);
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}

select {
  appearance: none;
  padding-right: 1.6rem;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 0.75rem center, right 0.5rem center;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
}

::placeholder {
  color: var(--text-3);
  opacity: 1;
}

.checkbox {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  font-size: var(--fs-sm);
  cursor: pointer;
}

.checkbox input[type="checkbox"] {
  width: 15px;
  height: 15px;
  margin: 2px 0 0;
  flex: none;
  accent-color: var(--signal);
  cursor: pointer;
}

/* Barra de filtros: una línea de campos que envuelve en móvil. */
.filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
}

.filters .field {
  flex: 1 1 150px;
}

.filters .field--wide {
  flex: 2 1 240px;
}

.filters__actions {
  display: flex;
  gap: var(--s-2);
  margin-left: auto;
}

/* Selector de producto de la cabecera: es estado global, no un filtro más. */
.product-switch {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: 2px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
}

.product-switch a {
  padding: 0.22rem 0.6rem;
  border-radius: var(--r-1);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  color: var(--text-2);
  transition: background-color var(--t-hover) ease, color var(--t-hover) ease;
}

.product-switch a:hover {
  color: var(--text);
  background: var(--row-hover);
}

.product-switch a[aria-current="true"] {
  background: var(--signal);
  color: var(--on-signal);
  font-weight: 500;
}


/* ============================================================
   8. TABLAS — el centro del panel
   ============================================================ */

.table-wrap {
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  background: var(--surface);
  overflow-x: auto;
}

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

thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: var(--s-2) var(--s-3);
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--text-3);
  white-space: nowrap;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}

tbody td {
  padding: var(--s-2) var(--s-3);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

tbody tr:nth-child(even) {
  background: var(--stripe);
}

tbody tr:hover {
  background: var(--row-hover);
}

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

td.num,
th.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

td.actions {
  text-align: right;
  white-space: nowrap;
}

td.tight,
th.tight {
  width: 1%;
  white-space: nowrap;
}

.table--fixed {
  table-layout: fixed;
}

.row-title {
  display: block;
  font-weight: 500;
  color: var(--text);
}

.row-sub {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-3);
}

/* Fila que pide una decisión. */
tbody tr.is-flagged td:first-child {
  box-shadow: inset 2px 0 0 var(--signal);
}

.empty {
  padding: var(--s-6) var(--s-4);
  text-align: center;
  color: var(--text-2);
  font-size: var(--fs-sm);
}

.empty strong {
  display: block;
  margin-bottom: var(--s-1);
  color: var(--text);
  font-weight: 500;
}


/* ============================================================
   9. ESTADO Y PÍLDORAS
   ============================================================

   El estado se lee por el cuadro Y por la palabra. El color solo refuerza,
   nunca informa a solas: hay gente que no lo distingue y hay tablas que se
   imprimen. */

.state {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.04em;
  white-space: nowrap;
  color: var(--text-2);
}

.state::before {
  content: "";
  width: 7px;
  height: 7px;
  flex: none;
  border: 1px solid currentColor;
}

/* Activa: sin chroma. Que la normalidad no llame la atención. */
.state--active {
  color: var(--text-2);
}

.state--active::before {
  background: var(--text-2);
}

.state--disabled {
  color: var(--signal-text);
}

.state--disabled::before {
  background: var(--signal);
  border-color: var(--signal);
}

.state--expired {
  color: var(--warn);
}

.state--expired::before {
  background: var(--warn);
  border-color: var(--warn);
}

/* Pendiente: cuadro hueco. Es literalmente un hueco por rellenar. */
.state--pending {
  color: var(--text-3);
}

.state--pending::before {
  background: transparent;
}

.state--waiting {
  color: var(--text-3);
}

.state--waiting::before {
  background: repeating-linear-gradient(
    45deg,
    currentColor 0 1px,
    transparent 1px 3px
  );
}

/* Píldora de producto, para la columna del listado de clientes. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.1rem 0.45rem 0.1rem 0.35rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-2);
  white-space: nowrap;
}

.pill::before {
  content: "";
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: var(--r-pill);
  background: var(--text-2);
}

.pill--disabled {
  color: var(--signal-text);
  border-color: color-mix(in srgb, var(--signal) 35%, var(--border));
}

.pill--disabled::before {
  background: var(--signal);
}

.pill--expired {
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 35%, var(--border));
}

.pill--expired::before {
  background: var(--warn);
}

.pill--waiting::before {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--text-3);
}

.pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1);
}

/* Marca de «esto necesita que decidas algo». */
.flag {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.05rem 0.4rem;
  background: var(--signal-soft);
  border-radius: var(--r-1);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--signal-text);
}

.flag--warn {
  background: var(--warn-soft);
  color: var(--warn);
}

/* Token: se enseña entero, en mono, con botón de copiar al lado. */
.token {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 0.2rem 0.45rem;
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.02em;
  word-break: break-all;
}

.token--block {
  display: flex;
  padding: var(--s-2) var(--s-3);
  font-size: var(--fs-sm);
}


/* ============================================================
   10. TARJETAS Y PANELES
   ============================================================ */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
}

.card__head {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--border);
}

.card__head h2 {
  font-size: var(--fs-h2);
  font-weight: 600;
}

.card__head .btn {
  margin-left: auto;
}

.card__body {
  padding: var(--s-4);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}

.card__body--flush {
  padding: 0;
}

.card__foot {
  padding: var(--s-3) var(--s-4);
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: var(--s-3);
}

/* La esquina recortada es el guiño al chasis de la web. Se reserva para las
   fichas de resumen del panel, que son las piezas «de aparato». Ponerla en
   todo la convertiría en un borde más. */
.tile {
  position: relative;
  padding: var(--s-4);
  background: var(--surface);
  border: 1px solid var(--border);
  clip-path: var(--cut-path);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}

.tile__head {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
}

.tile__name {
  font-family: var(--font-display);
  font-stretch: 112%;
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: -0.015em;
}

.tile__slug {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: 0.08em;
  color: var(--text-3);
}

.tile__stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-2);
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.stat__value {
  font-family: var(--font-mono);
  font-size: 1.375rem;
  font-weight: 500;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.stat__value--zero {
  color: var(--text-3);
}

.stat__value--alert {
  color: var(--signal-text);
}

.stat__value--warn {
  color: var(--warn);
}

.stat__label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
}

/* Lista de datos de las fichas. */
.data {
  display: grid;
  grid-template-columns: minmax(120px, auto) minmax(0, 1fr);
  gap: var(--s-2) var(--s-4);
  font-size: var(--fs-sm);
  margin: 0;
}

.data dt {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--text-3);
  padding-top: 2px;
}

.data dd {
  margin: 0;
  min-width: 0;
  word-break: break-word;
}

/* Fila de producto en la ficha del cliente: es la pantalla central del
   modelo multi-producto, así que cada producto ocupa su propia banda. */
.product-row {
  display: grid;
  grid-template-columns: minmax(180px, 1.2fr) repeat(auto-fit, minmax(110px, 1fr)) auto;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--border);
}

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

.product-row--off {
  background: var(--stripe);
}

.product-row__name {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.product-row__name strong {
  font-weight: 500;
}

.product-row__actions {
  display: flex;
  gap: var(--s-2);
  justify-content: flex-end;
}

@media (max-width: 860px) {
  .product-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .product-row__actions {
    justify-content: flex-start;
  }
}

/* Línea de tiempo de la auditoría. */
.timeline {
  display: flex;
  flex-direction: column;
}

.timeline__item {
  position: relative;
  padding: var(--s-2) 0 var(--s-2) var(--s-5);
  font-size: var(--fs-sm);
  border-left: 1px solid var(--border);
  margin-left: var(--s-2);
}

.timeline__item::before {
  content: "";
  position: absolute;
  left: -3px;
  top: 1.05rem;
  width: 5px;
  height: 5px;
  background: var(--border-strong);
  border-radius: var(--r-pill);
}

.timeline__item--signal::before {
  background: var(--signal);
}

.timeline__when {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-3);
}


/* ============================================================
   11. PULSO Y GRÁFICA
   ============================================================

   El pulso es la pieza que da nombre a este panel: una marca por día de los
   últimos treinta. Contesta de un vistazo a «¿me va o no me va?» sin abrir
   nada: si la instalación llama a diario hay una banda continua, si dejó de
   llamar se ve el hueco, y los días en que el servidor respondió que no
   salen en rojo. */

.pulse {
  height: 18px;
  width: 150px;
  overflow: visible;
}

.pulse--empty {
  display: inline-block;
  width: 150px;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
}

.pulse__tick {
  fill: var(--border-strong);
}

.pulse__tick--ok {
  fill: var(--text-2);
}

.pulse__tick--denied {
  fill: var(--signal);
}

.pulse__tick--none {
  fill: var(--border);
}

.pulse--lg {
  width: 100%;
  height: 40px;
}

.chart {
  width: 100%;
  height: 220px;
}

.chart__grid {
  stroke: var(--border);
  stroke-width: 1;
}

.chart__tick {
  fill: var(--text-3);
  font-family: var(--font-mono);
  font-size: 10px;
}

.chart__line {
  fill: none;
  stroke-width: 1.5;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.chart__dot {
  stroke: var(--surface);
  stroke-width: 1;
}

.chart__empty {
  padding: var(--s-6);
  text-align: center;
  color: var(--text-3);
  font-size: var(--fs-sm);
}

/* Series: rojo para la primera, tinta para la segunda y trazos distintos a
   partir de ahí. Con dos productos casi nunca hará falta más, y meter
   colores nuevos rompería la paleta por un caso que no ocurre. */
.chart__line[data-serie="0"],
.chart__dot[data-serie="0"] {
  stroke: var(--signal);
}

.chart__dot[data-serie="0"] {
  fill: var(--signal);
}

.chart__line[data-serie="1"],
.chart__dot[data-serie="1"] {
  stroke: var(--text-2);
}

.chart__dot[data-serie="1"] {
  fill: var(--text-2);
}

.chart__line[data-serie="2"] {
  stroke: var(--warn);
  stroke-dasharray: 5 3;
}

.chart__dot[data-serie="2"] {
  stroke: var(--warn);
  fill: var(--warn);
}

.chart__line[data-serie="3"] {
  stroke: var(--signal);
  stroke-dasharray: 2 3;
}

.chart__dot[data-serie="3"] {
  stroke: var(--signal);
  fill: var(--signal);
}

.chart__line[data-serie="4"] {
  stroke: var(--text-3);
  stroke-dasharray: 8 3;
}

.chart__dot[data-serie="4"] {
  stroke: var(--text-3);
  fill: var(--text-3);
}

.chart__line[data-serie="5"] {
  stroke: var(--text-3);
  stroke-dasharray: 1 3;
}

.chart__dot[data-serie="5"] {
  stroke: var(--text-3);
  fill: var(--text-3);
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  padding-top: var(--s-3);
}

.legend__item {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-xs);
  color: var(--text-2);
}

.legend__swatch {
  width: 14px;
  height: 2px;
  flex: none;
  background: var(--text-3);
}

.legend__swatch[data-serie="0"] {
  background: var(--signal);
}

.legend__swatch[data-serie="1"] {
  background: var(--text-2);
}

.legend__swatch[data-serie="2"] {
  background: linear-gradient(90deg, var(--warn) 0 5px, transparent 5px 8px, var(--warn) 8px);
}

.legend__swatch[data-serie="3"] {
  background: linear-gradient(90deg, var(--signal) 0 2px, transparent 2px 5px, var(--signal) 5px 7px, transparent 7px);
}

.legend__value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--text-3);
}


/* ============================================================
   12. AVISOS, PAGINACIÓN Y VARIOS
   ============================================================ */

.notice {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--border);
  border-left-width: 2px;
  border-radius: var(--r-2);
  background: var(--surface);
  font-size: var(--fs-sm);
}

.notice .icon {
  width: 16px;
  height: 16px;
  flex: none;
  margin-top: 1px;
}

.notice--ok {
  border-left-color: var(--text-2);
}

.notice--error {
  border-left-color: var(--signal);
  background: var(--signal-soft);
}

.notice--warn {
  border-left-color: var(--warn);
  background: var(--warn-soft);
}

.notice--info {
  border-left-color: var(--border-strong);
}

.notice strong {
  font-weight: 500;
}

.flashes {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

.pagination {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
  padding-top: var(--s-3);
}

.pagination__info {
  margin-right: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--text-3);
}

.pagination a,
.pagination span {
  min-width: 30px;
  padding: 0.2rem 0.45rem;
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  color: var(--text-2);
}

.pagination a:hover {
  border-color: var(--border-strong);
  color: var(--text);
}

.pagination [aria-current="page"] {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--on-signal);
}

.pagination .gap {
  border-color: transparent;
}

/* Bloque de acción en lote: aparece cuando hay filas marcadas. */
.bulkbar {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
  padding: var(--s-3) var(--s-4);
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-2);
}

.bulkbar__count {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
}

.bulkbar[hidden] {
  display: none;
}

/* Diálogo de confirmación de las acciones que no se pueden deshacer. */
dialog {
  padding: 0;
  max-width: min(520px, calc(100vw - 2rem));
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-2);
  box-shadow: var(--shadow-2);
}

dialog::backdrop {
  background: rgba(0, 0, 0, 0.55);
}

.dialog__body {
  padding: var(--s-5);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}

.dialog__body h2 {
  font-family: var(--font-display);
  font-stretch: 112%;
  font-size: 1.125rem;
  letter-spacing: -0.015em;
}

.dialog__foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-5);
  border-top: 1px solid var(--border);
  background: var(--surface-2);
}

/* Bloque plegable para lo que no se mira todos los días. */
details.block {
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  background: var(--surface);
}

details.block > summary {
  padding: var(--s-3) var(--s-4);
  cursor: pointer;
  font-size: var(--fs-sm);
  font-weight: 500;
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

details.block > summary::-webkit-details-marker {
  display: none;
}

details.block > summary::before {
  content: "";
  width: 0;
  height: 0;
  border-left: 4px solid currentColor;
  border-top: 3.5px solid transparent;
  border-bottom: 3.5px solid transparent;
  transition: transform var(--t-hover) ease;
}

details.block[open] > summary::before {
  transform: rotate(90deg);
}

details.block > .card__body {
  border-top: 1px solid var(--border);
}

.icon {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Pantallas de entrada y de error: sin raíl, centradas. */
.bare {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--s-5);
}

.bare__panel {
  width: min(100%, 380px);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}

.bare__brand {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  font-family: var(--font-display);
  font-stretch: 125%;
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: var(--tr-display);
}

.bare__code {
  font-family: var(--font-mono);
  font-size: 3rem;
  font-weight: 500;
  line-height: 1;
  color: var(--signal);
}


/* ============================================================
   RESPONSIVE — el panel es de escritorio, pero tiene que servir en el
   móvil cuando alguien escribe un domingo diciendo que no le va.
   ============================================================ */

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

  .rail {
    position: static;
    height: auto;
    flex-direction: row;
    align-items: center;
    gap: var(--s-3);
    overflow-x: auto;
    border-right: 0;
    border-bottom: 1px solid var(--border);
    padding: var(--s-2) var(--s-3);
  }

  .rail__label,
  .rail__user,
  .brand__sub {
    display: none;
  }

  .rail__nav {
    flex-direction: row;
    gap: var(--s-1);
  }

  .rail__link {
    white-space: nowrap;
  }

  .rail__link[aria-current="page"]::before {
    top: auto;
    bottom: 0;
    left: 8px;
    right: 8px;
    width: auto;
    height: 2px;
  }

  .rail__foot {
    margin-top: 0;
    margin-left: auto;
    padding-top: 0;
    border-top: 0;
    flex-direction: row;
  }

  .page {
    padding: var(--s-4) var(--s-3);
  }

  .topbar {
    flex-wrap: wrap;
    padding: var(--s-2) var(--s-3);
  }

  .tile__stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .data {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-1) 0;
  }

  .data dd {
    margin-bottom: var(--s-2);
  }
}

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

@media print {
  .rail,
  .topbar__tools,
  .filters,
  .bulkbar,
  td.actions,
  .pagination {
    display: none;
  }

  .shell {
    grid-template-columns: minmax(0, 1fr);
  }

  body {
    background: #fff;
    color: #000;
  }
}
