/* ==========================================================================
   Rapidi Website Redesign - Prototype stylesheet
   Palette: Rapidi Brand Guidelines 2026 v12 only. No colour outside p13/p14.
   Contrast values in comments are measured WCAG 2.1 ratios.
   ========================================================================== */

/* ------------------------------------------------------------------ font ---
   DM Sans, self-hosted variable WOFF2. One file covers weights 300 to 900,
   so there are no separate regular / semibold / bold downloads.
   unicode-range keeps latin-ext off English pages and loads it only when a
   German, French or Spanish character actually needs it.
   Licence and provenance: assets/fonts/LICENSE.md
   --------------------------------------------------------------------------- */
@font-face {
  font-family: "DM Sans";
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url("/sa/al4pxev1lqzs34cwjmpb8p9m4ho9/dmsans-var-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "DM Sans";
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url("/sa/klq7z2chf47kewntjvsgv9a9c0f3/dmsans-var-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Italic. DM Sans ships an italic file, but it is a slanted roman rather than a
   redrawn italic: compared letter by letter against the roman, none of a, e, f, g
   or y is structurally different. Fine for the occasional emphasis this site uses,
   worth knowing before anyone sets a long passage in it. */
@font-face {
  font-family: "DM Sans";
  font-style: italic;
  font-weight: 300 900;
  font-display: swap;
  src: url("/sa/0rtuqw4u7n5crgdhdom7kdwf6jxm/dmsans-var-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "DM Sans";
  font-style: italic;
  font-weight: 300 900;
  font-display: swap;
  src: url("/sa/i58qnaen12cd219s5jpplni6kl3e/dmsans-var-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* Type stack. The fallbacks are chosen for similar metrics so the swap from
     fallback to DM Sans shifts as little as possible. */
  --font: "DM Sans", "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;

  /* Primary palette (v12 p13) */
  --navy:        #2A3850;  /* white on navy = 11.80:1 */
  /* Added to the palette 28 Aug 2026. Same hue 218 and same 31% saturation as
     Dark Navy, four points darker. It exists because neither pink clears the 3:1
     graphics floor on Dark Navy: raspberry 2.61 and logo pink 2.73. On this it is
     3.02 and 3.16. Use it wherever a pink mark or graphic sits on a dark ground.
     Print build approx CMYK 100/60/20/68, to be confirmed under the real profile. */
  --navy-deep:   #232E42;  /* raspberry 3.02:1, logo pink 3.16:1, white 13.63:1 */
  --raspberry:   #CC4474;  /* white on raspberry = 4.52:1 (AA normal text) */
  --raspberry-d: #A94164;  /* white on dark raspberry = 5.79:1 */
  --mid-blue:    #366DA4;  /* white on mid blue = 5.41:1 */
  --grey:        #6D6E6C;  /* grey on white = 5.12:1 */
  --near-white:  #EDEDEC;

  /* Secondary palette (v12 p14) */
  --teal:        #2B9DC0;  /* borders and highlights only, 3.14:1 on white */
  --light-teal:  #99CADD;
  --sage:        #688B85;
  --gold:        #E4C152;
  --sand:        #F4E0A4;

  /* Derived tints (allowed: tints derived from Light Teal) */
  --tint-1:      #F0F7FA;
  --tint-2:      #EAF4F9;
  --white:       #FFFFFF;

  /* Derived, not brand. Each is a documented colour mixed with white or navy. The
     original guidelines specify 18 colours and none of these; they exist because
     hairlines, tints and on-navy text are not covered by the 18. Named here so
     nobody later mistakes them for brand values. */
  --line:       #D9DBE0;  /* Dark Navy 18% on white */
  --tint:       #ECF6F9;  /* Teal 9% on white */
  --on-navy:    #81AABE;  /* Light Teal 78% over navy, 4.73:1 on navy */
  --pink-tint:  #FAEEF2;  /* Raspberry 9% on white */
  --pink-line:  #EFC3D3;  /* Raspberry 32% on white */
  --gold-tint:  #FDF8EA;  /* Gold 12% on white */
  --gold-text:  #8A6D1F;  /* Gold darkened, 4.6:1 on white */
  --sage-tint:  #E6EEEC;  /* Sage 14% on white */
  --sage-pale:  #CDDAD7;  /* the accent band. Navy Deep on it is 9.16:1 */

  /* Prototype scaffolding. These never ship: they colour the model switcher and the
     link inspector, which are development aids rather than site chrome. */






  /* Spacing scale, 4px base */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px; --s-5: 24px;
  --s-6: 32px; --s-7: 48px; --s-8: 64px; --s-9: 96px; --s-10: 128px;

  /* Fluid type scale, 320px to 1440px viewport */
  --t-xs:   clamp(0.75rem, 0.72rem + 0.15vw, 0.8125rem);
  --t-sm:   clamp(0.875rem, 0.85rem + 0.12vw, 0.9375rem);
  --t-base: clamp(1rem, 0.96rem + 0.2vw, 1.125rem);
  --t-lg:   clamp(1.125rem, 1.05rem + 0.36vw, 1.375rem);
  --t-xl:   clamp(1.375rem, 1.24rem + 0.67vw, 1.75rem);
  --t-2xl:  clamp(1.625rem, 1.4rem + 1.12vw, 2.25rem);
  /* DM Sans sets narrower than Montserrat did, so the scale has more room than
     pulled back from 3.25rem. Without this the hero H1 runs to five lines. */
  --t-3xl:  clamp(1.875rem, 1.5rem + 1.85vw, 2.875rem);

  --radius: 6px;
  --radius-btn: 25px;  /* buttons, Beate 29 Aug 2026 */
  --radius-lg: 12px;
  --header-h: 64px;
  --maxw: 1128px;   /* Celigo's container, measured 30 Aug 2026 */
  --shadow: 0 1px 2px rgba(42,56,80,.08), 0 8px 24px rgba(42,56,80,.08);
  --ease: cubic-bezier(.2,.6,.3,1);
}

/* --------------------------------------------------------------- base --- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: calc(var(--header-h) + 16px); }
body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--t-base);
  line-height: 1.65;
  color: var(--navy);
  background: var(--white);
  overflow-x: hidden;
}
img, svg { max-width: 100%; height: auto; display: block; }
a { color: var(--mid-blue); text-decoration-thickness: 1px; text-underline-offset: 2px; }
/* DM Sans is a geometric sans and runs narrower than Montserrat did, so
   large headings get negative tracking and small ones stay neutral. */
h1, h2, h3, h4 { line-height: 1.15; margin: 0 0 var(--s-4); font-weight: 800; }
h1 { font-size: var(--t-3xl); letter-spacing: -.028em; line-height: 1.08; }
h2 { font-size: var(--t-2xl); letter-spacing: -.02em; }
h3 { font-size: var(--t-lg);  letter-spacing: -.012em; }
h4 { letter-spacing: -.008em; }
p  { margin: 0 0 var(--s-4); }
:focus-visible {
  outline: 3px solid var(--mid-blue);
  outline-offset: 2px;
  border-radius: 3px;
}
.skip-link {
  position: absolute; left: var(--s-4); top: -60px; z-index: 200;
  background: var(--navy); color: var(--white); padding: var(--s-3) var(--s-4);
  border-radius: var(--radius); transition: top .15s var(--ease);
}
.skip-link:focus { top: var(--s-3); }
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: 20px; }
/* gutter stays 20px at every width, as Celigo's does */
.eyebrow {
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--mid-blue); margin: 0 0 var(--s-3);
}
.lede { font-size: var(--t-lg); color: var(--grey); max-width: 62ch; }
.section { padding-block: var(--s-8); }
@media (min-width: 900px) { .section { padding-block: var(--s-9); } }
.section--tint { background: var(--tint-1); }

/* ---------------------------------------------------------------------------
   Band rhythm, 29 August 2026. Measured off celigo.com, which runs one dark
   bookend, three distinguishable neutrals and a single soft accent band. Ours
   ran four teal tints two units apart, which reads as one smeared colour
   rather than as structure.

   Rapidi colours only. Teal and Sage never carry text, so they are grounds.
   --------------------------------------------------------------------------- */
main > section { background: var(--white); }
/* the teal wash is the hero, and only the hero, so it means something */
main > section:where(.section--tint):not(:first-of-type) { background: var(--white); }
main > section:nth-of-type(4n + 3) { background: var(--near-white); }
main > section:nth-of-type(4n + 4) { background: var(--sage-pale); }  /* Sage Pale, the accent band */

/* Sage Pale carries exactly two text colours in the whole palette. Measured
   30 Aug 2026 against #CDDAD7, luminance 0.6802:
     Navy Deep 9.48:1   Dark Navy 8.21:1   pass
     Mid Blue 3.76      Grey 3.56          fail 4.5:1
     Raspberry 3.14     Sage 2.60          fail
     Teal 2.18          White 1.44         fail even the 3:1 a graphic needs
   Teal against Raspberry is 1.44:1, so the two never sit side by side here.
   Anything that would otherwise be Grey, Teal, Mid Blue or a raspberry becomes
   Navy Deep on this band. Display-size numerals keep Raspberry, because 3:1
   applies at that size and 3.14 clears it. */
main > section:nth-of-type(4n + 4) :where(p, li, small, dd, figcaption, .lede,
  .hf-src, .hf-conn__n, .stamp, .faq__a p) { color: var(--navy-deep); }
main > section:nth-of-type(4n + 4) :where(a, .hf-more a) { color: var(--navy-deep); }
main > section:nth-of-type(4n + 4) :where(a):hover,
main > section:nth-of-type(4n + 4) :where(a):focus-visible {
  color: var(--navy-deep); text-decoration: underline;
}
/* the label keeps its accent through weight and letterspacing, not colour */
main > section:nth-of-type(4n + 4) .hf-conn__n { opacity: .78; }
/* the one exception. A display numeral is large text, where 3:1 applies, and
   Raspberry clears it at 3.14:1. Sweeping it to navy would have removed an
   accent that passes. */
main > section:nth-of-type(4n + 4) .hf-big { color: var(--raspberry); }
/* one dark band inside the page, the last content section before the FAQ */
main > section:nth-last-of-type(3):not(.section--rasp):not(.cta-band):not(.rel-band) {
  background: var(--navy-deep); color: var(--white);
}
main > section:nth-last-of-type(3):not(.rel-band) h2,
main > section:nth-last-of-type(3):not(.rel-band) h3 { color: var(--white); }
main > section:nth-last-of-type(3):not(.rel-band) .lede,
main > section:nth-last-of-type(3):not(.rel-band) .eyebrow { color: var(--light-teal); }
main > section:nth-last-of-type(3):not(.rel-band) .card { background: rgba(255,255,255,.06);
  border-color: rgba(255,255,255,.22); color: var(--white); }
main > section:nth-last-of-type(3):not(.rel-band) .card h3,
main > section:nth-last-of-type(3):not(.rel-band) .card h3 a,
main > section:nth-last-of-type(3):not(.rel-band) a { color: var(--white); }
main > section:nth-last-of-type(3):not(.rel-band) a:hover { color: var(--light-teal); }
main > section:nth-last-of-type(3):not(.rel-band) .stamp { background: rgba(255,255,255,.10);
  border-color: rgba(255,255,255,.24); color: var(--white); }
/* the three that own their colour outright */
main > section.section--tint:first-of-type { background: var(--tint-1); }
main > section.section--navy { background: var(--navy-deep); color: var(--white); }
main > section.section--rasp { background: var(--raspberry); color: var(--white); }
main > section.qs-band { background: var(--white); }

/* navy-deep, not navy: these two bands carry a raspberry button, which is only
   3.02:1 against navy-deep and 2.61:1 against Dark Navy. */
.section--navy { background: var(--navy-deep); color: var(--white); }
.section--navy h2, .section--navy h3 { color: var(--white); }
.section--navy .lede { color: var(--light-teal); }
.section--navy .eyebrow { color: var(--light-teal); }

/* ------------------------------------------------------------ buttons --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 48px;                 /* tap target >= 44px */
  padding: var(--s-3) var(--s-5);
  font: inherit; font-weight: 700; font-size: var(--t-xs);
  letter-spacing: .05em; text-transform: uppercase;
  border-radius: var(--radius-btn); border: 2px solid transparent;
  text-decoration: none; cursor: pointer;
  /* Long labels must still wrap. Blanket nowrap pushed the landing page's
     "Download the NAV to Business Central integration checklist" button past
     the viewport at 500px and made the whole page scroll sideways. */
  text-wrap: balance;
  transition: background-color .15s var(--ease), border-color .15s var(--ease), transform .15s var(--ease);
}
.btn:active { transform: translateY(1px); }
/* Primary: raspberry fill. On white/tint the fill is 4.52:1 vs the page, well past
   the 3:1 non-text minimum. On navy it gets a near-white ring to clear 3:1. */
.btn--primary { background: var(--raspberry); color: var(--white); }
.btn--primary:hover { background: var(--raspberry-d); }
/* The light border was a workaround for raspberry-on-navy being 2.61:1. On
   navy-deep the button clears 3:1 on its own, so this is now belt and braces. */
.section--navy .btn--primary, .hero--navy .btn--primary { border-color: var(--near-white); }
.btn--secondary {
  background: transparent; color: var(--navy); border-color: var(--navy);
}
.btn--secondary:hover { background: var(--navy); color: var(--white); }
.section--navy .btn--secondary { color: var(--white); border-color: var(--light-teal); }
.section--navy .btn--secondary:hover { background: var(--white); color: var(--navy); }
/* Only the compact header button gets nowrap. Uppercase runs wide, and
   without this the sticky header CTA breaks onto a second line and drags the
   whole header taller on scroll. */
.btn--sm { min-height: 44px; padding: var(--s-2) var(--s-4); white-space: nowrap; }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.btn-row .btn { flex: 1 1 auto; }
@media (min-width: 560px) { .btn-row .btn { flex: 0 0 auto; } }

/* ------------------------------------------------------- sticky header --- */
.utility {
  background: var(--navy); color: var(--near-white);
  font-size: var(--t-xs);
}
.utility .wrap { display: flex; justify-content: flex-end; align-items: center; gap: var(--s-4); min-height: 34px; }
.utility a { color: var(--near-white); text-decoration: none; }
.utility a:hover { text-decoration: underline; }
@media (max-width: 899px) { .utility { display: none; } }

.header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255,255,255,.94);
  -webkit-backdrop-filter: saturate(180%) blur(8px);
  backdrop-filter: saturate(180%) blur(8px);
  border-bottom: 1px solid var(--near-white);
  transition: box-shadow .2s var(--ease);
}
.header.is-stuck { box-shadow: 0 2px 12px rgba(42,56,80,.10); }
.header.is-stuck .header__bar { min-height: 56px; }   /* compresses on scroll */
.header__bar {
  display: flex; align-items: center; gap: var(--s-4);
  min-height: var(--header-h);
  transition: min-height .2s var(--ease);
}
/* Real brand mark. rapidi-logo.svg is the official LOGO_11 horizontal lockup,
   rapidi-logo-rev.png is the reverse for dark backgrounds. Height is fixed and
   width is auto so the 4.5:1 aspect ratio is never squashed. */
.logo { display: inline-flex; align-items: center; text-decoration: none; margin-right: auto; flex: none; }
.logo img { height: 34px; width: auto; display: block; }
@media (max-width: 420px) { .logo img { height: 28px; } }
.logo--rev img { height: 30px; }

