/* Console layout — topnav (header) + contextual sidenav + main pane.
   See console/layout.md for the full navigation spec. */

/* --- Topnav: always present, holds the logo, main sections, and the
   user dropdown. The logo lives here, never in the sidenav — the
   sidenav is contextual to whichever section is active. Its height is a
   variable because the sticky sidenav sits right under it. --- */
:root { --topnav-h: 77px; }
.topnav { display: flex; align-items: center; gap: 28px; height: var(--topnav-h); padding: 0 24px; background: #fff; border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 20; }
.topnav-logo-link { display: flex; align-items: center; }
.topnav-logo { height: 56px; width: auto; display: block; } /* 2x the old 28px sidebar mark */
.topnav-main { display: flex; align-items: center; gap: 4px; flex: 1; }
.topnav-item { padding: 8px 14px; border-radius: 8px; font-weight: 600; font-size: 14px; color: var(--text-2); }
.topnav-item:hover { background: var(--panel-2); text-decoration: none; color: var(--text); }
.topnav-item.is-active { background: var(--accent-soft); color: var(--accent-2); }
.topnav-right { display: flex; align-items: center; gap: 10px; }

.user-menu { position: relative; }
.user-menu-trigger { background: none; border: 1px solid transparent; border-radius: 8px; padding: 8px 10px; font: inherit; font-size: 13px; color: var(--text); cursor: pointer; display: flex; align-items: center; gap: 4px; }
.user-menu-trigger:hover { background: var(--panel-2); }
.caret { font-size: 10px; color: var(--muted); }
.user-dropdown { position: absolute; top: calc(100% + 6px); right: 0; min-width: 220px; background: #fff; border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--sh-2, var(--shadow)); padding: 8px; z-index: 30; }
.user-dropdown-who { padding: 6px 10px 10px; }
.user-dropdown-sep, .row-menu-sep { border-top: 1px solid var(--line); margin: 6px 0; }
.user-dropdown-item, .row-menu-item { display: block; width: 100%; text-align: left; padding: 8px 10px; border-radius: 6px; font-size: 13.5px; color: var(--text); background: none; border: 0; cursor: pointer; font: inherit; }
.user-dropdown-item:hover, .row-menu-item:hover { background: var(--panel-2); text-decoration: none; }
.who-name { font-weight: 600; font-size: 13px; line-height: 1.2; }
.who-email { font-size: 11.5px; color: var(--muted); }
/* Phone-only parts of the menu: its button's icon and the sections. */
.user-menu-icon, .user-dropdown-sections { display: none; }
.user-dropdown-item.is-active { background: var(--accent-soft); color: var(--accent-2); font-weight: 600; }
.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; }

/* --- App body: sidenav (only when a section has sub-pages) + main. --- */
.app-body { display: flex; min-height: calc(100vh - var(--topnav-h)); }
.sidenav { width: 220px; flex: none; background: #fff; border-right: 1px solid var(--line); padding: 18px 12px; position: sticky; top: var(--topnav-h); height: calc(100vh - var(--topnav-h)); }
.nav { display: flex; flex-direction: column; gap: 2px; }
.nav-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 8px; color: var(--text-2); font-weight: 500; }
.nav-item:hover { background: var(--panel-2); text-decoration: none; color: var(--text); }
.nav-item.is-active { background: var(--accent-soft); color: var(--accent-2); }
.nav-item.is-active .nav-icon { color: var(--accent); }
.nav-icon { width: 18px; text-align: center; color: var(--muted); }

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

/* --- Breadcrumb: the way back, whether or not a sidenav is showing. --- */
.breadcrumb { padding: 14px 28px 0; font-size: 13px; color: var(--muted); }
.breadcrumb a { color: var(--muted); }
.breadcrumb a:hover { color: var(--accent-2); }
.crumb-sep { margin: 0 6px; }
.crumb-current { color: var(--text); font-weight: 500; }

.page { padding: 16px 28px 24px; max-width: 1180px; width: 100%; }

/* Shell-level banners (the finish-setup banner, ?flash= messages) run
   edge to edge under the topnav, but their text is padded to the same
   column as .page: 28px in, and ending where .page's 1180px cap does. */
.main > .flash { margin: 0; border-radius: 0; border-width: 0 0 1px; padding: 10px max(28px, calc(100% - 1180px + 28px)) 10px 28px; }

/* On a sidenav-less page (main-wide), the content otherwise sits flush
   against the left edge while the sidenav pages start ~220px in --
   pad both sides out to roughly where a sidenav's content would
   begin (symmetric, not just the left, so the page reads as
   deliberately margined rather than accidentally off-centre), and
   drop the 1180px cap entirely: these are exactly the pages (Clusters,
   Account settings, ...) whose tables are expected to grow more
   columns over time, so the content between the margins should use
   whatever width is actually available rather than stopping short.
   Collapses back to the normal symmetric padding below the width
   where the sidenav itself stops being assumed to fit (matches the
   .grid-2 breakpoint elsewhere in this file). */
@media (min-width: 1001px) {
  .main-wide .breadcrumb { padding-left: 248px; padding-right: 248px; }
  .main-wide .page { padding-left: 248px; padding-right: 248px; max-width: none; }
  .main-wide > .flash { padding-left: 248px; padding-right: 248px; }
}
/* The title keeps the gap to the page below it; a subtitle, where a page
   has one, pulls up under it and takes the gap over. */
.page-title { font-size: 24px; font-weight: 700; letter-spacing: -.01em; margin: 0 0 24px; }
.page-sub { color: var(--muted); margin: -20px 0 24px; }

.panel { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: 22px; }
.panel-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 8px 12px; padding: 14px 18px; border-bottom: 1px solid var(--line); }
.panel-head h2 { margin: 0; font-size: 15px; font-weight: 600; }
.panel-body { padding: 8px 4px; }
/* Prose panel bodies (no table, no .form) need real padding -- the
   thin 8px/4px above exists because table cells and .form already
   supply their own, wider padding and would double up otherwise. */
