/* ==========================================================================
   app.css — layout + page composition for the public status page.
   Consumes ONLY the tokens and primitive classes declared in theme.css (§1).
   There is no second palette here: every colour is a var(), a color-mix() of
   vars, transparent, or currentColor. Dynamic status colour arrives through
   the four --sc* custom properties, which JS sets with el.style.setProperty()
   (the CSP forbids inline style attributes, and hue must not be encoded in a
   class name — see CONTRACT §7a.1/§7a.2).
   ========================================================================== */

/* --- self-hosted faces -------------------------------------------------- */
/* Declared here so the page renders in brand type even if nothing else does;
   duplicate @font-face blocks with identical src are free (the browser
   de-duplicates by URL and only downloads the faces actually used). */
@font-face {
  font-family: 'Catamaran';
  src: url('fonts/catamaran-latin.woff2') format('woff2');
  font-weight: 300 800; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Catamaran';
  src: url('fonts/catamaran-latin-ext.woff2') format('woff2');
  font-weight: 300 800; font-style: normal; font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('fonts/jetbrains-mono-latin.woff2') format('woff2');
  font-weight: 400 700; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('fonts/jetbrains-mono-latin-ext.woff2') format('woff2');
  font-weight: 400 700; font-style: normal; font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face { font-family: 'GE Dinar One'; src: url('fonts/gedinarone-regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'GE Dinar One'; src: url('fonts/gedinarone-medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'GE Dinar One'; src: url('fonts/gedinarone-semibold.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'GE Dinar One'; src: url('fonts/gedinarone-bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap; }

/* --- page-local custom properties --------------------------------------- */
:root {
  /* Current status colour set. Re-pointed at another --st-* family by JS. */
  --sc: var(--st-unknown);
  --sc-soft: var(--st-unknown-soft);
  --sc-border: var(--st-unknown-border);
  --sc-text: var(--st-unknown-text);
  --wrap-max: 1160px;
  --gutter: clamp(1rem, 4vw, 2.5rem);
  --hc-x: 0px;
  --hc-y: 0px;
  --hc-tx: -50%;
  --hc-ty: -100%;
  --stagger: 0;
}

/* --- reset / base ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
/* Several composites below set display, which would otherwise beat the UA
   [hidden] rule and leak panels that JS keeps closed. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; overflow-x: clip; }
body {
  margin: 0;
  min-height: 100svh;
  overflow-x: clip;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, p, dl, dd, dt, figure, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
img, svg { display: block; max-width: 100%; }
:where(a, button, input, [tabindex]):focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r-sm); }

.mono, .kbd, code {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}
.wrap { width: 100%; max-width: var(--wrap-max); margin-inline: auto; padding-inline: var(--gutter); }
/* the top bar is sticky, so every anchor target has to clear it */
:where([id]) { scroll-margin-block-start: 5.5rem; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
.stack { display: grid; gap: var(--s-4); }
.skip-link {
  position: fixed; inset-inline-start: var(--s-4); inset-block-start: var(--s-4);
  z-index: 90; padding: var(--s-2) var(--s-4); border-radius: var(--r-full);
  background: var(--surface-3); border: 1px solid var(--border-strong);
  transform: translateY(-200%); transition: transform var(--d-fast) var(--e-out);
}
.skip-link:focus-visible { transform: none; }

/* --- aurora field + grain ---------------------------------------------- */
/* Fixed layer, transform-only keyframes, contained: scrolling the page never
   invalidates it, so the mesh costs one composited layer and nothing else. */
.aurora {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  overflow: hidden; contain: layout paint style;
  mask-image: linear-gradient(to bottom, #000 0%, #000 42%, transparent 92%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 42%, transparent 92%);
}
.aurora-blob {
  position: absolute; display: block; border-radius: 50%;
  filter: blur(70px); will-change: transform; opacity: .85;
  transition: background var(--d-xslow) var(--e-out);
}
.aurora-blob.b1 {
  inline-size: 62vmax; block-size: 62vmax; inset-block-start: -22vmax; inset-inline-start: -12vmax;
  background: radial-gradient(circle at 50% 50%,
    color-mix(in oklab, var(--sc) 42%, transparent) 0%,
    color-mix(in oklab, var(--sc) 12%, transparent) 45%, transparent 70%);
  animation: drift-a 44s var(--e-in-out) infinite alternate;
}
.aurora-blob.b2 {
  inline-size: 54vmax; block-size: 54vmax; inset-block-start: -18vmax; inset-inline-end: -14vmax;
  background: radial-gradient(circle at 50% 50%,
    color-mix(in oklab, var(--navy-600) 62%, transparent) 0%,
    color-mix(in oklab, var(--navy-700) 22%, transparent) 50%, transparent 72%);
  animation: drift-b 57s var(--e-in-out) infinite alternate;
}
.aurora-blob.b3 {
  inline-size: 34vmax; block-size: 34vmax; inset-block-start: 6vmax; inset-inline-start: 38%;
  background: radial-gradient(circle at 50% 50%,
    color-mix(in oklab, var(--sky-400) 26%, transparent) 0%, transparent 68%);
  animation: drift-c 39s var(--e-in-out) infinite alternate;
}
.aurora-blob.b4 {
  inline-size: 46vmax; block-size: 46vmax; inset-block-start: 12vmax; inset-inline-end: 10%;
  background: radial-gradient(circle at 50% 50%,
    color-mix(in oklab, var(--sc) 24%, transparent) 0%, transparent 66%);
  animation: drift-d 63s var(--e-in-out) infinite alternate;
}
@keyframes drift-a { from { transform: translate3d(0,0,0) scale(1); } to { transform: translate3d(6vmax,4vmax,0) scale(1.12); } }
@keyframes drift-b { from { transform: translate3d(0,0,0) scale(1.04); } to { transform: translate3d(-7vmax,5vmax,0) scale(.94); } }
@keyframes drift-c { from { transform: translate3d(0,0,0) scale(.92); } to { transform: translate3d(5vmax,-4vmax,0) scale(1.16); } }
@keyframes drift-d { from { transform: translate3d(0,0,0) scale(1.08); } to { transform: translate3d(-5vmax,-6vmax,0) scale(.96); } }

.grain-layer {
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background-image: var(--grain); background-repeat: repeat;
  opacity: .5; mix-blend-mode: soft-light;
}
:root[data-theme="light"] .grain-layer { opacity: .35; mix-blend-mode: multiply; }

/* Everything readable sits above the two decorative layers. */
.topbar, main, .site-foot, .announce-slot { position: relative; z-index: 2; }

/* --- top bar ------------------------------------------------------------ */
.topbar {
  position: sticky; inset-block-start: 0; z-index: 30;
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  background: color-mix(in oklab, var(--bg) 68%, transparent);
  border-block-end: 1px solid transparent;
  transition: border-color var(--d-med) var(--e-out), background var(--d-med) var(--e-out);
}
.topbar.scrolled { border-block-end-color: var(--border); box-shadow: var(--shadow-1); }
.topbar-in {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); min-block-size: 4rem;
}
.brand { display: inline-flex; align-items: center; gap: var(--s-3); color: var(--text); }
.brand-logo, .foot-logo, .hero-crest, .eb-mark {
  display: block; background-color: currentColor;
  mask-repeat: no-repeat; -webkit-mask-repeat: no-repeat;
  mask-position: center; -webkit-mask-position: center;
  mask-size: contain; -webkit-mask-size: contain;
}
.brand-logo {
  inline-size: 74px; block-size: 41px;
  mask-image: url('logo-full.svg'); -webkit-mask-image: url('logo-full.svg');
}
.brand-sub {
  font-family: var(--font-display); font-size: var(--fs-sm); font-weight: 600;
  letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-3);
  padding-inline-start: var(--s-3); border-inline-start: 1px solid var(--border);
}
.brand:hover .brand-sub { color: var(--text-2); }
.topbar-actions { display: flex; align-items: center; gap: var(--s-2); }
.icon-btn { display: inline-flex; align-items: center; gap: var(--s-2); }
.ico { display: inline-flex; inline-size: 1em; block-size: 1em; flex: none; }
.ico svg { inline-size: 100%; block-size: 100%; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.ico.filled svg { fill: currentColor; stroke: none; }
.palette-trigger { gap: var(--s-2); }
.palette-trigger-label { color: var(--text-3); }
.kbd {
  font-size: var(--fs-micro); padding: .1em .4em; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text-3);
  line-height: 1.5;
}
.lang-code { font-size: var(--fs-xs); font-weight: 700; letter-spacing: .04em; }
@media (max-width: 620px) {
  .brand-logo { inline-size: 34px; block-size: 34px; mask-image: url('logo-mark.svg'); -webkit-mask-image: url('logo-mark.svg'); }
  .palette-trigger-label, .palette-trigger .kbd, .brand-sub { display: none; }
}

/* --- announcement ------------------------------------------------------- */
.announce {
  display: flex; align-items: flex-start; gap: var(--s-3);
  max-width: var(--wrap-max); margin: var(--s-4) auto 0;
  padding: var(--s-3) var(--s-4);
  margin-inline: var(--gutter);
  border: 1px solid var(--sc-border); background: var(--sc-soft);
  border-radius: var(--r-lg); color: var(--text);
  animation: ann-in var(--d-slow) var(--e-spring) both;
}
@media (min-width: 1224px) { .announce { margin-inline: auto; } }
@keyframes ann-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
.announce .ico { color: var(--sc-text); margin-block-start: .18em; }
.announce-text { flex: 1 1 auto; font-size: var(--fs-body); }
.announce-until { display: block; margin-block-start: var(--s-1); color: var(--text-3); font-size: var(--fs-xs); }
.announce-x {
  flex: none; display: inline-grid; place-items: center; inline-size: 1.75rem; block-size: 1.75rem;
  border-radius: var(--r-full); border: 1px solid transparent; background: transparent; cursor: pointer;
  color: var(--text-2); transition: background var(--d-fast) var(--e-out), color var(--d-fast) var(--e-out);
}
.announce-x:hover { background: var(--surface-hover); color: var(--text); }

/* --- hero --------------------------------------------------------------- */
.hero { position: relative; padding-block: clamp(var(--s-10), 9vw, var(--s-20)) var(--s-10); text-align: center; }
.hero-inner { position: relative; z-index: 1; display: grid; justify-items: center; gap: var(--s-4); }
.hero-crest {
  inline-size: 46px; block-size: 46px; color: var(--sc);
  mask-image: url('logo-mark.svg'); -webkit-mask-image: url('logo-mark.svg');
  opacity: .9; animation: crest-spin 34s linear infinite;
}
@keyframes crest-spin { to { transform: rotate(360deg); } }
.hero-kicker { color: var(--text-3); font-size: var(--fs-sm); letter-spacing: var(--tracking-wide); text-transform: uppercase; }
.verdict {
  display: flex; align-items: center; justify-content: center; gap: var(--s-3);
  font-family: var(--font-display); font-size: var(--fs-hero); font-weight: 700;
  line-height: var(--lh-tight); letter-spacing: var(--tracking-tight);
  text-wrap: balance; max-inline-size: 22ch;
}
.verdict-mark { display: inline-flex; inline-size: .82em; block-size: .82em; color: var(--sc); flex: none; }
.verdict-mark svg {
  inline-size: 100%; block-size: 100%;
  /* The glyph arrives here as a bare <svg> without its .ico wrapper, so it
     needs the stroke treatment restated or the paths fill solid black. */
  fill: none; stroke: currentColor; stroke-width: 1.9;
  stroke-linecap: round; stroke-linejoin: round;
}
.verdict-text { transition: opacity var(--d-med) var(--e-out); }
.hero-meta {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: var(--s-2) var(--s-3); color: var(--text-3); font-size: var(--fs-sm);
}
.meta-item { display: inline-flex; align-items: center; gap: var(--s-1); white-space: nowrap; }
.meta-key { color: var(--text-3); }
.dot-sep { inline-size: 3px; block-size: 3px; border-radius: var(--r-full); background: var(--text-3); opacity: .6; }
#as-of, #checked-ago { color: var(--text-2); }
/* reserve width so the per-second relative clock can never shift the line */
#checked-ago { min-inline-size: 8.5ch; text-align: center; }

.live { display: inline-flex; align-items: center; gap: var(--s-2); color: var(--text-2); }
.live-dot {
  position: relative; inline-size: .5rem; block-size: .5rem; border-radius: var(--r-full);
  background: var(--sc); flex: none;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--sc) 22%, transparent);
  transition: background var(--d-med) var(--e-out);
}
.live.ping .live-dot::after {
  content: ''; position: absolute; inset: -2px; border-radius: var(--r-full);
  border: 1px solid var(--sc); animation: ping var(--d-xslow) var(--e-out) 1;
}
@keyframes ping { from { transform: scale(.6); opacity: .9; } to { transform: scale(3); opacity: 0; } }
.live[data-conn="down"] .live-dot, .live[data-conn="retry"] .live-dot { background: var(--st-degraded); box-shadow: none; }
.live[data-conn="retry"] .live-dot { animation: blink 1.1s var(--e-in-out) infinite; }
@keyframes blink { 50% { opacity: .25; } }
.live[data-conn="down"] .live-label, .live[data-conn="retry"] .live-label { color: var(--st-degraded-text); }

/* breathing halo — hue comes from --sc, never from a class name */
.halo { position: absolute; inset-block-start: 0; inset-inline: 0; block-size: 100%; pointer-events: none; display: grid; place-items: center; }
.halo-core, .halo-ring {
  position: absolute; border-radius: 50%; display: block;
  inset-block-start: clamp(2rem, 7vw, 5rem);
}
.halo-core {
  inline-size: clamp(16rem, 40vw, 30rem); aspect-ratio: 1;
  background: radial-gradient(circle at 50% 50%,
    color-mix(in oklab, var(--sc) 30%, transparent) 0%,
    color-mix(in oklab, var(--sc) 9%, transparent) 42%, transparent 68%);
  filter: blur(14px); animation: breathe 7.5s var(--e-in-out) infinite;
}
.halo-ring { inline-size: clamp(13rem, 33vw, 24rem); aspect-ratio: 1; border: 1px solid color-mix(in oklab, var(--sc) 22%, transparent); }
.halo-ring.r1 { animation: pulse-ring 7.5s var(--e-in-out) infinite; }
.halo-ring.r2 { animation: pulse-ring 7.5s var(--e-in-out) 2.4s infinite; }
@keyframes breathe { 0%, 100% { transform: scale(1); opacity: .85; } 50% { transform: scale(1.09); opacity: 1; } }
@keyframes pulse-ring { 0% { transform: scale(.86); opacity: 0; } 30% { opacity: .7; } 100% { transform: scale(1.28); opacity: 0; } }

.hero-stats { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-2) var(--s-3); margin-block-start: var(--s-2); }
.hstat {
  display: inline-flex; align-items: baseline; gap: var(--s-2);
  padding: var(--s-2) var(--s-4); border-radius: var(--r-full);
  border: 1px solid var(--border); background: var(--surface);
  font-size: var(--fs-sm); color: var(--text-2);
  animation: rise var(--d-slow) var(--e-spring) both;
  animation-delay: calc(var(--stagger) * 60ms);
}
.hstat b { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text); font-weight: 600; }
.hstat > span { color: var(--text-3); }
.hstat.is-bad b { color: var(--sc-text); }
@keyframes rise { from { opacity: 0; transform: translateY(10px) scale(.97); } to { opacity: 1; transform: none; } }

