/* ===========================================================================
   SkyPhage — customer dashboard redesign (Cloudflare-style shell)
   css/dashboard.css — tokens + layout + component layer

   This file is the port target: it is written to drop into
   frontend/web/static/css/style.css once the templates move off Tailwind.

   Colour is two layers, exactly as in mockups/redesign-07-09-2026:
     1. BRAND RAMPS — fixed. The three hues from branding/colours.txt with the
        seven-step ramps from branding/color-palette.png, plus a neutral ramp.
     2. SEMANTIC TOKENS — what components actually name (--bg, --surface, --fg,
        --accent …). Light lives on bare :root (the default for the app), dark
        is opt-in via <html data-theme="dark">.
   Tokens are space-separated RGB triplets so `rgb(var(--x) / .5)` works.
   =========================================================================== */

:root {
  /* --- brand ramps: green ------------------------------------------------ */
  --green-50:  210 252 223;   /* #D2FCDF */
  --green-200:  99 230 154;   /* #63E69A */
  --green-400:  79 187 124;   /* #4FBB7C  ← primary */
  --green-500:  61 149  98;   /* #3D9562 */
  --green-600:  43 109  71;   /* #2B6D47 */
  --green-800:  25  69  43;   /* #19452B */
  --green-950:   8  33  18;   /* #082112 */

  /* --- brand ramps: purple ----------------------------------------------- */
  --violet-50:  219 210 239;  /* #DBD2EF */
  --violet-200: 185 165 223;  /* #B9A5DF */
  --violet-400: 153 120 208;  /* #9978D0 */
  --violet-500: 124  79 187;  /* #7C4FBB  ← secondary */
  --violet-600:  86  53 132;  /* #563584 */
  --violet-800:  48  28  77;  /* #301C4D */
  --violet-950:  14   6  27;  /* #0E061B */

  /* --- brand ramps: orange ----------------------------------------------- */
  --amber-50:  241 209 188;   /* #F1D1BC */
  --amber-200: 228 160 112;   /* #E4A070 */
  --amber-400: 187 124  79;   /* #BB7C4F  ← accent */
  --amber-500: 145  95  60;   /* #915F3C */
  --amber-600: 101  65  39;   /* #654127 */
  --amber-800:  58  35  19;   /* #3A2313 */
  --amber-950:  19   9   3;   /* #130903 */

  /* --- neutral ramp ------------------------------------------------------ */
  --grey-50:  237 239 240;    /* #EDEFF0 */
  --grey-200: 194 201 204;    /* #C2C9CC */
  --grey-400: 155 163 168;    /* #9BA3A8 */
  --grey-500: 123 130 133;    /* #7B8285 */
  --grey-600:  89  95  97;    /* #595F61 */
  --grey-800:  56  59  61;    /* #383B3D */
  --grey-950:  25  27  28;    /* #191B1C */

  /* --- red: the one hue outside the brand palette. Failure, deletion and
         "offline" need a colour nobody will read as the brand. ------------ */
  --red-200: 245 170 155;
  --red-500: 212  53  28;     /* #D4351C */
  --red-600: 176  42  20;     /* #B02A14 */

  /* --- geometry ---------------------------------------------------------- */
  --topbar-h: 56px;
  --sidebar-w: 256px;
  --sidebar-w-collapsed: 56px;
  --radius: 6px;
  --radius-sm: 4px;
  /* The mark is a pointy-top hexagon; every marker in the kit is this shape. */
  --hex: polygon(50% 0%, 93.3% 25%, 93.3% 75%, 50% 100%, 6.7% 75%, 6.7% 25%);
}

/* ---------------------------------------------------------------------------
   LIGHT — the default. The Cloudflare dashboard is a white chrome on a very
   light grey canvas; cards separate by a hairline, not a shadow.
   --------------------------------------------------------------------------- */
:root {
  color-scheme: light;

  --bg:          246 247 248;   /* #F6F7F8 canvas                              */
  --surface:     255 255 255;   /* cards, panels                               */
  --surface-2:   246 247 248;   /* table heads, insets, hover                  */
  --surface-3:   237 239 240;   /* disabled inputs, inline code                */
  --line:        223 228 225;   /* #DFE4E1 hairlines                           */
  --line-strong: 200 208 203;   /* control borders                             */

  --topbar-bg:   255 255 255;
  --sidebar-bg:  255 255 255;

  --fg:         25  27  28;     /* #191B1C */
  --fg-muted:   var(--grey-600);
  --fg-subtle:  var(--grey-500);

  /* green: --accent is the graphic rung, --accent-text the one that survives
     as small text on white (brand #4FBB7C is only ~2.2:1 there). */
  --accent:        var(--green-400);
  --accent-solid:  var(--green-600);   /* white on #2B6D47 → 6.0:1            */
  --accent-hover:  var(--green-800);
  --accent-text:   var(--green-600);
  --accent-soft:   232 250 239;        /* tinted fills                        */
  --on-accent:    255 255 255;

  --violet:       var(--violet-500);
  --violet-text:  var(--violet-600);
  --violet-soft:  240 236 248;

  --amber:        var(--amber-400);
  --amber-text:   var(--amber-600);
  --amber-soft:   251 240 232;

  --red:          var(--red-500);
  --red-text:     var(--red-600);
  --red-soft:     253 236 233;

  --shadow-menu:  0 4px 16px rgb(25 27 28 / 0.12), 0 1px 3px rgb(25 27 28 / 0.08);
  --shadow-modal: 0 20px 60px rgb(25 27 28 / 0.25);
  --overlay:      25 27 28;
}

/* ---------------------------------------------------------------------------
   DARK — opt-in. Not an inversion: text tokens step UP the ramps for contrast
   and the canvas keeps the brand's green cast rather than going to pure grey.
   --------------------------------------------------------------------------- */
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg:          10  14  12;    /* #0A0E0C */
  --surface:     17  23  20;    /* #111714 */
  --surface-2:   24  32  28;    /* #18201C */
  --surface-3:   31  41  36;
  --line:        38  49  43;
  --line-strong: 55  70  62;

  --topbar-bg:   14  19  16;
  --sidebar-bg:  14  19  16;

  --fg:         var(--grey-50);
  --fg-muted:   var(--grey-400);
  --fg-subtle:  var(--grey-500);

  --accent:        var(--green-400);
  --accent-solid:  var(--green-400);
  --accent-hover:  var(--green-200);
  --accent-text:   var(--green-200);
  --accent-soft:   20  40  30;
  --on-accent:      8  33  18;         /* #082112 on #4FBB7C → 7.3:1          */

  --violet:       var(--violet-400);
  --violet-text:  var(--violet-200);
  --violet-soft:  36  28  56;

  --amber:        var(--amber-200);
  --amber-text:   var(--amber-200);
  --amber-soft:   48  32  20;

  --red:          var(--red-500);
  --red-text:     245 140 120;
  --red-soft:     50  22  18;

  --shadow-menu:  0 8px 24px rgb(0 0 0 / 0.5);
  --shadow-modal: 0 20px 60px rgb(0 0 0 / 0.6);
  --overlay:      0 0 0;
}

/* ---------------------------------------------------------------------------
   Base
   --------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: rgb(var(--fg));
  background: rgb(var(--bg));
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
body, .themed { transition: background-color 0.25s ease, border-color 0.25s ease, color 0.25s ease; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; } }

a { color: rgb(var(--accent-text)); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4, h5 { margin: 0; font-weight: 600; line-height: 1.3; }
p { margin: 0; }
ul, ol { margin: 0; padding-left: 1.25em; }
img { max-width: 100%; display: block; }
button { font: inherit; color: inherit; }
input, select, textarea { font: inherit; }
code, kbd, pre, .mono { font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace; }
hr { border: 0; border-top: 1px solid rgb(var(--line)); margin: 16px 0; }
::selection { background: rgb(var(--accent) / 0.3); }
[x-cloak] { display: none !important; }
.hidden { display: none !important; }
/* Heartbeats (SP.heartbeat): a filled heart, green when recent, orange when late. */
.hb { display: inline-flex; align-items: center; vertical-align: middle; cursor: default; }
.hb .ico { width: 16px; height: 16px; fill: currentColor; }
.hb.is-ok { color: rgb(var(--accent)); }
.hb.is-late { color: rgb(var(--amber)); }
.hb.is-ended { color: rgb(var(--fg-subtle)); } .hb.is-ended .ico { fill: none; }   /* ended: no more beats expected */
.stat-value .hb .ico { width: 22px; height: 22px; }

/* The workload page's stat row: Health narrow, the endpoint tile widest.
   Below 1100px the endpoint takes the first row, the other three share the next. */
.wl-stats { grid-template-columns: minmax(0, 0.7fr) minmax(0, 1.7fr) repeat(2, minmax(0, 1fr)); }
@media (max-width: 1100px) { .wl-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); } .wl-stats > :nth-child(2) { grid-column: 1 / -1; order: -1; } }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Brand lockup text — Lexend Exa Bold, the one place the display face lives. */
.wordmark { font-family: "Lexend Exa", sans-serif; font-weight: 700; letter-spacing: 0.08em; }

/* Scrollbars: the stock light scrollbar is the loudest thing on a dark page.
   scrollbar-color is the standard property (Firefox; Chrome 121+), inherited by
   every scroll container. Without it Firefox on Linux can still paint a light
   GTK track beside the hosting tree even with color-scheme: dark. */
:root[data-theme="dark"] { scrollbar-color: rgb(var(--line-strong)) rgb(var(--bg)); }
:root[data-theme="dark"] ::-webkit-scrollbar { width: 12px; height: 12px; }
:root[data-theme="dark"] ::-webkit-scrollbar-track { background: rgb(var(--bg)); }
:root[data-theme="dark"] ::-webkit-scrollbar-thumb { background: rgb(var(--line-strong)); border-radius: 999px; border: 3px solid rgb(var(--bg)); }

/* ---------------------------------------------------------------------------
   Utilities — a deliberately tiny set so pages do not grow bespoke CSS.
   --------------------------------------------------------------------------- */
.flex { display: flex; } .inline-flex { display: inline-flex; }
.items-center { align-items: center; } .items-start { align-items: flex-start; } .items-end { align-items: flex-end; }
.justify-between { justify-content: space-between; } .justify-end { justify-content: flex-end; } .justify-center { justify-content: center; }
.flex-wrap { flex-wrap: wrap; } .flex-1 { flex: 1 1 auto; min-width: 0; } .flex-none { flex: none; }
.gap-1 { gap: 4px; } .gap-2 { gap: 8px; } .gap-3 { gap: 12px; } .gap-4 { gap: 16px; } .gap-6 { gap: 24px; }
.mt-1 { margin-top: 4px; } .mt-2 { margin-top: 8px; } .mt-3 { margin-top: 12px; } .mt-4 { margin-top: 16px; } .mt-6 { margin-top: 24px; } .mt-8 { margin-top: 32px; }
.mb-1 { margin-bottom: 4px; } .mb-2 { margin-bottom: 8px; } .mb-3 { margin-bottom: 12px; } .mb-4 { margin-bottom: 16px; } .mb-6 { margin-bottom: 24px; }
.ml-auto { margin-left: auto; }
.text-xs { font-size: 12px; } .text-sm { font-size: 13px; } .text-base { font-size: 14px; } .text-lg { font-size: 16px; }
.muted { color: rgb(var(--fg-muted)); } .subtle { color: rgb(var(--fg-subtle)); }
.accent { color: rgb(var(--accent-text)); } .danger-text { color: rgb(var(--red-text)); } .amber-text { color: rgb(var(--amber-text)); } .violet-text { color: rgb(var(--violet-text)); }
.fw-500 { font-weight: 500; } .fw-600 { font-weight: 600; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.break-all { word-break: break-all; }
.text-right { text-align: right; } .text-center { text-align: center; }
.capitalize { text-transform: capitalize; }
.w-full { width: 100%; }
.max-w-2xl { max-width: 720px; } .max-w-3xl { max-width: 880px; }
.min-w-0 { min-width: 0; }
.relative { position: relative; }
.ico { width: 16px; height: 16px; flex: none; display: inline-block; vertical-align: -3px; }
.ico-sm { width: 14px; height: 14px; } .ico-lg { width: 20px; height: 20px; }

/* ---------------------------------------------------------------------------
   App frame: top bar across the full width, then sidebar + main.
   --------------------------------------------------------------------------- */
.app { min-height: 100vh; display: flex; flex-direction: column; }
.frame { display: flex; flex: 1 1 auto; min-height: 0; }
.main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.page { width: 100%; max-width: 1280px; margin: 0 auto; padding: 24px 24px 56px; }
.page-narrow { max-width: 880px; }
.page-wide { max-width: none; }

.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 20px; }
/* The title block gives way before the actions do: they stay at the top right
   beside a long description, and drop below it only on a narrow screen. */
.page-head > :first-child { flex: 1 1 320px; min-width: 0; }
.page-title { font-size: 22px; font-weight: 600; letter-spacing: -0.01em; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.page-desc { color: rgb(var(--fg-muted)); margin-top: 4px; font-size: 13.5px; max-width: 72ch; }
.page-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.page-back { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; color: rgb(var(--fg-muted)); margin-bottom: 8px; }
.page-back:hover { color: rgb(var(--accent-text)); text-decoration: none; }
.page-back .ico { width: 14px; height: 14px; }

.section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 28px 0 12px; flex-wrap: wrap; }
.section-head:first-child { margin-top: 0; }
.section-title { font-size: 16px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
.section-desc { font-size: 13px; color: rgb(var(--fg-muted)); margin-top: 2px; }
.eyebrow { font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: rgb(var(--fg-subtle)); margin-bottom: 8px; }
.eyebrow::before { content: ""; display: inline-block; width: 7px; height: 8px; margin-right: 7px; vertical-align: 0; background: currentColor; clip-path: var(--hex); }

/* ---------------------------------------------------------------------------
   Top bar
   --------------------------------------------------------------------------- */
.topbar {
  position: sticky; top: 0; z-index: 40;
  height: var(--topbar-h);
  display: flex; align-items: center; gap: 12px;
  padding: 0 16px;
  background: rgb(var(--topbar-bg));
  border-bottom: 1px solid rgb(var(--line));
}
.brand { display: flex; align-items: center; gap: 10px; color: rgb(var(--fg)); flex: none; }
.brand:hover { text-decoration: none; }
.brand .mark { width: 28px; height: 28px; }
/* The mark, one pre-coloured file per surface: logo_deep.png (green-600) on
   the light chrome, logo_green.png (green-200) on dark, logo.png (white) on the
   brand panels. A background image, not a CSS mask: browsers fetch mask images
   under CORS, and a page opened from file:// has no origin, so a mask never
   loads there. */
.mark { display: inline-block; flex: none; background: url(/static/img/logo_deep.png) center / contain no-repeat; }
:root[data-theme="dark"] .mark { background-image: url(/static/img/logo_green.png); }
.mark.white, :root[data-theme="dark"] .mark.white { background-image: url(/static/img/logo.png); }
.brand .wordmark { font-size: 13px; }
.topbar-divider { width: 1px; height: 22px; background: rgb(var(--line)); flex: none; }

.crumbs { display: flex; align-items: center; gap: 2px; min-width: 0; font-size: 13px; }
.crumbs .sep { color: rgb(var(--fg-subtle)); padding: 0 2px; }
.crumb { color: rgb(var(--fg-muted)); white-space: nowrap; padding: 4px 6px; border-radius: var(--radius-sm); }
a.crumb:hover { background: rgb(var(--surface-2)); color: rgb(var(--fg)); text-decoration: none; }
.crumb.current { color: rgb(var(--fg)); font-weight: 500; }
.crumb-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 8px; border-radius: var(--radius-sm);
  border: 1px solid transparent; background: transparent; cursor: pointer;
  color: rgb(var(--fg)); font-weight: 500; font-size: 13px; white-space: nowrap;
}
.crumb-btn:hover { background: rgb(var(--surface-2)); border-color: rgb(var(--line)); }
.crumb-btn .ico { width: 14px; height: 14px; color: rgb(var(--fg-subtle)); }
.crumb-btn .org-dot { width: 18px; height: 18px; border-radius: 4px; background: rgb(var(--accent-solid)); color: rgb(var(--on-accent)); font-size: 10px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }

