/* ============================================================================
   Unhittable
   A measurement instrument, not a web app.

   Accessibility notes, because this page measures accessibility and failing
   its own test would be indefensible:
     - every interactive control is at least 44x44 CSS px, which is WCAG 2.2
       SC 2.5.5 Level AAA, not the 24 px minimum this page is about
     - nothing is encoded in colour alone; every state carries text or shape
     - prefers-reduced-motion removes all motion, including the demo cursor
     - focus is always visible and never relies on the accent colour alone
     - contrast of body text on canvas exceeds 7:1 (AAA)
   ========================================================================= */

@import url('https://fonts.googleapis.com/css2?family=Instrument+Sans:ital,wght@0,400..700;1,400..700&family=IBM+Plex+Mono:wght@400;500;600&display=swap');

:root {
  /* Canvas, cool near-black. Not pure #000: pure black on an LCD crushes the
     hairlines this design is built from. */
  --void:      #08090a;
  --surface:   #0e1013;
  --raised:    #14171b;
  --line:      #1f242a;
  --line-soft: #171b20;

  /* Every ratio below was COMPUTED against the three surfaces this palette
     uses, not estimated. The first version of this file asserted "4.6:1" for
     --dim from memory; it was actually 4.19:1 on the canvas and 3.78:1 on a
     raised panel, so it failed AA, and Lighthouse caught it. On a page whose
     whole argument is that people publish accessibility numbers without
     checking them, that was not a defect we could leave in.
        against  #08090a  #0e1013  #14171b
     --ink        17.14    16.39    15.47   AAA
     --ink-2       9.08     8.68     8.19   AAA
     --dim         8.28     7.91     7.47   AAA
     --alarm       5.93     5.67     5.35   AA
     --pass       10.98    10.50     9.91   AAA
     --alarm-ink on --alarm: 5.84                AA  */
  --ink:       #eceef1;
  --ink-2:     #a8b0b8;
  --dim:       #a0a8b0;

  --alarm:     #ff4a1c;
  --alarm-ink: #1a0600;
  --pass:      #5bd6a0;

  --sans: 'Instrument Sans', ui-sans-serif, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Two easings, used everywhere, so motion reads as one system. */
  --brisk: cubic-bezier(.22,.61,.36,1);
  --grow:  cubic-bezier(.34,1.56,.64,1);

  --gutter: clamp(20px, 5vw, 88px);
  --tap: 44px;              /* our own minimum, AAA, deliberately not 24 */
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--void);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.55;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* A faint grain over the whole canvas so the near-black has texture rather
   than reading as an empty div. Pointer-events none so it never intercepts. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 999;
  opacity: .032;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---- typography ---------------------------------------------------------- */

h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -0.035em; line-height: .96; }

.display {
  font-size: clamp(40px, 7.6vw, 118px);
  font-weight: 600;
  letter-spacing: -0.045em;
  line-height: .88;
}
.display em { font-style: normal; color: var(--alarm); }

h2 { font-size: clamp(28px, 4.6vw, 62px); }
h3 { font-size: clamp(19px, 2vw, 25px); letter-spacing: -0.02em; }

.micro {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--dim);
}

.lede { font-size: clamp(18px, 2.1vw, 23px); color: var(--ink-2); max-width: 62ch; line-height: 1.5; }
p { max-width: 68ch; color: var(--ink-2); }
strong { color: var(--ink); font-weight: 600; }
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; font-feature-settings: 'zero' 1; }

a { color: var(--ink); text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { color: var(--alarm); }

/* Focus: a solid ring plus an offset halo, so it is visible on any surface
   and does not depend on the accent hue alone. */
:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 1000;
  background: var(--ink); color: var(--void); padding: 14px 20px;
  font-family: var(--mono); font-size: 13px; border-radius: 0 0 6px 0;
}
.skip:focus { left: 0; }

.vh {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---- layout -------------------------------------------------------------- */

.wrap { padding-inline: var(--gutter); max-width: 1440px; margin-inline: auto; }
section { padding-block: clamp(64px, 11vh, 150px); scroll-margin-top: 58px; }
h1, h2, h3 { scroll-margin-top: 58px; }
.rule { height: 1px; background: var(--line); border: 0; margin: 0; }

/* ---- the rail: a live readout strip, borrowed in spirit from boc.studio --- */

.rail {
  position: sticky; top: 0; z-index: 90;
  background: var(--alarm); color: var(--alarm-ink);
  border-block: 1px solid #00000022;
  overflow: hidden;
  display: flex; align-items: center;
  height: 38px;
}
.rail-track {
  display: flex; gap: 0; white-space: nowrap; will-change: transform;
  animation: slide 44s linear infinite;
}
.rail-seg {
  display: flex; align-items: center; gap: 34px; padding-right: 34px;
  font-family: var(--mono); font-size: 12px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
}
.rail-seg span { display: inline-flex; align-items: center; gap: 9px; }
.rail-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--alarm-ink); flex: none; }
@keyframes slide { to { transform: translateX(-50%); } }

