/* Spatial, the look Jesse picked on 11 November 2026: panes hung in a dark
   space, the outer two turned toward the reader, numbers that glow.

   One look, by choice, so there is no light theme. Layout, top to bottom, is
   the old Site Funnel page's: a row of tiles, then a stage of three panes
   (the funnel, by day, against typical), then flat sheets for reading rows,
   because a turned pane can only hold a few lines. */

@font-face {
  font-family: "Geist";
  src: url("vendor/geist.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}

:root {
  color-scheme: dark;

  /* Colour: a blue-black deep, lit from below the horizon. */
  --deep: #05070d;
  --mid: #0c1226;
  --horizon: #2b468a;
  --ink: #eaf0ff;
  --soft: #9fb0d9;
  --glow: #7fa2ff;
  --pale: #cfdcff;
  /* Two colours that mean something: a thing to look at, a thing going well. */
  --warn: #ffcf8a;
  --good: #a8f0c6;
  --edge: rgb(255 255 255 / 0.22);
  --rule: rgb(255 255 255 / 0.12);
  --glass-top: rgb(255 255 255 / 0.11);
  --glass-bottom: rgb(255 255 255 / 0.04);

  /* Type: one family. Weight does the work: 200 for a number, 300 to read. */
  --face: "Geist", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* How far the outer panes turn, and how far they turn back when read. */
  --turn: 20deg;
  --turn-reading: 6deg;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--deep);
  color: var(--ink);
  font-family: var(--face);
  font-weight: 300;
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

h1, h2, p, ul { margin: 0; }
ul { list-style: none; padding: 0; }
a { color: var(--ink); }
.soft { color: var(--soft); }
.fine { display: block; font-size: 12px; }
.mono { font-family: var(--mono); font-size: 12px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.space {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 2.4vw, 28px);
  padding: clamp(18px, 3vw, 32px) clamp(16px, 3vw, 40px);
  background: radial-gradient(120% 90% at 50% 115%, var(--horizon) 0%, var(--mid) 46%, var(--deep) 100%) fixed;
}

.top, .foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 10px 16px;
  color: var(--soft);
  font-size: 12px;
}

main {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: clamp(22px, 3vw, 40px);
  min-width: 0;
}

/* ── Buttons, and rows of choices ───────────────────────────────────────── */

button {
  padding: 8px 16px;
  border: 1px solid var(--edge);
  border-radius: 999px;
  background: rgb(255 255 255 / 0.07);
  color: var(--ink);
  font: inherit;
  cursor: pointer;
}

button:hover { background: rgb(255 255 255 / 0.14); }
button:disabled { opacity: 0.55; cursor: default; }

input:focus-visible, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--glow);
  outline-offset: 2px;
}

/* A row of choices where one is on. */
.chips { display: flex; flex-wrap: wrap; gap: 4px; }
.chips button { padding: 5px 12px; font-size: 12px; color: var(--soft); background: transparent; }
.chips button:hover { background: rgb(255 255 255 / 0.1); }
.chips button[aria-pressed="true"] { color: var(--deep); background: var(--ink); border-color: var(--ink); font-weight: 500; }
.chips button.x { color: var(--warn); border-color: rgb(255 207 138 / 0.45); }

/* ── The board ──────────────────────────────────────────────────────────── */

.board {
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 2.2vw, 26px);
  width: 100%;
  max-width: 1240px;
  margin: 0 auto;
}

.bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 20px; }
.title { margin-right: auto; font-size: 13px; font-weight: 400; letter-spacing: 0.08em; text-transform: uppercase; }
.title .soft { margin-left: 8px; letter-spacing: 0.02em; text-transform: none; }

.range { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--soft); }
.range[hidden] { display: none; }
.range input { width: auto; padding: 5px 8px; border-radius: 8px; font-size: 12px; }

.fault { color: var(--warn); font-size: 12px; }
.fault:empty { display: none; }
.counted { max-width: 96ch; font-size: 12px; }

/* The tiles: a number each, a hairline between, nothing boxed. */
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}

.tile { min-width: 0; padding: 16px 18px 14px; border-left: 1px solid var(--rule); }
.tile:first-child { padding-left: 0; border-left: 0; }

.tile .num {
  font-weight: 200;
  font-size: clamp(34px, 4.6vw, 62px);
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 34px rgb(127 162 255 / 0.5);
}

.tile.warn .num { color: var(--warn); text-shadow: 0 0 34px rgb(255 207 138 / 0.35); }
.tile .label { margin-top: 10px; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--soft); }
.tile .sub { margin-top: 2px; font-size: 12px; color: var(--soft); }

