/* ==========================================================================
   Novigen Biotech — page and section compositions
   Requires tokens.css and site.css.
   ========================================================================== */

/* ============================================================== HERO ==== */

.hero {
  position: relative;
  background: var(--c-teal);
  color: var(--c-ink-inverse);
  overflow: hidden;
}
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--pattern-lattice);
  color: var(--c-white);
  opacity: 0.05;
  pointer-events: none;
}
.hero__inner {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(var(--s-6), 4vw, var(--s-9));
  align-items: center;
  padding-block: clamp(3.5rem, 2rem + 7vw, 7.5rem);
}
.hero__headline {
  font-size: var(--t-display);
  line-height: var(--lh-tight);
  color: var(--c-white);
  max-width: 15ch;
  margin-bottom: var(--s-5);
}
.hero__standfirst {
  font-family: var(--font-serif);
  font-size: var(--t-lead);
  line-height: var(--lh-relaxed);
  color: var(--c-ink-inverse-70);
  max-width: 48ch;
  margin-bottom: var(--s-6);
}
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-bottom: var(--s-8); }

.hero__credentials {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr));
  border-top: 1px solid var(--c-line-dark);
}
.hero__credential { padding: var(--s-5) var(--s-4) 0 0; }
.hero__credential dt {
  font-size: var(--t-micro); letter-spacing: var(--track-micro);
  text-transform: uppercase; color: rgba(237,243,242,0.72);
  order: 2; margin-top: var(--s-2);
}
.hero__credential dd {
  margin: 0; order: 1;
  font-size: clamp(1.8rem, 1.3rem + 1.8vw, 2.6rem);
  font-weight: 600; line-height: 1;
  color: var(--c-amber);
  font-variant-numeric: tabular-nums;
}
.hero__credential { display: flex; flex-direction: column; }

.hero__visual { position: relative; }
.hero__figure {
  position: relative;
  border: 1px solid var(--c-line-dark);
  background: rgba(255,255,255,0.03);
  padding: var(--s-3);
}
.hero__figure .media { --ratio: 4 / 3; background: var(--c-teal-700); }
.hero__caption {
  position: absolute;
  left: var(--s-3); bottom: var(--s-3); right: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: rgba(4, 39, 39, 0.86);
  border-left: 2px solid var(--c-amber);
  font-size: var(--t-micro);
  letter-spacing: 0.02em;
  color: var(--c-ink-inverse);
}

@media (max-width: 1023px) {
  .hero__inner { grid-template-columns: minmax(0, 1fr); gap: var(--s-7); }
  .hero__headline { max-width: 18ch; }
}
@media (max-width: 559px) {
  .hero__visual { display: none; }
  .hero__actions { margin-bottom: var(--s-6); }
  .hero__actions .btn { width: 100%; }
  .hero__credentials { grid-template-columns: repeat(2, 1fr); }
}

/* Video hero ------------------------------------------------------------- */

/* One column over a full-bleed backdrop. The video never carries meaning: it is
   `aria-hidden`, untabbable, and everything readable sits above the scrim. */
.hero--video { position: relative; isolation: isolate; }

.hero--video .hero__inner {
  grid-template-columns: minmax(0, 1fr);
  align-content: center;
  min-height: min(41rem, calc(100svh - var(--header-h)));
  padding-block: clamp(4rem, 2rem + 9vw, 8rem);
}
.hero--video .hero__content { max-width: 100ch; }
.hero--video .hero__headline { max-width: 17ch; }
.hero--video .hero__standfirst { max-width: 52ch; }

.hero__backdrop {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
}
.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The poster is the first paint; the frames fade in behind it once playback starts. */
  background: var(--c-ground-dark);
}
.hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, var(--scrim-from) 0%, var(--scrim-to) 100%);
}

.hero__strapline {
  margin-top: var(--s-7);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-line);
  font-size: var(--t-small);
  color: var(--c-ink-60);
}

@media (max-width: 559px) {
  .hero--video .hero__inner { min-height: 0; }
}

/* Interior page hero ------------------------------------------------------ */

.page-hero { background: var(--c-sand); border-bottom: var(--border); }
.page-hero--dark { background: var(--c-teal); color: var(--c-ink-inverse); border-bottom: 0; }
.page-hero--dark .page-hero__title { color: var(--c-white); }
.page-hero--plain { background: var(--c-white); }

.page-hero__inner { padding-block: clamp(2.5rem, 1.6rem + 3.5vw, 4.5rem); }
.page-hero__title { font-size: var(--t-h1); margin-block: var(--s-3) var(--s-4); max-width: 20ch; }
.page-hero__lead { max-width: var(--measure-serif); }
.page-hero--feature .page-hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr);
  gap: clamp(var(--s-6), 4vw, var(--s-8));
  align-items: center;
}
/* Flip the picture to the left. `order` moves it visually without touching the DOM, so the
   heading is still the first thing read and the first thing tabbed to. */
.page-hero--media-left .page-hero__inner { grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr); }
.page-hero--media-left .page-hero__inner > *:first-child { order: 2; }
.page-hero--media-left .page-hero__inner > *:last-child { order: 1; }

@media (max-width: 767px) {
  .page-hero--feature .page-hero__inner { grid-template-columns: 1fr; }
  /* Stacked, the picture belongs under the words whichever side it takes on desktop. */
  .page-hero--media-left .page-hero__inner > *:first-child { order: 1; }
  .page-hero--media-left .page-hero__inner > *:last-child { order: 2; }
}

/* ================================================= HOMEPAGE SECTIONS ==== */

/* 02 Introduction */
.intro__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(var(--s-6), 4vw, var(--s-9));
}
@media (max-width: 767px) { .intro__grid { grid-template-columns: 1fr; } }

.intro__body p + p { margin-top: var(--s-4); }
.intro__body { font-family: var(--font-serif); font-size: var(--t-lead); line-height: var(--lh-relaxed); color: var(--c-ink-80); }

.principles { border-top: 1px solid var(--c-line-strong); }
.principle {
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr);
  gap: var(--s-4);
  padding: var(--s-5) 0;
  border-bottom: var(--border);
}
.principle__index {
  font-size: var(--t-micro); font-weight: 700; color: var(--c-accent-text);
  font-variant-numeric: tabular-nums; padding-top: 4px;
}
.principle__title { font-size: var(--t-h4); margin-bottom: var(--s-1); }
.principle__body { font-size: var(--t-small); color: var(--c-ink-60); }

/* 03 Capabilities */
.capability-list { border-top: 1px solid var(--c-line-strong); }
.capability {
  display: grid;
  grid-template-columns: 3rem minmax(0, 1.1fr) minmax(0, 1.4fr) auto;
  gap: var(--s-5);
  align-items: center;
  padding: var(--s-6) 0;
  border-bottom: var(--border);
  text-decoration: none;
  color: inherit;
  transition: background var(--dur) var(--ease-out), padding var(--dur) var(--ease-out);
}
.capability:hover { background: var(--c-sand); padding-inline: var(--s-4); color: inherit; }
.capability__index { font-size: var(--t-micro); font-weight: 700; color: var(--c-accent-text); font-variant-numeric: tabular-nums; }
.capability__title { font-size: var(--t-h3); display: flex; align-items: center; gap: var(--s-3); }
.capability__title .icon { color: var(--c-emerald); flex: 0 0 auto; }
.capability__text { font-size: var(--t-small); color: var(--c-ink-60); }
.capability__go { color: var(--c-emerald); }

@media (max-width: 1023px) {
  .capability { grid-template-columns: 2.5rem minmax(0, 1fr) auto; }
  .capability__text { grid-column: 2 / -1; }
}
@media (max-width: 559px) {
  .capability { grid-template-columns: 2rem minmax(0, 1fr); gap: var(--s-3); padding: var(--s-5) 0; }
  .capability__go { display: none; }
}

/* 04 Product showcase */
.showcase {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(min(84vw, 20rem), 1fr);
  gap: var(--s-4);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--s-4);
  scrollbar-width: thin;
}
.showcase > * { scroll-snap-align: start; }
@media (min-width: 1024px) {
  .showcase {
    grid-auto-flow: row;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    overflow: visible;
  }
}

.product-card { padding: 0; overflow: hidden; }
.product-card .media { --ratio: 4 / 3; }
.product-card__body { padding: var(--s-5); display: grid; gap: var(--s-2); }
.product-card__code {
  font-family: var(--font-mono); font-size: var(--t-micro);
  color: var(--c-ink-60); letter-spacing: 0;
}
.product-card__title { font-size: var(--t-h4); }
.product-card__title a { color: inherit; text-decoration: none; }
.product-card__title a::after { content: ""; position: absolute; inset: 0; }
.product-card__tagline { font-size: var(--t-small); color: var(--c-ink-60); }
.product-card__foot {
  margin-top: var(--s-3); padding-top: var(--s-3);
  border-top: var(--border);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  font-size: var(--t-micro); letter-spacing: var(--track-micro); text-transform: uppercase;
  color: var(--c-ink-60);
}

