/* ══════════════════════════════════════════════════════════════════════
   nav-fit.css — the phone bar is proportioned like a bar, and the strip
   above it is the same colour as the bar.

   THE BUG (owner, 2026-08-26), two halves of one message:
     "first nav is not proportioned properly (look at core chains and then
      lumina labs to compare). elements need to be properly oriented and
      scale proportionally for all mobile phones."
     "the nav ... [has] issues where they dont take up a full phone and you
      can see the site ... above the nav ... lumina ... uses a dark navy
      color to block out those secrions so you cant see the site scrolling
      behind."

   EVERY NUMBER BELOW IS MEASURED, by executing this stylesheet against the
   built site in headless Chrome at DPR 3 with an iPhone UA, at 320 · 360 ·
   375 · 390 · 414 · 430 · 500 · 700 · 767 · 768 · 780 · 800 · 844 · 860 ·
   861 · 1200 CSS px. Where a figure here and the browser disagreed, the
   browser won and the figure was rewritten. The reference figures are
   luminaresearchlabs.com at 390.

   ─────────────────────────────────────────────────────────────────────
   ONE THING THE BRIEF GOT WRONG, AND IT CHANGES WHAT THIS FILE DOES.

   The nav lockup was reported as "163x46 rendered from a 140x39 natural —
   UPSCALED 116%, soft on every retina phone". The 163x46 is real (measured
   162.64 x 46 at >=375px). The softness is not. On a fresh cache-disabled
   load the browser picks the 640w srcset candidate, which is a real
   640x181 file (verified by reading the WebP header, not by trusting the
   markup), and paints it into a 162.64 CSS px box — 488 device px at
   DPR 3, from 640 available. Oversupplied, not undersupplied.

   The small `naturalWidth` is an artefact of the srcset, not a property of
   the file: HTML defines naturalWidth as the intrinsic width DIVIDED BY
   the chosen candidate's density, and the density here is 640w /
   sizes="140px" = 4.571. Measured, the browser reports 139x39 for a file
   that is 640x181 on disk. Edit `sizes` and that number changes with no
   pixel moving. So NOTHING in this file shrinks the logo to make it
   sharper and nothing repoints it at a bigger asset — there is no
   sharpness defect to fix. The logo shrinks for the reason that IS real
   and IS visible in the owner's screenshot: it is 77% of the bar's height.

   ─────────────────────────────────────────────────────────────────────
   ONE BREAKPOINT, 860px, AND IT IS THE TEMPLATE'S OWN.

   An earlier draft of this file painted the bar at <=860px but did the
   proportion work only at <=768px, on the reasoning that 769-860 is
   "desktop". Measurement refutes that, and so does the template: the built
   page carries, in its own <style> (index.html:403),

     @media (min-width:769px) and (max-width:860px) {
       body:not(.layout-default) #site-nav .snav-links { display:none; }
       body:not(.layout-default) #snav-mob-left-btn   { display:flex; }
     }

   labelled "Bridge 769-860px". So the MOBILE bar — four links gone,
   hamburger showing — runs all the way to 860px, and 769-860 was getting
   the phone's navy paint with the DESKTOP's proportions: measured at 780 /
   800 / 844 / 860, lockup 51.75px in a 67px bar (77.2%), action glyphs
   25px against the hamburger's 20px, and the two edge glyphs 62.0px and
   69.5px from their own edges — 7.5px out of symmetry. That band contains
   real phones held sideways (iPhone 12/13/14 landscape is 844 CSS px,
   iPhone 14 Pro is 852), and the owner's sentence says "all mobile
   phones". Everything below is therefore one @media (max-width: 860px).

   Above 861px the desktop link row returns, the bar is 67px, desktop
   browsers do not tint their own chrome from the meta, and the 861px fit
   arithmetic in sf-refresh.css §4 is solved against the desktop lockup's
   183px width — so nothing here reaches up there.
   ══════════════════════════════════════════════════════════════════════ */


