/* The hosted console shell, from section 1b of the Flanner mockups.
 *
 * Structure only. Every colour comes from tokens.css so that both themes
 * resolve as a set; a literal here would render one theme's ink on the
 * other theme's ground for anyone following their OS setting.
 */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--app-bg);
  color: var(--text);
  font: 400 14px/1.55 var(--font-sans);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent-ink); text-decoration: none; }
a:hover { text-decoration: underline; }
.mono, code { font-family: var(--font-mono); font-size: .88em; }
.tnum { font-variant-numeric: tabular-nums; }
.dim { color: var(--text-3); }

:where(a, button, input, select, summary):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
.skip-link {
  position: absolute; left: -9999px; top: 8px; z-index: 60;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 14px; font-weight: 600;
}
.skip-link:focus { left: 8px; }

/* --- shell ---------------------------------------------------------------- */

.shell { display: flex; min-height: 100vh; align-items: stretch; }

.rail {
  width: 248px; flex: none;
  display: flex; flex-direction: column; gap: 4px;
  padding: 16px 12px;
  background: var(--rail-bg);
  border-right: 1px solid var(--border);
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
}
.rail-brand { display: flex; align-items: center; gap: 10px; padding: 6px 8px 14px; }
.rail-mark {
  width: 26px; height: 26px; border-radius: 7px; flex: none;
  background: var(--accent-grad);
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff; font: 700 13px var(--font-mono);
}
.rail-org {
  font-weight: 600; font-size: 14px; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rail-eyebrow {
  font: 600 10.5px var(--font-mono); color: var(--text-4);
  letter-spacing: .06em; padding: 4px 10px 6px;
}

/* The organisation switcher. Rendered as a menu only when there is more
   than one membership to switch to, so a single-team account sees a label
   and not a control that does nothing. */
.org-switch { margin-left: auto; position: relative; }
.org-switch > summary {
  list-style: none; cursor: pointer; color: var(--text-4);
  font-size: 11px; padding: 2px 4px; border-radius: 5px;
}
.org-switch > summary::-webkit-details-marker { display: none; }
.org-switch > summary:hover { color: var(--text); background: var(--chip); }
.org-menu {
  position: absolute; right: 0; top: 22px; z-index: 30; min-width: 210px;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: var(--shadow-pop); padding: 5px;
}
.org-menu button {
  display: block; width: 100%; text-align: left; border: 0; background: none;
  font: inherit; font-size: 13px; color: var(--text-2);
  padding: 7px 9px; border-radius: 7px; cursor: pointer;
}
.org-menu button:hover { background: var(--chip); color: var(--text); }
.org-menu button[aria-current="true"] { color: var(--text); font-weight: 600; }

.rail-nav { display: flex; flex-direction: column; gap: 2px; font-size: 13.5px; }
.rail-nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: 8px;
  color: var(--text-2); text-decoration: none;
}
.rail-nav a:hover { background: var(--chip); color: var(--text); text-decoration: none; }
.rail-nav a.active { background: var(--nav-active); color: var(--text); font-weight: 600; }
.rail-nav .glyph { width: 15px; text-align: center; flex: none; }
.rail-nav .n {
  margin-left: auto; font: 500 11px var(--font-mono); color: var(--text-3);
  white-space: nowrap;
}
.rail-nav .n.live { color: var(--accent-ink-hi); }

.rail-foot { margin-top: auto; display: flex; flex-direction: column; gap: 10px; padding-top: 14px; }
.e2e {
  border: 1px solid var(--accent-line); background: var(--accent-soft);
  border-radius: 10px; padding: 12px; font-size: 12px; line-height: 1.5;
}
.e2e .hd {
  display: flex; align-items: center; gap: 7px;
  font-weight: 600; color: var(--accent-ink); margin-bottom: 4px;
}
.e2e .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--fresh); flex: none; }
.e2e p { margin: 0; color: var(--text-2); }

