/* T-shell-chrome-fidelity (dispatched pixel-fidelity pass): rail + topline
   ported to the prototype's exact measured px values (mf.css) rather than
   the accumulated rem approximations. Two real bugs found and fixed along
   the way: (1) generic .button base sizing (foundation.css) was bleeding
   min-width/padding into the square topbar icon buttons — reset scoped
   locally with matching specificity, no change to foundation.css itself;
   (2) the rail divider line was on the wrong sibling (above the collapse
   toggle instead of above the operator row, per the prototype's DOM order).
   Presentation-only; no markup/behavior/route change beyond the two-item
   fixes noted in the work log (orphan "System" label, --ui-text-muted). */

/* Rail container: prototype's uniform 20/14 padding (was 20.8/12/12.8/12,
   an artifact of an asymmetric rem calc) and the prototype's translucent
   divider (the shared --ui-line-soft token is solid hex board-wide; scope
   the rgba to the rail only rather than touch that token everywhere). */
#tab-bar {
  padding: 20px max(14px, env(safe-area-inset-right, 0px)) max(20px, env(safe-area-inset-bottom, 0px)) max(14px, env(safe-area-inset-left, 0px));
  border-right-color: rgba(255, 255, 255, 0.05);
}
html[data-theme="light"] #tab-bar {
  border-right-color: rgba(20, 32, 51, 0.07);
}

/* Brand block: prototype gap/padding, mark radius/glow alpha, sub-label size. */
#tab-bar .brand-lockup { gap: 10px; padding: 4px 10px 18px; }
#tab-bar .brand-mark {
  border-radius: 10px;
  box-shadow: 0 2px 12px color-mix(in srgb, var(--ui-accent) 18%, transparent);
}
#tab-bar .brand-copy span { font-size: 11px; margin-top: -2px; }

/* Footer: prototype order is toggle (no border) then a bordered rail-foot
   wrapping the operator row — the divider sits directly above the profile,
   not above the toggle. Swap which sibling carries the line. */
.shell-nav-foot { border-top: none; }
.shell-operator {
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  padding: 10px;
}
html[data-theme="light"] .shell-operator { border-top-color: rgba(20, 32, 51, 0.07); }

/* Sidebar round 2 (operator report, 18 Aug): name + plan were direct flex
   children of .shell-operator (row layout), so "Mainframe · Solo" sat next
   to "Mariano" with no width and got clipped/overlapped. The prototype
   wraps name + plan in a plain block (index.html: <div><div>name</div>
   <div>plan</div></div>) so they stack. Match that with a column flex
   wrapper around the two spans. */
