/* ── site.css — the site's type, header and shared tokens ───────────────────
   The last shared layer: loaded after components.css, base.css, theme.css (and
   shop / page-blocks / inner-pages where a page uses them), then footer.css and
   the page's own CSS come after it. It sets:
     • the type: Manrope for the words and the UI, Newsreader (regular, italic for
       emphasis) for headlines and big numbers, JetBrains Mono for data (tags,
       readings, step numbers).
     • the header, with its search, the cart text, and the landing's three buttons
       under it (application/views/partials/header.php).
     • the tokens and section rhythm the homepage sections share (_dev/DESIGN.md). */

:root {
  /* type: the text face, the display face and JetBrains Mono (_dev/DESIGN.md) */
  --font: 'Manrope', 'Noto Sans Devanagari', 'Noto Sans Gujarati', 'Segoe UI', Arial, sans-serif;
  --display: 'Newsreader', Georgia, 'Times New Roman', serif;
  --serif: var(--display);
  --mono: 'JetBrains Mono', ui-monospace, Consolas, monospace;

  /* brand (Brand Guidelines): navy is the strong colour, gold the accent. Navy text on gold, never white on gold;
     never gold text on white (use --gold-ink). */
  --navy: #00396C; --navy-2: #0A4A85; --navy-deep: #002A50; --slate: #5D7E9B; --mist: #BACEDF;
  --gold: #F7B744; --gold-60: #FFD487; --gold-30: #FDE9C7; --gold-ink: #8C5E0E;
  --charcoal: #333333; --grey: #F1F1F1; --white: #FFFFFF;
  --page: #F4F6F9; --card: #FFFFFF; --line: #E2E8F0; --text: #2A3A4C; --muted: #5B6C80;

  /* spacing: a compact 4-based scale */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;
  /* layout + rhythm. Round three (owner: "the spacing between sections is a bit too little, it feels a bit fast"):
     the step between sections is about 1.5x round two's on a laptop (86px at 1366 x 900, 80px at 1366 x 768, was
     58/50) and a little more on phones (64px, was 53). Part width, part height, so a short laptop screen no longer
     squeezes it. On the homepage every section-to-section step is this one gap (the sections' own CSS). */
  --s7-max: 1240px;                                /* container width */
  --s7-gutter: clamp(16px, 4vw, 48px);             /* side room; 16px on phones */
  --s7-sec: clamp(64px, 3.4vw + 4.4vh, 116px);     /* a section's top and bottom padding: the step between sections */
  --s7-sec-sm: clamp(40px, 2vw + 2.8vh, 72px);     /* .s7-sec.tight, and the shorter steps (52px at 1366 x 900) */
  --s7-head-gap: clamp(20px, 2.4vw, 32px);         /* under a section head */
  --r-card: 20px; --r-panel: 28px;

  /* the header stack (see the header block below); shell.js measures the buttons into --s7-cta-h (their height)
     and --s7-cta-w (the room they take from the screen's right edge). These are the values before it has run:
     three 38px pills with 6px between them, about 262px wide with the 36px side inset. */
  --s7-nav-top: 22px; --s7-nav-h: 56px; --s7-cta-gap: 10px; --s7-cta-row: 38px; --s7-cta-step: 6px;
  --s7-cta-h: calc(3 * var(--s7-cta-row) + 2 * var(--s7-cta-step)); --s7-cta-w: 262px;
}
/* --s7-top: from the top of the screen to the bottom of the header stack, which the hero clears.
   --s7-bar: to the bottom of the header row alone (logo, pill, cart); the three buttons hang below it at the right only.
   Declared on body (not :root) so the measured --s7-cta-h and the inner-page zeroes below feed into it. */
body { --s7-top: calc(var(--s7-nav-top) + var(--s7-nav-h) + var(--s7-cta-gap) + var(--s7-cta-h)); --s7-bar: calc(var(--s7-nav-top) + var(--s7-nav-h)); }
body:not([data-page="home"]) { --s7-cta-gap: 0px; --s7-cta-h: 0px; --s7-cta-w: 0px; }   /* inner pages: the header alone */

/* ── type, site-wide ──
   theme.css sets headings with the `font:` shorthand in Plus Jakarta Sans 700; here
   h1 and h2 are Newsreader 400. (Specificity 0,1,2: a section can still change them with a
   two-class selector, or keep a heading in Manrope with class="s7-sans".) */
:where(button, input, select, textarea) { font-family: inherit; }   /* icon-only buttons fell back to Arial */
body.s6-body :is(h1, h2):where(:not(.s7-sans)) { font-family: var(--display); font-weight: 400; letter-spacing: -.018em; }
body.s6-body :is(h1, h2) :is(b, strong) { font-weight: 500; }
body.s6-body :is(h1, h2) em { font-family: var(--display); font-style: italic; }
.flow-head h1 em, .page-hero h1 em { font-family: var(--display) !important; font-style: italic !important; font-weight: 400 !important; }   /* shop.css had forced these upright in the sans */
/* Hindi, Marathi, Gujarati (the Academy's language switch sets <html lang>): Newsreader has no Devanagari or Gujarati
   letters, so they fell to a thin system face. Anything in --display now falls back to Noto Sans (academy.html loads
   it), and h1/h2 take --font (Manrope + Noto) at 600; no italics in these scripts. */
html:is(:lang(hi), :lang(mr), :lang(gu)) { --display: 'Newsreader', 'Noto Sans Devanagari', 'Noto Sans Gujarati', Georgia, serif; }
html:is(:lang(hi), :lang(mr), :lang(gu)) body.s6-body :is(h1, h2):where(:not(.s7-sans)) { font-family: var(--font); font-weight: 600; letter-spacing: -.01em; }
html:is(:lang(hi), :lang(mr), :lang(gu)) body.s6-body :is(h1, h2) em { font-family: var(--font) !important; font-style: normal !important; font-weight: inherit !important; }
html:is(:lang(hi), :lang(mr), :lang(gu)) :is(.s6-eyebrow, .kicker, .s7-eyebrow) { letter-spacing: .02em; }   /* wide caps tracking pulled the letters of these scripts apart */
.s6-eyebrow, .kicker { font-family: var(--font); font-weight: 700; letter-spacing: .22em; }   /* the kicker: Manrope 700, wide caps */

