/* shell.css — the Quiet app shell (UI Quiet build, phase 1, 23 Sep 2026).
   Cascade position 20 of 20: LAST, because it re-seats boxes other files style (the file
   chip moved from the header to the viewport, the dock moved from the pane to the
   toolbar) and those overrides have to win on order, not on `!important`.
   Authority: outputs/uiux-2026-09-18/designs/7-final/DESIGN.md §2, §3, §5.4, §5.7, §5.9,
   §5.10. Tokens only — no colour is introduced here (css-audit item 82).

   Contract for the four build lanes (the ids are in index.html):
     #paneHead #paneTitle #paneSub · #paneBody (the scroller) · #paneFoot
     #viewCrumb (top-left of the viewport) · #viewToolbar > .vtb__bar > #viewToolbarTools + #sheetDock
     #rail > #railNew, #railList, #railAll
     #filesPage > #filesPageBody
     html[data-route]  empty | prepare | preparing | result | files   (js/shell.js)
     html[data-detail] simple | full, and [data-detail-only] on anything tester-only */

/* ══ 1. The detail view ══════════════════════════════════════════════════════════════════
   The plan's one rule, verbatim. Anything that exists only for testers carries
   `data-detail-only`; with the switch off it is not rendered and not focusable. It is not
   the testing switch (css/layout.css §5) and never reads `data-testing`.
   Specificity (0,2,1) beats every class rule in the component files. An ID rule that sets
   `display` on a tagged element would beat it — none exists today (measured in the
   browser on every tagged node), and a lane that adds one must tag a wrapper instead. */
html:not([data-detail="full"]) [data-detail-only] { display: none; }
/* Its mirror (declutter, 24 Sep): the plain version of a line whose tester version carries
   the engine numbers. The two are siblings, so each view reads the fact exactly once. */
html[data-detail="full"] [data-simple-only] { display: none; }

/* ══ 2. Routes: the workspace or the files page, never both ══════════════════════════════
   index.html's head sets data-route="files" before the stylesheets for a deep link, so a
   visit to #/files never paints the workspace first. IDs, so no component rule can
   un-hide the other page by cascade order. */
html[data-route="files"] #workspace { display: none; }
html:not([data-route="files"]) #filesPage { display: none; }

/* ══ 3. Header: logo · Prepare · Your files N · avatar (DESIGN §3, §7) ═══════════════════
   The page and the header are one surface; the panes below are the cards. */
.top {
  background: var(--sn-surface-0); border-bottom: 0;
  gap: var(--sn-space-4);
}
.appnav { display: flex; align-items: center; gap: var(--sn-space-1); min-width: 0; }
.appnav__link {
  display: inline-flex; align-items: center; gap: var(--sn-space-2);
  height: 32px; padding: 0 var(--sn-space-3);
  border-radius: var(--sn-radius-sm);
  color: var(--sn-ink-dim); font-size: var(--sn-text-sm); font-weight: 500;
  text-decoration: none; white-space: nowrap;
  transition: background-color var(--sn-dur-fast) var(--sn-ease-out),
              color var(--sn-dur-fast) var(--sn-ease-out);
}
.appnav__link:hover { color: var(--sn-ink); background: var(--sn-surface-1); }
.appnav__link[aria-current="page"] { color: var(--sn-ink); background: var(--sn-surface-2); }
.appnav__count { font-size: var(--sn-text-2xs); color: var(--sn-ink-mute); }

/* Signed in, the account control is the 32 px avatar alone (DESIGN §5.9). The name stays
   in the accessibility tree — it is the button's name — and only leaves the picture.
   Signed out it is still the "Sign in" pill: no identity, no avatar (CORRECTIONS 5 Sep). */
