/**
 * @file
 * Subtheme-specific CSS. Colours/type come from --rc-* tokens (design-tokens.css);
 * re-theme via those tokens. Native nesting (no Sass &__suffix → BEM is flat).
 */

:root {
  /* Unscrolled navbar height; on :root so the hero can reference it too. */
  --nav-height-base: clamp(72px, 10vw, 132px);
}

/* Contain full-bleed (100vw) spill. clip, not hidden, keeps sticky working. */
html {
  overflow-x: clip;
}

/* Roboto is the global base face. Bootstrap drives its typography off its own
   CSS variables, so overriding those makes every Bootstrap component (buttons,
   forms, etc.) use Roboto. We also set it on body and the form elements that
   don't inherit by default. Orbitron is applied only where explicitly needed
   via var(--rc-font-family-display). (global-styling depends on bootstrap, so
   this loads after bootstrap.min.css and wins.) */
:root {
  --bs-font-sans-serif: var(--rc-font-family-base);
  --bs-body-font-family: var(--rc-font-family-base);
}
body,
button,
input,
select,
optgroup,
textarea,
.btn {
  font-family: var(--rc-font-family-base);
}

@media (min-width: 1200px) {
  .container {
    max-width: 1140px;
  }
}

/* Bootstrap Paragraph Image: keep the image within its container and scale it
   down on small screens (bp_image carries width/height attributes that
   otherwise force the intrinsic width and cause horizontal overflow on mobile). */
.paragraph--type--bp-image .field--type-image img {
  max-width: 100%;
  height: auto;
}

/* ============================================================
   TOP UTILITY BAR — block_content "top_utility" in the top_header region.
   Slim bar above the navbar: empty left track · clearance text (centre) ·
   contact (right). Grid 1fr auto 1fr guarantees a page-centred middle.
   ============================================================ */
/* The top navbar wrapper (#navbar-top) is full-width; the block inside only
   spans the .container. Put the slate strip on the wrapper so it goes edge to
   edge, and drop the navbar's default padding so the bar stays slim. */
#navbar-top {
  background: var(--rc-color-slate, #333F48);
  padding-block: 0;
}
/* Let the bar content run full-width: drop the .container width cap AND its
   navbar flex (`.navbar > .container` is display:flex; justify-content:
   space-between, which left the region not filling the container). Block layout
   lets the region .row + grid span the full width. */
#navbar-top > .container {
  max-width: none;
  display: block;
}
.top-utility {
  /* Fill the Bootstrap .row it sits in (otherwise it shrinks to content and
     the 3-col grid isn't full-width, so the centre column looks off). */
  flex: 1 1 100%;
  width: 100%;
  min-width: 0;
  color: var(--rc-color-surface-muted, #f0f0f1);
  font-size: 0.95rem;
}
.top-utility__inner {
  max-width: none;
  padding: 0.5rem 1.5rem;
  display: grid;
  /* minmax(0, 1fr) keeps the side tracks equal so the middle text stays
     page-centred even when the left track is intentionally empty. */
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: stretch;      /* all three columns take the row height */
  gap: 1rem;
}
.top-utility__spacer {
  min-width: 0;
}
.top-utility__contact {
  justify-self: end;
  display: flex;
  flex-direction: column;   /* phone + email each on their own row */
  align-items: flex-end;
  justify-content: center;  /* centre the 2 rows within the bar height */
  gap: 0.1rem;
}
.top-utility__security {
  justify-self: center;
  display: flex;
  align-items: center;
  text-align: center;
  font-weight: var(--rc-font-weight-semibold, 600);
  letter-spacing: var(--rc-letter-spacing-wider, 0.05em);
  text-wrap: balance;
}
.top-utility__link {
  white-space: nowrap;
}
.top-utility__link {
  color: var(--rc-color-surface-muted, #f0f0f1);
  text-decoration: none;
}
.top-utility__link:hover,
.top-utility__link:focus {
  color: var(--rc-color-border, #d0d0d0);
  text-decoration: underline;
}
@media (max-width: 1024px) {
  .top-utility__inner {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .top-utility__spacer {
    display: none;
  }

  .top-utility__security {
    justify-self: start;
    text-align: left;
  }
}
/* ============================================================
   HEADER / NAVBAR
   ============================================================ */

/* Stick #header (child of #page), not #navbar-main — the latter's containing
   block is no taller than the bar. top = Drupal admin toolbar offset. */
#page > #header {
  position: sticky;
  top: var(--drupal-displace-offset-top, 0px);
  z-index: 1030;
}

/* Keep Drupal's admin toolbar (bar + tray) above the sticky site header, which
   sits at z-index 1030. Scoped to logged-in users so the anonymous front-end
   stacking is untouched. Authoring-only convenience. */
.user-logged-in #toolbar-administration,
.user-logged-in #toolbar-bar,
.user-logged-in .toolbar-tray,
.user-logged-in .toolbar-orientation-vertical .toolbar-tray {
  z-index: 1040;
}

#navbar-main {
  /* Remap .bg-primary's var to our dark brand blue (beats its !important). */
  --bs-primary-rgb: var(--rc-color-brand-secondary-rgb);

  /* Force pure white links via the navbar's own vars, not .nav-link specificity. */
  --bs-navbar-color: var(--rc-color-brand-white);
  --bs-navbar-hover-color: var(--rc-color-brand-white);
  --bs-navbar-active-color: var(--rc-color-brand-white);

  --nav-height: var(--nav-height-base);
  --nav-shrink: 0.8;   /* scrolled band height & logo scale */
  /* Zero nav + brand padding so the brand box doesn't exceed the band height. */
  --bs-navbar-padding-y: 0;
  --bs-navbar-brand-padding-y: 0;

  /* Fixed height so shrink-on-scroll works (the burger menu is an overlay, so
     it never needs the band to grow). */
  height: var(--nav-height);
  transition: height var(--rc-transition-base) ease;

  /* Anchor for the ::before gradient + absolute burger panel. Transparent bg so
     only the ::before paints (its opacity can transition; a gradient can't). */
  position: relative;
  background-color: transparent !important;

  &::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background-image: linear-gradient(
      135deg,
      var(--rc-color-brand-secondary) 0%,
      var(--rc-color-brand-primary) 100%
    );
    transition: opacity var(--rc-transition-base) ease;
  }

  /* isolation (not position) lifts content above ::before without making this
     the offset parent — so the absolute burger panel anchors to the full-width
     navbar. align-items + height centre the items and cap the container height. */
  > .container {
    isolation: isolate;
    align-items: center;
    height: 100%;
  }

  /* Logo layout box stays at the unscrolled size so menu/CTA never shift; it
     shrinks visually via transform on scroll. */
  .navbar-brand img {
    height: var(--nav-height-base);
    width: auto;
    transform: scale(var(--nav-logo-scale, 1));
    transform-origin: left center;
    transition: transform var(--rc-transition-base) ease;
  }
}

/* Desktop three-zone layout (brand | menu | CTA). Source order is brand, CTA,
   collapse; flex `order` arranges them. Breakpoint = navbar-expand-xxl (1400px),
   set on the navbar in esl_subtheme_preprocess_page(); everything below 1400px
   gets the burger. Keep the two in sync. */
@media (min-width: 1400px) {
  #navbar-main > .container {
    display: flex;
    max-width: none;
    justify-content: space-evenly;

    > .navbar-brand    { order: 0; flex: 0 0 auto; }
    > .navbar-collapse {
      order: 1;
      flex: 0 1 auto;
      display: flex;
      justify-content: center;
    }
    > .navbar-form     { order: 2; flex: 0 0 auto; }
  }

  /* Was #navbar-main .navbar-nav (core menu). Superfish renders .sf-menu, not
     .navbar-nav, and floats its <li> for horizontal layout. Override with a
     clean flex row so the gap controls spacing. */
  #navbar-main .sf-menu.sf-horizontal {
    display: flex;
    align-items: center;
    /* Fluid gap: tightens on narrower desktops (≈0.9rem near 1200px) so the row
       fits and the CTA doesn't overflow the right edge, up to 2rem on wide
       screens. A fixed 2rem never shrank, which pushed the button off-screen
       between ~1200–1400px. */
    gap: clamp(0.6rem, 1.3vw, 2rem);
    flex-wrap: nowrap;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  #navbar-main .sf-menu.sf-horizontal > li {
    float: none;   /* drop Superfish's float so flex gap governs spacing */
    margin: 0;
  }

  /* JS toggles .is-scrolled past a threshold → shrink band + logo together. */
  #navbar-main.is-scrolled {
    --nav-height: calc(var(--nav-height-base) * var(--nav-shrink));
    --nav-logo-scale: var(--nav-shrink);
  }
}

/* Below xxl: burger dropdown. Absolutely positioned below the bar so it overlays
   content (doesn't push) and doesn't change the band height. Full-width panel. */