/* --- sections ----------------------------------------------------------- */
.sect { margin-block-start: clamp(var(--s-8), 6vw, var(--s-16)); scroll-margin-block-start: 5.5rem; }
.sect-head { display: flex; align-items: center; gap: var(--s-3); margin-block-end: var(--s-4); }
.sect-title {
  font-family: var(--font-display); font-size: var(--fs-h2); font-weight: 700;
  letter-spacing: var(--tracking-tight); line-height: var(--lh-snug);
}
.sect-note { margin-inline-start: auto; color: var(--text-3); font-size: var(--fs-sm); }
.group-head {
  display: flex; align-items: center; gap: var(--s-3);
  margin-block: var(--s-6) var(--s-3); padding-block-end: var(--s-2);
  border-block-end: 1px solid var(--border);
}
.group-head:first-child { margin-block-start: 0; }
.group-name {
  font-family: var(--font-display); font-size: var(--fs-h3); font-weight: 600;
  letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-2);
}
.group-meta { margin-inline-start: auto; display: inline-flex; align-items: center; gap: var(--s-2); font-size: var(--fs-xs); color: var(--text-3); }
.card { position: relative; }
.reveal-item {
  animation: rise var(--d-slow) var(--e-spring) both;
  animation-delay: calc(var(--stagger) * 55ms);
}
/* Section titles get their spring only once they are actually scrolled to; if
   the observer never fires they simply stay where they are (never hidden). */