.rail-user { display: flex; align-items: center; gap: 9px; padding: 4px 4px 0; }
.avatar {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  background: var(--chip); color: var(--text-2);
  display: inline-flex; align-items: center; justify-content: center;
  font: 600 11px var(--font-mono);
}
.rail-user .who { min-width: 0; line-height: 1.3; }
.rail-user .who b { display: block; font-size: 12.5px; font-weight: 600; }
.rail-user .who span {
  display: block; font-size: 11px; color: var(--text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rail-user form { margin-left: auto; }

/* --- main column ---------------------------------------------------------- */

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 18px 26px; border-bottom: 1px solid var(--border);
  background: var(--card);
}
.topbar h1 { font-size: 19px; font-weight: 700; letter-spacing: -.015em; margin: 0; }
.topbar .sub { font-size: 12.5px; color: var(--text-3); }
.topbar .actions { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.relay-state {
  display: inline-flex; align-items: center; gap: 7px;
  font: 500 12px var(--font-mono); color: var(--text-3);
}
.relay-state .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--fresh); }
.relay-state.down .dot { background: var(--stale); }

.pane { padding: 22px 26px 60px; display: flex; flex-direction: column; gap: 18px; }
.pane.narrow { max-width: 780px; }
.pane.centred { max-width: 460px; margin: 0 auto; padding-top: 64px; }

/* --- cards ---------------------------------------------------------------- */

.card {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r-lg); overflow: hidden;
}
.card-pad { padding: 18px; }
.card-head {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px; border-bottom: 1px solid var(--divider);
  font-size: 13.5px; font-weight: 600;
}
.card-head .note { font-weight: 400; font-size: 12px; color: var(--text-3); }
.card-head .spacer { margin-left: auto; }
.card-title { font-size: 14px; font-weight: 700; margin: 0 0 12px; }
.card.empty { padding: 40px 20px; text-align: center; }
.card.empty h2 { font-size: 15px; margin: 0 0 6px; }
.card.empty p { margin: 0 auto 14px; max-width: 46ch; font-size: 13px; color: var(--text-3); }

.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.stat {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: 14px 16px;
}
.stat .v {
  font: 700 22px/1.1 var(--font-sans); letter-spacing: -.02em;
  display: flex; align-items: center; gap: 8px;
}
.stat .k { font-size: 11.5px; color: var(--text-3); margin-top: 5px; }
.stat .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }

/* --- tables --------------------------------------------------------------- */

.tablewrap { overflow-x: auto; }
.grid-head, .grid-row {
  display: grid; gap: 0 14px; padding: 10px 18px; align-items: center;
}
.grid-head {
  font-size: 11.5px; color: var(--text-4);
  border-bottom: 1px solid var(--divider);
}
.grid-row { padding: 13px 18px; border-bottom: 1px solid var(--divider); font-size: 13px; }
.grid-row:last-child { border-bottom: 0; }
.grid-row:hover { background: var(--card-sunken); }
.grid-row .name { font-weight: 600; color: var(--text); }
.grid-row .sub { font-weight: 400; font-size: 12px; color: var(--text-3); margin-top: 2px; }
.grid-row .when { font-size: 12px; color: var(--text-3); }
.grid-row .id { font: 500 11.5px var(--font-mono); color: var(--text-3); }

.cols-devices { grid-template-columns: 1.5fr 110px 130px 110px 1fr 90px; }
.cols-members { grid-template-columns: 1.6fr 110px 120px 100px; }
.cols-audit   { grid-template-columns: 150px 1.2fr 1.5fr 130px; }
.cols-grants  { grid-template-columns: 1fr 200px; }

/* --- pills and states ------------------------------------------------------ */

.pill {
  display: inline-block; font: 600 11px var(--font-mono);
  border-radius: 10px; padding: 2px 8px; white-space: nowrap;
}
.pill-on    { color: var(--fresh-text);   background: var(--fresh-bg); }
.pill-warn  { color: var(--aging-text);   background: var(--aging-bg); }
.pill-off   { color: var(--stale-text);   background: var(--stale-bg); }
.pill-quiet { color: var(--text-3);       background: var(--chip); }

