/* ============================================================================
   Cosmos · sistema visual
   κόσμος = «orden». Herramienta de precisión, sobria y cálida, para profesorado.
   Una tinta índigo serena · escala tipográfica modular · profundidad de una capa.
   Todo local, sin fuentes ni CSS remotos. Claro y oscuro.
   ========================================================================== */

:root {
  /* — Superficies y tinta (paleta contenida: papel · tinta · 1 acento · funcionales) — */
  --bg:        #f4f5f8;   /* papel */
  --panel:     #ffffff;   /* tarjetas, cabecera, tabla */
  --panel-2:   #fafbfc;   /* zebra / campos */
  --ink:       #1a2130;   /* tinta principal */
  --ink-2:     #46536a;   /* secundaria */
  --muted:     #6b7688;   /* terciaria / etiquetas */
  --faint:     #9aa4b4;   /* mínima */
  --line:      #e5e8ef;   /* filete 1px */
  --line-2:    #eef1f6;   /* filete interior más leve */

  /* — Acento (índigo) — */
  --brand:     #3453d4;
  --brand-ink: #2b46b4;   /* texto de acento sobre claro */
  --brand-soft:#eef1fd;   /* fondo suave de acento */

  /* — Funcionales — */
  --ok:      #128a52;
  --warn:    #b76b0b;
  --danger:  #cf3b3b;
  --perf:    #7a52c9;     /* categoría: plazas perfiladas / requisitos */
  --larga:   #0b86a3;     /* categoría: larga duración */

  /* — Forma — */
  --r:    11px;           /* tarjetas, diálogos */
  --r-sm: 8px;            /* botones, campos, celdas de lista */
  --pill: 999px;
  --head: 58px;           /* alto de la cabecera fija */

  /* — Profundidad (una sola dirección de luz, capas con significado) — */
  --sh-1: 0 1px 2px rgba(20,26,45,.05);
  --sh-2: 0 2px 4px rgba(20,26,45,.05), 0 8px 24px -10px rgba(20,26,45,.14);
  --sh-pop: 0 12px 40px -8px rgba(20,26,45,.28);

  /* — Tipografía — */
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SFMono-Regular", "SF Mono", "Menlo", "Consolas", monospace;

  /* — Movimiento — */
  --ease: cubic-bezier(.2,.7,.2,1);
  --fast: .12s var(--ease);
  --mid:  .2s  var(--ease);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg:#0e1219; --panel:#161c26; --panel-2:#1a212c; --ink:#e7edf5; --ink-2:#b6c1d1;
    --muted:#8b97a9; --faint:#6b7789; --line:#242e3c; --line-2:#1f2833;
    --brand:#7f96ff; --brand-ink:#adbdff; --brand-soft:#1a2233;
    --ok:#3cc985; --warn:#e2a24a; --danger:#f0736f; --perf:#b191ef; --larga:#3fc0dc;
    --sh-1: 0 1px 2px rgba(0,0,0,.4);
    --sh-2: 0 2px 4px rgba(0,0,0,.3), 0 10px 30px -12px rgba(0,0,0,.6);
    --sh-pop: 0 16px 48px -8px rgba(0,0,0,.7);
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; }
html { height: 100%; }
body {
  font: 400 14px/1.55 var(--sans);
  background: var(--bg); color: var(--ink);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  font-variant-numeric: tabular-nums;
}
h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -.012em; line-height: 1.15; }
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }
button, select, input, textarea { font: inherit; color: inherit; }
::selection { background: color-mix(in oklch, var(--brand) 22%, transparent); }