.sect.in .sect-title { animation: rise var(--d-med) var(--e-spring) both; }

/* --- overall dial ------------------------------------------------------- */
.overview-card {
  display: grid; gap: var(--s-6) var(--s-8);
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  align-items: center; padding: var(--s-6);
}
.dial-wrap { position: relative; inline-size: clamp(9rem, 22vw, 13rem); aspect-ratio: 1; }
.dial { position: absolute; inset: 0; }
.dial > svg { inline-size: 100%; block-size: 100%; }
.agg { display: grid; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); gap: var(--s-4); }
.agg-item { display: grid; gap: var(--s-1); padding-inline-start: var(--s-3); border-inline-start: 2px solid var(--border); }
.agg-item dt { font-size: var(--fs-xs); color: var(--text-3); letter-spacing: .02em; }
.agg-item dd {
  font-size: var(--fs-h3); font-weight: 600; color: var(--text);
  /* These read as single values ("2h 52m", "2 hr ago", "738 ms"); letting
     them wrap mid-value splits the unit onto its own line. */
  white-space: nowrap;
}
@media (max-width: 720px) {
  .overview-card { grid-template-columns: 1fr; justify-items: center; }
  .agg { inline-size: 100%; }
}

/* --- service card ------------------------------------------------------- */
.svc { padding: var(--s-5) var(--s-5) var(--s-4); }
.svc.sk-card { display: grid; gap: var(--s-4); min-block-size: 8rem; }
.svc-top { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s-3) var(--s-4); align-items: start; }
.svc-id { display: grid; gap: var(--s-1); min-inline-size: 0; }
.svc-name-row { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.svc-name { font-family: var(--font-display); font-size: var(--fs-h3); font-weight: 600; color: var(--text); letter-spacing: -.01em; }
.svc-host { color: var(--text-3); font-size: var(--fs-xs); }
.svc-host:hover { color: var(--text-2); text-decoration: underline; text-underline-offset: 2px; }
.svc-desc { color: var(--text-2); font-size: var(--fs-sm); max-inline-size: 62ch; }
.svc-err { display: inline-flex; align-items: center; gap: var(--s-2); font-size: var(--fs-xs); color: var(--st-major-text); }
.svc-metrics { display: flex; align-items: center; gap: var(--s-5); }
.metric { display: grid; gap: 2px; justify-items: end; text-align: end; }
.metric-label { font-size: var(--fs-micro); letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-3); }
.metric-value { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--fs-h3); font-weight: 600; color: var(--text); line-height: 1.15; }
.metric-value.dim { color: var(--text-3); font-weight: 500; }
.metric-sub { font-size: var(--fs-micro); color: var(--text-3); font-family: var(--font-mono); }
.spark { inline-size: clamp(72px, 14vw, 132px); block-size: 34px; }
.spark > svg { inline-size: 100%; block-size: 100%; }
.cert { position: relative; display: grid; place-items: center; inline-size: 46px; block-size: 46px; }
.cert-ring { position: absolute; inset: 0; }
.cert-ring > svg { inline-size: 100%; block-size: 100%; }
.pill-dot { inline-size: .5rem; block-size: .5rem; border-radius: var(--r-full); background: currentColor; flex: none; }
.pill .ico { inline-size: .9em; block-size: .9em; }
.pill { display: inline-flex; align-items: center; gap: var(--s-2); white-space: nowrap; }

