:root {
  --bg: #f5f6f8;
  --surface: #ffffff;
  --border: #e2e5ea;
  --text: #1b1f24;
  --muted: #69717d;
  --primary: #2563eb;
  --primary-text: #ffffff;
  --danger: #c62828;
  --ok-bg: #e3f5e8;   --ok-fg: #1c6b34;
  --warn-bg: #fff3d6; --warn-fg: #8a5a00;
  --bad-bg: #fde6e6;  --bad-fg: #a52020;
  --info-bg: #e5efff; --info-fg: #1d4ea8;
  --radius: 10px;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #111418;
    --surface: #1a1e24;
    --border: #2c323b;
    --text: #e6e8eb;
    --muted: #98a1ad;
    --primary: #4f8cff;
    --danger: #ef5350;
    --ok-bg: #173323;   --ok-fg: #7fd99b;
    --warn-bg: #3a2f12; --warn-fg: #f2c461;
    --bad-bg: #3d1b1b;  --bad-fg: #f59a9a;
    --info-bg: #182a4a; --info-fg: #9dbdff;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

a { color: var(--primary); text-decoration: none; }
h1 { font-size: 1.5rem; margin: 0 0 1.25rem; }
h2 { font-size: 1.05rem; margin: 0 0 1rem; }
code { font-size: .85em; }

main { max-width: 1320px; margin: 0 auto; padding: 1.5rem 16px 3rem; }

.topbar {
  display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap;
  padding: .6rem 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.brand { font-weight: 700; color: var(--text); }
.nav-panel { display: flex; align-items: center; gap: 1.5rem; flex: 1; flex-wrap: wrap; }
.nav-toggle { display: none; }
.topbar nav { display: flex; gap: .25rem; flex-wrap: wrap; flex: 1; }
.topbar nav a { color: var(--muted); padding: .35rem .7rem; border-radius: 6px; }
.topbar nav a:hover { color: var(--text); }
.topbar nav a.active { color: var(--text); background: var(--bg); }
.logout { display: flex; align-items: center; gap: .6rem; color: var(--muted); }
.logout form { margin: 0; }
/* The signed-in username (top right) opens Account settings. */
.account-link { color: var(--muted); padding: .35rem .7rem; border-radius: 6px; }
.account-link:hover { color: var(--text); background: var(--bg); }
.account-link.active { color: var(--text); background: var(--bg); }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
  margin-bottom: 1.25rem;
}
.narrow { max-width: 460px; }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 1rem; margin-bottom: 1.25rem; }
.stat { display: flex; flex-direction: column; gap: .35rem; margin: 0; }
.stat-label { color: var(--muted); font-size: .85rem; }
.stat-value { font-size: 1.6rem; font-weight: 650; font-variant-numeric: tabular-nums; }
/* Count cards on the Dashboard link to the filtered client list. */
a.stat-link { color: inherit; transition: border-color .15s, transform .15s; }
a.stat-link:hover, a.stat-link:focus-visible { border-color: var(--primary); }
a.stat-link:active { transform: scale(.98); }
a.stat-link .stat-label::after { content: " →"; opacity: .6; }
/* The service card is wider: server name + status, then its addresses. */
/* Dashboard: server cards in their own grid, client counts in a row of four below. */
.server-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem; margin-bottom: 1.25rem; }
.server-grid .stat-server { margin: 0; }

/* Server page: the same server cards as the Dashboard, used to pick which server's settings show. */
a.server-select { display: block; text-decoration: none; color: inherit; transition: border-color .15s, box-shadow .15s; }
a.server-select:hover { border-color: var(--primary); }
a.server-select.active { border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
a.server-select.server-add { display: flex; align-items: center; justify-content: center; min-height: 100%;
  font-weight: 600; color: var(--primary); border-style: dashed; }
/* Label on the left, the active/inactive badge in the upper right corner. */
.server-card-head { display: flex; justify-content: space-between; align-items: center; gap: .5rem; }
.stats { grid-template-columns: repeat(4, 1fr); }
main > h1 + .section-title,
[data-live="dashboard"] > .section-title:first-of-type { margin-top: 0; }
.routed-ips code { display: inline-block; margin: 0 .35rem .25rem 0; }
.routed-ips .ip-old { opacity: .55; }
.routed-foot { margin: .75rem 0 0; }
.public-ip { margin-top: .2rem; }
.stat-server .stat-value { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; font-size: 1.35rem; overflow-wrap: anywhere; }
.server-facts { display: grid; grid-template-columns: max-content 1fr; gap: .15rem .8rem; margin: .2rem 0 0; font-size: .85rem; }
.server-facts dt { color: var(--muted); }
.server-facts dd { margin: 0; overflow-wrap: anywhere; }

label { display: flex; flex-direction: column; gap: .3rem; font-size: .85rem; color: var(--muted); }
input, select, textarea {
  font: inherit; color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: .5rem .65rem;
  min-width: 0;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--primary); outline-offset: -1px; }
