/* Winsock.
 *
 * A byte carries its own shell, so this file sets the page frame as well as
 * the machine's own surfaces. Measures in rem, never ch.
 */

* { margin: 0; padding: 0; box-sizing: border-box; }

/* Set --machine, never --accent.
 *
 * logical-art.css computes `body { --accent: var(--machine, var(--la-instrument)) }`,
 * so declaring --accent here on :root is overridden for everything inside
 * body and the whole page silently renders in the fallback grey, #bdbdbd.
 * That is the trap the canon warns about in as many words, and it cost a
 * measurement to find because the rule was present and the colour was not.
 * The accent is the roster's value for turnaround. */
body[data-machine="winsock"] { --machine: #559900; }

body {
  font-family: var(--la-font-ui);
  background: var(--la-page);
  color: var(--la-ink);
  line-height: var(--la-leading-body);
  -webkit-font-smoothing: antialiased;
}

.ws-main {
  max-width: var(--la-measure);
  margin: 0 auto;
  padding: 3rem 1.25rem 3rem;
}

.ws-head { margin-bottom: var(--la-space-6); }

.ws-lede {
  margin-top: var(--la-space-3);
  color: var(--la-ink-dim);
}

.ws-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.ws-panel {
  margin-top: var(--la-space-6);
  padding: var(--la-space-4);
  border: 1px solid var(--la-hairline-strong);
  border-radius: var(--la-radius, 6px);
  background: color-mix(in srgb, var(--la-ink) 3%, transparent);
}

.ws-panel h2 { margin-bottom: var(--la-space-2); }

.ws-hint, .ws-note {
  color: var(--la-ink-dim);
  font-size: var(--la-text-sm);
  margin-top: var(--la-space-2);
}

/* ---- knobs ------------------------------------------------------------ */

.ws-knobs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--la-space-3) var(--la-space-4);
  margin-top: var(--la-space-4);
}

.ws-knob label {
  display: block;
  font-family: var(--la-font-mono);
  font-size: var(--la-text-xs);
  color: var(--la-ink-dim);
  margin-bottom: var(--la-space-2);
}

.ws-value { color: var(--accent); }

.ws-range {
  width: 100%;
  accent-color: var(--accent);
  min-height: 1.5rem;
}

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

/* ---- the passes ------------------------------------------------------- */

.ws-passes {
  width: 100%;
  margin-top: var(--la-space-4);
  border-collapse: collapse;
  font-size: var(--la-text-sm);
}

.ws-passes th {
  text-align: right;
  font-family: var(--la-font-mono);
  font-size: var(--la-text-xs);
  font-weight: 400;
  color: var(--la-ink-dim);
  padding: 0 0 var(--la-space-2) var(--la-space-2);
  border-bottom: 1px solid var(--la-hairline-strong);
}

.ws-passes th:first-child { text-align: left; }

.ws-passes td {
  text-align: right;
  padding: var(--la-space-2) 0 var(--la-space-2) var(--la-space-2);
  border-bottom: 1px solid var(--la-hairline);
  color: var(--la-ink);
}

.ws-passes td:first-child { text-align: left; color: var(--la-ink-dim); }

/* The last pass is the answer: it stops being a guess. */
.ws-passes tbody tr:last-child td { color: var(--accent); }

.ws-num { font-family: var(--la-font-mono); }

/* ---- the readout ------------------------------------------------------ */

.ws-readout {
  margin-top: var(--la-space-4);
  border-top: 1px solid var(--la-hairline);
}

.ws-row {
  display: grid;
  grid-template-columns: 14rem 1fr;
  gap: var(--la-space-3);
  padding: var(--la-space-2) 0;
  border-bottom: 1px solid var(--la-hairline);
}

.ws-row dt {
  font-family: var(--la-font-mono);
  font-size: var(--la-text-xs);
  color: var(--la-ink-dim);
}

.ws-row dd {
  font-size: var(--la-text-sm);
  color: var(--la-ink);
  overflow-wrap: anywhere;
}

.ws-strong dd { color: var(--accent); font-weight: 600; }

.ws-why { margin-top: var(--la-space-6); }
.ws-why h2 { margin-top: var(--la-space-5); margin-bottom: var(--la-space-2); }
.ws-why p { margin-top: var(--la-space-3); color: var(--la-ink-dim); }