/* 05 Industries */
.industry-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1px; background: var(--c-line); border: var(--border); }
.industry-tile {
  background: var(--c-white);
  padding: var(--s-5);
  min-height: 12rem;
  display: flex; flex-direction: column; gap: var(--s-3);
  text-decoration: none; color: inherit;
  transition: background var(--dur) var(--ease-out);
}
.industry-tile:hover { background: var(--c-sand); color: inherit; }
.industry-tile .icon { color: var(--c-emerald); }
.industry-tile__title { font-size: var(--t-h4); }
.industry-tile__text { font-size: var(--t-small); color: var(--c-ink-60); margin-top: auto; }
@media (max-width: 1023px) { .industry-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 559px)  { .industry-grid { grid-template-columns: 1fr; } }

/* 06 Why Novigen */
.why-list { counter-reset: why; }
.why-item {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(var(--s-5), 3vw, var(--s-8));
  padding: var(--s-7) 0;
  border-bottom: 1px solid var(--c-line-dark);
}
.why-item:first-child { border-top: 1px solid var(--c-line-dark); }
.why-item__title { font-size: var(--t-h2); color: var(--c-white); display: flex; gap: var(--s-4); align-items: baseline; }
.why-item__title::before {
  counter-increment: why;
  content: counter(why, decimal-leading-zero);
  font-size: var(--t-micro);
  color: var(--c-amber);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.why-item__body { font-family: var(--font-serif); font-size: var(--t-lead); line-height: var(--lh-relaxed); color: var(--c-ink-inverse-70); }
@media (max-width: 767px) { .why-item { grid-template-columns: 1fr; gap: var(--s-4); padding: var(--s-6) 0; } }

/* 07 Scientific capability */
.capability-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-1); }
@media (max-width: 559px) { .capability-cards { grid-template-columns: 1fr; } }
.capability-card {
  border: var(--border);
  padding: var(--s-5);
  background: var(--c-white);
}
.capability-card__label { font-size: var(--t-h4); margin-bottom: var(--s-2); }
.capability-card__body { font-size: var(--t-small); color: var(--c-ink-60); }

.diagram { width: 100%; height: auto; }

/* 08 Partners */
.logo-wall {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 11rem), 1fr));
  gap: 1px;
  background: var(--c-line);
  border: var(--border);
}
.logo-wall__item {
  background: var(--c-white);
  aspect-ratio: 5 / 2;
  display: grid;
  place-items: center;
  padding: var(--s-4);
}
.logo-wall__item img { max-height: 3rem; width: auto; object-fit: contain; }
.logo-wall__placeholder {
  font-size: var(--t-micro);
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
  color: var(--c-ink-60);
  text-align: center;
}

.empty-note {
  border: 1px dashed var(--c-line-strong);
  border-radius: var(--r-2);
  padding: var(--s-6);
  text-align: center;
  color: var(--c-ink-60);
  font-size: var(--t-small);
  background: var(--c-sand);
}

/* 10 Conversion band */
.cta-band { background: var(--c-navy); color: var(--c-ink-inverse); }
.cta-band__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--s-6);
  align-items: center;
  padding-block: clamp(3rem, 2rem + 4vw, 5rem);
}
.cta-band__title { font-size: var(--t-h2); color: var(--c-white); max-width: 22ch; }
.cta-band__body { margin-top: var(--s-3); color: var(--c-ink-inverse-70); max-width: 52ch; font-size: var(--t-small); }
@media (max-width: 767px) {
  .cta-band__inner { grid-template-columns: 1fr; }
  .cta-band .btn-row .btn { width: 100%; }
}

/* ==================================================== LISTING PAGES ===== */

.listing-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s-4);
  padding-block: var(--s-5);
  border-bottom: var(--border);
  margin-bottom: var(--s-7);
}
.listing-toolbar__count { font-size: var(--t-small); color: var(--c-ink-60); }
/* A single row: search, sort, apply. The controls have to be reset to `width: auto` — form
   fields are 100% wide by default so they can fill a form column, and inside a flex row that
   makes every one of them take a line of its own, which stacked the whole toolbar. */
.listing-toolbar form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  align-items: center;
}
.listing-toolbar .input,
.listing-toolbar .select {
  width: auto;
  min-height: 44px;
  flex: 0 1 auto;
}
.listing-toolbar .input { min-width: 14rem; }
.listing-toolbar .select { min-width: 11rem; }
.listing-toolbar .btn { flex: 0 0 auto; }

/* Below the small breakpoint a row of three would be cramped, so the search takes the width
   and the sort and button share the line under it. */
@media (max-width: 559px) {
  .listing-toolbar form { width: 100%; }
  .listing-toolbar .input { flex: 1 1 100%; min-width: 0; }
  .listing-toolbar .select { flex: 1 1 auto; min-width: 0; }
}

.filter-rail { position: sticky; top: calc(var(--header-h) + var(--s-4)); }
.filter-group + .filter-group { margin-top: var(--s-6); }
.filter-group__title {
  font-size: var(--t-micro); letter-spacing: var(--track-micro); text-transform: uppercase;
  color: var(--c-ink-60); padding-bottom: var(--s-3); border-bottom: var(--border); margin-bottom: var(--s-3);
}
.filter-list li + li { margin-top: var(--s-1); }
.filter-list a {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  min-height: 40px; font-size: var(--t-small); color: var(--c-ink-80); text-decoration: none;
  border-left: 2px solid transparent; padding-left: var(--s-3);
}
.filter-list a:hover { color: var(--c-teal); border-left-color: var(--c-line-strong); }
.filter-list a[aria-current="true"] { color: var(--c-teal); font-weight: 600; border-left-color: var(--c-amber); }
.filter-list__count { color: var(--c-ink-60); font-variant-numeric: tabular-nums; font-size: var(--t-micro); }

@media (max-width: 1023px) {
  .filter-rail { position: static; margin-bottom: var(--s-6); }
  .filter-list { display: flex; flex-wrap: wrap; gap: var(--s-2); }
  .filter-list a { border: var(--border); border-radius: var(--r-1); padding-inline: var(--s-4); border-left-width: 1px; }
  .filter-list a[aria-current="true"] { background: var(--c-teal); border-color: var(--c-teal); color: var(--c-white); }
  /* The chip turns into a dark ground at this breakpoint, and the count is the one thing in it
     that does not inherit the white. `--c-ink-60` is the lightest legal grey *on white* and
     measures 3.67:1 here, so the count steps to a translucent white instead — still quieter
     than the label, and 10:1 against the chip. */
  .filter-list a[aria-current="true"] .filter-list__count { color: rgba(255, 255, 255, 0.78); }
}

.empty-state {
  padding: var(--s-9) var(--s-5);
  text-align: center;
  border: 1px dashed var(--c-line-strong);
  border-radius: var(--r-2);
}
.empty-state__title { font-size: var(--t-h3); margin-bottom: var(--s-3); }
.empty-state__text { color: var(--c-ink-60); max-width: 44ch; margin-inline: auto; }

/* ===================================================== PRODUCT DETAIL === */

.product-head {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(var(--s-6), 4vw, var(--s-8));
  align-items: start;
  padding-block: var(--s-7) var(--s-8);
}
/* `1fr` is `minmax(auto, 1fr)`, and that `auto` floor is the min-content width of the item —
   here the row of 5rem thumbnails — so the gallery refused to shrink and pushed the page 4px
   wide at 375. `minmax(0, 1fr)` removes the floor; `min-width: 0` does the same for the items
   themselves, which is what lets the thumbnail strip scroll instead of stretching its parent. */
@media (max-width: 900px) { .product-head { grid-template-columns: minmax(0, 1fr); } }
.product-head > * { min-width: 0; }

.product-gallery__main { border: var(--border); background: var(--c-white); }
.product-gallery__main .media { --ratio: 4 / 3; background: var(--c-white); }
.product-gallery__main .media img { object-fit: contain; padding: var(--s-5); }
.product-gallery__thumbs {
  display: flex; gap: var(--s-2); margin-top: var(--s-2);
  overflow-x: auto; padding-bottom: var(--s-1);
}
.product-gallery__thumb {
  flex: 0 0 5rem;
  border: var(--border);
  background: var(--c-white);
  padding: var(--s-1);
  cursor: pointer;
}
.product-gallery__thumb[aria-current="true"] { border-color: var(--c-teal); }
.product-gallery__thumb .media { --ratio: 1 / 1; background: var(--c-white); }
.product-gallery__thumb img { object-fit: contain; }