@media (max-width: 860px) {

/* ── 1. THE BAR IS ONE FLAT NAVY, AND THE STRIP ABOVE IT IS THAT SAME
       NAVY ──────────────────────────────────────────────────────────────

   MEASURED: <meta name="theme-color"> is #060E1A (the page ground) while
   the bar paints linear-gradient(96deg, #081525 0%, #0B1A2C 48%, #102A46
   100%) (sf-refresh.css:163). On iOS the strip behind the status bar is
   painted FROM theme-color, so the phone draws a #060E1A band directly
   above a bar that is nowhere near #060E1A. That band is the "site showing
   above the nav".

   THE REFERENCE HAS NO SEAM, AND IT IS WORTH SAYING WHY EXACTLY, because
   the reason is not the one the owner's sentence suggests. Measured on
   luminaresearchlabs.com at 390 this session: theme-color #0D1B3E,
   html and body background rgb(13, 27, 62) — the SAME colour — and a bar
   painting rgba(5, 10, 22, 0.62), i.e. translucent over that ground. So
   there is only ever one opaque colour anywhere near the top of that page:
   the strip is the ground, and the bar is the ground with a tint on it.
   This site's bar is OPAQUE and a different colour from its ground, which
   is what turns the strip into a visible second band. Matching the two is
   the fix available here — going translucent is not, because the seam and
   the 1.25 chrome-visibility floor pull in opposite directions on a bar
   you can see the page through.

   Two colours cannot agree while one of them is a sweep, so the phone bar
   becomes a single colour and the meta is stamped to it. The stamping
   lives in final/26-nav-fit.mjs — a meta tag is markup, not CSS — and that
   module refuses to run unless this file, as copied into the build, still
   carries the same literal.

   WHY --cc-navy-700 #10294A AND NOT AN INVENTED COLOUR. It is already in
   this client's palette (sf-refresh.css:12), and it is within four units
   of #102A46, the LIGHT end of the sweep it replaces — the end every
   existing ink ratio was solved against ("the ratio is owed at the
   BRIGHTEST stop, not the average", sf-refresh.css). So flattening to it
   takes nothing away from any pair anyone has measured (every ratio below
   recomputed from the shipped hexes this session):

     #10294A vs the page ground #060E1A ....... 1.3248:1   (floor 1.25 OK)
     --sf-nav-ink     #F0F6FA on #10294A ...... 13.3982:1  (floor 4.5  OK)
     --sf-nav-ink-dim #A6BACB on #10294A ......  7.3064:1              OK
     --cc-cyan-400    #16BFD1 (cart badge) ....  6.5414:1              OK

   And it closes a visibility failure nobody had measured, because a
   gradient has no single ratio to measure: the DARK end of the sweep,
   #081525, is 1.0542:1 against the page ground, and the 48% stop #0B1A2C
   is 1.1040:1. Both are under the 1.25 chrome-visibility floor —
   arithmetically, the left two thirds of this bar was not a bar, it was
   the page. Only the last stretch of the sweep ever cleared the floor.
   Now the whole width does.

   A SECOND THING THIS FIXES FOR FREE. sf-refresh.css §6b bleeds the bar's
   ground 120px upward with `#site-nav::before { background: inherit }` to
   cover iOS rubber-band overscroll. `inherit` copies the background VALUE,
   so a gradient is re-rasterized across the pseudo-element's own box —
   120px tall, not 60px — and a 96deg sweep over a different geometry is a
   different colour at the same x. MEASURED against the built page: with
   the sweep, ::before computes that same gradient over that different box;
   with this rule, ::before computes rgb(16, 41, 74) — the bar's own flat
   colour — at 320, 390 and 860, and reverts to the gradient at 861. A flat
   colour inherits as itself, so the bleed and the bar are now identical by
   definition rather than by luck.

   `html body #site-nav` is (1,0,2) counting (ids, classes, elements),
   which out-specifies sf-refresh.css:152's `body #site-nav` at (1,0,1).
   Every rule in this file is written one step above the rule it replaces
   rather than relying on being linked last, because the template's nav CSS
   lives in a <style> in the BODY and beats any linked sheet at equal
   weight. This file is ALSO not the last lane sheet in <head> — lane
   sheets link in filename order and 27/28/29/30 follow it — so "linked
   last" was never available to lean on. (None of those four names a nav
   selector today; the point is that the rules below do not depend on it
   either way.)

   box-shadow and border-bottom are untouched — the 1px cyan seam under the
   bar is somebody else's measured decision and it still clears its ratio
   on this ground. */
  html body #site-nav { background: #10294A; }


/* ══════════════════════════════════════════════════════════════════════
   2. PROPORTION. --sf-nav-h is 60px at <=768px and 67px in the 769-860
   bridge (sf-refresh.css:1698 and :1639), so every size below is written
   as a ratio OF THE BAR and lands correctly in both halves of the band
   without a second breakpoint.
   ══════════════════════════════════════════════════════════════════════ */

  /* ── 2a. THE LOCKUP CANNOT LEAVE THE SPACE BETWEEN ITS NEIGHBOURS ──────
     At <=768px the template's own rule centres the lockup on the FULL
     VIEWPORT (`position:absolute; left:50%; transform:translateX(-50%)`,
     index.html:505), which is a promise the viewport cannot keep: a wide
     lockup on a narrow phone reaches THROUGH the cart button, because an
     absolutely-positioned box does not know its siblings exist.
     sf-refresh.css §6c already replaced that with flex centring; this
     restates it at higher specificity rather than depending on it. A
     geometric guarantee that lives in one file is a guarantee — one that
     lives in two files is a coincidence.

     In the 769-860 bridge the lockup is already static and untransformed,
     so those three declarations are inert there — MEASURED: at 780 / 800 /
     844 / 860 the lockup's box is identical with and without this file's
     position/transform/inset lines. What is NOT inert up there is
     `margin-inline:auto`, which replaces the template's `margin-right:2rem`
     (index.html:407) and centres the lockup in the bridge bar the same way
     it does on a phone. */
  /* SUPERSEDED 2026-08-26 by §2a-2 — the lockup is ABSOLUTELY CENTRED on
     the bar now, the way the reference does it, so `position:static` and
     the `margin-inline:auto` that centred it between its neighbours are
     both gone. The one declaration that survives from this rule is the
     padding; `min-width` and `flex-shrink` described a flex item and mean
     nothing to an out-of-flow box. Kept as ONE rule with §2a-2's block
     rather than two rules for the same selector fighting on order — which
     is the exact "guarantee that lives in two files is a coincidence" this
     section complains about three paragraphs up. */
  html body #site-nav .snav-logo {
    padding-inline: 0.5rem;
  }

  /* TWO SPACING MECHANISMS WERE COMPETING FOR THE SAME PIXELS, and on the
     narrowest phone the lockup lost. theme.css's layout rule puts
     `gap: clamp(16px, 3vw, 36px)` on .sf-nav-inner (theme.css:344 — this
     client's body carries layout-hero-product-forward) — 16px at every
     phone width — and the auto margins above ALSO distribute free space.

     MEASURED, by running this file with the `gap:0` line below deleted and
     everything else in place: at 320px the lockup's box shrinks to
     133.25px and §2b's `max-width: min(100%, …)` clamps the artwork to
     116.25px inside it — 11.03px SHORT of the 127.28px the height ratio
     asks for, letterboxed by the template's `object-fit: contain`. With
     `gap:0` in place the same measurement gives the full 127.28px and
     18.98px of clearance to the cart's box. (An earlier draft of §2b
     dropped the `100%` term; with the bare viewport cap the same 320px
     state OVERHANGS the lockup's padding box by 11.03px instead of
     letterboxing — the reason §2b now clamps with `min(100%, …)`.)

     THIS RULE ONLY MOVES A PIXEL AT THE 320px FLOOR. Measured at 360, 390,
     780, 800, 844 and 860 the row has enough slack that with and without
     it every rectangle is identical. It is kept because 320px is a width
     that exists and because §2b's reservation table is 32px short without
     it.

     With `margin-inline:auto` doing the centring, the gap is not a second
     opinion, it is a tax: it removes free space from the thing that
     distributes free space. Zeroing it gives the 320px bar 32px back. */
  html body #site-nav .sf-nav-inner { gap: 0; }

  /* AND THE THIRD auto MARGIN IS WHY THE LOCKUP HUGGED THE HAMBURGER.
     Flexbox splits leftover space EQUALLY between every `auto` margin in
     the row. .snav-logo contributes two (margin-inline:auto) and the
     template's `#site-nav .snav-right { margin-left:auto }`
     (index.html:447) contributes a third, sitting to the RIGHT of the
     lockup — so one third of the slack landed on the lockup's left and two
     thirds on its right.

     MEASURED at 390px, from the built page, with every term named:
       burger right edge                        51.06
       + .sf-nav-inner gap                      16.00
       + auto margin                             5.457  (free 16.37 / 3)
       + .snav-logo padding                      8.53
       = artwork at x 81.05 — 29.99px of air on the left
       artwork right                           243.69
       + padding 8.53 + auto 5.457 + gap 16.00 + auto 5.457
       = .snav-right at x 279.14 — 35.45px of air on the right
     (Chrome reports `margin-left: 0px` for that third auto through
     getComputedStyle rather than its used value, so this was proved by
     rectangle arithmetic and not by reading a computed style. The
     arithmetic is what shows all three autos resolved to 5.457px.)

     Zeroing that one margin leaves exactly two autos, so the slack splits
     in half and the artwork sits with EQUAL air on both sides of itself —
     MEASURED 53.91 left / 53.89 right at 390px, and 18.98 / 18.98 at
     320px. The actions do not move: with no other auto in the row the free
     space is fully consumed by the lockup's pair, which puts .snav-right's
     right edge on the content box's right edge anyway. (It stays `auto`
     above 860px, where .snav-links is flex:1 and the desktop row genuinely
     needs it.)

     EQUAL AIR AROUND THE LOCKUP IS NOT THE SAME AS CENTRING IT IN THE BAR,
     and until 2026-08-26 this file settled for the first and argued the
     second was unreachable. MEASURED on the shipped build at 393px, which
     is what sent the owner back: gapBurgerToLogo 55.25, gapLogoToRight
     55.25 — equal to the hundredth — and the artwork's own centre 28.40px
     LEFT of the bar's. Both facts at once, because the two sides do not
     weigh the same: one 44px button on the left, two plus their gap on the
     right. Equal air is what the RULE produced; off-centre is what the EYE
     read, and the eye was right.

     OWNER, 2026-08-26: "core chains lab logo needs to be in the middle of
     the mobile nav. its a little left centered. so move core chain labs to
     the middle and push the cart icon a little to the right so the middle
     isnt cluttered and the logo isnt covered at all and has enough space."
     That is a decision, so §2a-2 below centres it in the BAR and this
     paragraph records what changed rather than arguing against what the
     file now does.

     AND THE ZEROING GOES BACK TO `auto`, WHICH IS THE TEMPLATE'S OWN VALUE
     (index.html:447). This rule used to read `margin-left: 0` for the
     reason argued above — three `auto` margins in one row split the slack
     three ways and pushed the lockup left. That reason DIED with §2a-2:
     the lockup is `position:absolute` now, so it is out of flow and
     contributes no margins to the flex line at all. The only flex items
     left are the hamburger and this cluster, and with no `auto` between
     them the actions sit immediately after the burger.

     MEASURED, and this is why the rule is written out rather than just
     deleted: with `margin-left: 0` and an absolute lockup, .snav-right's
     box lands at x = 49.07 on a 393px bar — hard against the hamburger,
     247px of empty bar to its right. The cart and the account icon were
     in the middle-left of the nav. It looked nothing like the reference
     and nothing like a nav.

     `auto` is what pushes them to the far edge, and with the lockup out of
     flow there is nothing left for it to skew. MEASURED after: cluster at
     x = 291.39, right glyph inset 17.06 — the mirror of the burger's, by
     §2d's identity. */
  html body #site-nav .snav-right { margin-left: auto; }

  /* ── 2a-2. DEAD CENTRE, THE WAY THE REFERENCE DOES IT ──────────────────
     OWNER, 2026-08-26, after a flex-spacer version of this measured 1.00px
     off centre and still did not satisfy him on the phone: "just look at
     what we did for lumina labs - look at the code or see what i did there
     and copy it - copy the layout of mobile nav as well."

     So this is luminaresearchlabs.com's own rule, read out of that repo's
     index.html:356 and confirmed against the live site:

         @media(max-width:768px) {
           #site-nav .snav-logo { position:absolute; left:50%;
                                  transform:translateX(-50%); margin-right:0; }
         }

     MEASURED on the live reference at 393x852, iPhone UA: logo box
     127.16 x 38 in a 64px bar (59.4%), centre offset EXACTLY 0.00,
     computed position `absolute`.

     THIS FILE USED TO ARGUE AGAINST EXACTLY THIS RULE, and the objection
     was not wrong — it was incomplete. §2a's own paragraph says an
     absolutely-positioned box "does not know its siblings exist, so on a
     narrow phone the lockup reaches THROUGH the cart", and that is true of
     the rule ON ITS OWN. It is what the TEMPLATE ships at ≤768px
     (index.html:508) with no width bound at all, and it is why the lockup
     was overlapping the cart before any of this. The reference gets away
     with it because its lockup is small and its action glyphs are 21px in
     38px boxes.

     The answer is not to avoid the rule, it is to BOUND it: §2b's
     `max-width` cap is solved so the artwork can never reach the
     furniture, at any width, including 320. With that cap in place the
     overlap the old objection describes is arithmetically impossible, and
     absolute centring gives exactly 0.00 rather than the spacer's 1.00.
     Same geometry, one fewer moving part, and it is the rule the owner
     pointed at.

     (The two approaches give the SAME available width — the spacer made
     the free space symmetric about the bar's midpoint, which is the same
     constraint absolute centring states directly. Nothing about §2b's
     table changes.) */
  html body #site-nav .snav-logo {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    margin-inline: 0;
    margin-right: 0;
  }

  /* ── 2a-3. THE ACTIONS MOVE RIGHT, AND THE GAP CLOSES A LITTLE ─────────
     "push the cart icon a little to the right so the middle isnt
     cluttered" — both halves of that sentence buy centre width, and the
     centre needs it, because §2a-2 doubles the RIGHT side's reservation
     onto the left as well. Every pixel taken off the right cluster is
     taken off twice.

     TWO DIALS, both small and both bounded by the 44px touch floor, which
     is lane 02's measured accessibility contract and does not move:

       gap  0.75rem -> 0.5rem   (12.75px -> 8.50px)  saves 4.25 x 2
       edge -12px   -> -14px    (2px further right)  saves 2.00 x 2

     `--cc-nav-action-gap` is declared once here and read by §2a-2's
     reservation and by the gap itself, so the two cannot drift apart —
     the identity above is only true while both terms say the same thing.

     MEASURED consequences at 393px: the right cluster narrows 100.75 ->
     96.50 and its outer edge moves from 5.07px off the glass to 3.07px;
     the 44x44 boxes are unchanged and still entirely on screen, and the
     glyph reads (gutter - 2) from the edge instead of exactly the gutter,
     which is the "a little to the right" that was asked for. §2d's
     identity still holds on the left, where -12px is untouched.

     THE -14px LIVES IN §2d, NOT HERE. §2d already declares
     `html body #site-nav .snav-right { margin-right: … }` at this exact
     specificity and LATER in the file, so a second copy up here would lose
     to it on order and read like a rule that works. One declaration, in
     the section that owns edge insets. */
  html body #site-nav { --cc-nav-action-gap: 0.5rem; }
  html body #site-nav .snav-right { gap: var(--cc-nav-action-gap) !important; }

  /* ── 2b. 60% OF THE BAR, NOT 77% ──────────────────────────────────────
     MEASURED before: 46px of artwork in a 60px bar = 76.7% at <=768px, and
     51.75px in a 67px bar = 77.2% across the 769-860 bridge — leaving 7px
     of air top and bottom, and the lockup's mark bleeds to the edges of
     its own artwork, so there is no built-in breathing room to spend
     either. Reference, measured on luminaresearchlabs.com at 390 this
     session: 38px of lockup in a 64px bar = 59.4%.

     A RATIO OFF THE BAR, NOT A STACK OF BREAKPOINTS. --sf-nav-h is the one
     knob the whole chrome reads, so 0.6 x it holds the proportion exactly
     wherever the bar goes: MEASURED 36.0px tall on the 60px phone bar and
     40.2px on the 67px bridge bar — 60.0% in both halves of the band.

     THE WIDTH FOLLOWS THE CHOSEN SRCSET CANDIDATE, NOT THE ATTRIBUTES. The
     <img> carries width="1506" height="425" (aspect 3.5435) but the
     browser renders the 640w candidate, whose real file is 640x181 (aspect
     3.5359), and it is the CANDIDATE's aspect that sizes the box: MEASURED
     127.28px wide at height 36. Against the reference's measured
     127.16 x 38 that is 0.12px of difference in width. Continuous by construction:
     one expression, no step, nothing to re-tune at a width nobody tested.

     WHY NOT MOVE --sf-logo-nav-h INSTEAD. Because .snav-mob-logo img (the
     DRAWER's lockup) is calc(--sf-logo-nav-h * 0.82) (index.html:481), and
     the drawer is another lane's surface. Moving the variable would resize
     a surface this lane does not own, so the height is set on the nav's
     own img.

     THE min() IS THE COLLISION PROOF, and the arithmetic is worth writing
     down — the first pass at it was wrong, which is why it was measured
     rather than trusted. It is solved for the NARROW half of the band
     (<=768px, gutter 1rem, .sf-nav-inner's own padding zeroed by
     sf-refresh §6c), where the row reserves at most:
         2 x gutter (1rem, fluid 17.00 -> 17.21px) ...  34.42
         burger   44px box, pulled out 12px .........   32.00
         actions  44 + 44 + 0.75rem gap, pulled out 12  88.90
         the lockup's own padding-inline 0.5rem x2 ...  17.21
                                                       ------
                                                       172.53
     The 0.75rem in that table is sf-refresh.css:2224's
     `body #site-nav .snav-right { gap:0.75rem !important }` at (1,1,1),
     which out-specifies sf-final-mobile.css:101's `#site-nav .snav-right
     { gap:0.6rem !important }` at (1,1,0) — MEASURED computed gap 12.75px
     at 320px, so 0.75rem is the number that is really in the row.

     .sf-nav-inner's own flex `gap` is NOT in that table, and it was the
     term the first draft missed: it is 2 x 16px more, and at 320px it is
     exactly what pushed the row over its width. §2a above zeroes it, so
     the table is complete as written — if that rule is ever removed, this
     constant is 32px short and 320px is where it shows (measured: the
     lockup loses 11.03px of its width there and letterboxes).

     190px is a deliberately fat over-reservation of the 172.53. Cap the
     artwork at (100vw - 190px) / 3.55 — 3.55 is >= both the attribute
     aspect 3.5435 and the rendered aspect 3.5359, so the cap errs in the
     safe direction — and the image can never be wider than the gap it sits
     in, at ANY width, including ones nobody tested. At the 320px floor the
     cap is 36.62px while the ratio wants 36.0px, so the cap does not bind
     on any phone that exists: it is a guard, not a size, and below 317.8px
     it takes over and scales the lockup down rather than letting it crowd.
     (100vw over-reports by the scrollbar width in a narrow DESKTOP window,
     which only makes the cap more generous; the ~17px of slack absorbs
     it.)

     THE CAP IS INERT IN THE BRIDGE, AND DELIBERATELY SO. At 769px it
     computes to 163px while the ratio asks for 40.2px, so the ratio always
     wins up there. MEASURED after, clearance between the artwork and the
     actions: 209.6px at 800 and 237.8px at 860. There is no collision to
     guard against in the bridge; the same expression simply never binds.

     max-width restates the bound in the axis it is measured in, and it is
     `min(100%, …)`, not the bare viewport term. The 100% half is what
     sf-refresh.css:2214 supplied and this rule replaces: it keeps the
     artwork inside its own flex-shrunk box. Combined with the template's
     `object-fit: contain` (index.html:419) the failure mode of a wrongly
     edited min() above is a letterboxed logo rather than a lockup sitting
     on top of the cart. MEASURED: with the bare viewport term alone the
     artwork escaped its own padding box by 11.03px at 320px; with min() it
     letterboxes instead, at every tested width. */
  /* THE RESERVATION IS 212px SINCE 2026-08-26, NOT 190. It was 190 while
     the lockup sat between its neighbours: the row reserved 172.53 and 190
     was a deliberately fat rounding of it. §2a-2 centres the lockup in the
     BAR instead, which means the LEFT now reserves what the right does, so
     the table doubles the wider side rather than adding the two:

         gutter (1rem, fluid 17.00 -> 18.00) ....  18.00   (worst case)
         two 44px action boxes ..................  88.00
         their gap (0.5rem) .....................   8.50
         the right cluster's -14px pull ......... -14.00
                                          one side 100.50
                                          x 2 .... 201.00

     212 is that with 11px of slack, in the same spirit as the old figure.
     MEASURED against the ratio at every width in the band: the cap is
     inert everywhere the ratio can be honoured and only takes over at the
     narrow floor —

       320 -> cap 30.42px BINDS (ratio wants 36.0); artwork 108.0 wide in
              117.0 of free space, 4.5px clear on each side
       360 -> cap 41.69   inert      375 -> cap 45.92   inert
       390 -> cap 50.14   inert      393 -> cap 50.99   inert
       430 -> cap 61.41   inert      767 -> cap 156.34  inert
       800 -> cap 165.63  inert (ratio 40.2 in the 67px bridge bar)

     So on every phone from 360 up the lockup is exactly 60% of the bar, as
     before; at 320 it steps down to 50.7% rather than colliding, which is
     the same failure direction §2b already chose. `max-width` restates it
     in its own axis with `min(100%, …)` for the reason written above — the
     failure mode of a wrongly edited min() stays a letterboxed logo, never
     a lockup sitting on the cart. */
  html body #site-nav .snav-logo img {
    height: min(
      calc(var(--sf-nav-h, 60px) * 0.6),
      calc((100vw - 212px) / 3.55)
    );
    width: auto;
    max-width: min(100%, calc(100vw - 212px));
  }

  /* ── 2c. THE THREE GLYPHS ARE ONE SIZE ────────────────────────────────
     MEASURED before: hamburger 20px, cart 25px, account 25px — at every
     width in the whole 320-860 band. The 25px came from sf-refresh.css:1685
     (`#site-nav .snav-right .snav-icon-btn svg`, in no media query at
     all), which grew the actions to suit the 67px DESKTOP bar and was
     never re-solved for the phone — so on a phone the two right-hand
     glyphs are 25% heavier than the one on the left, which is the
     imbalance in the owner's screenshot. 20px is not a new number: it is
     the hamburger's own inline width/height attribute, and the hamburger
     is the thing the eye compares them against. (The action <svg>s carry
     inline width="21" height="21"; a presentational attribute loses to any
     stylesheet, which is why 25px is what shipped and 20px is what ships
     now.)

     THE 44x44 TOUCH TARGET DOES NOT MOVE. sf-final-mobile.css:100 pins the
     button box to 44px !important as a measured accessibility contract
     across this same <=860px band; only the glyph inside it changes, so
     the extra target is padding — exactly as it should be. MEASURED after:
     the button boxes are still 44x44 at every tested width. */
  html body #site-nav .snav-right .snav-icon-btn svg { width: 20px; height: 20px; }

  /* ── 2d. BOTH EDGE INSETS ARE THE BAR'S OWN GUTTER, BY ARITHMETIC ─────
     What the eye reads at the edge of the bar is the GLYPH, not the
     invisible 44px box around it. So each box is pulled out by exactly
     half the difference between box and glyph — (44 - 20) / 2 = 12px — on
     both sides. Then, whatever the bar's own left/right inset is (call it
     `gutter`; it is #site-nav's padding plus .sf-nav-inner's, and both are
     symmetric):

         left  glyph inset = (gutter - 12) + 12 = gutter
         right glyph inset = (gutter - 12) + 12 = gutter

     The identity does not care what `gutter` is, which is what lets one
     pair of rules cover both halves of the band. MEASURED after — left and
     right glyph inset, equal to the hundredth at every width:
       320 -> 17.00 / 17.00      390 -> 17.06 / 17.06
       430 -> 17.20 / 17.20      767 -> 18.00 / 18.00
       800 -> 60.00 / 60.00      860 -> 61.80 / 61.80
     (the <=768 gutter is 1rem and the root is
     clamp(17px, 0.35vw + 15.7px, 18px) at sf-refresh.css:633, so it
     tracks; in the bridge it is #site-nav's 2rem plus .sf-nav-inner's own
     clamp(16px, 3vw, 28px), which is why the number jumps and the identity
     does not.) MEASURED before, the same pairs read 19.00 / 19.50 at 320,
     19.06 / 19.56 at 390 and 62.00 / 69.50 at 800 — the asymmetry the
     owner was looking at.

     That replaces sf-refresh.css:2224's -7px, an optical correction
     measured FOR the 25px glyph that stops being right the moment the
     glyph is 20px, and sf-final-mobile.css:98's -10px on the burger,
     measured for a 20px glyph in a bar whose gutter it did not restate.
     The 44px boxes end 5.07px from the glass on both sides at 320px; they
     are still 44x44 and still entirely on screen.

     `gap` is deliberately not restated — the distance BETWEEN the two
     action glyphs is not what the owner was looking at, and §2b's table
     already accounts for the 0.75rem that is really there. */
  html body #site-nav #snav-mob-left-btn { margin-left: -12px; }

  /* BACK TO -12px, AND SYMMETRIC, 2026-08-26. It was briefly -14 to buy
     centre width, which was only ever worth anything to the flex-spacer
     centring §2a-2 has now replaced: with the lockup absolutely centred,
     the bar's midpoint does not depend on how wide the right cluster is,
     so the 2px bought nothing and cost the symmetry the identity above
     proves. It also read cramped — 3.07px of glass at the right edge
     against the reference's 16.00.

     THE REFERENCE IS SYMMETRIC AND ROOMIER, measured live at 393: burger
     box 34x34 at x=16.00, action boxes 38x38 ending 16.00 from the right,
     glyphs 20px and 21px. Its glyphs therefore sit ~23px in. This site
     cannot copy those box sizes — 34 and 38 are under the 44x44 touch
     floor that lane 02 measured and this file will not walk back — so it
     copies the SYMMETRY instead: -12px on both sides puts a 20px glyph in
     a 44px box exactly at the bar's own gutter, on the left and the right,
     by the identity above. MEASURED after: 17.06 / 17.06 at 393. */
  html body #site-nav .snav-right { margin-right: -12px; }   /* margin-left is zeroed in §2a */
}