.nav { display: none; }
@media (min-width: 1000px) { .nav { display: flex; align-items: center; gap: var(--s-1); } }
.nav__item { position: relative; }
.nav__link {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; padding: 0 var(--s-3);
  font-size: var(--t-sm); font-weight: 700; color: var(--navy);
  background: none; border: 0; cursor: pointer; text-decoration: none; font-family: inherit;
  border-radius: var(--radius);
}
/* Beate, 30 Aug 2026: no chevron, and the hover effect is raspberry rather than
   a tinted pill. Raspberry #CC4474 on the header measures 4.52:1, which passes AA
   for the 14px bold the nav uses. The chevron rules are deleted rather than
   hidden, because the element no longer exists. */
.nav__link:hover, .nav__link:focus-visible { color: var(--raspberry); }
.nav__link[aria-expanded="true"], details[open] > .nav__link { color: var(--raspberry); }
.nav__item:hover > details > .nav__link { color: var(--raspberry); }

/* The panel opens on hover. <details> is kept, so click and keyboard still work;
   this only reveals the closed panel while the pointer is over the item.
   ::details-content is what makes that possible without setting an attribute, and
   where it is unsupported the menu falls back to opening on click. */
@media (hover: hover) and (min-width: 1000px) {
  .nav__item:hover > details::details-content,
  .nav__item:focus-within > details::details-content {
    content-visibility: visible; display: block;
  }
}

/* mega menu */
.mega {
  position: absolute; top: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  width: min(920px, 92vw);
  background: var(--white); border: 1px solid var(--near-white); border-top: 3px solid var(--raspberry);
  border-radius: var(--radius-lg); box-shadow: var(--shadow);
  padding: var(--s-6); z-index: 110;
}
.mega[hidden] { display: none; }
.mega__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-6); }
.mega__col h3 { font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .09em; color: var(--mid-blue); margin-bottom: var(--s-3); }
.mega__col ul { list-style: none; margin: 0; padding: 0; }
.mega__col li + li { margin-top: 2px; }
.mega__col a {
  display: block; padding: var(--s-2) var(--s-2); margin-inline: calc(var(--s-2) * -1);
  border-radius: var(--radius); color: var(--navy); text-decoration: none;
  font-size: var(--t-sm); font-weight: 600; min-height: 36px;
}
.mega__col a:hover { background: var(--tint-1); color: var(--mid-blue); }
.mega__col a small { display: block; font-weight: 400; color: var(--grey); font-size: var(--t-xs); line-height: 1.35; }
.mega__foot {
  margin-top: var(--s-5); padding-top: var(--s-4); border-top: 1px solid var(--near-white);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-3);
  font-size: var(--t-sm);
}

/* language switcher */
.lang { position: relative; }
.lang__btn {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 var(--s-3);
  background: none; border: 0; font: inherit; font-size: var(--t-sm); font-weight: 700;
  color: var(--navy); cursor: pointer; border-radius: var(--radius);
}
.lang__btn:hover { background: var(--tint-1); }
.lang__menu {
  position: absolute; right: 0; top: calc(100% + 4px); min-width: 190px;
  background: var(--white); border: 1px solid var(--near-white); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: var(--s-2); list-style: none; margin: 0; z-index: 110;
}
.lang__menu[hidden] { display: none; }
.lang__menu a { display: block; padding: var(--s-2) var(--s-3); border-radius: var(--radius); color: var(--navy); text-decoration: none; font-size: var(--t-sm); min-height: 40px; }
.lang__menu a:hover { background: var(--tint-1); }
.lang__menu small { display: block; color: var(--grey); font-size: var(--t-xs); }

.header .btn--primary { display: none; }
@media (min-width: 700px) { .header .btn--primary { display: inline-flex; } }

/* ------------------------------------------------------- mobile menu ---
   Zero JavaScript. A visually hidden checkbox, its label drawn as the
   burger, and the nav as their sibling. Checked state opens the nav with
   an adjacent-sibling selector, which every browser has supported for
   years. Deliberately NOT ::details-content, which is too new to be the
   only thing holding the desktop menu up.

   The six panels are already <details>, so on mobile they become
   accordions with no extra markup. Replaces the .burger and .drawer
   rules that lived here, which had no markup on any page and needed a
   JavaScript class toggle to work at all. */
.mnav-input { position: absolute; width: 1px; height: 1px; opacity: 0;
  pointer-events: none; }
.mnav-btn { display: none; align-items: center; justify-content: center;
  width: 48px; height: 48px; margin-left: auto; flex: none; cursor: pointer;
  border-radius: var(--radius); color: var(--navy); }
.mnav-btn:hover { color: var(--raspberry); }
.mnav-input:focus-visible + .mnav-btn { outline: 3px solid var(--mid-blue);
  outline-offset: 2px; }
.mnav-btn i { display: block; width: 22px; height: 2px; background: currentColor;
  position: relative; transition: background-color .15s var(--ease); }
.mnav-btn i::before, .mnav-btn i::after { content: ""; position: absolute; left: 0;
  width: 22px; height: 2px; background: currentColor;
  transition: transform .18s var(--ease), top .18s var(--ease); }
.mnav-btn i::before { top: -7px; }
.mnav-btn i::after  { top: 7px; }

@media (max-width: 999px) {
  .mnav-btn { display: inline-flex; }
  /* the burger becomes a cross while the menu is open */
  .mnav-input:checked + .mnav-btn i { background: transparent; }
  .mnav-input:checked + .mnav-btn i::before { top: 0; transform: rotate(45deg); }
  .mnav-input:checked + .mnav-btn i::after  { top: 0; transform: rotate(-45deg); }

  .header__bar { flex-wrap: wrap; }
  .nav { display: none; }
  .mnav-input:checked ~ .nav { display: block; width: 100%;
    margin-top: var(--s-3); padding-bottom: var(--s-4);
    border-top: 1px solid var(--near-white);
    max-height: calc(100vh - var(--header-h) - 60px); overflow-y: auto;
    -webkit-overflow-scrolling: touch; }

  .nav__item { display: block; border-bottom: 1px solid var(--near-white); }
  .nav__item > details > summary.nav__link { display: flex; align-items: center;
    justify-content: space-between; width: 100%; min-height: 52px;
    font-size: var(--t-base); font-weight: 800; padding: 0 4px; }
  /* a plus that becomes a minus, so a closed section reads as openable */
  .nav__item > details > summary.nav__link::after { content: "+";
    font-size: var(--t-xl); line-height: 1; color: var(--mid-blue); }
  .nav__item > details[open] > summary.nav__link::after { content: "−"; }

  .mega, .mega[hidden] { display: block; position: static; width: auto;
    max-width: none; transform: none; margin: 0 0 var(--s-3);
    padding: 0 0 var(--s-2); background: transparent; border: 0;
    box-shadow: none; }
  .mega__grid, .mega__grid--4, .mega__grid--5 { grid-template-columns: 1fr;
    gap: var(--s-4); }
  .mega__foot { flex-direction: column; align-items: flex-start;
    margin-top: var(--s-3); padding-top: var(--s-3); }
  .mnav-input:checked ~ .btn--primary { display: none; }
}
@media (min-width: 1000px) { .mnav-btn { display: none; } }

/* ---------------------------------------------------- sticky mobile CTA --- */
.mobile-cta {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  display: flex; gap: var(--s-2); padding: var(--s-3);
  padding-bottom: calc(var(--s-3) + env(safe-area-inset-bottom, 0px));
  background: rgba(255,255,255,.96);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border-top: 1px solid var(--near-white);
  transform: translateY(110%); transition: transform .25s var(--ease);
}
.mobile-cta.is-visible { transform: none; }
.mobile-cta .btn { flex: 1; }
@media (min-width: 700px) { .mobile-cta { display: none; } }
@media (max-width: 699px) { body { padding-bottom: 76px; } }

/* ----------------------------------------------------------------- hero --- */
.hero { background: var(--white); padding-block: var(--s-7) var(--s-8); }
.hero--tint { background: linear-gradient(180deg, var(--tint-1) 0%, var(--white) 100%); }
.hero__grid { display: grid; gap: var(--s-6); align-items: center; }
@media (min-width: 900px) { .hero__grid { grid-template-columns: 1fr 1fr; gap: var(--s-7); } }
.hero h1 { max-width: 21ch; }
.hero__sub { font-size: var(--t-lg); color: var(--grey); max-width: 52ch; margin-bottom: var(--s-5); }
.hero__entity {
  border-left: 3px solid var(--teal); padding: var(--s-2) 0 var(--s-2) var(--s-4);
  font-size: var(--t-sm); color: var(--navy); background: var(--tint-1);
  margin: 0 0 var(--s-5); border-radius: 0 var(--radius) var(--radius) 0;
}
.hero__proof { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4); margin-top: var(--s-5); font-size: var(--t-sm); color: var(--grey); }
.avatars { display: flex; }
.avatars span {
  width: 30px; height: 30px; border-radius: 50%; border: 2px solid var(--white);
  margin-left: -8px; display: grid; place-items: center; color: var(--white);
  font-size: 11px; font-weight: 800;
}
.avatars span:first-child { margin-left: 0; }
.hero__visual {
  background: var(--white); border: 1px solid var(--near-white); border-radius: var(--radius-lg);
  box-shadow: var(--shadow); padding: var(--s-5); position: relative;
}
.hero__visual::before {
  content: ""; position: absolute; inset: auto 0 0 0; height: 4px; background: var(--teal);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
.flow { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--s-3); }
.flow__node { border: 1px solid var(--light-teal); background: var(--tint-1); border-radius: var(--radius); padding: var(--s-4) var(--s-3); text-align: center; }
.flow__node b { display: block; font-size: var(--t-sm); }
.flow__node small { color: var(--grey); font-size: var(--t-xs); }
.flow__arrow { color: var(--raspberry); font-weight: 800; font-size: 20px; text-align: center; }
.flow__rows { margin-top: var(--s-4); border-top: 1px solid var(--near-white); padding-top: var(--s-3); }
.flow__row { display: flex; justify-content: space-between; gap: var(--s-3); font-size: var(--t-sm); padding: 6px 0; }
.flow__row span:last-child { color: var(--sage); font-weight: 700; }

/* ------------------------------------------------------------- logo bar --- */
.logobar { border-block: 1px solid var(--near-white); padding-block: var(--s-5); background: var(--white); }
.logobar__label { text-align: center; font-size: var(--t-xs); letter-spacing: .09em; text-transform: uppercase; color: var(--grey); margin-bottom: var(--s-4); }
.logobar__row { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: var(--s-4) var(--s-6); }
.logobar__row span { font-weight: 800; color: var(--grey); font-size: var(--t-sm); letter-spacing: .04em; }

/* ---------------------------------------------------------------- cards --- */
.grid { display: grid; gap: var(--s-4); }
.grid--2 { grid-template-columns: 1fr; }
.grid--3 { grid-template-columns: 1fr; }
.grid--4 { grid-template-columns: 1fr 1fr; }
@media (min-width: 700px) { .grid--2 { grid-template-columns: 1fr 1fr; } .grid--3 { grid-template-columns: repeat(3,1fr); } .grid--4 { grid-template-columns: repeat(4,1fr); } }
.card {
  background: var(--white); border: 1px solid var(--near-white); border-radius: var(--radius-lg);
  padding: var(--s-5); display: flex; flex-direction: column; gap: var(--s-2);
  text-decoration: none; color: inherit; transition: border-color .15s var(--ease), transform .15s var(--ease), box-shadow .15s var(--ease);
}
a.card:hover { border-color: var(--teal); transform: translateY(-2px); box-shadow: var(--shadow); }
.card h3 { margin: 0; font-size: var(--t-base); }
.card p { margin: 0; font-size: var(--t-sm); color: var(--grey); }
.card__tag { font-size: var(--t-xs); font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--mid-blue); }
.card__arrow { margin-top: auto; padding-top: var(--s-2); font-size: var(--t-sm); font-weight: 800; color: var(--raspberry); }
.section--navy .card { background: rgba(255,255,255,.06); border-color: rgba(153,202,221,.3); }
.section--navy .card p { color: var(--light-teal); }

/* ---------------------------------------------------------------- stats --- */
.stats { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4); }
@media (min-width: 700px) { .stats { grid-template-columns: repeat(4,1fr); } }
.stat { text-align: center; padding: var(--s-4) var(--s-2); border: 1px solid var(--near-white); border-radius: var(--radius-lg); background: var(--white); }
.stat b { display: block; font-size: var(--t-2xl); color: var(--raspberry); line-height: 1.1; }
.stat small { color: var(--grey); font-size: var(--t-xs); }

/* -------------------------------------------------------------- filters --- */
.filters { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-bottom: var(--s-5); }
.chip {
  min-height: 44px; padding: var(--s-2) var(--s-4); border-radius: 999px;
  border: 1px solid var(--light-teal); background: var(--white); color: var(--navy);
  font: inherit; font-size: var(--t-sm); font-weight: 700; cursor: pointer;
}
.chip[aria-pressed="true"] { background: var(--navy); color: var(--white); border-color: var(--navy); }
.chip:hover { border-color: var(--teal); }

/* ------------------------------------------------------------------ FAQ --- */
.faq { max-width: 78ch; }
.faq__item { border-bottom: 1px solid var(--near-white); padding-block: var(--s-4); }
.faq__item h3 { margin-bottom: var(--s-2); font-size: var(--t-base); }
.faq__item p { margin: 0; color: var(--grey); font-size: var(--t-sm); }

/* ------------------------------------------------------------ breadcrumb --- */
.crumbs { font-size: var(--t-xs); color: var(--grey); padding-block: var(--s-3); }
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s-2); margin: 0; padding: 0; }
.crumbs a { color: var(--grey); }
.crumbs li + li::before { content: "/"; margin-right: var(--s-2); color: var(--light-teal); }

/* ----------------------------------------------------------------- form --- */
.form { display: grid; gap: var(--s-4); background: var(--white); border: 1px solid var(--near-white); border-radius: var(--radius-lg); padding: var(--s-5); box-shadow: var(--shadow); }
.field { display: grid; gap: var(--s-2); }
.field label { font-size: var(--t-sm); font-weight: 700; }
.field input, .field select {
  min-height: 48px; padding: var(--s-3); font: inherit; font-size: 16px; /* 16px stops iOS zoom */
  border: 1px solid var(--grey); border-radius: var(--radius); background: var(--white); color: var(--navy); width: 100%;
}
.field input:focus-visible, .field select:focus-visible { border-color: var(--mid-blue); }
.form__note { font-size: var(--t-xs); color: var(--grey); margin: 0; }

/* --------------------------------------------------------------- footer --- */
.footer { background: var(--navy); color: var(--near-white); padding-block: var(--s-8) var(--s-6); margin-top: var(--s-8); }
.footer a { color: var(--near-white); text-decoration: none; font-size: var(--t-sm); }
.footer a:hover { text-decoration: underline; color: var(--light-teal); }
.footer__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-6); }
@media (min-width: 900px) { .footer__grid { grid-template-columns: 1.4fr repeat(4, 1fr); } }
.footer h3 { font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .09em; color: var(--light-teal); margin-bottom: var(--s-3); }
.footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.footer__bottom { margin-top: var(--s-7); padding-top: var(--s-4); border-top: 1px solid rgba(237,237,236,.18); display: flex; flex-wrap: wrap; gap: var(--s-3); justify-content: space-between; font-size: var(--t-xs); color: var(--light-teal); }

