/* ===========================================================================
   topnav.css. THE SECTION NAV AS A COMPACT TOP HEADER (2026-09-14)

   Owner: "the sections should not be on the side but on the top (header) and
   they should be small like in paradex."

   EVERY NUMBER IN THIS FILE IS QUOTED FROM research/ui-paradex/PARADEX-UI.md,
   a teardown of app.paradex.trade captured live on 2026-09-14. None is
   chosen. The five that carry the file:

     header            1430x60 at 1440x900, padding `0 16px`, gap 16px   (4.3)
     tab label         12px, weight 400, and 400 when selected too        (5)
     active mark       a 2px underline, transform 0.1s
                       cubic-bezier(0.4, 0, 0.2, 1)                     (3.2, 5)
     tab height        28px secondary, 32px primary; every data row 24px  (4, 5)
     hover             colour step from label ink to primary ink.
                       No scale, no translate, no shadow, no glow.       (3.6)

   WHAT IS DELIBERATELY NOT COPIED, from section 7 of the same report: no
   buy/sell colour pair, no filled CTA, no order ticket, no trade path, no
   wallet, no price. Moneyness is a measurement surface for the eleven venues
   it indexes and their investors. This file adds navigation and takes a
   column away; it adds no action and it publishes no figure.

   ---------------------------------------------------------------------------
   WHY THIS FILE EXISTS AT ALL, AND WHY IT IS LAST IN THE HEAD

   The rail's appearance has never been in nav.css. nav.css says so in its own
   header. It is spread across instrument.css sections 12, 28, 41, 53b, 62 and
   65, chrome.css section 3, and density.css section 9. instrument.css and
   density.css are both off limits to this job, so the only lawful place to
   write a new look is a sheet that loads after both.

   TWO !important DECLARATIONS RESOLVE BY SPECIFICITY FIRST AND ONLY THEN BY
   ORDER, so loading last is not on its own enough. The three weights this
   file has to clear, each computed rather than guessed:

     instrument.css:844  body .rail                                (0,1,1)
     instrument.css:854  body .rl-item                             (0,1,1)
     instrument.css:4801 body .rail .rl-item.on                    (0,3,1)
     chrome.css:353      html body > nav.rail .rl-item:hover       (0,3,3)
     density.css:477     :root x6 body nav.rail .rl-l              (0,8,2)

   The base selector used below is `html body header.top nav.rail ...`, which
   is (0,3,4) at the item and (0,4,4) at `.rl-item.on`. That clears everything
   except density.css's six-deep :root prefix, and the two rules that have to
   clear THAT say so at the rule and borrow the same idiom rather than
   inventing a second one.

   A LARGE PART OF THE OLD LOOK IS NOT FOUGHT, IT IS ORPHANED. The sidebar
   geometry in instrument.css is addressed through the CHILD selector
   `body > nav.rail`: section 41's measure-centring padding (:1998), the
   overflow-x (:2127), the glass background (:3876), the seam shadow (:3895)
   and section 65's `body > nav.rail.rail` (:4452). index.html moves the node
   inside header.top, so all five stop matching and none of them has to be
   overridden. chrome.css section 3's `html body > nav.rail` sidebar rules go
   the same way, which is why the hover and the focus ring are re-declared
   below: they were in that block and they went with it.

   DEFINES NO NEW COLOUR AND NO NEW KEYFRAME. Every value is an existing token.
   =========================================================================== */


/* ---------------------------------------------------------------------------
   1. THE MASTHEAD BECOMES THE NAV BAR

   Paradex's header is 1430x60 with `padding: 0 16px` and `gap: 16px`. Two of
   those three are taken literally. The third is not, and the reason is this
   app's own law rather than a preference: instrument.css section 41 insets
   every full-width band by `max(--gutter, (100% - --measure) / 2)` so the
   masthead's CONTENTS line up with the board underneath it. That is the same
   job Paradex's 16px does on a full-bleed terminal, done against a 1300px
   measure instead of a viewport edge. Overriding it would align the wordmark
   to nothing. So the horizontal inset is left alone and ONLY the vertical
   padding is written here, which is why this is `padding-block` and not the
   `padding` shorthand: the shorthand would reset the left and right longhands
   section 41 owns and un-align the whole band.

   min-height rather than height. The two-row phone layout in section 6 makes
   this box taller on purpose, and a stated `height` would clip it.
   --------------------------------------------------------------------------- */