/* ══════════════════════════════════════════════════════════════════════
   3. THE STRIP ABOVE THE BAR IS THE BAR'S OWN COLOUR, BECAUSE THE ROOT
      ELEMENT IS PAINTED IT.

   OWNER, 2026-08-26, after a viewport-fit=cover / safe-area-inset version
   of this shipped and STILL did not fix his phone: "nav bar didnt work
   still. just look at what we did for lumina labs - look at the code or
   see what i did there and copy it."

   SO THIS IS THE REFERENCE'S MECHANISM, READ OUT OF ITS OWN SOURCE. From
   C:\Users\matty\Desktop\Aether Research Labs\index.html:91-93 —

       :root { --navy: #0D1B3E; --teal: #1A56A0; --bg: #0D1B3E; }
       html { scroll-behavior: smooth; background: var(--navy); }
       body { ... background: var(--bg); ... }

   `--navy` and `--bg` ARE THE SAME COLOUR. So on that site the root
   element, the body, and (measured live) the theme-color meta are one
   value, #0D1B3E, and the bar itself is a translucent tint OVER that one
   ground — rgba(5,10,22,0.62) with a 24px backdrop blur. MEASURED live at
   393x852 with an iPhone UA: htmlBg rgb(13,27,62), bodyBg rgb(13,27,62),
   theme-color #0D1B3E. There is nothing for the page to show "through",
   because everything near the top of that page is the same colour.

   WHAT THIS SITE HAD INSTEAD, and it is the whole defect: theme-color
   #10294A (the bar) against html and body #060E1A (the page ground). Two
   different colours, and the strip above the bar was painting the SECOND
   one. Every earlier attempt worked on the bar — flattening its gradient,
   stamping the meta, bleeding a pseudo-element upward, growing it by a
   safe-area inset — and none of them touched the surface that was actually
   showing.

   WHY THE SAFE-AREA VERSION DID NOT WORK, stated so nobody rebuilds it. It
   depended on `env(safe-area-inset-top)` being non-zero, which needs
   `viewport-fit=cover`; the reference ships NO viewport-fit at all and is
   correct on the owner's own phone, so that whole mechanism was a theory
   the device did not agree with. Under the default `contain`, iOS keeps
   the web content below the island and fills that strip from the page's
   CANVAS — and the canvas comes from the root element's background. Paint
   the root, and the strip is right without asking the browser for
   anything. `viewport-fit=cover` is therefore REMOVED from the metas by
   final/26-nav-fit.mjs, and the rules that read env() are gone with it.

   WHAT IS DELIBERATELY *NOT* COPIED: the reference's actual colours, and
   its `--bg` = `--navy` equality. This client's page ground stays #060E1A
   and its chrome stays #10294A — a client site a visitor would recognise
   as the owner's store is a failed deliverable (CLAUDE.md), and the owner
   asked for the LAYOUT and the MECHANISM, not the palette. Painting the
   ROOT the chrome colour gets the reference's result — one colour anywhere
   the page is not — while leaving the site's own design alone.

   WHERE THIS ACTUALLY SHOWS, since body covers the whole document: only
   OUTSIDE the body box — the island/status strip, and rubber-band
   overscroll at both ends. At the top that is the fix. At the bottom the
   footer is already the brand wash, so navy below it is continuous rather
   than a third colour, which was the objection recorded against this rule
   in the previous pass. That objection is withdrawn: it weighed a
   hypothetical bottom seam against a top seam the owner was actually
   looking at, twice.
   ══════════════════════════════════════════════════════════════════════ */