.product-meta { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; margin-bottom: var(--s-4); }
.product-title { font-size: var(--t-h1); margin-bottom: var(--s-3); }
.product-tagline { font-family: var(--font-serif); font-size: var(--t-lead); color: var(--c-ink-80); margin-bottom: var(--s-5); }
.product-code {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: var(--font-mono); font-size: var(--t-small);
  padding: var(--s-1) var(--s-3);
  background: var(--c-sand); border: var(--border); border-radius: var(--r-1);
}

.product-quickspecs { border-top: 1px solid var(--c-line-strong); margin: var(--s-6) 0; }
.product-quickspecs div {
  display: grid; grid-template-columns: 40% minmax(0, 1fr); gap: var(--s-4);
  padding: var(--s-3) 0; border-bottom: var(--border); font-size: var(--t-small);
}
.product-quickspecs dt { color: var(--c-ink-60); }
.product-quickspecs dd { margin: 0; font-weight: 500; }

.product-actions { display: grid; gap: var(--s-3); margin-top: var(--s-6); }
@media (min-width: 480px) { .product-actions { grid-template-columns: 1fr 1fr; } }

.product-body { display: grid; grid-template-columns: minmax(0, 1fr) 20rem; gap: clamp(var(--s-6), 4vw, var(--s-8)); align-items: start; }
/* No sidebar to show: the body takes the full boxed width rather than leaving a third of the
   row empty. Running text still caps at a readable measure. */
.product-body--wide { grid-template-columns: minmax(0, 1fr); }
.product-body--wide .prose { max-width: var(--measure); }
@media (max-width: 1023px) { .product-body { grid-template-columns: 1fr; } }

/* Clears the sticky header when a CTA anchor is jumped to. */
.product-sidebar__anchor { scroll-margin-top: calc(var(--header-h) + var(--s-5)); }

.product-sidebar { position: sticky; top: calc(var(--header-h) + var(--s-4)); display: grid; gap: var(--s-4); }

.feature-list li {
  position: relative;
  padding-left: var(--s-6);
  padding-block: var(--s-2);
  font-size: var(--t-small);
}
.feature-list li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.95em;
  width: var(--s-4); height: 1px;
  background: var(--c-amber);
}

/* ======================================================= ARTICLE ======== */

.article-head { padding-block: var(--s-7) var(--s-6); border-bottom: var(--border); }
.article-title { font-size: var(--t-h1); max-width: 22ch; margin-block: var(--s-3); }
.article-standfirst { max-width: var(--measure-serif); }
.article-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4);
  margin-top: var(--s-5); font-size: var(--t-small); color: var(--c-ink-60);
}
.article-meta__item { display: inline-flex; align-items: center; gap: var(--s-2); }

.article-layout {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr) 17rem;
  gap: clamp(var(--s-5), 3vw, var(--s-8));
  align-items: start;
  padding-block: var(--s-8);
}
@media (max-width: 1279px) {
  .article-layout { grid-template-columns: minmax(0, 1fr) 17rem; }
  .article-toc { grid-row: 1; grid-column: 1 / -1; position: static; }
}
@media (max-width: 1023px) {
  .article-layout { grid-template-columns: minmax(0, 1fr); }
  .article-aside { position: static; }
}

.article-toc { position: sticky; top: calc(var(--header-h) + var(--s-5)); }
.article-toc__title {
  font-size: var(--t-micro); letter-spacing: var(--track-micro); text-transform: uppercase;
  color: var(--c-ink-60); padding-bottom: var(--s-3); border-bottom: var(--border); margin-bottom: var(--s-3);
}
.article-toc a {
  display: block; padding: var(--s-2) 0 var(--s-2) var(--s-3);
  font-size: var(--t-small); color: var(--c-ink-60);
  text-decoration: none; border-left: 2px solid var(--c-line);
}
.article-toc a:hover { color: var(--c-teal); border-left-color: var(--c-line-strong); }
.article-toc a[aria-current="true"] { color: var(--c-teal); font-weight: 600; border-left-color: var(--c-amber); }
.article-toc .lvl-3 { padding-left: var(--s-5); }

.article-aside { position: sticky; top: calc(var(--header-h) + var(--s-5)); display: grid; gap: var(--s-5); }

/* Long-form prose --------------------------------------------------------- */

.prose {
  font-family: var(--font-serif);
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.2rem);
  line-height: var(--lh-relaxed);
  color: var(--c-ink-80);
  max-width: var(--measure-serif);
}
.prose > * + * { margin-top: var(--s-5); }
.prose h2 {
  font-family: var(--font-display);
  font-size: var(--t-h2);
  color: var(--c-ink);
  margin-top: var(--s-8);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-line-strong);
  scroll-margin-top: calc(var(--header-h) + var(--s-5));
}
.prose h3 {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  color: var(--c-ink);
  margin-top: var(--s-6);
  scroll-margin-top: calc(var(--header-h) + var(--s-5));
}
.prose h4 { font-family: var(--font-display); font-size: var(--t-h4); color: var(--c-ink); margin-top: var(--s-5); }
.prose strong { color: var(--c-ink); font-weight: 600; }
.prose a { color: var(--c-emerald); }
.prose ul, .prose ol { padding-left: var(--s-5); }
.prose ul li { list-style: none; position: relative; padding-left: var(--s-4); }
.prose ul li::before {
  content: ""; position: absolute; left: 0; top: 0.85em;
  width: 10px; height: 1px; background: var(--c-amber);
}
.prose ol { list-style: decimal; }
.prose ol li { padding-left: var(--s-2); }
.prose li + li { margin-top: var(--s-2); }
.prose blockquote {
  border-left: 3px solid var(--c-amber);
  padding-left: var(--s-5);
  font-style: italic;
  font-weight: 500;
  color: var(--c-ink);
  font-size: 1.08em;
}
.prose code {
  font-family: var(--font-mono); font-size: 0.88em;
  background: var(--c-sand); padding: 0.15em 0.4em; border-radius: var(--r-1);
}
.prose pre {
  background: var(--c-navy); color: var(--c-ink-inverse);
  padding: var(--s-5); border-radius: var(--r-2); overflow-x: auto;
  font-size: var(--t-small);
}
.prose pre code { background: none; padding: 0; }
.prose table { font-family: var(--font-display); font-size: var(--t-small); }
.prose th, .prose td { text-align: left; padding: var(--s-3); border-bottom: var(--border); }
.prose th { color: var(--c-ink); font-weight: 600; border-bottom-color: var(--c-line-strong); }
.prose figure { margin-block: var(--s-6); }
.prose hr { margin-block: var(--s-7); }

.prose--sans { font-family: var(--font-display); font-size: var(--t-body); max-width: var(--measure); }

/* Author card ------------------------------------------------------------- */

.author-card {
  display: flex; gap: var(--s-4); align-items: center;
  padding: var(--s-5); border: var(--border); border-radius: var(--r-2);
  background: var(--c-sand);
}
.author-card__name { font-size: var(--t-h4); }
.author-card__role { font-size: var(--t-small); color: var(--c-ink-60); }

.share-row { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }

/* ==================================================== CONTENT BLOCKS ==== */

.block { margin-block: var(--s-7); }
.block--tight { margin-block: var(--s-5); }

.block-cta {
  display: grid; gap: var(--s-4);
  padding: var(--s-6);
  background: var(--c-teal);
  color: var(--c-ink-inverse);
  border-radius: var(--r-2);
  font-family: var(--font-display);
}
.block-cta__heading { font-size: var(--t-h3); color: var(--c-white); }
.block-cta__body { font-size: var(--t-small); color: var(--c-ink-inverse-70); max-width: 52ch; }

.block-callout {
  border: var(--border);
  border-left: 3px solid var(--c-emerald);
  border-radius: var(--r-1);
  padding: var(--s-5);
  background: var(--c-white);
  font-family: var(--font-display);
  font-size: var(--t-small);
}
.block-callout--notice { border-left-color: var(--c-amber); background: var(--c-warning-bg); }
.block-callout--warning { border-left-color: var(--c-danger); background: var(--c-danger-bg); }
.block-callout__heading { font-size: var(--t-h4); margin-bottom: var(--s-2); }

.block-quote {
  border-left: 3px solid var(--c-amber);
  padding-left: var(--s-6);
  margin-block: var(--s-7);
}
.block-quote__text { font-family: var(--font-serif); font-size: var(--t-h3); font-style: italic; line-height: 1.4; color: var(--c-ink); }
.block-quote__attr { margin-top: var(--s-3); font-family: var(--font-display); font-size: var(--t-small); color: var(--c-ink-60); }