html body header.top {
  min-height: 60px;
  padding-block: 0 !important;
  /* column-gap AND row-gap SEPARATELY, NOT THE `gap` SHORTHAND, and this was
     a measured bug before it was a rule. `gap: 16px !important` sets row-gap
     to 16px with !important too, so the unflagged `row-gap: 0` beside it lost
     to its own neighbour and the two-row layout in section 6 came out 16px
     taller than the sum of its rows: measured 106px against 90px of content.
     Paradex's 16px is a HORIZONTAL gap between header items; it was never a
     gap between rows, because Paradex's header has one row. */
  column-gap: 16px !important;
  row-gap: 0 !important;
  align-items: stretch !important;
  justify-content: flex-start !important;
  /* nowrap IS THE DEFAULT AND SECTION 6 TURNS IT ON, which is the opposite of
     what the first draft did, and the sweep is why. With `wrap` on at every
     width the browser breaks the line on flex-BASIS, before any shrinking, and
     the item it pushed down was the LAST one: measured at 1340, the status
     reading dropped to a second row while the tabs stayed on the first, giving
     a 107px header that neither layout asked for. Wrapping is a layout
     decision here, so it is made by a media query at a measured width and not
     left to whichever child happens to be last in the DOM. */
  flex-wrap: nowrap;
}

/* The lockup and the reading centre themselves in the 60px row; only the nav
   is full height, because the nav is the only thing carrying a bottom mark. */
html body header.top .brand { align-self: center; flex: 0 0 auto; }

/* `justify-content: space-between` used to do this with two children. With
   three it would put the nav in the middle of the leftover space and move it
   every time the status string changes length, so the status is pushed right
   explicitly and the nav sits where the brand leaves it. */
html body header.top .topright { align-self: center; margin-left: auto; }


/* ---------------------------------------------------------------------------
   2. THE STRIP

   Flush tabs, `gap: 0`. PARADEX-UI.md section 2.8 measures gap 0 on eight
   flush tab lists and 24px on exactly one (the Book/Trades pair, which is two
   items). Seven items is a tab list, not a pair.

   overflow-x: auto is kept from the old rail and it is load-bearing, not
   defensive. nav.js's show() scrolls the active item into view only when
   `rail.scrollWidth > rail.clientWidth + 1`, which is its guard for "this is
   the horizontal strip, not the vertical column". Keeping the strip
   scrollable is what keeps that guard true at phone widths, where the 2026-08-19
   measurement found the lit bracket sitting off screen on three of six
   sections.

   The scrollbar itself is hidden. A 15px scrollbar track inside a 60px header
   would be a fifth of its height, and the strip's overflow only ever engages
   below the breakpoint in section 6 where the strip is already a swipe
   affordance.
   --------------------------------------------------------------------------- */