/* ── 3a. THE ROOT IS THE CHROME COLOUR ─────────────────────────────────────
   Not `background` shorthand — `background-color` only, so `scroll-behavior`
   and anything else the engine puts on the root are untouched, and so that a
   future background-image on <html> is not silently erased by this line. */
html {
  background-color: #10294A;
}

/* ── 3b. AND THE BLEED IS A LITERAL, AND TALLER ────────────────────────────
   sf-refresh.css §6b writes `background: inherit` on #site-nav::before with a
   comment telling the next reader not to replace it with a literal because
   "the chrome ground is gate-measured where it is declared". That was true of
   a bar painting a GRADIENT — §1 flattened this one to a single colour, and a
   flat colour has exactly one value to inherit, so the literal and the
   inherit cannot disagree.

   This is now BELT, not the fix: 3a covers the strip. What the bleed still
   earns its place for is the iOS rubber-band, where the visual viewport moves
   and the fixed layer does not — that happens INSIDE the layout viewport,
   which is the one place a fixed element's paint is not clipped away. 120px
   -> 300px because a hard flick moves further than 120px, and the extra is
   off-screen in every settled state, so it costs nothing. */
html body #site-nav::before {
  background: #10294A;
  height: 300px;
}


/* ══════════════════════════════════════════════════════════════════════
   3c. THE BAR'S OWN BOX STARTS ABOVE THE VIEWPORT — AND THIS IS THE ONE
       THAT MATTERS, BECAUSE IT IS THE ONLY FIX HERE THAT DOES NOT DEPEND
       ON SOMETHING PAINTING *OUTSIDE* A FIXED ELEMENT.

   THE OWNER'S PHOTOGRAPH, 2026-08-26, after four attempts: the products
   page's "Shop by category" heading and its paragraph are rendering in a
   strip at the very top of the screen, with the status bar drawn over
   them, and the navy bar begins BELOW that strip. Measured off the image:
   the bar's top edge is ~54 CSS px down. So on that device the page paints
   from screen y = 0 while `position: fixed; top: 0` resolves to y = 54 —
   the layout viewport (what fixed positioning is measured against) is
   inset by the safe area, and the document is not.

   WHY EVERY PREVIOUS ATTEMPT MISSED IT, and it is one shared assumption:
     · flattening the bar's gradient      — worked on the bar
     · stamping <meta name="theme-color"> — worked on the browser chrome
     · sf-refresh §6b's 120px ::before    — an OVERFLOWING CHILD of the bar
     · viewport-fit=cover + env() padding — needed env() to be non-zero
     · html { background-color: navy }    — paints the canvas, and the
                                            strip is showing DOCUMENT, not
                                            canvas, so it cannot help
   Every one of them either targeted the wrong surface or relied on paint
   escaping a `position: fixed` box. iOS Safari promotes a fixed element to
   its own compositor layer and sizes that layer to the element; content
   that overflows it — which is exactly what a `bottom: 100%` pseudo-element
   is — is not reliably composited during a scroll. That is why the bleed
   is fine in every desktop engine and absent on his phone.

   MEASURED, and this is the honest part: headless Chrome CANNOT REPRODUCE
   THE BUG. Simulating the 54px offset (`#site-nav { top: 54px }`) on the
   live page and sampling the real pixels of the strip above the bar gives
   13 distinct colours, dominant rgb(18,43,75) at 31% — i.e. already navy,
   because Chrome composites the ::before perfectly well. Four passes were
   "verified" against an engine that never had the defect. Do not treat a
   green screenshot here as evidence about this rule.

   SO THE RULE STOPS ASKING FOR PAINT OUTSIDE THE BOX. The bar's own border
   box starts 120px ABOVE the layout viewport's top and pads its contents
   back down by the same amount. The navy in that strip is then the
   element's own background — the thing a compositor layer is sized around,
   not something overflowing it — and no engine has to do anything special
   for it to be there.

   THE ARITHMETIC, with `box-sizing: border-box` so the height includes the
   padding and `align-items: center` keeps centring the row in the CONTENT
   box (i.e. below the padding):

     layout-viewport inset 54 (his phone, no viewport-fit)
       box      screen  -66 → 114     ... covers 0 → 114 in navy
       content  screen   54 → 114     ... the row, clear of the island
     no inset (Android, desktop)
       box      screen -120 → 60      ... the extra is simply off-screen
       content  screen    0 → 60      ... byte-identical to today

   MEASURED both states against the live page: nav box -66→114 with the
   logo top at 65 under the simulated inset, and the logo top unchanged at
   11 without one. The row does not move in either case; only the painted
   box grows upward.

   120px IS DELIBERATELY MORE THAN ANY INSET THAT EXISTS. The largest top
   safe-area inset on any shipping iPhone is 59px; 120 is double it, so the
   cover holds for a device that has not been released yet. It costs
   nothing — the surplus is above the screen.

   THE env() TERMS ARE INERT TODAY AND KEPT ON PURPOSE. Without
   `viewport-fit=cover` every safe-area inset reports 0, so both `calc()`s
   reduce to the 120px case above. If cover is ever turned back on — which
   would make the layout viewport the whole screen and put the row under
   the island — these two terms arm themselves and push it clear, with no
   other edit. That is the one thing the cover attempt got right, kept at
   zero cost. */
