/* assets/css/status.css
 * The public status page at /status.
 *
 * Same tokens and same type as the rest of the marketing site, but the tone is
 * dialled down on purpose. A status page is read by somebody who wants to know
 * whether it is Verde or their wifi — the handwriting stays in the eyebrow and
 * nowhere else, and there is no artwork.
 *
 * THE BAND TAKES THE STATUS COLOUR. Green when everything is up, amber when
 * something is slow, red when it is down. That is the one place on this site
 * colour is allowed to mean state rather than brand, because the state IS the
 * content.
 */

/* ---- Head ------------------------------------------------------------- */

/* ONE GRID FOR THE WHOLE PAGE.
 *
 * The head used the 1300 container and the body narrowed to 900, so the
 * headline started 325px left of everything under it. Two grids on one page
 * is the first thing the eye catches, and it was most of why this did not
 * look like the rest of the site.
 *
 * 980 everywhere: wide enough for a service row with a name, a description
 * and a state on one line, narrow enough that an incident update is not a
 * 1300px measure of body copy. */
.status-head .container,
.status-body .container {
  max-width: 980px;
}

.status-head {
  padding: 58px 0 54px;
  background: var(--band);
}

.status-head--warn {
  background: #fbeccd;
}

.status-head--bad {
  background: #f7d7d1;
}

/* The same treatment as every other hero headline on the site: the heading
   face at 700 with the hard shadow. It was inheriting a default weight and
   carrying no shadow, which is why it read as a different page. */
.status-head__title {
  --hard-shadow-offset: 3px;
  margin-top: 12px;
  max-width: 820px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 46px;
  line-height: 56px;
  color: var(--ink);
}

.status-head__meta {
  margin-top: 16px;
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--forest);
  opacity: 0.8;
}

/* ---- Body -------------------------------------------------------------- */

.status-body {
  padding: 54px 0 90px;
}

.status-block + .status-block {
  margin-top: 46px;
}

.status-block > h2 {
  margin-bottom: 16px;
  font-size: var(--h5);
  line-height: var(--h5-lh);
}

.status-empty {
  padding: 22px 24px;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  font-size: var(--body);
  line-height: 24px;
  color: var(--ink-soft);
}

/* ---- Services ---------------------------------------------------------- */

.status-services {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.status-services li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 16px 22px;
}

.status-services li + li {
  border-top: 1px solid var(--line);
}

.status-services__name b {
  display: block;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--body);
  line-height: 22px;
  color: var(--ink);
}

.status-services__name span {
  display: block;
  margin-top: 2px;
  font-size: var(--small);
  line-height: 19px;
  color: var(--ink-soft);
}

.status-services__state {
  display: flex;
  align-items: center;
  gap: 9px;
  flex: none;
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--ink);
  white-space: nowrap;
}

/* Latency is for us, not for a club deciding whether to call. It stays, at
   the weight of a footnote. */
.status-services__ms {
  font-family: var(--font-data);
  color: var(--ink-soft);
  opacity: 0.7;
}

.status-dot {
  width: 9px;
  height: 9px;
  border-radius: 99px;
  background: var(--brand);
}