@media (max-width: 1399.98px) {
  #navbar-main .navbar-collapse {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 5;
    background-color: var(--rc-color-brand-secondary);
    padding: 0.5rem 0;
  }

  #navbar-main .navbar-collapse .navbar-nav {
    text-align: center;
    align-items: center;
    gap: 0.5rem;
  }

  /* Superfish sf-Smallscreen accordion. Stack items full width (kill the float)
     and centre links — .navbar-collapse .navbar-nav above doesn't catch .sf-menu. */
  #navbar-main .sf-menu,
  #navbar-main .sf-menu li {
    float: none;
    width: 100%;
    margin: 0;
  }

  #navbar-main #block-sf-navbar-main .sf-menu a {
    display: block;
    text-align: center;
    font-size: 1.2rem;
  }

  /* sf-Smallscreen is disabled, so there's a single horizontal menu (no accordion
     duplicate, no "Main navigation" master toggle). Submenus are revealed on tap
     by sf-Touchscreen, which toggles .sfHover on the parent li. Make the revealed
     sub-ul flow inline in the stacked panel instead of Superfish's off-screen
     absolute position. Belt-and-suspenders: hide any stray accordion artifacts. */
  #navbar-main .sf-accordion-toggle,
  #navbar-main ul.sf-menu.sf-accordion {
    display: none;
  }

  /* Two-id selector (#navbar-main #block-sf-navbar-main) outranks the desktop
     dropdown rule (#block-sf-navbar-main .sf-menu ul) so the mobile sub-menu
     styling wins without !important. */
  #navbar-main #block-sf-navbar-main .sf-menu ul {
    position: static;
    display: none;
    width: 100%;
    min-width: 0;
    box-shadow: none;
    padding-block: 0.25rem;
    margin-block: 0.25rem;
    /* Lighter brand blue so the expanded submenu reads as nested. */
    background-color: var(--rc-color-brand-primary);
  }
  #navbar-main #block-sf-navbar-main .sf-menu li.sfHover > ul,
  #navbar-main #block-sf-navbar-main .sf-menu li:focus-within > ul {
    display: block;
  }
}

/* Superfish top-level links. Was #block-esl-subtheme-main-menu .nav-link (core
   menu markup); the nav is now a Superfish block, so target its top links.
   Superfish defaults are blue + underlined — force white, bold-ish, no underline
   on both the transparent hero and the solid navbar. */
#block-sf-navbar-main .sf-menu > li > a,
#block-sf-navbar-main .sf-menu a.sf-depth-1 {
  display: block;
  color: var(--rc-color-brand-white);
  font-weight: var(--rc-font-weight-semibold);
  font-size: clamp(1rem, 0.5vw + 0.9rem, 1.2rem);
  text-decoration: none;
  white-space: nowrap;     /* don't break "Types of Testing" */
  padding: 0.5rem 0.75rem; /* comfortable click target */

  &:hover,
  &:focus {
    color: var(--rc-color-brand-white);
    text-decoration: none;
    opacity: 0.85;
  }
}

/* Dropdown submenus (when items get children). Navy panel + white links to
   match the brand and the burger panel. Superfish sets absolute top/left — we
   only skin it. z-index above the sticky header (1030). */
#block-sf-navbar-main .sf-menu ul {
  background-color: var(--rc-color-brand-secondary);
  box-shadow: 0 0.5rem 1rem rgba(var(--rc-color-brand-secondary-rgb), 0.25);
  padding: 0;
  min-width: 12rem;
  list-style: none;
  z-index: 1031;
}

#block-sf-navbar-main .sf-menu ul a {
  display: block;
  padding: 0.7rem 1rem;
  color: var(--rc-color-brand-white);
  font-weight: var(--rc-font-weight-semibold);
  text-decoration: none;
  white-space: nowrap;

  &:hover,
  &:focus {
    color: var(--rc-color-brand-white);
    text-decoration: none;
    /* Brand gradient: light (primary) → mid (tertiary). */
    background: linear-gradient(
      135deg,
      var(--rc-color-brand-primary) 0%,
      var(--rc-color-brand-tertiary) 100%
    );
  }
}

/* Submenu indicator. Superfish's own .sf-sub-indicator is absolutely positioned
   inside a reserved 3em right-padding (which our link padding overrides, so it
   collapses/overlaps). Disable it and use our own inline caret after the label
   on parent links (.sf-with-ul) — works for both the desktop dropdown and the
   mobile accordion. */
#block-sf-navbar-main .sf-menu .sf-sub-indicator {
  display: none;
}
#block-sf-navbar-main .sf-menu a.sf-with-ul::after {
  content: "";
  display: inline-block;
  margin-left: 0.5em;
  width: 0.45em;
  height: 0.45em;
  border-right: 0.13em solid currentColor;
  border-bottom: 0.13em solid currentColor;
  transform: rotate(45deg);        /* down chevron */
  transform-origin: center;
  vertical-align: middle;
  position: relative;
  top: -0.22em;                    /* sit higher, aligned with cap height */
  transition: transform var(--rc-transition-fast) ease;
}
/* Flip the chevron up when the parent is open (sf-Touchscreen .sfHover on tap,
   or .sf-expanded if accordion is ever re-enabled). */
#block-sf-navbar-main .sf-menu li.sfHover > a.sf-with-ul::after,
#block-sf-navbar-main .sf-menu li.sf-expanded > a.sf-with-ul::after {
  transform: rotate(-135deg);
  top: 0.02em;
}
/* The cloned parent link at the top of an expanded submenu — point its chevron
   left toward its label (it's the "back to this section" link). */
#block-sf-navbar-main .sf-menu li.sf-clone-parent > a.sf-with-ul::after {
  transform: rotate(135deg);
  top: -0.02em;
}

/* DESKTOP only: nested submenu parents (depth 2+) open as a side flyout, so
   their chevron points RIGHT by default (top-level stays down; the hover rule
   above still flips it up). Scoped to the expanded-navbar breakpoint so the
   mobile accordion keeps its down→up behaviour. */
@media (min-width: 1400px) {
  #block-sf-navbar-main .sf-menu a.sf-with-ul:not(.sf-depth-1)::after {
    transform: rotate(-45deg);   /* right chevron */
    top: -0.08em;
  }
  /* Long dropdown/flyout items wrap (balanced) instead of forcing a very wide
     panel. Cap the submenu width so wrapping can happen (an absolutely-
     positioned flyout won't wrap without a max-width); text stays left. */
  #block-sf-navbar-main .sf-menu ul {
    max-width: 22rem;
    border-left: 4px solid var(--rc-color-brand-primary, #1d84c3);
  }
  #block-sf-navbar-main .sf-menu ul a {
    white-space: normal;
    text-wrap: balance;
    text-align: left;
  }
}

/* MOBILE (burger): let long menu/submenu items wrap (balanced) instead of being
   clipped by the desktop nowrap. */
@media (max-width: 1399.98px) {
  #block-sf-navbar-main .sf-menu > li > a,
  #block-sf-navbar-main .sf-menu a.sf-depth-1,
  #block-sf-navbar-main .sf-menu ul a {
    white-space: normal;
    text-wrap: balance;
  }
  /* Delimit nested (2nd-level+) submenus with top + bottom borders (instead of
     the desktop left border) — the top border separates the parent item from
     the repeated clone-parent link at the top of its submenu. */
  #block-sf-navbar-main .sf-menu ul ul {
    border-block: 2px solid rgba(var(--rc-color-brand-white-rgb, 255, 255, 255), 0.2);
  }
}

/* Zero the form wrapper's default margins (uneven space around the pill). */
#navbar-main .navbar-form {
  margin: 0;
}

/* CTA pill. rgba() comma syntax (token is a comma triplet). inline-flex avoids
   the inline-block baseline gap below the pill. */
#navbar-main .navbar-form a {
  display: inline-flex;
  align-items: center;
  background: rgba(var(--rc-color-brand-white-rgb), 0.85);
  color: var(--rc-color-brand-secondary);
  font-weight: var(--rc-font-weight-bold);
  /* One fluid clamp: small enough at phone widths to fit beside logo + burger. */
  font-size: clamp(0.9rem, 0.4rem + 1.3vw, 1.35rem);
  padding: clamp(0.5rem, 0.3rem + 0.7vw, 1rem) clamp(1rem, 0.2rem + 2.6vw, 2.8rem);
  border-radius: var(--rc-radius-pill);
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--rc-transition-fast) ease;

  &:hover,
  &:focus {
    background: var(--rc-color-brand-white);
  }
}

/* ============================================================
   HERO PAGES
   Navbar overlaps the hero transparently and fades to solid on scroll. Scoped
   to the `has-hero-banner` body class (added by esl_subtheme_preprocess_html
   only when the route node has a banner image), so nodes WITHOUT a banner — and
   all other pages — keep the normal solid navbar + page title.
   ============================================================ */
.has-hero-banner {
  /* Hero leads the page — hide breadcrumb + title. */
  .block-system-breadcrumb-block,
  .block-page-title-block {
    display: none;
  }

  /* Empty .highlighted region still adds space above the hero. */
  .highlighted {
    display: none;
  }

  /* Overlap + pin: sticky sizes to #page (excludes scrollbar → no right-edge
     overhang, unlike fixed). height:0 reserves no space so the banner starts at
     y=0 under the navbar, yet still pins on scroll. #page prefix wins specificity. */
  #page > #header {
    position: sticky;
    top: var(--drupal-displace-offset-top, 0px);
    height: 0;
    z-index: 1030;
  }

  /* Collapse wrapper spacing so the body/tabs sit snug under the page-level
     hero (#page prefix beats the global rule). The hero now lives OUTSIDE #main,
     so the container keeps its normal Bootstrap gutters — only top spacing is
     zeroed; the side-padding/row-gutter overrides for the old in-#main breakout
     have been removed. */
  #page > #main-wrapper { padding-top: 0; }
  #main.container {
    padding-top: 0;
  }
  #main .section,
  #main main.main-content > .section {
    padding-top: 0;
  }
  /* .node__content margin-top collapses up and shows as a strip. */
  .node__content {
    margin-top: 0;
  }

  /* Navbar transparent over the hero; gradient fades in on scroll. */
  #navbar-main::before { opacity: 0; }
  #navbar-main.is-scrolled::before { opacity: 1; }
}