/* ── 3c. THE CANONICAL NOTCH HEADER, AND NOTHING ELSE ─────────────────────
   SEVENTH ATTEMPT, and the first one that REMOVES rather than adds.

   What this rule accumulated over attempts 3-6, all of it now deleted:
     top: -400px + padding-top: 400px   a box starting above the viewport
     transform: translateZ(0)           a forced compositor layer
     backface-visibility: hidden        "
     will-change: transform             "
   None of it fixed the phone, and TWO of them are actively dangerous here:
   in WebKit a `transform` on a fixed element is a documented way to BREAK
   fixed positioning, because a transformed box becomes a containing block
   and the element can start resolving against the document instead of the
   viewport. Attempt 5 added that while trying to fix attempt 4. A workaround
   that does not work is not free — it is a new variable.

   THE REFERENCE'S BAR IS NINE WORDS: position:fixed, top:0, height:64px.
   The only thing it needs that this one also needs is the safe-area inset,
   and this is the canonical way to spend it — grow the bar by the inset and
   push its contents down by the same amount, so the bar's own background
   fills the island strip and the row sits clear below it. box-sizing is what
   keeps `align-items:center` centring the row in the CONTENT box.

   `top: 0` is restated deliberately: attempts 4-6 left it negative, and a
   negative top is exactly what has to go for the layout to be inspectable
   again. If this still fails, the next move is data from the device, not a
   ninth declaration — see nav-debug.html, written by final/33-nav-debug.mjs. */
