/* Componentes reutilizables: paneles, botones, tablas, badges, formularios. */

/* Paneles */
.panel {
  scroll-margin-top: 90px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  box-shadow: var(--shadow);
  min-width: 0;
}

.panel__title {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin-bottom: var(--space-3);
}

/*
 * Fila de cabecera título + acciones. La última acción siempre se ancla al
 * borde derecho con margin-left:auto (no con justify-content:space-between):
 * así, si la fila se parte en dos líneas en pantallas estrechas, el botón
 * sigue flush a la derecha en vez de "caer" a la izquierda al quedar solo
 * en su línea (bug real de flexbox con space-between + wrap).
 */
.panel__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
}

.panel__head > :last-child {
  margin-left: auto;
}

.panel__head .panel__title {
  margin-bottom: var(--space-2);
}

/* Paneles plegables (js/ui/collapsible.js) */
.panel__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.panel--collapsible > .panel__head {
  flex-wrap: nowrap;
}

.panel--collapsible > .panel__head .panel__title {
  margin-bottom: 0;
}

.panel--collapsible > .panel__body {
  margin-top: var(--space-3);
}

.panel.is-collapsed {
  padding-block: var(--space-3);
}

.panel__toggle {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  color: var(--text-muted);
  cursor: pointer;
  line-height: 1;
  transition: color 0.15s, border-color 0.15s;
}

.panel__toggle:hover {
  color: var(--text);
  border-color: var(--accent);
}

.panel__toggle-icon {
  transition: transform 0.2s;
}

.panel.is-collapsed .panel__toggle-icon {
  transform: rotate(-90deg);
}

/* Cabecera de laboratorio */
.lab__header,
.intro__hero {
  padding: var(--space-2) 0;
}

.lab__header h2,
.intro__hero h2 {
  font-size: clamp(1.4rem, 2.4vw, 1.9rem);
  margin-bottom: var(--space-2);
}

.lab__summary {
  max-width: 85ch;
  font-size: 1.02rem;
  color: var(--text-soft);
}

.eyebrow {
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 0.75rem;
  font-weight: 700;
  margin-bottom: var(--space-2);
}

/* Botones */
.btn {
  border: 1px solid var(--border-strong);
  background: var(--panel-2);
  border-radius: var(--radius-sm);
  padding: 7px 12px;
  cursor: pointer;
  font-weight: 550;
  transition: background 0.15s, border-color 0.15s, transform 0.05s;
}

.btn:hover:not(:disabled) {
  border-color: var(--accent);
}

.btn:active:not(:disabled) {
  transform: translateY(1px);
}

.btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

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

.btn--primary:hover:not(:disabled) {
  filter: brightness(1.1);
}

.btn--ghost {
  background: transparent;
}

.btn--sm {
  padding: 4px 10px;
  font-size: 0.85rem;
}

.btn--preset {
  text-align: left;
  font-size: 0.88rem;
  width: 100%;
}

.btn--ctrl {
  min-width: 40px;
  font-family: var(--font-mono);
}

.icon-btn {
  border: 1px solid transparent;
  background: transparent;
  border-radius: 4px;
  width: 24px;
  height: 24px;
  cursor: pointer;
  color: var(--text-muted);
  line-height: 1;
}

.icon-btn:hover:not(:disabled) {
  background: var(--panel-2);
  color: var(--text);
}

.icon-btn:disabled {
  opacity: 0.25;
  cursor: default;
}

.icon-btn--danger:hover:not(:disabled) {
  color: var(--drop);
}

/* Badges */
.badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--panel-2);
  border: 1px solid var(--border-strong);
  color: var(--text-muted);
  white-space: nowrap;
}

.badge--nat {
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 40%, transparent);
  background: var(--warn-soft);
  margin-right: 4px;
}

/* Tablas */
.table-scroll {
  overflow-x: auto;
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}

