/**
 * Copyright (c) Tetrate, Inc All Rights Reserved.
 */

/*
 * Status page styles. One stylesheet, no build step, no framework — see the
 * comment in index.html for why this page carries no dependencies.
 *
 * Colour is never the only signal. Every status also carries a text label, and
 * the dots differ in shape as well as hue, so the page reads correctly with any
 * form of colour blindness and in a monochrome print.
 */

:root {
  --bg: #ffffff;
  --bg-subtle: #f6f7f9;
  --border: #e2e5ea;
  --text: #1a1d21;
  --text-muted: #5b6270;

  --operational: #12805c;
  --degraded: #b7791f;
  --outage: #c0322b;
  --unknown: #6b7280;

  --operational-bg: #e6f4ef;
  --degraded-bg: #fdf4e3;
  --outage-bg: #fbeae9;
  --unknown-bg: #f1f2f4;

  --radius: 8px;

  /* Tetrate orange, matching the logo mark and the app's --brand token.
     Confined to page chrome — the top rule, links, focus rings — and never used
     for a status, so it cannot be misread as a signal. It sits close to
     --degraded in hue, which is exactly why the two never appear in the same
     role. */
  --brand: #ff5500;
}

/* The viewer's theme is respected rather than overridden: this page is often
   opened in the middle of the night by someone already annoyed. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #14161a;
    --bg-subtle: #1b1e24;
    --border: #2b3038;
    --text: #eceef1;
    --text-muted: #9aa2b1;

    --operational: #3ecf9a;
    --degraded: #e3b341;
    --outage: #f4776c;
    --unknown: #9aa2b1;

    --operational-bg: #16302a;
    --degraded-bg: #322a17;
    --outage-bg: #38201f;
    --unknown-bg: #22262c;

    /* Unchanged: the orange has enough contrast on the dark ground too. */
    --brand: #ff5500;
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.wrap {
  max-width: 980px;
  margin: 0 auto;
  padding: 0 20px;
}

/* A thin brand rule across the top. The one piece of pure decoration on the
   page, and it earns its place by making the page recognisably Tetrate's above
   the fold without spending any of the status palette. */
.page-header {
  border-top: 3px solid var(--brand);
  border-bottom: 1px solid var(--border);
  padding: 26px 0 22px;
  margin-bottom: 28px;
}

.brand {
  display: inline-block;
  text-decoration: none;
}

.brand-logo {
  display: block;
  height: 26px;
  /* Overrides the width attribute in the HTML, which is only there to reserve
     the aspect ratio while the image loads. */
  width: auto;
}

/*
 * The wordmark ships as near-black artwork on transparency, so on a dark ground
 * it is invisible. invert() lifts it to near-white but also swings the orange
 * mark to blue; rotating the hue a half-turn brings the mark back. The result is
 * a 2 degree hue shift on a fully saturated orange — indistinguishable from the
 * brand colour, and it keeps the real logo rather than substituting a
 * monochrome lockup.
 */
@media (prefers-color-scheme: dark) {
  .brand-logo {
    filter: invert(1) hue-rotate(180deg);
  }
}

h1 {
  margin: 12px 0 0;
  font-size: 26px;
  font-weight: 650;
  letter-spacing: -0.01em;
}

/* ---------- staleness banner ---------- */

.banner {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 12px 14px;
  margin-bottom: 16px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--degraded);
  border-radius: var(--radius);
  background: var(--degraded-bg);
  font-size: 14px;
}

.banner[hidden] {
  display: none;
}

/* ---------- overall ---------- */

.overall {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 12px;
  align-items: center;
  padding: 18px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 28px;
}

.overall h2 {
  margin: 0;
  font-size: 19px;
  font-weight: 600;
}

.overall .dot {
  grid-row: 1 / span 2;
  width: 14px;
  height: 14px;
}

.overall .updated {
  grid-column: 2;
  margin: 0;
  font-size: 13px;
  color: var(--text-muted);
}

.overall--operational { background: var(--operational-bg); border-color: var(--operational); }
.overall--degraded    { background: var(--degraded-bg);    border-color: var(--degraded); }
.overall--outage      { background: var(--outage-bg);      border-color: var(--outage); }
.overall--unknown     { background: var(--unknown-bg);     border-color: var(--unknown); }

