/* ============================================================================
 * nergyapp/chrome.css — the app's own chrome, transcribed.
 * ----------------------------------------------------------------------------
 * The top bar, the status pill, the account chip and its menu, and the settings
 * overlay with its left rail. Taken from `newapp.html`'s rules rather than
 * approximated, because a second visual language across one product reads as two
 * products.
 *
 * NO DRIFT TEST GUARDS THIS, AND THAT IS A DECISION, NOT AN OVERSIGHT.
 *
 * The mirror bargain (BIBLE.md §8.8) says a transcribed table is legal only while a
 * test fails on drift — and it says that because two live copies drift. These rules
 * have ONE live copy from the moment `newapp.html` is retired, which is the plan; a
 * drift test would guard a source that is being deleted, and would have to be
 * deleted with it.
 *
 * If that retirement is ever cancelled, this file needs a drift test the same day.
 * That is the condition, written down so nobody has to reconstruct the reasoning.
 *
 * Two deliberate departures from the original, both because the shell is not the
 * monolith:
 *
 *   · no `--rail-w` offset. `newapp.html` indents its bar by the width of a rail
 *     that runs the whole left edge; this shell's rail starts BELOW the bar, so
 *     the bar owns the top edge outright and the brand sits in the corner where
 *     a brand belongs.
 *   · the settings overlay is styled here rather than borrowed from `.hist-overlay`,
 *     which in the original carries history-panel behaviour this has no use for.
 *
 * Nothing below hard-codes a colour. Every value is a token from theme.css.
 * ==========================================================================*/

/* ── the top bar ─────────────────────────────────────────────────────────── */
/* Glass rather than a slab: the page's own colour and its wash show through a
   blur, so the bar reads as a layer over the product instead of a lid on it.
   The hairline under it is the accent at 40% width — enough to place the brand,
   not enough to become a rule across the screen. */
/* ONE SIZE FOR EVERYTHING THE BAR SAYS: 15px, from the wordmark to the project
   name to the mono figures in the pills. The bar is a row of unrelated things —
   who you are, where you are, whether the service is up, what the balance is —
   and a type ramp across them would rank them, which is exactly what a bar full
   of peers must not do. Sizes are still per-element below because the elements
   are different shapes; the number is the same one. */
.na-topbar {
  position: fixed; top: 0; left: 0; right: 0; height: var(--topbar-h); z-index: 100;
  display: flex; align-items: center; gap: 16px; padding: 0 20px;
  background: var(--shell-bg); border-bottom: 1px solid var(--shell-border);
  box-shadow: var(--shell-elev);
  backdrop-filter: saturate(1.6) blur(14px);
  -webkit-backdrop-filter: saturate(1.6) blur(14px);
}
.na-topbar::after {
  content: ''; position: absolute; left: 0; right: 60%; bottom: -1px; height: 1px;
  background: var(--accent-line); opacity: .75;
}
.na-brand {
  display: flex; align-items: center; gap: 10px; font-family: var(--sans);
  font-weight: 700; font-size: 14px; letter-spacing: 0.14em; color: var(--text);
  text-transform: uppercase; background: none; border: 0; padding: 0; cursor: pointer;
}
.na-brand-word {
  font-family: var(--sans); font-weight: 700; font-size: 15px;
  letter-spacing: -0.015em; text-transform: none; color: var(--text);
}
.na-brand svg { flex-shrink: 0; color: var(--blue); transition: transform .18s ease }
.na-brand:hover svg { transform: translateY(-1px) }
.na-brand:focus-visible { outline: 2px solid var(--blue); outline-offset: 4px; border-radius: 6px }

/* WHERE YOU ARE AND THE WAY BACK, after the brand. One group, one divider: the
   two belong together — the name of the thing you are in, and the door out of
   it — and drawing a rule for each would put two hairlines in six inches of bar.
   It carries the divider so that hiding the group hides the rule with it. */
.na-topbar-where {
  display: flex; align-items: center; gap: 8px; min-width: 0;
  padding-left: 16px; position: relative;
}
.na-topbar-where[hidden] { display: none }
.na-topbar-where::before {
  content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 1px; height: 20px; background: var(--border2);
}

/* The way out. Quiet, because it is not what anybody came to this screen to do —
   but a real button with a real arrow, because it is how they leave. Scoped to
   the bar so it outranks `.na-btn`, which is one class in a stylesheet that
   loads after this one and would otherwise keep its own padding. */
.na-topbar .na-back { flex: 0 0 auto; gap: 7px; padding: 8px 13px 8px 11px; font-size: 15px }
.na-topbar .na-back[hidden] { display: none }
.na-topbar .na-back svg { width: 16px; height: 16px; flex-shrink: 0 }

