/* site-rail.css - the navigation rail (task 11.11), Console direction.
 *
 * THIS SHEET IS DELIBERATELY UNSCOPED, and it is the only stylesheet in
 * docs/ that is allowed to be. `tests/test_dashboard_html.py`'s
 * `test_per_skin_stylesheets_are_scoped_to_their_own_skin` polices the eight
 * PER-SKIN sheets, each of which must start every selector with its own
 * `html[data-skin="..."]`. The rail is not a skin: it is chrome that sits
 * OUTSIDE `<main>`, where every skin renders, so it takes no `data-skin`
 * prefix and - the point of putting it there - not one of those eight sheets
 * is edited to make it work. `tests/test_site_rail.py` asserts both halves:
 * that this file owns only `.sr-*` / `[data-rail-*]` selectors plus the one
 * `body` offset, and that no per-skin sheet mentions the rail at all.
 *
 * THE OFFSET. The rail is `position: fixed`, and the page is moved aside by
 * `body { padding-inline-start: var(--rail-w) }`. `body` is chosen over
 * `.wrap` because six of the eight skins already set `.wrap` padding or
 * max-width (hilma, klint, alien, tech, retro, paper) and would fight it,
 * while NOT ONE sets any padding on `body` - checked across all eight sheets
 * before this was written, and pinned by a test so it stays true.
 *
 * ONE LOOK ON EVERY SKIN, which is most of the point. The rail keeps the
 * console ground whether the page around it is Arnie Paper's white or the
 * Alien skin's black, so navigation is the one element that does not change
 * identity when the reader changes skin. Its accent is Arnie Paper's cobalt
 * (#5D8DFF, the dark-palette blue from docs/ARNIE_PAPER_MOCKUP.md) because
 * that palette is what the rail's ground is dark enough to need.
 */

:root{
  --rail-w:236px;
  --rail-bg:#0E1013;
  --rail-ink:#E8EAED;
  --rail-muted:#7E858F;
  --rail-rule:#23282F;
  --rail-accent:#5D8DFF;
  --rail-ok:#7AB893;
  --rail-degraded:#D9A441;
  --rail-critical:#F14A50;
  --rail-mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}
/* On a dark page the rail drops to the deepest ground in the Graphite Signal
   palette so it reads as recessed rather than as a lighter panel. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){ --rail-bg:#08090A; --rail-rule:#1E2227; }
}
:root[data-theme="dark"]{ --rail-bg:#08090A; --rail-rule:#1E2227; }

/* The workbench layout is wider by its context column. Declaring the width
   here rather than in JS is what makes the evolution one attribute. */
[data-rail-layout="workbench"]{ --rail-w:272px; }

/* THE OFFSET IS GATED ON THE RENDER, and carries a `[data-rail="on"]`
   prefix for two independent reasons. (1) Degradation: ungated, a page whose
   site-rail.js failed to load would still be indented by 236px with nothing
   in the gap, since #siteRail ships `hidden`. Gated, a failed rail leaves the
   page exactly as it was. (2) Specificity: `html[data-skin="tech"] body` sets
   `padding-top`, which at (0,2,1) beats a bare `body` whatever the source
   order - so the narrow-viewport rule below has to match that weight to win.
   It does, and this sheet loads after all eight skin sheets, so the tie goes
   to the rail. */
html[data-rail="on"] body{ padding-inline-start:var(--rail-w); }

#siteRail{
  position:fixed;
  inset-block:0;
  inset-inline-start:0;
  width:var(--rail-w);
  display:flex;
  background:var(--rail-bg);
  color:var(--rail-ink);
  border-inline-end:1px solid var(--rail-rule);
  z-index:900;
  overflow:hidden;
}
#siteRail *{ box-sizing:border-box; }