.acct:has(> .avatar:not([hidden])) {
  width: 32px; padding: 0; justify-content: center;
}
.acct:has(> .avatar:not([hidden])) > .acct__name {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
.acct:has(> .avatar:not([hidden])) > .acct__chev { display: none; }
.acct:has(> .avatar:not([hidden])) > .avatar { margin-left: 0; }
.acct__menu { width: 288px; }

/* The tester switch row (DESIGN §5.10): label + description, and a 32 x 20 track on the
   right. `--sn-accent` is allowed here: "the tester switch when on" is one of the four
   places principle 4 spends the green. */
.acct__row.acct__detail {
  height: auto; min-height: 36px; align-items: flex-start;
  padding: var(--sn-space-2) var(--sn-space-3);
  gap: var(--sn-space-3); white-space: normal;
}
.acct__detail-text { display: grid; gap: var(--sn-space-1); flex: 1 1 auto; min-width: 0; }
.acct__detail-label { font-size: var(--sn-text-sm); font-weight: 600; color: var(--sn-ink); }
.acct__detail-hint { font-size: var(--sn-text-xs); line-height: var(--sn-lh-xs); color: var(--sn-ink-dim); }
.acct__switch {
  position: relative; flex: 0 0 32px; width: 32px; height: 20px; margin-top: 1px;
  border-radius: var(--sn-radius-pill); background: var(--sn-line-strong);
  transition: background-color var(--sn-dur-base) var(--sn-ease-out);
}
.acct__switch-knob {
  position: absolute; top: 3px; left: 3px; width: 14px; height: 14px;
  border-radius: var(--sn-radius-pill); background: var(--sn-ink);
  transition: translate var(--sn-dur-base) var(--sn-ease-out),
              background-color var(--sn-dur-base) var(--sn-ease-out);
}
.acct__detail[aria-checked="true"] .acct__switch { background: var(--sn-accent); }
.acct__detail[aria-checked="true"] .acct__switch-knob { translate: 12px 0; background: var(--sn-accent-ink); }

/* ══ 4. Left pane: head · scroller · foot (DESIGN §3) ════════════════════════════════════ */
.pane__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sn-space-3); min-width: 0;
  padding: var(--sn-space-5) var(--sn-space-5) var(--sn-space-3);
}
.pane__title {
  font-family: var(--sn-font-display); font-weight: 700;
  font-size: var(--sn-text-lg); line-height: var(--sn-lh-lg); letter-spacing: -.01em;
  color: var(--sn-ink);
}
.pane__sub { font-size: var(--sn-text-xs); color: var(--sn-ink-mute); white-space: nowrap; }
.pane__sub:empty { display: none; }
/* Final polish: a hairline where the scroller ends. Without it, a pane whose content runs
   under the foot (a reopened failed job at 1280 x 800) looked cut off by an overlapping
   panel ("…add screenshots if / they help" sliced by "What happens next"). */