/* The project you are in, said once. It is the heading this window has — the
   band that used to carry it is gone — so it is set as one rather than as an
   aside, and it is the thing that gives up its width when the bar runs out. */
.na-topbar-context {
  font-size: 15px; font-weight: 600; letter-spacing: -0.012em; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.na-topbar-context:empty { display: none }
/* A breadcrumb chevron before the title, so "Projects" and the title read as a
   path rather than two loose pieces. `:empty` above hides the title with no
   project, so this never renders orphaned. */
.na-topbar-context::before {
  content: "\203A";   /* › single right-pointing angle quote */
  color: var(--muted);
  font-weight: 400;
  font-size: 17px;
  margin-right: 8px;
}
.na-topbar-spacer { flex: 1; }
.na-topbar-actions { display: flex; align-items: center; gap: 10px; }

.na-status {
  display: flex; align-items: center; gap: 8px; font-family: var(--mono);
  font-size: 15px; letter-spacing: 0.05em; color: var(--muted2);
  background: var(--surface-sunken); border: 1px solid var(--border); border-radius: 99px;
  padding: 6px 15px; cursor: default; white-space: nowrap;
}
.na-status-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--muted);
  flex-shrink: 0; transition: background 0.3s, box-shadow 0.3s;
}
.na-status.is-ok .na-status-dot { background: var(--green); box-shadow: 0 0 0 3px var(--green-dim) }
.na-status.is-bad .na-status-dot { background: var(--red); box-shadow: 0 0 0 3px var(--red-dim) }
.na-status.is-warn .na-status-dot { background: var(--amber) }

/* ── the credit meter (creditmeter.js) ─────────────────────────────────────
   Built to the status pill's own recipe — same height, same radius, same mono
   figure — because the two answer one question between them ("will the next
   thing I press work") and two pills of different shapes beside each other read
   as two unrelated widgets. The difference is that this one is a BUTTON: a
   balance is only useful if the thing you do about it is one press away. */
.na-meter {
  display: flex; align-items: center; gap: 9px; font-family: var(--mono);
  font-size: 15px; letter-spacing: 0.05em; color: var(--muted2);
  background: var(--surface-sunken); border: 1px solid var(--border); border-radius: 99px;
  padding: 6px 15px; cursor: pointer; white-space: nowrap;
  transition: border-color .15s ease, color .15s ease;
}
/* `display` above outranks the UA sheet's [hidden] rule, so it is restored here —
   without this the meter's own "not yet / signed out" hide (creditmeter.js sets
   `hidden`) never takes visually, and the bar shows an empty meter until a
   balance lands. */
.na-meter[hidden] { display: none }
.na-meter:hover, .na-meter:focus-visible { color: var(--text); border-color: var(--muted) }
.na-meter-track {
  width: 56px; height: 6px; border-radius: 99px; background: var(--border);
  overflow: hidden; flex-shrink: 0;
}
.na-meter-track[hidden] { display: none }
.na-meter-fill {
  display: block; height: 100%; width: 0; border-radius: 99px;
  background: var(--green); transition: width .3s ease, background .3s ease;
}
.na-meter-figure { font-variant-numeric: tabular-nums }
/* THE BALANCE IS THE ACCOUNT'S, so it leaves the top bar on the way in. The sign-in
   screen wears this same bar, and a credit figure beside a password field is a
   number for an account nobody has named yet. `app.js` marks the gate on the body;
   hidden here rather than by the meter's own reads because the stand-in wallet
   (`?api=mock`) has no signed-out state for the meter to key on. */
body.na-signin-open .na-topbar .na-meter { display: none }
/* TONE ONLY AT THE END. A bar that changes colour on the way down is a bar
   nagging about a balance that is fine; these two are the states where the next
   run is the one that will not go through. */
.na-meter.is-low .na-meter-fill { background: var(--amber) }
.na-meter.is-low .na-meter-figure { color: var(--amber) }
.na-meter.is-empty .na-meter-fill { background: var(--red) }
.na-meter.is-empty .na-meter-figure { color: var(--red) }
/* THE NARROWEST TOP BAR DROPS THE BAR, NOT THE FIGURE. "12 / 200" still says
   everything; a 46px track with no number beside it says nothing at all. */
@media (max-width: 700px) { .na-meter-track { display: none } }

.na-icon-btn {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: var(--radius); background: var(--surface-sunken);
  border: 1px solid var(--border); color: var(--muted2); cursor: pointer;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
  flex-shrink: 0;
}
.na-icon-btn:hover { border-color: var(--blue); color: var(--blue); background: var(--blue-dim) }
.na-icon-btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px }
.na-icon-btn svg { width: 18px; height: 18px; }