.sr-single,.sr-column{
  display:flex;
  flex-direction:column;
  gap:18px;
  padding:16px 0 14px;
  min-width:0;
  flex:1;
  overflow-y:auto;
  overscroll-behavior:contain;
}
.sr-strip{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:6px;
  padding:16px 0 14px;
  width:58px;
  flex:none;
  border-inline-end:1px solid var(--rail-rule);
}
.sr-column{ border-inline-start:0; }

/* ── Brand ─────────────────────────────────────────────────────────────── */
.sr-brand{ display:flex; align-items:center; gap:8px; padding:0 16px 2px; }
.sr-brand i{ width:8px; height:8px; background:var(--rail-accent); flex:none; display:block; }
.sr-brand b{
  font-family:var(--rail-mono);
  font-size:12px; font-weight:600;
  letter-spacing:.16em; text-transform:uppercase;
  white-space:nowrap;
}
.sr-strip .sr-brand{ padding:0 0 10px; }
.sr-strip .sr-brand b{ display:none; }

/* ── Context (the spot) ────────────────────────────────────────────────── */
.sr-context{
  display:flex; align-items:center; gap:8px;
  margin:0 16px; padding:9px 10px;
  background:transparent;
  border:1px solid var(--rail-rule);
  color:inherit; cursor:pointer; text-align:start;
  font:inherit;
}
.sr-context:hover{ border-color:var(--rail-accent); }
.sr-context > span:first-child{ min-width:0; }
.sr-context b{
  display:block; font-family:var(--rail-mono);
  font-size:12px; font-weight:600; letter-spacing:.1em; text-transform:uppercase;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.sr-context em{
  display:block; font-style:normal; font-family:var(--rail-mono);
  font-size:9px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--rail-muted); margin-top:2px;
}
.sr-caret{ margin-inline-start:auto; color:var(--rail-muted); font-size:10px; flex:none; }

.sr-ctxhead{ padding:0 14px; }
.sr-ctxhead b{ display:block; font-family:var(--rail-mono); font-size:12px;
  font-weight:600; letter-spacing:.1em; text-transform:uppercase; }
.sr-ctxhead em{ display:block; font-style:normal; font-family:var(--rail-mono);
  font-size:9px; letter-spacing:.11em; text-transform:uppercase; color:var(--rail-muted); }

/* ── Readout — the Console direction's reason for existing ─────────────── */
.sr-readout{ margin:0 16px; border:1px solid var(--rail-rule); }
.sr-rrow{ display:flex; align-items:baseline; justify-content:space-between;
  gap:8px; padding:6px 10px; }
.sr-rrow + .sr-rrow{ border-top:1px solid var(--rail-rule); }
.sr-rrow k{
  font-family:var(--rail-mono); font-size:9px;
  letter-spacing:.12em; text-transform:uppercase; color:var(--rail-muted);
}
.sr-rrow v{
  font-family:var(--rail-mono); font-size:12.5px; font-weight:600;
  font-variant-numeric:tabular-nums; color:var(--rail-ink); white-space:nowrap;
}
.sr-rrow v.sr-acc{ color:var(--rail-accent); }

/* ── Groups and items ──────────────────────────────────────────────────── */
.sr-group{ display:flex; flex-direction:column; }
.sr-glabel{
  font-family:var(--rail-mono); font-size:9px;
  letter-spacing:.16em; text-transform:uppercase; color:var(--rail-muted);
  padding:0 16px; margin-bottom:6px;
}
.sr-item{
  display:flex; align-items:center; gap:10px;
  min-height:44px; box-sizing:border-box;
  padding:7px 16px; position:relative;
  color:var(--rail-muted); text-decoration:none; cursor:pointer;
  font-family:var(--rail-mono); font-size:12px; font-weight:500;
  letter-spacing:.11em; text-transform:uppercase;
  background:transparent; border:0; text-align:start; width:100%;
}
.sr-item svg{ width:15px; height:15px; flex:none; }
.sr-item:hover{ color:var(--rail-ink); background:rgba(255,255,255,.04); }
.sr-item.sr-current{ color:var(--rail-accent); background:rgba(93,141,255,.1); }
.sr-item.sr-current::before{
  content:""; position:absolute; inset-block:0; inset-inline-start:0;
  width:2px; background:var(--rail-accent);
}
.sr-action{ font-family:var(--rail-mono); }

