/* Wyrd admin — Web of Wyrd palette (brandbook v0.3, dark-only) */
:root {
  /* Raw brand palette — mirrors plans/rebranding/styles/tokens.css */
  --void:        #080D14;
  --carbon:      #0E1826;
  --graphite:    #132234;
  --hairline:    #22384F;
  --deep-blue:   #10263F;
  --blue:        #4A9FDA;
  --blue-dk:     #2E6FA8;
  --mark-web:    #3A7EBB;   /* mark's thread-net; heading underlines */
  --mark-node:   #A5D6F5;   /* mark's nodes and core */
  --deep-green:  #0F2B1C;
  --green:       #86B86A;
  --green-dk:    #6E9E58;
  --alarm:       #D64152;   /* red is alarm-only — error, failure, lost device */
  --alarm-dk:    #A93544;
  --alarm-lt:    #EE7A86;
  --fog:         #D4DADE;
  --ash:         #93A0AC;
  --steel:       #5F6E7C;
  --iron:        #33424E;

  /* Semantic tokens mapped onto the brand palette */
  --bg:           var(--void);
  --bg-elev:      #0B121C;
  --panel:        var(--carbon);
  --panel-2:      var(--graphite);
  --hover:        #1B2E44;
  --border:       var(--hairline);
  --border-soft:  var(--graphite);
  --text:         var(--fog);
  --text-muted:   var(--ash);
  --text-dim:     var(--steel);

  --accent:       var(--blue);
  --accent-soft:  rgba(74, 159, 218, 0.14);
  --accent-fg:    var(--void);

  --ok:           var(--green);
  --warn:         #f4c47a;   /* outside the brandbook; kept as its own UI role */
  --danger:       var(--alarm);
  --info:         var(--blue);

  --radius-sm: 4px;
  --radius:    6px;
  --radius-lg: 10px;

  --shadow-sm: 0 1px 0 rgba(8, 13, 20, 0.45);
  --shadow:    0 4px 16px rgba(8, 13, 20, 0.55);
  --shadow-lg: 0 12px 40px rgba(8, 13, 20, 0.75);

  --sidebar-w: 232px;
  --sidebar-w-rail: 60px;
  --topbar-h: 52px;

  --font-sans:    "Manrope", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-display: "Oswald", "Manrope", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace;

  --row-h: 40px;
  --pad-row: 10px 14px;
}

[data-density="compact"] { --row-h: 32px; --pad-row: 6px 10px; }
[data-density="comfortable"] { --row-h: 48px; --pad-row: 14px 16px; }

* { box-sizing: border-box; }
html, body, #app { margin: 0; padding: 0; min-height: 100vh; height: 100%; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--accent-soft); color: var(--text); }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 8px; border: 2px solid var(--bg); }
::-webkit-scrollbar-track { background: transparent; }

a { color: inherit; text-decoration: none; }

/* Layout */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  grid-template-rows: var(--topbar-h) 1fr;
  grid-template-areas:
    "sidebar topbar"
    "sidebar main";
  height: 100vh;
}
.app[data-nav="rail"]    { grid-template-columns: var(--sidebar-w-rail) 1fr; }
.app[data-nav="topbar"]  {
  grid-template-columns: 1fr;
  grid-template-areas: "topbar" "main";
}

.sidebar {
  grid-area: sidebar;
  background: var(--bg-elev);
  border-right: 1px solid var(--border-soft);
  display: flex; flex-direction: column;
  min-width: 0;
}
.app[data-nav="topbar"] .sidebar { display: none; }

.sidebar-brand {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px; height: var(--topbar-h);
  border-bottom: 1px solid var(--border-soft);
  font-weight: 600; letter-spacing: 0.2px;
}
.sidebar-brand .logo {
  width: 22px; height: 22px;
  display: grid; place-items: center;
  flex: 0 0 22px;
}
.sidebar-brand .logo svg { width: 100%; height: 100%; display: block; }
.sidebar-brand .name { font-size: 15px; font-family: var(--font-display); letter-spacing: 0.01em; }
.app[data-nav="rail"] .sidebar-brand .name { display: none; }

.sidebar-section {
  padding: 14px 12px 6px;
  font-size: 10px; font-weight: 600; letter-spacing: 0.6px;
  color: var(--text-dim); text-transform: uppercase;
}
.app[data-nav="rail"] .sidebar-section { padding: 14px 0 6px; text-align: center; opacity: 0.6; }

.nav-list { display: flex; flex-direction: column; gap: 1px; padding: 0 8px; }
.app[data-nav="rail"] .nav-list { padding: 0 6px; }