.status-dot--warn { background: #d79a24; }
.status-dot--bad  { background: #c0483a; }

/* ---- Cards -------------------------------------------------------------- */

/* WHITE, not --paper. Paper is a green tint, and a green card behind the
   words "Part of Verde is down" says two different things at once. The left
   rule carries the severity; the card itself stays neutral. */
.status-card {
  padding: 22px 24px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--white);
}

.status-card + .status-card {
  margin-top: 12px;
}

/* The left rule carries the severity, so the card itself stays quiet. A card
   that is entirely red reads as alarm whatever it says. */
.status-card--warn { border-left: 4px solid #d79a24; }
.status-card--bad  { border-left: 4px solid #c0483a; }

.status-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}

.status-card h3 {
  font-size: var(--h6);
  line-height: var(--h6-lh);
}

.status-card__when {
  margin-top: 6px;
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--ink-soft);
}

.status-card p {
  margin-top: 12px;
  font-size: var(--body);
  line-height: 24px;
  color: var(--ink-soft);
}

.status-tag {
  flex: none;
  padding: 3px 11px;
  border-radius: 99px;
  background: var(--band-soft);
  font-size: 12px;
  line-height: 18px;
  color: var(--forest);
}

.status-tag--warn { background: #fbeccd; color: #7a5510; }
.status-tag--bad  { background: #f7d7d1; color: #8c2e22; }

/* ---- Updates ------------------------------------------------------------ */

.status-updates {
  margin: 18px 0 0;
  padding: 0 0 0 18px;
  list-style: none;
  border-left: 2px solid var(--line);
}

.status-updates li {
  display: flex;
  gap: 16px;
  padding: 9px 0;
  font-size: var(--body);
  line-height: 24px;
  color: var(--ink-soft);
}

.status-updates__when {
  flex: none;
  width: 74px;
  font-family: var(--font-data);
  font-size: var(--small);
  color: var(--ink-soft);
  opacity: 0.75;
}

.status-updates__what b {
  display: block;
  font-family: var(--font-heading);
  font-weight: 500;
  color: var(--ink);
}

/* ---- Subscribe ----------------------------------------------------------- */

.status-subscribe {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 32px;
  align-items: center;
  margin-top: 54px;
  padding: 30px 34px;
  border-radius: var(--radius);
  background: var(--forest);
  color: var(--white);
}

.status-subscribe h2 {
  font-size: var(--h6);
  line-height: var(--h6-lh);
  color: var(--white);
}

.status-subscribe > div > p {
  margin-top: 8px;
  font-size: var(--body);
  line-height: 24px;
  color: var(--verde-100);
}

.status-subscribe__form {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.status-subscribe__form .input {
  flex: 1;
  min-width: 0;
  min-height: 48px;
  border-color: transparent;
}

.status-subscribe__msg {
  flex: 1 0 100%;
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--accent);
}

.status-subscribe__msg--bad {
  color: #f3b8ae;
}

.status-subscribe__msg a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---- Responsive ---------------------------------------------------------- */

@media (max-width: 900px) {
  .status-head {
    padding: 44px 0 42px;
  }

  .status-head__title {
    font-size: 34px;
    line-height: 42px;
  }

  .status-subscribe {
    grid-template-columns: 1fr;
    gap: 20px;
  }
}

@media (max-width: 640px) {
  .status-head__title {
    font-size: 28px;
    line-height: 36px;
  }

  .status-services li {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .status-updates li {
    flex-direction: column;
    gap: 2px;
  }

  .status-updates__when {
    width: auto;
  }
}


/* ---- Uptime chips --------------------------------------------------------
 * In the head, under the answer. A club deciding whether to trust this
 * platform wants the number before the incident list, not after it.
 */

.status-uptime {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 24px;
}

/* A figure with its own label beneath it, rather than both on one line with a
   comma between them. The pill shape came from the inline version and does not
   suit a two-line block; a soft card does. */
.status-uptime__chip {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 148px;
  padding: 14px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.62);
}

.status-uptime__chip b {
  font-family: var(--font-data);
  font-weight: 500;
  font-size: var(--h5);
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.status-uptime__chip span {
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--ink-soft);
}

@media (max-width: 640px) {
  .status-uptime__chip {
    flex: 1 0 100%;
    justify-content: space-between;
  }
}

/* ---- The ninety-day strip ----------------------------------------------
 * One bar per day.
 *
 * PARTIAL, NOT BINARY. Most bad days are a few bad minutes. Four failed
 * probes out of 288 is 98.6% of a day working, and colouring that day solid
 * red overstates it by two orders of magnitude — which is how a status page
 * ends up looking worse than the product it reports on.
 */

/* The three tones the strip uses, named here rather than repeated as literals
   in the component — the bar fill is built in JS because the proportion is
   per-day data, and it should still be reading its colours from the
   stylesheet. */
.status-bars {
  --status-ok: var(--brand);
  --status-warn: #d79a24;
  --status-bad: #c0483a;
}

/* The strip is the positioning context for the day panel. */
.status-bars {
  position: relative;
  display: flex;
  gap: 2px;
  align-items: stretch;
  height: 40px;
}

/* A button now, not a span: the detail has to be reachable by keyboard, and
   a native title tooltip never was. The reset is here because a button brings
   a border, a font and a background with it. */
.status-bars__day {
  flex: 1;
  min-width: 2px;
  padding: 0;
  border: 0;
  border-radius: 2px;
  cursor: pointer;
  appearance: none;

  /* Fallback only. The real fill is an inline gradient whose green share is
     that day's uptime, set in dayFill(). */
  background: var(--status-ok);
}

/* Hit area without visual weight. Ninety bars in forty pixels is a hard
   target; this lets the cursor and a finger land above and below one. */
.status-bars__day::after {
  content: '';
  position: absolute;
  top: -8px;
  bottom: -8px;
  width: inherit;
}

.status-bars__day:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* Rounded only at the ends of the run, so ninety 2px bars do not each read as
   a separate pill. */
.status-bars__day:not(:first-child):not(:last-child) {
  border-radius: 1px;
}

/* A day before monitoring started is not a good day or a bad one. Grey says
   that; leaving it out would silently shorten the window. */
/* Before monitoring started. Faint, and shorter than a measured day, so the
   strip shows at a glance how much of the window is actually covered rather
   than implying ninety days of history that does not exist. */
.status-bars__day--none {
  background: var(--line);
  opacity: 0.5;
  align-self: center;
  height: 45%;
}

.status-bars__legend {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--ink-soft);
}

@media (max-width: 640px) {
  .status-bars {
    height: 32px;
    gap: 1px;
  }
}

/* ---- Measured versus reported -------------------------------------------
 * A hollow dot for a service nothing probes.
 *
 * The same solid green on a measured row and a hand-set one is a borrowed
 * confidence — not a wrong fact, but a reader has no way to tell which is
 * which. Hollow says "somebody told us this" without needing a word for it,
 * and the note above the group says it in words for anybody who looks twice.
 */

/* A hollow ring used to mark a hand-set service. Two dot styles for the same
   three states read as six states, and the block already carries a heading and
   a note explaining how those rows are set — the dot was saying it a second
   time, less clearly. Solid, like everywhere else. */



/* ---- Day panel -----------------------------------------------------------
   Replaces the browser's title tooltip on the ninety-day strip.

   The native one could only ever be a single line of unstyled text, appeared
   after a delay, was invisible to a keyboard, and could not distinguish a
   service of ours from a partner's. All four of those are the reason this
   exists rather than any visual preference.
   -------------------------------------------------------------------------- */

.status-pop {
  position: absolute;
  bottom: calc(100% + 12px);
  z-index: 5;
  width: max-content;
  max-width: min(340px, 86vw);
  transform: translateX(-50%);
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--white);
  box-shadow: 0 16px 40px rgba(5, 52, 36, 0.16);

  /* The pointer never enters it — it follows the bar under the cursor — so it
     must not eat the mouseleave that closes it. */
  pointer-events: none;
}

.status-pop__day {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--ink-soft);
}

