/* Heimdall skin. Design language: quiet business SaaS in the vein of
   Hyperping and Fluent. One accent (emerald), two surface levels above the
   page, soft tinted chips instead of solid badges, 14px body type on the
   self-hosted Inter variable font. Dark mode rides Bootstrap's
   data-bs-theme attribute, set on <html> before paint; every color below
   goes through a token so both themes stay in step. */

/* ---- Fonts ---- */

@font-face {
  font-family: "Inter var";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/static/css/fonts/InterVariable.woff2") format("woff2");
}

@font-face {
  font-family: "Inter var";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("/static/css/fonts/InterVariable-Italic.woff2") format("woff2");
}

/* ---- Design tokens ---- */

:root {
  /* Brand accent */
  --hd-green: #10b981;
  --hd-green-hover: #0da173;
  --hd-green-soft: #d9f4ea;
  --hd-green-soft-text: #067a55;
  --hd-red: #ef4444;
  --hd-link: #0e9268;

  /* Surfaces: page, card, sunken (inputs, segmented tracks), raised
     (dropdowns, tooltips), sidebar. */
  --hd-bg: #f6f7f9;
  --hd-surface: #ffffff;
  --hd-surface-2: #f0f2f5;
  --hd-surface-raised: #ffffff;
  --hd-sidebar-bg: #f1f3f6;

  --hd-border: #e6e8ee;
  --hd-border-strong: #d5dae2;
  --hd-text: #16191f;
  --hd-muted: #66707f;
  --hd-faint: #98a1b0;
  --hd-paused: #cbd2dc;
  --hd-row-hover: rgba(22, 25, 31, 0.03);

  --hd-shadow-xs: 0 1px 2px rgba(16, 24, 40, 0.05);
  --hd-shadow-card: 0 1px 2px rgba(16, 24, 40, 0.04), 0 1px 3px rgba(16, 24, 40, 0.03);
  --hd-shadow-pop: 0 4px 6px -2px rgba(16, 24, 40, 0.05), 0 12px 16px -4px rgba(16, 24, 40, 0.12);

  /* Semantic tints. Blue is reserved for planned work, so "under
     maintenance" never reads as a failure. */
  --hd-info: #3b82f6;
  --hd-info-soft: #dcebfe;
  --hd-info-soft-text: #1d5cd8;
  --hd-amber-soft: #fdf0cd;
  --hd-amber-soft-text: #91530e;
  --hd-red-soft: #fde5e5;
  --hd-red-soft-text: #b62020;
  --hd-grey-soft: #eef0f3;
  --hd-grey-soft-text: #58606e;

  /* Bootstrap bridge. The -rgb triplets must track their hex twins: the
     bg-body-* and text-body-* utilities read only the triplets. */
  --bs-body-bg: #f6f7f9;
  --bs-body-bg-rgb: 246, 247, 249;
  --bs-body-color: #16191f;
  --bs-body-color-rgb: 22, 25, 31;
  --bs-emphasis-color: #05070a;
  --bs-emphasis-color-rgb: 5, 7, 10;
  --bs-secondary-color: #66707f;
  --bs-secondary-color-rgb: 102, 112, 127;
  --bs-secondary-bg: #f0f2f5;
  --bs-secondary-bg-rgb: 240, 242, 245;
  --bs-tertiary-color: #98a1b0;
  --bs-tertiary-bg: #f0f2f5;
  --bs-tertiary-bg-rgb: 240, 242, 245;
  --bs-border-color: #e6e8ee;
  --bs-link-color: #0e9268;
  --bs-link-color-rgb: 14, 146, 104;
  --bs-link-hover-color: #067a55;
  --bs-link-hover-color-rgb: 6, 122, 85;
  --bs-body-font-size: 0.875rem;
  --bs-body-font-family: "Inter var", "Inter", "Segoe UI Variable Text",
    "Segoe UI", ui-sans-serif, system-ui, -apple-system, "Helvetica Neue",
    Arial, sans-serif;
}

/* This block must stay below :root: same specificity, so source order
   decides. */