.nav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: var(--radius);
  color: var(--text-muted); cursor: pointer;
  font-size: 13.5px; font-weight: 500;
  position: relative;
  transition: background 0.12s, color 0.12s;
}
.nav-item:hover { background: var(--hover); color: var(--text); }
.nav-item.active { background: var(--accent-soft); color: var(--text); }
.nav-item.active::before {
  content: ""; position: absolute; left: -8px; top: 6px; bottom: 6px; width: 2px;
  background: var(--accent); border-radius: 2px;
}
.nav-item .ico { width: 16px; height: 16px; flex: 0 0 16px; opacity: 0.85; }
.nav-item .label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-item .badge-count {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--text-dim);
  padding: 1px 6px; border: 1px solid var(--border-soft); border-radius: 4px;
  background: var(--panel);
}
.nav-item.active .badge-count { color: var(--text); border-color: var(--border); }
/* "There is something here", where a number would be meaningless — an update
   is available, not four of them. Unlike the counts it survives rail mode,
   which is exactly where the page name is invisible. */
.nav-item .badge-dot {
  width: 6px; height: 6px; flex: 0 0 6px; border-radius: 50%;
  background: var(--warn); box-shadow: 0 0 0 3px oklch(from var(--warn) l c h / 0.15);
}
.app[data-nav="rail"] .nav-item { justify-content: center; padding: 9px 6px; }
.app[data-nav="rail"] .nav-item .label,
.app[data-nav="rail"] .nav-item .badge-count { display: none; }

/* Licensee + device-count meter, pinned just above the account footer. It
   takes over the footer's `margin-top: auto` so the pair sits at the bottom as
   one block; without the tag the footer keeps its own auto margin. The
   handover is scoped away from rail mode: the tag is `display: none` there,
   but a sibling selector still matches it, which would unpin the footer. */
