/* topbar.css — The top bar: .top, .brand, .filechip, #creditsChip. (The job strip is gone, UI Quiet.)
   Cascade position 6 of 18. Order is load-bearing and is asserted by
   verify-fixtures.mjs; index.html links these explicitly (never @import) because Caddy's
   try_files turns a missing file into a 200 text/html SPA shell.
   Owner after Step 1: section (a).

   Section (a), batch 1. Items 22, 23, 24, 25, 71, 77b, 134, 148 and the credits half
   of item 12. Reference targets: REFERENCE-STUDY §1.5 (every control in the bar is one
   32 px rhythm, left gutter === right gutter); DESIGN-SPEC §3.3, §4.2, §4.5, §4.6, §6.1.
   The bar is 56 px, not §1.5's 64 px — COMPONENT-PLAN §2 settles that conflict in favour
   of DESIGN-SPEC §3.2, whose body grid is literally `56px minmax(0,1fr)`. */

/* ── top bar ────────────────────────────────────────────────────────────── */
/* `position: relative` and the removal of `overflow: hidden` land TOGETHER, which is
   IMPLEMENTATION-PLAN §5.1's trap: #acctMenu (section b) escaped the header only
   because .top was unpositioned, so positioning it while the clip was still on would
   have trapped the menu inside a 56 px box. With the clip gone there is nothing to
   escape. No z-index: giving .top one would open a stacking context and re-scope
   #acctMenu's z-index 90 inside it; that is section (b)/(o)'s change to make, not this
   one's, and the header already paints above .main as a positioned element. */
.top {
  position: relative;
  display: flex; align-items: center; gap: var(--sn-space-3);
  height: 56px; padding: 0 var(--sn-space-3);
  border-bottom: 1px solid var(--sn-line-strong); background: var(--sn-surface-1);
  min-width: 0;
}

/* ── brand lockup (item 22) ─────────────────────────────────────────────────
   The shipped mark was /assets/logo.png: a 256 px raster that BAKES IN the
   "SLICER NINJA" lockup and rendered it 6-7 px tall at 42 px — present, not
   readable, and the only place the product was named. js/topbar.js swaps the src
   for the wordmark-free /assets/mark-64.png (DESIGN-SPEC §4.2) and unhides the real
   text wordmark beside it. 32 px tall like every other control in the bar. */
.brand {
  display: inline-flex; align-items: center; gap: var(--sn-space-2);
  height: 32px; padding: 0 var(--sn-space-2); margin-left: calc(var(--sn-space-2) * -1);
  border-radius: var(--sn-radius-sm);
  flex: 0 0 auto; min-width: 0; color: inherit; text-decoration: none;
}
.brand__mark {
  width: 26px; height: 26px; flex: 0 0 auto; display: block; object-fit: contain;
  transition: filter var(--sn-dur-fast) var(--sn-ease-out);
}
/* Hover changes fill only (REFERENCE-STUDY §18). A filter is not a transform and does
   not reflow: the mark's rect is byte-identical at rest and on hover. */
.brand:hover .brand__mark { filter: brightness(1.12); }
.brand__word {
  font-family: var(--sn-font-display); font-weight: 800;
  font-size: var(--sn-text-md); letter-spacing: -.02em; line-height: 1;
  color: var(--sn-ink); white-space: nowrap;
}

/* ── job strip (item 23): removed with the markup, UI Quiet 23 Sep (js/topbar.js). */

/* ── file chip (items 134, 148, 71, 77b) ────────────────────────────────────
   `width: max-content` replaces `flex: 1 1 auto; max-width: 320px`, which always
   filled to the cap and left 84 px (26%) of empty pill to the right of the remove
   button at every viewport from 1440 to 960.

   The cap is tighter than DESIGN-SPEC §4.6's min(360px, 32vw). MEASURED reason: the job
   strip is absolutely centred, so a wide chip and the strip collide. The room the chip
   actually has is `(W/2 - S/2) - 138.53 - 12`, which with S = clamp(320, 40vw, 640) is
   `30vw - 152px` from 1024 to 1600 and more above it — 232px at 1280, 281px at 1440.
   `min(280px, 30vw - 152px)` stays inside that at every width; 360px would overlap the
   strip by 128px at 1280 with a long filename.

   The edge is an INSET RING, not §4.6's `border`. MEASURED reason: item 77b requires
   #clearFile to be 32x32 and the chip is 32px tall, so a 1px border would leave a 30px
   content box that a 32px target cannot fit in. A ring keeps the content box at 32px.
   This is also the edge treatment the chip shipped with, so nothing repaints. */
.filechip {
  display: none; align-items: center; gap: var(--sn-space-2);
  flex: 0 1 auto; width: max-content; max-width: min(280px, calc(30vw - 152px)); min-width: 0;
  height: 32px; padding: 0 var(--sn-space-2) 0 var(--sn-space-3);
  border-radius: var(--sn-radius-sm); background: var(--sn-surface-2);
  box-shadow: inset 0 0 0 1px var(--sn-line);
  font-size: var(--sn-text-sm);
}
.filechip.on { display: inline-flex; }
/* Middle truncation, item 134: the head ellipsises and the tail — the last 12
   characters, which is where `-v2-final.stl` lives — never does. js/topbar.js does
   the split and carries the full name in a `title`. */
.filechip b {
  display: inline-flex; align-items: baseline; min-width: 0;
  font-weight: 600; color: var(--sn-ink);
}
/* `pre`, not `nowrap` (final polish): the two halves are separate flex items, and `nowrap`
   drops a space at either edge of each, so "My Model Final Version 2.stl" split at a space
   rendered as "My Model FinalVersion 2.stl". `pre` keeps the space and still never wraps. */