/* Foco visible coherente en toda la app */
:where(button, a, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid color-mix(in oklch, var(--brand) 65%, transparent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* ============================ Cabecera ============================ */
.top {
  display: flex; align-items: center; gap: 13px;
  min-height: var(--head); padding: 9px 22px;
  background: color-mix(in oklch, var(--panel) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(8px);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 30;
}
.top .logo {
  width: 34px; height: 34px; border-radius: 9px;
  display: grid; place-items: center; color: #fff; font-size: 18px;
  background: linear-gradient(150deg, color-mix(in oklch, var(--brand) 88%, white), var(--brand) 55%, color-mix(in oklch, var(--brand) 78%, #101a4a));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), var(--sh-1);
  flex: none;
}
.top h1 { font-size: 17px; display: flex; align-items: baseline; gap: 9px; }
.top h1 .etim { font-size: 11.5px; font-weight: 400; color: var(--muted); letter-spacing: 0; }
@media (max-width: 620px) { .top h1 .etim { display: none; } }
.top .sub { color: var(--muted); font-size: 12px; margin-top: 1px; }
.top .spacer { flex: 1; }

.badge-priv {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 500; color: var(--ok);
  background: color-mix(in oklch, var(--ok) 11%, transparent);
  padding: 5px 11px; border-radius: var(--pill);
  border: 1px solid color-mix(in oklch, var(--ok) 26%, transparent);
  white-space: nowrap;
}
.badge-priv svg { width: 13px; height: 13px; }
@media (max-width: 620px) { .badge-priv .t { display: none; } }

/* ============================ Maquetación ============================
   La PÁGINA hace scroll (no un item de altura fija con overflow): así la tabla
   se dimensiona por su contenido y no se estira. NO envolver la tabla en un
   contenedor de altura fija. (Antes existía una colisión de clase: el grid de
   página y las celdas de texto compartían «.wrap» → celdas rotas. Resuelto:
   grid = .layout ; celdas de texto largo = .cw) */
.layout { display: grid; grid-template-columns: 344px minmax(0, 1fr); align-items: start; }
@media (max-width: 940px) { .layout { grid-template-columns: 1fr; } .side { position: static; max-height: none; border-right: none; border-bottom: 1px solid var(--line); } }

.side {
  align-self: start; position: sticky; top: var(--head);
  max-height: calc(100vh - var(--head)); overflow-y: auto;
  padding: 18px 16px; border-right: 1px solid var(--line); background: var(--panel);
  scrollbar-width: thin;
}
.main { padding: 18px 20px 64px; min-width: 0; }

/* ============================ Tarjetas de paso ============================ */
.card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); padding: 16px; margin-bottom: 14px;
}
.card + .card { margin-top: 0; }
.card > h3 {
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); margin-bottom: 12px; display: flex; align-items: center; gap: 8px;
}
.card > h3 .n {
  margin-left: auto; font-weight: 600; font-size: 11px; color: var(--brand-ink);
  background: var(--brand-soft); padding: 2px 9px; border-radius: var(--pill);
  text-transform: none; letter-spacing: 0;
}

/* ============================ Formularios ============================ */
.row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.row.mt { margin-top: 10px; }
label.lbl { display: block; font-size: 12px; font-weight: 500; color: var(--ink-2); }
label.lbl + * { margin-top: 6px; }

input[type=text], input[type=email], select, textarea {
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 8px 10px; width: 100%;
  transition: border-color var(--fast), box-shadow var(--fast), background var(--fast);
}
input::placeholder { color: var(--faint); }
input[type=text]:hover, input[type=email]:hover, select:hover { border-color: color-mix(in oklch, var(--ink) 20%, var(--line)); }
input[type=text]:focus, input[type=email]:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--brand); background: var(--panel);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--brand) 16%, transparent);
}