.panel-copy { padding: 8px 18px 16px; }
.panel-copy p { margin: 0 0 10px; }
.panel-copy p:last-child { margin-bottom: 0; }

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

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; margin-bottom: 24px; }
.stat-card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px; color: inherit; transition: transform .08s ease, box-shadow .12s ease; box-shadow: var(--shadow); }
.stat-card:hover { transform: translateY(-1px); text-decoration: none; }
.stat-label { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; font-weight: 600; }
.stat-value { font-size: 30px; font-weight: 700; margin-top: 4px; color: var(--text); }
.stat-foot { font-size: 12px; margin-top: 4px; }

table.data { width: 100%; border-collapse: collapse; font-size: 13px; }
table.data thead th { text-align: left; padding: 10px 18px; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; font-size: 11.5px; border-bottom: 1px solid var(--line); }
table.data tbody td { padding: 12px 18px; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: var(--panel-2); }
/* A table cell, not a flex box: display:flex takes the cell out of the
   row's height, so its borders stop lining up with its neighbours'. */
table.data td.actions > form, table.data td.actions > .btn, table.data td.actions > .badge { display: inline-flex; vertical-align: middle; margin: 2px 6px 2px 0; }
table.data td.actions > :last-child { margin-right: 0; }
/* The actions column is as narrow as its content and keeps it at the
   row's end: a ⋯ button, or the one inline button a row may have. */
table.data td.actions { width: 1%; white-space: nowrap; text-align: right; }
/* A row's ⋯ menu: a popover, so it sits above the table's scroll box
   rather than being clipped by it; console.js places it by the button. */
