/* Laboratorio TCP: escalera de la conexión, estados y terminales. */

/* Escalera ------------------------------------------------------------- */
.ladder-wrap {
  max-height: 420px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-elev);
  scroll-behavior: smooth;
}

@container main (min-width: 1033px) {
  .lab__start .ladder-wrap {
    max-height: max(260px, calc(100vh - 420px));
  }
}

.ladder {
  display: block;
  width: 100%;
  /* En pantallas anchas no se agranda más allá de su tamaño natural: así queda compacto. */
  max-width: 600px;
  height: auto;
  margin: 0 auto;
}

.ladder__life {
  stroke: var(--border-strong);
  stroke-width: 2;
}

.ladder__node {
  fill: var(--node-router);
  stroke: var(--accent);
  stroke-width: 1.5;
}

.ladder__name {
  fill: var(--text);
  font: 600 13px var(--font-sans);
  text-anchor: middle;
}

.ladder__sub {
  fill: var(--text-muted);
  font: 10px var(--font-mono);
  text-anchor: middle;
}

.ladder__row {
  cursor: pointer;
  outline: none;
}

.ladder__band {
  fill: transparent;
  transition: fill 0.15s;
}

.ladder__row:hover .ladder__band {
  fill: color-mix(in srgb, var(--accent-soft) 55%, transparent);
}

.ladder__row.is-current .ladder__band {
  fill: var(--accent-soft);
}

.ladder__row.is-future .ladder__arrow,
.ladder__row.is-future .ladder__label,
.ladder__row.is-future .ladder__nums,
.ladder__row.is-future .ladder__call,
.ladder__row.is-future .ladder__dot,
.ladder__row.is-future .ladder__tip,
.ladder__row.is-future .ladder__pill,
.ladder__row.is-future .ladder__pilltext,
.ladder__row.is-future .ladder__note {
  opacity: 0.4;
}

.ladder__time {
  fill: var(--text-dim);
  font: 10px var(--font-mono);
}

.ladder__arrow {
  stroke-width: 2.5;
  stroke-linecap: round;
}

.ladder__arrow--open { stroke: var(--accent); }
.ladder__arrow--data { stroke: var(--reply); }
.ladder__arrow--ack { stroke: var(--request); }
.ladder__arrow--close { stroke: var(--warn); }
.ladder__arrow--reset { stroke: var(--drop); }

.ladder__arrow.is-lost {
  stroke-dasharray: 5 4;
}

/* El segmento actual se «dibuja» al llegar. */
.ladder__row.is-current .ladder__arrow:not(.is-lost) {
  stroke-width: 3.5;
  stroke-dasharray: 300;
  stroke-dashoffset: 300;
  animation: ladder-draw 0.5s ease-out forwards;
}