/* ============================ Botones ============================ */
button {
  cursor: pointer; border: 1px solid var(--line); background: var(--panel);
  color: var(--ink); border-radius: var(--r-sm); padding: 8px 12px; font-weight: 500;
  display: inline-flex; align-items: center; gap: 7px;
  transition: background var(--fast), border-color var(--fast), color var(--fast), box-shadow var(--fast), transform var(--fast);
}
button svg { width: 15px; height: 15px; flex: none; }
button:hover { background: color-mix(in oklch, var(--brand) 6%, var(--panel)); border-color: color-mix(in oklch, var(--brand) 32%, var(--line)); }
button:active { transform: translateY(.5px); }
button.primary {
  background: var(--brand); color: #fff; border-color: transparent;
  box-shadow: 0 1px 2px color-mix(in oklch, var(--brand) 45%, transparent), inset 0 1px 0 rgba(255,255,255,.18);
}
button.primary:hover { background: color-mix(in oklch, var(--brand) 92%, #000); color: #fff; }
button.mini { padding: 5px 9px; font-size: 12.5px; border-radius: 7px; gap: 5px; }
button.ghost { background: transparent; border-color: transparent; }
button.ghost:hover { background: color-mix(in oklch, var(--ink) 6%, transparent); border-color: transparent; }
button:disabled { opacity: .45; cursor: not-allowed; transform: none; }
button:disabled:hover { background: var(--panel); border-color: var(--line); }

/* ============================ Dropzone (administrador) ============================ */
.drop {
  border: 1.5px dashed var(--line); border-radius: var(--r); padding: 22px 14px;
  text-align: center; color: var(--muted); cursor: pointer; background: var(--panel-2);
  transition: border-color var(--fast), background var(--fast), color var(--fast);
}
.drop:hover { border-color: color-mix(in oklch, var(--brand) 45%, var(--line)); }
.drop.drag { border-color: var(--brand); background: var(--brand-soft); color: var(--brand-ink); }
.drop strong { color: var(--ink); font-weight: 600; }

.files { list-style: none; margin: 12px 0 0; padding: 0; font-size: 13px; }
.files li { display: flex; align-items: center; gap: 8px; padding: 7px 0; border-top: 1px solid var(--line-2); }
.files li .x { margin-left: auto; }

/* ============================ Facetas / checks ============================ */
.check { display: flex; align-items: center; gap: 9px; padding: 5px 0; font-size: 13.5px; cursor: pointer; line-height: 1.35; }
.check input { accent-color: var(--brand); width: 16px; height: 16px; flex: none; }
.check:hover { color: var(--brand-ink); }
.check .c {
  margin-left: auto; color: var(--muted); font-size: 11.5px; font-variant-numeric: tabular-nums;
  background: color-mix(in oklch, var(--ink) 5%, transparent); border-radius: var(--pill); padding: 1px 8px;
}
.facet { max-height: 216px; overflow: auto; padding-right: 4px; scrollbar-width: thin; }
.facet::-webkit-scrollbar, .side::-webkit-scrollbar, .facet::-webkit-scrollbar { width: 8px; }

/* ============================ Segmentos (pills seleccionables) ============================ */
.seg { display: flex; gap: 6px; flex-wrap: wrap; }
.seg button {
  border-radius: var(--pill); font-size: 12.5px; padding: 6px 12px; font-weight: 500;
  background: var(--panel-2); border-color: var(--line);
}
.seg button:hover { background: color-mix(in oklch, var(--brand) 8%, var(--panel-2)); }
.seg button.on {
  background: var(--brand); color: #fff; border-color: transparent;
  box-shadow: 0 1px 2px color-mix(in oklch, var(--brand) 40%, transparent);
}
.seg button.on:hover { background: color-mix(in oklch, var(--brand) 92%, #000); }
.seg button.needs { border-style: dashed; }

/* ============================ Listas reordenables (prioridad / desempates) ============================ */
.olist { list-style: none; margin: 0; padding: 0; }
.olist li {
  display: flex; align-items: center; gap: 8px; padding: 8px 9px;
  border: 1px solid var(--line); border-radius: var(--r-sm); margin-bottom: 6px;
  background: var(--panel-2); font-size: 13px; transition: border-color var(--fast), background var(--fast);
}
.olist li:hover { border-color: color-mix(in oklch, var(--brand) 30%, var(--line)); }
.olist li[draggable] { cursor: grab; }
.olist li.dragging { opacity: .45; }
.olist li.drag-over { border-color: var(--brand); box-shadow: inset 0 2px 0 0 var(--brand); }
.olist li .grip { color: var(--faint); cursor: grab; letter-spacing: -2px; }
.olist li .name { flex: 1; }
.olist li .arrows { display: flex; gap: 3px; }
.olist li .arrows button { padding: 3px 7px; line-height: 1; }
.olist li.dis { opacity: .5; }
/* Lista de prioridad de orden: el número marca el puesto en la cascada (1.º
   decide, 2.º rompe empates…). Solo lo llevan los criterios activos, así que se
   reserva su hueco para que las etiquetas no bailen al marcar y desmarcar. */
.olist li .onum {
  min-width: 18px; text-align: right; font-variant-numeric: tabular-nums;
  font-weight: 650; color: var(--brand); font-size: 12px;
}
.olist li.dis .onum { color: var(--faint); }
.olist li .name { cursor: pointer; }
.olist li .needsorig { font-size: 11px; color: var(--warn); white-space: nowrap; }
.dirtog { font-size: 11.5px; min-width: 78px; justify-content: center; }

/* ============================ Elección Agrupar / Mezclar ============================ */
.choices { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 6px 0 4px; }
.choices .choice {
  text-align: left; padding: 10px 12px; border-radius: var(--r-sm); line-height: 1.3;
  align-items: flex-start; flex-direction: column; gap: 0; background: var(--panel-2);
}
.choices .choice strong { display: block; font-size: 12.5px; font-weight: 600; }
.choices .choice small { display: block; margin-top: 3px; color: var(--muted); font-size: 11px; line-height: 1.4; }
.choices .choice.on { background: var(--brand-soft); border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); }
.choices .choice.on strong { color: var(--brand-ink); }
.choices .choice.on small { color: color-mix(in oklch, var(--brand-ink) 82%, var(--muted)); }

/* ============================ «details» avanzado ============================ */
.adv { margin-top: 14px; border-top: 1px solid var(--line-2); padding-top: 12px; }
.adv > summary {
  cursor: pointer; font-size: 12.5px; color: var(--brand-ink); font-weight: 600;
  list-style: none; display: inline-flex; align-items: center; gap: 6px; user-select: none;
}
.adv > summary::-webkit-details-marker { display: none; }
.adv > summary::before {
  content: ''; width: 6px; height: 6px; border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: rotate(-45deg); transition: transform var(--fast); margin-right: 1px;
}
.adv[open] > summary::before { transform: rotate(45deg); }

/* ============================ Datos precargados ============================ */
.datos-info { font-size: 13px; }
.datos-info .di-big { font-size: 27px; font-weight: 700; letter-spacing: -.02em; color: var(--ink); line-height: 1.05; }
.datos-info .di-big::after { content: ''; }
.datos-info .di-sub { color: var(--muted); font-size: 12px; margin-top: 3px; }
.datos-info .di-tipos { margin-top: 11px; display: flex; gap: 6px; flex-wrap: wrap; }

/* ============================ Toolbar de exportación ============================ */
.toolbar { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.toolbar .count { font-weight: 650; font-size: 15px; font-variant-numeric: tabular-nums; }
.toolbar .count #nRes { color: var(--brand-ink); }
.toolbar > .hint { margin-top: 0; }
.toolbar .spacer { flex: 1; }

/* ============================ Tabla de resultados ============================ */
.tablewrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel); }
/* border-collapse:separate (no collapse): así `position:sticky` en <th> funciona
   sin el desfase de Chromium que solapaba la primera fila. height:auto evita que
   se estiren las filas para rellenar un contenedor. */
table { border-collapse: separate; border-spacing: 0; width: 100%; font-size: 13px; }
tr { height: auto; }
th, td { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--line-2); white-space: nowrap; height: auto; vertical-align: middle; }
tbody tr:last-child td { border-bottom: none; }
th {
  /* Estática, no sticky: con scroll horizontal el wrapper (overflow-x) sería el
     contenedor de referencia y desplazaría la cabecera; y la tabla no debe ir en
     un contenedor de altura fija (estira las filas). Cabecera fuerte y legible. */
  background: color-mix(in oklch, var(--ink) 3%, var(--panel));
  font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--muted);
  border-bottom: 1px solid var(--line);
}
/* Celdas de texto largo (antes .wrap: colisionaba con el grid de página) */
td.cw, th.cw { white-space: normal; min-width: 180px; }
tbody tr:nth-child(even) td { background: color-mix(in oklch, var(--ink) 2.2%, transparent); }
tbody tr:hover td { background: color-mix(in oklch, var(--brand) 7%, transparent); }
td.idx { color: var(--faint); font-variant-numeric: tabular-nums; text-align: right; width: 1%; padding-right: 6px; }
/* Centinela de scroll infinito (js/app.js): fila invisible que dispara la
   carga del siguiente lote al acercarse el usuario. Sin altura ni borde. */
