/* ============================================================
   Novix IT — Brand layer
   Loads after style.css to apply the v1.16 brand identity:
   palette, headline face (Gilroy), and surface tweaks.

   Demo build only. Gilroy is used internally for the directors
   review; the production site swaps to Manrope (OFL) unless a
   commercial Gilroy webfont licence is procured.
   ============================================================ */

/* ---- Gilroy headline face --------------------------------- */
@font-face {
  font-family: 'Gilroy';
  src: url('../fonts/gilroy/Gilroy-Light.ttf') format('truetype');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Gilroy';
  src: url('../fonts/gilroy/Gilroy-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Gilroy';
  src: url('../fonts/gilroy/Gilroy-Medium.ttf') format('truetype');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Gilroy';
  src: url('../fonts/gilroy/Gilroy-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Gilroy';
  src: url('../fonts/gilroy/Gilroy-Heavy.ttf') format('truetype');
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}

/* ---- Brand palette (v1.16) -------------------------------- */
:root {
  /* Override the Aiero theme's font tokens.
     The theme declares these in style.css and references them with
     var(--font-primary) / var(--font-secondary) at high specificity,
     so re-pointing them here is the only reliable way to swap fonts
     site-wide. !important ensures we beat any later :root declaration
     that the theme or its plugins may also set on the root. */
  --font-primary: 'Gilroy', 'Manrope', system-ui, -apple-system, sans-serif !important;
  --font-secondary: 'Inter', 'Manrope', system-ui, -apple-system, sans-serif !important;

  /* === Core palette === */
  --novix-ink:        #02102D;
  --novix-light-blue: #0AD3FB;
  --novix-dark-blue:  #0F77F9;
  --novix-purple:     #831AE7;
  --novix-pink:       #DF0DE2;

  /* === Tints — same hue, lightness 75% (brand guide naming) === */
  --novix-light-blue-tint: #4DDFFC;
  --novix-blue-tint:       #83B5FC;
  --novix-purple-tint:     #BA8CF2;
  --novix-pink-tint:       #F687F8;

  /* === Shades — same hue, lightness 35% (brand guide naming) === */
  --novix-light-blue-shade: #0490AF;
  --novix-blue-shade:       #044BAE;
  --novix-purple-shade:     #5212A1;
  --novix-pink-shade:       #A30AA6;

  /* === Light surfaces — paper + paper-soft from brand guide === */
  --novix-paper:      #FFFFFF;
  --novix-paper-soft: #F6F7FB;
  --novix-rule:       rgba(2, 16, 45, 0.10);
  --novix-muted-text: rgba(2, 16, 45, 0.55);

  /* === Light elevation ladder (5 stops, lightest to deepest)
     Anchored on brand paper-soft. Outer steps computed with subtle
     Ink-blue tint for cohesion; not formally in the brand guide. */
  --novix-paper-elev-1: #FBFCFE;
  --novix-paper-elev-2: var(--novix-paper-soft);
  --novix-paper-elev-3: #EEF1F8;
  --novix-paper-elev-4: #E7EBF4;

  /* === Dark elevation ladder (4 stops, deepest to most elevated)
     Near-black #111111 is the deepest structural layer (Aiero original);
     Ink is the primary brand dark; ink-elev-1 is a computed step that
     follows the Ink hue family; ink-tint is the most elevated dark. */
  --novix-near-black: #111111;
  --novix-ink-elev-1: #0E1B3F;
  --novix-ink-tint:   #2C384F;

  /* === Text-on-surface tokens === */
  --novix-text-on-dark:   var(--novix-paper);
  --novix-text-on-light:  var(--novix-ink);
  --novix-muted-on-dark:  rgba(255, 255, 255, 0.72);
  --novix-muted-on-light: var(--novix-muted-text);

  /* === Legacy aliases (kept for any future references) === */
  --novix-bg-dark:       var(--novix-ink);
  --novix-bg-light:      var(--novix-paper);
  --novix-ink-t1:        var(--novix-ink-tint);
  --novix-light-blue-t1: var(--novix-light-blue-tint);
  --novix-dark-blue-t1:  var(--novix-blue-tint);
  --novix-purple-t1:     var(--novix-purple-tint);
  --novix-pink-t1:       var(--novix-pink-tint);

  /* === Brand "Wave" gradient (90deg per brand guide) === */
  --novix-gradient: linear-gradient(90deg,
    var(--novix-light-blue) 0%,
    var(--novix-dark-blue)  35%,
    var(--novix-purple)     70%,
    var(--novix-pink)       100%);

  /* === Hero / page-banner photo overlay ===
     Standard dark wash laid over a banner hero photo so the title reads
     cleanly. Used overlay-first in the background-image stack:
     background-image: var(--novix-hero-overlay-1), url(photo). 40% black,
     matching the About banner. Keep all banners referencing this so the
     overlay stays consistent; change it here to retune every banner. */
  --novix-hero-overlay-1: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4));
}

/* ---- Aiero theme variable overrides -----------------------
   Repoint the Aiero :root tokens at Novix tokens. Loaded after
   style.css so the Aiero defaults are overridden cleanly. Any
   CSS rule using var(--color-primary) etc. now resolves to the
   Novix value. See context/AIERO_TOKEN_MAP.md for the full map.
   ----------------------------------------------------------- */
:root {
  --color-primary:        var(--novix-light-blue);
  --color-secondary:      var(--novix-pink-tint);
  --color-secondary-alt:  var(--novix-pink-tint);

  --color-content-white:  var(--novix-paper);
  --color-content-black:  var(--novix-ink);
  --color-heading:        var(--novix-ink);

  --color-surface-white:    var(--novix-paper);
  --color-surface-dark:     var(--novix-near-black);
  --color-surface-dark-2:   var(--novix-ink-tint);
  --color-surface-light:    var(--novix-paper-elev-3);
  --color-surface-light-1:  var(--novix-paper-elev-4);
  --color-surface-light-3:  var(--novix-paper-soft);

  --color-border: var(--novix-rule);

  --gradient-1: linear-gradient(159deg,
    var(--novix-light-blue-tint) 2.13%,
    var(--novix-pink-tint)       95.42%);
  --gradient-3: linear-gradient(113deg,
    var(--novix-light-blue) 2.7%,
    var(--novix-dark-blue)  98.55%);
  --gradient-btn-1: linear-gradient(102deg,
    var(--novix-purple)    0%,
    var(--novix-dark-blue) 100%);
}

/* ---- Typography overrides --------------------------------- */

/* Body face — Inter (brand guide current placeholder body face).
   Manrope and system fonts as fallbacks. */
body,
.ibt-btn, .ibt-btn span,
.menu-item, .menu-item2,
.accordion-button, .accordion-body,
.price-item, .pricing-list,
.test-block2,
input, textarea, button, select {
  font-family: 'Inter', 'Manrope', system-ui, -apple-system, sans-serif;
}

/* Headline face — Gilroy. Applies to all H1-H6 and titles. */
h1, h2, h3, h4, h5, h6,
.title, .sub-title, .style-text,
.testi-title, .price {
  font-family: 'Gilroy', 'Manrope', system-ui, -apple-system, sans-serif;
}

h1, h2, h3, h4, h5, h6, .title {
  letter-spacing: normal;
}

/* Display headings — use Heavy for impact. Letter-spacing kept at
   normal: with Gilroy on a dark surface, negative tracking causes
   adjacent glyphs to optically bloom into each other. */
.hero-style6 .title,
.sec-title .title,
.testi-title .title,
.footer-content .title,
.footer-top .title {
  font-weight: 900;
  letter-spacing: normal;
}

/* Sub-titles — Light, uppercase, letter-spaced (per brand guide) */
.sec-title .sub-title {
  font-weight: 300;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 13px;
}

/* ---- Brand surface tweaks --------------------------------- */
.novix-trust-strip {
  background: var(--novix-ink);
  color: var(--novix-text-on-dark);
  padding: 28px 0;
  border-top: 1px solid rgba(255,255,255,0.06);
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.novix-trust-strip .trust-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 32px 56px;
  font-size: 14px;
  letter-spacing: 0.02em;
}
.novix-trust-strip .trust-row span {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--novix-muted-on-dark);
}
.novix-trust-strip .trust-row i {
  color: var(--novix-light-blue);
  font-size: 16px;
}

.novix-gradient-text {
  background: var(--novix-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.novix-pill {
  display: inline-block;
  padding: 6px 14px;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--novix-muted-on-dark);
}

/* Commitment cards — used on home + service pages */
.novix-commitments {
  background: var(--novix-ink);
  color: var(--novix-text-on-dark);
  padding: 80px 0;
}
.novix-commitments .commit-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 24px;
  margin-top: 40px;
}
.novix-commitments .commit-card {
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 16px;
  padding: 28px;
}
.novix-commitments .commit-card h4 {
  font-family: 'Gilroy', sans-serif;
  font-weight: 700;
  font-size: 20px;
  margin-bottom: 8px;
  color: var(--novix-text-on-dark);
}
.novix-commitments .commit-card p {
  color: var(--novix-muted-on-dark);
  font-size: 14px;
  line-height: 1.6;
  margin: 0;
}
.novix-commitments .commit-card .stamp {
  display: inline-block;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--novix-light-blue);
  margin-bottom: 12px;
}

/* Gradient accent stroke for select section titles */
.novix-accent-rule {
  display: block;
  width: 64px;
  height: 4px;
  border-radius: 4px;
  background: var(--novix-gradient);
  margin-bottom: 20px;
}

/* Logo size override — brand PNGs are larger than the original SVGs */
.theme-logo,
.footer-logo img,
.side-menu .logo img {
  height: auto;
  max-height: 36px;
  width: auto;
}
.footer-logo img {
  max-height: 56px;
}

/* Gradient button — uses --gradient-btn-1 (Purple → Dark Blue, 2-stop)
   as the primary visible background. Pairs with the .ibt-btn base
   class for layout/structure. */
.ibt-btn.ibt-btn-gradient {
  background: var(--gradient-btn-1);
  color: var(--novix-paper);
  position: relative;
  overflow: hidden;
}
.ibt-btn.ibt-btn-gradient:hover {
  filter: brightness(1.08);
}

/* Counter on .fun-fact-content.black — Aiero fills it with --color-heading
   (Ink), invisible against the Ink-coloured .black background. Fill with
   paper-soft so the "500+" reads cleanly on the dark surface. */
.fun-fact-content.black .counter-box {
  color: var(--novix-paper-soft);
  -webkit-text-fill-color: var(--novix-paper-soft);
}

/* Dark mode — flip the .black highlight box: light background with
   dark Ink text for the 500+ counter. Specificity beats the Aiero
   .active-body rules at style.css:6830 and 36144. */
.active-body .fun-fact-content.black {
  background-color: var(--novix-paper-soft);
}
.active-body .fun-fact-content.black .title,
.active-body .fun-fact-content.black p {
  color: var(--novix-ink);
}
.active-body .fun-fact-content.black .counter-box,
.active-body .fun-fact-content.black .counter-box span {
  color: var(--novix-ink);
  -webkit-text-fill-color: var(--novix-ink);
}

/* Light mode — give the non-.black counters (99%, 24/7) an Ink fill
   so the digits read against the light page; without this they fall
   back to Aiero's white fill which blends into a paper or paper-soft
   background. Gradient outline (text-stroke 2px) is preserved. */
.fun-fact-content:not(.black) .counter-box,
.fun-fact-content:not(.black) .counter-box span {
  color: var(--novix-ink);
  -webkit-text-fill-color: var(--novix-ink);
}

/* Dark mode — flip the non-.black counter fill to paper-soft so the
   digits read against the dark page. Same gradient outline. */
.active-body .fun-fact-content:not(.black) .counter-box,
.active-body .fun-fact-content:not(.black) .counter-box span {
  color: var(--novix-paper-soft);
  -webkit-text-fill-color: var(--novix-paper-soft);
}

/* "Novix IT" brand-name emphasis in testimonial heading — simple
   2-stop Dark Blue -> Purple gradient. */
.testi-title .title span {
  background-image: linear-gradient(90deg,
    var(--novix-dark-blue) 0%,
    var(--novix-purple)    100%);
}

/* Match the vertical gap between stacked testimonial cards to the
   Bootstrap row gutter (24px). Aiero ships .test-block2 at
   margin-bottom: 20px which doesn't quite line up. */
.testimonial-sec2 .test-block2 {
  margin-bottom: 24px;
}

/* The shadow overlay (.testimonial-sec2::before) is a 751px-tall PNG
   gradient that fades from transparent (top) to opaque (bottom).
   Shrinking the overlay clips the gradient, so leave it intact and
   instead push the cards up via padding-bottom. The bottom row now
   sits above the opaque zone of the fade, peeking through. */
.testimonial-sec2 {
  padding-bottom: 110px;
}

/* Aiero's .vs-header6 is position: absolute; top: 0 with no
   background colour on desktop -- a transparent overlay. The
   .page-banner11 sits behind it in flow, so the section's rounded
   top corners and decorative ::before bleed through the transparent
   header areas (visible at top-left where the contact pill doesn't
   cover the page-banner background). Two fixes:

   1. Hide .page-banner11::before. It's a decorative bg-layer2.png
      blob positioned at top: -29% of the section, extending well
      into the header zone.
   2. Push .page-banner11 below the header zone (~140px margin-top)
      so the rounded top corners don't overlap with the absolutely-
      positioned header. */
/* Aiero ships decorative pseudo-elements behind .team-detail-sec
   and .contact-sec2 (purple glow blob, world-map outline). Two
   issues hide them on most viewports:
   1. They're @media (max-width: 1440px) display: none. Show them
      everywhere; CSS background-image at right: 0 just clips at the
      viewport edge on narrower screens, no harm.
   2. The decorations are z-index: -1 absolute on a section with
      position: relative but no z-index, so they escape the section's
      stacking context and render behind unrelated elements.
      isolation: isolate creates a stacking context per section so
      the decorations sit cleanly behind the section's own content. */
.team-detail-sec,
.contact-sec2 {
  isolation: isolate;
}
@media (max-width: 1440px) {
  .contact-sec2::before {
    display: block;
  }
}

/* Team page side accent (team-layer.png), per Ricci: painted ONCE
   (Aiero's default tiled it every 1332px so it appeared to stop
   mid-page), anchored to the viewport so it travels with the scroll
   (background-attachment: fixed, right edge, vertically centred), and
   visible from the hero all the way to the footer. The original
   .team-detail-sec::after strip only covered the profile section, so
   the accent vanished at "what they've built and led"; it now lives on
   .team-page-body, a wrapper in team-page.php around the profile,
   selected-work, testimonial and leadership sections. NB a CSS
   transform on the painting element would force the fixed background
   back to scroll behaviour, so the wrapper must stay transform-free.
   Browsers without fixed-attachment support (older iOS) degrade to the
   image pinned at the top of the wrapper. */
.team-detail-sec::after {
  display: none; /* superseded by .team-page-body::after */
}
.team-page-body {
  position: relative;
  isolation: isolate;
}
.team-page-body::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 485px;
  height: 100%;
  background-image: url(../images/layers/team-layer.png);
  background-repeat: no-repeat;
  background-attachment: fixed;
  background-position: right center;
  z-index: -1;
}

/* Light-mode header backdrop. Aiero's .vs-header6 is position: absolute;
   top: 0 with a transparent desktop background -- the floating white nav
   pill relies on whatever sits behind it for contrast. On the homepage
   that's .hero-style6 (paper-elev-4); on inner pages the banners are pushed
   140px down (below), so nothing fills the header zone and it fell back to
   the white page -- white pill on white, so the menu looked like it
   vanished. Dark mode already gives the header its own backdrop
   (.active-body .vs-header6 { background: --novix-ink-elev-1 }); this is the
   light-mode counterpart. Painting just the header strip (not <body>) keeps
   the rest of the page white, matching index.php; on the homepage the tint
   sits flush against the identical hero colour, so it stays seamless.
   Desktop only -- below 1201px Aiero paints the header solid white and that
   rule must win. */
@media (min-width: 1202px) {
  .vs-header6 {
    background-color: var(--novix-paper-elev-4);
  }
}

/* Dark-mode menu fill. In light mode the .header-menu-area pill is white;
   Aiero leaves it transparent in dark mode (so it shows the --novix-ink-elev-1
   header backdrop behind it). Novix fills the pill itself with near-black --
   the dark counterpart of the white pill. The backdrop behind it stays
   Aiero's --novix-ink-elev-1. Applies at all widths. */
.active-body .vs-header6 .header-menu-area {
  background-color: var(--novix-near-black);
}
/* The sticky header (slides down on scroll, toggled with .is-sticky). Unlike
   the main header it's a single full-width bar -- the .sticky-active container
   IS the fill (Aiero paints it --novix-ink-elev-1; the inner .header-menu-area
   stays transparent). Recolour the container to near-black to match. Both the
   base and .is-sticky selectors, so it's near-black the whole slide-in. */
.active-body .sticky-active,
.active-body .sticky-active.is-sticky {
  background-color: var(--novix-near-black);
}

.page-banner2,
.page-banner4,
.page-banner9,
.page-banner11 {
  margin-top: 140px;
}
/* Page-banner hero images. Each banner carries its own image under the
   shared --novix-hero-overlay-1 wash, so the overlay stays consistent while
   the photos differ per page. Swap any url() for a real photo later.
   (page1-2.png / page1-4.png are Aiero's stock dimension placeholders.) */
.page-banner2,
.page-banner4,
.page-banner9,
.page-banner11 {
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  background-color: var(--novix-ink);
}
.page-banner2 {
  background-image: var(--novix-hero-overlay-1), url(../images/bg/page1-2.png);
}
/* Operations Director rides .page-banner2 (the shared team-single base) and
   carries this extra class only to swap in its real hero photo. Same
   placement and single-class rules as .page-banner-office below: it must sit
   after the .page-banner2 image rule it overrides but before the desktop zone
   block, and stay single-class so the >=1202px zone shorthand can still reset
   it behind the inset card. The other two director pages keep the page1-2.png
   placeholder. */
.page-banner-od {
  background-image: var(--novix-hero-overlay-1), url(../heros/about-od-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-od {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/about-od-hero.avif) type("image/avif"),
        url(../heros/about-od-hero.jpg) type("image/jpeg")
      );
  }
}
/* Business Development Director hero, same single-class pattern as
   .page-banner-od above. */
.page-banner-bdd {
  background-image: var(--novix-hero-overlay-1), url(../heros/about-bdd-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-bdd {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/about-bdd-hero.avif) type("image/avif"),
        url(../heros/about-bdd-hero.jpg) type("image/jpeg")
      );
  }
}
/* "/ Business Development Director /" is the longest of the director
   role names and, at the stock 80px hero title, overruns the 877px
   .page-content box (not the 1340px container) and wraps "Director /"
   onto a second line. The real constraint is that box, so on desktop
   widen it for this page and hold the title on one line. The title
   keeps the full 80px, so it stays uniform with the Operations /
   Technology Director heroes. Scoped to .page-banner-bdd only; on
   mobile (< 1202px) the title may wrap, which is expected. */
@media (min-width: 1202px) {
  .page-banner-bdd .page-content {
    max-width: 1100px;
  }
  .page-banner-bdd .page-content .title {
    white-space: nowrap;
  }
}
/* Technology Director hero, same single-class pattern as .page-banner-od
   above. All three director pages now carry their real hero. */
.page-banner-td {
  background-image: var(--novix-hero-overlay-1), url(../heros/about-td-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-td {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/about-td-hero.avif) type("image/avif"),
        url(../heros/about-td-hero.jpg) type("image/jpeg")
      );
  }
}
.page-banner4 {
  background-image: var(--novix-hero-overlay-1), url(../images/bg/page1-4.png);
}
/* Office.eu rides .page-banner4 (same banner mechanics as microsoft-365)
   and carries this extra class only to swap the photo. It must sit HERE,
   after the .page-banner4 image rule it overrides but before the desktop
   zone block, and stay SINGLE-CLASS: the zone's background: shorthand at
   >=1202px is same-specificity-later, so it resets this image and the
   area behind the inset card stays a toggle-controlled colour. (First
   ship had this rule at the end of the file, which painted the photo
   over the zone colour in both modes.) Real photo wired 2026-06-17:
   abstract Europe network + security shield (data-residency cue). */