html body #site-nav {
  box-sizing: border-box;
  top: 0;
  padding-top: env(safe-area-inset-top, 0px);
  height: calc(var(--sf-nav-h, 60px) + env(safe-area-inset-top, 0px));
}


/* ══════════════════════════════════════════════════════════════════════
   3d. WHAT THE PAGE IS OFFSET BY MUST GROW WITH THE BAR.

   THE HIGHEST-RISK RULE IN THIS FILE, and the one nothing here can
   self-check: the bar is fixed, so every page clears it BY HAND. With
   `viewport-fit=cover` back on (final/26-nav-fit.mjs), the bar is
   `--sf-nav-h + env(safe-area-inset-top)` tall instead of `--sf-nav-h`.
   If these two do not grow by the same term, the first screenful of every
   page slides under the bar — which is a worse defect than the one being
   fixed, and it appears only on the devices this whole section exists for.

   There are exactly TWO clearances in this build and no others. Grepped
   across every built page and every linked stylesheet for margin-top /
   padding-top / scroll-padding-top keyed to --sf-nav-h:

     index.html:120   body:not(.layout-default) #hero { margin-top: var(--sf-nav-h, 64px) }
     every inner page, INLINE on its header section:
                      style="padding-top:calc(var(--sf-nav-h,64px) + 32px); …"

   The second is an INLINE style, which no stylesheet beats without
   `!important` — that is why one rule below carries it and the other does
   not. `html body …` at (1,1,2) out-specifies the page's own (0,1,1) block
   for the hero.

   BOTH TERMS ARE 0 ON EVERY DEVICE WITHOUT AN INSET, so a phone with no
   notch, an Android and every desktop browser compute exactly what they
   computed before this line existed. Nothing here is conditional on a
   width or a user agent.

   Lane 27 owns the hero's HEIGHT; this owns its CLEARANCE. Same selector,
   different properties, split along which lane the decision belongs to. */