.block-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr)); gap: var(--s-5); margin-block: var(--s-7); }

.block-download {
  display: flex; align-items: center; gap: var(--s-4);
  padding: var(--s-5); border: var(--border); border-radius: var(--r-2);
  background: var(--c-sand); text-decoration: none; color: inherit;
  font-family: var(--font-display);
}
.block-download:hover { border-color: var(--c-teal); color: inherit; }
.block-download__icon { color: var(--c-emerald); flex: 0 0 auto; }
.block-download__title { font-weight: 600; }
.block-download__meta { font-size: var(--t-micro); color: var(--c-ink-60); text-transform: uppercase; letter-spacing: var(--track-micro); }

.block-newsletter {
  padding: var(--s-6);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-2);
  background: var(--c-white);
  font-family: var(--font-display);
}
.block-newsletter form { display: flex; gap: var(--s-2); margin-top: var(--s-4); flex-wrap: wrap; }
.block-newsletter .input { flex: 1 1 14rem; }

.block-related { font-family: var(--font-display); }
.block-related__title {
  font-size: var(--t-micro); letter-spacing: var(--track-micro); text-transform: uppercase;
  color: var(--c-ink-60); padding-bottom: var(--s-3); border-bottom: 1px solid var(--c-line-strong); margin-bottom: var(--s-4);
}

.video-embed { position: relative; background: var(--c-navy); }
.video-embed iframe, .video-embed video { width: 100%; aspect-ratio: 16 / 9; border: 0; display: block; }
.video-embed__transcript { margin-top: var(--s-3); }
.video-embed__transcript summary { cursor: pointer; font-size: var(--t-small); font-weight: 600; }
.video-embed__transcript div { margin-top: var(--s-3); font-size: var(--t-small); color: var(--c-ink-60); max-height: 22rem; overflow-y: auto; }

/* ======================================================== ADVERTS ======= */

.ad {
  border: 1px dashed var(--c-line-strong);
  border-radius: var(--r-2);
  padding: var(--s-5);
  background: var(--c-sand);
  font-family: var(--font-display);
}
.ad__label {
  font-size: var(--t-micro); letter-spacing: var(--track-micro); text-transform: uppercase;
  color: var(--c-ink-60); margin-bottom: var(--s-3);
  display: flex; align-items: center; gap: var(--s-2);
}
.ad__label::after { content: ""; flex: 1; height: 1px; background: var(--c-line); }
.ad__headline { font-size: var(--t-h4); margin-bottom: var(--s-2); }
.ad__body { font-size: var(--t-small); color: var(--c-ink-60); margin-bottom: var(--s-4); }
.ad--inline { margin-block: var(--s-7); }
.ad--announcement { border: 0; border-radius: 0; background: var(--c-amber); color: var(--c-navy); text-align: center; padding: var(--s-3); }

/* ======================================================== SUPPORT ======= */

.support-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-4); }
@media (max-width: 900px) { .support-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 559px) { .support-grid { grid-template-columns: 1fr; } }

.support-tile {
  display: flex; flex-direction: column; gap: var(--s-3);
  padding: var(--s-6); border: var(--border); border-radius: var(--r-2);
  background: var(--c-white); text-decoration: none; color: inherit;
  transition: border-color var(--dur) var(--ease-out);
}
.support-tile:hover { border-color: var(--c-teal); color: inherit; }
.support-tile .icon { color: var(--c-emerald); }
.support-tile__title { font-size: var(--t-h4); }
.support-tile__text { font-size: var(--t-small); color: var(--c-ink-60); }

.download-row {
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr) auto auto;
  gap: var(--s-4);
  align-items: center;
  padding: var(--s-4) 0;
  border-bottom: var(--border);
}
.download-row__icon { color: var(--c-emerald); }
.download-row__title { font-weight: 600; font-size: var(--t-small); }
.download-row__desc { font-size: var(--t-micro); color: var(--c-ink-60); text-transform: none; letter-spacing: 0; }
.download-row__meta { font-size: var(--t-micro); color: var(--c-ink-60); text-transform: uppercase; letter-spacing: var(--track-micro); }
@media (max-width: 767px) {
  .download-row { grid-template-columns: 2rem minmax(0, 1fr); gap: var(--s-3); }
  .download-row__meta { grid-column: 2; }
  .download-row__action { grid-column: 2; justify-self: start; }
}

/* ======================================================== CAREERS ======= */

.job-row {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr) auto;
  gap: var(--s-4);
  align-items: center;
  padding: var(--s-5) 0;
  border-bottom: var(--border);
  text-decoration: none; color: inherit;
  transition: background var(--dur) var(--ease-out), padding-inline var(--dur) var(--ease-out);
}
.job-row:hover { background: var(--c-sand); padding-inline: var(--s-4); color: inherit; }
.job-row__title { font-size: var(--t-h4); }
.job-row__meta { font-size: var(--t-small); color: var(--c-ink-60); }
@media (max-width: 767px) {
  .job-row { grid-template-columns: minmax(0, 1fr) auto; gap: var(--s-2); }
  .job-row__meta { grid-column: 1; }
}

.apply-panel {
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-2);
  padding: clamp(var(--s-5), 3vw, var(--s-7));
  background: var(--c-sand);
  scroll-margin-top: calc(var(--header-h) + var(--s-5));
}

.file-field {
  display: grid; gap: var(--s-2);
  padding: var(--s-5);
  border: 1px dashed var(--c-line-strong);
  border-radius: var(--r-2);
  background: var(--c-white);
  text-align: center;
}
.file-field input[type="file"] { font-size: var(--t-small); }

/* ======================================================== CONTACT ======= */

.contact-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: clamp(var(--s-6), 4vw, var(--s-9));
  align-items: start;
}
@media (max-width: 900px) { .contact-layout { grid-template-columns: 1fr; } }

.contact-block { border-top: 1px solid var(--c-line-strong); padding-top: var(--s-4); margin-bottom: var(--s-6); }
.contact-block__label { font-size: var(--t-micro); letter-spacing: var(--track-micro); text-transform: uppercase; color: var(--c-ink-60); }
.contact-block__value { font-size: var(--t-h4); margin-top: var(--s-2); }
.contact-block__value a { color: var(--c-ink); text-decoration: none; }
.contact-block__value a:hover { color: var(--c-emerald); }
.contact-block__note { font-size: var(--t-small); color: var(--c-ink-60); margin-top: var(--s-2); }

.map-frame { border: var(--border); background: var(--c-sand); }
.map-frame iframe { width: 100%; height: 22rem; border: 0; display: block; }

/* ========================================================= SEARCH ======= */

.search-hero { background: var(--c-sand); border-bottom: var(--border); padding-block: var(--s-7); }
.search-hero form { display: flex; gap: var(--s-3); max-width: 44rem; }
.search-hero .input { min-height: 56px; font-size: var(--t-lead); }

.result {
  display: grid;
  gap: var(--s-2);
  padding: var(--s-5) 0;
  border-bottom: var(--border);
}
.result__type { font-size: var(--t-micro); letter-spacing: var(--track-micro); text-transform: uppercase; color: var(--c-accent-text); font-weight: 600; }
.result__title { font-size: var(--t-h4); }
.result__title a { color: var(--c-ink); text-decoration: none; }
.result__title a:hover { color: var(--c-emerald); text-decoration: underline; }
.result__url { font-size: var(--t-micro); color: var(--c-ink-60); font-family: var(--font-mono); letter-spacing: 0; }
.result__text { font-size: var(--t-small); color: var(--c-ink-60); max-width: var(--measure); }

/* ==================================================== SECTION RAIL ====== */

.section-rail { position: sticky; top: calc(var(--header-h) + var(--s-5)); }
.section-rail__title {
  font-size: var(--t-micro); letter-spacing: var(--track-micro); text-transform: uppercase;
  color: var(--c-ink-60); padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--c-line-strong); margin-bottom: var(--s-3);
}
.section-rail a {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-2) 0;
  font-size: var(--t-small); color: var(--c-ink-60); text-decoration: none;
}
.section-rail a::before {
  content: ""; width: 12px; height: 1px; background: var(--c-line-strong); flex: 0 0 auto;
  transition: width var(--dur) var(--ease-out), background var(--dur) var(--ease-out);
}
.section-rail a:hover { color: var(--c-teal); }
.section-rail a[aria-current="true"] { color: var(--c-teal); font-weight: 600; }
.section-rail a[aria-current="true"]::before { width: 22px; background: var(--c-amber); }