/* 90-day ribbon */
.ribbon-block { margin-block-start: var(--s-4); }
.ribbon-scale { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3); font-size: var(--fs-micro); color: var(--text-3); margin-block-end: var(--s-2); }
.ribbon-shell { position: relative; }
.ribbon {
  position: relative; block-size: 40px; border-radius: var(--r-sm);
  cursor: crosshair; touch-action: pan-y;
}
.ribbon > svg { inline-size: 100%; block-size: 100%; }
.ribbon:focus-visible { box-shadow: var(--ring); }
/* keyboard cursor for ribbon days: a real, visible caret independent of hover */
.ribbon-caret {
  position: absolute; inset-block: -3px; inline-size: 2px; border-radius: var(--r-full);
  background: var(--text); opacity: 0; pointer-events: none;
  inset-inline-start: var(--caret-x, 0);
  transform: translateX(-50%);
  transition: inset-inline-start var(--d-fast) var(--e-out), opacity var(--d-fast) linear;
}
.ribbon-shell[data-caret="on"] .ribbon-caret { opacity: .85; }
[dir="rtl"] .ribbon-caret { transform: translateX(50%); }
.ribbon-hint { margin-block-start: var(--s-2); font-size: var(--fs-micro); color: var(--text-3); }

/* expand region */
.svc-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); margin-block-start: var(--s-3); }
.svc-checked { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--text-3); min-inline-size: 12ch; }
.expand-btn { display: inline-flex; align-items: center; gap: var(--s-2); }
.expand-btn .ico { transition: transform var(--d-med) var(--e-out); }
.expand-btn[aria-expanded="true"] .ico { transform: rotate(180deg); }
.expando { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--d-slow) var(--e-out); }
.expando[data-open="1"] { grid-template-rows: 1fr; }
.expando > div { overflow: hidden; min-block-size: 0; }
.expando-in { padding-block-start: var(--s-4); margin-block-start: var(--s-4); border-block-start: 1px solid var(--border); display: grid; gap: var(--s-4); }
.range-row { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.range-tabs { display: inline-flex; padding: 3px; gap: 2px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-full); }
.range-tab {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  padding: var(--s-1) var(--s-3); border-radius: var(--r-full);
  font-size: var(--fs-xs); font-family: var(--font-mono); color: var(--text-3);
  transition: color var(--d-fast) var(--e-out), background var(--d-fast) var(--e-out);
}
.range-tab:hover { color: var(--text); }
.range-tab[aria-selected="true"] { background: var(--surface-3); color: var(--text); box-shadow: var(--shadow-1); }
.range-meta { margin-inline-start: auto; font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--text-3); }
.chart-box { position: relative; min-block-size: 168px; }
.chart-box > div { inline-size: 100%; }
.chart-box svg { inline-size: 100%; }
.chart-loading { position: absolute; inset: 0; display: grid; place-items: center; gap: var(--s-2); }
.lat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); gap: var(--s-3); }
.lat-cell { display: grid; gap: 2px; padding: var(--s-2) var(--s-3); background: var(--surface-2); border-radius: var(--r-md); border: 1px solid var(--border); }
.lat-cell dt { font-size: var(--fs-micro); color: var(--text-3); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.lat-cell dd { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--fs-body); font-weight: 600; }