.reach { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-2); }
.reach .bars { display: inline-flex; gap: 2px; align-items: flex-end; }
.reach .bars i { width: 3px; border-radius: 1px; background: var(--drift-empty); }
.reach .bars i:nth-child(1) { height: 6px; }
.reach .bars i:nth-child(2) { height: 9px; }
.reach .bars i:nth-child(3) { height: 12px; }
.reach[data-reach="direct"]  .bars i { background: var(--fresh); }
.reach[data-reach="relayed"] .bars i:nth-child(-n+2) { background: var(--aging); }
.reach[data-reach="none"]    .bars i { background: var(--drift-empty); }

/* --- buttons and forms ----------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; gap: 7px;
  font: 500 13px var(--font-sans); color: var(--text-2);
  background: var(--card); border: 1px solid var(--border);
  border-radius: 8px; padding: 7px 13px; cursor: pointer;
  text-decoration: none; white-space: nowrap;
}
.btn:hover { color: var(--text); border-color: var(--border-firm); background: var(--card-sunken); text-decoration: none; }
.btn-primary {
  color: #fff; background: var(--accent); border-color: var(--accent);
}
.btn-primary:hover { color: #fff; background: var(--accent-hi); border-color: var(--accent-hi); }
.btn-sm { font-size: 12px; padding: 4px 9px; border-radius: 6px; }
.btn-danger { color: var(--stale-text); }
.btn-danger:hover { color: var(--stale-text); border-color: var(--stale); }
.btn-quiet { border-color: transparent; background: none; color: var(--text-3); }
.btn-quiet:hover { color: var(--text); background: var(--chip); border-color: transparent; }

form.inline { display: inline; }
.field { display: flex; flex-direction: column; gap: 5px; }
.field-label { font-size: 12px; font-weight: 600; color: var(--text-2); }
.field-label .opt { font-weight: 400; color: var(--text-4); }
.input, select.input, textarea.input {
  font: 400 13.5px var(--font-sans); color: var(--text);
  background: var(--card); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 11px; width: 100%;
}
.input:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus); }
.input.mono { font-family: var(--font-mono); font-size: 12.5px; }
.hint { margin: 5px 0 0; font-size: 12px; color: var(--text-3); }
.form-row { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
.form-row .field { flex: 1; min-width: 200px; }

.switch-row { display: flex; align-items: center; gap: 12px; padding: 11px 0; flex-wrap: wrap; }
.switch-row + .switch-row { border-top: 1px solid var(--divider); }
.switch-row .body { font-size: 13px; font-weight: 600; min-width: 0; }
.switch-row .body span {
  display: block; font-weight: 400; font-size: 12px; color: var(--text-3);
  overflow-wrap: anywhere;
}

.kv { display: flex; align-items: baseline; gap: 12px; padding: 7px 0; font-size: 13px; }
.kv + .kv { border-top: 1px solid var(--divider); }
.kv > span:first-child { color: var(--text-3); min-width: 150px; flex: none; }
.kv b { font-weight: 600; }

/* --- notices --------------------------------------------------------------- */

.notice {
  border: 1px solid var(--border); border-left-width: 3px;
  border-radius: 10px; padding: 12px 14px; font-size: 13px;
  background: var(--card); color: var(--text-2);
}
.notice p { margin: 0 0 8px; }
.notice p:last-child { margin-bottom: 0; }
.notice strong { color: var(--text); }
.notice.good { border-left-color: var(--fresh); background: var(--fresh-bg); }
.notice.bad  { border-left-color: var(--stale); background: var(--stale-bg); }
.notice.info { border-left-color: var(--suspect); background: var(--suspect-bg); }

/* Not flex. A flex container makes every child a column, so a footnote
   containing a link or a <code> broke into shrink-wrapped columns with
   gaps mid-sentence. The chip floats instead, which lets the text flow as
   one paragraph however it is marked up. */
