/* Must Connection Check — diagnostic console (SPEC §6.1).
   Refined dark instrument-panel aesthetic. Self-hosted IBM Plex. */

/* ---------- fonts (self-hosted woff2, OFL) ---------- */
@font-face {
  font-family: "IBM Plex Sans"; font-style: normal; font-weight: 400;
  font-display: swap; src: url("fonts/IBMPlexSans-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans"; font-style: normal; font-weight: 600;
  font-display: swap; src: url("fonts/IBMPlexSans-SemiBold.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400;
  font-display: swap; src: url("fonts/IBMPlexMono-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 500;
  font-display: swap; src: url("fonts/IBMPlexMono-Medium.woff2") format("woff2");
}

/* ---------- tokens ---------- */
:root {
  --bg: #0b0f14;
  --surface: #11161d;
  --surface-2: #1a212b;
  --line: #222b35;
  --accent: #3b9eff;
  --accent-dim: #1f5d99;
  --ok: #3fb950;
  --warn: #d8a23a;
  --bad: #f15a4f;
  --text: #e6edf3;
  --muted: #8b949e;
  --faint: #57606a;

  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --sans: "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;

  --r-sm: 6px; --r-md: 10px; --r-lg: 16px;
  --sp-1: 6px; --sp-2: 12px; --sp-3: 20px; --sp-4: 32px; --sp-5: 52px;
  --ease: cubic-bezier(.2, .7, .2, 1);
  --maxw: 720px;
}

/* ---------- reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  position: relative;
  overflow-x: hidden;
}

/* ---------- atmosphere: grid + glows + grain ---------- */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background-image:
    linear-gradient(var(--line) 1px, transparent 1px),
    linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size: 32px 32px;
  opacity: .12;
  mask-image: radial-gradient(circle at 50% 30%, #000 0%, transparent 80%);
}
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(60vmax 60vmax at 12% -8%, rgba(59,158,255,.13), transparent 60%),
    radial-gradient(50vmax 50vmax at 100% 108%, rgba(59,158,255,.09), transparent 55%);
}
/* fine grain via tiny SVG noise */
.grain {
  position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: .035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- layout ---------- */
.wrap {
  position: relative; z-index: 1;
  max-width: var(--maxw); margin: 0 auto;
  padding: var(--sp-4) var(--sp-3) var(--sp-5);
  min-height: 100%;
  display: flex; flex-direction: column;
}
header.site {
  display: flex; align-items: baseline; gap: var(--sp-2);
  padding-bottom: var(--sp-4);
}
.wordmark {
  font-family: var(--mono); font-weight: 500; font-size: 18px; letter-spacing: .04em;
  color: var(--text);
}
.wordmark b { color: var(--accent); font-weight: 500; }
.tagline { font-size: 13px; color: var(--muted); }

main { flex: 1; }
footer.site {
  margin-top: var(--sp-5); padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
  font-size: 13px; color: var(--muted); line-height: 1.9;
}
footer.site a { color: var(--accent); text-decoration: none; }
footer.site a:hover { text-decoration: underline; }
.sig { color: var(--faint); }

/* ---------- state machine ---------- */
.state { display: none; }
#app[data-state="input"]   .state--input,
#app[data-state="process"] .state--process,
#app[data-state="result"]  .state--result { display: block; animation: rise .5s var(--ease) both; }

/* ---------- input hero ---------- */
.hero { padding: var(--sp-5) 0 var(--sp-4); }
.hero h1 {
  font-family: var(--sans); font-weight: 600; font-size: clamp(26px, 4.5vw, 40px);
  line-height: 1.15; margin: 0 0 var(--sp-2); letter-spacing: -.01em;
}
.hero p.lede { color: var(--muted); margin: 0 0 var(--sp-4); max-width: 46ch; }
.field { display: flex; flex-direction: column; gap: var(--sp-2); }
.linkrow { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
#link {
  flex: 1 1 320px; min-width: 0;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 16px 18px; font-family: var(--mono); font-size: 15px;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
#link::placeholder { color: var(--faint); }
#link:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(59,158,255,.18);
}
button.primary {
  background: var(--accent); color: #04101e; border: 0; cursor: pointer;
  border-radius: var(--r-md); padding: 16px 26px;
  font-family: var(--mono); font-weight: 500; font-size: 15px; letter-spacing: .02em;
  transition: transform .15s var(--ease), filter .2s var(--ease), box-shadow .2s var(--ease);
  box-shadow: 0 6px 24px -8px rgba(59,158,255,.5);
}
button.primary:hover { filter: brightness(1.08); transform: translateY(-1px); }
button.primary:active { transform: translateY(0); }
button.primary:disabled { opacity: .55; cursor: default; box-shadow: none; transform: none; }
.hint { font-size: 13px; color: var(--faint); font-family: var(--mono); }
.hint[data-bad="1"] { color: var(--warn); }

/* ---------- process: signal graph + stages ---------- */
.signal-wrap { padding: var(--sp-3) 0 var(--sp-4); }
#signal { width: 100%; height: 132px; display: block; overflow: visible; }
#signal .track { stroke: var(--line); stroke-width: 2; fill: none; }
#signal .seg { stroke: var(--accent-dim); stroke-width: 2.5; fill: none;
  stroke-dasharray: var(--len, 200); stroke-dashoffset: var(--len, 200);
  transition: stroke .35s var(--ease); }
#signal .seg.active { stroke: var(--accent); animation: draw .7s var(--ease) forwards, hum 1.4s ease-in-out infinite .7s; }
#signal .seg.done { stroke: var(--accent); stroke-dashoffset: 0; }
#signal .seg.bad  { stroke: var(--bad); stroke-dashoffset: 0; }
#signal .node { fill: var(--surface-2); stroke: var(--line); stroke-width: 2; transition: fill .3s var(--ease), stroke .3s var(--ease); }
#signal .node.active { stroke: var(--accent); animation: ping 1.4s ease-out infinite; }
#signal .node.ok   { fill: var(--ok);   stroke: var(--ok); }
#signal .node.warn { fill: var(--warn); stroke: var(--warn); }
#signal .node.bad  { fill: var(--bad);  stroke: var(--bad); }
#signal text { font-family: var(--mono); font-size: 10px; fill: var(--muted); }

.progress {
  height: 3px; background: var(--line); border-radius: 2px; overflow: hidden; margin-bottom: var(--sp-3);
}
.progress > i { display: block; height: 100%; width: 0; background: var(--accent);
  transition: width .5s var(--ease); }

ol#stages { list-style: none; margin: 0; padding: 0; }
ol#stages li {
  display: grid; grid-template-columns: 26px 1fr auto; align-items: center; gap: var(--sp-2);
  padding: 14px 4px; border-bottom: 1px solid var(--line);
  opacity: .45; transition: opacity .35s var(--ease);
}
ol#stages li .idx { font-family: var(--mono); font-size: 12px; color: var(--faint); }
ol#stages li .label { font-size: 15px; }
ol#stages li .detail { font-family: var(--mono); font-size: 12px; color: var(--muted); grid-column: 2 / 4; }
ol#stages li.active, ol#stages li.done, ol#stages li.fail, ol#stages li.skip { opacity: 1; }
ol#stages li .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--faint); justify-self: end; }
li.active .dot { background: var(--accent); animation: ping 1.3s ease-out infinite; }
li.done .dot { background: var(--ok); }
li.fail .dot { background: var(--bad); }
li.skip .dot { background: var(--faint); opacity: .5; }
li.active .idx { color: var(--accent); }

/* ---------- result: verdict + blocks ---------- */
.verdict {
  border: 1px solid var(--line); border-left-width: 4px;
  background: var(--surface); border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4);
}
.verdict .kicker { font-family: var(--mono); font-size: 12px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 6px; }
.verdict h2 { margin: 0 0 var(--sp-2); font-size: clamp(22px, 3.5vw, 30px); font-weight: 600; letter-spacing: -.01em; }
.verdict .cause { margin: 0 0 var(--sp-2); }
.verdict .rec { margin: 0; color: var(--muted); }
.verdict.v-ok   { border-left-color: var(--ok); }
.verdict.v-warn { border-left-color: var(--warn); }
.verdict.v-bad  { border-left-color: var(--bad); }
.verdict.v-ok   .kicker { color: var(--ok); }
.verdict.v-warn .kicker { color: var(--warn); }
.verdict.v-bad  .kicker { color: var(--bad); }
.viewer-meta { font-family: var(--mono); font-size: 12px; color: var(--faint); margin-bottom: var(--sp-2); }