.page-banner-office {
  background-image: var(--novix-hero-overlay-1), url(../heros/office-eu-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-office {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/office-eu-hero.avif) type("image/avif"),
        url(../heros/office-eu-hero.jpg) type("image/jpeg")
      );
  }
}
/* Microsoft Office vs Office.eu rides .page-banner4 the same way; this
   class only swaps the photo. Same placement and single-class rules as
   .page-banner-office above. Real photo wired 2026-06-17: a client being
   walked through a Microsoft vs Office.eu comparison on screen. */
.page-banner-versus {
  background-image: var(--novix-hero-overlay-1), url(../heros/microsoft-office-vs-office-eu-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-versus {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/microsoft-office-vs-office-eu-hero.avif) type("image/avif"),
        url(../heros/microsoft-office-vs-office-eu-hero.jpg) type("image/jpeg")
      );
  }
}
/* Plans / tier banners ride .page-banner4 the same way; each class only
   swaps the photo. Same placement and single-class rules as
   .page-banner-office above. Real photos wired 2026-06-23. */
.page-banner-plans {
  background-image: var(--novix-hero-overlay-1), url(../heros/plans-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-plans {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/plans-hero.avif) type("image/avif"),
        url(../heros/plans-hero.jpg) type("image/jpeg")
      );
  }
}
.page-banner-launch {
  background-image: var(--novix-hero-overlay-1), url(../heros/launch-plan-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-launch {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/launch-plan-hero.avif) type("image/avif"),
        url(../heros/launch-plan-hero.jpg) type("image/jpeg")
      );
  }
}
.page-banner-build {
  background-image: var(--novix-hero-overlay-1), url(../heros/build-plan-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-build {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/build-plan-hero.avif) type("image/avif"),
        url(../heros/build-plan-hero.jpg) type("image/jpeg")
      );
  }
}
.page-banner-scale {
  background-image: var(--novix-hero-overlay-1), url(../heros/scale-plan-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-scale {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/scale-plan-hero.avif) type("image/avif"),
        url(../heros/scale-plan-hero.jpg) type("image/jpeg")
      );
  }
}
.page-banner9 {
  background-image: var(--novix-hero-overlay-1), url(../team-photos/contact-us-team.jpg);
}
.page-banner11 {
  background-image: var(--novix-hero-overlay-1), url(../heros/about-us-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner11 {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/about-us-hero.avif) type("image/avif"),
        url(../heros/about-us-hero.jpg) type("image/jpeg")
      );
  }
}
/* Privacy policy rides .page-banner11 (same banner mechanics as About)
   and carries this extra class only to swap the photo. Same placement
   rules as .page-banner-office above: single-class, after the base
   image rules, before the desktop zone block. page1-11.png is Aiero's
   stock dimension placeholder. */
.page-banner-privacy {
  background-image: var(--novix-hero-overlay-1), url(../heros/privacy-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-privacy {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/privacy-hero.avif) type("image/avif"),
        url(../heros/privacy-hero.jpg) type("image/jpeg")
      );
  }
}
/* Downtime calculator rides .page-banner4 the same way; this class only
   swaps the photo. Real hero wired 2026-06-30 (Ricci) — the shattered-clock
   brand graphic, dark-left so the white H1 reads. */
.page-banner-downtime {
  background-image: var(--novix-hero-overlay-1), url(../heros/downtime-calculator-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-downtime {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/downtime-calculator-hero.avif) type("image/avif"),
        url(../heros/downtime-calculator-hero.jpg) type("image/jpeg")
      );
  }
}
/* Have You Been Hacked? rides .page-banner4 the same way; this class only
   swaps the photo. Real hero wired 2026-06-30 (Ricci) — the Mr-Robot-style
   contained-mask graphic, dark-left so the white H1 reads. */
.page-banner-hacked {
  background-image: var(--novix-hero-overlay-1), url(../heros/have-you-been-hacked-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-hacked {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/have-you-been-hacked-hero.avif) type("image/avif"),
        url(../heros/have-you-been-hacked-hero.jpg) type("image/jpeg")
      );
  }
}
/* AI & Automation rides .page-banner4 the same way; this class only swaps
   the photo. Same placement and single-class rules as .page-banner-office
   above. Real photo wired 2026-06-17: presenter directing the Novix workflow
   editor (human-in-control, holds voice rule 15). */
.page-banner-ai {
  background-image: var(--novix-hero-overlay-1), url(../heros/ai-automation-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-ai {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/ai-automation-hero.avif) type("image/avif"),
        url(../heros/ai-automation-hero.jpg) type("image/jpeg")
      );
  }
}
/* Location pages: their hero rules are NOT here. Both the base (mobile)
   and desktop inset-card background-image rules are emitted by
   includes/location-page.php, derived from the location's slug, so a new
   location cannot ship with a missing hero rule. Only the shared
   .page-banner-location title-width class below lives in this file. */
/* Managed IT (service pillar) rides .page-banner4 the same way; this class
   only swaps the photo. Same placement and single-class rules as
   .page-banner-office above. Real photo wired 2026-06-17: the team in a
   considered working session. */
.page-banner-managed {
  background-image: var(--novix-hero-overlay-1), url(../heros/managed-it-hero.jpg);
}
/* AVIF hero with JPEG fallback. Must be an @supports override, not a second
   declaration in the rule above: because the value contains var(), a browser
   without image-set() would invalidate it at computed-value time and drop the
   background entirely instead of keeping the earlier declaration. Pattern to
   copy for every hero as its AVIF lands. */
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-managed {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/managed-it-hero.avif) type("image/avif"),
        url(../heros/managed-it-hero.jpg) type("image/jpeg")
      );
  }
}
/* Location hero titles ("/ IT Support in Manchester /" is the longest)
   overrun the 877px .page-content box at the 80px hero size and wrap. Same
   fix as .page-banner-bdd: on desktop widen the box and hold the title on
   one line. Shared marker class .page-banner-location carries it across all
   location pages (present and future). On mobile (< 1202px) the title may
   wrap, which is expected. */
@media (min-width: 1202px) {
  .page-banner-location .page-content {
    max-width: 1200px;
  }
  .page-banner-location .page-content .title {
    white-space: nowrap;
  }
  /* The decorative vertical .staff-text word is the place name, which varies
     in length; at the stock 100px a long one (Manchester, Southampton...)
     runs taller than the inset card and pokes out past its top edge. Shrink
     it for location pages so the current names sit comfortably inside, and
     clip the inset card so no future long name can ever escape the card
     again. (The corner notches and breadcrumbs sit inside the card, so the
     clip leaves them untouched; the H1 is centred well within the card, so
     it is never clipped.) */
  .page-banner-location > .page-banner-inner {
    overflow: hidden;
  }
  .page-banner-location .staff-text {
    font-size: 80px;
  }
}
/* Cyber Security service page rides .page-banner4 the same way; this class
   only swaps the photo. Same placement and single-class rules as
   .page-banner-office above. Real photo wired 2026-06-17: presenter at a
   Zero Trust / network-access dashboard (control and visibility, no fear
   framing). */
.page-banner-cyber {
  background-image: var(--novix-hero-overlay-1), url(../heros/cyber-security-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-cyber {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/cyber-security-hero.avif) type("image/avif"),
        url(../heros/cyber-security-hero.jpg) type("image/jpeg")
      );
  }
}
/* Terms of Use rides .page-banner4 the same way; this class only swaps the
   photo. Same placement and single-class rules as .page-banner-office above.
   page1-9.png is Aiero's stock dimension placeholder. */
.page-banner-terms {
  background-image: var(--novix-hero-overlay-1), url(../heros/terms-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-terms {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/terms-hero.avif) type("image/avif"),
        url(../heros/terms-hero.jpg) type("image/jpeg")
      );
  }
}
/* Services overview (hub) rides .page-banner4 the same way; this class only
   swaps the photo. Same placement and single-class rules as
   .page-banner-office above. Real photo wired 2026-06-17: the team in a
   considered conversation (the hub umbrella). */
.page-banner-services {
  background-image: var(--novix-hero-overlay-1), url(../heros/services-overview-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-services {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/services-overview-hero.avif) type("image/avif"),
        url(../heros/services-overview-hero.jpg) type("image/jpeg")
      );
  }
}
/* Microsoft 365 service page. Unlike the others it shipped riding the bare
   .page-banner4 base image (page1-4.png) with no swap class of its own, so
   this adds the class it was missing — applied in microsoft-365.php alongside
   .page-banner4. Same placement and single-class rules as .page-banner-office
   above. Real photo wired 2026-06-17: a client being walked through choosing
   a Microsoft 365 plan. */
.page-banner-microsoft {
  background-image: var(--novix-hero-overlay-1), url(../heros/microsoft-365-hero.jpg);
}
@supports (background-image: image-set(url("x.avif") type("image/avif"))) {
  .page-banner-microsoft {
    background-image: var(--novix-hero-overlay-1),
      image-set(
        url(../heros/microsoft-365-hero.avif) type("image/avif"),
        url(../heros/microsoft-365-hero.jpg) type("image/jpeg")
      );
  }
}
/* Hide Aiero's decorative ::before blob on every page-banner variant
   we use — it bleeds up through the absolutely-positioned site
   header and Euan does not want any overlay on the hero. */
.page-banner2::before,
.page-banner4::before,
.page-banner9::before,
.page-banner11::before {
  display: none;
}

/* ----------------------------------------------------------------
   Desktop: rebuild the navy banners (contact = .page-banner9, about =
   .page-banner11, team-single = .page-banner2, service single =
   .page-banner4) exactly the way the homepage
   hero (.hero-style6) is built, instead of the margin-inset card Aiero ships.

   The SECTION becomes the full-width grey zone -- its own background,
   flush to the top so it tucks under the transparent header, rounded only
   at the bottom -- and the navy/photo banner becomes an inset card inside
   it (.page-banner-inner), exactly like the hero photo sits inside
   .hero-style6. Padding does all the framing: top clears the menu, the
   sides inset the card, the bottom closes the zone. Because the grey is the
   section's own background it is always 100% wide and ends cleanly at the
   section bottom -- no pseudo-element, no overhang.

   Below 1202px the banners keep Aiero's full-bleed card (the section keeps
   its navy/photo background and padding; .page-banner-inner is an inert
   passthrough whose absolute children still anchor to the section). */
@media (min-width: 1202px) {
  .page-banner2,
  .page-banner4,
  .page-banner9,
  .page-banner11 {
    margin: 0;
    padding: 183px 20px 32px;  /* top clears the menu; 20px frame; 32px below */
    background: var(--novix-paper-elev-4);
    border-radius: 0 0 25px 25px;
  }
  .page-banner2 > .page-banner-inner,
  .page-banner4 > .page-banner-inner,
  .page-banner9 > .page-banner-inner,
  .page-banner11 > .page-banner-inner {
    position: relative;        /* re-anchor the shapes/staff-text/breadcrumbs */
    padding: 217px 0 235px;    /* match Aiero's .page-banner9 hero height */
    border-radius: 28px;
    background-repeat: no-repeat;
    background-position: center;
    background-size: cover;
    background-color: var(--novix-ink);
  }
  .page-banner2 > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../images/bg/page1-2.png);
  }
  .page-banner4 > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../images/bg/page1-4.png);
  }
  .page-banner9 > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../team-photos/contact-us-team.jpg);
  }
  .page-banner11 > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/about-us-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner11 > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/about-us-hero.avif) type("image/avif"),
          url(../heros/about-us-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Operations Director inset card: real hero photo over the .page-banner2 base. */
  .page-banner-od > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/about-od-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-od > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/about-od-hero.avif) type("image/avif"),
          url(../heros/about-od-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Business Development Director inset card: real hero photo over the base. */
  .page-banner-bdd > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/about-bdd-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-bdd > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/about-bdd-hero.avif) type("image/avif"),
          url(../heros/about-bdd-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Technology Director inset card: real hero photo over the .page-banner2 base. */
  .page-banner-td > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/about-td-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-td > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/about-td-hero.avif) type("image/avif"),
          url(../heros/about-td-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* "Technology" is a wider word than the other directors' staff words
     ("Operations", "Business"), so at the shared 100px the rotated word runs
     taller than the inset card and bleeds up into the header clearance zone.
     Nudge just this page's staff word down so the whole word sits inside the
     card. Scoped inside the desktop media query so the <=1201px 65px rule (set
     in style.css) is untouched. */
  .page-banner-td .staff-text {
    font-size: 88px;
  }
  /* Office.eu inset card: page-specific photo over the .page-banner4 base. */
  .page-banner-office > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/office-eu-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-office > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/office-eu-hero.avif) type("image/avif"),
          url(../heros/office-eu-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Microsoft Office vs Office.eu inset card, same pattern. */
  .page-banner-versus > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/microsoft-office-vs-office-eu-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-versus > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/microsoft-office-vs-office-eu-hero.avif) type("image/avif"),
          url(../heros/microsoft-office-vs-office-eu-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Privacy policy inset card: page-specific photo over the .page-banner11 base. */
  .page-banner-privacy > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/privacy-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-privacy > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/privacy-hero.avif) type("image/avif"),
          url(../heros/privacy-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Downtime calculator inset card: page-specific photo over the .page-banner4 base. */
  .page-banner-downtime > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/downtime-calculator-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-downtime > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/downtime-calculator-hero.avif) type("image/avif"),
          url(../heros/downtime-calculator-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Have You Been Hacked? inset card: page-specific photo over the .page-banner4 base. */
  .page-banner-hacked > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/have-you-been-hacked-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-hacked > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/have-you-been-hacked-hero.avif) type("image/avif"),
          url(../heros/have-you-been-hacked-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* AI & Automation inset card: page-specific photo over the .page-banner4 base. */
  .page-banner-ai > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/ai-automation-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-ai > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/ai-automation-hero.avif) type("image/avif"),
          url(../heros/ai-automation-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Managed IT inset card: page-specific photo over the .page-banner4 base. */
  .page-banner-managed > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/managed-it-hero.jpg);
  }
  /* AVIF + JPEG fallback — same @supports pattern (and reason) as the base
     .page-banner-managed rule further up. */
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-managed > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/managed-it-hero.avif) type("image/avif"),
          url(../heros/managed-it-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Location inset cards: emitted per page by includes/location-page.php
     (derived from the slug), not listed here. */
  /* Cyber Security inset card: page-specific photo over the .page-banner4 base. */
  .page-banner-cyber > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/cyber-security-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-cyber > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/cyber-security-hero.avif) type("image/avif"),
          url(../heros/cyber-security-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Plans / tier inset cards: page-specific photo over the .page-banner4 base. */
  .page-banner-plans > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/plans-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-plans > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/plans-hero.avif) type("image/avif"),
          url(../heros/plans-hero.jpg) type("image/jpeg")
        );
    }
  }
  .page-banner-launch > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/launch-plan-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-launch > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/launch-plan-hero.avif) type("image/avif"),
          url(../heros/launch-plan-hero.jpg) type("image/jpeg")
        );
    }
  }
  .page-banner-build > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/build-plan-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-build > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/build-plan-hero.avif) type("image/avif"),
          url(../heros/build-plan-hero.jpg) type("image/jpeg")
        );
    }
  }
  .page-banner-scale > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/scale-plan-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-scale > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/scale-plan-hero.avif) type("image/avif"),
          url(../heros/scale-plan-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Terms of Use inset card: page-specific photo over the .page-banner4 base. */
  .page-banner-terms > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/terms-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-terms > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/terms-hero.avif) type("image/avif"),
          url(../heros/terms-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Services overview inset card: page-specific photo over the .page-banner4 base. */
  .page-banner-services > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/services-overview-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-services > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/services-overview-hero.avif) type("image/avif"),
          url(../heros/services-overview-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Microsoft 365 inset card: page-specific photo over the .page-banner4 base.
     Like the base swap, M365 needed its own desktop inset rule — without it the
     card fell back to .page-banner4's page1-4 placeholder on desktop. */
  .page-banner-microsoft > .page-banner-inner {
    background-image: var(--novix-hero-overlay-1), url(../heros/microsoft-365-hero.jpg);
  }
  @supports (background-image: image-set(url("x.avif") type("image/avif"))) {
    .page-banner-microsoft > .page-banner-inner {
      background-image: var(--novix-hero-overlay-1),
        image-set(
          url(../heros/microsoft-365-hero.avif) type("image/avif"),
          url(../heros/microsoft-365-hero.jpg) type("image/jpeg")
        );
    }
  }
  /* Dark mode: the hero zone is the deep-ink hero colour (matching the
     homepage hero in dark mode), not the light-mode grey. */
  .active-body .page-banner2,
  .active-body .page-banner4,
  .active-body .page-banner9,
  .active-body .page-banner11 {
    background: var(--novix-ink-elev-1);
  }
  /* Corner notches (.shape = top-left, .shape3 = bottom-right): fill them
     with the hero-zone colour so the notch blends into the zone behind the
     card instead of showing Aiero's stock PNG. Same recolour-via-mask trick
     dark mode already uses globally -- grey in light mode, the deep-ink zone
     colour in dark mode. */
  .page-banner2 .shape::before,
  .page-banner4 .shape::before,
  .page-banner9 .shape::before,
  .page-banner11 .shape::before {
    background-image: none;
    background-color: var(--novix-paper-elev-4);
    -webkit-mask: url(../images/layers/shape1-4-dark.png) no-repeat 0 0 / 100% 100%;
            mask: url(../images/layers/shape1-4-dark.png) no-repeat 0 0 / 100% 100%;
  }
  .page-banner2 .shape3::before,
  .page-banner4 .shape3::before,
  .page-banner9 .shape3::before,
  .page-banner11 .shape3::before {
    background-image: none;
    background-color: var(--novix-paper-elev-4);
    -webkit-mask: url(../images/layers/shape1-4-dark2.png) no-repeat 0 0 / 100% 100%;
            mask: url(../images/layers/shape1-4-dark2.png) no-repeat 0 0 / 100% 100%;
  }
  .active-body .page-banner2 .shape::before,
  .active-body .page-banner4 .shape::before,
  .active-body .page-banner9 .shape::before,
  .active-body .page-banner11 .shape::before,
  .active-body .page-banner2 .shape3::before,
  .active-body .page-banner4 .shape3::before,
  .active-body .page-banner9 .shape3::before,
  .active-body .page-banner11 .shape3::before {
    background-color: var(--novix-ink-elev-1);
  }
}

/* Page-banner corner notches (.shape / .shape3). Aiero swaps these to
   shape1-4-dark.png / shape1-4-dark2.png in dark mode, but those PNGs are
   coloured for Aiero's original near-black theme. Against the Novix dark
   body (--color-surface-dark-2, the same colour .active-body paints the
   page) they read as off-colour panels floating in front of the banner and
   header. Drop the PNG as a fill, use it as a mask instead, and re-fill the
   exact notch silhouette with the dark body colour so it blends into the
   page background like the light-mode notch does. */
.active-body .shape::before {
  background-image: none;
  background-color: var(--color-surface-dark-2);
  -webkit-mask: url(../images/layers/shape1-4-dark.png) no-repeat 0 0 / 100% 100%;
          mask: url(../images/layers/shape1-4-dark.png) no-repeat 0 0 / 100% 100%;
}
.active-body .shape3::before {
  background-image: none;
  background-color: var(--color-surface-dark-2);
  -webkit-mask: url(../images/layers/shape1-4-dark2.png) no-repeat 0 0 / 100% 100%;
          mask: url(../images/layers/shape1-4-dark2.png) no-repeat 0 0 / 100% 100%;
}
/* Breadcrumb concave-corner fillets (.breadcrumbs::before / ::after). In dark
   mode Aiero's corner3-dark.png reads as a grey/off-colour square against the
   Novix navy breadcrumb bar. Recolour it to the bar colour via mask (same
   image + the existing rotate, so the geometry is unchanged) so the fillet
   corners match the colour behind the breadcrumbs. */