.table th {
  text-align: left;
  font-weight: 600;
  color: var(--text-muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.table td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

.table--compact td,
.table--compact th {
  padding: 4px 6px;
}

/* Formularios */
input[type='text'],
input[type='number'],
select {
  background: var(--bg-elev);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 5px 8px;
  min-width: 0;
  width: 100%;
}

input:disabled,
select:disabled {
  opacity: 0.5;
}

input.is-invalid {
  border-color: var(--drop);
  background: var(--drop-soft);
}

input[type='checkbox'] {
  accent-color: var(--accent);
  width: 16px;
  height: 16px;
}

.field-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.field {
  display: grid;
  gap: 2px;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.field:first-child {
  grid-column: 1 / -1;
}

.form-error {
  color: var(--drop);
  font-size: 0.85rem;
  min-height: 1em;
  margin: 0 0 var(--space-2);
}

/* Panel de envío */
.presets__head {
  margin: 0;
  padding: var(--space-1) 0 var(--space-2);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-soft);
}

.presets {
  display: grid;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.custom {
  border-top: 1px solid var(--border);
  padding-top: var(--space-3);
}

.custom summary {
  cursor: pointer;
  color: var(--accent);
  font-weight: 600;
}

.custom[open] summary {
  margin-bottom: var(--space-3);
}

.panel__hint {
  margin: 0 0 var(--space-3);
}

.challenges ol:not(.challenges__list) {
  margin: 0;
  padding-left: 1.3em;
  display: grid;
  gap: var(--space-2);
  font-size: 0.9rem;
  color: var(--text-soft);
}

/* Reproductor */
.player {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
}

.player__counter {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-left: var(--space-2);
}

.player__speed-label {
  margin-left: auto;
  font-size: 0.85rem;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.player__speed {
  width: auto;
}

.stage-caption {
  /* Alto fijo de dos líneas: si el texto cambia de largo, el escenario (y las
     columnas que se igualan a él) no salta. El texto completo está en el detalle. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  box-sizing: content-box;
  height: 2.8em;
  line-height: 1.4;
  margin: var(--space-2) 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  border-left: 3px solid var(--border-strong);
  font-weight: 550;
}

.stage-caption__node {
  color: var(--text-muted);
  font-weight: 600;
  margin-right: 4px;
}

.stage-caption.is-ok { border-left-color: var(--ok); }
.stage-caption.is-warn { border-left-color: var(--warn); }
.stage-caption.is-drop { border-left-color: var(--drop); background: var(--drop-soft); }

/* Barra de pipeline */
.pipe {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  flex-wrap: wrap;
}

.pipe__router {
  font-weight: 650;
  font-size: 0.9rem;
  min-width: 150px;
  color: var(--accent);
}

.pipe.is-idle .pipe__router {
  color: var(--text-muted);
  font-weight: 500;
}

.pipe__flow {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: 1;
  flex-wrap: wrap;
}

.pipe__group {
  display: flex;
  gap: 4px;
}

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

.pipe__stage {
  display: grid;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 3px 8px;
  background: var(--bg-elev);
  line-height: 1.2;
  transition: all 0.2s;
  opacity: 0.6;
}

.pipe__stage strong {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--text-muted);
}

.pipe__stage small {
  font-size: 0.66rem;
  color: var(--text-dim);
}

.pipe__stage.is-visited {
  opacity: 1;
  border-color: var(--border-strong);
}

.pipe__stage.is-visited strong {
  color: var(--text);
}

.pipe__stage.is-active {
  opacity: 1;
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.pipe__stage.is-active strong {
  color: var(--accent);
}

.pipe__stage.is-drop {
  border-color: var(--drop);
  background: var(--drop-soft);
}

.pipe__stage.is-drop strong {
  color: var(--drop);
}

/* Traza */
.trace-wrap {
  max-height: 460px;
  overflow-y: auto;
}

.trace {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
}

.trace__btn {
  width: 100%;
  display: grid;
  /* Columnas fijas (icono | equipo | fase | paso): todo queda tabulado. */
  grid-template-columns: 22px 128px 112px minmax(0, 1fr);
  align-items: center;
  gap: var(--space-2);
  text-align: left;
  border: 1px solid transparent;
  background: transparent;
  border-radius: var(--radius-sm);
  padding: 5px 8px;
  cursor: pointer;
  font-size: 0.86rem;
}

.trace__btn:hover {
  background: var(--panel-2);
}

.trace__icon {
  text-align: center;
  color: var(--text-muted);
}

.trace__node {
  color: var(--text-muted);
  font-size: 0.78rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.trace__item.is-future {
  opacity: 0.38;
}

.trace__item.is-current .trace__btn {
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}

.trace__item.is-ok .trace__icon { color: var(--ok); }
.trace__item.is-warn .trace__icon { color: var(--warn); }
.trace__item.is-drop .trace__icon,
.trace__item.is-drop .trace__title { color: var(--drop); }
.trace__item.kind-encap .trace__icon,
.trace__item.kind-decap .trace__icon { color: var(--vpn); }
.trace__item.kind-result .trace__title { font-weight: 700; }

/* Inspector */
.inspector__title {
  font-size: 1rem;
  margin-bottom: var(--space-2);
}

.inspector__title.is-ok { color: var(--ok); }
.inspector__title.is-warn { color: var(--warn); }
.inspector__title.is-drop { color: var(--drop); }

.inspector__detail {
  margin: var(--space-2) 0 0;
  color: var(--text-soft);
  font-size: 0.9rem;
}

.inspector__caption {
  font-size: 0.72rem;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: var(--space-2) 0 var(--space-1);
}

.evals__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 2px;
}

/* Una regla por línea: marca | número | motivo · regla (se corta). */
.evals__item {
  display: grid;
  grid-template-columns: 12px 24px minmax(0, 1fr);
  column-gap: var(--space-1);
  align-items: baseline;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  background: var(--bg-elev);
  border: 1px solid var(--border);
  font-size: 0.78rem;
}

.evals__mark {
  color: var(--text-dim);
  font-weight: 700;
}

.evals__num {
  font-family: var(--font-mono);
  color: var(--text-muted);
}

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

.evals__why {
  color: var(--text-soft);
}

.evals__rule {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--text-dim);
}

.evals__item.is-match {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.evals__item.is-match .evals__mark,
.evals__item.is-match .evals__why {
  color: var(--accent);
}

/* Pestañas del panel Detalle (Paso · Estado · Internet). */
.detail__tabs {
  display: inline-flex;
  gap: 1px;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--panel-2);
}

.detail__tab {
  position: relative;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-size: 0.74rem;
  font-weight: 600;
  padding: 3px 7px;
  border-radius: 999px;
  cursor: pointer;
}

.detail__tab:hover {
  color: var(--text);
}

.detail__tab[aria-selected='true'] {
  background: var(--panel);
  color: var(--accent);
  box-shadow: 0 0 0 1px var(--border);
}


.detail__pane > .muted.small:first-child,
.detail__pane > .muted.small {
  margin-top: 0;
}



/* Tabla de estado compacta: una tarjeta mínima por conexión. */
.ct {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 4px;
}

.ct__entry {
  padding: 4px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-elev);
  font-size: 0.8rem;
}

.ct__head {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-bottom: 2px;
}

.ct__id {
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--text-muted);
}

.ct__row {
  display: grid;
  /* Ancho de la etiqueta más larga («vuelta») + hueco: nunca se corta. */
  grid-template-columns: 44px minmax(0, 1fr);
  column-gap: 4px;
  align-items: baseline;
}

.ct__dir {
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0;
  color: var(--text-dim);
}

.ct__row code {
  font-size: 0.7rem;
  padding-inline: 2px;
}

.ct__tuple > span {
  white-space: nowrap;
}


/* Captura */
.capture__list {
  margin: 0;
  padding-left: 1.4em;
  display: grid;
  gap: var(--space-2);
}

.capture__item {
  display: grid;
  gap: 2px;
}

.capture__hdr {
  width: fit-content;
  max-width: 100%;
  font-size: 0.76rem;
  overflow-wrap: anywhere;
}

.capture__data {
  font-size: 0.84rem;
  color: var(--warn);
}

.capture__item.is-encrypted .capture__data {
  color: var(--vpn);
  font-family: var(--font-mono);
}

/* Conntrack */
/* Pestaña Estado: cabecera compacta, nota breve y la tabla por router. */
.state__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.state__title {
  margin: 0;
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}

.state__clear {
  margin-left: auto;
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text-muted);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 0.74rem;
  font-weight: 600;
  cursor: pointer;
}

.state__clear:hover {
  color: var(--text);
  border-color: var(--accent);
}

/* Reloj del lab: una fila bajo la cabecera con el tiempo y los botones para avanzarlo. */
.state__time {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: var(--space-1);
}

.state__clock {
  margin-right: auto;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--text-muted);
}

