/* ---------------------------------------------------------------------------
   Barlow Semi Condensed, self-hosted: the wall screen must render correctly
   with no internet access.
--------------------------------------------------------------------------- */
@font-face {
  font-family: "Barlow Semi Condensed";
  font-style: normal; font-weight: 400; font-display: swap;
  src: url("/fonts/barlow-semi-condensed-400.woff2") format("woff2");
}
@font-face {
  font-family: "Barlow Semi Condensed";
  font-style: normal; font-weight: 500; font-display: swap;
  src: url("/fonts/barlow-semi-condensed-500.woff2") format("woff2");
}
@font-face {
  font-family: "Barlow Semi Condensed";
  font-style: normal; font-weight: 600; font-display: swap;
  src: url("/fonts/barlow-semi-condensed-600.woff2") format("woff2");
}
@font-face {
  font-family: "Barlow Semi Condensed";
  font-style: normal; font-weight: 700; font-display: swap;
  src: url("/fonts/barlow-semi-condensed-700.woff2") format("woff2");
}

:root {
  --ink: #0f1c26;
  --panel: #16262f;
  --panel-raised: #1b2f3a;
  --rule: #24394a;
  --text: #e7edf2;
  --muted: #8da4b4;

  --ok: #35b98a;
  --warn: #e9a23b;
  --down: #e2564b;
  --info: #4f9dd6;
  --idle: #4a6375;

  --gutter: clamp(16px, 1.6vw, 34px);
  --tile-gap: clamp(10px, 0.9vw, 18px);
  --radius: 3px;
}

* { box-sizing: border-box; }

/* The UA stylesheet gives [hidden] display:none, but any author display rule
   outranks it - .overlay and .tally-item below both set display:flex, which
   would leave the drill-down sheet covering the board on load. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--ink);
  color: var(--text);
  font-family: "Barlow Semi Condensed", "Roboto Condensed", "Arial Narrow", system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

body {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

button, a.ctl { font-family: inherit; }

:focus-visible {
  outline: 2px solid var(--info);
  outline-offset: 2px;
}

/* --- header ------------------------------------------------------------- */
.head {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--gutter);
  padding: clamp(10px, 1vw, 20px) var(--gutter);
  border-bottom: 1px solid var(--rule);
}

.board-title {
  margin: 0;
  font-size: clamp(19px, 1.5vw, 30px);
  font-weight: 600;
  letter-spacing: 0.01em;
}

.link-note {
  margin-top: 2px;
  font-size: clamp(12px, 0.8vw, 15px);
  color: var(--warn);
}

.tally {
  display: flex;
  align-items: baseline;
  gap: clamp(16px, 1.6vw, 38px);
  justify-self: center;
}

.tally-item { display: flex; align-items: baseline; gap: 8px; }

.tally-num {
  font-size: clamp(30px, 3.4vw, 64px);
  font-weight: 700;
  line-height: 0.9;
}

.tally-label {
  font-size: clamp(13px, 0.95vw, 19px);
  color: var(--muted);
}

.tally-down .tally-num { color: var(--down); }
.tally-pending .tally-num { color: var(--warn); }

.head-right { justify-self: end; text-align: right; }

.clock {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 4px;
  font-size: clamp(26px, 2.6vw, 48px);
  font-weight: 500;
  line-height: 1;
}

.clock-sec {
  font-size: 0.5em;
  color: var(--muted);
}

.clock-zone {
  font-size: clamp(11px, 0.75vw, 14px);
  color: var(--muted);
}

/* --- controls ----------------------------------------------------------- */
.controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gutter);
  padding: 8px var(--gutter);
  border-bottom: 1px solid var(--rule);
}

.filters { display: flex; flex-wrap: wrap; gap: 6px; }

.chip, .ctl {
  appearance: none;
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  color: var(--muted);
  cursor: pointer;
  font-size: clamp(12px, 0.85vw, 16px);
  padding: 5px 11px;
  text-decoration: none;
}