/* Icon-only strip (workbench). The label rides along as a hover tip rather
   than being dropped, so the strip stays reachable by name. */
.sr-strip .sr-item{
  width:38px; height:38px; min-height:0; padding:0;
  justify-content:center; gap:0;
}
.sr-strip .sr-item svg{ width:17px; height:17px; }
.sr-strip .sr-item.sr-current::before{ display:none; }
.sr-strip .sr-item.sr-current{ background:var(--rail-accent); color:#0E1013; }
.sr-strip .sr-glabel{ display:none; }
.sr-tip{
  position:absolute; inset-inline-start:calc(100% + 8px); top:50%;
  transform:translateY(-50%);
  background:var(--rail-ink); color:var(--rail-bg);
  font-family:var(--rail-mono); font-size:10px; font-weight:600;
  letter-spacing:.08em; padding:3px 7px; white-space:nowrap;
  opacity:0; pointer-events:none; transition:opacity .12s ease; z-index:5;
}
.sr-item:hover .sr-tip,.sr-item:focus-visible .sr-tip{ opacity:1; }
.sr-single .sr-tip{ position:static; transform:none; opacity:1; background:none;
  color:inherit; padding:0; font-weight:500; }

/* ── Spot list (workbench's column; console's popover) ─────────────────── */
.sr-locrow{
  display:flex; align-items:center; gap:9px; padding:6px 16px;
  color:var(--rail-muted); text-decoration:none; cursor:pointer;
  font-family:var(--rail-mono); font-size:11px; letter-spacing:.06em;
}
.sr-locrow:hover{ color:var(--rail-ink); background:rgba(255,255,255,.04); }
.sr-locrow.sr-current{ color:var(--rail-ink); background:rgba(93,141,255,.1); }
.sr-sq{ width:6px; height:6px; background:var(--rail-rule); flex:none; display:block; }
.sr-locrow.sr-current .sr-sq{ background:var(--rail-accent); }

/* ── Footer ────────────────────────────────────────────────────────────── */
.sr-spacer{ flex:1 1 auto; min-height:12px; }
.sr-foot{
  display:flex; flex-direction:column; gap:9px;
  padding:12px 16px 0; border-top:1px solid var(--rail-rule);
}
.sr-health{
  display:flex; align-items:center; gap:7px;
  font-family:var(--rail-mono); font-size:9px;
  letter-spacing:.08em; text-transform:uppercase; color:var(--rail-muted);
}
.sr-dot{ width:7px; height:7px; border-radius:50%; flex:none; display:block; }
.sr-dot.sr-ok{ background:var(--rail-ok); }
.sr-dot.sr-degraded{ background:var(--rail-degraded); }
.sr-dot.sr-critical{ background:var(--rail-critical); }
.sr-appearance{
  display:flex; align-items:center; gap:7px;
  background:transparent; border:0; padding:0; cursor:pointer; font:inherit;
  font-family:var(--rail-mono); font-size:9px;
  letter-spacing:.08em; text-transform:uppercase; color:var(--rail-muted);
}
.sr-appearance:hover{ color:var(--rail-ink); }

/* The desktop-site request (a phone reader asking for the desktop layout).
   Rendered only where the page opts in (index.html), and DISPLAYED only where
   it means something: on a narrow viewport, or - crucially - once desktop
   mode is ON, when the layout viewport is wide and the narrow media query no
   longer matches. Without that second rule the button that turns the mode on
   would hide itself, stranding the reader in desktop mode with no way back. */
.sr-desktop{
  display:none; align-items:center; gap:7px;
  background:transparent; border:0; padding:0; cursor:pointer; font:inherit;
  font-family:var(--rail-mono); font-size:9px;
  letter-spacing:.08em; text-transform:uppercase; color:var(--rail-muted);
}
.sr-desktop:hover{ color:var(--rail-ink); }
html[data-rail-desktop-site="on"] .sr-desktop{ display:flex; }

/* The account slot (task 11.13). It renders only where the caller resolved an
   accounts API, so there is no "absent" styling to write - an absent account
   contributes no element at all. Same footer weight as the health line and
   Appearance: this is chrome, not a call to action. */
.sr-account{
  display:flex; align-items:center; gap:7px; text-decoration:none;
  font-family:var(--rail-mono); font-size:9px;
  letter-spacing:.08em; text-transform:uppercase; color:var(--rail-muted);
}
.sr-account:hover{ color:var(--rail-ink); }
.sr-avatar{
  width:7px; height:7px; flex:none; display:block; border-radius:50%;
  border:1px solid var(--rail-rule);
}
.sr-account.sr-signed-in .sr-avatar{
  background:var(--rail-accent); border-color:var(--rail-accent);
}
/* An email is longer than the rail is wide, and wrapping it would push the
   footer around. */
.sr-aname{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.sr-strip .sr-foot{ padding:12px 0 0; align-items:center; }
.sr-strip .sr-appearance span,.sr-strip .sr-health{ display:none; }
/* In the icon strip the label has nowhere to go; the dot and the `title`
   carry it, exactly as the health line's own label is dropped above. */
.sr-strip .sr-aname{ display:none; }

/* The 16.7 per-page header nav is redundant once the rail is up - and only
   then. `[data-rail="on"]` is set by the page's own wiring AFTER a successful
   render, so a failed or missing site-rail.js leaves the old navigation
   visible instead of hiding it behind a rail that never appeared. */
html[data-rail="on"] #headerNav{ display:none; }

/* ── What the rail makes redundant ────────────────────────────────────────
 * All five 16.7 clusters carried BOTH navigation and the two operator
 * buttons; the rail now carries both, so the clusters are hidden whole
 * rather than emptied (an emptied flex row still leaves its own gap). Every
 * one of these rules is gated on `[data-rail="on"]`, which the page sets
 * only after a successful render - so a missing site-rail.js leaves all five
 * clusters exactly where they were.
 *
 * The markup is NOT removed from the pages. `tests/test_site_nav.py` pins
 * the five mounts, their containers and the operator handlers inside them,
 * and those assertions are still true and still worth having: they are what
 * keeps the fallback real.
 */
html[data-rail="on"] .action-bar,
html[data-rail="on"] .k-system-actions,
html[data-rail="on"] .cs-actions,
html[data-rail="on"] .cs-mobile-actions{ display:none; }
html[data-rail="on"] .h-sidebar nav{ display:none; }

/* The eight-button skin toggle is demoted, not removed: it keeps owning
   `wingcheck-skin` and every stored value still resolves. It is revealed by
   the rail's Appearance button. Gated on `[data-rail="on"]` for the same
   reason as above - with no rail there is no Appearance button, and hiding
   it would strand the control. */
html[data-rail="on"] .skin-toggle{ display:none; }
html[data-rail="on"][data-rail-appearance="on"] .skin-toggle{ display:flex; }

#siteRail :focus-visible{ outline:2px solid var(--rail-accent); outline-offset:-2px; }

/* ── Narrow viewports ──────────────────────────────────────────────────────
 * The rail becomes a top strip rather than disappearing: the destinations
 * stay reachable, and the readout - which is the direction's whole argument -
 * stays with them. Everything that only makes sense in a column is dropped.
 */
@media (max-width:860px){
  :root,[data-rail-layout="workbench"]{ --rail-w:0px; }
  html[data-rail="on"] body{ padding-inline-start:0; padding-block-start:52px; }
  #siteRail{
    inset-block:auto 0; inset-block-start:0; inset-inline:0;
    width:auto; height:52px;
    border-inline-end:0; border-block-end:1px solid var(--rail-rule);
  }
  .sr-single,.sr-column,.sr-strip{
    flex-direction:row; align-items:center; gap:10px;
    padding:0 12px; width:auto; border:0; overflow-x:auto; overflow-y:hidden;
  }
  .sr-group{ flex-direction:row; align-items:center; gap:2px; }
  .sr-glabel,.sr-spacer,.sr-readout,.sr-brand b,.sr-context em,.sr-health{ display:none; }
  /* The FOOTER stays, as part of the scrollable strip. Hiding it whole (as
     this rule first shipped) hid the Appearance button with it - and that
     button is the ONLY control that reveals the demoted skin toggle, so on a
     phone there was no way to change skin at all. Only the health line is
     dropped: it is a status, not a control, and the strip is short on room. */
  .sr-foot{ flex-direction:row; align-items:center; gap:12px; border-top:0;
    padding:0; flex:none; }
  .sr-appearance,.sr-desktop{ white-space:nowrap; flex:none; }
  .sr-desktop{ display:flex; }
  .sr-item{ width:auto; padding:6px 9px; white-space:nowrap; }
  .sr-item.sr-current::before{ inset-block:auto 0; inset-inline:0; width:auto; height:2px; }
  .sr-context{ margin:0; padding:5px 9px; flex:none; }
  /* Where the revealed skin toggle GOES on a phone. The rail is a fixed
     52px top strip at z-index 900, and two skins (HILMA's own mobile rule at
     top:7px is the one that was reported) position the toggle absolutely at
     the top of the page - underneath the strip, unreachable. This selector
     outweighs every per-skin `html[data-skin="..."] .skin-toggle` rule
     ((0,3,1) vs (0,2,1)) and this sheet loads last, so the revealed toggle
     always drops in as a panel directly below the strip, whatever skin is
     showing. */
  html[data-rail="on"][data-rail-appearance="on"] .skin-toggle{
    position:fixed; top:52px; inset-inline:0; z-index:899;
    margin:0; max-width:none; border-radius:0;
  }
}

/* ── Primary navigation must not scroll (Gate B / REMEDIATION_DIRECTION.md
 * 5.1: "Mobile must not depend on horizontally scrolling the primary
 * navigation") — Slice 2 review finding: the ORIGINAL version of this rule
 * only covered <=480px, leaving 481-860px on the wider `@media
 * (max-width:860px)` block above, which still scrolls its whole strip
 * horizontally (`overflow-x:auto` on `.sr-single,.sr-column,.sr-strip`).
 * That is exactly the scrolling-primary-nav failure Gate B forbids, just at
 * a wider width, so this rule now spans the FULL 481-860px phone/tablet
 * range, not only the narrowest phones. The 860px block above is otherwise
 * unchanged and still supplies the top-strip layout (fixed height, row
 * direction) that this block builds on.
 *
 * At and below 860px the PRIMARY destinations plus the account entry become
 * one non-scrolling, equal-width row: a compact tab bar, `display:contents`
 * on their two wrapping elements (`.sr-group`, `.sr-foot`) so every
 * surviving item - across however many groups a given page's capability
 * gating leaves - shares the row as ONE flex line rather than as nested,
 * unevenly-sized boxes.
 *
 * Everything else this repo already treats as secondary - the spot/context
 * switcher, the desktop-site request, and (on design-lab.html only) the
 * Appearance reveal - collapses OUT of this row rather than fighting it for
 * width, which is exactly what REMEDIATION_DIRECTION.md 5.1 allows ("Use a
 * compact menu or a tested bottom navigation"). None of them loses its
 * markup or its stored preference: `.sr-appearance` still reveals
 * `.skin-toggle` and `.sr-desktop` still restores itself the instant
 * desktop-site mode is ON, because the unconditional
 * `html[data-rail-desktop-site="on"] .sr-desktop{ display:flex; }` rule
 * above has higher specificity than this one and carries no media guard at
 * all - the same safety net `test_desktop_mode_keeps_its_own_off_switch_visible`
 * already pins - but above 860px, not inside this collapsed row; there is no
 * on-screen affordance for either control between 481 and 860px, which is
 * the documented trade REMEDIATION_DIRECTION.md 5.1 accepts (design-lab.html
 * is not a production page and is exempt from Gate B).
 *
 * LABELS NEVER ELLIPSIS-CLIP (review finding (b)): a truncated primary
 * destination label is unreadable and unrecoverable by the reader, so a
 * label that does not fit its cell WRAPS onto a second line instead of
 * being clipped. `site-nav.js`'s own labels were also shortened (`Wind
 * map` -> `Map`) so wrapping is the exception rather than the rule at
 * 375px, not a substitute for short labels.
 *
 * MID-WORD WRAP AT SIX CELLS (task 25.6): 18.13's own reviewer measured
 * that adding the sixth destination (Spots, 2026-09-03) shrank each cell to
 * 53px on a page carrying the account slot, and `overflow-wrap:break-word`
 * alone - the only line-break control the label rule had - was breaking
 * "Forecast" and "Sessions" at an arbitrary character ("FORECA"/"ST",
 * "SESSIO"/"NS") rather than a real word boundary. `hyphens:auto` was tried
 * first (with `lang="en"`, already present on every production page, needing
 * no label-text change) but a REAL RENDERED CHECK (this row's own precedent,
 * required by premise (g)) showed it does not fire in the browser used for
 * verification here - a known gap in headless/Linux Chromium's hyphenation
 * dictionary support - so it survives below only as an inert safety net for
 * a browser that DOES support it, never as the actual fix.
 *
 * FIRST ATTEMPT, OBJECTED TO ON REVIEW: giving `.sr-item,.sr-account` a
 * `flex-basis:auto` let each cell claim room proportional to its own
 * label's natural width instead of the six cells splitting the row exactly
 * evenly - which did stop the wrap, but only by taking room FROM the short
 * cells, three of which fell under the 44 CSS-px hit-region floor
 * REMEDIATION_DIRECTION.md:78 (Gate C item 5) and this task's own
 * Requirements 2/3 require ("Map" 52.5px -> 33.4px wide at 375px, 24.3px at
 * 320px on `gear.html`; `spots.html`'s "Map" 52.4px -> 35.2px at 320px) -
 * `origin/main` was compliant at both widths and the fix silently traded
 * that away while its own PR body measured only cell HEIGHT (pinned
 * separately by `min-height:44px`, untouched either version). Recorded, not
 * merged: `docs/improvement-round/STATE.md`'s "25.6 — review objection
 * (PR #811)" entry.
 *
 * THE FIX THAT HOLDS BOTH: `min-width:44px` on `.sr-item,.sr-account`
 * (replacing the previous `min-width:0`) makes 44px an absolute floor the
 * flex-shrink algorithm cannot cross - a short cell's base size is clamped
 * up to 44px before any growing/shrinking happens, so it can only end up AT
 * or ABOVE the floor, never below it. `min-width:44px` alone does not close
 * the six cells' arithmetic, though (six 44px cells plus gaps still need
 * more than the ~325px of row actually available at 375px once the rail's
 * `.sr-brand` mark and its own gap are subtracted) - the pixel has to come
 * from somewhere else in the row. `.sr-brand` is a plain decorative `<div>`
 * (a dot plus a wordmark `site-rail.js:545`), never a link - the wordmark
 * `<b>` is ALREADY hidden below 860px by the pre-existing
 * `.sr-brand b{ display:none; }` rule above, leaving only an 8px dot inside
 * 16px of horizontal padding (40px total); nothing in `REMEDIATION_DIRECTION.md`
 * or any test pins that dot's presence at these widths (`grep -rn
 * "sr-brand" tests/` finds no such assertion), so hiding it entirely inside
 * this block is a clean CSS-only trim, not a pin violation. That reclaims
 * the ~40px plus one gap the six-item row needs, and `flex-basis:auto`
 * (kept, now written directly into the `flex` shorthand rather than as a
 * separate longhand override - see the relaxed test below) still gives
 * "Forecast"/"Sessions" priority claim on their own natural width before
 * the remaining slack is redistributed evenly. Verified by real render
 * (Requirement 2): every label sits on one line, every cell measures
 * >=44px in BOTH dimensions, at both 375 and 320px, with no scroll, on
 * `gear.html` (six cells) and `spots.html` (five, already clean and now
 * also gaining width from the freed brand-mark space at 320px - see the
 * measurement table in the PR body; the previous version of this comment
 * called `spots.html` at 320px "unaffected", which was wrong - `origin/main`
 * already wraps "Forecast"/"Sessions" there, and the fix corrects it the
 * same way it does on `gear.html`, and "before every label including
 * Map/Gear mid-word-wraps" at 320px on `gear.html`, also wrong -
 * `origin/main` wraps only "Forecast"/"Sessions"/"Sign in" there, not
 * "Map"/"Spots"/"Gear").
 */
@media (max-width:860px){
  .sr-context,.sr-appearance,.sr-desktop,.sr-brand{ display:none; }
  .sr-single,.sr-column,.sr-strip{ overflow-x:hidden;
    /* Tighter than the layout block's own 12px/10px: the fifth slot (the
       account entry, on a page that carries one) leaves each of five equal
       cells only about a sixth of the viewport at 375px, and the layout
       block's roomier gap/padding was enough on its own to force
       `Forecast`/`Sessions` into a mid-word wrap that a few more pixels of
       cell width avoids. Trimmed a further 1px off both the gap and the
       side padding for task 25.6: at the SIX-cell width, closing the
       44px-hit-region arithmetic (see the block comment above) needed every
       spare pixel it could get, on top of hiding `.sr-brand`. */
    gap:1px; padding:0 2px;
  }
  /* Unwraps each group/foot into the row itself, so up to six leaf items -
     never more, since `site-nav.js`'s own destination list is capped at
     five (task 18.13 added Spots on 2026-09-03, the owner's six-stop
     decision) plus this one account slot - share ONE flex line instead of
     several unevenly-sized boxes. */
  .sr-group,.sr-foot{ display:contents; }
  .sr-item,.sr-account{
    /* task 25.6: `flex-basis` moved from `0` (equal-share sizing regardless
       of label length, the ORIGINAL cause of the mid-word wrap) to `auto`
       (content-proportional sizing) directly in this shorthand, and
       `min-width` raised from `0` to `44px` so no cell can shrink below the
       hit-region floor - see the block comment above for why both changes
       together, and neither alone, close this task's Requirements 2/3.
       `test_the_no_scroll_block_does_not_rely_on_horizontal_scrolling` was
       relaxed to assert what it actually guards (items may shrink, rather
       than being pinned to their content width with `nowrap`) instead of a
       literal `flex:1 1 0` that no longer describes the computed value. */
    flex:1 1 auto; min-width:44px; min-height:44px; box-sizing:border-box;
    flex-direction:column; justify-content:center; align-items:center;
    gap:2px; padding:4px 1px; white-space:normal; text-align:center;
  }
  .sr-item span,.sr-aname{
    font-size:12px; letter-spacing:.01em; max-width:100%;
    -webkit-hyphens:auto; hyphens:auto;
    overflow-wrap:break-word; white-space:normal; text-overflow:clip;
    line-height:1.15;
  }
  .sr-item svg{ width:16px; height:16px; }
  .sr-item.sr-current::before{ inset-block:auto 0; inset-inline:0; width:auto; height:2px; }
  .sr-avatar{ display:none; } /* the stacked layout has no room for both a dot and a label */
}

@media (prefers-reduced-motion: reduce){
  #siteRail *{ transition:none !important; }
}

/* Printing a forecast should print the forecast. */
@media print{
  #siteRail{ display:none; }
  html[data-rail="on"] body{ padding-inline-start:0; padding-block-start:0; }
}
