/* ==========================================================================
   chrome.css — THE SITE CHROME STYLESHEET. Loaded by every preview page.

   These rules are the header/dock half of v21.css, lifted VERBATIM (2026-07-24)
   so the shared chrome can ship everywhere without dragging home-v21 page rules
   along with it. The rest of v21.css stays home-v21-only — in particular
   :root{--sec:80px}, which ten other stylesheets read for section padding;
   linking v21.css site-wide would silently retighten every page.

   Pair with partials/header.html + partials/dock.html; stamp with
   tools/sync-chrome.mjs. Edit header styling HERE, not in v21.css.
   ========================================================================== */

/* --- 1 · HEADER — ONE ROW, THREE GROUPS -------------------------------------
   2026-08-05, the client's nav round. THE TWO-ROW BAR IS GONE. She read the
   utility row stacked over the menu row as "weird, not angled properly, not
   symmetrical enough", and her designer's four alternatives all answer it with a
   single row; she leans to his Version 3. What is built here is that one row plus
   George's correction of it — the designer spaced all eight elements evenly, so
   the bar read as eight unrelated things in a line. It is THREE GROUPS:

     [logo]        [COMPANY · ACCOUNTING · PAYROLL · FREELANCERS · TEAM]        [CTA·Login | EN]

   Wide space BETWEEN the groups, tight space WITHIN them. That contrast IS the
   fix, and the two numbers are --nav-gap against the two inner gaps below.

   ⚠ THE PHONE, THE POSTAL ADDRESS AND THE EMAIL LEFT THE HEADER with the utility
   row and are not coming back into it. No information was lost, and it is THE
   FOOTER that makes that true: all three are in the footer of all 42 pages, checked
   page by page, with no gaps. The mobile dock's "Call now" carries the number as
   well. The floating contact chip (.cslide) carries them too: since 2026-09-29 it
   ships in partials/dock.html and is on every page. The footer is still the one that
   must keep them; if it ever loses these details, the removal above stops being safe.
   ========================================================================== */
.site-header .glass-tint{background:rgba(255,255,255,.68)}

/* review r1 #1: the menu loads WITH the rest of the bar — no separate fade-in */
@media (min-width:1280px){
  .nav-collapsible{animation:none;opacity:1;transform:none}
}