.shell-operator-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Sidebar round 2: rail-item hover/active background. --ui-panel-hover is
   referenced board-wide (var(--ui-panel-hover, var(--ui-hover))) but was
   never defined in tokens.css, so every consumer has silently been falling
   back to --ui-hover — an opaque, blue-tinted surface color (#182a42 dark)
   instead of the prototype's translucent white wash. Fixing the shared
   token would also repaint unrelated hover states (topbar buttons, overview
   list) that were never part of this operator report, so — same rationale
   as the divider rgba above — the correct value is scoped to the rail only.
   Light theme already matches (T426 forces solid #ffffff, equal to the
   prototype's light --ui-panel-hover). */
html:not([data-theme="light"]) #tab-bar .tab-link:hover,
html:not([data-theme="light"]) #tab-bar .tab-link[aria-selected="true"] {
  background: rgba(255, 255, 255, 0.05);
}

/* Icon-only topbar buttons: neutralize the generic .button min-width/
   padding (foundation.css) that was inflating them past the prototype's
   34px square — matched/higher specificity so this always wins. */
.topbar .button.quiet.topbar-icon-control,
.topbar .button.primary.topbar-icon-control {
  min-width: 0;
  min-height: 0;
  width: 34px;
  height: 34px;
  padding: 0;
  gap: 0;
}

/* Topline: prototype's slim ~34px row with 30px breathing room below — the
   base .topbar rule's min-height (--ui-topbar-height, 4rem) was forcing a
   64px band even after the earlier padding-only passes. Horizontal padding
   now shares the real page gutter so the topline aligns with page content
   below it (the prototype's own clamp() doesn't apply to this product's
   narrower content columns).

   Second gradient band (operator report, 19 Aug): the 30px gap was a
   MARGIN. At >=821px this grid row is `auto`-sized (chrome-visual.css's
   desktop grid-template-rows), so the margin is counted into the row's
   height but paints nothing — margins never render a box's own background.
   That left a 30px unpainted strip at the bottom of the topbar's grid cell
   showing the plain body background straight through, which still carries
   the T376 console-glow radial gradient (peak ~85% viewport width, just
   above the top edge) — reading as a second, dimmer band under the icon
   row, brightest at the bottom-right exactly where the glow peaks. Same
   family of bug as the first flattened band (12a87ebe): a supposedly-flat
   region that wasn't actually covered by the topbar's own painted surface.
   Fixed at the source: the breathing room is now PADDING, not margin, so
   it's inside .topbar's own border-box and paints with its background
   (var(--ui-bg), flat, both themes) like the rest of the bar. Same 30px
   visual gap, same layout — now opaque.

   Height-floor regression (operator/lifecycle-caught, 19 Aug):
   test_t307_browser.py asserts the topbar's rendered height is exactly
   64px (--ui-topbar-height) at desktop width — the doctrine that put the
   page title INTO the topbar exists precisely to RECLAIM vertical px, so
   a taller-than-64px topbar is a straight regression, not a rounding
   error. Measured live: padding-top 17.6px (chrome-visual.css's own
   `padding-block: 1.1rem 0`, T417) + the 34px icon-only-button row (the
   correct height, not to be re-squished) + this rule's 30px padding-
   bottom summed to 81.6px, 17.6px over floor. Both padding-top (below,
   overriding chrome-visual.css's stale 1.1rem — this file loads last) and
   padding-bottom shrink to 15px each: 15 + 34 + 15 = 64px exactly, same
   flat-painted-background fix (still padding, never margin, so the
   gradient-bleed bug above never comes back), same visual family, just
   sized to the actual design floor instead of an unmeasured guess. */
@media (min-width: 821px) {
  .topbar {
    min-height: 0;
    padding-inline: var(--ui-page-gutter);
    padding-top: 15px;
    padding-bottom: 15px;
    margin-bottom: 0;
    /* Responsive one-row topbar (doc 57 audit item, 19 Aug): the topbar's
       own container-type, so its buttons can compress by the space they
       actually have — a docked/launch column narrowing the "workspace"
       grid track, or the rail expanding/collapsing, changes that at a
       FIXED viewport width, which only a container query (not a media
       query) can see. Desktop-only, matching this block's own scope. */
    container-type: inline-size;
    container-name: topbar;
  }
}

/* Responsive one-row topbar, continued: progressive compression as the
   named "topbar" container shrinks. .topbar-actions is flex-wrap:nowrap
   (never a real second row) but flex-shrink was squeezing #launch-open
   below its content width, wrapping "Launch agent" onto two lines inside
   the button — reading as a cramped second row. Measured on a real render:
   wrap starts between 648-653px of .topbar's own inline size (not
   viewport) with the rail expanded; tiers below carry margin above that
   and reach the narrow docked-column floor (multi-dock-push.css's
   minmax(360px,1fr), ~317px left for actions after topbar padding). */
@container topbar (max-width: 720px) {
  .topbar #launch-open .launch-label-wide { display: none; }
  .topbar #launch-open .launch-label-narrow { display: inline; }
}
@container topbar (max-width: 560px) {
  /* Icon-only: static aria-label/title on both buttons (index.html) carry
     the accessible name and hover tooltip from here down. AR-round6: the
     desktop Agents toggle (index.html, #agents-dock-open) joins Launch and
     Ask at this same tier — same priority class of topbar action, same
     compression point, per the shell landing worker's existing tiers. */
  .topbar #launch-open .launch-label-wide,
  .topbar #launch-open .launch-label-narrow,
  .topbar #agents-dock-open .agents-dock-open-label,
  .topbar #ask-mainframe .ask-label { display: none; }
  .topbar #launch-open,
  .topbar #agents-dock-open,
  .topbar #ask-mainframe {
    width: 2.125rem;
    min-width: 2.125rem;
    /* Real bug (operator report, 19 Aug — item 3): no height was ever set
       here, so these three collapsed to whatever a single 14px glyph
       naturally needs (measured live: 34x14-16px) instead of the proper
       34px SQUARE every other topbar icon-only control (Apps/Settings/
       Help/theme) gets — a squished rectangle with a visibly smaller
       glyph sitting right next to full 34px/16px squares in the same row.
       That size/shape mismatch is what read as "icons too small / too
       much padding". Matched to the sibling controls exactly: 34px square,
       zero padding, 16px glyph (below) instead of their normal 14px
       (.button:not(.topbar-icon-control) .ui-icon, chrome-visual.css) —
       at this tier they ARE topbar icon-only controls, same visual role
       as Apps/Settings/Help, so they get the same glyph size. */
    height: 2.125rem;
    padding: 0;
    justify-content: center;
    gap: 0;
  }
  .topbar #launch-open .ui-icon,
  .topbar #agents-dock-open .ui-icon,
  .topbar #ask-mainframe .ui-icon {
    width: 1rem;
    height: 1rem;
  }
}