.state__tick {
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text-muted);
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 0.72rem;
  font-weight: 600;
  cursor: pointer;
}

.state__tick:hover {
  color: var(--text);
  border-color: var(--accent);
}

.state__expired {
  margin: var(--space-1) 0 0;
  font-size: 0.76rem;
  color: var(--warn);
}

.ct__ttl {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--text-muted);
  white-space: nowrap;
}

.ct__ttl.is-soon {
  color: var(--warn);
}

.state__note {
  margin: var(--space-1) 0 var(--space-3);
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--text-muted);
}

.conntrack__router {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-3) 0 var(--space-1);
  font-size: 0.82rem;
  font-weight: 650;
  color: var(--text-strong);
}

.conntrack__router:first-child {
  margin-top: 0;
}

.conntrack__count {
  min-width: 18px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  font-size: 0.7rem;
  font-weight: 600;
  text-align: center;
  color: var(--text-muted);
}

.ct__empty {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  font-size: 0.8rem;
  color: var(--text-muted);
}



/* Introducción */
.intro__section p {
  max-width: 80ch;
}

.ranges {
  display: flex;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-3);
  flex-wrap: wrap;
}

.flow {
  --flow-gap: 28px;
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-3);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--flow-gap);
}

.flow__step {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4);
}

/* Flecha que conecta cada etapa con la siguiente */
.flow__step:not(:last-child)::after {
  content: '→';
  position: absolute;
  top: 50%;
  right: calc(var(--flow-gap) / -2);
  transform: translate(50%, -50%);
  color: var(--accent);
  font-weight: 700;
  font-size: 1.1rem;
}

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

.flow__num {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font: 700 0.8rem var(--font-mono);
}

.flow__name {
  font: 700 0.95rem var(--font-mono);
  color: var(--text-strong);
}

.flow__tags {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0;
  padding: 0;
}

.flow__text {
  margin: 0;
  font-size: 0.9rem;
  color: var(--text-soft);
  line-height: 1.5;
}

.howto {
  display: grid;
  gap: var(--space-2);
  padding-left: 1.3em;
  margin: 0 0 var(--space-4);
}

@container main (max-width: 952px) {
  .flow {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .flow__step:nth-child(2)::after {
    content: none;
  }
}

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

  .flow__step:not(:last-child)::after {
    content: '↓';
    top: auto;
    right: 50%;
    bottom: calc(var(--flow-gap) / -2);
    transform: translate(50%, 50%);
  }
}

/* Introducción: fabricante activo y comparativa */
.intro__vendor {
  max-width: 85ch;
  padding: var(--space-2) var(--space-3);
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
  border-radius: var(--radius-sm);
}

.table--vendors tr.is-current td {
  background: var(--accent-soft);
}

.table--vendors tr.is-current td:first-child {
  box-shadow: inset 3px 0 0 var(--accent);
}

.badge--current {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-soft);
}

/* Nota del fabricante simulado */
.vendor-note {
  margin-top: var(--space-3);
  max-width: 110ch;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
}

.vendor-note__title {
  margin-bottom: var(--space-2);
  color: var(--text-soft);
}

.vendor-note ul {
  margin: 0 0 var(--space-2);
  padding-left: 1.2em;
  display: grid;
  gap: var(--space-1);
}

.vendor-note p:last-child {
  margin: 0;
}

.badge--hint {
  margin-left: 4px;
  color: var(--text-dim);
  border-style: dashed;
}

/* Cabecera de laboratorio: texto + diagrama conceptual */
.lab__header {
  display: grid;
  gap: var(--space-4);
  justify-items: start;
}