/* ============================================================
   HERO BANNER — site-specific tuning
   The module ships generic hero defaults keyed on .--hero; here we add only
   theme-specific bits: navbar clearance, display font, mockup type/button scale.
   Selector doubled (0,2,0) to beat the module's base `padding` shorthand.
   ============================================================ */
.paragraph-cta-banner.paragraph-cta-banner--hero {
  --rc-cta-banner-hero-min-height: 800px;
  /* Clear the overlapping navbar; +2rem nudges centred content lower.
     (--nav-height-base is a theme var, so this can only live here.) */
  padding-top: calc(var(--nav-height-base) + 2rem);
  /* Gap below the hero before the first content section. */
  margin-bottom: var(--rc-paragraph-spacing);

  .paragraph-cta-banner__title {
    /* Orbitron = display face (loaded via the `fonts` library). */
    font-family: var(--rc-font-family-display);
    font-optical-sizing: auto;
    /* Floor low enough that ENVIRONMENTAL fits the narrowest phone unbroken. */
    font-size: clamp(1.5rem, 5vw + 0.5rem, 4.5rem);
    text-transform: uppercase;
    letter-spacing: var(--rc-letter-spacing-wider);
    margin-bottom: 1.5rem;
  }

  .paragraph-cta-banner__body {
    font-size: clamp(1.4rem, 1.4vw + 0.9rem, 2rem);
    font-weight: var(--rc-font-weight-semibold);
    margin-bottom: 2.5rem;
  }

  /* Module defaults the subtitle to brand accent (gold); force white on the
     dark hero. */
  .paragraph__subtitle {
    color: var(--rc-color-brand-white);
  }

  /* Bigger pill CTA; mockup is mixed-case (module forces uppercase). */
  .btn-primary {
    font-size: clamp(1.4rem, 0.8vw + 1.1rem, 1.85rem);
    padding: clamp(1rem, 0.8vw + 0.8rem, 1.5rem) clamp(2.5rem, 2.5vw + 1.5rem, 4rem);
    border-radius: var(--rc-radius-pill);
    text-transform: none;
    border-color: var(--rc-color-brand-primary);
    background-color: var(--rc-color-brand-primary);
  }
  .btn-primary:hover {
    border-color: var(--rc-color-brand-tertiary);
    background-color: var(--rc-color-brand-tertiary);
  }
}

.paragraph-cta-banner--center .paragraph-cta-banner__body {
  max-width: 45em;
}

/* Banner Overview pages: shorter hero + smaller heading so long headlines fit
   the reduced height. Scoped to the content type (body carries
   node--type-banner-overview-page). */
.node--type-banner-overview-page .paragraph-cta-banner.paragraph-cta-banner--hero {
  --rc-cta-banner-hero-min-height: 600px;
}
/* Heading */
.node--type-banner-overview-page .paragraph-cta-banner--hero .paragraph-cta-banner__title {
  font-size: clamp(1.4rem, 3.5vw + 0.4rem, 3rem);
}
/* Subheading (body) */
.node--type-banner-overview-page .paragraph-cta-banner--hero .paragraph-cta-banner__body {
  font-size: clamp(1.15rem, 1vw + 0.8rem, 1.65rem);
}
/* CTA button */
.node--type-banner-overview-page .paragraph-cta-banner--hero .btn-primary {
  font-size: clamp(1.15rem, 0.6vw + 0.95rem, 1.5rem);
  padding: clamp(0.8rem, 0.6vw + 0.65rem, 1.2rem) clamp(2rem, 2vw + 1.2rem, 3.25rem);
}

/* Anchored section headings (bp header id from the template, or rcomms
   *__title id from js/global.js) clear the sticky navbar when jumped to. */
.paragraph__column > h2[id],
.paragraph-text-image__title[id],
.paragraph-faq__title[id],
.paragraph-feature-list__title[id],
.paragraph-feature-icon-grid__title[id],
.paragraph-product-grid__title[id],
.paragraph-steps__title[id],
.paragraph-app-promotion__title[id],
.paragraph-gallery__title[id],
.paragraph-hubspot-popup__title[id],
.rcomms-section-title[id] {
  scroll-margin-top: calc(var(--nav-height-base, 5rem) + 2rem);
}

/* ============================================================
   STICKY FOOTER — #main-wrapper grows so the footer sits at the viewport bottom.
   ============================================================ */
#page {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - var(--drupal-displace-offset-top, 0px));

  > #main-wrapper {
    flex: 1 0 auto;
    /* Padding (not margin) avoids margin-collapse with the inner .row. */
    padding-top: var(--rc-paragraph-spacing);
  }
  > .site-footer { flex: 0 0 auto; }
}

/* ============================================================
   FOOTER CTA BLOCK — only what Bootstrap utilities can't cover.
   ============================================================ */

/* Flatten Bootstrap's site-footer wrapper (black bg, padding, top border). */
.site-footer {
  padding: 0;
  background: none;
}
.site-footer__bottom {
  margin-top: 0;
  border-top: 0;
}

/* Unconstrain the wrapper chain so the bands reach the edges; the block's own
   inner .container keeps content boxed. */
.site-footer > .container,
.region-wrapper-footer-fifth > .container,
.region-wrapper-footer-fifth .row.full-width {
  max-width: none;
  width: 100%;
  margin-inline: 0;
  padding-inline: 0;
}
.region-wrapper-footer-fifth .row.full-width > .footer-cta-block {
  padding-inline: 0;
}

/* Blue band. */
.footer-cta {
  /* White gap above the band, matching the gap below it (legal band's py-4). */
  margin-block-start: 1.5rem;
  background: linear-gradient(
    135deg,
    var(--rc-color-brand-secondary) 0%,
    var(--rc-color-brand-primary) 100%
  );

  /* Force white text (BS5 .text-white / heading colours aren't reliable here). */
  &,
  & h2,
  & .footer-cta__heading {
    color: var(--rc-color-brand-white);
  }

  /* Keep mixed-case (module forces .btn-primary uppercase). */
  & .btn-primary {
    color: var(--rc-color-brand-secondary);
    background: rgba(var(--rc-color-brand-white-rgb), 0.85);
    padding: clamp(0.5rem, 0.3rem + 0.7vw, 1rem) clamp(1rem, 0.2rem + 2.6vw, 2.8rem);
    font-size: clamp(0.9rem, 0.4rem + 1.3vw, 1.35rem);
    font-weight: var(--rc-font-weight-bold);
    text-transform: none;
    border: none;
  }

  & a:not(.btn) {
    color: var(--rc-color-brand-white);
  }
}

/* BEM suffixes as flat rules (native nesting can't concatenate &__suffix). */
.footer-cta__contact a:hover {
  text-decoration: underline;
}
.footer-cta__address {
  font-style: normal;
}

/* Self-contained brand icons (e.g. white-box LinkedIn): just size them. */
.footer-cta__social img {
  width: 3.3rem;
  height: 3.3rem;
  object-fit: contain;
}
.footer-cta__social:hover img {
  opacity: 0.85;
}

/* White legal band. */
.footer-legal {
  color: var(--rc-color-text-muted);
}
.footer-legal__notice {
  line-height: var(--rc-line-height-relaxed);
}

/* ============================================================
   BADGE STRIP (Views block "Badges", CSS class: badge-strip)
   Desktop: centred single row. Mobile: 2-column grid; a lone odd last badge
   spans both columns and centres.
   ============================================================ */
.badge-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(1.5rem, 4vw, 3.5rem);
}
.badge-strip img {
  height: 150px;
  width: auto;
  object-fit: contain;
}

@media (max-width: 575.98px) {
  .badge-strip {
    display: grid;
    grid-template-columns: 1fr 1fr;
    justify-items: center;
    align-items: center;
    gap: 2rem 1.5rem;
  }
  /* Odd number of badges: the last one is alone on its row → span both columns
     so it centres across the full width instead of sitting in column 1. */
  .badge-strip > .views-row:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }
}

/* ============================================================
   BOOTSTRAP PARAGRAPHS — vertical rhythm
   Give bootstrap_paragraphs columns the same vertical section spacing the
   rcomms paragraphs use, so mixed pages share one rhythm. (bootstrap_paragraphs
   is contrib, so this alignment lives in the theme, not the rcomms module.)
   ============================================================ */
.paragraph > .paragraph__column {
  padding: var(--rc-paragraph-spacing, 4rem) 0;
}
/* Section rhythm is for TOP-LEVEL paragraphs only. Nested paragraphs (a
   bp_simple inside a bp_columns column, tabs, accordion, etc.) must not re-add
   the section padding, or it compounds at every level and leaves a huge gap
   between, e.g., a Simple and the two-column block below it. */
.paragraph .paragraph > .paragraph__column {
  padding-block: 0;
}
/* Restore a modest gap between paragraphs stacked in the same column, now that
   their compounding padding is gone. */
.paragraph__column .paragraph + .paragraph {
  margin-top: 1.5rem;
}
/* Collapse the DOUBLE section-gap ONLY for the Simple-then-Columns case (each
   section has symmetric top+bottom padding, so the two stack to ~8rem). When a
   Columns section directly follows a Simple, drop the Columns' top padding so a
   single section-gap (the Simple's bottom) sits between them. Scoped with :has()
   so all other section transitions keep their normal spacing. Covers the plain,
   two-uneven, and three-uneven column types via the [class*=] match. */