@media (min-width:1280px){
  /* THE 3-TRACK GRID. `1fr auto 1fr` is what centres the menu optically in THE BAR
     rather than in whatever the flanking groups leave over: the two 1fr tracks are
     equal by construction, so the centre track's midpoint is the bar's midpoint no
     matter how much wider one flank is than the other. tools/measure-navfit.mjs
     reports that midpoint at nine widths from 1280 to 1920 and it is 0px off the
     bar's at every one of them. Do not "simplify" this back to flex or to auto
     margins: those centre the menu between the GROUPS, so it drifts by half the
     difference between the two flanks wherever they diverge — which is exactly the
     lopsidedness the client is calling unsymmetrical.
     ⚠ BOTH SIDE TRACKS SIZE TO THE WIDER FLANK, so the wider one is paid TWICE.
     Today that is the 300px lockup (the actions group is 301 at 1280, 326 at 1512),
     which spends 600px of a 1178px box before the menu is placed at all. It costs
     less than it looks: because the two flanks are within a few px of each other,
     true centring is nearly free here — `auto 1fr auto` would buy the menu ~1px.
     See the fit budget at --nav-fs.
     display:contents dissolves .nav-collapsible on desktop so its two children
     become grid items of .nav-row directly. Below 1280 it is a real flex column
     again and carries the dropdown's max-height transition (zara.css). */
  .site-header .nav-row{display:grid;grid-template-columns:1fr auto 1fr;
    align-items:center;column-gap:var(--nav-gap);row-gap:0;flex-wrap:nowrap;
    padding:var(--nav-padv) 0}
  .site-header .nav-collapsible{display:contents}
  .site-header .nav-row .brand{justify-self:start}
  .site-header .nav-row .navigation-menu{justify-self:center;margin:0}
  .site-header .nav-actions{justify-self:end}
  .site-header .nav-row .lang{display:none}

  :root{
    /* THE BETWEEN/WITHIN PAIR: this is the deliverable, not decoration. Measured
       between-group / within-menu: 33/10 at 1280, 51/15 at 1440, 45/16 at 1512,
       224/18 at 1920, never below 2.8x. Anything that narrows the between-gap or
       widens the within-gaps undoes the round.
       ⚠ --nav-gap IS A FLOOR, NOT THE GAP. It is the grid's column-gap, i.e. the
       MINIMUM; the real between-group distance is that plus whatever the two 1fr
       tracks have left over once the menu is placed, which is why the measured
       figure passes the 48px "cap" and reaches 224px at 1920. An earlier draft of
       this comment claimed the cap stopped the groups sailing apart on a 27"
       screen. It does not, and it cannot: the grid is what centres the menu, so
       the leftover width has to go somewhere. It is also not a bug. The clamp only
       governs the tight end, where the tracks have nothing spare. */
    --nav-gap:clamp(26px,2.1vw,48px);      /* BETWEEN the three groups (a floor) */
    --nav-mgap:clamp(10px,1.05vw,18px);    /* WITHIN the menu */
    --nav-padv:16px;                       /* the bar's own top/bottom padding */
    /* 🔴 THE FLANK RULE: THE LOGO AND THE ACTIONS GROUP MEASURE THE SAME, PER BAND.
       278/278 below 1400, 300/300 to 1511, 330/330 above. This is not tidiness, it is
       the only way the two between-group gaps can be equal. With the menu centred on
       the bar and both flanks flush to their outer edges the system is
       over-constrained: gapL = menuLeft − logoWidth and gapR = barWidth − actsWidth −
       menuRight, so every pixel of difference between the two flanks lands directly
       in the gaps. 330 against 326 at 1512 read as 45/49 — four pixels of asymmetry
       on the one bar the client is inspecting FOR symmetry. --nav-sepgap is the knob
       that closes it (it widens the actions group without moving the buttons off the
       content edge); --nav-btnpad/--nav-btnfs do the coarse work below 1400.
       ⚠ Never change --brand-w, --nav-btnpad, --nav-btnfs, --nav-langfs or
       --nav-sepgap without re-running tools/measure-navfit.mjs and checking the
       `flank` column back to 0. Chasing the gap numbers directly chases a symptom.

       THE FIT BUDGET — measured, never guessed. The row is genuinely tight and the
       binding width is 1280, not the client's 1440. There the box is 1178px and the
       two flanks take 2x278, leaving 555px of menu at the 12px floor with 33px gaps.
       ⚠ 12px IS A FLOOR, NOT A TARGET (the fluid value wants 10.92px at 1280). Small
       uppercase with letter-spacing is the least forgiving thing on the page to
       shrink, and the live site sets 13.76px in this band — 10.92 is not "a bit
       smaller", it is a different order of legibility. The mark pays for the floor by
       banding to 278 below 1400, which is the same banding this file already does at
       1400 and 1512; 300 and 330 are untouched, and those are the widths the client
       actually reviews on.
       ⚠ UPPERCASE IS EXPENSIVE AND NON-NEGOTIABLE. These five labels run 68
       characters; at .055em they measured 577px even at 11.5px. Sentence case fits at
       13.8px and was tried and REJECTED: the live site, all four of the designer's
       versions and the client's eye all say uppercase, and at this size lower case
       reads as body links rather than navigation. The width came out of the SIZE and
       the TRACKING instead (.055em → .035em below 1512).
       ⚠ Do NOT raise these without re-measuring. The labels carry white-space:nowrap
       so the old "Company in / Bulgaria" wrap cannot come back — the failure mode is
       now silent clipping at the glass edge, which is harder to notice. */
    /* ⚠ THE 14.4px CEILING IS THE BRIEF, NOT A ROUND NUMBER. George asked for menu items
       "a bit smaller"; the pre-round sizes were 13.76px below 1512 and 15.2px above it.
       The cap was 16px, which meant the fluid value crossed back over the OLD size at
       ~1673px and ran BIGGER than before the round from there up: 15.81px at 1728, 16px
       at 1920 and on a 27" screen. Correct at the client's 1440, wrong on the display
       George works on, and the one width nobody thinks to measure. 14.4px holds it under
       15.2px at every width from 1512 to 2560. Raise it and the round stops being true
       at the top end. */
    --nav-fs:clamp(13.4px,calc(1.1vw - 3.2px),14.4px);
    --nav-btnfs:.9rem;                     /* 14.4px — the buttons stay legible */
    --nav-btnpad:1.25rem;
    --nav-sepgap:13px;
    --nav-langfs:.8rem;
    --nav-track:.045em;
  }

  /* the menu — the uppercase cobalt the site has always used, at the smaller size
     George asked for (see the fit budget above for why it is exactly this small) */
  .site-header .nav-row .navigation-menu{flex:0 0 auto;gap:var(--nav-mgap)}
  .site-header .navigation-menu > li > a{white-space:nowrap}
  .navigation-menu a{font-size:var(--nav-fs);font-weight:600;
    text-transform:uppercase;letter-spacing:var(--nav-track);color:var(--blue)}

  /* the actions — the two buttons are a TIGHT pair at 10px, then a hairline, then
     the language control. The hairline is doing the grouping work inside the
     group: it says the globe is not a third button. */
  /* ⚠ DO NOT "FIX" THE FLANKS WITH min-width HERE. It was tried on 2026-08-05 and
     removed the same day, and the reason is a trap worth naming: min-width pads the
     actions BOX while the buttons stay flush to its right edge, so the box gap
     equalises but the gap the eye actually reads (menu to first button) does not.
     measure-navfit.mjs measures this element's rect, so it would cheerfully report
     `flank 0` and equal gaps while 1512 drifted visibly back to 45/49 — a rule that
     hides its own regression from the tool built to catch it. The flanks are made
     equal by sizing the CONTENT instead: --nav-sepgap above 1512, --nav-btnpad and
     --nav-btnfs below 1400. See the flank rule at the top of this block. */
  .site-header .nav-actions{display:flex;align-items:center;gap:10px}
  .site-header .nav-actsep{width:1px;height:26px;flex:none;
    background:rgba(1,30,147,.22);margin-inline:var(--nav-sepgap)}
  .site-header .nav-actions .langdd{display:block;position:relative;margin:0}
  .site-header .nav-actions .lang-btn{padding:.35rem 0;gap:.35rem}
  .site-header .nav-actions .lang-btn svg{width:19px;height:19px}
  .site-header .nav-actions .lang-code{font-size:var(--nav-langfs);font-weight:600;
    letter-spacing:.05em;color:var(--blue)}
  /* the control now sits ON the bar's right edge, so its panel hangs from that
     edge — v16.css centres the panel under the button, which would overhang the
     glass by ~50px here */
  .site-header .nav-actions .lang-menu{left:auto;right:0;transform:none;margin-top:.55rem}
}