/* ======================================================= SUMMARY BLOCK ===
   The "In short" block. Written for two readers at once: a human skimming
   before they commit to the page, and a model looking for a liftable answer
   near the top. It is a <dl>, because a definition list is the one HTML
   structure that already means "key, then value" without any markup we invent.

   Rules: it must add facts the hero does not state, never restate the H1, and
   never contain anything that is not also said in full further down the page.
   Searchable flags 31 rapidionline.com pages for having no summary block.
   =========================================================================== */
.summary {
  border: 1px solid var(--light-teal); background: var(--tint-1);
  border-radius: var(--radius-lg); padding: var(--s-5);
  margin-block: var(--s-6); max-width: 82ch;
}
.summary > h2 {
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--mid-blue); margin: 0 0 var(--s-3);
}
.summary dl { margin: 0; display: grid; gap: var(--s-2) var(--s-4); }
@media (min-width: 640px) { .summary dl { grid-template-columns: minmax(9rem, 15rem) 1fr; } }
.summary dt { font-weight: 700; font-size: var(--t-sm); color: var(--navy); }
.summary dd { margin: 0; font-size: var(--t-sm); color: var(--grey); }
@media (max-width: 639px) { .summary dd { margin-bottom: var(--s-2); } }
.summary__meta {
  margin: var(--s-4) 0 0; padding-top: var(--s-3);
  border-top: 1px solid var(--light-teal);
  font-size: var(--t-xs); color: var(--grey);
}

/* ============================================================== GRAPHICS ===
   Every graphic on this site is built from one motif: horizontal lines that
   terminate in ring-nodes, with a diagonal break. That is the Rapidi_lines
   watermark from the 2017 brand collateral, and using it as the drawing
   vocabulary is what makes the illustrations look like Rapidi rather than
   like any other integration vendor.

   All icons live in a single inline <svg><defs> sprite at the top of each
   page, referenced with <use href="#id">. Inline means zero extra HTTP
   requests and it works over file:// where an external sprite would not.
   In the HubSpot theme the sprite becomes one partial include.
   =========================================================================== */

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Icon sizing. Icons inherit currentColor so one drawing works on any
   background, which is why none of them carry hard-coded fills. */
.ico { width: 24px; height: 24px; display: block; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.ico--lg { width: 40px; height: 40px; }
.ico--sm { width: 18px; height: 18px; stroke-width: 2.2; }

.icobox {
  width: 52px; height: 52px; border-radius: 12px; display: grid; place-items: center;
  background: var(--tint-2); color: var(--mid-blue); flex: none; margin-bottom: var(--s-3);
}
.icobox--raspberry { background: var(--pink-tint); color: var(--raspberry); }
.icobox--sage { background: var(--sage-tint); color: var(--sage); }
.section--navy .icobox { background: rgba(153,202,221,.14); color: var(--light-teal); }

/* The circuit-node watermark, used at low opacity behind sections. Kept as a
   background image so it never enters the accessibility tree.

   SIZING. The artwork is sized as a PERCENTAGE of the section, not in fixed
   pixels, so the motif holds the same proportion at every width. This is the
   same rule the carousels and the ebook CTA banners use, and it is the only
   part of this block that is a judgement call rather than a measurement.

   The ring-and-bar unit is 0.0875 of the artwork width, measured off the brand
   file. At 150% the ring lands at 13.1% of the section width, which sits inside
   the band the two reference systems use:

     carousels   ring 14.8% to 35% of a 1200px canvas
     ebook CTA   ring 11.8% and 17.8% of a 2000px canvas
     here        ring 13.1% of the section, at any width

   The old rule pinned the artwork at 520px, which put the ring at about 3.8% of
   a desktop section and froze it again at 320px on mobile. That is what made it
   read as a stray texture rather than the brand motif.

   The artwork is a 3200px render of Rapidi_lines.ai. The 842px files are kept
   because other work references them. */
.wm { position: relative; isolation: isolate; }
.wm::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: url("/sa/crowou33cuwi89054mfyxgmu7adf/rapidi-lines-hi.png") right -8vw top 50% / 150% auto no-repeat;
  opacity: .06;
}
.section--navy.wm::before { background-image: url("/sa/tz9jn189tlnrlgl9rrrldrs55t9u/rapidi-lines-white-hi.png"); opacity: .10; }
/* Mobile keeps the same proportional size. Only the vertical anchor moves, so
   the rings sit above the text block rather than behind it. */
@media (max-width: 700px) { .wm::before { background-position: right -14vw top 8%; } }

/* Hero artwork. Sits in the same slot the old plain box occupied, but is now a
   drawn SVG scene on a tinted card. */
.hero__art {
  position: relative; border-radius: var(--radius-lg); overflow: hidden;
  background: linear-gradient(150deg, var(--tint-2) 0%, var(--white) 62%);
  border: 1px solid var(--near-white); box-shadow: var(--shadow);
}
.hero__art svg { display: block; width: 100%; height: auto; }

/* Logo bar chips. Deliberately not fake vendor logos: these are drawn badges
   with a node glyph. Real Salesforce, Microsoft and HubSpot marks are dropped
   in at build time, under their own trademark rules. */
.badge {
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: 8px 14px; border: 1px solid var(--near-white); border-radius: 999px;
  background: var(--white); color: var(--grey);
  font-size: var(--t-xs); font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}
.badge .ico { width: 16px; height: 16px; color: var(--teal); }

/* Card artwork strip. A flat vector scene at the top of a card, drawn from the
   same line-and-node vocabulary. */
.card__art {
  margin: calc(var(--s-5) * -1) calc(var(--s-5) * -1) var(--s-4);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0; overflow: hidden;
  background: var(--tint-1); border-bottom: 1px solid var(--near-white);
}
.card__art svg { display: block; width: 100%; height: auto; }
.card--art { padding-top: var(--s-5); }

/* Inline node rule, used as a section divider and under eyebrows. */
.noderule { display: block; width: 76px; height: 10px; margin-bottom: var(--s-4); color: var(--raspberry); }

/* Step number plate for the how-it-works row. */
.stepnum {
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  background: var(--raspberry); color: var(--white);
  font-size: var(--t-sm); font-weight: 800; flex: none;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}

/* ==========================================================================
   TEMPLATE SYSTEM MODULES                                    added 5 Aug 2026
   Everything below serves the seven-template mockup system. Each block maps to
   a numbered point in the AI-search page structure, noted in the comment.
   Nothing here introduces a second layout system: same tokens, same grid.
   ========================================================================== */

/* --- Point 5. The answer block ------------------------------------------
   A 40 to 60 word prose answer to the page's main question, placed above the
   fold. It sits inside the existing .summary card, ahead of the <dl>, because
   AI engines lift the first prose paragraph and humans read the list. */
.summary__answer {
  margin: 0 0 var(--s-4); font-size: var(--t-lg); line-height: 1.55;
  color: var(--navy); font-weight: 500; max-width: 62ch;
}
.summary__answer + dl { padding-top: var(--s-4); border-top: 1px solid var(--light-teal); }

/* --- Point 2. The byline -------------------------------------------------
   A named person with a face, a credential and a link to their bio. Author
   markup is one of the strongest citation signals, so this is a real module
   rather than a decorative line of grey text. */
.byline { display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap; margin-block: var(--s-5); }
.byline__avatar {
  width: 52px; height: 52px; border-radius: 50%; flex: none; overflow: hidden;
  display: grid; place-items: center;
  background: var(--tint-2); color: var(--mid-blue);
  font-size: var(--t-base); font-weight: 800; letter-spacing: .02em;
  border: 1px solid var(--light-teal);
}
.byline__avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.byline__who { min-width: 0; }
.byline__name { display: block; margin: 0; font-size: var(--t-base); font-weight: 700; color: var(--navy); }
.byline__name a { color: inherit; }
.byline__cred { display: block; margin: 2px 0 0; font-size: var(--t-sm); color: var(--grey); }
.byline__meta { margin: 2px 0 0; font-size: var(--t-xs); color: var(--grey); }
.byline__meta time { font-variant-numeric: tabular-nums; }

/* --- Point 14. The last-updated stamp -----------------------------------
   Visible, not just in schema. A page with no date reads as undated, and an
   undated page gets treated as stale. */
.stamp {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-xs); color: var(--grey);
  padding: var(--s-2) var(--s-3); border: 1px solid var(--near-white);
  border-radius: 999px; background: var(--white);
}
.stamp .ico { width: 14px; height: 14px; color: var(--teal); }
.section--navy .stamp { background: transparent; border-color: rgba(153,202,221,.32); color: var(--light-teal); }

/* --- Point 12. The comparison table -------------------------------------
   A real <table> with a caption and scoped headers. The horizontal scroll
   lives on the wrapper so a wide table never widens the page on a phone.
   Header row padding equals body row padding: a shorter header row is a
   standing correction on Rapidi tables. */
.cmp { overflow-x: auto; margin-block: var(--s-5); border: 1px solid var(--near-white); border-radius: var(--radius-lg); }
.cmp table { width: 100%; min-width: 34rem; border-collapse: collapse; font-size: var(--t-sm); }
.cmp caption { text-align: left; padding: var(--s-4) var(--s-4) 0; font-size: var(--t-sm); color: var(--grey); caption-side: top; }
.cmp th, .cmp td { padding: var(--s-4); text-align: left; vertical-align: top; border-bottom: 1px solid var(--near-white); }
.cmp thead th { background: var(--tint-1); color: var(--navy); font-weight: 700; white-space: nowrap; }
.cmp tbody th { font-weight: 600; color: var(--navy); }
.cmp tbody tr:last-child th, .cmp tbody tr:last-child td { border-bottom: 0; }
.cmp td[data-own="yes"] { color: var(--navy); font-weight: 600; }
.cmp .unverified { color: var(--grey); font-style: italic; }

/* --- Point 4 support. Table of contents ---------------------------------
   Built from the page's own H2 questions, so the contents list doubles as a
   list of the questions the page answers. */
.toc { border-left: 3px solid var(--raspberry); padding: 0 0 0 var(--s-4); margin-block: var(--s-6); }
.toc h2 { font-size: var(--t-xs); font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--mid-blue); margin: 0 0 var(--s-3); }
.toc ol { margin: 0; padding-left: var(--s-5); display: grid; gap: var(--s-2); }
.toc li { font-size: var(--t-sm); }
.toc a { color: var(--navy); text-decoration-color: var(--light-teal); }

/* --- Key takeaways -------------------------------------------------------
   Three to five extractable single-sentence claims. This is the block an AI
   engine quotes when it summarises the article. */
.takeaways { background: var(--tint-2); border-radius: var(--radius-lg); padding: var(--s-5); margin-block: var(--s-6); }
.takeaways h2 { font-size: var(--t-xs); font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--mid-blue); margin: 0 0 var(--s-3); }
.takeaways ul { margin: 0; padding-left: var(--s-5); display: grid; gap: var(--s-3); }
.takeaways li { font-size: var(--t-sm); color: var(--navy); }

/* --- Article body --------------------------------------------------------
   One measure, one rhythm. Everything an author writes lands inside .article,
   so prose spacing is decided once rather than per page. */
.article { max-width: 72ch; }
.article > * + * { margin-top: var(--s-4); }
.article h2 { margin-top: var(--s-7); font-size: var(--t-xl); scroll-margin-top: calc(var(--header-h) + 16px); }
.article h3 { margin-top: var(--s-5); font-size: var(--t-lg); }
.article p { color: var(--grey); }
.article ul, .article ol { padding-left: var(--s-5); display: grid; gap: var(--s-2); color: var(--grey); }
.article figure { margin: var(--s-6) 0; }
.article figure svg, .article figure img { display: block; width: 100%; height: auto; border-radius: var(--radius-lg); border: 1px solid var(--near-white); }
.article figcaption { margin-top: var(--s-2); font-size: var(--t-xs); color: var(--grey); }
.article blockquote {
  margin: var(--s-6) 0; padding: var(--s-4) var(--s-5);
  border-left: 3px solid var(--teal); background: var(--tint-1); border-radius: 0 var(--radius) var(--radius) 0;
}
.article blockquote p { color: var(--navy); font-size: var(--t-lg); margin: 0; }
.article blockquote cite { display: block; margin-top: var(--s-2); font-size: var(--t-sm); font-style: normal; color: var(--grey); }
.article .cmp, .article .takeaways, .article .toc { max-width: none; }

/* --- Article header meta row -------------------------------------------- */
.artmeta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); font-size: var(--t-sm); color: var(--grey); }
.artmeta .chip { cursor: default; min-height: 0; padding: 4px 12px; font-size: var(--t-xs); }

/* --- Post card, used by both overview templates -------------------------- */
.postcard__meta { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-3); font-size: var(--t-xs); color: var(--grey); margin-bottom: var(--s-2); }
.postcard__meta time { font-variant-numeric: tabular-nums; }
.postcard h3 { font-size: var(--t-lg); margin-bottom: var(--s-2); }
.postcard p { font-size: var(--t-sm); color: var(--grey); }

/* --- Release group, product update overview ------------------------------
   Product updates are read by release, not by relevance, so the overview
   groups by version rather than offering a topic filter. */
.release { border-top: 1px solid var(--near-white); padding-top: var(--s-5); margin-top: var(--s-7); }
.release__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s-3); margin-bottom: var(--s-4); }
.release__head h2 { margin: 0; font-size: var(--t-xl); }
.verchip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 12px; border-radius: 999px; background: var(--raspberry); color: var(--white);
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .04em; font-variant-numeric: tabular-nums;
}
.verchip--past { background: var(--near-white); color: var(--navy); }

/* --- Pagination ---------------------------------------------------------- */
.pager { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; justify-content: center; margin-top: var(--s-7); }
.pager a, .pager span {
  min-width: 44px; min-height: 44px; display: grid; place-items: center; padding: 0 var(--s-3);
  border: 1px solid var(--near-white); border-radius: var(--radius); font-size: var(--t-sm); color: var(--navy);
}
.pager [aria-current="page"] { background: var(--navy); color: var(--white); border-color: var(--navy); }

/* --- Build note ----------------------------------------------------------
   Visible only in the mockups. It says what a block needs before it can ship,
   so a placeholder never gets mistaken for finished content. */
.note {
  border: 1px dashed var(--gold); background: var(--gold-tint); border-radius: var(--radius);
  padding: var(--s-4); margin-block: var(--s-5); font-size: var(--t-sm); color: var(--navy);
}
.note b { color: var(--navy); }
.note p { margin: 0; }
.note p + p { margin-top: var(--s-2); }

/* --- Template index page ------------------------------------------------- */
.tplgrid { display: grid; gap: var(--s-4); grid-template-columns: 1fr; }
@media (min-width: 700px) { .tplgrid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .tplgrid { grid-template-columns: repeat(3, 1fr); } }
.tplcard { display: flex; flex-direction: column; gap: var(--s-2); }
.tplcard__no { font-size: var(--t-xs); font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--mid-blue); }
.matrix { overflow-x: auto; }
.matrix table { width: 100%; min-width: 52rem; border-collapse: collapse; font-size: var(--t-xs); }
.matrix th, .matrix td { padding: var(--s-3); border-bottom: 1px solid var(--near-white); text-align: left; }
.matrix thead th { background: var(--tint-1); color: var(--navy); position: sticky; top: 0; }
.matrix tbody th { font-weight: 600; color: var(--navy); min-width: 15rem; }
.matrix td { text-align: center; color: var(--grey); }
.matrix .yes { color: var(--raspberry); font-weight: 800; }