@media (max-width: 720px) {
  .svc-top { grid-template-columns: 1fr; }
  .svc-metrics { justify-content: space-between; gap: var(--s-3); flex-wrap: wrap; }
  .metric { justify-items: start; text-align: start; }
  .spark { inline-size: 100%; }
}

/* --- hover card --------------------------------------------------------- */
.hovercard {
  position: fixed; z-index: 60; pointer-events: none;
  inset-inline-start: var(--hc-x); inset-block-start: var(--hc-y);
  /* JS picks the translate so the card flips instead of leaving the viewport */
  transform: translate(var(--hc-tx, -50%), var(--hc-ty, -100%));
  min-inline-size: 13rem; max-inline-size: 19rem;
  padding: var(--s-3) var(--s-4);
  background: var(--surface-3); border: 1px solid var(--border-strong);
  border-radius: var(--r-md); box-shadow: var(--shadow-3);
  opacity: 0; transition: opacity var(--d-fast) var(--e-out), transform var(--d-fast) var(--e-out);
}
.hovercard[data-show="1"] { opacity: 1; }
.hc-day { display: flex; align-items: center; gap: var(--s-2); font-weight: 600; font-size: var(--fs-sm); color: var(--text); }
.hc-day .pill-dot { color: var(--sc); }
.hc-rows { display: grid; gap: 2px; margin-block-start: var(--s-2); }
.hc-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4); font-size: var(--fs-xs); }
.hc-row dt { color: var(--text-3); }
.hc-row dd { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text); }
.hc-nodata { margin-block-start: var(--s-2); font-size: var(--fs-xs); color: var(--text-3); }