.filechip__head { overflow: hidden; text-overflow: ellipsis; white-space: pre; min-width: 0; }
.filechip__tail { flex: 0 0 auto; white-space: pre; }
/* No tabular figures anywhere in the bar: Schibsted Grotesk gives the full stop a full
   digit advance and renders `10 . 8 MB` (mocks/NOTES.md B4). Neither value is a column
   being compared, so neither needs them. */
/* `> span`, not ` span` — the one character section (k) found (CORRECTIONS, 6 Sep).
   This rule is for the SIZE/COUNT text, which is the chip's only direct span child. Written
   as a descendant selector it also matched `.filechip__head` and `.filechip__tail`, which
   live inside the `<b>`, and at (0,1,1) it outranked `.filechip__head`'s (0,1,0) — so the
   head's computed flex-shrink was 0 and it could not ellipsise at all. MEASURED with a
   77-character filename: `#filechip` correctly 280 px but `.filechip__head` 397.5 px,
   painting straight across the step strip (after/W2k/gaps/33-longname.png). Section (a)'s
   file is closed and this is that section's one outstanding rule, reassigned to (o). */
.filechip > span {
  color: var(--sn-ink-mute); font-size: var(--sn-text-xs);
  font-variant-numeric: normal; white-space: nowrap; flex: 0 0 auto;
}
/* 18x18 unlabelled glyph -> 32x32 with a real name (items 71, 77b).
   The negative block margins keep the 32px border-box inside the chip's 32px content
   box; getBoundingClientRect() still reports 32 x 32. */
.filechip button {
  display: inline-grid; place-items: center;
  width: 32px; height: 32px; margin-block: -1px; margin-right: calc(var(--sn-space-1) * -1);
  border: 0; border-radius: var(--sn-radius-sm); background: none;
  color: var(--sn-ink-mute); font-size: var(--sn-text-sm); line-height: 1; flex: 0 0 auto;
  transition: background-color var(--sn-dur-fast) var(--sn-ease-out),
              color var(--sn-dur-fast) var(--sn-ease-out);
}
.filechip button:hover { color: var(--sn-bad); background: var(--sn-bad-tint); }

/* ── right cluster ──────────────────────────────────────────────────────────
   gap === the bar's own padding, so the right gutter equals the left gutter to the
   pixel (REFERENCE-STUDY §1.5). */
.top__right {
  margin-left: auto; display: flex; align-items: center; gap: var(--sn-space-3);
  color: var(--sn-ink-dim); flex: 0 0 auto;
}

/* `.avatar` USED TO LIVE HERE. Step 1 parked it in this file, but it is only ever worn
   by #acctAvatar, which is section (b)'s. Section (b) now declares it in full in
   css/account.css (it carries the auto-assigned profile mark), so the copy here is
   deleted rather than kept as a second, drifting definition.
   DEPENDENCY, stated so a partial merge cannot silently un-style it: this deletion is
   only safe once fix/dash-sec-b-account is merged. If (b) is dropped, restore the block
   from git history at this line. */

/* ── credits chip (items 12, 25) ────────────────────────────────────────────
   .chip-top is CONSUMED, NEVER REDEFINED: its height, padding, font-size and
   line-height are base.css's and item 12 depends on both pills computing from the one
   formula. Everything this rule used to carry — .34em/.7em padding, its own radius,
   its own fill, its own ring and `align-items: baseline` — is deleted, because that
   second box formula is exactly what made the two pills 28.77 px and 28.00 px tall
   with baselines a full 1 px apart (CORRECTIONS.md, item 12). */
/* `gap` is the one thing left that could still make the two pills different boxes:
   base.css's .chip-top ships --sn-space-1 and section (b)'s .acct sets --sn-space-2 per
   DESIGN-SPEC §4.3. base.css is frozen, so the credits pill matches the account pill
   here rather than both waiting on a shared-file change. */
.credits { cursor: default; gap: var(--sn-space-2); }
.credits b { font-weight: 700; color: var(--sn-ink); font-variant-numeric: normal; }
/* Item 25: the product never checks credits, and a `0 credits` counter beside the
   primary action reads as a block. The chip renders only when js/topbar.js has seen a
   POSITIVE balance; js/account.js's `hidden = !signedIn` can no longer reveal a zero. */
#creditsChip:not(.has-balance) { display: none; }

/* ── responsive (item 24): the bar ADAPTS, it does not only subtract ──────── */
/* <1024: the strip collapses to the current step alone (DESIGN-SPEC §3.3). With the
   centre down to ~67px the file chip has room again, so its cap goes back to a plain
   viewport fraction. */
@media (max-width: 1023px) {
  .filechip { max-width: min(280px, 26vw); }
}
/* <=640: the wordmark goes, the mark stays 26 px (it was 42 px at every width, eating
   42 of the 56 px bar on a phone), and the strip stops being centred so it cannot sit
   under the chip. */
@media (max-width: 640px) {
  .brand__word { display: none; }
  .top { gap: var(--sn-space-2); padding: 0 var(--sn-space-2); }
  .filechip { max-width: 40vw; }
}
/* <=430: the credits chip goes and its balance reappears in the account menu's
   identity row (item 16, section b, via topbar.creditsVisible()); the three steps are
   still readable in the rail's own step headers. */
@media (max-width: 430px) {
  .credits { display: none; }
  /* Same one-character correction as the base rule above, and here it was visible rather
     than latent: as a descendant selector this hid `.filechip__head` and
     `.filechip__tail` too, so at 390 the chip rendered as an empty pill with a ✕ and no
     filename in it at all. What a phone drops is the SIZE, which the rail's file list
     already states; the name is the whole reason the chip exists. */
  .filechip > span { display: none; }
}