/* 2026-07-26 (client): the WhatsApp mark is gone — the number now carries the plain
   handset from the red-seal registry (same glyph as the mobile dock's "Call now").
   That number itself left the header on 2026-08-05; the glyph survives in the dock. */

/* 13-14 INCH SCREENS (1280-1511) — the band that decides the whole layout, and the
   band the client reviews on (1440 x 609). The mark steps 330 → 300 here (§2) and
   everything else steps with it so the three groups keep their proportions.
   ⚠ --nav-fs IS A CLAMP WITH AN OFFSET, and the offset is the whole point. A plain
   vw clamp cannot do what this band needs: it has to reach the 12px floor at 1280 and
   still hand 1440 the ~13.2px that width can afford, a spread no pure `Nvw` covers —
   any slope that lands one end wastes type at the other. `calc(1.4vw - 7px)` hits
   both: floored at 12px to ~1357, 12.6px at 1400, 13.16px at 1440, ceiling 13.6px
   from ~1471. Flat values were tried and both are worse: 13.6px overflows 1280 by
   ~110px, 12px throws away a pixel at the width the client is actually looking at.
   ⚠ The actions group is trimmed in this band (300px against 330 above 1512) so it
   stays level with the mark — see THE FLANK RULE above before touching --nav-sepgap
   or --nav-btnpad; they are what keep the two between-group gaps equal. */
@media (min-width:1280px) and (max-width:1511px){
  :root{--nav-fs:clamp(12px,calc(1.4vw - 7px),13.6px);--nav-btnfs:.84rem;--nav-btnpad:1.05rem;
        --nav-sepgap:9.7px;--nav-langfs:.75rem;--nav-track:.035em}
}

/* THE TWO HEADER BUTTONS. Desktop only up here — below 1280 they move into the
   hamburger panel (see the mobile block further down), and the dock carries the CTA.
   ONE set of box values feeds BOTH: same min-height, same padding, same type size,
   so "Log in" reads as the CTA's equal in weight and differs only in colour.
   ⚠ LOG IN IS NOT A SECOND RED BUTTON, deliberately. Outlined cobalt keeps one
   primary action in the bar; two reds side by side split the eye and there is no
   portal behind Log in to justify the emphasis. */