html body header.top nav.rail.rail {
  position: static !important;
  display: flex !important;
  flex-direction: row !important;
  flex: 0 1 auto;
  min-width: 0;
  align-items: stretch !important;
  gap: 0 !important;
  width: auto !important;
  height: auto !important;
  min-height: 0 !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
html body header.top nav.rail.rail::-webkit-scrollbar { width: 0; height: 0; }


/* ---------------------------------------------------------------------------
   3. THE TAB

   Full header height so the underline in section 4 lands on the header's own
   bottom edge rather than floating inside it, which is where Paradex puts its
   tab indicator. `position: relative` is the only reason the item is a
   positioning context; nothing else here depends on it.

   `padding: 0 12px` and the height stated on the element, which is the rule
   PARADEX-UI.md section 7 warns about breaking: Paradex gets away with zero
   vertical padding because the height is stated and the line-height is 1.0.
   Copying the padding without the stated height gives a box whose height is
   set by whatever wraps first.

   THE BORDER-RADIUS IS NOT CONTESTED. density.css section 9 pins 4px on
   .rl-item at (0,7,1) and this rule is (0,3,4), so density wins. That is
   correct and deliberate: the tab paints no background in any state, so a
   radius on it is invisible, and spending a specificity hack to win an
   invisible argument with another agent's live file is not worth the churn.
   --------------------------------------------------------------------------- */
html body header.top nav.rail .rl-item {
  position: relative;
  display: inline-flex !important;
  flex: 0 0 auto !important;
  flex-direction: row !important;
  align-items: center !important;
  gap: 6px;
  height: 60px;
  padding: 0 10px !important;
  margin: 0 !important;
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  color: var(--ink3) !important;
  /* The ANCHOR carries no text of its own, so these two are invisible today
     and are set anyway, because a census that reports three weights and two
     tracking values on a seven item strip cannot tell an invisible one from a
     visible one. instrument.css:2093 puts 600 on `.rl-item.on` and
     instrument.css:2074's `body .rail *` puts 0.01em on every descendant,
     which computes to 0.12px at 12px. Paradex runs two weights and
     `letter-spacing: normal` on 170 of 170 nodes, uppercase included. */
  font-weight: 400 !important;
  letter-spacing: normal !important;
  white-space: nowrap;
  text-decoration: none;
  /* Paradex writes `transition: unset` on its hot surfaces and carries a
     transition on almost nothing else. The only thing that moves here is the
     underline in section 4, so the tab itself declares colour only, at the
     0.1s the indicator uses, and nothing that costs layout. */
  transition: color 0.1s cubic-bezier(0.4, 0, 0.2, 1);
}

/* THE LABEL, 12px.

   This is the one rule in the file that overrides a live decision in
   density.css rather than an old one in instrument.css, so it is stated
   plainly. density.css:477 sets the rail label to `var(--t-md)`, 13px, with
   the argument that Paradex runs its top nav links and its bottom tab strip at
   13px, which PARADEX-UI.md section 2.5 does measure. Section 5 of the same
   report measures its TAB labels at 12px, and this is a tab strip with a tab
   underline, so it takes the tab number. 12px is --t-sm, the size carrying
   82.4 percent of Paradex's text; it is not a new literal.

   Reverting is this rule alone.

   The six :root prefix is density.css's own idiom, copied rather than
   reinvented, for the reason its section 9 gives: `:root` is a pseudo-class,
   so each repetition buys one class-level point and names nothing new.
   density.css:477 is (0,8,2); adding `header.top` to the same prefix makes
   this (0,9,3). It is deliberately ugly so that it reads as a specificity
   device and not as a component.

   THE FIRST DRAFT OF THIS RULE MATCHED NOTHING AND THE LABEL STAYED 13px,
   which is written down because it is the exact trap a specificity prefix
   sets. It read `:root x6 html body header.top ...`. `:root` IS the <html>
   element, so a DESCENDANT `html` after it asks for an <html> inside an
   <html> and can never match. The prefix has to be followed by `body`, which
   is what density.css does and what this now does. Caught by measuring the
   computed font-size on the rendered page, not by reading the file: the
   selector parses, the sheet loads, and a rule that matches nothing looks
   exactly like a rule that lost. */
:root:root:root:root:root:root body header.top nav.rail .rl-l {
  font-size: var(--t-sm) !important;
  font-weight: 400 !important;
  letter-spacing: normal !important;
  text-transform: none !important;
  color: inherit !important;
  line-height: 1;
}

/* The bracket digit is the keyboard affordance and nothing else, so it is the
   quietest thing in the row. --t-xs is 10px, which is the size Paradex gives
   its PERP tag, the only 10px on its page. */
html body header.top nav.rail .rl-n {
  font-size: var(--t-xs) !important;
  font-weight: 400 !important;
  letter-spacing: normal !important;
  color: inherit !important;
  opacity: .45;
  line-height: 1;
  transition: opacity 0.1s cubic-bezier(0.4, 0, 0.2, 1);
}


/* ---------------------------------------------------------------------------
   4. THE ACTIVE MARK IS A 2px UNDERLINE AND NOTHING ELSE

   What it replaces, all of which is orphaned or overridden here: a gold fill
   (instrument.css:2089 and :2931), a warm halo box-shadow (:3751), a 6 to 11
   percent wash with a 2px bottom border (:1537), and the current live version
   at :4801, an inset 2px LEFT bar with a `0 8px 8px 0` radius. That last one
   is the giveaway that the whole treatment was drawn for a vertical column: a
   left bar is a margin mark, and there is no margin in a horizontal strip.

   PARADEX-UI.md section 5: "Tabs do not change weight when selected. Every tab
   is weight 400 in both states. The only differences are colour and a separate
   sliding underline element that transitions transform over 100ms on
   cubic-bezier(0.4, 0, 0.2, 1). No bold, no background pill, no border."

   IT IS A PER-TAB ::after AND NOT ONE SLIDING BAR, which is a real difference
   from Paradex and is a choice. A single shared indicator has to be positioned
   from JavaScript, which means measuring on load, on resize, on font load, on
   the strip's own horizontal scroll and on every hash change, and a mark that
   is wrong for one frame after any of those is worse than one that is never
   wrong. The transform, the duration and the curve are the measured ones; only
   the number of elements differs, and scaleX from the centre reads as the same
   gesture. Nothing here animates a layout property.

   `transform-origin: 50%` so it opens from the middle of the tab rather than
   sweeping in from one side, which at seven adjacent tabs would read as
   direction the reader did not ask for.
   --------------------------------------------------------------------------- */
/* EVERY PROPERTY IS DECLARED, INCLUDING THE ONES THAT LOOK REDUNDANT, AND
   THAT IS THE WHOLE POINT OF THIS RULE. paper.css:553 already owns this exact
   pseudo-element: inside `@media (min-width: 900px)` it draws the paper
   plotter's take-off stub as `body nav.rail .rl-item.on::after`, a 40px wide,
   1px tall, 58 percent opacity gradient at `top: calc(50% + var(--pp-takeoff))`
   and `right: -14px`, with a 240ms scaleX animation on it.

   MEASURED ON THE RENDERED PAGE, not reasoned about: the active tab's ::after
   came back 40px wide at opacity 0.58 sitting at the vertical MIDDLE of the
   tab, which reads on screen as an orange strikethrough across "[1] Today".
   The specificity was never the problem. This selector is (0,3,4) against
   paper.css's (0,3,2) and wins every property it names, but it named neither
   `width` nor `opacity` nor `top`, so those three came through unopposed, and
   `top` plus `height` over-constrains an absolutely positioned box against
   `bottom`, which is why the mark left the header's edge entirely.

   paper.css is not this job's file to edit and it is not edited. It is worth
   saying plainly for whoever owns it: THAT STUB IS GEOMETRICALLY OBSOLETE. It
   exists to hand the plotter's leader line off from the ACTIVE ROW'S RIGHT
   EDGE into the stage, which is a sentence about a 208px vertical column. In
   a horizontal header the active tab's right edge is another tab, so the stub
   now points at Compare instead of at the page. Neutralising it here is a
   containment, not a fix; the fix is in paper.css. */
html body header.top nav.rail .rl-item::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: auto;
  bottom: 0;
  width: auto;
  height: 2px;
  opacity: 1;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 50% 50%;
  transition: transform 0.1s cubic-bezier(0.4, 0, 0.2, 1);
  animation: none;
  pointer-events: none;
}

