/* ─────────────────────────────────────────────────────────────────────────────
   Solvix platform rail — the ONE sidebar spec, shared by all three apps.

   Delivery Solution (Matrix) is a single 39k-line index.html we do not edit, so
   its rail is injected at runtime by nav.js and styled here. UAT and Governance
   render their own markup but follow the same numbers, so the three read as one
   product:

       rail 232px · bg #fff · border-right 1px #e2e8f0
       group label  10px / 600 / .14em / uppercase / #64748b
       item         28px tall · 13.5px / 500 · radius 8px · pitch 30px
       icon         14px / stroke 1.6 / opacity .9
       hover        #f1f5f9 on #0f172a
       active       #e6f4f2 on #0f766e / 600
       footer       44px, pinned, avatar + name/email + sign out

   THOSE NUMBERS ARE A SUMMARY, NOT THE SOURCE. Every one of them is a token in
   tokens.css and every rule below reads the token. They were literals here
   until the rail-fit work, which is the drift tokens.css exists to prevent --
   and is why "make the icons smaller" was a four-file change in four idioms.

   THIS FILE IS THE REFERENCE RAIL. The other three are matched to it, not the
   other way round, because it is the only one whose every number is already a
   token and the only one with no framework idiom in the way. When P2's
   styles.css, P3's Sidebar.tsx or the shell's inline block disagrees with a
   rule below, the rule below is right. So the standing obligation on this file
   is stricter than on those: NO SHARED NUMBER MAY BE A LITERAL HERE. A literal
   in a reference is a number three other files will copy and then outlive.

   "Shared" is the line, and it is drawn deliberately rather than as an excuse.
   A number is shared -- and must be a token -- if it appears in the fit
   arithmetic, or if any other rail states it too. Everything in the item,
   group, header and footer rules is one or both, and all of it now reads a
   token. What stays a literal is single-implementation ornament that exists in
   this file ALONE: .solvix-launcher and .solvix-launcher-bars, since no other
   rail has a launcher -- it is the <900px control Matrix needs because it has
   no chrome of its own -- plus sub-pixel nudges with no twin anywhere, a 2px
   hit-area padding, a 1px optical margin, border-radius:50% on a disc.
   Tokenising those would add variables with one consumer each, which is the
   other way to make a shared file unreadable.

   The rail is sized to fit a 1366x768 laptop with all three groups expanded,
   the Administration row present and the footer visible. The arithmetic lives
   beside the geometry tokens in tokens.css; do not change --sx-item-h,
   --sx-head-h, --sx-foot-h, the group margins or the Administration margins
   without redoing it. It is currently 597px against a MEASURED 633px of usable
   height, which is ~40px less than the estimate the previous pass used -- the
   reporter's screenshots are at 1.5x DPR and the 232px rail measures 348 image
   px, so the whole image divides by 1.5 and the budget was simply wrong. That
   40px is why the footer was half off the bottom of the screen.

   Every selector stays namespaced `solvix-` so it cannot collide with the host
   page. On wide screens the rail is permanent; under 900px it collapses back to
   the launcher + overlay, which is what small screens actually want.

   How Matrix's content is inset, and why it is a margin:

   A transform on <body> also works — it makes body the containing block for its
   position:fixed descendants, so all 27 move with it — but that is exactly the
   problem. Measured on the running page: with a transform, `bottom`-anchored
   fixed elements resolve against body's box instead of the viewport, so the
   Co-Pilot launcher and the feedback button drift mid-page on short pages and
   scroll away entirely on long ones. That is a functional regression, not a
   cosmetic one.

   A plain margin keeps position:fixed genuinely viewport-fixed. It leaves
   left-anchored fixed elements sitting over the rail, but measured on the
   running page there is exactly one: #copilotLauncher (and #copilotPanel when
   opened), handled by name below. Full-viewport overlays (inset:0 modals) are
   deliberately left covering the rail, which is what a modal should do.

   The rail is mounted on <html> rather than <body> so it is never affected by
   whatever the host page does to body.
   ───────────────────────────────────────────────────────────────────────────── */

:root{
  /* DERIVED, not restated. This was a second literal 232px sitting beside
     tokens.css's --sx-rail-w, which is the drift tokens.css exists to prevent
     and which made the rail impossible to collapse from one place: two
     variables held the same number and only one of them moved.

     The fallback keeps this stylesheet standalone-correct. tokens.css is
     injected ahead of nav.css everywhere (inject-config.js for Matrix, <link>
     order in the shell), but if it ever failed to load the rail should still be
     232px wide rather than 0. */
  --solvix-rail-w: var(--sx-rail-w, 232px);
}