.license-tag {
  margin-top: auto; padding: 10px 12px;
  border-top: 1px solid var(--border-soft);
  min-width: 0;
  cursor: pointer; transition: background 0.12s;
}
.license-tag:hover { background: var(--panel-2); }
.license-tag:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.app:not([data-nav="rail"]) .license-tag + .sidebar-footer { margin-top: 0; }
.license-tag .lt-name {
  font-size: 11.5px; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.license-tag .lt-count {
  font-family: var(--font-mono); font-size: 10px; color: var(--text-dim); margin-top: 2px;
}
/* Sidebar half of the "test build" mark; see .lic-testbuild. Hidden with the
   rest of the tag in rail mode, where the license line is collapsed away. */
.license-tag .lt-testbuild {
  display: inline-block; margin-bottom: 4px; padding: 1px 5px;
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  border: 1px solid oklch(from var(--warn) l c h / 0.35); border-radius: 4px;
  background: oklch(from var(--warn) l c h / 0.08);
  color: var(--warn);
}
.app[data-nav="rail"] .license-tag { display: none; }

/* Licensing state banner, first block on every page. Yellow inside the 30-day
   warning window, red once expired and the server has stopped managing devices. */
.license-banner,
.updates-banner {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 14px; margin: 0 0 18px;
  border: 1px solid; border-radius: var(--radius);
}
.license-banner .lb-title,
.updates-banner .lb-title { font-size: 13px; font-weight: 500; }
.license-banner .lb-body,
.updates-banner .lb-body { font-size: 12px; margin-top: 2px; opacity: 0.85; }
.license-banner svg,
.updates-banner svg { flex: 0 0 auto; margin-top: 1px; }
.license-banner.warn,
.updates-banner.warn {
  color: var(--warn);
  border-color: oklch(from var(--warn) l c h / 0.35);
  background: oklch(from var(--warn) l c h / 0.08);
}
.license-banner.danger {
  color: var(--danger);
  border-color: oklch(from var(--danger) l c h / 0.35);
  background: oklch(from var(--danger) l c h / 0.08);
}

/* License page (#/license) */
.lic-head { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.lic-customer {
  font-size: 16px; font-weight: 600; letter-spacing: -0.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The client id is a 36-character UUID and the other four facts are short, so
   equal columns wrapped the identifier mid-string while the rest sat half
   empty. Give the first column the extra width and take it from the others.
   minmax(0, …) so a long value shrinks the track instead of blowing past it. */
.lic-facts { display: grid; grid-template-columns: minmax(0, 1.9fr) repeat(4, minmax(0, 1fr)); gap: 16px 24px; }
@media (max-width: 900px) { .lic-facts { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); } }
.lic-fact .k {
  font-size: 11px; color: var(--text-dim);
  text-transform: uppercase; letter-spacing: 0.06em;
}
.lic-fact .v { font-size: 14px; margin-top: 3px; }
/* The client id is meant to be copied into a support ticket, so it's shown
   whole — wrapping rather than truncating on a narrow column. */
.lic-fact .v.mono {
  font-family: var(--font-mono); font-size: 12.5px;
  user-select: all; word-break: break-all;
}
.lic-add-title { font-size: 13px; font-weight: 600; }

/* "Test build" mark — shown only where the binary trusts the development
   signing key, so every license fact beside it is meaningless. It is a
   positive marker on the untrusted build rather than a "production" badge on
   the trusted one: a badge someone forgot to remove looks exactly like a
   production build, this one cannot be forgotten into silence. Yellow, not
   red: red is reserved for alarm states. */
.lic-testbuild {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 14px; margin: 0 0 18px;
  border: 1px solid oklch(from var(--warn) l c h / 0.35); border-radius: var(--radius);
  background: oklch(from var(--warn) l c h / 0.08);
  color: var(--warn);
}
.lic-testbuild svg { flex: 0 0 auto; margin-top: 1px; }
.lic-testbuild .tb-title { font-size: 13px; font-weight: 500; }
.lic-testbuild .tb-body { font-size: 12px; margin-top: 2px; opacity: 0.85; }

.sidebar-footer {
  margin-top: auto; padding: 12px;
  border-top: 1px solid var(--border-soft);
  display: flex; align-items: center; gap: 10px;
}
.avatar {
  width: 28px; height: 28px; border-radius: 50%;
  background: linear-gradient(135deg, var(--blue-dk), var(--blue));
  display: grid; place-items: center; color: white; font-size: 11px; font-weight: 600;
  flex: 0 0 28px;
}
.user-meta { min-width: 0; }
.user-meta .un { font-size: 13px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-meta .role { font-family: var(--font-mono); font-size: 10px; color: var(--text-dim); }
.icon-btn {
  margin-left: auto; background: none; border: 1px solid transparent;
  width: 28px; height: 28px; display: grid; place-items: center;
  color: var(--text-muted); border-radius: var(--radius); cursor: pointer;
}
.icon-btn:hover { background: var(--hover); color: var(--text); }
.app[data-nav="rail"] .sidebar-footer { padding: 10px 6px; flex-direction: column; }
.app[data-nav="rail"] .user-meta { display: none; }
.app[data-nav="rail"] .icon-btn { margin-left: 0; }

/* Topbar */
.topbar {
  grid-area: topbar;
  display: flex; align-items: center; gap: 12px;
  padding: 0 18px;
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border-soft);
  height: var(--topbar-h);
  position: sticky; top: 0; z-index: 20;
}
.crumbs { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-muted); min-width: 0; }
.crumbs .sep { opacity: 0.4; display: inline-flex; }
.crumbs .crumb-link { cursor: pointer; }
.crumbs .crumb-link:hover { color: var(--text); }
.crumbs .crumb-current { color: var(--text); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.search {
  flex: 1; max-width: 420px; margin-left: 16px;
  display: flex; align-items: center; gap: 8px;
  background: var(--panel); border: 1px solid var(--border-soft);
  border-radius: var(--radius); padding: 6px 10px;
  color: var(--text-muted);
  cursor: pointer; transition: border-color 0.12s, background 0.12s;
}
.search:hover { border-color: var(--border); background: var(--panel-2); }
.search .placeholder { flex: 1; font-size: 13px; }
.kbd {
  font-family: var(--font-mono); font-size: 11px;
  padding: 1px 6px; border: 1px solid var(--border);
  border-radius: 4px; background: var(--bg);
  color: var(--text-dim);
}
.topbar-tools { margin-left: auto; display: flex; align-items: center; gap: 6px; }

/* Connection indicator: a small dot in the topbar tools. Green when the admin
   event WebSocket is live; amber + pulsing while it's down/reconnecting, a hint
   that views may be stale until pushes resume. */
.conn-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; margin-right: 2px; }
.conn-dot.live { background: var(--ok); box-shadow: 0 0 0 3px oklch(from var(--ok) l c h / 0.18); }
.conn-dot.reconnecting {
  background: var(--warn); box-shadow: 0 0 0 3px oklch(from var(--warn) l c h / 0.18);
  animation: conn-pulse 1.2s ease-in-out infinite;
}
@keyframes conn-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* Main */
.main { grid-area: main; overflow: auto; background: var(--bg); }
.page { max-width: 1320px; margin: 0 auto; padding: 22px 28px 60px; }

.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  margin: 4px 0 18px; gap: 16px; flex-wrap: wrap;
}
.page-head h1 { font-size: 22px; font-weight: 600; margin: 0; letter-spacing: -0.01em; font-family: var(--font-display); }
.page-head .subtitle { color: var(--text-muted); font-size: 13px; margin-top: 4px; }
.page-actions { display: flex; gap: 8px; align-items: center; }

/* Cards */
.card {
  background: var(--panel);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.card-pad { padding: 18px 20px; }
.card-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--border-soft);
}
.card-head h3 { margin: 0; font-size: 13px; font-weight: 600; letter-spacing: 0.01em; }
.card-head .meta { color: var(--text-dim); font-size: 12px; margin-left: auto; }