.na-chip {
  display: flex; align-items: center; gap: 10px; padding: 4px 15px 4px 4px;
  border-radius: 99px; border: 1px solid var(--border); background: var(--surface-sunken);
  cursor: pointer; transition: border-color .15s ease, background .15s ease;
}
.na-chip:hover { border-color: var(--border3); background: var(--bg3) }
.na-chip:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px }
.na-chip-avatar {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--accent-fill);
  color: var(--on-accent); display: flex; align-items: center;
  justify-content: center; font-size: 13px; font-weight: 700; flex-shrink: 0;
  letter-spacing: 0;
}
/* ONE LINE, ALWAYS. At the bar's larger type a two-word name wrapped inside its
   own pill on a narrow bar — a 62px bar holding a two-line chip. It gives up the
   whole name below (see the narrow block), which is the honest answer; it never
   gives up half of it to a line break. */
.na-chip-who {
  font-size: 15px; color: var(--muted2); font-family: var(--mono);
  letter-spacing: 0.02em; white-space: nowrap;
}

.na-menu {
  position: absolute; top: calc(var(--topbar-h) + 6px); right: 16px; background: var(--surface-raised);
  border: 1px solid var(--border2); border-radius: var(--radius-lg); padding: 8px;
  min-width: 216px; box-shadow: var(--elev-3); z-index: 400; display: none;
}
.na-menu.is-open { display: block; }
.na-menu-email {
  font-size: 15px; color: var(--text); padding: 9px 11px;
  border-bottom: 1px solid var(--border); margin-bottom: 6px; word-break: break-all;
}
.na-menu-role {
  font-family: var(--mono); font-size: 11px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .08em; padding: 0 10px 8px;
}
.na-menu-item {
  display: block; width: 100%; text-align: left; padding: 8px 10px;
  border-radius: var(--radius-sm); border: none; background: none; color: var(--muted3);
  font-size: 15px; cursor: pointer; font-family: var(--sans);
  transition: background .12s ease, color .12s ease;
}
.na-menu-item:hover { background: var(--bg3); color: var(--text) }
.na-menu-item:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px }

/* The screen sits under a fixed bar, so it starts below one — as a MARGIN on the
   root rather than a wrapper element. A wrapper broke the height chain the bounded
   project window depends on: `height:100vh` resolved against a div with no height of
   its own, and the planner's search box (with Stop on it) ended up below the fold,
   which is the one place it must never be.

   AND THE MARGIN HAS TO STAY INSIDE `body`, which is what `display:flow-root`
   below is for. Adjoining top margins collapse THROUGH a parent that is only a
   block box, so this one escaped: `body` itself was pushed down the height of the
   bar while `height:100%` (theme.css) kept it exactly one viewport tall, and the
   document came out one bar taller than the window. Every screen then had a page
   scroll of exactly `--topbar-h` — enough, in the project window, to take the tab
   strip off the top of the screen and leave the reader with no tab names. The
   window is bounded and scrolls INSIDE itself; a page scroll over it was never
   part of the design, it was a collapsed margin.

   `flow-root` and not `overflow:hidden`: body's overflow propagates to the
   viewport, so hiding it here would take away the page scroll the workspace and
   the settings screens genuinely use. This makes a block formatting context and
   changes nothing else about the box. */
body { display: flow-root; }
body.na-has-topbar #nergyapp-root {
  margin-top: var(--topbar-h);
  /* The unbounded screens are a minimum tall, not a fixed height, and the minimum
     is what is LEFT under the bar. `100vh` (the base rule) plus the margin above
     is a viewport and a bar, which is a scroll on a screen with nothing to scroll. */
  min-height: calc(var(--screen-h) - var(--topbar-h));
}
/* THE BAR IS THE FULL WIDTH OF THE WINDOW AND THE RAIL STARTS UNDER IT. It used
   to be the other way round — a rail up the whole left edge, and a bar indented
   by its width to get clear of it — which pushed the brand 80px in from the
   corner and made the two read as one L-shaped slab. The bar now owns the top
   edge (it is where the brand, where-you-are and the account live, and those are
   the app's, not a column's), and the rail is a PANEL floating below it. Two
   things, each with its own edges, which is what they are.
   The rail is fixed, so the screens are moved off it rather than laid out beside
   it — one number, and no screen has to know the rail exists. */
body.na-has-rail #nergyapp-root { margin-left: calc(var(--rail-w) + var(--rail-gap) * 2); }
/* Narrow, the rail is a bar along the BOTTOM: nothing to move sideways for, and
   room to be left under the screen instead so the last row is not behind it. The
   bottom padding applies to the bounded screens too — the project window and the
   workspace both set `padding:0`, and both would otherwise put their last row
   (the composer, the last project) under the bar. */