@media (max-width: 1023px) {
  .section-rail { position: static; margin-bottom: var(--s-6); }
  .section-rail nav { display: flex; gap: var(--s-4); overflow-x: auto; padding-bottom: var(--s-2); }
  .section-rail a { white-space: nowrap; }
  .section-rail a::before { display: none; }
}

/* ================================================== TEAM & PEOPLE ======= */

.person {
  display: grid; gap: var(--s-3);
}
.person .media { --ratio: 3 / 4; background: var(--c-teal-050); }
.person__name { font-size: var(--t-h4); }
.person__role { font-size: var(--t-small); color: var(--c-ink-60); }
.person__quals { font-size: var(--t-micro); letter-spacing: var(--track-micro); text-transform: uppercase; color: var(--c-accent-text); }

/* ================================================== FOOTER REGIONS ====== */

/* Sits above the legal bar and provides its own rule, so the strip reads as part of the
   footer body rather than as a second legal row. `.on-media` is already in scope from the
   footer, so the tokens here are the inverted set. */
.footer-regions {
  padding-block: var(--s-6);
  border-top: 1px solid var(--c-line-dark);
}
.footer-regions__label {
  font-size: var(--t-micro);
  font-weight: var(--fw-medium);
  color: var(--c-ink-60);
  margin-bottom: var(--s-4);
}
.footer-regions__list {
  display: grid;
  /* Column counts are explicit rather than auto-fit. Auto-fit packs as many as will fit,
     which for eleven countries gave 8/3 and 7/4 — full rows, but visually lopsided. These
     counts keep every last row at most one short: 2, 3, 4, 6, then all eleven. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-3) var(--s-4);
  list-style: none;
  padding: 0;
  margin: 0;
}
@media (min-width: 560px) {
  .footer-regions__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 768px) {
  .footer-regions__list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .footer-regions__list { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}
/* One row only where all of them genuinely fit. Below this the even grid takes over and
   wraps cleanly — a row that fits by truncating a country name is not a row that fits. */
@media (min-width: 1400px) {
  .footer-regions__list {
    grid-template-columns: repeat(var(--region-count, 6), minmax(0, 1fr));
    gap: var(--s-2);
  }
  /* A smaller badge and a tighter gap buy back the width the longest country name needs, so
     nothing in the row has to truncate. */
  .footer-region { gap: 0.35rem; }
  .footer-region__flag { width: 1.25rem; height: 1.25rem; }
}
.footer-region { display: flex; align-items: center; gap: var(--s-2); min-width: 0; }
.footer-region__flag {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  flex: 0 0 auto;
  border-radius: var(--r-pill);
  overflow: hidden;
  background: rgba(255, 255, 255, 0.1);
}
.footer-region__flag img { width: 100%; height: 100%; object-fit: cover; display: block; }
.footer-region__flag abbr {
  font-size: 0.55rem;
  font-weight: var(--fw-semi);
  color: var(--c-ink-60);
  text-decoration: none;
}
/* Truncates rather than wraps: a country name breaking across two lines would throw the
   whole grid row out of alignment. */
.footer-region__name {
  font-size: var(--t-micro);
  color: var(--c-ink-60);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ================================================= PARTNER DIALOG ======= */

/* A real <dialog>: the top layer, the backdrop, focus trapping and Escape all come from the
   platform. Every trigger is still a link to the full form, so this is an enhancement over a
   working page rather than the only way through. */
.pdialog {
  width: min(34rem, calc(100vw - 2rem));
  max-height: calc(100vh - 4rem);
  padding: 0;
  border: var(--border);
  border-radius: var(--r-3);
  background: var(--c-white);
  color: var(--c-ink);
  box-shadow: var(--shadow-3);
}
.pdialog::backdrop { background: rgba(9, 12, 20, 0.55); }
.pdialog__form { padding: var(--s-6); margin: 0; }

.pdialog__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-2);
}
.pdialog__title { font-size: var(--t-h3); font-weight: var(--fw-semi); line-height: var(--lh-snug); }
.pdialog__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  flex: 0 0 auto;
  border-radius: var(--r-1);
  color: var(--c-ink-60);
}
.pdialog__close:hover { background: var(--gray-100); color: var(--c-ink); }
.pdialog__lead { font-size: var(--t-small); color: var(--c-ink-60); margin-bottom: var(--s-5); }

.pdialog__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-3);
  margin-top: var(--s-6);
  padding-top: var(--s-5);
  border-top: var(--border);
}

@media (max-width: 559px) {
  .pdialog__actions { flex-direction: column-reverse; align-items: stretch; }
  .pdialog__actions .btn { width: 100%; }
}

/* ==================================================== COOKIE NOTICE ===== */

/* Deliberately not a modal. It takes no focus on arrival and traps none — a cookie notice
   that hijacks the keyboard is a worse accessibility problem than the cookies it describes.
   It sits above the support widget so the two never overlap. */
.consent {
  position: fixed;
  left: var(--gutter);
  right: var(--gutter);
  /* Clear the support widget, which is fixed in the same corner on every page. */
  bottom: calc(var(--gutter) + 4.5rem);
  z-index: 60;
  padding: var(--s-5);
  border: var(--border);
  border-radius: var(--r-2);
  background: var(--c-white);
  box-shadow: var(--shadow-3);
}
.consent[hidden] { display: none; }

.consent__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  max-width: var(--container-max);
  margin-inline: auto;
}
.consent__text {
  margin: 0;
  min-width: 0;
  font-size: var(--t-small);
  line-height: var(--lh-relaxed);
  color: var(--c-ink-80);
}
.consent__text a { text-decoration: underline; text-underline-offset: 0.2em; }
.consent__actions { display: flex; gap: var(--s-3); flex: 0 0 auto; }

@media (max-width: 767px) {
  .consent__inner { flex-direction: column; align-items: stretch; }
  .consent__actions .btn { flex: 1 1 auto; }
}

/* ================================================ OPERATING REGIONS ===== */

.region-row {
  /* An even grid rather than a wrapping flex row: eleven chips flowed left-to-right left a
     short, ragged last line. Equal tracks keep every row the same shape. */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--s-5);
  list-style: none;
  padding: 0;
  margin: var(--s-6) 0 0;
}

/* A chip, not a card: the flag reads as a small round badge beside the country, which is how
   a market list is normally shown and keeps six of them on one line. */
.region { display: flex; align-items: center; gap: var(--s-3); }

.region__flag {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  flex: 0 0 auto;
  border-radius: var(--r-pill);
  overflow: hidden;
  background: var(--c-white);
  box-shadow: 0 0 0 1px var(--c-line);
}
/* The artwork fills the circle. `cover` rather than `contain`, because a flag is rectangular
   and letterboxing one inside a round badge leaves white wedges top and bottom. */
.region__flag img { width: 100%; height: 100%; object-fit: cover; display: block; }
.region__flag--empty { background: var(--gray-50); }
.region__flag abbr {
  font-size: var(--t-micro);
  font-weight: var(--fw-semi);
  color: var(--c-ink-60);
  text-decoration: none;
}

.region__label { display: flex; flex-direction: column; line-height: var(--lh-snug); }
.region__name { font-size: var(--t-small); font-weight: var(--fw-medium); color: var(--c-ink); }
.region__role { font-size: var(--t-micro); color: var(--c-ink-60); }

/* The country the company is actually established in is marked, so the row cannot be read as
   six equal offices. */
.region--base .region__flag { box-shadow: 0 0 0 2px var(--c-accent); }
.region--base .region__role { color: var(--c-accent); font-weight: var(--fw-medium); }

/* ================================================= PARTNER SLIDER ======= */

/* A marquee, not a carousel: no controls to operate and nothing hidden behind a step, so
   there is no keyboard trap and nothing a visitor has to click to see the rest. The mask
   fades both edges so logos enter and leave rather than being clipped. */
.logo-slider {
  --logo-slider-duration: 42s;
  display: flex;
  gap: var(--s-6);
  margin-top: var(--s-7);
  overflow: hidden;
}
.logo-slider:not(.logo-slider--animated) { flex-wrap: wrap; justify-content: center; }
.logo-slider--animated {
  mask-image: linear-gradient(90deg, transparent, #000 6rem, #000 calc(100% - 6rem), transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6rem, #000 calc(100% - 6rem), transparent);
}

.logo-slider__track {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  list-style: none;
  padding: 0;
  margin: 0;
  flex: 0 0 auto;
}
.logo-slider--animated .logo-slider__track { animation: logo-marquee var(--logo-slider-duration) linear infinite; }

/* Pause on hover and on keyboard focus, so a visitor can actually read a mark that interests
   them — and so a focused link inside the track does not slide out from under the caret. */
.logo-slider--animated:hover .logo-slider__track,
.logo-slider--animated:focus-within .logo-slider__track { animation-play-state: paused; }

.logo-slider__item {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 10rem;
  height: 4.5rem;
  padding: var(--s-4) var(--s-5);
  border: var(--border);
  border-radius: var(--r-2);
  background: var(--c-white);
  flex: 0 0 auto;
}
.logo-slider__logo { max-width: 100%; max-height: 100%; width: auto; display: block; }
.logo-slider__name {
  font-size: var(--t-small);
  font-weight: var(--fw-medium);
  color: var(--c-ink-80);
  text-align: center;
  white-space: nowrap;
}

/* Half the distance, because the track is rendered twice — one full cycle lands exactly where
   it started, which is what makes the loop seamless. */
@keyframes logo-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-100% - var(--s-6))); }
}