/* ---------- status dots ---------- */

.dot {
  display: inline-block;
  flex: none;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--unknown);
}

/* Shape carries the signal alongside hue: operational is a circle, degraded a
   rounded square, an outage a square, unknown a hollow ring. */
.status--operational .dot { background: var(--operational); }
.status--degraded .dot    { background: var(--degraded); border-radius: 3px; }
.status--outage .dot      { background: var(--outage); border-radius: 1px; }
.status--unknown .dot     { background: transparent; border: 2px solid var(--unknown); }

.overall--operational .dot { background: var(--operational); }
.overall--degraded .dot    { background: var(--degraded); border-radius: 4px; }
.overall--outage .dot      { background: var(--outage); border-radius: 2px; }
.overall--unknown .dot     { background: transparent; border: 2px solid var(--unknown); }

/* ---------- groups and components ---------- */

.group {
  margin-bottom: 26px;
}

.group h3 {
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Two columns of cards rather than one tall list: at twelve components the
   single-column version ran to several screens, and nothing here rewards
   scrolling. Collapses to one column on narrow viewports, where side-by-side
   cards would squeeze both the description and the history bar. */
.components {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}

@media (min-width: 720px) {
  .components {
    grid-template-columns: 1fr 1fr;
  }
}

/* A column, so the history bar can be pushed to the bottom. Grid rows stretch
   cards to a common height, and without this a card whose neighbour carries an
   extra detail line would sit its bar higher — leaving the bars unaligned across
   the row, which reads as sloppy on the one element meant to be scanned. */
.component {
  display: flex;
  flex-direction: column;
  padding: 13px 16px 15px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.component-head {
  display: flex;
  gap: 10px;
  align-items: baseline;
}

.component-name {
  font-weight: 600;
  flex: 1;
}

.component-label {
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

.status--operational .component-label { color: var(--operational); }
.status--degraded .component-label    { color: var(--degraded); }
.status--outage .component-label      { color: var(--outage); }
.status--unknown .component-label     { color: var(--unknown); }

.component-description,
.component-detail {
  margin: 4px 0 0;
  font-size: 13.5px;
  color: var(--text-muted);
}

.component-detail {
  color: var(--text);
}

.component-more {
  margin: 7px 0 0;
  font-size: 13px;
}

/* An arrow marks the link as leaving the page, so it is distinguishable from
   the surrounding prose without relying on the underline alone. */
.component-link::after {
  content: " \2197";
  text-decoration: none;
}

/* ---------- history bar ---------- */

.history {
  display: flex;
  gap: 1.5px;
  /* auto pushes the bar to the card's bottom edge; the padding keeps it clear
     of the text above when the card has spare height. */
  margin-top: auto;
  padding-top: 11px;
  height: 18px;
  align-items: stretch;
  box-sizing: content-box;
}

.history-day {
  flex: 1 1 0;
  min-width: 1px;
  border-radius: 1.5px;
  background: var(--bg-subtle);
}

.history-day--operational { background: var(--operational); }
.history-day--degraded    { background: var(--degraded); }
.history-day--outage      { background: var(--outage); }
.history-day--unknown     { background: var(--unknown); opacity: 0.35; }
.history-day--nodata      { background: var(--border); opacity: 0.5; }

/* One legend per group, under the grid. Repeating "90 days ago / Today" beneath
   every card was twelve lines of the same information. */
.history-legend {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
  font-size: 11.5px;
  color: var(--text-muted);
}

/* ---------- misc ---------- */

.notice {
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-subtle);
  font-size: 14px;
}

.page-footer {
  border-top: 1px solid var(--border);
  margin-top: 36px;
  padding-top: 18px;
  padding-bottom: 40px;
  font-size: 13px;
  color: var(--text-muted);
}

.page-footer p {
  margin: 0 0 6px;
}

a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

a:hover {
  color: var(--brand);
}

/* Visible keyboard focus, in the brand colour. The page is mostly text, so the
   few links here are the whole keyboard surface and must be obvious. */
a:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: 2px;
}

.brand:focus-visible {
  outline-offset: 5px;
}

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