@media (max-width: 34rem) {
  .ws-row { grid-template-columns: 1fr; }
  .ws-row dt { color: var(--la-ink-faint); }
}


/* ---- the deck ---------------------------------------------------------- */

.ws-label {
  margin-top: var(--la-space-4);
  font-family: var(--la-font-mono);
  font-size: var(--la-text-xs);
  color: var(--la-ink-dim);
}

.ws-deck {
  display: flex;
  flex-wrap: wrap;
  gap: var(--la-space-2);
  margin-top: var(--la-space-4);
}

.ws-card {
  display: inline-flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: var(--la-space-2) 0.7rem;
  border: 1px solid var(--la-hairline-strong);
  border-radius: 2px;
  background: color-mix(in srgb, var(--la-ink) 5%, transparent);
  font-family: var(--la-font-mono);
  font-size: var(--la-text-xs);
}

.ws-card-key { color: var(--la-ink); font-size: var(--la-text-sm); }
.ws-card-ctl { color: var(--accent); }
.ws-card-val { color: var(--la-ink-dim); }

/* ---- the fifteen items ------------------------------------------------- */

.ws-items {
  margin-top: var(--la-space-2);
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--la-hairline);
}

.ws-item {
  display: flex;
  gap: var(--la-space-2);
  align-items: baseline;
  padding: var(--la-space-2) 0.4rem;
  border-bottom: 1px solid var(--la-hairline);
  font-size: var(--la-text-sm);
  color: var(--la-ink-dim);
}

.ws-item-n {
  flex: none;
  width: 1.6rem;
  text-align: right;
  font-family: var(--la-font-mono);
  font-size: var(--la-text-xs);
  color: var(--la-ink-faint);
}

/* Yours and the compiler's, told apart by a rule down the side as well as by
   colour, so it survives greyscale. */
.ws-item[data-yours="yes"] {
  border-left: 3px solid var(--accent);
  color: var(--la-ink);
}

.ws-item[data-yours="no"] { border-left: 3px solid transparent; }

.ws-item[data-here="yes"] {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--la-ink);
}

.ws-item[data-here="yes"] .ws-item-n { color: var(--accent); font-weight: 600; }

/* ---- the printer ------------------------------------------------------- */

.ws-print {
  margin-top: var(--la-space-2);
  padding: var(--la-space-3);
  border: 1px solid var(--la-hairline-strong);
  border-radius: var(--la-radius, 6px);
  background: #05070a;
  font-family: var(--la-font-mono);
  font-size: var(--la-text-sm);
  color: var(--la-ink);
  white-space: pre;
  overflow-x: auto;
  min-height: 6rem;
}

/* ---- the days ---------------------------------------------------------- */

.ws-days {
  width: 100%;
  margin-top: var(--la-space-4);
  border-collapse: collapse;
  font-size: var(--la-text-sm);
}

.ws-days th {
  text-align: left;
  font-family: var(--la-font-mono);
  font-size: var(--la-text-xs);
  font-weight: 400;
  color: var(--la-ink-dim);
  padding: 0 var(--la-space-2) var(--la-space-2) 0;
  border-bottom: 1px solid var(--la-hairline-strong);
}

.ws-days td {
  padding: var(--la-space-2) var(--la-space-2) var(--la-space-2) 0;
  border-bottom: 1px solid var(--la-hairline);
  color: var(--la-ink);
  vertical-align: top;
}

.ws-days tbody tr:last-child td { color: var(--accent); }

.ws-presets {
  display: flex;
  flex-wrap: wrap;
  gap: var(--la-space-2);
  margin-top: var(--la-space-4);
}

.ws-btn {
  font-family: var(--la-font-mono);
  font-size: var(--la-text-sm);
  color: var(--la-ink);
  background: color-mix(in srgb, var(--la-ink) 6%, transparent);
  border: 1px solid var(--la-hairline-strong);
  border-radius: var(--la-radius, 6px);
  padding: 0.4em 0.9em;
  cursor: pointer;
  /* 2.5.8 asks for 24 CSS pixels. */
  min-height: 2.25rem;
  min-width: 2.25rem;
}

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

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