.row-menu { position: fixed; inset: auto; margin: 0; min-width: 180px; padding: 6px; background: #fff; border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); color: var(--text); text-align: left; }
.row-menu form { margin: 0; }
.row-menu-item.danger { color: var(--danger); }
.row-menu-item.danger:hover { background: var(--danger-soft); }
table.data td.nowrap { white-space: nowrap; }
/* A flash inside a table/form panel body lines up with its .form. */
.panel-body > .flash { margin: 6px 12px 14px; }
table.data code.record-bytes { display: block; max-width: 48ch; max-height: 9em; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; }
table.data code.record-bytes + code.record-bytes { margin-top: 4px; }
table.data td input:not([type=checkbox]):not([type=hidden]) { padding: 5px 8px; border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: #fff; font-size: 13px; }
/* An edit row's one field with its buttons beside it and the hint under
   them (a topic config key, a quota). */
.edit-line { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.edit-line + .field-hint { margin-top: 6px; }
/* A topic config key's edit row: what the key does, then its field, a
   list's select as wide and as tall as a typed value's input. */
.config-help { margin: 0 0 14px; max-width: 72ch; font-size: 13px; line-height: 1.5; color: var(--text-2); }
table.data td .config-field { width: 220px; }
table.data td select.config-field { padding-top: 5px; padding-bottom: 5px; }
.muted.small { font-size: 12px; margin-top: 6px; }
.form .checkbox { display: flex; flex-direction: row; align-items: center; gap: 8px; font-size: 13px; color: var(--text); }
.form .checkbox input { width: auto; }
.hidden { display: none !important; }

.filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: end; margin-bottom: 18px; }
.filters label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
.filters input { padding: 7px 10px; border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: #fff; }

.form { padding: 16px 18px; background: var(--panel-2); border: 1px dashed var(--line-2); border-radius: var(--radius-sm); margin: 6px 12px 14px; }
.form.hidden { display: none; }
.form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; align-items: end; }
.form label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--text-2); font-weight: 500; }
.form textarea { padding: 7px 10px; border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: #fff; font: 12.5px/1.5 var(--mono); resize: vertical; }
.form input { padding: 7px 10px; border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: #fff; font-size: 13px; }
/* The submit button is a grid item too, but it must never stretch to
   fill its (potentially wide) column like the fields beside it. */
.form-row > .btn { justify-self: start; width: auto; }
.form-row + .form-row { margin-top: 12px; }

/* Tom Select (vendored at /static/vendor/tom-select) reskinned to the
   app's own tokens -- every plain <select> is enhanced into one of
   these by console.js, so this replaces the browser's native
   dropdown chrome everywhere, not just in one form. */
.ts-wrapper.single .ts-control { padding: 7px 10px; }
.ts-control, .ts-wrapper.single .ts-control input {
  border: 1px solid var(--line-2);
  border-radius: var(--radius-sm);
  background: #fff;
  font: 13px var(--font);
  color: var(--text);
  box-shadow: none;
}
.focus > .ts-control { border-color: var(--accent-line); box-shadow: 0 0 0 3px var(--accent-soft); }
.ts-control > input::placeholder { color: var(--muted); }
.ts-wrapper.disabled .ts-control { background: var(--panel-2); color: var(--muted); }
.ts-dropdown {
  border: 1px solid var(--line-2);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  font: 13px var(--font);
  margin-top: 4px;
  z-index: 40;
}
.ts-dropdown .option, .ts-dropdown .optgroup-header, .ts-dropdown .no-results, .ts-dropdown .create { padding: 7px 10px; }
.ts-dropdown [data-selectable].option { color: var(--text); }
.ts-dropdown .active { background: var(--accent-soft); color: var(--text); }
.ts-dropdown [data-selectable] .highlight { background: none; font-weight: 700; color: var(--accent-2); }
.ts-dropdown .no-results { color: var(--muted); }

/* Every plain <select> gets this skin, not just the ones TomSelect
   enhances -- a handful (the members table's role select, which
   submits on change) are deliberately excluded from TomSelect in
   console.js, and a bare native <select> looked completely
   out-of-brand next to it. TomSelect hides its source <select>
   (display:none, replaced by .ts-wrapper), so styling it here too is
   harmless -- this is also what a select looks like if JS never runs. */
select {
  appearance: none;
  -webkit-appearance: none;
  padding: 7px 30px 7px 10px;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-sm);
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23717b91' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 10px center;
  font: 13px var(--font);
  color: var(--text);
  cursor: pointer;
}
select:hover { border-color: var(--line-2); background-color: var(--panel-2); }
select:focus-visible { outline: none; border-color: var(--accent-line); box-shadow: 0 0 0 3px var(--accent-soft); }
select:disabled { background-color: var(--panel-2); color: var(--muted); cursor: default; }

/* Reset-offsets form: a multi-fieldset .form, not a single .form-row --
   "which partitions" and "where to move them" are two separate
   decisions and read better visually grouped apart, with the submit
   action set off from the fields rather than crammed into their grid. */
.reset-offsets-form fieldset { border: 0; padding: 0; margin: 0 0 16px; }
.reset-offsets-form fieldset:last-of-type { margin-bottom: 0; }
.reset-offsets-form legend { padding: 0 0 8px; font-size: 12px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.reset-offsets-footer { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.reset-offsets-footer p { margin: 0; }

.steps { padding-left: 22px; margin: 0; }
.steps li { margin: 8px 0; }

/* Auth */
.auth-bg { min-height: 100vh; display: grid; place-items: center; background: linear-gradient(180deg, #f9fdfb, #f1f8f4); }
.auth-card { background: #fff; padding: 36px; border-radius: 16px; box-shadow: 0 12px 40px rgba(5,150,105,.12); width: 380px; max-width: 92vw; }
.auth-card.wide { width: 640px; }
.auth-inner { display: flex; flex-direction: column; gap: 12px; }
.auth-brand { display: flex; align-items: center; gap: 10px; }
.brand-logo { height: 40px; width: auto; display: block; }
.brand-logo.big { height: 48px; }
.auth-title { font-size: 22px; font-weight: 700; margin: 6px 0 0; }
.auth-sub { color: var(--muted); margin: 0; }
.auth-form { display: flex; flex-direction: column; gap: 12px; margin-top: 8px; }
.auth-form label { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; font-weight: 500; color: var(--text-2); }
.auth-form input { padding: 10px 12px; border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: #fff; font-size: 14px; }
.auth-form input:focus { outline: 2px solid var(--accent-line); border-color: var(--accent); }
.auth-form label.check { flex-direction: row; align-items: center; gap: 8px; font-weight: 400; color: var(--text); }
.auth-form label.check input { margin: 0; padding: 0; }
.auth-form input.code-input { font-family: var(--mono); font-size: 20px; letter-spacing: 3px; text-transform: uppercase; text-align: center; }
.auth-foot { font-size: 12.5px; margin-top: 4px; }
form.auth-foot { margin: 0; }
/* "Finish setting up" banner above every page of an account whose signup
   Checkout is unfinished. A form, so the button can POST straight to it. */
.flash.warn { background: var(--warn-soft); border-color: #f0d8a4; color: var(--warn); }
.setup-banner { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
/* Plan choice on /onboarding: two radio cards side by side inside .auth-form,
   stacked when the card is narrow. The radio sits top-left of each card. The
   same cards pick a region, in the wizard and in the cluster list's .form. */
.plan-choice { border: 0; margin: 0; padding: 0; min-width: 0; }
.plan-choice legend { display: flex; justify-content: space-between; width: 100%; font-size: 12.5px; font-weight: 500; color: var(--text-2); margin-bottom: 6px; padding: 0; }
.plan-choice legend a { font-weight: 400; }
.form .plan-choice legend { font-size: 12px; }
.plan-choice > .field-hint { margin-top: 8px; }
.plan-opts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 600px) { .plan-opts { grid-template-columns: 1fr; } }
.auth-form .plan-opt, .form .plan-opt { position: relative; display: block; padding: 14px 14px 12px 40px; border: 1px solid var(--line-2); border-radius: var(--radius-sm); cursor: pointer; font-weight: 400; font-size: 12.5px; color: var(--text-2); }
.form .plan-opt { background: var(--panel); }
.auth-form .plan-opt:has(input:checked), .form .plan-opt:has(input:checked) { border-color: var(--accent); background: var(--ok-soft); box-shadow: 0 0 0 1px var(--accent) inset; }
.auth-form .plan-opt input, .form .plan-opt input { position: absolute; left: 14px; top: 16px; margin: 0; padding: 0; }
.plan-opt-hd { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.plan-opt-hd strong { color: var(--text); font-size: 14.5px; }
.plan-opt-price { color: var(--text); font-weight: 700; font-size: 15px; white-space: nowrap; }
.plan-opt-price small { color: var(--muted); font-weight: 400; font-size: 11.5px; }
.plan-opt ul { margin: 10px 0 0; padding: 0 0 0 14px; display: grid; gap: 5px; line-height: 1.35; }
.plan-opt-note { display: block; margin-top: 4px; line-height: 1.35; }
/* The "Next, ..." note under the form follows the selected plan. */
.plan-note-paid { display: none; }
.auth-inner:has(input[name="plan"][value="paid"]:checked) .plan-note-free { display: none; }
.auth-inner:has(input[name="plan"][value="paid"]:checked) .plan-note-paid { display: block; }

/* Onboarding stepper: Organization -> Billing details -> First cluster. */
.wizard-steps { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; list-style: none; margin: 2px 0 0; padding: 0; font-size: 12.5px; color: var(--muted); }
.wizard-steps li { display: flex; align-items: center; gap: 6px; }
.wizard-steps li + li::before { content: ""; width: 18px; border-top: 1px solid var(--line-2); margin-right: 2px; }
.wizard-step-n { width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; border: 1px solid var(--line-2); font-size: 11px; font-weight: 600; }
.wizard-steps .is-current { color: var(--text); font-weight: 600; }
.wizard-steps .is-current .wizard-step-n { background: var(--accent); border-color: var(--accent); color: #fff; }
.wizard-steps .is-done .wizard-step-n { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-2); }

/* First-cluster wizard (/onboarding/cluster): the auth card widens to fit
   the form beside its tips, which stack below it on a narrow screen. The
   region cards reuse the plan cards' look. */
.auth-card:has(.wizard) { width: 960px; }
.wizard-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 360px); gap: 28px; align-items: start; }
@media (max-width: 900px) { .wizard-body { grid-template-columns: 1fr; } }
.wizard-form { margin-top: 0; }
.field-hint { margin: 0; font-weight: 400; font-size: 12px; line-height: 1.45; color: var(--muted); }
.field-hint code { font-size: 11.5px; white-space: nowrap; }
/* One region per row: a handful at most, and each card needs the width for its address. */
.region-opts { display: grid; grid-template-columns: 1fr; gap: 10px; }
.region-addr { display: block; margin-top: 6px; font: 12px var(--mono); color: var(--text-2); overflow-wrap: anywhere; }
.wizard-skip { align-self: center; }
.wizard-tips, .form-tips { background: var(--panel-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px; font-size: 13px; line-height: 1.5; color: var(--text-2); }
.wizard-tips section + section, .form-tips section + section { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.wizard-tips h2, .form-tips h2 { margin: 0 0 6px; font-size: 13px; font-weight: 600; color: var(--text); }
.wizard-tips p, .form-tips p { margin: 0; }
.wizard-tips ul, .form-tips ul { margin: 0; padding-left: 16px; display: grid; gap: 6px; }
.wizard-tips strong, .form-tips strong { color: var(--text); }

/* A .form with tips beside its fields (the new-topic form): the tips stack
   below the fields on a narrow screen, and sit white on the form's grey. */
.form-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 400px); gap: 28px; align-items: start; }
@media (max-width: 1000px) { .form-split { grid-template-columns: 1fr; } }
.form-fields { display: flex; flex-direction: column; gap: 16px; max-width: 460px; }
.form-fields > .btn { align-self: flex-start; }
.form-tips { background: var(--panel); border-radius: var(--radius-sm); }

/* What a cluster has left of a counted quota, as a bar per dimension. A
   <meter>, not a styled div: the CSP allows no inline style for the width. */
/* One grid for every row (each row's cells join it through display:
   contents), so the bars line up whatever the figures beside them. */
.quota-use { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 10px 12px; align-items: center; padding: 12px 14px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-sm); font-size: 13px; color: var(--text-2); }
.quota-use h3, .quota-use .field-hint { grid-column: 1 / -1; }
.quota-use h3 { margin: 0; font-size: 11.5px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.quota-use-row { display: contents; }
.quota-use-row > :last-child { text-align: right; }
.quota-use-row strong { color: var(--text); }
.quota-use-row.is-over strong { color: var(--danger); }
.quota-use meter { -webkit-appearance: none; appearance: none; display: block; width: 100%; height: 8px; border: 0; border-radius: 4px; background: var(--line); }
.quota-use meter::-webkit-meter-bar { height: 8px; border: 0; border-radius: 4px; background: var(--line); }
.quota-use meter::-webkit-meter-optimum-value { border-radius: 4px; background: var(--accent); }
.quota-use meter::-moz-meter-bar { border-radius: 4px; background: var(--accent); }

/* A quota set apart from its plan: the badge, and for staff the plan's
   own value beside it, kept on one line under the value. */
.quota-custom { margin-top: 2px; white-space: nowrap; }

/* "1 of 10" beside a panel's title (the cluster list's limit). */
.panel-count { margin-left: 6px; font-size: 12.5px; font-weight: 500; color: var(--muted); white-space: nowrap; }

/* Error page */
.error-page { min-height: 100vh; display: grid; place-items: center; background: linear-gradient(180deg, #f9fdfb, #f1f8f4); padding: 24px; }
.error-card { background: #fff; border-radius: 16px; box-shadow: 0 12px 40px rgba(5,150,105,.12); padding: 36px 40px; max-width: 480px; text-align: center; border: 1px solid var(--line); }
.error-mark { width: 56px; height: 56px; margin: 0 auto 14px; border-radius: 50%; background: var(--danger-soft); color: var(--danger); display: grid; place-items: center; font-weight: 700; font-size: 20px; }
.error-title { font-size: 22px; margin: 0 0 6px; }
.error-message { color: var(--text-2); margin: 0 0 12px; }
.error-ref { color: var(--muted); font-size: 13px; margin: 0 0 18px; }
.error-actions { display: flex; gap: 10px; justify-content: center; }

/* Principal passwords (see [data-secret] in console.js): masked until
   the eye is used; the icon buttons sit inline next to the value. */
.icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; border: 1px solid transparent; border-radius: var(--radius-sm); background: none; color: var(--muted); cursor: pointer; vertical-align: middle; }
.icon-btn:hover { background: var(--panel-2); border-color: var(--line); color: var(--text); }
.icon-btn.is-copied { color: var(--accent); border-color: var(--accent-line); }
.icon-btn.is-failed { color: var(--danger); border-color: var(--danger); }
.icon-eye-off { display: none; }
.is-revealed .icon-eye { display: none; }
.is-revealed .icon-eye-off { display: inline; }
.secret { display: inline-flex; align-items: center; gap: 4px; }
.secret code { word-break: break-all; }
/* Kept under the row height a td.actions button sets: that cell is flex,
   not a table-cell, so it does not stretch when a sibling cell grows. */
.secret .icon-btn { width: 24px; height: 24px; }

.client-config-bar { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.client-config-principal { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--text-2); font-weight: 500; min-width: 220px; }
.client-config-actions { display: inline-flex; gap: 4px; }
.client-config:not([data-secret-url]) .client-config-actions { display: none; }
.client-config .code-block { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.client-config-hint:empty { display: none; }

/* Buttons that end a page, after its last panel. */
.page-actions { display: flex; flex-wrap: wrap; gap: 10px; }

/* The first-topics step's rows: a name and a partition count each, and a
   remove button once there is more than one. */
.topic-rows { display: grid; gap: 8px; }
.topic-row { display: grid; grid-template-columns: minmax(0, 1fr) 96px 28px; gap: 8px; align-items: center; }
.topic-rows-head { font-size: 12.5px; font-weight: 500; color: var(--text-2); }
.topic-rows-add { align-self: flex-start; }

/* The ACL grant form shows what its "What it may do" choice needs: each
   [data-for] element lists the choices it belongs to. CSS rather than
   script, so a hidden field is never left required. */
.acl-grant [data-for] { display: none; }
.acl-grant .acl-section { gap: 10px; }
.acl-grant:has(input[name="access"][value="produce"]:checked) [data-for~="produce"],
.acl-grant:has(input[name="access"][value="consume"]:checked) [data-for~="consume"],
.acl-grant:has(input[name="access"][value="produce_consume"]:checked) [data-for~="produce_consume"],
.acl-grant:has(input[name="access"][value="custom"]:checked) [data-for~="custom"] { display: grid; }

/* The ACLs page's search, a GET form so a search is a link: its fields in
   a row that wraps, the "applies to" switch under them. The results are
   ticked for the revoke bar under the table, which keeps to the right
   with its warning on the left. */
.acl-search { display: grid; gap: 10px; padding: 10px 14px 6px; }
.acl-search-fields { display: flex; flex-wrap: wrap; gap: 10px; align-items: end; }
.acl-search-fields label { display: flex; flex-direction: column; gap: 4px; min-width: 170px; font-size: 12px; font-weight: 500; color: var(--text-2); }
.acl-search-fields input { padding: 7px 10px; border: 1px solid var(--line-2); border-radius: var(--radius-sm); background: #fff; font-size: 13px; }
/* A link and a button side by side: .btn leaves the font to each. */
.acl-search-fields .btn { font: 500 13px/1.25 var(--font); }
.acl-search .checkbox { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text-2); }
table.data .select-col { width: 1%; padding-right: 0; }
.revoke-bar { display: flex; align-items: center; justify-content: flex-end; gap: 14px; padding: 12px 14px 8px; border-top: 1px solid var(--line); }
.revoke-warning { margin: 0 auto 0 0; font-size: 12.5px; color: var(--warn); }

/* A quota value as forms take it (quota_field): the number, its unit
   picked beside it, and the Unlimited box. In a .form it sits under a
   .field-label, as a <label> would put it; in a table cell it stands alone. */
.quota-field { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.quota-field input[type="number"] { width: 11ch; }
.quota-field select { padding-top: 5px; padding-bottom: 5px; }
.quota-field .checkbox { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 400; color: var(--text-2); }
.quota-field input:disabled, .quota-field select:disabled { opacity: .5; }
.form .field { display: flex; flex-direction: column; gap: 4px; }
.form .field-label { font-size: 12px; font-weight: 500; color: var(--text-2); }

/* The overview's usage chart: peak figures, two canvases the script draws
   side by side, and one tooltip that follows the pointer over either. The
   series colours are variables the script reads, so the lines, the legend
   and the tooltip's swatches agree. */
.usage-panel { --usage-in: #059669; --usage-out: #2563eb; --usage-stored: #7c3aed; }
.usage-panel .panel-head select { padding-top: 5px; padding-bottom: 5px; }
/* The heading's info button and the popup it opens, below the heading. */
.usage-title { position: relative; display: flex; align-items: center; gap: 4px; }
.usage-info { position: absolute; top: calc(100% + 8px); left: 0; z-index: 10; width: min(360px, 80vw); padding: 12px 14px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-sm); box-shadow: var(--shadow); font-size: 13px; line-height: 1.5; color: var(--text-2); }
.usage-info p { margin: 0; }
.usage-info p + p { margin-top: 6px; }
.usage-info strong { color: var(--text); }
.usage-panel .panel-body { position: relative; }
.usage-stats { display: flex; flex-wrap: wrap; gap: 8px 32px; margin: 6px 0 16px; }
.usage-stats dt { font-size: 11.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.usage-stats dd { margin: 2px 0 0; font-size: 18px; font-weight: 600; color: var(--text); }
.usage-charts { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 28px; margin-bottom: 12px; }
@media (max-width: 1000px) { .usage-charts { grid-template-columns: minmax(0, 1fr); } }
.usage-chart { margin: 0; }
.usage-chart figcaption { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 6px; font-size: 12px; font-weight: 600; color: var(--text-2); }
.usage-legend { display: flex; gap: 14px; font-weight: 500; color: var(--muted); }
.usage-legend i, .usage-tooltip i { display: inline-block; width: 10px; height: 3px; border-radius: 2px; margin-right: 6px; vertical-align: middle; }
.usage-panel i.in { background: var(--usage-in); }
.usage-panel i.out { background: var(--usage-out); }
.usage-panel i.stored { background: var(--usage-stored); }
.usage-chart canvas { display: block; width: 100%; height: 190px; cursor: crosshair; touch-action: pan-y; }
.usage-tooltip { position: absolute; z-index: 5; min-width: 190px; padding: 8px 10px; border-radius: var(--radius-sm); background: var(--text); color: #fff; font-size: 12px; line-height: 1.5; pointer-events: none; box-shadow: var(--shadow); }
.usage-tooltip b { display: block; margin-bottom: 4px; font-weight: 600; }
.usage-tip-row { display: flex; justify-content: space-between; gap: 16px; }
.usage-tip-row strong { font-weight: 600; }

/* --- Phones. Kept last so it overrides the rules above. The header
   keeps the logo and a menu button; the sections and the user menu move
   into a full-screen sheet under it. A section's sidenav becomes a row
   of tabs under the header that scrolls sideways, and a table scrolls
   inside its panel instead of widening the page. --- */
@media (max-width: 760px) {
  :root { --topnav-h: 56px; }
  .topnav { gap: 12px; padding: 0 8px 0 16px; }
  .topnav-logo { height: 48px; }
  .topnav-main { display: none; }
  .topnav-right { margin-left: auto; gap: 4px; }
  .env-pill { margin-right: 0; }
  .user-menu-email { display: none; }
  .user-menu-icon { display: inline-flex; }
  .user-menu-trigger { padding: 8px; color: var(--text-2); }
  .user-menu-trigger[aria-expanded="true"] .icon-menu,
  .user-menu-trigger:not([aria-expanded="true"]) .icon-close { display: none; }
  .user-dropdown { position: fixed; top: var(--topnav-h); right: 0; bottom: 0; left: 0; min-width: 0; padding: 8px 8px 24px; border: 0; border-radius: 0; box-shadow: none; overflow-y: auto; overscroll-behavior: contain; }
  .user-dropdown-sections { display: block; }
  .user-dropdown-who { padding: 10px 12px 12px; }
  .user-dropdown-item, .row-menu-item { padding: 12px; font-size: 15px; }

  .app-body { flex-direction: column; }
  .sidenav { width: auto; height: auto; padding: 0; z-index: 15; border-right: 0; border-bottom: 1px solid var(--line); overflow-x: auto; scrollbar-width: none; }
  .sidenav::-webkit-scrollbar { display: none; }
  .nav { flex-direction: row; gap: 0; width: max-content; min-width: 100%; padding: 0 6px; }
  .nav-item { padding: 12px 10px 10px; border-radius: 0; border-bottom: 2px solid transparent; white-space: nowrap; }
  .nav-item:hover { background: none; }
  .nav-item.is-active { background: none; border-bottom-color: var(--accent); }
  .nav-icon { display: none; }

  .breadcrumb { padding: 12px 16px 0; }
  .page { padding: 12px 16px 24px; }
  .main > .flash { padding: 10px 16px; }
  .page-title { font-size: 22px; margin-bottom: 18px; }
  .page-sub { margin-top: -14px; margin-bottom: 18px; }
  .panel { margin-bottom: 16px; }
  .panel-head { padding: 12px 14px; }
  .table-scroll { overflow-x: auto; }
  /* A table read and edited a row at a time (table.stack: topic
     configuration, quotas) makes each row a block of its own rather than
     one to scroll sideways to: its .stack-title cell and its actions on
     the first line, the other cells on the next (a data-label naming
     them, as the header row is gone), a .stack-wide cell on a line of
     its own, and an open edit row across the whole width. */
  table.data.stack, table.data.stack tbody { display: block; }
  table.data.stack thead { display: none; }
  table.data.stack tbody tr { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 10px 12px; border-bottom: 1px solid var(--line); }
  table.data.stack tbody tr::after { content: ""; order: 3; flex-basis: 100%; }
  table.data.stack tbody tr:last-child { border-bottom: 0; }
  table.data.stack tbody td { order: 4; padding: 0; border: 0; }
  table.data.stack td.stack-title { order: 1; flex: 1 1 0; min-width: 0; }
  table.data.stack td.actions { order: 2; width: auto; }
  table.data.stack td.stack-wide { order: 5; flex-basis: 100%; }
  table.data.stack td[colspan] { order: 1; flex: 1 1 100%; }
  table.data.stack td[colspan] .form { margin: 0; }
  table.data.stack td[data-label]::before { content: attr(data-label) ": "; color: var(--muted); }
  table.data.stack .edit-line label { flex: 1; min-width: 0; }
  table.data.stack td .config-field { width: 100%; }
  /* A wide table's ⋯ stays at the scroll box's right edge, in reach
     without scrolling the table first. Only the ⋯: a wider actions cell
     (a quota's pending request and its button) would cover its columns. */
  .table-scroll td.actions:has(> .row-menu) { position: sticky; right: 0; background: var(--panel); }
  table.data tbody tr:hover td.actions:has(> .row-menu) { background: var(--panel-2); }
  table.data thead th, table.data tbody td { padding-left: 12px; padding-right: 12px; }
}