[data-bs-theme="dark"] {
  --hd-green: #12c088;
  --hd-green-hover: #0fae7b;
  --hd-green-soft: rgba(18, 192, 136, 0.13);
  --hd-green-soft-text: #3fd6a4;
  --hd-link: #34d399;

  --hd-bg: #0b0e14;
  --hd-surface: #11151d;
  --hd-surface-2: #181d28;
  --hd-surface-raised: #1a2029;
  --hd-sidebar-bg: #0d1119;

  --hd-border: #1f2530;
  --hd-border-strong: #2a3140;
  --hd-text: #e7eaf1;
  --hd-muted: #8b93a5;
  --hd-faint: #5d6577;
  --hd-paused: #3d4554;
  --hd-row-hover: rgba(231, 234, 241, 0.03);

  --hd-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.25);
  --hd-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.2);
  --hd-shadow-pop: 0 8px 24px rgba(0, 0, 0, 0.45);

  --hd-info: #60a5fa;
  --hd-info-soft: rgba(59, 130, 246, 0.16);
  --hd-info-soft-text: #93c5fd;
  --hd-amber-soft: rgba(250, 178, 25, 0.14);
  --hd-amber-soft-text: #fcd34d;
  --hd-red-soft: rgba(239, 68, 68, 0.14);
  --hd-red-soft-text: #fca5a5;
  --hd-grey-soft: rgba(156, 163, 175, 0.12);
  --hd-grey-soft-text: #9ca3af;

  --bs-body-bg: #0b0e14;
  --bs-body-bg-rgb: 11, 14, 20;
  --bs-body-color: #e7eaf1;
  --bs-body-color-rgb: 231, 234, 241;
  --bs-emphasis-color: #ffffff;
  --bs-emphasis-color-rgb: 255, 255, 255;
  --bs-secondary-color: #8b93a5;
  --bs-secondary-color-rgb: 139, 147, 165;
  --bs-secondary-bg: #181d28;
  --bs-secondary-bg-rgb: 24, 29, 40;
  --bs-tertiary-color: #5d6577;
  --bs-tertiary-bg: #181d28;
  --bs-tertiary-bg-rgb: 24, 29, 40;
  --bs-border-color: #1f2530;
  --bs-link-color: #34d399;
  --bs-link-color-rgb: 52, 211, 153;
  --bs-link-hover-color: #6ee7b7;
  --bs-link-hover-color-rgb: 110, 231, 183;
}

/* ---- Base ---- */

body {
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
  letter-spacing: -0.015em;
}

/* Stat values line up when they tick over. */
.h1, .h2, .h3, .h4,
.table,
.chart-label {
  font-variant-numeric: tabular-nums;
}

a {
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

.btn:hover,
.nav-link:hover,
a.badge:hover {
  text-decoration: none;
}

::selection {
  background: rgba(16, 185, 129, 0.22);
}

* {
  scrollbar-width: thin;
  scrollbar-color: var(--hd-border-strong) transparent;
}

.text-secondary {
  color: var(--hd-muted) !important;
}

.text-success {
  color: var(--hd-green) !important;
}

/* Fluent-style focus: a crisp offset ring instead of a blurred glow. */
.btn:focus-visible,
.nav-link:focus-visible,
a:focus-visible {
  outline: 2px solid var(--hd-green);
  outline-offset: 2px;
  box-shadow: none;
}

.border-bottom,
.border-top {
  border-color: var(--hd-border) !important;
}

/* htmx: subtle feedback while a request is in flight */
.htmx-request {
  opacity: 0.55;
  transition: opacity 0.15s ease-in;
}

/* ---- Buttons ---- */

.btn {
  --bs-btn-font-size: 0.875rem;
  --bs-btn-border-radius: 0.5rem;
  --bs-btn-font-weight: 500;
  transition: color 0.12s ease, background-color 0.12s ease,
    border-color 0.12s ease, box-shadow 0.12s ease;
}

.btn-sm,
.btn-group-sm > .btn {
  --bs-btn-font-size: 0.8125rem;
  --bs-btn-border-radius: 0.45rem;
}

/* Primary action: brand green with a faint inner highlight so it reads as
   a surface, not a flat fill. */
.btn-success {
  --bs-btn-bg: var(--hd-green);
  --bs-btn-border-color: var(--hd-green);
  --bs-btn-hover-bg: var(--hd-green-hover);
  --bs-btn-hover-border-color: var(--hd-green-hover);
  --bs-btn-active-bg: var(--hd-green-hover);
  --bs-btn-active-border-color: var(--hd-green-hover);
  --bs-btn-color: #fff;
  --bs-btn-hover-color: #fff;
  --bs-btn-active-color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), var(--hd-shadow-xs);
}

/* The other solid variants get the same treatment as btn-success so no
   button on the page reads as stock Bootstrap. Blue stays reserved for
   planned work (maintenance), amber for upgrade and acknowledge actions. */
.btn-primary {
  --bs-btn-bg: #3b82f6;
  --bs-btn-border-color: #3b82f6;
  --bs-btn-hover-bg: #2f6fe0;
  --bs-btn-hover-border-color: #2f6fe0;
  --bs-btn-active-bg: #2f6fe0;
  --bs-btn-active-border-color: #2f6fe0;
  --bs-btn-color: #fff;
  --bs-btn-hover-color: #fff;
  --bs-btn-active-color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), var(--hd-shadow-xs);
}