/* the section kit (homepage sections use these; _dev/DESIGN.md) */
.s7-wrap { width: min(var(--s7-max), 100% - 2 * var(--s7-gutter)); margin-inline: auto; }
.s7-sec { position: relative; padding-block: var(--s7-sec); }
.s7-sec.tight { padding-block: var(--s7-sec-sm); }
.s7-head { display: grid; gap: var(--sp-3); margin-bottom: var(--s7-head-gap); max-width: 760px; }
.s7-head.center { margin-inline: auto; justify-items: center; text-align: center; }
.s7-eyebrow { margin: 0; font: 700 12px/1 var(--font); letter-spacing: .22em; text-transform: uppercase; color: var(--gold-ink); }
.s7-h1 { margin: 0; font: 400 clamp(40px, 5.6vw, 84px)/1 var(--display); letter-spacing: -.02em; color: var(--navy); text-wrap: balance; }
.s7-h2 { margin: 0; font: 400 clamp(32px, 3.9vw, 58px)/1.04 var(--display); letter-spacing: -.02em; color: var(--navy); text-wrap: balance; }
.s7-h3 { margin: 0; font: 700 clamp(16px, 1.25vw, 19px)/1.3 var(--font); letter-spacing: -.005em; color: var(--navy); }
:is(.s7-h1, .s7-h2) em { font-style: italic; }
:is(.s7-h1, .s7-h2) .mut { color: var(--slate); }
.s7-lede { margin: 0; max-width: 62ch; font: 500 clamp(15px, 1.15vw, 18px)/1.6 var(--font); color: var(--muted); }
.s7-num { font: 400 clamp(30px, 3vw, 44px)/1 var(--display); letter-spacing: -.02em; color: var(--navy); }
.s7-mono { font: 500 11.5px/1.3 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--slate); }
/* a navy panel: white headings, gold eyebrow, mist text */
.s7-dark { background: var(--navy-deep); color: #D5E1EE; }
.s7-dark :is(.s7-h1, .s7-h2, .s7-h3, .s7-num) { color: #fff; }
.s7-dark .s7-eyebrow { color: var(--gold); }
.s7-dark .s7-lede { color: #A9BDD1; }
.s7-dark .s7-mono { color: var(--mist); }

/* ── the header ──
   header.nav is application/views/partials/header.php: logo · glass pill (Home, Commercial, Residential, Platform ▾,
   and the search at its end) · at the far right "Sign up / Log in", then the glowing "Cart 0" last.
   Default is the light glass (navy type); over anything marked data-tone="dark" it goes white-on-glass (.on-dark). */
body.s6-body .nav {
  top: var(--s7-nav-top); height: var(--s7-nav-h); padding: 0 36px; gap: 14px;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); transition: top 300ms var(--ease);
}
body.s6-body .nav.scrolled { top: 12px; }
/* the logo: 13% smaller than round one's 138px (owner's round two, item 4), at every width (see the media queries) */
body.s6-body .nav .logo { width: 120px; position: relative; }
body.s6-body .nav .logo img { height: auto; }
/* the pill sits above the landing's three buttons (its backdrop-filter makes it a stacking context of its own,
   so without a z-index the Platform menu and the search results painted UNDER "Book a service") */
body.s6-body .nav .pill {
  position: relative; z-index: 2;
  gap: 4px; padding: 5px; background: rgba(255, 255, 255, .78); border: 1px solid rgba(0, 57, 108, .1); box-shadow: none;
  -webkit-backdrop-filter: blur(18px) saturate(150%); backdrop-filter: blur(18px) saturate(150%); transition: background 300ms ease, border-color 300ms ease;
}
/* at the top of the page the header has no bar. Once scrolled, the glass gets thicker so the page's words
   don't read through it, and the logo gets a small chip of the same glass (it no longer sits bare on eyebrows and
   headlines). On phones theme.css puts the whole header on a frosted strip instead. */
body.s6-body .nav.scrolled .pill { background: rgba(255, 255, 255, .9); }
body.s6-body .nav .logo::before {
  content: ""; position: absolute; inset: -11px -18px; z-index: -1; border-radius: 999px; pointer-events: none; opacity: 0;
  background: rgba(255, 255, 255, .9); border: 1px solid rgba(0, 57, 108, .1);
  -webkit-backdrop-filter: blur(18px) saturate(150%); backdrop-filter: blur(18px) saturate(150%); transition: opacity 300ms ease, background 300ms ease, border-color 300ms ease;
}
@media (min-width: 941px) { body.s6-body .nav.scrolled .logo::before { opacity: 1; } }
body.s6-body .nav .pill > a { font: 600 14px/1 var(--font); padding: 11px 16px; color: var(--navy); }
body.s6-body .nav .more > button { gap: 4px; font: 600 14px/1 var(--font); padding: 11px 14px; color: var(--navy); }
body.s6-body .nav .pill > a:hover, body.s6-body .nav .more > button:hover, body.s6-body .nav .more > button[aria-expanded="true"],
body.s6-body .nav .pill > a[aria-current="page"], body.s6-body .nav .more > button[aria-current="page"] { background: rgba(0, 57, 108, .07); color: var(--navy); }
body.s6-body .more-menu { top: calc(100% + 12px); right: -6px; width: 280px; border-radius: 20px; }
/* the search, sized to the pill's own buttons so the pill keeps its height */
body.s6-body .nav .srch-btn { width: 36px; height: 36px; }
body.s6-body .nav .srch-in { height: 36px; }
body.s6-body .nav.searching .srch-in { width: clamp(150px, 15vw, 240px); }
/* over dark */
body.s6-body .nav.on-dark .pill { background: rgba(255, 255, 255, .14); border-color: rgba(255, 255, 255, .22); }
body.s6-body .nav.on-dark .pill > a, body.s6-body .nav.on-dark .more > button { color: #fff; }
body.s6-body .nav.on-dark .pill > a:hover, body.s6-body .nav.on-dark .more > button:hover, body.s6-body .nav.on-dark .more > button[aria-expanded="true"],
body.s6-body .nav.on-dark .pill > a[aria-current="page"], body.s6-body .nav.on-dark .more > button[aria-current="page"] { background: rgba(255, 255, 255, .18); color: #fff; }
/* scrolled over dark, the glass is navy-tinted: white type never sits bare on a bright patch (snow, a panel's edge) */
body.s6-body .nav.scrolled.on-dark :is(.pill, .s7-acct), body.s6-body .nav.scrolled.on-dark .logo::before { background: rgba(0, 42, 80, .56); border-color: rgba(255, 255, 255, .18); }
body.s6-body .nav.scrolled.on-dark .icon-btn { background: rgba(0, 42, 80, .56) !important; }

/* ── each item's own colour on hover and keyboard focus (owner's round two, item 24) ──
   shell.js gives every header item a data-f key, so the colours are theme.css's feature colours exactly (--c main,
   --cd dark, --ct tint): Commercial blue, Residential yellow, IoT & AI its gradient; in the Platform menu providers
   green, suppliers orange, OEMs violet, technicians and the Academy turquoise. Home, Platform, the search, Contact and
   the staff sign-in are the brand's navy and gold ('brand', below).
   On the pill the hover is a solid chip of the colour, with text that passes WCAG AA on it (14px, so 4.5:1):
   Commercial white on #2F6FEB 4.6:1 · Residential navy on #F5A524 5.7:1 · brand gold on navy 6.6:1 ·
   IoT & AI near-black on the gradient 5.3:1 or better wherever the letters sit (the violet end, 3.6:1, lies under
   the chip's padding only). It shows the same way over the dark hero and over light pages. The menus' rows carry two
   lines and violet passes with neither white nor black, so there the colour is a tint, the name in its dark shade
   (5.7–10:1) and a bar of the full colour (components.css). */
.nav [data-f="brand"], .menu-sheet [data-f="brand"] { --c: #00396C; --c2: #F7B744; --cd: #00396C; --ct: #EEF3F8; --bar: #F7B744; }
body.s6-body .nav :is(.pill > a, .more > button, .srch-btn)[data-f] { --hc-bg: var(--c); --hc-ink: #0B1B2B; }
body.s6-body .nav :is(.pill > a, .more > button, .srch-btn)[data-f="brand"] { --hc-ink: var(--gold); }
body.s6-body .nav .pill > a[data-f="commercial"] { --hc-ink: #fff; }
body.s6-body .nav .pill > a[data-f="residential"] { --hc-ink: var(--navy); }
body.s6-body .nav .pill > a[data-f="iot"] { --hc-bg: #00396C; --hc-ink: #fff; }   /* the navy under its neon blobs (below) */
body.s6-body .nav .pill > a[data-f="iot"]:is(:hover, :focus-visible) { box-shadow: inset 0 0 0 1.5px rgba(247, 183, 68, .7); }
body.s6-body .nav :is(.pill > a, .more > button, .srch-btn)[data-f]:is(:hover, :focus-visible),
body.s6-body .nav .more > button[data-f][aria-expanded="true"] { background: var(--hc-bg); color: var(--hc-ink); }
/* IoT & AI: coloured blobs floating in the chip (owner, 29 Sep: the still gradient "looks low effort, it should be
   animated like blobs floating in it"). On a lavender base, three soft round blobs in IoT's violet, cyan and magenta
   drift behind the name, each on its own slow path: its x and its y each swing there and back on their own period
   (10 to 14 s a round trip), so the six together never visibly repeat. A still gloss sits over them (the top half
   catches a little light, a hairline highlight on the top edge). The blobs are ::before, the gloss ::after, both
   clipped to the chip's rounded shape and behind the text (isolation, z-index -1), so the keyboard ring is untouched.
   Contrast: the blob colours are IoT's own, lifted a little towards white where the violet was too dark (#7C4DFF
   would be 3.9:1 under the name), so the deep indigo name passes AA on every mix of them: 5.4:1 at the violet's core
   and more everywhere else, at every frame measured over 15 s, over the hero and over light pages alike (the chip
   is opaque). Cost: the drift only runs while the tab is hovered or has keyboard focus; at rest it is paused and
   hidden, so nothing ticks. Reduced motion: no drift, the blobs stay in the arrangement they start from.
   The phone menu's IoT & AI row gets the same blobs, in pastels under its violet name (5.7:1 or better; its tint and
   bar stay). */
@property --s7-b1x { syntax: '<percentage>'; inherits: false; initial-value: 18%; }
@property --s7-b1y { syntax: '<percentage>'; inherits: false; initial-value: 64%; }
@property --s7-b2x { syntax: '<percentage>'; inherits: false; initial-value: 80%; }
@property --s7-b2y { syntax: '<percentage>'; inherits: false; initial-value: 22%; }
@property --s7-b3x { syntax: '<percentage>'; inherits: false; initial-value: 104%; }
@property --s7-b3y { syntax: '<percentage>'; inherits: false; initial-value: 92%; }
@keyframes s7-b1x { to { --s7-b1x: 62%; } }
@keyframes s7-b1y { to { --s7-b1y: 24%; } }
@keyframes s7-b2x { to { --s7-b2x: 30%; } }
@keyframes s7-b2y { to { --s7-b2y: 82%; } }
@keyframes s7-b3x { to { --s7-b3x: 54%; } }
@keyframes s7-b3y { to { --s7-b3y: 18%; } }
body.s6-body .nav .pill > a[data-f="iot"], body.s6-body .menu-sheet nav a[data-f="iot"] { position: relative; isolation: isolate; }
body.s6-body .nav .pill > a[data-f="iot"]::before, body.s6-body .menu-sheet nav a[data-f="iot"]::after {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; opacity: 0;
  --s7-b1x: 18%; --s7-b1y: 64%; --s7-b2x: 80%; --s7-b2y: 22%; --s7-b3x: 104%; --s7-b3y: 92%;   /* the still arrangement */
  background:
    radial-gradient(var(--s7-br3, 46% 98%) at var(--s7-b3x) var(--s7-b3y), var(--s7-bm), color-mix(in srgb, var(--s7-bm) 62%, transparent) 42%, transparent),
    radial-gradient(var(--s7-br2, 48% 104%) at var(--s7-b2x) var(--s7-b2y), var(--s7-bc), color-mix(in srgb, var(--s7-bc) 62%, transparent) 42%, transparent),
    radial-gradient(var(--s7-br1, 58% 124%) at var(--s7-b1x) var(--s7-b1y), var(--s7-bv), color-mix(in srgb, var(--s7-bv) 62%, transparent) 46%, transparent);
  animation: s7-b1x 6.6s, s7-b1y 5.1s, s7-b2x 7s, s7-b2y 5.6s, s7-b3x 5.4s, s7-b3y 6.8s;
  animation-timing-function: ease-in-out; animation-iteration-count: infinite; animation-direction: alternate; animation-play-state: paused;
  transition: opacity 260ms ease;
}
body.s6-body .nav .pill > a[data-f="iot"]::before { --s7-bv: rgba(247, 183, 68, .42); --s7-bc: rgba(186, 206, 223, .4); --s7-bm: rgba(255, 212, 135, .38); }   /* gold, ice, light gold, dimmed so the white name stays 4.5:1+ */
body.s6-body .nav .pill > a[data-f="iot"]::after {   /* the gloss */
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; opacity: 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, .26), rgba(255, 255, 255, .06) 46%, rgba(255, 255, 255, 0) 58%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .55), inset 0 -1px 0 rgba(0, 20, 40, .3);
  transition: opacity 260ms ease;
}
body.s6-body .nav .pill > a[data-f="iot"]:is(:hover, :focus-visible)::before,
body.s6-body .menu-sheet nav a[data-f="iot"]:is(:hover, :focus-visible, :active)::after { opacity: 1; animation-play-state: running; }
body.s6-body .nav .pill > a[data-f="iot"]:is(:hover, :focus-visible)::after { opacity: 1; }
body.s6-body .menu-sheet nav a[data-f="iot"]::after { --s7-bv: #FFE3A6; --s7-bc: #DCE7F1; --s7-bm: #FFF1D2; --s7-br1: 30% 110%; --s7-br2: 26% 100%; --s7-br3: 24% 96%; }
html.fx-reduce body.s6-body .nav .pill > a[data-f="iot"]::before, html.fx-reduce body.s6-body .menu-sheet nav a[data-f="iot"]::after { animation: none; }
/* over dark ground (the hero sky, the navy bands) a navy chip is navy on navy and all but vanished, so the brand items
   (Home, Platform, the search) wear the navy and gold the other way round there: a lifted navy chip with a gold
   ring and gold text (5.1:1). Not a solid gold chip: that read as Residential's yellow one. */
body.s6-body .nav.on-dark :is(.pill > a, .more > button, .srch-btn)[data-f="brand"]:is(:hover, :focus-visible),
body.s6-body .nav.on-dark .more > button[data-f="brand"][aria-expanded="true"] { background: var(--navy-2); color: var(--gold); box-shadow: inset 0 0 0 1.5px var(--gold); }
/* the page you are on, over light ground: its tab rests in the colour's tint with its dark text (Commercial pale blue
   on commercial.html, and so on); over the dark hero it keeps the white wash. Hovering it still shows the solid chip. */
body.s6-body .nav:not(.on-dark) :is(.pill > a, .more > button)[data-f][aria-current="page"]:not(:hover, :focus-visible, [aria-expanded="true"]) { background: var(--ct); color: var(--cd); }
/* the keyboard ring: over light ground a navy ring (the site-wide gold one is under 2:1 on white and all but vanished
   around the yellow chip); over dark it stays gold. The menus' rows get the same navy ring, just inside the row. */
body.s6-body .nav:not(.on-dark) :is(.pill > a, .more > button, .srch-btn):focus-visible { outline: 2px solid var(--navy) !important; outline-offset: 2px; }
body.s6-body :is(.more-menu, .menu-sheet nav) a:focus-visible { outline: 2px solid var(--navy) !important; outline-offset: -2px; }

/* the far right: "Sign up / Log in", then #cart (its glow) last, at the very edge (owner's brief).
   On the dark hero it glows; on light pages the same type in navy. Once the page is scrolled
   the pair sits on the pill's glass, so it stays readable over whatever passes under it. */
body.s6-body .nav .s7-acct {
  justify-self: end; display: flex; align-items: center; gap: 26px; height: 46px; padding: 0 16px; margin-right: -16px;
  border-radius: 999px; border: 1px solid transparent; transition: background 300ms ease, border-color 300ms ease;
}
.s7-glow {
  appearance: none; border: 0; background: none; padding: 8px 4px; cursor: pointer; text-decoration: none; white-space: nowrap;
  font: 600 13px/1 var(--font); letter-spacing: .12em; text-transform: uppercase;
  color: rgba(0, 57, 108, .88); text-shadow: 0 0 10px rgba(93, 126, 155, .28);
  transition: color 250ms ease, text-shadow 250ms ease;
}
.s7-glow:hover { color: var(--gold-ink); text-shadow: 0 0 14px rgba(247, 183, 68, .55), 0 0 2px rgba(247, 183, 68, .4); }
.s7-glow .count { margin-left: 4px; color: var(--gold-ink); }
.s7-glow:focus-visible { outline: 2px solid var(--navy) !important; outline-offset: 3px; border-radius: 4px; }   /* navy on the light glass (a gold ring there is under 2:1), gold on dark */
.nav.on-dark .s7-glow:focus-visible { outline-color: var(--gold) !important; }
.nav.on-dark .s7-glow { color: rgba(241, 241, 241, .78); text-shadow: 0 0 10px rgba(186, 206, 223, .35), 0 1px 8px rgba(2, 12, 23, .3); }   /* + a faint dark halo for bright snow */
.nav.on-dark .s7-glow:hover { color: var(--gold-60); text-shadow: 0 0 14px rgba(247, 183, 68, .65), 0 0 2px rgba(247, 183, 68, .5); }
.nav.on-dark .s7-glow .count { color: var(--gold-60); }
body.s6-body .nav.scrolled .s7-acct { background: rgba(255, 255, 255, .92); border-color: rgba(0, 57, 108, .1); -webkit-backdrop-filter: blur(18px) saturate(150%); backdrop-filter: blur(18px) saturate(150%); }
body.s6-body .nav.scrolled.on-dark .s7-acct { background: rgba(0, 42, 80, .56); border-color: rgba(255, 255, 255, .18); }

/* the landing's three buttons, under the cart and sign-up: button text only (owner's brief), stacked at the right in
   equal widths (round two, item 3). Round three (owner: the solid sharp-cornered bars "look out of place, match
   them"): they now use the site's own button language. Each is a rounded pill on the header pill's frosted glass, in
   the pill's navy Manrope 600 type (white on its dark glass over the hero sky), ending in a small round chip with an
   arrow, like the hero's doors (sections/hero.css .s7h-door). The chip is the button's feature colour (shell.js gives
   each its data-f; theme.css sets --c): Book a service the residential yellow #F5A524, Become a Service Provider the
   providers green #16A34A, Join our academy the academy turquoise #0EA5B7. The arrow is navy on all three (5.7:1,
   3.5:1, 3.9:1; white would fall under 3:1 on the turquoise). Chip and arrow are the link's ::before and ::after, so
   the markup is unchanged. Below the pill in the stacking order, so the Platform menu and the search results cover them. */
body.s6-body .nav .s7-ctas {
  --cta-in: 5px;                                                        /* the chip's inset from the pill's edge */
  --cta-chip: calc(var(--s7-cta-row) - 2 * var(--cta-in) - 2px);        /* 26px in a 38px pill (the 2px is its border) */
  position: absolute; z-index: 1; top: calc(100% + var(--s7-cta-gap)); right: 36px;
  display: grid; grid-auto-rows: var(--s7-cta-row); gap: var(--s7-cta-step); width: max-content;
  transition: opacity 250ms ease, transform 250ms var(--ease), visibility 0s linear 0s;
}
body.s6-body .nav .s7-ctas a {
  position: relative; box-sizing: border-box; display: flex; align-items: center;
  padding: 0 calc(var(--cta-in) + var(--cta-chip) + 12px) 0 18px; border-radius: 999px; border: 1px solid rgba(0, 57, 108, .1);
  text-decoration: none; white-space: nowrap;
  background: rgba(255, 255, 255, .78); color: var(--navy); font: 600 14px/1 var(--font); letter-spacing: -.005em;
  -webkit-backdrop-filter: blur(18px) saturate(150%); backdrop-filter: blur(18px) saturate(150%);
  box-shadow: 0 10px 24px -18px rgba(0, 18, 36, .55);
  transition: transform 250ms var(--ease), background-color 250ms ease, border-color 250ms ease, box-shadow 250ms ease;
}
body.s6-body .nav .s7-ctas a::before, body.s6-body .nav .s7-ctas a::after {
  content: ""; position: absolute; top: 50%; right: var(--cta-in); width: var(--cta-chip); height: var(--cta-chip);
  margin-top: calc(var(--cta-chip) / -2); border-radius: 50%; pointer-events: none; transition: transform 250ms var(--ease);
}
body.s6-body .nav .s7-ctas a::before { background: var(--c); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 3px 8px -4px color-mix(in srgb, var(--cd) 70%, transparent); }
body.s6-body .nav .s7-ctas a::after {   /* the arrow: sections/hero.html's, drawn as a mask so it takes the ink colour */
  background: var(--navy);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m13 6 6 6-6 6'/%3E%3C/svg%3E") center / 58% no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m13 6 6 6-6 6'/%3E%3C/svg%3E") center / 58% no-repeat;
}
/* hover: the pill lifts a little (as the doors do), its glass thickens, its edge takes a trace of its colour, and the
   chip nudges forward */
body.s6-body .nav .s7-ctas a:hover {
  transform: translateY(-2px); background: rgba(255, 255, 255, .94); border-color: color-mix(in srgb, var(--c) 55%, transparent);
  box-shadow: 0 14px 26px -16px color-mix(in srgb, var(--cd) 60%, transparent);
}
body.s6-body .nav .s7-ctas a:hover::before, body.s6-body .nav .s7-ctas a:hover::after { transform: translateX(3px); }
body.s6-body .nav .s7-ctas a:active { transform: none; box-shadow: none; }
/* over dark (the hero sky): the pill's dark glass with white type. Tinted navy, as the pill is once scrolled: its
   plain white-on-glass (.14) fell to 3:1 where the lower buttons sit over the paler sky; this keeps white 14px
   type at 6:1 or better there. Hover deepens the glass (lightening it would lose contrast). */
body.s6-body .nav.on-dark .s7-ctas a { background: rgba(0, 42, 80, .38); border-color: rgba(255, 255, 255, .22); color: #fff; box-shadow: 0 10px 24px -18px rgba(0, 10, 25, .7); text-shadow: 0 1px 8px rgba(2, 12, 23, .3); }
body.s6-body .nav.on-dark .s7-ctas a:hover { background: rgba(0, 42, 80, .52); border-color: color-mix(in srgb, var(--c) 70%, transparent); box-shadow: 0 14px 26px -16px rgba(0, 10, 25, .75); }
body.s6-body .nav.scrolled .s7-ctas a { background: rgba(255, 255, 255, .9); }
body.s6-body .nav.scrolled.on-dark .s7-ctas a { background: rgba(0, 42, 80, .56); border-color: rgba(255, 255, 255, .18); }
/* keyboard: a navy ring on the light glass, gold over dark (as the header's own items) */
body.s6-body .nav .s7-ctas a:focus-visible { outline: 2px solid var(--navy) !important; outline-offset: 2px; }
body.s6-body .nav.on-dark .s7-ctas a:focus-visible { outline-color: var(--gold) !important; }
/* they step away as soon as the hero's words scroll up to them (shell.js sets .s7-past), and while the search, the
   Platform menu or the signed-in account menu (.acct-open, checkout-account.js) is open; the phone menu has the main ones */
body.s6-body .nav:is(.s7-past, .searching, .more-open, .acct-open) .s7-ctas { opacity: 0; transform: translateY(-8px); visibility: hidden; pointer-events: none; transition: opacity 250ms ease, transform 250ms var(--ease), visibility 0s linear 250ms; }
html.fx-reduce body.s6-body .nav .s7-ctas, html.fx-reduce body.s6-body .nav .s7-ctas a,
html.fx-reduce body.s6-body .nav .s7-ctas a::before, html.fx-reduce body.s6-body .nav .s7-ctas a::after { transition: none; transform: none; }

/* widths: the pill gives way to the menu button at 1080px */
@media (min-width: 1081px) { body.s6-body .nav .pill { display: flex; } body.s6-body .nav .burger { display: none; } }
@media (min-width: 1081px) and (max-width: 1280px) { body.s6-body .nav.searching .s7-acct { visibility: hidden; } }   /* the open search needs the room */
@media (min-width: 1081px) and (max-width: 1240px) {   /* the account pill ran into the nav pill here; a little tighter keeps a gap */
  body.s6-body .nav .s7-acct { gap: 16px; padding: 0 14px; margin-right: -10px; }
  body.s6-body .nav .s7-acct .s7-glow { letter-spacing: .1em; }
}
@media (min-width: 1081px) and (max-width: 1180px) { body.s6-body .nav .pill > a, body.s6-body .nav .more > button { padding-inline: 13px; } }
@media (max-width: 1080px) {
  body.s6-body .nav { grid-template-columns: auto 1fr auto; top: var(--s7-nav-top); }
  body.s6-body .nav.scrolled { top: 12px; }
  body.s6-body .nav .pill { display: none; }
  body.s6-body .nav .burger { display: inline-grid; margin-left: 8px; }
  body.s6-body .nav .s7-acct { margin-right: 0; }
}
@media (max-width: 940px) {   /* theme.css gives the whole header a frosted backing here once scrolled; the pair needs no glass of its own */
  body.s6-body .nav.scrolled .s7-acct, body.s6-body .nav.scrolled.on-dark .s7-acct { background: none; border-color: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
}
/* phones: the same stack, smaller (three 30px pills, 4px apart, 12.5px type), still at the right under the menu button,
   so it takes about 100px of height and a little over half the width; the hero's words start below it (--s7-top) */
@media (max-width: 720px) {
  :root { --s7-nav-top: 14px; --s7-nav-h: 52px; --s7-cta-gap: 8px; --s7-cta-row: 30px; --s7-cta-step: 4px; --s7-cta-w: 212px; }
  body.s6-body .nav { padding: 0 14px; gap: 10px; height: var(--s7-nav-h); }
  body.s6-body .nav.scrolled { top: 10px; }
  body.s6-body .nav .logo { width: 98px; }
  body.s6-body .nav .s7-acct { gap: 14px; padding: 0 2px; }
  .s7-glow { font-size: 11px; letter-spacing: .1em; }
  body.s6-body .nav .s7-ctas { right: 14px; --cta-in: 4px; }   /* a 20px chip in the 30px pill */
  body.s6-body .nav .s7-ctas a { padding: 0 calc(var(--cta-in) + var(--cta-chip) + 10px) 0 14px; font-size: 12.5px; }
  body.s6-body .nav .s7-ctas a::after { -webkit-mask-size: 66%; mask-size: 66%; }   /* the arrow a touch larger in the small chip */
}
@media (max-width: 420px) {
  body.s6-body .nav { padding: 0 10px 0 14px; }
  body.s6-body .nav .logo { width: 80px; }
  body.s6-body .nav .s7-acct { gap: 10px; }
  body.s6-body .nav .burger { margin-left: 4px; }
  .s7-glow { font-size: 10.5px; letter-spacing: .07em; padding: 8px 2px; }
  body.s6-body .nav .s7-ctas { right: 10px; }
}
/* the narrowest phones (320–359px): "Sign up / " drops ("Log in" stays; "Your account" becomes "Account"), the gaps
   tighten, so logo, account, cart and the 44px menu button all fit */
@media (max-width: 359px) {
  body.s6-body .nav { padding: 0 8px 0 12px; gap: 8px; }
  body.s6-body .nav .logo { width: 76px; }
  body.s6-body .nav .burger { margin-left: 0; }
  .s7-glow .s7-su { display: none; }
  body.s6-body .nav .s7-ctas { right: 8px; }
  body.s6-body .nav .s7-ctas a { padding-left: 12px; font-size: 12px; }
}
/* large text on a phone (shell.js measures the row): "Sign up / " drops, then the account link (the menu has it) */
body.s6-body .nav.s7-fit1 .s7-glow .s7-su { display: none; }
body.s6-body .nav.s7-fit2 .acct-btn { display: none; }
body.s6-body .nav .s7-acct { min-width: 0; }
body.s6-body .nav .s7-glow { white-space: nowrap; }

/* ── the signed-in account button and its menu (6 Oct 2026) ──
   Owner: "the person's name with the profile icon, and when they click on it a drop down with my dashboard and logout".
   partials/header.php .acct-menu (and .menu-acct in the phone menu); assets/js/checkout-account.js shows it once the
   visitor is known, fills in the names and opens the menu. Signed out, nothing here shows.
   The button is a .s7-glow like "Cart 0", so it takes the same caps, colours over the hero and on light pages, hover and
   phone sizes: a round gold avatar with the initials in navy (a person glyph when there is no name), the first name
   (checkout-account.js shortens a long one with an ellipsis) and a chevron. The menu hangs under it, right edges
   aligned: a solid white panel (his rule: no translucent pop-ups) with the Platform menu's radius, edge and shadow,
   navy type whatever the header is over; its rows' hover and keyboard focus are the brand tint with a gold bar at the
   left (the Platform menu's brand rows), plus a navy ring for the keyboard (a gold ring is under 2:1 on white). While
   it is open the homepage's three buttons step aside, as for the Platform menu (.acct-open, above). */
body.s6-body .nav .s7-acct { position: relative; z-index: 3; }   /* the menu opens over the homepage's three buttons */
body.s6-body :is(.s7-acct, .menu-foot) [hidden] { display: none !important; }   /* each part's own display never beats [hidden] */
body.s6-body .nav .acct-menu { position: relative; }
body.s6-body .nav .acct-who { display: inline-flex; align-items: center; gap: 9px; padding: 4px 6px 4px 4px; border-radius: 999px; }
body.s6-body .nav .acct-who:focus-visible { border-radius: 999px; }
body.s6-body .nav .acct-who > svg { flex: none; transition: transform 200ms ease; }
body.s6-body .nav .acct-who[aria-expanded="true"] { color: var(--gold-ink); }
body.s6-body .nav.on-dark .acct-who[aria-expanded="true"] { color: var(--gold-60); }
body.s6-body .nav .acct-who[aria-expanded="true"] > svg { transform: rotate(180deg); }
.acct-av {
  flex: none; display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: 50%;
  background: var(--gold); color: var(--navy); font: 800 11px/1 var(--font); letter-spacing: .02em; text-transform: uppercase; text-shadow: none;
  box-shadow: inset 0 0 0 1px rgba(0, 57, 108, .14); transition: box-shadow 250ms ease;
}
.acct-ini:empty, .acct-ini:not(:empty) + svg { display: none; }   /* the initials, or the person glyph when there are none */
body.s6-body .nav .acct-who:is(:hover, [aria-expanded="true"]) .acct-av { box-shadow: inset 0 0 0 1px rgba(0, 57, 108, .14), 0 0 0 3px rgba(247, 183, 68, .35); }
body.s6-body .nav .acct-pop {
  position: absolute; top: calc(100% + 12px); right: 0; z-index: 1; box-sizing: border-box;
  width: max-content; min-width: 228px; max-width: min(300px, calc(100vw - 24px)); padding: 8px; display: grid;
  border-radius: 18px; background: #FFFFFF; border: 1px solid rgba(0, 57, 108, .08); box-shadow: 0 30px 60px -24px rgba(0, 25, 50, .45);
  color: var(--navy); text-align: left; text-shadow: none; letter-spacing: normal; text-transform: none; white-space: normal;
}
body.s6-body .acct-id { display: grid; gap: 4px; min-width: 0; margin: 0 0 6px; padding: 10px 16px 12px 18px; border-bottom: 1px solid rgba(0, 57, 108, .08); }
body.s6-body .acct-name { font: 700 14.5px/1.25 var(--font); color: var(--navy); }
body.s6-body .acct-sub { font: 500 12.5px/1.35 var(--font); color: #4E6A84; font-variant-numeric: tabular-nums; }
body.s6-body :is(.acct-id, .menu-who-t) > * { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.s6-body .acct-list { display: grid; gap: 2px; }
body.s6-body .acct-list [role="menuitem"] {
  position: relative; box-sizing: border-box; display: flex; align-items: center; gap: 12px; width: 100%; margin: 0;
  padding: 12px 16px 12px 18px; border: 0; border-radius: 14px; background: none; cursor: pointer; text-align: left; text-decoration: none;
  font: 600 14.5px/1.2 var(--font); color: var(--navy); white-space: nowrap; transition: background 180ms ease;
}
body.s6-body .acct-list [role="menuitem"] svg { flex: none; color: #4E6A84; transition: color 180ms ease; }
body.s6-body .acct-list [role="menuitem"]::before { content: ""; position: absolute; left: 7px; top: 12px; bottom: 12px; width: 3px; border-radius: 2px; background: var(--gold); opacity: 0; transition: opacity 180ms ease; }
body.s6-body .acct-list [role="menuitem"]:is(:hover, :focus-visible) { background: #EEF3F8; }
body.s6-body .acct-list [role="menuitem"]:is(:hover, :focus-visible)::before { opacity: 1; }
body.s6-body .acct-list [role="menuitem"]:is(:hover, :focus-visible) svg { color: var(--gold-ink); }
body.s6-body .acct-list [role="menuitem"]:focus { outline: none; }
body.s6-body .acct-list [role="menuitem"]:focus-visible { outline: 2px solid var(--navy) !important; outline-offset: -2px; }
@media (max-width: 720px) {
  body.s6-body .nav .acct-who { gap: 7px; padding: 4px 4px 4px 2px; }
  body.s6-body .nav .acct-who > svg { width: 12px; height: 12px; }
  body.s6-body .nav .acct-av { width: 24px; height: 24px; font-size: 10px; }
  body.s6-body .nav .acct-pop { top: calc(100% + 10px); min-width: 220px; }
}
@media (max-width: 420px) {
  body.s6-body .nav .acct-who { gap: 6px; }
  body.s6-body .nav .acct-av { width: 22px; height: 22px; font-size: 9.5px; }
}
/* large text (site.js fitNav): the first name drops first, then the whole button (the phone menu has the account) */
body.s6-body .nav.s7-fit1 .acct-who .acct-first { display: none; }
body.s6-body .nav.s7-fit2 .acct-menu { display: none; }
/* the phone menu's foot, signed in: the avatar with the full name and the mobile, then "My dashboard" and "Log out"
   side by side, the office's number under them */
body.s6-body .menu-foot.signed-in { flex-wrap: wrap; row-gap: 18px; }
body.s6-body .menu-acct { flex: 1 1 100%; display: grid; grid-template-columns: 1fr 1fr; gap: 14px 10px; }
body.s6-body .menu-who { grid-column: 1 / -1; display: flex; align-items: center; gap: 12px; min-width: 0; margin: 0; }
body.s6-body .menu-who .acct-av { width: 42px; height: 42px; font-size: 15px; }
body.s6-body .menu-who-t { display: grid; gap: 3px; min-width: 0; }
body.s6-body .menu-who .acct-name { font-size: 16px; }
body.s6-body .menu-who .acct-sub { font-size: 13px; }
body.s6-body .menu-acct .btn { width: 100%; padding: 0 14px; justify-content: center; font: 700 15px/1 var(--font); }
html.fx-reduce body.s6-body .nav .acct-who > svg, html.fx-reduce .acct-av { transition: none; }

/* phones (under 768px, owner 2026-09-30): the landing's three buttons leave the header for the top of the menu sheet
   (shell.js builds that row on every page; it shows only here), so the header is the one bar and the hero starts under it.
   The menu's own "Book a service" would repeat the first of them, so only "Book a demo" stays in its row. */
body.s6-body .menu-start { display: none; }
@media (max-width: 767px) {
  body[data-page="home"] { --s7-cta-gap: 0px; --s7-cta-h: 0px; --s7-cta-w: 0px; }
  body.s6-body .nav .s7-ctas { display: none; }
  body.s6-body .menu-start { display: grid; gap: 10px; }
  body.s6-body .menu-start .btn { height: auto; min-height: 52px; padding: 12px 18px; justify-content: center; text-align: center; line-height: 1.2; text-decoration: none; }
  body.s6-body .menu-start .btn.line { background: #fff; color: var(--navy); border: 1.5px solid color-mix(in srgb, var(--c) 70%, #00396C); box-shadow: inset 5px 0 0 var(--c); }
  body.s6-body .menu-start .btn.line:hover { background: var(--ct, #EEF3F8); }
  body.s6-body .menu-ctas { grid-template-columns: 1fr; }
  body.s6-body .menu-ctas .btn.gold { display: none; }
  body.s6-body .menu-ctas .btn { height: auto; min-height: 50px; line-height: 1.2; }
}

/* keyboard: the first Tab stop is a "Skip to content" link (shell.js), out of sight until it has focus */
.s7-skip {
  position: fixed; left: 12px; top: 10px; z-index: 100; padding: 13px 18px; border-radius: 12px;
  background: var(--gold); color: var(--navy); font: 700 14px/1 var(--font); text-decoration: none;
  transform: translateY(calc(-100% - 20px)); transition: transform 200ms var(--ease);
}
.s7-skip:focus { transform: none; }
.s7-skip:focus-visible { outline: 3px solid var(--navy) !important; outline-offset: 2px; }
html.fx-reduce .s7-skip { transition: none; }
main[tabindex="-1"]:focus { outline: none; }
/* read by screen readers only (the search's result count) */
.s7-sr { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

/* a jump to a section (the search's ./#industries, a #demo link) parks its heading just under the scrolled header.
   :where() keeps these at zero specificity, so a section's own scroll-margin still wins. A .s7-sec's padding is
   already room above its heading, so only the rest is added. */
body { --s7-clear: calc(12px + var(--s7-nav-h) + 20px); }
@media (max-width: 720px) { body { --s7-clear: calc(10px + var(--s7-nav-h) + 20px); } }
:where(main > section[id]) { scroll-margin-top: var(--s7-clear); }
:where(main > .s7-sec[id]) { scroll-margin-top: max(12px, calc(var(--s7-clear) - var(--s7-sec))); }
:where(main > .s7-sec.tight[id]) { scroll-margin-top: max(12px, calc(var(--s7-clear) - var(--s7-sec-sm))); }

/* the flows (sign-in, checkout, contact, booking): the footer follows <main> straight on now, so a short step no longer
   stretches to the full screen height (it left a dead gap of 200–300px before the footer) */
body.s6-body .flow-page { min-height: 0; }

/* ── motion: the Animations button, and the calm version of the shared layers (app/fx.js, README "Motion") ──
   The button (fx.js motionToggle): a real <button aria-pressed>, "Animations: On" / "Off", with a small switch. The
   phone menu has it under the pages (.menu-fx, here); the footer's legal row has it at every width (footer.css). */
.fx-toggle {
  display: inline-flex; align-items: center; gap: 10px; min-height: 40px; padding: 4px 14px 4px 6px; border-radius: 999px;
  border: 1px solid var(--line); background: #fff; color: var(--navy); cursor: pointer; font: 600 13.5px/1.2 var(--font); text-align: left;
  transition: border-color .2s ease, background-color .2s ease;
}
.fx-toggle b { font-weight: 800; }
.fx-toggle .fx-sw { position: relative; flex: none; width: 34px; height: 20px; border-radius: 999px; background: #C3D0DD; transition: background-color .2s ease; }
.fx-toggle .fx-sw::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 14px; height: 14px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 2px rgba(0, 30, 60, .35); transition: transform .2s var(--ease);
}
.fx-toggle[aria-pressed="true"] .fx-sw { background: var(--gold); }
.fx-toggle[aria-pressed="true"] .fx-sw::after { transform: translateX(14px); }
.fx-toggle:hover { border-color: rgba(0, 57, 108, .3); background: #F5F8FB; }
html.fx-reduce .fx-toggle, html.fx-reduce .fx-toggle .fx-sw, html.fx-reduce .fx-toggle .fx-sw::after { transition: none; }
body.s6-body .menu-fx { display: flex; }
body.s6-body .menu-fx .fx-toggle { min-height: 48px; padding-right: 18px; font-size: 15px; }

/* calm: the shared pop-ups and overlays (components.css, shop.css, page-blocks.css) fade where they stand instead of
   sliding or popping; the idle floats, the logo ticker and the orb hold still; pulses, glows and scans keep going */
@keyframes fx-fade { from { opacity: 0; } }
html.fx-calm :is(.menu-sheet, .modal, .toast, .help-card, .sheet, .step, .dnode, .drill-unit, .ask6 .msg) { animation-name: fx-fade; }
html.fx-calm .toast.out { transform: none; }
html.fx-calm .qbar5.on.bump { animation: none; }
html.fx-calm :is(.float, .logos5 .row2, .orb img, .orb .ring) { animation: none; }
html.fx-calm .drawer { transform: none; opacity: 0; transition: opacity 300ms ease; }
html.fx-calm .drawer-wrap.on .drawer { opacity: 1; }
html.fx-calm body.s6-body .help-btn { transition: opacity 300ms ease; }

/* behind any pop-up (the booking, a dialog, sign-in) the page's CSS animations pause: app/fx.js puts fx-held on each
   element running one and takes it off when the last pop-up closes (moved here from app/flows.css, 1 Oct 2026) */
.fx-held, .fx-held::before, .fx-held::after { animation-play-state: paused !important; }