.footnote {
  font-size: 12px; color: var(--text-4); line-height: 1.5;
}
.footnote .i {
  float: left; width: 15px; height: 15px; border-radius: 50%;
  margin: 1px 9px 0 0;
  background: var(--chip); color: var(--text-3);
  display: inline-flex; align-items: center; justify-content: center;
  font: 600 10px var(--font-mono);
}
/* Confine the float, so two footnotes in a row cannot have the second's
   text ride up beside the first's chip. */
.footnote::after { content: ""; display: block; clear: both; }

/* --- setup checklist and activity ------------------------------------------ */

.checklist { display: flex; flex-direction: column; }
.checklist .step {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 18px; font-size: 13px;
}
.checklist .step + .step { border-top: 1px solid var(--divider); }
.checklist .box {
  width: 18px; height: 18px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 700;
  border: 1px solid var(--border-firm); color: var(--text-4);
}
.checklist .step.done .box {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
.checklist .step .what { font-weight: 600; }
.checklist .step .why { color: var(--text-3); font-size: 12px; }
.checklist .step .why::before { content: "·"; margin: 0 6px; color: var(--text-4); }
.checklist .step .go { margin-left: auto; }

.feed { display: flex; flex-direction: column; }
.feed .row { display: flex; align-items: center; gap: 11px; padding: 11px 18px; font-size: 13px; }
.feed .row + .row { border-top: 1px solid var(--divider); }
.feed .mark {
  width: 10px; height: 10px; border-radius: 3px; flex: none;
  background: var(--text-4);
}
.feed .mark[data-kind="device"]  { background: var(--accent); }
.feed .mark[data-kind="member"]  { background: var(--mark-people); }
.feed .mark[data-kind="access"]  { background: var(--mark-jira); }
.feed .mark[data-kind="billing"] { background: var(--mark-warm); }
.feed .mark[data-kind="revoke"]  { background: var(--mark-alert); }
.feed .what { min-width: 0; }
.feed .what b { font-weight: 600; }
.feed .what span { color: var(--text-3); }
.feed .when { margin-left: auto; font-size: 11.5px; color: var(--text-4); white-space: nowrap; }

/* --- plan tiers (billing) --------------------------------------------------- */

.tiers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; align-items: stretch; }
.tier {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: 18px; display: flex; flex-direction: column; gap: 10px;
}
.tier.current { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.tier .badge {
  align-self: flex-start; font: 600 10px var(--font-mono); letter-spacing: .05em;
  color: var(--accent-ink); background: var(--accent-soft);
  border-radius: 5px; padding: 2px 6px;
}
.tier h3 { margin: 0; font-size: 15px; font-weight: 700; }
.tier .price { display: flex; align-items: baseline; gap: 5px; }
.tier .price .amt { font: 700 26px/1 var(--font-sans); letter-spacing: -.02em; }
.tier .price .per { font-size: 12px; color: var(--text-3); }
.tier .blurb { font-size: 12.5px; color: var(--text-3); margin: 0; }
.tier ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.tier li { display: flex; gap: 8px; font-size: 12.5px; color: var(--text-2); }
.tier li::before { content: "✓"; color: var(--accent-ink); font-weight: 700; flex: none; }
.tier .foot { margin-top: auto; }

.segmented {
  display: inline-flex; background: var(--chrome); border: 1px solid var(--border);
  border-radius: 8px; padding: 2px; gap: 2px;
}
.segmented a, .segmented button {
  font: 500 12px var(--font-sans); color: var(--text-3);
  background: none; border: 0; border-radius: 6px; padding: 4px 11px; cursor: pointer;
  text-decoration: none;
}
.segmented a.on, .segmented button[aria-pressed="true"] {
  background: var(--card); color: var(--text); font-weight: 600;
  box-shadow: 0 1px 2px rgba(10, 12, 16, .06);
}
.segmented .save { color: var(--accent-ink); font-size: 11px; margin-left: 4px; }

/* --- dialogs ---------------------------------------------------------------- */

dialog {
  border: 1px solid var(--border); border-radius: 14px; padding: 0;
  background: var(--card); color: var(--text);
  box-shadow: var(--shadow-pop); max-width: 560px; width: calc(100% - 32px);
}
dialog::backdrop { background: rgba(10, 12, 16, .42); }
.dlg-head {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 18px; border-bottom: 1px solid var(--divider);
}
.dlg-head h2 { margin: 0; font-size: 15px; font-weight: 700; }
.dlg-head .x { margin-left: auto; }
.dlg-body { padding: 18px; display: flex; flex-direction: column; gap: 14px; }
.dlg-foot {
  display: flex; gap: 8px; justify-content: flex-end;
  padding: 14px 18px; border-top: 1px solid var(--divider); background: var(--card-sunken);
}

.steps { display: flex; gap: 8px; }
.steps .s { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text-4); }
.steps .s + .s::before { content: ""; width: 14px; height: 1px; background: var(--border-firm); }
.steps .s .n {
  width: 18px; height: 18px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font: 600 10px var(--font-mono);
  border: 1px solid var(--border-firm);
}
.steps .s.on { color: var(--text); font-weight: 600; }
.steps .s.on .n { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ------------------------------------------------------------ site footer */

.sitefoot {
  margin-top: auto; border-top: 1px solid var(--border);
  background: var(--rail-bg); padding: 18px 28px;
}
.sitefoot-in {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px 20px;
  font-size: 12px; color: var(--text-4);
}
.sitefoot .mark {
  display: inline-flex; align-items: center; gap: 7px;
  font-weight: 600; color: var(--text-3);
}
.sitefoot .mark .dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
}
.sitefoot .links { display: flex; flex-wrap: wrap; gap: 8px 18px; }
.sitefoot .links a { color: var(--text-3); }
.sitefoot .links a:hover { color: var(--text); text-decoration: underline; }
.sitefoot .note { margin-left: auto; }

