/*
 * ECWE custom CSS: everything the Bricks controls cannot express.
 *
 * This file is the ONLY allowed home for hand-written CSS on this site.
 * The Bricks database must contain zero custom CSS (enforced by
 * scripts/bricks-css-audit.sh in the site repo).
 *
 * Rules for editing:
 * - If a Bricks control can express it, use the control, not this file.
 * - Selectors must stay scoped (a class or a #brxe-… id); no bare tags.
 * - Tablet breakpoint is max-width: 991px, mobile is max-width: 767px,
 *   matching the Bricks breakpoints.
 *
 * Migrated from the Bricks data stores on 2026-08-14. Every block carries
 * a comment saying where it used to live.
 */

/* ====================================================================
   GLOBAL CLASSES (formerly class _cssCustom)
   ==================================================================== */

/* class ecwe-btn [base] */
.ecwe-btn {
  white-space: nowrap;
}

/* class ecwe-hero__emblem--ink [base] */
.ecwe-hero__emblem--ink {
  filter: brightness(0);
}

/* class ecwe-editorial__body [base] */
@media (max-width: 767px) {
  .ecwe-editorial__body {
    column-count: 1 !important;
  }
}
.ecwe-editorial__body {
  column-count: 2;
}
.ecwe-editorial__body p {
  margin: 0 0 24px;
  font-family: var(--font-sans);
  font-size: 18px;
  line-height: 1.74;
  color: var(--ink-700);
  break-inside: avoid;
}
.ecwe-editorial__body p:last-child {
  margin-bottom: 0 !important;
}

/* class ecwe-editorial__body--dropcap nested selector '& p:first-of-type::first-letter' */
.ecwe-editorial__body--dropcap p:first-of-type::first-letter {
  float: left;
  font-family: Canela;
  font-weight: 600;
  font-size: 68px;
  line-height: 0.74;
  color: var(--ink-900);
  padding: 6px 14px 0 0;
}

/* class ecwe-awards-banner__seal [base] */
.ecwe-awards-banner__seal {
  --copper-300: #d6a074;
  --copper-400: #c5824f;
  --copper-600: #9b5a33;
  --copper-700: #7e4828;
  --obsidian: #15120d;
}

/* class ecwe-awards-banner__seal-disc [base] */
.ecwe-awards-banner__seal-disc {
  box-sizing: border-box;
}

/* class ecwe-feature-split--image-right [base]
   Desktop only: below 992px the grid class control stacks the columns.
   Unwrapped, this rule kept /certifications/ and /awards/ in two narrow
   columns on phones. */
@media (min-width: 992px) {
  .ecwe-feature-split--image-right .ecwe-feature-split__grid {
    grid-template-columns: 1.08fr 0.92fr;
  }
}
.ecwe-feature-split--image-right .ecwe-feature-split__image {
  order: 1;
  height: clamp(340px, 36vw, 480px);
}

/* class ecwe-split-grid [tablet_portrait] */
.ecwe-split-grid .ecwe-feature-split__image {
  order: -1;
}

/* class ecwe-feature-split__link [base] */
.ecwe-feature-split__link-icon {
  transition: transform 0.2s ease;
}
.ecwe-feature-split__link:hover .ecwe-feature-split__link-icon {
  transform: translateX(3px);
}

/* class ecwe-index-row--linked [base]
   Phones: the class control switches the grid to two columns
   (minmax(0, 1fr) 24px). The number sits alone on the first row with the
   chevron at its right; title and body span the full width below it.
   Grid placement of text elements has no Bricks control. */
@media (max-width: 767px) {
  .ecwe-index-row--linked.brxe-div .ecwe-index-row__title,
  .ecwe-index-row--linked.brxe-div .ecwe-index-row__body {
    grid-column: 1 / -1;
    margin-top: 0;
  }
  .ecwe-index-row--linked.brxe-div .ecwe-index-nav__chevron {
    grid-row: 1;
    grid-column: 2;
    align-self: center;
    margin-top: 0;
  }
}
.ecwe-index-row--linked .ecwe-index-row__title {
  font-size: clamp(24px, 2.8vw, 34px);
}

/* class ecwe-quote-band--dark [base] */
.ecwe-quote-band--dark .ecwe-quote-band__quote {
  color: var(--text-on-dark);
}
.ecwe-quote-band--dark .ecwe-quote-band__credit {
  color: var(--copper-300);
}

/* class ecwe-quote-band--credit-bottom [base] */
.ecwe-quote-band--credit-bottom .ecwe-quote-band__credit {
  order: 3;
  margin-top: 30px;
  letter-spacing: 0.04em;
}
.ecwe-quote-band--credit-bottom .ecwe-quote-band__quote {
  margin-bottom: 30px;
}

/* class ecwe-quote-band__ornament-line--left [base] */
.ecwe-quote-band__ornament-line--left {
  background: linear-gradient(90deg, transparent, var(--copper-500));
}

/* class ecwe-quote-band__ornament-line--right [base] */
.ecwe-quote-band__ornament-line--right {
  background: linear-gradient(90deg, var(--copper-500), transparent);
}

/* class ecwe-contact-section__input [base] */
.ecwe-contact-section__input {
  box-sizing: border-box;
}

/* class ecwe-contact-section__textarea [base] */
.ecwe-contact-section__textarea {
  box-sizing: border-box;
  resize: vertical;
}

/* class ecwe-header [base] */
.ecwe-header {
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}

/* Header hover state: same solid background as the scrolled state.
   Not a control, because the hover background must be limited to real
   pointing devices. On a touch screen a tap counts as hover and the
   background would stay solid until the visitor taps elsewhere.
   The .brxe-div qualifier is needed to beat the class's own base
   background control (see the cascade rule in
   docs/bricks-css-exceptions.md). The scrolled state still wins over
   this one: its selector carries the #brx-header id. */
@media (hover: hover) and (pointer: fine) {
  .ecwe-header.brxe-div:hover {
    background-color: var(--surface-header-scrolled);
  }
}

/* class ecwe-icon-arrow [base] */
.brxe-div.ecwe-icon-arrow {
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239B5A33' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3Cpolyline points='12 5 19 12 12 19'/%3E%3C/svg%3E")
    center / contain no-repeat;
}

/* class ecwe-tax-subcats [base] */
.ecwe-tax-subcats.brxe-section {
  counter-reset: subcatrow;
}

/* class ecwe-tax-subcats__row [base]
   Phones: one column (class control), so the counter number gets its own
   row above the name. */
@media (max-width: 767px) {
  .ecwe-tax-subcats__row.brxe-div .ecwe-tax-eyebrow {
    grid-column: 1 / -1;
  }
}
@media (max-width: 767px) {
  .ecwe-tax-subcats__row.brxe-div .ecwe-index-row__link {
    grid-column: 1 / -1;
    justify-content: flex-start;
  }
}
.ecwe-tax-subcats__row .ecwe-tax-subcats__name {
  transition: color var(--dur-base) var(--ease-standard);
}
.ecwe-tax-subcats__row:hover .ecwe-tax-subcats__name {
  color: var(--copper-600);
}

/* class ecwe-tax-subcats__row nested selector '&::before' */
.ecwe-tax-subcats__row.brxe-div::before {
  counter-increment: subcatrow;
  content: counter(subcatrow, decimal-leading-zero);
}

/* class ecwe-tax-listing [base] */
.ecwe-tax-listing.brxe-section {
  counter-reset: protorow;
}

/* class ecwe-tax-row [base]
   Phones: two columns (class control: thumbnail + text). The counter
   number (::before) spans the first row on its own. */
@media (max-width: 767px) {
  .ecwe-tax-row.brxe-div::before {
    grid-column: 1 / -1;
    margin-bottom: 4px;
  }
  .ecwe-tax-row.brxe-div .ecwe-tax-row__excerpt {
    grid-column: 2;
  }
}
@media (max-width: 767px) {
  .ecwe-tax-row.brxe-div .ecwe-index-row__link {
    grid-column: 2;
    justify-content: flex-start;
    padding-top: 4px;
  }
}

/* class ecwe-tax-group__head: on phones the head is one column (class
   control) and "View all" sits under the group name, aligned left like
   the rest of the text. The link class is shared and right-aligned on
   desktop, so the phone alignment lives here. */
@media (max-width: 767px) {
  .ecwe-tax-group__head.brxe-div .ecwe-index-row__link {
    justify-content: flex-start;
  }
}
.ecwe-tax-row .ecwe-tax-row__title {
  transition: color var(--dur-base) var(--ease-standard);
}
.ecwe-tax-row:hover .ecwe-tax-row__title {
  color: var(--copper-600);
  text-decoration: underline;
}

/* class ecwe-tax-row nested selector '&::before' */
.ecwe-tax-row.brxe-div::before {
  counter-increment: protorow;
  content: counter(protorow, decimal-leading-zero);
}