.lab__heading {
  margin: 0;
}

.lab__header > .lab__summary {
  margin: 0;
  max-width: 75ch;
  font-size: 1.08rem;
  line-height: 1.6;
}

/* Dos tarjetas hermanas, misma altura, misma cabecera (eyebrow + título). */
.lab__intro-grid {
  justify-self: stretch;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: var(--space-4);
  align-items: stretch;
}

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

.lab__concepts,
.lab__intro-grid > .concept {
  display: flex;
  flex-direction: column;
  margin: 0;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  box-shadow: var(--shadow);
}

.lab__intro-grid .concept__caption {
  margin-bottom: var(--space-3);
}

/* El diagrama se centra en el alto que deja la tarjeta de conceptos. */
.lab__intro-grid > .concept .concept__art {
  flex: 1;
  display: grid;
  align-content: center;
}

/* Conceptos: lista con marcador y divisores finos dentro de la tarjeta. */
.lab__points {
  list-style: none;
  margin: 0 0 var(--space-3);
  padding: 0;
}

.lab__points li {
  position: relative;
  padding: var(--space-2) 0 var(--space-2) var(--space-5);
  color: var(--text-soft);
}

.lab__points li + li {
  border-top: 1px solid var(--border);
}

.lab__points li::before {
  content: '';
  position: absolute;
  left: 4px;
  top: calc(var(--space-2) + 0.62em);
  width: 7px;
  height: 7px;
  border-radius: 2px;
  background: var(--accent);
}

/* Pie de la tarjeta (fabricante + límites): pegado abajo, separado por divisores, no otra caja. */
.lab__concepts-foot {
  margin-top: auto;
  display: grid;
}

.lab__concepts .vendor-note {
  max-width: none;
  margin: 0;
  padding: var(--space-3) 0 0;
  background: none;
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
}

.lab__concepts .vendor-note__title {
  margin: 0;
  font-size: 0.9rem;
}

.lab__concepts .vendor-note ul {
  margin-top: var(--space-2);
  font-size: 0.92rem;
}

/* «Para profundizar»: desplegable dentro de la tarjeta de conceptos. */
.lab__deeper {
  margin: 0 0 var(--space-3);
}

.lab__deeper > summary {
  cursor: pointer;
  color: var(--accent);
  font-weight: 600;
  font-size: 0.92rem;
}

.lab__deeper[open] > summary {
  margin-bottom: var(--space-1);
}

/* Objetivos: una línea de lectura entre la entradilla y las tarjetas. */
.lab__goals-wrap {
  display: grid;
  gap: var(--space-1);
  max-width: 110ch;
}

.lab__goals-wrap .eyebrow {
  margin: 0;
}

.lab__goals {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-5);
  color: var(--text-soft);
  font-size: 0.95rem;
}

.lab__goals li {
  position: relative;
  padding-left: 1.4em;
  flex: 1 1 260px;
}

.lab__goals li::before {
  content: '✓';
  position: absolute;
  left: 0;
  color: var(--ok);
  font-weight: 700;
}

/* Retos: pregunta + solución plegada. */
.challenges__list {
  margin: 0;
  padding-left: 1.3em;
  display: grid;
  gap: var(--space-3);
  font-size: 0.9rem;
  color: var(--text-soft);
}

.challenges__q {
  margin: 0;
}

.challenges__a {
  margin-top: var(--space-1);
}

.challenges__a > summary {
  cursor: pointer;
  color: var(--accent);
  font-weight: 600;
  font-size: 0.85rem;
}

.challenges__a > p {
  margin: var(--space-1) 0 0;
  padding-left: var(--space-3);
  border-left: 2px solid var(--ok);
}

/* Cierre del laboratorio: dos tarjetas hermanas, como la cabecera. */
.lab__wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: var(--space-4);
  align-items: stretch;
}

.diag {
  margin: 0;
  display: grid;
  gap: var(--space-1);
}

.diag dt {
  margin-top: var(--space-2);
}

.diag dt:first-child {
  margin-top: 0;
}

.diag dt code {
  display: block;
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 0.8rem;
}

.diag dd {
  margin: 0;
  color: var(--text-soft);
  font-size: 0.88rem;
}

/* Introducción: listas de campos y glosario. */
.intro__fields {
  margin: var(--space-3) 0 0;
  padding-left: 1.2em;
  display: grid;
  gap: var(--space-1);
  color: var(--text-soft);
  font-size: 0.92rem;
}

.glossary {
  margin: 0;
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: var(--space-2) var(--space-4);
  font-size: 0.9rem;
}

.glossary dt {
  font-weight: 650;
  color: var(--text-strong);
}

.glossary dd {
  margin: 0;
  color: var(--text-soft);
}

@container main (max-width: 1032px) {
  .lab__intro-grid,
  .lab__wrap {
    grid-template-columns: minmax(0, 1fr);
  }
}

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

  .glossary dd {
    margin-bottom: var(--space-2);
  }
}

/* Comparativa de fabricantes: tabla y diagrama lado a lado en pantallas anchas */
.intro__compare {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
}

.intro__compare .concept {
  margin-top: 0;
}

@container main (max-width: 1152px) {
  .intro__compare {
    grid-template-columns: minmax(0, 1fr);
  }

  .intro__compare .concept {
    margin-top: var(--space-3);
  }
}

/* Figura conceptual */
.concept {
  margin: 0;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4) var(--space-4);
  box-shadow: var(--shadow);
}