/* Buttons */
.btn {
  --btn-cut: 10px;
  --btn-body: var(--panel-2);
  --btn-edge: var(--border);
  position: relative;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px;
  background: var(--btn-edge);
  color: var(--text);
  border: 0;
  isolation: isolate;
  clip-path: polygon(
    var(--btn-cut) 0, 100% 0,
    100% calc(100% - var(--btn-cut)), calc(100% - var(--btn-cut)) 100%,
    0 100%, 0 var(--btn-cut)
  );
  font: inherit; font-size: 13px; font-weight: 500;
  cursor: pointer; transition: background 0.12s, color 0.12s;
  white-space: nowrap;
}
.btn::before {
  content: ""; position: absolute; inset: 1px;
  background: var(--btn-body);
  clip-path: polygon(
    var(--btn-cut) 0, 100% 0,
    100% calc(100% - var(--btn-cut)), calc(100% - var(--btn-cut)) 100%,
    0 100%, 0 var(--btn-cut)
  );
  z-index: -1;
  transition: background 0.12s;
}
.btn > * { position: relative; }
.btn:hover { --btn-body: var(--hover); }
.btn.primary {
  --btn-body: var(--accent);
  --btn-edge: var(--border);
  color: var(--accent-fg);
  font-weight: 600;
}
.btn.primary:hover { filter: brightness(1.07); }
.btn.ghost {
  --btn-body: transparent;
  --btn-edge: transparent;
  color: var(--text-muted);
}
.btn.ghost:hover { --btn-body: var(--hover); color: var(--text); }
.btn.danger {
  color: var(--danger);
  --btn-edge: color-mix(in srgb, var(--danger) 65%, white);
}
.btn.danger:hover { --btn-body: oklch(from var(--danger) l c h / 0.10); }
.btn.sm { padding: 4px 9px; font-size: 12px; --btn-cut: 7px; }
.btn.xs { padding: 2px 8px; font-size: 11.5px; --btn-cut: 5px; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
/* A link to a host of ours is offered twice: the labelled button carries the
   clearnet address, the narrow one beside it the onion mirror.

   The pair takes the outline of one button rather than of two. Each .btn cuts
   its top-left and bottom-right corner, so a pair left alone notches itself
   twice in the middle and reads as two unrelated controls; dropping the two
   inner cuts leaves the cut top-left and cut bottom-right of a single button,
   which is the shape the brand actually uses. The clip has to be repeated on
   ::before, the inset layer that paints the body inside the 1px edge.
   align-items: stretch keeps the icon-only half the height of the labelled
   one, whose text line is the taller of the two. */
.link-pair { display: inline-flex; gap: 2px; align-items: stretch; }
/* "TOR" is a destination, not a second action, so it is set as a small-caps
   tag — the same 11.5px/+letterspacing the table headers use — rather than at
   the labelled button's own weight, where it would compete with it. */
.link-pair > .btn.onion {
  padding-left: 9px; padding-right: 9px;
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.06em;
}
.link-pair > .btn:first-child,
.link-pair > .btn:first-child::before {
  clip-path: polygon(var(--btn-cut) 0, 100% 0, 100% 100%, 0 100%, 0 var(--btn-cut));
}
.link-pair > .btn.onion,
.link-pair > .btn.onion::before {
  clip-path: polygon(
    0 0, 100% 0,
    100% calc(100% - var(--btn-cut)), calc(100% - var(--btn-cut)) 100%,
    0 100%
  );
}

.btn-icon {
  width: 28px; padding: 0; justify-content: center; height: 28px;
  --btn-cut: 0; clip-path: none; border-radius: var(--radius);
  background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--border);
}
.btn-icon::before { display: none; }
.btn .ico { width: 14px; height: 14px; }

/* Tables */
.tbl-wrap {
  background: var(--panel);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  overflow: hidden;
}
table.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl th {
  text-align: left; font-weight: 500; font-size: 11.5px;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-dim);
  padding: 9px 14px;
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border-soft);
}
.tbl td {
  padding: var(--pad-row);
  border-bottom: 1px solid var(--border-soft);
  vertical-align: middle;
  color: var(--text);
}
.tbl tr:last-child td { border-bottom: none; }
.tbl tbody tr { transition: background 0.08s; }
.tbl tbody tr.clickable { cursor: pointer; }
.tbl tbody tr.clickable:hover td { background: var(--hover); }
.tbl tbody tr.selected td { background: var(--accent-soft); }
.tbl td.actions { text-align: right; white-space: nowrap; padding-right: 8px; }
.tbl td.num { font-variant-numeric: tabular-nums; font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); }

.row-name { display: flex; align-items: center; gap: 10px; }
.row-name .device-ico {
  width: 26px; height: 26px; border-radius: 6px;
  background: var(--panel-2); border: 1px solid var(--border-soft);
  display: grid; place-items: center; color: var(--text-muted);
}
.row-name .name { font-weight: 500; }
.row-name .sub { font-family: var(--font-mono); font-size: 11px; color: var(--text-dim); }

