/* StealthLogger — instrument readout
   Dark-only by decision: the page is a strip-chart recorder, and a strip chart
   in light mode is a contradiction. Three channel colours because the data has
   three axes; they appear only in the trace and its legend. */

:root {
  --ink:      #0A0D13;
  --panel:    #111621;
  --rule:     #1E2534;
  --rule-hi:  #2B3549;

  --text:     #E8ECF4;
  --muted:    #8A94A8;
  --dim:      #5C6678;

  --ch-x:     #FFC214;   /* brand amber */
  --ch-y:     #45C8E0;
  --ch-z:     #FF6E9C;

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

  --gut: clamp(20px, 5vw, 56px);
  --max: 1180px;
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--text);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--ch-x); text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible { outline: 2px solid var(--ch-x); outline-offset: 3px; }

.col {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gut);
}

/* ---------- Instrument bar ---------- */

.bar {
  border-bottom: 1px solid var(--rule);
  background: var(--ink);
  position: sticky;
  top: 0;
  z-index: 10;
}

.bar-inner {
  max-width: var(--max);
  margin-inline: auto;
  padding: 14px var(--gut);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.wordmark { font-weight: 600; }

.state { display: inline-flex; align-items: center; gap: 8px; color: var(--ch-x); text-decoration: none; }
.state:hover { text-decoration: underline; }

.led {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--ch-x);
  box-shadow: 0 0 0 3px rgb(255 194 20 / 0.14);
}

/* ---------- Hero ---------- */

.hero {
  padding-block: clamp(56px, 11vw, 130px) clamp(36px, 6vw, 64px);
  position: relative;
  overflow: hidden;          /* lets the device bleed past the band edges */
}

/* Decorative, so it's a background rather than an <img>: nothing to fall back
   to full size and stack above the headline if this stylesheet ever fails to
   load. `contain` keeps it inside the band — it never dictates the height. */
.hero::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  right: clamp(16px, 15%, 250px);   /* inset from the edge, capped on wide screens */
  width: min(30vw, 330px);
  background: url("assets/hero.png") no-repeat right center / contain;
  filter: drop-shadow(0 26px 55px rgb(0 0 0 / 0.6));
  z-index: 0;
  pointer-events: none;
}

.hero > .col { position: relative; z-index: 1; }

/* Below this, there's no horizontal room left to offset the device from the
   headline — the two lines it takes to write the full headline start
   running under the phone regardless of how narrow the image gets. Fading
   it out just made it invisible instead of solving the overlap. Drop it
   out of the absolute-positioned background trick and stack it in normal
   flow below the text instead, full opacity, like every other device shot
   on the page. */
@media (max-width: 900px) {
  .hero::after {
    position: static;
    display: block;
    width: min(58vw, 260px);
    aspect-ratio: 820 / 1367;
    margin: 32px auto 0;
    background-position: center;
    opacity: 1;
  }
}

.display {
  margin: 0;
  font-family: var(--mono);
  font-weight: 600;
  font-size: clamp(2.1rem, 7.4vw, 4.6rem);
  line-height: 1.03;
  letter-spacing: -0.045em;
}
.display span { display: block; }
.display span:nth-child(2) { color: var(--muted); }

.lede {
  margin: clamp(26px, 4vw, 40px) 0 0;
  max-width: 58ch;
  font-size: clamp(1rem, 1.5vw, 1.15rem);
  color: var(--muted);
  text-wrap: pretty;
}

/* Page-load sequence: three lines, then the lede. One moment, then stillness. */
@media (prefers-reduced-motion: no-preference) {
  .display span, .lede { animation: rise 620ms cubic-bezier(.2,.7,.3,1) backwards; }
  .display span:nth-child(1) { animation-delay: 40ms; }
  .display span:nth-child(2) { animation-delay: 130ms; }
  .display span:nth-child(3) { animation-delay: 220ms; }
  .lede { animation-delay: 340ms; }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- Signature: strip chart ---------- */

.scope {
  border-block: 1px solid var(--rule);
  background: var(--panel);
  padding-block: 22px 20px;
}

.scope-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
}

.eyebrow {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text);
}

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