/* --- incidents ---------------------------------------------------------- */
.inc {
  position: relative; padding: var(--s-5); padding-inline-start: calc(var(--s-5) + 4px);
  overflow: hidden;
}
.inc::before {
  content: ''; position: absolute; inset-block: 0; inset-inline-start: 0; inline-size: 4px;
  background: linear-gradient(to bottom, var(--sc), color-mix(in oklab, var(--sc) 35%, transparent));
}
.inc-head { display: flex; align-items: flex-start; gap: var(--s-3); flex-wrap: wrap; }
.inc-title { font-family: var(--font-display); font-size: var(--fs-h3); font-weight: 600; color: var(--text); flex: 1 1 16ch; min-inline-size: 0; }
.inc-title a { color: inherit; }
.inc-title a:hover { text-decoration: underline; text-underline-offset: 3px; }
.inc-when { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-3); white-space: nowrap; }
.inc-note { margin-block-start: var(--s-2); color: var(--text-2); font-size: var(--fs-sm); white-space: pre-wrap; }
.inc-chips { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-block-start: var(--s-3); }
.chip {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: 2px var(--s-2); border-radius: var(--r-full);
  border: 1px solid var(--border); background: var(--surface-2);
  font-size: var(--fs-micro); color: var(--text-2);
}
.chip:hover { border-color: var(--border-strong); color: var(--text); }
.chip .pill-dot { background: var(--sc); }
.inc-latest {
  margin-block-start: var(--s-4); padding: var(--s-3) var(--s-4);
  background: var(--surface-2); border-radius: var(--r-md); border: 1px solid var(--border);
}
.inc-latest-head { display: flex; align-items: center; gap: var(--s-2); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--text-3); }
.inc-body { margin-block-start: var(--s-2); white-space: pre-wrap; font-size: var(--fs-sm); color: var(--text); overflow-wrap: anywhere; }
.inc-actions { display: flex; align-items: center; gap: var(--s-2); margin-block-start: var(--s-3); flex-wrap: wrap; }
.timeline { display: grid; gap: var(--s-4); margin-block-start: var(--s-4); padding-inline-start: var(--s-5); position: relative; }
.timeline::before { content: ''; position: absolute; inset-block: .4rem; inset-inline-start: 4px; inline-size: 1px; background: var(--border); }
.tl-item { position: relative; }
.tl-item::before {
  content: ''; position: absolute; inset-inline-start: calc(-1 * var(--s-5) + 1px); inset-block-start: .45rem;
  inline-size: 7px; block-size: 7px; border-radius: var(--r-full);
  background: var(--sc); box-shadow: 0 0 0 3px var(--bg);
}
.tl-head { display: flex; align-items: baseline; gap: var(--s-3); flex-wrap: wrap; }
.tl-status { font-size: var(--fs-xs); font-weight: 600; text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--sc-text); }
.tl-ts { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--text-3); }
.tl-body { margin-block-start: var(--s-1); font-size: var(--fs-sm); color: var(--text-2); white-space: pre-wrap; overflow-wrap: anywhere; }
.inc.is-target { box-shadow: var(--ring), var(--shadow-2); }

/* history */
.month-group { margin-block-end: var(--s-6); }
.month-head {
  display: flex; align-items: center; gap: var(--s-3);
  margin-block-end: var(--s-3); color: var(--text-2);
  font-family: var(--font-display); font-size: var(--fs-h3); font-weight: 600;
}
.month-head::after { content: ''; flex: 1 1 auto; block-size: 1px; background: var(--border); }
.month-count { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-3); }
.history-more { display: flex; align-items: center; justify-content: center; gap: var(--s-3); margin-block-start: var(--s-4); }
.empty {
  display: grid; justify-items: center; gap: var(--s-2); text-align: center;
  padding: var(--s-10) var(--s-4); border: 1px dashed var(--border);
  border-radius: var(--r-lg); color: var(--text-3);
}
.empty-ico { inline-size: 2rem; block-size: 2rem; color: var(--st-ok); }
.empty-title { color: var(--text-2); font-size: var(--fs-body); font-weight: 600; }
.empty-sub { font-size: var(--fs-sm); }

/* maintenance */
.maint-when { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); margin-block-start: var(--s-3); font-size: var(--fs-sm); }
.maint-when div { display: grid; gap: 1px; }
.maint-when dt { font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--text-3); }
.maint-when dd { font-family: var(--font-mono); color: var(--text); }
.countdown { font-family: var(--font-mono); color: var(--sc-text); }