/* Status pill */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 500;
  padding: 2px 8px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--border-soft);
  color: var(--text-muted);
}
.pill .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--text-dim); }
.pill.ok { color: var(--ok); border-color: oklch(from var(--ok) l c h / 0.3); background: oklch(from var(--ok) l c h / 0.08); }
.pill.ok .dot { background: var(--ok); box-shadow: 0 0 0 3px oklch(from var(--ok) l c h / 0.18); }
.pill.warn { color: var(--warn); border-color: oklch(from var(--warn) l c h / 0.35); background: oklch(from var(--warn) l c h / 0.08); }
.pill.warn .dot { background: var(--warn); }
.pill.danger { color: var(--danger); border-color: oklch(from var(--danger) l c h / 0.35); background: oklch(from var(--danger) l c h / 0.08); }
.pill.danger .dot { background: var(--danger); }
.pill.info { color: var(--info); border-color: oklch(from var(--info) l c h / 0.35); background: oklch(from var(--info) l c h / 0.08); }
.pill.info .dot { background: var(--info); }
.pill.muted .dot { background: var(--text-dim); }
/* Pills grouped in a table cell (status + warning + CVE badges): flex so mixed
   dot-led and icon-led pills align on their vertical centers — inline-flex pills
   otherwise sit on differing baselines and the icon ones drop a couple px. */
.cell-pills { display: flex; align-items: center; flex-wrap: wrap; row-gap: 4px; }

/* Toolbar */
.toolbar {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--border-soft);
  border-bottom: none;
  background: var(--bg-elev);
  border-radius: var(--radius) var(--radius) 0 0;
  flex-wrap: wrap;
}
.toolbar + .tbl-wrap { border-radius: 0 0 var(--radius) var(--radius); border-top: none; }
.tb-search {
  display: flex; align-items: center; gap: 6px;
  background: var(--panel); border: 1px solid var(--border-soft);
  border-radius: var(--radius); padding: 5px 9px;
  flex: 1; min-width: 180px; max-width: 320px;
  color: var(--text-muted);
}
.tb-search input {
  background: transparent; border: none; outline: none;
  color: var(--text); font: inherit; flex: 1; min-width: 0; font-size: 13px;
}
.tb-search input::placeholder { color: var(--text-dim); }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 9px; border-radius: var(--radius);
  background: var(--panel); border: 1px solid var(--border-soft);
  font-size: 12px; color: var(--text-muted); cursor: pointer;
  transition: background-color 0.12s, color 0.12s;
}
.chip:hover { color: var(--text); border-color: var(--border); }
.chip.active {
  background: oklch(from var(--accent) l c h / 0.18);
  color: var(--text);
  border-color: var(--accent);
}
.tb-group { display: flex; gap: 0; }
.tb-group .chip { border-radius: 0; margin-left: -1px; position: relative; }
.tb-group .chip:first-child { border-radius: var(--radius) 0 0 var(--radius); margin-left: 0; }
.tb-group .chip:last-child { border-radius: 0 var(--radius) var(--radius) 0; }
.tb-group .chip.active { z-index: 2; }

.tb-spacer { flex: 1; }

/* Forms */
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.field label { font-size: 12px; color: var(--text-muted); font-weight: 500; }
.field .hint { font-size: 11.5px; color: var(--text-dim); }
input.in, select.in, textarea.in {
  background: var(--panel); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 7px 10px; font: inherit; font-size: 13px;
  transition: border-color 0.12s, box-shadow 0.12s;
  width: 100%;
}
input.in:focus, select.in:focus, textarea.in:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
textarea.in { font-family: var(--font-mono); font-size: 12.5px; min-height: 120px; resize: vertical; }