tr.ib-sentinel td { padding: 0; border: none; height: 1px; }

/* ---------------------- Ajuste manual del orden final ----------------------
   Último paso antes de exportar: el usuario coloca a mano las plazas que
   quiera. Tiene que verse SIEMPRE que el orden ya no es el automático, así que
   se marca en tres sitios: la fila movida, el distintivo de la barra y el
   aviso de la cabecera de resultados. */
td.man, th.man { width: 1%; white-space: nowrap; padding-left: 4px; padding-right: 4px; }
.mbtn {
  padding: 2px 5px; line-height: 1.1; font-size: 12px; min-width: 0;
  border: 1px solid var(--line); border-radius: 5px; background: var(--panel-2);
  color: var(--muted); cursor: pointer;
}
.mbtn:hover:not(:disabled) { border-color: var(--brand); color: var(--brand-ink); background: color-mix(in oklch, var(--brand) 8%, var(--panel-2)); }
.mbtn:disabled { opacity: .3; cursor: default; }
tbody tr[draggable="true"] { cursor: grab; }
tbody tr.dragging { opacity: .45; }
tbody tr.drag-over td { box-shadow: inset 0 2px 0 0 var(--brand); }
/* Fila colocada a mano: franja de color a la izquierda + etiqueta junto al nº. */
tbody tr.movida td:first-child { box-shadow: inset 3px 0 0 0 var(--brand); }
tbody tr.movida td { background: color-mix(in oklch, var(--brand) 6%, transparent) !important; }
.mtag {
  display: inline-block; margin-left: 6px; padding: 1px 5px; border-radius: 999px;
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  background: color-mix(in oklch, var(--brand) 18%, transparent); color: var(--brand-ink);
}
/* Plaza descartada: sigue en su sitio pero se retira visualmente del primer
   plano. Atenuada, en gris, con el código tachado y su etiqueta. Tiene que
   quedar claro de un vistazo que esa plaza YA NO cuenta. */