.search {
  display: flex; align-items: center; gap: 8px;
  height: 34px; width: 280px; max-width: 32vw;
  padding: 0 10px; border-radius: var(--radius-sm);
  border: 1px solid rgb(var(--line-strong)); background: rgb(var(--surface));
  color: rgb(var(--fg-subtle)); font-size: 13px; cursor: text;
  margin-left: auto;
}
.search:focus-within { border-color: rgb(var(--accent)); box-shadow: 0 0 0 3px rgb(var(--accent) / 0.2); }
.search input { flex: 1; min-width: 0; border: 0; background: transparent; color: rgb(var(--fg)); outline: none; }
.search .ico { width: 15px; height: 15px; }
.kbd { display: inline-block; padding: 0 5px; border: 1px solid rgb(var(--line-strong)); border-bottom-width: 2px; border-radius: 3px; font-size: 11px; line-height: 16px; color: rgb(var(--fg-subtle)); background: rgb(var(--surface-2)); }

.topbar-actions { display: flex; align-items: center; gap: 4px; flex: none; }
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: var(--radius-sm);
  border: 1px solid transparent; background: transparent; color: rgb(var(--fg-muted)); cursor: pointer;
}
.icon-btn:hover { background: rgb(var(--surface-2)); color: rgb(var(--fg)); }
.icon-btn .ico { width: 18px; height: 18px; }
.icon-btn:focus-visible, .btn:focus-visible, .tab:focus-visible, .chip:focus-visible { outline: 2px solid rgb(var(--accent)); outline-offset: 2px; }

.theme-toggle .icon-sun { display: none; } .theme-toggle .icon-moon { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

.user-btn { display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 0 8px 0 4px; border-radius: var(--radius-sm); border: 1px solid transparent; background: transparent; cursor: pointer; font-size: 13px; font-weight: 500; color: rgb(var(--fg)); }
.user-btn:hover { background: rgb(var(--surface-2)); }
.user-btn .ico { width: 14px; height: 14px; color: rgb(var(--fg-subtle)); }
.avatar-user { width: 26px; height: 26px; border-radius: 50%; background: rgb(var(--accent-solid)); color: rgb(var(--on-accent)); font-size: 11px; font-weight: 600; display: inline-flex; align-items: center; justify-content: center; flex: none; }

.menu { position: relative; }
.menu-panel {
  position: absolute; right: 0; top: calc(100% + 6px); min-width: 208px;
  background: rgb(var(--surface)); border: 1px solid rgb(var(--line)); border-radius: var(--radius);
  box-shadow: var(--shadow-menu); padding: 6px; z-index: 50;
}
.menu-panel.left { right: auto; left: 0; }
.menu-item { display: flex; align-items: center; gap: 8px; width: 100%; padding: 7px 10px; border-radius: var(--radius-sm); font-size: 13px; text-align: left; background: none; border: 0; cursor: pointer; color: rgb(var(--fg)); white-space: nowrap; }
.menu-item:hover { background: rgb(var(--surface-2)); text-decoration: none; }
.menu-item .ico { width: 15px; height: 15px; color: rgb(var(--fg-subtle)); }
.menu-item.selected { background: rgb(var(--accent-soft)); color: rgb(var(--accent-text)); }
.menu-item.selected .ico { color: rgb(var(--accent-text)); }
.menu-sep { height: 1px; background: rgb(var(--line)); margin: 6px 0; }
.menu-label { padding: 6px 10px 2px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: rgb(var(--fg-subtle)); }
.menu-head { padding: 8px 10px 6px; }
.menu-head .name { font-weight: 600; font-size: 13px; }
.menu-head .mail { font-size: 12px; color: rgb(var(--fg-subtle)); }

/* ---------------------------------------------------------------------------
   Sidebar
   --------------------------------------------------------------------------- */
.sidebar {
  width: var(--sidebar-w); flex: none;
  position: sticky; top: var(--topbar-h);
  height: calc(100vh - var(--topbar-h)); overflow-y: auto; overflow-x: hidden;
  background: rgb(var(--sidebar-bg)); border-right: 1px solid rgb(var(--line));
  padding: 12px 8px; display: flex; flex-direction: column;
  transition: width 0.15s ease;
}
.side-group { margin-bottom: 12px; }
.side-label { padding: 8px 12px 4px; font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: rgb(var(--fg-subtle)); white-space: nowrap; }
.side-item {
  position: relative; display: flex; align-items: center; gap: 10px;
  padding: 7px 12px; border-radius: var(--radius-sm);
  color: rgb(var(--fg-muted)); font-size: 13.5px; font-weight: 500; white-space: nowrap;
  border: 0; background: none; width: 100%; text-align: left; cursor: pointer;
}
.side-item:hover { background: rgb(var(--surface-2)); color: rgb(var(--fg)); text-decoration: none; }
.side-item.active { background: rgb(var(--accent-soft)); color: rgb(var(--accent-text)); }
.side-item.active::before { content: ""; position: absolute; left: -8px; top: 6px; bottom: 6px; width: 3px; border-radius: 0 2px 2px 0; background: rgb(var(--accent)); }
.side-item .ico { width: 18px; height: 18px; flex: none; }
.side-item .count { margin-left: auto; font-size: 11px; font-weight: 600; color: rgb(var(--fg-subtle)); background: rgb(var(--surface-2)); padding: 0 6px; border-radius: 999px; }
.side-item .ext { margin-left: auto; width: 12px; height: 12px; color: rgb(var(--fg-subtle)); }
.side-back { display: flex; align-items: center; gap: 6px; padding: 6px 12px; font-size: 12.5px; color: rgb(var(--fg-muted)); white-space: nowrap; }
.side-back:hover { color: rgb(var(--accent-text)); text-decoration: none; }
.side-back .ico { width: 14px; height: 14px; }
.side-project { display: flex; align-items: center; gap: 10px; padding: 6px 12px 14px; border-bottom: 1px solid rgb(var(--line)); margin-bottom: 10px; }
.side-project img { width: 32px; height: 32px; border-radius: 6px; border: 1px solid rgb(var(--line)); flex: none; }
.side-project .meta { min-width: 0; }
.side-project .name { font-weight: 600; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.side-foot { margin-top: auto; padding-top: 8px; border-top: 1px solid rgb(var(--line)); }

html[data-sidebar="collapsed"] .sidebar { width: var(--sidebar-w-collapsed); padding: 12px 6px; }
html[data-sidebar="collapsed"] .side-label { height: 1px; padding: 0; margin: 8px 8px; background: rgb(var(--line)); font-size: 0; }
html[data-sidebar="collapsed"] .side-item { padding: 9px 12px; justify-content: center; }
html[data-sidebar="collapsed"] .side-item > span, html[data-sidebar="collapsed"] .side-item .count, html[data-sidebar="collapsed"] .side-item .ext,
html[data-sidebar="collapsed"] .side-back > span, html[data-sidebar="collapsed"] .side-project .meta { display: none; }
html[data-sidebar="collapsed"] .side-item.active::before { left: -6px; }
html[data-sidebar="collapsed"] .side-project { justify-content: center; padding: 4px 0 12px; }
html[data-sidebar="collapsed"] .side-back { justify-content: center; }
html[data-sidebar="collapsed"] .side-collapse .ico { transform: rotate(180deg); }

.menu-toggle { display: none; }
.backdrop { display: none; position: fixed; inset: var(--topbar-h) 0 0 0; background: rgb(var(--overlay) / 0.45); z-index: 44; }
@media (max-width: 900px) {
  .sidebar { position: fixed; left: 0; top: var(--topbar-h); width: var(--sidebar-w) !important; padding: 12px 8px !important; transform: translateX(-100%); z-index: 45; box-shadow: var(--shadow-menu); transition: transform 0.2s ease; }
  html[data-sidebar="open"] .sidebar { transform: none; }
  html[data-sidebar="open"] .backdrop { display: block; }
  html[data-sidebar="collapsed"] .side-label { height: auto; padding: 8px 12px 4px; margin: 0; background: none; font-size: 11px; }
  html[data-sidebar="collapsed"] .side-item { justify-content: flex-start; padding: 7px 12px; }
  html[data-sidebar="collapsed"] .side-item > span, html[data-sidebar="collapsed"] .side-back > span, html[data-sidebar="collapsed"] .side-project .meta { display: inline; }
  .side-collapse { display: none; }
  .menu-toggle { display: inline-flex; }
  .topbar .search { display: none; }
  .crumbs .crumb:not(.current):not(.crumb-btn) { display: none; }
  .crumbs .sep { display: none; }
  .page { padding: 16px 16px 48px; }
  .user-btn > span { display: none; }
  .topbar { gap: 6px; padding: 0 10px; }
  .topbar-divider { display: none; }
  .topbar-actions .btn > span { display: none; }
  .topbar-actions .btn .ico:last-child { display: none; }
  .topbar-actions > a.icon-btn { display: none; }
}
@media (max-width: 640px) {
  .crumbs { display: none; }
  .brand .wordmark { display: none; }
}

/* ---------------------------------------------------------------------------
   Cards, grids, stat tiles
   --------------------------------------------------------------------------- */
.card { background: rgb(var(--surface)); border: 1px solid rgb(var(--line)); border-radius: var(--radius); }
.card + .card, .card + .section-head { margin-top: 16px; }
.grid > .card + .card, .grid > .card + .section-head, .grid > * { margin-top: 0; }
.card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 14px 20px; border-bottom: 1px solid rgb(var(--line)); flex-wrap: wrap; }
.card-title { font-size: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
.card-sub { font-size: 13px; color: rgb(var(--fg-muted)); margin-top: 2px; }
.card-body { padding: 20px; }
.card-body.compact { padding: 14px 16px; }
.card-foot { padding: 12px 20px; border-top: 1px solid rgb(var(--line)); background: rgb(var(--surface-2)); border-radius: 0 0 var(--radius) var(--radius); display: flex; justify-content: flex-end; gap: 8px; align-items: center; }
.card-foot.between { justify-content: space-between; }
.card-link { display: block; color: inherit; transition: border-color 0.15s ease, box-shadow 0.15s ease; }
.card-link:hover { border-color: rgb(var(--accent) / 0.6); text-decoration: none; box-shadow: 0 1px 2px rgb(var(--overlay) / 0.06); }
.card.selectable { transition: border-color 0.15s ease; } .card.selectable:hover { border-color: rgb(var(--accent) / 0.5); }

.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) { .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: minmax(0, 1fr); } }

.stat { padding: 14px 16px; background: rgb(var(--surface)); border: 1px solid rgb(var(--line)); border-radius: var(--radius); min-width: 0; }
.stat-label { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: rgb(var(--fg-subtle)); }
.stat-value { font-size: 20px; font-weight: 600; margin-top: 4px; letter-spacing: -0.01em; line-height: 1.25; overflow-wrap: anywhere; }
.stat-value.sm { font-size: 14px; font-weight: 500; }
.stat-note { font-size: 12px; color: rgb(var(--fg-muted)); margin-top: 3px; }
.stat-inset { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; text-align: center; }
.stat-inset > div { background: rgb(var(--surface-2)); border-radius: var(--radius-sm); padding: 8px 4px; }
.stat-inset .v { font-size: 18px; font-weight: 600; } .stat-inset .l { font-size: 11px; color: rgb(var(--fg-subtle)); }

/* ---------------------------------------------------------------------------
   Tables
   --------------------------------------------------------------------------- */