@media (max-width: 720px) {
  body.na-has-rail #nergyapp-root { margin-left: 0; padding-bottom: 76px }
  /* And the bar itself gives up the wordmark rather than the project's name: at
     this width the two of them together leave the name three letters. */
  .na-topbar { gap: 10px; padding: 0 12px }
  .na-brand-word { display: none }
  .na-topbar-where { padding-left: 12px; gap: 6px }
  .na-topbar .na-back span { display: none }
  .na-topbar .na-back { padding: 7px 9px }
  /* And the account chip gives up the name rather than the avatar: the avatar is
     the thing you press and the initial still says whose session this is, while
     a name at this width is what pushes the row of pills off the bar. */
  .na-chip-who { display: none }
  .na-chip { padding: 4px }
}
/* MARGIN, not padding, and the height comes down to match. On a scrolling container
   the padding band still hit-tests as the container, so content scrolled up into it
   is visible and unclickable — a tab strip under the bar looked fine and refused
   every click. Margin puts the box below the bar instead of reserving space inside
   it, and nothing can scroll under a region that is not part of the box. */
body.na-has-topbar #nergyapp-root.na-window { height: calc(var(--screen-h) - var(--topbar-h)); }

/* ── EMBEDDED: no bar, no rail, and the offsets they reserve taken back ──────
   Set by `config.embedded()` when the shell is framed by a surface that draws its
   own chrome — the enterprise workbench's Custom model screen. The bar and rail
   are still MOUNTED (they hold the session, the theme and the settings overlay,
   and unmounting them would mean teaching every caller they might be absent);
   they are hidden, and the two margins they set on the root are returned.

   `!important` is warranted on the margins for once: `na-has-topbar` and
   `na-has-rail` are set by the chrome at mount, on the same element and at the
   same specificity, so this has to win against a class that arrives after it. */
body.na-embedded .na-topbar,
body.na-embedded .na-apprail { display: none !important; }
body.na-embedded.na-has-topbar #nergyapp-root,
body.na-embedded.na-has-rail #nergyapp-root {
  margin-top: 0 !important;
  margin-left: 0 !important;
  padding-bottom: 0 !important;
  min-height: var(--screen-h);
}
body.na-embedded.na-has-topbar #nergyapp-root.na-window { height: var(--screen-h); }

/* ── settings: the overlay and its left rail ─────────────────────────────── */
.na-overlay {
  position: fixed; inset: 0; z-index: 500; display: none;
  align-items: center; justify-content: center; background: rgba(3, 6, 12, 0.62);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
}
.na-overlay.is-open { display: flex; }
.na-modal {
  display: flex; flex-direction: column; width: min(880px, calc(var(--screen-w) * .92));
  height: min(620px, calc(var(--screen-h) * .86)); background: var(--surface-raised);
  border: 1px solid var(--border2); border-radius: var(--radius-lg);
  box-shadow: var(--elev-3); overflow: hidden;
}
/* Settings gets its own footprint — a dedicated screen, not the shared dialog
   box. Widen/tallen HERE, not on `.na-modal` (dialog.js leans on that base).

   IT IS EIGHT FULL SCREENS OF FORMS, and it was being given a 1000×760 window to
   show them in: Integrations scrolled its card stack inside a box occupying two
   thirds of the monitor, and Compute's SSH form ran off the bottom of one. So the
   box takes the room the screen actually has — near-full on a laptop, capped on a
   wide monitor so the measure inside it stays readable rather than stretching. */
.na-modal-settings {
  width: min(1400px, calc(var(--screen-w) - 96px));
  height: min(1000px, calc(var(--screen-h) - 88px));
}
.na-modal-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--border);
}
.na-modal-title { font-size: 13.5px; font-weight: 600; color: var(--text); letter-spacing: -0.01em }
.na-modal-split { display: flex; flex: 1; min-height: 0; }
/* v2 section rail: a 190px list with no divider — the body's own left padding is
   the gutter (v2's `.snav`/`.slayout` look), so nav and body sit on one surface. */
.na-settings-nav {
  width: 190px; flex: none;
  padding: 18px 12px; display: flex; flex-direction: column; gap: 2px; overflow-y: auto;
}
/* A window's navigation, not a dropdown's: `.na-menu-item`'s 12.5px was sized for
   a list that appears under a chip and goes away again. v2 `.snav-item` = 14px. */