/* (0,4,4): four classes (.top, .rail, .rl-item, .on) over instrument.css:4801's
   three (.rail, .rl-item, .on). Everything the older rules painted is unset
   here explicitly rather than left to luck, because five separate sections of
   instrument.css have had an opinion about this element and a future sixth
   should find the reset in one place. */
html body header.top nav.rail .rl-item.on,
html body header.top nav.rail .rl-item[aria-current="page"] {
  background: transparent !important;
  color: var(--ink) !important;
  box-shadow: none !important;
  border: 0 !important;
  padding: 0 10px !important;
  font-weight: 400 !important;
}
html body header.top nav.rail .rl-item.on::after,
html body header.top nav.rail .rl-item[aria-current="page"]::after {
  transform: scaleX(1);
}
html body header.top nav.rail .rl-item.on .rl-n { opacity: .8; }

/* The active label does NOT bold. instrument.css:877 and :1549 set 600 and
   density.css:297 moved that to 500; both are cleared here for the reason
   quoted in section 4's note. Colour is the whole difference, which is the
   second of Paradex's four hover and state primitives. */
:root:root:root:root:root:root body header.top nav.rail .rl-item.on .rl-l {
  font-weight: 400 !important;
  color: var(--ink) !important;
}


/* ---------------------------------------------------------------------------
   5. HOVER AND FOCUS

   PARADEX-UI.md section 3.6: the whole hover system is four primitives, and
   the one for a tab is a colour step from label ink to primary ink. "There is
   no scale, no translate, no box-shadow and no glow on any hover on the entire
   page."

   chrome.css:353 gave the rail item a `--hover-wash` background through
   `html body > nav.rail`, which no longer matches now that the node is inside
   the header. It is NOT re-declared: a background wash is the row primitive,
   not the tab primitive, and PARADEX-UI.md section 7 is explicit that a
   hovered row on a measurement surface must not imply an action. A tab is the
   one thing here that IS clickable, and it says so with ink.

   THE FOCUS RING IS RE-DECLARED BECAUSE IT WENT WITH THE SAME BLOCK.
   chrome.css:313 covered `html body > nav.rail a:focus-visible` and stopped
   matching. ui.css:237 still reserves a transparent 2px outline on .rl-item so
   there is no layout cost when it appears, and this paints it. The accent is
   the one meaning chrome.css's colour law assigns it, "where you are", which
   is exactly what focus is. */
