/* The status page. System fonts, no third-party request; light and dark follow the system.
   One banner in the state's color, one card of the parts with their 90 days, past problems by
   day. */
:root {
  color-scheme: light dark;
  --page: #f4f6f8;
  --surface: #ffffff;
  --border: #dde1e6;
  --text: #1c2127;
  --quiet: #59626d;
  --link: #0b5cba;
  --ok: #1b7f40;
  --late: #a65c00;
  --down: #cf2c2c;
  --none: #8c949e;
  --before: #e6e9ed;
  --bar: #34a35a;
  --bok: #1f8442;
  --blate: #a35400;
  --bdown: #c42b2b;
  --bnone: #5e6873;
  --on: #ffffff;
}
@media (prefers-color-scheme: dark) {
  :root {
    --page: #0c0f13;
    --surface: #151a20;
    --border: #2a313a;
    --text: #e9edf1;
    --quiet: #9ba5b0;
    --link: #79b4ff;
    --ok: #3ccf6e;
    --late: #f0a83a;
    --down: #ff6b63;
    --none: #6c7682;
    --before: #262d36;
    --bar: #34b862;
    --bok: #1f8442;
    --blate: #a35400;
    --bdown: #c42b2b;
    --bnone: #4f5965;
    --on: #ffffff;
  }
}
* {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  margin: 0;
  background: var(--page);
  color: var(--text);
  font:
    1rem/1.5 system-ui,
    -apple-system,
    'Segoe UI',
    Roboto,
    sans-serif;
}
/* Numbers that change in place keep their width. Only on these lines, which never hold a
   part's name: in some system typefaces tabular numbers also widen the hyphen of "Snow-day". */
.more,
.upd,
.mid,
.when {
  font-variant-numeric: tabular-nums;
}
/* With scripts off the page cannot fill in: only the line that says so is shown, and the
   footer does not explain bars that are not there. */
@media (scripting: none) {
  main,
  .how {
    display: none;
  }
}
/* While the page waits for its first answer the footer is not drawn, so the list above it can
   take its own size when it fills and nothing moves. With scripts off it is drawn at once,
   and on a page whose script never starts, 10 s on, with the line that says so. */
main.wait ~ footer {
  display: none;
}
main.wait:not(.on) ~ footer {
  animation: drawn 0.01s 10s forwards;
}
@media (scripting: none) {
  main.wait ~ footer {
    display: block;
  }
}
@keyframes drawn {
  to {
    display: block;
  }
}
p,
ul,
ol,
h1,
h2,
h3 {
  margin: 0;
  padding: 0;
  list-style: none;
}
a {
  color: var(--link);
  text-underline-offset: 0.15em;
}

/* The header: a white bar across the page, the name on the left and the way back on the right.
   The side gutters, of the page and inside each card, are 16 px at every text size, as on the
   website: larger text gets the room, not the margins. */
header {
  background: var(--surface);
  border-block-end: 1px solid var(--border);
}
.bar-top,
main,
.foot-in,
.noscript {
  max-inline-size: 61.25rem;
  margin-inline: auto;
  padding-inline: 16px;
}
.bar-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem 1rem;
  padding-block: 0.875rem;
}
h1 {
  display: flex;
  /* With very large text on a narrow screen "Status" goes under the name, never off the edge. */
  flex-wrap: wrap;
  align-items: center;
  gap: 0 0.5rem;
  font-size: 1.25rem;
  line-height: 2rem;
  letter-spacing: -0.01em;
}
.tile {
  flex: none;
  inline-size: 2rem;
  block-size: 2rem;
}
.brand {
  font-weight: 600;
}
.page {
  font-weight: 400;
  color: var(--quiet);
}
.go {
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 2.75rem;
}
/* Every layout below that sets things side by side asks how much room <main> has in text
   units, not how wide the screen is: with larger text the same screen holds fewer words. */
main {
  container-type: inline-size;
  padding-block: 1.5rem 0;
}
h2 {
  margin-block-end: 0.75rem;
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.75rem;
}
section + section {
  margin-block-start: 2.25rem;
}
.shape {
  flex: none;
  inline-size: 1rem;
  block-size: 1rem;
}
.s-ok {
  color: var(--ok);
}
.s-late {
  color: var(--late);
}
.s-down {
  color: var(--down);
}
.s-unknown,
.s-wait {
  color: var(--quiet);
}