.legend {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.legend li { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 14px; height: 2px; border-radius: 1px; }
.legend i[data-ch="x"] { background: var(--ch-x); }
.legend i[data-ch="y"] { background: var(--ch-y); }
.legend i[data-ch="z"] { background: var(--ch-z); }
.legend .rate { color: var(--dim); letter-spacing: 0.13em; }

#trace {
  display: block;
  width: 100%;
  height: clamp(120px, 20vw, 190px);
  margin-block: 14px 10px;
}

.row {
  margin: 0;
  font-family: var(--mono);
  font-size: clamp(0.66rem, 1.55vw, 0.8rem);
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.row .dim { letter-spacing: 0.08em; }

/* ---------- Bands ---------- */

.band { padding-block: clamp(52px, 8vw, 96px); }
.band + .band { border-top: 1px solid var(--rule); }
.band > .eyebrow { margin-bottom: 30px; }

/* ---------- Signal path ---------- */

/* The 1px gap over a rule-coloured background draws the hairlines between
   cells. That means any vacant cell shows up as a filled block, so the column
   count is pinned to 3 or 1 — never 2, which would leave the third item alone
   in a row beside an empty box. */
.path {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  background: var(--rule);
  border: 1px solid var(--rule);
}

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

.path li {
  background: var(--ink);
  padding: 26px 24px 24px;
  display: flex;
  flex-direction: column;
}

.path h3 {
  margin: 0 0 10px;
  font-family: var(--mono);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.path p { margin: 0; color: var(--muted); font-size: 0.95rem; text-wrap: pretty; }

/* Two classes (0,2,0) so this beats `.path p` (0,1,1) without !important. */
.path .artifact {
  margin-top: auto;
  padding-top: 20px;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--ch-x);
  word-break: break-all;
}
.path .artifact.done { color: var(--dim); }

/* ---------- Readout ---------- */

.readout {
  display: grid;
  gap: clamp(32px, 5vw, 64px);
  grid-template-columns: minmax(0, 1fr) minmax(0, 300px);
  align-items: center;
}

.readout-text p { margin: 0 0 16px; color: var(--muted); max-width: 54ch; text-wrap: pretty; }
.readout-text p:last-child { margin-bottom: 0; }

/* The screenshots are device frames on a transparent ground — no border or
   radius of our own, or we'd draw a rectangle around the phone. */
.shot-lock { margin: 0; }
.shot-lock img {
  width: 100%;
  height: auto;
  filter: drop-shadow(0 18px 40px rgb(0 0 0 / 0.55));
}

/* ---------- Screens ---------- */

.screens {
  display: grid;
  gap: clamp(20px, 3vw, 34px);
  grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
}

.screens figure { margin: 0; }

.screens img {
  width: 100%;
  height: auto;
  filter: drop-shadow(0 12px 28px rgb(0 0 0 / 0.5));
}

.screens figcaption {
  margin-top: 12px;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}

/* ---------- Spec ---------- */

.spec { margin: 0; border-top: 1px solid var(--rule); }

.spec > div {
  display: grid;
  grid-template-columns: minmax(140px, 230px) 1fr;
  gap: 6px 32px;
  padding: 15px 0;
  border-bottom: 1px solid var(--rule);
}

.spec dt {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--dim);
  padding-top: 3px;
}

.spec dd { margin: 0; color: var(--text); font-size: 0.97rem; }

/* ---------- Footer ---------- */

footer {
  border-top: 1px solid var(--rule);
  background: var(--panel);
  padding-block: clamp(40px, 6vw, 64px);
}

.foot-note {
  margin: 0;
  max-width: 60ch;
  font-size: 0.9rem;
  color: var(--muted);
}

/* ---------- Narrow ---------- */

@media (max-width: 820px) {
  .readout { grid-template-columns: 1fr; justify-items: start; }
  .shot-lock { max-width: 280px; }
  /* Same cap as .shot-lock, so a device screenshot is the same size
     wherever it appears on the page instead of ballooning to fill
     whatever grid column it happens to land in. */
  .screens img { max-width: 280px; display: block; margin-inline: auto; }
}

@media (max-width: 560px) {
  body { font-size: 16px; }
  .spec > div { grid-template-columns: 1fr; gap: 3px; }
  .legend { gap: 12px; }
}