.site-header .nav-cta,.site-header .nav-login{display:none}
@media (min-width:1280px){
  .site-header .nav-actions .btn{display:inline-flex;position:static;z-index:4;
    margin:0;padding:.62rem var(--nav-btnpad);min-height:42px;
    font-size:var(--nav-btnfs);font-weight:500;letter-spacing:.02em;
    text-transform:none;white-space:nowrap}
  .site-header .nav-login{background:transparent;color:var(--blue);
    border-color:var(--blue)}
  .site-header .nav-login:hover{background:var(--blue);color:#fff}
}

/* Below 1280 the bar is logo + hamburger and everything else is in the panel.
   zara.css hides .nav-cta there (it predates the dock and assumed the menu had no
   buttons at all); both buttons are wanted now, full-width and stacked, above the
   EN/DE pair. The globe dropdown stays hidden — .lang is the mobile control. */
@media (max-width:1279px){
  .site-header .nav-actions{display:flex;flex-direction:column;align-items:stretch;
    gap:.75rem;width:min(100%,19rem);margin-top:1.7rem}
  .site-header .nav-actions .btn{display:inline-flex;width:100%}
  .site-header .nav-cta,.site-header .nav-login{display:inline-flex}
  .site-header .nav-login{background:transparent;color:var(--blue);border-color:var(--blue)}
  .site-header .nav-actsep,.site-header .nav-actions .langdd{display:none}

  /* A WRAPPED LABEL STAYS CENTRED LIKE ITS NEIGHBOURS. The panel centres each <li>
     via align-items:center, which only centres the BOX — "Accounting & Tax
     Compliance" is the one label that breaks to two lines at 390, its box then
     fills the panel width, and the two lines set left while every item around them
     was centred. It read as a broken item rather than a long one. Centring the
     link's own text is the fix; the list-level centring cannot reach inside it. */
  .site-header .navigation-menu > li{width:100%}
  .site-header .navigation-menu a{display:block;text-align:center}

  /* THE CLOSE STATE IS AN X, NOT A BOWTIE. The button's SVG is 45 x 16, so the two
     45px rules stayed 45px wide when they rotated and the "X" came out flattened and
     twice as wide as it was tall. v16.css only turned them 16deg, which made a
     shallow cross rather than fixing the proportion. scaleX(.45) shortens each rule
     to ~20px BEFORE the rotation (transforms apply right to left), 45deg then draws a
     true diagonal, and the ±4px lands both on y=9 so they cross once in the middle.
     overflow:visible because a 20px diagonal is 14.1px tall on each arm and would
     otherwise clip against the 16px viewBox.
     ⚠ The CLOSED state is untouched: two clean horizontal rules, which is her mark. */
  .hamburger svg{overflow:visible}
  .hamburger line{transition:transform .32s ease;transform-box:fill-box;
    transform-origin:center}
  .hamburger.active line:first-of-type{transform:translateY(4px) rotate(45deg) scaleX(.45)}
  .hamburger.active line:last-of-type{transform:translateY(-4px) rotate(-45deg) scaleX(.45)}
  @media (prefers-reduced-motion:reduce){ .hamburger line{transition:none} }

  /* THE OPEN PANEL NEEDS ITS OWN GROUND. The bar's glass is a white tint over a
     blurred backdrop, which is right for a 107px strip and wrong for a 500px panel:
     over the homepage hero portrait the page read straight through it and the links
     lost their footing. .95 is measured, not picked — it is the lowest value at
     which the busiest backdrop on the site (the hero film behind home-v21) stops
     being legible through the panel.
     ⚠ SCOPED TO THE OPEN MOBILE PANEL ONLY. The desktop bar's liquid glass is a
     locked design decision (CLAUDE.md, 2026-06-09) and is untouched — as is the
     CLOSED mobile bar, which is still the same glass strip it always was. */
  .site-header:has(.nav-collapsible.open) .glass-tint{background:rgba(255,255,255,.95)}

  /* …and nothing floats ON TOP of it. The contact chip (.cs-handle) is fixed to the
     right edge and slides in ~1.5s after load, so on the homepage it landed across
     both panel buttons — measured overlap with 2 buttons at 390 and 1 at 360. It was
     always there; the opaque panel just made it obvious instead of a ghost.
     zara.css already does exactly this for .sticky-cta with the same :has() test, so
     this is that rule finishing the job rather than a new idea.
     ⚠ The chip itself is styled in v18.css, which another lane owns. This rule only
     hides it WHILE the menu is open; if that lane would rather own the behaviour,
     move this line there and delete it here. */
  body:has(.nav-collapsible.open) .cs-handle{display:none}
}


/* --- 2 · BRAND — the client's VECTOR lockup, sized from one variable ----------
   The lockup is unchanged as artwork: TAX LEGAL CORPORATE over ZARACONSULT over
   the CHARTERED ACCOUNTANTS | CORPORATE LAWYERS | TAX ADVISORS strapline.

   ⚠ THE FILE IS NOW VECTOR: img/zara-logo-lockup.svg, the client's own
   logo-footer-1.svg (2026-07-27), replacing the raster zara-logo-lockup.webp.
   Only the viewBox was touched — trimmed from "0 0 586 136.4" to the artwork's
   real ink bounds "35.3 2.1 533.3 133.8", which is lossless on an SVG and is the
   same trim the webp carried. It matters: the delivered file has 6% dead margin
   on its left edge, and untrimmed the mark would sit visibly indented from the
   bar while every size calc below silently measured the margin too.
   ⚠ The old raster file stays on disk — the FOOTER (zara.css) still points at
   img/zara-logo.webp, and nothing here touches it.

   🔴 THE TWO FILES ARE NOT THE SAME LOCKUP, AND THAT IS WHY --brand-w MOVED.
   They are proportioned differently, measured not guessed (as a fraction of the
   box width, ink only):

                       wordmark h   wordmark w   strapline w   whole mark
       webp (old)         10.65%       58.95%        99.50%      AR 6.03
       svg  (new)         17.52%       99.75%       100.00%      AR 3.986

   In the webp the STRAPLINE is the widest element and the ZARACONSULT wordmark
   floats inside it at 59% of the box. In the svg the wordmark runs the full
   width and the strapline is subordinate. So one box width cannot reproduce both:
   matching the whole footprint (592px) would have blown the wordmark up 68% and
   the bar to 136px, and matching the box (542px) would have done the same.
   ⚠ WHAT IS MATCHED IS THE WORDMARK, because that is what reads as "the logo":
   at --brand-w:330px the ZARACONSULT block renders 328.5 x 57.7px against the
   webp's 319.4 x 57.6px at 542px — the letters are the same height to 0.1px.
   The consequence, and it is deliberate: the mark's FOOTPRINT is narrower
   (330 vs 542) because the new lockup simply is more compact. That buys back
   room on line 1 — see --brand-max below, which no longer has to squeeze it.

   ⚠ Everything is driven by the vars below, and NOTHING should hardcode a brand
   size again. tools/live.mjs injects a tuner that writes them on :root, so the
   mark is sized live in the navbar (⌥L); whatever wins gets pasted back here.
   ⚠ --brand-ar is a NUMBER (width ÷ height), not a ratio pair: aspect-ratio takes
   it directly AND the calcs below divide by it to get the mark's height.
   Trimmed svg 533.3/133.8 = 3.986 · old lockup webp 1200/199 = 6.03 · old padded
   webp 1100/240 = 4.5833 · simple svg 5.365.

   Overrides zara.css .brand and the v16/v17/v18 header heights; chrome.css loads
   after all of them on every page, and the desktop rule matches v18's
   `.site-header .nav-row .brand` selector so it wins on specificity too. */
:root{
  --brand-src:url("/img/zara-logo-lockup.svg");
  --brand-ar:3.986;
  --brand-w:330px;          /* >=1512 — George's tune; ≈ the 337px in her mock at its
                               native width. The 1280-1511 band steps it to 300px.
                               ⚠ UNCHANGED by the 2026-08-05 one-row round: the mark
                               renders at exactly the pixel width it did in the two-row
                               bar. It was the only element George ruled out shrinking. */
  --brand-top:0px;          /* INERT since 2026-08-05. The one-row grid centres the mark
                               vertically (align-items:center), so nothing reads this any
                               more. It is declared only because tools/live.mjs's brand
                               tuner reads --brand-top and Math.round()s it; deleting the
                               variable feeds the tuner NaN. Do not wire it back up. */
  /* Below 1280 the floor is vw, not px: at 320 the glass bar gives ~248px of
     content and the hamburger needs 45 of it, so a fixed floor wraps the burger
     onto a second line.
     ⚠ Scaled by the same 0.608 the desktop width was (10.65/17.52 — the ratio of
     the two files' wordmark heights), so the mobile wordmark also renders at the
     size it does today rather than 64% bigger. */
  --brand-w-sm:clamp(97px,31.6vw,195px);
  /* what the fixed bar measures, and the top padding a page needs to clear it —
     every hero's padding-top reads --chrome-clear, so the bar can grow without
     ending up on top of an H1. Overridden per breakpoint below.
     ⚠ The added constant is the chrome around the mark, and it is NOT one number:
     it is the header's own top offset plus the bar's padding, top and bottom.
     Below 680 that is 1rem + 2x1rem = 3rem (zara.css:263-264); from 681 to 1279
     it is 1.5rem + 2x1.1rem = 3.7rem (zara.css:79-80). It was written as a flat
     48px, i.e. the <=680 case, so it under-reported the bar by 11.2px across the
     whole tablet band. That never showed while it only fed --chrome-clear, whose
     max() against clamp(12rem,17vw,15.5rem) wins there at every width — but the
     v21 hero now pins the film to this variable, and 11px of stray video above
     the bar is visible. Corrected below; --chrome-clear is unchanged at 192px. */
  --chrome-h:calc(var(--brand-w-sm) / var(--brand-ar) + 3rem);
  --chrome-clear:max(clamp(12rem,17vw,15.5rem), calc(var(--chrome-h) + 4.5rem));
}
.site-header .brand{
  background-image:var(--brand-src);
  aspect-ratio:var(--brand-ar);height:auto;
  width:var(--brand-w-sm)}
@media (max-width:1279px){
  /* space-between already parks the two at opposite ends — this gap is only the
     minimum between them, and 2rem of it is width the logo could be using */
  .site-header .nav-row{column-gap:1rem}
}
/* the tablet band pays 1.5rem of header offset and 1.1rem of bar padding, not the
   1rem/1rem the base assumes — see the --chrome-h note above */
@media (min-width:681px) and (max-width:1279px){
  :root{--chrome-h:calc(var(--brand-w-sm) / var(--brand-ar) + 3.7rem)}
}
@media (min-width:1280px){
  :root{
    /* THE MARK'S CEILING, re-derived 2026-08-05 for the one-row grid. In
       `1fr auto 1fr` the two side tracks are equal, so the mark's real ceiling is
       the width of a side track — overflow it and the grid pushes past the glass:
           track = (100vw − padding×2 − menu − nav-gap×2) ÷ 2
       Padding is clamp(1.5rem,4vw,3.5rem): 4vw until it caps at 56px at 1400,
       hence the first band carries 92vw and the rest 100vw. Menu widths are
       measured with tools/measure-navfit.mjs, not guessed.
       ⚠ EACH BAND IS PINNED AT ITS NARROW END, where the box is tightest, so the
       constant runs generous towards the band's wide end (the menu grows with the
       vw-driven type while the constant does not). Deliberate: its only jobs are to
       report a real ceiling to the tuner and to stop a hand-raised --brand-w
       bursting the bar.
       ⚠ AT 1280 IT LANDS ON ~300px, i.e. ON --brand-w, and that is not a mistake —
       it is the same fact the fit budget states from the other side. The mark IS
       the binding flank at that width and the bar is genuinely full, so the true
       ceiling and the actual width coincide. Verified rendering at exactly 300 /
       330 from 1280 to 2560 by tools/verify-navnew.mjs; if a future change makes
       this dip under --brand-w the lockup will silently shrink, which is the one
       thing George ruled out. Re-measure rather than nudging the constant. */
    --brand-max:calc((92vw - 608px) / 2);   /* 1280-1399 · menu 555 + 2x27 gap, pad 4vw */
    /* THE BAR IS ONE ROW NOW, so its height is simply the tallest thing in it plus
       the row's own padding — and the tallest thing is always the lockup (82.8px at
       330, 75.3px at 300, 69.7px at 278; the buttons are 42). So the bar now steps
       with the mark across three bands — 101.7px below 1400, 107.3px to 1511,
       114.8px above — against the two-row bar's fixed 143px. The 74px floor is the
       buttons' own row height (42 + 2x16) and only bites if the mark is tuned far
       down. --nav-line1 is GONE with the second row; scale.css §5 already notes it
       was retired as a lever.
       ⚠ Three heights means --chrome-clear is re-derived three times (scale.css §2
       floors it at --chrome-h + 1.5rem). Verified: zero drift between this variable
       and the bar's real bottom, and a seamless film edge on the v21 hero, at 1280 /
       1366 / 1440 / 1920 on the homepage, a service page and /about. */
    --chrome-h:max(74px, calc(min(var(--brand-w), var(--brand-max)) / var(--brand-ar) + var(--nav-padv) * 2));
  }
  /* position:static undoes v18 round 10, which pulled the mark out of the flow and
     absolutely centred it across both rows. It is a grid item now. */
  .site-header .nav-row .brand{position:static;transform:none;top:auto;
    width:min(var(--brand-w), var(--brand-max));height:auto}
}
/* From 1400 the bar's padding stops growing (clamp caps at 3.5rem):
   (100vw − 112 pad − 600 menu − 2x29 gap) ÷ 2. */
@media (min-width:1400px){ :root{--brand-max:calc((100vw - 771px) / 2)} }
/* From 1512 the menu steps up with the mark (13.16px → 13.43px and climbing) and
   measures 650 with its gaps: (100vw − 112 pad − 650 menu − 2x32 gap) ÷ 2. */
@media (min-width:1512px){ :root{--brand-max:calc((100vw - 826px) / 2)} }
/* client image 2026-07-28: in the 1280-1511 band the mark steps down WITH the type —
   330 × .909 (the same ratio as the menu's .95→.86 step) = the 300px her mock
   measures at 1440. Sits AFTER the base :root so the band value wins the cascade. */
@media (min-width:1280px) and (max-width:1511px){ :root{--brand-w:300px} }
/* 🔴 THE NARROW END OF THAT BAND PAYS FOR THE TYPE, 2026-08-05. --nav-fs now has a
   12px FLOOR (§ the band rule above): the fluid value wants 10.92px at 1280, and at
   that size uppercase menu labels with letter-spacing stop being legible — the live
   site set 13.76px here, so 10.92 is not "a bit smaller", it is a different order.
   The floor costs the menu ~52px it does not have at 1280, and the money has to come
   from somewhere. It comes from the mark, 300 → 278, which is the same banding this
   file already does at 1400 and 1512, NOT a new idea and not a contradiction of
   "the logo stays the same size" — that instruction was about not shrinking the mark
   to make room for the new layout in general. 300px is untouched from 1400 and 330px
   from 1512, which is every width the client actually reviews on.
   --nav-mgap drops to its 10px floor in the same band for the same reason: spending
   13.4px x 4 inside the menu at the one width that has nothing to spare would eat the
   between-group gaps, and those gaps are the entire point of this layout. */
@media (min-width:1280px) and (max-width:1399px){
  /* 278px, not a round number: it is what the ACTIONS group measures once the buttons
     are trimmed here, and matching the two flanks exactly is what makes the two gaps
     equal as well as the menu centred. The grid centres the menu either way; equal
     flanks are what stop the eye reading one side as tighter than the other. */
  :root{--brand-w:278px;--nav-mgap:10px;--nav-btnpad:.8rem;--nav-btnfs:.8rem}
}

/* ============================================================================
   §4 · CERTIFICATION BAND — the Bureau Veritas ISO/IEC 27001 mark, site-wide,
   sitting immediately above the footer on 38 pages.

   ⚠ EVERY VALUE HERE IS CONTRACTUAL AND IS CHECKED DURING BUREAU VERITAS AUDITS.
   The full guide is docs/brand/bureau-veritas/README.md; read it before changing
   anything here. The four rules that shape this CSS:

     · THE BADGE RENDERS AT 200px (250 maximum). The SVG canvas carries BV's
       required protective field, so width:240px on the file puts the badge itself
       at exactly 200. Do not shrink it, and do not let a narrow container squeeze
       it — hence flex:0 0 auto.
     · THE STATEMENT MUST NOT BE SEPARATED FROM THE LOGO. The mark and the sentence
       are ONE row and have to stay one row at every width. Never move the text to
       another column, another section, or behind a toggle.
     · THREE COLOURS ONLY: #00049E blue, #706F6F grey. No recolouring to Zara
       cobalt, no greyscale, no reduced opacity. This is why the band is WHITE and
       sits ABOVE the navy footer rather than inside it: on navy the mark cannot
       legally be adapted, and BV's supplied mono file is black on transparent, so
       it is no use there either.
     · THE MARK CERTIFIES THE MANAGEMENT SYSTEM, NOT THE SERVICES. The wording in
       the markup is BV's own approved sentence. Never reword it to "our services
       are ISO certified".

   ⚠ SCOPE. The certificate covers accounting, business consulting, company
   incorporation, tax planning and payroll. It does NOT cover registered address,
   legal services or audit, so the band is deliberately ABSENT from
   /services/registered-address. Do not "complete the set" by adding it there.
   ⚠ /about and the homepage do not carry the band either: both already show the
   mark in a richer, contextual block, and BV's size rule makes a second one on the
   same page read as a repeat.
   ============================================================================ */
.certband{background:var(--paper);border-top:1px solid var(--line);
  padding-block:clamp(2rem,4vw,3rem)}
.certband-in{display:flex;flex-wrap:wrap;align-items:center;
  gap:clamp(1.4rem,3vw,2.6rem)}
.certband-mark{width:240px;max-width:100%;height:auto;display:block;flex:0 0 auto}
.certband-txt{flex:1 1 22rem;min-width:0}
.certband-txt p{margin:0;font-family:var(--sans);font-weight:300;color:var(--blue);
  font-size:1.0625rem;line-height:1.65;max-width:58ch}
.certband-txt p + p{margin-top:.7rem;font-size:.95rem}
.certband-txt a{color:var(--blue);border-bottom:1px solid var(--line);padding-bottom:1px}
.certband-txt a:hover{border-color:var(--blue)}
.certband-txt .sep{margin:0 .5rem}

/* ── LANGUAGE MENU (2026-09-29, George) ─────────────────────────────────────
   The EN control opens a panel again. English is the only language at launch, so the other
   three are printed as coming and are NOT links: a dead link in the bar is what was removed
   in the launch round. The bridge keeps the panel open while the pointer crosses the gap. */
.site-header .lang-menu{min-width:190px}
.site-header .lang-menu::before{content:"";position:absolute;left:0;right:0;top:-.8rem;height:.8rem}
.site-header .lang-opt{display:flex;align-items:baseline;justify-content:space-between;gap:1.2rem;
  padding:.6rem 1.1rem;font-family:var(--sans);font-size:.95rem;line-height:1.3;color:var(--blue);white-space:nowrap}
.site-header .lang-opt.active{font-weight:600}
.site-header .lang-opt.soon{color:#414E67;cursor:default}
.site-header .lang-opt i{font-style:normal;font-size:.72rem;letter-spacing:.08em;text-transform:uppercase;color:#414E67}
/* 2026-10-05: Bulgarian is live, so the other language is a link. Below 1280 the globe menu is
   hidden and the panel carries the same switch as a plain link under the two buttons. */
.site-header a.lang-opt:hover,.site-header a.lang-opt:focus-visible{background:var(--wash,#F2F2F3)}
.site-header .lang-m{display:none}
@media (max-width:1279px){
  .site-header .nav-actions .lang-m{display:block;align-self:center;margin-top:.35rem;padding:.4rem .6rem;
    font-family:var(--sans);font-size:.95rem;color:var(--blue);border-bottom:1px solid rgba(1,30,147,.3)}
}

/* ── 5 · PAGE TRANSITIONS (client call 2026-09-29) ───────────────────────────
   Osmo's "overlapping parallax": the new page slides up from the bottom over the old one,
   which drifts up 25vh and darkens to 80% black, 1.2s on the Osmo ease (0.625,.05,0,1).
   Built on native cross-document view transitions, NOT Barba: every page here is its own
   HTML file with its own stylesheets and scripts, which a container swap would break.
   Chrome, Edge and Safari 18.2+ animate; other browsers simply load the page.
   The header and the mobile dock are named, so they stay put while the pages move under
   them (Osmo's "navigation outside the container"). Reduced motion gets no transition.
   ⚠ The names apply only while a transition runs: a named element is a backdrop root, so a
   permanent name left the glass blurring nothing and the bars read as plain tint (2026-10-01). */
/* The opt-in, @view-transition{navigation:auto}, is inline in every <head> (tools/sync-transition.mjs). */
@media (prefers-reduced-motion:reduce){
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}
}
:active-view-transition .site-header{view-transition-name:zara-header}
:active-view-transition .glass-dock{view-transition-name:zara-dock}
::view-transition-old(root),::view-transition-new(root){mix-blend-mode:normal;
  animation-duration:1.2s;animation-timing-function:cubic-bezier(.625,.05,0,1);animation-fill-mode:both}
::view-transition-old(root){animation-name:zara-page-leave}
::view-transition-new(root){animation-name:zara-page-enter}
@keyframes zara-page-leave{from{transform:none;filter:brightness(1)}to{transform:translateY(-25vh);filter:brightness(.2)}}
@keyframes zara-page-enter{from{transform:translateY(100vh)}to{transform:none}}
/* The fallback (2026-09-30). Some Chromium browsers support all of the above but decline it
   between pages (T3's built-in browser did on every click; George saw one transition in his).
   There the new page opens under a black cover and a same-page transition slides it up with
   the same keyframes: the starter is stamped into every <head> by tools/sync-transition.mjs.
   Once a browser has declined, site-runtime.js also lifts and darkens the old page over the
   cover before it navigates (.zt-leaving), so the two halves meet on the same black frame. */
html.zt-cover::after{content:"";position:fixed;inset:0;z-index:49;background:#000}
html.zt-leaving::view-transition-old(root){z-index:1;animation-duration:.6s}
html.zt-leaving::view-transition-new(root){animation:none}

/* ── 6 · BUTTON 016 (Osmo), on every button (client call 2026-09-29) ─────────
   The label rolls up out of the button and the same label rolls in from below while the
   colours change. site-runtime.js wraps each label in .b16 once; the incoming copy is the
   ::after, drawn from data-b16, so the words exist once in the DOM and are read once.
   Each button keeps its own hover colours (red deepens, ghosts invert); 016 supplies the
   motion and its two eases. The clip is the label's box grown by .5em top and bottom, so
   the label travels through most of the button as in 016, and it works at any button size
   and on wrapped labels. ⚠ Every button's own vertical padding must stay above .5em of its
   font size, or the rolling label shows outside the button (all of them do, 2026-09-29).
   Only for a fine pointer that can hover, and never under reduced motion. */
:root{--b16-ease:cubic-bezier(.785,.135,.15,.86)}
.btn,.dock-btn,.cs-wa,.cs-book{transition:background-color .325s var(--b16-ease),
  color .325s var(--b16-ease),border-color .325s var(--b16-ease),opacity .25s ease}
.b16{display:inline-grid;overflow:clip;padding:.5em .08em;margin:-.5em -.08em;min-width:0}
.b16>span,.b16::after{grid-area:1/1;transition:translate .3s var(--b16-ease)}
.b16::after{content:attr(data-b16);content:attr(data-b16) / "";translate:0 calc(100% + .75em)}
@media (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
  :is(.btn,.dock-btn,.cs-wa,.cs-book):not(:disabled):is(:hover,:focus-visible) .b16>span{translate:0 calc(-100% - .75em)}
  :is(.btn,.dock-btn,.cs-wa,.cs-book):not(:disabled):is(:hover,:focus-visible) .b16::after{translate:0 0}
}
/* 016's colour swap (2026-09-30, George: the hover did not read). The red call to action
   turns cobalt, the blue of the contact tab beside it (2026-10-06, George: navy read as a
   second blue), or white where it sits on navy (site-runtime.js marks those .b16-dark). The
   cobalt inquiry button in the contact panel darkens to navy. Ghost buttons already invert.
   Colour is not motion, so this half stays under reduced motion. */
@media (hover:hover) and (pointer:fine){
  :is(.btn-primary,.dock-btn.primary,.btn-red):not(:disabled):is(:hover,:focus-visible){
    background-color:var(--blue,#011E93);border-color:var(--blue,#011E93);color:#fff}
  .b16-dark:is(.btn-primary,.btn-red):not(:disabled):is(:hover,:focus-visible){
    background-color:#fff;border-color:#fff;color:var(--navy,#0D1F3C)}
  .cs-book:is(:hover,:focus-visible){background-color:var(--navy,#0D1F3C)}
}