.btn-warning {
  --bs-btn-bg: #d97706;
  --bs-btn-border-color: #d97706;
  --bs-btn-hover-bg: #b45309;
  --bs-btn-hover-border-color: #b45309;
  --bs-btn-active-bg: #b45309;
  --bs-btn-active-border-color: #b45309;
  --bs-btn-color: #fff;
  --bs-btn-hover-color: #fff;
  --bs-btn-active-color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), var(--hd-shadow-xs);
}

.btn-danger {
  --bs-btn-bg: #ef4444;
  --bs-btn-border-color: #ef4444;
  --bs-btn-hover-bg: #dc2626;
  --bs-btn-hover-border-color: #dc2626;
  --bs-btn-active-bg: #dc2626;
  --bs-btn-active-border-color: #dc2626;
  --bs-btn-color: #fff;
  --bs-btn-hover-color: #fff;
  --bs-btn-active-color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), var(--hd-shadow-xs);
}

/* The workhorse secondary button: neutral surface with a real border, not
   Bootstrap's gray outline. */
.btn-outline-secondary {
  --bs-btn-color: var(--bs-body-color);
  --bs-btn-bg: var(--hd-surface);
  --bs-btn-border-color: var(--hd-border-strong);
  --bs-btn-hover-color: var(--bs-emphasis-color);
  --bs-btn-hover-bg: var(--hd-surface-2);
  --bs-btn-hover-border-color: var(--hd-border-strong);
  --bs-btn-active-color: var(--bs-emphasis-color);
  --bs-btn-active-bg: var(--hd-surface-2);
  --bs-btn-active-border-color: var(--hd-border-strong);
  box-shadow: var(--hd-shadow-xs);
}

.btn-outline-danger {
  --bs-btn-color: var(--hd-red-soft-text);
  --bs-btn-bg: var(--hd-surface);
  --bs-btn-border-color: var(--hd-border-strong);
  --bs-btn-hover-color: var(--hd-red-soft-text);
  --bs-btn-hover-bg: var(--hd-red-soft);
  --bs-btn-hover-border-color: var(--hd-border-strong);
  --bs-btn-active-color: var(--hd-red-soft-text);
  --bs-btn-active-bg: var(--hd-red-soft);
  --bs-btn-active-border-color: var(--hd-border-strong);
  box-shadow: var(--hd-shadow-xs);
}

/* Row actions melt into the table until hovered: icon buttons, no chrome. */
.table .btn-outline-secondary,
.table .btn-outline-danger {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--hd-muted);
}

.table .btn-outline-secondary:hover {
  background: var(--hd-surface-2);
  color: var(--bs-emphasis-color);
}

.table .btn-outline-danger:hover {
  background: var(--hd-red-soft);
  color: var(--hd-red-soft-text);
}

/* Toggle groups (the ones with a selected .btn-success inside) become a
   segmented control: sunken track, raised chip for the active option.
   Plain action groups keep the joined-buttons layout. */
.btn-group:has(> .btn-success),
.btn-group:has(> form > .btn-success) {
  background: var(--hd-surface-2);
  border: 1px solid var(--hd-border);
  border-radius: 0.625rem;
  padding: 3px;
  gap: 2px;
}

.btn-group:has(> .btn-success) > .btn,
.btn-group:has(> form > .btn-success) > .btn {
  border: 0;
  border-radius: 0.45rem !important;
  background: transparent;
  color: var(--hd-muted);
  box-shadow: none;
  font-weight: 500;
}

.btn-group:has(> .btn-success) > .btn:hover,
.btn-group:has(> form > .btn-success) > .btn:hover {
  color: var(--bs-emphasis-color);
}

.btn-group:has(> .btn-success) > .btn-success,
.btn-group:has(> form > .btn-success) > .btn-success {
  background: var(--hd-surface);
  color: var(--bs-emphasis-color);
  box-shadow: var(--hd-shadow-xs);
}

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

.card {
  --bs-card-bg: var(--hd-surface);
  --bs-card-border-color: var(--hd-border);
  --bs-card-border-radius: 0.75rem;
  --bs-card-inner-border-radius: calc(0.75rem - 1px);
  border: 1px solid var(--hd-border);
  box-shadow: var(--hd-shadow-card);
}

/* Templates say bg-body on headers and footers; on a card that must mean
   "the card's surface", not the page behind it. */
.card > .card-header,
.card > .card-footer {
  background: transparent !important;
  border-color: var(--hd-border);
}

.card > .card-header {
  padding-top: 0.875rem;
  padding-bottom: 0.875rem;
  font-size: 0.875rem;
}

/* ---- Tables ---- */

.table {
  --bs-table-bg: transparent;
  --bs-table-color: var(--bs-body-color);
  --bs-table-border-color: var(--hd-border);
  --bs-table-hover-bg: var(--hd-row-hover);
  --bs-table-hover-color: var(--bs-body-color);
  margin-bottom: 0;
}

.table thead th {
  color: var(--hd-muted);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding-top: 0.75rem;
  padding-bottom: 0.6rem;
}