@keyframes ladder-draw {
  to { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ladder__row.is-current .ladder__arrow:not(.is-lost) {
    animation: none;
    stroke-dasharray: none;
    stroke-dashoffset: 0;
  }
}

.ladder__tip--open path { fill: var(--accent); }
.ladder__tip--data path { fill: var(--reply); }
.ladder__tip--ack path { fill: var(--request); }
.ladder__tip--close path { fill: var(--warn); }
.ladder__tip--reset path { fill: var(--drop); }

.ladder__cross {
  fill: none;
  stroke: var(--drop);
  stroke-width: 2.5;
  stroke-linecap: round;
}

.ladder__label {
  font: 700 11px var(--font-mono);
  text-anchor: middle;
}

.ladder__label--open { fill: var(--accent); }
.ladder__label--data { fill: var(--reply); }
.ladder__label--ack { fill: var(--text-muted); }
.ladder__label--close { fill: var(--warn); }
.ladder__label--reset { fill: var(--drop); }

.ladder__nums {
  fill: var(--text-dim);
  font: 9.5px var(--font-mono);
  text-anchor: middle;
}

.ladder__dot {
  stroke: var(--bg-elev);
  stroke-width: 2;
}

.ladder__dot--kernel { fill: var(--accent); }
.ladder__dot--app { fill: var(--vpn); }
.ladder__dot--red { fill: var(--text-dim); }

.ladder__call {
  fill: var(--text);
  font: 600 11px var(--font-mono);
}

.ladder__call.is-right {
  text-anchor: end;
}

.ladder__note {
  fill: var(--text-muted);
  font: italic 11px var(--font-sans);
  text-anchor: middle;
}

.ladder__gap {
  stroke: var(--bg-elev);
  stroke-width: 4;
  stroke-dasharray: 3 6;
}

.ladder__pill {
  fill: var(--panel-2);
  stroke: var(--border-strong);
}

.ladder__pilltext {
  fill: var(--text);
  font: 600 11px var(--font-mono);
  text-anchor: middle;
}

.ladder__chip rect {
  fill: var(--panel-2);
  stroke: var(--border-strong);
}

.ladder__chip text {
  fill: var(--text-muted);
  font: 700 9.5px var(--font-mono);
  text-anchor: middle;
}

.ladder__chip.is-estab rect { fill: var(--ok-soft); stroke: var(--ok); }
.ladder__chip.is-estab text { fill: var(--ok); }
.ladder__chip.is-open rect { stroke: var(--accent); }
.ladder__chip.is-open text { fill: var(--accent); }
.ladder__chip.is-closing rect { stroke: var(--warn); }
.ladder__chip.is-closing text { fill: var(--warn); }

/* Leyenda de categorías (comparte estilo con la del resto de labs). */
.legend__swatch--tcp-open { background: var(--accent); }
.legend__swatch--tcp-data { background: var(--reply); }
.legend__swatch--tcp-ack { background: var(--request); }
.legend__swatch--tcp-close { background: var(--warn); }
.legend__swatch--tcp-reset { background: var(--drop); }

/* Escenarios ------------------------------------------------------------ */
.tcp-preset {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  text-align: left;
}

.tcp-preset.is-active {
  border-color: var(--accent);
  background: var(--accent-soft);
}

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

/* El segmento ------------------------------------------------------------ */
.tcp-seg__path {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin: 0 0 var(--space-2);
  font-size: 0.78rem;
}

.tcp-lost {
  margin-left: var(--space-2);
  border-color: var(--drop);
  color: var(--drop);
}

.tcp-seg__opts {
  margin: var(--space-2) 0 0;
  overflow-wrap: anywhere;
}

/* Terminales ------------------------------------------------------------- */
.tcp-terms {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-1);
}

.tcp-term {
  min-width: 0;
}

.tcp-terms {
  /* Un solo tamaño de letra para todas las terminales (tcpdump, ss y strace). */
  --term-font: 0.6rem;
}

.tcp-term .sock__term {
  max-height: 170px;
  overflow: auto;
}

.tcp-line {
  display: block;
  opacity: 0.62;
}

.tcp-line.is-now {
  opacity: 1;
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: 2px;
}

.tcp-line.is-empty {
  font-style: italic;
  opacity: 0.55;
}


.tcp-seg__path {
  margin-bottom: var(--space-1);
  font-size: 0.72rem;
}

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

.tcp-opts {
  margin-top: var(--space-1);
  font-size: 0.72rem;
}

.tcp-opts summary {
  cursor: pointer;
  color: var(--text-muted);
}

.tcp-opts code {
  display: block;
  margin-top: 2px;
  font-size: 0.66rem;
  overflow-wrap: anywhere;
}

.tcp-term {
  margin-top: 0;
  padding: 4px 6px;
}

.tcp-term .sock__title {
  margin-bottom: 2px;
  font-size: 0.68rem;
}

.tcp-term .sock__term {
  /* Alto fijo: la terminal no crece con cada línea, el contenido se desplaza dentro (como un `tail -f`). */
  height: 96px;
  max-height: none;
  overflow: auto;
  font-size: var(--term-font);
  line-height: 1.35;
}

/*
 * `ss` es una tabla ancha (la columna Process es larga): letra menor y, si no cabe, sus líneas se
 * parten en lugar de esconderse a la derecha. Cada fila ocupa una o dos líneas.
 */
.tcp-term .sock__term.sock__term--cols {
  height: 72px;
  white-space: pre-wrap !important;
  overflow-wrap: anywhere;
  overflow-x: hidden;
}

.lab--tcp .panel--device .level-block + .level-block {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
}

/* Ayuda de cada terminal: un ⓘ en su título (el texto sale en un tooltip) en vez de un párrafo debajo. */
.sock__info {
  margin-left: 6px;
  color: var(--text-muted);
  font-size: 0.8rem;
  cursor: default;
}