.ws-btn[aria-pressed="true"] {
  border-color: var(--accent);
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.ws-btn:disabled { opacity: 0.45; cursor: default; }

.ws-now { margin-top: var(--la-space-4); }

/* ---- the states ------------------------------------------------------- */

.ws-states {
  display: flex;
  flex-wrap: wrap;
  gap: var(--la-space-2);
  margin-top: var(--la-space-4);
  padding: 0;
  list-style: none;
}

.ws-state {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
  padding: var(--la-space-2) 0.6rem;
  border: 1px solid var(--la-hairline);
  border-radius: var(--la-radius, 6px);
  font-family: var(--la-font-mono);
  font-size: var(--la-text-xs);
  color: var(--la-ink-dim);
}

.ws-state-n { color: var(--la-ink-faint); }

/* Opened is the one that matters, so it is marked even when you are not in it. */
.ws-state[data-opened="yes"] { border-style: dashed; }

.ws-state[data-here="yes"] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--la-ink);
  font-weight: 600;
}

.ws-state[data-here="yes"] .ws-state-n { color: var(--accent); }

/* ---- the trace -------------------------------------------------------- */

.ws-trace {
  width: 100%;
  margin-top: var(--la-space-4);
  border-collapse: collapse;
  font-size: var(--la-text-sm);
}

.ws-trace th {
  text-align: left;
  font-family: var(--la-font-mono);
  font-size: var(--la-text-xs);
  font-weight: 400;
  color: var(--la-ink-dim);
  padding: 0 var(--la-space-2) var(--la-space-2) 0;
  border-bottom: 1px solid var(--la-hairline-strong);
}

.ws-trace td {
  padding: var(--la-space-2) var(--la-space-2) var(--la-space-2) 0;
  border-bottom: 1px solid var(--la-hairline);
  color: var(--la-ink);
  vertical-align: top;
}

.ws-trace tbody tr:last-child td { color: var(--accent); }

.ws-ev { font-family: var(--la-font-mono); }
.ws-act { color: var(--la-ink); }
.ws-illegal { color: var(--la-ink-faint); font-style: italic; }

/* ---- the matrix ------------------------------------------------------- */

.ws-matrix {
  border-collapse: collapse;
  font-family: var(--la-font-mono);
  font-size: var(--la-text-xs);
  min-width: 44rem;
}

.ws-matrix th, .ws-matrix td {
  padding: 0.35rem 0.5rem;
  border-bottom: 1px solid var(--la-hairline);
  border-right: 1px solid var(--la-hairline);
  text-align: left;
  white-space: nowrap;
}

.ws-matrix .ws-m-head th {
  color: var(--la-ink-dim);
  font-weight: 400;
  border-bottom: 1px solid var(--la-hairline-strong);
  vertical-align: bottom;
}

.ws-m-n { display: block; color: var(--la-ink-faint); }
.ws-m-s { display: block; }

.ws-matrix tbody tr:not(.ws-m-head) th {
  color: var(--accent);
  font-weight: 400;
  position: sticky;
  left: 0;
  background: var(--la-page);
}

.ws-matrix td { color: var(--la-ink); }
.ws-matrix td[data-illegal="yes"] { color: var(--la-ink-faint); }

.ws-matrix td[data-here="yes"] {
  background: color-mix(in srgb, var(--accent) 26%, transparent);
  color: var(--la-ink);
  font-weight: 600;
}

/* ---- the ladder --------------------------------------------------------- */

.ws-ascent {
    list-style: none;
    margin: 1.2rem 0 1rem;
    padding: 0;
    display: grid;
    gap: 0.5rem;
}

.ws-rung {
    display: flex;
    gap: 0.85rem;
    align-items: flex-start;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--la-hairline);
    border-left-width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--la-raised);
}

/* A locked rung was drawn at opacity 0.55 and its text failed AA at six
 * nodes. Dimming is the wrong way to say "not yet" anyway: the reader most
 * likely to need the sentence explaining WHY it is locked is the one least
 * able to read it at half strength. So the state is carried by the border and
 * the words, and the text stays legible. */
.ws-rung[data-state="shut"] {
    border-left-style: dashed;
    border-left-color: var(--la-ink-faint);
    background: transparent;
}
.ws-rung[data-state="open"] { border-left-color: var(--la-ink-faint); }
.ws-rung[data-state="done"] {
    border-left-color: var(--accent);
    background: var(--la-card);
}

