/* IP Tracker — white card, Verdana, like the hbeta.com home page. The page behind the
   card is a very light slate rather than pure white, so the white card still reads as
   a card; the dark slate of the home page is kept for the dark theme only. */
:root {
  --bg: #eef2f7;
  --card: #ffffff;
  --ink: #1f2937;
  --muted: #6b7280;
  --line: #e5e7eb;
  --line-strong: #cccccc;
  --head: #f3f4f6;
  --accent: #1d4ed8;
  --accent-soft: #e8f0fe;
  --danger: #b91c1c;
  --danger-soft: #fee2e2;
  --ok: #047857;
  --ok-soft: #d1fae5;
  --hover: #f9fafb;
  --input-focus: #fffbea;
  --st-used: #dbeafe;     --st-used-ink: #1e40af;
  --st-free: #dcfce7;     --st-free-ink: #166534;
  --st-reserved: #fef3c7; --st-reserved-ink: #92400e;
  --st-gateway: #ede9fe;  --st-gateway-ink: #5b21b6;
  --st-unknown: #e5e7eb;  --st-unknown-ink: #374151;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #111827; --card: #1f2937; --ink: #e5e7eb; --muted: #9ca3af; --line: #374151;
    --line-strong: #4b5563; --head: #273244; --accent: #93c5fd; --accent-soft: #1e3a5f;
    --danger: #fca5a5; --danger-soft: #4c1d1d; --ok: #6ee7b7; --ok-soft: #064e3b;
    --hover: #243041; --input-focus: #2b3446;
    --st-used: #1e3a5f; --st-used-ink: #bfdbfe; --st-free: #14432a; --st-free-ink: #bbf7d0;
    --st-reserved: #4a3a12; --st-reserved-ink: #fde68a; --st-gateway: #352a5c; --st-gateway-ink: #ddd6fe;
    --st-unknown: #374151; --st-unknown-ink: #d1d5db;
    color-scheme: dark;
  }
}

/* Forced dark (theme picker). Generated from the block above — if you change one,
   change both; they are intentionally identical. */
:root[data-theme="dark"] {
  --bg: #111827; --card: #1f2937; --ink: #e5e7eb; --muted: #9ca3af; --line: #374151;
  --line-strong: #4b5563; --head: #273244; --accent: #93c5fd; --accent-soft: #1e3a5f;
  --danger: #fca5a5; --danger-soft: #4c1d1d; --ok: #6ee7b7; --ok-soft: #064e3b;
  --hover: #243041; --input-focus: #2b3446;
  --st-used: #1e3a5f; --st-used-ink: #bfdbfe; --st-free: #14432a; --st-free-ink: #bbf7d0;
  --st-reserved: #4a3a12; --st-reserved-ink: #fde68a; --st-gateway: #352a5c; --st-gateway-ink: #ddd6fe;
  --st-unknown: #374151; --st-unknown-ink: #d1d5db;
  color-scheme: dark;
  /* group colors, mirrored from the second dark media block further down */
  --grp-row-l: 0.285;  --grp-row-c: 0.030;
  --grp-rowh-l: 0.330; --grp-rowh-c: 0.038;
  --grp-pill-l: 0.345; --grp-pill-c: 0.050;
  --grp-ink-l: 0.865;  --grp-ink-c: 0.075;
  --grp-bar-l: 0.740;  --grp-bar-c: 0.110;
}