.table td {
  padding-top: 0.8rem;
  padding-bottom: 0.8rem;
}

.table > :not(caption) > * > * {
  box-shadow: none;
}

/* The last row's border would double up with the card edge (or a card-footer's
   top border) right below it. Let the container draw that line. */
.table > tbody:last-child > tr:last-child > * {
  border-bottom-width: 0;
}

/* Tree indentation in the monitor list */
.tree-indent {
  display: inline-block;
}

/* Collapse toggle on a group row, and the spacer that keeps rows without one
   aligned with the rows that have it. See static/js/monitor-tree.js. */
.tree-toggle,
.tree-toggle-spacer {
  display: inline-block;
  width: 1.25rem;
  text-align: center;
}

.tree-toggle {
  padding: 0;
  border: 0;
  background: none;
  color: var(--bs-secondary-color);
  line-height: 1;
}

.tree-toggle:hover {
  color: var(--bs-emphasis-color);
}

.tree-toggle i {
  display: inline-block;
  font-size: 0.8rem;
  transition: transform 0.15s ease-in-out;
}

.tree-toggle.collapsed i {
  transform: rotate(-90deg);
}

/* Hidden because a group above it is collapsed. */
.tree-row-hidden {
  display: none;
}

/* With rows hidden, the structurally last row is not the one on screen; the
   card edge draws that line instead (see the :last-child rule above). */
.table > tbody > tr.tree-last-visible > * {
  border-bottom-width: 0;
}

/* Selection column of the monitor list: as narrow as the box it holds, and
   out of the way of the name beside it. See static/js/monitor-bulk.js. */
.bulk-cell {
  width: 1px;
  padding-right: 0;
}

/* The bar is a card, and `.card` sets display: flex, which would win over
   the browser's own rule for [hidden] and leave the empty bar on screen. */
.bulk-bar[hidden] {
  display: none;
}

/* ---- Badges ---- */

.badge {
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.01em;
  padding: 0.34em 0.55em;
  border-radius: 0.375rem;
}

/* Solid Bootstrap fills become quiet tints; color carries the meaning,
   the page keeps its calm. */
.badge.text-bg-danger {
  background: var(--hd-red-soft) !important;
  color: var(--hd-red-soft-text) !important;
}

.badge.text-bg-warning {
  background: var(--hd-amber-soft) !important;
  color: var(--hd-amber-soft-text) !important;
}

.badge.text-bg-success {
  background: var(--hd-green-soft) !important;
  color: var(--hd-green-soft-text) !important;
}

.badge.text-bg-info,
.badge.text-bg-primary {
  background: var(--hd-info-soft) !important;
  color: var(--hd-info-soft-text) !important;
}

.badge.text-bg-secondary,
.badge.text-bg-light,
.badge.text-bg-dark {
  background: var(--hd-grey-soft) !important;
  color: var(--hd-grey-soft-text) !important;
}

.badge.bg-body-secondary {
  border: 1px solid var(--hd-border);
  color: var(--hd-muted) !important;
}

.badge-status-up {
  background: var(--hd-green-soft);
  color: var(--hd-green-soft-text);
}

/* ---- Forms ---- */

.form-label {
  font-weight: 500;
  font-size: 0.85rem;
  margin-bottom: 0.35rem;
}