.active-body .breadcrumbs::before,
.active-body .breadcrumbs::after {
  background-image: none;
  background-color: var(--color-surface-dark-2);
  -webkit-mask: url(../images/layers/corner3-dark.png) no-repeat 0 0 / 100% 100%;
          mask: url(../images/layers/corner3-dark.png) no-repeat 0 0 / 100% 100%;
}

/* Widen the navigation sub-menu so longer items like "Operations
   Director" sit on a single line. Aiero defaults to 286px, which
   wrapped at ~19 characters; 360px gives ~25 characters of comfortable
   text room while preserving the fixed-width pill look. */
.main-menu > ul li .sub-menu {
  width: 360px;
}

/* About-section "Novix IT" wordmark: ~32% off the original Aiero
   400px (the previous 25% off, then another 10% off that). Both
   stroke shorthand and width matched at 3px so the gradient outline
   reads solidly at the smaller size. Gradient background-clip:text
   inherits untouched. */
.about-content9 .title {
  font-size: 270px;
  line-height: 203px;
  -webkit-text-stroke: 4px rgba(2, 1, 1, 0);
  -webkit-text-stroke-width: 4px;
}
@media (max-width: 1440px) {
  .about-content9 .title {
    font-size: 189px;
    line-height: 167px;
  }
}
@media (max-width: 1366px) {
  .about-content9 .title {
    font-size: 179px;
  }
}
@media (max-width: 1201px) {
  .about-content9 .title {
    font-size: 150px;
    line-height: 153px;
  }
}
@media (max-width: 1025px) {
  .about-content9 .title {
    font-size: 135px;
    line-height: 122px;
  }
}
@media (max-width: 577px) {
  .about-content9 .title {
    font-size: 90px;
    line-height: 75px;
  }
}
@media (max-width: 390px) {
  .about-content9 .title {
    font-size: 79px;
  }
}

/* Marquee text size reduction. Aiero ships .marquee-sec2 .marquee-inner
   span at 60px which felt overpowering for the brand voice. Drop to
   40px so the brand purpose statement reads clearly without shouting. */
.marquee-sec2 .marquee-inner span {
  font-size: 40px;
}
@media (max-width: 769px) {
  .marquee-sec2 .marquee-inner span {
    font-size: 28px;
    line-height: 36px;
  }
}
@media (max-width: 577px) {
  .marquee-sec2 .marquee-inner span {
    font-size: 22px;
    line-height: 30px;
  }
}

/* About page marquee (.marquee-sec) shrunk 50%. Aiero defaults are
   120 / 80 / 50 across breakpoints; shrink to 60 / 40 / 25. */
.marquee-sec .marquee span {
  font-size: 60px;
  line-height: 65px;
}
@media (max-width: 769px) {
  .marquee-sec .marquee span {
    font-size: 40px;
    line-height: 28px;
  }
}
@media (max-width: 577px) {
  .marquee-sec .marquee span {
    font-size: 25px;
  }
}

/* Footer "Edinburgh & London" wordmark in .about-widget — Aiero ships
   it as outline-only (color: transparent + 1px purple-tint stroke).
   Fill the glyphs white so the text reads against the Ink footer
   background while keeping the existing stroke as the outline.
   Selector list covers both default and Aiero's .active-body dark-mode
   override (which has !important locking color to transparent at
   style.css:6459). */
.about-widget .title,
.active-body .about-widget .title {
  color: var(--novix-paper) !important;
}

/* Equal-height pricing cards — Bootstrap row stretches columns by
   default, but the .price-card2 inside doesn't fill its column.
   Make the inner col flex-display so the card can fill height; set
   the card to flex-column so the CTA can pin to the bottom via
   margin-top: auto. Result: all three cards line up at the bottom
   regardless of feature-list length. */
.pricing-sec3 .col-xl-8 > .row > [class*="col-"] {
  display: flex;
}
.pricing-sec3 .price-card2 {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
}
.pricing-sec3 .price-item-price2 {
  margin-top: auto;
}

/* Pricing card price sizing — Aiero defaults render the price at
   60px and the /per-period unit at 20px (same as body copy, so the
   unit doesn't read as supporting info). Drop both one step down
   so the price still anchors visually but the unit reads as a
   secondary label. */
.pricing-sec3 .price-item-price2 .price {
  font-size: 44px;
  line-height: 1.1;
}
.pricing-sec3 .price-item-price2 .price span {
  font-size: 14px;
  line-height: 1.2;
}

/* Card CTA buttons: Aiero left-aligns them and lets the arrow push to
   the far edge, so they read as misaligned and clip the card padding.
   Make them full-width with centred content so all three line up. */
.pricing-sec3 .price-item-price2 .ibt-btn {
  display: flex;
  width: 100%;
  justify-content: center;
  gap: 10px;
}

/* Pricing card text sizing — Aiero ships line-height: 40px on 16px
   feature items, so wrapped lines look detached from each other and
   each continuation line reads like a new item. Tighten line-height
   to 1.5 across feature lists and the tagline so wrapped lines
   read as continuations. */
.pricing-sec3 .price-heade2 span {
  line-height: 1.4;
}
.pricing-sec3 .price-item2 li {
  line-height: 1.5;
  margin-bottom: 6px;
}

/* "All plans include" callout in the description column. */
.pricing-content .pricing-include-label {
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--novix-muted-text);
  margin: 24px 0 10px;
}
.pricing-content .pricing-include {
  list-style: none;
  padding: 0;
  margin: 0 0 24px;
}
.pricing-content .pricing-include li {
  font-size: 15px;
  line-height: 1.5;
  padding-left: 20px;
  position: relative;
  margin-bottom: 4px;
}
.pricing-content .pricing-include li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--novix-light-blue);
}
.active-body .pricing-content .pricing-include li {
  color: var(--novix-paper-soft);
}

/* "Launch plus:" / "Build plus:" / "Base services" label inside each
   pricing card. Sits above the feature list, below the tagline. */
.price-card2 .price-card-plus {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--novix-muted-text);
  margin: 0 0 12px;
}
.active-body .price-card2 .price-card-plus {
  color: rgba(255, 255, 255, 0.65);
}

/* "what we do" image — original choose2.png shipped with rounded
   corners baked into the PNG itself; replacement JPG is a plain
   rectangle. Apply CSS border-radius + overflow hidden so the team
   photo gets the same rounded look. Container has the original
   721x1124 portrait aspect so the landscape photo is cropped to fit
   via object-fit: cover. Brandmark overlay at 60% opacity. */
.choose-img5 {
  display: block;
  width: 100%;
  aspect-ratio: 721 / 1124;
  position: relative;
  overflow: hidden;
  border-radius: 24px;
}
.choose-img5 > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.choose-img5 .logo4 {
  opacity: 0.6 !important;
}

/* "what we do" wordmark — override font to Gilroy (not Heavy; keep
   Aiero's existing 700 weight) and fill colour to white. Gradient
   outline effect (text-stroke + background-clip: text) is left
   untouched. Selector list covers the .active-body dark-mode
   override in style.css:7385. */
.choose-us-sec5 .style-text,
.active-body .choose-us-sec5 .style-text {
  font-family: 'Gilroy', 'Manrope', system-ui, -apple-system, sans-serif;
  font-weight: 900;
  letter-spacing: 0;
  -webkit-text-fill-color: var(--novix-paper);
}

/* Direct contact form embedded in team-single page sits below the
   contact card. Paper-soft surface so the form reads as its own
   panel without darkening the column too much. 48px = Aiero's
   default 28px plus the 20px Euan asked for. */
.team-direct-form {
  margin-top: 32px;
  background: var(--novix-paper-soft);
  padding: 48px;
  border-radius: 16px;
}
.team-direct-form .custom-form > h2 {
  margin-bottom: 24px;
  font-size: 28px;
  line-height: 1.2;
}
.active-body .team-direct-form {
  background: var(--novix-ink-elev-1);
  border: 1px solid rgba(255, 255, 255, 0.14);
}

/* Dark mode legibility inside the direct form. Aiero's dark-mode rules
   assume .contact-form keeps its stock WHITE card (the footer form
   does), so they force the form heading to near-black (style.css:6809)
   and the button text to #333 (style.css:6843), and the inputs keep
   their light-mode grey border (#ADADAD) and placeholder (#898989).
   On this card we repaint the surface deep ink, so everything sitting
   on it has to be re-lit. Selectors carry one extra class to out-rank
   the style.css !important rules. */
.active-body .team-direct-form .custom-form h2 {
  color: var(--novix-text-on-dark) !important;
}
.active-body .team-direct-form .custom-form .ibt-btn.ibt-btn-outline {
  color: var(--novix-text-on-dark) !important;
}
.active-body .team-direct-form .custom-form input,
.active-body .team-direct-form .custom-form textarea {
  border-color: rgba(255, 255, 255, 0.35);
  color: var(--novix-text-on-dark);
}
.active-body .team-direct-form .custom-form input::-webkit-input-placeholder,
.active-body .team-direct-form .custom-form textarea::-webkit-input-placeholder {
  color: var(--novix-muted-on-dark);
}
.active-body .team-direct-form .custom-form input::-moz-placeholder,
.active-body .team-direct-form .custom-form textarea::-moz-placeholder {
  color: var(--novix-muted-on-dark);
}
.active-body .team-direct-form .custom-form input::placeholder,
.active-body .team-direct-form .custom-form textarea::placeholder {
  color: var(--novix-muted-on-dark);
}

/* Bio block to "Professional experience": Aiero's 101px stock margin
   (style.css:30344) made the bio and the timeline read as two islands.
   64px keeps them one column of content. Same-specificity override,
   later file wins (also out-cascades the 80px tablet media rule). */
.team-detail .sec-title {
  margin-bottom: 64px;
}

/* Pull quote on the team pages: one line of the director's philosophy,
   set between the two bio paragraphs. Gilroy with a vertical brand-
   gradient bar. blockquote is not covered by style.css's .active-body
   element list, so dark mode needs its own colour. */
.team-pull-quote {
  position: relative;
  margin: 34px 0;
  padding: 6px 0 6px 30px;
  font-family: 'Gilroy', 'Manrope', system-ui, -apple-system, sans-serif;
  font-size: 26px;
  line-height: 1.35;
  font-weight: 700;
  color: var(--novix-ink);
}
.team-pull-quote::before {
  content: "";
  position: absolute;
  left: 0;
  /* Inset by the blockquote's 25px corner radius (style.css:34854) so
     the bar sits flush with the straight part of the card edge instead
     of overlapping the curves. */
  top: 25px;
  bottom: 25px;
  width: 4px;
  border-radius: 2px;
  background: linear-gradient(180deg,
    var(--novix-light-blue) 0%,
    var(--novix-dark-blue)  35%,
    var(--novix-purple)     70%,
    var(--novix-pink)       100%);
}
.active-body .team-pull-quote {
  color: var(--novix-text-on-dark);
}
@media (max-width: 991px) {
  .team-pull-quote {
    font-size: 22px;
  }
}

/* Bio-only profile column. The 64px above separated the bio from the
   professional-experience timeline; with the timeline gone (2026-08-26)
   that gap dangles at the foot of the column, so team-page.php marks the
   column .team-detail-bio-only and it is zeroed here. If a timeline ever
   returns, the class goes and the 64px is correct again. */
.team-detail-bio-only .sec-title {
  margin-bottom: 0;
}

/* ----------------------------------------------------------------
   Track record figures (.team-track). Replaced the professional
   experience timeline on 2026-08-26: four figures per director,
   driven by $member['marks'].

   They sit in the profile row's right-hand column, under the bio
   and beside the sticky contact form, which is exactly where the
   timeline used to be, so the column fills rather than leaving a
   tall gap. Two per row at every width, including phones, where
   four stacked rows read as a list rather than a set.

   Two things the block learned the hard way:

   1. The gradient rule is the full width of its cell, not a 38px
      stub. Every rule is the SAME width, so it makes no claim
      about relative scale — that was the point of dropping the
      proportional bars, since four figures in four different
      units (users, people, pounds, years) cannot share one. But
      the width is where the presence comes from: the stub version
      left the figures floating and the block read as weightless
      against the rest of the page.
   2. It carries the standard .sec-title, eyebrow and all, because
      every other heading on the site does — including the name
      directly above it in the same column. A bare heading with no
      eyebrow read as a different kind of heading in the same
      space.
   ---------------------------------------------------------------- */

/* The bio's own .sec-title already carries 64px below it (the gap that
   used to separate the bio from the timeline), so this only tops it up to
   about 90px, which is what a heading this size needs above it. */
.team-track {
  margin-top: 26px;
}
/* Same specificity as .team-detail .sec-title above (0,2,0) and later in
   the file, so this wins. Keep it below that rule. */
.team-track .sec-title {
  margin-bottom: 44px;
}
/* Stepped down from the 55px used by full-width section titles: this one
   sits INSIDE a section, directly under the 55px name in the same ~770px
   column, and two 55px headings stacked there read as a layout fault
   rather than a rhythm. 38px is the largest that stays clearly
   subordinate to the name while still being a heading, not a label. */
.team-track .sec-title .title {
  font-size: 38px;
  line-height: 1.15;
  margin-bottom: 0;
}
/* Optional standfirst under the heading (only Ricci's page sets one, for
   the two-environments point). .sec-title paragraphs inherit the theme's
   700 weight, which reads as a second heading, so drop it to 500. */
.team-track .track-intro {
  max-width: 460px;
  margin: 14px 0 0;
  font-size: 16px;
  line-height: 1.6;
  font-weight: 500;
  color: var(--novix-muted-on-light);
}
.active-body .team-track .track-intro {
  color: var(--novix-muted-on-dark);
}
.track-marks {
  /* Bootstrap 5 row gutter: the only supported way to space wrapped
     columns without fighting the negative row margins. */
  --bs-gutter-y: 44px;
}
/* 54px, not the 44px this block started at: it has to hold its own
   against a 551px photo and a full contact form across the row. The cells
   are ~300px wide, which fits "8,800" at 54px with room to spare. */
.track-mark .fig {
  font-family: 'Gilroy', 'Manrope', system-ui, -apple-system, sans-serif;
  font-size: 54px;
  line-height: 1;
  font-weight: 900;
  color: var(--novix-ink);
}
.track-mark .fig .unit {
  font-size: 24px;
  font-weight: 700;
  margin-left: 2px;
}
.track-mark .rule {
  display: block;
  width: 100%;
  /* Stops short of the gutter so two side-by-side rules read as two
     figures rather than one banded row. */
  max-width: 88%;
  height: 3px;
  border-radius: 2px;
  margin: 16px 0 14px;
  background: linear-gradient(90deg,
    var(--novix-light-blue) 0%,
    var(--novix-dark-blue)  35%,
    var(--novix-purple)     70%,
    var(--novix-pink)       100%);
}
.track-mark .lbl {
  font-size: 14px;
  line-height: 1.4;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--novix-ink);
  margin: 0 0 8px;
}
.track-mark .sub {
  font-size: 15px;
  line-height: 1.6;
  color: var(--novix-muted-on-light);
  margin: 0;
}
.active-body .track-mark .fig,
.active-body .track-mark .lbl {
  color: var(--novix-text-on-dark);
}
.active-body .track-mark .sub {
  color: var(--novix-muted-on-dark);
}
@media (max-width: 575px) {
  .team-track .sec-title .title { font-size: 30px; }
  .track-marks { --bs-gutter-y: 32px; }
  .track-mark .fig { font-size: 40px; }
  .track-mark .fig .unit { font-size: 19px; }
}

/* Straight answers (#answers). Reuses the service-page accordion
   (includes/faq-section.php) with a "straight answers" eyebrow, so
   there is one accordion on the site rather than two. The service
   pages nest theirs inside .ser-detail, which supplies a 60px top
   margin and a section gap; here the section carries its own
   spacing, so the wrapper class is swapped for .team-answers and the
   accordion sits in a plain .container. */
.team-answers {
  margin-top: 0;
}
.team-answers .faq-content4 {
  max-width: 900px;
}
.team-answers .sec-title {
  margin-bottom: 40px;
}

/* Client testimonial slot on the team pages (renders only when the
   page supplies $member['testimonial']). Centred, quiet, no card
   chrome — the words are the feature. */
.team-testimonial blockquote {
  max-width: 820px;
  margin: 0 auto;
  text-align: center;
}
.team-testimonial blockquote p {
  font-family: 'Gilroy', 'Manrope', system-ui, -apple-system, sans-serif;
  font-size: 28px;
  line-height: 1.4;
  font-weight: 600;
  color: var(--novix-ink);
  margin-bottom: 18px;
}
.team-testimonial cite {
  font-style: normal;
  font-size: 15px;
  color: var(--novix-muted-text);
}
.active-body .team-testimonial cite {
  color: var(--novix-muted-on-dark);
}
@media (max-width: 991px) {
  .team-testimonial blockquote p {
    font-size: 22px;
  }
}

/* Leadership cross-links at the foot of each team page. Reuses Aiero's
   .team-card; the ::after on the name link stretches the click target
   across the whole card (the share-box sits at z-index 999, so the
   LinkedIn link stays clickable above it). */
.team-cross-card .name a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 10;
}

/* Aiero's dark-mode border for team cards is near-black
   (--color-content-black2, style.css:6894), which vanishes against the
   ink-tint page background — the card outlines disappeared when
   toggling to dark. Same-specificity override, later file wins. */
.active-body .team-content {
  border-color: rgba(255, 255, 255, 0.16);
}

/* Section-level cross.png decoration on team-single. Aiero places
   the cross inside .team-detail-info, relying on the absolute
   resolving up to .team-detail-sec since neither .team-detail-info
   nor .col-lg-5 is positioned in the stock template.

   We made .col-lg-5 position: sticky (for the contact column to
   track scroll). Sticky is a positioned value, so the absolute
   img then resolved to the column, not the section, and got
   trapped inside the column's stacking context behind the form.

   Fix: move the img out of the column and anchor it to the section
   directly via .team-detail-cross. Same Aiero coordinates
   (bottom-left of the section). z-index: -1 inside the section's
   isolation: isolate context keeps it behind text but visible
   against the section background. */
.team-detail-cross {
  position: absolute;
  bottom: 163px;
  left: 49px;
  z-index: -1;
  pointer-events: none;
}
@media (max-width: 991px) {
  .team-detail-cross {
    display: none;
  }
}

/* Sticky left column on team-single pages: the photo + contact card
   + form follow the visitor down the page while they read the bio
   and experience timeline on the right. Only enabled at lg+ where
   the two columns are actually side-by-side; on mobile the layout
   stacks so sticky has nothing to anchor against. The 100px top
   offset clears the absolute-positioned site header. */
@media (min-width: 992px) {
  .team-detail-sec .col-lg-5 {
    position: sticky;
    top: 100px;
    align-self: flex-start;
  }
}

/* Selected work / capability cards on team-single page. Each card
   shows a domain heading and a bullet list of items. Sits inside a
   Swiper carousel so we can show many cards on a small footprint;
   user navigates via arrows + dots. */
.selected-work .achievements-swiper {
  position: relative;
  /* Bottom padding reserves the dots/arrows row; 40px is the minimum
     that still clears the 36px arrow buttons. */
  padding: 0 0 40px;
}
.selected-work .achievements-swiper .swiper-button-next,
.selected-work .achievements-swiper .swiper-button-prev {
  color: var(--novix-ink);
  top: auto;
  bottom: 0;
  width: 36px;
  height: 36px;
}
.selected-work .achievements-swiper .swiper-button-prev { left: auto; right: 50px; }
.selected-work .achievements-swiper .swiper-button-next { right: 0; }
.selected-work .achievements-swiper .swiper-button-next::after,
.selected-work .achievements-swiper .swiper-button-prev::after {
  font-size: 18px;
  font-weight: 700;
}
.selected-work .achievements-swiper .swiper-pagination {
  bottom: 10px;
  text-align: left;
  width: auto;
  left: 0;
}
.selected-work .achievements-swiper .swiper-pagination-bullet {
  background: var(--novix-rule);
  opacity: 1;
  width: 8px;
  height: 8px;
}
.selected-work .achievements-swiper .swiper-pagination-bullet-active {
  background: var(--novix-light-blue);
  width: 24px;
  border-radius: 4px;
}
.active-body .selected-work .achievements-swiper .swiper-button-next,
.active-body .selected-work .achievements-swiper .swiper-button-prev {
  color: var(--novix-paper);
}
.active-body .selected-work .achievements-swiper .swiper-pagination-bullet {
  background: rgba(255, 255, 255, 0.2);
}