/* class ecwe-tax-row__excerpt [base] */
.ecwe-tax-row__excerpt {
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

/* class ecwe-mega-section [base] */
@media (max-width: 991px) {
  .ecwe-mega-section {
    box-shadow: none;
  }
}

/* class ecwe-mega-container [base] */
.ecwe-mega-container {
  margin-block: 0px;
  margin-inline: auto;
  padding-block: 40px;
  padding-inline: 48px;
}

/* class ecwe-mega-rail [base] */
@media (min-width: 992px) {
  .brx-has-megamenu.open .ecwe-mega-sector:hover::after,
  .brx-has-megamenu.open .ecwe-mega-sector:focus-within::after {
    content: "";
    position: absolute;
    top: 40px;
    bottom: 40px;
    left: 264px;
    width: 92px;
  }
}
.brx-has-megamenu.open
  .ecwe-mega-rail:not(:hover):not(:focus-within)
  .ecwe-mega-sector:first-child
  .ecwe-mega-panel {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition:
    opacity 0s linear 0s,
    visibility 0s linear 0s;
}
.ecwe-mega-rail:not(:hover):not(:focus-within)
  .ecwe-mega-sector:first-child
  .ecwe-mega-rail-row {
  color: var(--copper-600);
}
.ecwe-mega-rail:not(:hover):not(:focus-within)
  .ecwe-mega-sector:first-child
  .ecwe-mega-arrow {
  opacity: 1;
}
.brx-has-megamenu.open .ecwe-mega-sector:hover .ecwe-mega-panel {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition:
    opacity 0.16s var(--ease-standard) 0.04s,
    visibility 0s linear 0s;
}
.brx-has-megamenu.open .ecwe-mega-sector:focus-within .ecwe-mega-panel {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition:
    opacity 0.16s var(--ease-standard) 0.04s,
    visibility 0s linear 0s;
}
.ecwe-mega-sector:hover .ecwe-mega-rail-row {
  color: var(--copper-600);
}
.ecwe-mega-sector:focus-within .ecwe-mega-rail-row {
  color: var(--copper-600);
}
.ecwe-mega-sector:hover .ecwe-mega-arrow {
  opacity: 1;
}
.ecwe-mega-sector:focus-within .ecwe-mega-arrow {
  opacity: 1;
}

/* class ecwe-mega-rail-row [base] */
@media (max-width: 991px) {
  .ecwe-mega-rail-row {
    font-weight: 400 !important;
    color: var(--ink-700) !important;
    padding: 13px 24px !important;
    border-bottom: 1px solid var(--border-hairline);
  }
}

/* class ecwe-mega-panel [base] */
@media (max-width: 991px) {
  .ecwe-mega-panel {
    display: none !important;
  }
}
.ecwe-mega-panel {
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}

/* class ecwe-mega-subgroup-title [base]
   Qualified with .brxe-text-link: this file loads before the Bricks inline
   CSS, so the rule must outrank the control rule instead of relying on
   source order the way the old in-database block did. */
.ecwe-mega-subgroup-title.brxe-text-link:first-child {
  margin-top: 0;
}

/* class ecwe-mega-feature-col [base] */
@media (max-width: 991px) {
  .ecwe-mega-feature-col {
    display: none !important;
  }
}

/* class ecwe-mega-cat-link [base] */
@media (max-width: 991px) {
  .ecwe-mega-cat-link {
    display: block;
    font-family: "Neue Haas Grotesk Text";
    font-weight: 400 !important;
    font-size: 15px;
    color: var(--ink-700) !important;
    padding: 13px 24px !important;
    border-bottom: 1px solid var(--border-hairline);
  }
  /* Certification category links also carry ecwe-mega-subgroup-title, whose
     desktop margins (20px/11px) and 12px font-size would gap and shrink the
     stacked drawer rows; the drawer list item also passes down a 60px
     line-height. Triple class qualifier so this outranks the compiled class
     rule (this file loads before the Bricks inline CSS). */
  .ecwe-mega-subgroup-title.ecwe-mega-cat-link.brxe-text-link {
    margin: 0;
    font-size: 15px;
    line-height: 1.5;
    letter-spacing: 0;
  }
}

/* class ecwe-pmega-rail [base] */
@media (min-width: 992px) {
  .brx-has-megamenu.open .ecwe-pmega-sector:hover::after,
  .brx-has-megamenu.open .ecwe-pmega-sector:focus-within::after {
    content: "";
    position: absolute;
    top: 40px;
    bottom: 40px;
    left: 264px;
    width: 92px;
  }
}
@media (min-width: 992px) {
  .brx-has-megamenu.open
    .ecwe-pmega-rail:not(:hover):not(:focus-within)
    .ecwe-pmega-sector:first-child
    .ecwe-pmega-panel {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition:
      opacity 0s linear 0s,
      visibility 0s linear 0s;
  }
}
@media (min-width: 992px) {
  .ecwe-pmega-rail:not(:hover):not(:focus-within)
    .ecwe-pmega-sector:first-child
    .ecwe-pmega-rail-row {
    color: var(--copper-600);
  }
}
@media (min-width: 992px) {
  .ecwe-pmega-rail:not(:hover):not(:focus-within)
    .ecwe-pmega-sector:first-child
    .ecwe-pmega-arrow {
    opacity: 1;
  }
}
@media (min-width: 992px) {
  .brx-has-megamenu.open .ecwe-pmega-sector:hover .ecwe-pmega-panel,
  .brx-has-megamenu.open .ecwe-pmega-sector:focus-within .ecwe-pmega-panel {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition:
      opacity 0.16s var(--ease-standard) 0.04s,
      visibility 0s linear 0s;
  }
}
@media (min-width: 992px) {
  .ecwe-pmega-sector:hover .ecwe-pmega-rail-row,
  .ecwe-pmega-sector:focus-within .ecwe-pmega-rail-row {
    color: var(--copper-600);
  }
}
@media (min-width: 992px) {
  .ecwe-pmega-sector:hover .ecwe-pmega-arrow,
  .ecwe-pmega-sector:focus-within .ecwe-pmega-arrow {
    opacity: 1;
  }
}

/* class ecwe-pmega-panel [base] */
.ecwe-pmega-panel {
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
  position: absolute;
  top: 20px;
  right: 396px;
  bottom: 40px;
  left: 356px;
  visibility: hidden;
  overflow: auto;
  opacity: 0;
  pointer-events: none;
  transition:
    opacity 0s linear 0s,
    visibility 0s linear 0s;
}

/* class ecwe-meta [base] */
.ecwe-meta {
  font-variant-numeric: tabular-nums lining-nums;
  font-family: "IBM Plex Mono";
  font-size: 12px;
  line-height: 1.4;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-500);
}

