/* carparks.je admin portal — light only, Overpass, app tokens.
   Colour discipline mirrors the iOS app: the tier triple appears ONLY on
   data (counts, sparklines, incident marks, fault text); chrome is ink,
   greys, and brand blue for interaction. No pills, no dots, no boxes. */

:root {
  --brand: #0075FF;
  --safe: #11E787;
  --busy: #F59E0B;
  --full: #DC2626;
  --ink: #111114;
  --muted: #75757c;
  --faint: #b9b9c0;
  --hairline: #ececef;
  --wash: rgba(0, 117, 255, 0.04);
  --bg: #ffffff;
  --field: #f4f4f6;
  /* safe-text is the app's tierSafe verbatim — the hero is big and bold
     enough to carry the brand mint straight. busy/full stay darkened
     for smaller text. */
  --safe-text: #11E787;
  --busy-text: #92510a;
  --full-text: #b91c1c;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: "Overpass", -apple-system, sans-serif;
  font-size: 15px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--brand); text-decoration: none; }
button { font-family: inherit; }

/* ── Sign-in page ─────────────────────────────────────────────────── */

.gate {
  min-height: 100vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; padding: 24px;
  text-align: center;
}
.gate > div { display: flex; flex-direction: column; align-items: center; }
.gate > div[hidden] { display: none; }
.gate .logo-big { width: clamp(120px, 16vw, 170px); height: auto; margin-bottom: 26px; }
/* Wordmark + h1 form one lockup: "carparks.je / Admin portal". */
.gate .wordmark {
  font-weight: 800; font-size: 27px; color: var(--brand);
  letter-spacing: -0.02em; margin-bottom: 2px;
}
.gate h1 {
  font-size: 34px; font-weight: 800; letter-spacing: -0.02em;
  margin: 0 0 10px; text-align: center;
}
.gate .sub {
  color: var(--muted); margin: 0 0 36px; text-align: center; max-width: 380px;
}
.gate form { width: min(340px, 86vw); margin: 34px auto 0; display: flex; flex-direction: column; gap: 12px; }
.gate input[type=email] {
  font-family: inherit; font-size: 16px; padding: 13px 16px;
  border: none; border-radius: 12px; background: var(--field); color: var(--ink);
  outline: none; transition: box-shadow .15s;
}
.gate input[type=email]:focus { box-shadow: 0 0 0 3px rgba(0,117,255,.3); }
.gate button {
  font-size: 16px; font-weight: 700; padding: 13px 16px; border: none;
  border-radius: 12px; background: var(--brand); color: #fff; cursor: pointer;
  transition: opacity .15s;
}
.gate button:hover { opacity: .92; }
.gate .msg { margin-top: 22px; color: var(--muted); text-align: center; max-width: 360px; }
.gate .msg.err { color: var(--full-text); }
.gate .sent h1 { font-size: 26px; }
.gate footer {
  position: fixed; bottom: 22px; color: var(--faint); font-size: 12.5px;
}

/* ── App shell ────────────────────────────────────────────────────── */

.bar {
  display: flex; align-items: baseline; gap: 18px;
  padding: 16px 28px 12px;
}
a.wordmark, .bar .wordmark { font-weight: 800; font-size: 16px; color: var(--brand);
  display: flex; align-items: center; gap: 9px; text-decoration: none; }
.bar .wordmark img { height: 22px; width: auto; display: block; }
.bar .wordmark span { color: var(--faint); font-weight: 600; }
.bar nav { margin-left: auto; display: flex; gap: 18px; align-items: baseline; }
.bar nav a { font-weight: 700; color: var(--muted); font-size: 14px; }
.bar nav a.active { color: var(--ink); }
.bar .who { color: var(--faint); font-size: 13px; }
.bar .who button {
  background: none; border: none; color: var(--faint); cursor: pointer;
  font-size: 13px; padding: 0; margin-left: 8px; text-decoration: underline;
}

/* ── Overview grid ────────────────────────────────────────────────── */