.selected-work .work-card {
  background: var(--novix-paper-soft);
  border-radius: 16px;
  padding: 28px 28px 24px;
  height: 100%;
  /* No bottom margin: slides never stack vertically in the swiper, so
     it only pushed the dots/arrows row further from the cards. */
  margin-bottom: 0;
}
.selected-work .work-card .title {
  margin: 0 0 16px;
  font-size: 22px;
  letter-spacing: -0.01em;
  color: var(--novix-ink);
}
.selected-work .work-card ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
.selected-work .work-card li {
  font-size: 15px;
  line-height: 1.6;
  padding-left: 20px;
  position: relative;
  margin-bottom: 6px;
  color: var(--novix-text-on-light);
}
.selected-work .work-card li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--novix-light-blue);
}
.active-body .selected-work .work-card {
  background: var(--novix-ink-elev-1);
}
.active-body .selected-work .work-card .title,
.active-body .selected-work .work-card li {
  color: var(--novix-paper);
}

/* Footer "Edinburgh & London" headline: reduced 20% from Aiero defaults */
.about-widget .title {
  font-size: 84px;
  line-height: 68px;
}
@media (max-width: 1201px) {
  .about-widget .title {
    font-size: 68px;
  }
}
@media (max-width: 1025px) {
  .about-widget .title {
    font-size: 41px;
  }
}
@media (max-width: 769px) {
  .about-widget .title {
    font-size: 68px;
  }
}
@media (max-width: 577px) {
  .about-widget .title {
    font-size: 46px;
  }
}
@media (max-width: 480px) {
  .about-widget .title {
    font-size: 34px;
    line-height: 50px;
  }
}
@media (max-width: 390px) {
  .about-widget .title {
    font-size: 30px;
    line-height: 34px;
  }
}

/* ----------------------------------------------------------------
   Comparison table (.compare-table) — first used on the Microsoft Office
   vs Office.eu page. style.css only styles the shop cart tables, so this
   is the general-purpose comparison surface: bordered cells on
   --novix-rule, a header row on the elevated paper surface, and re-lit
   borders/headings in dark mode (style.css gives dark mode no table
   treatment at all). The wrapper scrolls horizontally below tablet width
   so the table never breaks the column. */
.compare-table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin-bottom: 40px;
}
.compare-table {
  min-width: 640px;
  margin-bottom: 0;
}
.compare-table th,
.compare-table td {
  border: 1px solid var(--novix-rule);
  padding: 14px 18px;
  vertical-align: top;
  font-size: 16px;
  line-height: 26px;
}
.compare-table thead th,
.compare-table tbody th {
  font-weight: 600;
  color: var(--novix-ink);
}
.compare-table thead th {
  background: var(--novix-paper-elev-3);
}
.active-body .compare-table th,
.active-body .compare-table td {
  border-color: rgba(255, 255, 255, 0.14);
}
.active-body .compare-table thead th,
.active-body .compare-table tbody th {
  color: var(--novix-text-on-dark);
}
/* The body cells were missed in the dark pass: they inherited the light-mode
   ink and sat near-invisible on the dark surface. */
.active-body .compare-table td {
  color: var(--novix-muted-on-dark);
}
.active-body .compare-table thead th {
  background: var(--novix-ink-tint);
}

/* Visually-hidden text utility (screen readers only). Used to give the
   tick/dash cells in the plans matrix an accessible "Included" /
   "Not included" label without showing it. */
.vis-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ----------------------------------------------------------------
   Plans feature matrix (.plans-matrix on /plans). A purpose-built,
   branded version of the comparison table: tier headers carry the
   price, the Build column is highlighted as the popular choice,
   capabilities are grouped into labelled bands, and inclusion is
   shown with a brand tick rather than the word "Yes". */
.plans-matrix {
  width: 100%;
  min-width: 680px;
  margin-bottom: 0;
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid var(--novix-rule);
  border-radius: 16px;
  overflow: hidden;
}
.plans-matrix th,
.plans-matrix td {
  border-bottom: 1px solid var(--novix-rule);
  padding: 14px 18px;
  vertical-align: middle;
}
.plans-matrix tbody tr:last-child th,
.plans-matrix tbody tr:last-child td {
  border-bottom: 0;
}
/* Column headers: deep ink band, tier name over price. */
.plans-matrix thead th {
  background: var(--novix-ink);
  color: var(--novix-text-on-dark);
  text-align: center;
  vertical-align: bottom;
  padding: 22px 18px 20px;
  border-bottom: 0;
}
.plans-matrix thead th:first-child {
  text-align: left;
  vertical-align: bottom;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--novix-muted-on-dark);
}
.plans-matrix .matrix-plan {
  display: block;
  font-family: 'Gilroy', 'Manrope', system-ui, -apple-system, sans-serif;
  font-weight: 900;
  font-size: 24px;
  line-height: 1.1;
}
.plans-matrix .matrix-price {
  display: block;
  margin-top: 4px;
  font-size: 18px;
  font-weight: 700;
  color: var(--novix-light-blue);
}
.plans-matrix .matrix-price small {
  font-size: 12px;
  font-weight: 500;
  color: var(--novix-muted-on-dark);
}
/* Popular tag on the Build header. */
.plans-matrix .matrix-tag {
  display: inline-block;
  margin-bottom: 8px;
  padding: 3px 12px;
  border-radius: 999px;
  background: var(--novix-gradient);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
/* Row label column. */
.plans-matrix tbody th {
  text-align: left;
  font-weight: 600;
  font-size: 15px;
  line-height: 1.45;
  color: var(--novix-ink);
}
.plans-matrix tbody td {
  text-align: center;
  width: 130px;
}
/* Grouped band rows that break the list into scannable sections. */
.plans-matrix .matrix-group th {
  background: var(--novix-paper-elev-3);
  font-family: 'Gilroy', 'Manrope', system-ui, -apple-system, sans-serif;
  font-weight: 900;
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--novix-ink);
}
/* Zebra striping on the feature rows (not the group bands). */
.plans-matrix tbody tr:not(.matrix-group):nth-of-type(even) th,
.plans-matrix tbody tr:not(.matrix-group):nth-of-type(even) td {
  background: var(--novix-paper-soft);
}
/* Tick / dash marks. */
.plans-matrix .m-yes i {
  color: var(--novix-light-blue);
  font-size: 17px;
}
.plans-matrix .m-no span[aria-hidden]::before {
  content: "";
  display: inline-block;
  width: 14px;
  height: 2px;
  border-radius: 2px;
  background: var(--novix-rule);
  vertical-align: middle;
}
/* Highlight the Build column (3rd cell in every row) as the popular pick. */
.plans-matrix tr > *:nth-child(3) {
  background: rgba(10, 211, 251, 0.07);
}
.plans-matrix thead th.col-pop {
  background: var(--novix-ink-elev-1);
}
.plans-matrix .matrix-group th.col-pop,
.plans-matrix tbody tr:not(.matrix-group):nth-of-type(even) td:nth-child(3) {
  background: rgba(10, 211, 251, 0.12);
}

/* Dark mode: re-light the borders and the row labels; keep the ink
   header and the Build highlight, which already read on dark. */
.active-body .plans-matrix {
  border-color: rgba(255, 255, 255, 0.14);
}
.active-body .plans-matrix th,
.active-body .plans-matrix td {
  border-bottom-color: rgba(255, 255, 255, 0.14);
}
.active-body .plans-matrix tbody th {
  color: var(--novix-text-on-dark);
}
.active-body .plans-matrix .matrix-group th {
  background: var(--novix-ink-tint);
  color: var(--novix-text-on-dark);
}
.active-body .plans-matrix tbody tr:not(.matrix-group):nth-of-type(even) th,
.active-body .plans-matrix tbody tr:not(.matrix-group):nth-of-type(even) td {
  background: rgba(255, 255, 255, 0.04);
}
.active-body .plans-matrix .m-no span[aria-hidden]::before {
  background: rgba(255, 255, 255, 0.25);
}
.active-body .plans-matrix tr > *:nth-child(3) {
  background: rgba(10, 211, 251, 0.10);
}

/* The comparison page's in-body section headings (h3 between the table
   and the bullet lists). .ser-detail only styles its h2 .title, so give
   the h3s their breathing room here. */
/* Section rhythm inside .ser-detail. style.css ships big, uneven gaps
   (h3 had no system, lists carry a 35px top margin, paragraphs 30px),
   which left ragged whitespace between the h3 sections on the plans and
   tier pages. Even the rhythm: clear separation ABOVE each h3, tight
   heading-to-text, and contained list spacing. */
.ser-detail h3 {
  margin: 44px 0 14px;
}
.ser-detail h3:first-child {
  margin-top: 0;
}
.ser-detail .ser-detail-list {
  margin-top: 18px;
  margin-bottom: 10px;
}
.ser-detail .faq-sec4 {
  margin-top: 60px;
}
/* In-content image on the service pages. The brand rounds its imagery
   everywhere (banners 28px, cards 16px); a flush rectangle here reads as
   off-pattern, so round it and let it fill the column width (the global
   img rule already caps it at 100% and keeps the aspect ratio). */
.ser-detail img {
  width: 100%;
  border-radius: 16px;
}

/* Two-button call-to-action row at the foot of the tier plan pages
   (launch/build/scale). Aiero's .ibt-btn is inline-flex with no sibling
   spacing, so wrap them in a flex row that wraps on narrow screens. */
.ser-detail .ser-cta-row,
.ser-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 40px;
}
/* Centred variant for standalone CTA rows (e.g. the services hub),
   where the row sits in a centred .text-center column rather than the
   left-aligned .ser-detail body. */
.ser-cta-row.ser-cta-center {
  justify-content: center;
}

/* ----------------------------------------------------------------
   Legal document body (.privacy-body on privacy-policy.php,
   .terms-body on terms-of-use.php). Long-form legal text in a
   centred column. The service-page .ser-detail typography is too
   heavy for this (55px titles, 700-weight paragraphs), so these
   pages carry their own lighter scale. Dark mode needs nothing
   here: Aiero's global .active-body rules already force headings,
   paragraphs and list items white. */
.privacy-body .policy-updated,
.terms-body .policy-updated {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--novix-dark-blue);
  margin: 0 0 24px;
}
.privacy-body h2,
.terms-body h2 {
  font-size: 28px;
  line-height: 1.3;
  font-weight: 400;
  letter-spacing: -0.02em;
  margin: 48px 0 0;
  /* The header floats over the page, so an in-page anchor lands with its
     heading hidden underneath it and the reader arrives mid-paragraph. Added
     2026-09-07 with the Privacy Policy's first internal links (the referrals
     section and back to "Who we are"). Roughly the header's height plus a
     breathing line. */
  scroll-margin-top: 130px;
}
/* Run-in subheadings inside a long h2 section. Added 2026-09-07 for the
   referral section of the Privacy Policy, whose supplied copy is structured
   as labelled parts rather than continuous prose. Deliberately closer to the
   body than to the 28px h2, so the section still reads as one thing: an h3
   that competes with its h2 turns one section into six. */
.privacy-body h3,
.terms-body h3 {
  font-size: 18px;
  line-height: 1.4;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 28px 0 0;
}
.privacy-body p,
.terms-body p {
  font-size: 16px;
  line-height: 30px;
  font-weight: 500;
  color: var(--color-content-black2);
  margin: 16px 0 0;
}
.privacy-body ul,
.terms-body ul {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
}
.privacy-body ul li,
.terms-body ul li {
  position: relative;
  font-size: 16px;
  line-height: 30px;
  font-weight: 500;
  color: var(--color-content-black2);
  margin: 8px 0 0;
  padding-left: 30px;
}
.privacy-body ul li i,
.terms-body ul li i {
  position: absolute;
  top: 0;
  left: 0;
  font-size: 11px;
  color: var(--novix-dark-blue);
}
.privacy-body a,
.terms-body a {
  color: var(--novix-dark-blue);
  text-decoration: underline;
}

/* ----------------------------------------------------------------
   Downtime cost calculator (.downtime-tool on downtime-calculator.php).
   The site's first interactive tool page. Two panels side by side on
   desktop (inputs left, results right), stacked on mobile. Panels sit on
   the elevated paper surface in light mode and the ink-tint surface in
   dark mode, matching the rest of the brand layer. No new JS file: the
   calculation is a small inline script on the page. */
.downtime-intro {
  max-width: 760px;
  margin: 0 auto 48px;
  text-align: center;
}
.downtime-intro .sub-title {
  display: block;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--novix-light-blue-shade);
  margin-bottom: 14px;
}
.downtime-intro .title {
  margin-bottom: 20px;
}
.downtime-intro p {
  font-size: 16px;
  line-height: 30px;
  font-weight: 500;
  color: var(--color-content-black2);
  margin: 0 0 16px;
}

.downtime-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
  align-items: start;
}
@media (max-width: 991px) {
  .downtime-grid {
    grid-template-columns: 1fr;
  }
}

.downtime-panel {
  background: var(--novix-paper-elev-3);
  border: 1px solid var(--novix-rule);
  border-radius: 20px;
  padding: 36px;
}
.downtime-panel-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--novix-dark-blue);
  margin: 0 0 28px;
}

.downtime-field {
  margin-bottom: 22px;
}
.downtime-field:last-child {
  margin-bottom: 0;
}
.downtime-field label {
  display: block;
  font-size: 15px;
  font-weight: 600;
  color: var(--novix-ink);
  margin-bottom: 8px;
}
.downtime-field input {
  width: 100%;
  padding: 13px 16px;
  font-size: 17px;
  font-weight: 600;
  color: var(--novix-ink);
  background: var(--novix-paper);
  border: 1px solid var(--novix-rule);
  border-radius: 12px;
  outline: none;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.downtime-field input:focus {
  border-color: var(--novix-dark-blue);
  box-shadow: 0 0 0 3px rgba(15, 119, 249, 0.15);
}
.downtime-field .field-hint {
  font-size: 13px;
  line-height: 20px;
  color: #676767;
  margin: 7px 0 0;
}

/* Prefix/suffix wrap for the £ sign and the "× salary" note. */
.input-wrap {
  position: relative;
  display: flex;
  align-items: center;
}
.input-wrap .input-prefix {
  position: absolute;
  left: 16px;
  font-size: 17px;
  font-weight: 600;
  color: #676767;
  pointer-events: none;
}
.input-wrap .input-prefix ~ input {
  padding-left: 30px;
}
.input-wrap .input-suffix {
  position: absolute;
  right: 16px;
  font-size: 14px;
  font-weight: 500;
  color: #676767;
  pointer-events: none;
}

/* Weeks / days / hours sit on one row on desktop. */
.downtime-field-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 16px;
}
.downtime-field-row .downtime-field {
  margin-bottom: 0;
}
@media (max-width: 575px) {
  .downtime-field-row {
    grid-template-columns: 1fr;
    gap: 22px;
  }
}

/* Results panel. */
.downtime-headline {
  padding-bottom: 28px;
  margin-bottom: 28px;
  border-bottom: 1px solid var(--novix-rule);
}
.downtime-headline .value {
  display: block;
  font-size: 48px;
  line-height: 1.05;
  font-weight: 700;
  letter-spacing: -0.02em;
  background: var(--gradient-3);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--novix-dark-blue);
}
.downtime-headline .label {
  display: block;
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #676767;
  margin-top: 6px;
}
.downtime-result-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.downtime-result {
  padding: 20px;
  background: var(--novix-paper);
  border: 1px solid var(--novix-rule);
  border-radius: 14px;
}
.downtime-result.downtime-result-feature {
  background: var(--gradient-btn-1);
  border-color: transparent;
}
.downtime-result .value {
  display: block;
  font-size: 26px;
  line-height: 1.1;
  font-weight: 700;
  color: var(--novix-ink);
}
.downtime-result .label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #676767;
  margin-top: 6px;
}
.downtime-result-feature .value,
.downtime-result-feature .label {
  color: var(--novix-text-on-dark);
}
.downtime-basis {
  font-size: 14px;
  line-height: 22px;
  color: #676767;
  margin: 24px 0 0;
}

/* Explainer below the tool. */
.downtime-explainer {
  max-width: 820px;
  margin: 48px auto 0;
}
.downtime-explainer-title {
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--novix-ink);
  margin: 0 0 20px;
}
.downtime-explainer p {
  font-size: 16px;
  line-height: 30px;
  font-weight: 500;
  color: var(--color-content-black2);
  margin: 16px 0 0;
}
.downtime-explainer a {
  color: var(--novix-dark-blue);
  text-decoration: underline;
}

/* Dark mode: panels move to the ink-tint surface, text and fields re-lit
   the way the team-direct-form is on the director pages. */
.active-body .downtime-intro p,
.active-body .downtime-explainer p,
.active-body .downtime-field .field-hint,
.active-body .downtime-headline .label,
.active-body .downtime-result .label,
.active-body .downtime-basis,
.active-body .input-wrap .input-prefix,
.active-body .input-wrap .input-suffix {
  color: var(--novix-muted-on-dark);
}
.active-body .downtime-intro .title,
.active-body .downtime-explainer-title,
.active-body .downtime-field label {
  color: var(--novix-text-on-dark);
}
.active-body .downtime-panel {
  background: var(--novix-ink-tint);
  border-color: rgba(255, 255, 255, 0.14);
}
.active-body .downtime-field input {
  color: var(--novix-text-on-dark);
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.18);
}
.active-body .downtime-field input:focus {
  border-color: var(--novix-light-blue);
  box-shadow: 0 0 0 3px rgba(10, 211, 251, 0.2);
}
.active-body .downtime-result {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.14);
}
.active-body .downtime-result .value {
  color: var(--novix-text-on-dark);
}
.active-body .downtime-result-feature {
  background: var(--gradient-btn-1);
}
.active-body .downtime-explainer a {
  color: var(--novix-light-blue);
}

/* ----------------------------------------------------------------
   Have You Been Hacked? (.hack-tool on have-you-been-hacked.php).
   The site's second interactive tool. Two checker panels side by side
   on desktop (password left, email right), a guidance block below, and
   colour-coded result states (clear / found / warn / error) that stay
   calm rather than alarming, per the no-fear cyber voice rule. Panels
   reuse the brand surface tokens the downtime tool established; the
   result-state tints are local to this block. No new JS file: the
   browser-side password check and the email fetch are inline on the
   page. */
.hack-intro {
  max-width: 760px;
  margin: 0 auto 48px;
  text-align: center;
}
.hack-intro .sub-title {
  display: block;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--novix-light-blue-shade);
  margin-bottom: 14px;
}
.hack-intro .title {
  margin-bottom: 20px;
}
.hack-intro p {
  font-size: 16px;
  line-height: 30px;
  font-weight: 500;
  color: var(--color-content-black2);
  margin: 0 0 16px;
}

.hack-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
  align-items: start;
}
@media (max-width: 991px) {
  .hack-grid {
    grid-template-columns: 1fr;
  }
}

.hack-panel {
  background: var(--novix-paper-elev-3);
  border: 1px solid var(--novix-rule);
  border-radius: 20px;
  padding: 36px;
}
.hack-panel-kicker {
  display: block;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--novix-dark-blue);
  margin-bottom: 12px;
}
.hack-panel-title {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--novix-ink);
  margin: 0 0 14px;
}
.hack-panel-lead {
  font-size: 15px;
  line-height: 25px;
  font-weight: 500;
  color: var(--color-content-black2);
  margin: 0 0 24px;
}