tbody tr.descartada td {
  opacity: .45; color: var(--faint);
  background: color-mix(in oklch, var(--ink) 3%, transparent) !important;
}
tbody tr.descartada .code { text-decoration: line-through; color: var(--faint); }
tbody tr.descartada .pill { filter: grayscale(1); }
/* La atenuación es uniforme en TODA la fila: dejar una celda a plena opacidad
   (p. ej. la del botón de recuperar) la convertía en un recuadro más oscuro que
   el resto, y parecía un defecto de pintado. Al pasar el ratón, la fila entera
   recupera legibilidad para poder leerla y decidir si se recupera. */
tbody tr.descartada:hover td { opacity: .9; }
.mtag.desc { background: color-mix(in oklch, var(--ink) 14%, transparent); color: var(--muted); }
.mbtn.desc:hover:not(:disabled) { border-color: var(--warn); color: var(--warn); background: color-mix(in oklch, var(--warn) 10%, var(--panel-2)); }
.mbtn.rest { color: var(--brand-ink); border-color: color-mix(in oklch, var(--brand) 40%, var(--line)); }

.badge-manual {
  display: inline-flex; align-items: center; gap: 8px; padding: 3px 6px 3px 10px;
  border: 1px solid color-mix(in oklch, var(--brand) 45%, var(--line));
  border-radius: 999px; background: color-mix(in oklch, var(--brand) 10%, transparent);
  color: var(--brand-ink); font-size: 12px;
}
.badge-manual[hidden] { display: none; }
.badge-manual .mb-txt { white-space: nowrap; }
/* En papel, los botones sobran pero la marca de «movida» debe seguir viéndose. */
@media print {
  td.man, th.man { display: none; }
  tbody tr.movida td:first-child { box-shadow: none; }
  tbody tr.movida td { background: none !important; }
  /* [RCD: en papel, una descartada no debe salir. El aviso de la propia app
     promete que «no se cuentan ni se copian, imprimen o exportan», pero al
     imprimir la página con Ctrl+P salían atenuadas (y en gris al 45 %, casi
     ilegibles) mezcladas con las buenas: justo la lista que el usuario va
     tecleando en PADDOC. El botón «Imprimir» ya excluye las descartadas. */
  tbody tr.descartada { display: none; }
}
td.prov { text-align: center; color: var(--ink-2); }
.code { font-family: var(--mono); font-weight: 600; font-size: 12.5px; color: var(--brand-ink); letter-spacing: .01em; }
.km { font-variant-numeric: tabular-nums; color: var(--muted); white-space: nowrap; }
td.cw .km { font-family: var(--mono); font-size: 11.5px; }
/* Tiempo de viaje bajo los km: es el dato que de verdad decide si una plaza es
   asumible (100 km de autovía no son 100 km de puerto de montaña). */