/* Topline buttons: prototype gap (8px, was 6.4px from a 0.4rem base) and
   radius (11px, was 11.2px from 0.7rem). Dark-theme ghost background/border
   to the prototype's translucent glass (production --ui-panel/--ui-line are
   solid hex board-wide; light theme keeps this product's pure-white panel
   per doc57's ratified PDF-surface exception, unchanged here). */
.topbar .button.primary,
.topbar .button.quiet {
  gap: 8px;
  border-radius: 11px;
  /* Responsive one-row topbar: labels must shrink via the container-query
     tiers (chrome-visual.css) before the browser ever gets a chance to
     wrap them onto a second line inside a flex-shrunk button — that
     internal wrap was the actual mechanism behind "reads as two rows". */
  white-space: nowrap;
}
html:not([data-theme="light"]) .topbar .button.quiet {
  background: color-mix(in srgb, var(--ui-text) 2.7%, transparent);
  border-color: color-mix(in srgb, var(--ui-text) 7.5%, transparent);
}
html[data-theme="light"] .topbar .button.quiet {
  border-color: rgba(20, 32, 51, 0.1);
}

/* Health signal — ROUND 2 operator design refinement (19 Aug): a labeled
   pill at every width was itself the real debt. Its ~60px Online <->
   Reconnecting… width swing was the direct cause of round 1's page-
   identity flicker (fixed there by reserving the pill's longer footprint
   at all times, which then ate the room the title needed at tight
   widths — the very bug this whole round exists to fix). Fixed at the
   actual source instead: the pill IS a small dot now, at every container
   width, on every page — there is no swing left to have, and the whole
   "compress the pill first" tier logic above simply isn't needed anymore.
   #board-health-label (index.html) is now permanently .visually-hidden —
   still written by the session refresh's setBoardHealth(), so the accessible
   name / aria-live announcement for role=status is unchanged, only the
   painted pill is gone. That call site also
   now mirror the same text onto #board-health's title attribute (sighted
   hover tooltip) and aria-label (belt-and-braces alongside the live
   region). cursor:default, not pointer — doc 57's click-for-why popover
   is a flagged future item, not built yet; this dot does not lie about
   being clickable today. */