.chip[aria-pressed="true"] {
  color: var(--text);
  border-color: currentColor;
}

.chip .swatch {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-right: 7px;
  background: var(--tag, var(--muted));
  vertical-align: 1px;
}

.ctl:hover, .chip:hover { color: var(--text); }

.control-buttons { display: flex; gap: 6px; align-items: center; }

/* --- incidents ---------------------------------------------------------- */
.incidents { padding: 0 var(--gutter); }

.incident-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 10px 0 0;
}

.incident {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: baseline;
  gap: clamp(10px, 1vw, 22px);
  padding: 7px 12px 7px 10px;
  background: color-mix(in srgb, var(--down) 13%, var(--panel));
  border-left: 4px solid var(--down);
}

.incident.is-pending {
  background: color-mix(in srgb, var(--warn) 9%, var(--panel));
  border-left-color: var(--warn);
}

/* Only a fresh outage moves. A tile that flashes for hours gets ignored. */
.incident.is-fresh { animation: pulse-bg 1.7s ease-in-out 4; }

@keyframes pulse-bg {
  0%, 100% { background: color-mix(in srgb, var(--down) 13%, var(--panel)); }
  50%      { background: color-mix(in srgb, var(--down) 30%, var(--panel)); }
}

.incident-site {
  color: var(--muted);
  font-size: clamp(13px, 0.95vw, 18px);
  white-space: nowrap;
}

.incident-name {
  font-size: clamp(15px, 1.15vw, 23px);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.incident-host {
  color: var(--muted);
  font-weight: 400;
  font-size: 0.82em;
  margin-left: 8px;
}

.incident-dur {
  font-size: clamp(14px, 1.05vw, 21px);
  font-weight: 600;
  color: var(--down);
  white-space: nowrap;
}

.incident.is-pending .incident-dur { color: var(--warn); }

.all-clear {
  margin: 10px 0 0;
  padding: 7px 12px;
  border-left: 4px solid var(--ok);
  background: color-mix(in srgb, var(--ok) 8%, var(--panel));
  color: var(--muted);
  font-size: clamp(13px, 0.95vw, 18px);
}

.all-clear b { color: var(--text); font-weight: 600; }

.more-pill {
  align-self: flex-start;
  color: var(--muted);
  font-size: clamp(12px, 0.85vw, 16px);
  padding: 4px 2px;
}

/* --- site grid ---------------------------------------------------------- */
.grid {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(clamp(220px, 18vw, 360px), 1fr));
  /* Rows stretch to fill the screen so a wall TV has no dead space below,
     but never below a readable minimum - past that the grid overflows and
     the board paginates instead of squashing tiles. */
  align-content: stretch;
  grid-auto-rows: minmax(clamp(88px, 10.5vh, 165px), 1fr);
  gap: var(--tile-gap);
  padding: var(--tile-gap) var(--gutter) var(--gutter);
  overflow: hidden;
}

.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  /* Chrome's UA stylesheet sets align-items: flex-start on <button>, so
     without this the head, unit grid and footer all shrink to their content
     width instead of filling the tile. */
  align-items: stretch;
  gap: 6px;
  padding: 10px 12px 10px;
  background: var(--panel);
  border: 1px solid var(--rule);
  border-left: 4px solid var(--state, var(--idle));
  justify-content: space-between;
  border-radius: var(--radius);
  cursor: pointer;
  text-align: left;
  color: inherit;
  min-height: 0;
}

.tile.is-up { --state: var(--ok); }
.tile.is-down { --state: var(--down); background: color-mix(in srgb, var(--down) 12%, var(--panel)); }
.tile.is-pending { --state: var(--warn); background: color-mix(in srgb, var(--warn) 8%, var(--panel)); }
.tile.is-maintenance { --state: var(--info); }
.tile.is-stale, .tile.is-unknown { --state: var(--idle); }
.tile.is-paused { --state: var(--idle); opacity: 0.55; }