.field--name-field-rcomms-paragraphs > .field__item:has(> .paragraph--type--bp-simple) + .field__item:has(> [class*="paragraph--type--bp-columns"]) > .paragraph > .paragraph__column {
  padding-top: 0;
}

/* CTA banner reserves its tall (min-height 400px), vertically-centred height
   ONLY when it has a background image or colour. An image-less, non-hero,
   non-coloured banner collapses to a normal text section instead of leaving a
   big empty band above/below its text. */
.paragraph--type--cta-banner.paragraph-cta-banner:not(.paragraph-cta-banner--has-bg):not(.paragraph-cta-banner--hero):not(.paragraph-cta-banner--primary):not(.paragraph-cta-banner--secondary):not(.paragraph-cta-banner--accent) {
  min-height: 0;
}

/* ============================================================
   RCOMMS PARAGRAPH SECTION HEADINGS — site styling
   The module leaves section titles unstyled (inherit). This site wants them
   big and brand-blue across every rcomms section type. Site-specific, so it
   lives here, not in the generic module.
   ============================================================ */
.paragraph-product-grid__title,
.paragraph-faq__title,
.paragraph-feature-list__title,
.paragraph-feature-icon-grid__title,
.paragraph-steps__title,
.paragraph-app-promotion__title,
.paragraph-gallery__title,
.paragraph-text-image__title,
.paragraph-hubspot-popup__title,
.rcomms-section-title,
.field--name-bp-header {
  color: var(--rc-color-brand-tertiary);
  font-size: clamp(1.75rem, 2vw + 1rem, 2.75rem);
  font-weight: var(--rc-font-weight-bold);
  line-height: var(--rc-line-height-tight);
}
/* bootstrap_paragraphs column headers: centre them like section titles. */
.field--name-bp-header {
  text-align: center;
  margin-bottom: 2rem;
}

/* Webform headings (e.g. the "Connect With Us" processed-text heading in the
   contact form): match the site's heading look — brand blue + centred — but
   KEEP each heading's own size (no font-size override). */