html body header.top nav.rail .rl-item:hover { color: var(--ink) !important; }
html body header.top nav.rail .rl-item:hover .rl-n { opacity: .8; }

html body header.top nav.rail .rl-item:focus-visible {
  outline: 2px solid var(--accent) !important;
  outline-offset: -3px;
  border-radius: 0 !important;
}

/* A gated item is a <span class="rl-item rl-locked">, not an anchor, and
   nav.js's own comment records why. It must not read as clickable. No rail
   entry carries `soon` today, so this rule currently matches nothing; it is
   here because dropping `offRail` from the Tools entry is a one-line revert
   that nav.js explicitly invites. */
html body header.top nav.rail .rl-locked { opacity: .35; cursor: not-allowed; }


/* ---------------------------------------------------------------------------
   6. PHONE AND NARROW DESKTOP: THE STRIP TAKES ITS OWN ROW

   PARADEX-UI.md section 4.4 records two phone answers on Paradex, a horizontal
   Book / Trades / Contract Details strip and a five item bottom bar. The strip
   is the one taken, for three reasons and none of them is taste:

     1. Seven items do not fit a bottom bar. Paradex's has five.
     2. Section 7 of the same report refuses the pinned bottom bar by name:
        "A measurement surface with a pinned action bar has to put something in
        it, and there is nothing."
     3. nav.js's show() already contains a measured scroll correction for a
        horizontal strip, guarded on `scrollWidth > clientWidth`. Keeping the
        strip keeps that correction live. A bottom bar would strand it.

   THE BREAKPOINT IS 1360px AND IT IS MEASURED. Swept on the mirror at 21
   widths from 1600 down to 360 with the strip built, reading the rendered
   rects rather than the stylesheet:

     1600 1440 1400 1360    header 61px, one row, nothing scrolls
     1340 1320 1300 1280    the row stops fitting

   The arithmetic behind 1340 being the first failure: the header's content box
   is `viewport - 2 x max(--gutter, (100% - 1300) / 2)`, which is 1228 at 1340.
   The lockup measures 413, the reading 159, the strip 629 at the first draft's
   12px tab padding, and two 16px gaps, for 1233. Three pixels short, and the
   line broke.

   The tab padding went from 12px to 10px in section 3 on the strength of that
   number, which takes the strip to 601 and leaves 55px of slack at 1360 for
   the status reading to grow into: it is not a constant string, it says
   "34,500 CONTRACTS / LIVE 57s AGO" when the feed is healthy and "STALE 792s"
   when it is not. 10px is on Paradex's own padding scale, which runs 2, 4, 6,
   8, 10, 12, 16, 20, 24.

   ABOVE THE BREAKPOINT THE HEADER CANNOT WRAP, because section 1 sets
   `flex-wrap: nowrap` there and the strip carries `min-width: 0`. If the
   status reading ever outgrows that 55px the strip shrinks and scrolls, which
   is a degradation the reader can act on, rather than silently becoming a
   two-row header at a width that was designed for one.
   --------------------------------------------------------------------------- */