.cmd {
  display: flex; align-items: center; gap: 10px;
  background: var(--term-bg); border-radius: 9px; padding: 11px 13px;
  font: 500 12.5px var(--font-mono); color: var(--term-text);
}
.cmd .p { color: var(--term-ok); flex: none; }
.cmd .t { flex: 1; overflow-x: auto; white-space: nowrap; }
/* An icon, not the word "Copy": the label was as wide as the command on a
   narrow card, and the button is the least interesting thing in the row. */
.cmd-copy {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; cursor: pointer;
  color: var(--term-dim); background: none;
  border: 1px solid var(--term-dim); border-radius: 6px;
}
.cmd-copy:hover { color: var(--term-text); border-color: var(--term-text); }
.cmd-copy:focus-visible { outline: 2px solid var(--term-ok); outline-offset: 2px; }
.cmd-copy .ic-done { display: none; }
.cmd-copy.is-copied { color: var(--term-ok); border-color: var(--term-ok); }
.cmd-copy.is-copied .ic-copy { display: none; }
.cmd-copy.is-copied .ic-done { display: block; }

.code-out {
  text-align: center; font: 700 26px/1 var(--font-mono);
  letter-spacing: .12em; padding: 14px; border-radius: 10px;
  background: var(--accent-soft); color: var(--accent-ink);
  border: 1px solid var(--accent-line);
}

/* --- sign-in / sign-up ------------------------------------------------------ */

.auth-mark {
  display: flex; align-items: center; gap: 10px; justify-content: center; margin-bottom: 22px;
}
.auth-mark b { font-size: 15px; font-weight: 700; }
.auth-card { display: flex; flex-direction: column; gap: 14px; }
.auth-card h1 { margin: 0; font-size: 20px; font-weight: 700; letter-spacing: -.015em; }

/* --- responsive -------------------------------------------------------------- */

/* The shell rules for a small screen live in the mobile block at the foot of
   this file. What is left here is the content. */
@media (max-width: 900px) {
  .pane { padding-left: 16px; padding-right: 16px; }
  .stat-grid, .tiers { grid-template-columns: 1fr 1fr; }
  .cols-devices, .cols-members, .cols-audit, .cols-grants {
    grid-template-columns: 1fr; gap: 6px;
  }
  .grid-head { display: none; }
  .input { max-width: 100%; }
}
@media (max-width: 560px) {
  .stat-grid, .tiers { grid-template-columns: 1fr; }
}