.table-wrap { overflow-x: auto; }
.card > .table-wrap:first-child .table th:first-child { border-top-left-radius: var(--radius); }
.table { width: 100%; border-collapse: collapse; font-size: 13px; }
.table th { text-align: left; font-weight: 600; font-size: 12px; color: rgb(var(--fg-muted)); padding: 9px 16px; background: rgb(var(--surface-2)); border-bottom: 1px solid rgb(var(--line)); white-space: nowrap; }
.table td { padding: 11px 16px; border-bottom: 1px solid rgb(var(--line)); vertical-align: middle; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover td { background: rgb(var(--surface-2) / 0.55); }
.table .right { text-align: right; } .table .center { text-align: center; }
.table .actions { text-align: right; white-space: nowrap; }
.table .actions form { display: inline; }
.table .actions .btn-link + form, .table .actions form + form, .table .actions .btn-link + .btn-link { margin-left: 12px; }
.table tr.row-danger td { background: rgb(var(--red-soft)); }
/* A column of checkboxes that pick rows for one action (network members). */
.table .pick { width: 1%; padding-right: 0; }
.table .pick input { accent-color: rgb(var(--accent-solid)); width: 15px; height: 15px; margin: 0; vertical-align: middle; cursor: pointer; }
.table tbody tr:has(td.pick input:checked) td { background: rgb(var(--accent-soft)); }
.table td .tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.table .mono { font-size: 12px; }
.table-foot { display: flex; justify-content: center; align-items: center; gap: 12px; padding: 10px; font-size: 13px; }

/* ---------------------------------------------------------------------------
   Badges, tags, dots
   --------------------------------------------------------------------------- */
.badge { display: inline-flex; align-items: center; gap: 6px; padding: 1px 8px; border-radius: 999px; font-size: 12px; font-weight: 500; line-height: 18px; border: 1px solid transparent; white-space: nowrap; vertical-align: middle; }
/* The hexagon: the mark is a pointy-top hexagon, and every status marker,
   tree dot, eyebrow and step marker in the product is that same shape. Never
   a circle. The shape lives on a pseudo-element where a glow has to sit
   outside it (a clip-path would clip the glow). Shared with the public site
   (mockups/redesign-21-10-2026). */
.badge .dot { position: relative; width: 6px; height: 7px; flex: none; }
.badge .dot::before { content: ""; position: absolute; inset: 0; background: currentColor; clip-path: var(--hex); }
.badge .dot.pulse { animation: pulse 1.8s infinite; }
@keyframes pulse { 0% { filter: drop-shadow(0 0 0 currentColor); } 70% { filter: drop-shadow(0 0 4px transparent); } 100% { filter: drop-shadow(0 0 0 transparent); } }
.badge-neutral { background: rgb(var(--surface-2)); color: rgb(var(--fg-muted)); border-color: rgb(var(--line)); }
.badge-green  { background: rgb(var(--accent-soft)); color: rgb(var(--accent-text)); }
.badge-violet { background: rgb(var(--violet-soft)); color: rgb(var(--violet-text)); }
.badge-amber  { background: rgb(var(--amber-soft)); color: rgb(var(--amber-text)); }
.badge-red    { background: rgb(var(--red-soft)); color: rgb(var(--red-text)); }
.badge-outline { background: transparent; border-color: rgb(var(--line-strong)); color: rgb(var(--fg-muted)); }
/* Enclave tiers: Bronze wears the brand amber; Gold (SEV-ES) and Platinum
   (SEV-SNP) step outside the brand palette, to gold and silver, so the three
   read as the medals they are named after. */
.badge-gold { background: linear-gradient(135deg, #FFF8DC, #F2D675); border-color: #D2A52A; color: #574000; }
:root[data-theme="dark"] .badge-gold { background: linear-gradient(135deg, rgb(234 179 8 / .28), rgb(202 138 4 / .14)); border-color: rgb(234 179 8 / .5); color: #F7DC8A; }
.badge-platinum { background: linear-gradient(135deg, #F8FAFC, #D5DCE4); border-color: #A8B3BF; color: #2F3A46; }
:root[data-theme="dark"] .badge-platinum { background: linear-gradient(135deg, rgb(226 232 240 / .22), rgb(148 163 184 / .14)); border-color: rgb(203 213 225 / .45); color: #E6ECF2; }
.badge-outline-red { background: transparent; border-color: rgb(var(--red) / 0.5); color: rgb(var(--red-text)); }
.badge-sm { font-size: 11px; line-height: 16px; padding: 0 6px; }
.tag { display: inline-block; padding: 0 6px; border-radius: 3px; font-size: 11px; line-height: 18px; background: rgb(var(--surface-2)); color: rgb(var(--fg-muted)); border: 1px solid rgb(var(--line)); white-space: nowrap; }
.status-dot { display: inline-block; width: 8px; height: 9px; background: rgb(var(--fg-subtle)); clip-path: var(--hex); vertical-align: middle; }
.status-dot.ok { background: rgb(var(--accent)); } .status-dot.warn { background: rgb(var(--amber)); } .status-dot.bad { background: rgb(var(--red)); }

/* ---------------------------------------------------------------------------
   Buttons
   --------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 32px; padding: 0 12px; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 500; line-height: 1;
  border: 1px solid transparent; cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.btn:hover { text-decoration: none; }
.btn .ico { width: 15px; height: 15px; }
.btn-primary { background: rgb(var(--accent-solid)); color: rgb(var(--on-accent)); border-color: rgb(var(--accent-solid)); }
.btn-primary:hover { background: rgb(var(--accent-hover)); border-color: rgb(var(--accent-hover)); color: rgb(var(--on-accent)); }
.btn-secondary { background: rgb(var(--surface)); color: rgb(var(--fg)); border-color: rgb(var(--line-strong)); }
.btn-secondary:hover { background: rgb(var(--surface-2)); }
.btn-violet { background: rgb(var(--violet-500)); color: #fff; border-color: rgb(var(--violet-500)); }
.btn-violet:hover { background: rgb(var(--violet-600)); border-color: rgb(var(--violet-600)); }
.btn-danger { background: rgb(var(--red)); color: #fff; border-color: rgb(var(--red)); }
.btn-danger:hover { background: rgb(var(--red-600)); border-color: rgb(var(--red-600)); }
.btn-danger-outline { background: rgb(var(--surface)); color: rgb(var(--red-text)); border-color: rgb(var(--red) / 0.5); }
.btn-danger-outline:hover { background: rgb(var(--red-soft)); }
.btn-warn { background: rgb(var(--amber-500)); color: #fff; border-color: rgb(var(--amber-500)); }
.btn-warn:hover { background: rgb(var(--amber-600)); border-color: rgb(var(--amber-600)); }
.btn-warn-outline { background: rgb(var(--surface)); color: rgb(var(--amber-text)); border-color: rgb(var(--amber) / 0.6); }
.btn-warn-outline:hover { background: rgb(var(--amber-soft)); }
.btn-ghost { background: transparent; color: rgb(var(--fg-muted)); }
.btn-ghost:hover { background: rgb(var(--surface-2)); color: rgb(var(--fg)); }
.btn-link { background: none; border: 0; padding: 0; height: auto; color: rgb(var(--accent-text)); font-weight: 500; font-size: 12.5px; }
.btn-link:hover { text-decoration: underline; }
.btn-link.danger { color: rgb(var(--red-text)); } .btn-link.warn { color: rgb(var(--amber-text)); } .btn-link.muted { color: rgb(var(--fg-muted)); }
/* A node's public IP, hidden until clicked (SP.ipReveal in dashboard.js). The
   dots are a fixed length so the mask gives nothing away. */
.ip-reveal { display: inline; background: none; border: 0; border-bottom: 1px dotted rgb(var(--fg-subtle)); border-radius: 0; padding: 0; height: auto; font: inherit; font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace; color: inherit; cursor: pointer; }
.ip-reveal:hover { color: rgb(var(--accent-text)); border-bottom-color: currentColor; }
.ip-reveal:focus-visible { outline: none; box-shadow: 0 0 0 3px rgb(var(--accent) / .45); border-radius: 2px; }
.ip-reveal:not(.is-shown) .ip-value { display: none; }
.ip-reveal:not(.is-shown)::before { content: '•••.•••.•••.•••'; content: '•••.•••.•••.•••' / ''; color: rgb(var(--fg-muted)); letter-spacing: .02em; }
.ip-reveal:not(.is-shown):hover::before { color: inherit; }
.ip-reveal.is-shown .sr-only { display: none; }
/* A choice row holding an IP: the submit button stretches over the row so the
   whole row still picks it, and the IP sits above to be clicked on its own. */
.choice.has-stretch { position: relative; align-items: center; }
.choice-stretch { background: none; border: 0; padding: 0; height: auto; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.choice-stretch::after { content: ''; position: absolute; inset: 0; border-radius: inherit; }
.choice.has-stretch .ip-reveal { position: relative; z-index: 1; }
.btn-sm { height: 28px; padding: 0 10px; font-size: 12px; }
.btn-lg { height: 38px; padding: 0 16px; font-size: 14px; }
.btn-block { width: 100%; }
.btn[disabled], .btn.disabled, .btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-group { display: inline-flex; gap: 8px; }

/* ---------------------------------------------------------------------------
   Forms
   --------------------------------------------------------------------------- */
.field { margin-bottom: 16px; }
.field:last-child { margin-bottom: 0; }
.label { display: block; font-size: 13px; font-weight: 500; margin-bottom: 6px; }
.label .opt { font-weight: 400; color: rgb(var(--fg-subtle)); }
.label-sm { font-size: 12px; }
.input, .select, .textarea {
  display: block; width: 100%; height: 36px; padding: 0 10px;
  border: 1px solid rgb(var(--line-strong)); border-radius: var(--radius-sm);
  background: rgb(var(--surface)); color: rgb(var(--fg)); font-size: 13.5px;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.textarea { height: auto; padding: 8px 10px; min-height: 84px; resize: vertical; line-height: 1.45; }
.select { padding-right: 28px; appearance: none; -webkit-appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%237B8285'%3E%3Cpath fill-rule='evenodd' d='M5.23 7.21a.75.75 0 011.06.02L10 11.17l3.71-3.94a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z' clip-rule='evenodd'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 8px center; background-size: 16px; cursor: pointer; }
.input:focus, .select:focus, .textarea:focus { outline: none; border-color: rgb(var(--accent)); box-shadow: 0 0 0 3px rgb(var(--accent) / 0.2); }
.input[disabled], .select[disabled], .textarea[disabled], .input[readonly] { background: rgb(var(--surface-3)); color: rgb(var(--fg-muted)); }
.input.danger:focus { border-color: rgb(var(--red)); box-shadow: 0 0 0 3px rgb(var(--red) / 0.2); }
.input-sm, .select-sm { height: 30px; font-size: 13px; }
.input-mono { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 13px; }
.input-code { font-family: ui-monospace, Menlo, Consolas, monospace; text-align: center; letter-spacing: 0.2em; font-size: 18px; text-transform: uppercase; height: 44px; }
.input-inline { display: inline-block; width: auto; }
.help { font-size: 12px; color: rgb(var(--fg-subtle)); margin-top: 6px; line-height: 1.45; }
.help code { font-size: 11.5px; }
.form-row { display: grid; gap: 16px; grid-template-columns: 1fr 1fr; }
.form-row-3 { display: grid; gap: 12px; grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 640px) { .form-row, .form-row-3 { grid-template-columns: 1fr; } }
/* A field with a fixed prefix inside it: "£", "CA$", "/hosts/". The prefix
   takes real space, so the value always starts after it, whatever its width.
   (It used to be laid over the input, which left room for one symbol, so a
   longer prefix ran into the text.) The group draws the field (border,
   background, focus ring) and the input inside it is bare, so give a width
   to the group, not the input. app.js focuses the input on a click on the
   prefix. */
.input-group { position: relative; display: flex; align-items: center; width: 100%; max-width: 100%; height: 36px; cursor: text;
  border: 1px solid rgb(var(--line-strong)); border-radius: var(--radius-sm); background: rgb(var(--surface));
  transition: border-color 0.12s ease, box-shadow 0.12s ease; }
.input-group:has(.input-sm) { height: 30px; }
.input-group:focus-within { border-color: rgb(var(--accent)); box-shadow: 0 0 0 3px rgb(var(--accent) / 0.2); }
.input-group:has(.input[disabled]), .input-group:has(.input[readonly]) { background: rgb(var(--surface-3)); cursor: default; }
.input-group .prefix { flex: none; padding-left: 10px; color: rgb(var(--fg-subtle)); font-size: 13px; white-space: nowrap; pointer-events: none; }
.input-group .input { flex: 1 1 auto; min-width: 0; width: auto; height: 100%; padding-left: 4px; border: 0; border-radius: inherit; background: transparent; }
.input-group .input:focus { box-shadow: none; }
.input-file { padding: 6px 10px; height: auto; }
.input-file::file-selector-button { font: inherit; font-size: 12px; font-weight: 500; margin-right: 10px; padding: 4px 10px; border: 1px solid rgb(var(--line-strong)); border-radius: 3px; background: rgb(var(--surface-2)); color: rgb(var(--fg)); cursor: pointer; }
.check { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; cursor: pointer; }
.check input { margin: 3px 0 0; accent-color: rgb(var(--accent-solid)); width: 15px; height: 15px; flex: none; }
.check .desc { display: block; font-size: 12px; color: rgb(var(--fg-subtle)); }
input[type="range"] { accent-color: rgb(var(--accent-solid)); width: 100%; }
.form-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }

.toggle { position: relative; width: 36px; height: 20px; border-radius: 999px; background: rgb(var(--line-strong)); border: 0; cursor: pointer; flex: none; padding: 0; transition: background-color 0.15s ease; }
.toggle::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgb(0 0 0 / 0.3); transition: transform 0.15s ease; }
.toggle[aria-checked="true"], .toggle.on { background: rgb(var(--accent-solid)); }
.toggle[aria-checked="true"]::after, .toggle.on::after { transform: translateX(16px); }
.toggle-row { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.toggle-row .t-label { font-size: 13px; font-weight: 500; } .toggle-row .t-note { font-size: 12px; color: rgb(var(--fg-subtle)); }

/* Choice cards — radio / checkbox options with a title and description. */
.choice { display: flex; align-items: flex-start; gap: 10px; padding: 12px; border: 1px solid rgb(var(--line)); border-radius: var(--radius); cursor: pointer; background: rgb(var(--surface)); text-align: left; width: 100%; transition: border-color 0.12s ease, background-color 0.12s ease; }
.choice:hover { border-color: rgb(var(--line-strong)); background: rgb(var(--surface-2) / 0.5); }
.choice.selected { border-color: rgb(var(--accent)); background: rgb(var(--accent-soft)); box-shadow: inset 0 0 0 1px rgb(var(--accent)); }
.choice[aria-disabled="true"], .choice:disabled { opacity: 0.55; cursor: not-allowed; }
.choice input { margin-top: 2px; accent-color: rgb(var(--accent-solid)); flex: none; }
.choice .ico { width: 22px; height: 22px; color: rgb(var(--accent-text)); margin-top: 1px; }
.choice-title { font-size: 13.5px; font-weight: 600; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.choice-desc { display: block; font-size: 12.5px; color: rgb(var(--fg-muted)); margin-top: 2px; }
.choice-body { min-width: 0; flex: 1; }
.choice-list { display: flex; flex-direction: column; gap: 8px; }

/* Segmented filter chips */
.chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.chips-label { font-size: 12px; font-weight: 600; color: rgb(var(--fg-muted)); margin-right: 4px; }
.chip { height: 26px; padding: 0 10px; border-radius: 999px; font-size: 12px; font-weight: 500; border: 1px solid rgb(var(--line-strong)); background: rgb(var(--surface)); color: rgb(var(--fg-muted)); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.chip:hover { background: rgb(var(--surface-2)); color: rgb(var(--fg)); }
.chip.active { background: rgb(var(--fg)); color: rgb(var(--bg)); border-color: rgb(var(--fg)); }
.chip .dot { width: 6px; height: 7px; clip-path: var(--hex); }
.filters { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }

/* Tabs */
.tabs { display: flex; gap: 24px; border-bottom: 1px solid rgb(var(--line)); margin-bottom: 20px; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tab { padding: 10px 2px; font-size: 13.5px; font-weight: 500; color: rgb(var(--fg-muted)); border: 0; border-bottom: 2px solid transparent; background: none; cursor: pointer; white-space: nowrap; }
.tab:hover { color: rgb(var(--fg)); text-decoration: none; }
.tab.active { color: rgb(var(--accent-text)); border-color: rgb(var(--accent)); }

/* ---------------------------------------------------------------------------
   Alerts, empty states, setting rows, danger zone
   --------------------------------------------------------------------------- */
.alert { display: flex; gap: 10px; padding: 12px 14px; border-radius: var(--radius); border: 1px solid; font-size: 13px; line-height: 1.5; }
.alert + .alert, .alert + .card, .card + .alert { margin-top: 16px; }
.alert .ico { width: 18px; height: 18px; flex: none; margin-top: 1px; }
.alert-title { font-weight: 600; }
.alert-body { min-width: 0; flex: 1; }
.alert-body p + p { margin-top: 4px; }
.alert-info    { background: rgb(var(--accent-soft)); border-color: rgb(var(--accent) / 0.4); } .alert-info .ico, .alert-info .alert-title { color: rgb(var(--accent-text)); }
.alert-warning { background: rgb(var(--amber-soft)); border-color: rgb(var(--amber) / 0.5); }  .alert-warning .ico, .alert-warning .alert-title { color: rgb(var(--amber-text)); }
.alert-danger  { background: rgb(var(--red-soft)); border-color: rgb(var(--red) / 0.4); }      .alert-danger .ico, .alert-danger .alert-title { color: rgb(var(--red-text)); }
.alert-success { background: rgb(var(--accent-soft)); border-color: rgb(var(--accent) / 0.5); } .alert-success .ico, .alert-success .alert-title { color: rgb(var(--accent-text)); }
.alert-violet  { background: rgb(var(--violet-soft)); border-color: rgb(var(--violet) / 0.45); } .alert-violet .ico, .alert-violet .alert-title { color: rgb(var(--violet-text)); }
.alert-neutral { background: rgb(var(--surface-2)); border-color: rgb(var(--line)); }
.alert-dismiss { margin-left: auto; align-self: flex-start; }

.empty { padding: 40px 20px; text-align: center; color: rgb(var(--fg-muted)); }
.empty.compact { padding: 24px 16px; font-size: 13px; }
.empty .ico { width: 36px; height: 36px; color: rgb(var(--fg-subtle)); margin: 0 auto 10px; display: block; }
.empty-title { font-size: 15px; font-weight: 600; color: rgb(var(--fg)); }
.empty p { margin-top: 4px; font-size: 13px; }
.empty .actions { margin-top: 16px; display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; }

.setting-row { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 16px 20px; border-bottom: 1px solid rgb(var(--line)); }
.setting-row:last-child { border-bottom: 0; }
.setting-row.top { align-items: flex-start; }
.setting-main { min-width: 0; flex: 1; }
.setting-title { font-size: 14px; font-weight: 500; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.setting-desc { font-size: 13px; color: rgb(var(--fg-muted)); margin-top: 2px; max-width: 64ch; }
.setting-control { flex: none; display: flex; align-items: center; gap: 8px; }
@media (max-width: 640px) { .setting-row { flex-direction: column; align-items: flex-start; gap: 12px; } }

.danger-zone { border-color: rgb(var(--red) / 0.45); }
.danger-zone .card-head { background: rgb(var(--red-soft)); border-color: rgb(var(--red) / 0.3); border-radius: var(--radius) var(--radius) 0 0; }
.danger-zone .card-title { color: rgb(var(--red-text)); }

/* ---------------------------------------------------------------------------
   Code, logs, description lists
   --------------------------------------------------------------------------- */
.code { background: #0F1512; color: #D2FCDF; border-radius: var(--radius); padding: 10px 12px; font-size: 12px; line-height: 1.6; overflow-x: auto; white-space: pre; margin: 0; border: 1px solid rgb(var(--line)); }
.code .c { color: #7B8285; } .code .k { color: #63E69A; } .code .s { color: #E4A070; }
.code-inline { padding: 1px 5px; border-radius: 3px; background: rgb(var(--surface-3)); font-size: 12px; border: 1px solid rgb(var(--line)); }
.code-copy { display: flex; gap: 8px; align-items: stretch; }
.code-copy .code, .code-copy .code-inline { flex: 1; min-width: 0; }
.log { background: #0B100D; color: #63E69A; border-radius: var(--radius); padding: 14px 16px; font-size: 12.5px; line-height: 1.55; max-height: 360px; overflow: auto; white-space: pre-wrap; word-break: break-word; margin: 0; border: 1px solid rgb(var(--line)); }
.log .ts { color: #7B8285; } .log .err { color: #F5AA9B; } .log .warn { color: #E4A070; }

.dl { display: grid; grid-template-columns: 220px minmax(0, 1fr); font-size: 13px; margin: 0; }
.dl dt { color: rgb(var(--fg-muted)); padding: 10px 20px; border-bottom: 1px solid rgb(var(--line)); font-weight: 500; }
.dl dd { margin: 0; padding: 10px 20px; border-bottom: 1px solid rgb(var(--line)); overflow-wrap: anywhere; }
.dl dt:nth-last-child(2), .dl dd:last-child { border-bottom: 0; }
@media (max-width: 640px) { .dl { grid-template-columns: 1fr; } .dl dt { border-bottom: 0; padding-bottom: 0; } }
.kv { display: flex; justify-content: space-between; align-items: center; gap: 12px; font-size: 13px; padding: 5px 0; margin: 0; }
.kv dt { color: rgb(var(--fg-muted)); } .kv dd { margin: 0; font-weight: 500; text-align: right; }
.kv-list > .kv + .kv { border-top: 1px solid rgb(var(--line)); }

/* ---------------------------------------------------------------------------
   Wizard step indicator
   --------------------------------------------------------------------------- */
.steps { display: grid; grid-template-columns: repeat(4, 1fr); }
.step { display: flex; flex-direction: column; align-items: center; }
.step-line { display: flex; align-items: center; width: 100%; }
.step-line .bar { flex: 1; height: 2px; background: rgb(var(--line)); }
.step-line .bar.done { background: rgb(var(--accent)); } .step-line .bar.none { background: transparent; }
/* Step marker: ::before is the edge hexagon, ::after the fill, both behind the number. */
.step-num { position: relative; isolation: isolate; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600; color: rgb(var(--fg-muted)); flex: none; }
.step-num::before, .step-num::after { content: ""; position: absolute; z-index: -1; clip-path: var(--hex); transition: background-color 0.15s ease; }
.step-num::before { inset: 1px; background: rgb(var(--line-strong)); }
.step-num::after { inset: 2px; background: rgb(var(--line)); }
.step-num.done { color: rgb(var(--on-accent)); }
.step-num.done::before, .step-num.done::after { background: rgb(var(--accent-solid)); }
.step-label { font-size: 11px; color: rgb(var(--fg-muted)); margin-top: 6px; text-align: center; }
.progress-dots { display: flex; gap: 6px; align-items: center; }
.progress-dots i { height: 6px; width: 16px; border-radius: 999px; background: rgb(255 255 255 / 0.3); transition: all 0.25s ease; }
.progress-dots i.done { background: rgb(255 255 255 / 0.8); } .progress-dots i.current { width: 32px; background: rgb(var(--green-200)); }

/* ---------------------------------------------------------------------------
   Modals.

   The .modal-panel / .modal-head / .modal-body / .modal-foot block is carried
   over VERBATIM in behaviour from frontend/web/static/css/style.css. It is
   load-bearing: the panel is a bounded flex column so a tall dialog scrolls
   its body while the title and the action buttons stay on screen. The
   community Deploy dialog and the workload wizard depend on it. Padding lives
   on the parts, never on the panel, so the scroll region runs edge to edge.
   --------------------------------------------------------------------------- */
.modal { position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center; padding: 16px; background: rgb(var(--overlay) / 0.55); }
.modal-panel {
  display: flex; flex-direction: column;
  max-height: calc(100vh - 2rem);
  max-height: calc(100dvh - 2rem);
  width: 100%; max-width: 480px;
  background: rgb(var(--surface)); border: 1px solid rgb(var(--line)); border-radius: 8px;
  box-shadow: var(--shadow-modal); position: relative;
}
.modal-panel.modal-lg { max-width: 560px; } .modal-panel.modal-xl { max-width: 680px; }
.modal-panel > form { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.modal-head, .modal-foot { flex: 0 0 auto; }
.modal-body { flex: 1 1 auto; overflow-y: auto; min-height: 0; overscroll-behavior: contain; padding: 18px 20px; }
.modal-head { padding: 18px 20px 14px; border-bottom: 1px solid rgb(var(--line)); }
.modal-title { font-size: 16px; font-weight: 600; padding-right: 28px; }
.modal-sub { font-size: 13px; color: rgb(var(--fg-muted)); margin-top: 3px; }
.modal-close { position: absolute; top: 12px; right: 12px; }
.modal-foot { padding: 12px 20px; border-top: 1px solid rgb(var(--line)); background: rgb(var(--surface-2)); border-radius: 0 0 8px 8px; display: flex; justify-content: flex-end; gap: 8px; align-items: center; }
.modal-foot.between { justify-content: space-between; }
.modal-errors:empty { display: none; }
.modal-errors { margin-top: 10px; }
.modal-cost { padding: 10px 20px; background: rgb(var(--surface-2)); border-top: 1px solid rgb(var(--line)); font-size: 13px; flex: 0 0 auto; }

/* Modal head variant with the brand wash (onboarding). */
.modal-head.brand-wash { background: linear-gradient(135deg, rgb(var(--green-800)), rgb(var(--green-950)) 60%, rgb(var(--violet-950))); color: #fff; border-bottom: 0; border-radius: 8px 8px 0 0; padding: 22px 24px 18px; }
.modal-head.brand-wash .eyebrow { color: rgb(var(--green-200)); }
.modal-head.brand-wash .modal-title { font-size: 22px; font-weight: 700; }
.modal-head.brand-wash .modal-close { color: rgb(255 255 255 / 0.7); } .modal-head.brand-wash .modal-close:hover { color: #fff; background: rgb(255 255 255 / 0.1); }

/* ---------------------------------------------------------------------------
   Toast (mockup feedback for intercepted form submits)
   --------------------------------------------------------------------------- */
.toast { position: fixed; right: 20px; bottom: 20px; z-index: 100; max-width: 360px; padding: 10px 14px; border-radius: var(--radius); background: rgb(var(--fg)); color: rgb(var(--bg)); font-size: 13px; box-shadow: var(--shadow-menu); opacity: 0; transform: translateY(6px); transition: opacity 0.2s ease, transform 0.2s ease; pointer-events: none; }
.toast.show { opacity: 1; transform: none; }
.toast code { color: rgb(var(--green-200)); font-size: 12px; }
:root[data-theme="dark"] .toast code { color: rgb(var(--green-600)); }

/* ---------------------------------------------------------------------------
   Avatars, misc components
   --------------------------------------------------------------------------- */
.avatar { width: 32px; height: 32px; border-radius: 6px; border: 1px solid rgb(var(--line)); object-fit: cover; background: rgb(var(--surface-2)); flex: none; }
.avatar-lg { width: 56px; height: 56px; border-radius: 8px; }
.avatar-xl { width: 64px; height: 64px; border-radius: 8px; }
.avatar-btn { position: relative; display: block; border: 0; padding: 0; background: none; cursor: pointer; border-radius: 8px; }
.avatar-btn .over { position: absolute; inset: 0; border-radius: 8px; background: rgb(0 0 0 / 0.45); color: #fff; display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.12s ease; }
.avatar-btn:hover .over { opacity: 1; }
.avatar-btn .over .ico { width: 18px; height: 18px; }
/* Built-in avatar picker (partials/modals.html "avatar-preset-picker"). */
.av-picker { margin: 12px 0 0; padding: 0; border: 0; min-width: 0; }
.av-groups { display: grid; grid-template-columns: repeat(2, max-content); gap: 12px 24px; }
.av-group-wide { grid-column: 1 / -1; }
.av-group-label { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: rgb(var(--fg-subtle)); margin-bottom: 6px; }
.av-tiles { display: flex; gap: 6px; }
.av-tile { position: relative; display: block; border-radius: 7px; cursor: pointer; }
.av-tile img { display: block; width: 40px; height: 40px; border-radius: 7px; transition: transform 0.12s ease, box-shadow 0.12s ease; }
.av-tile:hover img { transform: translateY(-1px); }
.av-tile input:checked + img { box-shadow: 0 0 0 2px rgb(var(--surface)), 0 0 0 4px rgb(var(--accent-solid)); }
.av-tile input:focus-visible + img { outline: 2px solid rgb(var(--accent)); outline-offset: 4px; }
@media (max-width: 440px) { .av-groups { grid-template-columns: max-content; } }

.icon-tile { width: 36px; height: 36px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; flex: none; background: rgb(var(--accent-soft)); color: rgb(var(--accent-text)); border: 1px solid rgb(var(--accent) / 0.25); }
.icon-tile .ico { width: 18px; height: 18px; }
.icon-tile.violet { background: rgb(var(--violet-soft)); color: rgb(var(--violet-text)); border-color: rgb(var(--violet) / 0.25); }
.icon-tile.amber { background: rgb(var(--amber-soft)); color: rgb(var(--amber-text)); border-color: rgb(var(--amber) / 0.3); }
.icon-tile.neutral { background: rgb(var(--surface-2)); color: rgb(var(--fg-muted)); border-color: rgb(var(--line)); }
.icon-tile.sm { width: 28px; height: 28px; border-radius: 6px; } .icon-tile.sm .ico { width: 14px; height: 14px; }
.icon-tile.lg { width: 44px; height: 44px; border-radius: 10px; } .icon-tile.lg .ico { width: 22px; height: 22px; }

.copy-btn { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 4px; border: 0; background: none; color: rgb(var(--fg-subtle)); cursor: pointer; }
.copy-btn:hover { background: rgb(var(--surface-2)); color: rgb(var(--fg)); }
.copy-btn .ico { width: 14px; height: 14px; } .copy-btn .ico-check { display: none; color: rgb(var(--accent-text)); }
.copy-btn.copied .ico-copy { display: none; } .copy-btn.copied .ico-check { display: inline-block; }

.num-list { counter-reset: n; list-style: none; padding: 0; display: flex; flex-direction: column; gap: 8px; font-size: 13px; }
.num-list li { display: flex; gap: 8px; align-items: flex-start; }
.num-list li::before { counter-increment: n; content: counter(n); width: 20px; height: 20px; border-radius: 50%; background: rgb(var(--accent-soft)); color: rgb(var(--accent-text)); font-size: 11px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; flex: none; margin-top: 1px; }

.pill-nav { display: inline-flex; border: 1px solid rgb(var(--line-strong)); border-radius: var(--radius-sm); overflow: hidden; }
.pill-nav button { padding: 8px 12px; border: 0; background: rgb(var(--surface)); font-size: 13px; font-weight: 500; color: rgb(var(--fg-muted)); cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 4px; flex: 1; }
.pill-nav button + button { border-left: 1px solid rgb(var(--line-strong)); }
.pill-nav button.active { background: rgb(var(--accent-soft)); color: rgb(var(--accent-text)); }
.pill-nav .ico { width: 18px; height: 18px; }

.map { width: 100%; height: 180px; border-radius: var(--radius); border: 1px solid rgb(var(--line-strong)); z-index: 0; background: rgb(var(--surface-2)); }
.leaflet-container { font: inherit; }

.footer { margin-top: auto; padding: 20px 24px; border-top: 1px solid rgb(var(--line)); font-size: 12px; color: rgb(var(--fg-subtle)); display: flex; gap: 16px; flex-wrap: wrap; align-items: center; }
.footer a { color: rgb(var(--fg-muted)); } .footer .ml-auto { margin-left: auto; }

.community-card { display: flex; flex-direction: column; height: 100%; }
.community-card.bundle { border-left: 3px solid rgb(var(--violet)); }
.community-card .emoji { font-size: 24px; line-height: 1; }
/* The deploy wizard (community-deploy.html): the application, then each
   component it deploys. */
.app-intro { display: flex; gap: 14px; align-items: flex-start; padding: 14px 16px; border: 1px solid rgb(var(--line)); border-radius: var(--radius); background: rgb(var(--surface-2)); }
.app-intro .emoji { font-size: 30px; line-height: 1; }
.app-parts { border: 1px solid rgb(var(--line)); border-radius: var(--radius); }
.app-part { display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-bottom: 1px solid rgb(var(--line)); }
.app-part:last-child { border-bottom: 0; }
.app-part .emoji.sm { font-size: 18px; line-height: 1; width: 22px; text-align: center; flex: none; }
.community-card .card-body { flex: 1; display: flex; flex-direction: column; }

/* ---------------------------------------------------------------------------
   Auth pages: brand panel + form.
   --------------------------------------------------------------------------- */
.auth { min-height: 100vh; display: grid; grid-template-columns: 5fr 7fr; }
.auth-brand { position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: space-between; padding: 40px; color: #fff; background: radial-gradient(70rem 40rem at 10% -10%, rgb(var(--green-800) / 0.9), transparent 60%), radial-gradient(50rem 30rem at 100% 110%, rgb(var(--violet-800) / 0.8), transparent 65%), rgb(var(--green-950)); }
.auth-brand .lockup { display: flex; align-items: center; gap: 14px; }
.auth-brand .lockup .mark { width: 52px; height: 52px; }
.auth-brand .lockup .wordmark { font-size: 22px; color: #fff; }
.auth-brand h2 { font-size: 26px; font-weight: 700; line-height: 1.2; letter-spacing: -0.01em; }
.auth-brand p { color: rgb(255 255 255 / 0.75); margin-top: 10px; max-width: 42ch; font-size: 14px; }
.auth-brand .fine { font-size: 12px; color: rgb(255 255 255 / 0.5); }
.auth-form { display: flex; align-items: center; justify-content: center; padding: 40px 24px; }
.auth-card { width: 100%; max-width: 400px; }
.auth-card h1 { font-size: 22px; font-weight: 600; }
.auth-card .lead { color: rgb(var(--fg-muted)); font-size: 13.5px; margin-top: 4px; margin-bottom: 24px; }
.auth-foot { margin-top: 20px; font-size: 13px; color: rgb(var(--fg-muted)); text-align: center; }
@media (max-width: 800px) { .auth { grid-template-columns: 1fr; } .auth-brand { padding: 24px; min-height: 160px; } .auth-brand .copy { display: none; } .auth-brand .lockup { width: 120px; } }

/* ---------------------------------------------------------------------------
   Terminal frame (static in the mockup)
   --------------------------------------------------------------------------- */
.term { background: #0b1020; border-radius: var(--radius); border: 1px solid rgb(var(--line)); overflow: hidden; }
.term-bar { display: flex; align-items: center; gap: 6px; padding: 8px 12px; background: #141a2e; border-bottom: 1px solid rgb(255 255 255 / 0.06); font-size: 11px; color: rgb(255 255 255 / 0.5); }
.term-bar i { width: 10px; height: 10px; border-radius: 50%; background: #3a4160; }
.term-bar i:nth-child(1) { background: #e5484d; } .term-bar i:nth-child(2) { background: #e2b53e; } .term-bar i:nth-child(3) { background: #4fbb7c; }
.term pre { margin: 0; padding: 12px 14px; height: 62vh; min-height: 320px; overflow: auto; color: #d6dae8; font-size: 13px; line-height: 1.5; }
.term .p { color: #63E69A; } .term .d { color: #9978D0; } .term .cur { display: inline-block; width: 8px; height: 15px; background: #d6dae8; vertical-align: -3px; animation: blink 1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

/* ---------------------------------------------------------------------------
   Styleguide + gallery helpers
   --------------------------------------------------------------------------- */
.swatch { height: 56px; border-radius: var(--radius-sm); border: 1px solid rgb(var(--line)); display: flex; align-items: flex-end; padding: 6px 8px; font-size: 11px; font-family: ui-monospace, Menlo, monospace; }
.gallery-card .shot { aspect-ratio: 16 / 10; background: rgb(var(--surface-2)); border-bottom: 1px solid rgb(var(--line)); display: flex; align-items: center; justify-content: center; color: rgb(var(--fg-subtle)); overflow: hidden; }
.gallery-card .shot .ico { width: 32px; height: 32px; }
.mock-note { position: fixed; left: 50%; bottom: 12px; transform: translateX(-50%); z-index: 90; font-size: 11px; color: rgb(var(--fg-subtle)); background: rgb(var(--surface)); border: 1px solid rgb(var(--line)); border-radius: 999px; padding: 3px 10px; box-shadow: var(--shadow-menu); white-space: nowrap; }
.mock-note a { color: rgb(var(--fg-muted)); }

/* ---------------------------------------------------------------------------
   Charts (js/charts.js). Marks carry colour; every label wears a text token.
   The emphasis pair (errors in --chart-error, everything else in the
   de-emphasis --chart-base) and the single hues were checked with the
   dataviz validator in both themes. Where a chart tells entities apart
   (one line per host), --series-1..3 is the one categorical palette: the
   brand's green, violet and amber hues, re-stepped in OKLCH (same hue, a
   little more chroma, lightness spread apart) until every pair passes the
   validator's checks, all pairs, light on #FFFFFF and dark on #111714. Fixed
   order, never cycled; a fourth entity folds into "Other".
   --------------------------------------------------------------------------- */
:root {
  --chart-base:   123 130 133;          /* grey-500 — de-emphasis            */
  --chart-accent: var(--green-500);     /* #3D9562 on white → 3.6:1          */
  --chart-error:  212  53  28;          /* #D4351C                            */
  --chart-warn:   var(--amber-500);
  --series-1:      22 118  69;          /* #167645 green  L.50 C.115         */
  --series-2:     124  79 187;          /* #7C4FBB violet-500                 */
  --series-3:     203 126  69;          /* #CB7E45 amber  L.665 C.12          */
}
:root[data-theme="dark"] {
  --chart-accent: var(--green-400);     /* #4FBB7C on #111714                 */
  --chart-error:  245 140 120;          /* #F58C78                            */
  --chart-warn:   var(--amber-200);
  --series-1:      69 171 112;          /* #45AB70 green  L.665 C.13         */
  --series-2:     137  98 197;          /* #8962C5 violet L.58  C.15         */
  --series-3:     152  86  32;          /* #985620 amber  L.52  C.11         */
}
.chart { position: relative; width: 100%; }
.chart-svg { display: block; overflow: visible; font-family: inherit; }
.chart-grid { stroke: rgb(var(--line)); stroke-width: 1; }
.chart-axis { stroke: rgb(var(--line-strong)); stroke-width: 1; }
.chart-tick { font-size: 11px; fill: rgb(var(--fg-subtle)); font-variant-numeric: tabular-nums; }
.chart-label { font-size: 11px; font-weight: 500; fill: rgb(var(--fg-muted)); font-variant-numeric: tabular-nums; }
.chart-bar { transition: opacity 0.1s ease; }
.chart-bucket.is-hover .chart-bar { opacity: 0.72; }
.chart-hit { fill: transparent; outline: none; }
.chart-hit:focus-visible { stroke: rgb(var(--accent)); stroke-width: 1; }
.chart-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart-area { opacity: 0.10; }
.chart-ring { fill: rgb(var(--surface)); }
.chart-cross { stroke: rgb(var(--fg-subtle)); stroke-width: 1; }
.chart-tip { position: absolute; left: 0; top: 0; z-index: 5; pointer-events: none; min-width: 150px; padding: 8px 10px; border-radius: 6px; background: rgb(var(--fg)); color: rgb(var(--bg)); font-size: 12px; box-shadow: var(--shadow-menu); opacity: 0; transition: opacity 0.1s ease; }
.chart-tip.show { opacity: 1; }
.chart-tip .t-time { opacity: 0.7; margin-bottom: 4px; font-size: 11px; }
.chart-tip .t-row { display: flex; align-items: center; gap: 8px; padding: 1px 0; }
.chart-tip .t-row .key { width: 12px; height: 2px; border-radius: 1px; flex: none; }
.chart-tip .t-row .n { opacity: 0.8; }
.chart-tip .t-row .v { margin-left: auto; font-weight: 600; font-variant-numeric: tabular-nums; }
.legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12px; color: rgb(var(--fg-muted)); }
.legend-item { display: inline-flex; align-items: center; gap: 6px; }
.legend .sw { width: 10px; height: 10px; border-radius: 2px; flex: none; }
.legend .sw.line { width: 14px; height: 2px; border-radius: 1px; }
.chart-card .chart-table-wrap { display: none; }
.chart-card.show-table .chart, .chart-card.show-table .legend { display: none; }
.chart-card.show-table .chart-table-wrap { display: block; }
.chart-table td, .chart-table th { padding: 6px 12px; font-size: 12px; }
.chart-table-wrap { max-height: 240px; overflow: auto; }
.spark { display: block; }
.spark-line { fill: none; stroke: rgb(var(--chart-base)); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.stat .spark-wrap { position: absolute; right: 14px; bottom: 12px; }
.stat.with-spark { position: relative; padding-right: 96px; }
.stat-delta { font-size: 12px; font-weight: 500; margin-top: 3px; }
.stat-delta.up { color: rgb(var(--accent-text)); } .stat-delta.down { color: rgb(var(--red-text)); } .stat-delta.flat { color: rgb(var(--fg-subtle)); }
.hbars { display: flex; flex-direction: column; gap: 4px; }
.hbar-row { display: grid; grid-template-columns: minmax(90px, 160px) 1fr 56px; align-items: center; gap: 10px; font-size: 12.5px; padding: 4px 0; }
.hbar-label { color: rgb(var(--fg)); }
.hbar-track { height: 14px; }
.hbar { display: block; height: 100%; border-radius: 0 4px 4px 0; min-width: 2px; }
.hbar-value { text-align: right; font-variant-numeric: tabular-nums; color: rgb(var(--fg-muted)); }
.meter { height: 8px; border-radius: 999px; background: rgb(var(--accent-soft)); overflow: hidden; }
.meter > i { display: block; height: 100%; border-radius: 999px; background: rgb(var(--accent-solid)); }
.meter.warn { background: rgb(var(--amber-soft)); } .meter.warn > i { background: rgb(var(--amber)); }
.meter.orange { background: rgb(var(--amber-soft)); } .meter.orange > i { background: rgb(var(--amber-400)); transition: width .6s; }
.meter.violet { background: rgb(var(--violet-soft)); } .meter.violet > i { background: rgb(var(--violet-500)); transition: width .6s; }
.filter-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.filter-row .search { margin-left: 0; width: 300px; max-width: 100%; }
.level-info { color: rgb(var(--fg-muted)); } .level-warn { color: rgb(var(--amber-text)); } .level-error { color: rgb(var(--red-text)); }
.row-expand { background: rgb(var(--surface-2)); }
.row-expand td { padding-top: 8px; padding-bottom: 10px; }
.code-sm { font-size: 11.5px; line-height: 1.5; margin: 0; white-space: pre-wrap; }
.query-bar { display: grid; grid-template-columns: auto auto auto auto 1fr auto; gap: 8px; align-items: center; }
@media (max-width: 900px) { .query-bar { grid-template-columns: 1fr 1fr; } }

/* ---------------------------------------------------------------------------
   Hosting (phase 2). Proxmox's resource tree, section list and task log,
   drawn in the Cloudflare chrome. Everything below reuses the tokens above.
   --------------------------------------------------------------------------- */
:root {
  --rack-chassis: 31 41 36;      /* dark chassis in both themes — it is a physical object */
  --rack-slot:    20 27 23;
  --rack-line:    52 66 58;
  /* What a rack entry is decides its colour, always from the palette: an
     entry has no colour of its own (a stored item colour is not drawn). The
     admin rack page (handlers/hosting.go, buildRackElevation) uses the same. */
  --rack-server:  var(--grey-800);    /* neutral, the status dot carries state   */
  --rack-phage:   var(--green-600);   /* every Phage OS host, whatever its role  */
  --rack-power:   var(--amber-500);
  --rack-net:     var(--violet-500);
  --rack-passive: var(--grey-600);
}
/* tree */
.tree-search { display: flex; align-items: center; gap: 8px; margin: 0 4px 8px; padding: 0 10px; height: 32px; border: 1px solid rgb(var(--line-strong)); border-radius: var(--radius-sm); background: rgb(var(--surface)); color: rgb(var(--fg-subtle)); }
.tree-search:focus-within { border-color: rgb(var(--accent)); box-shadow: 0 0 0 3px rgb(var(--accent) / 0.2); }
.tree-search input { border: 0; background: none; outline: none; flex: 1; min-width: 0; font: inherit; font-size: 13px; color: rgb(var(--fg)); }
.tree-search .ico { width: 15px; height: 15px; flex: none; }
.tree { display: flex; flex-direction: column; }
.tree-row { display: flex; align-items: center; padding-left: calc(var(--lvl, 0) * 14px); }
.tree-row.dim { opacity: 0.35; }
.tree-toggle { width: 20px; height: 28px; flex: none; display: inline-flex; align-items: center; justify-content: center; border: 0; background: none; color: rgb(var(--fg-subtle)); cursor: pointer; border-radius: 4px; padding: 0; }
.tree-toggle:hover { background: rgb(var(--surface-2)); color: rgb(var(--fg)); }
.tree-toggle .ico { width: 14px; height: 14px; transition: transform 0.12s ease; }
.tree-toggle.open .ico { transform: rotate(90deg); }
.tree-instant .tree-toggle .ico { transition: none; } /* SP.tree.restore: a page arriving in its saved state does not animate */
.tree-toggle.spacer { pointer-events: none; }
.tree-item { position: relative; flex: 1; min-width: 0; display: flex; align-items: center; gap: 7px; padding: 5px 8px 5px 6px; border-radius: var(--radius-sm); color: rgb(var(--fg-muted)); font-size: 13px; font-weight: 500; white-space: nowrap; }
.tree-item:hover { background: rgb(var(--surface-2)); color: rgb(var(--fg)); text-decoration: none; }
.tree-item.active { background: rgb(var(--accent-soft)); color: rgb(var(--accent-text)); }
.tree-item .ico { width: 16px; height: 16px; flex: none; }
.tree-label { overflow: hidden; text-overflow: ellipsis; }
.tree-dot { position: relative; width: 8px; height: 9px; clip-path: var(--hex); flex: none; background: rgb(var(--grey-400)); margin-left: -2px; }
.tree-dot.ok { background: rgb(var(--accent)); } .tree-dot.warn { background: rgb(var(--amber)); } .tree-dot.bad { background: rgb(var(--grey-400)); } .tree-dot.none { background: rgb(var(--line-strong)); }
.tree-dot.none::before { content: ""; position: absolute; inset: 1.5px; background: rgb(var(--surface)); clip-path: var(--hex); }
.tree-tags { display: inline-flex; gap: 3px; margin-left: 2px; }
.tree-tags i { font-style: normal; font-size: 9px; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; line-height: 14px; padding: 0 4px; border-radius: 3px; background: rgb(var(--surface-3)); color: rgb(var(--fg-subtle)); }
.tree-item.active .tree-tags i { background: rgb(var(--accent) / 0.18); color: rgb(var(--accent-text)); }
.tree-count { margin-left: auto; font-size: 11px; font-weight: 600; color: rgb(var(--fg-subtle)); background: rgb(var(--surface-2)); padding: 0 6px; border-radius: 999px; }
.tree-children { display: flex; flex-direction: column; }
.tree-children[hidden] { display: none !important; }
html[data-sidebar="collapsed"] .tree-search, html[data-sidebar="collapsed"] .tree-children, html[data-sidebar="collapsed"] .tree-toggle, html[data-sidebar="collapsed"] .tree-label, html[data-sidebar="collapsed"] .tree-count, html[data-sidebar="collapsed"] .tree-tags, html[data-sidebar="collapsed"] .tree-dot { display: none; }
html[data-sidebar="collapsed"] .tree-row { padding-left: 0; }
html[data-sidebar="collapsed"] .tree-item { justify-content: center; padding: 9px 12px; }
html[data-sidebar="collapsed"] .side-project .icon-tile { margin: 0 auto; }
@media (max-width: 900px) {
  html[data-sidebar="collapsed"] .tree-search, html[data-sidebar="collapsed"] .tree-children, html[data-sidebar="collapsed"] .tree-toggle, html[data-sidebar="collapsed"] .tree-label, html[data-sidebar="collapsed"] .tree-count, html[data-sidebar="collapsed"] .tree-tags, html[data-sidebar="collapsed"] .tree-dot { display: inline-flex; }
  html[data-sidebar="collapsed"] .tree-search { display: flex; } html[data-sidebar="collapsed"] .tree-children { display: flex; }
  html[data-sidebar="collapsed"] .tree-row { padding-left: calc(var(--lvl, 0) * 14px); }
  html[data-sidebar="collapsed"] .tree-item { justify-content: flex-start; padding: 5px 8px 5px 6px; }
}
/* right-click menu */
.ctx-menu { position: fixed; z-index: 90; min-width: 200px; padding: 6px; background: rgb(var(--surface)); border: 1px solid rgb(var(--line)); border-radius: var(--radius); box-shadow: var(--shadow-menu); }
.ctx-menu .menu-item { width: 100%; }
.ctx-menu .menu-item.danger { color: rgb(var(--red-text)); }
/* section list (machine page) */
.split { display: grid; grid-template-columns: 208px minmax(0, 1fr); gap: 20px; align-items: start; }
.subnav { display: flex; flex-direction: column; gap: 2px; position: sticky; top: calc(var(--topbar-h) + 16px); }
.subnav-item { display: flex; align-items: center; gap: 9px; padding: 7px 10px; border-radius: var(--radius-sm); color: rgb(var(--fg-muted)); font-size: 13.5px; font-weight: 500; }
.subnav-item:hover { background: rgb(var(--surface-2)); color: rgb(var(--fg)); text-decoration: none; }
.subnav-item.active { background: rgb(var(--accent-soft)); color: rgb(var(--accent-text)); }
.subnav-item .ico { width: 17px; height: 17px; flex: none; }
.subnav-item .count { margin-left: auto; font-size: 11px; font-weight: 600; color: rgb(var(--fg-subtle)); background: rgb(var(--surface-2)); padding: 0 6px; border-radius: 999px; }
.subnav-item .status-dot { margin-left: auto; }
@media (max-width: 900px) {
  .split { grid-template-columns: minmax(0, 1fr); }
  .subnav { position: static; flex-direction: row; overflow-x: auto; scrollbar-width: none; gap: 4px; padding-bottom: 2px; border-bottom: 1px solid rgb(var(--line)); margin-bottom: 4px; }
  .subnav::-webkit-scrollbar { display: none; }
  .subnav-item { white-space: nowrap; }
  .subnav-item .count { margin-left: 4px; }
}
/* Proxmox-style status table: label, value, optional meter */
.status-list { display: grid; grid-template-columns: 180px minmax(0, 1fr); font-size: 13px; }
.status-list > dt { color: rgb(var(--fg-muted)); padding: 8px 20px; border-bottom: 1px solid rgb(var(--line)); font-weight: 500; }
.status-list > dd { margin: 0; padding: 8px 20px; border-bottom: 1px solid rgb(var(--line)); display: flex; align-items: center; gap: 10px; min-width: 0; flex-wrap: wrap; }
.status-list > dt:nth-last-child(2), .status-list > dd:last-child { border-bottom: 0; }
.status-list .meter { flex: 1; min-width: 120px; max-width: 280px; }
.status-list .v { font-variant-numeric: tabular-nums; }
@media (max-width: 640px) { .status-list { grid-template-columns: 1fr; } .status-list > dt { border-bottom: 0; padding-bottom: 0; } }
.meter.bad { background: rgb(var(--red-soft)); } .meter.bad > i { background: rgb(var(--red)); }
.meter.lg { height: 10px; }
/* lifecycle */
.steps.steps-5 { grid-template-columns: repeat(5, 1fr); }
.step-num.current { color: rgb(var(--amber-text)); }
.step-num.current::before { background: rgb(var(--amber)); }
.step-num.current::after { background: rgb(var(--amber-soft)); }
/* rack elevation */
.rack-el { background: rgb(var(--rack-chassis)); border: 1px solid rgb(var(--rack-line)); border-radius: 4px; overflow: hidden; }
.rk-row { display: flex; align-items: stretch; border-bottom: 1px solid rgb(var(--rack-line)); box-sizing: border-box; }
.rk-row:last-child { border-bottom: 0; }
.rk-u { width: 26px; flex: none; display: flex; align-items: center; justify-content: flex-end; padding-right: 5px; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 9px; color: rgb(var(--grey-400)); }
.rk-u + .rk-item + .rk-u { justify-content: flex-start; padding: 0 0 0 5px; }
.rk-item { flex: 1; min-width: 0; margin: 1px 2px; border-radius: 2px; display: flex; align-items: center; gap: 6px; padding: 0 7px; color: #fff; font-size: 11px; font-weight: 500; background: rgb(var(--rack-slot)); border-left: 1px solid rgb(var(--rack-line)); border-right: 1px solid rgb(var(--rack-line)); }
.rk-item > span, .rk-item > a { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #fff; }
.rk-item > a:hover { text-decoration: underline; }
/* Selectable elevation (site page): each machine or item opens its dialog. */
.rk-row.is-selectable { cursor: pointer; outline: none; }
.rk-row.is-selectable:hover .rk-item, .rk-row.is-selectable:focus-visible .rk-item { box-shadow: 0 0 0 2px rgb(var(--accent)); }
/* A short facts grid inside a dialog. */
.kv-mini { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 16px; margin: 0; padding: 12px 14px; border: 1px solid rgb(var(--line)); border-radius: var(--radius); background: rgb(var(--surface-2)); }
.kv-mini dt { font-size: 11.5px; color: rgb(var(--fg-subtle)); }
.kv-mini dd { margin: 2px 0 0; font-size: 13px; }
.rk-item em { margin-left: auto; font-style: normal; font-size: 9px; color: rgb(255 255 255 / 0.65); text-transform: uppercase; letter-spacing: 0.04em; flex: none; }
.rk-tags { display: inline-flex; gap: 3px; flex: none; }
.rk-tags i { font-style: normal; font-size: 8px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; line-height: 13px; padding: 0 4px; border-radius: 3px; background: rgb(255 255 255 / 0.18); color: rgb(255 255 255 / 0.9); }
.rk-dot { width: 7px; height: 7px; border-radius: 50%; margin-left: auto; flex: none; background: rgb(var(--grey-400)); }
.rk-row.is-phage .rk-dot { box-shadow: 0 0 0 2px rgb(var(--rack-chassis) / 0.85); }   /* the status dot stays readable on the host's green */
.rk-dot.ok { background: rgb(var(--green-400)); box-shadow: 0 0 0 2px rgb(var(--green-400) / 0.25); } .rk-dot.warn { background: rgb(var(--amber-200)); } .rk-dot.bad { background: rgb(var(--grey-400)); } .rk-dot.none { background: rgb(var(--grey-600)); }
.rk-row.is-server .rk-item { background: rgb(var(--rack-server)); border-color: transparent; }
.rk-row.is-phage .rk-item { background: rgb(var(--rack-phage)); }
.rk-mark { width: 12px; height: 12px; flex: none; object-fit: contain; }
.rack-el.compact .rk-mark { width: 10px; height: 10px; }
.rk-row.is-pdu .rk-item, .rk-row.is-ups .rk-item { background: rgb(var(--rack-power)); border-color: transparent; }
.rk-row.is-patch_panel .rk-item, .rk-row.is-other .rk-item { background: rgb(var(--rack-net)); border-color: transparent; }
.rk-row.is-shelf .rk-item, .rk-row.is-blank .rk-item, .rk-row.is-cable_manager .rk-item { background: rgb(var(--rack-passive)); border-color: transparent; }
.rk-row.is-empty .rk-item { background: rgb(var(--rack-slot)); }
.rk-row.is-empty.drop-ok .rk-item { background: rgb(var(--green-600) / 0.45); outline: 1px dashed rgb(var(--green-400)); }
.rk-row[draggable="true"] { cursor: grab; } .rk-row[draggable="true"]:active { cursor: grabbing; }
.rk-x { display: none; width: 16px; height: 16px; line-height: 14px; border-radius: 50%; border: 0; background: rgb(0 0 0 / 0.35); color: rgb(255 255 255 / 0.7); font-size: 13px; font-weight: 700; cursor: pointer; padding: 0; flex: none; margin-left: 4px; }
.rk-x:hover { background: rgb(var(--red)); color: #fff; }
.rk-row:hover .rk-x { display: inline-flex; align-items: center; justify-content: center; }
.rack-el.compact .rk-u { width: 20px; font-size: 8px; } .rack-el.compact .rk-item { font-size: 10px; padding: 0 5px; }
.rack-legend { display: flex; gap: 12px; flex-wrap: wrap; font-size: 12px; color: rgb(var(--fg-muted)); }
.rack-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; vertical-align: -1px; margin-right: 5px; }
.rack-card .card-head { padding: 10px 14px; }
.rack-card .card-body { padding: 8px; }
.color-swatch { width: 36px; height: 32px; border: 1px solid rgb(var(--line-strong)); border-radius: var(--radius-sm); background: none; padding: 2px; cursor: pointer; }
/* disks */
.disk-dev { font-family: ui-monospace, Menlo, Consolas, monospace; font-weight: 600; }
.disk-kind { font-size: 11px; color: rgb(var(--fg-subtle)); }
.smart-ok { color: rgb(var(--accent-text)); } .smart-warn { color: rgb(var(--amber-text)); }
/* task drawer */
.task-drawer { position: sticky; bottom: 0; z-index: 30; margin-top: auto; background: rgb(var(--surface)); border-top: 1px solid rgb(var(--line)); box-shadow: 0 -4px 16px rgb(var(--overlay) / 0.06); }
.task-bar { width: 100%; display: flex; align-items: center; gap: 10px; padding: 0 20px; height: 38px; border: 0; background: none; font: inherit; font-size: 13px; color: rgb(var(--fg)); cursor: pointer; text-align: left; }
.task-bar:hover { background: rgb(var(--surface-2)); }
.task-bar .ico { width: 16px; height: 16px; color: rgb(var(--fg-subtle)); flex: none; }
.task-bar .chev { transition: transform 0.15s ease; transform: rotate(180deg); }
.task-drawer.open .task-bar .chev { transform: none; }
.task-last { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.task-body { display: none; max-height: 240px; overflow: auto; border-top: 1px solid rgb(var(--line)); }
.task-drawer.open .task-body { display: block; }
.table-tasks td, .table-tasks th { padding: 7px 14px; font-size: 12.5px; }
.table-tasks .nowrap { white-space: nowrap; }
.task-row { cursor: pointer; }
.task-row.open td { background: rgb(var(--surface-2)); }
.task-detail td { background: rgb(var(--surface-2)); padding-top: 4px; padding-bottom: 10px; }
.task-meter { display: block; width: 140px; margin-top: 4px; height: 4px; }
.task-status { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 500; }
.task-status.ok { color: rgb(var(--accent-text)); } .task-status.error { color: rgb(var(--red-text)); } .task-status.running { color: rgb(var(--amber-text)); }
.task-status .spin { width: 10px; height: 10px; border-radius: 50%; border: 2px solid rgb(var(--amber) / 0.3); border-top-color: rgb(var(--amber)); animation: spin 0.9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (max-width: 900px) { .task-bar { padding: 0 12px; } .task-last, .task-bar .ml-auto { display: none; } }
/* overview health panel */
.health { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; }
.health > div { padding: 14px 16px; border-right: 1px solid rgb(var(--line)); }
.health > div:last-child { border-right: 0; }
.health .big { font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
.health .l { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: rgb(var(--fg-subtle)); }
.health .row { display: flex; gap: 12px; flex-wrap: wrap; font-size: 12.5px; color: rgb(var(--fg-muted)); margin-top: 6px; }
@media (max-width: 640px) { .health { grid-template-columns: 1fr; } .health > div { border-right: 0; border-bottom: 1px solid rgb(var(--line)); } .health > div:last-child { border-bottom: 0; } }
.claim-code { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 22px; letter-spacing: 0.2em; text-transform: uppercase; }
.claim-code.input { height: 48px; padding: 0 14px; }
.pending-dot { position: relative; width: 8px; height: 9px; display: inline-block; color: rgb(var(--violet)); animation: pulse 1.8s infinite; }
.pending-dot::before { content: ""; position: absolute; inset: 0; background: currentColor; clip-path: var(--hex); }
.nowrap { white-space: nowrap; }
@media (max-width: 1100px) { .rack-split { grid-template-columns: minmax(0, 1fr) !important; } }
/* expandable rows: one tbody per item so the detail row shares its state */
.table tbody.expandable tr:last-child td { border-bottom: 1px solid rgb(var(--line)); }
.table tbody.expandable:last-of-type tr:last-child td { border-bottom: 0; }
.table tbody.expandable .tree-toggle { height: 24px; }

/* ---------------------------------------------------------------------------
   Create a workload: the full-page wizard (workload-new.html). Steps on the
   left, the step in the middle, the summary and cost on the right. Below
   1200px the summary moves under the step; below 900px the steps become a
   row along the top.
   --------------------------------------------------------------------------- */
.back-link { display: inline-flex; align-items: center; gap: 4px; margin-bottom: 8px; font-size: 13px; font-weight: 500; color: rgb(var(--fg-muted)); }
.back-link:hover { color: rgb(var(--fg)); text-decoration: none; }
.wiz { display: grid; grid-template-columns: 210px minmax(0, 1fr) 300px; gap: 24px; align-items: start; }
.wiz-steps { position: sticky; top: calc(var(--topbar-h) + 24px); }
.wiz-steps ol { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
.wiz-step { display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 10px; border: 0; border-radius: var(--radius); background: none; color: rgb(var(--fg-subtle)); font: inherit; font-size: 13px; text-align: left; cursor: pointer; }
.wiz-step:disabled { cursor: default; }
.wiz-step:not(:disabled):hover { background: rgb(var(--surface-3) / .6); color: rgb(var(--fg)); }
.wiz-step.done { color: rgb(var(--fg)); }
.wiz-step.current { background: rgb(var(--surface)); color: rgb(var(--fg)); font-weight: 600; box-shadow: inset 2px 0 0 rgb(var(--accent)), 0 0 0 1px rgb(var(--line)); }
.wiz-step .step-num { width: 26px; height: 26px; font-size: 11px; }
.wiz-step.current .step-num { color: rgb(var(--on-accent)); }
.wiz-step.current .step-num::before, .wiz-step.current .step-num::after { background: rgb(var(--accent-solid)); }
.wiz-main { min-width: 0; }
.wiz-head { padding: 20px 24px 16px; border-bottom: 1px solid rgb(var(--line)); }
.wiz-kicker { font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: rgb(var(--accent-text)); }
.wiz-title { margin-top: 4px; font-size: 18px; font-weight: 600; letter-spacing: -0.01em; }
.wiz-desc { margin-top: 4px; font-size: 13.5px; color: rgb(var(--fg-muted)); max-width: 70ch; }
.wiz-body { padding: 20px 24px 8px; }
.wiz-foot { display: flex; justify-content: space-between; gap: 12px; padding: 14px 24px; border-top: 1px solid rgb(var(--line)); background: rgb(var(--surface-2)); border-radius: 0 0 var(--radius) var(--radius); }
.wiz-foot > div { display: flex; gap: 8px; }
.wiz-side { position: sticky; top: calc(var(--topbar-h) + 24px); }
.summary { margin: 0; padding: 6px 20px 8px; }
.summary > div { padding: 9px 0; border-bottom: 1px solid rgb(var(--line)); }
.summary > div:last-child { border-bottom: 0; }
.summary dt { font-size: 11.5px; color: rgb(var(--fg-subtle)); }
.summary dd { margin: 2px 0 0; font-size: 13px; line-height: 1.45; }
.wiz-cost { padding: 14px 20px 16px; border-top: 1px solid rgb(var(--line)); background: rgb(var(--surface-2)); border-radius: 0 0 var(--radius) var(--radius); font-size: 13px; }
.wiz-total { font-size: 18px; font-weight: 600; letter-spacing: -0.01em; }
.type-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.type-card { align-items: flex-start; gap: 14px; padding: 16px; min-height: 120px; }
.type-card .choice-body { display: flex; flex-direction: column; gap: 3px; }
/* The create-deployment wizard (pages/deployment-new). */
.icon-tile.emoji { background: rgb(var(--surface-2)); border-color: rgb(var(--line)); font-size: 19px; line-height: 1; }
.dw-apps-help { margin: -2px 0 12px; }
.dw-apps .choice-desc.subtle { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.dw-points { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.dw-points li { display: flex; gap: 10px; align-items: flex-start; }
.dw-points .ico { width: 16px; height: 16px; margin-top: 2px; flex: none; color: rgb(var(--accent-text)); }
.wiz-disclosure { background: none; border: 0; cursor: pointer; text-align: left; }
.wiz-blocks { border-top: 1px solid rgb(var(--line)); }
.wiz-inset { background: rgb(var(--surface-2)); border-radius: var(--radius); }
.review { margin: 0 0 12px; border: 1px solid rgb(var(--line)); border-radius: var(--radius); }
.review > div { display: grid; grid-template-columns: 120px minmax(0, 1fr) auto; gap: 16px; align-items: baseline; padding: 12px 16px; border-bottom: 1px solid rgb(var(--line)); }
.review > div:last-child { border-bottom: 0; }
.review dt { font-size: 12.5px; color: rgb(var(--fg-subtle)); }
.review dd { margin: 0; font-size: 13.5px; }
/* Local agents: what the organisation's own agents cover (free, green) and
   what has to come from the network (billed, amber). */
.local-plan { margin-top: 4px; }
.lp-rows { margin: 0; padding: 2px 20px; list-style: none; }
.lp-rows li { display: grid; grid-template-columns: 9px minmax(0, 1fr) auto; gap: 12px; align-items: start; padding: 10px 0; border-bottom: 1px solid rgb(var(--line)); }
.lp-rows li:last-child { border-bottom: 0; }
.lp-hex { width: 9px; height: 10px; margin-top: 4px; clip-path: var(--hex); background: rgb(var(--accent)); }
.lp-rows li.is-billed .lp-hex { background: rgb(var(--amber)); }
.lp-what b { display: block; font-size: 13px; font-weight: 600; }
.lp-what span { display: block; margin-top: 1px; font-size: 12.5px; line-height: 1.45; color: rgb(var(--fg-muted)); }
.lp-cost { font-size: 13px; font-weight: 600; color: rgb(var(--accent-text)); white-space: nowrap; }
.lp-rows li.is-billed .lp-cost { color: rgb(var(--amber-text)); }
.lp-note { margin: 0; padding: 10px 20px 14px; border-top: 1px solid rgb(var(--line)); font-size: 12.5px; color: rgb(var(--fg-muted)); }
.loc-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 10px; flex-wrap: wrap; }
.loc-head > div { flex: 1 1 320px; }
.loc-search { width: 240px; max-width: 100%; }
.loc-bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-top: 12px; }
.loc-pick { display: flex; align-items: center; gap: 12px; flex: 1 1 320px; min-width: 0; }
.loc-hex { width: 18px; height: 20px; flex: none; clip-path: var(--hex); background: rgb(var(--green-950)); position: relative; }
.loc-hex::after { content: ""; position: absolute; inset: 2.5px; clip-path: var(--hex); background: #fff; }
.loc-sub { display: block; margin-top: 2px; }
.loc-coords { display: grid; grid-template-columns: 140px 140px; gap: 10px; }

/* The location map: the landing page hero's hexagon map, worldwide. Black in
   both themes, land in brand green, the chosen hexagon white. */
.hexmap { position: relative; height: 460px; border-radius: var(--radius); overflow: hidden; background: #0A0E0C; border: 1px solid rgb(var(--green-400) / .22); touch-action: none; user-select: none; outline: none; }
.hexmap:focus-visible { box-shadow: 0 0 0 3px rgb(var(--accent) / .45); }
.hexmap canvas { display: block; width: 100%; height: 100%; cursor: grab; }
.hexmap.is-dragging canvas { cursor: grabbing; }
.hexmap-tools { position: absolute; top: 12px; right: 12px; display: flex; flex-direction: column; border-radius: var(--radius); overflow: hidden; border: 1px solid rgb(var(--green-400) / .3); }
.hexmap-tools button { width: 34px; height: 34px; display: grid; place-items: center; border: 0; border-bottom: 1px solid rgb(var(--green-400) / .3); background: rgb(17 23 20 / .92); color: rgb(var(--green-50)); cursor: pointer; }
.hexmap-tools button:last-child { border-bottom: 0; }
.hexmap-tools button:hover { background: rgb(var(--green-800)); }
.hexmap-tools .ico { width: 16px; height: 16px; }
.hexmap-scale { position: absolute; left: 12px; bottom: 12px; margin: 0; padding: 5px 10px; border-radius: var(--radius-sm); background: rgb(17 23 20 / .92); border: 1px solid rgb(var(--green-400) / .3); color: rgb(var(--green-50)); font-size: 12px; pointer-events: none; }
.hexmap-scale b { color: #fff; font-weight: 600; }
.hexmap-credit { position: absolute; right: 12px; bottom: 10px; margin: 0; font-size: 10.5px; color: rgb(var(--green-50) / .45); pointer-events: none; }

.hexmap .hexmap-overlay { position: absolute; inset: 0; pointer-events: none; }
/* The incident map's key, in the map's own colours on a dark chip. */
.hexmap-legend { position: absolute; left: 12px; top: 12px; display: flex; flex-wrap: wrap; gap: 6px 14px; max-width: calc(100% - 76px); margin: 0; padding: 6px 10px; border-radius: var(--radius-sm); background: rgb(17 23 20 / .92); border: 1px solid rgb(var(--green-400) / .3); color: rgb(var(--green-50)); font-size: 12px; pointer-events: none; }
.hexmap-legend span { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.hexmap-legend i { position: relative; width: 10px; height: 11px; flex: none; clip-path: var(--hex); }
.hexmap-legend i.ring { background: rgb(var(--green-400)); } .hexmap-legend i.ring::after { content: ""; position: absolute; inset: 2px; clip-path: var(--hex); background: rgb(var(--violet-500)); }
.hexmap-legend i.hollow { background: rgb(var(--grey-200)); } .hexmap-legend i.hollow::after { content: ""; position: absolute; inset: 2px; clip-path: var(--hex); background: rgb(10 14 12); }
.hexmap-legend i.trail { width: 14px; height: 3px; clip-path: none; border-radius: 2px; }
.hexmap-legend i.wall { width: 16px; height: 8px; clip-path: none; background: repeating-linear-gradient(90deg, rgb(var(--violet-500)) 0 5px, transparent 5px 6.5px); }

/* DDoS incident (workload and machine pages): a timeline of its stages, each
   in its hero-map colour (red attack, purple perimeter and restore, orange
   migration), then the numbers that matter. */
.inc-steps { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); margin: 0; padding: 0; list-style: none; }
.inc-steps li { position: relative; padding-right: 12px; }
.inc-steps li::before { content: ""; position: absolute; left: 20px; right: 4px; top: 7px; height: 2px; border-radius: 1px; background: rgb(var(--line)); }
.inc-steps li:last-child::before { display: none; }
.inc-steps li.done::before { background: rgb(var(--fg-subtle) / .55); }
.inc-mark { position: relative; z-index: 1; display: block; width: 14px; height: 16px; clip-path: var(--hex); background: rgb(var(--line-strong)); }
.inc-steps li.done .inc-mark, .inc-steps li.current .inc-mark { background: var(--k); }
.inc-steps li.current .inc-mark { animation: pulse 1.8s infinite; }
.inc-steps .k-red { --k: rgb(var(--red)); } .inc-steps .k-violet { --k: rgb(var(--violet-500)); } .inc-steps .k-orange { --k: rgb(var(--amber-400)); } .inc-steps .k-grey { --k: rgb(var(--fg-subtle)); }
.inc-label { display: block; margin-top: 8px; font-size: 13px; font-weight: 500; }
.inc-steps li:not(.done):not(.current) .inc-label { color: rgb(var(--fg-subtle)); }
.inc-time { display: block; margin-top: 1px; font-size: 12px; color: rgb(var(--fg-muted)); font-variant-numeric: tabular-nums; }
.inc-facts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin: 18px 0 0; padding-top: 16px; border-top: 1px solid rgb(var(--line)); }
.inc-facts dt { font-size: 11.5px; color: rgb(var(--fg-subtle)); }
.inc-facts dd { margin: 2px 0 0; font-size: 18px; font-weight: 600; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.inc-facts dd small { font-size: 12.5px; font-weight: 500; color: rgb(var(--fg-muted)); }

/* Deployment page: a component's facts, and a host wearing its chart colour as
   a short line swatch beside its ID, as in the chart's legend. */
.comp-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 16px; margin: 14px 0 0; padding-top: 12px; border-top: 1px solid rgb(var(--line)); }
.comp-facts dt { font-size: 11.5px; color: rgb(var(--fg-subtle)); }
.comp-facts dd { margin: 2px 0 0; font-size: 13px; font-variant-numeric: tabular-nums; }
.comp-facts .span-3 { grid-column: 1 / -1; }
.host-cell { display: inline-flex; align-items: center; gap: 6px; }
.host-cell .sw { width: 14px; height: 2px; border-radius: 1px; flex: none; }
.tabular { font-variant-numeric: tabular-nums; }
@media (max-width: 640px) { .comp-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Networks (networks.html, network.html, app-gateway*.html; planned). A
   member's kind wears a hue from the validated series palette on a small
   hexagon: workloads green, agents violet, resources amber. That is identity,
   not status; health is the heart beside it. */
.kind-hex { display: inline-block; width: 10px; height: 11px; flex: none; clip-path: var(--hex); vertical-align: -1px; }
.kind-workload { background: rgb(var(--series-1)); }
.kind-agent { background: rgb(var(--series-2)); }
.kind-resource { background: rgb(var(--series-3)); }
/* The topology: the Internet, the App Gateway, then the network's boundary
   with its subnets and every member at its address. */
.topo { display: flex; flex-direction: column; }
.topo-edge { align-self: center; display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: rgb(var(--fg-subtle)); }
.topo-edge .ico { width: 14px; height: 14px; }
.topo-link { align-self: center; width: 0; height: 18px; border-left: 2px dashed rgb(var(--line-strong)); }
.topo-gws { align-self: center; display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
.topo-gw { display: flex; flex-direction: column; gap: 6px; min-width: 0; max-width: 100%; padding: 8px 12px; border: 1px solid rgb(var(--line-strong)); border-radius: var(--radius); background: rgb(var(--surface)); font-size: 13px; }
.topo-gw-head { display: inline-flex; align-items: center; gap: 10px; color: inherit; }
.topo-gw-head:hover { text-decoration: none; color: rgb(var(--accent-text)); }
.topo-gw-head .ico { width: 16px; height: 16px; flex: none; color: rgb(var(--accent-text)); }
/* Where the gateway answers, and what each address sends to. */
.topo-routes { list-style: none; margin: 0; padding: 6px 0 0 26px; border-top: 1px solid rgb(var(--line)); display: grid; gap: 2px; font-size: 12px; }
.topo-routes li { display: flex; gap: 6px; min-width: 0; }
.topo-routes a { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topo-routes .subtle { white-space: nowrap; }
.topo-net { position: relative; margin-top: 10px; border: 1.5px solid rgb(var(--accent) / .45); border-radius: 10px; padding: 24px 14px 14px; background: rgb(var(--accent) / .04); }
.topo-net-label { position: absolute; top: -10px; left: 14px; padding: 0 8px; background: rgb(var(--surface)); font-size: 12px; font-weight: 600; white-space: nowrap; }
.topo-net-label .mono { font-weight: 500; color: rgb(var(--fg-muted)); }
.topo-subnets { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; }
.topo-subnet { border: 1px solid rgb(var(--line)); border-radius: var(--radius); background: rgb(var(--surface)); padding: 10px 12px; min-width: 0; }
.topo-subnet-head { display: flex; justify-content: space-between; gap: 8px; margin-bottom: 4px; font-size: 12px; color: rgb(var(--fg-subtle)); }
.topo-subnet-head b { color: rgb(var(--fg)); font-weight: 600; }
.topo-node { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 13px; min-width: 0; color: inherit; }
.topo-node:hover { text-decoration: none; color: rgb(var(--accent-text)); }
.topo-node .ip { margin-left: auto; font-size: 12px; color: rgb(var(--fg-muted)); }
.topo-empty { font-size: 12.5px; color: rgb(var(--fg-subtle)); padding: 4px 0; }
.net-explain { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 32px; align-items: center; }
.kinds { display: inline-flex; gap: 12px; font-size: 13px; font-variant-numeric: tabular-nums; }
.kinds > span { display: inline-flex; align-items: center; gap: 5px; }
.member-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 8px; }
.host-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 9px 12px; border: 1px solid rgb(var(--line)); border-radius: var(--radius); background: rgb(var(--surface-2)); font-size: 13px; }
.route-head, .route-row { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 0.8fr) minmax(0, 1.6fr) 84px 32px; gap: 8px; align-items: center; }
.route-head { font-size: 11.5px; color: rgb(var(--fg-subtle)); margin-bottom: 6px; }
.route-row { margin-bottom: 8px; }
.backends { display: flex; flex-wrap: wrap; gap: 4px 14px; }
.backend { display: inline-flex; align-items: center; gap: 5px; }
.row-muted td { background: rgb(var(--surface-2) / .6); }
.input-group .suffix { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); color: rgb(var(--fg-subtle)); font-size: 12px; pointer-events: none; }
.input-group .input:has(+ .suffix) { padding-left: 10px; padding-right: 46px; }
@media (max-width: 900px) { .net-explain { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 640px) { .route-head { display: none; } .route-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } .route-row > :nth-child(3) { grid-column: 1 / -1; } }
@media (max-width: 760px) {
  .inc-steps { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .inc-steps li { display: grid; grid-template-columns: 14px minmax(0, 1fr); column-gap: 10px; padding: 0; }
  .inc-steps li::before { display: none; }
  .inc-label { margin-top: 0; } .inc-time { grid-column: 2; }
  .inc-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Workload location (workload-detail.html): the hexagon map zoomed in on the
   host, beside the host, the live request rate and the busiest origins. */
.wl-loc { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 16px; align-items: start; }
.hexmap.wl-map { height: 380px; }
.wl-side { display: flex; flex-direction: column; }
.wl-block { padding: 14px 18px; border-bottom: 1px solid rgb(var(--line)); }
.wl-block:last-child { border-bottom: 0; }
.wl-k { margin-bottom: 6px; font-size: 11.5px; color: rgb(var(--fg-subtle)); }
.wl-host { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; color: rgb(var(--fg)); }
a.wl-host:hover { color: rgb(var(--accent-text)); text-decoration: none; }
.wl-hex { position: relative; flex: none; width: 14px; height: 16px; clip-path: var(--hex); background: rgb(var(--green-950)); }
.wl-hex::after { content: ""; position: absolute; inset: 2px; clip-path: var(--hex); background: #fff; }
.wl-hex.is-outline { background: rgb(var(--fg-muted)); } .wl-hex.is-outline::after { background: rgb(var(--surface)); }
.wl-hex.is-grey::after { background: rgb(var(--grey-200)); }
/* Tinted by a gateway instance (--tint): the instance itself ringed in it, what
   it fronts filled with it, not started yet hollow in it. */
.wl-hex.is-ring { background: var(--tint); } .wl-hex.is-ring::after { inset: 3px; background: #fff; box-shadow: none; }
.wl-hex.is-tint::after { background: var(--tint); }
.wl-hex.is-hollow { background: var(--tint); } .wl-hex.is-hollow::after { background: rgb(var(--surface)); }
.wl-list { display: grid; gap: 7px; }
.wl-list > div { display: flex; align-items: center; gap: 8px; font-size: 13px; min-width: 0; }
.wl-list .wl-hex { width: 12px; height: 14px; }
.wl-list .r { margin-left: auto; font-size: 12px; color: rgb(var(--fg-muted)); white-space: nowrap; font-variant-numeric: tabular-nums; }
.wl-sub { margin: 3px 0 0; font-size: 12.5px; color: rgb(var(--fg-muted)); }
.wl-rate { font-size: 28px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.wl-rate small { margin-left: 2px; font-size: 14px; font-weight: 500; color: rgb(var(--fg-muted)); }
.wl-top { display: grid; gap: 9px; margin: 0; padding: 0; list-style: none; }
.wl-top li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px 8px; font-size: 13px; }
.wl-top-n { color: rgb(var(--fg-muted)); font-variant-numeric: tabular-nums; }
.wl-bar { grid-column: 1 / -1; height: 4px; border-radius: 2px; background: rgb(var(--surface-3)); overflow: hidden; }
.wl-bar i { display: block; height: 100%; border-radius: 2px; background: rgb(var(--accent)); transition: width .4s; }
@media (max-width: 1000px) { .wl-loc { grid-template-columns: minmax(0, 1fr); } }
/* The hosting overview's map of sites (js/sites-map.js). */
.hexmap.sites-hexmap { height: 360px; }
/* The machine page's DDoS card: the incident map beside its numbers. */
.ddos-grid { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 16px; align-items: start; }
.hexmap.ddos-map { height: 400px; }
@media (max-width: 1100px) { .ddos-grid { grid-template-columns: minmax(0, 1fr); } }

/* The location step needs the room: its summary moves under the step. */
.wiz.is-wide { grid-template-columns: 210px minmax(0, 1fr); }
.wiz.is-wide .wiz-side { grid-column: 2; position: static; }
@media (max-width: 1200px) {
  .wiz, .wiz.is-wide { grid-template-columns: 190px minmax(0, 1fr); }
  .wiz-side { grid-column: 2; position: static; }
}
@media (max-width: 900px) {
  .wiz, .wiz.is-wide { grid-template-columns: minmax(0, 1fr); }
  .wiz.is-wide .wiz-side { grid-column: auto; }
  .wiz-steps { position: static; overflow-x: auto; }
  .wiz-steps ol { flex-direction: row; gap: 4px; }
  .wiz-step { white-space: nowrap; width: auto; }
  .wiz-side { grid-column: auto; }
  .type-grid { grid-template-columns: 1fr; }
  .hexmap { height: 380px; }
}
@media (max-width: 640px) {
  .wiz-head, .wiz-body { padding-left: 16px; padding-right: 16px; }
  .wiz-foot { padding: 12px 16px; }
  .review > div { grid-template-columns: minmax(0, 1fr) auto; }
  .review dt { grid-column: 1 / -1; }
  .loc-coords { grid-template-columns: 1fr 1fr; width: 100%; }
  .hexmap { height: 340px; }
  .hexmap-scale { bottom: 28px; }   /* the scale wraps here: keep it above the credit */
  .wiz-step-label { display: none; }
  .wiz-step.current .wiz-step-label { display: inline; }
}

/* ---------------------------------------------------------------------------
   Documentation (docs/*.html, js/docs.js): the article, an "On this page" list
   beside it, previous / next under it. Everything inside .doc-prose is styled by
   element, so the pages carry plain HTML.
   --------------------------------------------------------------------------- */
.doc-layout { display: grid; grid-template-columns: minmax(0, 1fr) 200px; gap: 40px; align-items: start; max-width: 1060px; }
.doc-prose { min-width: 0; max-width: 760px; font-size: 14.5px; line-height: 1.7; color: rgb(var(--fg)); }
.doc-prose > :first-child { margin-top: 0; }
.doc-prose h1 { font-size: 28px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; margin: 0 0 6px; }
.doc-prose h2 { font-size: 20px; font-weight: 650; letter-spacing: -0.01em; margin: 40px 0 12px; padding-top: 8px; scroll-margin-top: calc(var(--topbar-h) + 16px); }
.doc-prose h3 { font-size: 16px; font-weight: 600; margin: 28px 0 8px; scroll-margin-top: calc(var(--topbar-h) + 16px); }
.doc-prose h4 { font-size: 14px; font-weight: 600; margin: 20px 0 6px; }
.doc-prose p, .doc-prose ul, .doc-prose ol, .doc-prose table, .doc-prose pre, .doc-prose figure { margin: 0 0 14px; }
.doc-prose ul, .doc-prose ol { padding-left: 22px; }
.doc-prose li { margin: 4px 0; }
.doc-prose li::marker { color: rgb(var(--fg-subtle)); }
.doc-prose a { color: rgb(var(--accent-text)); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: rgb(var(--accent-text) / .35); }
.doc-prose a:hover { text-decoration-color: currentColor; }
.doc-prose strong { font-weight: 600; }
.doc-prose hr { border: 0; border-top: 1px solid rgb(var(--line)); margin: 28px 0; }
.doc-prose :not(pre) > code { font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; font-size: 0.86em; padding: 1px 5px; border-radius: 4px; background: rgb(var(--surface-2)); border: 1px solid rgb(var(--line)); }
.doc-prose pre { background: #0B100D; color: #D2FCDF; border-radius: var(--radius); padding: 14px 16px; overflow-x: auto; font-size: 12.5px; line-height: 1.6; }
.doc-prose pre code { font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; background: none; border: 0; padding: 0; color: inherit; }
.doc-code { position: relative; margin: 0 0 14px; }
.doc-code pre { margin: 0; }
.doc-code[data-lang]::before { content: attr(data-lang); position: absolute; top: 6px; right: 10px; font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; color: rgb(210 252 223 / .45); }
.doc-prose table { width: 100%; border-collapse: collapse; font-size: 13px; display: block; overflow-x: auto; }
.doc-prose th { text-align: left; font-weight: 600; color: rgb(var(--fg-muted)); padding: 7px 12px 7px 0; border-bottom: 1px solid rgb(var(--line-strong)); white-space: nowrap; }
.doc-prose td { padding: 7px 12px 7px 0; border-bottom: 1px solid rgb(var(--line)); vertical-align: top; }
.doc-prose td.mono, .doc-prose td .mono { font-size: 12.5px; }
.doc-lede { font-size: 16.5px; color: rgb(var(--fg-muted)); margin: 0 0 24px !important; line-height: 1.55; }
.doc-eyebrow { font-size: 11px !important; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: rgb(var(--fg-subtle)); margin: 0 0 6px !important; }
.doc-card { border: 1px solid rgb(var(--line)); border-radius: var(--radius); overflow: hidden; margin: 0 0 16px; background: rgb(var(--surface)); }
.doc-card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 16px; background: rgb(var(--surface-2)); border-bottom: 1px solid rgb(var(--line)); }
.doc-card-body { padding: 12px 16px; }
.doc-card-body > :last-child, .doc-box > :last-child, .doc-callout > :last-child { margin-bottom: 0; }
.doc-box { border: 1px solid rgb(var(--line)); border-radius: var(--radius); padding: 14px 16px; margin: 0 0 14px; background: rgb(var(--surface)); }
.doc-callout { border: 1px solid rgb(var(--accent) / .35); background: rgb(var(--accent-soft)); border-radius: var(--radius); padding: 12px 16px; margin: 0 0 16px; font-size: 13.5px; }
.doc-callout.warn { border-color: rgb(var(--amber) / .4); background: rgb(var(--amber-soft)); }
.doc-callout.danger { border-color: rgb(var(--red) / .4); background: rgb(var(--red-soft)); }
.doc-callout.neutral { border-color: rgb(var(--line)); background: rgb(var(--surface-2)); }
.doc-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 0 0 24px; }
.doc-grid > a { display: block; padding: 14px 16px; border: 1px solid rgb(var(--line)); border-radius: var(--radius); background: rgb(var(--surface)); color: inherit; text-decoration: none; }
.doc-grid > a:hover { border-color: rgb(var(--accent)); }
.doc-grid > a > div:first-child { display: flex; align-items: center; gap: 8px; margin-bottom: 2px; }
.doc-grid h3 { margin: 0 !important; font-size: 14.5px; }
.doc-grid p { margin: 4px 0 0 !important; font-size: 13px; color: rgb(var(--fg-muted)); line-height: 1.5; }
.doc-ico { width: 20px; height: 20px; color: rgb(var(--accent-text)); flex: none; }
.doc-anchor { opacity: 0; margin-left: 4px; font-weight: 400; color: rgb(var(--fg-subtle)) !important; text-decoration: none !important; }
.doc-prose h2:hover .doc-anchor, .doc-prose h3:hover .doc-anchor, .doc-anchor:focus-visible { opacity: 1; }
.doc-steps { counter-reset: dstep; list-style: none; padding-left: 0 !important; }
.doc-steps > li { counter-increment: dstep; position: relative; padding-left: 40px; margin: 0 0 18px; }
.doc-steps > li::before { content: counter(dstep); position: absolute; left: 0; top: 0; width: 26px; height: 29px; clip-path: var(--hex); background: rgb(var(--accent-solid)); color: rgb(var(--on-accent)); font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: center; }
.doc-console { background: #0B100D; color: #D2FCDF; border-radius: var(--radius); padding: 16px 20px; font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; font-size: 12.5px; line-height: 1.6; white-space: pre; overflow-x: auto; margin: 0 0 14px; border: 1px solid rgb(79 187 124 / .25); }
.doc-console b { color: #63E69A; font-weight: 600; }
.doc-toc { position: sticky; top: calc(var(--topbar-h) + 24px); font-size: 13px; }
.doc-toc-title { font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: rgb(var(--fg-subtle)); margin-bottom: 8px; }
.doc-toc ul { list-style: none; margin: 0; padding: 0; border-left: 1px solid rgb(var(--line)); }
.doc-toc a { display: block; padding: 4px 0 4px 12px; margin-left: -1px; border-left: 2px solid transparent; color: rgb(var(--fg-muted)); line-height: 1.4; }
.doc-toc a:hover { color: rgb(var(--fg)); text-decoration: none; }
.doc-toc a.active { color: rgb(var(--accent-text)); border-left-color: rgb(var(--accent)); }
.doc-pager { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; max-width: 760px; margin-top: 40px; padding-top: 20px; border-top: 1px solid rgb(var(--line)); }
.doc-pager-link { display: flex; flex-direction: column; gap: 2px; padding: 12px 16px; border: 1px solid rgb(var(--line)); border-radius: var(--radius); background: rgb(var(--surface)); color: inherit; }
.doc-pager-link:hover { border-color: rgb(var(--accent)); text-decoration: none; }
.doc-pager-link span { font-size: 12px; color: rgb(var(--fg-subtle)); }
.doc-pager-link b { font-weight: 600; color: rgb(var(--accent-text)); }
.doc-pager-link.next { text-align: right; }
@media (max-width: 1100px) { .doc-layout { grid-template-columns: minmax(0, 1fr); } .doc-toc { display: none; } }
@media (max-width: 640px) { .doc-grid { grid-template-columns: minmax(0, 1fr); } .doc-prose h1 { font-size: 24px; } }
.doc-tabs { margin: 0 0 18px; }
.doc-tabs .tab { background: none; border-top: 0; border-left: 0; border-right: 0; font: inherit; font-size: 13px; cursor: pointer; }
.doc-figure { margin: 0 0 18px; padding: 16px; background: #fff; border: 1px solid rgb(var(--line)); border-radius: var(--radius); text-align: center; }
.doc-figure img { max-width: 100%; height: auto; }
.doc-figure figcaption { margin-top: 8px; font-size: 12.5px; color: #59605f; }

/* --- Members, IAM and the account pages ------------------------------------
   Page-local styles from dashboard-redesign/{organisation,iam}.html and the
   project header's inline type picker. */
.role-pick, .type-select { width: auto; min-width: 132px; }
.matrix th.role { text-align: center; white-space: nowrap; }
.matrix td.cell { text-align: center; }
.matrix td.cell .hex { display: inline-block; width: 12px; height: 13px; background: rgb(var(--green-500)); clip-path: var(--hex); vertical-align: middle; }
.matrix td.cell .no { color: rgb(var(--grey-300)); }
.matrix tr.group td { background: rgb(var(--grey-50)); font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: rgb(var(--grey-500)); }
html[data-theme="dark"] .matrix tr.group td { background: rgb(var(--grey-800)); color: rgb(var(--grey-400)); }
html[data-theme="dark"] .matrix td.cell .no { color: rgb(var(--grey-700)); }
.perm { display: inline-block; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; padding: 1px 6px; border-radius: 4px; background: rgb(var(--grey-100)); color: rgb(var(--grey-700)); margin: 1px 2px 1px 0; }
html[data-theme="dark"] .perm { background: rgb(var(--grey-800)); color: rgb(var(--grey-300)); }
.role-card .card-head { flex-wrap: nowrap; align-items: flex-start; border-bottom: 0; height: 100%; box-sizing: border-box; }
.role-card .card-head > div:first-child { min-width: 0; }
.role-card .count { font-size: 22px; font-weight: 600; line-height: 1.1; flex-shrink: 0; margin-left: 12px; }
.act { display: flex; gap: 12px; align-items: baseline; padding: 10px 16px; border-top: 1px solid rgb(var(--line)); font-size: 13px; flex-wrap: wrap; }
.act:first-child { border-top: 0; }
.act .when { color: rgb(var(--grey-500)); white-space: nowrap; min-width: 86px; font-size: 12px; }
.act .who { font-weight: 500; }
.act .what { color: rgb(var(--grey-600)); }
.act .what > span { margin-right: 8px; }
html[data-theme="dark"] .act .what { color: rgb(var(--grey-400)); }
.profile-grid { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); align-items: start; }
@media (max-width: 900px) { .profile-grid { grid-template-columns: 1fr; } }
.centered { text-align: center; }

/* --- public host profile (hosting/profile-public.html) ---------------------- */
.pub-top { height: 56px; display: flex; align-items: center; gap: 12px; padding: 0 24px; background: rgb(var(--topbar-bg)); border-bottom: 1px solid rgb(var(--line)); }
.pub-banner { position: relative; height: 240px; background: linear-gradient(120deg, rgb(var(--green-800)), rgb(var(--green-950)) 60%, rgb(var(--violet-800))); overflow: hidden; }
.pub-banner img.bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.pub-banner::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgb(0 0 0 / 0.55), rgb(0 0 0 / 0.1) 55%, rgb(0 0 0 / 0.05)); }
.pub-id { position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; }
.pub-wrap { max-width: 1040px; margin: 0 auto; padding: 0 24px; }
.pub-logo { width: 96px; height: 96px; border-radius: 14px; background: #fff; box-shadow: 0 8px 24px rgb(0 0 0 / 0.3); display: flex; align-items: center; justify-content: center; font-size: 36px; font-weight: 700; color: rgb(var(--green-600)); flex: none; overflow: hidden; }
.pub-logo img { width: 100%; height: 100%; object-fit: cover; }
.pub-name { color: #fff; font-size: 28px; font-weight: 700; text-shadow: 0 2px 4px rgb(0 0 0 / 0.6); }
.pub-tag { color: rgb(255 255 255 / 0.9); text-shadow: 0 1px 3px rgb(0 0 0 / 0.6); }
.cc-badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 12px; border-radius: 999px; font-size: 12px; font-weight: 600; background: linear-gradient(90deg, #e2e8f0, #fff); color: #1e293b; box-shadow: 0 2px 8px rgb(0 0 0 / 0.3); }
.cc-badge.gold { background: #eab308; color: #422006; }
.cc-badge.bronze { background: rgb(var(--amber-500)); color: #fff; }
.cap { list-style: none; padding: 0; margin: 0; }
.cap li { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; padding: 7px 0; border-bottom: 1px solid rgb(var(--line)); } .cap li:last-child { border-bottom: 0; }
.cap .yes { color: rgb(var(--accent-text)); font-weight: 500; } .cap .no { color: rgb(var(--fg-subtle)); }
.pub-gallery img { width: 100%; height: 140px; object-fit: cover; border-radius: var(--radius); }
@media (max-width: 760px) { .pub-two { grid-template-columns: 1fr !important; } }