/* class ecwe-register__desc [base] */
.ecwe-register__desc {
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

/* ====================================================================
   COMPONENT VARIANTS (formerly component root _cssCustom)
   ==================================================================== */

/* component f06ef1 (f06ef1) element f06ef1 [_cssCustom] */
.brxe-f06ef1[data-brx-variant="copper"] .brxe-f2c6ed {
  filter: none;
}

/* component bffbb6 (bffbb6) element bffbb6 [_cssCustom] */
.brxe-bffbb6[data-brx-variant="no-dropcap"]
  .brxe-9dd080
  p:first-of-type::first-letter {
  float: none;
  font-family: inherit;
  font-weight: inherit;
  font-size: inherit;
  line-height: inherit;
  color: inherit;
  padding: 0px;
}

/* component d6543a (d6543a) element d6543a [_cssCustom] */
.brxe-d6543a[data-brx-variant="registry"] {
  background: var(--ivory-deep);
}
.brxe-d6543a[data-brx-variant="registry"] .brxe-0afc2c {
  margin-bottom: 28px;
}
.brxe-d6543a[data-brx-variant="registry"] .brxe-fd5d99 {
  font-style: italic;
  font-size: clamp(20px, 2.1vw, 23px);
  margin-bottom: 28px;
}

/* component 680a64 (680a64) element 680a64 [_cssCustom] */
.brxe-680a64[data-brx-variant="compact"] .brxe-c922bf {
  font-size: clamp(34px, 4.4vw, 52px);
  margin-bottom: 28px;
}
.brxe-680a64[data-brx-variant="compact"] .brxe-fd7c70 {
  margin-bottom: 0px;
}
/* Desktop only: below 992px the grid element's own control stacks the
   two columns (1fr). Without this media query the variant rule won at
   every width and kept /awards/ in two narrow columns on phones. */
@media (min-width: 992px) {
  .brxe-680a64[data-brx-variant="compact"] .brxe-d3b777 {
    grid-template-columns: 1.12fr 0.88fr;
  }
}

/* component 09e11a (09e11a) element 09e11a [_cssCustom] */
.brxe-09e11a[data-brx-variant="protocols"] .brxe-113d41 {
  font-size: clamp(18px, 2vw, 20px);
}
.brxe-09e11a[data-brx-variant="protocols"] .brxe-904c8a {
  color: #f4efe6;
  border-color: var(--obsidian);
  background: var(--obsidian);
}
.brxe-09e11a[data-brx-variant="protocols"] .brxe-904c8a:hover {
  background: #000;
}
.brxe-09e11a[data-brx-variant="protocols"] .brxe-0d8fb0 {
  color: var(--copper-700);
  border-color: var(--copper-500);
  background: transparent;
}
.brxe-09e11a[data-brx-variant="protocols"] .brxe-0d8fb0:hover {
  color: #fff;
  border-color: var(--copper-500);
  background: var(--copper-500);
}
.brxe-09e11a[data-brx-variant="certifications"] .brxe-b53515 {
  font-size: clamp(44px, 6vw, 84px);
}
.brxe-09e11a[data-brx-variant="awards"] .brxe-b53515 {
  font-size: clamp(46px, 6.2vw, 86px);
}
.brxe-09e11a[data-brx-variant="awards"] .brxe-113d41 {
  max-width: 580px;
}
.brxe-09e11a[data-brx-variant="contact"] {
  padding-bottom: clamp(56px, 7vw, 88px);
}
.brxe-09e11a[data-brx-variant="contact"] .brxe-4c1735 {
  display: none;
}
.brxe-09e11a[data-brx-variant="contact"] .brxe-0d5023 {
  display: none;
}
.brxe-09e11a[data-brx-variant="contact"] .brxe-f5df9f {
  display: block;
  padding-bottom: clamp(56px, 7vw, 88px);
}
.brxe-09e11a[data-brx-variant="contact"] .brxe-5217e1 {
  max-width: 860px;
}
.brxe-09e11a[data-brx-variant="contact"] .brxe-b53515 {
  font-size: clamp(46px, 6.4vw, 92px);
}
.brxe-09e11a[data-brx-variant="contact"] .brxe-113d41 {
  font-size: clamp(20px, 2.2vw, 25px);
  max-width: 680px;
}
/* Mobile pass 2026-09-25: the contact variant hides the buttons, so on tablet and phone
   the lede margin and the grid padding only added empty space (about 150px) above the form. */
@media (max-width: 991px) {
  .brxe-09e11a[data-brx-variant="contact"] .brxe-f5df9f {
    padding-bottom: 0;
  }
  .brxe-09e11a[data-brx-variant="contact"] .brxe-113d41 {
    margin-bottom: 0;
  }
}
@media (max-width: 478px) {
  .brxe-09e11a[data-brx-variant="contact"] .brxe-113d41 {
    font-size: 18px;
  }
}

/* component 695362 (695362) element 695362 [_cssCustom] */
.brxe-695362[data-brx-variant="methodology"] {
  background: var(--ivory-deep);
}
@media (min-width: 992px) {
  .brxe-695362[data-brx-variant="methodology"] .brxe-c6777a {
    grid-template-columns: 0.92fr 1.08fr;
  }
}
.brxe-695362[data-brx-variant="methodology"] .brxe-bbc4a6 {
  order: 1;
  height: clamp(360px, 38vw, 520px);
}
.brxe-695362[data-brx-variant="methodology"] .brxe-c86d2f {
  order: 2;
}

/* component 452866 (452866) element 452866 [_cssCustom] */
.brxe-452866[data-brx-variant="protocols"] {
  background: #ffffff;
}
.brxe-452866[data-brx-variant="certifications"] .brxe-f0b2a2 {
  border-bottom-color: var(--border-strong);
}
.brxe-452866[data-brx-variant="certifications"] .brxe-5a7d67 {
  border-bottom-color: var(--border-strong);
}
.brxe-452866[data-brx-variant="certifications"] .brxe-38c53a {
  border-bottom-color: var(--border-strong);
}
.brxe-452866[data-brx-variant="certifications"] .brxe-11b238 {
  border-bottom-color: var(--border-strong);
}
.brxe-452866[data-brx-variant="certifications"] .brxe-58fb29 {
  border-bottom-color: var(--border-strong);
}
.brxe-452866[data-brx-variant="certifications"] .brxe-fbe26a {
  border-bottom-color: var(--border-strong);
}
.brxe-452866[data-brx-variant="awards"] .brxe-f0b2a2 {
  grid-template-columns: 56px minmax(0, 1fr) 28px;
  align-items: baseline;
  padding-top: clamp(24px, 2.6vw, 34px);
  padding-bottom: clamp(24px, 2.6vw, 34px);
  border-bottom-color: var(--border-strong);
}
.brxe-452866[data-brx-variant="awards"] .brxe-5a7d67 {
  grid-template-columns: 56px minmax(0, 1fr) 28px;
  align-items: baseline;
  padding-top: clamp(24px, 2.6vw, 34px);
  padding-bottom: clamp(24px, 2.6vw, 34px);
  border-bottom-color: var(--border-strong);
}
.brxe-452866[data-brx-variant="awards"] .brxe-38c53a {
  grid-template-columns: 56px minmax(0, 1fr) 28px;
  align-items: baseline;
  padding-top: clamp(24px, 2.6vw, 34px);
  padding-bottom: clamp(24px, 2.6vw, 34px);
  border-bottom-color: var(--border-strong);
}
.brxe-452866[data-brx-variant="awards"] .brxe-11b238 {
  grid-template-columns: 56px minmax(0, 1fr) 28px;
  align-items: baseline;
  padding-top: clamp(24px, 2.6vw, 34px);
  padding-bottom: clamp(24px, 2.6vw, 34px);
  border-bottom-color: var(--border-strong);
}
.brxe-452866[data-brx-variant="awards"] .brxe-58fb29 {
  grid-template-columns: 56px minmax(0, 1fr) 28px;
  align-items: baseline;
  padding-top: clamp(24px, 2.6vw, 34px);
  padding-bottom: clamp(24px, 2.6vw, 34px);
  border-bottom-color: var(--border-strong);
}
.brxe-452866[data-brx-variant="awards"] .brxe-fbe26a {
  grid-template-columns: 56px minmax(0, 1fr) 28px;
  align-items: baseline;
  padding-top: clamp(24px, 2.6vw, 34px);
  padding-bottom: clamp(24px, 2.6vw, 34px);
  border-bottom-color: var(--border-strong);
}
/* Phones: same two-column row as the other variants (number and chevron
   on the first row, title below). The rules above would otherwise keep
   the desktop three columns at every width. */
@media (max-width: 767px) {
  .brxe-452866[data-brx-variant="awards"] .brxe-f0b2a2,
  .brxe-452866[data-brx-variant="awards"] .brxe-5a7d67,
  .brxe-452866[data-brx-variant="awards"] .brxe-38c53a,
  .brxe-452866[data-brx-variant="awards"] .brxe-11b238,
  .brxe-452866[data-brx-variant="awards"] .brxe-58fb29,
  .brxe-452866[data-brx-variant="awards"] .brxe-fbe26a {
    grid-template-columns: minmax(0, 1fr) 24px;
    align-items: start;
  }
}
.brxe-452866[data-brx-variant="awards"] .brxe-f0f820 {
  font-size: clamp(24px, 2.6vw, 32px);
  line-height: 1.04;
}
.brxe-452866[data-brx-variant="awards"] .brxe-19adda {
  font-size: clamp(24px, 2.6vw, 32px);
  line-height: 1.04;
}
.brxe-452866[data-brx-variant="awards"] .brxe-07f483 {
  font-size: clamp(24px, 2.6vw, 32px);
  line-height: 1.04;
}
.brxe-452866[data-brx-variant="awards"] .brxe-48bfd1 {
  font-size: clamp(24px, 2.6vw, 32px);
  line-height: 1.04;
}
.brxe-452866[data-brx-variant="awards"] .brxe-314231 {
  font-size: clamp(24px, 2.6vw, 32px);
  line-height: 1.04;
}
.brxe-452866[data-brx-variant="awards"] .brxe-78dfd2 {
  font-size: clamp(24px, 2.6vw, 32px);
  line-height: 1.04;
}
.brxe-452866[data-brx-variant="awards"] .brxe-aaeb3f {
  max-width: 880px;
}
.brxe-452866[data-brx-variant="awards"] .brxe-7e813b {
  border-top: 1px solid var(--border-strong);
}

/* component 18d508 (18d508) element 18d508 [_cssCustom] */
.brxe-18d508[data-brx-variant="dark-credit-top"] .brxe-911114 {
  margin-bottom: 0px;
}
.brxe-18d508[data-brx-variant="dark-credit-top"] .brxe-5957a5 {
  order: 1;
  margin-top: 0px;
  margin-bottom: 50px;
  letter-spacing: 0.02em;
}
.brxe-18d508[data-brx-variant="white"] {
  background: #ffffff;
  border-top: 1px solid var(--border-hairline);
}
.brxe-18d508[data-brx-variant="white"] .brxe-911114 {
  color: var(--ink-900);
}
.brxe-18d508[data-brx-variant="white"] .brxe-5957a5 {
  color: var(--copper-600);
}

/* component 1fc8aa (1fc8aa) element 1fc8aa [_cssCustom] */
.brxe-1fc8aa[data-brx-variant="dark"] {
  background: var(--obsidian);
  border-top: none;
}
.brxe-1fc8aa[data-brx-variant="dark"] .brxe-396ded {
  color: var(--copper-300);
}
.brxe-1fc8aa[data-brx-variant="dark"] .brxe-24b2ae {
  color: var(--text-on-dark);
}
.brxe-1fc8aa[data-brx-variant="dark"] .brxe-a4b720 {
  color: var(--copper-300);
}

/* ====================================================================
   PAGE / TEMPLATE ELEMENTS (formerly element _cssCustom)
   ==================================================================== */

/* Contact page (26) element ilg9e6 (form): the "Other purpose" field shows
   only while the Purpose select is on "Other". Bricks randomizes form input
   DOM ids on every render, so the stable name attributes are the hooks. */
#brxe-ilg9e6 .form-group:has(input[name="form-field-nqothr"]) {
  display: none;
}
#brxe-ilg9e6:has(select[name="form-field-nqpurp"] option[value="Other"]:checked)
  .form-group:has(input[name="form-field-nqothr"]) {
  display: flex;
}