@media (max-width: 1359px) {
  html body header.top { flex-wrap: wrap; }
  html body header.top nav.rail.rail {
    order: 3;
    flex: 1 0 100%;
    width: 100% !important;
    height: 36px;
    min-height: 36px;
    box-sizing: content-box;
    overflow-x: auto;
    border-top: 1px solid var(--line) !important;
  }
  html body header.top nav.rail .rl-item,
  html body header.top nav.rail .rl-item.on {
    height: 36px;
    padding: 0 10px !important;
  }
  /* THE BRAND ROW IS 46px AND THAT IS THE HEIGHT IT ALREADY HAD. Measured on
     the mirror before this change, phone profile at 390: the masthead was 46px
     and the section strip under it was 42px, 88px of chrome in total. This
     layout is 46 + 36 + 1 = 83, so the phone gains 5px of stage rather than
     losing any, which is the test a "compact" header has to pass on the width
     where compactness actually matters. */
  html body header.top .brand,
  html body header.top .topright { min-height: 46px; }
}

/* 36px IS THE ROW AND IT IS NOT 28px. Paradex's secondary tab is 28px and its
   primary tab is 32px, both of which are pointer targets on a terminal people
   sit in front of with a mouse. This row is the only navigation on a phone and
   it is touched, so it takes the largest of the three heights that report
   measures for a control (32px) plus the 2px underline and its own hairline.
   It is still 6px shorter than the 42px strip it replaces. */


/* ---------------------------------------------------------------------------
   7. THE HEADER RESERVES ITS OWN HEIGHT, WHICH IS THE WHOLE LAYOUT SHIFT STORY

   The shell is `body { height: 100dvh; overflow: hidden }` with `.app` as the
   one flexible child, so every pixel the chrome gains is a pixel .app loses
   and the entire page under it moves. Measured on the mirror before this
   change, phone profile at 4x CPU throttle, with a layout-shift
   PerformanceObserver: the largest desktop shift in the whole load was
   NAV.rail at 0.0052, the rail growing from an empty box to its painted size.

   nav.css's `@media (max-width: 899px) { body nav.rail { min-height: 55px } }`
   IS DELETED RATHER THAN CARRIED OVER, and this is the rule that replaces it.
   Three things about it stopped being true:
     - 55px was the settled height of a body-level strip with 42px items. The
       strip is 36px now and it is a row of the header, not a sibling of it.
     - 899px was chosen to match nav.css's own 900px sidebar boundary. There is
       no sidebar and no 900px boundary any more.
     - Above 900px it reserved nothing at all, because the rail was the fixed
       column. The desktop shift it therefore never covered is the one the
       60px min-height in section 1 removes.

   So the reservation is stated twice and both are exact rather than padded:
   60px above the breakpoint (section 1, the single row), and 46 + 36 + 1 below
   it (the brand row, the strip, and the strip's own hairline). Both are the
   measured sum of their rows, not a padded guess.
   --------------------------------------------------------------------------- */