/* Visually hidden, still read by assistive technology and by crawlers. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.lg__t b  { display: block; font-weight: 700; font-size: 12.5px; }
.lg__t em { display: block; font-style: normal; font-size: 11px; color: var(--grey); line-height: 1.4; margin: 1px 0 2px; }
.lg { display: flex; gap: 9px; align-items: flex-start; padding: 5px 0; border-top: 1px solid var(--near-white); }
.lg__n {
  flex: none; width: 21px; height: 21px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--near-white); color: var(--grey);
  font-size: 11px; font-weight: 700;
}
.lg__t { flex: 1; }
.lg__s { display: block; font-size: 10.5px; color: var(--grey); text-transform: uppercase; letter-spacing: .05em; }
.lg__s::after { content: "not on this page"; }

/* One rule per point. :has() reads the real markup, so the legend is measured,
   not maintained by hand. */
html:has([data-pt="1"])  .lg[data-n="1"]  .lg__n,
html:has([data-pt="2"])  .lg[data-n="2"]  .lg__n,
html:has([data-pt="3"])  .lg[data-n="3"]  .lg__n,
html:has([data-pt="4"])  .lg[data-n="4"]  .lg__n,
html:has([data-pt="5"])  .lg[data-n="5"]  .lg__n,
html:has([data-pt="6"])  .lg[data-n="6"]  .lg__n,
html:has([data-pt="7"])  .lg[data-n="7"]  .lg__n,
html:has([data-pt="8"])  .lg[data-n="8"]  .lg__n,
html:has([data-pt="9"])  .lg[data-n="9"]  .lg__n,
html:has([data-pt="10"]) .lg[data-n="10"] .lg__n,
html:has([data-pt="11"]) .lg[data-n="11"] .lg__n,
html:has([data-pt="12"]) .lg[data-n="12"] .lg__n,
html:has([data-pt="13"]) .lg[data-n="13"] .lg__n,
html:has([data-pt="14"]) .lg[data-n="14"] .lg__n { background: var(--sage); color: var(--white); }

html:has([data-pt="1"])  .lg[data-n="1"]  .lg__s::after,
html:has([data-pt="2"])  .lg[data-n="2"]  .lg__s::after,
html:has([data-pt="3"])  .lg[data-n="3"]  .lg__s::after,
html:has([data-pt="4"])  .lg[data-n="4"]  .lg__s::after,
html:has([data-pt="5"])  .lg[data-n="5"]  .lg__s::after,
html:has([data-pt="6"])  .lg[data-n="6"]  .lg__s::after,
html:has([data-pt="7"])  .lg[data-n="7"]  .lg__s::after,
html:has([data-pt="8"])  .lg[data-n="8"]  .lg__s::after,
html:has([data-pt="9"])  .lg[data-n="9"]  .lg__s::after,
html:has([data-pt="10"]) .lg[data-n="10"] .lg__s::after,
html:has([data-pt="11"]) .lg[data-n="11"] .lg__s::after,
html:has([data-pt="12"]) .lg[data-n="12"] .lg__s::after,
html:has([data-pt="13"]) .lg[data-n="13"] .lg__s::after,
html:has([data-pt="14"]) .lg[data-n="14"] .lg__s::after { content: "on this page"; color: var(--sage); }

/* Held blocks override the green, because built is not the same as finished. */
html:has([data-pt-held="2"])  .lg[data-n="2"]  .lg__n,
html:has([data-pt-held="11"]) .lg[data-n="11"] .lg__n,
html:has([data-pt-held="12"]) .lg[data-n="12"] .lg__n { background: var(--gold); color: var(--navy); }
html:has([data-pt-held="2"])  .lg[data-n="2"]  .lg__s::after,
html:has([data-pt-held="11"]) .lg[data-n="11"] .lg__s::after,
html:has([data-pt-held="12"]) .lg[data-n="12"] .lg__s::after { content: "built, waiting on content"; color: var(--gold-text); }

/* ---- Extended footer (11 columns, Boomi-shaped) -------------------------
   The four-column footer carried 22 links. This carries 76, which is the
   point: a footer this size is a second navigation, and it is where the
   pages that do not earn a menu slot stay reachable and crawlable. */
.footer__grid--wide {
  display: grid; gap: var(--s-6) var(--s-5);
  /* min(150px, 100%) stops the track demanding 150px on a 288px content box, and
     min-width:0 removes the implicit min-width:auto that lets a grid item push its
     track wider than the container. Together these were the 7px overflow at 320. */
  grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  align-items: start;
}
.footer__grid--wide > * { min-width: 0; }
.footer__grid--wide .footer__brand { grid-column: 1 / -1; max-width: 46ch; }
@media (min-width: 1100px) { .footer__grid--wide .footer__brand { grid-column: span 2; } }
.footer__brand p { color: var(--light-teal); font-size: var(--t-sm); margin: var(--s-3) 0 var(--s-4); }
.footer__col h4 {
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--light-teal); margin: 0 0 var(--s-3);
}
.footer__col a {
  display: block; color: var(--white); text-decoration: none;
  font-size: var(--t-sm); padding: 5px 0; min-height: 30px;
}
.footer__col a:hover { text-decoration: underline; }
.footer__legal, .footer__lang { display: flex; flex-wrap: wrap; gap: var(--s-4); margin: 0; }
.footer__legal a, .footer__lang a { color: var(--light-teal); font-size: var(--t-xs); }
.footer__bottom { margin-top: var(--s-7); padding-top: var(--s-5); border-top: 1px solid rgba(153,202,221,.22); }
.footer__bottom p { font-size: var(--t-xs); color: var(--light-teal); margin: 0 0 var(--s-3); }

/* ---- Pricing module (added 14 Aug 2026 for pricing.html) ----------------
   Rule: a price is never hidden. No display:none, no geo class, no JS
   reveal. Both currencies render together, separated, server-side. */
.tiers { display: grid; gap: var(--s-4); grid-template-columns: 1fr; margin-block: var(--s-5); }
@media (min-width: 700px) { .tiers { grid-template-columns: repeat(2,1fr); } }
@media (min-width: 1000px) { .tiers { grid-template-columns: repeat(4,1fr); } }
.plan { display: flex; flex-direction: column; border: 1px solid var(--near-white); border-radius: var(--radius-lg); padding: var(--s-5); background: var(--white); }
.tier--featured { border-color: var(--raspberry); box-shadow: 0 0 0 1px var(--raspberry) inset; }
.plan__name { font-size: var(--t-base); margin: 0 0 var(--s-2); color: var(--navy); }
.plan__price { margin: 0 0 var(--s-1); font-size: var(--t-lg); font-weight: 700; color: var(--navy); line-height: 1.15; }
.plan__price .cur { white-space: nowrap; }
.plan__price .sep { color: var(--grey); font-weight: 400; padding-inline: .35em; }
.plan__term { margin: 0 0 var(--s-4); font-size: var(--t-sm); color: var(--grey); }
.plan__lead { font-size: var(--t-sm); color: var(--grey); margin: 0 0 var(--s-4); }
.plan__list { list-style: none; margin: 0 0 var(--s-5); padding: 0; font-size: var(--t-sm); }
.plan__list li { padding-block: var(--s-2); border-top: 1px solid var(--near-white); }
.plan .btn { margin-top: auto; }
.pricekey { font-size: var(--t-sm); color: var(--grey); margin-block: var(--s-3); }
.pricekey b { color: var(--navy); }

/* ---- Expanded menu view (mockup only) -----------------------------------
   A mega menu only exists on hover or focus, so a static mockup shows seven
   words and nothing else. This toggle drops every panel open at once and
   stacks them, so the whole main menu can be read and screenshotted.

   It deliberately re-flows the header rather than overlaying, because seven
   overlapping absolute panels are unreadable. Mockup only, like the other
   toggles, and off by default. */

.menu-input { position: absolute; opacity: 0; pointer-events: none; }

.menu-toggle {
  position: fixed; left: 404px; bottom: 16px; z-index: 9000;
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 18px; border-radius: 22px; cursor: pointer;
  background: var(--navy); color: var(--white);
  font: 600 var(--t-xs)/1 var(--font); letter-spacing: .04em; text-transform: uppercase;
  box-shadow: 0 6px 20px rgba(42,56,80,.28);
}
.menu-toggle::before {
  content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--grey); flex: none;
}
html:has(.menu-input:checked) .menu-toggle { background: var(--sage); }
html:has(.menu-input:checked) .menu-toggle::before { background: var(--white); }

/* The header stops being sticky while expanded, or it would pin a very tall
   block to the top of the viewport. */
html:has(.menu-input:checked) .header { position: static; }
html:has(.menu-input:checked) .header__bar { flex-wrap: wrap; align-items: flex-start; }

html:has(.menu-input:checked) .nav {
  display: block; width: 100%; margin-top: var(--s-5);
  border-top: 1px solid var(--near-white);
}
html:has(.menu-input:checked) .nav__item {
  position: static; display: block;
  border-bottom: 1px solid var(--near-white); padding: var(--s-4) 0;
}
html:has(.menu-input:checked) .nav__link {
  font-size: var(--t-lg); font-weight: 800; color: var(--navy);
  pointer-events: none; padding-left: 0;
}

html:has(.menu-input:checked) .mega,
html:has(.menu-input:checked) .mega[hidden] {
  display: block; position: static; transform: none;
  width: 100%; margin-top: var(--s-3); padding: 0;
  background: transparent; border: 0; box-shadow: none;
}
html:has(.menu-input:checked) .mega__grid { gap: var(--s-5); }
html:has(.menu-input:checked) .mega__foot {
  margin-top: var(--s-4); padding-top: var(--s-3); font-size: var(--t-sm);
}
/* A menu item with no panel still needs to read as an item. */
html:has(.menu-input:checked) .nav__item > a.nav__link::after {
  content: " (no panel, links straight through)";
  font-size: var(--t-xs); font-weight: 400; color: var(--grey); letter-spacing: 0; text-transform: none;
}
@media (max-width: 760px) {
  html:has(.menu-input:checked) .mega__grid { grid-template-columns: 1fr; }
  .menu-toggle { left: 16px; bottom: 120px; }
}
@media print { .menu-toggle { display: none; } }

/* ---- Dropdown on hover and focus ----------------------------------------
   site.js opens the panels on click and manages aria-expanded, which is the
   accessible behaviour and stays. This adds hover and focus-within on top, so
   the dropdown also works with the script blocked, and so a static screenshot
   can capture a panel open. The [hidden] attribute needs out-specifying, hence
   the .nav__item prefix. */
@media (hover: hover) and (min-width: 900px) {
  .nav__item:hover > .mega[hidden],
  .nav__item:focus-within > .mega[hidden] { display: block; }
}
.nav__item:focus-within > .mega[hidden] { display: block; }

/* ---- Pricing plans ------------------------------------------------------
   Four tiers, so the grid has to hold four across on desktop and stack cleanly.
   The "most popular" tier is raised rather than recoloured, because a fifth
   colour would leave the v12 palette. */
.plans { display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fit, minmax(min(220px,100%), 1fr)); margin: var(--s-6) 0; }
.plan {
  background: var(--white); border: 1px solid var(--near-white); border-radius: var(--radius-lg);
  padding: var(--s-5); display: flex; flex-direction: column; min-width: 0;
}
.plan--best { border-color: var(--raspberry); box-shadow: 0 8px 26px rgba(204,68,116,.14); }
.plan__flag {
  display: inline-block; align-self: flex-start; margin-bottom: var(--s-3);
  background: var(--raspberry); color: var(--white); border-radius: 4px;
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  padding: 3px 9px;
}
.plan__name { font-size: var(--t-lg); font-weight: 800; margin: 0 0 var(--s-2); color: var(--navy); }
.plan__for { font-size: var(--t-sm); color: var(--grey); margin: 0 0 var(--s-4); }
.plan__price { font-size: var(--t-2xl); font-weight: 800; line-height: 1.1; margin: 0; }
.plan__alt { font-size: var(--t-sm); color: var(--grey); margin: 2px 0 0; }
.plan__cycle { font-size: var(--t-xs); color: var(--grey); margin: 2px 0 var(--s-4); }
.plan ul { list-style: none; margin: 0 0 var(--s-5); padding: 0; }
.plan li { font-size: var(--t-sm); padding-left: 22px; position: relative; margin-bottom: var(--s-2); }
.plan li::before { content: ""; position: absolute; left: 0; top: .55em; width: 10px; height: 6px;
  border-left: 2px solid var(--sage); border-bottom: 2px solid var(--sage); transform: rotate(-45deg); }
.plan .btn { margin-top: auto; }

/* ==================================================== PRICING, LOOM LAYOUT ===
   Structure taken from loom.com/pricing: a controls row above the cards, plan
   cards carrying a short key-feature list, then the full feature list grouped
   by category inside each card, then social proof, then a long open FAQ.

   Two deliberate departures, because copying them would make the page lie:
   Loom's controls are a team-size slider and a monthly/annual toggle. Rapidi is
   not priced per user and every published price is annual, so the honest
   equivalent controls are the currency (Rapidi publishes EUR and USD) and the
   number of applications, which is what actually moves you between plans.
   =========================================================================== */

.pricehead { text-align: center; }
.pricehead h1 { max-width: 18ch; margin-inline: auto; }
.pricehead .lede { margin-inline: auto; }