.na-settings-nav-btn { padding: 9px 12px; font-size: 14px; }
.na-settings-body { flex: 1; overflow-y: auto; padding: 32px clamp(24px, 3vw, 48px); min-width: 0; }
/* v2 `.snav-item.on`: a filled blue-dim pill in bold weight — no inset accent bar. */
.na-settings-nav .na-menu-item.is-active { background: var(--blue-dim); color: var(--text); font-weight: 600 }

/* Label/value rows (settingsaccount.js row()): a fixed label column + gap so
   "Email" and the address never collide into "Emailvinay@…". */
.na-row {
  display: flex; align-items: baseline; gap: 10px;
  padding: 7px 0; border-bottom: 1px solid var(--border);
}
/* Only a LEADING muted label gets the fixed column. A trailing muted span is
   a status/value (compute status, "failed" is-bad, billing note) and must
   keep its own color and natural width. */
.na-row > .na-muted:first-child { flex: none; min-width: 140px; }

/* ── THE SETTINGS LAYOUT SYSTEM ──────────────────────────────────────────────
   ONE system for all eight panels. Every panel is built from the same handful of
   classes — the `.na-title`/`.na-subtitle` header, `.na-conn` cards with a
   `.na-conn-head`, `.na-subhead` sub-sections, `.na-row` label/value lines and
   `.na-actions` button rows — so the design lives on THOSE classes, scoped to
   `.na-settings-body`, and every panel inherits it with no per-panel code. That
   is the whole fix: the previous rounds tuned panels one at a time, which is what
   let them drift apart. Spacing is one small scale — 2 / 6 / 8 / 12 / 16px; type
   is four steps; colour, radius and font all come from the tokens, so nothing
   here hard-codes one and both themes derive for free. Copy, structure and
   behaviour are untouched — this is weight, spacing and alignment only.

   SCOPED ON PURPOSE. `.na-conn*`, `.na-subhead`, `.na-key`, `.na-actions`,
   `.na-row` and `.na-select` are also the admin screens', the dialogs', the
   workspace's and the top bar's, so every rule is prefixed `.na-settings-body`
   and nothing outside the overlay moves. The admin billing sub-surface renders
   inside here and shares these classes, so it comes into the same rhythm — but
   its own dense controls keep their layout, and where `.na-actions` doubles as a
   promo form row (`.na-promo-when`/`.na-promo-amounts`) it is excluded by name. */

/* ALIGNMENT — one contained, left-aligned column. Was 880 centred, which drifted
   and left uneven margins in a wide window; a fixed measure pinned to the left
   gutter is what stops the content shifting sideways as you move between tabs. */
.na-settings-body > * { width: 100%; max-width: 660px; box-sizing: border-box; }

/* PANEL HEADER — the one deliberate gap: title, its subtitle, then the sections.
   Direct children only, so a card's own description is never caught by this.
   v2 `.stitle`/`.sdesc`: a 22/650 pane heading with a wider gap to the sections. */
.na-settings-body > .na-title { font-size: 22px; font-weight: 650; letter-spacing: -0.02em; margin-bottom: 6px; }
.na-settings-body > .na-subtitle { margin-bottom: 22px; }

/* TYPE — four steps: pane title (v2 `.stitle` 22/650) › section title (v2 `.sgh`
   15/650) › label & value (15, kept) › caption (14, kept). The section title
   unifies `.na-conn-name` (was 15/400 inline) and `.na-subhead` (was 15/500) into
   one thing. No colour is set; both already inherit `--text`. */
.na-settings-body .na-conn-name,
.na-settings-body .na-subhead { font-size: 15px; font-weight: 650; line-height: 1.3; }

/* CARD HEAD — a flex row so a status badge sits beside the name instead of
   dropping below it once the name is block-level type. */
.na-settings-body .na-conn-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 2px; }

/* DIVIDERS — exactly one line (1px, `--border`), drawn as a `border-top` on the
   element that BEGINS a section, never as a `border-bottom` (which the trailing
   empty aria-live `<div>`s would strand). First retire the old bottom borders on
   both `.na-row` and `.na-conn`, then rebuild. Adjacent cards / adjacent
   top-level rows / a sub-section heading each open with the same line. */
.na-settings-body .na-conn { padding: 20px 0; border-bottom: 0; }
/* v2 `.srow`: label/name left, value/actions pushed right, on a 15px vertical rhythm. */
.na-settings-body .na-row { padding: 15px 0; border-bottom: 0; align-items: center; justify-content: space-between; }
.na-settings-body .na-conn + .na-conn { border-top: 1px solid var(--border); }
.na-settings-body .na-row + .na-row { border-top: 1px solid var(--border); }
.na-settings-body .na-subhead { border-top: 1px solid var(--border); padding-top: 24px; margin-bottom: 5px; }
.na-settings-body .na-subhead:first-child { border-top: 0; padding-top: 0; }