@media (max-width: 1359px) {
  html body header.top { min-height: 83px; }
}


/* ---------------------------------------------------------------------------
   8. THE SCENT LINE IS CLIPPED, NOT DELETED, AND THAT IS A REAL LOSS

   `.rl-q` is nav.js's one-line question for wherever you are, and it swaps to
   another section's question while the cursor is on it. It came back on
   2026-08-05 on the owner's report that "users should go to the right place
   without searching", and it is the one thing this change cannot keep.

   The arithmetic, measured at 1440x900 with the strip built: the header's
   content box is 1300px, the lockup takes 413, the reading takes 100, the
   seven tabs take the rest. What is left for a sentence is under 200px, and
   nav.js's own comment records why that is worse than nothing: at 164px "five
   of the six were ellipsed mid-word anyway, which is worse than absent, a
   truncated sentence asks to be read and then refuses."

   SO IT IS CLIPPED RATHER THAN display:none, WHICH IS NOT A DETAIL. The
   element carries aria-live="polite" and nav.js writes the section's question
   into it on every navigation. A display:none live region announces nothing,
   so hiding it that way would have silently removed the only spoken
   confirmation a screen reader gets that the section changed. The standard
   clip keeps it in the accessibility tree and keeps say() working untouched.

   The sighted path is not gone either: nav.js still writes the same sentence
   into each item's `title`, which is where it lived before 2026-08-05.

   THIS IS ONE RULE TO REVERSE and it is flagged for the owner rather than
   decided for him. If he wants the sentence back on screen, the honest place
   for it at these widths is a second row, which costs the vertical pixel this
   whole change was made to recover.
   --------------------------------------------------------------------------- */
html body header.top nav.rail .rl-q {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  border: 0 !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap !important;
}


/* ---------------------------------------------------------------------------
   9. THE NEW BADGE

   nav.css's `.rl-new` is the reference implementation for text on an accent
   fill and it is not restyled here: --accent-ink resolves to the same value as
   --accent in this app, so the badge takes `color: var(--bg)` or it is orange
   on orange. That rule still wins its own arguments.

   Two things change, both because the badge now sits in a 60px row instead of
   a 44px sidebar item. Its `vertical-align: middle` and `top: -1px` were
   written for a baseline-aligned inline context; the tab is
   `align-items: center` flex now, so the baseline nudge is what would push it
   off centre. And the 7px left margin is the item's own 6px gap doing the same
   job twice. */
html body header.top nav.rail .rl-new {
  margin-left: 1px;
  top: 0;
  align-self: center;
  flex: 0 0 auto;
}


/* ---------------------------------------------------------------------------
   10. THE PLOTTER READS THE RAIL AND MUST NOT BE FOUND BY IT

   paper.js draws a decorative background sheet from the rail's geometry
   (`RAIL_SEL = "nav.rail .rl-item"`, and `railRight` from the rail's own
   rect). It reads and never writes, it guards every lookup, and it now reads
   a strip in the header instead of a column on the left, which is a different
   set of numbers and not a broken one.

   The one thing that would break is z-order: the sheet is appended to <body>
   and the header is `position: sticky`. Nothing is changed for it here, and it
   is named so the next person does not conclude it was missed.
   --------------------------------------------------------------------------- */