.block { border: 1px solid var(--line); background: var(--surface); border-radius: var(--r-md);
  padding: var(--sp-3); margin-bottom: var(--sp-3); }
.block > h3 { margin: 0 0 var(--sp-2); font-family: var(--mono); font-weight: 500; font-size: 13px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.kv { display: grid; grid-template-columns: auto 1fr; gap: 6px var(--sp-3); }
.kv dt { color: var(--muted); font-size: 14px; }
.kv dd { margin: 0; font-family: var(--mono); font-size: 14px; text-align: right; }

ul#nodes { list-style: none; margin: 0; padding: 0; }
ul#nodes li { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: var(--sp-3);
  padding: 12px 0; border-top: 1px solid var(--line); }
ul#nodes li:first-child { border-top: 0; }
ul#nodes .nname { display: flex; align-items: center; gap: 8px; }
ul#nodes .readout { font-family: var(--mono); font-size: 13px; color: var(--muted); }
ul#nodes .readout b { color: var(--text); font-weight: 500; }

/* status pills */
.pill { font-family: var(--mono); font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  padding: 3px 9px; border-radius: 999px; border: 1px solid; white-space: nowrap; }
.pill--ok   { color: var(--ok);   border-color: rgba(63,185,80,.4);  background: rgba(63,185,80,.1); }
.pill--warn { color: var(--warn); border-color: rgba(216,162,58,.4); background: rgba(216,162,58,.1); }
.pill--bad  { color: var(--bad);  border-color: rgba(241,90,79,.4);  background: rgba(241,90,79,.1); }
.pill--mut  { color: var(--muted); border-color: var(--line); background: var(--surface-2); }