.hack-form label {
  display: block;
  font-size: 15px;
  font-weight: 600;
  color: var(--novix-ink);
  margin-bottom: 8px;
}
.hack-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}
.hack-input-wrap input {
  width: 100%;
  padding: 13px 16px;
  font-size: 17px;
  font-weight: 600;
  color: var(--novix-ink);
  background: var(--novix-paper);
  border: 1px solid var(--novix-rule);
  border-radius: 12px;
  outline: none;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.hack-input-wrap input:focus {
  border-color: var(--novix-dark-blue);
  box-shadow: 0 0 0 3px rgba(15, 119, 249, 0.15);
}
/* Show/hide toggle sits inside the password field. */
.hack-reveal {
  position: absolute;
  right: 8px;
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--novix-dark-blue);
  background: transparent;
  border: 0;
  cursor: pointer;
}
.hack-input-wrap input[type="password"],
.hack-input-wrap input[type="text"] {
  padding-right: 72px;
}
.hack-submit {
  width: 100%;
  justify-content: center;
}

/* Result panel: shared shell, state-specific accent. */
.hack-result {
  margin-top: 22px;
  padding: 18px 20px;
  border-radius: 14px;
  border: 1px solid var(--novix-rule);
  border-left-width: 4px;
  font-size: 15px;
  line-height: 24px;
  color: var(--novix-ink);
}
.hack-result strong {
  display: block;
  font-weight: 700;
  margin-bottom: 4px;
}
.hack-result span {
  display: block;
  font-weight: 500;
  color: var(--color-content-black2);
}
.hack-result-checking {
  border-left-color: var(--novix-rule);
  color: #676767;
}
.hack-result-clear {
  background: #ecfaf3;
  border-color: #cdeedd;
  border-left-color: #1f9d63;
}
.hack-result-found {
  background: #fff6e9;
  border-color: #f4e2c2;
  border-left-color: #c9871a;
}
.hack-result-warn {
  background: #fff6e9;
  border-color: #f4e2c2;
  border-left-color: #c9871a;
}
.hack-result-error {
  background: #fdeeee;
  border-color: #f3d2d2;
  border-left-color: #c0392b;
}
.hack-breach-list {
  margin: 12px 0 0;
  padding-left: 18px;
}
.hack-breach-list li {
  font-size: 14px;
  line-height: 22px;
  font-weight: 600;
  color: var(--novix-ink);
}

.hack-note {
  font-size: 13px;
  line-height: 20px;
  color: #676767;
  margin: 18px 0 0;
}

/* Email panel "coming soon" state (shown until an API key is configured). */
.hack-soon {
  padding: 24px;
  background: var(--novix-paper);
  border: 1px dashed var(--novix-rule);
  border-radius: 14px;
}
.hack-soon-badge {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--novix-dark-blue);
  background: rgba(15, 119, 249, 0.1);
  padding: 5px 12px;
  border-radius: 999px;
  margin-bottom: 14px;
}
.hack-soon p {
  font-size: 15px;
  line-height: 25px;
  font-weight: 500;
  color: var(--color-content-black2);
  margin: 0;
}
.hack-soon a {
  color: var(--novix-dark-blue);
  text-decoration: underline;
}

/* Guidance block below the two checkers. */
.hack-guidance {
  max-width: 820px;
  margin: 56px auto 0;
}
.hack-guidance-title {
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--novix-ink);
  margin: 40px 0 16px;
}
.hack-guidance-title:first-child {
  margin-top: 0;
}
.hack-guidance p {
  font-size: 16px;
  line-height: 30px;
  font-weight: 500;
  color: var(--color-content-black2);
  margin: 0 0 16px;
}
.hack-steps {
  margin: 0 0 16px;
  padding-left: 20px;
  counter-reset: hack-step;
}
.hack-steps li {
  font-size: 16px;
  line-height: 28px;
  font-weight: 500;
  color: var(--color-content-black2);
  margin-bottom: 14px;
}
.hack-steps li strong {
  color: var(--novix-ink);
  font-weight: 700;
}

/* Closing CTA inside the guidance block. */
.hack-cta {
  margin-top: 40px;
  padding: 36px;
  border-radius: 20px;
  background: var(--gradient-btn-1);
}
.hack-cta-title {
  font-size: 24px;
  font-weight: 600;
  color: var(--novix-text-on-dark);
  margin: 0 0 14px;
}
.hack-cta p {
  font-size: 16px;
  line-height: 28px;
  font-weight: 500;
  color: var(--novix-text-on-dark);
  margin: 0 0 24px;
  opacity: 0.92;
}

/* Dark mode: panels move to the ink-tint surface and text is re-lit, the
   same treatment the downtime tool uses. The result-state tints keep their
   light fills but are dimmed slightly so they read on the dark panel. */
.active-body .hack-intro p,
.active-body .hack-panel-lead,
.active-body .hack-guidance p,
.active-body .hack-steps li,
.active-body .hack-note {
  color: var(--novix-muted-on-dark);
}
.active-body .hack-intro .title,
.active-body .hack-panel-title,
.active-body .hack-guidance-title,
.active-body .hack-form label,
.active-body .hack-steps li strong,
.active-body .hack-breach-list li {
  color: var(--novix-text-on-dark);
}
.active-body .hack-panel {
  background: var(--novix-ink-tint);
  border-color: rgba(255, 255, 255, 0.14);
}
.active-body .hack-input-wrap input {
  color: var(--novix-text-on-dark);
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.18);
}
.active-body .hack-input-wrap input:focus {
  border-color: var(--novix-light-blue);
  box-shadow: 0 0 0 3px rgba(10, 211, 251, 0.2);
}
.active-body .hack-input-wrap input::placeholder {
  color: var(--novix-muted-on-dark);
}
.active-body .hack-reveal {
  color: var(--novix-light-blue);
}
.active-body .hack-result {
  color: var(--novix-text-on-dark);
}
.active-body .hack-result span {
  color: var(--novix-muted-on-dark);
}
.active-body .hack-result-clear {
  background: rgba(31, 157, 99, 0.16);
  border-color: rgba(31, 157, 99, 0.3);
  border-left-color: #34c27e;
}
.active-body .hack-result-found,
.active-body .hack-result-warn {
  background: rgba(201, 135, 26, 0.16);
  border-color: rgba(201, 135, 26, 0.32);
  border-left-color: #e0a43b;
}
.active-body .hack-result-error {
  background: rgba(192, 57, 43, 0.16);
  border-color: rgba(192, 57, 43, 0.32);
  border-left-color: #e06453;
}
.active-body .hack-soon {
  background: rgba(255, 255, 255, 0.03);
  border-color: rgba(255, 255, 255, 0.2);
}
.active-body .hack-soon p {
  color: var(--novix-muted-on-dark);
}
.active-body .hack-soon a,
.active-body .hack-soon-badge {
  color: var(--novix-light-blue);
}
.active-body .hack-soon-badge {
  background: rgba(10, 211, 251, 0.12);
}

/* ============================================================
   Services overview (hub) — purpose-built card grid
   Used only by services.php. Same approach as the downtime-tool /
   hack-tool / plans-matrix blocks: a self-contained brand component
   (light + full dark mode) rather than an Aiero photo-overlay card,
   so the six pillars read as one intentional grid without depending
   on six hero photos. Cards link through to the full pillar pages.
   ============================================================ */
.services-hub .row {
  margin-bottom: -28px;
}
.service-hub-card {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  margin-bottom: 28px;
  padding: 38px 34px 34px;
  background: var(--novix-paper-elev-1);
  border: 1px solid var(--novix-rule);
  border-radius: 24px;
  transition: border-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
}
.service-hub-card:hover {
  transform: translateY(-4px);
  border-color: var(--novix-light-blue);
  box-shadow: 0 18px 40px rgba(2, 16, 45, 0.08);
}
.service-hub-card .shc-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  margin-bottom: 24px;
  border-radius: 14px;
  background: var(--novix-gradient);
  color: #ffffff;
  font-size: 20px;
}
.service-hub-card .shc-icon i {
  color: #ffffff;
}
.service-hub-card .shc-tag {
  display: inline-block;
  margin-bottom: 12px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--novix-light-blue-shade);
}
.service-hub-card .shc-title {
  font-size: 26px;
  line-height: 32px;
  font-weight: 400;
  margin-bottom: 14px;
  color: var(--novix-ink);
}
.service-hub-card .shc-title a {
  color: inherit;
  transition: color 0.3s ease;
}
.service-hub-card .shc-title a:hover {
  color: var(--novix-dark-blue);
}
.service-hub-card .shc-desc {
  font-size: 16px;
  line-height: 26px;
  font-weight: 500;
  margin-bottom: 22px;
  color: var(--color-content-black2);
}
.service-hub-card .shc-link {
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--novix-dark-blue);
  transition: gap 0.3s ease, color 0.3s ease;
}
.service-hub-card .shc-link i {
  font-size: 12px;
}
.service-hub-card .shc-link:hover {
  gap: 16px;
  color: var(--novix-purple);
}

/* Dark mode */
.active-body .service-hub-card {
  background: var(--novix-ink-tint);
  border-color: rgba(255, 255, 255, 0.14);
}
.active-body .service-hub-card:hover {
  border-color: var(--novix-light-blue);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.4);
}
.active-body .service-hub-card .shc-title {
  color: var(--novix-text-on-dark);
}
.active-body .service-hub-card .shc-title a:hover {
  color: var(--novix-light-blue);
}
.active-body .service-hub-card .shc-desc {
  color: var(--novix-muted-on-dark);
}
.active-body .service-hub-card .shc-tag {
  color: var(--novix-light-blue);
}
.active-body .service-hub-card .shc-link {
  color: var(--novix-light-blue);
}
.active-body .service-hub-card .shc-link:hover {
  color: var(--novix-light-blue-tint);
}

/* ----------------------------------------------------------------
   Location pages: "Did you know?" local-fact callout.
   One per page, carries the place's signature historical / technology
   fact -- the main thing that makes each location page individual
   rather than templated. Sits inside .ser-detail. Brand-gradient spine
   on the left, muted surface, full dark mode. ------------------- */
.local-fact {
  position: relative;
  margin: 44px 0;
  padding: 28px 34px 28px 38px;
  background: var(--novix-paper-elev-3);
  border-radius: 14px;
  overflow: hidden;
}
.local-fact::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 6px;
  background: var(--gradient-btn-1);
}
.local-fact .local-fact-eyebrow {
  display: block;
  margin-bottom: 10px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--novix-dark-blue);
}
.local-fact p {
  margin: 0;
  font-size: 19px;
  line-height: 1.6;
}
.local-fact .local-fact-source {
  display: block;
  margin-top: 12px;
  font-size: 14px;
  color: #676767;
}
.active-body .local-fact {
  background: var(--novix-ink-tint);
}
.active-body .local-fact .local-fact-eyebrow {
  color: var(--novix-light-blue);
}
.active-body .local-fact .local-fact-source {
  color: var(--novix-muted-on-dark);
}

/* ================================================================
   Location pages — sections below the map
   ================================================================ */

/* Capabilities: reuses Aiero .service-sec17 / .ser-card17 unchanged (glass
   icons, title, blurb, list, "Services full list" link). The only gap is
   the Aiero card has no dark-mode text colours, so add them here. */
.active-body .ser-card17 .title {
  color: var(--novix-text-on-dark);
}
.active-body .ser-card17 p,
.active-body .ser-card17 .ser-list17 li {
  color: var(--novix-muted-on-dark);
}
.active-body .ser-card17 .ser-list17 li::before {
  background-color: var(--novix-light-blue);
}

/* "Did you know?" -> Aiero .service-sec27 two-card layout (INDEX17).
   The whole section is ALWAYS dark: the did-you-know-bg.png swirl (which
   carries its own top/bottom fade) behind two translucent dark cards.
   Because the section is dark in both modes, the cards / text / icons
   never need to flip colour. */
.service-sec27 {
  position: relative;
  padding: 190px 0 170px;
  background-image: url(../backgrounds/did-you-know-bg.png);
  background-size: cover;
  background-position: center;
  overflow: hidden;
  border-radius: 0 0 25px 25px; /* round the bottom corners to match the footer */
}
/* No CSS fade: did-you-know-bg.png carries its own top/bottom fade. */
.service-sec27 .container {
  position: relative;
  z-index: 2;
}
.service-sec27 .sec-title .sub-title {
  color: var(--novix-light-blue);
}
.service-sec27 .ser-card27 {
  min-height: 520px;
  padding: 56px 56px 0;
  overflow: hidden;
  border-radius: 20px;
  background-color: rgba(2, 16, 45, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.service-sec27 .ser-card27 .ser27-dots {
  position: absolute;
  top: 60px;
  right: 56px;
  /* the dots.png canvas (225x225) has big transparent padding; the actual
     dots sit in a 201x103 region at (12,97). Crop the box to that region
     and offset the background so the dot block aligns cleanly to the
     top-right of the card. */
  width: 201px;
  height: 103px;
  background-image: url(../patterns/dots.png);
  background-repeat: no-repeat;
  background-size: 225px 225px;
  background-position: -12px -97px;
  opacity: 0.85;
}
.service-sec27 .ser-card27 .title {
  max-width: 440px;
}
.service-sec27 .ser-card27 img {
  position: absolute;
  left: 56px;
  right: 56px;
  bottom: 0;
  width: auto;
  height: 290px;
  object-fit: cover;
  border-radius: 20px 20px 0 0;
}
.service-sec27 .ser-card27_card3 {
  min-height: 520px;
  border-radius: 20px;
  overflow: hidden;
  background-color: rgba(2, 16, 45, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.service-sec27 .ser-content27 .title {
  color: #ffffff;
  font-size: 24px;
  font-weight: 700;
}
.service-sec27 .ser-content27 p {
  color: var(--novix-muted-on-dark);
}
.service-sec27 .ser-link27 .social-icon {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.service-sec27 .ser-link27 .social-icon li {
  margin: 0;
}
.service-sec27 .ser-link27 .social-icon a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: #ffffff;
  font-size: 17px;
  transition: transform 0.3s ease;
}
.service-sec27 .ser-link27 .social-icon a:hover {
  transform: translateY(-3px);
}
.service-sec27 .ser-link27 .social-icon a .fa-linkedin-in {
  color: #0a66c2;
}
.service-sec27 .ser-link27 .social-icon a .fa-x-twitter {
  color: #000000;
}
@media (max-width: 991px) {
  .service-sec27 {
    padding: 130px 0 120px;
  }
  .service-sec27 .ser-card27 {
    margin-bottom: 28px;
  }
}

/* ================================================================
   "Areas we cover" hub
   ================================================================ */
.areas-intro .sec-title {
  margin-bottom: 0;
}
.areas-region {
  margin-bottom: 44px;
}
.areas-region:last-child {
  margin-bottom: 0;
}
.areas-region-title {
  margin-bottom: 26px;
  padding-bottom: 14px;
  font-size: 24px;
  font-weight: 600;
  color: var(--novix-ink);
  border-bottom: 1px solid var(--novix-rule);
}
.area-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: 100%;
  margin-bottom: 24px;
  padding: 26px 28px;
  background: var(--novix-paper-elev-1);
  border: 1px solid var(--novix-rule);
  border-radius: 18px;
  transition: border-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
}
a.area-card:hover {
  border-color: var(--novix-light-blue);
  transform: translateY(-4px);
  box-shadow: 0 16px 34px rgba(2, 16, 45, 0.08);
}
.area-card .area-name {
  font-size: 22px;
  line-height: 1.2;
  color: var(--novix-ink);
  font-family: var(--font-secondary);
}
.area-card .area-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--novix-dark-blue);
}
.area-card .area-link i {
  font-size: 11px;
}
.area-card-soon {
  opacity: 0.55;
}
.area-card-soon .area-link {
  color: var(--color-content-black2);
}
.active-body .areas-region-title {
  color: var(--novix-text-on-dark);
  border-color: rgba(255, 255, 255, 0.14);
}
.active-body .area-card {
  background: var(--novix-ink-tint);
  border-color: rgba(255, 255, 255, 0.12);
}
.active-body .area-card .area-name {
  color: var(--novix-text-on-dark);
}
.active-body .area-card .area-link {
  color: var(--novix-light-blue);
}

/* ================================================================
   "Areas we cover" hero — interactive UK coverage map
   The hero rides .page-banner4's navy inset card (page-banner-areas),
   but instead of a photo it holds a two-column layout: copy on the left,
   the dotted UK map with animated arcs/pins on the right. The map base is
   a static SVG (assets/backgrounds/uk-dotted-map.svg); areas-map.js draws
   the live arcs/pins overlay on top in the same viewBox coordinate space.
   ================================================================ */
.page-banner-areas,
.page-banner-areas > .page-banner-inner {
  /* No photo on this hero — clear Aiero's stock placeholder image and its
     dark overlay so only the navy card shows behind the map. */
  background-image: none;
}
/* The navy card. Below 1202px there is no inset frame, so the section itself
   is the navy banner; the desktop block below restores the grey/dark frame
   around the card and keeps only .page-banner-inner navy. */
.page-banner-areas,
.page-banner-areas > .page-banner-inner {
  background-color: var(--novix-ink);
}
.areas-hero-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 36px;
  align-items: center;
}
.areas-hero-copy {
  text-align: center;
}
.areas-hero-eyebrow {
  display: inline-block;
  margin-bottom: 16px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--novix-light-blue);
}
.areas-hero-eyebrow::before { content: "[ "; opacity: 0.6; }
.areas-hero-eyebrow::after  { content: " ]"; opacity: 0.6; }
.areas-hero-copy .title {
  color: var(--novix-text-on-dark);
  margin: 0 0 20px;
  /* Keep "/ Areas We Cover /" on a single line; scale so it fits the hero
     copy column at every width. */
  font-size: clamp(32px, 4.4vw, 58px);
  white-space: nowrap;
}
.areas-hero-copy p {
  color: var(--novix-muted-on-dark);
  margin: 0 auto 28px;
  max-width: 32em;
}

/* Map: container locked to the basemap's 59:90 ratio so the absolutely
   positioned overlay lines up with the dots pixel-for-pixel. */
.areas-hero-map {
  display: flex;
  justify-content: center;
}
.uk-map {
  position: relative;
  width: 100%;
  max-width: 260px;
  margin: 0 auto;
  aspect-ratio: 59 / 90;
}
.uk-map-base {
  display: block;
  width: 100%;
  height: 100%;
}
.uk-map-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible; /* let pulse rings and labels spill past the edge */
}
.uk-arc {
  fill: none;
  stroke: var(--novix-light-blue);
  stroke-width: 0.45;
  stroke-linecap: round;
  opacity: 0.5;
}
.uk-arc-pulse {
  fill: #d4f6ff;
}
.uk-pin-ring {
  fill: var(--novix-light-blue);
}
.uk-pin-dot {
  fill: var(--novix-light-blue);
  transition: r 0.2s ease;
}
.uk-pin-hq .uk-pin-dot {
  fill: #ffffff;
}
.uk-pin-core {
  fill: var(--novix-dark-blue);
}
.uk-pin {
  cursor: pointer;
}
.uk-pin:hover .uk-pin-dot,
.uk-pin:focus .uk-pin-dot {
  r: 1.5;
}
.uk-pin-hq:hover .uk-pin-dot,
.uk-pin-hq:focus .uk-pin-dot {
  r: 1.9;
}
.uk-pin-label {
  fill: var(--novix-text-on-dark);
  font-family: var(--font-primary);
  font-size: 2.5px;
  font-weight: 600;
  opacity: 0;
  transition: opacity 0.25s ease;
  paint-order: stroke;
  stroke: var(--novix-ink);
  stroke-width: 0.6px;
  stroke-linejoin: round;
}
.uk-pin:hover .uk-pin-label,
.uk-pin:focus .uk-pin-label {
  opacity: 1;
}
.uk-pin-label.is-hq {
  opacity: 1;
  fill: var(--novix-light-blue);
}
@keyframes uk-arc-draw {
  to { stroke-dashoffset: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .uk-arc { opacity: 0.5; stroke-dashoffset: 0 !important; }
}
@media (min-width: 992px) {
  .areas-hero-grid {
    grid-template-columns: 1.1fr 0.9fr;
    gap: 50px;
  }
  .areas-hero-copy {
    text-align: left;
  }
  .areas-hero-copy p {
    margin-left: 0;
    margin-right: 0;
  }
  .uk-map {
    max-width: 268px;
  }
}

/* Desktop: the Areas hero rides the same navy inset card as the photo
   banners. With a smaller map the card now matches the standard banner
   height (~542px), so the copy and map sit centred with even padding
   instead of a tall column of empty navy above and below. */
@media (min-width: 1202px) {
  /* Restore the inset-card frame: the section is the grey/dark zone (mode
     aware), only the inner card stays navy. */
  .page-banner-areas {
    background-color: var(--novix-paper-elev-4);
  }
  .page-banner-areas > .page-banner-inner {
    padding: 64px 64px 64px;
  }
}

/* ================================================================
   Location pages — "Other areas we cover" cross-links
   A compact chip row of the nearest live locations, so each location
   page links to its siblings (not just up to the hub).
   ================================================================ */
.nearby-sec .sec-title {
  margin-bottom: 32px;
}
.nearby-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: center;
}
.nearby-card {
  display: inline-flex;
  flex-direction: column;
  gap: 6px;
  min-width: 168px;
  padding: 18px 24px;
  background: var(--novix-paper-elev-1);
  border: 1px solid var(--novix-rule);
  border-radius: 14px;
  transition: border-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
}
.nearby-card:hover {
  border-color: var(--novix-light-blue);
  transform: translateY(-3px);
  box-shadow: 0 14px 30px rgba(2, 16, 45, 0.08);
}
.nearby-name {
  font-size: 19px;
  line-height: 1.2;
  color: var(--novix-ink);
  font-family: var(--font-secondary);
}
.nearby-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 600;
  color: var(--novix-dark-blue);
}
.nearby-link i {
  font-size: 10px;
}
.nearby-all-wrap {
  margin-top: 30px;
  text-align: center;
}
.nearby-all {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 600;
  color: var(--novix-dark-blue);
}
.nearby-all i {
  font-size: 11px;
}
.active-body .nearby-card {
  background: var(--novix-ink-tint);
  border-color: rgba(255, 255, 255, 0.12);
}
.active-body .nearby-name {
  color: var(--novix-text-on-dark);
}
.active-body .nearby-link,
.active-body .nearby-all {
  color: var(--novix-light-blue);
}