.ws-rung-n {
    font-family: var(--la-font-mono);
    font-size: 0.85rem;
    color: var(--la-ink-faint);
    min-width: 1.1rem;
    padding-top: 0.15rem;
}

.ws-rung[data-state="done"] .ws-rung-n { color: var(--accent); }

.ws-rung-body {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.ws-rung-title {
    font-weight: 600;
    font-size: var(--la-text-sm);
    color: var(--la-ink);
}

.ws-rung-proto {
    font-family: var(--la-font-mono);
    font-size: 0.75rem;
    color: var(--accent);
}

.ws-rung-says {
    font-size: var(--la-text-sm);
    line-height: 1.5;
    color: var(--la-ink-dim);
}

.ws-socket {
    font-family: var(--la-font-mono);
    font-size: var(--la-text-xs);
    line-height: 1.6;
    margin: 0;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--la-hairline);
    border-radius: 3px;
    background: var(--la-sunken);
    color: var(--la-ink-dim);
}

.ws-socket[data-ok="yes"] { color: var(--accent); }

/* ---- what crossed the line ---------------------------------------------- */

.ws-auth-form {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9rem 1.2rem;
    align-items: flex-end;
    margin: 1rem 0;
}

.ws-field {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin: 0;
}

.ws-field:last-child { flex-direction: row; gap: 0.6rem; flex-wrap: wrap; }

.ws-field-label {
    font-size: var(--la-text-xs);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--la-ink-dim);
}

.ws-field-in {
    font-family: var(--la-font-mono);
    font-size: 0.95rem;
    padding: 0.4rem 0.5rem;
    background: var(--la-sunken);
    color: var(--la-ink);
    border: 1px solid var(--la-hairline-strong);
    border-radius: 2px;
}

.ws-field-in:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
}