/* The banner: one solid bar in the state's color, its words in white, centred top to bottom.
   Its block size holds its longest copy at the room it has, so nothing moves when it fills:
   scripts/shots.cjs checks every copy fits at every 2 px of room. */
.banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  align-content: center;
  gap: 0.75rem;
  margin-block-end: 2.25rem;
  padding: 0.75rem 12px;
  border-radius: 0.375rem;
  background: var(--bnone);
  color: var(--on);
  min-block-size: 14.5rem;
}
/* Each step is the room, in rem, from which every copy takes fewer lines, and the size it
   takes there (scripts/shots.cjs measures them). Under 22.625rem of room is a phone narrower
   than 400 px, or larger text. */
@container (min-width: 8.625rem) {
  .banner {
    min-block-size: 13.25rem;
  }
}
@container (min-width: 9rem) {
  .banner {
    min-block-size: 11.75rem;
  }
}
@container (min-width: 12.125rem) {
  .banner {
    min-block-size: 10.5rem;
  }
}
@container (min-width: 12.25rem) {
  .banner {
    min-block-size: 9rem;
  }
}
@container (min-width: 15.5rem) {
  .banner {
    min-block-size: 7rem;
  }
}
@container (min-width: 21.75rem) {
  .banner {
    min-block-size: 5.75rem;
  }
}
@container (min-width: 22.625rem) {
  .banner {
    min-block-size: 4.25rem;
  }
}

.st-ok {
  background: var(--bok);
}
.st-late {
  background: var(--blate);
}
.st-down {
  background: var(--bdown);
}
.banner .shape {
  inline-size: 1.25rem;
  block-size: 1.25rem;
  color: var(--on);
}
/* Its words keep at least 12rem: where that and the shape do not fit side by side (large text
   on a narrow phone), the shape goes above the words instead of squeezing them. */
.banner > div,
.banner .swap > div {
  flex: 1 1 12rem;
  min-inline-size: 0;
}
.lead {
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.5rem;
  /* No last line of one word. */
  text-wrap: balance;
}
.more {
  font-size: 0.875rem;
  line-height: 1.25rem;
  text-wrap: balance;
}
/* A part's name, wherever it is drawn, and a problem's date, time or length: whole on a line
   wherever it fits on one, broken between its words only where it is wider than the line. */
.nm,
.nb {
  display: inline-block;
}

/* The script marks <main> "on" when it starts. If it has not 10 seconds after the page opened
   (it did not load, or scripts are off in a browser that does not know the rule above), the
   banner stops saying "Checking" and says the page did not finish loading, in the same place,
   and the parts stop saying "Checking" too. Nothing moves: both share one grid cell. */
.swap {
  display: grid;
  flex: 1 1 12rem;
  min-inline-size: 0;
}
.swap > * {
  grid-area: 1 / 1;
}
.stuck {
  visibility: hidden;
}
main.on .stuck {
  display: none;
}
main:not(.on) .stuck {
  animation: shown 0.01s 10s forwards;
}
main:not(.on) .swap > :not(.stuck),
main:not(.on) .state {
  animation: gone 0.01s 10s forwards;
}
@keyframes shown {
  to {
    visibility: visible;
  }
}
@keyframes gone {
  to {
    visibility: hidden;
  }
}

/* The parts: one card, a part to a cell, the lines between them drawn by the card's color
   showing through a 1 px gap. */
.parts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 0.375rem;
}
.part {
  position: relative;
  padding: 1rem 16px 0.875rem;
  background: var(--surface);
}
/* The card's round corners, drawn by the parts in them (a tip may reach past the card). */
.part:first-child {
  border-start-start-radius: 0.3125rem;
  border-start-end-radius: 0.3125rem;
}
.part:last-child {
  border-end-start-radius: 0.3125rem;
  border-end-end-radius: 0.3125rem;
}
/* On a narrow phone a name and a long state ("Could not check") take two lines: both lines
   are kept whatever the state, so nothing moves when it changes. */