/* Own dropdown arrow, inset from the edge (browsers, especially on phones, put theirs right at it).
   Drawn with two gradients in the text colour, so it follows light/dark mode and needs no image. */
select {
  -webkit-appearance: none; appearance: none;
  padding-right: 2.4rem;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: right 1.15rem center, right .8rem center;
  background-size: .35rem .35rem, .35rem .35rem;
  background-repeat: no-repeat;
  cursor: pointer;
}
select::-ms-expand { display: none; }

.stack { display: flex; flex-direction: column; gap: .9rem; }
.grid-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: .9rem; align-items: end; }
.grid-form .span-2 { grid-column: span 2; }
.grid-form .form-full { grid-column: 1 / -1; }
.grid-form .form-full.tight { margin-top: -.4rem; }
/* Client options: full width, two halves side by side (one column on narrow screens). */
.options { border: 1px solid var(--border); border-radius: 8px; padding: .8rem 1rem 1rem; margin: 0;
           display: grid; grid-template-columns: 1fr 1fr; gap: 1rem 2rem; align-items: start; }
.options-col { display: flex; flex-direction: column; gap: .5rem; min-width: 0; }
.options-col > p { margin: -.2rem 0 .4rem; }
.options-col .ip-input { max-width: 14rem; }
.options legend { font-size: .85rem; color: var(--muted); padding: 0 .3rem; }
label.check { flex-direction: row; align-items: flex-start; gap: .55rem; color: var(--text); font-size: .9rem; }
/* Fixed size: the generic input padding/min-width would let flex squeeze the box. */
label.check input[type="checkbox"] {
  flex: 0 0 20px;
  width: 20px;
  height: 20px;
  min-width: 20px;
  margin: .05rem 0 0;
  padding: 0;
  accent-color: var(--primary);
  cursor: pointer;
}
label.check span { flex: 1; cursor: pointer; }
.script-paths { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: .6rem .9rem; margin-left: calc(20px + .55rem); }
.script-paths p { grid-column: 1 / -1; margin: 0; }
.script-paths.is-disabled { opacity: .5; }
.tags { display: flex; gap: .3rem; flex-wrap: wrap; margin-top: .25rem; }
.tag { font-size: .72rem; color: var(--muted); border: 1px solid var(--border); border-radius: 4px; padding: 0 .35rem; }
.form-end { display: flex; justify-content: flex-end; gap: .5rem; }
.toolbar { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: 1rem; }
.toolbar input { flex: 1; min-width: 180px; }

.btn {
  font: inherit; font-size: .9rem; cursor: pointer;
  display: inline-block;
  padding: .45rem .9rem;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  white-space: nowrap;
}
.btn:hover { border-color: var(--muted); }
.btn-primary { background: var(--primary); border-color: var(--primary); color: var(--primary-text); }
.btn-danger { color: var(--danger); }
.btn-danger:hover { border-color: var(--danger); }
/* Same outlined look as .btn-danger, in green (setup-link copy buttons). */
.btn-ok { color: var(--ok-fg); }
.btn-ok:hover { border-color: var(--ok-fg); }
.btn-ghost { border-color: transparent; background: none; color: var(--muted); }
.btn-small { font-size: .8rem; padding: .3rem .6rem; }

.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: .9rem; }
th, td { text-align: left; padding: .6rem .5rem; border-bottom: 1px solid var(--border); vertical-align: top; }
th { color: var(--muted); font-weight: 500; font-size: .8rem; }
tbody tr:last-child td { border-bottom: 0; }
/* The cell stays a real table cell (so row borders line up); the flex layout lives in .row-actions. */
td.actions { width: 1%; white-space: nowrap; }
.row-actions { display: flex; align-items: center; justify-content: flex-start; gap: .4rem; }
.row-actions form { margin: 0; }
.nowrap { white-space: nowrap; }