.form-control,
.form-select {
  background-color: var(--hd-surface);
  border-color: var(--hd-border-strong);
  border-radius: 0.5rem;
  font-size: 0.875rem;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

.form-control::placeholder {
  color: var(--hd-faint);
}

.form-control:focus,
.form-select:focus,
.form-check-input:focus {
  background-color: var(--hd-surface);
  border-color: var(--hd-green);
  box-shadow: 0 0 0 0.2rem rgba(16, 185, 129, 0.18);
}

.form-check-input {
  background-color: var(--hd-surface-2);
  border-color: var(--hd-border-strong);
}

.form-check-input:checked {
  background-color: var(--hd-green);
  border-color: var(--hd-green);
}

.input-group-text {
  background-color: var(--hd-surface-2);
  border-color: var(--hd-border-strong);
  color: var(--hd-muted);
  font-size: 0.875rem;
}

.form-text {
  color: var(--hd-muted);
}

/* ---- Dropdowns ---- */

.dropdown-menu {
  --bs-dropdown-bg: var(--hd-surface-raised);
  --bs-dropdown-border-color: var(--hd-border);
  --bs-dropdown-border-radius: 0.625rem;
  --bs-dropdown-link-color: var(--bs-body-color);
  --bs-dropdown-link-hover-bg: var(--hd-surface-2);
  --bs-dropdown-link-hover-color: var(--bs-emphasis-color);
  --bs-dropdown-link-active-bg: var(--hd-green-soft);
  --bs-dropdown-link-active-color: var(--hd-green-soft-text);
  --bs-dropdown-divider-bg: var(--hd-border);
  box-shadow: var(--hd-shadow-pop);
  padding: 0.375rem;
  font-size: 0.875rem;
}

.dropdown-item {
  border-radius: 0.4rem;
  padding: 0.4rem 0.6rem;
}

/* ---- Modals, offcanvas ---- */

.modal-content {
  background: var(--hd-surface-raised);
  border: 1px solid var(--hd-border);
  border-radius: 0.875rem;
  box-shadow: var(--hd-shadow-pop);
}

.modal-header,
.modal-footer {
  border-color: var(--hd-border);
}

.modal-backdrop {
  --bs-backdrop-opacity: 0.6;
}

.offcanvas,
.offcanvas-lg {
  --bs-offcanvas-bg: var(--hd-sidebar-bg);
}

/* ---- List groups ---- */

.list-group {
  --bs-list-group-bg: transparent;
  --bs-list-group-border-color: var(--hd-border);
  --bs-list-group-action-hover-bg: var(--hd-row-hover);
  --bs-list-group-action-hover-color: var(--bs-emphasis-color);
}

/* ---- Alerts ---- */

.alert {
  border-radius: 0.625rem;
  border: 1px solid transparent;
}

.alert-success {
  background: var(--hd-green-soft);
  color: var(--hd-green-soft-text);
  border-color: transparent;
}

.alert-danger {
  background: var(--hd-red-soft);
  color: var(--hd-red-soft-text);
  border-color: transparent;
}

.alert-warning {
  background: var(--hd-amber-soft);
  color: var(--hd-amber-soft-text);
  border-color: transparent;
}

.alert-info {
  background: var(--hd-info-soft);
  color: var(--hd-info-soft-text);
  border-color: transparent;
}

.alert-secondary {
  background: var(--hd-grey-soft);
  color: var(--hd-grey-soft-text);
  border-color: transparent;
}

/* ---- Tabs: underline style ---- */

.nav-tabs {
  border-bottom: 1px solid var(--hd-border);
  gap: 0.25rem;
}

.nav-tabs .nav-link {
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  margin-bottom: -1px;
  background: none;
  color: var(--hd-muted);
  font-weight: 500;
  padding: 0.5rem 0.75rem;
}

.nav-tabs .nav-link:hover {
  color: var(--bs-emphasis-color);
  border-bottom-color: var(--hd-border-strong);
}

.nav-tabs .nav-link.active {
  color: var(--bs-emphasis-color);
  background: none;
  border-bottom-color: var(--hd-green);
}

/* ---- Navbar (public pages) ---- */

.navbar-brand {
  letter-spacing: -0.02em;
  font-size: 1.05rem;
}

.nav-link {
  color: var(--hd-muted);
  transition: color 0.12s ease, background-color 0.12s ease;
}

.nav-link:hover {
  color: var(--bs-emphasis-color);
}

/* ---- App shell: sidebar layout for signed-in pages ---- */

/* Tables inside must shrink with the viewport, not widen the page. */
.app-main {
  min-width: 0;
}

.app-shell {
  min-height: 100vh;
}

.app-sidebar {
  background: var(--hd-sidebar-bg);
}

@media (min-width: 992px) {
  .app-sidebar {
    width: 260px;
    flex-shrink: 0;
    position: sticky;
    top: 0;
    height: 100vh;
    border-right: 1px solid var(--hd-border);
  }

  .app-sidebar .offcanvas-body {
    height: 100%;
    overflow-y: auto;
  }
}

.app-sidebar .nav-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.45rem 0.65rem;
  border-radius: 0.5rem;
  color: var(--hd-muted);
  font-weight: 500;
}

.app-sidebar .nav-link i {
  font-size: 1rem;
  width: 1.25rem;
  text-align: center;
  opacity: 0.85;
}

.app-sidebar .nav-link:hover {
  color: var(--bs-emphasis-color);
  background: var(--bs-secondary-bg);
}

.app-sidebar .nav-link.active {
  color: var(--hd-green-soft-text);
  background: var(--hd-green-soft);
}

/* Fluent-style rail: a small accent bar in the page gutter marks the
   active section. */
.app-sidebar .nav-link.active::before {
  content: "";
  position: absolute;
  left: -1rem;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 1.1rem;
  border-radius: 0 3px 3px 0;
  background: var(--hd-green);
}

.sidebar-heading {
  padding: 0 0.65rem;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--hd-faint);
}

.sidebar-footer {
  border-top: 1px solid var(--hd-border);
}

/* Lets the display name truncate inside the flex row. */
.sidebar-footer .nav-link {
  min-width: 0;
}

/* Mobile top bar: translucent with blur, like an app title bar. */
.app-main > header.sticky-top {
  background: rgba(var(--bs-body-bg-rgb), 0.85) !important;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--hd-border) !important;
}