@media (prefers-reduced-motion: reduce) {
  .logo-slider--animated { mask-image: none; -webkit-mask-image: none; overflow-x: auto; }
  .logo-slider--animated .logo-slider__track { animation: none; }
}

/* ================================================== PARTNER GRID ======== */

/* A logo wall. Manufacturer artwork arrives in every proportion there is, so the tile is
   standardised and the logo is left alone inside it — the same reasoning as the certification
   row, and the same reason there is no plate behind it. */
.partner-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: var(--s-4);
  list-style: none;
  padding: 0;
  margin: 0;
}
.partner-tile {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 7rem;
  padding: var(--s-5);
  border: var(--border);
  border-radius: var(--r-2);
  background: var(--c-white);
}
.partner-tile__logo { max-width: 100%; max-height: 3.5rem; width: auto; display: block; }
.partner-tile__name {
  font-size: var(--t-small);
  font-weight: var(--fw-medium);
  color: var(--c-ink-80);
  text-align: center;
}

/* ================================================== PURPOSE CARDS ======= */

/* Mission and vision, side by side. They are a pair — one says what the company is for, the
   other where it is going — so they get equal weight rather than following one another down
   the page as two more headings. */
.purpose-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-5);
}
.purpose-card {
  padding: var(--s-7) var(--s-6);
  border: var(--border);
  border-radius: var(--r-2);
  background: var(--c-white);
}
.purpose-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  margin-bottom: var(--s-5);
  border-radius: var(--r-2);
  background: var(--c-accent-soft);
  color: var(--c-accent);
}
.purpose-card__title {
  font-size: var(--t-h3);
  font-weight: var(--fw-semi);
  line-height: var(--lh-snug);
  margin-bottom: var(--s-3);
}
.purpose-card__body { color: var(--c-ink-60); }
.purpose-card__body p { margin: 0; }
.purpose-card__body p + p { margin-top: var(--s-3); }

@media (max-width: 767px) {
  .purpose-grid { grid-template-columns: minmax(0, 1fr); }
}

/* On a banded page the prose is the band's content, not a column inside one, so it spans.
   Doubled class for (0,2,0): `.prose { max-width: var(--measure) }` lives in theme.css, which
   loads after this file, so a single class here would be outranked on both counts. */
.prose.prose--wide { max-width: none; }
.prose.prose--wide > :where(p, ul, ol, blockquote) { max-width: var(--measure); }

/* ================================================== FEATURE GRID ======== */

/* Built by `Prose::featureGrids()` from runs of lead-in paragraphs in CMS rich text, so these
   rules style content an editor wrote as ordinary prose. The grid lives inside `.prose` and
   inherits its measure; two across is what that measure comfortably holds. */
.feature-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-4);
  margin-block: var(--s-6);
}
.feature-card {
  padding: var(--s-5);
  border: var(--border);
  border-radius: var(--r-2);
  background: var(--c-white);
  transition: border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.feature-card:hover { border-color: var(--c-line-strong); box-shadow: var(--shadow-2); }

/* The grid lives inside `.prose`, so these must outrank `.prose h3` / `.prose p` — a bare
   `.feature-card__title` is (0,1,0) and loses to (0,1,1), leaving prose's 32px top margin
   pushing the first line off the card's padding. Repeating the block class buys (0,2,0). */
.feature-card .feature-card__title {
  margin: 0 0 var(--s-2);
  font-size: var(--t-h4);
  font-weight: var(--fw-semi);
  line-height: var(--lh-snug);
  color: var(--c-ink);
}
.feature-card .feature-card__text {
  margin: 0;
  font-size: var(--t-small);
  line-height: var(--lh-relaxed);
  color: var(--c-ink-60);
}

@media (max-width: 559px) {
  .feature-grid { grid-template-columns: minmax(0, 1fr); }
}

/* ===================================================== PLACEHOLDER ====== */

.placeholder-flag {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-micro); letter-spacing: var(--track-micro); text-transform: uppercase;
  color: var(--c-accent-text); font-weight: 600;
}

/* ======================================================== UTILITIES ===== */

.flow-tight > * + * { margin-top: var(--s-3); }
.mt-0 { margin-top: 0 !important; }
.mt-4 { margin-top: var(--s-4); }
.mt-6 { margin-top: var(--s-6); }
.mt-7 { margin-top: var(--s-7); }
.mb-0 { margin-bottom: 0 !important; }
.mb-5 { margin-bottom: var(--s-5); }
.mb-7 { margin-bottom: var(--s-7); }
.w-full { width: 100%; }
.flex { display: flex; }
.flex-between { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); }
.flex-wrap { flex-wrap: wrap; }
.gap-2 { gap: var(--s-2); }
.gap-3 { gap: var(--s-3); }
.gap-4 { gap: var(--s-4); }
.items-center { align-items: center; }

/* ================================= REFERENCE-STRUCTURE SECTIONS ========= */

/* Why Novigen — numbered feature block on a dark band */
/* Three across, then two, then one. `auto-fit` is deliberately not used: it would stretch
   a trailing row of two cards to half the width each, which reads as a different component. */
.benefit-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-5);
}
.benefit { gap: 0; }
.benefit__index {
  display: block;
  font-size: var(--t-micro);
  font-weight: 700;
  color: var(--c-accent-text);
  font-variant-numeric: tabular-nums;
  margin-bottom: var(--s-4);
}
.benefit__title { font-size: var(--t-h4); margin-bottom: var(--s-3); }
.benefit__body { font-size: var(--t-small); color: var(--c-ink-60); }

@media (max-width: 899px) {
  .benefit-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 599px) {
  .benefit-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Clinical portfolio — a tab bar over one panel of items at a time.
   Without JavaScript the tab bar stays hidden and all four groups render as headed
   lists, which is the same information in a longer column. */

.tabs-bar {
  display: flex;
  gap: var(--s-2);
  overflow-x: auto;
  scrollbar-width: thin;
  padding-bottom: var(--s-4);
  margin-bottom: var(--s-6);
  border-bottom: var(--border);
  scroll-snap-type: x proximity;
}
.tabs-bar__tab {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  flex: 0 0 auto;
  min-height: 38px;
  padding: 0 var(--s-4);
  border: 1px solid var(--c-line);
  border-radius: var(--r-pill);
  background: var(--c-white);
  color: var(--c-ink-60);
  font-size: var(--t-small);
  font-weight: 500;
  white-space: nowrap;
  scroll-snap-align: start;
  transition: background var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease-out),
              color var(--dur) var(--ease-out);
}
.tabs-bar__tab:hover { border-color: var(--c-line-strong); color: var(--c-ink); }
.tabs-bar__tab[aria-selected="true"] {
  background: var(--c-ink);
  border-color: var(--c-ink);
  color: var(--c-white);
}
.tabs-bar__count {
  font-variant-numeric: tabular-nums;
  color: var(--c-ink-60);
  font-size: var(--t-micro);
}
.tabs-bar__tab[aria-selected="true"] .tabs-bar__count { color: rgba(255, 255, 255, 0.62); }

.portfolio__group[hidden] { display: none; }

/* Once the tabs are live the panel heading is redundant — the selected tab names it,
   and the panel is bound to that tab with aria-labelledby. */
[data-tabbed] .portfolio__title { display: none; }

.portfolio__title {
  font-size: var(--t-h4);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--c-line);
  margin-bottom: var(--s-4);
}
.portfolio__group + .portfolio__group { margin-top: var(--s-7); }
[data-tabbed] .portfolio__group + .portfolio__group { margin-top: 0; }

/* Inside a panel the items spread across columns rather than running down one. */
.portfolio__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 0 var(--s-7);
}
.portfolio__list li {
  position: relative;
  padding: var(--s-3) 0 var(--s-3) var(--s-5);
  font-size: var(--t-small);
  border-bottom: var(--border);
}
.portfolio__list li::before {
  content: "";
  position: absolute;
  left: 0; top: 1.35em;
  width: var(--s-4); height: 1px;
  background: var(--c-line-strong);
}