.pctl {
  display: flex; flex-wrap: wrap; gap: var(--s-5) var(--s-7); justify-content: center;
  align-items: center; margin: var(--s-6) 0 var(--s-4);
}
.pctl__group { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.pctl__label { font-size: var(--t-sm); font-weight: 700; color: var(--navy); }
.pctl__seg { display: inline-flex; background: var(--tint-2); border-radius: 22px; padding: 3px; }
.pctl__seg input { position: absolute; opacity: 0; pointer-events: none; }
.pctl__seg label {
  min-height: 38px; display: inline-flex; align-items: center; padding: 0 16px;
  border-radius: 19px; cursor: pointer; font-size: var(--t-sm); font-weight: 700; color: var(--navy);
}
body:has(#cur-eur:checked) label[for="cur-eur"],
body:has(#cur-usd:checked) label[for="cur-usd"],
body:has(#apps-2:checked)  label[for="apps-2"],
body:has(#apps-3:checked)  label[for="apps-3"],
body:has(#apps-many:checked) label[for="apps-many"] { background: var(--navy); color: var(--white); }
.pctl__seg input:focus-visible + label { outline: 3px solid var(--mid-blue); outline-offset: 2px; }
.pctl__note { font-size: var(--t-xs); font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--sage); background: var(--sage-tint); padding: 3px 9px; border-radius: 4px; }

/* currency swap, pure CSS */
.cur-usd { display: none; }
body:has(#cur-usd:checked) .cur-eur { display: none; }
body:has(#cur-usd:checked) .cur-usd { display: inline; }

/* the applications selector dims the plans it does not answer */
body:has(#apps-2:checked)    .plan:not([data-apps~="2"]),
body:has(#apps-3:checked)    .plan:not([data-apps~="3"]),
body:has(#apps-many:checked) .plan:not([data-apps~="many"]) { opacity: .45; }
body:has(#apps-2:checked)    .plan[data-apps~="2"],
body:has(#apps-3:checked)    .plan[data-apps~="3"],
body:has(#apps-many:checked) .plan[data-apps~="many"] { outline: 2px solid var(--mid-blue); outline-offset: 3px; }

.plan__inherit { font-size: var(--t-sm); font-weight: 700; color: var(--navy); margin: 0 0 var(--s-2); }
.plan__keys { font-size: var(--t-xs); font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--mid-blue); margin: var(--s-4) 0 var(--s-3); }
.plan__new { display: inline-block; margin-left: 6px; background: var(--gold); color: var(--navy);
  font-size: 9px; font-weight: 800; letter-spacing: .07em; padding: 1px 5px; border-radius: 3px; vertical-align: 2px; }

/* the full feature list, grouped, inside each card */
.plan details { margin-top: var(--s-4); border-top: 1px solid var(--near-white); padding-top: var(--s-3); }
.plan summary { cursor: pointer; font-size: var(--t-sm); font-weight: 700; color: var(--mid-blue); list-style: none; }
.plan summary::-webkit-details-marker { display: none; }
.plan summary::after { content: " +"; }
.plan details[open] summary::after { content: " -"; }
.plan details h4 { font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .07em;
  color: var(--grey); margin: var(--s-4) 0 var(--s-2); }

.proofbar { text-align: center; }
.proofbar p { max-width: 60ch; margin-inline: auto; font-size: var(--t-lg); font-weight: 700; }
.proofbar__row { display: flex; flex-wrap: wrap; gap: var(--s-5); justify-content: center; margin-top: var(--s-5); }
.proofbar__row span { font-size: var(--t-sm); color: var(--grey); }

/* ---- Hero motif at real watermark scale ---------------------------------
   The first CSS motif used 18px rings, which is 1.3 per cent of the hero width
   against the watermark's 13.1 per cent. This version uses the measured
   geometry from Rapidi_lines.ai, the same ratios the carousels and the section
   watermark use: ring outer 13.1% of width, stroke 0.875 of the radius, bar
   0.69 of the stroke, bar starting at the inner edge of the stroke.

   Two copies of the same group are laid end to end and translated together, so
   the loop has no seam. */
.mhero--xl { position: relative; overflow: hidden; background: var(--navy); min-height: 520px; display: grid; align-items: center; }
.mhero--xl .wrap { padding-block: var(--s-8); position: relative; z-index: 1; }
.mhero--xl h2 { color: var(--white); max-width: 20ch; }
.mhero--xl p { color: var(--light-teal); max-width: 54ch; }
.mrail {
  position: absolute; inset: 0; width: 100%; height: 100%;
  color: var(--light-teal); opacity: .16; pointer-events: none;
}
.mrail__g { animation: mrailrun 26s linear infinite; }
.mrail__g--b { transform: translateX(-1440px); }
@keyframes mrailrun { from { transform: translateX(0); } to { transform: translateX(1440px); } }
.mrail__g--b { animation-name: mrailrunb; }
@keyframes mrailrunb { from { transform: translateX(-1440px); } to { transform: translateX(0); } }
@media (prefers-reduced-motion: reduce) { .mrail__g { animation: none; } }

/* People footage is brighter and busier than abstract footage, so the scrim has
   to work harder on the left where the copy sits, while still letting the right
   of the frame stay readable as a picture. */
.vhero--people::after {
  background: linear-gradient(90deg, rgba(42,56,80,.97) 0%, rgba(42,56,80,.94) 45%, rgba(42,56,80,.74) 100%);
}
.vtag { display: inline-block; font-size: .66rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; padding: 3px 9px; border-radius: 4px; background: var(--tint-2);
  color: var(--mid-blue); margin-left: 8px; vertical-align: 3px; }


/* ============================================================================
   SITE BUILD OVERRIDES                                        26 August 2026
   The design system is used as authored. Three things are changed, each for a
   measured reason, and nothing else.
   ========================================================================== */

/* 1. The panel was centred on its trigger with left:50% and translateX(-50%),
      which pushes a 920px panel off the left edge when the trigger sits at the
      start of the bar. Anchor it to the header instead. */
.header__bar{position:relative}
.nav__item{position:static}
.mega{left:0;right:0;transform:none;width:auto;max-width:var(--maxw);margin-inline:auto}

/* 2. details as the mechanism, so navigation survives JavaScript being off.
      Visual treatment is unchanged from the authored .nav__link and .mega. */
.nav__item>details{position:static}
.nav__item>details>summary{list-style:none;cursor:pointer}
.nav__item>details>summary::-webkit-details-marker{display:none}
.lang>details>summary{list-style:none;cursor:pointer}
.lang>details>summary::-webkit-details-marker{display:none}
.lang>details>.lang__menu{display:block}

/* 3. Connectors has four groups, the authored grid is three. */
.mega__grid--4{grid-template-columns:repeat(4,1fr)}
@media (max-width:1080px){.mega__grid--4{grid-template-columns:repeat(2,1fr)}}
@media (max-width:900px){.mega__grid,.mega__grid--4{grid-template-columns:1fr}
  .mega{position:static;width:auto;max-width:none;box-shadow:none;border-width:1px 0 0}}

/* ---- utility bar, top right of every page ---- */
.utilbar{background:var(--navy);color:#fff;font-size:.8rem}
.utilbar__in{max-width:1180px;margin:0 auto;padding:0 clamp(16px,4vw,32px);
  display:flex;justify-content:flex-end;align-items:center;gap:4px;min-height:38px}
.utilbar a,.utilbar summary{color:#fff;text-decoration:none;padding:7px 10px;border-radius:4px;
  display:inline-flex;align-items:center;gap:6px;line-height:1;white-space:nowrap;
  min-height:32px;cursor:pointer}
.utilbar a:hover,.utilbar summary:hover{background:rgba(255,255,255,.14);text-decoration:none}
.utilbar a:focus-visible,.utilbar summary:focus-visible{outline:2px solid #fff;outline-offset:1px}
.utilbar .ico{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.utilbar .lang{position:relative}
.utilbar .lang>details>summary{list-style:none}
.utilbar .lang>details>summary::-webkit-details-marker{display:none}
.utilbar .lang__menu{position:absolute;right:0;top:calc(100% + 4px);min-width:210px;z-index:70;
  background:#fff;border:1px solid var(--line);border-radius:6px;padding:6px;margin:0;
  list-style:none;box-shadow:0 12px 28px rgba(42,56,80,.16)}
.utilbar .lang__menu a{color:var(--navy);display:block;padding:8px 10px}
.utilbar .lang__menu a:hover{background:var(--tint)}
.utilbar .lang__menu small{display:block;color:var(--grey);font-size:.72rem;margin-top:2px}
@media (max-width:640px){.utilbar__in{gap:0}.utilbar__hide{display:none}}
.k-held{display:inline-block;font-size:.66rem;letter-spacing:.08em;font-weight:700;color:var(--navy);
  background:var(--tint);border:1px solid var(--teal);border-radius:3px;padding:3px 7px}
.byline{font-size:.85rem;color:var(--grey);margin:0 0 14px}
.cmp{width:100%;border-collapse:collapse;margin:18px 0;font-size:.92rem}
.cmp th,.cmp td{border:1px solid var(--line);padding:10px 12px;text-align:left;vertical-align:top}
.cmp th{background:var(--tint);color:var(--navy)}

/* the footer sits on navy, so the logo is reversed in CSS rather than shipped
   as a second raster file. Keeps the whole build free of png and jpg. */
.footer .logo--rev{filter:brightness(0) invert(1)}

/* ---- footer bottom row: legal links and social icons ---- */
.footer__bottom{margin-top:36px;padding-top:20px;border-top:1px solid rgba(255,255,255,.18);
  display:flex;flex-wrap:wrap;gap:16px 28px;align-items:center;justify-content:space-between}
.footer__legalrow{display:flex;flex-wrap:wrap;gap:6px 20px;align-items:center;
  font-size:.85rem;margin:0}
.footer__legalrow a{color:var(--on-navy);text-decoration:none}
.footer__legalrow a:hover{color:#fff;text-decoration:underline}
.footer__legalrow span{color:var(--on-navy)}
.social{display:flex;gap:8px;align-items:center;margin:0;padding:0;list-style:none}
.social a{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;
  border-radius:50%;border:1px solid rgba(255,255,255,.28);color:#fff;
  transition:background .15s ease,border-color .15s ease}
.social a:hover{background:var(--raspberry);border-color:var(--raspberry)}
.social a:focus-visible{outline:2px solid #fff;outline-offset:2px}
.social svg{width:18px;height:18px;fill:currentColor;stroke:none}
@media (max-width:640px){.footer__bottom{flex-direction:column;align-items:flex-start}}

/* ============================================================================
   FOOTER, matched to the live rapidionline.com homepage footer
   Every value below is lifted from template_rapidi-boilerplate.min.css, read
   26 August 2026. The one deviation is noted where it occurs.
   ========================================================================== */
.rapidi-footer{padding:64px 24px 32px;background:var(--navy-deep);color:rgba(255,255,255,.7);
  font-family:var(--font,"DM Sans"),sans-serif}
.rapidi-footer-grid{display:grid;grid-template-columns:1.5fr repeat(3,1fr);gap:48px;
  max-width:1200px;margin:0 auto;padding-bottom:48px;
  border-bottom:1px solid rgba(255,255,255,.1)}
/* Beate, 30 Aug 2026: the reversed logo, not the text wordmark. 432 by 98 native,
   shown at 168 wide so it sits at the same optical weight the text had. */
.rapidi-footer-brand .footer-logo{display:block;width:168px;margin-bottom:14px}
.rapidi-footer-brand .footer-logo img{width:100%;height:auto;display:block}
.rapidi-footer-brand .footer-logo:focus-visible{outline:2px solid #fff;outline-offset:3px}
/* Beate, 30 Aug 2026: the brand line is bold. At 700 on rgba(255,255,255,.7) over
   Navy Deep it measures 7.22:1, so weight was the only thing that changed. */
.rapidi-footer-brand p{font-size:.85rem;line-height:1.7;margin-bottom:20px;
  font-weight:700;color:rgba(255,255,255,.7)}
/* Footer hover, Beate 30 Aug 2026: white and underlined, everywhere in the
   footer. It replaces Teal, which measured 4.19:1 on Navy Deep and fails the
   4.5:1 text minimum. White is 13.63:1. The social row is icons rather than text,
   so it goes white without an underline.

   Contact block, Beate 30 Aug 2026, above the social icons. Numbers are the live
   site's, verbatim. Text is white at 78 per cent, 8.6:1 on Navy Deep; the country
   label is 55 per cent, 5.07:1; the icons are white, 13.63:1. Beate asked for
   white icons on 30 Aug 2026, replacing the Teal they were drawn in. */
.fcontact{list-style:none;margin:0 0 20px;padding:0;display:grid;gap:9px}
.fcontact__row{display:flex;align-items:center;gap:10px;font-size:.85rem;
  color:rgba(255,255,255,.78)}
.fcontact__ico{flex:none;width:16px;height:16px;color:var(--white)}
.fcontact__cc{flex:none;min-width:26px;font-weight:700;font-size:.68rem;
  letter-spacing:.08em;text-transform:uppercase;color:rgba(255,255,255,.55)}
.fcontact a{color:inherit;text-decoration:none}
.fcontact a:hover,.fcontact a:focus-visible{color:#fff;text-decoration:underline}
.rapidi-footer-badges{display:flex;gap:12px;flex-wrap:wrap}
.rapidi-footer-badges img{height:48px;width:auto;opacity:.85}
.rapidi-footer-col h4{color:#fff;font-size:.85rem;text-transform:uppercase;letter-spacing:1px;
  margin:0 0 16px;font-weight:700}
.rapidi-footer-col ul{list-style:none;padding:0;margin:0}
.rapidi-footer-col li{margin-bottom:10px}
.rapidi-footer-col a{font-size:.85rem;color:rgba(255,255,255,.6);text-decoration:none;
  transition:color .2s}
.rapidi-footer-col a:hover,.rapidi-footer-col a:focus-visible{color:#fff;text-decoration:underline}
.rapidi-footer-col a:focus-visible{outline:2px solid #fff;outline-offset:2px}
/* Beate, 30 Aug 2026: one row, copyright first, pipe separated, in her order.
   Opacity raised from .4 to .62. At .4 the text measured 3.38:1 on Navy Deep,
   which fails AA for 12.8px; .62 measures 5.9:1. */
.rapidi-footer-bottom{max-width:1200px;margin:24px auto 0;display:flex;
  justify-content:flex-start;align-items:center;gap:0 10px;flex-wrap:wrap;
  font-size:.8rem;color:rgba(255,255,255,.62);line-height:1.9}
.rapidi-footer-bit{display:inline-flex;align-items:center;white-space:nowrap}
.rapidi-footer-bit:not(:last-child)::after{content:"|";margin-left:10px;
  color:inherit;opacity:.45}
/* Beate, 30 Aug 2026: copyright left, the four links right. The separator after the
   copyright goes with it, because a pipe floating in the gap reads as a mistake. */
.rapidi-footer-bit:first-child{margin-right:auto}
.rapidi-footer-bit:first-child::after{content:none}
.rapidi-footer-bottom a{color:inherit;text-decoration:none}
.rapidi-footer-bottom a:hover,.rapidi-footer-bottom a:focus-visible{color:#fff;text-decoration:underline}
.rapidi-footer-bottom a:focus-visible{outline:2px solid #fff;outline-offset:2px}
.rapidi-footer-social{display:flex;gap:16px}
.rapidi-footer-social a{color:rgba(255,255,255,.4);text-decoration:none;display:inline-flex;
  align-items:center;justify-content:center;width:32px;height:32px;transition:color .2s}
.rapidi-footer-social a:hover{color:#fff}
.rapidi-footer-social a:focus-visible{outline:2px solid #fff;outline-offset:2px}
.rapidi-footer-social a svg{width:20px;height:20px;fill:currentColor;stroke:none}
@media (max-width:900px){.rapidi-footer-grid{grid-template-columns:1fr 1fr;gap:32px}
  .rapidi-footer-bottom{justify-content:center;text-align:center}
  /* the split would strand the copyright on its own line once the row wraps */
  .rapidi-footer-bit:first-child{margin-right:0}
  .rapidi-footer-bit:first-child::after{content:"|"}}
@media (max-width:560px){.rapidi-footer-grid{grid-template-columns:1fr}}

/* four columns now that Partners and Support are separate */
.rapidi-footer-grid{grid-template-columns:1.5fr repeat(4,1fr)}
/* the social row sits in the brand column, above the certification badges */
.rapidi-footer-brand .rapidi-footer-social{margin:0 0 20px;gap:14px}
.rapidi-footer-brand .rapidi-footer-social a{width:34px;height:34px;
  border:1px solid rgba(255,255,255,.22);border-radius:50%;color:rgba(255,255,255,.6)}
.rapidi-footer-brand .rapidi-footer-social a:hover{color:#fff;background:var(--raspberry);
  border-color:var(--raspberry)}
@media (max-width:1080px){.rapidi-footer-grid{grid-template-columns:1.5fr repeat(2,1fr);gap:36px}}
@media (max-width:900px){.rapidi-footer-grid{grid-template-columns:1fr 1fr;gap:32px}}
@media (max-width:560px){.rapidi-footer-grid{grid-template-columns:1fr}}

/* ---- newsletter band, sits above the footer columns ---- */
.rapidi-footer-news{max-width:1200px;margin:0 auto 40px;padding-bottom:40px;
  border-bottom:1px solid rgba(255,255,255,.1);
  display:flex;gap:32px;align-items:center;justify-content:space-between;flex-wrap:wrap}
.rapidi-footer-news h4{color:#fff;font-size:1.05rem;letter-spacing:.5px;margin:0 0 6px;
  font-weight:700}
.rapidi-footer-news p{font-size:.85rem;line-height:1.6;margin:0;color:rgba(255,255,255,.7);
  max-width:52ch}
.newsform{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-start}
.newsform label{position:absolute;left:-9999px}
.newsform input[type=email]{min-width:290px;padding:13px 15px;font:inherit;font-size:.92rem;
  color:var(--navy);background:#fff;border:1px solid rgba(255,255,255,.3);border-radius:var(--radius-btn)}
.newsform input[type=email]::placeholder{color:var(--grey)}
.newsform input[type=email]:focus-visible{outline:3px solid var(--on-navy);outline-offset:2px}
.newsform button{padding:13px 22px;font:inherit;font-size:.92rem;font-weight:700;
  color:#fff;background:var(--raspberry);border:1px solid var(--raspberry);border-radius:var(--radius-btn);cursor:pointer;
  min-height:44px}
.newsform button:hover{background:var(--raspberry-d);border-color:var(--raspberry-d)}
.newsform button:focus-visible{outline:3px solid #fff;outline-offset:2px}
.newsform small{display:block;width:100%;font-size:.75rem;color:rgba(255,255,255,.45);
  margin-top:2px}
@media (max-width:900px){.rapidi-footer-news{flex-direction:column;align-items:flex-start;gap:18px}
  .newsform input[type=email]{min-width:0;width:100%}}

/* Find anything was removed, so the grid is brand plus three columns again */
.rapidi-footer-grid{grid-template-columns:1.5fr repeat(3,1fr)}
@media (max-width:900px){.rapidi-footer-grid{grid-template-columns:1fr 1fr;gap:32px}}
@media (max-width:560px){.rapidi-footer-grid{grid-template-columns:1fr}}

/* copyright sits right, links left */

/* newsletter: copy left, form right, one row on desktop */
.rapidi-footer-news{flex-wrap:nowrap;align-items:center;gap:40px}
.rapidi-footer-news>div:first-child{flex:1 1 auto;min-width:0}
.rapidi-footer-news p{max-width:60ch}
.newsform{flex:0 0 auto;flex-wrap:nowrap;align-items:center;position:relative;
  padding-bottom:18px}
.newsform input[type=email]{min-width:270px}
.newsform small{position:absolute;left:0;bottom:0;width:max-content;margin:0}
@media (max-width:1080px){.rapidi-footer-news{gap:28px}
  .newsform input[type=email]{min-width:210px}}
@media (max-width:900px){.rapidi-footer-news{flex-wrap:wrap;flex-direction:column;
    align-items:flex-start;gap:18px}
  .newsform{flex-wrap:wrap;width:100%;padding-bottom:0}
  .newsform input[type=email]{min-width:0;flex:1 1 200px}
  .newsform small{position:static;width:100%;margin-top:4px}}

/* Connectors now has five groups */
.mega__grid--5{grid-template-columns:repeat(5,1fr)}
.mega__grid--5 .mega__col a{font-size:.82rem;padding:4px 7px}
@media (max-width:1240px){.mega__grid--5{grid-template-columns:repeat(3,1fr)}}
@media (max-width:1080px){.mega__grid--4,.mega__grid--5{grid-template-columns:repeat(2,1fr)}}
@media (max-width:900px){.mega__grid,.mega__grid--4,.mega__grid--5{grid-template-columns:1fr}}

/* ---- systems with no page in the connector documentation ----
   Raspberry on white measures 4.52:1, so the label itself may carry the colour.
   A dot leads it so the mark survives for anyone who cannot see the hue. */
.mega__col a.on-request{color:var(--raspberry)}
.mega__col a.on-request::before{content:"";display:inline-block;width:7px;height:7px;
  border-radius:50%;background:var(--raspberry);margin-right:7px;vertical-align:middle;
  flex:0 0 auto}
.mega__col a.on-request small{color:var(--raspberry-d);opacity:.85}
.mega__col a.on-request:hover{background:var(--pink-tint);border-color:var(--pink-line)}
.mega__legend{display:inline-flex;align-items:center;gap:7px;font-size:.74rem;
  color:var(--grey);margin-right:auto}
.dot-req{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--raspberry);
  flex:0 0 auto}

/* ---- sections added 28 Aug, from the template gap audit ---- */
.factblock,.priceband,.tiers{width:100%;border-collapse:collapse;margin:14px 0;font-size:.92rem}
.factblock th,.factblock td,.priceband th,.priceband td,.tiers th,.tiers td{
  border:1px solid var(--line);padding:10px 13px;text-align:left;vertical-align:top}
.factblock th,.priceband th,.tiers th{background:var(--tint);width:26%;color:var(--navy)}
.factblock .held-cell{background:var(--pink-tint);color:var(--raspberry-d)}
.priceband .fit,.tiers .fit{color:var(--grey);font-size:.88rem}
.entity{font-size:1.05rem;font-weight:600;color:var(--navy);background:var(--tint);
  border-left:4px solid var(--mid-blue);padding:13px 16px;border-radius:0 6px 6px 0;margin:0 0 18px}
.steps .stepno{display:inline-flex;align-items:center;justify-content:center;width:34px;
  height:34px;border-radius:50%;background:var(--raspberry);color:#fff;font-weight:800;
  font-size:1.05rem}
.limits{margin:10px 0 0;padding-left:22px}
.limits li{margin:7px 0}
.whentheywin{background:#fff;border:1px solid var(--line);border-left:4px solid var(--mid-blue);
  border-radius:0 6px 6px 0;padding:14px 17px}
.hublist{font-size:.92rem;color:var(--grey);margin:0 0 12px}
.hublist b{color:var(--navy);font-size:1.1rem}
.pullquote{margin:0;background:var(--tint-2);border-left:4px solid var(--raspberry);
  padding:18px 22px;border-radius:0 6px 6px 0}
.pullquote p{font-size:1.12rem;line-height:1.5;margin:0 0 10px;color:var(--navy)}
.pullquote footer{font-size:.88rem;color:var(--grey)}
.pullquote footer b{color:var(--navy)}
.pullquote .k-held{display:inline-block;margin-left:9px}
.altroute{background:var(--tint);border-radius:6px;padding:15px 18px;margin:18px 0}
.altroute h3{margin:0 0 8px;font-size:1rem}
.altroute ul{margin:0;padding-left:20px}
.pairlist{margin:12px 0 0}
p.pairlist{color:var(--grey);font-size:.92rem}

/* ============================================================ blog + updates
   Structure ported from celigo.com/blog/ and /blog/celigo-headless/.

   Reuse note: .toc, .byline, .chip and .release already exist above and are
   used as-is. An earlier version of this block redefined all four, which
   dropped .chip's 44px tap target and introduced a second, competing active
   state. Only genuinely new components are defined here.

   Colour restraint, from the Celigo teardown: they spend almost no colour,
   black and white are 55% of their declarations. Raspberry stays on the
   primary button. Card borders, date labels and category labels carry navy,
   grey and tint. Hover goes to teal, matching a.card above. */

.wrap--article { max-width: 74ch; }

/* html already sets scroll-padding-top: calc(var(--header-h) + 16px), and
   .article h2 uses the same calc. Same formula here so there is one number to
   maintain. --header-h is 64px, so this is 80px, not the 96px first guessed
   against a header height that does not exist. */
h2[id], h3[id], .release-item[id] { scroll-margin-top: calc(var(--header-h) + 16px); }

/* --- byline. Extends the existing .byline row, does not redefine it. ----- */
.byline__role { color: var(--grey); font-size: var(--t-sm); }
.byline__dates { color: var(--grey); font-size: var(--t-sm); font-variant-numeric: tabular-nums; }
.byline__read { color: var(--grey); font-size: var(--t-sm); margin-left: auto; }

/* --- filter chips. Existing .chip, plus the current-page state to match
   the existing [aria-pressed] convention. Navy, not raspberry: a filter is
   a nav state repeated on every card row, not the page's one action. ----- */
.chip[aria-current="page"] { background: var(--navy); color: var(--white); border-color: var(--navy); }
.blog-filters { display: flex; flex-wrap: wrap; gap: var(--s-2); margin: var(--s-7) 0 var(--s-4); }
.blog-filters .chip { display: inline-flex; align-items: center; text-decoration: none; }

/* --- card grid. Breakpoints match .grid--3 and .tplgrid above rather than
   auto-fill, so column counts agree with the rest of the site. ----------- */
.blog-grid { display: grid; gap: var(--s-5); grid-template-columns: 1fr; }
@media (min-width: 700px)  { .blog-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .blog-grid { grid-template-columns: repeat(3, 1fr); } }

.blog-card, .blog-featured {
  display: flex; flex-direction: column; background: var(--white);
  border: 1px solid var(--near-white); border-radius: var(--radius-lg); overflow: hidden;
  transition: border-color .15s var(--ease);
  text-decoration: none; color: inherit;   /* the whole card is the anchor */
}
.blog-card:focus-visible, .blog-featured:focus-visible {
  outline: 3px solid var(--mid-blue); outline-offset: 2px;
}
.blog-card__flag {
  align-self: flex-start; font-size: var(--t-xs); font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: var(--raspberry); margin-bottom: var(--s-2);
}
.blog-card:hover, .blog-featured:hover { border-color: var(--teal); }
.blog-card__media { display: block; background: var(--tint-2); aspect-ratio: 16 / 9; overflow: hidden; }
.blog-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.blog-card__body { padding: var(--s-5); display: flex; flex-direction: column; flex: 1; }
.blog-card__meta {
  display: flex; gap: var(--s-3); align-items: center; margin: 0 0 var(--s-3);
  font-size: var(--t-xs); letter-spacing: .06em; text-transform: uppercase; color: var(--grey);
}
.blog-card__cat { color: var(--mid-blue); font-weight: 800; }
.blog-card__title {
  display: block; font-size: var(--t-base); line-height: 1.3; font-weight: 700;
  color: var(--navy); margin: 0 0 var(--s-3);
}
.blog-card:hover .blog-card__title, .blog-featured:hover .blog-card__title { text-decoration: underline; }
.blog-card__desc { display: block; font-size: var(--t-sm); color: var(--grey); margin: 0 0 var(--s-4); flex: 1; }
.blog-card__media { display: block; }
.blog-card__body { display: flex; }

.blog-featured { margin-bottom: var(--s-6); }
@media (min-width: 900px) {
  .blog-featured { display: grid; grid-template-columns: 1.1fr 1fr; align-items: stretch; }
  .blog-featured .blog-card__media { aspect-ratio: auto; height: 100%; min-height: 260px; }
  .blog-featured .blog-card__body { padding: var(--s-7); justify-content: center; }
  .blog-featured .blog-card__title { font-size: var(--t-2xl); }
  .blog-featured .blog-card__desc { font-size: var(--t-base); }
  .blog-featured .blog-card__title { font-size: var(--t-2xl); font-weight: 800; }
}

/* --- blog hero. On the reference page the featured post sits inside the hero
   band rather than below it: eyebrow, headline and subhead, then a two column
   block with the label, headline and button on the left and the post image on
   the right. Image is 16:9 here rather than their 606x362, because that is the
   ratio the stock library we already own is cut to. --- */
/* background and watermark come from .section--tint.wm, shared with every
   other hero on the site, so all heroes read the same. */
.blog-hero__h1 { max-width: none; margin: 0 0 var(--s-4); }
.blog-hero__sub { font-size: var(--t-lg); color: var(--grey); max-width: 62ch; margin: 0; }
.feat {
  /* the featured post is a distinct element inside the hero band, not a continuation
     of the copy above it, so it carries its own card treatment */
  background: var(--white); border: 1.5px solid var(--line); border-radius: var(--radius-lg);
  padding: var(--s-6);
  display: grid; gap: var(--s-6); align-items: center;
  margin-top: var(--s-7);
}
@media (min-width: 900px) { .feat { grid-template-columns: 1fr 1.1fr; gap: var(--s-8); } }
.feat__eyebrow {
  font-size: var(--t-xs); font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--raspberry); margin: 0 0 var(--s-3);
}
.feat__h { font-size: var(--t-2xl); line-height: 1.2; margin: 0 0 var(--s-4); }
.feat__h a { color: var(--navy); text-decoration: none; }
.feat__h a:hover { text-decoration: underline; }
.feat__sub { color: var(--grey); margin: 0 0 var(--s-5); max-width: 52ch; }
.feat__right { order: -1; }
@media (min-width: 900px) { .feat__right { order: 0; } }
.feat__img {
  width: 100%; height: auto; display: block; border-radius: var(--radius-lg);
  aspect-ratio: 16 / 9; object-fit: cover;
}

/* --- product updates. .release above is the group wrapper; one changelog
   entry is .release-item, so the two do not collide. -------------------- */
.release-group {
  font-size: var(--t-xs); letter-spacing: .1em; text-transform: uppercase; color: var(--grey);
  border-bottom: 1px solid var(--near-white); padding-bottom: var(--s-3);
  margin: var(--s-8) 0 var(--s-5);
}
.release-list { display: flex; flex-direction: column; gap: var(--s-5); }
.release-item {
  border: 1px solid var(--near-white); border-radius: var(--radius);
  padding: var(--s-5); background: var(--white);
}
.release-item:target { border-color: var(--teal); background: var(--tint-1); }
.release-item__meta { display: flex; gap: var(--s-3); align-items: center; margin: 0 0 var(--s-2); }
.release-item__date { font-size: var(--t-xs); color: var(--grey); font-variant-numeric: tabular-nums; }
/* Navy on every tag background. Grey on near-white measures 4.38:1 and fails
   AA; navy on near-white is 10.07:1 and navy on tint-2 is 10.57:1. */
.typetag {
  font-size: var(--t-xs); letter-spacing: .07em; text-transform: uppercase; font-weight: 800;
  border-radius: 999px; padding: 3px 10px; background: var(--tint-2); color: var(--navy);
}
.typetag--fix { background: var(--near-white); }
.typetag--improvement { background: var(--sand); }
.release-item__title { font-size: var(--t-base); margin: 0 0 var(--s-2); color: var(--navy); }
.release-item__body { margin: 0 0 var(--s-3); color: var(--grey); font-size: var(--t-sm); }
.release-item__link a { font-size: var(--t-xs); color: var(--mid-blue); text-decoration: none; }
.release-item__link a:hover { text-decoration: underline; }

/* --- byline avatar. The reference carries a 60px author image; we have no
   author photographs agreed, so this is an initial in the same footprint. --- */
.byline__avatar {
  width: 44px; height: 44px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: var(--tint-2); color: var(--mid-blue);
  font-weight: 800; border: 1px solid var(--light-teal);
}
.byline__who { display: flex; flex-direction: column; }
.byline__who .byline__name { font-weight: 700; color: var(--navy); }

/* --- FAQ accordion. The reference uses button + aria-expanded, which needs
   JavaScript to open. details and summary gives the same interaction with none,
   so the answers are in the HTML for a crawler that does not run scripts. --- */
.faq { border-bottom: 1px solid var(--near-white); }
.faq__q { list-style: none; cursor: pointer; display: flex; align-items: center;
  gap: var(--s-4); padding: var(--s-4) 0; }
.faq__q::-webkit-details-marker { display: none; }
.faq__q h3 { margin: 0; font-size: var(--t-base); color: var(--navy); flex: 1; }
.faq__q::after {
  content: "+"; font-size: var(--t-xl); line-height: 1; color: var(--mid-blue);
  flex: none; width: 1em; text-align: center;
}
.faq[open] .faq__q::after { content: "−"; }
.faq__q:focus-visible { outline: 3px solid var(--mid-blue); outline-offset: 2px; }
.faq__a { padding: 0 0 var(--s-4); }
.faq__a p { margin: 0; color: var(--grey); max-width: 74ch; }

.linklist { list-style: none; padding: 0; margin: var(--s-4) 0 0;
  display: grid; gap: var(--s-2); grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.linklist a { color: var(--mid-blue); }

/* Overflow link at the foot of a mega-menu column. The menu is rendered into
   every page, so each link in it costs words on all of them; columns cap at
   MENU_MAX and this points at the hub that holds the rest. */
.mega__more { margin-top: var(--s-2); border-top: 1px solid var(--near-white); padding-top: var(--s-2); }
.mega__more a { font-weight: 800; color: var(--mid-blue); }
.mega__more a small { color: var(--grey); font-weight: 400; }

/* --- resource library. The live page filters with jPList dropdowns, which need
   JavaScript, and its 62 items render as empty divs to anything that does not run
   scripts. Here the filter is a row of anchor links to the group headings and every
   item is in the HTML. --- */
.lib-filter { display: flex; flex-wrap: wrap; gap: var(--s-2); margin: var(--s-5) 0 0; }
.lib-filter .chip { display: inline-flex; align-items: center; gap: var(--s-2); text-decoration: none; }
.lib-filter .chip small { color: var(--grey); font-weight: 400; }
.lib-topics { font-size: var(--t-sm); color: var(--grey); margin: var(--s-4) 0 0; }
.lib-topics span { color: var(--navy); }
.lib-group {
  display: flex; align-items: baseline; gap: var(--s-3);
  font-size: var(--t-lg); border-bottom: 1px solid var(--near-white);
  padding-bottom: var(--s-3); margin: var(--s-8) 0 var(--s-5);
  scroll-margin-top: calc(var(--header-h) + 16px);
}
.lib-group__n { font-size: var(--t-xs); color: var(--grey); font-variant-numeric: tabular-nums; }
.lib-grid { display: grid; gap: var(--s-4); grid-template-columns: 1fr; }
@media (min-width: 700px)  { .lib-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .lib-grid { grid-template-columns: repeat(3, 1fr); } }
.lib-card {
  display: flex; flex-direction: column; gap: var(--s-2);
  border: 1px solid var(--near-white); border-radius: var(--radius-lg);
  padding: var(--s-5); background: var(--white);
  text-decoration: none; color: inherit; transition: border-color .15s var(--ease);
}
.lib-card:hover { border-color: var(--teal); }
.lib-card:hover .lib-card__title { text-decoration: underline; }
.lib-card:focus-visible { outline: 3px solid var(--mid-blue); outline-offset: 2px; }
.lib-card__type {
  font-size: var(--t-xs); letter-spacing: .07em; text-transform: uppercase;
  font-weight: 800; color: var(--mid-blue);
}
.lib-card__title { font-weight: 700; color: var(--navy); line-height: 1.3; }
.lib-card__topic { font-size: var(--t-sm); color: var(--grey); margin-top: auto; }

/* --- pricing. Four plans, then everything else behind one expander. The
   expander is details/summary so the full feature list is in the HTML for a
   crawler even while it is closed for a reader. --- */
.plancards { display: grid; gap: var(--s-4); grid-template-columns: 1fr; }
@media (min-width: 640px)  { .plancards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .plancards { grid-template-columns: repeat(4, 1fr); } }
.plancard {
  display: flex; flex-direction: column; gap: var(--s-2);
  border: 1px solid var(--near-white); border-radius: var(--radius-lg);
  padding: var(--s-5); background: var(--white);
}
.plancard__name { font-size: var(--t-lg); margin: 0; color: var(--navy); }
.plancard__price { margin: 0 0 var(--s-2); }
.plancard--popular { border-color: var(--raspberry); border-width: 2px; }
.plancard__flag {
  align-self: flex-start; font-size: var(--t-xs); font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase;
  background: var(--raspberry); color: var(--white); border-radius: 999px;
  padding: 3px 10px; margin: 0 0 var(--s-2);
}
.plancard__eur { font-size: var(--t-2xl); font-weight: 800; color: var(--navy); }
.plancard__per { font-size: var(--t-sm); color: var(--grey); margin-left: var(--s-2); }
.plancard__usd { margin: 0 0 var(--s-3); font-size: var(--t-xs); color: var(--grey); }
.plancard__list { list-style: none; margin: 0 0 var(--s-4); padding: 0; display: grid; gap: var(--s-2); }
.plancard__list li { font-size: var(--t-sm); color: var(--grey); padding-left: 1.4em; position: relative; }
.plancard__list li::before { content: "\2713"; position: absolute; left: 0; color: var(--teal); font-weight: 800; }
.pricing__billing { font-size: var(--t-sm); color: var(--grey); margin: var(--s-3) 0 0; }
.plancard__covers { margin: 0; color: var(--navy); font-size: var(--t-sm); }
.plancard__fit { margin: 0 0 var(--s-4); color: var(--grey); font-size: var(--t-sm); flex: 1; }
.plancard .btn { align-self: flex-start; }

.feat-toggle { margin-top: var(--s-7); border-top: 1px solid var(--near-white); }
.feat-toggle__btn {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: var(--s-3);
  min-height: 44px; margin-top: var(--s-5); padding: 0 var(--s-5);
  border: 2px solid var(--navy); border-radius: var(--radius);
  font-weight: 700; color: var(--navy); background: transparent;
}
.feat-toggle__btn::-webkit-details-marker { display: none; }
.feat-toggle__btn::after { content: "+"; font-size: var(--t-xl); line-height: 1; color: var(--mid-blue); }
.feat-toggle[open] .feat-toggle__btn::after { content: "−"; }
.feat-toggle__btn:hover { background: var(--navy); color: var(--white); }
.feat-toggle__btn:hover::after { color: var(--white); }
.feat-toggle__btn:focus-visible { outline: 3px solid var(--mid-blue); outline-offset: 2px; }
.feat-toggle__body { margin-top: var(--s-5); overflow-x: auto; }
.matrix tr.ft-group th {
  background: var(--tint-1); color: var(--navy); text-align: left;
  font-size: var(--t-xs); letter-spacing: .08em; text-transform: uppercase;
}

/* --- blog tools: search and topic filter, under the hero.
   Celigo runs the same two facets (their facet names are literally "search" and
   "topic") but as FacetWP, which needs JavaScript. The search here is a plain GET
   form and the topic filter is a details dropdown of anchor links, so both work
   with scripts off and every topic has a linkable URL. --- */
.blog-tools { padding-block: var(--s-5); }
.tools { display: flex; flex-wrap: wrap; gap: var(--s-4); align-items: center; }
.tools__search { display: flex; gap: var(--s-3); flex: 1; min-width: 280px; }
.tools__input {
  flex: 1; min-height: 44px; padding: var(--s-3) var(--s-4);
  border: 1px solid var(--light-teal); border-radius: var(--radius);
  font: inherit; font-size: 16px; /* 16px stops iOS zoom */
  background: var(--white); color: var(--navy);
}
.tools__input:focus-visible { outline: 3px solid var(--mid-blue); outline-offset: 2px; }
.tools__topic { position: relative; }
.tools__toggle {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center;
  gap: var(--s-3); min-height: 44px; padding: 0 var(--s-4);
  border: 1px solid var(--navy); border-radius: var(--radius);
  font-weight: 700; color: var(--navy); background: var(--white); white-space: nowrap;
}
.tools__toggle::-webkit-details-marker { display: none; }
.tools__toggle:focus-visible { outline: 3px solid var(--mid-blue); outline-offset: 2px; }
.tools__topic[open] > .tools__toggle { background: var(--navy); color: var(--white); }
.tools__topic[open] > .tools__toggle .chev { transform: rotate(180deg); }
.tools__menu {
  position: absolute; z-index: 60; top: calc(100% + 6px); left: 0; min-width: 240px;
  list-style: none; margin: 0; padding: var(--s-2);
  background: var(--white); border: 1px solid var(--near-white);
  border-top: 3px solid var(--raspberry);
  border-radius: var(--radius-lg); box-shadow: var(--shadow);
}
.tools__menu a {
  display: flex; justify-content: space-between; gap: var(--s-4);
  padding: var(--s-2) var(--s-3); border-radius: var(--radius);
  color: var(--navy); text-decoration: none; font-size: var(--t-sm);
}
.tools__menu a:hover { background: var(--tint-1); color: var(--mid-blue); }
.tools__menu small { color: var(--grey); font-variant-numeric: tabular-nums; }

.blog-topic {
  display: flex; align-items: baseline; gap: var(--s-3);
  font-size: var(--t-lg); border-bottom: 1px solid var(--near-white);
  padding-bottom: var(--s-3); margin: var(--s-8) 0 var(--s-5);
  scroll-margin-top: calc(var(--header-h) + 16px);
}
.blog-topic:first-child { margin-top: 0; }
.blog-topic__n { font-size: var(--t-xs); color: var(--grey); font-variant-numeric: tabular-nums; }

/* --- blog post, layout ported from celigo.com/blog/celigo-headless/.
   Hero: headline, read time, dates with a separator dot, author card, then a full
   width image. Body: a sticky left sidebar holding the contents and the share
   links, article on the right. Their sidebar list is built by script and is empty
   in the HTML; ours is server rendered, so the anchors exist for a crawler. --- */
.post-hero { padding-bottom: 0; }

/* Hero grid. Measured on the reference at 1280: container 1162, headline column
   744 which is 64 per cent, author column 398 which is 34 per cent, both 244 tall
   with the author card sitting on the dates baseline. Below 900 it is one column
   and the author card returns to reading order under the dates. */
.post-hero__grid { display: grid; gap: var(--s-5); }
@media (min-width: 900px) {
  .post-hero__grid { grid-template-columns: minmax(0, 64fr) minmax(0, 34fr); gap: var(--s-6); }
  .byline--right { align-self: end; justify-content: flex-end; }
}
.post-hero__head { min-width: 0; }

/* The read time chip. The reference sets it above the headline, 12px bold on
   their accent, radius 6. Ours is Navy Deep on Sage Pale, which is 9.16:1. */
.post-hero__read {
  display: inline-block; margin: 0 0 var(--s-3); padding: 6px 12px;
  background: var(--sage-pale); color: var(--navy-deep);
  border-radius: var(--radius); font-size: var(--t-xs); font-weight: 700;
  letter-spacing: .02em;
}
.post-hero__h1 { margin: 0 0 var(--s-4); max-width: 22ch; }
.post-hero__dates {
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;
  font-size: var(--t-xs); letter-spacing: .07em; text-transform: uppercase;
  font-weight: 700; color: var(--grey); margin: 0;
}
.post-hero__sep {
  width: 6px; height: 6px; border-radius: 50%; background: var(--light-teal);
  display: inline-block; flex: none;
}

/* Author card, right aligned with the avatar after the text, as the reference
   has it. The base .byline row is unchanged for every other template. */
/* nowrap, because the base .byline row wraps and that dropped the avatar onto a
   line of its own under the name instead of sitting beside it. */
.byline--right { margin: 0; align-items: flex-end; flex-wrap: nowrap; }
.byline--right .byline__who { text-align: right; min-width: 0; }
.byline--right .byline__avatar { flex: none; }
.byline--right .byline__role { display: block; }

.post-hero__figure { margin-top: var(--s-7); }
.post-hero__img {
  width: 100%; height: auto; display: block; aspect-ratio: 1162 / 380;
  object-fit: cover; border-radius: var(--radius-lg);
}

/* Body. Reference: sidebar 291, gap 100, article 822, so 26 and 74 per cent of
   the two columns with a wide gutter between them. */
.post-body { display: grid; gap: var(--s-7); }
@media (min-width: 960px) {
  .post-body {
    grid-template-columns: minmax(0, 26fr) minmax(0, 74fr);
    gap: clamp(40px, 7vw, 100px);
  }
  .post-side { position: sticky; top: calc(var(--header-h) + 24px); align-self: start; }
}
.post-main { min-width: 0; max-width: 78ch; }
.post-main .lede { margin-bottom: var(--s-5); }
.post__intro { font-size: var(--t-lg); color: var(--navy); }

/* Contents list. The reference clips each item to one line with an ellipsis and
   indents the list 28px from a thin rule at the container edge. Ours keeps real
   anchors, so the full text stays available as a title attribute. */
.post-side .toc { border-left-width: 2px; padding-left: 28px; margin-top: 0; }
.post-side .toc ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 27px; }
/* min-width 0, or the grid item takes its max-content width and the anchor
   overflows the column instead of clipping to an ellipsis. */
.post-side .toc li { font-size: var(--t-sm); line-height: 1.7; min-width: 0; }
.post-side .toc a {
  display: block; max-width: 100%; overflow: hidden;
  white-space: nowrap; text-overflow: ellipsis;
  color: var(--grey); text-decoration: none;
}
.post-side .toc a:hover, .post-side .toc a:focus-visible {
  color: var(--navy); text-decoration: underline;
}

/* Share row, unboxed as on the reference. */
.post-share {
  list-style: none; margin: var(--s-6) 0 0; padding: var(--s-5) 0 0;
  border-top: 1px solid var(--near-white); display: flex; flex-wrap: wrap; gap: var(--s-5);
}
.post-share a {
  font-size: var(--t-xs); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--mid-blue); text-decoration: none;
}
.post-share a:hover, .post-share a:focus-visible { text-decoration: underline; }

/* .vh is the visually-hidden class the generator emits for headings that are
   there for structure and screen readers but should not show. Without a rule
   they rendered visibly, which is why "The four plans" and "All articles" were
   appearing on the page. Same declarations as .sr-only above. */
.vh {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.typetag--new { background: var(--tint-2); }
.blog-card__date { color: inherit; }

/* Homepage hero, two columns: copy left, media right. Stacks under 900px. */
.hero-split{display:grid;gap:clamp(24px,3vw,44px);grid-template-columns:1fr;align-items:start}
@media(min-width:900px){.hero-split{grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr)}}
.hero-split__copy,.hero-split__media{min-width:0}

/* Hero media slot, homepage only. T1 section 2b. */
.heromedia{margin:26px 0 0;max-width:640px}
.hero-split .heromedia{margin:0;max-width:none}
.hero-split__copy>h1:first-child{margin-top:0}
/* the media box starts on the H1 cap line, not on its line box, so nudge it down by the
   H1 half-leading plus the ascender overshoot. Expressed in the H1 size so it scales. */
@media(min-width:900px){.hero-split__media{margin-top:calc(var(--t-3xl) * .15)}}
.heromedia__frame{position:relative;aspect-ratio:16/9;border:2px dashed var(--line);
 border-radius:10px;background:var(--tint);display:flex;flex-direction:column;
 align-items:center;justify-content:center;gap:6px;text-align:center;padding:16px}
.heromedia__play{width:0;height:0;border-style:solid;border-width:13px 0 13px 22px;
 border-color:transparent transparent transparent var(--raspberry);margin-bottom:4px;opacity:.85}
.heromedia__lbl{font-weight:800;font-size:1rem;letter-spacing:.02em;color:var(--navy)}
.heromedia__spec{font-size:.78rem;color:var(--grey);letter-spacing:.02em}
.heromedia__cap{margin:9px 2px 0;font-size:.8rem;line-height:1.5;color:var(--grey)}
@media(max-width:640px){.heromedia__lbl{font-size:.9rem}.heromedia__spec{font-size:.72rem}}

/* Customer quote carousel, homepage, T1 section 4. Scroll-snap, no script.
   White ground, and the same height as the pre-footer CTA band. Both read
   --band-h so they cannot drift apart. */
:root{--band-h:209px}
.qs-band{background:var(--white);min-height:var(--band-h);
 padding-top:var(--s-4);padding-bottom:var(--s-4);display:flex;align-items:center}
.qs-band__in{width:100%}
.cta-band{min-height:var(--band-h);display:flex;align-items:center}
.cta-band>.wrap{width:100%}
.qs__h{margin:0 0 var(--s-4)}
.qs{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(280px,1fr);gap:var(--s-5);
 overflow-x:auto;scroll-snap-type:x mandatory;scroll-behaviour:smooth;scroll-behavior:smooth;
 padding:2px 2px var(--s-4);scrollbar-width:thin}
@media(min-width:900px){.qs{grid-auto-columns:minmax(0,1fr);overflow-x:visible}}
.qs::-webkit-scrollbar{height:6px}
.qs::-webkit-scrollbar-thumb{background:var(--line);border-radius:3px}
.qs__card{scroll-snap-align:start;background:var(--white);border:1.5px solid var(--line);
 border-radius:10px;padding:12px var(--s-5);display:flex;flex-direction:column;gap:5px}
.qs__card:focus-visible{outline:3px solid var(--teal);outline-offset:2px}
.qs__q{margin:0}
.qs__q p{margin:0;font-size:.94rem;line-height:1.4;color:var(--navy)}
.qs__by{font-size:.78rem;color:var(--grey);margin-top:auto}
.qs__by b{display:block;line-height:1.35}
.qs__desc,.qs__stat{display:block;font-size:.78rem;color:var(--grey);margin-top:2px}
.qs__stat{color:var(--mid-blue);font-weight:600}
.qs__dots{display:flex;gap:8px;justify-content:center;margin-top:var(--s-2)}
@media(min-width:900px){.qs__dots{display:none}}
.qs__dot{display:block;padding:6px}
.qs__dot span{display:block;width:9px;height:9px;border-radius:50%;background:var(--line)}
.qs__dot:hover span,.qs__dot:focus-visible span{background:var(--raspberry)}
.qs__note{margin:var(--s-3) 0 0;font-size:.8rem;color:var(--grey)}

/* Pre-footer CTA band. Raspberry so it separates from the navy footer rather than
   merging with it. Shape adapted from jitterbit.com: one line, the action beside it. */
.section--rasp{background:var(--raspberry);color:var(--white)}
.section--rasp h2{color:var(--white)}
.section--rasp p{color:rgba(255,255,255,.92)}
.cta-band{padding-top:var(--s-7);padding-bottom:var(--s-7)}
.cta-band__in{display:grid;gap:var(--s-5);align-items:center;grid-template-columns:1fr}
@media(min-width:900px){.cta-band__in{grid-template-columns:minmax(0,1fr) auto;gap:var(--s-7)}}
.cta-band__copy h2{margin:0 0 var(--s-3)}
.cta-band__copy p{margin:0;max-width:56ch}
.cta-band__act{margin:0;flex-wrap:wrap}
/* white on raspberry is 4.52:1, navy on white is 11.80:1 */
.btn--onrasp{background:var(--white);color:var(--navy);border:2px solid var(--white)}
.btn--onrasp:hover{background:var(--near-white);border-color:var(--near-white);color:var(--navy)}
.btn--onrasp-ghost{background:transparent;color:var(--white);border:2px solid var(--white)}
.btn--onrasp-ghost:hover{background:rgba(255,255,255,.14);color:var(--white)}

/* Related articles after the FAQ. Shape from celigo.com/blog/celigo-headless/. */
.relgrid{display:grid;gap:var(--s-5);grid-template-columns:1fr;margin-top:var(--s-4)}
@media(min-width:760px){.relgrid{grid-template-columns:repeat(3,1fr)}}
.relpost{background:rgba(255,255,255,.8);border:1.5px solid var(--line);border-radius:12px;
 padding:var(--s-5);display:flex;flex-direction:column;gap:var(--s-2)}
.relpost__cat{margin:0;font-size:.68rem;font-weight:800;letter-spacing:.09em;
 text-transform:uppercase;color:var(--teal)}
.relpost__h{margin:0;font-size:1.05rem;line-height:1.3}
.relpost__h a{color:var(--navy);text-decoration:none}
.relpost__h a:hover{text-decoration:underline}
.relpost__date{margin:0;font-size:.78rem;color:var(--grey)}
.relpost__go{margin-top:auto;font-weight:700;font-size:.84rem;color:var(--raspberry-d)}

/* Blog pagination, under the card grids. Anchors, no script, crawlable. */
.pg{display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap;margin-top:var(--s-7);
 padding-top:var(--s-5);border-top:1px solid var(--line)}
.pg__nums{display:flex;gap:6px}
.pg__n,.pg__step{display:inline-flex;align-items:center;justify-content:center;min-height:44px;
 min-width:44px;padding:0 var(--s-4);border:1.5px solid var(--line);border-radius:var(--radius-btn);
 font-size:.88rem;font-weight:700;color:var(--navy);text-decoration:none;background:var(--white)}
.pg__n:hover,.pg__step:hover{border-color:var(--raspberry);color:var(--raspberry)}
.pg__n--on{background:var(--raspberry);border-color:var(--raspberry);color:var(--white)}
.pg__step--off{color:var(--grey);border-color:var(--near-white);background:var(--near-white);
 cursor:default}
.pg__step--off:hover{border-color:var(--near-white);color:var(--grey)}
.pg__count{margin-left:auto;font-size:.8rem;color:var(--grey)}
@media(max-width:620px){.pg__count{margin-left:0;width:100%}}

/* Utility page forms: contact, search, support. Three fields or fewer, no script. */
.uform{margin-top:var(--s-5);max-width:620px}
.uform__row{margin-bottom:var(--s-4)}
.uform label{display:block;font-weight:700;font-size:.86rem;color:var(--navy);
 margin-bottom:6px}
.uform input,.uform textarea{width:100%;font:inherit;font-size:1rem;color:var(--navy);
 background:var(--white);border:1.5px solid var(--line);border-radius:var(--radius-btn);
 padding:12px 20px;min-height:48px}
/* a 25px radius on a tall textarea reads as a lozenge, so it takes the same corner
   as the inputs without the full pill */
.uform textarea{min-height:112px;resize:vertical;border-radius:var(--radius-lg);padding:14px 20px}
.uform input::placeholder,.uform textarea::placeholder{color:var(--grey);opacity:.85}
.uform input:focus-visible,.uform textarea:focus-visible{outline:3px solid var(--teal);
 outline-offset:1px;border-color:var(--teal)}
.uform button{margin-top:var(--s-2)}
.uform__note{margin:var(--s-3) 0 0;font-size:.8rem;color:var(--grey);max-width:52ch}

/* T10 FAQ content: questions as accordions, two columns. No script. */
.faqcols{display:grid;gap:0 var(--s-7);grid-template-columns:1fr;margin-top:var(--s-4)}
@media(min-width:860px){.faqcols{grid-template-columns:1fr 1fr}}
.faq--col{break-inside:avoid}
.faq--col .faq__q h2{font-size:1.05rem;line-height:1.35;margin:0}

/* Resource library, rebuilt against the live rapidionline.com/resources.
   Their banner is a photograph under a dark gradient; ours is the brand watermark
   under the same gradient, so no stock image is invented. */
.lib-hero{background:var(--navy-deep);color:var(--white);position:relative;isolation:isolate;
 padding-top:var(--s-9);padding-bottom:var(--s-9);text-align:center}
.lib-hero::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
 background:linear-gradient(180deg,rgba(35,46,66,.55),rgba(35,46,66,.85)),
 url("/sa/tz9jn189tlnrlgl9rrrldrs55t9u/rapidi-lines-white-hi.png") center/cover no-repeat}
.lib-hero .eyebrow{color:var(--light-teal)}
.lib-hero__h1{color:var(--white);max-width:none;margin:var(--s-3) 0 var(--s-3)}
.lib-hero__sub{color:rgba(255,255,255,.88);font-size:var(--t-lg);margin:0}
.lib-bar{background:var(--white);padding-top:var(--s-6);padding-bottom:var(--s-6)}
.lib-filter{display:grid;gap:var(--s-4);grid-template-columns:1fr;align-items:end}
@media(min-width:900px){.lib-filter{grid-template-columns:2fr 1.4fr 1.4fr auto}}
.lib-filter__f label{display:block;font-weight:700;font-size:.8rem;color:var(--navy);
 margin-bottom:6px}
.lib-filter input,.lib-filter select{width:100%;font:inherit;font-size:.95rem;
 color:var(--navy);background:var(--white);border:1.5px solid var(--line);
 border-radius:var(--radius-btn);padding:12px 20px;min-height:48px}
.lib-filter input:focus-visible,.lib-filter select:focus-visible{outline:3px solid var(--teal);
 outline-offset:1px;border-color:var(--teal)}
.lib-listing{background:var(--near-white)}
.lib-grid{display:grid;gap:var(--s-5);grid-template-columns:1fr}
@media(min-width:620px){.lib-grid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1040px){.lib-grid{grid-template-columns:repeat(4,1fr)}}
.lib-card{display:flex;flex-direction:column;background:var(--white);border-radius:var(--radius-lg);
 overflow:hidden;text-decoration:none;color:var(--navy);border:1.5px solid var(--line)}
.lib-card:hover{border-color:var(--raspberry)}
.lib-card__media img{width:100%;height:auto;display:block;aspect-ratio:16/9;object-fit:cover}
.lib-card__title{display:block;padding:var(--s-4) var(--s-4) var(--s-2);font-weight:700;
 font-size:.95rem;line-height:1.35}
.lib-card__tags{display:block;padding:0 var(--s-4) var(--s-4);font-size:.76rem;color:var(--grey)}
.lib-card__tags b{color:var(--navy);font-weight:700}

/* ============================ INTEGRATION FIXES ============================
   Appended by tools/build-site-css.ts. Each is a bug in the handover CSS.
   ========================================================================= */

/* The locale dropdown printed each language's PATH under its name — "Deutsch"
   with "/de/" beneath it, in every entry. Michael asked for it gone, 7 Sep 2026:
   a language menu offers languages, not addresses.

   Unlike the rest of this block this is NOT a handover bug. The <small> is the
   ENGINE's: rs_sites emits it inside every language link, deliberately, as a
   "sublabel" that shows when a language will land you on its home page
   (lib/rs_sites/structural_renderer.rb:711). The handover then styles it in two
   places, .lang__menu small and .utilbar .lang__menu small, so the designer
   expected it too.

   Hidden here rather than deleted at the source, because that <small> is shared
   by every Sites42 tenant and removing it in the gem restyles all of their
   switchers at once. If Rapidi's answer turns out to be everyone's answer, the
   gem is where it belongs and this patch comes back out. display:none, not
   visibility or a clip, so the path leaves the accessibility tree as well —
   the language name stays the link's accessible name. */
.lang__menu small, .utilbar .lang__menu small { display: none; }

/* The language dropdown opened UNDERNEATH the main menu. Measured 31 Aug 2026:
   .utilbar is position:static with z-index:auto, so its .lang__menu's z-index:70
   competes in the ROOT stacking context against .header, which is sticky at
   z-index:100 — and loses. elementFromPoint at the open menu's own centre
   returned the Platform <summary>, not the menu. Giving the utility bar a
   positioned stacking context above the header fixes every dropdown it holds at
   once, rather than chasing the z-index of each one. The bar is not sticky, so
   it scrolls away and never fights the header for the same pixels. */
.utilbar { position: relative; z-index: 120; }

/* The design was drawn and measured in English, and English words are short.
   Measured 31 Aug 2026 on the German home at 390px: "Datenintegrationssoftware"
   is wider than the 350px the container allows, so min-content pushed the hero
   past the viewport — document scrollWidth 413 against a 390 viewport, with the
   text clipped away by body{overflow-x:hidden} rather than scrollable. English
   at the same width measured 390 and 390, which is exactly why this survived.

   overflow-wrap lets a word that cannot fit break rather than overflow; hyphens
   makes that break typographically correct, per language, using the dictionary
   the <html lang> selects. Neither does anything to a word that already fits, so
   English rendering is unchanged — verified, not assumed. */
h1, h2, h3, h4, p, li, dt, dd, figcaption, caption, blockquote { overflow-wrap: break-word; }

/* hyphens is scoped to German, and only German. overflow-wrap above is what
   actually prevents the overflow, in every language; hyphens only makes the
   break typographically correct, and German is the language measured needing it.
   Applied to all languages it also changed ENGLISH headline breaking — the Dutco
   h1 broke as "data flow be-tween", which is valid hyphenation and poor
   typography in a hero. Scoping it keeps English headlines breaking at word
   boundaries while German still hyphenates its compounds properly. */
html[lang="de"] h1, html[lang="de"] h2, html[lang="de"] h3, html[lang="de"] h4 { hyphens: auto; }

/* Two independent zebra rules collided and made FAQ answers invisible.
   Measured 1 Sep 2026 on the Educate 360 case story, in all four locales: its
   FAQ is section 8 of 10, which matches BOTH of these at once —

     main > section:nth-of-type(4n+4)    -> paragraph text  var(--navy-deep)
     main > section:nth-last-of-type(3)  -> background      var(--navy-deep)

   so the answers rendered #232E42 on #232E42. Contrast 1.00:1. The text is
   present, selectable and correct in the DOM; it simply cannot be seen, which is
   why an element-exists check and the open/closed height measurement both passed
   it. Reading the computed colour is the only thing that catches this class.

   The 4n+4 ink rule is right on its own terms: that band's background is
   var(--sage-pale), where navy-deep ink reads well. It has no business still
   applying once the third-from-last rule has repainted the same section navy, so
   the navy rule wins here. White on navy-deep measures 13.6:1. Without this the
   fallback would be .faq__a p's own var(--grey) at 2.66:1, which fails AA too, so
   this covers that case as well. Links and the +/- marker go to var(--light-teal)
   at 7.7:1 rather than white, so they stay distinguishable from body copy —
   var(--mid-blue) on this background measures 2.52:1.

   Scoped to the section the collision happens in, not to .faq, because the same
   band breaks any paragraph, list item or link that lands in it. */
main > section:nth-last-of-type(3):not(.section--rasp):not(.cta-band):not(.rel-band)
  :is(p, li, small, dd, figcaption, .faq__a p) { color: var(--white); }
main > section:nth-last-of-type(3):not(.section--rasp):not(.cta-band):not(.rel-band)
  :is(a, .faq__a a) { color: var(--light-teal); }
main > section:nth-last-of-type(3):not(.section--rasp):not(.cta-band):not(.rel-band)
  .faq__q::after { color: var(--light-teal); }