.km-t { display: block; font-size: 11px; color: var(--muted); opacity: .8; }

/* Pills */
.pill {
  display: inline-flex; align-items: center; font-size: 10.5px; font-weight: 600; letter-spacing: .01em;
  padding: 2px 8px; border-radius: var(--pill); border: 1px solid var(--line);
  background: color-mix(in oklch, var(--ink) 5%, transparent); color: var(--ink-2); white-space: nowrap;
}
.pill.oblig   { color: var(--danger); border-color: color-mix(in oklch, var(--danger) 32%, transparent); background: color-mix(in oklch, var(--danger) 11%, transparent); }
.pill.volu    { color: var(--ok);     border-color: color-mix(in oklch, var(--ok) 30%, transparent);     background: color-mix(in oklch, var(--ok) 11%, transparent); }
.pill.parcial { color: var(--warn);   border-color: color-mix(in oklch, var(--warn) 32%, transparent);   background: color-mix(in oklch, var(--warn) 12%, transparent); }
.pill.perf    { color: var(--perf);   border-color: color-mix(in oklch, var(--perf) 34%, transparent);   background: color-mix(in oklch, var(--perf) 12%, transparent); }
.pill.larga   { color: var(--larga);  border-color: color-mix(in oklch, var(--larga) 34%, transparent);  background: color-mix(in oklch, var(--larga) 12%, transparent); }