/* The rail owns its own box model instead of inheriting the host page's.
   PRE-EXISTING BUG, surfaced by the collapse work rather than caused by it:
   .solvix-panel declares width:var(--solvix-rail-w) and padding:0 10px plus a
   1px border, so under content-box it renders 253px while the body margin that
   clears it is exactly var(--solvix-rail-w) = 232px. 21px of rail over the
   page. Collapsed it is proportionally worse -- 81px of panel against a 64px
   inset -- which is how it got noticed.

   nav.css's own header states the spec as "rail 232px", so 253 was never the
   intention; the rail just happened to look right on hosts that set
   box-sizing:border-box globally, and depended on them for its geometry.
   Measured on a bare host page: 253px expanded, 81px collapsed.

   Namespaced to .solvix-panel and its descendants, so it cannot reach a single
   element of the host page. */
.solvix-panel, .solvix-panel *{ box-sizing:border-box; }

.solvix-launcher{
  position:fixed; top:10px; left:10px; z-index:2147483000;
  display:flex; align-items:center; gap:7px;
  height:32px; padding:0 11px 0 9px;
  background:var(--sx-accent,#0F766E); color:var(--sx-accent-fg,#fff); border:0;
  border-radius:var(--sx-mark-radius,7px);
  font-family:var(--sx-font-sans,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif);
  font-size:12px; font-weight:600; line-height:1;
  letter-spacing:.01em; cursor:pointer;
  /* Was this shadow spelled out by hand; it is byte-identical to --sx-shadow-pop. */
  box-shadow:var(--sx-shadow-pop, 0 1px 2px rgba(15,23,42,.18), 0 6px 18px -8px rgba(15,23,42,.4));
  transition:opacity var(--sx-t-slow,.18s) ease, transform var(--sx-t-slow,.18s) ease,
             background var(--sx-t-fast,.12s) ease;
}
.solvix-launcher:hover{ background:var(--sx-accent-hover,#115E56); }
.solvix-launcher.solvix-tucked{ opacity:0; pointer-events:none; transform:translateX(-6px); }
.solvix-launcher:focus-visible{ outline:var(--sx-focus-width,2px) solid var(--sx-focus-ring,#0F766E); outline-offset:2px; }
.solvix-launcher-bars{ display:flex; flex-direction:column; gap:2.5px; }
.solvix-launcher-bars i{ display:block; width:12px; height:1.8px; background:var(--sx-accent-fg,#fff); border-radius:1px; }

.solvix-scrim{
  position:fixed; inset:0; z-index:2147482998;
  background:var(--sx-scrim-bg,rgba(15,23,42,.34)); opacity:0; pointer-events:none;
  transition:opacity var(--sx-t-slow,.18s) ease;
}
.solvix-scrim.solvix-open{ opacity:1; pointer-events:auto; }

/* THREE ROWS, NOT ONE SCROLLING BOX. The panel used to be `overflow-y:auto`
   with everything inside it, which is exactly what scrolled once the rail grew
   a footer: the sign-out control would have been the last thing in the scroll
   flow, i.e. the first thing off-screen for the one person who has the most
   rows -- a platform administrator on a 768px laptop.

   So the panel is a flex column that does NOT scroll, and the middle row does.
   nav.js must emit the three rows in this order:

       .solvix-panel-head   fixed height, --sx-head-h
       .solvix-scroll       flex:1, the ONLY scrolling element; holds
                            .solvix-admin and every .solvix-group
       .solvix-foot         fixed height, --sx-foot-h, pinned

   `min-height:0` on the scroller is load-bearing and not defensive noise: a
   flex item's default `min-height:auto` refuses to shrink below its content,
   so without it the item list grows the column past the panel and overflows
   under the footer instead of scrolling inside it. */
.solvix-panel{
  position:fixed; top:0; left:0; bottom:0; z-index:2147482999;
  width:var(--solvix-rail-w); max-width:86vw;
  display:flex; flex-direction:column; overflow:hidden;
  background:var(--sx-rail-bg,#fff); border-right:1px solid var(--sx-rail-border,#E2E8F0);
  box-shadow:var(--sx-rail-shadow, 0 0 40px -12px rgba(15,23,42,.45));
  transform:translateX(-100%); transition:transform var(--sx-t-slow,.18s) ease;
  /* Split out of the `font:` shorthand. The shorthand RESETS every font
     property it does not name -- font-weight and font-style among them -- so
     it cannot be expressed in tokens without also silently restating those. */
  font-family:var(--sx-font-sans,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif);
  font-size:var(--sx-item-font-size,13.5px); line-height:1.5;
  color:var(--sx-item-idle-fg,#475569); padding:0;
  -webkit-font-smoothing:antialiased;
}
.solvix-panel.solvix-open{ transform:translateX(0); }

/* The horizontal padding that used to live on .solvix-panel now lives on the
   three rows, because a padded flex column would pad the footer's top rule in
   from the rail edges and it has to span them.

   The bottom padding is a term in the fit arithmetic, so it is a token
   (--sx-scroll-pad-b) rather than the literal 8px it was. */
.solvix-scroll{
  flex:1 1 auto; min-height:0; overflow-y:auto; overflow-x:hidden;
  padding:0 var(--sx-scroll-pad-x,10px) var(--sx-scroll-pad-b,6px);
}

.solvix-panel-head{
  flex:0 0 auto;
  display:flex; align-items:center; gap:var(--sx-head-gap,10px);
  height:var(--sx-head-h,44px); padding:0 var(--sx-item-pad-x,12px);
  margin:0 0 var(--sx-head-mb,4px);
  border-bottom:1px solid var(--sx-rail-border,#E2E8F0);
}
/* The brand is the route back to the platform home. Before this, nothing in
   any of the three apps linked to "/" — once you were inside an app the only
   way out was the browser's back button. */
.solvix-home{
  display:flex; align-items:center; gap:var(--sx-head-gap,10px);
  flex:1; min-width:0; text-decoration:none; color:inherit;
  border-radius:var(--sx-item-radius,8px); padding:2px;
}
.solvix-home:hover .solvix-title b{ color:var(--sx-accent,#0F766E); }
.solvix-home:focus-visible{ outline:var(--sx-focus-width,2px) solid var(--sx-focus-ring,#0F766E); outline-offset:1px; }
.solvix-mark{
  width:var(--sx-mark-size,28px); height:var(--sx-mark-size,28px);
  flex:0 0 var(--sx-mark-size,28px); border-radius:var(--sx-mark-radius,7px);
  background:var(--sx-mark-bg,#0F766E); color:var(--sx-mark-fg,#fff); display:grid; place-items:center;
  font-weight:700; font-size:var(--sx-mark-font-size,10.5px); letter-spacing:.02em;
}
.solvix-title{ flex:1; min-width:0; }
.solvix-title b{ display:block; font-size:var(--sx-wordmark-size,13.5px); font-weight:600; color:var(--sx-wordmark-fg,#0F172A); letter-spacing:-.01em; line-height:1.2; }
/* `> span`, not ` span`: this styles the DELIVERY PLATFORM subtitle, a direct
   child, and as a descendant selector it also caught the spans inside the
   wordmark in the <b> above -- stacking SOL / i / x vertically at 9px. */
.solvix-title > span{
  display:block; font-size:var(--sx-subtitle-size,9px);
  letter-spacing:var(--sx-subtitle-tracking,.18em); text-transform:uppercase;
  color:var(--sx-subtitle-fg,#64748B); font-weight:500; margin-top:1px;
}
.solvix-close{
  background:none; border:0; color:var(--sx-muted,#64748B); font-size:20px; line-height:1;
  cursor:pointer; padding:2px 6px; border-radius:var(--sx-ctl-radius,6px);
}
.solvix-close:hover{ color:var(--sx-item-hover-fg,#0F172A); background:var(--sx-item-hover-bg,#F1F5F9); }

/* Collapse toggle. Mirrors the shell landing page's button exactly — same 64px
   target, same tmc.rail key, same chevron flip — so the control behaves the
   same wherever you meet it.

   Hidden by default and shown only at >=900px, where the rail is PERMANENT.
   Below that the rail is already a drawer and .solvix-close is the right
   control; the two swap and are never both on screen. Collapsing a drawer to
   64px of icons over the content it overlays would be a worse drawer. */
.solvix-collapse{
  display:none; background:none; border:0; cursor:pointer;
  color:var(--sx-muted,#64748B); padding:4px; border-radius:var(--sx-ctl-radius,6px); line-height:0;
  transition:background var(--sx-t-fast,.12s) ease, color var(--sx-t-fast,.12s) ease;
}
.solvix-collapse:hover{ color:var(--sx-item-hover-fg,#0F172A); background:var(--sx-item-hover-bg,#F1F5F9); }
.solvix-collapse:focus-visible{ outline:var(--sx-focus-width,2px) solid var(--sx-focus-ring,#0F766E); outline-offset:1px; }
/* --sx-ctl-icon-size, NOT --sx-icon-size. This is header chrome, not a row
   glyph: the rows shrank to buy vertical budget and this control sits in a
   fixed-height header where shrinking it buys nothing and costs a target. */
.solvix-collapse svg{
  width:var(--sx-ctl-icon-size,15px); height:var(--sx-ctl-icon-size,15px);
  display:block; transition:transform var(--sx-t-slow,.18s) ease;
}
html.sx-rail-collapsed .solvix-collapse svg{ transform:scaleX(-1); }
@media (prefers-reduced-motion:reduce){ .solvix-collapse svg{ transition:none; } }

/* `display:flow-root` rather than a bare block, and the group no longer
   carries a margin of its own.

   Both changes exist to make this rail's spacing resolve to the SAME number as
   P2's and P3's. The old pair -- `.solvix-group + .solvix-group{margin-top:14px}`
   plus `margin:14px 0 6px` on the label -- collapsed to one 14px gap here,
   because .solvix-panel was a block and the label's top margin escaped its
   parent, and added up to 28px in the two flex columns, where margins do not
   collapse. Two rails, one stylesheet's worth of intent, two different gaps.

   Now --sx-group-mt on the LABEL is the only separation anywhere, and
   flow-root keeps it (and the last item's 2px bottom margin) inside the group
   box, so the block panel and the flex columns measure identically. */
.solvix-group{ padding:0; display:flow-root; }
.solvix-group-label{
  font-size:var(--sx-group-font-size,10px); letter-spacing:var(--sx-group-tracking,.14em);
  line-height:var(--sx-group-line-h,13px); text-transform:uppercase;
  color:var(--sx-group-fg,#64748B); font-weight:var(--sx-group-font-weight,600);
  padding:0 var(--sx-item-pad-x,12px);
  margin:var(--sx-group-mt,10px) 0 var(--sx-group-mb,3px);
}
/* This selector was DEAD until the .solvix-scroll wrapper went in: the first
   <div> child of .solvix-panel was .solvix-panel-head, so no .solvix-group was
   ever :first-of-type and the first group got the full inter-group margin under
   the header rule. Inside .solvix-scroll the only other child is the
   Administration <a>, so it matches now and the tighter first margin is real. */
.solvix-group:first-of-type .solvix-group-label{ margin-top:var(--sx-group-mt-first,4px); }

/* ── Per-group disclosure ──────────────────────────────────────────────────
   The heading is a <button> now (nav.js) and the item container it owns is
   hidden by a CLASS, not by rebuilding the rail, so the collapsed 64px state
   can override it in CSS alone with no second source of truth in JS. Which
   groups are open is decided by the tmc.navgroups contract documented in
   nav.js beside readGroups().

   .sxg-head is the button reset the old <div> never needed. It inherits the
   font and letter-spacing so .solvix-group-label above still styles the text,
   and `width:100%` keeps the chevron pinned right at both 232px and 64px.

   No tag qualifier on .sxg-closed: the four rails wrap their items in
   different elements, and this rule pair is copied between them verbatim.
   `sxg-closed` is a bespoke name used for nothing else. */
/* DELIBERATELY NOT a full button reset. This class shares its element with
   the group-label class, which already supplies font-size, font-weight,
   letter-spacing, text-transform and colour -- so setting `font: inherit` or
   `text-transform: inherit` here does not "leave them alone", it OVERRIDES
   them with the parent's values. The first draft did exactly that and the
   three headings rendered as mixed-case 13px Arial. Only the properties a
   <button> needs and the label class does not supply belong here. */
.sxg-head{
  display:flex; align-items:center; width:100%;
  background:transparent; border:0; cursor:pointer; text-align:left;
  font-family:inherit;
}
.sxg-head-txt{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.sxg-head:hover{ color:var(--sx-item-hover-fg,#0F172A); }
.sxg-head:focus-visible{ outline:var(--sx-focus-width,2px) solid var(--sx-focus-ring,#0F766E); outline-offset:-2px; border-radius:var(--sx-ctl-radius,6px); }
.sxg-chev{
  width:var(--sx-chev-size,13px); height:var(--sx-chev-size,13px); display:block;
  flex:0 0 var(--sx-chev-size,13px); opacity:var(--sx-chev-opacity,.75);
  transition:transform var(--sx-t-slow,.18s) ease;
}
.sxg-head[aria-expanded="true"] .sxg-chev{ transform:rotate(90deg); }

.sxg-closed{ display:none; }

/* Every literal here used to restate a token by hand. They read the tokens now,
   which is what makes --sx-item-h a one-line change rather than a four-file
   one -- the same reason the icon tokens were made live. */
.solvix-item{
  display:flex; align-items:center; gap:var(--sx-item-icon-gap,10px);
  height:var(--sx-item-h,28px); padding:0 var(--sx-item-pad-x,12px);
  margin-bottom:var(--sx-item-gap,2px);
  border-radius:var(--sx-item-radius,8px);
  color:var(--sx-item-idle-fg,#475569); text-decoration:none;
  font-size:var(--sx-item-font-size,13.5px); font-weight:var(--sx-item-font-weight,500);
  line-height:1;
  transition:background var(--sx-t-fast,.12s) ease, color var(--sx-t-fast,.12s) ease;
}
/* Alias for tokens.css's .sx-icon, kept because nav.js has emitted this class
   since the rail existed and this stylesheet should not depend on that file
   being reached for the rail to have correctly sized glyphs. Same declarations,
   same tokens -- see the contract on .sx-icon in tokens.css. */
.solvix-icon{
  width:var(--sx-icon-size,14px); height:var(--sx-icon-size,14px);
  flex:0 0 var(--sx-icon-size,14px);
  stroke-width:var(--sx-icon-stroke,1.6); opacity:var(--sx-icon-opacity,.9);
}
.solvix-item-label{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Administration sits above the application groups and is not one of them, so
   it gets a rule instead of a group heading: a little space, and a separator
   underneath that does the same job the group headings do for each other.

   No horizontal margin and no padding-left override any more. The old
   `margin:4px 8px 8px; padding-left:10px` put the glyph 18px in from the
   scroller's content box while every group label and every item sits at 12px
   -- the comment claimed they lined up and they never did. Inheriting
   .solvix-item's own --sx-item-pad-x is what actually aligns them.

   --sx-rule-soft and --sx-radius were both invented here and exist nowhere in
   tokens.css, so this rule was running on its fallback literals. Fixed to the
   tokens that do exist.

   The three remaining numbers are tokens now too (--sx-admin-mt / -mb /
   -rule-gap), because two of them are TERMS IN THE FIT ARITHMETIC and all three
   are hand-copied into the other three rails. --sx-admin-rule-gap sits INSIDE
   the border-box row, so it costs the budget nothing and only decides where the
   separator is drawn; the two margins are what the arithmetic counts. */
.solvix-admin{
  margin:var(--sx-admin-mt,2px) 0 var(--sx-admin-mb,6px);
  padding-bottom:var(--sx-admin-rule-gap,6px);
  border-bottom:1px solid var(--sx-border-soft,#EDF1F5);
  border-radius:var(--sx-item-radius,8px) var(--sx-item-radius,8px) 0 0;
}

.solvix-item:hover{ background:var(--sx-item-hover-bg,#F1F5F9); color:var(--sx-item-hover-fg,#0F172A); }
.solvix-item:focus-visible{ outline:var(--sx-focus-width,2px) solid var(--sx-focus-ring,#0F766E); outline-offset:-2px; }
.solvix-here{ background:var(--sx-item-active-bg,#E6F4F2); color:var(--sx-item-active-fg,#0F766E); font-weight:var(--sx-item-font-weight-active,600); }
.solvix-here:hover{ background:var(--sx-item-active-hover-bg,#DBEDEA); color:var(--sx-item-active-fg,#0F766E); }

/* ══ THE RAIL FOOTER — THIS IS THE CANONICAL SHAPE ═════════════════════════
   The four rails all grew a footer in commit 4283bac and three of them grew a
   DIFFERENT one. As seen on the live origin, BEFORE this pass corrected them:

     this file / P1   .solvix-foot > .solvix-who(avatar + name/EMAIL) + button
     P2               .sx-rail-foot > Link.sx-rail-who(...) + button
                      -- the same shape, a router Link instead of a div
     P3               a bordered CARD: bg-surface-panel, border-line-soft,
                      rounded-xl, p-3, a 28px Avatar, name + ROLE, and a
                      ChevronRight -- plus its own h-px/mt-auto/pt-3/mb-3
                      separator stack above it, ~79px against this 44px
     shell            the same flat row, but with a SECOND pinned block
                      (.rail-foot, the Theme button) sitting underneath it,
                      which was the visible difference and ~52px of height the
                      other three do not spend

   So two of the four were the odd ones out, and the reporter saw exactly that:
   "Governance's footer looks different" and "the shell's footer looks
   different". THIS ROW IS THE SHAPE THEY NOW MATCH. It is the reference not
   because it is nicer but because it is the one with no framework idiom in the
   way and no number that is not a token. The survey above is kept as the record
   of what each rail had to give up; if a fifth surface ever grows a footer,
   this is the block it copies.

   WHAT THE SHAPE IS, and what each rail had to do to it:

     · a FLAT ROW. No background, no border, no radius, no shadow on the
       identity element. The only rule in the footer is the 1px border-top on
       .solvix-foot itself, which is inside --sx-foot-h. P3 dropped the card
       chrome and its separate h-px separator.
     · TWO TEXT LINES: display name, then EMAIL. Not role. P3 showed
       roleLabel(user) and now shows the email, with the role falling back only
       where there is no email -- which is what P2 already did for the seeded
       local accounts that have none.
     · avatar at --sx-avatar-size (24px), a disc, one initial. P3's was a 28px
       gradient Avatar; both the size and the gradient went.
     · NO CHEVRON. P3's ChevronRight went.
     · sign-out LAST, always: a --sx-foot-btn-size square icon button at
       --sx-ctl-radius, muted, danger on hover. It is a FIXED SQUARE and not
       padding around a glyph, because the three rails spelled that padding
       three ways and the same control came out 25px on two surfaces and 28px
       on the third -- and moved every time --sx-icon-size did.

   CLICKABLE IS FINE AND MUST SURVIVE. P2's identity row is a Link to /profile
   and P3's is a button that opens the profile modal; both are real affordances
   those apps' users rely on and neither is what makes the footer look wrong. It
   is the CHROME that goes -- the card's border, fill, radius and chevron -- not
   the click. A clickable row keeps the hover fill (--sx-item-hover-bg at
   --sx-ctl-radius, spanning the row, no padding of its own) and its
   focus-visible ring, which is what P2 already does and is the pattern to copy.

   DOM nav.js must emit, as the LAST child of .solvix-panel and a SIBLING of
   .solvix-scroll -- inside the scroller it would scroll away, which is the
   whole point of the three-row panel:

       <div class="solvix-foot">
         <div class="solvix-who" title="Name — email">
           <span class="solvix-avatar" aria-hidden="true">A</span>
           <span class="solvix-who-txt">
             <b>Display Name</b><span>name@tallymarkscloud.com</span>
           </span>
         </div>
         <button type="button" class="solvix-signout"
                 title="Sign out" aria-label="Sign out"> <svg…/> </button>
       </div>

   The `title` goes on .solvix-who and not on the two text rows, because those
   rows are display:none at 64px and a title on a hidden element is a title
   nobody can reach -- the same reason P2 puts it on the profile link.

   A rail with an EXTRA footer control puts it in THIS row, as a
   --sx-foot-btn-size sibling immediately before the sign-out button -- never in
   a second block below. A second pinned block is a second footer, it costs the
   fit budget ~52px it does not have, and it is the reason the landing page read
   as a different product from the three apps it launches. Sign out stays last
   so the destructive control is in the same place on every surface.

   THE SHELL'S THEME TOGGLE WAS THE ONE CANDIDATE FOR THAT SLOT AND IT WAS
   DELETED INSTEAD, so today there is no rail with three footer children. The
   rule above still stands for the next one; it is just currently unexercised.
   Why deleted rather than folded: tmc.theme had exactly one reader and one
   writer, both on that page, and tokens.css's dark block only reaches a surface
   that stamps data-theme -- which of the four only Governance does. So the
   control made the front door dark and handed off to three light apps. The
   reasons and the order of operations for bringing theming back properly are
   written at the top of shell/html/index.html. */
.solvix-foot{
  flex:0 0 auto;
  display:flex; align-items:center; gap:var(--sx-foot-gap,8px);
  min-height:var(--sx-foot-h,44px);
  padding:var(--sx-foot-pad-y,6px) var(--sx-foot-pad-x,10px);
  border-top:1px solid var(--sx-rail-border,#E2E8F0);
  background:var(--sx-rail-bg,#fff);
}
/* border-radius and the transition are here even though THIS rail's .solvix-who
   is an inert <div>: P2's and P3's are a link and a button, and the point of a
   reference is that the three read identically when the other two are hovered.
   The hover fill is on a :hover rule below rather than unconditional, so the
   inert div in this rail still picks it up harmlessly and the interactive ones
   in the other two get it for free. No padding -- the fill spans the whole row,
   which is what keeps a 24px avatar and two text rows inside 31px of content
   box. Padding here is what would push it back out. */
.solvix-who{
  display:flex; align-items:center; gap:var(--sx-who-gap,9px);
  flex:1; min-width:0; border-radius:var(--sx-ctl-radius,6px);
  color:inherit; text-decoration:none;
  transition:background var(--sx-t-fast,.12s) ease;
}
.solvix-who:hover{ background:var(--sx-item-hover-bg,#F1F5F9); }
.solvix-who:focus-visible{ outline:var(--sx-focus-width,2px) solid var(--sx-focus-ring,#0F766E); outline-offset:1px; }
.solvix-avatar{
  width:var(--sx-avatar-size,24px); height:var(--sx-avatar-size,24px);
  flex:0 0 var(--sx-avatar-size,24px); border-radius:50%;
  background:var(--sx-accent,#0F766E); color:var(--sx-accent-fg,#fff);
  display:grid; place-items:center;
  font-size:var(--sx-avatar-font-size,10px); font-weight:700; line-height:1;
}
.solvix-who-txt{ min-width:0; flex:1; overflow:hidden; }
.solvix-who-txt b{
  display:block; font-size:var(--sx-who-name-size,12px); font-weight:600;
  line-height:var(--sx-who-line-h,1.3);
  color:var(--sx-ink,#0F172A);
  white-space:nowrap; text-overflow:ellipsis; overflow:hidden;
}
/* The EMAIL line. Second, muted, smaller, ellipsised -- addresses at this
   company run past 30 characters and the column is ~144px wide at 232px of
   rail. A role string would fit without ellipsis, which is part of why P3's
   footer does not look like this one. */
.solvix-who-txt span{
  display:block; font-size:var(--sx-who-sub-size,10.5px);
  line-height:var(--sx-who-line-h,1.3);
  color:var(--sx-muted,#64748B);
  white-space:nowrap; text-overflow:ellipsis; overflow:hidden;
}
/* A fixed square, not padding around a glyph. The three rails expressed this
   button three ways -- padding:5px here and in P2, w-7 h-7 in P3 -- so the same
   control was 25px on two surfaces and 28px on the third, and it moved every
   time --sx-icon-size did. A token-sized box holds still.

   26px, not 24: this chip is its own pointer target (the identity row beside it
   is a separate one), so it is kept clear of the WCAG 2.5.8 AA 24x24 floor
   rather than sitting exactly on it. It fits the 31px content box with 5px to
   spare. */
.solvix-signout{
  flex:0 0 auto; background:none; border:0; cursor:pointer;
  color:var(--sx-muted,#64748B);
  width:var(--sx-foot-btn-size,26px); height:var(--sx-foot-btn-size,26px);
  padding:0; border-radius:var(--sx-ctl-radius,6px); display:grid; place-items:center;
  transition:background var(--sx-t-fast,.12s) ease, color var(--sx-t-fast,.12s) ease;
}
/* Danger on hover, not the accent: this is the one destructive control in the
   rail and it should not look like the active nav item. Matches the shell. */
.solvix-signout:hover{ color:var(--sx-danger,#B0271F); background:var(--sx-item-hover-bg,#F1F5F9); }
.solvix-signout:focus-visible{ outline:var(--sx-focus-width,2px) solid var(--sx-focus-ring,#0F766E); outline-offset:1px; }
/* Full strength, no --sx-icon-opacity: this glyph is the whole control, not a
   label's companion. P2 pins the same thing with `.sx-rail-signout .sx-icon
   { opacity: 1 }` because its glyph comes from RailIcons and carries .sx-icon;
   this one deliberately does not carry the class, which is why it needs no
   such override. */
.solvix-signout svg{
  width:var(--sx-icon-size,14px); height:var(--sx-icon-size,14px); display:block;
}

/* ── Wide screens: the rail is permanent, and the host page is inset ─────── */
@media (min-width:900px){
  html.solvix-railed body{ margin-left:var(--solvix-rail-w) !important; }

  /* Placeholder rail, painted by CSS alone.

     inject-config.js now adds .solvix-railed from a NON-deferred head script so
     the 232px inset is in place for the first paint instead of being applied by
     the deferred nav.js after the 2.37 MB inline script had already painted —
     which is what made the whole page visibly slide right.

     But .solvix-panel is built by JS, so between first paint and nav.js
     mounting there would be a 232px strip of bare page. This fills it with the
     rail's own background and border, so the reserved space reads as the rail
     from frame one and the items simply appear inside it.

     Sits below .solvix-panel's z-index (2147482999) so the real rail paints
     straight over it, and is inert to pointers so it can never eat a click. */
  html.solvix-railed::before{
    content:''; position:fixed; top:0; left:0; bottom:0;
    width:var(--solvix-rail-w); z-index:2147482990;
    background:var(--sx-rail-bg,#fff); border-right:1px solid var(--sx-rail-border,#E2E8F0);
    pointer-events:none;
  }

  /* The one host element that would otherwise sit under the rail. Shifted by
     name because a margin cannot move position:fixed, and keeping it genuinely
     viewport-fixed is worth this two-line exception. */
  html.solvix-railed #copilotLauncher,
  html.solvix-railed #copilotPanel{ left:calc(24px + var(--solvix-rail-w)) !important; }
}

/* ── Retire Delivery Solution's own feedback button ────────────────────────
   The platform now has ONE feedback widget for all three apps
   (_platform/feedback.js), so the app's own floating button has to go — two
   buttons doing the same thing in different places is the problem being solved.

   Hidden from OUTSIDE the file: public/index.html is 39,056 lines and under a
   never-edit rule, so this is a CSS rule in the stylesheet already injected
   into its <head>.

   The selector is a CLASS on purpose. The button is
       <button class="feedback-fab" onclick="openFeedbackCapture()" ...>
   at index.html:427 and it has NO id — a #feedbackFab selector would silently
   match nothing and look like it had worked.

   The modal needs no rule: #feedbackOverlay starts display:none and only
   .active reveals it, and .feedback-fab is its sole entry point, so an
   unclickable button means it can never open. Matrix's own feedback ADMIN log
   (the Admin panel tab) is untouched — it still reads its existing rows.

   Not inside the min-width:900px block above: the app's button should be gone
   at every width, not just where the rail is permanent. */
html.solvix-railed .feedback-fab{ display:none !important; }

@media (min-width:900px){

  .solvix-panel{ transform:none !important; box-shadow:none; transition:none; }
  .solvix-launcher, .solvix-scrim, .solvix-close{ display:none !important; }

  /* The collapse control only exists where the rail is permanent. */
  .solvix-collapse{ display:grid; place-items:center; }

  /* ── Icon-only presentation ───────────────────────────────────────────────
     The WIDTH comes from tokens.css (html.sx-rail-collapsed retargets
     --sx-rail-w to 64px), and .solvix-panel plus the ::before placeholder plus
     the body margin plus #copilotLauncher all already read --solvix-rail-w,
     which now derives from it. So none of those need a rule here: they follow.
     What needs a rule is what to DO with 64px. */

  /* Mark above chevron rather than beside it: two 28px controls plus a gap do
     not fit in 64px side by side without both being cramped. */
  html.sx-rail-collapsed .solvix-panel-head{
    flex-direction:column; height:auto;
    gap:var(--sx-collapsed-gap,6px); padding:var(--sx-collapsed-pad-y,8px) 0;
  }
  html.sx-rail-collapsed .solvix-home{ flex:0 0 auto; justify-content:center; padding:0; }
  html.sx-rail-collapsed .solvix-title{ display:none; }
  html.sx-rail-collapsed .solvix-item-label{ display:none; }
  html.sx-rail-collapsed .solvix-item{ justify-content:center; padding:0; }
  /* The rule above is `padding:0`, which is more specific than .solvix-admin's
     own padding-bottom and would flatten the Administration separator against
     the first group label. Restated at a specificity that clears it. */
  html.sx-rail-collapsed .solvix-item.solvix-admin{ padding:0 0 var(--sx-admin-rule-gap,6px); }
  html.sx-rail-collapsed .solvix-scroll{
    padding:0 var(--sx-scroll-pad-x-collapsed,8px) var(--sx-scroll-pad-b,6px);
  }

  /* ── The collapsed footer ───────────────────────────────────────────────
     The avatar and the sign-out button do not fit side by side: 64px less the
     8px padding each side leaves 48px, and the pair needs 24 + 8 + 26 = 58px.
     So they STACK, and both survive.

     Both, deliberately. Dropping the avatar would leave the rail with no way
     to tell you whose session it is, and dropping the button would leave a
     rail you cannot sign out of -- which is the defect this footer exists to
     fix, reintroduced at 64px. P2 keeps its profile link clickable here for
     the same reason, and P3's identity button must stay clickable here too.

     min-height is released because the column is taller than the row:
     8 + 24 + 6 + 26 + 8 + 1 rule = 73px. The fit arithmetic is stated for the
     EXPANDED rail, which is the worse case -- at 64px the labels are gone and
     the groups lose their headings, so the column is far shorter overall even
     with a taller footer. A rail with a third footer control would grow this
     stack by --sx-foot-btn-size + --sx-collapsed-gap, to 105px, still well
     inside the collapsed budget -- headroom for the next one, since the only
     candidate there was (the shell's Theme toggle) was deleted rather than
     folded in. */
  html.sx-rail-collapsed .solvix-foot{
    flex-direction:column; gap:var(--sx-collapsed-gap,6px); min-height:0;
    padding:var(--sx-collapsed-pad-y,8px) 0;
  }
  /* flex:0 0 auto and centred, but NOT display:contents and not unstyled: the
     row is still the hover and focus target on the rails where it is clickable,
     so it keeps its fill and ring around the bare avatar. */
  html.sx-rail-collapsed .solvix-who{ flex:0 0 auto; justify-content:center; }
  html.sx-rail-collapsed .solvix-who-txt{ display:none; }

  /* Group labels are the casualty of an icon-only rail, and dropping them
     silently would merge three products into one undifferentiated column of
     glyphs. A rule replaces the label as the divider, which is what SAP's and
     Atlassian's collapsed side navs both do. */
  html.sx-rail-collapsed .solvix-group-label{ display:none; }
  html.sx-rail-collapsed .solvix-group + .solvix-group{
    margin-top:var(--sx-collapsed-pad-y,8px); padding-top:var(--sx-collapsed-pad-y,8px);
    border-top:1px solid var(--sx-rail-border,#E2E8F0);
  }

  /* PER-GROUP DISCLOSURE IS IGNORED AT 64px, and this rule is load-bearing.
     The rule above hides .solvix-group-label, which IS the disclosure button,
     so at 64px there is nothing left to click. A group left closed here would
     be permanently unreachable -- the user would see a few glyphs and no way
     to find the rest of the platform. Showing everything is the only safe
     behaviour, and an icon-only rail is compact enough not to need the
     grouping anyway.

     Higher specificity than `.sxg-closed` above (an extra html.class), so it
     wins without !important. */
  html.sx-rail-collapsed .sxg-closed{ display:block; }
}

@media (prefers-reduced-motion:reduce){
  .solvix-panel,.solvix-scrim{ transition:none; }
}