/* Contact page (26): keep the form clear of the header when the
   /contact/#purpose-<key> deep links scroll to it. */
#enquiry {
  scroll-margin-top: 120px;
}

/* Header template (36) element 7s2spr (nav-menu) [_cssCustom:tablet_portrait] */
@media (max-width: 991px) {
  #brxe-7s2spr .bricks-mobile-menu > li > .brx-submenu-toggle,
  #brxe-7s2spr .bricks-mobile-menu > li > .brx-submenu-toggle svg,
  #brxe-7s2spr .bricks-mobile-menu > li > .brx-submenu-toggle * {
    color: var(--ink-900);
  }
}

/* Header template (36) element 7s2spr (nav-menu) [_cssCustom] */
#brxe-7s2spr .bricks-nav-menu {
  gap: 25px;
  align-items: center;
}
#brxe-7s2spr .bricks-nav-menu > li {
  margin-left: 0px;
}
#brxe-7s2spr .bricks-nav-menu > li > a {
  gap: 6px;
}
#brxe-7s2spr .bricks-nav-menu > li > .brx-submenu-toggle {
  gap: 6px;
}
#brxe-7s2spr .bricks-nav-menu > .brx-has-megamenu > .brx-megamenu {
  top: calc(45px + 50% + 1px);
}
#brxe-7s2spr .bricks-nav-menu .current-menu-item > a {
  border-bottom-width: 1.5px;
  color: var(--ink-900);
}
#brxe-7s2spr .bricks-nav-menu .current-menu-item > .brx-submenu-toggle {
  border-bottom-width: 1.5px;
}
#brxe-7s2spr .bricks-nav-menu > .current-menu-parent > a {
  border-bottom-width: 1.5px;
  color: var(--ink-900);
}
#brxe-7s2spr .bricks-nav-menu > .current-menu-parent > .brx-submenu-toggle {
  border-bottom-width: 1.5px;
}
#brxe-7s2spr .bricks-nav-menu > .current-menu-ancestor > a {
  border-bottom-width: 1.5px;
  color: var(--ink-900);
}
#brxe-7s2spr .bricks-nav-menu > .current-menu-ancestor > .brx-submenu-toggle {
  border-bottom-width: 1.5px;
}
#brxe-7s2spr .bricks-nav-menu .current-menu-item > .brx-submenu-toggle > * {
  color: var(--ink-900);
}
#brxe-7s2spr .bricks-nav-menu > .current-menu-parent > .brx-submenu-toggle > * {
  color: var(--ink-900);
}
#brxe-7s2spr
  .bricks-nav-menu
  > .current-menu-ancestor
  > .brx-submenu-toggle
  > * {
  color: var(--ink-900);
}

/* Mega Menu Awards template (394) element awfeat (div) [_cssCustom] */
#brxe-awfeat:hover .brxe-awfhd0 {
  color: var(--copper-700);
}
#brxe-awfeat:hover .brxe-awflnk {
  color: var(--copper-500);
}

/* Mega Menu Awards template (394) element awcats (div) [_cssCustom] */
#brxe-awcats .brxe-awclst:first-of-type {
  border-top: 1px solid var(--border-hairline);
}
#brxe-awcats .brxe-awclst:hover .brxe-awcnam {
  color: var(--copper-600);
}

/* ====================================================================
   THEME STYLE (formerly ECWE Base customCss)
   ==================================================================== */

/* theme style ECWE Base (654097) general.customCss */
/* TRIAL-FONT WORKAROUND (remove when licensed Canela files arrive):
   the Canela / Canela Deck TRIAL OTFs ship without an ampersand glyph, so '&' fell back
   to the browser default serif (Times) mid-heading. These unicode-range faces serve U+26
   from the closest local serif instead. Exact weights per face: Chromium prefers an exact
   font-weight match over a range face, so a single 300-700 range declaration loses. */
@font-face {
  font-family: "Canela";
  src: local("IowanOldStyle-Roman"), local("Georgia");
  font-weight: 300;
  unicode-range: U+26;
}
@font-face {
  font-family: "Canela";
  src: local("IowanOldStyle-Roman"), local("Georgia");
  font-weight: 400;
  unicode-range: U+26;
}
@font-face {
  font-family: "Canela";
  src: local("IowanOldStyle-Roman"), local("Georgia");
  font-weight: 500;
  unicode-range: U+26;
}
@font-face {
  font-family: "Canela";
  src: local("IowanOldStyle-Roman"), local("Georgia");
  font-weight: 600;
  unicode-range: U+26;
}
@font-face {
  font-family: "Canela";
  src: local("IowanOldStyle-Roman"), local("Georgia");
  font-weight: 700;
  unicode-range: U+26;
}
@font-face {
  font-family: "Canela Deck";
  src: local("IowanOldStyle-Roman"), local("Georgia");
  font-weight: 300;
  unicode-range: U+26;
}
@font-face {
  font-family: "Canela Deck";
  src: local("IowanOldStyle-Roman"), local("Georgia");
  font-weight: 400;
  unicode-range: U+26;
}
@font-face {
  font-family: "Canela Deck";
  src: local("IowanOldStyle-Roman"), local("Georgia");
  font-weight: 500;
  unicode-range: U+26;
}
@font-face {
  font-family: "Canela Deck";
  src: local("IowanOldStyle-Roman"), local("Georgia");
  font-weight: 600;
  unicode-range: U+26;
}
@font-face {
  font-family: "Canela Deck";
  src: local("IowanOldStyle-Roman"), local("Georgia");
  font-weight: 700;
  unicode-range: U+26;
}
/* Same trial-font gap for Neue Haas Grotesk Text (the sans, used by .ecwe-mega-panel-eyebrow).
   Patch U+26 with a local SANS ampersand so it matches the sans run, not a serif Times. */
@font-face {
  font-family: "Neue Haas Grotesk Text";
  src: local("Helvetica Neue"), local("Arial");
  font-weight: 400;
  unicode-range: U+26;
}
@font-face {
  font-family: "Neue Haas Grotesk Text";
  src: local("Helvetica Neue"), local("Arial");
  font-weight: 500;
  unicode-range: U+26;
}
@font-face {
  font-family: "Neue Haas Grotesk Text";
  src: local("Helvetica Neue"), local("Arial");
  font-weight: 600;
  unicode-range: U+26;
}
@font-face {
  font-family: "Neue Haas Grotesk Text";
  src: local("Helvetica Neue"), local("Arial");
  font-weight: 700;
  unicode-range: U+26;
}

/* ====================================================================
   SITE-WIDE (formerly Bricks Settings > Custom CSS)
   ==================================================================== */

/* Bricks Settings > Custom code > Custom CSS (site-wide) */
.brxe-post-navigation {
  display: grid !important;
  width: 100% !important;
  gap: 20px !important;
}

/* Previous / next side by side from tablet up. On phones the grid keeps
   its single implicit column, so the two links stack at full width. */
@media (min-width: 768px) {
  .brxe-post-navigation {
    grid-template-columns: 1fr 1fr !important;
  }
}
@media (max-width: 767px) {
  .brxe-post-navigation {
    row-gap: 40px !important;
  }
}

.brxe-post-navigation > a {
  width: 100% !important;
  display: flex !important;
  flex-direction: column;
  justify-content: flex-start !important;
  align-items: flex-start !important;
  margin: 0 !important;
}

.brxe-post-navigation .content {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: 10px;
  order: 0;
}

.brxe-post-navigation .image {
  margin-top: 5px !important;
  order: 1;
  margin-bottom: 20px;
}