/* LABEL/VALUE grid — a fixed left column so labels and values line up on one grid;
   the column engages ONLY when the first child is a muted label, so name→actions
   rows (API key, plan rows, machine rows) are never forced into it. The value
   right-aligns (v2 `.sv`) and long keys/paths wrap rather than overflow.
   `.na-pre` command blocks are excluded — they keep their own `overflow-x:auto`. */
.na-settings-body .na-row > .na-muted:first-child { min-width: 150px; }
.na-settings-body .na-row > *:last-child { min-width: 0; overflow-wrap: anywhere; text-align: right; margin-left: auto; }

/* NESTED rows — a data line INSIDE a card (Billing "Remaining", Compute "Status")
   is tight and never divided: the card is the divided unit, not each line in it. */
.na-settings-body .na-conn .na-row { padding: 6px 0; }
.na-settings-body .na-conn .na-row + .na-row { border-top: 0; }

/* SECTION DESCRIPTION — the muted line under a card title, set off from the
   controls; and stacked body paragraphs (My Computer's "What this is") get a
   small gap so they are not one dense block. Compute's radio-choice text keeps
   its own spacing (it is a `.na-choice .na-subtitle`, not a card description). */
.na-settings-body .na-conn-head + .na-subtitle { margin-bottom: 12px; }
.na-settings-body .na-conn > .na-subtitle + .na-subtitle,
.na-settings-body .na-conn > .na-subtitle + .na-muted { margin-top: 8px; }

/* CONTROLS — button rows become real flex rows with even gaps and a step down
   from the control above. The admin promo form's `.na-actions` variants are
   excluded so their own layout is untouched. */
.na-settings-body .na-actions:not(.na-promo-when):not(.na-promo-amounts) {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 12px;
}
/* A button row INSIDE a label/value row is part of that row — no top step. The
   guards match the base rule's specificity (which the `:not()`s raise) so this
   reset actually wins. */
.na-settings-body .na-row > .na-actions:not(.na-promo-when):not(.na-promo-amounts) { margin-top: 0; }
/* Stacked choices (Compute "how may we reach your cluster") stay full-width
   columns — same specificity as the base and placed after it, so this wins. */
.na-settings-body .na-actions-stack:not(.na-promo-when):not(.na-promo-amounts) {
  flex-direction: column; align-items: stretch;
}
/* A bare section button (Security "Set up…", Account "Regenerate key") gets the
   same step down as a standalone `.na-actions`. */
.na-settings-body .na-conn > .na-btn { margin-top: 12px; }
.na-settings-body .na-row + .na-btn { margin-top: 12px; }

/* Stacked inputs in a card (Security current / new password) get a small gap. */
.na-settings-body .na-conn > .na-input + .na-input { margin-top: 8px; }

/* MONO VALUE — a standalone setup code / token reads as a distinct, copyable value:
   the app's mono in a sunken chip, the same treatment as the Account API key. */
.na-settings-body .na-key {
  display: inline-block; font-family: var(--mono); font-size: 13px; color: var(--text);
  background: var(--surface-sunken); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 9px 13px; overflow-wrap: anywhere;
}
/* Step headings (a Tools list, if brought back) are h4 `.sgh`; they need air above. */
.na-settings-body h4.sgh { margin-top: 22px; }

/* My Computer — the connected machine line (meta left, Disconnect right, no divider
   of its own; the group border is the single separator) and the auto-shown setup
   steps: numbered inline, with "download it" as a link that triggers the download. */