.pane__foot { padding: var(--sn-space-2) var(--sn-space-3) var(--sn-space-3); box-shadow: 0 -1px 0 var(--sn-line); }
/* "It is hidden while preparing and on the result." */
html[data-route="preparing"] .pane__foot,
html[data-route="result"] .pane__foot { display: none; }
/* Reopening the choices after a result must keep More control reachable (steps lane). */
html[data-route="result"]:has(#step2.is-done:not(.is-collapsed)) .pane__foot { display: block; }

/* ══ 5. The viewport: crumb top-left, toolbar bottom-centre (DESIGN §3, §5.4) ═══════════ */
/* The crumb never runs under the stats line: min(46%, 100% − 520px), floored so a narrow
   viewport still shows a name rather than nothing. */
.vp-crumb {
  position: absolute; z-index: var(--sn-z-toolbar);
  top: var(--sn-space-3); left: var(--sn-space-4);
  display: flex; min-width: 0;
  max-width: max(240px, min(46%, calc(100% - 520px)));
}
/* topbar.css caps the chip for a header it no longer lives in. Over the bed the surface is
   translucent surface-0 and every secondary text is --sn-ink-dim, never mute (§2). */
.vp-crumb .filechip {
  max-width: 100%;
  background: rgb(var(--sn-surface-0-rgb) / .55); backdrop-filter: blur(8px);
}
.vp-crumb .filechip > span { color: var(--sn-ink-dim); }
/* The support legend's band sits under the crumb instead of on it. */
.stage .band--tl { top: calc(var(--sn-space-3) + 32px + var(--sn-space-2)); }

/* The intake / preparing caption (css/progress.css) sat at 20,20 — exactly where the crumb
   now is. It moves under the crumb, where DESIGN §4.3 puts the progress card (left 16,
   below the crumb). Lane 2 replaces it with the ring card. */
.stage .work-caption { top: calc(var(--sn-space-3) + 32px + var(--sn-space-3)); left: var(--sn-space-4); }
/* The floating run log (a testing surface, css/progress.css) was pinned top-LEFT, over the
   old viewer column; that is now the pane. It floats over the viewport's right side
   instead, clear of the crumb and of the rail. ≤ 940 keeps progress.css's bottom sheet. */
@media (min-width: 941px) {
  .runlog { left: auto; right: calc(var(--sn-rail-w) + var(--sn-space-2) * 2 + var(--sn-space-4)); }
}

/* The empty-state card is centred in the viewport ABOVE the toolbar's band, not over it:
   measured at 1280 x 800 the toolbar's top edge sat 2 px inside the card. Lane 1 replaces
   the card; this only keeps the two from touching until then. */
.stage > .drop:not(.hide) { inset: 0 0 calc(var(--sn-space-7) + var(--sn-space-5)) 0; }

/* One bottom-centred COLUMN: band row 1 (gesture hint / underside badge), band row 2 (the
   text view tools), then the bar. Stacked by flex, so none of them can overlap another
   whatever height the bar grows to with a consent line or a wrapped note. The column is
   click-through; only its children take the pointer. */
.vtb {
  position: absolute; z-index: var(--sn-z-toolbar);
  left: var(--sn-space-4); right: var(--sn-space-4); bottom: var(--sn-space-4);
  display: flex; flex-direction: column; align-items: center; gap: var(--sn-space-2);
  pointer-events: none;
}
.vtb > .band { position: static; max-width: 100%; }
.vtb__bar {
  display: flex; align-items: center; gap: var(--sn-space-1);
  max-width: 100%; padding: var(--sn-space-1);
  border-radius: var(--sn-radius-lg);
  background: rgb(var(--sn-surface-0-rgb) / .72); backdrop-filter: blur(16px);
  box-shadow: 0 0 0 1px var(--sn-line), var(--sn-shadow-raised);
  pointer-events: auto;
}
.vtb__tools { display: flex; align-items: center; gap: var(--sn-space-1); }
.vtb__tools:empty { display: none; }

/* The dock, re-seated. dock.css styles it as a sticky pane footer (padding, a top border,
   its own blur); inside the bar it is a plain column: consent (repair refusal only), the
   split primary, then the note. js/dock.js renders all three exactly as before. */
.vtb .sheet__dock {
  position: static; flex: 0 1 auto;
  display: flex; flex-direction: column; gap: var(--sn-space-1);
  width: max-content; min-width: 0; max-width: 560px;
  padding: 0; border-top: 0; background: none; backdrop-filter: none;
}
.vtb .dock__row { min-width: 240px; }
.vtb .dock__row > .cta { min-height: 40px; padding: 0 var(--sn-space-5); font-size: var(--sn-text-md); }
.vtb .dock__row > .cta--caret { flex-basis: 40px; width: 40px; padding: 0; }
.vtb .consent { margin: 0; padding: var(--sn-space-2) var(--sn-space-2) 0; }
.vtb .cta__note { margin: 0; padding: 0 var(--sn-space-2) var(--sn-space-1); font-size: var(--sn-text-xs); }
.vtb .cta__note:not(.is-ok):not(.is-warn) { color: var(--sn-ink-dim); }
.vtb .cta__note:empty { display: none; }

/* ══ 6. The right rail, 64 px (DESIGN §5.7) ══════════════════════════════════════════════
   Lane 3 adds the thumbnails, the 288 px hover/focus overlay and the pin. */
.rail-pane {
  display: flex; flex-direction: column; align-items: center; gap: var(--sn-space-2);
  min-height: 0; min-width: 0; padding: var(--sn-space-3) 0;
  background: var(--sn-surface-1); border-radius: var(--sn-radius-md); overflow: clip;
}
.rail__new, .rail__all {
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--sn-radius-sm);
  background: transparent; color: var(--sn-ink-dim); text-decoration: none;
  transition: background-color var(--sn-dur-fast) var(--sn-ease-out),
              color var(--sn-dur-fast) var(--sn-ease-out);
}
.rail__new { width: 40px; height: 40px; flex: 0 0 auto; }
.rail__all { flex-direction: column; gap: var(--sn-space-1); width: 48px; padding: var(--sn-space-2) 0; font-size: var(--sn-text-2xs); }
.rail__new svg, .rail__all svg { width: 16px; height: 16px; display: block; }
.rail__new:hover, .rail__all:hover { background: var(--sn-surface-2); color: var(--sn-ink); }
.rail__list {
  flex: 1 1 auto; min-height: 0; width: 100%;
  display: flex; flex-direction: column; align-items: center; gap: var(--sn-space-2);
  overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none;
}

/* ══ 7. The files page (DESIGN §3, §4.5) ═════════════════════════════════════════════════
   Its own scroll, max-width 960, centred, padding 40 24 96. Lane 3 builds the log. */
.files-page { min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.files-page__inner {
  max-width: 960px; margin: 0 auto;
  padding: calc(var(--sn-space-6) + var(--sn-space-2)) var(--sn-space-5) calc(var(--sn-space-7) * 2);
}
.files-page__title {
  font-family: var(--sn-font-display); font-weight: 800;
  font-size: var(--sn-text-lg); line-height: var(--sn-lh-lg); margin-bottom: var(--sn-space-5);
}
/* The history panel is a pane section; on its own page it drops the pane's edge. */
.files-page .history { border: 0; padding-inline: 0; background: none; }

/* ══ 8. Short windows: ≤ 940 px tall (DESIGN §3) ═════════════════════════════════════════
   The pane head tightens to 20 / 8. The result's own tighter spacing is the result lane's. */
@media (max-height: 940px) {
  .pane__head { padding: calc(var(--sn-space-4) + var(--sn-space-1)) var(--sn-space-5) var(--sn-space-2); }
}