.top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  align-content: flex-start;
  column-gap: 0.375rem;
  min-block-size: 3rem;
}
.name {
  font-weight: 600;
  line-height: 1.5rem;
}
/* The small mark beside a name: its line about the part shows over it on a hover or a tap. */
.info {
  display: inline-grid;
  place-items: center;
  flex: none;
  color: var(--quiet);
  cursor: help;
}
.i {
  inline-size: 0.875rem;
  block-size: 0.875rem;
}
.about {
  position: absolute;
  inset-block-start: 2.75rem;
  inset-inline-start: 12px;
  z-index: 2;
  inline-size: max-content;
  max-inline-size: min(17rem, calc(100% - 24px));
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  background: var(--surface);
  color: var(--text);
  font-size: 0.8125rem;
  font-weight: 400;
  line-height: 1.25rem;
  box-shadow: 0 4px 14px rgb(0 0 0 / 0.14);
  visibility: hidden;
  pointer-events: none;
  overflow-wrap: break-word;
}
.info:hover .about,
.info:focus .about {
  visibility: visible;
}
.state {
  display: flex;
  flex-basis: 100%;
  align-items: center;
  gap: 0.375rem;
  margin-inline-start: auto;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.5rem;
  text-wrap: balance;
}
.state .shape {
  inline-size: 0.875rem;
  block-size: 0.875rem;
}

/* Ninety thin day bars filling the width, the oldest on the left. A day with no reading to
   show (before the checks began, or not due yet) is a light grey bar, so the row is always
   whole. */
.bars {
  position: relative;
  display: grid;
  grid-template-columns: repeat(90, 1fr);
  gap: 1px;
  block-size: 2.125rem;
  margin-block-start: 0.625rem;
  touch-action: pan-y;
}
.bar {
  border-radius: 1px;
  background: var(--before);
}
.b-ok {
  background: var(--bar);
}
.b-late {
  background: var(--late);
}
.b-down {
  background: var(--down);
}
.b-none {
  background: var(--none);
}
.b-before,
.b-wait,
.b-yet {
  background: var(--before);
}
/* The status could not be loaded: no day is drawn, only the row's outline, in no color of
   the key. */
.bars.off {
  outline: 1px dashed var(--none);
  outline-offset: -1px;
  border-radius: 2px;
}
.bar.on {
  outline: 2px solid var(--text);
  outline-offset: 1px;
}
/* The picked day, in a tip under its bar that never leaves the row: `--at` is the bar's place,
   0 at the left to 1 at the right, set by the script. */
.tip {
  position: absolute;
  inset-block-start: calc(100% + 0.5rem);
  inset-inline-start: calc(var(--at, 0) * 100%);
  z-index: 2;
  inline-size: max-content;
  max-inline-size: 100%;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  background: var(--surface);
  color: var(--text);
  font-size: 0.8125rem;
  line-height: 1.25rem;
  box-shadow: 0 4px 14px rgb(0 0 0 / 0.14);
  transform: translateX(calc(var(--at, 0) * -100%));
  pointer-events: none;
  text-wrap: balance;
}
/* "90 days ago" and "Today" with a rule between them, and the share of checks on a line of its
   own under them, kept while the page waits so nothing moves. Once the three fit on one line
   (from a 375 px screen at the usual text size) the share sits in the middle of the rule. */
.axis {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 0.5rem;
  margin-block-start: 0.375rem;
  color: var(--quiet);
  font-size: 0.75rem;
  line-height: 1.125rem;
}
.axis::before {
  content: '';
  grid-row: 1;
  grid-column: 2;
  border-block-start: 1px solid var(--border);
}
.axis > :first-child {
  grid-row: 1;
  grid-column: 1;
}
.axis > :last-child {
  grid-row: 1;
  grid-column: 3;
}
.mid {
  grid-row: 2;
  grid-column: 1 / -1;
  min-block-size: 1.125rem;
  text-align: center;
  text-wrap: balance;
}
@container (min-width: 21.5rem) {
  .axis {
    display: flex;
  }
  .axis::before {
    content: none;
  }
  .axis > :first-child,
  .axis > :last-child {
    flex: none;
  }
  .mid {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-inline-size: 0;
    min-block-size: 0;
  }
  .mid::before,
  .mid::after {
    content: '';
    flex: 1 1 0;
    min-inline-size: 0.5rem;
    border-block-start: 1px solid var(--border);
  }
  /* With no share to show, the rule runs whole from "90 days ago" to "Today". */
  .mid:empty {
    gap: 0;
  }
}
/* For a file part, when it was last made: its line is kept while it waits, so nothing moves. */
.upd {
  min-block-size: 1.25rem;
  margin-block-start: 0.25rem;
  color: var(--quiet);
  font-size: 0.8125rem;
  line-height: 1.25rem;
}