/* --- failure + stale states --------------------------------------------- */
.panel-fail {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--s-4) var(--s-5);
  align-items: center; margin-block-start: var(--s-6);
  padding: var(--s-6); border-radius: var(--r-xl);
  border: 1px solid var(--st-major-border); background: var(--st-major-soft);
  animation: rise var(--d-slow) var(--e-spring) both;
}
.fail-ico { inline-size: 2.25rem; block-size: 2.25rem; color: var(--st-major); }
.fail-ico svg { inline-size: 100%; block-size: 100%; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.fail-copy h2 { font-family: var(--font-display); font-size: var(--fs-h3); font-weight: 700; color: var(--text); }
.fail-copy p { color: var(--text-2); font-size: var(--fs-sm); margin-block-start: var(--s-1); }
.fail-detail { color: var(--st-major-text); font-size: var(--fs-xs); }
.fail-actions { display: grid; gap: var(--s-2); justify-items: center; }
.fail-countdown { font-size: var(--fs-micro); color: var(--text-3); }
@media (max-width: 720px) { .panel-fail { grid-template-columns: auto minmax(0, 1fr); } .fail-actions { grid-column: 1 / -1; justify-items: start; } }

.stale-note {
  display: flex; align-items: center; gap: var(--s-2);
  margin-block-start: var(--s-4); padding: var(--s-2) var(--s-4);
  border-radius: var(--r-full); border: 1px solid var(--st-degraded-border);
  background: var(--st-degraded-soft); color: var(--st-degraded-text); font-size: var(--fs-sm);
}

/* --- footer ------------------------------------------------------------- */
.site-foot { margin-block-start: clamp(var(--s-12), 10vw, var(--s-20)); border-block-start: 1px solid var(--border); background: color-mix(in oklab, var(--bg-2) 70%, transparent); }
.foot-in { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: var(--s-8); padding-block: var(--s-10); }
.foot-col { display: grid; gap: var(--s-3); align-content: start; }
.foot-brand { gap: var(--s-2); }
.foot-snips { gap: var(--s-4); }
.sub-form { display: grid; }
.subscribe-cta { white-space: nowrap; }
.foot-logo {
  inline-size: 96px; block-size: 53px; color: var(--text-2);
  mask-image: url('logo-full.svg'); -webkit-mask-image: url('logo-full.svg');
}
.foot-tag { color: var(--text-3); font-size: var(--fs-sm); max-inline-size: 34ch; }
.foot-h { font-family: var(--font-display); font-size: var(--fs-h3); font-weight: 600; color: var(--text); }
.foot-p { color: var(--text-3); font-size: var(--fs-sm); }
.foot-list { display: grid; gap: var(--s-2); }
.foot-link { display: inline-flex; align-items: center; gap: var(--s-2); color: var(--text-2); font-size: var(--fs-sm); width: fit-content; }
.foot-link:hover { color: var(--text); }
.foot-link .ico { color: var(--text-3); }
.sub-row { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.sub-row .input { flex: 1 1 11rem; min-inline-size: 0; }
.field-msg { min-block-size: 1.2em; font-size: var(--fs-xs); color: var(--text-3); }
.field-msg[data-kind="ok"] { color: var(--st-ok-text); }
.field-msg[data-kind="err"] { color: var(--st-major-text); }
.snip { display: grid; gap: var(--s-2); }
.snip-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); }
.snip-title { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--text-3); }
.snip-code {
  display: block; padding: var(--s-2) var(--s-3); border-radius: var(--r-md);
  border: 1px solid var(--border); background: var(--surface-2);
  font-size: var(--fs-micro); color: var(--text-2); line-height: 1.55;
  white-space: pre-wrap; overflow-wrap: anywhere;
  /* Height is a whole number of line boxes, so no line is ever bisected — that
     reads as broken rather than as "scroll for more", especially on macOS where
     overlay scrollbars stay invisible until you actually scroll. Only the TOP
     padding counts: in a scrolling box the block-end padding sits at the end of
     the scrollable content, not reserved against the bottom edge, so including
     it left exactly one padding's worth of the next line peeking through. */
  max-block-size: calc(1.55em * 7 + var(--s-2));
  overflow: auto; scrollbar-width: thin;
}
.snip-badge-img { block-size: 20px; inline-size: auto; }
.copy-btn.done { color: var(--st-ok-text); }
.foot-legal {
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;
  padding-block: var(--s-4); border-block-start: 1px solid var(--border);
  color: var(--text-3); font-size: var(--fs-xs);
}
.foot-legal-sep { inline-size: 3px; block-size: 3px; border-radius: var(--r-full); background: currentColor; opacity: .5; }