/* ---- Admin mode ----
   The instance admin area renders as a mode of its own, like a test-mode
   switch: violet replaces emerald as the accent, a hairline across the
   top of the viewport marks the state even with the sidebar collapsed,
   and an "Admin mode" pill names it. Everything else keeps the app skin,
   so the switch reads as a mode change, not a different product. */

:root {
  --hd-admin: #6366f1;
  --hd-admin-soft: #e5e6fb;
  --hd-admin-soft-text: #4649c8;
  --hd-admin-sidebar-bg: #f1f1f7;
}

[data-bs-theme="dark"] {
  --hd-admin: #818cf8;
  --hd-admin-soft: rgba(99, 102, 241, 0.16);
  --hd-admin-soft-text: #a5b4fc;
  --hd-admin-sidebar-bg: #10121d;
}

.admin-mode::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--hd-admin);
  z-index: 1100;
}

.admin-accent {
  color: var(--hd-admin) !important;
}

.admin-mode-pill {
  display: inline-flex;
  align-items: center;
  background: var(--hd-admin-soft);
  color: var(--hd-admin-soft-text);
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.28rem 0.55rem;
  border-radius: 2rem;
  white-space: nowrap;
}

.admin-mode .app-sidebar {
  background: var(--hd-admin-sidebar-bg);
}

.admin-mode .app-sidebar .nav-link.active {
  color: var(--hd-admin-soft-text);
  background: var(--hd-admin-soft);
}

.admin-mode .app-sidebar .nav-link.active::before {
  background: var(--hd-admin);
}

.admin-mode .app-sidebar .nav-link:focus-visible {
  outline-color: var(--hd-admin);
}

/* The mode switch entries: entering from the app footer, leaving from the
   admin footer. The entry turns violet on hover, hinting at the mode
   behind the door; the exit keeps the neutral hover of the app it
   returns to. */
.app-sidebar .admin-switch:hover {
  color: var(--hd-admin-soft-text);
  background: var(--hd-admin-soft);
}

.admin-mode .app-sidebar .admin-switch:hover {
  color: var(--bs-emphasis-color);
  background: var(--bs-secondary-bg);
}

/* ---- Status dots ----
   Each status only declares its colour as an rgb triplet; the resting ring
   and the pulse are both generated from it, so one keyframe set drives
   every dot on the app. */

.status-dot {
  display: inline-block;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  vertical-align: baseline;
  --hd-dot-rgb: 156, 163, 175;
  --hd-dot-ring: 8px;
  box-shadow: 0 0 0 3px rgba(var(--hd-dot-rgb), 0.2);
}

.status-up {
  background: var(--hd-green);
  --hd-dot-rgb: 16, 185, 129;
}

.status-down {
  background: var(--hd-red);
  --hd-dot-rgb: 239, 68, 68;
}

.status-paused {
  background: var(--hd-paused);
  --hd-dot-rgb: 156, 163, 175;
  box-shadow: 0 0 0 3px rgba(var(--hd-dot-rgb), 0.25);
}

.status-warn {
  background: var(--viz-warn);
  --hd-dot-rgb: 250, 178, 25;
}

.status-info {
  background: var(--hd-info);
  --hd-dot-rgb: 59, 130, 246;
}

/* Dark surfaces re-step the same hues, so the halos follow. */
[data-bs-theme="dark"] .status-up {
  --hd-dot-rgb: 18, 192, 136;
}

[data-bs-theme="dark"] .status-paused {
  --hd-dot-rgb: 109, 118, 136;
}

[data-bs-theme="dark"] .status-info {
  --hd-dot-rgb: 96, 165, 250;
}

/* Every dot breathes; a live signal, not a decoration. Down and warn beat
   faster because they are asking to be looked at. Paused stays still: the
   whole point of that state is that nothing is happening. */
@media (prefers-reduced-motion: no-preference) {
  .status-dot {
    animation: hd-dot-pulse 2.6s ease-out infinite;
  }

  .status-down {
    animation-duration: 1.6s;
  }

  .status-warn {
    animation-duration: 2s;
  }

  .status-paused {
    animation: none;
  }

  /* Page-title dots carry the headline status, so their wave travels
     further than the ones riding along a table row. */
  h1 .status-dot,
  .statuspage-banner .status-dot {
    --hd-dot-ring: 11px;
  }
}

/* The first shadow is the resting ring, held for the whole cycle; the
   second is the wave that expands out of it and fades. */
@keyframes hd-dot-pulse {
  0% {
    box-shadow: 0 0 0 3px rgba(var(--hd-dot-rgb), 0.2),
      0 0 0 3px rgba(var(--hd-dot-rgb), 0.35);
  }
  55% {
    box-shadow: 0 0 0 3px rgba(var(--hd-dot-rgb), 0.2),
      0 0 0 var(--hd-dot-ring) rgba(var(--hd-dot-rgb), 0);
  }
  100% {
    box-shadow: 0 0 0 3px rgba(var(--hd-dot-rgb), 0.2),
      0 0 0 3px rgba(var(--hd-dot-rgb), 0);
  }
}