.intro__section .concept {
  margin-top: var(--space-3);
  background: var(--bg-elev);
  box-shadow: none;
}

.concept__caption {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-bottom: var(--space-2);
}

.concept__caption .eyebrow {
  margin: 0;
}

.concept__title {
  font-weight: 650;
  color: var(--text-strong);
}

/* Leyenda del paquete */
.legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin: var(--space-2) 0 0;
  padding: 0;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.legend__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.legend__swatch {
  width: 18px;
  height: 11px;
  border-radius: 3px;
  background: var(--request);
}

.legend__swatch--reply { background: var(--reply); }
.legend__swatch--nat { background: var(--warn); }
.legend__swatch--vpn { background: var(--vpn); }
.legend__swatch--ok { background: var(--ok); }
.legend__swatch--drop { background: var(--drop); }

/* Primer escenario sugerido */
.btn--preset.is-suggested {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-2);
}

.preset__hint {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--on-accent);
  background: var(--accent);
  border-radius: 999px;
  padding: 1px 8px;
  white-space: nowrap;
}


.lab__start {
  scroll-margin-top: 90px;
}

.lab__start:focus {
  outline: none;
}

.vendor-note > summary {
  cursor: pointer;
}

.vendor-note[open] > summary {
  margin-bottom: var(--space-2);
}

/*
 * Paginador anterior/siguiente: el mismo al final de la introducción y de
 * cada laboratorio, para que ninguna página tenga un botón de cierre
 * distinto a las demás. El grupo derecho se ancla con margin-left:auto
 * (no con justify-content:space-between: ver la nota en .panel__head) para
 * que "Siguiente" quede flush a la derecha aunque la fila se parta en dos
 * líneas en pantallas estrechas.
 */
.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  padding-top: var(--space-2);
}

.pager__prev,
.pager__next,
.pager__top {
  text-decoration: none;
}

.pager__right {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  margin-left: auto;
}

/* Hero de la introducción: titular grande a la izquierda, fabricante a la derecha */
.intro__hero {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5);
  align-items: stretch;
  padding: var(--space-6);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(circle at 0% 0%, color-mix(in srgb, var(--accent) 18%, transparent), transparent 55%),
    var(--panel);
  box-shadow: var(--shadow);
}

.intro__hero-main {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-3);
}

.intro__hero-main .eyebrow,
.intro__hero-side .eyebrow {
  margin: 0;
}

.intro__hero h2 {
  margin: 0;
  font-size: clamp(2rem, 3.6vw, 3.4rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
}

.intro__hero-accent {
  color: var(--accent);
}

.intro__lede {
  margin: 0;
  max-width: 46ch;
  font-size: clamp(1.05rem, 1.5vw, 1.3rem);
  color: var(--text-soft);
}

/* Ruta sugerida: tres peldaños, de los fundamentos a lo avanzado. */
.intro__path {
  display: grid;
  gap: var(--space-2);
  margin: var(--space-2) 0 0;
  padding: 0;
  list-style: none;
}

.intro__path-step {
  display: grid;
  grid-template-columns: auto 7.2rem 1fr;
  align-items: center;
  gap: var(--space-2);
}

.intro__path-num {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.78rem;
  font-weight: 700;
}

.intro__path-title {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}

.intro__path-labs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-2);
}

@media (max-width: 520px) {
  .intro__path-step {
    grid-template-columns: auto 1fr;
  }

  .intro__path-labs {
    grid-column: 1 / -1;
  }
}

.intro__hero-side {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-6);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: var(--radius);
  background: var(--accent-soft);
}

.intro__hero-side .intro__vendor {
  margin: 0;
  padding: 0;
  max-width: none;
  border-left: 0;
  background: none;
}

@container main (max-width: 812px) {
  .intro__hero {
    grid-template-columns: 1fr;
    padding: var(--space-5);
  }
}

.intro__stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-3);
  margin: var(--space-3) 0 0;
  padding: var(--space-3) 0 0;
  border-top: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  list-style: none;
}

.intro__stats li {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.intro__stats strong {
  font-size: 1.8rem;
  line-height: 1;
  color: var(--accent);
}

.intro__stats span {
  font-size: 0.78rem;
  color: var(--text-muted);
}

.intro__hero-side .intro__vendor {
  font-size: 1.05rem;
}

.intro__stats strong {
  font-size: 2.4rem;
}

.intro__subtitle {
  margin: var(--space-3) 0 0;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.intro > .grid--two {
  align-items: stretch;
}

/* Diálogo «Reiniciar» (js/ui/reset-menu.js) */
.reset {
  width: min(26rem, calc(100vw - 32px));
  padding: var(--space-4) var(--space-4) var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
  color: var(--text);
  box-shadow: var(--shadow);
}

.reset::backdrop {
  background: rgb(0 0 0 / 0.45);
}

.reset__title {
  margin: 0;
  font-size: 1.1rem;
}

.reset__lead {
  margin: 2px 0 var(--space-3);
  font-size: 0.88rem;
  color: var(--text-muted);
}

.reset__cards {
  display: grid;
  gap: var(--space-2);
}

/* Cada opción: icono · qué reinicia (título) y qué conserva (explicación). */
.reset__card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s, background-color 0.15s;
}

.reset__card:hover:not(:disabled) {
  border-color: var(--accent);
  background: var(--accent-soft);
}

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

.reset__card:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

/* Reiniciarlo todo es más drástico: se distingue con el color de aviso. */
.reset__card--wide:hover:not(:disabled) {
  border-color: var(--warn);
  background: var(--warn-soft);
}

.reset__icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--panel);
  color: var(--accent);
  font-size: 1.15rem;
  line-height: 1;
}