.tile-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.tile-name {
  font-size: clamp(15px, 1.15vw, 23px);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tile-count {
  font-size: clamp(17px, 1.35vw, 27px);
  font-weight: 700;
  white-space: nowrap;
}

.tile-count .of { color: var(--muted); font-weight: 500; }
.tile.is-down .tile-count { color: var(--down); }
.tile.is-pending .tile-count { color: var(--warn); }

/* One dot per monitor, clustered by tag: firewalls, phones, then storage. */
/* One labelled row per monitor. The columns pack automatically, so a site
   with three checks stays compact and Dubai's fifteen still fit. */
.units {
  display: grid;
  /* auto-fill needs a plain fixed track size here - a clamp() in the minmax
     silently collapses the whole thing to one column. */
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 0 14px;
  align-content: start;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.unit {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}

.unit-name {
  color: var(--muted);
  font-size: clamp(10px, 0.68vw, 14px);
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A failing check names itself loudly; the healthy ones stay quiet. */
.unit.is-down .unit-name { color: var(--down); font-weight: 600; }
.unit.is-pending .unit-name { color: var(--warn); }
.unit.is-paused .unit-name, .unit.is-stale .unit-name, .unit.is-unknown .unit-name { opacity: 0.6; }

/* Tiles with a long list take two columns of the grid. */
.tile[data-wide="1"] { grid-column: span 2; }


.dot {
  flex-shrink: 0;
  width: clamp(8px, 0.6vw, 13px);
  height: clamp(8px, 0.6vw, 13px);
  border-radius: 50%;
  background: var(--idle);
}

.dot.is-up { background: var(--ok); }
.dot.is-down { background: var(--down); }
.dot.is-pending { background: var(--warn); }
.dot.is-maintenance { background: var(--info); }
.dot.is-paused { background: transparent; box-shadow: inset 0 0 0 1px var(--idle); }
.dot.is-stale, .dot.is-unknown { background: transparent; box-shadow: inset 0 0 0 1px var(--muted); }

.tile-foot {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  color: var(--muted);
  font-size: clamp(11px, 0.8vw, 15px);
}

.tile-note {
  color: var(--down);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- stale: greyscale, hatched, and question-marked, so colour is never
       the only thing carrying the meaning ---------------------------------- */
body.is-stale .tile {
  filter: grayscale(1);
  border-style: dashed;
  border-left-style: solid;
}

body.is-stale .tile::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    45deg,
    transparent 0 7px,
    color-mix(in srgb, var(--muted) 14%, transparent) 7px 14px
  );
  pointer-events: none;
}

body.is-stale .tile-count::before {
  content: "? ";
  color: var(--warn);
}

body.is-stale .incidents { opacity: 0.45; }

.stale-veil {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  padding: 10px var(--gutter);
  background: color-mix(in srgb, var(--warn) 22%, var(--ink));
  border-top: 2px solid var(--warn);
  z-index: 30;
}

.stale-title {
  font-size: clamp(16px, 1.25vw, 25px);
  font-weight: 700;
  color: var(--warn);
}

.stale-sub { color: var(--text); font-size: clamp(13px, 0.95vw, 18px); }

/* --- drill-down --------------------------------------------------------- */
.overlay {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--ink) 82%, transparent);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: clamp(20px, 4vh, 70px) var(--gutter);
  z-index: 40;
}

.sheet {
  width: min(1100px, 100%);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--panel-raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}

.sheet-head {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 16px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--rule);
}

.sheet-head h2 {
  margin: 0;
  font-size: clamp(19px, 1.5vw, 30px);
  font-weight: 600;
}

.sheet-meta { color: var(--muted); font-size: clamp(13px, 0.95vw, 18px); }

.sheet-body { overflow: auto; padding: 4px 0 8px; }

.row {
  display: grid;
  grid-template-columns: 14px minmax(0, 2fr) minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: 14px;
  padding: 9px 18px;
  border-bottom: 1px solid color-mix(in srgb, var(--rule) 60%, transparent);
  font-size: clamp(13px, 1vw, 19px);
}

.row:last-child { border-bottom: 0; }