/* Modal */
.scrim {
  position: fixed; inset: 0; background: rgba(8, 13, 20, 0.65);
  display: grid; place-items: center; z-index: 100;
  backdrop-filter: blur(2px);
  animation: fade 0.12s ease-out;
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
.modal {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  width: 460px; max-width: 92vw; max-height: 86vh;
  display: flex; flex-direction: column;
  overflow: hidden;
  animation: pop 0.16s cubic-bezier(0.2, 0.8, 0.4, 1);
}
@keyframes pop { from { transform: translateY(8px) scale(0.98); opacity: 0; } to { transform: none; opacity: 1; } }
.modal.lg { width: 620px; }
.modal-head {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px; border-bottom: 1px solid var(--border-soft);
}
.modal-head h2 { margin: 0; font-size: 15px; font-weight: 600; }
.modal-head .close { margin-left: auto; }
.modal-body { padding: 18px; overflow: auto; flex: 1; }
.modal-foot {
  display: flex; gap: 8px; justify-content: flex-end;
  padding: 12px 16px; border-top: 1px solid var(--border-soft);
  background: var(--panel);
}

/* Tabs */
.tabs {
  display: flex; gap: 2px;
  border-bottom: 1px solid var(--border-soft);
  margin-bottom: 18px;
  overflow-x: auto;
}
.tab {
  padding: 10px 14px; cursor: pointer; font-size: 13px; font-weight: 500;
  color: var(--text-muted); border-bottom: 2px solid transparent;
  white-space: nowrap;
  display: inline-flex; align-items: center; gap: 6px;
  transition: color 0.12s, border-color 0.12s;
  background: none; border-top: none; border-left: none; border-right: none;
}
.tab:hover { color: var(--text); }
.tab.active { color: var(--text); border-bottom-color: var(--accent); }

/* Detail layout */
.detail-head {
  display: flex; align-items: center; gap: 16px;
  margin: 0 0 4px;
}
.detail-head .device-icon-lg {
  width: 44px; height: 44px; border-radius: 10px;
  background: var(--panel-2); border: 1px solid var(--border);
  display: grid; place-items: center; color: var(--text-muted);
  flex: 0 0 44px;
}
.detail-head .titles { flex: 1; min-width: 0; }
.detail-head h1 { font-size: 22px; margin: 0 0 2px; font-weight: 600; }
.detail-head .subline { font-size: 13px; color: var(--text-muted); display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.detail-head .subline .sep { color: var(--text-dim); }
.detail-actions { display: flex; gap: 8px; align-items: center; }

.kv-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1px; background: var(--border-soft);
  border: 1px solid var(--border-soft); border-radius: var(--radius); overflow: hidden;
}
.kv-cell { background: var(--panel); padding: 12px 14px; min-width: 0; }
.kv-cell.wide { grid-column: span 2; }
.kv-cell .k { font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 4px; }
.kv-cell .v { font-size: 13.5px; }
.kv-cell .v.mono { font-family: var(--font-mono); font-size: 12px; overflow-wrap: anywhere; }
.kv-cell .v.big { font-size: 18px; font-weight: 500; }

.grid-2 { display: grid; grid-template-columns: 2fr 1fr; gap: 18px; }
@media (max-width: 1100px) { .grid-2 { grid-template-columns: 1fr; } }

/* Square device-location map filling the left grid column. */
.map-card { position: relative; aspect-ratio: 1 / 1; }
.map-canvas { position: absolute; inset: 0; }
.map-card-empty {
  display: flex; align-items: center; justify-content: center;
  text-align: center; padding: 16px;
}

.section-h {
  display: flex; align-items: center; justify-content: space-between;
  margin: 22px 0 10px;
}
.section-h h3 { font-size: 13px; margin: 0; color: var(--text-muted); font-weight: 500; letter-spacing: 0.02em; }

/* Code/Token */
.token, code.mono {
  font-family: var(--font-mono); font-size: 12px;
  background: var(--panel-2); padding: 3px 7px; border-radius: 4px;
  border: 1px solid var(--border-soft);
  color: var(--text); user-select: all;
}

.muted { color: var(--text-muted); }
.dim { color: var(--text-dim); }
.empty {
  display: flex; flex-direction: column; align-items: center;
  padding: 48px 24px; color: var(--text-dim);
  border: 1px dashed var(--border); border-radius: var(--radius); background: var(--panel);
  gap: 8px;
}

/* Toggle */
.toggle {
  /* inline-block so the span keeps its box outside flex parents too (e.g.
     plain table cells); flex containers blockify it anyway, so no change
     there. */
  display: inline-block; vertical-align: middle;
  width: 32px; height: 18px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--border);
  position: relative; cursor: pointer; transition: background 0.15s, border-color 0.15s;
  flex: 0 0 32px;
}
.toggle::after {
  content: ""; position: absolute; top: 1px; left: 1px;
  width: 14px; height: 14px; background: var(--text-muted); border-radius: 50%;
  transition: left 0.15s, background 0.15s;
}
.toggle.on { background: var(--accent); border-color: transparent; }
.toggle.on::after { left: 15px; background: var(--accent-fg); }

/* Restriction grid */
.rest-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1px; background: var(--border-soft);
  border: 1px solid var(--border-soft); border-radius: var(--radius); overflow: hidden;
}
.rest-cell {
  background: var(--panel); padding: 10px 14px;
  display: flex; align-items: center; gap: 10px;
}
.rest-cell .info { flex: 1; min-width: 0; }
.rest-cell .info .t { font-size: 13px; font-weight: 500; }
.rest-cell .info .s { font-size: 11.5px; color: var(--text-dim); }

/* Activity feed */
.feed { display: flex; flex-direction: column; gap: 0; }
.feed-item {
  display: flex; gap: 12px; padding: 10px 14px;
  border-bottom: 1px solid var(--border-soft);
}
.feed-item:last-child { border-bottom: none; }
.feed-item .ico {
  width: 28px; height: 28px; border-radius: 6px;
  background: var(--panel-2); border: 1px solid var(--border-soft);
  display: grid; place-items: center; color: var(--text-muted);
  flex: 0 0 28px;
}
.feed-item .body { flex: 1; min-width: 0; }
.feed-item .body .t { font-size: 13px; }
.feed-item .body .meta { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }

/* Code blocks (logs) */
.codeblock {
  font-family: var(--font-mono); font-size: 12px; line-height: 1.55;
  background: var(--bg); color: var(--text);
  padding: 14px 16px; border-radius: var(--radius);
  border: 1px solid var(--border-soft);
  white-space: pre-wrap; word-break: break-all; overflow-wrap: anywhere;
  overflow: auto;
  max-height: 60vh; margin: 0;
}