#board-health {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  width: 1.375rem;
  min-width: 1.375rem;
  height: 1.375rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: default;
}
#board-health .health-dot {
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  min-width: 0.5rem;
  min-height: 0.5rem;
  border-radius: 50%;
  background: var(--ui-success);
  box-shadow: 0 0 0.5rem color-mix(in srgb, var(--ui-success) 55%, transparent);
  animation: board-health-pulse 2.6s ease-in-out infinite;
}
/* Reconnecting (transient — a retry actively in flight): amber, faster
   pulse reads as "working on it" rather than the calm resting cadence. */
#board-health.reconnecting .health-dot {
  background: var(--ui-warning);
  box-shadow: 0 0 0.5rem color-mix(in srgb, var(--ui-warning) 55%, transparent);
  animation-duration: 1.1s;
}
/* Assistant needs attention (unavailable model/capacity/directory/liveness
   alarm; a real shell signal): red, static — a genuine problem, not a rhythm to watch.
   Takes priority over the amber reconnecting state on the rare tick both
   are true (same specificity, later in source order — reconnecting is
   transient network noise; an assistant alarm is the more real thing to
   surface). */
#board-health[data-assistant="attention"] .health-dot {
  background: var(--ui-danger);
  box-shadow: 0 0 0.5rem color-mix(in srgb, var(--ui-danger) 55%, transparent);
  animation: none;
}
@keyframes board-health-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.55; transform: scale(0.82); }
}
@media (prefers-reduced-motion: reduce) {
  #board-health .health-dot { animation: none; }
}

/* Operator round (2026-09-04): the dot finally says what it means.
   [data-conn-state] is derived (approvals-workforce.js) from the signals the
   dot already paints — green connected default above, amber .reconnecting
   above, and the new disconnected treatment below for gateway-status.js's
   transport overlay. The hover/focus tooltip is a body-level element
   (.board-health-tip) because .topbar is overflow:hidden — an in-bar bubble
   would clip; this one is position:fixed and JS-placed. */
#board-health[data-conn-state="disconnected"] .health-dot {
  background: var(--ui-danger);
  box-shadow: 0 0 0.5rem color-mix(in srgb, var(--ui-danger) 55%, transparent);
  animation: none;
}
#board-health:focus-visible {
  outline: 2px solid var(--ui-accent);
  outline-offset: 2px;
}
.board-health-tip {
  position: fixed; z-index: 90; pointer-events: none;
  padding: 6px 11px; border-radius: 9px; white-space: nowrap;
  background: color-mix(in srgb, var(--ui-bg) 30%, var(--ui-panel));
  backdrop-filter: blur(14px);
  border: 1px solid var(--ui-line);
  box-shadow: var(--ui-shadow);
  color: var(--ui-text); font-size: 12px; font-weight: 500;
  opacity: 0; transform: translateY(-3px);
  transition: opacity var(--speed, 140ms) ease, transform var(--speed, 140ms) ease;
}
.board-health-tip.show { opacity: 1; transform: translateY(0); }

/* Theme toggle glyph: prototype measures it one px smaller than the other
   three icon-only topbar controls (15px vs 16px, chrome-visual.css) —
   matched exactly. */
.topbar #theme-toggle .ui-icon { width: 0.9375rem; height: 0.9375rem; }

/* Shell round (operator-directed, 19 Aug): sign-out moves off the topbar
   (next to the visible email) onto the sidebar, next to the operator
   block, as an icon-only affordance. #hosted-session/#hosted-user/
   #hosted-sign-out simply MOVED in the DOM into .shell-operator — same
   ids, same auth-gate.js wiring (paintHostedSession() looks them up by
   id, not position), zero behavioural change. #hosted-user still exists
   (auth-gate bails on wiring sign-out entirely if any of the three ids is
   missing) but is visually-hidden — the email is what's removed from
   view, not the wiring. */