/* ──────────────────────────────────────────────────────────────────────────
   Hero / page-banner H1 — hold the title on a single line so wrapping never
   changes the hero height.

   The per-page fixes above (.page-banner-bdd, .page-banner-location) each
   widened the centred 877px .page-content box and applied white-space:nowrap
   so a long title would not drop a word onto a second line and grow the hero.
   This block generalises that to EVERY .page-banner4 hero — present and future
   — so every banner title behaves the same without per-page CSS.

   Desktop (>=1202px): widen the box to the full container and nowrap the title
   at the uniform 80px. Below 1202px the title may wrap (expected on tablet /
   mobile, where one line is not achievable at a readable size); text-wrap:balance
   keeps those wraps even and intentional rather than leaving an orphan word.

   The earlier .page-banner-bdd (1100px) and .page-banner-location (1200px) box
   widths are more specific, so they still win on those pages — left untouched.

   Editor: Ricci van Eeden — 2026-06-30
   ────────────────────────────────────────────────────────────────────────── */
.page-banner4 .page-content .title {
  text-wrap: balance;
}
@media (min-width: 1202px) {
  .page-banner4 .page-content {
    max-width: 1340px;
  }
  .page-banner4 .page-content .title {
    white-space: nowrap;
  }
}

/* Two titles are long enough to overrun even the full-width box on a narrow
   desktop ("/ Microsoft Office vs Office.eu /" and "/ Downtime Cost Calculator /").
   Ease the size on the 1202–1366px band only so they still hold one line there;
   they return to the uniform 80px on wider screens where they already fit. */
@media (min-width: 1202px) and (max-width: 1366px) {
  .page-banner-versus .page-content .title,
  .page-banner-downtime .page-content .title {
    font-size: 62px;
    line-height: 1.05;
  }
}

/* Homepage hero is a sentence, not a label, so it is meant to wrap across
   lines — just balance those lines so the break sits evenly. */
.hero-sec-info3 .title {
  text-wrap: balance;
}

/* ── Side menu footer photo ──
   Replaces the template's grey 389x188 placeholder (offcanvas.png) that
   sits as a full-bleed band at the foot of the slide-out side menu. The
   brand photo is the same 389x188, so it drops straight into the slot;
   we just round the bottom corners to match the panel's 20px radius. */
.side-menu::after {
  background-image: url(../team-photos/side-menu-footer.jpg);
  background-position: center;
  border-radius: 0 0 20px 20px;
}

/* ── Contact form guard rails ──
   Supports includes/contact-form.php's spam defences and the fixed
   failure path in contact-handler.php.
   .cf-extra      honeypot wrapper: moved off-screen (not display:none, so
                  naive bots still "see" and fill the field)
   .cf-turnstile  Cloudflare Turnstile widget slot (renders only when keys
                  are configured; see includes/turnstile.php)
   .cf-error      notice shown on /contact?contact=error */
.cf-extra {
  position: absolute !important;
  left: -9999px !important;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.contact-form .cf-turnstile {
  margin: 0 0 18px;
}

.cf-error {
  background: rgba(223, 13, 226, 0.08);
  border: 1px solid rgba(223, 13, 226, 0.35);
  border-radius: 12px;
  padding: 14px 18px;
  margin: 0 0 18px;
  font-size: 15px;
  line-height: 1.5;
}

.cf-error a {
  font-weight: 600;
  text-decoration: underline;
}

.active-body .cf-error {
  background: rgba(223, 13, 226, 0.14);
  border-color: rgba(223, 13, 226, 0.5);
  color: var(--novix-text-on-dark);
}

/* ── Contact form thank-you modal ──
   Shown by assets/js/contact-form.js after a successful background submit
   (the /contact-thanks page remains the no-JavaScript fallback and the
   copy source; keep the two in step). Click the overlay, the Close button
   or press Escape to dismiss. */
.cf-modal {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(2, 16, 45, 0.6);
  z-index: 9999;
  padding: 20px;
}

.cf-modal.open {
  display: flex;
}

.cf-modal-card {
  background: #fff;
  border-radius: 20px;
  padding: 44px 40px;
  max-width: 520px;
  width: 100%;
  text-align: center;
}

.cf-modal-card .title {
  margin: 0 0 14px;
  font-size: 30px;
  line-height: 1.2;
}

.cf-modal-card p {
  margin: 0 0 26px;
  line-height: 1.6;
}

.cf-modal-card p a {
  font-weight: 600;
}

.active-body .cf-modal-card {
  background: var(--novix-ink-elev-1);
  border: 1px solid rgba(255, 255, 255, 0.14);
}

.active-body .cf-modal-card .title,
.active-body .cf-modal-card p {
  color: var(--novix-text-on-dark);
}

/* Send button while the background submit is in flight */
.cf-busy {
  opacity: 0.6;
  pointer-events: none;
}

/* ── Thank-you page: "what happens next" steps ──
   Three centred steps under the confirmation on /contact-thanks. */
.thanks-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
  max-width: 1040px;
  margin: 24px auto 0;
  text-align: center;
}

.thanks-step {
  background: var(--novix-paper-elev-4);
  border-radius: 20px;
  padding: 34px 26px;
}

.thanks-step-num {
  display: inline-block;
  font-weight: 700;
  font-size: 15px;
  background: var(--gradient-btn-1);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  margin-bottom: 12px;
}

.thanks-step .title {
  margin: 0 0 10px;
  font-size: 20px;
}

.thanks-step p {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
}

@media (max-width: 991px) {
  .thanks-steps {
    grid-template-columns: 1fr;
    max-width: 560px;
  }
}

.active-body .thanks-step {
  background: var(--novix-ink-elev-1);
}

.active-body .thanks-step .title {
  color: var(--novix-text-on-dark);
}

.active-body .thanks-step p {
  color: var(--novix-muted-on-dark);
}

/* ============================================================
   Homepage pre-launch tweaks (2026-07)
   ============================================================ */

/* Hero: two CTAs side by side, stacking full-width on mobile.
   Wraps the two .ibt-btn links in .hero-btn2 so the description
   <p> above is unaffected. */
.hero-btn2 .hero-btn-row {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex-wrap: wrap;
      -ms-flex-wrap: wrap;
          flex-wrap: wrap;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
  gap: 14px;
}
/* Slightly tighter horizontal padding than the default .ibt-btn (26px)
   so both CTAs sit on one line inside the hero content column; they
   still wrap gracefully on narrower viewports. */
.hero-btn2 .hero-btn-row .ibt-btn {
  padding-left: 22px;
  padding-right: 22px;
}
@media (max-width: 480px) {
  .hero-btn2 .hero-btn-row {
    gap: 12px;
    width: 100%;
  }
  .hero-btn2 .hero-btn-row .ibt-btn {
    width: 100%;
    -webkit-box-pack: center;
    -webkit-justify-content: center;
        -ms-flex-pack: center;
            justify-content: center;
  }
}

/* CSAT block: demote the proof line to a small asterisked footnote
   so the card reads as a stat, not a sales claim. The .black card
   sits on a dark navy background in BOTH light and dark mode, so the
   note stays light in both. */
.fun-fact-content.black .fun-fact-note {
  display: block;
  margin-top: 10px;
  font-size: 13px;
  line-height: 18px;
  color: rgba(255, 255, 255, 0.6);
}
.fun-fact-content.black .fun-fact-asterisk {
  font-size: 0.4em;
  vertical-align: super;
  -webkit-text-fill-color: currentColor;
}

/* Dark-mode fix: the .black card inverts to a LIGHT surface in dark
   mode (semantic tokens flip). The title inverts to dark correctly,
   but the caption <p>, the footnote and the big "100%" counter stayed
   light and vanished on the light card. Force all three dark to match
   the title. Hex is pinned (not the inverting tokens) so the outcome
   holds regardless of theme token flips. */
.active-body .fun-fact-content.black p,
.active-body .fun-fact-content.black .counter-box {
  color: #02102d;
  -webkit-text-fill-color: #02102d;
}
.active-body .fun-fact-content.black .fun-fact-note {
  color: rgba(2, 16, 45, 0.6);
}

/* "What We Do": below ~1300px the text column grows taller than the
   fixed-ratio photo, leaving dark gaps above/below the photo and
   throwing the centred watermark off. Let the photo fill its column
   height (cover-crop) so it is always flush, top to bottom. The photo
   width and the wide-screen look are unchanged; only the vertical fill
   changes. The cover rules must target the <picture> child (the AVIF
   swap moved the <img> a level deeper, so the old `.choose-img5 > img`
   rule no longer reached the photo). */
.choose-us-sec5 .col-xl-5 {
  -webkit-align-self: stretch;
      -ms-flex-item-align: stretch;
          align-self: stretch;
}
.choose-img5 {
  height: 100%;
}
.choose-img5 > picture {
  display: block;
  width: 100%;
  height: 100%;
}
.choose-img5 > picture > img {
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
  display: block;
}

/* Nav: show the dropdown caret only on items that actually have a
   submenu. The Aiero base adds the arrow to EVERY top-level item
   (style.css: .menu-style1 > ul > li > a::before) and reserves 42px
   right padding for it, so Home and Contact — which have no dropdown —
   were showing a stray caret. main-menu.php now tags parents with
   .has-dropdown; hide the arrow and reclaim the padding on the rest. */
.menu-style1 > ul > li:not(.has-dropdown) > a::before {
  display: none;
}
.menu-style1 > ul > li:not(.has-dropdown) > a {
  padding-right: 22px;
}

/* Dark mode: How We Work (.faq-sec3) and Testimonials (.testimonial-sec2)
   both fell to --novix-ink-elev-1, so the two adjacent sections merged
   into one dark "wall". Drop How We Work to the deepest ink so the bands
   read as distinct steps down the page (FAQ body -> How We Work #02102D
   -> Testimonials #0E1B3F -> Pricing body). Only Testimonials carries the
   gradient overlay tied to ink-elev-1, so changing How We Work keeps that
   intact. */
.active-body .faq-sec3 {
  background-color: var(--novix-ink);
}

/* ---- Section scroll tracker -------------------------------
   Fixed dot-nav on the right that highlights the section currently in
   view (IntersectionObserver in index.php). Desktop only — it needs the
   side gutter, so it is hidden until there is room for it. */
.section-tracker {
  position: fixed;
  top: 50%;
  left: 20px;
  -webkit-transform: translateY(-50%);
      -ms-transform: translateY(-50%);
          transform: translateY(-50%);
  z-index: 60;
  display: none;
  /* Hidden over the hero; JS adds .is-visible once the hero scrolls away. */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  -webkit-transition: opacity 0.3s ease, visibility 0.3s ease;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}
@media (min-width: 1400px) {
  .section-tracker {
    display: block;
  }
}
.section-tracker.is-visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
/* Clear the tracker: only "What We Do" has content reaching the left edge,
   so at >=1400px (where the tracker shows) pad the section in from the left
   so the photo clears the dot-nav.

   NOT applied to the director pages, deliberately. The expanded tracker
   label overlaps left-edge content there between 1400px and about 1630px
   (the label ends at 141px; those sections start their text at 62px at
   1440px), and it has done so on Selected work and Leadership since they
   were built. Indenting one section would make it the one misaligned band
   on the page without fixing the others, and indenting all of them means
   moving the profile row's photo column. Logged as its own job instead:
   docs/POST-LAUNCH-LIST.md. */
@media (min-width: 1400px) {
  .choose-us-sec5 {
    padding-left: 145px;
  }
}
.section-tracker ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
      -ms-flex-direction: column;
          flex-direction: column;
  gap: 15px;
}
.section-tracker li {
  margin: 0;
}
.section-tracker a {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: start;
  -webkit-justify-content: flex-start;
      -ms-flex-pack: start;
          justify-content: flex-start;
  gap: 10px;
  text-decoration: none;
}
.section-tracker .st-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--novix-blue-tint);
  opacity: 0.4;
  -webkit-box-flex: 0;
  -webkit-flex: none;
      -ms-flex: none;
          flex: none;
  -webkit-transition: all 0.25s ease;
  transition: all 0.25s ease;
}
.section-tracker .st-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--novix-ink);
  background: var(--novix-paper);
  padding: 4px 11px;
  border-radius: 7px;
  -webkit-box-shadow: 0 2px 10px rgba(2, 16, 45, 0.12);
          box-shadow: 0 2px 10px rgba(2, 16, 45, 0.12);
  opacity: 0;
  -webkit-transform: translateX(-8px);
      -ms-transform: translateX(-8px);
          transform: translateX(-8px);
  -webkit-transition: all 0.25s ease;
  transition: all 0.25s ease;
  white-space: nowrap;
  pointer-events: none;
}
.section-tracker a:hover .st-label,
.section-tracker a.active .st-label {
  opacity: 1;
  -webkit-transform: translateX(0);
      -ms-transform: translateX(0);
          transform: translateX(0);
}
.section-tracker a:hover .st-dot {
  opacity: 1;
}
.section-tracker a.active .st-dot {
  opacity: 1;
  width: 12px;
  height: 12px;
  background: var(--novix-dark-blue);
  -webkit-box-shadow: 0 0 0 4px rgba(15, 119, 249, 0.18);
          box-shadow: 0 0 0 4px rgba(15, 119, 249, 0.18);
}
/* Dark mode */
.active-body .section-tracker .st-label {
  color: #ffffff;
  background: var(--novix-ink-tint);
  -webkit-box-shadow: 0 2px 12px rgba(0, 0, 0, 0.4);
          box-shadow: 0 2px 12px rgba(0, 0, 0, 0.4);
}
.active-body .section-tracker a.active .st-dot {
  background: var(--novix-light-blue);
  -webkit-box-shadow: 0 0 0 4px rgba(10, 211, 251, 0.22);
          box-shadow: 0 0 0 4px rgba(10, 211, 251, 0.22);
}

/* ---- Theme control: Light / System / Dark tabs -------------
   Horizontal segmented pill living in the header button-box (between the
   search icon and Get in Touch), the mobile menu, and docked top-right on
   the standalone 404. Local, dependency-free; behaviour in main.js. */
.theme-tabs {
  display: -webkit-inline-box;
  display: -webkit-inline-flex;
  display: -ms-inline-flexbox;
  display: inline-flex;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -webkit-flex-direction: row;
      -ms-flex-direction: row;
          flex-direction: row;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: var(--novix-paper-elev-3);
  border: 1px solid var(--novix-paper-elev-4);
  vertical-align: middle;
}
/* 404 has no header bar: pin the control top-right there. */
.theme-tabs-dock {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 99999;
}
/* Mobile slide-out menu placement. */
.menu-theme-tabs {
  margin: 12px 0 4px;
}
/* Mobile menu: pin the theme control top-left, opposite the search/close
   pair (which sit top-right), so it is visible the moment the menu opens. */
.side-menu2 .menu-theme-tabs-top {
  position: absolute;
  top: 22px;
  left: 30px;
  margin: 0;
  z-index: 100;
}
/* Mobile menu chevron: the Aiero base draws TWO arrows on every item — one
   on the <a> (`li > a::before`) and one on the `.sub-menu` li. The <a> one
   inherits the link colour, so it lit up light-blue on sticky touch-hover
   and "ghosted" after collapse. Drop the <a> arrow entirely and keep only
   the `.sub-menu::before` one (which lives on the li, so it only shows on
   real dropdown items and never inherits the hover colour). */
.side-menu2 > ul > li > a::before {
  display: none;
}
/* Cancel sticky :hover on touch devices — after a tap the link kept
   :hover and stayed blue once collapsed. Only the expanded (.active)
   parent stays highlighted. */
@media (hover: none) {
  .side-menu2 > ul > li > a:hover,
  .side-menu2 > ul ul li a:hover {
    color: #333;
  }
  .active-body .side-menu2 > ul > li > a:hover,
  .active-body .side-menu2 > ul ul li a:hover {
    color: var(--color-content-white);
  }
  .side-menu2 > ul > li.active > a:hover {
    color: var(--color-primary);
  }
}
/* Mobile: centre the logo in the header. The hamburger is absolute-right
   and the menu / button-box columns are hidden at this width, so the row
   just needs centring (the hamburger overlays the right edge). */
@media (max-width: 1200px) {
  .header-menu-area > .row {
    -webkit-box-pack: center !important;
    -webkit-justify-content: center !important;
        -ms-flex-pack: center !important;
            justify-content: center !important;
  }
}

/* Smooth tap-to-expand. Aiero animated `height: 0 -> height: 100%` (and our
   first fix set `height: auto`), but height can't transition to/from auto or a
   percentage of an auto-height parent, so the submenu snapped open and shut.
   The fix is the CSS grid 0fr->1fr row trick: the li.sub-menu is the grid
   container (row 1 = the link, row 2 = the submenu <ul>), and the second track
   grows from 0fr to 1fr — which resolves to the <ul>'s natural content height,
   so it eases open to exactly the right size with no guessed pixel value
   (max-height would over/undershoot and lag on close). The <ul> clips its own
   overflow while the track is collapsed. Chevron rotates in sync; the opacity
   fade already on `.side-menu2 > ul ul` rides along. reduced-motion users get
   the original instant behaviour. */
.side-menu2 > ul > li.sub-menu {
  display: grid;
  /* minmax(0, ...) rather than a bare 0fr so the collapsed track is a true 0 —
     a bare 0fr keeps the <ul>'s min-content (its top padding) as a ~7px sliver
     that would space the dropdown items unevenly against the leaf links. */
  grid-template-rows: auto minmax(0, 0fr);
  -webkit-transition: grid-template-rows 300ms ease;
  transition: grid-template-rows 300ms ease;
}
.side-menu2 > ul > li.sub-menu.active {
  grid-template-rows: auto minmax(0, 1fr);
}
.side-menu2 > ul > li.sub-menu > ul,
.side-menu2 > ul > li.sub-menu.active > ul {
  height: auto;
  min-height: 0;
  overflow: hidden;
}
.side-menu2 .sub-menu::before {
  -webkit-transition: -webkit-transform 300ms ease;
  transition: transform 300ms ease;
}
@media (prefers-reduced-motion: reduce) {
  .side-menu2 > ul > li.sub-menu {
    -webkit-transition: none;
    transition: none;
  }
}
/* Submenu child links were a fixed 34px, so two-line labels (e.g. "Senior
   Leadership Team", "Business Development Director") overflowed onto the
   next item. Let them grow. */