.reset__card--wide .reset__icon {
  color: var(--warn);
}

.reset__text {
  display: grid;
  gap: 2px;
}

.reset__label {
  font-size: 0.95rem;
  font-weight: 650;
}

.reset__hint {
  font-size: 0.8rem;
  line-height: 1.4;
  color: var(--text-muted);
}

.reset__foot {
  display: flex;
  margin: var(--space-3) 0 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
}

.reset__foot > :last-child {
  margin-left: auto;
}

/*
 * Conexión que trata el paso actual, aunque ya existiera de antes (acento):
 * es a la que se hace scroll. Si además se creó justo en este paso, gana el
 * ámbar de "nueva" — por eso esta regla va primero y la de abajo después.
 */
.ct__entry.is-current {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}

.ct__entry.is-new {
  border-color: var(--warn);
  box-shadow: 0 0 0 2px var(--warn-soft);
}

/* Pestaña Reglas: el título del paso y la lista, pegados para que quepan. */
.inspector--rules .inspector__caption {
  margin-top: 2px;
}

/*
 * Niveles del simulador (js/ui/lab-view.js):
 *   1 · Dónde está el paquete (escenario)  2 · Qué pasa en el equipo
 *   3 · Cómo va el paquete. Un número en círculo marca el orden de lectura.
 */
.level {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.level__num {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.75rem;
  font-weight: 700;
}

.level__title {
  margin: 0;
  white-space: nowrap;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}

.level > .detail__tabs {
  margin-left: auto;
}

.level-block + .level-block {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
}

.inspector--step .inspector__detail {
  margin-top: var(--space-1);
  /* Igual que las viñetas de .step-bullets: una frase suelta no debe verse mayor que varias. */
  font-size: 0.74rem;
  line-height: 1.35;
}

/* Recorrido completo dentro del escenario, bajo los controles (línea de tiempo). */
.stage__trace {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
}

.stage__trace-title {
  margin: 0 0 var(--space-1);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}

.panel--stage .trace-wrap {
  /* Alto fijo: el escenario (y las columnas que se igualan a él) no cambia
     de tamaño según cuántos pasos tenga el recorrido. */
  height: 172px;
  max-height: none;
}

/* Etapas del equipo en vertical (nivel 2): se leen de arriba abajo. */
.panel--device .pipe {
  position: relative;
  display: block;
  margin: 0 0 var(--space-2);
}

.panel--device .pipe__router {
  display: none;
}

/* Fuera de un router: el aviso se superpone a las etapas atenuadas, así el
   bloque mide lo mismo y el nivel 3 no se mueve. */
.panel--device .pipe.is-idle .pipe__router {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  min-width: 0;
  padding: 0 var(--space-4);
  text-align: center;
  font-size: 0.84rem;
  font-weight: 500;
  color: var(--text-soft);
  background: color-mix(in srgb, var(--panel) 72%, transparent);
  border-radius: var(--radius-sm);
}

.panel--device .pipe.is-idle .pipe__flow {
  opacity: 0.4;
}

.panel--device .pipe__flow {
  flex-direction: column;
  align-items: stretch;
  flex-wrap: nowrap;
  gap: 0;
}

.panel--device .pipe__sep {
  align-self: center;
  font-size: 0.7rem;
  line-height: 0.75;
  transform: rotate(90deg);
}

.panel--device .pipe__group {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px;
}

.panel--device .pipe__stage {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: 1px 8px;
  min-width: 0;
  line-height: 1.25;
}

.panel--device .pipe__stage small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.panel--device .pipe__group .pipe__stage {
  display: grid;
  gap: 0;
}

/* Nivel 2: una sola línea fija (nombre del equipo + puertas), para que el
   bloque no cambie de alto entre pasos. El nombre se corta si no cabe. */
.panel--device .level-block:first-child > .level {
  flex-wrap: nowrap;
  min-height: 22px;
}

.level__title--device {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.level__ports {
  display: inline-flex;
  flex: none;
  gap: var(--space-1);
  margin-left: auto;
}

.port-badge {
  padding: 0 7px;
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--on-accent);
}

.port-badge.is-in {
  background: var(--accent);
}

.port-badge.is-out {
  background: var(--warn);
}

/* Aviso breve al recalcular la simulación tras cambiar reglas. */
.stage__trace-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
}

.rerun-note {
  margin-left: auto;
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--accent);
  animation: rerun-in 0.25s ease-out;
}

@keyframes rerun-in {
  from { opacity: 0; transform: translateY(-2px); }
  to { opacity: 1; transform: none; }
}

.port-badge.is-pending {
  background: none;
  color: var(--text-muted);
  border: 1px dashed var(--border-strong);
}

.port-badge.is-local {
  background: var(--panel-2);
  color: var(--text-soft);
  border: 1px solid var(--border-strong);
}

.panel--device .pipe.is-idle .pipe__router {
  gap: 2px;
  align-content: center;
}

.pipe__note {
  font-size: 0.72rem;
  font-weight: 400;
  color: var(--text-muted);
}

.panel--device .pipe.is-idle .pipe__router:empty {
  display: none;
}

/* «Visto desde el equipo»: salida de ss / log de acceso en el destino. */
.sock {
  margin-top: var(--space-2);
  padding: var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
}

