/* Nocturne, light — the tokens the design file carries, extracted once so
   pages stop repeating inline hex values and can be converted one at a time.
   Every colour, radius and font here comes from the design; nothing is
   invented to fill a gap. */

:root {
  --bg: #f3f5fe;
  --surface: #fafbff;
  --border: #cfd3e5;
  --border-soft: #e6e9f5;
  --text: #292b31;
  --muted: #595d6c;
  --faint: #8b8fa0;

  --accent: #9184d9;
  --accent-strong: #5d5294;
  --accent-soft: #b5abfc;
  --accent-tint: #f5f4ff;
  --accent-fill: #e7e5fe;
  --accent-border: #d2cefd;

  --warn-text: #8a6a2f;
  --warn-fill: #fbf4e6;
  --warn-border: #ecdcb8;
  --ok-text: #3f7d58;
  --ok-fill: #eaf5ee;
  --ok-border: #c6e2d1;
  --bad-text: #9b3d3d;
  --bad-fill: #fbeded;
  --bad-border: #edc9c9;

  --radius: 8px;
  --radius-sm: 7px;
  /* Density 0.70x, as the design system specifies. */
  --space-1: 5.6px;
  --space-2: 8.4px;
  --space-3: 11.2px;
  --space-4: 16.8px;
  --space-5: 22.4px;
}

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Vazirmatn", system-ui, sans-serif;
  font-size: 15px;
  line-height: 1.6;
}
h1, h2, h3, h4, h5, h6 { font-weight: 600; letter-spacing: 0; margin: 0; }
a { color: var(--accent-strong); text-decoration: none; }
a:hover { color: #423a6a; text-decoration: underline; text-underline-offset: 3px; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
::selection { background: var(--accent-fill); }

.mono { font-family: "JetBrains Mono", ui-monospace, monospace; }
.muted { color: var(--muted); }
.faint { color: var(--faint); }

.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.card-head { padding: 13px 16px; border-bottom: 1px solid var(--border); }
.card-body { padding: 14px 16px; }

/* Chips carry state. Outlined, tinted from the ramp — never a saturated
   flood, per the design system's own rule. */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; border-radius: 999px; padding: 2px 10px;
  border: 1px solid transparent; white-space: nowrap;
}
.chip-accent { color: var(--accent-strong); background: var(--accent-tint); border-color: var(--accent-border); }
.chip-ok     { color: var(--ok-text);   background: var(--ok-fill);   border-color: var(--ok-border); }
.chip-warn   { color: var(--warn-text); background: var(--warn-fill); border-color: var(--warn-border); }
.chip-bad    { color: var(--bad-text);  background: var(--bad-fill);  border-color: var(--bad-border); }
.chip-plain  { color: var(--muted); border-color: var(--border); }

/* Primary actions are an accent outline, not a fill. */
.btn {
  font-family: inherit; font-size: 12.5px; border-radius: var(--radius-sm);
  padding: 5px 12px; cursor: pointer; background: transparent;
  border: 1px solid var(--border); color: var(--text);
}
.btn:hover { background: var(--accent-tint); border-color: var(--accent-border); color: var(--accent-strong); }
.btn:active { background: var(--accent-fill); }
.btn:disabled { opacity: .45; cursor: default; }
.btn-primary { border-color: var(--accent-soft); color: var(--accent-strong); }
.btn-primary:hover { background: var(--accent-fill); }

/* space-between was harmless while the link held a single span; with an icon
   beside the label it would push the two to opposite edges. A gap keeps them
   together and reads the same in both directions. */
.navlink { display: flex; align-items: center; gap: 9px; border-radius: var(--radius-sm); padding: 5px 9px; font-size: 13px; color: var(--muted); }
/* Stroke follows the link's own colour, so hover and the active state need no
   icon-specific rules. flex-shrink:0 stops a long label squashing it. */
.navicon { flex: 0 0 16px; width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; opacity: .85; }
.navlink.on .navicon { opacity: 1; }
.navlink:hover { background: var(--accent-tint); color: var(--accent-strong); text-decoration: none; }
.navlink.on { background: var(--accent-fill); color: var(--accent-strong); font-weight: 600; }
.navgroup { font-size: 10.5px; color: var(--faint); padding: 0 9px; margin: 10px 0 4px; }