/* ---- Landing hero ---- */

.hero-badge {
  background: var(--hd-green-soft);
  color: var(--hd-green-soft-text);
  font-weight: 500;
  padding: 0.5rem 0.9rem;
}

.display-4 {
  letter-spacing: -0.03em;
}

.demo-card {
  text-align: left;
}

/* ---- Data viz ----
   Categorical series palette (CVD-validated fixed slot order); the dark
   column is the same hues re-stepped for dark surfaces, not a new palette. */
:root {
  --viz-1: #2a78d6;
  --viz-2: #eb6834;
  --viz-3: #1baf7a;
  --viz-4: #eda100;
  --viz-5: #e87ba4;
  --viz-6: #008300;
  --viz-7: #4a3aa7;
  --viz-8: #e34948;
  --viz-warn: #fab219;
}

[data-bs-theme="dark"] {
  --viz-1: #3987e5;
  --viz-2: #d95926;
  --viz-3: #199e70;
  --viz-4: #c98500;
  --viz-5: #d55181;
  --viz-6: #008300;
  --viz-7: #9085e9;
  --viz-8: #e66767;
}

.series-1 { --series-color: var(--viz-1); }
.series-2 { --series-color: var(--viz-2); }
.series-3 { --series-color: var(--viz-3); }
.series-4 { --series-color: var(--viz-4); }
.series-5 { --series-color: var(--viz-5); }
.series-6 { --series-color: var(--viz-6); }
.series-7 { --series-color: var(--viz-7); }
.series-8 { --series-color: var(--viz-8); }

/* Response-time chart */
.latency-chart {
  position: relative;
  outline: none;
}

.latency-chart:focus-visible {
  box-shadow: 0 0 0 0.2rem rgba(16, 185, 129, 0.18);
  border-radius: 0.5rem;
}

/* Fixed plot height; the SVG stretches to fill it (paths use non-scaling
   strokes), while labels and grid are HTML at normal site type size. */
.chart-area {
  height: 260px;
}