.ws-wire {
    list-style: none;
    margin: 1rem 0 0.9rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.ws-packet {
    display: grid;
    grid-template-columns: 1.4rem 10rem minmax(0, 1fr);
    gap: 0.3rem 0.8rem;
    align-items: baseline;
    padding: 0.45rem 0.6rem;
    background: var(--la-raised);
    border-radius: 2px;
    font-size: var(--la-text-sm);
}

.ws-packet-dir {
    font-family: var(--la-font-mono);
    color: var(--la-ink-faint);
}

.ws-packet[data-from="you"] .ws-packet-dir { color: var(--accent); }

.ws-packet-name { font-weight: 600; color: var(--la-ink); }

.ws-packet-carries {
    font-family: var(--la-font-mono);
    font-size: 0.78rem;
    color: var(--accent);
    word-break: break-all;
}

.ws-packet-says {
    grid-column: 2 / -1;
    color: var(--la-ink-dim);
    line-height: 1.5;
}

.ws-verdict {
    margin: 0;
    font-size: var(--la-text-sm);
    line-height: 1.6;
    color: var(--la-ink-dim);
    padding-left: 0.75rem;
    border-left: 3px solid var(--la-hairline-strong);
}

.ws-verdict[data-ok="yes"] { border-left-color: var(--accent); color: var(--la-ink); }

/* ---- TCP ---------------------------------------------------------------- */

.ws-steps {
    list-style: none;
    margin: 1rem 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.ws-step {
    display: grid;
    grid-template-columns: 9rem 14rem minmax(0, 1fr);
    gap: 0.25rem 0.8rem;
    align-items: baseline;
    padding: 0.45rem 0.6rem;
    background: var(--la-raised);
    border-radius: 2px;
    font-size: var(--la-text-sm);
}

.ws-step-ev {
    font-family: var(--la-font-mono);
    font-size: 0.8rem;
    color: var(--accent);
}

.ws-step-move { font-family: var(--la-font-mono); font-size: 0.8rem; color: var(--la-ink); }
.ws-step-act { font-size: 0.8rem; color: var(--la-ink-faint); }

.ws-step-says {
    grid-column: 1 / -1;
    color: var(--la-ink-dim);
    line-height: 1.5;
}

.ws-step[data-undrawn="yes"] { opacity: 0.6; }

.ws-tcp-states {
    border: 1px solid var(--la-hairline);
    border-radius: 3px;
    padding: 0.85rem 0.95rem;
    background: var(--la-sunken);
    max-height: 22rem;
    overflow-y: auto;
}

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

.ws-tcp-states-head {
    margin: 0 0 0.6rem;
    font-size: var(--la-text-xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--la-ink-dim);
}

.ws-state-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.ws-tcp-state {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.35rem 0.55rem;
    border-left: 3px solid transparent;
    font-size: var(--la-text-sm);
}

.ws-tcp-state[data-here="yes"] {
    border-left-color: var(--accent);
    background: var(--la-raised);
}

.ws-tcp-state-name {
    font-family: var(--la-font-mono);
    font-size: 0.82rem;
    color: var(--la-ink-dim);
}

.ws-tcp-state[data-here="yes"] .ws-tcp-state-name { color: var(--accent); }

.ws-tcp-state-mean { color: var(--la-ink-faint); line-height: 1.5; font-size: 0.82rem; }

@media (max-width: 640px) {
    .ws-packet { grid-template-columns: 1.2rem minmax(0, 1fr); }
    .ws-packet-carries { grid-column: 2; }
    .ws-step { grid-template-columns: minmax(0, 1fr); }
}

.ws-selfcheck {
    margin: 0.9rem 0 0;
    font-family: var(--la-font-mono);
    font-size: var(--la-text-xs);
    line-height: 1.6;
    color: var(--la-ink-dim);
    word-break: break-all;
}

.ws-selfcheck[data-ok="yes"] { color: var(--accent); }

/* ---- the fifth rung ----------------------------------------------------- */

.ws-wire-pair {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 0.9rem;
    margin: 1rem 0;
}

.ws-wire-head {
    margin: 0 0 0.4rem;
    font-size: var(--la-text-xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--la-ink-dim);
}

.ws-bytes {
    font-family: var(--la-font-mono);
    font-size: 0.78rem;
    line-height: 1.5;
    margin: 0;
    padding: 0.7rem 0.8rem;
    background: var(--la-sunken);
    border: 1px solid var(--la-hairline);
    border-radius: 3px;
    color: var(--accent);
    white-space: pre-wrap;
    word-break: break-word;
    min-height: 5rem;
}

.ws-sub {
    font-size: var(--la-text-md);
    margin: 1.8rem 0 0.5rem;
    color: var(--la-ink);
}

.ws-crawl {
    width: 100%;
    border-collapse: collapse;
    margin: 0.9rem 0;
    font-size: var(--la-text-sm);
}

.ws-crawl th,
.ws-crawl td {
    text-align: left;
    padding: 0.4rem 0.6rem;
    border-bottom: 1px solid var(--la-hairline);
}

.ws-crawl th {
    font-size: var(--la-text-xs);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--la-ink-dim);
    font-weight: 600;
}

.ws-crawl td { font-family: var(--la-font-mono); font-size: 0.8rem; color: var(--la-ink-dim); }

/* Right and wrong are carried by a word and a border, never by colour alone. */
.ws-crawl td[data-right="yes"] { color: var(--accent); }
.ws-crawl td[data-right="no"] {
    color: var(--la-ink);
    border-left: 3px solid var(--la-ink);
    padding-left: 0.45rem;
}

/* The stream the connection carries. */
.ws-flow td { font-variant-numeric: tabular-nums; }
.ws-flow tr[data-kind="retransmit"] td { color: var(--accent); }
.ws-flow tr[data-lost="yes"] td:first-child {
    color: var(--la-ink);
    border-left: 3px solid var(--la-ink);
    padding-left: 0.45rem;
}

/* The automaton, drawn. Opened is the one state worth pointing at, so it is
   the only one in the accent, and it is also the only one whose label goes
   bold: a reader who cannot see the colour still knows which box is the end. */
.dia .dia-field .dia-state-open { fill: var(--accent); fill-opacity: 0.14; stroke: var(--accent); stroke-width: 2; }
.dia .dia-field .dia-state-text { fill: var(--la-ink); font-size: 13px; text-anchor: middle; }
.dia .dia-field .dia-state-text-open { fill: var(--accent); font-size: 13px; font-weight: 700; text-anchor: middle; }
.dia .dia-msg .dia-arrowhead { fill: var(--la-ink-faint); stroke: none; }
.dia .dia-lede { fill: var(--la-ink); font-size: 15px; }