.side-menu2 > ul ul li a {
  height: auto;
  min-height: 34px;
}
.theme-tab {
  width: 30px;
  height: 30px;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
      -ms-flex-pack: center;
          justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--novix-ink);
  opacity: 0.5;
  cursor: pointer;
  -webkit-transition: all 0.2s ease;
  transition: all 0.2s ease;
}
.theme-tab svg {
  width: 16px;
  height: 16px;
}
.theme-tab:hover {
  opacity: 1;
}
.theme-tab.active {
  opacity: 1;
  background: var(--novix-ink);
  color: #ffffff;
}
.theme-tab:focus-visible {
  outline: 2px solid var(--novix-dark-blue);
  outline-offset: 2px;
}
/* Dark mode */
.active-body .theme-tabs {
  background: var(--novix-ink-elev-1);
  border-color: rgba(255, 255, 255, 0.08);
}
.active-body .theme-tab {
  color: #ffffff;
}
.active-body .theme-tab.active {
  background: var(--novix-light-blue);
  color: var(--novix-ink);
}

/* Even out the header button-box: the search icon carried a 30px
   margin-right, leaving the theme pill flush against Get in Touch. Use a
   shared gap so search / theme control / button are evenly spaced. */
.btn-box {
  gap: 18px;
}
.btn-box .popup-search {
  margin-right: 0;
}

/* About page — team cards link to each director's page.
   The whole photo tile is clickable via a transparent overlay anchor inside
   .team-img (which is position:relative, z-index:9). The overlay sits above
   the image but the .share-box (z-index:999) keeps the LinkedIn icon on top
   and independently clickable. The name link points at the same page. */
.team-card .team-img {
  position: relative;
}
.team-card .team-card-link {
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: 25px;
}

/* About page — certifications & partnerships. On-brand credential cards
   (replacing the Aiero stock-logo swiper) presented in a scrolling marquee.
   Official badge artwork, when supplied, drops into
   assets/images/certifications/<slug>.(svg|png|webp) and the .cert-mark--img
   img replaces the placeholder icon (see about.php). */
.cert-marquee {
  margin-top: 12px;
  width: 100%;
  overflow: hidden;
  white-space: nowrap;
}
.cert-marquee .marquee-inner {
  -webkit-animation-duration: 32s;
          animation-duration: 32s;
}
.cert-marquee:hover .marquee-inner,
.cert-marquee:focus-within .marquee-inner {
  -webkit-animation-play-state: paused;
          animation-play-state: paused;
}
.cert-set {
  display: inline-block;
  white-space: nowrap;
}
.cert-marquee .cert-card {
  display: -webkit-inline-box;
  display: -webkit-inline-flex;
  display: -ms-inline-flexbox;
  display: inline-flex;
  vertical-align: middle;
  margin-right: 16px;
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .cert-marquee { white-space: normal; }
  .cert-marquee .marquee-inner {
    -webkit-animation: none;
            animation: none;
  }
  .cert-set { white-space: normal; }
  .cert-set + .cert-set { display: none; }
}
.cert-card {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
  gap: 14px;
  padding: 16px 22px;
  border: 1px solid var(--novix-rule);
  border-radius: 16px;
  background: var(--novix-paper-elev-1);
}
.cert-mark {
  -webkit-box-flex: 0;
  -webkit-flex: 0 0 46px;
      -ms-flex: 0 0 46px;
          flex: 0 0 46px;
  width: 46px;
  height: 46px;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
      -ms-flex-pack: center;
          justify-content: center;
  border-radius: 12px;
  color: var(--novix-dark-blue);
  background: rgba(15, 119, 249, 0.10);
}
.cert-mark svg { width: 26px; height: 26px; }
.cert-mark--img {
  -webkit-flex-basis: auto;
      -ms-flex-preferred-size: auto;
          flex-basis: auto;
  width: auto;
  background: none;
  border-radius: 0;
}
.cert-mark--img img { max-width: 100%; max-height: 46px; width: auto; height: auto; }
.cert-text {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
      -ms-flex-direction: column;
          flex-direction: column;
}
.cert-name {
  font-family: var(--font-secondary);
  font-weight: 700;
  font-size: 16px;
  line-height: 1.3;
  color: var(--color-heading);
}
.cert-status {
  font-size: 13px;
  line-height: 1.3;
  color: var(--novix-muted-text);
  margin-top: 2px;
}
@media (max-width: 575px) {
  .cert-card { width: 100%; }
}
.active-body .cert-card {
  background: var(--novix-ink-elev-1);
  border-color: rgba(255, 255, 255, 0.12);
}
.active-body .cert-mark {
  color: var(--novix-light-blue);
  background: rgba(10, 211, 251, 0.12);
}
.active-body .cert-name { color: var(--novix-text-on-dark); }
.active-body .cert-status { color: var(--novix-muted-on-dark); }

/* Mobile quick-contact FAB (includes/mobile-contact-fab.php). Shown only below
   the desktop breakpoint; on mobile #scrollBtn is lifted above it so the two
   never overlap in the bottom-right corner. */
.mobile-contact-fab {
  position: fixed;
  right: 15px;
  bottom: 15px;
  z-index: 9999;
  display: none;
  gap: 10px;
}
.mcf-btn {
  width: 52px;
  height: 52px;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
      -ms-flex-pack: center;
          justify-content: center;
  border-radius: 14px;
  background: var(--color-primary);
  color: var(--novix-ink);
  -webkit-box-shadow: 0 6px 18px rgba(2, 16, 45, 0.22);
          box-shadow: 0 6px 18px rgba(2, 16, 45, 0.22);
  -webkit-transition: -webkit-transform 200ms ease;
  transition: -webkit-transform 200ms ease;
  transition: transform 200ms ease;
  transition: transform 200ms ease, -webkit-transform 200ms ease;
}
.mcf-btn:hover,
.mcf-btn:focus {
  color: var(--novix-ink);
  -webkit-transform: translateY(-2px);
      -ms-transform: translateY(-2px);
          transform: translateY(-2px);
}
.mcf-btn svg { width: 24px; height: 24px; display: block; }
@media (max-width: 991.98px) {
  .mobile-contact-fab {
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
  }
  #scrollBtn { bottom: 80px; }
}

/* Mobile: stacked cards need vertical breathing room. The About team cards
   carry Bootstrap .mb-0 (margin-bottom:0 !important), so they touch when they
   stack; the index Plans cards get the same 10px top/bottom for consistency. */
@media (max-width: 767.98px) {
  #team .team-card,
  #leadership .team-cross-card {
    margin-top: 10px;
    margin-bottom: 10px !important;
  }
  /* One card per row on mobile, so the desktop equal-height flex (which
     absorbs the card's own margin) isn't needed; revert to block flow so the
     card margin actually spaces the stacked cards. */
  .pricing-sec3 .col-xl-8 > .row > [class*="col-"] {
    display: block;
  }
  .pricing-sec3 .price-card2 {
    height: auto;
    margin-top: 10px;
    margin-bottom: 10px;
  }
}

/* Team cards: the LinkedIn icon lives in a .social-links panel that Aiero
   reveals only on hover (translateY 155px -> 0). On touch devices there is no
   hover, so the icon was unreachable. Reveal it on pointers that can't hover
   (About team cards + the director-page leadership cross-links). */
@media (hover: none) {
  .team-card .social-links {
    -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
            transform: translateY(0);
  }
}

/* Turnstile fit on mobile. The widget is a fixed 300px Cloudflare iframe; on
   narrow screens it overran the form card (worst on the director-page sidebar
   form). Reclaim width by trimming the card padding, then scale the widget so
   it sits inside the card instead of overlapping the border. */
@media (max-width: 575.98px) {
  .contact-form {
    padding-left: 22px;
    padding-right: 22px;
  }
  .team-direct-form {
    padding: 28px 18px;
  }
  .contact-form .cf-turnstile {
    zoom: 0.9;
  }
}
@media (max-width: 360px) {
  .contact-form .cf-turnstile {
    zoom: 0.8;
  }
}

/* Plan pages — "What is included / What <tier> adds" card grid. Replaces the
   ser-detail-list bullet wall with numbered cards (same copy, restyled).
   Gradient number in the brand ramp; light + dark; single column on mobile. */
.plan-include-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin: 28px 0 44px;
}
.plan-include-card {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: start;
  -webkit-align-items: flex-start;
      -ms-flex-align: start;
          align-items: flex-start;
  gap: 16px;
  padding: 22px 24px;
  border: 1px solid var(--novix-rule);
  border-radius: 16px;
  background: var(--novix-paper-elev-1);
}
.pic-num {
  -webkit-box-flex: 0;
  -webkit-flex: 0 0 auto;
      -ms-flex: 0 0 auto;
          flex: 0 0 auto;
  font-family: var(--font-secondary);
  font-weight: 800;
  font-size: 28px;
  line-height: 1;
  margin-top: 2px;
  background: var(--novix-gradient);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
}
.plan-include-card .pic-title {
  font-family: var(--font-secondary);
  font-size: 17px;
  line-height: 1.35;
  font-weight: 700;
  margin: 0 0 6px;
  color: var(--color-heading);
}
.plan-include-card p {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--novix-muted-text);
}
@media (max-width: 767.98px) {
  .plan-include-grid {
    grid-template-columns: 1fr;
  }
}
.active-body .plan-include-card {
  background: var(--novix-ink-elev-1);
  border-color: rgba(255, 255, 255, 0.12);
}
.active-body .plan-include-card .pic-title {
  color: var(--novix-text-on-dark);
}
.active-body .plan-include-card p {
  color: var(--novix-muted-on-dark);
}

/* Footer contact section: even out the boundary. Pages end with ~120px of
   white (ibt-section-gapBottom) before the dark footer starts, but the
   contact-sec added its own 120px top padding PLUS ~64px of sec-title
   margins — reading as a ~184px dead black slab (reported as "footer top
   padding too wide" on the plan pages, site-wide in fact). Trim the top so
   black-above-content visually matches the white gap before the section. */
.main-sec .contact-sec.ibt-section-gap {
  padding-top: 56px;
}

/* Director QR contact-card pages (includes/qr-card-page.php). Scanned from a
   printed business card, so it reads as a digital business card: ink-navy
   card with the brand X pattern + gradient accents, then About/What-to-do
   panels. Mobile-first; no page banner (the section clears the header).
   The ink card is deliberately dark in BOTH themes (a business card). */
.qr-card-sec {
  padding: 170px 0 90px;
}
.qr-biz-card {
  position: relative;
  max-width: 560px;
  margin: 0 auto 18px;
  text-align: center;
  padding: 52px 30px 40px;
  border-radius: 24px;
  background:
    url('../patterns/nit-13-x-pattern-sm.png') right -40px top -40px / 220px auto no-repeat,
    var(--novix-ink);
  overflow: hidden;
}
.qr-biz-card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 5px;
  background: var(--novix-gradient);
}
/* Big faded first name behind the card content (banner staff-text motif) */
.qr-biz-name-bg {
  position: absolute;
  right: -8px;
  bottom: -26px;
  font-family: var(--font-secondary);
  font-weight: 800;
  font-size: 110px;
  line-height: 1;
  letter-spacing: 2px;
  color: rgba(255, 255, 255, 0.05);
  pointer-events: none;
  white-space: nowrap;
}
.qr-photo-ring {
  display: inline-block;
  padding: 4px;
  border-radius: 50%;
  background: var(--novix-gradient);
  margin-bottom: 20px;
}
.qr-card-photo {
  display: block;
  width: 158px;
  height: 158px;
  border-radius: 50%;
  object-fit: cover;
  border: 4px solid var(--novix-ink);
}
.qr-card-name {
  font-family: var(--font-secondary);
  font-size: 32px;
  line-height: 1.2;
  margin-bottom: 8px;
  color: var(--novix-text-on-dark);
}
.qr-card-role {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  margin-bottom: 28px;
  background: var(--novix-gradient);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
}
.qr-cta {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
      -ms-flex-pack: center;
          justify-content: center;
  gap: 10px;
  width: 100%;
  max-width: 380px;
  margin: 0 auto 14px;
  padding: 15px 20px;
  border-radius: 14px;
  background: var(--novix-gradient);
  color: var(--novix-paper);
  font-family: var(--font-secondary);
  font-weight: 700;
  font-size: 16px;
  -webkit-transition: -webkit-transform 200ms ease;
  transition: -webkit-transform 200ms ease;
  transition: transform 200ms ease;
  transition: transform 200ms ease, -webkit-transform 200ms ease;
}
.qr-cta:hover,
.qr-cta:focus {
  color: var(--novix-paper);
  -webkit-transform: translateY(-2px);
      -ms-transform: translateY(-2px);
          transform: translateY(-2px);
}
.qr-cta svg { width: 20px; height: 20px; }
.qr-actions {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
      -ms-flex-pack: center;
          justify-content: center;
  gap: 10px;
  max-width: 380px;
  margin: 0 auto;
}
.qr-action {
  -webkit-box-flex: 1;
  -webkit-flex: 1 1 0;
      -ms-flex: 1 1 0;
          flex: 1 1 0;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
      -ms-flex-direction: column;
          flex-direction: column;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
  gap: 7px;
  padding: 14px 8px 12px;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.06);
  color: var(--novix-text-on-dark);
  font-size: 13px;
  font-weight: 600;
  -webkit-transition: background 200ms ease, border-color 200ms ease;
  transition: background 200ms ease, border-color 200ms ease;
}
.qr-action:hover,
.qr-action:focus {
  color: var(--novix-text-on-dark);
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(10, 211, 251, 0.6);
}
.qr-action svg { width: 21px; height: 21px; color: var(--novix-light-blue); }
.qr-card-block {
  max-width: 560px;
  margin: 0 auto 16px;
  text-align: left;
  border: 1px solid var(--novix-rule);
  border-radius: 16px;
  background: var(--novix-paper-elev-1);
  padding: 24px 26px;
}
.qr-block-tag {
  display: block;
  font-family: var(--font-secondary);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--novix-muted-text);
  margin-bottom: 8px;
}
.qr-card-block h2 {
  font-family: var(--font-secondary);
  font-size: 18px;
  margin-bottom: 10px;
  color: var(--color-heading);
}
.qr-card-block p {
  font-size: 15px;
  line-height: 1.65;
  color: var(--novix-muted-text);
  margin: 0;
}
.qr-card-block p + p { margin-top: 10px; }
.qr-card-block a {
  color: var(--novix-dark-blue);
  text-decoration: underline;
}
@media (max-width: 575.98px) {
  .qr-card-sec { padding: 145px 0 60px; }
  .qr-biz-card { padding: 42px 20px 32px; }
  .qr-biz-name-bg { font-size: 78px; bottom: -18px; }
}
.active-body .qr-card-block {
  background: var(--novix-ink-elev-1);
  border-color: rgba(255, 255, 255, 0.12);
}
.active-body .qr-block-tag { color: var(--novix-muted-on-dark); }
.active-body .qr-card-block h2 { color: var(--novix-text-on-dark); }
.active-body .qr-card-block p { color: var(--novix-muted-on-dark); }
.active-body .qr-card-block a { color: var(--novix-light-blue); }
/* Dark mode: a generic .active-body p colour rule outranks .qr-card-role and
   turns the gradient clip white - restore the transparent fill. */
.active-body .qr-card-role {
  color: transparent;
}

/* Footer consistency (site audit 2026-07-28). Two fixes:

   1. On pages where the footer contact section is suppressed (contact,
      contact-thanks, the QR cards, all location pages - they carry their own
      form), .footer-style1 is the first child of .main-sec and its
      "Bring IT and security..." CTA started at the very top edge of the dark
      block (.footer-top has no padding of its own; on every other page the
      contact section above provided the breathing room). Give the bare
      footer a 40px top (Ricci's boundary rhythm, 2026-07-28). Scoped to
      :first-child so contact-footer pages are untouched.

   2. Aiero's .googel-map carries margin-bottom:31px, which on /contact (map
      last before the footer) left a stray white sliver above the dark block
      - the only page with a visible gap there. Zeroed for all uses; on the
      location pages the following section's own gap padding absorbs it. */
.main-sec > .footer-style1:first-child .footer-top {
  padding-top: 40px;
}
.googel-map {
  margin-bottom: 0;
}

/* /contact only: the map is the page's last element before the footer, so it
   carries the final-section bottom space (40px, Ricci's boundary rhythm). */
.map-final {
  margin-bottom: 40px;
}

/* ---- Header compact band (1200-1599px) ----
   On common laptop widths the header's three columns (logo | menu | search+
   theme+CTA) total ~1400px while the container is narrower until 1600px, so
   the row wrapped and the buttons dropped onto a second line - a double-
   height header covering content (reported 2026-07-28). In this band the
   pieces slim down so one line always fits, and the row is nowrap so it can
   never stack again. Below 1200px the hamburger takes over as before. */
@media (min-width: 1200px) and (max-width: 1599.98px) {
  .header-menu-area > .row {
    -webkit-flex-wrap: nowrap;
        -ms-flex-wrap: nowrap;
            flex-wrap: nowrap;
  }
  /* Menu links: 64px -> ~40px horizontal per item */
  .menu-style1 > ul > li > a {
    padding: 0 26px 0 8px;
    font-size: 13px;
  }
  .menu-style1 > ul > li > a::before {
    right: 10px;
  }
  .menu-style1 > ul > li:not(.has-dropdown) > a {
    padding-right: 8px;
  }
  .menu-style1 > ul > li:last-child a {
    padding: 0 8px;
  }
  /* Button cluster: tighter gap + slimmer CTA */
  .btn-box {
    gap: 10px;
  }
  .btn-box .ibt-btn {
    padding: 13px 16px;
    height: 54px;
  }
  /* Logo: cap the mark's size so the column narrows */
  .header-logo img {
    max-height: 34px;
    width: auto;
  }
}

/* ---- Skip link -------------------------------------------------------
   Paired with the <main id="main"> that nav.php opens and footer.php
   closes (404.php carries its own). Off-screen until focused, so it is
   invisible to mouse users and the first thing a keyboard visitor gets.
   Uses clip-path rather than display:none - a hidden element cannot take
   focus. Sits above the sticky header, hence the z-index.               */
.skip-link {
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 10000;
  transform: translate(-50%, -120%);
  padding: 12px 22px;
  border-radius: 0 0 12px 12px;
  font-family: var(--font-secondary);
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  color: var(--novix-text-on-dark);
  background: var(--novix-ink);
  border: 2px solid var(--novix-light-blue);
  border-top: 0;
  text-decoration: none;
  transition: transform .18s ease-out;
}
.skip-link:focus,
.skip-link:focus-visible {
  transform: translate(-50%, 0);
  color: var(--novix-text-on-dark);
  outline: 3px solid var(--novix-light-blue);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .skip-link { transition: none; }
}

/* ---- Credential badge: pending certification ------------------------
   ISO 27001 is not certified yet, so its official mark is greyed back
   while the card's status line carries the board-approved phrase
   ("Certification in progress for 2026"). The greyed mark plus that
   wording is what keeps the card from reading as certified. A literal
   "coming soon" band across the art was considered and rejected: the
   badge renders at 46px, where overlaid text is illegible.            */
.cert-mark--pending img {
  filter: grayscale(1);
  opacity: .55;
}
.active-body .cert-mark--pending img {
  /* Slightly stronger on ink: pure greyscale sinks too far into the card */
  opacity: .65;
}

/* ---- "Video coming soon" placeholder --------------------------------
   The four Watch Video buttons all pointed at the same third-party
   YouTube clip with the template thumbnail behind them (2026-09-07).
   Rather than pull the blocks out of the layout while the real videos
   are recorded, they render as a genuine disabled state.

   Deliberately a <span>, not a styled <a>: inert for mouse, touch AND
   keyboard, unfocusable, and it cannot be activated. That also means no
   YouTube request is ever made from the site, which the live buttons
   were making on click. Reuses .video-popup for position/shape so the
   block sits exactly where it did.                                    */