.sock__title {
  margin: 0 0 4px;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--text-muted);
}

.sock__term {
  /* Las líneas largas (tcpdump, logs) se parten en vez de esconderse a la derecha. */
  white-space: pre-wrap !important;
  overflow-wrap: anywhere;
  margin: 0 0 4px;
  padding: 4px 8px;
  border-radius: 4px;
  background: #0f1720;
  color: #d6e2ee;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  line-height: 1.4;
  overflow-x: auto;
  white-space: pre;
}

.sock__note {
  margin: 0;
  font-size: 0.74rem;
  color: var(--text-muted);
}

/* Paso final («al terminar»): letra algo menor para que cada línea de ss quepa entera. */
.sock--end .sock__term {
  font-size: 0.68rem;
  line-height: 1.4;
}

.sock--fw {
  border-color: color-mix(in srgb, var(--drop) 45%, var(--border));
}

.sock--fw .sock__term {
  white-space: pre-wrap;
  word-break: break-all;
  font-size: 0.66rem;
  line-height: 1.35;
}

.sock {
  padding: 6px var(--space-2);
}

.trace__stage {
  min-width: 0;
}

.trace__stage .badge {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}

@media (max-width: 640px) {
  .trace__btn {
    grid-template-columns: 22px 92px minmax(0, 1fr);
  }

  .trace__stage {
    display: none;
  }
}

/* Recuadros «Visto desde…» y log del firewall: márgenes mínimos para que
   quepan con el paquete en la columna lateral. */
.sock {
  margin-top: 6px;
}

.sock__title,
.sock__term {
  margin-bottom: 2px;
}

.state__info {
  cursor: default;
  color: var(--accent);
  font-weight: 700;
}

.inspector__note {
  margin: var(--space-1) 0 0;
  font-size: 0.78rem;
  color: var(--text-muted);
}

/*
 * Banco de trabajo compacto en vertical: el diagrama no cambia; se ganan
 * píxeles en el recorrido, los controles, la leyenda y los márgenes.
 */
.lab__start .panel {
  padding: var(--space-3);
}

.lab__start .level {
  margin-bottom: 6px;
}

.panel--stage .legend {
  margin-top: 6px;
  font-size: 0.74rem;
}

.panel--stage .player {
  padding-top: var(--space-2);
}

.panel--stage .btn--ctrl {
  min-width: 34px;
  padding: 4px 8px;
}

.panel--stage .player__counter,
.panel--stage .player__speed-label {
  font-size: 0.84rem;
}

.stage__trace {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
}

.panel--stage .trace-wrap {
  height: 136px;
}

.panel--stage .trace__btn {
  padding: 3px 8px;
  font-size: 0.82rem;
}

/* Reproductor: ▶ / ⏸ / ↺ es la acción principal; los desactivados, bien apagados. */
.btn--ctrl.btn--play:not(:disabled) {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

.btn--ctrl:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

/* Separación entre niveles 2 y 3 más ajustada (gana alto para el paquete). */
.panel--device .level-block + .level-block {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
}

/*
 * Panel plegable «abierto temporal» (js/ui/collapsible.js): el contenido
 * flota sobre lo demás, sin mover el resto de la página.
 */
.panel.is-collapsed > .panel__head .panel__title[role='button'] {
  cursor: pointer;
}

.panel.is-collapsed > .panel__head .panel__title[role='button']:hover {
  color: var(--accent);
}

.panel__peek-bar {
  display: none;
}

.panel.is-peek {
  position: relative;
  z-index: 40;
}

.panel.is-peek > .panel__body {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  width: 100%;
  max-height: 70vh;
  overflow-y: auto;
  margin: 0;
  padding: var(--space-3);
  background: var(--panel);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: 0 12px 32px rgb(0 0 0 / 0.22);
  animation: peek-in 0.15s ease-out;
}

.panel.is-peek > .panel__body > .panel__peek-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.panel__peek-title {
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}

.panel__pin {
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text-muted);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 0.74rem;
  font-weight: 600;
  cursor: pointer;
}

.panel__pin:hover {
  color: var(--text);
  border-color: var(--accent);
}

@keyframes peek-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: none; }
}

/*
 * Cabecera del laboratorio compacta en vertical: mismo contenido, menos aire.
 * Título más pequeño, interlineados más ajustados y tarjetas con menos relleno.
 */
.lab {
  gap: var(--space-3);
}

.lab__header {
  gap: 10px;
}

.lab__heading {
  font-size: 1.5rem;
  line-height: 1.2;
}

.lab__header > .lab__summary {
  font-size: 0.98rem;
  line-height: 1.5;
}

.lab__goals {
  font-size: 0.86rem;
  line-height: 1.4;
  gap: 2px var(--space-5);
}

.lab__concepts,
.lab__intro-grid > .concept {
  padding: var(--space-3) var(--space-4);
}

.lab__intro-grid .concept__caption {
  margin-bottom: var(--space-2);
}

.lab__concepts .lab__points li {
  padding: 5px 0 5px var(--space-5);
  font-size: 0.9rem;
  line-height: 1.45;
}

.lab__concepts .lab__points li::before {
  top: calc(5px + 0.6em);
}

.lab__concepts .lab__points {
  margin-bottom: var(--space-2);
}

.lab__deeper {
  margin-bottom: var(--space-2);
}

.lab__concepts .vendor-note {
  padding-top: var(--space-2);
}

.lab__concepts .vendor-note__title {
  font-size: 0.86rem;
}