/* --- command palette ---------------------------------------------------- */
.palette-scrim {
  position: fixed; inset: 0; z-index: 70; background: var(--overlay);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  animation: fade-in var(--d-fast) linear both;
}
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
.palette {
  position: fixed; z-index: 71; inset-block-start: max(8vh, var(--s-6));
  inset-inline: 0; margin-inline: auto; inline-size: min(40rem, calc(100vw - 2 * var(--s-4)));
  animation: pal-in var(--d-med) var(--e-spring) both;
}
@keyframes pal-in { from { opacity: 0; transform: translateY(-14px) scale(.97); } to { opacity: 1; transform: none; } }
.palette-in {
  display: grid; background: var(--surface-3); border: 1px solid var(--border-strong);
  border-radius: var(--r-xl); box-shadow: var(--shadow-3); overflow: hidden;
}
.palette-input-row { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-4) var(--s-5); border-block-end: 1px solid var(--border); }
.palette-input-row .ico { color: var(--text-3); inline-size: 1.1em; block-size: 1.1em; }
.palette-input { flex: 1 1 auto; min-inline-size: 0; border: 0; background: transparent; font-size: var(--fs-h3); outline: none; }
.palette-input::placeholder { color: var(--text-3); }
.palette-body { max-block-size: min(58vh, 30rem); overflow-y: auto; overscroll-behavior: contain; }
.palette-list { padding: var(--s-2); display: grid; gap: 2px; }
.pal-group { padding: var(--s-2) var(--s-3) var(--s-1); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--text-3); }
.pal-item {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-2) var(--s-3); border-radius: var(--r-md); cursor: pointer;
  color: var(--text-2); font-size: var(--fs-body);
}
.pal-item .ico { color: var(--text-3); }
.pal-item[aria-selected="true"] { background: var(--surface-hover); color: var(--text); }
.pal-item[aria-selected="true"] .ico { color: var(--sc); }
.pal-label { flex: 1 1 auto; min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pal-hint { font-size: var(--fs-micro); color: var(--text-3); font-family: var(--font-mono); }
.palette-empty { padding: var(--s-8) var(--s-5); text-align: center; color: var(--text-3); font-size: var(--fs-sm); }
.palette-foot {
  display: flex; gap: var(--s-4); flex-wrap: wrap; padding: var(--s-2) var(--s-5);
  border-block-start: 1px solid var(--border); background: var(--surface-2);
  font-size: var(--fs-micro); color: var(--text-3);
}
.palette-foot span { display: inline-flex; align-items: center; gap: var(--s-1); }

/* --- toasts ------------------------------------------------------------- */
.toasts {
  position: fixed; z-index: 80; inset-block-end: var(--s-5); inset-inline-end: var(--s-5);
  display: grid; gap: var(--s-2); justify-items: end; max-inline-size: min(24rem, calc(100vw - 2 * var(--s-4)));
  pointer-events: none;
}
.toast {
  pointer-events: auto; display: flex; align-items: flex-start; gap: var(--s-3);
  padding: var(--s-3) var(--s-4); border-radius: var(--r-lg);
  background: var(--surface-3); border: 1px solid var(--sc-border);
  box-shadow: var(--shadow-2); color: var(--text); font-size: var(--fs-sm);
  animation: toast-in var(--d-med) var(--e-spring) both;
}
.toast[data-leaving="1"] { animation: toast-out var(--d-med) var(--e-out) both; }
.toast .ico { color: var(--sc-text); margin-block-start: .15em; }
.toast-body { display: grid; gap: 2px; min-inline-size: 0; }
.toast-title { font-weight: 600; }
.toast-sub { color: var(--text-3); font-size: var(--fs-xs); }
@keyframes toast-in { from { opacity: 0; transform: translateY(12px) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(6px) scale(.98); } }
@media (max-width: 520px) { .toasts { inset-inline: var(--s-3); justify-items: stretch; } }

/* --- skeleton composites (shimmer itself comes from .skel in theme.css) -- */
.skel { display: block; border-radius: var(--r-sm); background-color: var(--surface-2); }
.sk-line { block-size: 1em; }
.sk-line.w-hero { block-size: .8em; inline-size: min(18ch, 70vw); border-radius: var(--r-md); }
.w-140 { inline-size: 140px; } .w-180 { inline-size: 180px; } .w-200 { inline-size: 200px; } .w-220 { inline-size: 220px; }
.sk-stat { inline-size: 8rem; block-size: 2.1rem; border-radius: var(--r-full); }
.sk-num { inline-size: 4.5rem; block-size: 1.2rem; }
.sk-ribbon { block-size: 40px; border-radius: var(--r-sm); }
.sk-card { opacity: .8; }

/* --- reduced motion ----------------------------------------------------- */
/* theme.css owns the global kill-switch; these are the extras it cannot know
   about (decorative layers that should simply not exist without motion). */
@media (prefers-reduced-motion: reduce) {
  .aurora { display: none; }
  .halo-ring { display: none; }
  .halo-core { filter: blur(18px); }
  .hero-crest { animation: none; }
}

/* --- narrow + zoomed ---------------------------------------------------- */
@media (max-width: 400px) {
  :root { --gutter: .75rem; }
  .verdict { font-size: clamp(1.7rem, 9vw, 2.2rem); gap: var(--s-2); }
  .topbar-in { min-block-size: 3.25rem; }
  .svc { padding: var(--s-4); }
  .inc { padding: var(--s-4); padding-inline-start: calc(var(--s-4) + 4px); }
  .hstat { padding: var(--s-1) var(--s-3); font-size: var(--fs-xs); }
  .foot-in { padding-block: var(--s-6); gap: var(--s-6); }
}
@media print {
  .aurora, .grain-layer, .topbar, .palette, .palette-scrim, .toasts, .hovercard { display: none !important; }
  body { background: var(--paper-50); color: var(--navy-900); }
}

/* --- embeddable widget (embed.html) ------------------------------------- */
/* Lives here so the widget needs no stylesheet of its own: the CSP bans inline
   <style>, and the widget must still speak in the same tokens as the page. */
/* the widget is an iframe: it must be exactly as tall as its content */
.embed-body { background: transparent; padding: 0; min-block-size: 0; }
.eb {
  display: grid; gap: var(--s-3);
  padding: var(--s-4);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); color: var(--text);
  font-family: var(--font-ui); font-size: var(--fs-sm);
}
.eb-strip { display: flex; align-items: center; gap: var(--s-3); }
.eb-mark {
  inline-size: 22px; block-size: 22px; flex: none; color: var(--sc);
  mask-image: url('logo-mark.svg'); -webkit-mask-image: url('logo-mark.svg');
}
.eb-verdict { flex: 1 1 auto; min-inline-size: 0; font-weight: 600; font-size: var(--fs-body); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.eb-dot {
  inline-size: .625rem; block-size: .625rem; border-radius: var(--r-full); flex: none;
  background: var(--sc); box-shadow: 0 0 0 3px color-mix(in oklab, var(--sc) 22%, transparent);
}
.eb-list { display: grid; gap: var(--s-1); }
.eb-row { display: flex; align-items: center; gap: var(--s-2); font-size: var(--fs-xs); color: var(--text-2); }
.eb-row-dot { inline-size: .5rem; block-size: .5rem; border-radius: var(--r-full); background: var(--sc); flex: none; }
.eb-row-name { flex: 1 1 auto; min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.eb-row-state { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--sc-text); }
.eb-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); padding-block-start: var(--s-2); border-block-start: 1px solid var(--border); }
.eb-link { display: inline-flex; align-items: center; gap: var(--s-1); color: var(--text-2); font-size: var(--fs-xs); }
.eb-link:hover { color: var(--text); }
.eb-arrow { inline-size: .5rem; block-size: .5rem; border-block-start: 1.5px solid currentColor; border-inline-end: 1.5px solid currentColor; transform: rotate(45deg); }
[dir="rtl"] .eb-arrow { transform: rotate(-135deg); }
.eb-time { font-size: var(--fs-micro); color: var(--text-3); }
.eb-error { font-size: var(--fs-xs); color: var(--st-major-text); }
@media (max-width: 260px) { .eb-list, .eb-foot { display: none; } }