.badge { display: inline-block; padding: .1rem .55rem; border-radius: 5px; font-size: .78rem; font-weight: 600; }
.badge-ok { background: var(--ok-bg); color: var(--ok-fg); }
.badge-warn { background: var(--warn-bg); color: var(--warn-fg); }
.badge-bad { background: var(--bad-bg); color: var(--bad-fg); }
/* Client name as a badge (like Status), at the name's normal size: green when connected, grey when not. */
.name-online, .name-offline { display: inline-block; padding: .05rem .55rem; border-radius: 5px; font-weight: 600; }
.name-online { background: var(--ok-bg); color: var(--ok-fg); }
.name-offline { background: var(--border); color: var(--muted); }
.online-for { color: var(--ok-fg); white-space: nowrap; margin-top: .2rem; }

/* Status messages float over the page (bottom right) instead of pushing the content down. */
.flashes {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 60;
  display: flex; flex-direction: column; gap: .5rem;
  width: min(420px, calc(100vw - 32px));
}
/* Inline errors inside a page (form problems) stay in place. */
.flash { padding: .7rem 1rem; border-radius: 8px; margin-bottom: 1rem; }
.flashes .flash {
  display: flex; align-items: flex-start; gap: .75rem; margin: 0;
  padding: .7rem .6rem .7rem 1rem;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .18);
  transition: opacity .3s, transform .3s;
}
.flashes .flash > span { flex: 1; overflow-wrap: anywhere; }
.flashes .flash.is-leaving { opacity: 0; transform: translateY(.5rem); }
.flash-close {
  flex: none; border: 0; background: none; color: inherit; cursor: pointer;
  font-size: 1.25rem; line-height: 1; padding: 0 .25rem; opacity: .7;
}
.flash-close:hover { opacity: 1; }
@media (max-width: 760px) {
  .flashes { right: 16px; left: 16px; bottom: 16px; width: auto; }
}
.flash-success { background: var(--ok-bg); color: var(--ok-fg); }
.flash-error { background: var(--bad-bg); color: var(--bad-fg); }
.flash-info { background: var(--info-bg); color: var(--info-fg); }

.muted { color: var(--muted); }
.small { font-size: .8rem; }
.pager { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-top: 1rem; }

.login-card { max-width: 380px; margin: 12vh auto 0; }
.login-card h1 { margin-bottom: .25rem; }

@media (max-width: 600px) {
  .grid-form .span-2 { grid-column: auto; }
}
@media (max-width: 760px) {
  .options { grid-template-columns: 1fr; }
  .stats { grid-template-columns: repeat(2, 1fr); }
}

.facts { display: grid; grid-template-columns: max-content 1fr; gap: .45rem 1.25rem; margin: 0 0 1.25rem; }
.facts dt { color: var(--muted); font-size: .85rem; }
.facts dd { margin: 0; display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }

.ip-input { display: flex; align-items: center; max-width: 16rem; }
.ip-prefix {
  padding: .5rem .55rem; border: 1px solid var(--border); border-right: 0;
  border-radius: 6px 0 0 6px; background: var(--surface); color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .9rem;
}
.ip-prefix + input { border-radius: 0 6px 6px 0; flex: 1; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

.page-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.page-head h1 { margin: 0; }
.page-head form { margin: 0; }

.retention { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.retention input[type="number"] { width: 6rem; }
.retention + p { margin: .5rem 0 0; }

.options-form { display: flex; flex-direction: column; gap: .7rem; }
.options-form p { margin: 0; }

textarea { resize: vertical; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .85rem; line-height: 1.4; }

label.inline { flex-direction: row; align-items: center; gap: .5rem; color: var(--text); font-size: .9rem; }
.toolbar form { margin: 0; }

/* Search/filter on the left, "Purge revoked" on the right of the same row. */
.list-head { display: flex; justify-content: space-between; align-items: flex-start; gap: .5rem; flex-wrap: wrap; }
.list-head > form { margin: 0 0 1rem; }
.list-head > .toolbar { flex: 1; }


/* ---------- Mobile ---------------------------------------------------------------------- */

/* Menu: a button that opens a full-width vertical list. */
@media (max-width: 760px) {
  .topbar { gap: .5rem; padding: .5rem 16px; }
  .js .nav-toggle {
    display: flex; flex-direction: column; justify-content: center; gap: 4px;
    margin-left: auto; width: 42px; height: 38px; padding: 0 10px; cursor: pointer;
    background: none; border: 1px solid var(--border); border-radius: 6px;
  }
  .nav-toggle span { display: block; height: 2px; background: var(--text); border-radius: 1px; transition: transform .15s, opacity .15s; }
  .nav-open .nav-toggle span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
  .nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
  .nav-open .nav-toggle span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }
  /* The bar stays at the top; the open menu drops down over the page instead of pushing it down. */
  .topbar { position: sticky; top: 0; z-index: 50; }
  .nav-panel { flex-basis: 100%; flex-direction: column; align-items: stretch; gap: .25rem; }
  .js .nav-panel {
    display: none; position: absolute; top: 100%; left: 0; right: 0;
    padding: .5rem 16px .75rem; background: var(--surface); border-bottom: 1px solid var(--border);
    box-shadow: 0 12px 24px rgba(0, 0, 0, .18); max-height: calc(100vh - 60px); overflow-y: auto;
  }
  .js .nav-open .nav-panel { display: flex; }
  /* Dim the page behind the open menu; tapping it closes the menu (see app.js). */
  .js .nav-open::after {
    content: ""; position: fixed; inset: 0; z-index: -1; background: rgba(0, 0, 0, .35);
  }
  .topbar nav { flex-direction: column; gap: 0; }
  /* Right-aligned under the menu button, a line between items; admin + Log out on the left below. */
  .topbar nav a { padding: .75rem .6rem; font-size: 1rem; border-radius: 0; text-align: right;
                  border-bottom: 1px solid var(--border); }
  .topbar nav a:last-child { border-bottom: 0; }
  .logout { justify-content: flex-start; gap: .75rem; padding: .5rem .6rem 0; border-top: 1px solid var(--border); }
}

/* Tables become one card per row with "label: value" lines. */
@media (max-width: 700px) {
  .table-wrap { overflow: visible; }
  table.responsive thead { display: none; }
  table.responsive, table.responsive tbody, table.responsive tr { display: block; width: 100%; }
  table.responsive tr {
    border: 1px solid var(--border); border-radius: 8px; padding: .6rem .8rem; margin-bottom: .75rem;
    background: var(--surface);
  }
  /* Label floats left, the value (which may be several inline pieces) flows on the right. */
  table.responsive td {
    display: flow-root; padding: .3rem 0; border: 0; text-align: right;
    overflow-wrap: anywhere; white-space: normal;
  }
  table.responsive td[data-label]::before {
    content: attr(data-label); float: left; margin-right: 1rem; color: var(--muted); font-size: .8rem;
    line-height: 1.9;
  }
  /* The first cell is the card title. */
  table.responsive td:first-child { display: block; text-align: left; font-size: 1rem; padding-bottom: .4rem; }
  table.responsive td:first-child::before { display: none; }
  table.responsive td.actions { display: block; width: auto; padding-top: .6rem; }
  table.responsive td.actions .row-actions { justify-content: flex-start; flex-wrap: wrap; }

  /* Clients list: collapsed to just the name and notes; tap the card for everything else. */
  .page-clients table.responsive td:first-child { padding-right: 1.6rem; position: relative; }
  .page-clients table.responsive .tags,
  .page-clients table.responsive td:not(:first-child) { display: none; }
  .page-clients table.responsive tr.is-expanded .tags,
  .page-clients table.responsive tr.is-expanded td { display: flow-root; }
  .page-clients table.responsive tr.is-expanded td.actions { display: block; }
  .page-clients table.responsive tr { cursor: pointer; position: relative; }
  .page-clients table.responsive tr::after {
    content: "›"; position: absolute; top: .6rem; right: .8rem; color: var(--muted);
    transition: transform .15s; pointer-events: none;
  }
  .page-clients table.responsive tr.is-expanded::after { transform: rotate(90deg); }
}

/* Phone-sized forms, buttons and info lists. */
@media (max-width: 600px) {
  main { padding-top: 1rem; }
  h1 { font-size: 1.3rem; }
  input, select, textarea { font-size: 16px; }   /* smaller text makes iOS zoom in on focus */
  .btn { min-height: 40px; padding: .55rem .9rem; }
  .btn-small { min-height: 36px; padding: .45rem .75rem; }
  .card { padding: 1rem; }
  .stats { grid-template-columns: repeat(2, 1fr); gap: .6rem; }
  .stat-value { font-size: 1.3rem; }
  .stat-server .stat-value { font-size: 1.15rem; }
  .facts { grid-template-columns: 1fr; gap: .15rem; }
  .facts dd { margin-bottom: .5rem; }
  .script-paths { margin-left: 0; }
  .options-col .ip-input { max-width: none; }
  .form-end { flex-wrap: wrap; }
  .form-end .btn { flex: 1; text-align: center; }
  .page-head .btn { flex: none; }
  .toolbar input { min-width: 0; flex-basis: 100%; }
  .list-head > form:not(.toolbar) { width: 100%; }
  .list-head > form:not(.toolbar) .btn { width: 100%; }
  .muted.small, code { overflow-wrap: anywhere; }
}

/* Server page: one tab per VPN server. */
.tabs { display: flex; gap: .4rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.tabs a { display: inline-flex; align-items: center; gap: .45rem; padding: .45rem .8rem; border: 1px solid var(--border);
          border-radius: 8px; color: var(--text); background: var(--surface); }
.tabs a.active { border-color: var(--primary); box-shadow: inset 0 -2px 0 var(--primary); }
.section-title { margin: 2rem 0 1rem; font-size: 1.15rem; }

/* Dashboard: connected client names link to their Edit page. */
a.client-link { color: var(--text); text-decoration: underline; text-decoration-color: var(--border); text-underline-offset: 3px; }
a.client-link:hover, a.client-link:focus-visible { color: var(--primary); text-decoration-color: var(--primary); }

/* One-time setup links (Clients list, Edit client). */
/* Clients list: the setup-link buttons are a second line under Download / Edit / Revoke. */
.setup-link { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; flex-basis: 100%; justify-content: flex-end;
              margin-top: .15rem; }
.setup-link form { margin: 0; }
.setup-link-full { justify-content: flex-start; margin-bottom: .75rem; }
.setup-link.is-expired [data-copy]:not(.btn-copy) { display: none; }
.link-meta { white-space: nowrap; }
.passphrase { font-size: .8rem; letter-spacing: .02em; }
.btn-copy { font: inherit; font-size: .75rem; padding: 0 .35rem; border: 1px solid var(--border); border-radius: 4px;
            background: var(--surface); color: var(--muted); cursor: pointer; }
.btn-copy:hover { color: var(--text); border-color: var(--muted); }
.setup-commands { display: flex; flex-direction: column; gap: .6rem; }
.copy-row { display: flex; align-items: flex-start; gap: .5rem; }
.copy-row code { flex: 1; min-width: 0; overflow-wrap: anywhere; padding: .4rem .55rem; border: 1px solid var(--border);
                 border-radius: 6px; background: var(--bg); color: var(--text); font-size: .8rem; }
/* Clients list: Download / Edit / Revoke stay on one line; the setup-link buttons are the line below. */
td.actions .setup-link { flex-wrap: nowrap; justify-content: flex-start; margin-top: .4rem; }
@media (max-width: 700px) {
  td.actions .setup-link { flex-wrap: wrap; }
}

/* Clients list: line 2 = +10 min / KILL / time left, line 3 = CURL / WGET / PASS (hidden once expired). */
.setup-copy { display: flex; align-items: center; gap: .4rem; margin-top: .4rem; }
.setup-block.is-expired .setup-copy { display: none; }
@media (max-width: 700px) {
  .setup-copy { flex-wrap: wrap; }
}

/* "used 10:42 from 203.0.113.7" next to Setup link after a link was downloaded. */
.link-used { color: var(--ok-fg); white-space: nowrap; }

/* Two-factor login (Account page, login) */
.totp-qr { display: inline-block; background: #fff; padding: .5rem; border-radius: 8px; line-height: 0; }
.totp-qr svg { width: 220px; height: 220px; max-width: 100%; }
.totp-secret { word-break: break-all; letter-spacing: .05em; }
.backup-codes { columns: 2; gap: 1.5rem; padding-left: 1.5rem; margin: .5rem 0 1rem; }
.backup-codes code { font-size: .95rem; }
.code-input { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 1.2rem; letter-spacing: .15em; }

/* Backup & restore (Admins page): two columns, stacked on narrow screens. */
.backup-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: stretch; }
.backup-grid h3 { margin: 0; font-size: 1rem; }
@media (max-width: 760px) { .backup-grid { grid-template-columns: 1fr; gap: 1.5rem; } }
.recovery-key { font-size: 1.05rem; letter-spacing: .04em; word-break: break-all; }

/* Client groups: the group tag, and sortable column headers in the Clients list. */
.tag-group { display: inline-block; background: var(--info-bg); color: var(--info-fg); border-color: transparent; font-size: .78rem; font-weight: 600; text-decoration: none; white-space: nowrap; }
a.tag-group:hover { text-decoration: underline; }
.sort-link { color: inherit; text-decoration: none; white-space: nowrap; }
.sort-link:hover { text-decoration: underline; }
.sort-link.is-sorted { color: var(--text); font-weight: 700; }
/* Group dropdown in the Clients list: compact; tinted like the group tag when a group is set. */
.group-pick { margin: 0; }
.group-pick select { font-size: .8rem; padding: .2rem 1.6rem .2rem .45rem; min-width: 7rem; }
.group-pick select.has-group { background-color: var(--info-bg); color: var(--info-fg); font-weight: 600; }

/* info_tip(): a small "i" with its explanation as a tooltip (hover, tap or keyboard focus). */
.info-tip { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 1.05rem; height: 1.05rem;
  margin-left: .35rem; border-radius: 50%; border: 1px solid var(--muted); color: var(--muted); font: 600 .7rem/1 ui-serif, Georgia, serif;
  font-style: italic; cursor: help; vertical-align: middle; user-select: none; }
.info-tip:hover, .info-tip:focus { color: var(--primary); border-color: var(--primary); outline: none; }
.info-tip:hover::after, .info-tip:focus::after {
  /* Anchored at the icon's own left edge so it opens down and to the right by default; JS nudges
     --tip-left negative only if that would run past the right edge of the window. */
  content: attr(data-tip); position: absolute; z-index: 40; top: calc(100% + .45rem); left: var(--tip-left, 0);
  width: max-content; max-width: min(22rem, calc(100vw - 2rem)); padding: .55rem .7rem; border-radius: 8px;
  background: var(--text); color: var(--surface); font: 400 .8rem/1.45 system-ui, sans-serif; font-style: normal;
  white-space: normal; text-align: left; box-shadow: 0 6px 20px rgba(0, 0, 0, .25); }

/* Two columns of cards where there's room (Server page); one column on narrow screens. */
/* Cards side by side get the same height (the row's tallest). */
.card-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; align-items: stretch; margin-bottom: 1.25rem; }
.card-grid > .card { margin: 0; }
@media (max-width: 900px) { .card-grid { grid-template-columns: minmax(0, 1fr); } }
.card-grid > .card-wide { grid-column: 1 / -1; }

/* Two-column cards: content from the top, the submit button(s) in the bottom-right corner.
   .card-form fills the card and pins its .form-actions to the bottom; .card-bottom pushes a
   one-line form or toolbar there. */
.card-grid > .card { display: flex; flex-direction: column; }
.card-form { flex: 1; display: flex; flex-direction: column; gap: .9rem; }
.form-actions { margin-top: auto; display: flex; justify-content: flex-end; align-items: center; gap: .5rem; flex-wrap: wrap; }
.card-grid > .card > .card-bottom { margin-top: auto; margin-bottom: 0; display: flex; justify-content: flex-end; align-items: center; gap: .5rem; flex-wrap: wrap; }

/* Clients: the table has many columns; where there's room, short values stay on one line instead
   of wrapping (the page uses the same width as the rest of the panel, see "main" above). */
@media (min-width: 701px) {
  .page-clients table.responsive th,
  .page-clients td[data-label="Group"], .page-clients td[data-label="Server"], .page-clients td[data-label="VPN IP"],
  .page-clients td[data-label="Email"], .page-clients td[data-label="Status"], .page-clients td[data-label="Expires"],
  .page-clients td[data-label="Created"] { white-space: nowrap; }
  .page-clients td[data-label="Name"] > a, .page-clients td[data-label="Name"] > strong { white-space: nowrap; }
  /* Narrow columns shrink to fit their content instead of sharing the table's width equally;
     Name and Email (the variable-length ones) take up the rest. */
  .page-clients table.responsive { table-layout: auto; }
  .page-clients td[data-label="Group"], .page-clients th:nth-child(2),
  .page-clients td[data-label="Server"], .page-clients th:nth-child(3),
  .page-clients td[data-label="VPN IP"], .page-clients th:nth-child(4),
  .page-clients td[data-label="Status"], .page-clients th:nth-child(6),
  .page-clients td[data-label="Expires"], .page-clients th:nth-child(7),
  .page-clients td[data-label="Created"], .page-clients th:nth-child(8) { width: 1%; }
}