.status-pop__verdict {
  margin-top: 2px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--body);
  line-height: 22px;
  color: var(--ink);
}

.status-pop__cover {
  margin-top: 6px;
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--ink-soft);
}

.status-pop__sub {
  margin-top: 12px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.status-pop__list {
  margin-top: 10px;
  display: grid;
  gap: 6px;
}

.status-pop__list li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  font-size: var(--small);
  line-height: var(--small-lh);
}

.status-pop__list b {
  flex: none;
  font-weight: 600;
}

.status-pop__bad  { color: var(--status-bad, #c0483a); }
.status-pop__warn { color: #a9761a; }

/* A partner's outage is reported in the same panel but never in our colour,
   so it cannot be mistaken for one of ours at a glance. */
.status-pop__dep  { color: var(--ink-soft); }

@media (max-width: 640px) {
  .status-pop {
    max-width: 82vw;
    padding: 12px 14px;
  }
}


/* ---- Help ----------------------------------------------------------------
   Three paragraphs of method were sitting permanently under the strip. Most
   readers understand the bars at a glance and never needed them; the ones who
   do still get them, in one place, when they ask.
   -------------------------------------------------------------------------- */

.status-block__head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.status-help {
  position: relative;
  display: inline-flex;
}

.status-help__btn {
  width: 20px;
  height: 20px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 99px;
  background: var(--white);
  color: var(--ink-soft);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.status-help__btn:hover,
.status-help__btn[aria-expanded='true'] {
  border-color: var(--forest);
  color: var(--ink);
}

.status-help__btn:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* Left-aligned to the button rather than centred on it: the button sits near
   the left edge of a wide block, and a centred panel would hang off it. */
.status-help__panel {
  position: absolute;
  top: calc(100% + 8px);
  left: -8px;
  z-index: 5;
  width: max-content;
  max-width: min(420px, 84vw);
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--white);
  box-shadow: 0 16px 40px rgba(5, 52, 36, 0.16);
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--ink-soft);
}

.status-help__panel p + p {
  margin-top: 10px;
}