* { box-sizing: border-box; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: Verdana, Arial, sans-serif;
  font-size: 90%;
  margin: 2.5em 0;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
.mono { font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; font-size: 0.95em; }
.muted { color: var(--muted); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

.card {
  background: var(--card);
  border: 1px solid var(--line-strong);
  border-radius: 11px;
  margin: 0 auto;
  padding: 0 1.25em 1.25em;
  width: calc(100% - 32px);
}
.card.wide { max-width: 1250px; }

/* ---- header */
.top {
  display: flex; align-items: center; gap: 1em; flex-wrap: wrap;
  border-bottom: 2px solid var(--line-strong);
  padding: 0.9em 0;
}
.top h1 { font-size: 140%; margin: 0; display: flex; align-items: center; gap: 0.4em; flex: 1; justify-content: center; }
.title-icon { width: 28px; height: 28px; border-radius: 7px; box-shadow: 0 1px 4px rgba(0,0,0,.22); }
.top-actions { display: flex; gap: 0.3em; }
.top-actions form { margin: 0; }

/* ---- buttons & inputs */
.btn {
  font: inherit; font-size: 0.95em;
  border: 1px solid var(--line-strong); background: var(--card); color: var(--ink);
  border-radius: 6px; padding: 0.4em 0.8em; cursor: pointer; white-space: nowrap;
  display: inline-block;
}
.btn:hover { background: var(--hover); text-decoration: none; }
.btn.primary { background: #2563eb; border-color: #2563eb; color: #fff; }
.btn.primary:hover { background: #1d4ed8; }
.btn.danger { color: var(--danger); }
.btn.danger:hover { background: var(--danger-soft); }
.btn.danger.solid { background: #dc2626; border-color: #dc2626; color: #fff; }
.btn.danger.solid:hover { background: #b91c1c; }
.btn.link { border-color: transparent; background: none; color: var(--accent); padding: 0.4em 0.5em; }
.btn.small { font-size: 0.85em; padding: 0.3em 0.6em; }
.btn.icon { border-color: transparent; background: none; padding: 0.2em 0.45em; font-size: 0.9em; }
input, select, textarea { font: inherit; color: var(--ink); }
.toolbar input, .filters input, .filters select, dialog input, .login-card input {
  border: 1px solid var(--line-strong); border-radius: 6px; padding: 0.4em 0.6em; background: var(--card);
}

/* ---- tabs */
.tabs { display: flex; gap: 0.4em; flex-wrap: wrap; margin: 1em 0 0.6em; }
.tab {
  font: inherit; text-align: left; cursor: pointer;
  border: 1px solid var(--line); background: var(--head); color: var(--ink);
  border-radius: 8px; padding: 0.45em 0.8em; display: flex; flex-direction: column; gap: 0.1em;
}
.tab:hover { border-color: var(--line-strong); }
.tab.active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.tab-label { font-weight: bold; }
.tab-sub { font-size: 0.8em; color: var(--muted); }

/* ---- selected network */
.net-info { background: var(--head); border-radius: 8px; padding: 0.6em 0.8em; margin-bottom: 0.8em; }
.net-head { display: flex; align-items: center; gap: 0.8em; flex-wrap: wrap; }
.cidr { font-weight: bold; font-family: ui-monospace, Menlo, Consolas, monospace; }
.net-head .name { flex: 1; min-width: 12em; font-weight: bold; }
.net-info .notes { width: 100%; margin-top: 0.4em; }

/* ---- toolbar / filters */
.toolbar, .filters { display: flex; gap: 0.8em 1.5em; flex-wrap: wrap; align-items: center; margin: 0.6em 0; }
.group { display: flex; gap: 0.4em; flex-wrap: wrap; align-items: center; margin: 0; }
.toolbar input[name="cidr"] { width: 17em; }
.toolbar input[name="ip"] { width: 11em; }
.filters input[type="search"] { width: 16em; }
/* Only the first trailing button takes the slack, so the pair stays together on the right. */
.filters #groups-open { margin-left: auto; }
.hint { font-size: 0.85em; color: var(--muted); }
.hint.bad { color: var(--danger); }

.msg { border-radius: 6px; padding: 0.5em 0.8em; margin: 0.6em 0; }
.msg.ok { background: var(--ok-soft); color: var(--ok); }
.msg.error { background: var(--danger-soft); color: var(--danger); }
.msg.warn { background: var(--st-reserved); color: var(--st-reserved-ink); }
.msg.warn .btn.link { color: inherit; text-decoration: underline; padding: 0 0.2em; }
.top-actions { align-items: center; }
.top-actions .user { font-size: 0.85em; margin-right: 0.3em; }

/* ---- table */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 8px; }
table { border-collapse: collapse; width: 100%; min-width: 980px; }
th {
  position: sticky; top: 0; z-index: 1;
  background: var(--head); text-align: left; font-size: 0.78em; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--muted); padding: 0.6em 0.5em; border-bottom: 1px solid var(--line-strong);
}
/* Sortable headers: the button has to borrow the th's own type styling. */
th .sort-btn {
  font: inherit; color: inherit; text-transform: inherit; letter-spacing: inherit;
  background: none; border: 0; padding: 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: 0.35em;
}
th .sort-btn:hover { color: var(--accent); }
th[aria-sort] .sort-btn { color: var(--accent); }
th .arrow { font-size: 0.95em; opacity: 0.3; }
th .sort-btn:hover .arrow { opacity: 0.7; }
th[aria-sort] .arrow { opacity: 1; }

td { border-bottom: 1px solid var(--line); padding: 0.15em 0.25em; vertical-align: top; }
tbody tr:hover { background: var(--hover); }
tr.st-free td.c-ip, tr.st-unknown td.c-ip { color: var(--muted); }
td.c-ip { padding: 0.45em 0.5em; white-space: nowrap; font-weight: bold; }
td.c-upd { padding: 0.45em 0.5em; white-space: nowrap; font-size: 0.85em; }
td.c-del { width: 2em; text-align: center; }
td.c-notes { min-width: 16em; }
td.c-sites { min-width: 12em; }
td.c-os { min-width: 10em; }
td.c-hostname { min-width: 8em; }

.inline {
  width: 100%; border: 1px solid transparent; border-radius: 4px; background: transparent;
  padding: 0.3em 0.35em; resize: none; overflow: hidden; display: block; line-height: 1.35;
  transition: background-color .4s, border-color .4s;
}
.inline:hover { border-color: var(--line); }
.inline:focus { outline: none; border-color: var(--accent); background: var(--input-focus); }
.inline.saving { border-color: var(--line-strong); }
.inline.saved { background: var(--ok-soft); }
.inline.failed { border-color: var(--danger); background: var(--danger-soft); }

select.status {
  border: 1px solid transparent; border-radius: 999px; padding: 0.25em 0.5em; margin: 0.15em 0;
  font-size: 0.85em; font-weight: bold; cursor: pointer;
}
select.status.saved { outline: 2px solid var(--ok); }
select.status.failed { outline: 2px solid var(--danger); }
.st-used     select.status, select.st-used     { background: var(--st-used);     color: var(--st-used-ink); }
.st-free     select.status, select.st-free     { background: var(--st-free);     color: var(--st-free-ink); }
.st-reserved select.status, select.st-reserved { background: var(--st-reserved); color: var(--st-reserved-ink); }
.st-gateway  select.status, select.st-gateway  { background: var(--st-gateway);  color: var(--st-gateway-ink); }
.st-unknown  select.status, select.st-unknown  { background: var(--st-unknown);  color: var(--st-unknown-ink); }

/* ---- host groups
   Every grouped element carries --gh (a hue, 0-359) set from JS; the tints below are
   derived from it, so one hue drives the row, the dropdown and the swatches, and the
   whole palette re-balances for dark mode by changing lightness in one place. */
:root {
  /* OKLCH, not HSL: its lightness is perceptually uniform, so a yellow group and a
     blue group carry the same visual weight. In HSL the yellows washed out while the
     blues stayed heavy, which is what made a mixed palette look uneven. */
  /* Light mode carries more chroma than dark: the same tint that reads as pleasant
     against a dark card disappears against a white one. */
  --grp-row-l: 0.930;  --grp-row-c: 0.062;   /* row tint        */
  --grp-rowh-l: 0.900; --grp-rowh-c: 0.075;  /* row tint, hover */
  --grp-pill-l: 0.880; --grp-pill-c: 0.095;  /* dropdown pill   */
  --grp-ink-l: 0.380;  --grp-ink-c: 0.130;   /* text on the pill */
  --grp-bar-l: 0.560;  --grp-bar-c: 0.180;   /* bar / chip / swatch */
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --grp-row-l: 0.285;  --grp-row-c: 0.030;
    --grp-rowh-l: 0.330; --grp-rowh-c: 0.038;
    --grp-pill-l: 0.345; --grp-pill-c: 0.050;
    --grp-ink-l: 0.865;  --grp-ink-c: 0.075;
    --grp-bar-l: 0.740;  --grp-bar-c: 0.110;
  }
}

tbody tr.grouped > td { background: oklch(var(--grp-row-l) calc(var(--grp-row-c)  * var(--gc, 1)) var(--gh)); }
tbody tr.grouped:hover > td { background: oklch(var(--grp-rowh-l) calc(var(--grp-rowh-c) * var(--gc, 1)) var(--gh)); }
/* Solid bar down the IP cell: grouped rows that sit next to each other read as one block. */
tbody tr.grouped > td.c-ip { box-shadow: inset 4px 0 0 oklch(var(--grp-bar-l) calc(var(--grp-bar-c)  * var(--gc, 1)) var(--gh)); }

td.c-group { min-width: 9em; }
select.group-sel {
  font: inherit; font-size: 0.85em; max-width: 100%;
  border: 1px solid transparent; border-radius: 999px; padding: 0.25em 0.5em; margin: 0.15em 0;
  background: transparent; color: var(--muted); cursor: pointer;
}
select.group-sel:hover { border-color: var(--line); }
select.group-sel.grouped {
  background: oklch(var(--grp-pill-l) calc(var(--grp-pill-c) * var(--gc, 1)) var(--gh));
  color: oklch(var(--grp-ink-l) calc(var(--grp-ink-c)  * var(--gc, 1)) var(--gh));
  font-weight: bold;
}
select.group-sel.saving { border-color: var(--line-strong); }
select.group-sel.saved { outline: 2px solid var(--ok); }
select.group-sel.failed { outline: 2px solid var(--danger); }

/* "Group colors" off: drop the tinting in the table only. Group membership, the Group
   dropdown and the Manage-groups dialog (where colors are chosen) all stay as they are. */
body.no-group-colors tbody tr.grouped > td { background: transparent; }
body.no-group-colors tbody tr.grouped > td.c-ip { box-shadow: none; }
body.no-group-colors select.group-sel.grouped {
  background: transparent; color: var(--muted); font-weight: normal;
}
body.no-group-colors select.group-sel.grouped:hover { border-color: var(--line); }

.theme-pick { display: inline-flex; align-items: center; }
.theme-pick select {
  font: inherit; font-size: 0.9em; cursor: pointer;
  border: 1px solid transparent; border-radius: 6px; padding: 0.35em 0.4em;
  background: var(--card); color: var(--accent);
}
.theme-pick select:hover { border-color: var(--line-strong); background: var(--hover); }

.toggle { display: inline-flex; align-items: center; gap: 0.35em; cursor: pointer; white-space: nowrap; font-size: 0.9em; }
.toggle input { cursor: pointer; margin: 0; }

/* ---- honeycomb color picker
   Pointy-top hexagons. Rows interlock by pulling each one up a quarter of a cell
   height; every row is symmetric about the centre, so centring them is enough to
   form the hexagon — no per-row offsets needed. */
.honeycomb { --hex-w: 30px; --hex-h: 34.64px; /* w * 2/sqrt(3) */
  display: flex; flex-direction: column; align-items: center; margin: 0.2em 0 0.1em;
}
.hex-row { display: flex; }
.hex-row + .hex-row { margin-top: calc(var(--hex-h) * -0.25); }
.hex {
  width: var(--hex-w); height: var(--hex-h); padding: 0; border: 0; cursor: pointer;
  margin: 0 1px;
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  background: oklch(var(--grp-bar-l) calc(var(--grp-bar-c) * var(--gc, 1)) var(--gh));
  transition: transform .1s;
}
.hex:hover { transform: scale(1.12); z-index: 1; }
.hex:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
/* clip-path would eat an outline, so the selected cell is marked with an inset ring. */
.hex.on { box-shadow: inset 0 0 0 3px var(--card), inset 0 0 0 5px var(--ink); }

.swatches { display: flex; flex-direction: column; align-items: center; }

dialog.groups { max-width: min(34em, calc(100% - 32px)); }
.hue-pick { border: 1px solid var(--line); border-radius: 8px; padding: 0.4em 0.6em 0.6em; margin: 0 0 0.7em; }
.hue-pick legend { font-size: 0.85em; color: var(--muted); padding: 0 0.3em; }
.group-add { display: flex; gap: 0.4em; margin: 0.8em 0; }
.group-add input { flex: 1; min-width: 0; }
.group-row {
  border: 1px solid var(--line); border-left: 4px solid oklch(var(--grp-bar-l) calc(var(--grp-bar-c)  * var(--gc, 1)) var(--gh));
  border-radius: 8px; padding: 0.5em 0.6em; margin-bottom: 0.5em;
  background: oklch(var(--grp-row-l) calc(var(--grp-row-c)  * var(--gc, 1)) var(--gh));
}
.group-row-top { display: flex; align-items: center; gap: 0.5em; margin-bottom: 0.45em; }
.group-row-top .name { flex: 1; min-width: 6em; font-weight: bold; }
.group-row .chip {
  width: 0.85em; height: 0.85em; border-radius: 50%; flex: none;
  background: oklch(var(--grp-bar-l) calc(var(--grp-bar-c)  * var(--gc, 1)) var(--gh));
}
.nowrap { white-space: nowrap; }

.empty { text-align: center; color: var(--muted); padding: 2em; margin: 0; }

/* ---- dialogs */
dialog { border: 1px solid var(--line-strong); border-radius: 10px; padding: 1.2em 1.4em; background: var(--card); color: var(--ink); max-width: min(30em, calc(100% - 32px)); }
dialog::backdrop { background: rgba(0,0,0,.45); }
dialog h2 { margin: 0 0 0.8em; font-size: 120%; }
dialog label { display: flex; flex-direction: column; gap: 0.25em; margin-bottom: 0.7em; }
.dialog-actions { display: flex; gap: 0.5em; justify-content: flex-end; margin-top: 0.8em; }
.dialog-actions.column { flex-direction: column; align-items: stretch; }

/* ---- OS support info */
.info-btn {
  font: bold 0.95em Georgia, serif; font-style: italic; text-transform: none;
  width: 1.45em; height: 1.45em; border-radius: 50%; margin-left: 0.3em; padding: 0; vertical-align: middle;
  border: 1px solid var(--accent); background: var(--accent-soft); color: var(--accent); cursor: pointer;
}
.info-btn:hover { background: var(--accent); color: var(--card); }
dialog.os-info { max-width: min(40em, calc(100% - 32px)); }
.os-info h3 { font-size: 95%; margin: 1em 0 0.4em; }
table.lifecycle { min-width: 0; width: 100%; font-size: 0.9em; }
table.lifecycle th { position: static; font-size: 0.75em; }
table.lifecycle td { padding: 0.35em 0.5em; white-space: nowrap; }
.life { font-size: 0.85em; font-weight: bold; border-radius: 999px; padding: 0.15em 0.6em; }
.life.ok  { background: var(--st-free); color: var(--st-free-ink); }
.life.pro { background: var(--st-reserved); color: var(--st-reserved-ink); }
.life.eol { background: var(--danger-soft); color: var(--danger); }
.small { font-size: 0.8em; }

/* ---- login */
.login-page { display: flex; min-height: 80vh; align-items: center; }
.login-card { max-width: 340px; text-align: center; padding-top: 1.5em; }
.login-card h1 { font-size: 140%; margin: 0.4em 0 1em; }
.login-icon { width: 48px; height: 48px; border-radius: 11px; box-shadow: 0 1px 4px rgba(0,0,0,.22); }
.login-card form { display: flex; flex-direction: column; gap: 0.6em; text-align: left; }
.login-card code { font-size: 0.85em; word-break: break-all; }
.back { margin: 1.2em 0 0; font-size: 0.85em; }

@media (max-width: 640px) {
  body { margin: 1em 0; }
  .card { padding: 0 0.8em 0.8em; }
  .top h1 { order: -1; flex-basis: 100%; }
  .toolbar input[name="cidr"], .filters input[type="search"] { width: 100%; }
  .filters #groups-open { margin-left: 0; }
}