/* ── A pane, and the stage of three ─────────────────────────────────────── */

.pane {
  min-width: 0;
  padding: 20px;
  border: 1px solid var(--edge);
  border-radius: 20px;
  background: linear-gradient(180deg, var(--glass-top), var(--glass-bottom));
  box-shadow: 0 30px 70px rgb(0 0 0 / 0.55), inset 0 1px 0 rgb(255 255 255 / 0.25);
}

.pane h2, .sheet h2 {
  margin-bottom: 12px;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--soft);
}

.pane h1 { margin-bottom: 8px; font-size: 28px; font-weight: 300; letter-spacing: -0.02em; }

.pane-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 4px 12px; }

.stage {
  display: grid;
  grid-template-columns: 1fr 1.35fr 1fr;
  gap: 16px;
  align-items: center;
  perspective: 1500px;
}

.stage .pane { transition: transform 320ms cubic-bezier(0.2, 0.7, 0.2, 1); }
.stage .left { transform: rotateY(var(--turn)); transform-origin: right center; }
.stage .right { transform: rotateY(calc(var(--turn) * -1)); transform-origin: left center; }

/* A pane you are reading turns to face you. */
.stage .left:hover, .stage .left:focus-within { transform: rotateY(var(--turn-reading)); }
.stage .right:hover, .stage .right:focus-within { transform: rotateY(calc(var(--turn-reading) * -1)); }

.line { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.figure { font-size: 22px; font-weight: 300; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.figure.low { color: var(--warn); }
.figure.good { color: var(--good); }
.figure.few { color: var(--soft); }

/* The funnel: a bar a stage, each against the top of the funnel. */
.frow { padding: 10px 0 8px; border-top: 1px solid var(--rule); }
.track { height: 6px; margin: 8px 0 6px; border-radius: 3px; background: rgb(255 255 255 / 0.08); overflow: hidden; }
.track i {
  display: block;
  width: calc(var(--share) * 100%);
  min-width: 3px;
  height: 100%;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--glow), var(--pale));
  box-shadow: 0 0 12px rgb(127 162 255 / 0.6);
}
.track i.zero { display: none; }
#funnel-note { margin-top: 10px; }
#funnel-note:empty { display: none; }

/* By day: a bar a slot, a dot over a slot somebody joined in. */
.key { display: flex; gap: 14px; font-size: 11px; color: var(--soft); }
.key span { display: inline-flex; align-items: center; gap: 6px; }
.k-bar { width: 9px; height: 9px; border-radius: 1px; background: var(--pale); }
.k-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--good); }

.days { display: flex; align-items: flex-end; gap: 3px; height: 190px; }
.day {
  flex: 1;
  min-width: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 4px;
}
/* The top 34px of a column is kept for its number and its dot. */
.day .vis {
  flex: none;
  width: 100%;
  height: calc(var(--share) * (100% - 34px));
  min-height: 1px;
  border-radius: 2px 2px 0 0;
  background: linear-gradient(180deg, var(--pale), rgb(127 162 255 / 0.3));
}
.day:hover .vis { background: #ffffff; }
.day .dnum { font-size: 10px; line-height: 1; color: var(--soft); font-variant-numeric: tabular-nums; }
.day .join { flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--good); box-shadow: 0 0 8px var(--good); }

.ticks { display: flex; gap: 3px; margin-top: 6px; font-size: 10px; color: var(--soft); }
.ticks span { flex: 1; min-width: 0; white-space: nowrap; }

/* Against typical: two ranges in lanes of their own, our rate a mark across both. */
.brow { padding: 10px 0 12px; border-top: 1px solid var(--rule); }
.scale { position: relative; display: grid; gap: 4px; margin: 10px 0 8px; }
.lane { position: relative; height: 7px; border-radius: 4px; background: rgb(255 255 255 / 0.07); }
.lane i { position: absolute; top: 0; bottom: 0; left: var(--from); width: var(--width); border-radius: 4px; }
.lane .cold { background: rgb(143 176 255 / 0.6); }
.lane .warm { background: rgb(255 207 138 / 0.65); }
.scale .ours { position: absolute; top: -4px; bottom: -4px; left: var(--at); width: 2px; margin-left: -1px; background: #ffffff; box-shadow: 0 0 8px #ffffff; }
.scale .ours.few { background: var(--soft); box-shadow: none; }

.verdict { white-space: nowrap; }
.verdict.low { color: var(--warn); }
.verdict.good { color: var(--good); }
.verdict.few { color: var(--soft); }

.axis { position: relative; height: 14px; font-size: 10px; color: var(--soft); border-top: 1px solid var(--rule); padding-top: 4px; }
.axis span { position: absolute; left: var(--at); transform: translateX(-50%); }
.axis span:first-child { transform: none; }
.axis span:last-child { transform: translateX(-100%); }

/* ── The flat sheets under the stage ────────────────────────────────────── */

.sheet { width: 100%; max-width: 1240px; margin: 0 auto; min-width: 0; }
.sheet-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px; margin-bottom: 10px; }
.sheet-head h2 { margin: 0 auto 0 0; }