.sock__info:hover,
.sock__info:focus-visible {
  color: var(--accent);
}

/* Puerto de cada extremo en la cabecera de la escalera: el del servidor, resaltado. */
.ladder__port {
  font-weight: 600;
}

.ladder__port.is-listen {
  fill: var(--accent);
}

/* ---- Lab DHCP: campos del mensaje, opciones y configuraciones ---- */
.dh-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.2rem, 1fr));
  gap: 6px 10px;
  margin: 6px 0;
}

.dh-field {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 3px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
}

.dh-field.is-zero {
  opacity: 0.55;
}

.dh-field__k {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

.dh-field__v {
  font-size: 0.78rem;
  background: none;
  border: 0;
  padding: 0;
  overflow-wrap: anywhere;
}

.dh-bcast,
.dh-ucast {
  margin-left: 6px;
}

.dh-bcast {
  background: color-mix(in srgb, var(--warn) 22%, transparent);
}

.dh-ucast {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}

.dh-opts {
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.78rem;
}

.dh-opts li {
  display: grid;
  grid-template-columns: 2rem minmax(8rem, 12rem) 1fr;
  gap: 6px;
  padding: 2px 0;
  border-top: 1px solid var(--border);
}

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

.dh-opts__name {
  font-weight: 600;
}

.dh-config {
  margin-top: var(--space-2);
}

/* La tabla del paso con tres equipos no cabe en un móvil: se desplaza dentro de su caja. */
.lab--proto .inspector--step .table-scroll {
  max-width: 100%;
  overflow-x: auto;
}

.lab--proto .inspector--step .table-scroll .mini-table {
  width: max-content;
  min-width: 100%;
}

/* Lab DNS: los registros de un mensaje (nombre y TTL en una línea, el dato debajo). */
.dns-records li {
  grid-template-columns: minmax(0, 1fr) auto;
}

.dns-records li code {
  grid-column: 1 / -1;
  background: none;
  border: 0;
  padding: 0;
  overflow-wrap: anywhere;
}

.dns-records .dh-opts__name {
  overflow-wrap: anywhere;
}

.dns-records .dns-sec {
  display: block;
  padding-top: 6px;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  border-top: 0;
}

/* Con 4 o 5 equipos las pestañas de terminal no caben en una fila: bajan a otra. */
.lab--proto .detail__tabs {
  flex-wrap: wrap;
  max-width: 100%;
  border-radius: var(--radius);
}

.lab--proto .detail__tabs .detail__tab {
  flex: 1 1 auto;
}

/* ---- Lab «Direcciones IP»: calculadora, binario y campos ---- */
.lab__calc {
  margin-top: var(--space-4);
}

.ipc-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: var(--space-2) 0;
}

.ipc-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  gap: var(--space-4);
  align-items: start;
}

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

.ipc-bin {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.ipc-row {
  display: grid;
  grid-template-columns: 9rem minmax(0, auto) 1fr;
  gap: 8px;
  align-items: center;
  font-size: 0.8rem;
}

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

.ipc-row__dec {
  font-size: 0.78rem;
  overflow-wrap: anywhere;
}

.ipc-bits {
  display: inline-flex;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 0.74rem;
}

.ipc-octet {
  display: inline-flex;
}

.ipc-bit.is-net {
  color: var(--accent);
  font-weight: 700;
}

.ipc-bit.is-host {
  color: var(--text-muted);
  opacity: 0.55;
}

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

  .ipc-bits {
    font-size: 0.66rem;
    gap: 4px;
  }
}

.ipc-summary {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 4px 12px;
  margin: var(--space-3) 0 0;
  font-size: 0.84rem;
}

.ipc-summary dt {
  color: var(--text-muted);
}

.ipc-summary dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.ipc-errors {
  margin: var(--space-2) 0 0;
  padding-left: 1.1rem;
  font-size: 0.82rem;
  color: var(--drop);
}

.ipc-route {
  margin-top: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-left: 4px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
}

.ipc-route p {
  margin: 2px 0 0;
  font-size: 0.84rem;
}

.ipc-route.is-ok {
  border-left-color: var(--accent);
}

.ipc-route.is-warn {
  border-left-color: var(--warn);
}

.ipc-route.is-bad {
  border-left-color: var(--drop);
}