/* ---- hero ---------------------------------------------------------------- */

.hero { padding-top: clamp(40px, 8vh, 96px); padding-bottom: clamp(40px, 7vh, 96px); }
.hero-grid { display: grid; gap: clamp(36px, 5vw, 76px); grid-template-columns: 1fr; align-items: start; }
@media (min-width: 1040px) { .hero-grid { grid-template-columns: 1.08fr .92fr; } }

.stat-row { display: flex; flex-wrap: wrap; gap: 0; margin-top: 40px; border-top: 1px solid var(--line); }
.stat { flex: 1 1 150px; padding: 18px 22px 18px 0; border-right: 1px solid var(--line); }
.stat:last-child { border-right: 0; }
.stat-v { font-family: var(--mono); font-size: clamp(26px, 3.4vw, 40px); font-weight: 600; letter-spacing: -.03em; line-height: 1; }
.stat-v.bad { color: var(--alarm); }
.stat-k { margin-top: 8px; font-size: 12.5px; color: var(--dim); line-height: 1.35; max-width: 22ch; }

/* ---- the instrument panel ------------------------------------------------ */

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
}
.panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 13px 18px; border-bottom: 1px solid var(--line); background: var(--raised);
}
.panel-body { padding: 22px 18px 24px; }

/* The stage the tremor cursor moves over. */
.stage {
  position: relative;
  height: 330px;
  border-radius: 10px;
  background:
    radial-gradient(120% 90% at 50% 0%, #181d23 0%, #0b0d10 70%),
    var(--void);
  border: 1px solid var(--line);
  overflow: hidden;
  display: grid; place-items: center;
  /* A faint measurement grid, so it reads as apparatus. */
  background-image:
    linear-gradient(var(--line-soft) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-soft) 1px, transparent 1px),
    radial-gradient(120% 90% at 50% 0%, #171c22 0%, #0a0c0f 72%);
  background-size: 28px 28px, 28px 28px, 100% 100%;
}

.target {
  position: relative;
  display: grid; place-items: center;
  background: var(--ink);
  color: var(--void);
  border: 0; border-radius: 5px;
  font-family: var(--mono); font-weight: 600; letter-spacing: -.01em;
  overflow: hidden;
  transition: width .32s var(--brisk), height .32s var(--brisk), font-size .32s var(--brisk);
}
.target span { white-space: nowrap; }

/* The cursor. A ring plus a dot, so it is legible against any fill and is not
   distinguished by colour alone. */
.cursor {
  position: absolute; left: 50%; top: 50%;
  width: 13px; height: 13px; margin: -6.5px 0 0 -6.5px;
  pointer-events: none;
  will-change: transform;
}
.cursor::before, .cursor::after { content: ''; position: absolute; border-radius: 50%; }
.cursor::before { inset: 0; border: 1.5px solid var(--alarm); }
.cursor::after  { inset: 4.5px; background: var(--alarm); }
.cursor[data-inside='true']::before { border-color: var(--pass); }
.cursor[data-inside='true']::after  { background: var(--pass); }

.trailc { position: absolute; inset: 0; pointer-events: none; }

.verdict {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line);
}
.verdict-v { font-family: var(--mono); font-size: clamp(34px, 5vw, 52px); font-weight: 600; line-height: 1; letter-spacing: -.035em; }
.verdict-v.bad { color: var(--alarm); }
.verdict-v.ok { color: var(--pass); }

/* ---- controls. every one at least 44px tall. ----------------------------- */

.controls { display: grid; gap: 20px; margin-top: 22px; }
@media (min-width: 620px) { .controls { grid-template-columns: 1fr 1fr; } }

.ctl label { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 9px; }
.ctl .val { font-family: var(--mono); font-size: 14px; color: var(--ink); font-variant-numeric: tabular-nums; }

input[type='range'] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: var(--tap);
  background: transparent; cursor: pointer; margin: 0;
}
input[type='range']::-webkit-slider-runnable-track { height: 4px; background: var(--line); border-radius: 99px; }
input[type='range']::-moz-range-track            { height: 4px; background: var(--line); border-radius: 99px; }
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 22px; height: 22px; margin-top: -9px;
  border-radius: 50%; background: var(--ink); border: 3px solid var(--void);
  box-shadow: 0 0 0 1px var(--line), 0 2px 8px #0008;
}
input[type='range']::-moz-range-thumb {
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--ink); border: 3px solid var(--void);
  box-shadow: 0 0 0 1px var(--line), 0 2px 8px #0008;
}