/* Audit log stream (device → Audit logs tab) */
.audit-bar {
  display: flex; align-items: center; gap: 28px; flex-wrap: wrap;
  padding: 12px 16px;
}
.audit-toggle { display: flex; align-items: center; gap: 10px; }
.audit-toggle .info { min-width: 0; }
.audit-toggle .info .t { font-size: 13px; font-weight: 500; }
.audit-toggle .info .s { font-size: 11.5px; color: var(--text-dim); }
.audit-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.audit-panel { overflow: hidden; margin-top: 14px; }
.audit-filters {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 10px 14px; border-bottom: 1px solid var(--border-soft); flex-wrap: wrap;
}
.audit-filters .group { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.audit-filters .vsep { width: 1px; height: 20px; background: var(--border); }
.audit-filters .tb-search { min-width: 200px; max-width: 280px; }
.audit-count { font-size: 12px; color: var(--text-dim); white-space: nowrap; }

.audit-grid {
  display: grid;
  grid-template-columns: 88px 92px 116px 220px 1fr 28px;
  gap: 14px; align-items: center;
}
.audit-head {
  padding: 9px 16px; background: var(--bg-elev);
  border-bottom: 1px solid var(--border-soft);
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--text-dim);
}
.audit-rows { max-height: 60vh; overflow-y: auto; }
.audit-row { border-bottom: 1px solid var(--border-soft); }
.audit-row:last-child { border-bottom: none; }
.audit-row-main {
  padding: 11px 16px; cursor: pointer;
  border-left: 2px solid transparent; transition: background 0.1s;
}
.audit-row-main:hover { background: var(--hover); }
.audit-row.expanded > .audit-row-main { background: var(--accent-soft); border-left-color: var(--accent); }
.audit-row .col-time { font-family: var(--font-mono); font-size: 12px; color: var(--text-dim); }
.audit-row .col-event,
.audit-row .col-detail {
  font-family: var(--font-mono); font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.audit-row .col-event { color: var(--text); }
.audit-row .col-detail { color: var(--text-dim); }
.audit-source { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text-muted); }
.audit-source .dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; background: var(--text-dim); }
.audit-source.security .dot { background: var(--ok); }
.audit-source.network .dot { background: var(--info); }
.audit-chevron { color: var(--text-dim); transition: transform 0.15s ease; flex: 0 0 auto; }
.audit-row.expanded .audit-chevron { transform: rotate(90deg); }
.audit-level {
  display: inline-block; padding: 2px 8px; border-radius: 5px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.03em;
}
.audit-level.info { color: var(--info); background: oklch(from var(--info) l c h / 0.13); border: 1px solid oklch(from var(--info) l c h / 0.25); }
.audit-level.warning { color: var(--warn); background: oklch(from var(--warn) l c h / 0.13); border: 1px solid oklch(from var(--warn) l c h / 0.3); }
.audit-level.none { color: var(--text-dim); }
.audit-raw {
  margin: 0; padding: 14px 16px 16px; background: var(--bg);
  border-left: 2px solid var(--accent); color: var(--text-muted);
  font-family: var(--font-mono); font-size: 12px; line-height: 1.6;
  white-space: pre-wrap; word-break: break-word;
}
.audit-empty { padding: 48px; text-align: center; color: var(--text-dim); font-size: 13.5px; }

/* Login (kept simple, restyled) */
.login-wrap {
  height: 100vh; display: grid; place-items: center;
  background: radial-gradient(circle at 30% 20%, var(--graphite) 0%, var(--bg) 55%);
}
.login-card {
  width: 360px; padding: 30px;
  background: var(--bg-elev); border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg); box-shadow: var(--shadow);
}
.login-card .brand-row { display: flex; align-items: center; gap: 10px; justify-content: center; margin-bottom: 20px; }
.login-card .brand-row .logo {
  width: 28px; height: 28px;
  display: grid; place-items: center;
  flex: 0 0 28px;
}
.login-card .brand-row .logo svg { width: 100%; height: 100%; display: block; }
.login-card h1 { font-size: 18px; margin: 0; font-weight: 600; font-family: var(--font-display); letter-spacing: 0.01em; }
.login-card form { display: flex; flex-direction: column; gap: 12px; }
.login-card .error { color: var(--danger); font-size: 13px; }
/* Pre-auth language picker — the account menu's switcher is behind login. */
.login-locales {
  display: flex; justify-content: center; gap: 14px;
  margin-top: 20px; padding-top: 16px;
  border-top: 1px solid var(--border-soft);
}
.login-locale {
  font-size: 12.5px; color: var(--text-dim); cursor: pointer;
  border-radius: var(--radius-sm); padding: 2px 6px;
}
.login-locale:hover { color: var(--text); }
.login-locale.active { color: var(--accent); }
.login-locale:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; color: var(--text);
}

/* Dropdown menu */
.menu {
  position: absolute; z-index: 200;
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  min-width: 220px; padding: 4px;
}
.menu-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: 4px;
  font-size: 13px; cursor: pointer; color: var(--text);
}
.menu-item:hover { background: var(--hover); }
.menu-item.danger { color: var(--danger); }
.menu-item .ico { width: 14px; color: var(--text-muted); }
.menu-sep { height: 1px; background: var(--border-soft); margin: 4px 6px; }
.menu-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-dim); padding: 8px 10px 4px; }