.ecwe-entry__seq.brxe-div a {
  max-width: none !important;
}

.ecwe-entry__body .ecwe-note {
  display: none !important;
}

.prev-post.hide {
  display: none !important;
}

.image {
  object-fit: cover !important;
}

/* ====================================================================
   SITE SEARCH POPUP (template 660)
   Overlay placement, backdrop and input focus: not expressible via
   Bricks controls (popup wrapper and inner input pseudo-state).
   ==================================================================== */

/* Both the popup wrapper and its content div are column flexboxes, so
   align-items is the horizontal axis and justify-content the vertical. */
.brx-popup[data-popup-id="660"] {
  align-items: center;
  justify-content: flex-start;
}

/* One dimming layer only: the Bricks backdrop, warm and slightly blurred. */
.brx-popup[data-popup-id="660"] .brx-popup-backdrop {
  background-color: rgba(21, 18, 13, 0.42);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

/* Open / close. Bricks shows and hides the popup by toggling .hide
   (opacity + visibility, no display change), so it can be transitioned:
   the overlay fades, the search panel drops in and settles. Closing is
   quicker than opening. */
.brx-popup[data-popup-id="660"] {
  transition:
    opacity 0.3s var(--ease-standard),
    visibility 0s linear 0s;
}
.brx-popup[data-popup-id="660"].hide {
  transition:
    opacity 0.22s var(--ease-exit),
    visibility 0s linear 0.22s;
}
.brx-popup[data-popup-id="660"] .ecwe-search {
  transition:
    transform 0.55s var(--ease-entrance),
    opacity 0.35s var(--ease-standard);
}
.brx-popup[data-popup-id="660"].hide .ecwe-search {
  transform: translateY(-16px);
  opacity: 0;
  transition-duration: 0.22s;
}
@media (prefers-reduced-motion: reduce) {
  .brx-popup[data-popup-id="660"] .ecwe-search,
  .brx-popup[data-popup-id="660"].hide .ecwe-search {
    transform: none;
  }
}

/* Magnifier inside the input (image longhands only, so the class
   control's background colour is untouched). */
.ecwe-search__input.brxe-filter-search input {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239C9484' stroke-width='1.6' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cline x1='15.5' y1='15.5' x2='20' y2='20'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left 2px center;
  background-size: 22px 22px;
}

/* Quick links show only while the field is empty. */
.brx-popup[data-popup-id="660"]:has(.ecwe-search__input input:not(:placeholder-shown)) #brxe-srchql {
  display: none;
}

/* "No matches" message (the loop's no-results text). */
.brx-popup[data-popup-id="660"] .bricks-posts-nothing-found {
  padding: 22px 0;
  font-family: "Neue Haas Grotesk Text";
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-500);
}
.brx-popup[data-popup-id="660"] .bricks-posts-nothing-found a {
  color: var(--copper-600);
  text-decoration: underline;
}


/* The popup content wrapper renders as .brx-popup-content.brxe-container,
   so it inherits the 1320px container width from the theme style and the
   white background + 30px padding from the Bricks popup defaults. Reset
   all three so only the ecwe-search card is visible. */
.brx-popup[data-popup-id="660"] .brx-popup-content {
  margin-top: 12vh;
  align-items: center;
  width: auto;
  background: transparent;
  padding: 0;
}

.ecwe-search__input.brxe-filter-search input:focus {
  border-color: var(--copper-500);
  outline: none;
}

/* Show the results list only while the visitor has typed something.
   :placeholder-shown is true exactly when the input is empty. */
.brx-popup[data-popup-id="660"]:has(.ecwe-search__input input:placeholder-shown) .ecwe-search__results {
  display: none;
}

/* Phones: the panel fills the screen (class controls), so the content
   wrapper drops its 12vh top offset. */
@media (max-width: 767px) {
  .brx-popup[data-popup-id="660"] .brx-popup-content {
    margin-top: 0;
    width: 100%;
  }
}


/* Awards mega menu accordion (template 394, elements awcrow/awcpnl/awctgl).
   The category row is a native <button>; a Bricks click interaction toggles
   aria-expanded="true" on it. Controls hold the closed state
   (grid-template-rows: 0fr + transition); only the attribute-state rules
   live here because controls cannot express them. Selectors are qualified
   with .brxe-awclst to outrank the compiled loop rules (this file loads
   before the Bricks inline CSS). */
.brxe-awclst .brxe-awcrow[aria-expanded="true"] + .brxe-awcpnl {
  grid-template-rows: 1fr;
}
.brxe-awclst .brxe-awcrow[aria-expanded="true"] .brxe-awctgl {
  transform: rotate(45deg);
  color: var(--copper-600);
}
.brxe-awclst .brxe-awcrow:hover .brxe-awcnam.brxe-text-basic,
.brxe-awclst .brxe-awcrow[aria-expanded="true"] .brxe-awcnam.brxe-text-basic {
  color: var(--copper-600);
}

/* Certifications mega menu accordion, mobile drawer only (template 393,
   elements crtrow/crtpnl/crttgl). Same mechanism as the awards accordion
   above: the row button toggles [aria-expanded="true"] on itself via a
   native Bricks interaction; controls hold the closed state. Desktop keeps
   the original always-visible 5-column layout, so these rules live inside
   the drawer breakpoint. */
@media (max-width: 991px) {
  .brxe-2obww8 .brxe-crtrow[aria-expanded="true"] + .brxe-crtpnl {
    grid-template-rows: 1fr;
  }
  .brxe-2obww8 .brxe-crtrow[aria-expanded="true"] .brxe-crttgl {
    transform: rotate(45deg);
    color: var(--copper-600);
  }
  .brxe-2obww8 .brxe-crtrow[aria-expanded="true"] .brxe-crtnam.brxe-text-basic {
    color: var(--copper-600);
  }
}

/* Protocols mega menu accordion, mobile drawer only (template 281,
   elements prtrow/panel1/prttgl). Unlike awards and certifications this
   one REUSES the desktop panel (panel1) as the collapsible body instead of
   duplicating the sub-category and protocol loops: the panel class carries
   the mobile static/grid/0fr state, pnlwrp does the clipping, and the
   desktop rail link (rlrow1) is hidden below 992px in favour of the
   button row. Only the open state needs CSS. */
@media (max-width: 991px) {
  .brxe-sectr1 .brxe-prtrow[aria-expanded="true"] + .brxe-panel1 {
    grid-template-rows: 1fr;
  }
  .brxe-sectr1 .brxe-prtrow[aria-expanded="true"] .brxe-prttgl {
    transform: rotate(45deg);
    color: var(--copper-600);
  }
  .brxe-sectr1 .brxe-prtrow[aria-expanded="true"] .brxe-prtnam {
    color: var(--copper-600);
  }
  /* Sub-category titles declare no line-height, so inside the drawer they
     pick up the mobile menu's 60px one and the list falls apart. Same leak
     the certification category links hit above. */
  .brxe-sectr1 .ecwe-pmega-subgroup-title.brxe-text-basic {
    line-height: 1.35;
    margin-bottom: 9px;
  }
}

/* ====================================================================
   MOBILE MENU DRAWER (header 36, nav-menu 7s2spr, below 992px)
   The drawer is markup that Bricks generates around the menu, and the
   three mega templates (281, 393, 394) render inside it with their
   desktop classes. These rules only style that drawer context, so they
   are scoped to #brxe-7s2spr .bricks-mobile-menu. The id also outranks
   the desktop class and element controls without !important.
   Top-level item spacing and type are the nav-menu's own controls.

   One hierarchy for all three submenus:
   level 2  category rows      sans 15.5px, medium, hairline dividers
   level 3  sub-category title mono 10.5px, uppercase, muted
   level 4  entries            sans 14.5px, indented behind a thin rule
   links    "All ..." / index  copper, small uppercase
   ==================================================================== */