.row-name { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-host, .row-num { color: var(--muted); font-size: 0.88em; }
.row-num { text-align: right; min-width: 5ch; }
.row.is-down .row-name { color: var(--down); }
.row.is-paused { opacity: 0.5; }

/* Beat strip: newest on the right, same reading direction as Kuma's own. */
.beats { display: flex; gap: 2px; align-items: flex-end; height: 18px; }
.beat { width: 3px; height: 100%; background: var(--idle); }
.beat.s1 { background: var(--ok); }
.beat.s0 { background: var(--down); }
.beat.s2 { background: var(--warn); }
.beat.s3 { background: var(--info); }

/* --- login -------------------------------------------------------------- */
.login-page { display: grid; place-items: center; overflow: auto; }

.login-wrap { width: min(380px, 92vw); padding: 24px 0; }

.login-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 26px 24px 24px;
  background: var(--panel);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}

.login-title { margin: 0; font-size: 25px; font-weight: 600; }
.login-sub { margin: -8px 0 4px; color: var(--muted); font-size: 15px; }

.field { display: flex; flex-direction: column; gap: 6px; }
.field-label { color: var(--muted); font-size: 14px; }

.field input {
  background: var(--ink);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  color: var(--text);
  font: inherit;
  font-size: 17px;
  padding: 9px 11px;
}

.check { display: flex; align-items: center; gap: 9px; color: var(--muted); font-size: 15px; }
.check input { accent-color: var(--ok); width: 15px; height: 15px; }

.submit {
  appearance: none;
  background: var(--ok);
  border: 0;
  border-radius: var(--radius);
  color: #062018;
  cursor: pointer;
  font: inherit;
  font-size: 17px;
  font-weight: 600;
  padding: 10px;
}

.login-error { margin: 0; color: var(--down); font-size: 15px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

@media (max-width: 720px) {
  body { overflow: auto; }
  .head { grid-template-columns: 1fr; gap: 10px; }
  .tally, .head-right { justify-self: start; text-align: left; }
  .grid { overflow: visible; }
  .row { grid-template-columns: 14px minmax(0, 1fr) auto; }
  .row-host, .beats { display: none; }
}

/* --- edit mode ---------------------------------------------------------- */
.edit-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gutter);
  margin: 10px var(--gutter) 0;
  padding: 9px 13px;
  background: color-mix(in srgb, var(--info) 12%, var(--panel));
  border-left: 4px solid var(--info);
}

.edit-hint { color: var(--text); font-size: clamp(12px, 0.9vw, 17px); }
.edit-hint b { color: var(--info); }

.edit-actions { display: flex; gap: 6px; }

.ctl-primary {
  background: var(--ok);
  border-color: var(--ok);
  color: #062018;
  font-weight: 600;
}

.ctl-primary:hover { color: #062018; }

body.is-editing .tile { cursor: grab; }
body.is-editing .tile:active { cursor: grabbing; }

/* Dim the status colours while arranging so the layout is what you look at. */
body.is-editing .tile { filter: saturate(0.45); }
body.is-editing .tile.is-dragging { opacity: 0.4; }

body.is-editing .tile.is-drop-target {
  outline: 2px dashed var(--info);
  outline-offset: -3px;
}

.edit-controls {
  display: flex;
  gap: 4px;
  justify-content: center;
  padding-top: 4px;
}

.edit-btn {
  appearance: none;
  background: var(--panel-raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  color: var(--text);
  cursor: pointer;
  font: inherit;
  font-size: clamp(11px, 0.8vw, 15px);
  line-height: 1;
  padding: 5px 10px;
}

.edit-btn:hover { border-color: var(--info); }
.edit-wide[aria-pressed="true"] { background: var(--info); border-color: var(--info); color: #04121c; }

/* While arranging, a card only needs to say which site it is - the check list
   would otherwise be clipped by the controls, which looks broken. */
body.is-editing .units,
body.is-editing .tile-foot { display: none; }
body.is-editing .edit-controls { margin-top: auto; }