.webform-submission-form :is(h1, h2, h3, h4, h5, h6) {
  color: var(--rc-color-brand-tertiary, #064895);
  text-align: center;
}

/* Webform submit buttons: match the footer "Get a Quote" CTA — pill shape with
   comfortable padding. Colour already matches (both .btn-primary), so only the
   shape/size are set here. */
.webform-submission-form .form-submit,
.webform-submission-form .webform-button--submit {
  border-radius: var(--rc-radius-pill, 999px);
  padding: 0.5rem 1.75rem;
}

/* Feature-list ITEM headers in the same heading blue as the section titles
   (--rc-color-brand-tertiary; the module leaves them inheriting grey). Low
   specificity (0,1,0) on purpose so the module's full-bleed white-on-dark
   variants (0,3,0) still win. The inner field div is color:inherit, so it
   follows the h3. */
.paragraph-feature-list__item-title {
  color: var(--rc-color-brand-tertiary, #064895);
}

/* Headings typed inside rich-text bodies (CKEditor h1–h6) — give them the same
   brand treatment as section headings so in-body headings aren't plain black.
   Applies to any formatted-text field (bp_text, field_body, …) via .text-formatted.
   Paragraphs/lists are left untouched. Excluded inside CTA banners/hero, whose
   body text is white over an image (handled by the 2-axis banner rules). */
.text-formatted :is(h1, h2, h3, h4, h5, h6) {
  color: var(--rc-color-brand-tertiary, #064895);
  font-weight: var(--rc-font-weight-bold, 700);
  line-height: var(--rc-line-height-tight, 1.2);
  margin-top: 1.5rem;
  margin-bottom: 0.75rem;
}
/* h1 (page title + any in-body h1) matches the h2 look — brand-blue, bold,
   centred — but larger. The hero title uses .paragraph-cta-banner__title (its
   own display styling), so it's untouched here. */
h1.title,
.text-formatted h1 {
  color: var(--rc-color-brand-tertiary, #064895);
  font-weight: var(--rc-font-weight-bold, 700);
  line-height: var(--rc-line-height-tight, 1.2);
  text-align: center;
  font-size: clamp(2.25rem, 2.5vw + 1.25rem, 3.5rem);
}
/* h2 matches the section Header exactly (same clamp) and is centred; other
   levels stay left-aligned at their own sizes. */
.text-formatted h2 {
  font-size: clamp(1.75rem, 2vw + 1rem, 2.75rem);
  text-align: center;
}

/* Standalone (boxed, non-hero) CTA banner: centre its heading like a Simple
   h2, overriding the --left content alignment. The heading text lives in an
   inner field div, which the module's `--left __content *` rule left-aligns, so
   we centre the title AND its children. Body/link stay as set. */
/* Only centre when NO explicit left/right alignment modifier is set — otherwise
   this would override the module's --bottom_left/--left/etc. positioning (e.g.
   the case-study overlay card). Center-column modifiers (--top/--center/--bottom,
   no underscore) are left in so they still centre. */
.paragraph-cta-banner:not(.paragraph--full-bleed):not(.paragraph-cta-banner--hero):not([class*="cta-banner--top_"]):not([class*="cta-banner--bottom_"]):not(.paragraph-cta-banner--left):not(.paragraph-cta-banner--right) .paragraph-cta-banner__title,
.paragraph-cta-banner:not(.paragraph--full-bleed):not(.paragraph-cta-banner--hero):not([class*="cta-banner--top_"]):not([class*="cta-banner--bottom_"]):not(.paragraph-cta-banner--left):not(.paragraph-cta-banner--right) .paragraph-cta-banner__title * {
  text-align: center;
}
.text-formatted h3 { font-size: clamp(1.35rem, 1rem + 1vw, 1.75rem); }
.text-formatted h4 { font-size: clamp(1.15rem, 1rem + 0.5vw, 1.4rem); }
.text-formatted h5 { font-size: 1.1rem; }
.text-formatted h6 { font-size: 1rem; text-transform: uppercase; letter-spacing: 0.04em; }
/* Keep banner/hero body headings white (their body is over an image). */
.paragraph-cta-banner .text-formatted :is(h1, h2, h3, h4, h5, h6) {
  color: inherit;
}

/* Step-by-step paragraph nested in a column: drop the section's vertical
   padding (module sets `padding: var(--rc-paragraph-spacing) 0` at 0,2,0;
   this 0,3,0 selector wins). */
.paragraph__column .paragraph--type--step-by-step-with-links.paragraph-steps {
  padding: 0;
}

/* ============================================================
   TESTING SERVICES VIEW — image cards w/ blue title overlay (mockup look)
   The homepage "Our Testing Services" grid (view `testing_services`). Each card
   is a full-bleed image with a left-anchored blue title box overlaid, vertically
   centred. Fully self-contained — does NOT reuse the generic rcomms
   product-category-grid classes, so the view and the paragraph are independent.
   ============================================================ */
.testing-services-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-flow: row;         /* fill left-to-right, then wrap: [1 2] / [3 4] */
  gap: 1rem;
}
/* Odd item count: the final card sits alone on its row — span both columns
   but keep it one column wide and centre it horizontally. */
.testing-services-grid__card:last-child:nth-child(odd) {
  grid-column: 1 / -1;
  justify-self: center;
  width: calc(50% - 0.5rem);   /* one column = (100% - 1rem gap) / 2 */
}
@media (max-width: 768px) {
  .testing-services-grid { grid-template-columns: 1fr; }
  /* Single column: lone card fills the row like the rest. */
  .testing-services-grid__card:last-child:nth-child(odd) {
    grid-column: auto;
    justify-self: stretch;
    width: auto;
  }
}
.testing-services-grid__card {
  position: relative;          /* positioning context for the overlaid title */
  display: block;
  aspect-ratio: 3 / 2;         /* same proportions on mobile as desktop */
  overflow: hidden;            /* nothing escapes the card (no page overflow) */
  text-decoration: none;
  color: var(--rc-color-brand-white, #fff);
  transition: transform 0.2s, filter 0.2s;
}
.testing-services-grid__card:hover,
.testing-services-grid__card:focus {
  color: var(--rc-color-brand-white, #fff);
  text-decoration: none;
  transform: translateY(-4px);
  filter: drop-shadow(0 8px 16px rgba(0, 0, 0, 0.2));
}
/* Image fills the whole card; the title sits on top of it. */
.testing-services-grid__card-image {
  position: absolute;
  inset: 0;
}
.testing-services-grid__card-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Left-anchored blue title box, vertically centred over the image.
   Long titles wrap and the box stays inside the card (never clipped). */
.testing-services-grid__card-title {
  background-color: var(--rc-color-brand-tertiary);
  color: var(--rc-color-brand-white, #fff);
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 60%;                  /* fixed strip width: same on every card, only the
                                  height varies with the number of title lines */
  max-height: 100%;            /* never taller than the card */
  margin: 0;
  text-align: left;
  text-transform: uppercase;
  font-family: var(--rc-font-family-base);
  /* ~0.7x the original title/box so more of the photo shows behind it. */
  font-size: clamp(1.05rem, 1.26vw + 0.7rem, 1.925rem);
  font-weight: var(--rc-font-weight-bold);
  line-height: var(--rc-line-height-tight);
  padding: 0.875rem 1.225rem;
  /* Lift the strip off busy/dark photo areas so the title pops. */
  box-shadow: 0 5px 30px #ffffff44;
  word-break: normal;
}

/* ============================================================
   FAQ ACCORDION (bootstrap_paragraphs bp-accordion) — site styling
   Mockup: every header (open or closed) has the light-blue band, larger bold
   blue text, and a +/- symbol BEFORE the title, with symbol + text centred
   horizontally. Scoped to bp-accordion so other accordions are untouched.
   ============================================================ */
.paragraph--type--bp-accordion .accordion-button {
  justify-content: center;     /* centre the +/- symbol + title group */
  background-color: var(--bs-accordion-active-bg, #cfe2ff);
  color: var(--rc-color-brand-tertiary);
  font-size: clamp(1.125rem, 0.9rem + 0.6vw, 1.5rem);
  font-weight: var(--rc-font-weight-bold);
}
/* Keep the blue band when open too (override BS active state, same colour). */
.paragraph--type--bp-accordion .accordion-button:not(.collapsed) {
  background-color: var(--bs-accordion-active-bg, #cfe2ff);
  color: var(--rc-color-brand-tertiary);
  box-shadow: none;
}
/* Drop Bootstrap's chevron icon. */
.paragraph--type--bp-accordion .accordion-button::after {
  content: none;
  display: none;
}
/* +/- indicator BEFORE the title: "+" when collapsed, "−" when open. */
.paragraph--type--bp-accordion .accordion-button::before {
  content: "+";
  margin-right: 0.6rem;
  font-size: 1.25em;
  font-weight: var(--rc-font-weight-bold);
  line-height: 1;
}
.paragraph--type--bp-accordion .accordion-button:not(.collapsed)::before {
  content: "\2212";            /* minus sign − */
}

/* Q/A items: one bp-simple per question (question in bp_header, answer in
   bp_text). Left-align the block and divide each Q/A from the next. */
.paragraph--type--bp-accordion .paragraph--type--bp-simple {
  text-align: left;
}
.paragraph--type--bp-accordion .paragraph--type--bp-simple:not(:last-child) {
  border-bottom: 1px solid var(--rc-color-border, #d0d0d0);
}
/* Question heading (bp_header): override the global .field--name-bp-header
   centre + bottom-margin rule so it's left-aligned with no vertical margin. */
.paragraph--type--bp-accordion .paragraph--type--bp-simple .field--name-bp-header {
  text-align: left;
  margin-block: 0;
  /* Match the accordion header ("FAQs") size, overriding the big global
     section-heading size. */
  font-size: clamp(1.125rem, 0.9rem + 0.6vw, 1.5rem);
}
/* Answer paragraphs (bp_text): drop the default block margins. */
.paragraph--type--bp-accordion .paragraph--type--bp-simple .field--name-bp-text p {
  margin-block: 0;
}
/* Last Q/A: bootstrap_paragraphs adds 30px bottom padding to adjacent-sibling
   columns; trim the last one to 15px. High specificity to beat that rule. */
.paragraph.paragraph--type--bp-accordion .panel-collapse .paragraph.paragraph--type--bp-simple:last-child > .paragraph__column {
  padding-bottom: 15px;
}

/* ============================================================
   UNEVEN 2-COL (image left / content right) — left image fill (mockup)
   The bp_columns_two_uneven flex row is align-items:stretch, so column 1
   already stretches to the taller (right) column. The theme, though, floats
   the image field and renders it at its natural pixel width, overflowing the
   1/3 column. Here we un-float it, constrain it to the column width, and — at
   the breakpoint where the columns sit side by side (xl) — make it fill the
   column height and cover. Below xl the columns stack, so the image keeps its
   natural height.
   ============================================================ */
.paragraph--type--bp-columns-two-uneven__2col-column1 .paragraph--type--bp-image .field,
.paragraph--type--bp-columns-two-uneven__2col-column1 .paragraph--type--bp-image .field__item {
  float: none;
  margin: 0;
  width: 100%;
}
.paragraph--type--bp-columns-two-uneven__2col-column1 .paragraph--type--bp-image img {
  width: 100%;
  height: auto;
  object-fit: cover;
  display: block;
  margin: 0;
}
@media (min-width: 1200px) {
  .paragraph--type--bp-columns-two-uneven__2col-column1 .paragraph--type--bp-image,
  .paragraph--type--bp-columns-two-uneven__2col-column1 .paragraph--type--bp-image > .paragraph__column,
  .paragraph--type--bp-columns-two-uneven__2col-column1 .paragraph--type--bp-image .field,
  .paragraph--type--bp-columns-two-uneven__2col-column1 .paragraph--type--bp-image .field__item {
    height: 100%;
  }
  .paragraph--type--bp-columns-two-uneven__2col-column1 .paragraph--type--bp-image img {
    height: 100%;
  }
}

/* ============================================================
   SIMPLE paragraphs inside Columns — left-align (site)
   Any bp_simple placed in a column wrapper has its heading and body
   left-aligned (overrides the global centred .field--name-bp-header and any
   inherited centring). Scoped to column wrappers so standalone Simples keep
   their default alignment.
   ============================================================ */
.paragraph--type--bp-column-wrapper .paragraph--type--bp-simple,
.paragraph--type--bp-column-wrapper .paragraph--type--bp-simple .field--name-bp-header,
.paragraph--type--bp-column-wrapper .paragraph--type--bp-simple .field--name-bp-text,
[class*="col-column"] .paragraph--type--bp-simple,
[class*="col-column"] .paragraph--type--bp-simple .field--name-bp-header,
[class*="col-column"] .paragraph--type--bp-simple .field--name-bp-text {
  text-align: left;
}

/* ============================================================
   CTA BUTTON paragraph (rcomms cta_button) — brand pill (mockup)
   Single rounded brand-blue button, bold white label. The module outputs a
   plain Bootstrap .btn; this is the site look.
   ============================================================ */
.paragraph-cta-button {
  margin-block: 1rem;
}
.paragraph-cta-button__btn,
.paragraph-cta-button__btn:visited {
  background-color: var(--rc-color-brand-tertiary);
  color: var(--rc-color-brand-white, #fff);
  font-weight: var(--rc-font-weight-bold);
  border: 0;
  border-radius: var(--rc-radius-pill, 999px);
  padding: 0.85rem 2rem;
}
.paragraph-cta-button__btn:hover,
.paragraph-cta-button__btn:focus {
  background-color: var(--rc-color-brand-primary, #1d84c3);
  color: var(--rc-color-brand-white, #fff);
}

/* ============================================================
   BOOTSTRAP PARAGRAPHS TABS (bp_tabs) — site styling (mockup)
   A flush row of equal-width tabs: active = brand-blue with white text,
   inactive = light grey with brand-blue text, all bold and centred. Square
   corners, no Bootstrap underline/border. Thin gaps separate the tabs.
   Scoped to bp-tabs so other .nav-tabs (if any) are untouched.
   ============================================================ */
.paragraph--type--bp-tabs,
.paragraph--type--bp-tabs .tab-pane {
  scroll-margin-top: calc(var(--nav-height-base, 5rem) + 1.5rem);
}
.paragraph--type--bp-tabs .nav-tabs {
  border-bottom: 0;
  gap: 2px;
  flex-wrap: nowrap;
}
.paragraph--type--bp-tabs .nav-tabs .nav-link {
  flex: 1 1 0;
  margin-bottom: 0;
  border: 0;
  border-radius: 0;
  background-color: var(--rc-color-surface-muted, #f0f0f1);
  color: var(--rc-color-brand-tertiary);
  font-weight: var(--rc-font-weight-bold);
  font-size: 0.9rem;
  line-height: var(--rc-line-height-tight);
  text-align: center;
  padding: 0.85rem 1rem;
}
.paragraph--type--bp-tabs .nav-tabs .nav-link:hover,
.paragraph--type--bp-tabs .nav-tabs .nav-link:focus {
  border-color: transparent;          /* kill Bootstrap's hover border */
  isolation: auto;
}
.paragraph--type--bp-tabs .nav-tabs .nav-link.active {
  background-color: var(--rc-color-brand-tertiary);
  color: var(--rc-color-brand-white, #fff);
  border: 0;
}
.paragraph--type--bp-tabs .tab-content {
  padding-top: 1.25rem;
}
/* Left-align a Simple heading ONLY when it's a sibling of a tabs component
   inside a multi-column wrapper (overrides the global centred
   .field--name-bp-header). In the DOM each paragraph is wrapped in an unclassed
   <div>, so the heading and the tabs are siblings at that wrapper-div level
   inside the column wrapper's .paragraph__column. Two selectors cover either
   order: :has() for a heading wrapper that precedes the tabs wrapper, ~ for one
   after it. */
.paragraph--type--bp-column-wrapper > .paragraph__column > div:has(~ div .paragraph--type--bp-tabs) .field--name-bp-header,
.paragraph--type--bp-column-wrapper > .paragraph__column > div:has(.paragraph--type--bp-tabs) ~ div .field--name-bp-header {
  text-align: left;
}
/* Mobile: let the four tabs wrap to two per row instead of squashing. */
@media (max-width: 576px) {
  .paragraph--type--bp-tabs .nav-tabs { flex-wrap: wrap; }
  .paragraph--type--bp-tabs .nav-tabs .nav-link { flex: 1 1 calc(50% - 2px); }
}

/* ============================================================
   TEXT + IMAGE — dual-panel look (mockup)
   Two image panels side by side; heading + body overlaid in white over the
   image (the mockup uses dark photos). Module supplies the structure; this is
   the site-specific look. Text-shadow keeps text legible on busy images.
   ============================================================ */
.paragraph-text-image__panel-overlay {
  padding: clamp(1.5rem, 3vw, 4rem);
  color: var(--rc-color-brand-white, #fff);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
}
.paragraph-text-image__panel-title {
  color: var(--rc-color-brand-white, #fff);
  font-weight: var(--rc-font-weight-bold);
  font-size: clamp(1.75rem, 1rem + 2vw, 2.75rem);
  line-height: var(--rc-line-height-tight);
  margin: 0 0 1rem;
}
.paragraph-text-image__panel-body {
  color: var(--rc-color-brand-white, #fff);
}
.paragraph-text-image__panel-body p:last-child {
  margin-bottom: 0;
}

/* ============================================================
   FEATURE ICON GRID over a background image — site styling
   When a bg image is set (module's --has-bg), the mockup wants white text,
   white icons, and a left-aligned title. Site-specific → here.
   ============================================================ */
/* Taller band: more top/bottom padding than the default section rhythm.
   Compound selector matches the module's 0,2,0 padding rule so this wins. */
.paragraph--type--feature-grid-with-icon.paragraph-feature-icon-grid--has-bg {
  padding-block: clamp(3rem, 6vw, 7rem);
}
.paragraph-feature-icon-grid--has-bg .paragraph-feature-icon-grid__title,
.paragraph-feature-icon-grid--has-bg .paragraph-feature-icon-grid__intro,
.paragraph-feature-icon-grid--has-bg .paragraph-feature-icon-grid__card-title,
.paragraph-feature-icon-grid--has-bg .paragraph-feature-icon-grid__card-body {
  color: var(--rc-color-brand-white, #fff);
}
/* Larger card titles to match the mockup (wrap to ~2 lines). */
.paragraph-feature-icon-grid--has-bg .paragraph-feature-icon-grid__card-title {
  font-size: clamp(1.25rem, 0.9rem + 1vw, 1.6rem);
  line-height: var(--rc-line-height-snug, 1.35);
}
/* Cells are half the (wide) container, so the icon+text pair floats left with
   empty space to the right. Cap each card's content and centre it in its cell
   so the two columns sit toward the middle like the mockup. */
.paragraph-feature-icon-grid--has-bg .paragraph-feature-icon-grid__card {
  max-width: 28rem;
  margin-inline: auto;
}

/* ============================================================
   INDUSTRIES VIEW — round blue icon badges (site styling)
   Each .views-row is a circular blue badge: icon + label stacked and centred
   inside. Display only (no links — Industry nodes have no public pages).
   ============================================================ */
.industries-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(1.5rem, 3vw, 2.5rem);
}

.industries-grid .views-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0.5rem;
  width: clamp(11rem, 14vw, 12rem);
  aspect-ratio: 1;                    /* perfect circle */
  border-radius: 50%;
  padding: 1.5rem;
  background-color: var(--rc-color-brand-tertiary, #064895);
  transition: transform var(--rc-transition-base, 0.2s),
              filter var(--rc-transition-base, 0.2s);
}
.industries-grid .views-row:hover,
.industries-grid .views-row:focus-within {
  transform: translateY(-4px);
  filter: drop-shadow(0 8px 16px rgba(var(--rc-color-brand-secondary-rgb), 0.2));
}

/* Icon */
.industries-grid .views-field-field-icon img {
  width: clamp(3rem, 5vw, 4.5rem);
  height: auto;
  object-fit: contain;
  display: block;
}

/* Label */
.industries-grid .views-field-title {
  color: var(--rc-color-brand-white, #fff);
  font-size: var(--rc-font-size-base, 1.0625rem);
  font-weight: var(--rc-font-weight-medium, 500);
  line-height: var(--rc-line-height-tight, 1.2);
}

/* ============================================================
   TESTING PROCESS section — site styling
   Left: numbered steps as bordered boxes (numbering itself is the module's
   field_show_numbers feature; this is the boxed/circle look for this site).
   Right: a CTA banner used as a "case study" card — bottom-left title.
   ============================================================ */
/* Boxed steps with a tertiary-blue number circle. */
.paragraph-steps--numbered .paragraph-steps__list {
  gap: 1.5rem;
}
.paragraph-steps--numbered .paragraph-steps__step {
  align-items: center;
  gap: 1.25rem;
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--rc-color-border, #d0d0d0);
  border-radius: var(--rc-radius-sm, 6px);
}
/* Drop the module's divider borders in this boxed variant. */
.paragraph-steps--numbered .paragraph-steps__step,
.paragraph-steps--numbered .paragraph-steps__step:last-child {
  border-top: 1px solid var(--rc-color-border, #d0d0d0);
  border-bottom: 1px solid var(--rc-color-border, #d0d0d0);
}
.paragraph-steps--numbered .paragraph-steps__step::before {
  background-color: var(--rc-color-brand-tertiary, #064895);
}
.paragraph-steps--numbered .paragraph-steps__step-title {
  color: var(--rc-color-brand-tertiary, #064895);
  margin: 0;
  font-size: var(--rc-text-heading-md, 1.5rem);
}

/* CTA banner as a nested "case study" card: bottom-left content. */
.paragraph__column .paragraph-cta-banner .paragraph-cta-banner__content {
  text-align: left;
  margin-top: auto;            /* push content to the bottom of the banner */
}
.paragraph__column .paragraph-cta-banner {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  height: 100%;                /* fill the column so it matches the steps height */
}

/* Row direction is handled by Bootstrap's flex-xl-row (≥1200px) on the wrapper.
   Below xl the columns stack. bp's own CSS (≥768px) sets float + 33%/66%
   widths on the columns; in our flex column the float is ignored but the
   width still squishes them, so force full width and add a gap. */
@media (max-width: 1199.98px) {
  /* bp's width rule is 4 classes (.paragraph.paragraph--type--…
     .paragraph--style--33-66 .__2col-columnN = 0,4,0). Triple the wrapper
     class (0,5,0) to win regardless of stylesheet load order. */
  .bp-two-uneven__row.bp-two-uneven__row.bp-two-uneven__row > .paragraph--type--bp-columns-two-uneven__2col-column1,
  .bp-two-uneven__row.bp-two-uneven__row.bp-two-uneven__row > .paragraph--type--bp-columns-two-uneven__2col-column2 {
    width: 100%;
    float: none;
    padding-right: 0;          /* bp adds 1.5rem right padding to column1 ≥768 */
    padding-left: 0;
  }
  .bp-two-uneven__row > .paragraph--type--bp-columns-two-uneven__2col-column2 {
    margin-top: 1.5rem;
  }
  /* The steps sit inside a .container (≈0.75rem side gutter); the nested CTA
     banner bleeds to the column edge. Pad the banner's COLUMN by the same
     gutter so the banner insets to match the steps (padding shrinks the box,
     unlike margin which would push it off-screen). Overrides the padding:0
     above for column2 only. */
  .bp-two-uneven__row.bp-two-uneven__row.bp-two-uneven__row > .paragraph--type--bp-columns-two-uneven__2col-column2 {
    padding-inline: calc(var(--bs-gutter-x, 1.5rem) * 0.5);
  }
}

/* The two-uneven columns are now flex items (see the subtheme paragraph
   template). Make each column + its inner field wrapper full height so the
   banner can stretch to match the taller steps column. */
.paragraph--type--bp-columns-two-uneven__2col-column1,
.paragraph--type--bp-columns-two-uneven__2col-column2 {
  display: flex;
  flex-direction: column;
}
.paragraph--type--bp-columns-two-uneven__2col-column1 > div,
.paragraph--type--bp-columns-two-uneven__2col-column2 > div {
  flex: 1;
  display: flex;
  flex-direction: column;
}
/* Field items inside the column fill the height too. */
.paragraph--type--bp-columns-two-uneven__2col-column2 .field,
.paragraph--type--bp-columns-two-uneven__2col-column2 .field__item {
  flex: 1;
}

/* Block label ("Case Studies") in the case-studies region: match the Simple h2
   look — big, brand-blue, centred. Scoped to the region so other block titles
   are unaffected. */
.region-featured-bottom-third .block-views > h2 {
  color: var(--rc-color-brand-tertiary, #064895);
  font-weight: var(--rc-font-weight-bold, 700);
  line-height: var(--rc-line-height-tight, 1.2);
  text-align: center;
  font-size: clamp(1.75rem, 2vw + 1rem, 2.75rem);
  margin-bottom: 1rem;
}

/* ============================================================
   CASE STUDY CAROUSEL (Views block "case_studies", style = Unformatted)
   Bootstrap 5 carousel: 3 tiles per slide (2 tablet, 1 mobile via the
   responsive row-cols), advancing a whole slide per arrow. Custom styling
   below covers the container spacing, the prev/next controls and the tiles.
   Tokens only. The section heading comes from the embedding bp_view
   paragraph, not here.
   ============================================================ */
.case-study-carousel {
  position: relative;
  /* Side room so the nav controls sit in the gutters, not over tile content. */
  padding-inline: clamp(2.5rem, 5vw, 4rem);
  margin-block: var(--rc-paragraph-spacing, 1.5rem);
}
/* Nested in a column (e.g. single-card display): drop the carousel's section
   spacing — it's not a standalone section here. */
[class*="col-column"] .case-study-carousel,
.paragraph--type--bp-column-wrapper .case-study-carousel {
  margin-inline: 0;
  padding-block: 0;
  padding-inline: 1rem;
}
/* Centre the card vertically next to a taller sibling column. The columns are
   flex items of an align-items:stretch row, so they stretch to equal height;
   align-self:center on the card's column overrides that — the column shrinks to
   the card's height and centres vertically in the row. Scoped with :has() to
   columns that actually contain a case-study card. */
[class*="col-column"]:has(.case-study-carousel),
.paragraph--type--bp-column-wrapper:has(.case-study-carousel) {
  align-self: center;
}

/* --- Tile --- */
.cs-tile {
  position: relative;                 /* anchor for the stretched link */
  display: flex;
  flex-direction: column;
  height: 100%;                       /* equal-height tiles within a slide */
  max-width: 420px;                   /* keep card-sized when its column is wide
                                         (e.g. a 1-item display) instead of
                                         stretching full width */
  background-color: var(--rc-color-brand-white, #fff);
  border-radius: var(--rc-radius-sm, 6px);
  overflow: hidden;
  box-shadow: 0 4px 14px rgba(var(--rc-color-brand-secondary-rgb, 0, 43, 92), 0.12);
  transition: transform var(--rc-transition-base, 0.2s),
              box-shadow var(--rc-transition-base, 0.2s);
}
.cs-tile:hover,
.cs-tile:focus-within {
  transform: translateY(-4px);
  box-shadow: 0 10px 26px rgba(var(--rc-color-brand-secondary-rgb, 0, 43, 92), 0.22);
}

/* --- Media: pin the image to the box ourselves instead of relying on
   Bootstrap's `.ratio > *` (which Blazy's img handling can knock out, causing
   the image to render at natural height and overlap the bar). A CSS-native
   aspect-ratio guarantees the box height even if `.ratio::before` ever fails. */
.cs-tile__media {
  position: relative;
  aspect-ratio: 100 / 62;
  overflow: hidden;
}
.cs-tile__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* --- Footer bar: title left, arrow right --- */
.cs-tile__bar {
  display: flex;
  align-items: center;                 /* vertically centre title + arrow */
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  background-color: var(--rc-color-surface-muted, #f0f0f1);
  border-top: 1px solid var(--rc-color-border, #d0d0d0);
  flex: 1 1 auto;                      /* fill the leftover tile height so the
                                          grey reaches the card's bottom edge on
                                          uneven cards; align-items keeps the
                                          text vertically centred */
}

.cs-tile__title {
  color: var(--rc-color-brand-secondary, #002b5c);
  font-weight: var(--rc-font-weight-bold, 700);
  font-size: var(--rc-text-heading-sm, 1.25rem);
  line-height: var(--rc-line-height-snug, 1.35);
  /* Clamp long titles to 2 lines so bars stay even. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

/* --- Circular blue arrow button (visual affordance; not a link) --- */
.cs-tile__arrow {
  flex: none;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background-color: var(--rc-color-brand-primary, #0a5fc0);
  color: var(--rc-color-brand-white, #fff);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color var(--rc-transition-base, 0.2s),
              transform var(--rc-transition-base, 0.2s);
}
.cs-tile:hover .cs-tile__arrow,
.cs-tile:focus-within .cs-tile__arrow {
  background-color: var(--rc-color-brand-tertiary, #064895);
  transform: translateX(2px);
}

/* ============================================================
   CASE STUDY CARD paragraph (case_study_card) — a referenced Case Study
   rendered as one clickable image tile: node image background + dark scrim +
   bottom-left eyebrow/title. The whole <a> is the link (big hit target).
   ============================================================ */
.cs-card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;      /* content sits bottom-left */
  min-height: 320px;
  height: 100%;                   /* fill the column height (e.g. beside steps) */
  padding: clamp(1.25rem, 1rem + 2vw, 2.25rem);
  overflow: hidden;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  color: var(--rc-color-brand-white, #fff);
  text-decoration: none;
  transition: transform var(--rc-transition-base, 0.2s) ease,
              box-shadow var(--rc-transition-base, 0.2s) ease;
}
.cs-card__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.75) 0%,
    rgba(0, 0, 0, 0.35) 45%,
    rgba(0, 0, 0, 0.15) 100%
  );
  z-index: 0;
}
.cs-card__content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
}
.cs-card__eyebrow {
  text-transform: uppercase;
  letter-spacing: var(--rc-letter-spacing-wider, 0.05em);
  font-weight: var(--rc-font-weight-bold, 700);
  font-size: var(--rc-text-caption, 0.85rem);
  opacity: 0.9;
}
.cs-card__title {
  font-weight: var(--rc-font-weight-bold, 700);
  font-size: clamp(1.5rem, 1rem + 1.5vw, 2.25rem);
  line-height: var(--rc-line-height-tight, 1.2);
}
.cs-card__cta {
  margin-top: 0.5rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: var(--rc-font-weight-bold, 700);
}
.cs-card__cta::after { content: "\2192"; }
.cs-card:hover,
.cs-card:focus-visible {
  transform: translateY(-4px);
  box-shadow: 0 10px 26px rgba(var(--rc-color-brand-secondary-rgb, 0, 43, 92), 0.3);
  color: var(--rc-color-brand-white, #fff);
  text-decoration: none;
}
.cs-card__cta { text-decoration: none; }

/* ============================================================
   SPLIDE case-studies carousel — gaps, arrows outside, dots below, brand look.
   Scoped to this view's Splide (.splide--view--case-studies).
   ============================================================ */
/* Room in the side gutters for the arrows to sit OUTSIDE the cards — just wide
   enough for the chevron so they sit close to the slides, not floating far out. */
.splide--view--case-studies {
  position: relative;
  padding-inline: 3.5rem;
}
/* Gap between cards is set via the Splide optionset (gap option), not here. */
/* Arrows: plain brand-blue chevrons (no circle), pinned in the gutters. */
.splide--view--case-studies .splide__arrow {
  width: 2.75rem;
  height: 2.75rem;
  background: transparent;
  border-radius: 0;
  opacity: 1;
}
.splide--view--case-studies .splide__arrow svg {
  width: 1.75rem;
  height: 1.75rem;
  fill: var(--rc-color-brand-tertiary, #064895);
}
.splide--view--case-studies .splide__arrow:hover:not(:disabled) svg {
  fill: var(--rc-color-brand-primary, #1d84c3);
}
.splide--view--case-studies .splide__arrow:disabled { opacity: 0.35; }
/* Center arrows in the side gutter: (gutter 3.5rem − arrow 2.75rem) / 2 = 0.375rem,
   so each chevron sits midway between the card edge and the screen edge. */
.splide--view--case-studies .splide__arrow--prev { left: 0.375rem; }
.splide--view--case-studies .splide__arrow--next { right: 0.375rem; }
/* Pagination: below the strip (not overlapping cards) + brand dots. */
.splide--view--case-studies .splide__pagination {
  position: static;
  transform: none;
  margin-top: 1.25rem;
  padding: 0;
  justify-content: center;
}
.splide--view--case-studies .splide__pagination__page {
  width: 8px;
  height: 8px;
  margin: 0 4px;
  background: var(--rc-color-border, #d0d0d0);
  opacity: 1;
}
.splide--view--case-studies .splide__pagination__page.is-active {
  background: var(--rc-color-brand-tertiary, #064895);
  transform: scale(1.25);
}

/* --- Carousel controls: navy circular buttons in the side gutters --- */
.case-study-carousel .carousel-control-prev,
.case-study-carousel .carousel-control-next {
  top: 50%;
  bottom: auto;
  transform: translateY(-50%);
  z-index: 2;
  width: 2.75rem;
  height: 2.75rem;
  border: none;
  border-radius: 50%;
  background-color: var(--rc-color-brand-secondary, #002b5c);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 1;
  box-shadow: 0 2px 8px rgba(var(--rc-color-brand-secondary-rgb, 0, 43, 92), 0.25);
  transition: background-color var(--rc-transition-base, 0.2s);
}
/* Sit at the very edges, over the gutter, clear of tile content. */
.case-study-carousel .carousel-control-prev { left: 0; }
.case-study-carousel .carousel-control-next { right: 0; }
.case-study-carousel .carousel-control-prev:hover,
.case-study-carousel .carousel-control-prev:focus-visible,
.case-study-carousel .carousel-control-next:hover,
.case-study-carousel .carousel-control-next:focus-visible {
  background-color: var(--rc-color-brand-primary, #0a5fc0);
  opacity: 1;
}
/* Keep Bootstrap's white chevron icons crisp inside the smaller buttons. */
.case-study-carousel .carousel-control-prev-icon,
.case-study-carousel .carousel-control-next-icon {
  width: 1.25rem;
  height: 1.25rem;
}

/* ============================================================
   INDUSTRY CARDS (Views block "industry_cards", style = Unformatted)
   A vertical stack of full-width rounded banner cards. Each card has a
   background image, a base bottom gradient for legibility, bottom-left
   title/subtitle and a bottom-right "Get a Quote" pill. On hover (and
   keyboard focus-within) a near-full navy overlay fades in and the teaser
   (field_description) fades/slides in near the top; the title/subtitle/pill
   stay put on top of the darkened card. Pure CSS — no JS.
   Tokens only. Touch devices have no hover: the teaser/overlay never appear,
   but the title/subtitle/pill are always visible, so the card stays usable.
   ============================================================ */
.industry-cards {
  display: flex;
  flex-direction: column;
  gap: 2rem;
  margin-block: 0;
}

/* --- Card shell --- */
.industry-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--rc-radius-sm, 6px);
  min-height: clamp(400px, 42vw, 640px);
  display: flex;
  box-shadow: 0 10px 30px rgba(var(--rc-color-brand-secondary-rgb, 0, 43, 92), 0.18);
  /* isolation creates a stacking context so the internal z-index ladder
     (media 0 → overlay 1 → hover 2 → teaser 3 → bottom 4) stays self-contained. */
  isolation: isolate;
}

/* --- Background image (fills the card) --- */
.industry-card__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.industry-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* --- Base bottom gradient (always on) for legibility --- */
.industry-card__overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    to top,
    rgba(var(--rc-color-brand-secondary-rgb, 0, 43, 92), 0.85) 0%,
    rgba(var(--rc-color-brand-secondary-rgb, 0, 43, 92), 0.35) 35%,
    rgba(var(--rc-color-brand-secondary-rgb, 0, 43, 92), 0) 60%
  );
}

/* --- Hover fill (fades in over the whole card) --- */
.industry-card__hover {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: rgba(var(--rc-color-brand-secondary-rgb, 0, 43, 92), 0.9);
  opacity: 0;
  transition: opacity var(--rc-transition-base, 0.2s) ease;
}

/* --- Teaser (top, hidden until hover) --- */
.industry-card__teaser {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: 3;
  padding: 3rem 3.25rem;
  color: var(--rc-color-brand-white, #fff);
  /* Larger, roomier body copy (site preference for these cards). */
  font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.45rem);
  line-height: 1.7;
  opacity: 0;
  transform: translateY(-0.5rem);
  transition: opacity var(--rc-transition-base, 0.2s) ease,
              transform var(--rc-transition-base, 0.2s) ease;
  /* Stay clear of the bottom text/pill block (approx. its height) so the
     teaser never overlaps it; clip any overflow so long copy can't break out. */
  max-height: calc(100% - 6rem);
  overflow: hidden;
}
/* Space between teaser paragraphs / list items for the roomier look. */
.industry-card__teaser p {
  margin: 0 0 1.1rem;
}
.industry-card__teaser p:last-child,
.industry-card__teaser ul:last-child {
  margin-bottom: 0;
}

/* --- Bottom block: title/subtitle left, pill right --- */
.industry-card__bottom {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.75rem 2.5rem;
}

.industry-card__title {
  color: var(--rc-color-brand-white, #fff);
  font-weight: var(--rc-font-weight-bold, 700);
  margin: 0;
  font-size: clamp(1.25rem, 1vw + 1rem, 1.9rem);
  line-height: var(--rc-line-height-tight, 1.2);
}
.industry-card__title a {
  color: inherit;
  text-decoration: none;
  transition: opacity var(--rc-transition-fast, 0.15s) ease;
}
.industry-card__title a:hover,
.industry-card__title a:focus-visible {
  text-decoration: underline;
}

.industry-card__subtitle {
  color: rgba(var(--rc-color-brand-white-rgb, 255, 255, 255), 0.85);
  text-transform: uppercase;
  letter-spacing: var(--rc-letter-spacing-wider, 0.05em);
  margin: 0.25rem 0 0;
  font-size: 0.95rem;
}

/* --- "Get a Quote" pill --- */
.industry-card__cta a {
  display: inline-flex;
  align-items: center;
  background: var(--rc-color-brand-primary, #0a5fc0);
  color: var(--rc-color-brand-white, #fff);
  font-weight: var(--rc-font-weight-bold, 700);
  border: 1px solid rgba(var(--rc-color-brand-white-rgb, 255, 255, 255), 0.6);
  border-radius: var(--rc-radius-pill, 999px);
  padding: 0.75rem 1.75rem;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--rc-transition-fast, 0.15s) ease;
}
.industry-card__cta a:hover,
.industry-card__cta a:focus-visible {
  background: var(--rc-color-brand-tertiary, #064895);
}

/* --- Hover / keyboard reveal --- */
.industry-card:hover .industry-card__hover,
.industry-card:focus-within .industry-card__hover {
  opacity: 1;
}
.industry-card:hover .industry-card__teaser,
.industry-card:focus-within .industry-card__teaser {
  opacity: 1;
  transform: none;
}

/* --- Small screens: tighten padding; teaser stays clipped --- */
@media (max-width: 575.98px) {
  .industry-card__teaser {
    padding: 1.25rem 1.5rem;
    max-height: calc(100% - 5rem);
  }
  .industry-card__bottom {
    padding: 1.25rem 1.5rem;
    gap: 1rem;
  }
  .industry-card__cta a {
    padding: 0.6rem 1.25rem;
  }
}

/* ============================================================
   CASE STUDY PILLS
   "Case Study Industries" view: a centered, wrapping row of
   rounded pill links to the referenced Industry/Testing pages.
   Field wrappers are stripped in the View UI, so the children
   are bare <a> tags. The display:contents fallbacks below keep
   the anchors as flex children even if Views re-introduces a
   .field-content wrapper or an .item-list <ul><li> structure.
   ============================================================ */
.cs-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
  align-items: center;
  margin: 0;
}

.cs-pills a {
  display: inline-flex;
  align-items: center;
  background: var(--rc-color-surface-muted, #f0f0f1);
  color: var(--rc-color-brand-secondary, #002b5c);
  text-transform: uppercase;
  font-weight: var(--rc-font-weight-bold, 700);
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  padding: 0.55rem 1.4rem;
  border-radius: var(--rc-radius-pill, 999px);
  text-decoration: none;
  line-height: 1.2;
  transition:
    background var(--rc-transition-fast, 0.15s) ease,
    color var(--rc-transition-fast, 0.15s) ease;
}

.cs-pills a:hover,
.cs-pills a:focus {
  /* Token-derived tint: a slightly darker grey on hover. */
  background: rgba(var(--rc-color-brand-secondary-rgb, 0, 43, 92), 0.12);
  color: var(--rc-color-brand-secondary, #002b5c);
}

/* Fallback: if the field still emits an .item-list <ul>/<li> or a
   wrapper, collapse it so the bare anchors remain the flex children. */
.cs-pills ul,
.cs-pills li {
  display: contents;
}

/* ============================================================
   FEATURE-GRID CARD CTA — site look (module ships generic structure only).
   Bold brand-blue text link with a trailing arrow, per the About mockup.
   ============================================================ */
.paragraph-feature-icon-grid__card-cta {
  color: var(--rc-color-brand-primary);
  font-weight: var(--rc-font-weight-bold);
  transition: color var(--rc-transition-fast) ease;
}
.paragraph-feature-icon-grid__card-cta::after {
  content: "\2192"; /* → */
  margin-left: 0.4em;
}
.paragraph-feature-icon-grid__card-cta:hover,
.paragraph-feature-icon-grid__card-cta:focus {
  color: var(--rc-color-brand-tertiary);
  text-decoration: underline;
}


/* ============================================================
   FEATURE-GRID — BOXED CARDS variant (site look).
   Module ships the generic modifier class only; this theme
   provides the grey rounded bordered card look from the About
   mockup. Active only when the "Boxed cards" toggle is ON.
   ============================================================ */
.paragraph-feature-icon-grid--boxed .paragraph-feature-icon-grid__card {
  /* Box look */
  background: var(--rc-color-surface-muted, #f0f0f1);
  border: 1px solid var(--rc-color-brand-primary);
  border-radius: var(--rc-radius-sm);
  padding: clamp(1.5rem, 2vw, 2.25rem);
  height: 100%;
  /* Mockup layout: heading top-left, icon top-right, body + CTA below, left-aligned.
     DOM order is icon, title, body, cta — grid placement reorders it. */
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: start;
  column-gap: 1rem;
  text-align: left;
}
.paragraph-feature-icon-grid--boxed .paragraph-feature-icon-grid__card-title {
  grid-column: 1;
  grid-row: 1;
  align-self: center;   /* centre heading against the icon in the top row */
  margin: 0;
  color: var(--rc-color-brand-primary);
}
.paragraph-feature-icon-grid--boxed .paragraph-feature-icon-grid__card-icon,
.paragraph-feature-icon-grid--boxed .paragraph-feature-icon-grid__card-icon img {
  width: clamp(72px, 6vw, 120px);
  height: clamp(72px, 6vw, 120px);
}
.paragraph-feature-icon-grid--boxed .paragraph-feature-icon-grid__card-icon {
  grid-column: 2;
  grid-row: 1;
  align-self: center;
  margin: 0;
}
.paragraph-feature-icon-grid--boxed .paragraph-feature-icon-grid__card-body {
  grid-column: 1 / -1;
  grid-row: 2;
  margin-top: 1rem;
  color: var(--rc-color-text);
}
.paragraph-feature-icon-grid--boxed .paragraph-feature-icon-grid__card-cta {
  grid-column: 1 / -1;
  grid-row: 3;
  margin-top: 1rem;
}

/* ============================================================
   QUOTE — site look. Module ships the blockquote markup + curly quotes;
   here we add the light-grey panel + tokenised citation colour from the
   mockup. (Lightest grey token available; swap to a dedicated token later
   if needed.)
   ============================================================ */
.paragraph--type--quote {
  background: var(--rc-color-surface-muted, #f0f0f1);
  /* !important needed: Bootstrap's .border utility sets the border shorthand
     with !important, so only !important can recolor it. */
  border-color: var(--rc-color-gray-dark, #646464) !important;
}
.paragraph--type--quote .blockquote {
  font-weight: var(--rc-font-weight-bold);
}
.paragraph--type--quote .blockquote-footer {
  color: var(--rc-color-text);
}