html body:not(.layout-default) #hero {
  margin-top: calc(var(--sf-nav-h, 64px) + env(safe-area-inset-top, 0px));
}
html body .page-header-bg {
  padding-top: calc(var(--sf-nav-h, 64px) + 32px + env(safe-area-inset-top, 0px)) !important;
}


/* ══════════════════════════════════════════════════════════════════════
   3e. THE DOUBLE-HEIGHT BAR — HOME PAGE ONLY, AS A TEST.

   OWNER, 2026-08-27, after seven passes and after watching it happen on
   his own phone: "the navy box behind the real nav box will attatch to the
   top of the nav so it doubles the navs height when scrolling the page.
   push this out for the homepage and we will see if it works so we can
   push sitewide."

   That is this rule, exactly, and it is his design not mine. The bar's
   PAINTED box starts one full bar-height above the viewport top, so the
   navy reads as double height; the CONTENT row does not move, because the
   same amount is added to padding-top. Whatever the stationary navy box he
   can see actually is, the bar now reaches up to meet it.

   WHY THIS IS SCOPED TO ONE PAGE AND NOT SITEWIDE. He asked for the home
   page first, and he is right to: seven sitewide changes have each cost a
   full build, a deploy and a trip to his phone to find out. A one-page test
   answers the same question at the same cost and cannot make the other 25
   pages worse while it is being answered. Widening it is deliberately a
   ONE-LINE change — final/26-nav-fit.mjs stamps `data-cc-nav-double` on
   index.html's <body> and nowhere else; stamp it on `all` and this rule is
   sitewide with no CSS edit at all.

   HOW IT DIFFERS FROM THE -400px BOX THAT DID NOT WORK (attempt 6). That
   one asked for 400px of paint above the viewport, which is far outside
   anything the browser needs to composite for a fixed element and is the
   kind of overflow iOS discards. This asks for 60px — the bar's own height
   — which keeps the whole box within one bar-height of where a fixed bar
   already paints. It is a smaller request of the same shape, and the owner
   has seen a real navy box up there that suggests something IS painted in
   that band. If this works and 400px did not, that boundary is the finding.

   THE ARITHMETIC, with box-sizing:border-box so height includes padding
   and align-items:center still centres the row in the CONTENT box:

     painted box   -60  →  60 + inset      (2x the bar, plus the island)
     content row     0  →  60 + inset      unchanged, so nothing moves
     #hero's clearance is untouched — it clears the CONTENT row, which is
     where it always was.
   ══════════════════════════════════════════════════════════════════════ */
html body[data-cc-nav-double] #site-nav {
  box-sizing: border-box;
  top: calc(-1 * var(--sf-nav-h, 60px));
  padding-top: calc(var(--sf-nav-h, 60px) + env(safe-area-inset-top, 0px));
  height: calc((var(--sf-nav-h, 60px) * 2) + env(safe-area-inset-top, 0px));
}