@media (max-width: 991px) {
  /* Open parent: copper label, chevron turned. */
  #brxe-7s2spr .bricks-mobile-menu > li.open > .brx-submenu-toggle > a {
    color: var(--copper-700);
  }
  #brxe-7s2spr .bricks-mobile-menu > li > .brx-submenu-toggle svg {
    width: 16px;
    height: 16px;
    transition: transform 0.35s var(--ease-entrance);
  }
  #brxe-7s2spr .bricks-mobile-menu > li.open > .brx-submenu-toggle svg {
    transform: rotate(180deg);
  }

  /* Submenu surface: a slightly deeper ivory panel, no desktop shadow. */
  #brxe-7s2spr .bricks-mobile-menu .brx-megamenu > .brxe-section {
    background-color: var(--ivory-deep);
    border-width: 0 0 1px;
    border-style: solid;
    border-color: var(--border-hairline);
    box-shadow: none;
  }
  #brxe-7s2spr .bricks-mobile-menu #brxe-megact,
  #brxe-7s2spr .bricks-mobile-menu #brxe-gkcsiw,
  #brxe-7s2spr .bricks-mobile-menu #brxe-awmgct {
    padding: 4px 24px 24px;
  }

  /* Bricks gives every link in the drawer a 60px line-height. Reset it
     for everything inside the submenus; each level sets its own below. */
  #brxe-7s2spr .bricks-mobile-menu .brx-megamenu a {
    line-height: 1.4;
  }

  /* Level 2: category rows. */
  #brxe-7s2spr .bricks-mobile-menu .brxe-prtrow,
  #brxe-7s2spr .bricks-mobile-menu .brxe-crtrow,
  #brxe-7s2spr .bricks-mobile-menu .brxe-awcrow {
    width: 100%;
    padding: 15px 0;
    gap: 16px;
    border-width: 0 0 1px;
    border-style: solid;
    border-color: var(--border-hairline);
  }
  #brxe-7s2spr .bricks-mobile-menu .brxe-prtnam,
  #brxe-7s2spr .bricks-mobile-menu .brxe-crtnam,
  #brxe-7s2spr .bricks-mobile-menu .brxe-awcnam {
    font-family: "Neue Haas Grotesk Text";
    font-size: 15.5px;
    font-weight: 500;
    line-height: 1.3;
    letter-spacing: 0;
    color: var(--ink-800);
    text-align: left;
  }
  /* The rows carry the dividers; the list wrappers' own borders would
     double them. */
  #brxe-7s2spr .bricks-mobile-menu .brxe-sectr1,
  #brxe-7s2spr .bricks-mobile-menu .brxe-2obww8,
  #brxe-7s2spr .bricks-mobile-menu .brxe-awclst {
    border-width: 0;
  }
  #brxe-7s2spr .bricks-mobile-menu .brxe-prttgl,
  #brxe-7s2spr .bricks-mobile-menu .brxe-crttgl,
  #brxe-7s2spr .bricks-mobile-menu .brxe-awctgl {
    font-size: 17px;
    line-height: 1;
    color: var(--ink-400);
  }
  #brxe-7s2spr .bricks-mobile-menu .brxe-prtrow[aria-expanded="true"] .brxe-prtnam,
  #brxe-7s2spr .bricks-mobile-menu .brxe-crtrow[aria-expanded="true"] .brxe-crtnam,
  #brxe-7s2spr .bricks-mobile-menu .brxe-awcrow[aria-expanded="true"] .brxe-awcnam {
    color: var(--copper-700);
  }

  /* Open category body: clipped wrappers carry no padding (padding would
     keep them from closing fully), so spacing is margins on the content. */
  #brxe-7s2spr .bricks-mobile-menu .brxe-pnlwrp {
    padding: 0;
  }
  #brxe-7s2spr .bricks-mobile-menu .brxe-chsubl:first-child,
  #brxe-7s2spr .bricks-mobile-menu .brxe-crtits:first-child,
  #brxe-7s2spr .bricks-mobile-menu .brxe-awcits:first-child {
    margin-top: 10px;
  }

  /* Level 3: sub-category titles. */
  #brxe-7s2spr .bricks-mobile-menu .ecwe-pmega-subgroup-title {
    margin: 18px 0 8px;
    font-family: "IBM Plex Mono";
    font-size: 10.5px;
    font-weight: 500;
    line-height: 1.35;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-500);
  }

  /* Level 4: entries, indented behind a thin vertical rule. */
  #brxe-7s2spr .bricks-mobile-menu .ecwe-pmega-items {
    gap: 0;
  }
  #brxe-7s2spr .bricks-mobile-menu .brxe-crtpin,
  #brxe-7s2spr .bricks-mobile-menu .brxe-awcpin {
    gap: 0;
  }
  #brxe-7s2spr .bricks-mobile-menu .brxe-crtits,
  #brxe-7s2spr .bricks-mobile-menu .brxe-awcits {
    margin: 0;
  }
  #brxe-7s2spr .bricks-mobile-menu .ecwe-pmega-items .ecwe-pmega-item,
  #brxe-7s2spr .bricks-mobile-menu .brxe-crtlnk,
  #brxe-7s2spr .bricks-mobile-menu .brxe-awclnk {
    display: block;
    padding: 7px 0 7px 16px;
    border-left: 1px solid var(--border-strong);
    font-family: "Neue Haas Grotesk Text";
    font-size: 14.5px;
    line-height: 1.4;
    color: var(--ink-600);
    text-decoration: none;
  }

  /* "All ..." links at the end of each open category. */
  #brxe-7s2spr .bricks-mobile-menu .brxe-pnlall,
  #brxe-7s2spr .bricks-mobile-menu .brxe-crtall,
  #brxe-7s2spr .bricks-mobile-menu .brxe-awcall {
    display: inline-block;
    margin: 14px 0 20px 16px;
    font-family: "Neue Haas Grotesk Text";
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--copper-600);
  }

  /* Closing "Browse ..." links under the category lists. */
  #brxe-7s2spr .bricks-mobile-menu #brxe-idxlnk,
  #brxe-7s2spr .bricks-mobile-menu #brxe-idxcrt {
    padding: 20px 0 0;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--copper-600);
  }

  /* Awards feature card: compact image, tight type, normal button. */
  #brxe-7s2spr .bricks-mobile-menu #brxe-awfeat {
    align-self: start;
    margin: 16px 0 28px;
    background-color: var(--white);
    border: 1px solid var(--border-hairline);
    border-radius: 0;
    overflow: hidden;
  }
  #brxe-7s2spr .bricks-mobile-menu #brxe-awfimg {
    width: 100%;
    height: auto;
    max-height: 240px;
    aspect-ratio: 16 / 9;
    object-fit: cover;
  }
  #brxe-7s2spr .bricks-mobile-menu #brxe-awfbod {
    height: auto;
    flex-grow: 0;
    justify-content: flex-start;
    padding: 20px 20px 22px;
    gap: 0;
  }
  #brxe-7s2spr .bricks-mobile-menu #brxe-awfhd0 {
    margin: 0 0 10px;
    font-size: 23px;
    line-height: 1.12;
  }
  #brxe-7s2spr .bricks-mobile-menu #brxe-awfhd0 a {
    line-height: inherit;
  }
  #brxe-7s2spr .bricks-mobile-menu #brxe-awfquo {
    margin: 0 0 18px;
    font-size: 14.5px;
    line-height: 1.55;
    color: var(--ink-600);
  }
  #brxe-7s2spr .bricks-mobile-menu #brxe-jyfxgv {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 14px 18px;
    font-size: 14px;
    line-height: 1.2;
  }
  #brxe-7s2spr .bricks-mobile-menu #brxe-awclab {
    margin: 0 0 4px;
  }
  #brxe-7s2spr .bricks-mobile-menu #brxe-awcfot {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding-top: 22px;
  }
  #brxe-7s2spr .bricks-mobile-menu #brxe-awcbtn {
    padding: 11px 16px;
    line-height: 1.2;
  }
}

/* Drawer open / close. Bricks slides the drawer in from the left in
   0.2s. Here it fades instead, and with motion allowed it unrolls from
   under the header (clip-path) while the items rise in one after the
   other. The open state's opacity and transform are Bricks rules with
   !important, so only other properties are animated; the closed state
   is ours. */
@media (max-width: 991px) {
  #brxe-7s2spr .bricks-mobile-menu-wrapper {
    transform: none;
    opacity: 0;
    visibility: hidden;
    transition:
      opacity 0.2s var(--ease-standard),
      visibility 0s linear 0.2s;
  }
  #brxe-7s2spr.show-mobile-menu .bricks-mobile-menu-wrapper {
    visibility: visible;
    transition:
      opacity 0.25s var(--ease-standard),
      visibility 0s linear 0s;
  }
}
@media (max-width: 991px) and (prefers-reduced-motion: no-preference) {
  #brxe-7s2spr .bricks-mobile-menu-wrapper {
    clip-path: inset(0 0 100% 0);
    transition:
      clip-path 0.42s cubic-bezier(0.7, 0, 0.84, 0),
      opacity 0.3s linear 0.12s,
      visibility 0s linear 0.42s;
  }
  #brxe-7s2spr.show-mobile-menu .bricks-mobile-menu-wrapper {
    clip-path: inset(0 0 0 0);
    transition:
      clip-path 0.7s cubic-bezier(0.16, 1, 0.3, 1),
      opacity 0.2s linear,
      visibility 0s linear 0s;
  }

  #brxe-7s2spr .bricks-mobile-menu > li {
    opacity: 0;
    transform: translateY(12px);
    transition:
      opacity 0.2s linear,
      transform 0.3s var(--ease-standard);
  }
  #brxe-7s2spr.show-mobile-menu .bricks-mobile-menu > li {
    opacity: 1;
    transform: none;
    transition:
      opacity 0.5s var(--ease-entrance),
      transform 0.7s var(--ease-entrance);
  }
  #brxe-7s2spr.show-mobile-menu .bricks-mobile-menu > li:nth-child(1) { transition-delay: 0.14s; }
  #brxe-7s2spr.show-mobile-menu .bricks-mobile-menu > li:nth-child(2) { transition-delay: 0.19s; }
  #brxe-7s2spr.show-mobile-menu .bricks-mobile-menu > li:nth-child(3) { transition-delay: 0.24s; }
  #brxe-7s2spr.show-mobile-menu .bricks-mobile-menu > li:nth-child(4) { transition-delay: 0.29s; }
  #brxe-7s2spr.show-mobile-menu .bricks-mobile-menu > li:nth-child(5) { transition-delay: 0.34s; }
  #brxe-7s2spr.show-mobile-menu .bricks-mobile-menu > li:nth-child(6) { transition-delay: 0.39s; }

  /* Hamburger to X: slower, eased bars instead of the default snap. */
  #brxe-7s2spr .bricks-mobile-menu-toggle span {
    transition:
      top 0.35s var(--ease-entrance),
      transform 0.45s var(--ease-entrance),
      opacity 0.2s linear;
  }

  /* An opened submenu settles in instead of popping. */
  #brxe-7s2spr .bricks-mobile-menu > li.open > .brx-megamenu {
    animation: ecwe-drawer-sub 0.45s var(--ease-entrance) both;
  }
}
@keyframes ecwe-drawer-sub {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
}