/* For manufacturers — two action cards side by side. Each card is a whole proposition:
   a title, one short paragraph and a single button, so neither needs surrounding prose. */
.cta-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-5);
}
.cta-card { padding: var(--s-7); }
.cta-card__title { font-size: var(--t-h3); margin-bottom: var(--s-3); }
.cta-card__body { color: var(--c-ink-60); }
.cta-card__foot { margin-top: auto; padding-top: var(--s-6); }

@media (max-width: 767px) {
  .cta-cards { grid-template-columns: minmax(0, 1fr); }
  .cta-card { padding: var(--s-6); }
  .cta-card .btn { width: 100%; justify-content: center; }
}

/* ==================================================== SUPPORT WIDGET ==== */

/* A <details> pinned to the corner. The panel is anchored to the bottom-right so it grows
   upward and never pushes the launcher off screen; on narrow viewports it becomes a
   full-width sheet sitting above the sticky CTA bar. */
.support {
  position: fixed;
  right: var(--gutter);
  bottom: var(--gutter);
  z-index: var(--z-drawer);
}

.support__launcher {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 48px;
  padding: 0 var(--s-5);
  border-radius: var(--r-pill);
  /* Brand green, with a CHARCOAL label. White on this green is 2.72:1 and would be unreadable;
     charcoal on it is 4.88:1. Same pairing the accent button uses. */
  background: var(--c-accent-bright);
  color: var(--c-accent-on-bright);
  font-size: var(--t-small);
  font-weight: var(--fw-semi);
  cursor: pointer;
  list-style: none;
  user-select: none;
  box-shadow: var(--shadow-3);
  transition: background var(--dur) var(--ease-out);
}
.support__launcher::-webkit-details-marker { display: none; }
.support__launcher::marker { content: ""; }
/* Hover lifts the green rather than switching to teal — charcoal on brand teal is 2.80:1 and
   would fail on hover alone, which is exactly the kind of state that goes untested. */
.support__launcher:hover { background: #5FBC81; color: var(--c-accent-on-bright); }

/* One launcher, two glyphs: whichever matches the open state is the one shown. */
.support__launcher-icon { display: inline-flex; }
.support__launcher-icon--close,
.support[open] .support__launcher-icon--open { display: none; }
.support[open] .support__launcher-icon--close { display: inline-flex; }
.support[open] .support__launcher-label { display: none; }
.support[open] .support__launcher { padding-inline: var(--s-4); }

/* A closed <details> already hides its content, but the panel is absolutely positioned and
   that hiding is engine-specific for out-of-flow children. Stating it removes the doubt. */
.support:not([open]) .support__panel { display: none; }

.support__panel {
  position: absolute;
  right: 0;
  bottom: calc(100% + var(--s-3));
  width: min(21rem, calc(100vw - (var(--gutter) * 2)));
  padding: var(--s-5);
  background: var(--c-white);
  border: var(--border);
  border-radius: var(--r-3);
  box-shadow: var(--shadow-3);
}

.support__head { margin-bottom: var(--s-4); }
.support__title { font-size: var(--t-h4); font-weight: 500; }
.support__note { font-size: var(--t-micro); color: var(--c-ink-60); margin-top: var(--s-1); }

.support__list { list-style: none; display: grid; gap: var(--s-2); }

.support__channel {
  display: grid;
  grid-template-columns: 2.25rem minmax(0, 1fr);
  gap: var(--s-3);
  align-items: start;
  padding: var(--s-3);
  border: var(--border);
  border-radius: var(--r-2);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--dur) var(--ease-out), background var(--dur) var(--ease-out);
}
.support__channel:hover { border-color: var(--c-line-strong); background: var(--c-ground-alt); }

.support__channel-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--r-1);
  background: var(--c-accent-soft);
  color: var(--c-accent);
}
.support__channel-text { display: grid; gap: 2px; min-width: 0; }
.support__channel-label { font-size: var(--t-small); font-weight: 500; }
.support__channel-value { font-size: var(--t-small); overflow-wrap: anywhere; }
.support__channel-note { font-size: var(--t-micro); color: var(--c-ink-60); }

.support__foot {
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: var(--border);
  font-size: var(--t-micro);
  color: var(--c-ink-60);
}

/* Clear the sticky CTA bar, which owns the bottom edge below 768px. */
@media (max-width: 767px) {
  .support { right: var(--gutter); bottom: var(--gutter); }
  body:has(.sticky-bar[data-enabled]) .support { bottom: 5rem; }
  .support__panel { width: calc(100vw - (var(--gutter) * 2)); }
}

@media (prefers-reduced-motion: reduce) {
  .support__launcher, .support__channel { transition: none; }
}

/* ================================================== STATISTICS BAND ====== */

/* A gradient panel that straddles the foot of the hero: it rises into the dark surface by
   `--stats-overlap` and rests on the white section below, so it reads as one object bridging
   the two rather than a stripe belonging to either.

   The panel is the coloured surface, not the section — so the band still obeys the page's
   white → grey → tint rhythm. `position: relative` plus a z-index is what puts it over the
   hero: the hero isolates its own stacking context for the video, and without this the panel
   would slide underneath it. */
.stats-band {
  position: relative;
  z-index: 1;
  margin-top: calc(var(--stats-overlap) * -1);
  padding-top: 0;
}
.stats-band__panel {
  border-radius: var(--r-3);
  padding: var(--s-7) var(--s-6);
  background: linear-gradient(100deg, var(--stats-from) 0%, var(--stats-to) var(--stats-stop));
  box-shadow: var(--shadow-3);
}

/* The hero pays for the overlap out of its own padding, so the strapline keeps its distance
   from the panel however tall the panel gets. */
.hero--video .hero__inner { padding-bottom: calc(clamp(4rem, 2rem + 9vw, 8rem) + var(--stats-overlap)); }

/* A fixed four-column grid, not centred wrapping: equal columns are what let the hairline
   dividers land predictably, and they keep the four figures on a shared baseline however
   long the labels run. */
.stats-band .stats {
  display: grid;
  /* Follows however many figures could be established, so a band showing two does not leave
     half its width empty waiting for four. Four is the fallback for markup that omits it. */
  grid-template-columns: repeat(var(--stats-count, 4), minmax(0, 1fr));
  gap: var(--s-5) 0;
  align-items: start;
}

/* Dividers between columns, never leading a row. The nth-child rule is restated at each
   breakpoint because "not the first in its row" means something different per column count. */
.stats-band .stat + .stat { border-left: 1px solid rgba(255, 255, 255, 0.18); }

/* The credibility strip shares the statistics panel — same gradient, same overlap, same
   dividers — so the band reads identically whichever content the homepage is carrying. */
.credibility {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--s-5) 0;
  list-style: none;
  padding: 0;
  margin: 0;
}
.credibility__item { padding-inline: var(--s-5); }
.credibility__item + .credibility__item { border-left: 1px solid rgba(255, 255, 255, 0.18); }
.credibility__title {
  font-size: var(--t-small);
  font-weight: var(--fw-semi);
  color: var(--c-white);
  margin-bottom: var(--s-2);
}
.credibility__body { font-size: var(--t-small); color: var(--c-ink-60); }

@media (max-width: 1023px) {
  .credibility { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-6) 0; }
  .credibility__item:nth-child(2n + 1) { border-left: 0; }
  .credibility__item:nth-child(n + 3) { padding-top: var(--s-6); border-top: 1px solid rgba(255,255,255,0.18); }
}
@media (max-width: 559px) {
  .credibility { grid-template-columns: minmax(0, 1fr); }
  .credibility__item { border-left: 0; }
  .credibility__item + .credibility__item { padding-top: var(--s-5); border-top: 1px solid rgba(255,255,255,0.18); }
}

/* The pair is value-over-label visually; the DOM keeps <dt> first so the list stays valid. */
.stats-band .stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  text-align: center;
  padding: 0 var(--s-4);
  margin: 0;
  border-top: 0;
}
.stats-band .stat__value {
  order: 1;
  margin: 0;
  font-size: clamp(1.75rem, 1.2rem + 2.2vw, 2.5rem);
  font-weight: 700;
  color: var(--c-white);
  letter-spacing: var(--track-tight);
}
.stats-band .stat__label {
  order: 2;
  margin: var(--s-2) 0 0;
  font-size: var(--t-small);
  font-weight: 400;
  color: var(--c-ink-60);
}
.stats-band .stat__note {
  order: 3;
  margin: var(--s-1) 0 0;
  color: var(--c-ink-60);
}