/* CTAs */
.cta { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-4); }
.cta a { text-decoration: none; border-radius: var(--r-md); padding: 13px 20px;
  font-family: var(--mono); font-size: 14px; font-weight: 500; transition: filter .2s var(--ease), border-color .2s; }
.cta a.fill { background: var(--accent); color: #04101e; }
.cta a.ghost { border: 1px solid var(--line); color: var(--text); }
.cta a.fill:hover { filter: brightness(1.08); }
.cta a.ghost:hover { border-color: var(--accent); }
.ticket { margin-top: var(--sp-2); font-family: var(--mono); font-size: 12px; color: var(--faint); }
.ticket b { color: var(--accent); }

/* ---------- keyframes ---------- */
@keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes hum  { 0%,100% { opacity: .85; } 50% { opacity: 1; } }
@keyframes ping {
  0%   { box-shadow: 0 0 0 0 rgba(59,158,255,.5); }
  70%  { box-shadow: 0 0 0 7px rgba(59,158,255,0); }
  100% { box-shadow: 0 0 0 0 rgba(59,158,255,0); }
}
/* stagger stage reveal */
ol#stages li { animation: rise .4s var(--ease) both; }
ol#stages li:nth-child(1) { animation-delay: .02s; }
ol#stages li:nth-child(2) { animation-delay: .06s; }
ol#stages li:nth-child(3) { animation-delay: .10s; }
ol#stages li:nth-child(4) { animation-delay: .14s; }
ol#stages li:nth-child(5) { animation-delay: .18s; }
ol#stages li:nth-child(6) { animation-delay: .22s; }
ol#stages li:nth-child(7) { animation-delay: .26s; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  #signal .seg { stroke-dashoffset: 0; }
}