/* Aggregate status band: quiet when healthy, red-washed when degraded. */
.topline {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; flex-wrap: wrap;
  padding: 18px 30px 20px;
}
.topline.degraded { background: color-mix(in srgb, var(--full) 5%, white); }
.topline .tl-word {
  font-size: clamp(22px, 2.4vw, 30px); font-weight: 800; letter-spacing: -0.02em;
  line-height: 1.15;
}
.topline.degraded .tl-word { color: var(--full-text); }
.topline .tl-sub { font-size: 14px; margin-top: 2px; }
.topline .tl-note { color: var(--muted); font-size: 13px; margin-top: 1px; }
.topline .tl-sub a { color: var(--full-text); font-weight: 700; }
.topline .tl-stats { display: flex; gap: 38px; align-items: flex-end; }
.topline .stat .n { font-size: clamp(20px, 2vw, 26px); }

/* Hairline lattice via inset shadows — no background patches on the
   ragged last row, tiles stretch to fill the viewport on desktop. */
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  min-height: calc(100vh - 172px);
  grid-auto-rows: 1fr;
  border-top: 1px solid var(--hairline);
}
.tile {
  background: var(--bg);
  box-shadow: inset -1px -1px 0 var(--hairline);
  padding: clamp(18px, 2vw, 30px) clamp(20px, 2.2vw, 34px);
  cursor: pointer; transition: background .15s;
  display: flex; flex-direction: column; min-height: 200px;
}
.tile:hover { background: #fafafc; }
.tile h2 {
  margin: 0 0 2px; font-weight: 700; letter-spacing: -0.01em;
  font-size: clamp(16px, 1.4vw, 20px);
}
/* Health is the hero on a health dashboard; spaces are supporting data. */
.tile .hero {
  font-size: clamp(30px, 2.9vw, 44px); font-weight: 800;
  letter-spacing: -0.025em; line-height: 1.15;
}
.tile .hero.ok { color: var(--safe-text); }
.tile .hero.bad { color: var(--full-text); }
.tile .sub {
  color: var(--muted); font-size: clamp(13px, 1.05vw, 15.5px);
  min-height: 46px; margin-top: 2px;
  /* Whole line shares the odometer's tabular digit widths, so "66" and
     "137" space identically. */
  font-variant-numeric: tabular-nums;
}
.tile .sub b { color: var(--ink); font-weight: 800; font-variant-numeric: tabular-nums; }
.tile .sub .fault-line { color: var(--full-text); font-weight: 700; display: block; }

/* Odometer digits (Apple .contentTransition(.numericText()) feel).
   Row height MUST equal the surrounding line-height (1.5) so the
   rolling digits share the text baseline exactly. */
.od { display: inline-flex; overflow: hidden; height: 1.5em; vertical-align: bottom;
  font-variant-numeric: tabular-nums; }
.od .ch { display: inline-block; }
.od .col { display: inline-block; width: 1ch; text-align: center; }
.od .col .strip {
  display: block; transition: transform .5s cubic-bezier(.25, .8, .25, 1);
}
.od .col .strip span { display: block; height: 1.5em; line-height: 1.5em; }

/* Skeleton shimmer */
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
.skel {
  border-radius: 6px;
  background: linear-gradient(90deg, #f0f0f3 25%, #fafafb 50%, #f0f0f3 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s linear infinite;
  color: transparent !important; user-select: none;
}
.skel-block { display: block; }
/* Clamped: tall desktop tiles stop growing bars into towers (extra
   height becomes breathing room above), short phone tiles get a real
   chart instead of a strip. */
.tile .spark { flex: 1; min-height: 72px; max-height: 150px;
  margin-top: auto; padding-top: 12px; position: relative; }
/* The caption strip is reserved: bars can never overlap the labels. */
.tile .spark svg { position: absolute; inset: 0 0 18px 0; width: 100%; height: calc(100% - 18px); }
.tile .spark rect.b-pred { opacity: 0.55; }
.tile .spark rect.b-stale { opacity: 0.8; }
.spark-cap {
  position: absolute; bottom: -2px; font-size: 10.5px; font-weight: 700;
  color: var(--faint); letter-spacing: .04em; text-transform: uppercase;
  pointer-events: none;
}
.spark-cap.cap-top { top: 0; bottom: auto; }

/* Shared hover tooltip for charts */
#tip {
  position: fixed; z-index: 10; pointer-events: none;
  background: var(--ink); color: #fff; border-radius: 8px;
  padding: 6px 10px; font-size: 12.5px; line-height: 1.35;
  transform: translate(-50%, calc(-100% - 10px));
  white-space: nowrap; display: none;
}
#tip b { font-size: 15px; }
#tip .k { color: #b9b9c0; }

/* Ongoing-incident banner on the park page */
a.incident {
  display: block; background: color-mix(in srgb, var(--full) 7%, white);
  padding: 16px 20px; border-radius: 12px; margin: 0 0 26px;
  color: var(--ink);
}
a.incident .head { color: var(--full-text); font-weight: 800; font-size: 16px; }
a.incident .body { color: var(--muted); font-size: 13.5px; margin-top: 1px; }
a.incident:hover { background: color-mix(in srgb, var(--full) 10%, white); }

/* ── Park page ────────────────────────────────────────────────────── */

.page { max-width: 1060px; margin: 0 auto; padding: 18px 28px 80px; }
.crumb { font-size: 13.5px; font-weight: 700; margin-bottom: 18px; display: inline-block; }
.page h1 { font-size: 32px; font-weight: 800; letter-spacing: -0.02em; margin: 0 0 2px; }
.page .status { color: var(--muted); margin: 0 0 26px; }
.page .status.fault { color: var(--full-text); font-weight: 700; }

.stats { display: flex; gap: 46px; margin: 26px 0 34px; flex-wrap: wrap; }
.stat .n { font-size: 32px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.1;
  font-variant-numeric: tabular-nums; }
.stat .l { color: var(--muted); font-size: 12.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em; }

h2.sect { font-size: 15px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .05em; color: var(--muted); margin: 34px 0 12px; }

svg.viz { width: 100%; display: block; }
.mark { cursor: pointer; }
.mark:hover { opacity: 1 !important; }
.legend { display: flex; gap: 22px; font-size: 12.5px; font-weight: 700; margin: 2px 0 8px; }
.legend .t-sync, .legend .t-single, .legend .t-drop { font-weight: 700; }
.legend span span { color: var(--muted); font-weight: 600; }

table.eps { width: 100%; border-collapse: collapse; }
table.eps th {
  text-align: left; font-size: 11.5px; font-weight: 800; color: var(--faint);
  text-transform: uppercase; letter-spacing: .05em; padding: 6px 10px 8px;
}
table.eps td {
  padding: 11px 10px; border-top: 1px solid var(--hairline);
  font-size: 14px; font-variant-numeric: tabular-nums;
}
table.eps tr.rowlink { cursor: pointer; }
table.eps tr.rowlink:hover td { background: var(--wash); }
.t-sync { color: var(--full-text); font-weight: 700; }
.t-single { color: var(--busy-text); font-weight: 700; }
.t-drop { color: var(--brand); font-weight: 700; }
.t-open { color: var(--full-text); font-weight: 800; }

/* ── Episode page ─────────────────────────────────────────────────── */

.kv { display: grid; grid-template-columns: 170px 1fr; gap: 6px 20px; margin: 20px 0 8px; }
.kv dt { color: var(--muted); font-size: 13.5px; padding-top: 2px; }
.kv dd { margin: 0; font-weight: 700; font-variant-numeric: tabular-nums; }

.footnote { color: var(--faint); font-size: 12.5px; margin-top: 14px; }

@media (max-width: 640px) {
  .tiles { grid-template-columns: 1fr; min-height: 0; grid-auto-rows: auto; }
  .tile { min-height: 205px; }
  .tile .spark { min-height: 92px; }
  .topline { padding: 14px 20px 16px; }
  .topline .tl-stats { gap: 26px; }
  .bar { padding: 12px 16px 8px; gap: 10px; align-items: center; }
  .bar .wordmark span { display: none; }   /* "/ admin" suffix */
  .bar .who #whoami { display: none; }     /* email; sign out remains */
  .stats { gap: 26px; }
  /* Episode table: keep date/time/duration/type; details live one tap in */
  table.eps th:nth-child(n+5), table.eps td:nth-child(n+5) { display: none; }
  .page { padding: 14px 16px 60px; }
  .kv { grid-template-columns: 120px 1fr; }
}