/* ====================================================================
   Motion (child theme modules): page transitions, image loading,
   homepage intro and scroll reveals.
   The state classes on <html> are printed by includes/page-transitions.php,
   includes/image-loading.php and includes/home-motion.php; the behavior
   lives in the matching files under assets/js/. Options: WP admin >
   Theme settings. The option-driven variables (--ecwe-pt-*,
   --ecwe-img-duration) are injected from PHP as inline CSS on this
   stylesheet's handle; every var() below carries a literal fallback.
   ==================================================================== */
/*
 * Page transitions: fade in on load, fade out behind a veil on exit.
 *
 * The ecwe-pt / ecwe-pt-spin state classes on <html> are added by an
 * inline script in includes/page-transitions.php (options live under
 * Theme settings > Page transitions), and ecwe-pt-ready / ecwe-pt-leaving
 * are then toggled by assets/js/page-transitions.js as navigation
 * happens. Nothing is hidden without JS.
 *
 * Variables (:root, injected from PHP with the option values):
 * --ecwe-pt-duration, --ecwe-pt-ease, --ecwe-pt-shift
 */

html.ecwe-pt body {
  opacity: 0;
}

html.ecwe-pt #brx-content {
  transform: translateY(var(--ecwe-pt-shift, 10px));
}

/* Entrance */
html.ecwe-pt.ecwe-pt-ready body {
  opacity: 1;
  transition: opacity var(--ecwe-pt-duration, 350ms) var(--ecwe-pt-ease, cubic-bezier(0.22, 1, 0.36, 1));
}

html.ecwe-pt.ecwe-pt-ready #brx-content {
  transform: translateY(0);
  transition: transform calc(var(--ecwe-pt-duration, 350ms) * 1.7) var(--ecwe-pt-ease, cubic-bezier(0.22, 1, 0.36, 1));
}

/*
 * Exit: a fixed veil that covers the whole page when clicking an internal
 * link (class .ecwe-pt-leaving, set by page-transitions.js).
 */