/* Conexión que usa el paso actual (ya existía): borde de acento. */
.ct__entry.is-focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}

/* Título de «Laboratorio»: hace de cabecera de la sección, como «Retos» o «Resumen». */
.lab__section-head {
  margin: var(--space-3) 0 var(--space-1);
  scroll-margin-top: 90px;
}

/* Reglas evaluadas: cada fila abre un menú (explicar / ir a la regla). */
.evals__item--action {
  cursor: pointer;
}

.evals__item--action:hover {
  border-color: var(--accent);
}

.evals__item--action:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.evals__explain {
  position: relative;
  margin: 1px 0 3px 12px;
  padding: 5px 24px 5px 8px;
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--bg-elev);
  font-size: 0.76rem;
  line-height: 1.4;
  color: var(--text-soft);
}

.evals__explain p {
  margin: 0 0 3px;
}

.evals__explain p:last-of-type {
  margin-bottom: 0;
}

.evals__explain strong {
  color: var(--text);
}

.evals__close {
  position: absolute;
  top: 1px;
  right: 3px;
  padding: 0 5px;
  border: 0;
  background: none;
  color: var(--text-dim);
  font-size: 1rem;
  line-height: 1.4;
  cursor: pointer;
}

.evals__close:hover {
  color: var(--text);
}

/* Menú contextual (js/ui/context-menu.js). */
.ctxmenu {
  position: fixed;
  z-index: 60;
  min-width: 15rem;
  max-width: min(22rem, calc(100vw - 16px));
  padding: 4px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md, 8px);
  background: var(--panel);
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.18);
}

.ctxmenu__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  width: 100%;
  padding: 6px 8px;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 0.85rem;
  text-align: left;
  cursor: pointer;
}

.ctxmenu__item:hover:not(:disabled),
.ctxmenu__item:focus-visible {
  background: var(--accent-soft);
  outline: none;
}

.ctxmenu__item:disabled {
  color: var(--text-dim);
  cursor: not-allowed;
}

.ctxmenu__icon {
  flex: none;
  width: 1.2em;
  text-align: center;
}

.ctxmenu__text {
  display: grid;
}

.ctxmenu__hint {
  color: var(--text-dim);
  font-size: 0.74rem;
}

/* La regla de la configuración a la que se llega desde el menú. */
@keyframes rule-flash {
  0%, 55% {
    box-shadow: 0 0 0 3px var(--accent);
    background: var(--accent-soft);
  }
  100% {
    box-shadow: 0 0 0 0 transparent;
  }
}

.is-flash {
  animation: rule-flash 2.2s ease-out 1;
}

@media (prefers-reduced-motion: reduce) {
  .is-flash {
    animation: none;
    outline: 2px solid var(--accent);
  }
}

/* Escenario con una línea de contexto bajo su nombre. */
.preset__text {
  display: grid;
  gap: 1px;
}

.preset__sub {
  font-size: 0.72rem;
  font-weight: 400;
  color: var(--text-muted);
  white-space: normal;
}

/* Indicación de «Enviar un paquete» en una sola línea, con una «i» que despliega la aclaración del lab. */
.send-hint,
.send-note__hint {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.send-hint {
  margin: 0 0 var(--space-2);
  font-size: 0.8rem;
}

.send-note {
  margin: 0 0 var(--space-2);
  font-size: 0.8rem;
}

.send-note > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  cursor: pointer;
  list-style: none;
  color: var(--text-muted);
}

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

.send-note__hint {
  min-width: 0;
}

.send-note > summary:hover .send-note__icon,
.send-note[open] .send-note__icon {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-soft);
}

.send-note > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.send-note__icon {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--text-dim);
  border-radius: 999px;
  color: var(--text-dim);
  font: italic 700 0.68rem/1 Georgia, serif;
}

.send-note > p {
  margin: 4px 0 0;
  padding: 5px 8px;
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--bg-elev);
  line-height: 1.4;
  color: var(--text-soft);
}

.send-note > p strong {
  color: var(--text);
}

/* Cabecera del menú (nombre del lab, en el menú que abre el raíl) y entrada actual. */
.ctxmenu__heading {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 8px 12px 6px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}

.ctxmenu__heading span {
  font-weight: 700;
  font-size: 0.86rem;
}

.ctxmenu__heading small {
  font-size: 0.74rem;
  color: var(--text-muted);
}

.ctxmenu__item.is-current {
  font-weight: 700;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}

/* Opciones de una regla (acciones / tipos de NAT): término a la izquierda, qué hace a la derecha. */
.lab__options {
  margin-top: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-elev);
}

.lab__options[hidden] {
  display: none;
}

.lab__options-title {
  margin: 0 0 var(--space-2);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}

.lab__options-list {
  display: grid;
  grid-template-columns: minmax(max-content, 11rem) 1fr;
  gap: 6px var(--space-3);
  margin: 0;
  font-size: 0.86rem;
  line-height: 1.4;
}

.lab__options-list dt,
.lab__options-list dd {
  margin: 0;
}

.lab__options-list dt code {
  font-weight: 700;
  white-space: normal;
}

.lab__options-foot {
  margin: var(--space-2) 0 0;
  padding-top: var(--space-2);
  border-top: 1px solid var(--border);
  font-size: 0.8rem;
  color: var(--text-muted);
}

@media (max-width: 560px) {
  .lab__options-list {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .lab__options-list dd {
    margin-bottom: 8px;
  }
}