/* Estado vacío (diseñado, no un hueco) */
.empty {
  text-align: center; color: var(--muted); padding: 64px 24px; font-size: 13.5px; line-height: 1.6;
  text-wrap: balance; display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.empty strong { color: var(--ink-2); font-weight: 600; font-size: 14.5px; }
.empty-ico { width: 36px; height: 36px; margin-bottom: 6px; display: grid; place-items: center;
  color: var(--muted); background: color-mix(in oklch, var(--ink) 5%, transparent); border-radius: 50%; }
.empty-ico svg { width: 20px; height: 20px; }
.empty code { font-family: var(--mono); font-size: 12px; background: color-mix(in oklch, var(--ink) 6%, transparent); padding: 1px 6px; border-radius: 5px; }

.hint { font-size: 12px; color: var(--muted); margin-top: 6px; line-height: 1.5; text-wrap: pretty; }
.hint code { font-family: var(--mono); font-size: 11px; background: color-mix(in oklch, var(--ink) 6%, transparent); padding: 1px 5px; border-radius: 4px; }
.avisos { font-size: 12.5px; color: var(--warn); }

/* ============================ Avisos (banners) ============================ */
#banners { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
#banners:empty { display: none; }
.banner {
  border-radius: var(--r); padding: 11px 14px; font-size: 13px; display: flex; align-items: center; gap: 11px;
  border: 1px solid var(--line); background: var(--panel); line-height: 1.45;
  animation: banner-in .28s var(--ease) both;
}
@keyframes banner-in { from { opacity: 0; transform: translateY(-4px); } }
.banner .b-ico { flex: none; display: grid; place-items: center; width: 20px; height: 20px; }
.banner .b-ico svg { width: 18px; height: 18px; }
.banner .b-txt { flex: 1; }
.banner .b-txt strong { font-weight: 650; }
.banner .b-act { display: flex; gap: 6px; flex-wrap: wrap; }
.banner .b-act button { border-color: color-mix(in oklch, currentColor 40%, transparent); color: inherit; background: transparent; font-size: 12px; padding: 5px 10px; }
.banner .b-act button:hover { background: color-mix(in oklch, currentColor 12%, transparent); }
.banner.ok   { color: var(--ok);        background: color-mix(in oklch, var(--ok) 8%, var(--panel));     border-color: color-mix(in oklch, var(--ok) 28%, transparent); }
.banner.warn { color: var(--danger);    background: color-mix(in oklch, var(--danger) 7%, var(--panel)); border-color: color-mix(in oklch, var(--danger) 32%, transparent); }
.banner.perf { color: var(--perf);      background: color-mix(in oklch, var(--perf) 8%, var(--panel));   border-color: color-mix(in oklch, var(--perf) 30%, transparent); }
.banner.info { color: var(--brand-ink); background: var(--brand-soft);                                    border-color: color-mix(in oklch, var(--brand) 24%, transparent); }
.banner.ok .b-txt, .banner.warn .b-txt, .banner.perf .b-txt, .banner.info .b-txt { color: var(--ink); }
.banner.ok .b-txt strong, .banner.warn .b-txt strong, .banner.perf .b-txt strong, .banner.info .b-txt strong { color: currentColor; }

/* ============================ Diálogos ============================ */
dialog {
  border: none; border-radius: var(--r); padding: 0; max-width: 620px; width: 92%;
  box-shadow: var(--sh-pop); background: var(--panel); color: var(--ink);
}
dialog[open] { animation: dlg-in .22s var(--ease) both; }
@keyframes dlg-in { from { opacity: 0; transform: translateY(8px) scale(.985); } }
dialog::backdrop { background: color-mix(in oklch, var(--ink) 55%, transparent); backdrop-filter: blur(2px); }
.dlg-h { padding: 15px 18px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 8px; }
.dlg-h h3 { font-size: 15px; }
.dlg-b { padding: 16px 18px; }
textarea {
  width: 100%; min-height: 190px; font-family: var(--mono); font-size: 12.5px; line-height: 1.6;
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 12px; background: var(--panel-2);
  color: var(--ink); resize: vertical;
}

/* ============================ Toast ============================ */
.toast {
  position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%) translateY(8px);
  background: var(--ink); color: var(--bg); padding: 10px 18px; border-radius: 10px;
  box-shadow: var(--sh-pop); z-index: 60; opacity: 0; transition: opacity var(--mid), transform var(--mid);
  pointer-events: none; font-size: 13px; font-weight: 500;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ============================ Asistente PADDOC ============================ */
#wiz { max-width: 680px; }
.wiz-b { padding: 16px 18px; }
.wiz-progress { display: flex; align-items: center; gap: 12px; margin-bottom: 15px; }
.wiz-bar { flex: 1; height: 8px; border-radius: var(--pill); background: color-mix(in oklch, var(--ink) 8%, transparent); overflow: hidden; }
.wiz-bar span { display: block; height: 100%; width: 0; border-radius: var(--pill); background: var(--brand); transition: width var(--mid); }
.wiz-count { font-size: 12.5px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.wiz-count strong { color: var(--brand-ink); font-size: 15px; }
.wiz-current {
  border: 1px solid var(--brand); background: var(--brand-soft); border-radius: var(--r);
  padding: 14px 16px; margin-bottom: 14px; transition: border-color var(--mid), background var(--mid);
}
.wiz-current.done { border-color: color-mix(in oklch, var(--ok) 55%, transparent); background: color-mix(in oklch, var(--ok) 9%, var(--panel)); }
.wiz-c-lab { font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.wiz-c-code { font-family: var(--mono); font-size: 32px; font-weight: 700; color: var(--brand-ink); letter-spacing: .01em; margin: 3px 0 5px; line-height: 1; }
.wiz-current.done .wiz-c-code { color: var(--ok); font-size: 24px; }
.wiz-c-meta { font-size: 12.5px; color: var(--muted); margin-bottom: 12px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.wiz-c-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.wiz-c-actions button { padding: 9px 16px; font-size: 14px; }
.wiz-list { max-height: 44vh; overflow: auto; border: 1px solid var(--line); border-radius: var(--r-sm); scrollbar-width: thin; }
.wiz-row { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-bottom: 1px solid var(--line-2); font-size: 13px; cursor: pointer; transition: background var(--fast); }
.wiz-row:last-child { border-bottom: none; }
.wiz-row:hover { background: color-mix(in oklch, var(--brand) 6%, transparent); }
.wiz-row.is-done { opacity: .5; }
.wiz-row.is-next { background: var(--brand-soft); box-shadow: inset 3px 0 0 var(--brand); }
.wiz-row .wr-n { color: var(--faint); font-variant-numeric: tabular-nums; min-width: 30px; }
.wiz-row .wr-code { font-family: var(--mono); font-weight: 600; color: var(--brand-ink); min-width: 56px; }
.wiz-row.is-done .wr-code { text-decoration: line-through; }
.wiz-row .wr-info { flex: 1; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wiz-row input { width: 17px; height: 17px; accent-color: var(--brand); flex: none; }

/* ============================ Puerta de acceso (licencia) ============================ */
html.gate-locked body > *:not(#gate) { filter: blur(7px); pointer-events: none; user-select: none; }
#gate {
  position: fixed; inset: 0; z-index: 1000; padding: 20px;
  display: grid; place-items: center;
  background: color-mix(in oklch, var(--bg) 68%, rgba(10,14,22,.55));
  animation: gate-in .3s var(--ease) both;
}
@keyframes gate-in { from { opacity: 0; } }
.gate-card {
  width: 100%; max-width: 388px; background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  padding: 30px 26px; box-shadow: var(--sh-pop); text-align: center;
  animation: dlg-in .3s var(--ease) both;
}
.gate-logo {
  width: 46px; height: 46px; border-radius: 13px; margin: 0 auto 14px; font-size: 23px; color: #fff;
  display: grid; place-items: center;
  background: linear-gradient(150deg, color-mix(in oklch, var(--brand) 88%, white), var(--brand) 55%, color-mix(in oklch, var(--brand) 78%, #101a4a));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), var(--sh-1);
}
.gate-card h2 { font-size: 19px; }
.gate-sub { color: var(--muted); font-size: 13px; margin: 7px 0 18px; line-height: 1.55; text-wrap: pretty; }
.gate-lbl { display: block; text-align: left; font-size: 12px; font-weight: 500; color: var(--ink-2); margin: 12px 0 5px; }
.gate-card input { width: 100%; }
.gate-btn {
  width: 100%; margin-top: 18px; padding: 11px; font-size: 15px; font-weight: 600; justify-content: center;
  background: var(--brand); color: #fff; border-color: transparent;
  box-shadow: 0 1px 2px color-mix(in oklch, var(--brand) 45%, transparent), inset 0 1px 0 rgba(255,255,255,.18);
}
.gate-btn:hover { background: color-mix(in oklch, var(--brand) 92%, #000); color: #fff; }
.gate-btn:disabled { opacity: .6; }
.gate-msg { min-height: 18px; font-size: 12.5px; margin-top: 12px; color: var(--muted); }
.gate-msg.err { color: var(--danger); }
.gate-foot { margin-top: 18px; font-size: 11.5px; color: var(--muted); line-height: 1.7; }

/* ============================ Movimiento reducido ============================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}

/* ============================ Impresión ============================ */
@media print {
  .top, .side, .toolbar, #banners, .badge-priv { display: none !important; }
  .layout { display: block; }
  .main { padding: 0; }
  #resultado { break-inside: auto; }
  .tablewrap { border: none; }
  th { position: static; box-shadow: none; }
  a[href]::after { content: ''; }
}