/* Past problems: a day to a heading, newest first, as long as its days. */
.day + .day {
  margin-block-start: 1.5rem;
}
h3 {
  margin-block-end: 0.75rem;
  padding-block-end: 0.375rem;
  border-block-end: 1px solid var(--border);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.5rem;
}
.none,
.empty {
  color: var(--quiet);
  font-size: 0.875rem;
  line-height: 1.25rem;
  text-wrap: balance;
}
.note {
  margin-block-start: 0.75rem;
}
.end {
  margin-block-start: 1.5rem;
  color: var(--quiet);
  font-size: 0.875rem;
  line-height: 1.25rem;
  text-wrap: pretty;
}
.prob + .prob {
  margin-block-start: 1rem;
}
.what {
  font-weight: 600;
  line-height: 1.5rem;
  text-wrap: pretty;
}
.k-down {
  color: var(--down);
}
.k-late {
  color: var(--late);
}
.when {
  color: var(--quiet);
  font-size: 0.8125rem;
  line-height: 1.25rem;
  text-wrap: pretty;
}
.older {
  margin-block-start: 1.5rem;
}
.more-row {
  margin-block-start: 1.5rem;
}
button {
  min-block-size: 2.75rem;
  padding: 0 1rem;
  border: 1px solid var(--border);
  border-radius: 0.375rem;
  background: var(--surface);
  color: var(--link);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
}
button:hover {
  border-color: var(--quiet);
}
:focus-visible {
  outline: 2px solid var(--link);
  outline-offset: 2px;
}

footer {
  margin-block-start: 3rem;
  padding-block: 1.5rem 2.5rem;
  border-block-start: 1px solid var(--border);
  color: var(--quiet);
  font-size: 0.8125rem;
  line-height: 1.25rem;
}
footer p {
  max-inline-size: 44rem;
  text-wrap: pretty;
}
footer p + p,
.key + p {
  margin-block-start: 0.75rem;
}
/* What each color of bar means: a small bar of it before its word. */
.key {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  margin-block-start: 0.75rem;
}
.key li {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}
.sw {
  flex: none;
  inline-size: 0.375rem;
  block-size: 1rem;
  border-radius: 1px;
  /* The light grey is close to the page: a ring keeps its shape. */
  box-shadow: 0 0 0 1px var(--border);
}
/* One sentence: short lines of near one length. */
.privacy {
  text-wrap: balance;
}
.home {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-block-size: 2.75rem;
  color: var(--text);
  font-weight: 600;
}
.noscript {
  padding-block: 1.5rem;
}
.sr {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* From a 368 px screen at the usual text size a name and its state share one line. */
@container (min-width: 21rem) {
  .top {
    min-block-size: 0;
  }
  .state {
    flex-basis: auto;
  }
}
/* Side by side once <main> has the room: the banner's last-checked line goes to its right, the
   parts go two to a row. 36rem is a 608 px screen at the usual text size, 56rem a 928 px one. */
@container (min-width: 36rem) {
  .banner {
    padding-inline: 20px;
  }
  .banner > div:not(.swap),
  .banner .swap > div {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    column-gap: 1rem;
  }
  .lead {
    font-size: 1.25rem;
  }
  .bars {
    gap: 2px;
  }
  .part {
    padding-inline: 20px;
  }
}
@container (min-width: 56rem) {
  .parts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .part:first-child {
    border-start-end-radius: 0;
  }
  .part:nth-child(2) {
    border-start-end-radius: 0.3125rem;
  }
  .part:nth-last-child(2) {
    border-end-start-radius: 0.3125rem;
  }
  .part:last-child {
    border-end-start-radius: 0;
  }
}
/* Wide enough for the headline and the line under it side by side, whatever they say. */
@container (min-width: 45rem) {
  .banner {
    min-block-size: 3.5rem;
  }
}