#hosted-session {
  display: inline-flex;
  align-items: center;
  margin-left: auto;
  flex: none;
}
.shell-sign-out {
  display: grid;
  place-items: center;
  width: 1.875rem;                 /* 30px, matches the operator avatar */
  height: 1.875rem;
  border: none;
  border-radius: 0.5rem;
  padding: 0;
  background: transparent;
  color: var(--ui-text-muted);
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.shell-sign-out:hover {
  background: var(--ui-panel-hover, var(--ui-hover));
  color: var(--ui-text);
}
.shell-sign-out:active { transform: translateY(1px); }
.shell-sign-out svg { width: 1rem; height: 1rem; }

/* Collapsed rail (operator report, 19 Aug — reversed from the prior round):
   the footer used to show the SIGN-OUT icon when collapsed and hide the
   operator identity entirely. Flipped to match how every other collapsed
   rail control reads (an icon representing what it is, not an action) —
   the identity circle (chrome-visual.css/shell.css) is the SAME
   .shell-operator-avatar element the expanded footer uses, unstyled here
   beyond centering, so its look (accent-tinted circle, initials) is
   identical in both states, exactly the operator's ask. Name/plan text and
   the sign-out button hide when collapsed (sign-out stays reachable: one
   click on the avatar re-expands the rail, where sign-out is exactly where
   it always was). The prototype's OWN collapsed rail hides its whole
   .rail-foot outright (mf.css: body.rail-collapsed .rail-foot{display:
   none}) — it never shows an identity circle collapsed at all, so there is
   no literal prototype state to copy; this matches the prototype's
   GRAMMAR instead (an icon-only affordance, not a wrapped label, same as
   every rail-item and the toggle above it) using the prototype's own
   avatar treatment already in this file/shell.css, just kept visible
   through the state where the redesign's real auth requirement (sign-out
   must stay reachable) makes full-hide the wrong call. Click behaviour
   chosen: the collapsed avatar has no identity-menu equivalent to reuse
   (the expanded footer's avatar/name/plan block has never had its own
   click handler — confirmed, none exists) so the natural, honest option
   is the one shell.js already implements for every other collapsed-rail
   affordance: click re-expands the sidebar (setCollapsed(false)),
   keyboard-operable (role=button, tabindex, Enter/Space) only while
   collapsed — an inert decorative span again once expanded, unchanged
   from before this round. */
body.nav-collapsed .shell-operator {
  display: flex;
  justify-content: center;
  padding: 0.5rem 0;
}
body.nav-collapsed .shell-operator-avatar {
  cursor: pointer;
}
body.nav-collapsed .shell-operator-avatar:hover {
  filter: brightness(1.15);
}
body.nav-collapsed .shell-operator-avatar:focus-visible {
  outline: 2px solid var(--ui-accent);
  outline-offset: 2px;
}
body.nav-collapsed .shell-operator-text,
body.nav-collapsed #hosted-session {
  display: none;
}

/* Cross-surface shell round: Files' index status relocated from the
   removed .fn-page-head into .fn-page-tabs (index.html) — same element,
   same id, same files-new-owned styling (#files-tab .fn-index-status,
   files-new/styles.css, untouched). Purely additive nudge, scoped here
   rather than in files-new's own stylesheet.

   Operator report, mid-deploy live check (19 Aug): the first landing
   pushed the status to the row's far end and left Refresh/Upload
   floating mid-row right after the view tabs — wrong on both counts.
   Corrected: the status stays adjacent to the Search tab (index.html
   markup order — same "documents/search" context the operator wants it
   read next to), and Refresh+Upload (the actual right-aligned actions)
   get the margin-left:auto instead, pushed together as a group since
   margin-auto on the first carries every sibling after it along. */
#files-tab .fn-page-tabs #fn-refresh-tree { margin-left: auto; }