.na-settings-body .smrow { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 2px 0; }
.na-settings-body .smrow > span:first-child { min-width: 0; overflow-wrap: anywhere; }
.na-settings-body .ssteps { margin-top: 6px; }
.na-settings-body .sstep { margin-top: 16px; }
.na-settings-body .sstep-n { font-weight: 600; color: var(--muted2); }
.na-settings-body .sstep-act { font-weight: 500; color: var(--text); }
.na-settings-body button.sstep-act { font: inherit; font-weight: 500; background: none; border: 0; padding: 0; color: var(--blue); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.na-settings-body button.sstep-act:hover { text-decoration: none; }
.na-settings-body .ssteps > .na-pre { margin-top: 8px; }
.na-settings-body .ssteps > .na-key { margin-top: 12px; }
.na-settings-body .ssteps > .srevhead { margin-top: 22px; }
.na-settings-body .ssteps > .sgd:not(.sstep) { margin-top: 8px; }

/* Notifications — checkboxes stay checkboxes, sized and given the accent, laid out
   as clean rows; a step down from the group's description above them. */
.na-settings-body .na-checks { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; margin-top: 12px; }
.na-settings-body .na-check-row { display: flex; align-items: center; gap: 10px; cursor: pointer; font-size: 14px; color: var(--text); }
.na-settings-body .na-check-box { width: 16px; height: 16px; accent-color: var(--blue); cursor: pointer; flex: none; }
/* Breathing room between the last checkbox and the Save button. */
.na-settings-body .na-checks + .rowacts { margin-top: 18px; }
/* A right-aligned action row — Billing's "Manage subscription" sits at the same
   right edge as "Use code" above it, rather than left under the plan rows. */
.na-settings-body .rowacts.rowacts-end { justify-content: flex-end; }

/* SELECT — the theme and scheduler dropdowns brought up to the input's own recipe
   instead of a raw OS control. Scoped, so admin analytics' select outside Settings
   is untouched. */
.na-settings-body .na-select {
  font: inherit; font-size: 14px; padding: 8px 12px; border-radius: var(--radius);
  border: 1px solid var(--border2); background: var(--surface-sunken); color: var(--text); cursor: pointer;
}
.na-settings-body .na-select:focus { outline: none; border-color: var(--blue); box-shadow: var(--ring); }

/* STATUS PILL — kept as the bordered pill (dot + label, every state), just tightened
   to v2 spacing/weight inside Settings. Scoped so the top bar's own pill is untouched. */
.na-settings-body .na-status { font-size: 13px; padding: 4px 10px; gap: 7px; }
.na-settings-body .na-status .na-status-dot { width: 7px; height: 7px; }

/* Narrow: the rail goes on top rather than squeezing the body to a sliver. The
   modal is `screen-w − 96px`, so the split gets cramped well before a phone width —
   stack the nav at ~820px so the body keeps a readable measure on small laptops. */
@media (max-width: 820px) {
  .na-modal-split { flex-direction: column; }
  .na-settings-nav { width: auto; flex-direction: row; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--border); }
  /* Centered rows can get tall with long values — let them wrap. */
  .na-settings-body .na-row { flex-wrap: wrap; }
}

/* ── v2 SETTINGS PANE — a 1:1 port of v2_settings_REFERENCE.html's own classes ──
   Started with Account as the pilot; the other panels adopt these as they are
   rebuilt. Scoped to `.na-settings-body` so the bare class names cannot collide
   with anything global. The ONE token remap is v2's `--danger` → this app's
   `--red`/`--red-dim` (v2 declared `--danger`; the app does not). Every other
   value — sizes, weights, spacing, radii — is v2's verbatim. */
.na-settings-body .stitle { font-size: 22px; font-weight: 650; letter-spacing: -.02em; margin-bottom: 6px; }
.na-settings-body .sdesc { font-size: 14px; color: var(--muted); margin-bottom: 22px; line-height: 1.5; }
.na-settings-body .srow { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 15px 0; border-bottom: 1px solid var(--border); }
.na-settings-body .sk { font-size: 14px; color: var(--muted2); flex-shrink: 0; }
.na-settings-body .sv { font-size: 14px; color: var(--text); text-align: right; }
.na-settings-body .sv.mono { font-family: var(--mono); font-size: 13px; }
.na-settings-body .sgroup { margin-top: 30px; padding-top: 26px; border-top: 1px solid var(--border); }
.na-settings-body .sgh { font-size: 15px; font-weight: 650; margin-bottom: 5px; }
.na-settings-body .sgd { font-size: 13.5px; color: var(--muted); margin-bottom: 16px; line-height: 1.5; }
.na-settings-body .apikey { display: flex; align-items: center; gap: 16px; margin-bottom: 18px; }
.na-settings-body .apikey code { font-family: var(--mono); font-size: 13px; color: var(--text); background: var(--surface-sunken); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 9px 13px; }
/* v2 draws these as `.apikey a`; they are `<button>`s here for keyboard access. */
.na-settings-body .apikey button { font: inherit; font-family: var(--sans); font-size: 13px; font-weight: 500; color: var(--muted2); background: none; border: 0; padding: 0; cursor: pointer; }
.na-settings-body .apikey button:hover { color: var(--blue); }
.na-settings-body .rowacts { display: flex; gap: 12px; align-items: center; }
.na-settings-body .btn-quiet { font-family: var(--sans); font-size: 13px; font-weight: 500; color: var(--muted2); background: var(--surface-sunken); border: 1px solid var(--border2); border-radius: var(--radius); padding: 9px 15px; cursor: pointer; }
.na-settings-body .btn-quiet:hover { border-color: var(--border3); color: var(--text); }
.na-settings-body .btn-danger { font-family: var(--sans); font-size: 13px; font-weight: 600; color: var(--red); background: transparent; border: 1px solid color-mix(in srgb, var(--red) 42%, transparent); border-radius: var(--radius); padding: 9px 15px; cursor: pointer; }
.na-settings-body .btn-danger:hover { background: var(--red-dim); }
/* v2 `.btn-primary` — the one accent-filled action. v2's `#fff` → this app's
   `--on-accent`; the shadow is v2's own literal, matching `.na-btn-primary`. */