.summary { display: flex; flex-wrap: wrap; gap: 4px 24px; margin-bottom: 12px; color: var(--soft); font-size: 12px; }
.summary b { margin-right: 4px; font-size: 20px; font-weight: 300; color: var(--ink); font-variant-numeric: tabular-nums; }

.sheet .scroll {
  overflow-x: auto;
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: rgb(5 7 13 / 0.45);
}

table { width: 100%; min-width: 640px; border-collapse: collapse; font-variant-numeric: tabular-nums; }
th, td { padding: 9px 14px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--rule); overflow-wrap: anywhere; }
th { font-size: 11px; font-weight: 400; letter-spacing: 0.06em; text-transform: uppercase; color: var(--soft); white-space: nowrap; }
tbody tr:last-child td { border-bottom: 0; }
th.r, td.r { text-align: right; }
td.when { white-space: nowrap; color: var(--soft); }
/* An address or a plan's name is kept in one piece; the sheet scrolls sideways if it must. */
td.whole { white-space: nowrap; overflow-wrap: normal; }
td.r { color: var(--soft); }
td.r.many { color: var(--ink); }
tr.out td { opacity: 0.55; }

.why p + p { margin-top: 6px; padding-top: 6px; border-top: 1px dotted var(--rule); }

.kind { font-size: 12px; color: var(--soft); }
.kind.press { color: var(--ink); }

.tag {
  display: inline-block;
  padding: 0 7px;
  border: 1px solid rgb(255 207 138 / 0.45);
  border-radius: 999px;
  font-size: 11px;
  color: var(--warn);
  white-space: nowrap;
}

/* A visitor's id, as a button that lists what that visitor did. */
button.who {
  margin: 0 4px 2px 0;
  padding: 1px 8px;
  border-color: var(--rule);
  background: transparent;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--soft);
}
button.who:hover { color: var(--ink); border-color: var(--edge); }

.more { display: flex; align-items: center; gap: 12px; margin-top: 10px; font-size: 12px; }

/* ── Sign in, and messages ──────────────────────────────────────────────── */

.gate, .message { width: 100%; max-width: 420px; margin: auto; }

form { display: grid; gap: 8px; margin-top: 18px; }
label { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--soft); }

input {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--edge);
  border-radius: 12px;
  background: rgb(5 7 13 / 0.5);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
}

form button { margin-top: 6px; padding: 11px 16px; background: var(--ink); color: var(--deep); border-color: var(--ink); font-weight: 500; }
form button:hover { background: #ffffff; }

.note { margin-top: 14px; min-height: 1.45em; }
.hint { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--rule); font-size: 12px; color: var(--soft); }
.waiting { margin: auto; color: var(--soft); }
.foot-actions { display: flex; gap: 8px; }

/* ── Which parts each state shows ───────────────────────────────────────── */

#waiting, #gate, #board, #people, #activity, #message, #sites, .foot-actions, #updated { display: none; }

body[data-state="loading"] #waiting { display: block; }
body[data-state="signedout"] #gate { display: block; }
body[data-state="ready"] #board { display: flex; }
body[data-state="ready"] #people,
body[data-state="ready"] #activity { display: block; }
body[data-state="ready"] #sites { display: flex; }
body[data-state="ready"] #updated { display: inline; }
body[data-state="ready"] .foot-actions,
body[data-state="denied"] .foot-actions { display: flex; }
body[data-state="denied"] #message,
body[data-state="error"] #message { display: block; }
body[data-state="denied"] #refresh { display: none; }

/* ── Narrow screens: the panes stack and face you ───────────────────────── */

@media (max-width: 900px) {
  .stage { grid-template-columns: 1fr; perspective: none; }
  .stage .centre { order: -1; }
  .stage .left, .stage .right,
  .stage .left:hover, .stage .right:hover,
  .stage .left:focus-within, .stage .right:focus-within { transform: none; }
  .tile { padding-left: 0; border-left: 0; }
  .days { height: 150px; }
}

@media (prefers-reduced-motion: reduce) {
  .stage .pane { transition: none; }
}