.video-soon {
  cursor: default;
  opacity: .85;
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}
.video-soon i {
  opacity: .6;
}
.video-soon > span {
  white-space: nowrap;
}
/* ---- /contact "where we are" band ----------------------------------
   Replaced the Google Maps iframe (2026-09-07). Two columns on desktop:
   our own coverage map on the left, address + the outbound Maps link on
   the right. Single column on mobile with the map first, so the visual
   still leads. .uk-map brings its own sizing and aspect ratio.        */
.where-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 40px;
  padding: 40px;
  border: 1px solid var(--novix-rule);
  border-radius: 25px;
  background: var(--novix-paper-elev-1);
}
.where-card-map {
  flex: 0 0 auto;
  width: 260px;
  max-width: 100%;
}
.where-card-body {
  flex: 1 1 340px;
  min-width: 0;
}
.where-card-body .title {
  font-size: 32px;
  line-height: 1.25;
  margin-bottom: 14px;
}
.where-card-body p {
  margin-bottom: 18px;
}
.where-address {
  font-style: normal;
  font-weight: 600;
  line-height: 1.6;
  margin-bottom: 22px;
}
.where-note {
  margin: 14px 0 0;
  font-size: 13px;
  opacity: .7;
}
@media (max-width: 767px) {
  .where-card {
    padding: 28px 22px;
    gap: 28px;
    justify-content: center;
  }
  .where-card-body .title { font-size: 26px; }
}
/* Dark mode: match the card surfaces used elsewhere on the page */
.active-body .where-card {
  background: var(--novix-ink-elev-1);
  border-color: rgba(255, 255, 255, 0.12);
}
.active-body .where-card-body .title { color: var(--novix-text-on-dark); }
.active-body .where-card-body p,
.active-body .where-address { color: var(--novix-muted-on-dark); }

/* ---- Section boundary spacing: SPLIT the gap ------------------------
   Ricci's rule, 2026-09-07: the space at a boundary between two sections
   is HALF from the bottom of the section above and HALF from the top of
   the section below. Never stack two full gaps (240px), and never dump
   the whole gap on one side.

   The one-sided version is not merely uneven, it breaks any boundary
   that carries a visible edge. `.faq-sec` on the location pages has a
   tinted background band, so its top edge IS a line; with no bottom
   padding on the section above, that line lands flush against the
   previous section's last line of text. Splitting keeps the edge
   centred in the gap.

   Aiero's own `ibt-section-gap*-half` classes are NOT used for this:
   they are 60px / 40px-under-768px, while the site's full gap is 120px
   / 80px-under-1200px. Two of Aiero's halves therefore come to 120px at
   tablet widths where the site's own rhythm is 80px. These match the
   real breakpoints, so a split boundary equals a normal one at every
   width: 60+60=120 on desktop, 40+40=80 below 1200px.               */
.novix-gap-split,
.novix-gap-split-top {
  padding-top: 60px;
}
.novix-gap-split,
.novix-gap-split-bottom {
  padding-bottom: 60px;
}
@media (max-width: 1199.98px) {
  .novix-gap-split,
  .novix-gap-split-top {
    padding-top: 40px;
  }
  .novix-gap-split,
  .novix-gap-split-bottom {
    padding-bottom: 40px;
  }
}

/* ---- QR card: Add to Contacts + LinkedIn on one row -----------------
   Ricci, 2026-09-07. LinkedIn left and sized to its content, the primary
   CTA taking the rest. Both 56px so they align, and both well past the
   44px touch minimum - this page is reached by scanning a QR code, so
   it is phone traffic almost without exception. Row keeps the 380px
   max-width the old three-up action row used, so the card's rhythm is
   unchanged.                                                          */
.qr-cta-row {
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: 10px;
  max-width: 380px;
  margin: 0 auto;
}
.qr-cta-row .qr-cta {
  flex: 1 1 auto;
  width: auto;
  height: 56px;
  margin: 0;
}
.qr-linkedin {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 56px;
  padding: 0 18px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.07);
  color: var(--novix-text-on-dark);
  font-family: var(--font-secondary);
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  transition: background .18s ease, border-color .18s ease, transform .18s ease;
}
.qr-linkedin svg { width: 18px; height: 18px; color: var(--novix-light-blue); }
.qr-linkedin:hover,
.qr-linkedin:focus-visible {
  color: var(--novix-text-on-dark);
  background: rgba(255, 255, 255, 0.13);
  border-color: rgba(10, 211, 251, 0.6);
  transform: translateY(-2px);
}

/* Add to Contacts before Turnstile resolves. Not display:none - the button
   must hold its space so the row does not jump when it goes live. */
.qr-cta.is-pending,
.qr-cta.is-failed {
  opacity: .45;
  pointer-events: none;
  cursor: default;
}
.qr-cta.is-pending .qr-cta-label::after {
  content: "\2026";           /* ellipsis: "Add to Contacts…" while checking */
}
.qr-turnstile {
  display: flex;
  justify-content: center;
  margin: 14px auto 0;
  min-height: 65px;           /* reserve the widget's height, no layout jump */
}
.qr-cta-note {
  max-width: 380px;
  margin: 10px auto 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--novix-muted-on-dark);
  text-align: center;
}
.qr-cta-note:empty { margin: 0; }
.qr-cta-note a { color: var(--novix-light-blue); }
.qr-cta-row .qr-cta .qr-cta-label { white-space: nowrap; }
/* Narrow phones: LinkedIn goes icon-only so "Add to Contacts" stops wrapping
   to two lines inside a 56px button. The anchor keeps an accessible name via
   aria-label - an icon-only link with no name is exactly the link-name
   failure the PSI audit flagged elsewhere. */
@media (max-width: 430px) {
  .qr-linkedin { padding: 0 16px; }
  .qr-linkedin > span {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .qr-linkedin svg { width: 20px; height: 20px; }
}

/* ================================================================
   Brand banner: a photo-free page hero
   ================================================================
   .page-banner4 falls back to an Aiero stock photo when no swap class is
   present. Pages with no hero photograph of their own use this instead: flat
   brand ink and the X pattern as a corner watermark. A real photo drops in
   later exactly like the other heroes, by adding a .page-banner-<slug> class.

   READ THIS BEFORE CHANGING ANYTHING BELOW. Which element is the card
   CHANGES AT 1202px, and getting that wrong is what produced the "image
   behind it" Ricci reported twice on 2026-09-07.

     >= 1202px  The <section> is a full-width light grey zone running up
                behind the header, and .page-banner-inner is the rounded dark
                card inset 20px inside it. See the architecture block earlier
                in this file. Paint the INNER. Painting the section as well
                fills the light margin with ink: the card loses its edges and
                goes full-bleed, the pale notch shapes at the two left corners
                and the right edge become unexplained blobs instead of cuts in
                a frame, and the X pattern gets painted twice at two different
                offsets, which is what reads as a photograph behind the text.

     <= 1201px  Aiero's own structure. The SECTION is the card (its own navy
                and stock photo, margin 20px, radius 28px) and the inner is an
                inert passthrough. Paint the SECTION. Leaving it alone here is
                how the Aiero stock photo page1-4.png comes back, which is the
                same complaint from the other direction, and only below 1202px
                where a desktop check never looks.

   So both elements are styled, each inside its own half of the breakpoint,
   and neither is styled in the other's half. /about (.page-banner11) is the
   reference for what right looks like at both widths.                     */

/* -- The ink. One declaration, applied to whichever box is the card. ------
   Flat with one soft off-centre lift, not a diagonal band: an earlier version
   used a 135deg linear gradient, which itself read as a photograph bleeding
   through rather than a background colour (Ricci, 2026-09-07).

   position/z-index make the card a stacking context, which is what lets the
   watermark below sit at z-index -1: above the card's own background and
   beneath every one of its children. Without it, -1 drops the pattern behind
   the ink entirely and it is never seen. */
.page-banner-brand {
  position: relative;
  z-index: 0;
  background-image:
    radial-gradient(120% 90% at 78% 12%, #0C2559 0%, #02102D 62%);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}

/* -- The watermark. -------------------------------------------------------
   The X pattern gets its own layer rather than riding as a second background
   on the card, for one reason: a background layer cannot be given an opacity
   of its own. At full strength the pattern is line art the size of a
   photograph, and that is the other half of what read as an image behind the
   text. Here it is a corner watermark at just over a third strength, and the
   numbers can be tuned without touching the card's colour.

   z-index: -1 inside the card's stacking context does two jobs at once: the
   outlined vertical word reads over the pattern instead of through it, and
   the pale notch shape on the right edge stays a clean cut in the frame
   rather than picking up a faint X across its corner. The element's own
   border-radius clips it to the card's top-right corner, so nothing needs
   overflow: hidden, which would have cropped the notch shapes and the
   breadcrumb card out of the frame.

   Both pseudo-elements are free on whichever box is the card: Aiero's
   decorative bg-layer2 lives on the SECTION's ::before above 1202px, and this
   claims ::after. */
.page-banner-brand::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  z-index: -1;
  width: 300px;
  height: 391px;           /* the pattern's own 647x844 ratio, so it never distorts */
  max-width: 42%;
  pointer-events: none;
  opacity: .34;
  border-radius: 0 28px 0 0;
  background: url('../patterns/nit-13-x-pattern.png') no-repeat top right / contain;
}

/* -- Above 1202px, hand both to the inner card. -------------------------- */
@media (min-width: 1202px) {
  /* Section goes back to being the light zone. The architecture block sets
     this with a `background` shorthand, but it sits earlier in this file at
     equal specificity, so it has to be restated rather than inherited. */
  .page-banner-brand {
    background: var(--novix-paper-elev-4);
  }
  .page-banner-brand::after {
    content: none;
  }
  .page-banner-brand > .page-banner-inner {
    background-image:
      radial-gradient(120% 90% at 78% 12%, #0C2559 0%, #02102D 62%);
    background-repeat: no-repeat;
    background-position: center;
    background-size: cover;
    position: relative;    /* already set by the architecture block; kept explicit */
    z-index: 0;
  }
  .page-banner-brand > .page-banner-inner::after {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    z-index: -1;
    width: 300px;
    height: 391px;
    max-width: 42%;
    pointer-events: none;
    opacity: .34;
    border-radius: 0 28px 0 0;
    background: url('../patterns/nit-13-x-pattern.png') no-repeat top right / contain;
  }
}

/* Narrow screens have no room for a watermark beside the heading. */
@media (max-width: 767px) {
  .page-banner-brand::after { content: none; }
}

/* ADD .page-banner-rich ONLY when the banner carries more than a heading.
   The shared inner padding (217/235) is sized for a single H1, which is all
   the photo heroes hold. Stack a full hero inside it - eyebrow, heading,
   standfirst, CTA and its qualifier - and the banner runs ~280px taller than
   every other page's, which is what Ricci flagged. This brings the OVERALL
   height back in line with them rather than matching their padding.
   Do not put it on a banner that only has an H1: it would then be ~270px
   shorter than the rest of the site, which is the same fault inverted. */
.page-banner-rich > .page-banner-inner {
  padding-top: 104px;
  /* The bottom value also buys clearance for the breadcrumb card, which is
     absolutely positioned at the banner's bottom-left. At 76px the centred
     qualifier line collided with it around 1280px wide (measured: 33px
     across, 15px down) - it cleared at 1440 and again below ~1000, so it was
     a narrow band that eyeballing one width would have missed. More bottom
     padding moves the breadcrumb down without moving the content. */
  padding-bottom: 118px;
}
@media (max-width: 1201.98px) {
  .page-banner-rich > .page-banner-inner {
    padding-top: 92px;
    padding-bottom: 104px;
  }
}
@media (max-width: 767px) {
  .page-banner-rich > .page-banner-inner {
    padding-top: 72px;
    padding-bottom: 80px;
  }
}

/* ---- Referral Programme ------------------------------------------- */
.ref-eyebrow {
  display: block;
  margin-bottom: 10px;
  font-family: var(--font-secondary);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--novix-light-blue);
}
.ref-standfirst {
  max-width: 34rem;
  margin: 14px auto 0;
  font-size: 19px;
  line-height: 1.6;
  color: var(--novix-muted-on-dark);
}
/* The CTA and its qualifier are ONE block by legal requirement (rule 3:
   the terms link must sit with the call to action, not in the footer).
   Keep them together - do not restyle these apart. */
/* Centred in the banner to match the heading and standfirst; left-aligned
   in the closing block, which sits in a centred card of its own. */
.ref-cta-block { margin: 26px auto 0; max-width: 34rem; text-align: center; }
.ref-qualifier {
  margin: 14px 0 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--novix-muted-on-dark);
}
.ref-qualifier a { color: var(--novix-light-blue); text-decoration: underline; }
.ref-body p { margin-bottom: 18px; }
.ref-body p:last-child { margin-bottom: 0; }

.ref-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 22px;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}
.ref-step {
  position: relative;
  padding: 28px 26px;
  border: 1px solid var(--novix-rule);
  border-radius: 18px;
  background: var(--novix-paper-elev-1);
}
.ref-step-n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  margin-bottom: 14px;
  border-radius: 50%;
  background: var(--novix-gradient);
  color: #fff;
  font-family: var(--font-secondary);
  font-weight: 800;
  font-size: 16px;
}
.ref-step h3 { font-size: 19px; line-height: 1.35; margin-bottom: 10px; }
.ref-step p  { margin: 0; font-size: 15px; line-height: 1.65; }
.ref-step a  { color: var(--novix-dark-blue); text-decoration: underline; }

.ref-print { margin-bottom: 26px; }
.ref-print:last-child { margin-bottom: 0; }
.ref-print h3 { font-size: 20px; line-height: 1.35; margin-bottom: 10px; }
.ref-print p  { margin: 0; }
/* The employer-disclosure point. Given a left rule so it reads as the one
   thing on the page a referrer must not skim - it is the commonest reason a
   payout is refused, and rule 5 requires it in the body, not just the terms. */
.ref-print--flag {
  padding: 22px 24px;
  border-radius: 16px;
  border-left: 4px solid transparent;
  border-image: var(--novix-gradient) 1;
  border-top: 0; border-right: 0; border-bottom: 0;
  background: var(--novix-paper-elev-1);
}
.ref-close {
  max-width: 44rem;
  margin: 0 auto;
  text-align: center;
  padding: 44px 32px;
  border: 1px solid var(--novix-rule);
  border-radius: 24px;
  background: var(--novix-paper-elev-1);
}
.ref-close .title { font-size: 32px; line-height: 1.25; margin-bottom: 12px; }
.ref-close .ref-cta-block { margin-left: auto; margin-right: auto; }
.ref-faq-wrap { padding-bottom: 0; }

.active-body .ref-step,
.active-body .ref-print--flag,
.active-body .ref-close {
  background: var(--novix-ink-elev-1);
  border-color: rgba(255, 255, 255, 0.12);
}
.active-body .ref-step h3,
.active-body .ref-print h3,
.active-body .ref-close .title { color: var(--novix-text-on-dark); }
.active-body .ref-step p,
.active-body .ref-print p,
.active-body .ref-body p,
.active-body .ref-close p { color: var(--novix-muted-on-dark); }
.active-body .ref-step a { color: var(--novix-light-blue); }
@media (max-width: 767px) {
  .ref-close { padding: 32px 22px; }
  .ref-close .title { font-size: 26px; }
}

/* ---- IT Services Buyer's Guide ------------------------------------- */
.guide-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 48px;
  padding: 44px;
  border: 1px solid var(--novix-rule);
  border-radius: 24px;
  background: var(--novix-paper-elev-1);
}
.guide-hero-media { flex: 0 0 auto; }
.guide-hero-body  { flex: 1 1 320px; min-width: 0; }
.guide-eyebrow {
  display: block;
  margin-bottom: 10px;
  font-family: var(--font-secondary);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--novix-dark-blue);
}
.guide-hero-body .title { font-size: 34px; line-height: 1.2; margin-bottom: 8px; }
.guide-sub {
  margin: 0 0 16px;
  font-size: 17px;
  color: var(--novix-muted);
}
.guide-blurb { margin: 0 0 26px; font-size: 16px; line-height: 1.7; }
.guide-meta {
  margin: 14px 0 0;
  font-size: 13px;
  color: var(--novix-muted);
}

/* The cover. Real artwork drops into assets/guides/<slug>.(avif|webp|jpg|png)
   and replaces all of this; until then it is drawn in CSS so the page never
   shows a placeholder box or a broken image. */
.guide-cover {
  position: relative;
  display: block;
  width: 178px;
  /* A4 is the default because that is what the CSS-drawn placeholder is shaped
     like. Real artwork overrides it with its own measured ratio (the 2024
     guide is US Letter), so nothing is cropped to fit a box it was not
     designed for. */
  aspect-ratio: var(--guide-ratio, 1 / 1.414);
  border-radius: 4px 10px 10px 4px;
  overflow: hidden;
  background: linear-gradient(150deg, #0A1F4D 0%, #02102D 60%, #14306B 100%);
  box-shadow: 0 18px 40px rgba(2, 16, 45, .28);
}
.guide-cover--lg { width: 250px; }
.guide-cover--art { background: none; }
/* <picture> is an inline box by default and would leave a baseline gap under
   the image inside a height-constrained parent. */
.guide-cover--art picture { display: block; width: 100%; height: 100%; }
.guide-cover--art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.guide-cover-spine {
  position: absolute; inset: 0 auto 0 0;
  width: 10px;
  background: var(--novix-gradient);
}
.guide-cover-body {
  position: absolute; inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 18px 0 28px;
  color: #fff;
}
.guide-cover-eyebrow {
  font-family: var(--font-secondary);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  opacity: .72;
}
.guide-cover-year {
  font-family: var(--font-primary);
  font-size: 46px;
  font-weight: 900;
  line-height: 1;
  margin: 6px 0 10px;
}
.guide-cover--lg .guide-cover-year { font-size: 62px; }
.guide-cover-rule {
  width: 46px; height: 3px;
  border-radius: 2px;
  background: var(--novix-gradient);
}
.guide-cover-sub {
  margin-top: 12px;
  font-family: var(--font-secondary);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  opacity: .6;
}

.guide-for p { margin-bottom: 18px; }
.guide-for p:last-child { margin-bottom: 0; }
.guide-for a { color: var(--novix-dark-blue); text-decoration: underline; }

.guide-archive-note {
  max-width: 44rem;
  margin: -8px 0 30px;
  color: var(--novix-muted);
}
.guide-archive {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 22px;
}
.guide-card {
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 22px;
  border: 1px solid var(--novix-rule);
  border-radius: 18px;
  background: var(--novix-paper-elev-1);
}
.guide-card .guide-cover { width: 104px; }
.guide-card .guide-cover-year { font-size: 30px; }
.guide-card .guide-cover-body { padding: 0 12px 0 20px; }
.guide-card-body { min-width: 0; }
.guide-card-body h3 { font-size: 18px; line-height: 1.35; margin-bottom: 6px; }
.guide-card-link {
  display: inline-block;
  margin-top: 10px;
  font-weight: 600;
  color: var(--novix-dark-blue);
  text-decoration: underline;
}

.active-body .guide-hero,
.active-body .guide-card {
  background: var(--novix-ink-elev-1);
  border-color: rgba(255, 255, 255, .12);
}
.active-body .guide-hero-body .title,
.active-body .guide-card-body h3 { color: var(--novix-text-on-dark); }
.active-body .guide-blurb,
.active-body .guide-for p,
.active-body .guide-sub,
.active-body .guide-meta,
.active-body .guide-archive-note { color: var(--novix-muted-on-dark); }
.active-body .guide-eyebrow,
.active-body .guide-card-link,
.active-body .guide-for a { color: var(--novix-light-blue); }

@media (max-width: 767px) {
  .guide-hero { padding: 28px 22px; gap: 30px; justify-content: center; }
  .guide-hero-body .title { font-size: 26px; }
  .guide-card { flex-direction: column; align-items: flex-start; }
}