.latency-svg {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.latency-line {
  fill: none;
  stroke: var(--series-color);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.chart-label {
  font-size: 0.75rem;
  color: var(--hd-muted);
  white-space: nowrap;
}

.chart-ylabels {
  flex: 0 0 3.75rem;
}

.chart-ylabels .chart-label {
  position: absolute;
  right: 0.75rem;
  transform: translateY(-50%);
}

.chart-xlabels {
  margin-left: 3.75rem;
  height: 1.5rem;
}

.chart-xlabels .chart-label {
  position: absolute;
  top: 0.25rem;
  transform: translateX(-50%);
}

.chart-gridline {
  position: absolute;
  left: 0;
  right: 0;
  border-top: 1px solid var(--hd-border);
}

.chart-crosshair {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--hd-muted);
  pointer-events: none;
}

/* Hover marker: series fill with a 2px surface ring so it stays legible
   where it crosses a line. */
.chart-dot {
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--series-color);
  box-shadow: 0 0 0 2px var(--bs-card-bg, var(--bs-body-bg));
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.chart-tip {
  position: absolute;
  top: 0;
  left: 0;
  min-width: 10rem;
  padding: 0.5rem 0.75rem;
  background: var(--hd-surface-raised);
  border: 1px solid var(--hd-border);
  border-radius: 0.5rem;
  box-shadow: var(--hd-shadow-pop);
  font-size: 0.8rem;
  pointer-events: none;
  z-index: 10;
}

.chart-tip-header {
  color: var(--hd-muted);
  margin-bottom: 0.25rem;
}

/* Status line of the uptime-day hover card. */
.chart-tip-status {
  font-weight: 600;
  margin-bottom: 0.25rem;
  white-space: nowrap;
}

.chart-tip-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.chart-tip-row .tip-value {
  margin-left: auto;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.chart-tip-row .tip-name {
  color: var(--hd-muted);
}

/* Short stroke of the series color: keys lines in legend and tooltip. */
.legend-key {
  display: inline-block;
  width: 1rem;
  height: 2px;
  border-radius: 1px;
  vertical-align: middle;
  background: var(--series-color);
}

/* 90-day uptime strip */
.uptime-strip {
  display: flex;
  gap: 3px;
}

.uptime-cell {
  position: relative;
  flex: 1 1 0;
  height: 2.25rem;
  min-width: 2px;
  border-radius: 3px;
  overflow: hidden;
  transform-origin: bottom;
  transition: transform 0.1s ease-out;
}

.uptime-cell:hover {
  transform: scaleY(1.12);
}

.uptime-cell.uptime-data {
  background: var(--hd-green);
}

/* Failed share of the day, growing from the baseline. */
.uptime-fail,
.uptime-warn {
  position: absolute;
  inset: auto 0 0 0;
}

.uptime-fail {
  background: var(--hd-red);
}

/* A group its own thresholds only called degraded: impaired, not down. */
.uptime-warn {
  background: var(--viz-warn);
}

.uptime-cell.uptime-empty {
  background: var(--hd-paused);
  opacity: 0.35;
}

/* ---- Public status pages ----
   Rendered without the app chrome, so the page carries its own width. The
   status dots, uptime strips and hover cards are the same components the
   signed-in UI uses. */
.statuspage {
  max-width: 880px;
}

.statuspage-logo {
  max-height: 2.5rem;
  max-width: 10rem;
}

/* The one line a visitor reads first. */
.statuspage-banner {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  border: 1px solid transparent;
  border-radius: 0.75rem;
  padding: 1rem 1.25rem;
  font-size: 1.05rem;
  font-weight: 500;
}

.statuspage-banner-time {
  margin-left: auto;
  font-size: 0.8rem;
  opacity: 0.75;
  font-weight: 400;
}

.banner-up {
  background: var(--hd-green-soft);
  color: var(--hd-green-soft-text);
}

.banner-warn {
  background: var(--hd-amber-soft);
  color: var(--hd-amber-soft-text);
}

.banner-down {
  background: var(--hd-red-soft);
  color: var(--hd-red-soft-text);
}

.banner-info {
  background: var(--hd-info-soft);
  color: var(--hd-info-soft-text);
}

.banner-unknown {
  background: var(--hd-grey-soft);
  color: var(--hd-grey-soft-text);
}

/* Impact reads as a colour before it reads as a word. */
.badge.sp-impact.impact-none,
.badge.sp-impact.impact-minor {
  background: var(--hd-amber-soft);
  color: var(--hd-amber-soft-text);
}

.badge.sp-impact.impact-major,
.badge.sp-impact.impact-critical {
  background: var(--hd-red-soft);
  color: var(--hd-red-soft-text);
}

.badge.sp-impact.impact-none {
  background: var(--hd-grey-soft);
  color: var(--hd-grey-soft-text);
}

/* A stripe down the side of an incident card, in its impact colour. */
.statuspage-incident {
  border-left: 3px solid var(--hd-paused);
}

.statuspage-incident.impact-minor {
  border-left-color: var(--viz-warn);
}

.statuspage-incident.impact-major,
.statuspage-incident.impact-critical {
  border-left-color: var(--hd-red);
}

.statuspage-timeline .statuspage-update + .statuspage-update {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--hd-border);
}

.statuspage-update p {
  white-space: pre-line;
}

/* Component strips sit closer together than the single one on a monitor. */
.statuspage-component .uptime-strip {
  gap: 2px;
}

.statuspage-component .uptime-cell {
  height: 1.5rem;
}

/* What a group lists when it is opened up: indented behind a rule, so a
   reader can see at a glance which line they belong to and skip the lot. */
.statuspage-members {
  margin-left: 1.25rem;
  border-left: 2px solid var(--hd-border);
  padding-left: 1.25rem;
}

/* The first one clears the toggle; the rest stand further apart than the
   components on the page do, so a strip and the name under it do not read as
   one block. */
.statuspage-member {
  margin-top: 0.75rem;
  font-size: 0.95em;
}

.statuspage-member + .statuspage-member {
  margin-top: 1.5rem;
}

.statuspage-member .uptime-cell {
  height: 1.1rem;
}

.statuspage-members-toggle {
  text-decoration: none;
  color: var(--bs-secondary-color);
}

/* The chevron points at what it does: right when shut, down when open. */
.statuspage-members-toggle .bi {
  display: inline-block;
  transition: transform 0.15s ease-in-out;
  transform: rotate(90deg);
}

.statuspage-members-toggle.collapsed .bi {
  transform: rotate(0deg);
}

/* Client-side switches: both variants are rendered, the switch shows one. */

/* Incidents Open/All filter. */
#incident-list[data-filter="open"] tr[data-incident-open="false"] {
  display: none;
}

/* Billing cycle on the plan grids. */
[data-cycle="month"] .cycle-year,
[data-cycle="year"] .cycle-month {
  display: none;
}

[data-cycle="month"] .plan-card.current-month,
[data-cycle="year"] .plan-card.current-year {
  border-color: var(--bs-success);
}

/* Advanced-options card on the monitor form: the chevron points down while
   the card is folded and flips once it is open. */
[data-advanced-toggle] .bi-chevron-down {
  transition: transform 0.15s ease-in-out;
}

[data-advanced-toggle][aria-expanded="true"] .bi-chevron-down {
  transform: rotate(180deg);
}