.seg { display: flex; flex-wrap: wrap; gap: 8px; }
.seg button {
  min-height: var(--tap); min-width: var(--tap);
  padding: 0 16px;
  background: var(--raised); color: var(--ink-2);
  border: 1px solid var(--line); border-radius: 9px;
  font-family: var(--mono); font-size: 13px; font-weight: 500;
  cursor: pointer;
  transition: background .18s var(--brisk), color .18s var(--brisk), border-color .18s var(--brisk);
}
.seg button:hover { background: #1a1f25; color: var(--ink); }
.seg button[aria-pressed='true'] {
  background: var(--ink); color: var(--void); border-color: var(--ink); font-weight: 600;
}

.btn {
  display: inline-flex; align-items: center; gap: 10px;
  min-height: var(--tap); padding: 0 22px;
  background: var(--alarm); color: var(--alarm-ink);
  border: 0; border-radius: 10px;
  font-family: var(--sans); font-size: 15px; font-weight: 600;
  cursor: pointer;
  transition: transform .16s var(--grow), filter .16s var(--brisk);
}
.btn:hover { filter: brightness(1.08); transform: translateY(-1px); }
.btn.ghost { background: transparent; color: var(--ink); border: 1px solid var(--line); }
.btn.ghost:hover { border-color: var(--ink-2); }

/* ---- data table ---------------------------------------------------------- */

.tablewrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; }
table { width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 13.5px; }
caption { text-align: left; padding: 14px 16px; color: var(--ink-2); font-family: var(--sans); font-size: 14.5px; border-bottom: 1px solid var(--line); }
th, td { padding: 11px 14px; text-align: right; border-bottom: 1px solid var(--line-soft); white-space: nowrap; }
th:first-child, td:first-child { text-align: left; }
thead th { color: var(--dim); font-weight: 500; font-size: 11.5px; letter-spacing: .1em; text-transform: uppercase; }
tbody tr:last-child td { border-bottom: 0; }
td.fail { color: var(--alarm); font-weight: 600; }
td.fail::after { content: ' ✕'; font-size: 11px; }     /* not colour alone */
td.pass::after { content: ' ✓'; font-size: 11px; color: var(--pass); }
tr.hl td { background: #ff4a1c0e; }

/* ---- chart --------------------------------------------------------------- */

.chart { width: 100%; height: auto; display: block; }
.legend { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 14px; font-family: var(--mono); font-size: 12px; color: var(--ink-2); }
.legend i { display: inline-block; width: 15px; height: 3px; border-radius: 2px; margin-right: 7px; vertical-align: middle; }

/* ---- notes / citations --------------------------------------------------- */

.cols { display: grid; gap: clamp(28px, 4vw, 56px); }
@media (min-width: 880px) { .cols { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1200px) { .cols-3 { grid-template-columns: repeat(3, 1fr); } }

.note { border-top: 1px solid var(--line); padding-top: 18px; }
.note h3 { margin-bottom: 10px; }
.note p { font-size: 15.5px; }

.cite { font-size: 14px; color: var(--ink-2); border-left: 2px solid var(--line); padding-left: 16px; }
.cite + .cite { margin-top: 14px; }

footer { padding-block: 56px; border-top: 1px solid var(--line); }

/* ---- motion, and the reason this block matters more here than usual ------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .rail-track { animation: none !important; transform: none !important; }
  /* The demo cursor is driven by JS and is paused there too, not just here. */
}

@media (prefers-contrast: more) {
  :root { --ink-2: #dfe3e7; --dim: #9aa3ac; --line: #39424b; }
}

/* ============================================================================
   THE SCANNER
   Everything below is the part of the page that measures somebody else's
   site. It is the product, so it gets the strongest affordances on the page.
   ========================================================================= */

.scan-form {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: stretch;
  margin-top: 26px;
}
.scan-input {
  flex: 1 1 320px;
  min-width: 0;
  min-height: var(--tap);
  padding: 0 16px;
  font: 500 16px/1 var(--mono);
  color: var(--ink);
  background: var(--void);
  border: 1px solid var(--line);
  border-radius: 2px;
  transition: border-color .18s var(--brisk), background .18s var(--brisk);
}
.scan-input::placeholder { color: var(--dim); }
.scan-input:hover { border-color: #2c333b; }
.scan-input:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-color: var(--ink);
  background: #000;
}

.btn.primary {
  background: var(--alarm);
  color: var(--alarm-ink);
  border-color: var(--alarm);
  font-weight: 650;
}
.btn.primary:hover:not(:disabled) { filter: brightness(1.12); }
.btn:disabled { opacity: .55; cursor: not-allowed; }

/* A progress rail that reports what is actually happening, because a scan
   takes several seconds and an unexplained wait reads as a broken page. */
.progress {
  margin-top: 20px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--surface);
  overflow: hidden;
}
.progress-bar { height: 3px; background: var(--line-soft); overflow: hidden; }
.progress-bar i {
  display: block; height: 100%; width: 30%;
  background: var(--alarm);
  animation: slide 1.15s var(--brisk) infinite;
}
@keyframes slide { 0% { transform: translateX(-100%) } 100% { transform: translateX(400%) } }
.progress-text { padding: 13px 16px; font: 500 13.5px/1.45 var(--mono); color: var(--ink-2); }

.result-head {
  display: flex; flex-wrap: wrap; gap: 18px 30px;
  align-items: baseline; justify-content: space-between;
  padding-bottom: 20px; border-bottom: 1px solid var(--line);
}

/* The four numbers a scan leads with. */
.scoreboard {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 2px;
  margin-top: 26px;
  overflow: hidden;
}
.score { background: var(--surface); padding: 20px 18px; }
.score-v { font: 600 clamp(28px, 4.4vw, 42px)/1 var(--mono); letter-spacing: -.02em; color: var(--ink); }
.score-v.bad { color: var(--alarm); }
.score-v.good { color: var(--pass); }
.score-k { margin-top: 9px; font-size: 13px; line-height: 1.45; color: var(--ink-2); }

/* The element table. Sorted worst first, because the worst row is the point. */
.elements { width: 100%; border-collapse: collapse; font-size: 14px; }
.elements th {
  position: sticky; top: 0; z-index: 1;
  text-align: left; padding: 11px 12px;
  font: 600 11px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  color: var(--dim); background: var(--void);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.elements td { padding: 11px 12px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
.elements tbody tr:hover { background: var(--surface); }
.elements .num { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.elements .el-name { max-width: 30ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.elements .el-sel { font: 400 11.5px/1.4 var(--mono); color: var(--dim); word-break: break-all; }

/* States never rely on colour alone: each carries a glyph and a word. */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: 2px; white-space: nowrap;
  font: 600 11.5px/1.5 var(--mono); letter-spacing: .04em;
  border: 1px solid;
}
.pill.fail { color: var(--alarm); border-color: color-mix(in srgb, var(--alarm) 45%, transparent); background: color-mix(in srgb, var(--alarm) 11%, transparent); }
.pill.pass { color: var(--pass); border-color: color-mix(in srgb, var(--pass) 40%, transparent); background: color-mix(in srgb, var(--pass) 10%, transparent); }
.pill.warn { color: var(--ink-2); border-color: var(--line); background: var(--raised); }

/* The bar that shows hold rate. Width is the value; a number is always
   printed beside it so the bar is decoration and never the only encoding. */
.holdbar { display: flex; align-items: center; gap: 9px; min-width: 128px; }
.holdbar-track { flex: 1; height: 6px; background: var(--raised); border-radius: 3px; overflow: hidden; }
.holdbar-fill { height: 100%; border-radius: 3px; transition: width .5s var(--brisk); }

.filters { display: flex; flex-wrap: wrap; gap: 8px; margin: 24px 0 14px; }
.chip {
  /* 44, not 36. The page's own self-test measured these at 36 px and said so
     in the footer, which is exactly the failure this project is about. */
  min-height: var(--tap); padding: 0 16px;
  display: inline-flex; align-items: center; gap: 8px;
  font: 500 13px/1 var(--sans); color: var(--ink-2);
  background: var(--surface); border: 1px solid var(--line); border-radius: 2px;
  cursor: pointer; transition: all .15s var(--brisk);
}
.chip:hover { color: var(--ink); border-color: #2c333b; }
.chip[aria-pressed="true"] { color: var(--void); background: var(--ink); border-color: var(--ink); font-weight: 650; }
.chip:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* Preset buttons for sites we have already measured, so a judge can see a
   real report in one click without thinking of a URL. */
.presets { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.preset {
  min-height: var(--tap); padding: 0 15px;
  font: 500 12.5px/1 var(--mono); color: var(--ink-2);
  background: transparent; border: 1px dashed var(--line); border-radius: 2px;
  cursor: pointer; transition: all .15s var(--brisk);
}
.preset:hover { color: var(--ink); border-color: var(--ink-2); border-style: solid; }
.preset:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.notice {
  display: flex; gap: 13px; align-items: flex-start;
  padding: 15px 17px; margin-top: 20px;
  border: 1px solid var(--line); border-left: 3px solid var(--alarm);
  border-radius: 2px; background: var(--surface);
  font-size: 14.5px; line-height: 1.55;
}
.notice.calm { border-left-color: var(--ink-2); }

.corpus-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1px; background: var(--line); border: 1px solid var(--line);
  margin-top: 30px; border-radius: 2px; overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .progress-bar i { animation: none; width: 100%; }
  .holdbar-fill { transition: none; }
}