/* Four across needs the room; below that it halves to 2×2, and the divider moves to match —
   the third figure now starts a row, so it must lose the border the +.stat rule gave it. */
@media (max-width: 767px) {
  .stats-band .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-6) 0; }
  .stats-band .stat:nth-child(2n + 1) { border-left: 0; }
  .stats-band .stat:nth-child(n + 3) { padding-top: var(--s-6); border-top: 1px solid rgba(255, 255, 255, 0.18); }
}

@media (max-width: 559px) {
  .stats-band__panel { padding: var(--s-6) var(--s-4); border-radius: var(--r-2); }
}

/* ===================================================== DIVISION CARDS ==== */

/* A 2×2 grid of media tiles: photograph, scrim, copy, one action. The whole tile is the
   link — the button carries the accessible name and its ::after covers the card — so there
   is exactly one target and one label per tile, not a card link plus a button link. */
.division-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-5);
}

.division-card {
  position: relative;
  isolation: isolate;
  /* Grid rather than flex so the body stretches the full card width: its gradient has to
     reach both edges, or it reads as a rectangular patch laid over the photograph. */
  display: grid;
  align-content: end;
  min-height: clamp(17rem, 14rem + 12vw, 21rem);
  border-radius: var(--r-3);
  overflow: hidden;
  background: var(--c-ground-dark);
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.division-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-3); }

.division-card__media { position: absolute; inset: 0; z-index: -2; }
.division-card__media img,
.division-card__media picture { width: 100%; height: 100%; object-fit: cover; display: block; }

/* No photograph yet: the tile falls back to the lattice the hero uses, so the grid reads as
   designed instead of as four empty boxes. The class is set in PHP rather than keyed off
   `:empty`, which browsers disagree about once the element contains whitespace. */
.division-card__media--placeholder::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--pattern-lattice);
  color: var(--c-white);
  opacity: 0.16;
}

/* An even wash over the whole tile, for depth and to stop a bright photograph fighting the
   grid. It carries no contrast duty — the body below does that. */
.division-card__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(9, 12, 20, 0.3);
}

/* The copy carries its own ground, anchored to the text rather than to a percentage of the
   card. A percentage scrim fails the moment the card grows taller than its content: at 768px
   the titles rode up into the thin end of the gradient and fell to 3.38:1. Here the solid
   band runs from the bottom to `--card-fade` short of the top edge, and `padding-top` matches
   that distance — so no glyph can sit in the fade, however tall the card gets. */
.division-card__body {
  --card-fade: 4rem;
  padding: var(--card-fade) var(--s-6) var(--s-6);
  background: linear-gradient(
    to top,
    rgba(9, 12, 20, 0.94) 0%,
    rgba(9, 12, 20, 0.94) calc(100% - var(--card-fade)),
    rgba(9, 12, 20, 0) 100%
  );
}
.division-card__title,
.division-card__text { max-width: 44ch; }
.division-card__title {
  font-size: var(--t-h3);
  font-weight: var(--fw-semi);
  color: var(--c-white);
  margin-bottom: var(--s-2);
}
.division-card__text {
  font-size: var(--t-small);
  color: var(--c-ink-60);
  margin-bottom: var(--s-5);
}
.division-card__cta::after { content: ""; position: absolute; inset: 0; }

@media (max-width: 767px) {
  .division-grid { grid-template-columns: minmax(0, 1fr); }
  .division-card { min-height: 15rem; }
  .division-card__body { --card-fade: 3rem; padding-inline: var(--s-5); padding-bottom: var(--s-5); }
}

/* ================================================ FOOTER CERTIFICATIONS == */

.footer-certs { margin-top: var(--s-6); }
.footer-certs__label {
  font-size: var(--t-micro);
  font-weight: var(--fw-medium);
  color: var(--c-ink-60);
  margin-bottom: var(--s-3);
}
.footer-certs__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  list-style: none;
  padding: 0;
  margin: 0;
}

/* The supplied frame (`certification_frame.svg`) as a background: a layered hexagon —
   light-blue rim, indigo band, white centre — in the brand mark's proportion. It carries the
   whole visual, so the tile itself has no border and no background colour.

   Sizing is driven by `--cert-frame` alone. The frame is expensive in area: its rings take
   about 19% off each edge, so the badge only ever gets the white hexagon inside. At 6rem a
   square mark paints ~47px; drop the frame to 4rem and it paints 31px. Change this one value
   and the badge follows. */
.footer-certs {
  --cert-frame: 6rem;
}
.footer-certs__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--cert-frame);
  aspect-ratio: 90.73 / 102.35;
  padding: 0;
  border: 0;
  background: url("../img/certification_frame.svg") center / contain no-repeat;
}
/* An empty slot shows the frame but nothing in it — no mark, no name, no claim. Held back so
   it reads as a slot waiting to be filled rather than as a credential already held. */
.footer-certs__item--empty { opacity: 0.45; }

/* The largest box that fits the frame's white centre, with margin. The hexagon's sloped
   corners bind the two axes — for a centred box, h ≤ 0.754 - 0.556w as fractions of the frame
   — so 50%/44% is geometry, not free-hand padding, and the pair must move together.

   The explicit size is not cosmetic either: with `width: auto` an unloaded image has a 0×0
   box, a `loading="lazy"` image with a 0×0 box is never seen to enter the viewport, and so it
   never loads — the badges silently stayed blank. */
.footer-certs__badge {
  width: 50%;
  height: 44%;
  object-fit: contain;
  display: block;
}
/* A certification published before its artwork exists is credited by name rather than being
   silently dropped. It sits on the frame's WHITE centre, not the navy footer, so it has to
   break out of the `.on-media` inversion — inherited, it would be white on white. The plate
   is invisible against the centre and keeps the ground honest for the contrast audit. */
.footer-certs__name {
  max-width: 62%;
  padding: 2px 4px;
  border-radius: var(--r-1);
  background: var(--c-white);
  font-size: var(--t-micro);
  font-weight: var(--fw-medium);
  color: var(--gray-700);
  text-align: center;
  line-height: var(--lh-snug);
  hyphens: auto;
}


/* ---------------------------------------------------------------- banner strip
   A wide image band between sections, replacing the partner logo row.

   The image is height-capped and cropped rather than letterboxed, so the strip keeps a
   consistent band height whatever proportions the client's photograph arrives in. The
   drawn placeholder is authored at the same ratio, so it is never actually cropped.
   `aspect-ratio` on the frame rather than a fixed height keeps it proportional on small
   screens, where a full-height strip would eat the viewport. */
.banner-strip {
  overflow: hidden;
  border-radius: var(--r-3);
  border: 1px solid var(--c-line);
  background: var(--c-ground-alt);
}
.banner-strip__image {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1600 / 340;
  object-fit: cover;
  object-position: center;
}
@media (max-width: 768px) {
  /* At phone width the full strip would be about 80px tall and the instruments unreadably
     small, so the band is deepened and the image cropped instead. The crop is anchored LEFT,
     not centred: a centred crop cuts the microscope down the middle and clips the molecule,
     leaving two half objects at either edge. Anchored left it shows the microscope, flask,
     beaker and tube rack whole, and simply ends after them. */
  .banner-strip__image {
    aspect-ratio: 1600 / 560;
    object-position: left center;
  }
}

/* ------------------------------------------------------------- about intro
   The opening section of the banded About template, prose beside a photograph.

   Text first in the source so it is read first without JavaScript and on a phone, where the
   columns stack; the image is placed to the right on wide screens by grid position rather than
   by reordering the markup. The figure is sticky-free and height-capped so a tall portrait
   cannot stretch the band beyond its copy. */
.about-intro {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-7);
  align-items: start;
}
.about-intro__figure { margin: 0; }
.about-intro__figure img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 26rem;
  object-fit: cover;
  border-radius: var(--r-3);
  border: 1px solid var(--c-line);
}

@media (min-width: 900px) {
  /* Prose is held to a readable measure rather than half the container, so a wide viewport
     widens the image instead of stretching the line length past comfortable reading. */
  .about-intro { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: var(--s-8); }
  .about-intro .prose { max-width: var(--measure); }
}

/* ------------------------------------------------------------------ captcha
   The reCAPTCHA field on public forms. Visible mode renders Google's own widget, which
   arrives as a fixed 304px iframe: it is allowed to scroll rather than forced to shrink,
   because scaling it down is against Google's terms and breaks the challenge on a phone. */
.captcha { margin-block: var(--s-5); }
.captcha .g-recaptcha { max-width: 100%; overflow-x: auto; }
.captcha__notice {
  font-size: var(--t-micro);
  color: var(--c-ink-60);
  line-height: var(--lh-snug);
  margin: 0;
}
.captcha__notice a { color: var(--c-accent-text); }