/* Command palette */
.palette-scrim {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(8, 13, 20, 0.6);
  backdrop-filter: blur(4px);
  display: flex; justify-content: center; align-items: flex-start;
  padding-top: 12vh;
}
.palette {
  width: 560px; max-width: 92vw;
  background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.palette input {
  width: 100%; background: transparent; color: var(--text);
  border: none; outline: none; padding: 16px 18px; font-size: 15px;
  border-bottom: 1px solid var(--border-soft);
}
.palette-list { max-height: 50vh; overflow: auto; padding: 6px; }
.palette-item {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 12px; border-radius: var(--radius);
  cursor: pointer; font-size: 13.5px;
}
.palette-item.active { background: var(--accent-soft); }
.palette-item .ico { color: var(--text-muted); }
.palette-item .meta { margin-left: auto; font-size: 11px; color: var(--text-dim); font-family: var(--font-mono); }
.palette-section { font-size: 10.5px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.06em; padding: 10px 14px 4px; }

/* Stat */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 18px; }
@media (max-width: 900px) { .stats { grid-template-columns: repeat(2, 1fr); } }
.stat {
  background: var(--panel); border: 1px solid var(--border-soft);
  border-radius: var(--radius); padding: 14px 16px;
}
.stat .k { font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.06em; }
.stat .v { font-size: 22px; font-weight: 600; margin-top: 4px; letter-spacing: -0.01em; }
.stat .delta { font-size: 11.5px; color: var(--text-dim); margin-top: 4px; }
.stat .delta.up { color: var(--ok); }
.stat .delta.down { color: var(--danger); }

/* Toast */
.toast-stack {
  position: fixed; right: 16px; bottom: 16px; z-index: 400;
  display: flex; flex-direction: column; gap: 8px;
}
.toast {
  background: var(--bg-elev); border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  padding: 10px 14px; border-radius: var(--radius);
  box-shadow: var(--shadow-lg); min-width: 240px; max-width: 380px;
  font-size: 13px;
  animation: pop 0.18s ease-out;
}
.toast.ok { border-left-color: var(--ok); }
.toast.warn { border-left-color: var(--warn); }
.toast.danger { border-left-color: var(--danger); }
.toast .meta { font-size: 11px; color: var(--text-dim); margin-top: 2px; }

/* Drop zone */
.drop {
  border: 2px dashed var(--border); border-radius: var(--radius);
  padding: 28px; text-align: center; color: var(--text-muted);
  font-size: 13px; transition: all 0.12s; cursor: pointer;
  background: var(--panel);
}
.drop.hover { border-color: var(--accent); background: var(--accent-soft); color: var(--text); }

/* Misc */
.row { display: flex; gap: 10px; align-items: center; }
.spacer { flex: 1; }
.divider { height: 1px; background: var(--border-soft); margin: 16px 0; }
.tag {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 7px; font-size: 11px; border-radius: 4px;
  background: var(--panel-2); border: 1px solid var(--border-soft);
  color: var(--text-muted); font-family: var(--font-mono);
}

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

.qr-frame {
  background: white; padding: 14px; border-radius: 8px;
  display: inline-block;
}
.qr-frame img { display: block; max-width: 200px; image-rendering: pixelated; }
.qr-frame.lg img { max-width: 320px; }

/* ---------- Alerts ---------- */
/* Red unread badge (vs the neutral inventory counts). Same selector specificity
   as `.nav-item .badge-count`, defined later so it wins. */
.nav-item .badge-alert {
  color: var(--danger);
  border-color: oklch(from var(--danger) l c h / 0.4);
  background: oklch(from var(--danger) l c h / 0.12);
}
.nav-item.active .badge-alert {
  color: var(--danger);
  border-color: oklch(from var(--danger) l c h / 0.5);
}

.alerts-filters { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; }

.alerts-feed { display: flex; flex-direction: column; gap: 8px; }
.alert-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border: 1px solid var(--border-soft); border-radius: var(--radius);
  background: var(--panel);
}
.alert-main { flex: 1; min-width: 0; }
.alert-title { font-size: 13.5px; font-weight: 500; }
.alert-link { cursor: pointer; color: var(--text); }
.alert-link:hover { color: var(--accent); text-decoration: underline; }
.alert-detail { font-size: 12.5px; color: var(--text-muted); margin-top: 2px; }
.alert-meta { font-size: 11.5px; margin-top: 3px; }
.alert-actions { display: flex; gap: 6px; flex: none; }
/* Dashboard alert panel: kind tag + whole-row deep-link to the device. */
.alert-row .pill.kind { flex: none; align-self: flex-start; }
.alert-row.clickable { cursor: pointer; transition: background 0.08s, border-color 0.08s; }
.alert-row.clickable:hover { background: var(--hover); border-color: var(--border); }