@media print {
  .rail, .topbar .actions, .btn { display: none; }
  body { background: #fff; }
}

/* Labels only a screen reader needs. The filter and sort controls read as
   what they are by placement and placeholder, but still need real labels. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Theme cycler and the list controls, in the top bar. */
.btn-icon { width: 30px; height: 30px; padding: 0; justify-content: center; font-size: 12px; }
.input-sm { font-size: 12.5px; padding: 5px 9px; width: auto; min-width: 170px; }
.empty-filter { padding: 26px 18px; text-align: center; font-size: 13px; color: var(--text-3); }

/* Boosted navigation. Pages that scan git take a second or more, and a swap
   with no browser spinner behind it needs to say so itself. */
.is-navigating { cursor: progress; }
.is-navigating .rail-nav a { pointer-events: none; }
.is-navigating::after {
  content: ""; position: fixed; inset: 0 auto auto 0; z-index: 90;
  height: 2px; width: 100%; transform-origin: 0 50%;
  background: var(--accent-grad);
  animation: nav-progress 1.4s ease-in-out infinite;
}
@keyframes nav-progress {
  0%   { transform: scaleX(0);   opacity: 1; }
  60%  { transform: scaleX(.75); opacity: 1; }
  100% { transform: scaleX(1);   opacity: .35; }
}
@media (prefers-reduced-motion: reduce) {
  .is-navigating::after { animation: none; transform: scaleX(1); opacity: .6; }
}

/* One control height across every top bar. Five had crept in - 23, 28, 30,
   31 and 35px - which reads as carelessness even when nobody can name what
   is wrong. The 32px is the size of the Projects sort menu, which is the one
   that looked right. Both apps use these same rules. */
.topbar .actions { --control-h: 32px; }
.topbar .actions form { display: flex; align-items: center; gap: 8px; margin: 0; }
.topbar .actions .btn,
.topbar .actions .input,
.topbar .actions select {
  height: var(--control-h);
  font-size: 12.5px;
  border-radius: 8px;
}
.topbar .actions .input,
.topbar .actions select { padding: 0 10px; min-width: 176px; width: auto; }
.topbar .actions .btn { padding: 0 14px; }
.topbar .actions .btn-icon { width: var(--control-h); min-width: 0; padding: 0; }
.topbar .actions .segmented { height: var(--control-h); align-items: center; }
.topbar .actions .segmented a,
.topbar .actions .segmented button { height: calc(var(--control-h) - 6px); display: inline-flex; align-items: center; }

/* Back to the page above this one. A real parent link, not history.back():
   arriving from a search or a bookmark should still offer the way up. */
.topbar .back {
  width: var(--control-h, 32px); height: var(--control-h, 32px);
  padding: 0; flex: none; font-size: 14px; justify-content: center;
}

/* `hidden` has to win. The browser's own [hidden] rule is weaker than any
   author declaration, so `.grid-row { display: grid }` quietly outranked it
   and every filtered-out row stayed on screen. */
[hidden] { display: none !important; }

/* --- custom select ---------------------------------------------------------
   The native control stays in the DOM and keeps doing the work; only its
   drawn presentation is replaced, because the option list is the one part of
   a <select> no stylesheet can reach. */
.sel { position: relative; display: inline-flex; }
.sel-native {
  position: absolute; opacity: 0; pointer-events: none;
  width: 100%; height: 100%; margin: 0;
}
.sel-button {
  display: inline-flex; align-items: center; gap: 8px;
  cursor: pointer; text-align: left;
}
.sel-button .sel-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sel-caret { color: var(--text-4); font-size: 11px; line-height: 1; flex: none; }
.sel-button[aria-expanded="true"] { border-color: var(--accent); box-shadow: var(--focus); }

.sel-list {
  position: absolute; z-index: 40; top: calc(100% + 5px); left: 0; min-width: 100%;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: var(--shadow-pop);
  padding: 5px; display: flex; flex-direction: column; gap: 1px;
  max-height: min(320px, 60vh); overflow-y: auto;
}
.sel-option {
  display: flex; align-items: center; gap: 8px;
  font: 400 12.5px var(--font-sans); color: var(--text-2);
  background: none; border: 0; border-radius: 7px;
  padding: 7px 10px; cursor: pointer; text-align: left; white-space: nowrap;
}
.sel-option:hover, .sel-option:focus-visible { background: var(--chip); color: var(--text); outline: none; }
.sel-option[aria-selected="true"] { color: var(--text); font-weight: 600; }
.sel-option[aria-selected="true"]::after {
  content: "¹3"; margin-left: auto; color: var(--accent-ink); font-weight: 700;
}
/* Right-aligned when the control sits at the right edge of the top bar, so
   the panel opens inward instead of off the page. */
.topbar .actions .sel-list { left: auto; right: 0; }

/* The filter and sort controls sit side by side in the top bar. This rule
   was missing entirely: `.listctl` was only ever styled inside the mobile
   media query, where it becomes a sheet, so on a wide screen it fell back
   to a plain block and stacked its children — which made the whole bar two
   rows tall and pushed the buttons out of line. */
.listctl { display: flex; align-items: center; gap: 8px; }

/* Hidden on a wide screen; the media query below turns it on. Declared
   first, because these have equal specificity and the last one would win. */
.menu-toggle, .rail-theme, .filter-toggle { display: none; }

/* --- mobile ------------------------------------------------------------------
 *
 * One header row, phone-first: menu, brand, search, theme. The navigation is a
 * drawer that covers the page rather than pushing it down, so opening the menu
 * never moves the thing you were reading. The filter and sort controls fold
 * into an icon and open as a sheet.
 */
@media (max-width: 900px) {
  .shell { flex-direction: column; }

  .rail {
    position: sticky; top: 0; z-index: 30;
    width: auto; height: auto;
    flex-direction: row; align-items: center; flex-wrap: nowrap; gap: 8px;
    padding: 8px 12px;
    border-right: 0; border-bottom: 1px solid var(--border);
    background: var(--rail-bg);
  }
  .rail-brand { padding: 0; flex: 1; min-width: 0; gap: 8px; }
  .rail-eyebrow, .rail-foot { display: none; }

  .menu-toggle, .rail-theme { display: inline-flex; }
  /* A thumb, not a mouse pointer: 40px is the smallest comfortable target. */
  .menu-toggle, .rail-theme, .rail-search { width: 40px; height: 40px; flex: none; }
  .menu-toggle { font-size: 15px; }
  .topbar-theme { display: none; }

  /* The palette trigger keeps only its icon; the full search opens on tap. */
  .rail-search {
    padding: 0; justify-content: center; margin: 0; gap: 0;
    border-radius: 8px;
  }
  .rail-search span:not(:first-child), .rail-search kbd { display: none; }
  .rail-search span:first-child { font-size: 15px; }

  /* The drawer itself. Fixed, over the page, with its own scrim. */
  .rail-nav {
    position: fixed; inset: 0 auto 0 0; z-index: 60;
    width: min(82vw, 320px); max-width: 100%;
    display: flex; flex-direction: column; gap: 2px;
    padding: 14px 12px; overflow-y: auto;
    background: var(--rail-bg); border-right: 1px solid var(--border);
    box-shadow: var(--shadow-pop);
    transform: translateX(-100%);
    transition: transform .18s ease-out;
    visibility: hidden;
  }
  .rail.is-open .rail-nav { transform: none; visibility: visible; }
  .rail-nav a { padding: 11px 12px; font-size: 15px; }
  .rail-nav .n { font-size: 12px; }

  .scrim {
    position: fixed; inset: 0; z-index: 55;
    background: rgba(10, 12, 16, .45);
    opacity: 0; pointer-events: none; transition: opacity .18s ease-out;
  }
  .scrim.is-open { opacity: 1; pointer-events: auto; }

  /* Top bar: back, title, then the two icons. */
  /* Wrapping is what lets a full-width row drop to the next line; without
     it a 100% flex-basis just shrinks back down again. */
  .topbar { padding: 10px 14px; gap: 7px; flex-wrap: wrap; }
  .topbar .actions { margin-left: auto; gap: 6px; --control-h: 38px; }
  .filter-toggle { display: inline-flex; width: 40px; height: 40px; font-size: 15px; }

  /* Filter and sort become a sheet, opened by that icon. */
  .listctl { display: none; }
  .listctl.is-open {
    position: fixed; inset: auto 0 0 0; z-index: 70;
    display: flex; flex-direction: column; gap: 10px;
    padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
    background: var(--card);
    border-top: 1px solid var(--border);
    border-radius: 14px 14px 0 0;
    box-shadow: var(--shadow-pop);
  }
  .listctl.is-open > *, .listctl.is-open form { width: 100%; }
  .listctl.is-open .input,
  .listctl.is-open select,
  .listctl.is-open .sel,
  .listctl.is-open .sel-button { width: 100%; min-width: 0; height: 44px; font-size: 15px; }
  .listctl.is-open .sel-list { left: 0; right: 0; bottom: calc(100% + 6px); top: auto; }

  .topbar .actions .btn { flex: 0 0 auto; }
  .sel-option { padding: 11px 12px; font-size: 14px; }
}

/* A key/value row holds a name, a device id and a timestamp. On a narrow card
   the three do not fit side by side, and the row was clipping its own content
   rather than wrapping. The id is one unbroken token, so it needs permission
   to break as well as room to wrap into. */
.kv { flex-wrap: wrap; }
.kv > * { min-width: 0; }
.kv .mono, .kv b { overflow-wrap: anywhere; }
.kv-end { margin-left: auto; }

/* The pairing code is a 24-character token, not the short one in the design.
   At 26px with letter-spacing it was wider than the dialog and made the whole
   thing scroll sideways. It wraps now, and shrinks with the viewport. */
.code-out {
  font-size: clamp(17px, 5.4vw, 26px);
  letter-spacing: .07em;
  line-height: 1.35;
  word-break: break-all;
  white-space: normal;
}

@media (max-width: 900px) {
  /* Label above value: side by side leaves no usable width for either. */
  .kv { flex-direction: column; align-items: flex-start; gap: 2px; }
  .kv > span:first-child { min-width: 0; }
  .kv-end { margin-left: 0; }
  /* The command is a single line by design, but on a phone wrapping it beats
     hiding half of it behind a scroll nobody notices. */
  .cmd { flex-wrap: wrap; }
  .cmd .t { white-space: normal; word-break: break-all; overflow-x: visible; }
}

/* The header stays above the scrim so the menu button can close what it
   opened; everything else behind is inert (see the mobile shell in the JS). */
@media (max-width: 900px) {
  .rail { z-index: 65; }
  .is-locked, .is-locked body { overflow: hidden; }
  [inert] { cursor: default; }
}

/* Paired fields sit side by side when there is room and stack when there is
   not. It was an inline grid, which no media query can answer. */
.field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.field-grid > .wide { grid-column: 1 / -1; }

@media (max-width: 900px) {
  .field-grid { grid-template-columns: 1fr; }

  /* Breadcrumbs get the line to themselves. Sharing it with four buttons
     squeezed the trail down to "che... serv..." and told you nothing.
     Scoped with :has, so pages whose title is a short heading keep their
     actions alongside it; a browser without :has simply keeps today's
     behaviour rather than breaking. */
  .topbar:has(.crumbs) .actions {
    flex: 1 1 100%; margin-left: 0; justify-content: flex-end;
  }
  .topbar .crumbs { flex: 1 1 auto; min-width: 0; }
}

/* A card heading carries a title, a count and a note; let them wrap. */
.card-head { flex-wrap: wrap; }