.panel-table { width: 100%; border-collapse: collapse; }
.panel-table th { font-size: 11px; color: var(--muted); font-weight: 500; text-align: start; padding: 8px 10px; border-bottom: 1px solid var(--border); }
.panel-table td { padding: 9px 10px; border-bottom: 1px solid var(--border-soft); vertical-align: top; }
.panel-table tr:last-child td { border-bottom: 0; }

.bar { height: 6px; border-radius: 999px; background: #e6e9f5; overflow: hidden; }
.bar > span { display: block; height: 100%; border-radius: 999px; background: var(--accent); }

[x-cloak] { display: none !important; }

/* Alpine's :style, given a string, REPLACES the element's style attribute —
   a static style="" beside one is silently destroyed. That is how the
   cluster map's pod blocks ended up in the DOM with height:0. Anything
   static an element with :style needs therefore lives here, in a class. */
.swatch   { width: 9px; height: 9px; border-radius: 3px; display: inline-block; flex: none; }
.dot      { width: 9px; height: 9px; border-radius: 999px; display: inline-block; flex: none; }
.bar > i  { position: absolute; top: 0; bottom: 0; width: 2px; background: #2c2f3a99; }
.podblock { height: 26px; border-radius: 4px; border: 1px solid #ffffff80; cursor: pointer; }
.clickable { cursor: pointer; }

/* Segmented control: buttons that read as one control, divided by a rule. */
.seg { border: 0; border-radius: 0; }
.seg + .seg { border-inline-start: 1px solid var(--border); }
.seg.on { background: var(--accent-fill); color: var(--accent-strong); font-weight: 600; }

/* A cell whose value is itself the warning (restart counts, missing SSH). */
.warn-cell { color: var(--warn-text); font-weight: 600; }

/* x-show hides with style.display:none and shows again by REMOVING the
   display property — which also removes an inline display:grid/flex the
   element depended on, leaving it a plain block. The overview's three
   platform-state cards stacked full-width for exactly this reason. Layout
   for an x-show element therefore belongs in a class, where x-show cannot
   reach it. */
.row    { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.col    { display: flex; flex-direction: column; gap: 10px; }
.cards  { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 14px; }
.fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 11px; }

/* ---- shell layout -------------------------------------------------
   Kept here rather than inline in panel-shell.js so it can respond to
   viewport width at all: an inline style has nowhere to put a media
   query. */
.panel-layout { display: flex; min-height: 100vh; }
.panel-aside {
  flex: 0 0 244px;
  background: var(--surface);
  border-inline-end: 1px solid var(--border);
  padding: 17px 11px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  position: sticky;
  top: 0;
  height: 100vh;
}
.panel-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.panel-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 11px;
  padding: 14px 22px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.panel-content { padding: 22px; }
.panel-burger { display: none; }
.panel-scrim { display: none; }

/* Below this width the 244px sidebar is most of a phone screen, so it
   becomes a drawer: off-canvas by default, over the content when opened,
   and the content gets the full width back. */
@media (max-width: 860px) {
  .panel-aside {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    z-index: 30;
    width: 244px;
    flex-basis: auto;
    transform: translateX(-110%);
    transition: transform .18s ease-out;
    box-shadow: 0 0 24px #2c2f3a26;
  }
  html[dir="rtl"] .panel-aside { transform: translateX(110%); }
  .panel-aside.open,
  html[dir="rtl"] .panel-aside.open { transform: translateX(0); }

  .panel-burger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px; height: 32px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    cursor: pointer;
    padding: 0;
    flex: none;
  }
  .panel-scrim.open {
    display: block;
    position: fixed;
    inset: 0;
    background: #2c2f3a55;
    z-index: 25;
  }
  .panel-header { padding: 11px 14px; gap: 9px; }
  .panel-content { padding: 14px; gap: 13px; }
}

@media (max-width: 520px) {
  /* At phone width the header's title and controls need their own rows
     rather than competing for one. */
  .panel-header h4 { font-size: 16px; }
  .panel-content { padding: 11px; }
  .card-head, .card-body { padding: 11px 13px; }
}

/* Nothing in the panel may push the page sideways; wide tables scroll
   inside their own container instead. */
html, body { max-width: 100%; overflow-x: hidden; }