html.ecwe-pt::after {
  content: '';
  position: fixed;
  inset: 0;
  background: var(--ivory, #FDFCFA);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  z-index: 2147483100;
  transition:
    opacity var(--ecwe-pt-duration, 350ms) var(--ecwe-pt-ease, cubic-bezier(0.22, 1, 0.36, 1)),
    visibility 0s var(--ecwe-pt-duration, 350ms);
}

html.ecwe-pt.ecwe-pt-leaving::after {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity var(--ecwe-pt-duration, 350ms) var(--ecwe-pt-ease, cubic-bezier(0.22, 1, 0.36, 1));
}

/*
 * Loading indicator: a thin ring centered on the screen, above the veil.
 * The .ecwe-pt-spin class is only added when the option is active.
 * It appears with a delay: if the load is immediate, it never becomes
 * visible.
 */
html.ecwe-pt-spin::before {
  content: '';
  position: fixed;
  top: 50%;
  left: 50%;
  width: 28px;
  height: 28px;
  margin: -14px 0 0 -14px;
  border: 2px solid rgba(28, 26, 23, 0.12);
  border-top-color: var(--copper-600, #9B5A33);
  border-radius: 50%;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  z-index: 2147483101;
}

/* Outgoing page: appears once the exit fade has finished. */
html.ecwe-pt-spin.ecwe-pt-leaving::before,
/* Incoming page: appears if it takes a while to reveal; goes away with .ecwe-pt-ready. */
html.ecwe-pt-spin:not(.ecwe-pt-ready)::before {
  visibility: visible;
  animation:
    ecwe-spin-in 0.25s ease-out both,
    ecwe-spin 0.8s linear infinite;
}

html.ecwe-pt-spin.ecwe-pt-leaving::before {
  animation-delay: calc(var(--ecwe-pt-duration, 350ms) + 150ms), 0s;
}

html.ecwe-pt-spin:not(.ecwe-pt-ready)::before {
  animation-delay: 400ms, 0s;
}

@keyframes ecwe-spin {
  to { transform: rotate(360deg); }
}

@keyframes ecwe-spin-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/*
 * Image loading skeleton + entrance reveal.
 *
 * The ecwe-img / ecwe-img-skeleton state classes on <html> are added by
 * an inline script in includes/image-loading.php (options live under
 * Theme settings > Image loading), and each <img> is then marked while
 * it loads by assets/js/image-loading.js: .ecwe-img-loading while
 * loading, .ecwe-img-in once it finishes. Exclude an image or a
 * wrapper from both the skeleton and the entrance animation with a
 * data-no-skeleton attribute.
 *
 * No important flags anywhere (site-wide rule). Bricks' own lazy load
 * ships ".bricks-lazy-hidden { background-image: none }" carrying an
 * important flag, and the reference version of this module used two
 * important flags of its own to beat that rule. Without them, the
 * skeleton background stays hidden for as
 * long as an image still carries the bricks-lazy-hidden class, i.e.
 * before Bricks swaps the real src in. The shimmer below still covers
 * the actual network-loading phase after that swap, because Bricks
 * removes bricks-lazy-hidden itself the moment it sets the real src.
 */

/* Skeleton: warm neutral background with a shimmer sweeping across it.
   filter: none carries no important flag either, but two classes plus
   two type selectors is specific enough on its own to still beat
   Bricks' own dimming filter for its .wait state. */
html.ecwe-img-skeleton img.ecwe-img-loading {
  background-color: var(--ink-100, #EFE9DD);
  background-image: linear-gradient(
    100deg,
    rgba(255, 255, 255, 0) 36%,
    rgba(255, 255, 255, 0.7) 50%,
    rgba(255, 255, 255, 0) 64%
  );
  background-size: 200% 100%;
  background-position: 0 0;
  background-repeat: no-repeat;
  filter: none;
  animation: ecwe-shimmer 1.3s ease-in-out infinite;
}

@keyframes ecwe-shimmer {
  from { background-position: 120% 0; }
  to   { background-position: -80% 0; }
}

/* Entrance once loading finishes: from translucent and blurred to sharp.
   Starts at opacity 0.3, not 0, so the image slot is never fully empty. */
html.ecwe-img img.ecwe-img-in {
  animation: ecwe-img-in var(--ecwe-img-duration, 600ms) cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes ecwe-img-in {
  from {
    opacity: 0.3;
    filter: blur(10px);
  }
  to {
    opacity: 1;
    filter: blur(0);
  }
}

/*
 * Homepage motion.
 *
 * html.ecwe-home and html.ecwe-home-scroll are set on <html> by
 * includes/home-motion.php, and only ever on the front page, only when
 * the matching option is switched on, and only when the visitor's
 * system is not asking for reduced motion.
 *
 * html.ecwe-home-go (the whole page's intro) and the per-section
 * .ecwe-in class (each scroll reveal) are added only by
 * assets/js/home-motion.js, once it decides an element is ready to
 * show. If JavaScript never runs at all, nothing on the page breaks or
 * shifts beyond that: the affected elements simply stay at the opacity
 * this file gives them while waiting for those classes, which is the
 * one and only hiding effect anything here can have.
 */

/* Shared easing: modern expressive ease-out, used by every homepage motion rule. */
:root {
  --ecwe-home-ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* Initial hold: header and hero content stay invisible (opacity only, no
   transform) between first paint and the go class landing. Held on
   opacity alone so a JS failure leaves the static, laid-out page rather
   than shifted content; the 300ms safety net in the JS plus the html
   classes only ever existing when the PHP printed them keep this window
   short. */
html.ecwe-home:not(.ecwe-home-go) #brx-header,
html.ecwe-home:not(.ecwe-home-go) .ecwe-hero__eyebrow,
html.ecwe-home:not(.ecwe-home-go) .ecwe-hero__heading,
html.ecwe-home:not(.ecwe-home-go) .ecwe-hero__actions,
html.ecwe-home:not(.ecwe-home-go) .ecwe-hero__stats {
  opacity: 0;
}

/* From-only keyframes: each element animates back to its own natural
   styles rather than to a hardcoded end state, and the animation leaves
   no permanent transform behind. That matters for the header, since a
   lingering transform would give the sticky header a new containing
   block. */
@keyframes ecwe-home-fade { from { opacity: 0; } }
@keyframes ecwe-home-rise { from { opacity: 0; transform: translateY(18px); } }

/* Intro sequence: fires once .ecwe-home-go lands. "both" fill mode so a
   delayed element holds its hidden from-frame during its delay instead
   of flashing visible early. The header only fades, never rises: see
   the note on transforms above. */
html.ecwe-home.ecwe-home-go #brx-header {
  animation: ecwe-home-fade 500ms var(--ecwe-home-ease) both;
}
html.ecwe-home.ecwe-home-go .ecwe-hero__eyebrow {
  animation: ecwe-home-rise 550ms var(--ecwe-home-ease) 50ms both;
}
html.ecwe-home.ecwe-home-go .ecwe-hero__heading {
  animation: ecwe-home-rise 700ms var(--ecwe-home-ease) 120ms both;
}
html.ecwe-home.ecwe-home-go .ecwe-hero__actions {
  animation: ecwe-home-rise 600ms var(--ecwe-home-ease) 220ms both;
}
html.ecwe-home.ecwe-home-go .ecwe-hero__stats {
  animation: ecwe-home-rise 600ms var(--ecwe-home-ease) 300ms both;
}

/* Scroll reveals: every top-level homepage section after the hero fades
   and rises up the first time it scrolls into view. The pillars section
   is excluded here because it delegates to its own cards below instead
   of moving as one block. */
html.ecwe-home-scroll #brx-content > .brxe-section:not(.ecwe-hero):not(.ecwe-pillars) {
  transition: opacity 700ms var(--ecwe-home-ease), transform 900ms var(--ecwe-home-ease);
}
html.ecwe-home-scroll #brx-content > .brxe-section:not(.ecwe-hero):not(.ecwe-pillars):not(.ecwe-in) {
  opacity: 0;
  transform: translateY(22px);
}

/* Pillars stagger: the section wrapper itself never moves or fades; its
   three cards carry the reveal instead, so they animate in left to right
   rather than the whole grid arriving as one block. */
html.ecwe-home-scroll .ecwe-pillars__card {
  transition: opacity 600ms var(--ecwe-home-ease), transform 700ms var(--ecwe-home-ease);
}
html.ecwe-home-scroll .ecwe-pillars:not(.ecwe-in) .ecwe-pillars__card {
  opacity: 0;
  transform: translateY(16px);
}
html.ecwe-home-scroll .ecwe-pillars.ecwe-in .ecwe-pillars__card:nth-child(2) { transition-delay: 80ms; }
html.ecwe-home-scroll .ecwe-pillars.ecwe-in .ecwe-pillars__card:nth-child(3) { transition-delay: 160ms; }

/* ====================================================================
   INDEX PAGE (page 680) — master index accordions + type filter
   ==================================================================== */

/* class ecwe-index-nav__summary [base] */
.ecwe-index-nav__summary {
  list-style: none;
}

/* /index/ page rows on phones: the class control switches the summary grid
   to two columns (minmax(0, 1fr) 24px). Number and chevron share the first
   row, the category name spans the full width below, like the listings on
   /protocols/ and the category archives. */
@media (max-width: 767px) {
  .ecwe-index-nav__summary.brxe-div .ecwe-index-nav__name {
    grid-column: 1 / -1;
  }
  .ecwe-index-nav__summary.brxe-div .ecwe-index-nav__chevron {
    grid-row: 1;
    grid-column: 2;
  }
}

/* Index type filter: assets/js/index-filter.js toggles [hidden] on the
   per-type blocks; guard against any display rule beating the UA style. */
[data-index-type][hidden] {
  display: none;
}

/*
 * Inner pages motion.
 *
 * html.ecwe-inner and html.ecwe-inner-scroll are set on <html> by
 * includes/inner-motion.php, and only ever off the front page (the
 * homepage has its own module above), only when the matching option is
 * switched on, and only when the visitor's system is not asking for
 * reduced motion. html.ecwe-inner-go and the per-block .ecwe-in class
 * are added only by assets/js/inner-motion.js.
 *
 * The intro targets are the shared template components, so one rule set
 * covers every inner template: statement hero (archives, contact),
 * tax hero (taxonomy archives), entry (single protocols, certifications
 * and awards). Selectors that do not exist on a given page simply do
 * not apply. The /index/ page has neither component and only one
 * top-level section, so nothing here ever animates it.
 */

/* Same curve as the homepage module, declared per module so each block
   stays self-contained. */
:root {
  --ecwe-inner-ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* Initial hold: heading-zone elements stay invisible (opacity only, no
   transform) between first paint and the go class landing. */
html.ecwe-inner:not(.ecwe-inner-go) .ecwe-statement-hero__eyebrow,
html.ecwe-inner:not(.ecwe-inner-go) .ecwe-statement-hero__heading,
html.ecwe-inner:not(.ecwe-inner-go) .ecwe-statement-hero__lede,
html.ecwe-inner:not(.ecwe-inner-go) .ecwe-statement-hero__actions,
html.ecwe-inner:not(.ecwe-inner-go) .ecwe-tax-hero__crumb,
html.ecwe-inner:not(.ecwe-inner-go) .ecwe-tax-hero__heading,
html.ecwe-inner:not(.ecwe-inner-go) .ecwe-tax-hero__desc,
html.ecwe-inner:not(.ecwe-inner-go) .ecwe-entry__crumb,
html.ecwe-inner:not(.ecwe-inner-go) .ecwe-entry__title,
html.ecwe-inner:not(.ecwe-inner-go) .ecwe-entry__layout {
  opacity: 0;
}

/* From-only keyframe: each element animates back to its own natural
   styles and no transform lingers afterwards. A touch shorter and
   tighter than the homepage rise: inner pages are visited over and
   over, so the intro stays quicker and quieter. */
@keyframes ecwe-inner-rise {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}

/* Intro sequence once .ecwe-inner-go lands. Breadcrumbs and eyebrows
   lead, the heading follows, supporting content closes. "both" fill
   mode so delayed elements hold their hidden from-frame during their
   delay instead of flashing visible early. */
html.ecwe-inner.ecwe-inner-go .ecwe-statement-hero__eyebrow,
html.ecwe-inner.ecwe-inner-go .ecwe-tax-hero__crumb,
html.ecwe-inner.ecwe-inner-go .ecwe-entry__crumb {
  animation: ecwe-inner-rise 500ms var(--ecwe-inner-ease) both;
}
html.ecwe-inner.ecwe-inner-go .ecwe-statement-hero__heading,
html.ecwe-inner.ecwe-inner-go .ecwe-tax-hero__heading,
html.ecwe-inner.ecwe-inner-go .ecwe-entry__title {
  animation: ecwe-inner-rise 650ms var(--ecwe-inner-ease) 70ms both;
}
html.ecwe-inner.ecwe-inner-go .ecwe-statement-hero__lede,
html.ecwe-inner.ecwe-inner-go .ecwe-tax-hero__desc {
  animation: ecwe-inner-rise 550ms var(--ecwe-inner-ease) 150ms both;
}
html.ecwe-inner.ecwe-inner-go .ecwe-entry__layout {
  animation: ecwe-inner-rise 600ms var(--ecwe-inner-ease) 160ms both;
}
html.ecwe-inner.ecwe-inner-go .ecwe-statement-hero__actions {
  animation: ecwe-inner-rise 550ms var(--ecwe-inner-ease) 230ms both;
}

/* Scroll reveals: every top-level block after the heading zone fades and
   rises the first time it scrolls into view. Inner templates mix
   section and container wrappers at the top level, so both are covered;
   :not(:first-child) keeps the heading zone out, since it already has
   the load intro. */
html.ecwe-inner-scroll #brx-content > .brxe-section:not(:first-child),
html.ecwe-inner-scroll #brx-content > .brxe-container:not(:first-child) {
  transition: opacity 650ms var(--ecwe-inner-ease), transform 850ms var(--ecwe-inner-ease);
}
html.ecwe-inner-scroll #brx-content > .brxe-section:not(:first-child):not(.ecwe-in),
html.ecwe-inner-scroll #brx-content > .brxe-container:not(:first-child):not(.ecwe-in) {
  opacity: 0;
  transform: translateY(18px);
}