.na-settings-body .btn-primary { font-family: var(--sans); font-size: 13.5px; font-weight: 600; color: var(--on-accent); background: var(--accent-fill); border: 1px solid transparent; border-radius: var(--radius); padding: 9px 16px; cursor: pointer; box-shadow: 0 1px 2px rgba(0, 0, 0, .18); }
.na-settings-body .btn-primary:hover { filter: brightness(1.07); }

/* Controls step down from the description above them inside a group; stacked inputs
   (Security current/new password) get a smaller gap between the two. */
.na-settings-body .sgroup > .btn-quiet,
.na-settings-body .sgroup > .btn-primary,
.na-settings-body .sgroup > .btn-danger,
.na-settings-body .sgroup > .rowacts,
.na-settings-body .sgroup > .na-input { margin-top: 12px; }
.na-settings-body .sgroup > .na-input + .na-input { margin-top: 8px; }
/* An input sharing a `.rowacts` row with a button (the TOTP code field) flexes
   rather than blowing out to full width. */
.na-settings-body .rowacts .na-input { flex: 1; min-width: 0; }

/* A `note()` inside Settings is a square box on the section's own measure, not the
   global oval pill — same radius as the inputs/boxes, body font/size/colour, and
   capped at the 660 content width so it wraps like every paragraph rather than
   stretching to the panel edge. */
.na-settings-body .na-notice-note {
  align-self: stretch; width: 100%; max-width: 660px;
  border-radius: var(--radius); padding: 12px 15px;
  font-size: 13.5px; line-height: 1.5; color: var(--muted);
  background: var(--surface-sunken); border-color: var(--border);
}

/* A group heading that carries a status pill / badge beside the name (Integrations
   providers, the Tools list) — name and pill on one line, description below. */
.na-settings-body .sghead { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 5px; }
.na-settings-body .sghead .sgh { margin-bottom: 0; }
/* A revealed credential form sits between a provider's description and its buttons. */
.na-settings-body .na-connform { margin-top: 12px; }
/* Tool rows (Zoo Text-to-CAD) stack inside the Tools group, each its own block. */
.na-settings-body .toolrow { margin-top: 18px; }
.na-settings-body .toolrow > .na-linkish { display: inline-block; margin: 4px 0 2px; }

/* Compute's "where does work run" — native radios (control type kept) laid out as v2
   choice rows: the circle, a medium-weight label, a muted line under it. */
.na-settings-body .schoice { padding: 2px 0; }
.na-settings-body .schoice .na-choice { display: flex; align-items: flex-start; gap: 11px; cursor: pointer; padding: 9px 0; }
.na-settings-body .schoice input[type="radio"] { margin-top: 2px; width: 16px; height: 16px; accent-color: var(--blue); flex: none; cursor: pointer; }
.na-settings-body .schoice-label { font-size: 14px; font-weight: 500; color: var(--text); }
.na-settings-body .schoice .na-choice .sgd { margin: 2px 0 0; }
/* Compute's revealed "own server" area: a hairline separates the selection from the
   question, then the ways (SSH / agent) are radios identical to the chooser above,
   and the chosen one's form flows below — all on ONE quiet type scale, no heading
   bigger or heavier than its peers. */
.na-settings-body .sreveal { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--border); }
/* Every heading inside the reveal — the question and "Connect over SSH" — is this
   one quiet label, matched to the section's body scale. */
.na-settings-body .srevhead { font-size: 13.5px; font-weight: 500; color: var(--muted2); margin-bottom: 2px; }
.na-settings-body .sform { margin-top: 22px; padding-top: 22px; border-top: 1px solid var(--border); }
.na-settings-body .sform > .sgd { margin-bottom: 2px; }
/* Clean sentence-case field labels + full-width inputs to the 660 measure. */
.na-settings-body .sfield { margin-top: 15px; }
.na-settings-body .sfield-label { display: block; font-size: 12.5px; font-weight: 500; color: var(--muted2); margin-bottom: 6px; }
.na-settings-body .sform .na-input,
.na-settings-body .sform .na-select { width: 100%; }
.na-settings-body .sform .rowacts { margin-top: 20px; }
