/* status.portal26.ai
 *
 * No build step, no preprocessor. Served from the distribution root as
 * /app.css and uploaded at deploy time, not per invocation (design §6).
 *
 * The CSP is `style-src 'self'` — every colour here is reached through a class
 * on the element. Nothing in the rendered HTML carries a `style=` attribute,
 * and a test enforces that.
 *
 * Neutrals and the type scale below are placeholders. Replace with the Pulse
 * tokens (design §7) — the status colours are fixed and should not change.
 */

:root {
  /* Status colours: fixed by design §7. */
  --op:      #1F9D55;
  --partial: #E8590C;
  --major:   #C92A2A;
  --nodata:  #D6D6D6;

  /* Text-on-tint variants. Pills use a tinted ground with saturated text
     rather than white-on-colour, which would not clear WCAG AA at these
     hues for normal-weight text. */
  --op-ink:      #14663A;
  --partial-ink: #9A3A05;
  --major-ink:   #8F1D1D;
  --nodata-ink:  #545454;

  --bg:        #FFFFFF;
  --bg-subtle: #F7F7F8;
  --ink:       #1A1A1C;
  --ink-muted: #5E5E66;
  --rule:      #E4E4E8;

  --radius: 8px;
  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --op:      #2FA968;
    --partial: #F07419;
    --major:   #D93A3A;
    --nodata:  #3A3A40;

    --op-ink:      #5BE49B;
    --partial-ink: #FDBA74;
    --major-ink:   #FCA5A5;
    --nodata-ink:  #9A9AA4;

    --bg:        #111113;
    --bg-subtle: #191920;
    --ink:       #ECECEF;
    --ink-muted: #9A9AA4;
    --rule:      #2A2A31;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 0 1rem 4rem;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

main, header, footer { max-width: 920px; margin-inline: auto; }

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

.banner {
  display: flex;
  align-items: center;
  gap: .75rem;
  margin: 2.5rem auto 2rem;
  padding: 1.1rem 1.25rem;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  background: var(--bg-subtle);
}

.banner h1 { margin: 0; font-size: 1.25rem; font-weight: 600; letter-spacing: -.01em; }

/* Colour never carries meaning alone (design §7): the icon shape differs per
   state, and the banner text always states the status in words. */
.banner__icon {
  flex: none;
  width: 1.4rem; height: 1.4rem;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: .95rem; font-weight: 700; color: var(--bg);
}
.banner__icon::before { content: "?"; }

.banner--none    { border-color: var(--op); }
.banner--none    .banner__icon { background: var(--op); }
.banner--none    .banner__icon::before { content: "\2713"; }   /* check */

.banner--minor   { border-color: var(--partial); }
.banner--minor   .banner__icon { background: var(--partial); }
.banner--minor   .banner__icon::before { content: "\0021"; }   /* ! */

.banner--major   { border-color: var(--major); }
.banner--major   .banner__icon { background: var(--major); }
.banner--major   .banner__icon::before { content: "\00D7"; }   /* x */

.banner--unknown { border-color: var(--nodata); }
.banner--unknown .banner__icon { background: var(--nodata-ink); }
.banner--unknown .banner__icon::before { content: "?"; }

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

.group { margin-bottom: 2.75rem; }

.group__head,
.component__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.group__head {
  padding-bottom: .6rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 1.25rem;
}
.group__head h2 { margin: 0; font-size: 1.05rem; font-weight: 650; letter-spacing: -.01em; }

.incidents__empty { margin: 0; color: var(--ink-muted); }

.incident { margin-bottom: 1.6rem; }
.incident h3 { margin: 0; font-size: .95rem; font-weight: 550; color: var(--ink); }
.incident__affects { margin: .3rem 0 .6rem; font-size: .85rem; color: var(--ink-muted); }
.incident__updates { margin: 0; padding: 0; list-style: none; }
.incident__updates li { margin-bottom: .6rem; }
.incident__updates time { display: block; font-size: .78rem; color: var(--ink-muted); }

.component { margin-bottom: 1.6rem; }
.component__head h3 { margin: 0; font-size: .95rem; font-weight: 550; color: var(--ink); }

.pill {
  flex: none;
  font-size: .75rem;
  font-weight: 600;
  padding: .2rem .6rem;
  border-radius: 999px;
  white-space: nowrap;
}
.pill--operational { background: color-mix(in srgb, var(--op) 14%, transparent);      color: var(--op-ink); }
.pill--partial     { background: color-mix(in srgb, var(--partial) 16%, transparent); color: var(--partial-ink); }
.pill--major       { background: color-mix(in srgb, var(--major) 16%, transparent);   color: var(--major-ink); }
.pill--nodata      { background: color-mix(in srgb, var(--nodata) 40%, transparent);  color: var(--nodata-ink); }

/* ---------- rows and bars ------------------------------------------------ */

/* A component renders as a single row. Individual endpoints are deliberately
   not shown (see src/view/mod.rs) — the location count stands in for them. */
.component__locations {
  font-weight: 400;
  font-size: .78rem;
  color: var(--ink-muted);
  margin-left: .5rem;
}

.component__head { margin-bottom: .5rem; }

.bars {
  display: flex;
  gap: 2px;
  height: 34px;
  align-items: stretch;
}

.bar {
  flex: 1 1 0;
  min-width: 2px;
  border-radius: 1.5px;
  position: relative;
  transition: transform .08s ease;
}
.bar--operational { background: var(--op); }
.bar--partial     { background: var(--partial); }
.bar--major       { background: var(--major); }
.bar--nodata      { background: var(--nodata); }

.bar:hover { transform: scaleY(1.12); }

/* Tooltip from the aria-label, so the visible text and the announced text can
   never drift apart.
   Hover only, deliberately: a focus tooltip needs tabindex on every bar, and
   ~990 tab stops is far worse for keyboard users than no tooltip. Screen
   readers get the same string from aria-label. */
.bar:hover::after {
  content: attr(aria-label);
  position: absolute;
  bottom: calc(100% + 7px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  padding: .35rem .55rem;
  border-radius: 6px;
  background: var(--ink);
  color: var(--bg);
  font-size: .74rem;
  font-weight: 500;
  line-height: 1.35;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 2px 10px rgb(0 0 0 / .18);
}

.row__legend {
  display: flex;
  justify-content: space-between;
  margin-top: .35rem;
  font-size: .74rem;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

/* ---------- footer ------------------------------------------------------- */

footer {
  margin-top: 3rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
  font-size: .82rem;
  color: var(--ink-muted);
}
footer p { margin: .3rem 0; }
footer a { color: inherit; text-underline-offset: 2px; }
/* Bottom right: when the page was rendered, and by which build. */
.footer__meta { text-align: right; font-size: .75rem; }

/* ---------- narrow viewports --------------------------------------------- */

/* Bars are oldest-first, so hiding the leading n drops the oldest days.
   Degrades without JavaScript (design §7). The full series stays in
   /api/uptime.json regardless. */
@media (max-width: 900px) {
  .bar:nth-child(-n+30) { display: none; }
}
@media (max-width: 640px) {
  .bar:nth-child(-n+60) { display: none; }
  body { font-size: 14px; }
  .bars { height: 30px; }
  /* A nowrap tooltip overflows a narrow screen; let it wrap instead. */
  .bar:hover::after { white-space: normal; max-width: 60vw; width: max-content; }
}

@media (prefers-reduced-motion: reduce) {
  .bar, .bar:hover { transition: none; transform: none; }
}
