/* ==========================================================================
   LifeSpark Pharma — Corporate Design System
   --------------------------------------------------------------------------
   Blueprint rule: "depth of information = authority. Design is secondary."

   The job of this stylesheet is to make dense, factual content legible:
   long tables, specification lists, bios, certificate rows. It is deliberately
   quieter than the previous consumer theme.

   Accessibility (§I): every text colour below is checked at >= 4.5:1 on its
   own background. Do not introduce a lighter grey for body copy.
   ========================================================================== */

:root {
    /* --- Ink scale. Contrast ratios are against --paper (#fff). --- */
    --ink:        #14171d;   /* 16.6:1 — headings                        */
    --ink-2:      #2b3240;   /* 12.1:1 — strong body                     */
    --body:       #3c4452;   /*  9.9:1 — body copy                       */
    --muted:      #5b6472;   /*  6.3:1 — secondary copy, captions        */
    --faint:      #6b7280;   /*  4.8:1 — MINIMUM. Never go lighter.      */

    /* --- Brand --- */
    --red:        #c2192f;   /*  6.4:1 — links and accents on paper      */
    --red-bright: #e01e37;   /*  4.8:1 — rules, marks, non-text accents  */
    --red-deep:   #961224;
    --red-wash:   #fdf2f3;
    --navy:       #16233c;
    --navy-2:     #1e2f4d;

    /* --- Surfaces --- */
    --paper:      #ffffff;
    --paper-2:    #f7f8fa;
    --paper-3:    #eef1f5;
    --line:       #dfe3ea;
    --line-2:     #c9d0da;

    /* --- State --- */
    --ok:         #14713d;
    --ok-wash:    #eef7f1;
    --warn:       #8a5a00;
    --warn-wash:  #fdf6e8;

    --font:  'Schibsted Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --serif: var(--font);

    --header-h: 68px;        /* §I: anchor links must clear the sticky header */
    --marquee-h: 0px;        /* set to a real height by body.has-marquee below */
    --hdr-gap: 16px;         /* the floating header's inset from the viewport edges */
    --wrap: 1180px;
    --wrap-narrow: 820px;
    --gut:  clamp(20px, 5vw, 72px);
    --pulse: #e8392f;

    /* Sharp, flat geometry — no rounded cards or pillowy buttons. */
    --r:    0;
    --r-sm: 0;

    --sh-sm: 0 1px 2px rgba(20, 23, 29, .05);
    --sh-md: 0 1px 3px rgba(20, 23, 29, .06);
    --sh-lg: 0 2px 8px rgba(20, 23, 29, .08);
    --sh-focus: 0 0 0 3px rgba(194, 25, 47, .16);

    /* --- Motion. One easing vocabulary for the whole site, so a card, a
           field and a section all decelerate the same way. --- */
    --ease-soft:  cubic-bezier(.22, .8, .26, .99);   /* settle — entrances   */
    --ease-out:   cubic-bezier(.33, 1, .68, 1);      /* quick UI response    */
    --ease-back:  cubic-bezier(.34, 1.4, .64, 1);    /* small pop, no bounce */
    --stagger: 70ms;                                 /* per-item entrance gap */
}

/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
    overflow-x: clip;
    scroll-behavior: smooth;
    /* §I: anchor targets must not hide under the sticky header. */
    scroll-padding-top: calc(var(--header-h) + var(--marquee-h) + var(--hdr-gap) + 16px);
    -webkit-text-size-adjust: 100%;
}

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

body {
    font-family: var(--font);
    font-size: 17px;
    line-height: 1.6;
    color: var(--body);
    background: var(--paper);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

img, svg, video { max-width: 100%; height: auto; display: block; }

/* The announcement marquee lives inside .hdr, so it travels with it whether
   the header is sticky or fixed. This is the only place its height is set. */
body.has-marquee { --marquee-h: 38px; }
a { color: var(--red); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--red-deep); }

:focus-visible {
    outline: 3px solid var(--red-bright);
    outline-offset: 2px;
    border-radius: 0;
}

/* Skip link — keyboard users land here first. */
.skip {
    position: absolute; left: -9999px; top: 0; z-index: 200;
    background: var(--navy); color: #fff;
    padding: 12px 20px; font-weight: 600;
}
.skip:focus { left: 8px; top: 8px; }

/* --------------------------------------------------------------------------
   Typography
   -------------------------------------------------------------------------- */
h1, h2, h3, h4, h5 {
    color: var(--ink);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -.02em;
}
h1 { font-size: clamp(1.9rem, 1.35rem + 2.2vw, 2.85rem); letter-spacing: -.03em; }
h2 { font-size: clamp(1.75rem, 1.4rem + 2vw, 2.65rem);   letter-spacing: -.03em; }
h3 { font-size: clamp(1.15rem, 1.02rem + .5vw, 1.35rem); letter-spacing: -.02em; }
h4 { font-size: 1.0625rem; }
h5 { font-size: .9375rem; }

p { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

strong, b { color: var(--ink-2); font-weight: 650; }

.lead {
    font-size: clamp(1.0625rem, 1rem + .35vw, 1.1875rem);
    line-height: 1.6;
    color: var(--ink-2);
}

.eyebrow {
    display: inline-block;
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--red);
    margin-bottom: 1.25rem;
}

.small  { font-size: .875rem; }
.muted  { color: var(--muted); }
.faint  { color: var(--faint); }

/* Source/date stamp — §H "Every number needs a source or a date." */
.asof {
    display: inline-block;
    font-size: .75rem;
    font-weight: 500;
    color: var(--faint);
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Layout primitives
   -------------------------------------------------------------------------- */
.wrap {
    width: 100%;
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: 20px;
}
.wrap--narrow { max-width: var(--wrap-narrow); }

.section { padding-block: clamp(72px, 10vh, 132px); }
.section--tint   { background: var(--paper-2); }
.section--line   { border-top: 1px solid var(--line); }
.section--navy   { background: var(--navy); }
.section--tight  { padding-block: clamp(2rem, 1.5rem + 2vw, 3rem); }

.section__head { max-width: 720px; margin-bottom: 2rem; }
.section__head p { color: var(--muted); }

.stack > * + * { margin-top: 1rem; }
.stack-lg > * + * { margin-top: 2rem; }

.grid { display: grid; gap: 20px; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

.split {
    display: grid;
    gap: clamp(1.5rem, 1rem + 3vw, 3.5rem);
    align-items: start;
}
@media (min-width: 900px) {
    .split { grid-template-columns: 1.15fr .85fr; }
    .split--even { grid-template-columns: 1fr 1fr; }
    .split--aside { grid-template-columns: 260px 1fr; }
}

/* --------------------------------------------------------------------------
   Buttons  (Blueprint §F — strict rules on where buttons may appear)
   -------------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: .7rem 1.25rem;
    font: inherit;
    font-size: .9375rem;
    font-weight: 600;
    line-height: 1.2;
    border: 1.5px solid transparent;
    border-radius: 0;
    cursor: pointer;
    text-decoration: none;
    transition: background-color .15s, border-color .15s, color .15s;
}
.btn svg { width: 1.05em; height: 1.05em; flex: none; }

.btn--primary { background: var(--red); color: #fff; border-color: var(--red); }
.btn--primary:hover { background: var(--red-deep); border-color: var(--red-deep); color: #fff; }

.btn--outline { background: transparent; color: var(--ink); border-color: var(--line-2); }
.btn--outline:hover { border-color: var(--ink); color: var(--ink); background: var(--paper-2); }

.btn--navy { background: var(--navy); color: #fff; border-color: var(--navy); }
.btn--navy:hover { background: var(--navy-2); color: #fff; }

.btn--sm { padding: .5rem .9rem; font-size: .875rem; }
.btn--full { width: 100%; }

/* §D-3: "text link with arrow, not a solid button" */
.tlink {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-weight: 600;
    font-size: .9375rem;
    text-decoration: none;
    color: var(--red);
}
.tlink:hover { text-decoration: underline; }
.tlink::after { content: '\2192'; transition: transform .15s; }
.tlink:hover::after { transform: translateX(3px); }

/* Visually hidden but still announced by a screen reader. */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------------------------------
   Announcement marquee — admin-editable text (Dashboard > Website settings).
   Lives INSIDE .hdr, above .hdr__bar, so it scrolls/sticks/fixes as one unit
   with the header rather than needing its own position rules. Height is
   fixed (not padding-driven) so --marquee-h stays exactly in sync with what
   other rules (hero offsets, the mobile drawer) compensate for.
   -------------------------------------------------------------------------- */
.marquee {
    height: var(--marquee-h);
    background: var(--red);
    color: #fff;
    overflow: hidden;
    display: flex;
    align-items: center;
}
.marquee__inner {
    display: flex;
    align-items: center;
    width: max-content;
    animation: marquee-scroll 26s linear infinite;
}
.marquee__text {
    flex: none;
    padding-inline: 2rem;
    font-size: .8125rem;
    font-weight: 600;
    letter-spacing: .01em;
    white-space: nowrap;
}
@keyframes marquee-scroll {
    from { transform: translateX(0); }
    to   { transform: translateX(-25%); }
}
@media (prefers-reduced-motion: reduce) {
    .marquee__inner { animation: none; }
    .marquee { overflow-x: auto; }
}

/* --------------------------------------------------------------------------
   Header  (§B — 8 dropdowns + Contact + ONE outline button: Partner Login)
   --------------------------------------------------------------------------
   A floating pill, inset from the viewport edges on all sides — rounded
   corners + a lifted shadow instead of an edge-to-edge bar with a hairline.
   -------------------------------------------------------------------------- */
.hdr {
    position: sticky;
    top: var(--hdr-gap);
    z-index: 100;
    margin-inline: var(--hdr-gap);
    background: var(--paper);
    border-radius: 16px;
    /* Two layers: a tight, crisp edge plus a soft wide lift — reads as a
       floating card rather than a flat bar with a blur under it. */
    box-shadow: 0 1px 2px rgba(16, 28, 52, .08), 0 18px 40px -14px rgba(16, 28, 52, .38);
}
.hdr__bar {
    display: flex;
    align-items: center;
    gap: 1rem;
    height: var(--header-h);
}
.hdr__brand { display: flex; align-items: center; text-decoration: none; margin-right: auto; }
.hdr__brand img, .hdr__brand svg { height: 38px; width: auto; }

.hdr__brand-txt { display: flex; flex-direction: column; line-height: 1.1; }
.hdr__brand-txt b {
    font-size: 1.0625rem; font-weight: 800; letter-spacing: .01em; color: var(--ink);
}
.hdr__brand-txt span { font-size: .625rem; letter-spacing: .13em; text-transform: uppercase; color: var(--faint); }

/* --- Desktop nav --- */
.nav { display: none; }
@media (min-width: 1200px) { .nav { display: flex; align-items: center; gap: 2px; } }

.nav__item { position: relative; }

.nav__link {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .55rem .6rem;
    font-size: .875rem;
    font-weight: 600;
    color: var(--ink-2);
    text-decoration: none;
    border-radius: 0;
    white-space: nowrap;
    background: none; border: 0; cursor: pointer; font-family: inherit;
}
.nav__link:hover { color: var(--red); background: var(--paper-2); }
.nav__link[aria-expanded="true"] { color: var(--red); background: var(--paper-2); }
.nav__link.is-current { color: var(--red); }
.nav__link.is-current::after {
    content: ''; position: absolute; left: .6rem; right: .6rem; bottom: -1px;
    height: 2px; background: var(--red-bright);
}
.nav__caret { width: 9px; height: 9px; flex: none; opacity: .55; transition: transform .15s; }
.nav__link[aria-expanded="true"] .nav__caret { transform: rotate(180deg); }

/* --- Dropdown ---
   The panel is styled in PART 24. It used to be display:none / display:block
   here, which fought that: an element cannot transition out of display:none,
   so the menu snapped instead of opening, and the old link rules layered on
   top of the new ones. Only the things PART 24 does not own are left here. */
.drop { position: absolute; top: calc(100% + 1px); left: 0; }

/* --- The single header button (§B). Outline, never solid-red. --- */
.hdr__login {
    display: none;
    padding: .5rem 1rem;
    font-size: .875rem;
    font-weight: 600;
    color: var(--ink);
    border: 1.5px solid var(--line-2);
    border-radius: 0;
    text-decoration: none;
    white-space: nowrap;
}
.hdr__login:hover { border-color: var(--ink); color: var(--ink); background: var(--paper-2); }
@media (min-width: 1200px) { .hdr__login { display: inline-flex; align-items: center; gap: .4rem; } }

/* --- Burger --- */
.burger {
    display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
    width: 42px; height: 42px; padding: 0 10px;
    background: none; border: 1px solid var(--line); border-radius: 0;
    cursor: pointer;
}
@media (min-width: 1200px) { .burger { display: none; } }
.burger span { display: block; height: 2px; background: var(--ink); border-radius: 0; transition: transform .2s, opacity .2s; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* --- Mobile drawer --- */
.mnav {
    display: none;
    position: fixed;
    inset: calc(var(--header-h) + var(--marquee-h) + var(--hdr-gap)) 0 0;
    background: var(--paper);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 12px 0 40px;
    z-index: 99;
}
.mnav[data-open="true"] { display: block; }
@media (min-width: 1200px) { .mnav { display: none !important; } }

.mnav__group { border-bottom: 1px solid var(--line); }
.mnav__toggle {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    width: 100%; padding: .95rem 20px;
    background: none; border: 0; cursor: pointer;
    font: inherit; font-size: 1rem; font-weight: 650; color: var(--ink);
    text-align: left;
}
.mnav__toggle .nav__caret { width: 12px; height: 12px; }
.mnav__toggle[aria-expanded="true"] .nav__caret { transform: rotate(180deg); }
.mnav__panel { display: none; padding: 0 20px .8rem; }
.mnav__panel[data-open="true"] { display: block; }
.mnav__panel a {
    display: block; padding: .55rem 0 .55rem .9rem;
    border-left: 2px solid var(--line);
    font-size: .9375rem; color: var(--body); text-decoration: none;
}
.mnav__panel a:hover { color: var(--red); border-left-color: var(--red-bright); }
.mnav__flat {
    display: block; padding: .95rem 20px;
    font-size: 1rem; font-weight: 650; color: var(--ink); text-decoration: none;
    border-bottom: 1px solid var(--line);
}
.mnav__cta { padding: 1.2rem 20px; }

/* --------------------------------------------------------------------------
   Page hero + breadcrumbs
   -------------------------------------------------------------------------- */
.phero {
    background: var(--paper-2);
    border-bottom: 1px solid var(--line);
    padding-block: clamp(1.75rem, 1.4rem + 1.6vw, 2.75rem);
}
.phero h1 { margin-bottom: .6rem; }
.phero .lead { max-width: 760px; }

.crumbs {
    display: flex; flex-wrap: wrap; align-items: center; gap: .4rem;
    font-size: .8125rem; color: var(--faint);
    margin-bottom: .85rem;
}
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--red); text-decoration: underline; }
.crumbs__sep { opacity: .6; }
.crumbs [aria-current] { color: var(--ink-2); font-weight: 600; }

/* --------------------------------------------------------------------------
   Homepage hero  (§D-1 — who you are, not what you sell; max 2 buttons)
   -------------------------------------------------------------------------- */
.hero {
    padding-block: clamp(3rem, 2.2rem + 4vw, 5.5rem);
    background:
        linear-gradient(180deg, #fff 0%, var(--paper-2) 100%);
    border-bottom: 1px solid var(--line);
}
.hero h1 { max-width: 16ch; margin-bottom: 1rem; }
.hero__sub { max-width: 60ch; margin-bottom: 1.75rem; }
.hero__cta { display: flex; flex-wrap: wrap; gap: .75rem; }

/* --------------------------------------------------------------------------
   Snapshot strip  (§D-2 — hard numbers, static, no buttons)
   -------------------------------------------------------------------------- */
.snap {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: 0;
    overflow: hidden;
}
.snap__cell { background: var(--paper); padding: 1.25rem 1.15rem; }
.snap__num {
    display: block;
    font-size: clamp(1.5rem, 1.25rem + 1vw, 2rem);
    font-weight: 750;
    color: var(--ink);
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.02em;
}
.snap__label { display: block; font-size: .8125rem; color: var(--muted); margin-top: .25rem; }
.snap__asof  { display: block; margin-top: .35rem; }

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */
.card {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 0;
    padding: 1.4rem;
    display: flex;
    flex-direction: column;
    gap: .55rem;
}
.card--link { text-decoration: none; transition: border-color .15s, box-shadow .15s, transform .15s; }
.card--link:hover { border-color: var(--line-2); box-shadow: var(--sh-md); transform: translateY(-2px); }
.card h3 { font-size: 1.0625rem; }
.card p { color: var(--muted); font-size: .9375rem; }
.card__foot { margin-top: auto; padding-top: .5rem; }

.card__kicker {
    font-size: .75rem; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--faint);
}

/* Numbered/lettered tile used for therapy + dosage-form grids */
.tile {
    display: flex; flex-direction: column; gap: .35rem;
    padding: 1.15rem 1.25rem;
    background: var(--paper);
    border: 1px solid var(--line);
    border-left: 3px solid var(--red-bright);
    border-radius: 0;
    text-decoration: none;
}
.tile:hover { background: var(--paper-2); }
.tile strong { color: var(--ink); font-size: 1rem; }
.tile span { font-size: .875rem; color: var(--muted); }

/* --------------------------------------------------------------------------
   Data tables — the backbone of an authority site
   -------------------------------------------------------------------------- */
.tablewrap {
    /* Wide tables scroll inside their own box; the page never scrolls sideways. */
    overflow-x: auto;
    border: 1px solid var(--line);
    border-radius: 0;
    -webkit-overflow-scrolling: touch;
}
table.data {
    width: 100%;
    min-width: 560px;
    border-collapse: collapse;
    font-size: .9375rem;
}
table.data caption {
    text-align: left;
    padding: .9rem 1rem;
    font-size: .8125rem;
    color: var(--muted);
    border-bottom: 1px solid var(--line);
    background: var(--paper-2);
}
table.data th, table.data td { padding: .8rem 1rem; text-align: left; vertical-align: top; }
table.data thead th {
    background: var(--paper-2);
    color: var(--ink-2);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}
table.data tbody tr + tr { border-top: 1px solid var(--line); }
table.data tbody tr:hover { background: var(--paper-2); }
table.data td { color: var(--body); }
table.data .num { font-variant-numeric: tabular-nums; text-align: right; }
table.data .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .875rem; }

/* Specification list — label/value pairs (product, plant, quality pages) */
.spec { border-top: 1px solid var(--line); }
.spec__row {
    display: grid;
    gap: .15rem .5rem;
    padding: .8rem 0;
    border-bottom: 1px solid var(--line);
}
@media (min-width: 640px) { .spec__row { grid-template-columns: 220px 1fr; gap: 1.5rem; } }
.spec__k { font-size: .875rem; font-weight: 600; color: var(--muted); }
.spec__v { color: var(--ink-2); }
.spec__v ul { margin: 0; padding-left: 1.1rem; }

/* --------------------------------------------------------------------------
   Status pills
   -------------------------------------------------------------------------- */
.pill {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .2rem .6rem;
    font-size: .75rem; font-weight: 650;
    border-radius: 999px;
    border: 1px solid var(--line-2);
    color: var(--muted);
    background: var(--paper-2);
    white-space: nowrap;
}
.pill--ok   { color: var(--ok);   background: var(--ok-wash);   border-color: #bfe0cb; }
.pill--warn { color: var(--warn); background: var(--warn-wash); border-color: #ecd9a8; }
.pill--rx   { color: var(--red);  background: var(--red-wash);  border-color: #f2c9ce; }

/* --------------------------------------------------------------------------
   People cards  (§E — Board and Leadership carry a lot of authority)
   -------------------------------------------------------------------------- */
.person {
    display: grid;
    grid-template-columns: 84px 1fr;
    gap: 1.1rem;
    padding: 1.35rem;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 0;
}
.person__photo {
    width: 84px; height: 84px;
    border-radius: 0;
    object-fit: cover;
    background: var(--paper-3);
}
.person__photo--ph {
    display: grid; place-items: center;
    font-size: 1.5rem; font-weight: 700; color: var(--faint);
}
.person h3 { font-size: 1.0625rem; margin-bottom: .1rem; }
.person__role { font-size: .875rem; font-weight: 600; color: var(--red); }
.person__meta {
    display: flex; flex-wrap: wrap; gap: .3rem .9rem;
    font-size: .8125rem; color: var(--faint);
    margin-top: .35rem;
}
.person__bio { font-size: .9375rem; color: var(--muted); margin-top: .6rem; }

/* --------------------------------------------------------------------------
   Timeline  (§E "About Us > Milestones" — vertical, year by year)
   -------------------------------------------------------------------------- */
.timeline { position: relative; padding-left: 2rem; }
.timeline::before {
    content: ''; position: absolute; left: 6px; top: .5rem; bottom: .5rem;
    width: 2px; background: var(--line);
}
.timeline__item { position: relative; padding-bottom: 1.75rem; }
.timeline__item::before {
    content: ''; position: absolute; left: -2rem; top: .45rem;
    width: 14px; height: 14px; border-radius: 50%;
    background: var(--paper); border: 3px solid var(--red-bright);
}
.timeline__year {
    font-size: .8125rem; font-weight: 700; letter-spacing: .06em;
    color: var(--red); font-variant-numeric: tabular-nums;
}
.timeline__item h3 { font-size: 1rem; margin: .1rem 0 .2rem; }
.timeline__item p { font-size: .9375rem; color: var(--muted); }

/* --------------------------------------------------------------------------
   Numbered process steps  (Partner With Us onboarding)
   -------------------------------------------------------------------------- */
.steps { counter-reset: s; display: grid; gap: 1px; background: var(--line);
         border: 1px solid var(--line); border-radius: 0; overflow: hidden; }
.steps__item { counter-increment: s; background: var(--paper); padding: 1.35rem; display: grid; gap: .4rem; }
.steps__item::before {
    content: counter(s, decimal-leading-zero);
    font-size: .8125rem; font-weight: 800; color: var(--red);
    letter-spacing: .06em;
}
.steps__item h3 { font-size: 1rem; }
.steps__item p { font-size: .9375rem; color: var(--muted); }
.steps__when { font-size: .8125rem; font-weight: 600; color: var(--faint); }
@media (min-width: 780px) { .steps { grid-template-columns: repeat(4, 1fr); } }

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
.form { display: grid; gap: 1.1rem; }
.form__row { display: grid; gap: 1.1rem; }
@media (min-width: 640px) { .form__row--2 { grid-template-columns: 1fr 1fr; } }

.field { display: grid; gap: .35rem; }
.field > label {
    font-size: .875rem;
    font-weight: 600;
    color: var(--ink-2);
}
.field__req { color: var(--red); }
.field__hint { font-size: .8125rem; color: var(--faint); }

.field input[type=text], .field input[type=email], .field input[type=tel],
.field input[type=date], .field input[type=file], .field select, .field textarea {
    width: 100%;
    padding: .65rem .8rem;
    font: inherit;
    font-size: .9375rem;
    color: var(--ink);
    background: var(--paper);
    border: 1.5px solid var(--line-2);
    border-radius: 0;
    transition: border-color .15s, box-shadow .15s;
}
.field textarea { min-height: 120px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus {
    outline: none;
    border-color: var(--red-bright);
    box-shadow: 0 0 0 3px rgba(224, 30, 55, .12);
}
.field input::placeholder, .field textarea::placeholder { color: var(--faint); }
.field input[aria-invalid="true"], .field select[aria-invalid="true"], .field textarea[aria-invalid="true"] {
    border-color: var(--red-bright);
}
.field__err { font-size: .8125rem; color: var(--red); font-weight: 500; }

.check { display: flex; gap: .6rem; align-items: flex-start; font-size: .875rem; color: var(--muted); }
.check input { margin-top: .25rem; flex: none; width: 16px; height: 16px; accent-color: var(--red-bright); }

.formbox {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 0;
    padding: clamp(1.25rem, 1rem + 1vw, 2rem);
}

/* Honeypot — visually gone, still in the tab order for bots only. */
.hp { position: absolute !important; left: -9999px !important; opacity: 0; height: 0; }

/* --------------------------------------------------------------------------
   Alerts
   -------------------------------------------------------------------------- */
.alert {
    display: grid; gap: .3rem;
    padding: 1rem 1.15rem;
    border-radius: 0;
    border: 1px solid;
    font-size: .9375rem;
}
.alert--ok   { background: var(--ok-wash);   border-color: #bfe0cb; color: #0f5b31; }
.alert--warn { background: var(--warn-wash); border-color: #ecd9a8; color: #6f4900; }
.alert--err  { background: var(--red-wash);  border-color: #f2c9ce; color: var(--red-deep); }
.alert strong { color: inherit; }

/* Editor-only notice: shows which client data is still missing. Local env only. */
.pending {
    display: block;
    padding: .85rem 1rem;
    border: 1px dashed var(--line-2);
    border-radius: 0;
    background: var(--paper-2);
    font-size: .875rem;
    color: var(--muted);
}
.pending b { color: var(--warn); }

/* --------------------------------------------------------------------------
   Prose — blog posts, policies, long-form pages
   -------------------------------------------------------------------------- */
.prose { max-width: 72ch; }
.prose > * + * { margin-top: 1.1rem; }
.prose h2 { margin-top: 2.25rem; font-size: 1.4rem; }
.prose h3 { margin-top: 1.75rem; font-size: 1.125rem; }
.prose ul, .prose ol { padding-left: 1.35rem; }
.prose li + li { margin-top: .4rem; }
.prose blockquote {
    border-left: 3px solid var(--red-bright);
    padding: .25rem 0 .25rem 1.15rem;
    color: var(--muted);
    font-style: italic;
}
.prose table { width: 100%; border-collapse: collapse; font-size: .9375rem; }
.prose th, .prose td { padding: .6rem .8rem; border: 1px solid var(--line); text-align: left; }
.prose code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .875em; background: var(--paper-3); padding: .1em .35em; border-radius: 0;
}
.prose hr { border: 0; border-top: 1px solid var(--line); margin: 2rem 0; }

/* Bulleted fact list used across About/Quality pages */
.ticks { list-style: none; display: grid; gap: .65rem; }
.ticks li { position: relative; padding-left: 1.6rem; color: var(--body); }
.ticks li::before {
    content: '';
    position: absolute; left: 0; top: .5em;
    width: 8px; height: 8px; border-radius: 0;
    background: var(--red-bright);
}
.ticks li strong { display: block; color: var(--ink-2); }

/* --------------------------------------------------------------------------
   Article / news listing
   -------------------------------------------------------------------------- */
.artlist { display: grid; gap: 0; border-top: 1px solid var(--line); }
.artitem {
    display: grid; gap: .35rem;
    padding: 1.35rem 0;
    border-bottom: 1px solid var(--line);
    text-decoration: none;
}
.artitem:hover h3 { color: var(--red); }
.artitem__meta {
    display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .9rem;
    font-size: .8125rem; color: var(--faint);
}
.artitem h3 { font-size: 1.125rem; }
.artitem p { color: var(--muted); font-size: .9375rem; }

/* Medically-reviewed tag — §E requires this on health articles. */
.medrev {
    display: inline-flex; align-items: center; gap: .35rem;
    font-size: .75rem; font-weight: 650; color: var(--ok);
    background: var(--ok-wash); border: 1px solid #bfe0cb;
    padding: .15rem .5rem; border-radius: 999px;
}

/* --------------------------------------------------------------------------
   Empty state — used wherever a list has no published entries yet
   -------------------------------------------------------------------------- */
.empty {
    text-align: center;
    padding: clamp(2rem, 1.5rem + 2vw, 3.5rem) 1.5rem;
    border: 1px dashed var(--line-2);
    border-radius: 0;
    background: var(--paper-2);
}
.empty h3 { font-size: 1.0625rem; margin-bottom: .4rem; }
.empty p { color: var(--muted); font-size: .9375rem; max-width: 46ch; margin-inline: auto; }

/* --------------------------------------------------------------------------
   Filters (product listing)
   -------------------------------------------------------------------------- */
.filters {
    display: grid; gap: .9rem;
    padding: 1.15rem;
    background: var(--paper-2);
    border: 1px solid var(--line);
    border-radius: 0;
    margin-bottom: 1.75rem;
}
@media (min-width: 760px) { .filters { grid-template-columns: repeat(3, 1fr) auto; align-items: end; } }
.filters .field > label { font-size: .8125rem; }

.chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.chip {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .35rem .75rem;
    font-size: .8125rem; font-weight: 600;
    color: var(--body);
    background: var(--paper);
    border: 1px solid var(--line-2);
    border-radius: 999px;
    text-decoration: none;
}
.chip:hover { border-color: var(--ink); color: var(--ink); }
.chip.is-on { background: var(--navy); border-color: var(--navy); color: #fff; }

/* --------------------------------------------------------------------------
   Product card  (§E — brand, composition, pack, category. NO price.)
   -------------------------------------------------------------------------- */
.prod {
    display: flex; flex-direction: column; gap: .5rem;
    padding: 1.25rem;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 0;
    text-decoration: none;
    transition: border-color .15s, box-shadow .15s;
}
.prod:hover { border-color: var(--line-2); box-shadow: var(--sh-md); }
.prod h3 { font-size: 1.0625rem; }
.prod__comp { font-size: .875rem; color: var(--muted); line-height: 1.5; }
.prod__tags { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: auto; padding-top: .6rem; }

/* --------------------------------------------------------------------------
   Certificate rows  (§E — name, issuer, number, valid till, view link)
   -------------------------------------------------------------------------- */
.certrow {
    display: grid; gap: .35rem;
    padding: 1.15rem 0;
    border-bottom: 1px solid var(--line);
}
@media (min-width: 820px) {
    .certrow { grid-template-columns: 1.4fr 1fr .9fr .8fr auto; align-items: center; gap: 1rem; }
}
.certrow__name { font-weight: 650; color: var(--ink); }
.certrow__k { font-size: .75rem; color: var(--faint); text-transform: uppercase; letter-spacing: .06em; }
@media (min-width: 820px) { .certrow__k { display: none; } }

/* --------------------------------------------------------------------------
   Enquiry strip  (§D-13 — two paths, equal weight)
   -------------------------------------------------------------------------- */
.paths { display: grid; gap: 20px; }
@media (min-width: 760px) { .paths { grid-template-columns: 1fr 1fr; } }
.path {
    display: flex; flex-direction: column; gap: .5rem;
    padding: 1.65rem;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 0;
    text-decoration: none;
}
.path:hover { border-color: var(--line-2); box-shadow: var(--sh-md); }
.path h3 { font-size: 1.125rem; }
.path p { color: var(--muted); font-size: .9375rem; }
.path .tlink { margin-top: auto; padding-top: .6rem; }

/* --------------------------------------------------------------------------
   Footer  (§D-14)
   -------------------------------------------------------------------------- */
.ftr { background: var(--navy); color: #c3cddd; padding-top: clamp(2.5rem, 2rem + 2vw, 3.5rem); }
.ftr a { color: #c3cddd; text-decoration: none; }
.ftr a:hover { color: #fff; text-decoration: underline; }

.ftr__top { display: grid; gap: 2rem; padding-bottom: 2.5rem; }
@media (min-width: 900px) { .ftr__top { grid-template-columns: 1.5fr repeat(3, 1fr); gap: 2.5rem; } }
@media (min-width: 1080px) { .ftr__top { grid-template-columns: 1.6fr repeat(3, 1fr); } }

.ftr__brand b { display: block; color: #fff; font-size: 1.0625rem; margin-bottom: .5rem; }
.ftr__addr { font-size: .875rem; line-height: 1.7; font-style: normal; }

.ftr__ids {
    display: grid; gap: .2rem;
    margin-top: .9rem;
    font-size: .8125rem;
    color: #93a3bb;
}
.ftr__ids span { font-variant-numeric: tabular-nums; }

.ftr__col h4 {
    color: #fff; font-size: .75rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase; margin-bottom: .85rem;
}
.ftr__col a { display: block; font-size: .875rem; padding: .22rem 0; }

.ftr__legal {
    border-top: 1px solid rgba(255, 255, 255, .12);
    padding-block: 1.35rem;
    display: grid; gap: .85rem;
    font-size: .8125rem;
    color: #93a3bb;
}
.ftr__legal-links { display: flex; flex-wrap: wrap; gap: .4rem 1.15rem; }
.ftr__legal-links a { font-size: .8125rem; }

/* The mandatory medicine line (§D-14). */
.ftr__disclaimer {
    border-top: 1px solid rgba(255, 255, 255, .12);
    padding-block: 1.1rem;
    font-size: .8125rem;
    color: #a9b7cc;
}

/* --------------------------------------------------------------------------
   Cookie consent  (§I — must be live before launch)
   -------------------------------------------------------------------------- */
.cookie {
    position: fixed;
    right: 16px; bottom: 16px;
    z-index: 150;
    width: min(400px, calc(100vw - 32px));
    background: var(--paper);
    border: 1px solid var(--line-2);
    border-radius: 0;
    box-shadow: var(--sh-lg);
    padding: 1.15rem 1.25rem;
    display: none;
}
.cookie[data-open="true"] { display: grid; gap: .85rem; }
.cookie p { font-size: .875rem; color: var(--muted); }
.cookie__row { display: flex; flex-wrap: wrap; gap: .6rem; }
@media (max-width: 560px) { .cookie { left: 16px; right: 16px; width: auto; } }

/* --------------------------------------------------------------------------
   Print — certificates, product pages and policies get printed a lot
   -------------------------------------------------------------------------- */
@media print {
    .hdr, .ftr, .cookie, .burger, .mnav, .skip, .btn { display: none !important; }
    body { color: #000; font-size: 11pt; }
    .section { padding-block: 1rem; }
    a[href^="http"]::after { content: ' (' attr(href) ')'; font-size: 9pt; color: #444; }
}

/* ==========================================================================
   PART 2 — Motion, imagery and the brand pulse
   --------------------------------------------------------------------------
   Everything below is presentation only. None of it invents a fact, animates
   a number (§D-2 forbids counters) or creates urgency (§F). Motion is used to
   pace a long, dense page — not to sell.

   Every effect is disabled under prefers-reduced-motion at the end of the file.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Scroll reveal
   Elements start slightly low and faded, and settle as they enter view.
   `.is-in` is added by IntersectionObserver; without JS everything is visible
   because `.reveal` only dims once JS marks the document as capable.
   -------------------------------------------------------------------------- */
.js .reveal {
    opacity: 0;
    transform: translate3d(0, 24px, 0);
    transition: opacity .75s var(--ease-soft), transform .75s var(--ease-soft);
    /* --i is written by the script for every member of a group, so a row of
       twelve cards staggers as cleanly as a row of three. */
    transition-delay: calc(var(--i, 0) * var(--stagger));
}
/* will-change is set only while an element is still waiting, and dropped the
   moment it lands — a long page must not hold hundreds of promoted layers. */
.js .reveal:not(.is-in) { will-change: opacity, transform; }
.js .reveal.is-in { opacity: 1; transform: none; will-change: auto; }

/* --------------------------------------------------------------------------
   The ECG pulse — carried over from the previous theme.
   It is the one piece of brand motion on the site. Used as a section rule,
   never across content.
   -------------------------------------------------------------------------- */
.pulse-rule {
    position: relative;
    height: clamp(34px, 4vw, 54px);
    overflow: hidden;
    pointer-events: none;
}
.pulse-rule svg { width: 100%; height: 100%; display: block; overflow: visible; }

.pulse-rule__base {
    stroke: rgba(224, 30, 55, .18);
    stroke-width: 2;
    fill: none;
}
.pulse-rule__trace {
    stroke: var(--red-bright);
    stroke-width: 2.4;
    fill: none;
    stroke-dasharray: 9 91;
    stroke-dashoffset: 100;
    animation: ecgTravel 6s linear infinite;
}
.pulse-rule--slow .pulse-rule__trace { animation-duration: 9s; }

@keyframes ecgTravel { to { stroke-dashoffset: 0; } }

/* On a dark section the base line needs to read against navy. */
.section--navy .pulse-rule__base { stroke: rgba(255, 255, 255, .16); }

/* Header — the floating shadow deepens slightly once the page scrolls. */
.hdr { transition: box-shadow .25s; }

/* Thin brand progress bar under the header. Reading progress only — this is
   not a countdown or a scarcity device. */
.hdr__progress {
    position: absolute; left: 0; bottom: -1px;
    height: 2px; width: 100%;
    transform: scaleX(var(--p, 0));
    transform-origin: 0 50%;
    background: linear-gradient(90deg, var(--red-bright), #ff6a5e);
    pointer-events: none;
}

/* --------------------------------------------------------------------------
   Hero — ambient depth behind the headline
   -------------------------------------------------------------------------- */
.hero { position: relative; overflow: hidden; }

.hero__bg { position: absolute; inset: 0; pointer-events: none; z-index: 0; }

/* soft brand glow, drifting slowly */
.hero__bg::before,
.hero__bg::after {
    content: '';
    position: absolute;
    border-radius: 50%;
}
.hero__bg::before {
    width: 46vw; height: 46vw; min-width: 420px; min-height: 420px;
    top: -18%; right: -10%;
    background: radial-gradient(closest-side, rgba(224,30,55,.10), rgba(224,30,55,.03) 55%, transparent 72%);
    animation: drift1 26s ease-in-out infinite alternate;
}
.hero__bg::after {
    width: 38vw; height: 38vw; min-width: 340px; min-height: 340px;
    bottom: -22%; left: -12%;
    background: radial-gradient(closest-side, rgba(22,35,60,.10), rgba(22,35,60,.03) 55%, transparent 72%);
    animation: drift2 32s ease-in-out infinite alternate;
}
@keyframes drift1 { from { transform: none } to { transform: translate(-50px, 40px) scale(1.08) } }
@keyframes drift2 { from { transform: none } to { transform: translate(60px, -30px) scale(.94) } }

/* engineering grid, faded out towards the bottom */
.hero__grid-lines {
    position: absolute; inset: 0;
    background-image:
        linear-gradient(rgba(22,35,60,.045) 1px, transparent 1px),
        linear-gradient(90deg, rgba(22,35,60,.045) 1px, transparent 1px);
    background-size: 54px 54px;
    -webkit-mask-image: radial-gradient(120% 85% at 50% 0%, #000 20%, transparent 76%);
            mask-image: radial-gradient(120% 85% at 50% 0%, #000 20%, transparent 76%);
}

.hero__inner { position: relative; z-index: 1; }
@media (min-width: 960px) {
    .hero__inner { display: grid; grid-template-columns: 1.05fr .95fr; gap: 3rem; align-items: center; }
}

.hero__art { display: none; }
@media (min-width: 960px) { .hero__art { display: block; } }

/* the capsule breathes very slightly */
.hero__capsule { animation: floatY 7s ease-in-out infinite; transform-origin: center; }
@keyframes floatY { 0%,100% { transform: translateY(0) } 50% { transform: translateY(-9px) } }

/* the trace inside the capsule draws itself, once */
.hero__trace {
    stroke-dasharray: 100;
    stroke-dashoffset: 100;
    animation: drawTrace 2.6s cubic-bezier(.6,0,.2,1) .4s forwards;
}
@keyframes drawTrace { to { stroke-dashoffset: 0 } }

/* floating credential chips */
.hero__chip {
    position: absolute;
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .45rem .8rem;
    background: rgba(255,255,255,.9);
    backdrop-filter: blur(8px);
    border: 1px solid var(--line);
    border-radius: 999px;
    box-shadow: var(--sh-md);
    font-size: .8125rem; font-weight: 600; color: var(--ink-2);
    white-space: nowrap;
    animation: floatY 6s ease-in-out infinite;
}
.hero__chip .ico { color: var(--red); }
.hero__chip--1 { top: 8%;  left: -4%; animation-delay: -1s }
.hero__chip--2 { top: 44%; right: -6%; animation-delay: -3s }
.hero__chip--3 { bottom: 8%; left: 6%; animation-delay: -5s }

/* --------------------------------------------------------------------------
   Icons
   -------------------------------------------------------------------------- */
.ico { flex: none; display: block; }

.ico-badge {
    display: inline-grid; place-items: center;
    width: 44px; height: 44px;
    border-radius: 0;
    background: var(--red-wash);
    color: var(--red);
    border: 1px solid #f4d3d8;
    margin-bottom: .35rem;
}
.ico-badge--navy { background: #eef1f7; color: var(--navy); border-color: #dbe2ee; }
.ico-badge--ok   { background: var(--ok-wash); color: var(--ok); border-color: #bfe0cb; }

/* Tiles and cards lift their icon on hover */
.tile .ico-badge, .card--link .ico-badge { transition: transform .2s, background-color .2s; }
.tile:hover .ico-badge, .card--link:hover .ico-badge { transform: translateY(-2px); background: #fbe6e9; }

/* --------------------------------------------------------------------------
   Card polish
   -------------------------------------------------------------------------- */
.card--link { position: relative; overflow: hidden; }

/* a hairline of brand colour wipes in along the top edge on hover */
.card--link::before {
    content: '';
    position: absolute; top: 0; left: 0; right: 0; height: 2px;
    background: linear-gradient(90deg, var(--red-bright), #ff8577);
    transform: scaleX(0); transform-origin: 0 50%;
    transition: transform .3s cubic-bezier(.22,.8,.26,.99);
}
.card--link:hover::before { transform: scaleX(1); }

.tile { position: relative; transition: transform .18s, box-shadow .18s, border-left-color .18s; }
.tile:hover { transform: translateX(3px); box-shadow: var(--sh-sm); }

/* --------------------------------------------------------------------------
   Figures and photographs
   -------------------------------------------------------------------------- */
.figure {
    margin: 0;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 0;
    overflow: hidden;
}
.figure img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    transition: transform .5s cubic-bezier(.22,.8,.26,.99);
}
.figure:hover img { transform: scale(1.03); }
.figure figcaption {
    padding: .8rem 1rem;
    font-size: .875rem;
    color: var(--muted);
    border-top: 1px solid var(--line);
}

/*
   Photo placeholder.

   We do NOT put a stock photograph of someone else's factory here. §K forbids
   showing what we cannot prove, and a purchased lab photo captioned as our
   plant is exactly that. This slot states plainly what belongs in it, and is
   replaced the moment a real photograph is uploaded.
*/
.photo-slot {
    position: relative;
    display: grid;
    place-content: center;
    gap: .5rem;
    text-align: center;
    aspect-ratio: 4 / 3;
    padding: 1.5rem;
    border: 1px dashed var(--line-2);
    border-radius: 0;
    background:
        repeating-linear-gradient(45deg,
            transparent 0 10px,
            rgba(22,35,60,.022) 10px 20px),
        var(--paper-2);
    color: var(--faint);
}
.photo-slot .ico { margin-inline: auto; color: var(--line-2); }
.photo-slot strong { font-size: .875rem; color: var(--muted); font-weight: 650; }
.photo-slot span { font-size: .75rem; max-width: 26ch; margin-inline: auto; line-height: 1.5; }

/* --------------------------------------------------------------------------
   India map  (§D-8, §E — states highlighted, plus a district count)
   --------------------------------------------------------------------------
   Built from district-level boundaries dissolved to states. A state is only
   filled when config/company.php actually lists coverage for it.
   -------------------------------------------------------------------------- */
.in-map { width: 100%; height: auto; display: block; }

.in-map__state {
    fill: #e8ecf2;
    stroke: #ffffff;
    stroke-width: 1;
    stroke-linejoin: round;
    transition: fill .25s;
}
.in-map__state.is-covered { fill: #f0a9b0; }
.in-map__state.is-covered:hover { fill: var(--red-bright); }
.in-map__state.is-hq { fill: var(--red); }

.mapbox {
    display: grid;
    gap: 1.5rem;
    align-items: start;
}
@media (min-width: 880px) { .mapbox { grid-template-columns: minmax(0,1fr) 260px; } }

.mapkey { display: grid; gap: .6rem; }
.mapkey__row { display: flex; align-items: center; gap: .6rem; font-size: .875rem; color: var(--muted); }
.mapkey__sw { width: 15px; height: 15px; border-radius: 0; border: 1px solid rgba(0,0,0,.08); flex: none; }

/* --------------------------------------------------------------------------
   Stat strip — subtle entrance, but the NUMBER never animates (§D-2)
   -------------------------------------------------------------------------- */
.snap__cell { position: relative; transition: background-color .2s; }
.snap__cell:hover { background: var(--paper-2); }
.snap__cell::after {
    content: '';
    position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
    background: var(--red-bright);
    transform: scaleX(0); transform-origin: 0 50%;
    transition: transform .35s cubic-bezier(.22,.8,.26,.99);
}
.js .snap.is-in .snap__cell::after { transform: scaleX(1); }
.js .snap.is-in .snap__cell:nth-child(2)::after { transition-delay: .08s }
.js .snap.is-in .snap__cell:nth-child(3)::after { transition-delay: .16s }
.js .snap.is-in .snap__cell:nth-child(4)::after { transition-delay: .24s }
.js .snap.is-in .snap__cell:nth-child(5)::after { transition-delay: .32s }
.js .snap.is-in .snap__cell:nth-child(6)::after { transition-delay: .40s }

/* --------------------------------------------------------------------------
   Timeline + steps entrance
   -------------------------------------------------------------------------- */
.js .timeline__item { opacity: 0; transform: translateY(16px); transition: opacity .6s, transform .6s; }
.js .timeline__item.is-in { opacity: 1; transform: none; }
.timeline__item::before { transition: transform .3s, background-color .3s; }
.timeline__item.is-in::before { animation: pinPop .5s cubic-bezier(.34,1.56,.64,1); }
@keyframes pinPop { 0% { transform: scale(.2) } 100% { transform: scale(1) } }

.steps__item { transition: background-color .2s; }
.steps__item:hover { background: var(--paper-2); }

/* --------------------------------------------------------------------------
   Prefers-reduced-motion — everything above degrades to a static page
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .js .reveal,
    .js .timeline__item { opacity: 1 !important; transform: none !important; transition: none !important; }
    .pulse-rule__trace,
    .hero__capsule, .hero__chip, .hero__trace,
    .hero__bg::before, .hero__bg::after { animation: none !important; }
    .hero__trace { stroke-dashoffset: 0 }
    .js .snap.is-in .snap__cell::after { transform: scaleX(1); transition: none }
    .figure:hover img { transform: none }
    .card--link::before { transition: none }
}

/* ==========================================================================
   PART 3 — Brand lockup
   ========================================================================== */

/* --------------------------------------------------------------------------
   Brand lockup — the original mark. flex:none stops the mark collapsing
   inside the flex header, and the descriptor never wraps.
   -------------------------------------------------------------------------- */
.brand-lockup {
    display: inline-flex;
    align-items: center;
    gap: 11px;
    color: var(--ink);
    text-decoration: none;
}
.brand-lockup__mark { height: 40px; width: auto; flex: none; }
.brand-lockup__text { display: grid; line-height: 1; text-align: left; }
.brand-lockup__text b {
    font-weight: 800;
    font-size: 19px;
    letter-spacing: .012em;
    color: inherit;
    white-space: nowrap;
}
.brand-lockup__text i {
    font-style: normal;
    font-size: 8.4px;
    font-weight: 600;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--faint);
    margin-top: 4px;
    white-space: nowrap;
}
@media (max-width: 420px) {
    .brand-lockup__mark { height: 34px; }
    .brand-lockup__text b { font-size: 16px; }
    .brand-lockup__text i { font-size: 7.4px; letter-spacing: .16em; }
}

/* Footer variant sits on navy. */
.ftr .brand-lockup { color: #fff; }
.ftr .brand-lockup__text i { color: #93a3bb; }
.ftr .brand-lockup__mark path:first-child { fill: #fff; stroke: #fff; }

/* --------------------------------------------------------------------------
   Fix: scope the hero artwork sizing to the illustration itself.
   `.hero__art svg` also matched the icons inside the floating chips and blew
   them up to full width.
   -------------------------------------------------------------------------- */
.hero__art > svg { width: 100%; height: auto; }
.hero__chip .ico { width: 15px; height: 15px; flex: none; }

/* ==========================================================================
   PART 4 — Header width, card artwork, feature bands
   ========================================================================== */

/* --------------------------------------------------------------------------
   Header runs full width.
   Eight menu groups, a lockup and a button do not fit inside the 1180px
   content measure — the bar gets its own wider container and larger gaps so
   the menu can breathe.
   -------------------------------------------------------------------------- */
:root { --header-h: 78px; }

.hdr__bar {
    max-width: 1720px;
    padding-inline: clamp(20px, 3vw, 48px);
    gap: clamp(1rem, 2.5vw, 2.5rem);
}
.hdr__brand { margin-right: 0; }

.nav { gap: clamp(2px, .5vw, 10px); margin-inline: auto; }

.nav__link {
    padding: .6rem clamp(.5rem, .8vw, .9rem);
    font-size: .9375rem;
    letter-spacing: -.005em;
}
.nav__link.is-current::after {
    left: clamp(.5rem, .8vw, .9rem);
    right: clamp(.5rem, .8vw, .9rem);
    bottom: -2px;
}

/* The tight-zone handling that used to live here (1080–1300px: smaller type,
   less padding) is superseded by the capsule sizing in PART 24b, which
   already starts tight at 1200px (where the drawer hands off) and only
   grows comfortable at 1400px. */

/* The dropdowns anchor to the bar, so widen their reach too. */
/* superseded by PART 24 */

/* --------------------------------------------------------------------------
   Hover polish
   -------------------------------------------------------------------------- */
.card--link {
    transition: border-color .2s, box-shadow .2s, transform .2s;
}
.card--link:hover { transform: translateY(-2px); box-shadow: var(--sh-md); }

/* Path cards (the enquiry strip) get the same treatment. */
.path { transition: border-color .2s, box-shadow .25s, transform .25s; }
.path:hover { transform: translateY(-3px); }

/* Tiles: the icon badge slides, the arrow appears. */
.tile { overflow: hidden; }
.tile::after {
    content: '\2192';
    position: absolute; right: 1.1rem; top: 1.1rem;
    color: var(--red);
    opacity: 0;
    transform: translateX(-6px);
    transition: opacity .2s, transform .2s;
}
.tile:hover::after { opacity: 1; transform: none; }

/* Table rows flash when the map scrolls to them. */
tr.is-flash { animation: rowFlash 1.6s ease-out; }
@keyframes rowFlash {
    0%, 40% { background: var(--red-wash); }
    100%    { background: transparent; }
}

/* --------------------------------------------------------------------------
   Feature band — full-bleed navy section with artwork behind it
   -------------------------------------------------------------------------- */
.band {
    position: relative;
    overflow: hidden;
    background: linear-gradient(120deg, var(--navy) 0%, #1d3054 55%, #24406e 100%);
    color: #dbe3ef;
    padding-block: clamp(2.75rem, 2.2rem + 2.5vw, 4.25rem);
}
.band h2, .band h3 { color: #fff; }
.band p { color: #b4c2d8; }
.band a:not(.btn) { color: #fff; }

.band__art {
    position: absolute; inset: 0;
    opacity: .5;
    pointer-events: none;
}
.band__art svg { width: 100%; height: 100%; }
.band > .wrap { position: relative; z-index: 1; }

.band .btn--outline { color: #fff; border-color: rgba(255,255,255,.4); }
.band .btn--outline:hover { background: rgba(255,255,255,.1); border-color: #fff; color: #fff; }

.band__stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1.5rem;
    margin-top: 2rem;
    padding-top: 2rem;
    border-top: 1px solid rgba(255,255,255,.14);
}
.band__stat b {
    display: block;
    font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem);
    font-weight: 750; color: #fff;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.02em;
}
.band__stat span { font-size: .8125rem; color: #9fb0c9; }

@media (prefers-reduced-motion: reduce) {
    .card--link { transition: none !important; }
    .card--link:hover { transform: none }
    tr.is-flash { animation: none }
}

/* --------------------------------------------------------------------------
   Band + map corrections
   -------------------------------------------------------------------------- */

/* The default red eyebrow only reaches 2.6:1 on navy. This one clears 6.6:1. */
.band .eyebrow { color: #ff8577; }
.band .card__kicker { color: #9fb0c9; }

/* The India map is tall and mostly empty at full width — cap it so it reads as
   a figure rather than taking over the section. */
.mapbox .in-map { max-height: 460px; width: auto; margin-inline: auto; }
@media (max-width: 880px) { .mapbox .in-map { max-height: 380px; } }

/* Give the map a surface of its own so it does not float on the section tint. */
.mapbox > div:first-child {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 0;
    padding: 1.25rem;
}

/* ==========================================================================
   PART 5 — Photography
   --------------------------------------------------------------------------
   Editorial imagery: laboratory, packaging, warehouse and workplace scenes.

   IMPORTANT — these are licensed stock photographs, used decoratively behind
   headings. They are never captioned as our facility, our team or our plant,
   because §K forbids presenting what we cannot prove. The labelled photo slots
   on Manufacturing, Careers and Gallery are where the company's own
   photographs go, and those slots stay empty until real ones arrive.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Photo page hero — image behind, navy scrim over, white type on top
   -------------------------------------------------------------------------- */
.phero--photo {
    position: relative;
    isolation: isolate;
    border-bottom: 0;
    padding-block: clamp(2.5rem, 2rem + 3vw, 4.5rem);
    background: var(--navy);
}
.phero--photo picture,
.phero--photo img {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    z-index: -2;
}
/* The scrim does the accessibility work: it keeps white type above 4.5:1 no
   matter how bright the photograph behind it is. */
.phero--photo::before {
    content: '';
    position: absolute; inset: 0; z-index: -1;
    background:
        linear-gradient(100deg, rgba(13,20,32,.94) 0%, rgba(13,20,32,.86) 45%, rgba(13,20,32,.62) 100%),
        linear-gradient(0deg, rgba(13,20,32,.5), rgba(13,20,32,.5));
}
.phero--photo h1 { color: #fff; }
.phero--photo .lead { color: #cdd8e8; }
.phero--photo .crumbs { color: #93a3bb; }
.phero--photo .crumbs a { color: #b9c6d8; }
.phero--photo .crumbs a:hover { color: #fff; }
.phero--photo .crumbs [aria-current] { color: #fff; }
.phero--photo .eyebrow { color: #ff8577; }

/* A thin brand rule closes the hero off from the content below. */
.phero--photo::after {
    content: '';
    position: absolute; left: 0; right: 0; bottom: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--red-bright), #ff8577 55%, transparent);
}

/* --------------------------------------------------------------------------
   Photo section — a full-bleed band with an image behind it
   -------------------------------------------------------------------------- */
.section--photo {
    position: relative;
    isolation: isolate;
    background: var(--navy);
    color: #dbe3ef;
}
.section--photo picture, .section--photo > img {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    z-index: -2;
}
.section--photo::before {
    content: '';
    position: absolute; inset: 0; z-index: -1;
    background: linear-gradient(105deg, rgba(13,20,32,.95) 0%, rgba(13,20,32,.8) 55%, rgba(13,20,32,.55) 100%);
}
.section--photo h2, .section--photo h3 { color: #fff; }
.section--photo p { color: #b8c5da; }
.section--photo .eyebrow { color: #ff8577; }
.section--photo .btn--outline { color: #fff; border-color: rgba(255,255,255,.42); }
.section--photo .btn--outline:hover { background: rgba(255,255,255,.12); border-color: #fff; color: #fff; }

/* --------------------------------------------------------------------------
   Split feature — image one side, copy the other
   -------------------------------------------------------------------------- */
.feature { display: grid; gap: clamp(1.5rem, 1rem + 3vw, 3rem); align-items: center; }
@media (min-width: 900px) {
    .feature { grid-template-columns: 1fr 1fr; }
    .feature--flip > :first-child { order: 2; }
}
.feature__img {
    position: relative;
    border-radius: 0;
    overflow: hidden;
    box-shadow: var(--sh-lg);
    aspect-ratio: 4 / 3;
}
.feature__img img { width: 100%; height: 100%; object-fit: cover; transition: transform .7s cubic-bezier(.22,.8,.26,.99); }
.feature__img:hover img { transform: scale(1.04); }

/* A brand corner bracket, so the photo reads as designed rather than dropped in. */

/* Small print marking imagery as illustrative, wherever a photo could be
   mistaken for our own facility. */
.imgnote {
    font-size: .75rem;
    line-height: 1.5;
    color: var(--faint);
    margin-top: .5rem;
}
.section--photo .imgnote, .phero--photo .imgnote { color: #8fa0b8; }

@media (prefers-reduced-motion: reduce) {
    .feature__img img { transition: none !important; transform: none !important; }
}

/* ==========================================================================
   PART 6 — Hero, rebuilt on photography
   ========================================================================== */
.hero {
    position: relative;
    isolation: isolate;
    background: #0d1420;
    border-bottom: 0;
    padding-block: clamp(3.5rem, 2.5rem + 5vw, 7rem);
    overflow: hidden;
}

.hero__photo {
    position: absolute; inset: 0; z-index: -3;
    width: 100%; height: 100%;
    object-fit: cover;
    /* a slow drift so the still reads as alive without distracting */
    animation: heroPan 32s ease-in-out infinite alternate;
    transform-origin: 60% 40%;
}
@keyframes heroPan { from { transform: scale(1.06) } to { transform: scale(1.14) translateX(-1.5%) } }

/* Scrim. Two layers: a hard left wedge for the type, and an overall floor so
   white copy clears 4.5:1 wherever the photograph happens to be bright. */
.hero::before {
    content: '';
    position: absolute; inset: 0; z-index: -2;
    background:
        linear-gradient(100deg, rgba(9,14,24,.96) 0%, rgba(9,14,24,.9) 38%, rgba(9,14,24,.55) 68%, rgba(9,14,24,.35) 100%),
        linear-gradient(180deg, rgba(9,14,24,.55), rgba(9,14,24,.65));
}

/* Brand pulse washing across the artwork side. */

.hero__grid-lines {
    position: absolute; inset: 0; z-index: -1;
    background-image:
        linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
    background-size: 58px 58px;
    -webkit-mask-image: radial-gradient(110% 80% at 70% 30%, #000 10%, transparent 72%);
            mask-image: radial-gradient(110% 80% at 70% 30%, #000 10%, transparent 72%);
}

/* --- Type on the dark hero --- */
.hero h1 { color: #fff; max-width: 17ch; letter-spacing: -.025em; }
.hero .lead, .hero__sub { color: #c6d2e4; }

/* A small credential line above the headline. */
.hero__eyebrow {
    display: inline-flex; align-items: center; gap: .55rem;
    padding: .4rem .85rem .4rem .5rem;
    margin-bottom: 1.25rem;
    border: 1px solid rgba(255,255,255,.18);
    background: rgba(255,255,255,.07);
    backdrop-filter: blur(10px);
    border-radius: 999px;
    font-size: .8125rem; font-weight: 600;
    color: #e4ebf6;
    letter-spacing: .01em;
}
.hero__eyebrow .ico { color: #ff8577; }
.hero__eyebrow b { color: #fff; font-weight: 700; }

.hero .btn--outline { color: #fff; border-color: rgba(255,255,255,.42); background: transparent; }
.hero .btn--outline:hover { background: rgba(255,255,255,.12); border-color: #fff; color: #fff; }

/* --- Key facts strip sitting inside the hero --- */
.hero__facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
    gap: 1.25rem 2rem;
    margin-top: 2.5rem;
    padding-top: 1.75rem;
    border-top: 1px solid rgba(255,255,255,.16);
    max-width: 620px;
}
.hero__fact b {
    display: block;
    font-size: clamp(1.35rem, 1.1rem + .9vw, 1.75rem);
    font-weight: 750; color: #fff;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.02em;
    line-height: 1.15;
}
.hero__fact span { display: block; font-size: .8125rem; color: #9fb0c9; margin-top: .2rem; }

/* --- Artwork column --- */
.hero__inner { position: relative; z-index: 1; }
@media (min-width: 1000px) {
    .hero__inner { grid-template-columns: 1.1fr .9fr; gap: 3.5rem; }
}

/* the capsule now sits on dark, so its chips flip to a glass-dark treatment */
.hero__chip {
    background: rgba(255,255,255,.1);
    border-color: rgba(255,255,255,.2);
    color: #eaf0f8;
    box-shadow: 0 10px 30px -12px rgba(0,0,0,.6);
}
.hero__chip .ico { color: #ff8577; }

@media (prefers-reduced-motion: reduce) {
    .hero__photo { animation: none; transform: scale(1.06); }
}

/* Chip placement: keep them clear of the capsule itself. */
.hero__chip--1 { top: 2%;   left: -2%;   right: auto; bottom: auto; }
.hero__chip--2 { top: 42%;  right: -8%;  left: auto;  bottom: auto; }
.hero__chip--3 { bottom: 4%; left: 2%;   top: auto;   right: auto; }
@media (min-width: 1000px) and (max-width: 1200px) {
    .hero__chip--2 { right: -2%; }
    .hero__chip { font-size: .75rem; padding: .38rem .65rem; }
}

/* ==========================================================================
   PART 7 — Premium pass
   --------------------------------------------------------------------------
   Two problems this fixes:

   1. The engineering grid over the hero photograph. Two competing textures in
      one frame read as noise, so the grid is gone.

   2. Orphaned cards. Five divisions in a four-column grid left one card alone
      on a second row, which is the single most obvious "unfinished" tell on a
      layout. Sections with five items now get layouts built for five.
   ========================================================================== */

/* Grid overlay retired — the photograph carries the hero on its own. */
.hero__grid-lines { display: none; }

/* --------------------------------------------------------------------------
   Hero — cinematic, parallax, no competing texture
   -------------------------------------------------------------------------- */
.hero {
    min-height: min(88vh, 820px);
    display: flex;
    align-items: center;
    padding-block: clamp(4rem, 3rem + 6vw, 8rem);
}

.hero__photo {
    /* taller than the frame so the parallax has room to travel */
    height: 128%;
    top: -14%;
    animation: none;
    will-change: transform;
    transform: translate3d(0, var(--par, 0px), 0) scale(1.04);
}

/* A cleaner scrim: a strong left wedge and a deep floor, nothing else. */
.hero::before {
    background:
        linear-gradient(96deg,
            rgba(7,11,19,.97) 0%,
            rgba(7,11,19,.93) 30%,
            rgba(7,11,19,.72) 58%,
            rgba(7,11,19,.42) 100%),
        linear-gradient(180deg, rgba(7,11,19,.35) 0%, rgba(7,11,19,.72) 100%);
}

.hero h1 {
    font-size: clamp(2.1rem, 1.4rem + 3vw, 3.6rem);
    line-height: 1.06;
    letter-spacing: -.032em;
    max-width: 15ch;
}
.hero__sub { font-size: clamp(1.0625rem, 1rem + .4vw, 1.1875rem); max-width: 52ch; }

/* Headline settles in as a soft clip-reveal rather than a plain fade. */
.js .hero h1, .js .hero__eyebrow, .js .hero__sub, .js .hero__cta, .js .hero__facts {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity .85s cubic-bezier(.22,.8,.26,.99), transform .85s cubic-bezier(.22,.8,.26,.99);
}
.js .hero.is-in .hero__eyebrow { opacity: 1; transform: none; transition-delay: .05s }
.js .hero.is-in h1             { opacity: 1; transform: none; transition-delay: .14s }
.js .hero.is-in .hero__sub     { opacity: 1; transform: none; transition-delay: .26s }
.js .hero.is-in .hero__cta     { opacity: 1; transform: none; transition-delay: .36s }
.js .hero.is-in .hero__facts   { opacity: 1; transform: none; transition-delay: .46s }

.hero__facts { border-top-color: rgba(255,255,255,.2); max-width: 660px; }
.hero__fact { position: relative; padding-left: .9rem; }
.hero__fact::before {
    content: '';
    position: absolute; left: 0; top: .35rem; bottom: .35rem;
    width: 2px; border-radius: 0;
    background: var(--red-bright);
    opacity: .8;
}

/* --------------------------------------------------------------------------
   Five-across row — for short-label tiles (therapies)
   -------------------------------------------------------------------------- */
.row5 { display: grid; gap: 16px; grid-template-columns: 1fr; }
@media (min-width: 560px)  { .row5 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px)  { .row5 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1200px) { .row5 { grid-template-columns: repeat(5, 1fr); } }

/* At 3 columns, five items leave two on the last row — centre them so the
   gap reads as intentional rather than broken. */
@media (min-width: 900px) and (max-width: 1199px) {
    .row5 > :nth-child(4) { grid-column: 1 / 2; margin-left: 50%; }
    .row5 > :nth-child(5) { grid-column: 2 / 4; margin-right: 50%; }
}

.row5 .tile {
    padding: 1.4rem 1.15rem;
    border-left: 0;
    border-top: 3px solid var(--red-bright);
    text-align: left;
}
.row5 .tile:hover { transform: translateY(-3px); }
.row5 .tile::after { display: none; }

/* --------------------------------------------------------------------------
   Section rhythm — alternate surfaces so no two neighbours look alike
   -------------------------------------------------------------------------- */
.section--edge { border-top: 1px solid var(--line); }

/* A numbered section label, used to give each block its own identity. */
.sec-label {
    display: flex; align-items: center; gap: .75rem;
    margin-bottom: .75rem;
}
.sec-label__n {
    display: grid; place-items: center;
    width: 30px; height: 30px;
    border-radius: 0;
    background: var(--red-wash);
    border: 1px solid #f2c9ce;
    color: var(--red);
    font-size: .75rem; font-weight: 800;
    font-variant-numeric: tabular-nums;
    flex: none;
}
.sec-label .eyebrow { margin-bottom: 0; }
.section--photo .sec-label__n, .band .sec-label__n {
    background: rgba(255,255,255,.1);
    border-color: rgba(255,255,255,.22);
    color: #ff8577;
}

@media (prefers-reduced-motion: reduce) {
    .hero__photo { transform: scale(1.04) !important; }
    .js .hero h1, .js .hero__eyebrow, .js .hero__sub,
    .js .hero__cta, .js .hero__facts { opacity: 1 !important; transform: none !important; }
}

/* --------------------------------------------------------------------------
   Hero, single-column.
   A photograph and a floating illustration were two focal points fighting for
   the same frame. The illustration is gone; the credentials it carried are now
   a quiet row under the facts.
   -------------------------------------------------------------------------- */
.hero__inner { display: block; max-width: 1180px; }
.hero__inner > .reveal { max-width: 760px; }

.hero__marks {
    display: flex; flex-wrap: wrap; gap: .5rem .65rem;
    margin-top: 1.75rem;
}
.hero__mark {
    display: inline-flex; align-items: center; gap: .45rem;
    padding: .38rem .8rem;
    border: 1px solid rgba(255,255,255,.2);
    background: rgba(255,255,255,.07);
    backdrop-filter: blur(10px);
    border-radius: 999px;
    font-size: .8125rem; font-weight: 600;
    color: #dce5f2;
    white-space: nowrap;
}
.hero__mark .ico { color: #ff8577; }
.js .hero .hero__marks { opacity: 0; transform: translateY(20px);
    transition: opacity .85s cubic-bezier(.22,.8,.26,.99), transform .85s cubic-bezier(.22,.8,.26,.99); }
.js .hero.is-in .hero__marks { opacity: 1; transform: none; transition-delay: .56s }

/* A scroll cue anchored to the bottom of the frame. */
.hero__cue {
    position: absolute; left: 50%; bottom: 26px;
    transform: translateX(-50%);
    display: grid; place-items: center; gap: .4rem;
    color: #8fa0b8; font-size: .6875rem;
    letter-spacing: .16em; text-transform: uppercase;
}
.hero__cue i {
    display: block; width: 1px; height: 26px;
    background: linear-gradient(180deg, rgba(255,255,255,.5), transparent);
    animation: cueDrop 2.2s ease-in-out infinite;
}
@keyframes cueDrop { 0%,100% { transform: scaleY(.4); transform-origin: top } 50% { transform: scaleY(1); transform-origin: top } }
@media (max-width: 900px) { .hero__cue { display: none } }
@media (prefers-reduced-motion: reduce) { .hero__cue i { animation: none } }

/* Photograph behind the careers band, under the existing pattern artwork. */
.band { isolation: isolate; }
.band__photo {
    position: absolute; inset: 0; z-index: -2;
    width: 100%; height: 100%;
    object-fit: cover;
}
.band::before {
    content: '';
    position: absolute; inset: 0; z-index: -1;
    background: linear-gradient(102deg, rgba(11,18,30,.96) 0%, rgba(13,22,38,.9) 48%, rgba(20,36,62,.72) 100%);
}
.band__art { z-index: 0; opacity: .35; }
.band > .wrap { position: relative; z-index: 1; }

/* ==========================================================================
   PART 8 — Overlay header and split-text headings
   ========================================================================== */

/* --------------------------------------------------------------------------
   Header over a photographic hero.
   --------------------------------------------------------------------------
   One header, one look, everywhere: solid white with ink type from the first
   pixel, whether the hero below is a photograph or plain paper. Only the
   positioning differs — `$darkHero` pages need the bar fixed over their
   edge-to-edge hero rather than pushing it down.
   -------------------------------------------------------------------------- */
.hdr--over {
    position: fixed;
    /* The marquee is full-width and NOT fixed, so on first paint the fixed
       header must start below it — not just below the top-of-viewport gap. */
    top: calc(var(--marquee-h) + var(--hdr-gap)); left: var(--hdr-gap); right: var(--hdr-gap);
    transition: box-shadow .25s ease;
}

/* The hero sits under a fixed header, so it carries its own top offset. */
.has-overlay-header .hero,
.has-overlay-header .phero--photo { padding-top: calc(var(--header-h) + var(--marquee-h) + var(--hdr-gap) + clamp(2rem, 1.5rem + 3vw, 4rem)); }
.has-overlay-header .hero--light { padding-top: calc(var(--header-h) + var(--marquee-h) + var(--hdr-gap) + clamp(1.75rem, 1.25rem + 3vw, 3.5rem)); }

/* --------------------------------------------------------------------------
   Split-text headings
   --------------------------------------------------------------------------
   JS splits a heading into words, characters or lines and animates the pieces
   in. The original text is kept on the element as aria-label and every
   generated span is aria-hidden, so assistive technology still reads one
   clean sentence rather than a stream of fragments.
   -------------------------------------------------------------------------- */
.split-line { display: block; overflow: hidden; }
.split-unit {
    display: inline-block;
    will-change: transform, opacity;
}
/* A trailing space is collapsed by inline-block, so it is restored explicitly. */
.split-space { display: inline-block; width: .28em; }

/* One quiet entrance for every heading, regardless of which data-split value
   the template uses: a slight rise and fade, nothing rotated, skewed, blurred
   or clipped. */
[data-split="rise"] .split-unit,
[data-split="fade"] .split-unit,
[data-split="wipe"] .split-unit,
[data-split="drop"] .split-unit,
[data-split="skew"] .split-unit {
    opacity: 0;
    transform: translateY(10px);
    transition: opacity .5s var(--ease-soft), transform .5s var(--ease-soft);
}
[data-split="rise"].is-split-in .split-unit,
[data-split="fade"].is-split-in .split-unit,
[data-split="wipe"].is-split-in .split-unit,
[data-split="drop"].is-split-in .split-unit,
[data-split="skew"].is-split-in .split-unit {
    opacity: 1;
    transform: none;
}

/* Nothing splits, and nothing hides, when motion is unwelcome. */
@media (prefers-reduced-motion: reduce) {
    [data-split] .split-unit {
        opacity: 1 !important;
        transform: none !important;
        filter: none !important;
        clip-path: none !important;
        transition: none !important;
    }
}

/* ==========================================================================
   PART 9 — Light hero
   --------------------------------------------------------------------------
   The full-bleed dark hero read as heavy. This replaces it with a light,
   airy split: copy on a near-white field, the photograph contained as a
   framed figure beside it. Same photograph, far less weight.
   ========================================================================== */

.hero--light {
    background:
        radial-gradient(120% 90% at 88% 12%, rgba(224,30,55,.07), transparent 58%),
        linear-gradient(180deg, #ffffff 0%, #fbfcfd 55%, var(--paper-2) 100%);
    border-bottom: 1px solid var(--line);
    min-height: 0;
    padding-block: clamp(2.75rem, 2rem + 5vw, 6rem);
    color: var(--body);
}

/* Everything the dark treatment added is switched back off. */
.hero--light::before,
.hero--light::after { content: none; }

.hero--light .hero__inner { max-width: var(--wrap); }
@media (min-width: 1000px) {
    .hero--light .hero__inner {
        display: grid;
        grid-template-columns: 1.02fr .98fr;
        gap: clamp(2rem, 1rem + 4vw, 4.5rem);
        align-items: center;
    }
}
.hero--light .hero__inner > .reveal { max-width: none; }

/* --- Type --- */
.hero--light h1 { color: var(--ink); }
.hero--light .hero__sub { color: var(--muted); }

.hero--light .hero__eyebrow {
    background: var(--paper);
    border-color: var(--line);
    color: var(--ink-2);
    backdrop-filter: none;
    box-shadow: var(--sh-sm);
}
.hero--light .hero__eyebrow b { color: var(--ink); }
.hero--light .hero__eyebrow .ico { color: var(--red); }

.hero--light .btn--outline { color: var(--ink); border-color: var(--line-2); }
.hero--light .btn--outline:hover { background: var(--paper-2); border-color: var(--ink); color: var(--ink); }

/* --- Facts --- */
.hero--light .hero__facts { border-top-color: var(--line); max-width: none; }
.hero--light .hero__fact b { color: var(--ink); }
.hero--light .hero__fact span { color: var(--muted); }

/* --- Credential marks --- */
.hero--light .hero__mark {
    background: var(--paper);
    border-color: var(--line);
    color: var(--body);
    backdrop-filter: none;
}
.hero--light .hero__mark .ico { color: var(--red); }

/* --- The photograph, contained --- */
.hero__figure {
    position: relative;
    border: 1px solid var(--line);
    overflow: hidden;
    aspect-ratio: 4 / 3.4;
}
@media (max-width: 999px) { .hero__figure { aspect-ratio: 16 / 10; margin-top: 2.5rem; } }

.hero__figure img {
    position: static;
    width: 100%; height: 100%;
    object-fit: cover;
    animation: none;
    /* a gentle parallax drift inside its own frame */
    transform: translate3d(0, var(--par, 0px), 0) scale(1.08);
    will-change: transform;
}

/* Brand corner bracket. */

/* A soft tint so the photograph sits in the palette rather than fighting it. */
.hero__figure::before {
    content: '';
    position: absolute; inset: 0; z-index: 1;
    background: linear-gradient(145deg, rgba(224,30,55,.10), transparent 45%, rgba(22,35,60,.16));
    pointer-events: none;
}

/* A floating stat card overlapping the photo's edge. */
.hero__badge {
    position: absolute;
    left: -18px; bottom: 34px;
    z-index: 2;
    display: grid; gap: .1rem;
    padding: .9rem 1.15rem;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 0;
    box-shadow: var(--sh-md);
}
.hero__badge b {
    font-size: 1.35rem; font-weight: 750; color: var(--ink);
    line-height: 1.1; font-variant-numeric: tabular-nums;
}
.hero__badge span { font-size: .75rem; color: var(--muted); }
@media (max-width: 999px) { .hero__badge { left: 14px; } }

.hero--light .hero__cue { color: var(--faint); }
.hero--light .hero__cue i { background: linear-gradient(180deg, var(--line-2), transparent); }

/* --------------------------------------------------------------------------
   Glass header over a LIGHT hero — same transparency, dark type
   -------------------------------------------------------------------------- */
.hdr--glass {
    position: fixed;
    top: calc(var(--marquee-h) + var(--hdr-gap)); left: var(--hdr-gap); right: var(--hdr-gap);
    background: var(--paper);
    transition: box-shadow .25s ease;
}
@media (prefers-reduced-motion: reduce) {
    .hero__figure img { transform: scale(1.08) !important; }
}

/* --------------------------------------------------------------------------
   Light-hero corrections
   -------------------------------------------------------------------------- */

/* Four facts in a narrower column wrapped 3 + 1. Fix the track count so the
   row is always balanced. */
.hero--light .hero__facts {
    grid-template-columns: repeat(2, 1fr);
    gap: 1.25rem 1.5rem;
    max-width: 520px;
}
@media (min-width: 1240px) {
    .hero--light .hero__facts { grid-template-columns: repeat(4, 1fr); max-width: none; }
}

/* The stat card and the corner bracket were competing for the same corner. */
.hero--light .hero__badge {
    left: auto; right: -16px;
    bottom: auto; top: 26px;
}
@media (max-width: 999px) { .hero--light .hero__badge { right: 14px; } }

/* The split-space span is no longer emitted; keep the rule harmless. */
.split-space { width: auto; }

/* Credential row spans the hero grid so the pills sit on one line. */
@media (min-width: 1000px) {
    .hero--light .hero__marks {
        grid-column: 1 / -1;
        margin-top: 2.5rem;
        padding-top: 1.75rem;
        border-top: 1px solid var(--line);
    }
}

/* ==========================================================================
   PART 10 — Light hero with a full-bleed background photograph
   --------------------------------------------------------------------------
   The photograph fills the hero, but a light scrim keeps the left two-thirds
   near-white so the headline stays ink-dark and the section still reads clean
   rather than heavy. Same image, none of the weight of a dark treatment.
   ========================================================================== */

.hero--light {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background: var(--paper);
}

.hero--light .hero__photo {
    position: absolute;
    inset: 0;
    z-index: -3;
    width: 100%;
    height: 118%;
    top: -9%;
    object-fit: cover;
    object-position: 50% 50%;
    transform: translate3d(0, var(--par, 0px), 0);
    will-change: transform;
}

/* A clean split rather than a wash.

   The copy side is solid paper, the photograph side is left completely
   untouched, and the two meet in a short blend. An all-over white veil made
   the photograph look hazy — this keeps it crisp. */
.hero--light .hero__scrim {
    position: absolute; inset: 0; z-index: -2;
    background: linear-gradient(94deg,
        #ffffff 0%,
        #ffffff 44%,
        rgba(255,255,255,.92) 52%,
        rgba(255,255,255,.55) 60%,
        rgba(255,255,255,0)  70%);
}
@media (max-width: 999px) {
    /* Stacked layout: the photo sits behind the lower half only. */
    .hero--light .hero__scrim {
        background: linear-gradient(180deg, #ffffff 0%, #ffffff 62%, rgba(255,255,255,.72) 80%, rgba(255,255,255,.45) 100%);
    }
}

/* A soft brand tint in the photograph corner, and a clean bottom fade into
   the next section. */
.hero--light::before {
    content: '';
    position: absolute; inset: 0; z-index: -1;
    /* Only a bottom fade into the next section — no tint over the photograph. */
    background: linear-gradient(180deg, transparent 82%, rgba(247,248,250,.9) 100%);
}
.hero--light::after { content: none; }

/* The copy column no longer needs a partner column. */
@media (min-width: 1000px) {
    .hero--light .hero__inner { grid-template-columns: minmax(0, 640px) 1fr; align-items: center; }
    .hero--light .hero__facts { grid-template-columns: repeat(4, 1fr); max-width: none; }
}

/* Floating capacity card, sitting over the photographed side. */
.hero--light .hero__badge {
    position: absolute;
    right: clamp(24px, 5vw, 96px);
    bottom: clamp(90px, 12vh, 150px);
    left: auto; top: auto;
    z-index: 2;
}
@media (max-width: 999px) { .hero--light .hero__badge { display: none; } }

@media (prefers-reduced-motion: reduce) {
    .hero--light .hero__photo { transform: none !important; }
}

/* ==========================================================================
   PART 11 — The scroll motion system
   --------------------------------------------------------------------------
   One engine, driven from corporate.js:

     · a single IntersectionObserver marks elements `.is-in` as they arrive
     · a single rAF loop publishes scroll state as custom properties
       (--sy on <html>, --p on the progress bar, --par on parallax layers)

   Nothing here animates a number, counts anything down or manufactures
   urgency — §D-2 and §F rule those out. Motion is used only to pace a long,
   dense page and to show what belongs together.

   Every rule is gated on `.js`, so a script failure leaves a fully readable
   static page, and the whole part switches off under prefers-reduced-motion.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Reveal variants — `.reveal` alone still means "rise from below".
   Add data-reveal to pick a different character.
   -------------------------------------------------------------------------- */
.js .reveal[data-reveal="up"]    { transform: translate3d(0, 42px, 0); }
.js .reveal[data-reveal="left"]  { transform: translate3d(-36px, 0, 0); }
.js .reveal[data-reveal="right"] { transform: translate3d(36px, 0, 0); }
.js .reveal[data-reveal="down"]  { transform: translate3d(0, -22px, 0); }
.js .reveal[data-reveal="zoom"]  { transform: scale(.94); }
.js .reveal[data-reveal="flip"]  {
    transform: perspective(1000px) rotateX(10deg) translate3d(0, 30px, 0);
    transform-origin: 50% 100%;
}
.js .reveal[data-reveal="blur"] {
    filter: blur(12px);
    transform: translate3d(0, 16px, 0);
    transition-property: opacity, transform, filter;
}

/* A wipe rather than a fade: the element is fully opaque throughout and is
   uncovered from the top down.

   Done with a mask, NOT clip-path. An IntersectionObserver measures the
   target's clipped rectangle, so an element that clip-paths itself to nothing
   can never be told it has arrived — it would hang invisible forever. Masks
   are not part of that calculation. */
.js .reveal[data-reveal="mask"] {
    opacity: 1;
    transform: none;
    -webkit-mask-image: linear-gradient(180deg, #000 0 0);
            mask-image: linear-gradient(180deg, #000 0 0);
    -webkit-mask-size: 100% 0%;
            mask-size: 100% 0%;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    transition: -webkit-mask-size .95s var(--ease-soft), mask-size .95s var(--ease-soft);
}

/* Landed state, last so it wins over every variant above. */
.js .reveal.is-in { opacity: 1; transform: none; filter: none; }
.js .reveal[data-reveal="mask"].is-in { -webkit-mask-size: 100% 100%; mask-size: 100% 100%; }

/* Slower, longer entrance for a section's leading block. */
.js .reveal[data-reveal-speed="slow"] { transition-duration: 1.05s; }

/* --------------------------------------------------------------------------
   Media wipe — a photograph is uncovered instead of fading in.

   Applied to the wrapper, never the <img>, so it cannot fight the hover zoom
   those wrappers already own.
   -------------------------------------------------------------------------- */
/* The clip goes on the PICTURE, never on the wrapper.

   An IntersectionObserver measures the target's clipped rectangle: an element
   clipped to zero height never reports as intersecting, so a wrapper that
   clipped itself could never be told it had arrived. Clipping the image inside
   it leaves the observed box intact. */
.js [data-media] { overflow: hidden; }
.js [data-media] > picture { display: block; height: 100%; }

.js [data-media] > img,
.js [data-media] > picture > img {
    clip-path: inset(0 0 100% 0);
    /* and a slight push-in that settles as the photograph is uncovered */
    transform: scale(1.09);
    transition: clip-path 1.05s var(--ease-soft), transform 1.4s var(--ease-soft);
    transition-delay: calc(var(--i, 0) * var(--stagger));
}
.js [data-media].is-in > img,
.js [data-media].is-in > picture > img {
    clip-path: inset(0 0 0 0);
    transform: scale(1);
}

/* Hover zoom still wins once the element has landed. */
.js .figure:hover > img,
.js .feature__img:hover > img { transform: scale(1.05); }

/* --------------------------------------------------------------------------
   Parallax — the script writes a pixel offset into --par on anything carrying
   data-par. Layers only; never text, never anything interactive.
   -------------------------------------------------------------------------- */
.js [data-par] {
    transform: translate3d(0, var(--par, 0px), 0);
    will-change: transform;
}
/* The hero photograph keeps its own rule (PART 10) — it also scales. */
.js .hero__photo[data-par] { transform: translate3d(0, var(--par, 0px), 0) scale(1.04); }
.js .hero--light .hero__photo[data-par] { transform: translate3d(0, var(--par, 0px), 0); }

/* A photograph that drifts must be taller than its frame, or the frame empties
   at one edge. Inner-page heroes and the careers band are inset:0 — give them
   the headroom the drift needs, and clip it, or the overhang spills into the
   section below. */
.phero--photo { overflow: hidden; }
.js .phero--photo img[data-par],
.js .band__photo[data-par] { top: -9%; height: 118%; }

/* --------------------------------------------------------------------------
   Section furniture — small pieces that play as their block lands
   -------------------------------------------------------------------------- */
.js .reveal.is-in .sec-label__n {
    animation: numPop .55s var(--ease-back) both;
    animation-delay: calc(var(--i, 0) * var(--stagger) + 60ms);
}
@keyframes numPop {
    from { opacity: 0; transform: scale(.5) rotate(-8deg); }
    to   { opacity: 1; transform: none; }
}

/* The eyebrow's own rule draws itself in under the label. */
.js .section__head .eyebrow { position: relative; }
.js .section__head .eyebrow::after {
    content: '';
    position: absolute; left: 0; right: 0; bottom: -3px; height: 1.5px;
    background: currentColor; opacity: .35;
    transform: scaleX(0); transform-origin: 0 50%;
    transition: transform .7s var(--ease-soft) .25s;
}
.js .section__head.is-in .eyebrow::after,
.js .reveal.is-in .section__head .eyebrow::after { transform: scaleX(1); }

/* Fact lists tick down one line at a time. */
.js .reveal.is-in .ticks > li {
    animation: tickIn .5s var(--ease-soft) both;
    animation-delay: calc(140ms + var(--i, 0) * 55ms);
}
@keyframes tickIn {
    from { opacity: 0; transform: translate3d(-10px, 0, 0); }
    to   { opacity: 1; transform: none; }
}

/* Chips arrive as a shoal rather than all at once. */
.js .reveal.is-in .chip {
    animation: chipIn .45s var(--ease-back) both;
    animation-delay: calc(var(--i, 0) * 40ms);
}
@keyframes chipIn {
    from { opacity: 0; transform: scale(.9) translate3d(0, 6px, 0); }
    to   { opacity: 1; transform: none; }
}

/* Table rows settle in sequence — the figures themselves never change. */
.js tbody tr[data-row] {
    opacity: 0;
    transform: translate3d(0, 10px, 0);
    transition: opacity .45s var(--ease-out), transform .45s var(--ease-out);
    transition-delay: calc(var(--i, 0) * 45ms);
}
.js .is-in tbody tr[data-row] { opacity: 1; transform: none; }

/* A wide table that scrolls sideways says so, with a soft edge and a hint. */
.tablewrap { position: relative; }
.tablewrap::after {
    content: '';
    position: absolute; top: 0; right: 0; bottom: 0; width: 56px;
    background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.96));
    opacity: 0; transition: opacity .25s; pointer-events: none;
}
.tablewrap.has-overflow::after { opacity: 1; }
.tablewrap.is-end::after { opacity: 0; }
.section--tint .tablewrap::after {
    background: linear-gradient(90deg, rgba(247,248,250,0), rgba(247,248,250,.96));
}

/* --------------------------------------------------------------------------
   Timeline — the spine fills as you read past each entry
   -------------------------------------------------------------------------- */
.js .timeline { position: relative; }
.js .timeline::after {
    content: '';
    position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
    background: linear-gradient(180deg, var(--red-bright), var(--red));
    transform: scaleY(var(--fill, 0));
    transform-origin: 50% 0;
    transition: transform .18s linear;
}
/* The existing ::before rule owns the left offset; match it. */
.js .timeline::after { left: 5px; }

/* The reading hairline gains a soft glow at the leading edge. */
.hdr__progress { transform-origin: 0 50%; transition: opacity .3s; }
.hdr__progress::after {
    content: '';
    position: absolute; right: 0; top: -2px; bottom: -2px; width: 26px;
    background: radial-gradient(closest-side, rgba(224,30,55,.55), transparent);
}

/* --------------------------------------------------------------------------
   Back to top — appears once the page is genuinely long behind you.
   The ring is reading position, nothing else.
   -------------------------------------------------------------------------- */
.totop {
    position: fixed;
    right: clamp(16px, 3vw, 28px);
    bottom: clamp(16px, 3vw, 28px);
    z-index: 90;
    width: 44px; height: 44px;
    display: grid; place-items: center;
    padding: 0;
    border-radius: 50%;
    border: 1px solid var(--line-2);
    cursor: pointer;
    color: var(--ink);
    background: var(--paper);
    opacity: 0;
    transform: translate3d(0, 10px, 0);
    pointer-events: none;
    transition: opacity .25s var(--ease-out), transform .25s var(--ease-out), border-color .15s, background-color .15s;
}
.totop svg { width: 17px; height: 17px; }
.totop.is-on { opacity: 1; transform: none; pointer-events: auto; }
.totop:hover { color: var(--red); border-color: var(--red-bright); background: var(--paper-2); }
.totop:active { transform: scale(.96); }
@media print { .totop { display: none; } }

/* --------------------------------------------------------------------------
   Scroll-linked odds and ends
   -------------------------------------------------------------------------- */

/* The hero's scroll cue fades out as soon as it has been obeyed. */
.js .hero__cue { transition: opacity .3s linear; opacity: clamp(0, calc(1 - var(--sy, 0) * 3), 1); }

/* Stat cells wipe their figure up behind a mask. The VALUE never animates
   (§D-2) — only its arrival. */
.js .snap.is-in .snap__num {
    animation: numRise .6s var(--ease-soft) both;
    animation-delay: calc(var(--i, 0) * 70ms);
}
@keyframes numRise {
    from { opacity: 0; transform: translate3d(0, 60%, 0); }
    to   { opacity: 1; transform: none; }
}
.snap__cell { overflow: hidden; }


/* --------------------------------------------------------------------------
   Reduced motion — the whole part collapses to a plain, static page
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .js .reveal,
    .js [data-media],
    .js [data-media] > img,
    .js [data-media] > picture > img,
    .js tbody tr[data-row] {
        opacity: 1 !important;
        transform: none !important;
        filter: none !important;
        clip-path: none !important;
        transition: none !important;
    }
    .js [data-par] { transform: none !important; }
    .js .timeline::after { display: none; }
    .js .reveal.is-in .sec-label__n,
    .js .reveal.is-in .ticks > li,
    .js .reveal.is-in .chip,
    .js .snap.is-in .snap__num { animation: none !important; }
    .js .section__head .eyebrow::after { transform: scaleX(1); transition: none; }
    .js .hero__cue { opacity: 1; }
    .totop { transition: none; }
}

/* ==========================================================================
   PART 12 — Forms, properly dressed
   --------------------------------------------------------------------------
   Every form on the site — enquiry, careers, pharmacovigilance — is built from
   the same five primitives: .formbox, .form, .form__row, .field, .check. So
   they are restyled once, here, and every form inherits it.

   Priorities, in order: legibility, an obvious focus target, an error you
   cannot miss, and a hit area a thumb can actually land on. §I sets a 44px
   minimum for touch targets and 4.5:1 for every piece of text.
   ========================================================================== */

/* --------------------------------------------------------------------------
   The panel
   -------------------------------------------------------------------------- */
.formbox {
    position: relative;
    overflow: hidden;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 0;
    padding: clamp(1.35rem, 1rem + 1.6vw, 2.5rem);
    box-shadow: var(--sh-md);
}
/* A brand hairline across the top edge, so the panel reads as ours. */
.formbox::before {
    content: '';
    position: absolute; top: 0; left: 0; right: 0; height: 3px;
    background: linear-gradient(90deg, var(--red), var(--red-bright) 45%, #ff8577);
}

/* Progress across the required fields. Feedback on a long form — it is not a
   timer and nothing expires (§F). */
.formbox__progress {
    position: absolute; top: 0; left: 0; height: 3px; width: 100%;
    transform: scaleX(var(--done, 0)); transform-origin: 0 50%;
    background: var(--ok);
    transition: transform .35s var(--ease-out);
    pointer-events: none;
}

.formbox > h2:first-child, .formbox__head h2 { letter-spacing: -.018em; }
.formbox__head { margin-bottom: 1.75rem; }

/* --------------------------------------------------------------------------
   Rows and fields
   -------------------------------------------------------------------------- */
.form { display: grid; gap: 1.35rem; }
.form__row { display: grid; gap: 1.35rem; }
@media (min-width: 640px) {
    .form__row--2 { grid-template-columns: 1fr 1fr; }
    .form__row--3 { grid-template-columns: repeat(3, 1fr); }
}

.field { display: grid; gap: .4rem; position: relative; }

.field > label {
    display: flex;
    align-items: center;
    gap: .35rem;
    font-size: .8125rem;
    font-weight: 650;
    letter-spacing: .01em;
    color: var(--ink-2);
    transition: color .2s;
}
.field:focus-within > label { color: var(--red); }

/* The asterisk is decorative; the word "required" is what assistive tech
   reads, from the input's own required attribute. */
.field__req { color: var(--red-bright); font-weight: 800; line-height: 1; }
.field__hint { font-size: .8125rem; color: var(--faint); line-height: 1.5; }

/* --------------------------------------------------------------------------
   Controls
   -------------------------------------------------------------------------- */
.field input[type=text], .field input[type=email], .field input[type=tel],
.field input[type=password], .field input[type=search], .field input[type=url],
.field input[type=number], .field input[type=date],
.field select, .field textarea {
    width: 100%;
    min-height: 46px;
    padding: .7rem .9rem;
    font: inherit;
    font-size: .9375rem;
    line-height: 1.5;
    color: var(--ink);
    background: var(--paper);
    border: 1.5px solid var(--line-2);
    border-radius: 0;
    box-shadow: 0 1px 0 rgba(16,28,52,.02);
    transition: border-color .18s, box-shadow .18s, background-color .18s;
    -webkit-appearance: none;
    appearance: none;
}

.field input:hover:not(:disabled):not([readonly]),
.field select:hover:not(:disabled),
.field textarea:hover:not(:disabled) { border-color: #aab3c1; }

.field input:focus, .field select:focus, .field textarea:focus {
    outline: none;
    border-color: var(--red-bright);
    box-shadow: var(--sh-focus);
    background: var(--paper);
}
/* The browser's own outline would double up on the ring above. */
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible { outline: none; }

.field input::placeholder, .field textarea::placeholder { color: #9aa2b1; }

.field textarea {
    min-height: 140px;
    line-height: 1.6;
    resize: vertical;              /* the script grows it to fit as you type */
}

/* A pre-filled, non-editable value (the enquiry subject) should read as a
   statement of fact, not as something you failed to be allowed to type in. */
.field input[readonly] {
    background: var(--paper-2);
    color: var(--ink-2);
    border-style: dashed;
    cursor: default;
}
.field input[readonly]:focus { box-shadow: none; border-color: var(--line-2); }

.field input:disabled, .field select:disabled, .field textarea:disabled {
    background: var(--paper-3);
    color: var(--faint);
    cursor: not-allowed;
}

/* Select — native chevron replaced so it matches on every platform. */
.field select {
    padding-right: 2.6rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='m2.5 4.5 3.5 3.5 3.5-3.5' stroke='%235b6472' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .95rem center;
    background-size: 13px 13px;
    cursor: pointer;
}
.field select:focus {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='m2.5 4.5 3.5 3.5 3.5-3.5' stroke='%23e01e37' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   Validation state
   -------------------------------------------------------------------------- */
.field input[aria-invalid="true"], .field select[aria-invalid="true"], .field textarea[aria-invalid="true"] {
    border-color: var(--red-bright);
    background: var(--red-wash);
}
.field input[aria-invalid="true"]:focus,
.field select[aria-invalid="true"]:focus,
.field textarea[aria-invalid="true"]:focus { box-shadow: 0 0 0 4px rgba(224,30,55,.16); }

/* Answered correctly: a quiet tick, never a green wash. */
.field.is-ok > input:not([type=file]), .field.is-ok > select, .field.is-ok .pwfield > input {
    border-color: #b6d8c3;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='m3 8.4 3.2 3.2L13 4.8' stroke='%2314713d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .9rem center;
    background-size: 15px 15px;
}
.field.is-ok > input:not([type=file]) { padding-right: 2.5rem; }
.field.is-ok > select {
    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='m3 8.4 3.2 3.2L13 4.8' stroke='%2314713d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='m2.5 4.5 3.5 3.5 3.5-3.5' stroke='%235b6472' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat, no-repeat;
    background-position: right 2.4rem center, right .95rem center;
    background-size: 15px 15px, 13px 13px;
    padding-right: 4rem;
}

.field__err {
    display: flex;
    align-items: flex-start;
    gap: .35rem;
    font-size: .8125rem;
    font-weight: 600;
    color: var(--red);
    animation: errIn .28s var(--ease-out) both;
}
.field__err::before {
    content: '';
    flex: none;
    width: 15px; height: 15px;
    margin-top: .1em;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Ccircle cx='8' cy='8' r='6.9' stroke='%23c2192f' stroke-width='1.6'/%3E%3Cpath d='M8 4.6v4.2' stroke='%23c2192f' stroke-width='1.8' stroke-linecap='round'/%3E%3Ccircle cx='8' cy='11.4' r='.95' fill='%23c2192f'/%3E%3C/svg%3E") center/contain no-repeat;
}
@keyframes errIn {
    from { opacity: 0; transform: translate3d(0, -4px, 0); }
    to   { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   Checkboxes and radios — the native control, restyled, so keyboard and
   screen-reader behaviour is untouched.
   -------------------------------------------------------------------------- */
.check {
    display: flex;
    gap: .75rem;
    align-items: flex-start;
    padding: .85rem 1rem;
    font-size: .875rem;
    line-height: 1.55;
    color: var(--body);
    background: var(--paper-2);
    border: 1.5px solid var(--line);
    border-radius: 0;
    cursor: pointer;
    transition: border-color .18s, background-color .18s;
}
.check:hover { border-color: var(--line-2); background: var(--paper-3); }
.check:focus-within { border-color: var(--red-bright); box-shadow: var(--sh-focus); }
.check:has(input:checked) { border-color: #f0b7bf; background: var(--red-wash); }

.check input[type=checkbox], .check input[type=radio] {
    flex: none;
    width: 20px; height: 20px;
    margin: .1rem 0 0;
    display: grid; place-content: center;
    border: 1.5px solid var(--line-2);
    border-radius: 0;
    background: var(--paper);
    cursor: pointer;
    transition: background-color .18s, border-color .18s;
    -webkit-appearance: none;
    appearance: none;
}
.check input[type=radio] { border-radius: 50%; }

.check input[type=checkbox]:checked, .check input[type=radio]:checked {
    background-color: var(--red);
    border-color: var(--red);
}
.check input[type=checkbox]:checked::before {
    content: '';
    width: 13px; height: 13px;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='m3 8.4 3.2 3.2L13 4.8' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
    animation: tickPop .22s var(--ease-back);
}
.check input[type=radio]:checked::before {
    content: '';
    width: 8px; height: 8px; border-radius: 50%; background: #fff;
    animation: tickPop .22s var(--ease-back);
}
@keyframes tickPop { from { transform: scale(.4); } to { transform: none; } }

.check a { font-weight: 600; }

/* A group of radios reads as a set of choices, not a stack of loose rows. */
.field fieldset, .form fieldset { border: 0; display: grid; gap: .5rem; }
.form legend { font-size: .8125rem; font-weight: 650; color: var(--ink-2); margin-bottom: .5rem; }

/* --------------------------------------------------------------------------
   File upload — a drop target, with the native input laid over it so that
   click, keyboard, drag-and-drop and form validation all still work.
   -------------------------------------------------------------------------- */
.filefield {
    position: relative;
    display: flex;
    align-items: center;
    gap: .85rem;
    padding: 1rem 1.1rem;
    border: 1.5px dashed var(--line-2);
    border-radius: 0;
    background: var(--paper-2);
    transition: border-color .18s, background-color .18s;
}
.filefield input[type=file] {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    opacity: 0;
    cursor: pointer;
}
.filefield:hover, .filefield.is-drag { border-color: var(--red-bright); background: var(--red-wash); }
.filefield:focus-within { border-color: var(--red-bright); box-shadow: var(--sh-focus); }
.filefield.is-filled { border-style: solid; border-color: #b6d8c3; background: var(--ok-wash); }

.filefield__icon {
    flex: none;
    display: grid; place-items: center;
    width: 38px; height: 38px;
    border-radius: 0;
    background: var(--paper);
    border: 1px solid var(--line);
    color: var(--red);
}
.filefield.is-filled .filefield__icon { color: var(--ok); border-color: #bfe0cb; }
.filefield__icon svg { width: 18px; height: 18px; }

.filefield__text { display: grid; gap: .1rem; min-width: 0; }
.filefield__text b {
    font-size: .9375rem;
    color: var(--ink-2);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.filefield__text span { font-size: .8125rem; color: var(--faint); }

.filefield__clear {
    position: relative;
    z-index: 2;
    margin-left: auto;
    flex: none;
    display: grid; place-items: center;
    width: 30px; height: 30px;
    border: 1px solid var(--line);
    border-radius: 0;
    background: var(--paper);
    color: var(--muted);
    cursor: pointer;
    transition: color .18s, border-color .18s;
}
.filefield__clear:hover { color: var(--red); border-color: var(--red-bright); }
.filefield__clear svg { width: 13px; height: 13px; }

/* --------------------------------------------------------------------------
   Character count — appears once you start writing, never as a limit you are
   being pushed against.
   -------------------------------------------------------------------------- */
.field__count {
    justify-self: end;
    font-size: .75rem;
    font-variant-numeric: tabular-nums;
    color: var(--faint);
    opacity: 0;
    transition: opacity .2s, color .2s;
}
.field:focus-within .field__count, .field__count.is-on { opacity: 1; }
.field__count.is-near { color: var(--warn); font-weight: 600; }

/* --------------------------------------------------------------------------
   Actions row
   -------------------------------------------------------------------------- */
.form__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .85rem 1.15rem;
    padding-top: .35rem;
}
.form__actions .btn { min-height: 46px; }
.form__actions .form__note { font-size: .8125rem; color: var(--faint); }

/* Submitting: the label is replaced by a spinner so a slow connection cannot
   produce a duplicate enquiry, and the reason for the wait is visible. */
.btn { position: relative; overflow: hidden; }
.btn.is-busy { pointer-events: none; opacity: .85; }
.btn.is-busy::before {
    content: '';
    width: 15px; height: 15px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* A light sweep across a primary button on hover — one moving highlight, no
   pulsing and nothing that reads as a countdown. */
.btn--primary::after, .btn--navy::after {
    content: '';
    position: absolute; top: 0; left: -30%;
    width: 30%; height: 100%;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,.22), transparent);
    transform: skewX(-18deg);
    transition: left .55s var(--ease-out);
    pointer-events: none;
}
.btn--primary:hover::after, .btn--navy:hover::after { left: 130%; }
.btn:active { transform: translateY(1px); }

/* --------------------------------------------------------------------------
   Alerts — the answer to a submitted form, so they carry more weight than a
   line of tinted text.
   -------------------------------------------------------------------------- */
.alert {
    display: grid;
    gap: .35rem;
    padding: 1.15rem 1.25rem 1.15rem 3.35rem;
    position: relative;
    border-radius: 0;
    border: 1px solid;
    font-size: .9375rem;
    line-height: 1.6;
    animation: errIn .4s var(--ease-soft) both;
}
.alert::before {
    content: '';
    position: absolute; left: 1.15rem; top: 1.2rem;
    width: 20px; height: 20px;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}
.alert--ok::before {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'%3E%3Ccircle cx='10' cy='10' r='9' fill='%2314713d'/%3E%3Cpath d='m5.8 10.3 2.8 2.8 5.6-6' stroke='white' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.alert--warn::before {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M10 2.6 18.4 17H1.6L10 2.6Z' fill='%238a5a00'/%3E%3Cpath d='M10 7.6v4' stroke='white' stroke-width='1.7' stroke-linecap='round'/%3E%3Ccircle cx='10' cy='14.4' r='1' fill='white'/%3E%3C/svg%3E");
}
.alert--err::before {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'%3E%3Ccircle cx='10' cy='10' r='9' fill='%23c2192f'/%3E%3Cpath d='M10 5.4v5' stroke='white' stroke-width='1.9' stroke-linecap='round'/%3E%3Ccircle cx='10' cy='14' r='1.1' fill='white'/%3E%3C/svg%3E");
}
.alert strong { color: inherit; font-size: 1rem; }
/* A reference number is something people copy down — set it as data. */
.alert .ref, .alert strong .ref {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-variant-numeric: tabular-nums;
    letter-spacing: .02em;
}

/* Summary of what failed, shown above a form after a server round-trip. */
.form__errors { margin-bottom: 1.25rem; }
.form__errors ul { margin: .35rem 0 0; padding-left: 1.15rem; }
.form__errors li { font-size: .875rem; }

@media (prefers-reduced-motion: reduce) {
    .field__err, .alert { animation: none; }
    .btn--primary::after, .btn--navy::after { display: none; }
    .check input:checked::before { animation: none; }
}

/* ==========================================================================
   PART 13 — The full-bleed photographic hero
   --------------------------------------------------------------------------
   The photograph runs edge to edge and top to bottom. Nothing white is laid
   over it: the only overlay is a dark gradient, and that is there for one
   reason — §I requires white type to clear 4.5:1 wherever the photograph
   happens to be bright. It is weighted to the left, so the right two-thirds of
   the image stay close to untouched.
   ========================================================================== */
.hero--full {
    min-height: min(94vh, 900px);
    display: flex;
    align-items: center;
    /* The overlay header sits on top of this, so the copy needs to clear it. */
    padding-block: calc(var(--header-h) + clamp(3rem, 2rem + 4vw, 6rem))
                   clamp(3.5rem, 2.5rem + 4vw, 6.5rem);
}

.hero--full .hero__photo {
    height: 122%;
    top: -11%;
    animation: none;                       /* the drift is scroll-driven now */
    object-position: 65% 45%;
    transform: translate3d(0, var(--par, 0px), 0) scale(1.03);
}

/* NO overlay. Not a scrim, not a tint, not a wash — the photograph is shown
   exactly as it is.

   That is only safe because the picture was chosen for it: white type sits over
   a region measured at 10:1 contrast at its brightest point, well clear of the
   4.5:1 §I needs. Swapping in a brighter photograph would break that, so
   whoever replaces hero.jpg must check the left half is dark first. */
.hero--full::before,
.hero--full::after { content: none; }

.hero--full h1 { max-width: 20ch; }
.hero--full .hero__sub { max-width: 56ch; }
.hero--full .hero__facts { max-width: 700px; }

/* The capacity card floats over the photographed side rather than hanging off
   the left edge of the copy. */
.hero--full .hero__badge {
    left: auto; right: 0;
    top: auto; bottom: clamp(120px, 16vh, 190px);
    background: rgba(255,255,255,.93);
}
@media (max-width: 1099px) { .hero--full .hero__badge { display: none; } }

/* Credential pills sit on their own rule at the foot of the hero. */
.hero--full .hero__marks {
    margin-top: 2.5rem;
    padding-top: 1.75rem;
    border-top: 1px solid rgba(255,255,255,.16);
}

.hero--full .hero__cue { color: rgba(255,255,255,.72); }
.hero--full .hero__cue i { background: linear-gradient(180deg, rgba(255,255,255,.6), transparent); }

/* On a phone the crop tightens onto the darkest part of the frame instead of
   reaching for a gradient. */
@media (max-width: 640px) {
    .hero--full .hero__photo { object-position: 32% 50%; }
}

/* ==========================================================================
   PART 14 — The header
   --------------------------------------------------------------------------
   One flat, solid bar everywhere — on an ordinary page, over a photographic
   hero, scrolled or not. No transparency, no blur.
   ========================================================================== */

.hdr--over:not(.is-stuck) {
    background: var(--paper);
}

/* A touch more lift once scrolled, on top of the always-on floating shadow. */
.hdr.is-stuck,
.hdr--over.is-stuck,
.hdr--glass.is-stuck {
    box-shadow: 0 2px 4px rgba(16, 28, 52, .1), 0 22px 46px -14px rgba(16, 28, 52, .44);
}

/* ==========================================================================
   PART 15 — Photography components
   --------------------------------------------------------------------------
   Two small pieces used across the site: a photograph heading a card, and a
   strip of framed photographs. Both are decorative — §K governs what they may
   be captioned as, and the caption is written in the template, not here.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Framed figure — caption plus the illustrative note
   -------------------------------------------------------------------------- */
.figure figcaption .imgnote {
    display: block;
    margin-top: .15rem;
    font-size: .75rem;
}

/* ==========================================================================
   PART 16 — Long-page choreography
   ========================================================================== */

/* --------------------------------------------------------------------------
   The hero hands the page over
   The copy lifts and dims as you scroll past it; the photograph stays put and
   drifts at its own rate, so the two separate as you leave.
   -------------------------------------------------------------------------- */
.js .hero__inner--handoff {
    opacity: clamp(0, calc(1.75 - var(--sy, 0) * 1.9), 1);
    transform: translate3d(0, calc(var(--sy, 0) * -70px), 0);
    will-change: opacity, transform;
}
.js .hero--full .hero__badge { transform: translate3d(0, calc(var(--sy, 0) * -34px), 0); }

/* --------------------------------------------------------------------------
   Chapter rail — where you are, in the page's own numbering
   -------------------------------------------------------------------------- */
.chapters {
    position: fixed;
    left: max(14px, calc((100vw - var(--wrap)) / 2 - 92px));
    top: 50%;
    z-index: 80;
    display: none;
    flex-direction: column;
    gap: .1rem;
    transform: translateY(-50%);
    opacity: 0;
    transition: opacity .35s var(--ease-out);
    pointer-events: none;
}
@media (min-width: 1340px) { .chapters { display: flex; } }
.chapters.is-on { opacity: 1; pointer-events: auto; }

.chapters__item {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .3rem 0;
    text-decoration: none;
    color: var(--faint);
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
}
.chapters__n {
    position: relative;
    width: 26px;
    font-variant-numeric: tabular-nums;
    color: var(--line-2);
    transition: color .3s;
}
/* A hairline that grows into a full rule for the section you are in. */
.chapters__n::after {
    content: '';
    position: absolute; right: -8px; top: 50%;
    width: 10px; height: 1.5px;
    background: currentColor;
    transform: scaleX(.5); transform-origin: 100% 50%;
    transition: transform .3s var(--ease-out), background-color .3s;
}
.chapters__l {
    max-width: 0;
    overflow: hidden;
    white-space: nowrap;
    opacity: 0;
    transition: max-width .4s var(--ease-out), opacity .3s;
}
.chapters__item:hover .chapters__l,
.chapters__item.is-here .chapters__l { max-width: 160px; opacity: 1; }

.chapters__item:hover .chapters__n { color: var(--muted); }
.chapters__item.is-here { color: var(--ink-2); }
.chapters__item.is-here .chapters__n { color: var(--red); }
.chapters__item.is-here .chapters__n::after { transform: scaleX(1.6); }

@media print { .chapters { display: none; } }

/* --------------------------------------------------------------------------
   A statement that reads itself in
   The words start as a ghost of themselves and reach full ink as the line
   crosses the middle of the screen. Nothing moves — only weight of colour.
   -------------------------------------------------------------------------- */
.js [data-fill].is-filling .split-unit {
    color: rgba(20, 23, 29, .2);
    transition: color .45s var(--ease-out);
}
.js [data-fill].is-filling .split-unit.is-read { color: var(--ink); }

/* On a dark section the ghost has to be light, not dark. */
.js .section--navy [data-fill].is-filling .split-unit,
.js .band [data-fill].is-filling .split-unit,
.js .section--photo [data-fill].is-filling .split-unit { color: rgba(255, 255, 255, .28); }
.js .section--navy [data-fill].is-filling .split-unit.is-read,
.js .band [data-fill].is-filling .split-unit.is-read,
.js .section--photo [data-fill].is-filling .split-unit.is-read { color: #fff; }

@media (prefers-reduced-motion: reduce) {
    .js .hero__inner--handoff { opacity: 1 !important; transform: none !important; }
    .js .hero--full .hero__badge { transform: none !important; }
    .js [data-fill].is-filling .split-unit { color: inherit !important; }
}

/* ==========================================================================
   PART 17 — Inner-page furniture
   --------------------------------------------------------------------------
   Forty-odd inner pages are built from the same handful of parts: a photo
   hero, a split with an aside, a data table, a spec list, a steps strip. They
   are upgraded here, once, rather than page by page.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Page hero — more room, bigger type, and the photograph slowly settling
   -------------------------------------------------------------------------- */
.phero--photo {
    padding-block: clamp(3.25rem, 2.5rem + 4vw, 6rem);
    display: flex;
    align-items: flex-end;
    min-height: min(52vh, 460px);
}
.phero h1 {
    font-size: clamp(2.1rem, 1.5rem + 2.6vw, 3.25rem);
    letter-spacing: -.028em;
    line-height: 1.06;
    max-width: 20ch;
}
.phero--photo .lead { max-width: 62ch; }

/* The photograph settles from a slight push-in on arrival — the same language
   as the reveals, so the page feels like one piece. */
.js .phero--photo img {
    animation: pheroSettle 1.6s var(--ease-soft) both;
}
@keyframes pheroSettle {
    from { transform: scale(1.09); opacity: .55; }
    to   { transform: scale(1);    opacity: 1; }
}

/* Crumbs read as a quiet line above the title, not as another heading. */
.phero--photo .crumbs { margin-bottom: 1.1rem; font-size: .8125rem; letter-spacing: .01em; }

/* --------------------------------------------------------------------------
   Split layouts — the aside travels with you
   -------------------------------------------------------------------------- */
@media (min-width: 1000px) {
    .split > aside,
    .split > .aside-sticky {
        position: sticky;
        top: calc(var(--header-h) + 24px);
    }
}

/* --------------------------------------------------------------------------
   Data tables — these pages ARE the tables, so they get treated as such
   -------------------------------------------------------------------------- */
.tablewrap {
    background: var(--paper);
    box-shadow: var(--sh-sm);
}
table.data thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--paper-3);
    color: var(--ink);
    box-shadow: inset 0 -1px 0 var(--line-2);
    border-bottom: 0;
}
table.data tbody tr { transition: background-color .15s; }
table.data tbody tr:nth-child(even) { background: rgba(247, 248, 250, .7); }
table.data tbody tr:hover { background: var(--red-wash); }
table.data tbody th[scope="row"] { color: var(--ink); font-weight: 650; }
table.data td, table.data th { padding: .85rem 1.1rem; }

/* The row a map click sends you to. */
table.data tr.is-flash { animation: rowFlash 1.6s ease-out; }
@keyframes rowFlash {
    0%   { background: rgba(224, 30, 55, .16); }
    100% { background: transparent; }
}

/* --------------------------------------------------------------------------
   Spec lists — label and value, with the label sitting quietly to one side
   -------------------------------------------------------------------------- */
.spec__row { transition: background-color .15s; }
.spec__row:hover { background: var(--paper-2); }
@media (min-width: 640px) {
    .spec__row { padding-inline: .65rem; margin-inline: -.65rem; border-radius: 0; }
}
.spec__k { letter-spacing: .01em; }

/* --------------------------------------------------------------------------
   Steps — numbered process strips
   -------------------------------------------------------------------------- */
.steps__item { position: relative; overflow: hidden; }
.steps__item::after {
    content: '';
    position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
    background: var(--red-bright);
    transform: scaleY(0); transform-origin: 50% 0;
    transition: transform .5s var(--ease-soft);
}
.js .reveal.is-in .steps__item::after,
.js .steps.is-in .steps__item::after { transform: scaleY(1); }
.js .steps.is-in .steps__item:nth-child(2)::after { transition-delay: .08s }
.js .steps.is-in .steps__item:nth-child(3)::after { transition-delay: .16s }
.js .steps.is-in .steps__item:nth-child(4)::after { transition-delay: .24s }
.js .steps.is-in .steps__item:nth-child(5)::after { transition-delay: .32s }

/* --------------------------------------------------------------------------
   Next steps — three doors at the foot of a page that would otherwise stop
   -------------------------------------------------------------------------- */
.nextsteps { background: var(--paper-2); border-top: 1px solid var(--line); }
.nextsteps__grid { display: grid; gap: 16px; }
@media (min-width: 780px) { .nextsteps__grid { grid-template-columns: repeat(3, 1fr); } }

.nextsteps__card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: .4rem;
    padding: 1.5rem 1.4rem;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 0;
    text-decoration: none;
    overflow: hidden;
    transition: transform .25s var(--ease-soft), box-shadow .25s, border-color .2s;
}
.nextsteps__card:hover { transform: translateY(-4px); box-shadow: var(--sh-lg); border-color: var(--line-2); }
.nextsteps__card::before {
    content: '';
    position: absolute; inset: 0 auto 0 0; width: 3px;
    background: linear-gradient(180deg, var(--red-bright), #ff8577);
    transform: scaleY(0); transform-origin: 50% 0;
    transition: transform .3s var(--ease-soft);
}
.nextsteps__card:hover::before { transform: scaleY(1); }
.nextsteps__card b { color: var(--ink); font-size: 1.0625rem; font-weight: 650; }
.nextsteps__card span { color: var(--muted); font-size: .9375rem; }
.nextsteps__card .tlink { margin-top: auto; padding-top: .75rem; }

@media (prefers-reduced-motion: reduce) {
    .js .phero--photo img { animation: none; }
    .steps__item::after { transform: scaleY(1); transition: none; }
}

/* ==========================================================================
   PART 18 — A wider motion vocabulary
   --------------------------------------------------------------------------
   Section after section of the same rise reads as a template. The engine now
   cycles a different entrance per section, and two scroll-linked moments were
   added that do not exist anywhere else on the site.
   ========================================================================== */

/* --- New entrance variants ------------------------------------------------ */

/* Rises out from under the section above it, like a card being dealt. The
   uncovering is a mask, for the reason given against the "mask" variant. */
.js .reveal[data-reveal="curtain"] {
    transform: translate3d(0, 64px, 0) scale(.985);
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 22%);
            mask-image: linear-gradient(180deg, transparent 0, #000 22%);
    -webkit-mask-size: 100% 260%;
            mask-size: 100% 260%;
    -webkit-mask-position: 0 100%;
            mask-position: 0 100%;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    transition: opacity .8s var(--ease-soft), transform .8s var(--ease-soft),
                -webkit-mask-position .9s var(--ease-soft), mask-position .9s var(--ease-soft);
}
.js .reveal[data-reveal="curtain"].is-in { -webkit-mask-position: 0 0; mask-position: 0 0; }

/* Unfolds from its own top edge. */
.js .reveal[data-reveal="unfold"] {
    transform: perspective(1200px) rotateX(-16deg) translate3d(0, 22px, 0);
    transform-origin: 50% 0;
}

/* Wiped in from the left, the text arriving with the block. */
.js .reveal[data-reveal="wipe"] {
    opacity: 1;
    transform: none;
    -webkit-mask-image: linear-gradient(90deg, #000 0 0);
            mask-image: linear-gradient(90deg, #000 0 0);
    -webkit-mask-size: 0% 100%;
            mask-size: 0% 100%;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    transition: -webkit-mask-size .85s var(--ease-soft), mask-size .85s var(--ease-soft);
}
.js .reveal[data-reveal="wipe"].is-in { -webkit-mask-size: 100% 100%; mask-size: 100% 100%; }

/* Settles out of a soft focus. */
.js .reveal[data-reveal="focus"] {
    filter: blur(14px);
    transform: scale(1.03);
    transition-property: opacity, transform, filter;
    transition-duration: .95s;
}

/* Swings up from the lower-left, very slightly. */
.js .reveal[data-reveal="swing"] {
    transform: translate3d(-18px, 30px, 0) rotate(-1.4deg);
}

/* THE LANDED STATE FOR EVERY VARIANT, and it must be the last word.

   PART 11's `.reveal.is-in` rule carries the same weight as a variant rule, so
   any variant declared after it would keep its starting transform — a section
   would arrive and then sit there blurred or shifted. Naming both the
   attribute and the class outranks every variant above, wherever it was
   declared. */
.js .reveal[data-reveal].is-in {
    opacity: 1;
    transform: none;
    filter: none;
}

/* --- A full-bleed band photograph that breathes as it crosses ------------- */
.js .band__photo[data-zoom] {
    transform: translate3d(0, var(--par, 0px), 0) scale(var(--zoom, 1.06));
    transform-origin: 50% 50%;
}

@media (prefers-reduced-motion: reduce) {
    .js .reveal[data-reveal="curtain"],
    .js .reveal[data-reveal="mask"],
    .js .reveal[data-reveal="wipe"] {
        -webkit-mask-image: none !important;
                mask-image: none !important;
    }
    .js .band__photo[data-zoom] { transform: none !important; }
}

/* ==========================================================================
   PART 19 — The light hero
   --------------------------------------------------------------------------
   Same full-bleed photograph, opposite polarity: a bright picture with ink
   type on it, and still no overlay of any kind.

   The rule for replacing hero.jpg is the mirror of the dark version — the left
   half must stay BRIGHT. Every text zone here was measured against the bare
   photograph and clears 4.5:1 (§I). A darker picture would break that.
   ========================================================================== */
.hero--bright { background: var(--paper); }
.hero--bright .hero__photo { object-position: 6% 50%; }

/* --- Ink type on the photograph ------------------------------------------ */
.hero--bright h1 { color: var(--ink); }
.hero--bright .lead,
.hero--bright .hero__sub { color: var(--ink-2); }

.hero--bright .hero__eyebrow {
    background: var(--paper);
    border-color: var(--line);
    color: var(--ink-2);
    box-shadow: var(--sh-sm);
}
.hero--bright .hero__eyebrow b { color: var(--ink); }
.hero--bright .hero__eyebrow .ico { color: var(--red); }

.hero--bright .btn--outline {
    color: var(--ink);
    border-color: rgba(20, 23, 29, .28);
    background: var(--paper);
}
.hero--bright .btn--outline:hover {
    background: #fff;
    border-color: var(--ink);
    color: var(--ink);
}

/* --- Facts and credential pills ------------------------------------------ */
.hero--bright .hero__facts { border-top-color: rgba(20, 23, 29, .14); }
.hero--bright .hero__fact b { color: var(--ink); }
.hero--bright .hero__fact span { color: var(--muted); }

.hero--bright .hero__marks { border-top-color: rgba(20, 23, 29, .12); }
.hero--bright .hero__mark {
    background: var(--paper);
    border-color: var(--line);
    color: var(--body);
}
.hero--bright .hero__mark .ico { color: var(--red); }

/* --- The floating capacity card, and the scroll cue ---------------------- */
.hero--bright .hero__badge {
    background: var(--paper);
    border-color: var(--line);
}
.hero--bright .hero__cue { color: var(--muted); }
.hero--bright .hero__cue i { background: linear-gradient(180deg, var(--line-2), transparent); }

/* --- The section below closes onto paper, not onto navy ------------------ */
.hero--bright + .pulse-rule { background: var(--paper); }

/* On a phone the copy stacks over the brightest part of the frame. */
@media (max-width: 640px) {
    .hero--bright .hero__photo { object-position: 30% 50%; }
}

/* ==========================================================================
   PART 20 — Sign-in
   --------------------------------------------------------------------------
   A split screen: the form on paper, a photograph beside it. On a phone the
   photograph steps aside entirely — nobody signs in to look at a picture.
   ========================================================================== */
.auth-body { background: var(--paper-2); }

.auth {
    display: grid;
    min-height: 100vh;
    min-height: 100dvh;
}
@media (min-width: 900px) { .auth { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
@media (min-width: 1400px) { .auth { grid-template-columns: minmax(0, 560px) 1fr; } }

/* --- The form side -------------------------------------------------------- */
.auth__panel {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(1.5rem, 1rem + 3vw, 3.5rem);
    background: var(--paper);
}
.auth__inner { width: 100%; max-width: 420px; }

.auth__brand { display: inline-flex; text-decoration: none; margin-bottom: clamp(1.75rem, 1rem + 3vw, 3rem); }
.auth__brand img, .auth__brand svg { height: 40px; width: auto; }

.auth__head { margin-bottom: 1.75rem; }
.auth__chip {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .3rem .7rem;
    margin-bottom: .9rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--paper-2);
    font-size: .75rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted);
}
.auth__chip svg { width: 13px; height: 13px; color: var(--red); }

.auth h1 { font-size: clamp(1.6rem, 1.3rem + 1.2vw, 2rem); letter-spacing: -.02em; }
.auth__sub { margin-top: .6rem; color: var(--muted); font-size: .9375rem; }

.auth__form { margin-top: 1.5rem; }
.auth .alert { margin-bottom: 1.25rem; }

/* Password field with a reveal control that never overlaps the text. */
.pwfield { position: relative; display: block; }
.pwfield input { padding-right: 3rem !important; }
.pwfield__eye {
    position: absolute; right: 6px; top: 50%;
    transform: translateY(-50%);
    display: grid; place-items: center;
    width: 36px; height: 36px;
    border: 0; border-radius: 0;
    background: transparent;
    color: var(--faint);
    cursor: pointer;
    transition: color .15s, background-color .15s;
}
.pwfield__eye:hover { color: var(--ink-2); background: var(--paper-2); }
.pwfield__eye svg { width: 18px; height: 18px; }
.pwfield__eye[aria-pressed="true"] { color: var(--red); }
/* A struck-through eye once the password is showing. */
.pwfield__eye[aria-pressed="true"]::after {
    content: '';
    position: absolute; left: 8px; right: 8px; top: 50%;
    height: 1.6px; background: currentColor;
    transform: rotate(-38deg);
}

.auth__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}
/* The "keep me signed in" tick is not a consent panel — strip the framing. */
.check.check--bare {
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    font-size: .875rem;
}
.check.check--bare:hover { background: none; border: 0; }
.check.check--bare:focus-within { box-shadow: none; }
.check.check--bare:has(input:checked) { background: none; border: 0; }

.auth__help { font-size: .875rem; font-weight: 600; text-decoration: none; }
.auth__help:hover { text-decoration: underline; }
.auth__note { margin-top: .25rem; }

.auth__divider {
    display: flex; align-items: center; gap: 1rem;
    margin: 1.75rem 0 1rem;
    color: var(--faint); font-size: .8125rem;
}
.auth__divider::before, .auth__divider::after {
    content: ''; flex: 1; height: 1px; background: var(--line);
}

.auth__foot { margin-top: 2rem; }
.tlink--back::after { content: none; }
.tlink--back::before { content: '\2190'; transition: transform .15s; }
.tlink--back:hover::before { transform: translateX(-3px); }

/* --- The photograph side -------------------------------------------------- */
.auth__art { position: relative; display: none; overflow: hidden; background: var(--navy); }
@media (min-width: 900px) { .auth__art { display: block; } }

.auth__art img {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    animation: pheroSettle 1.8s var(--ease-soft) both;
}
/* White type over a photograph needs the floor under it (§I). */
.auth__art::after {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(9,14,24,.28) 0%, rgba(9,14,24,.55) 55%, rgba(9,14,24,.9) 100%);
}

.auth__quote {
    position: absolute; left: 0; right: 0; bottom: 0;
    z-index: 1;
    padding: clamp(1.75rem, 1rem + 3vw, 3rem);
    color: #fff;
}
.auth__kicker {
    display: inline-block;
    font-size: .75rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
    color: #ff8577;
    margin-bottom: .75rem;
}
.auth__quote p {
    font-size: clamp(1.0625rem, 1rem + .5vw, 1.35rem);
    line-height: 1.45;
    max-width: 24ch;
    color: #fff;
}
.auth__meta { display: block; margin-top: 1rem; font-size: .8125rem; color: #b9c6d8; }

/* ==========================================================================
   PART 21 — Directional media wipes
   --------------------------------------------------------------------------
   A photograph can be uncovered from either side instead of top-down. The clip
   sits on the image, never on the observed wrapper (see PART 11) — so the
   entrance can still be told when it has arrived.
   ========================================================================== */
.js [data-media][data-wipe="left"]  > img,
.js [data-media][data-wipe="left"]  > picture > img { clip-path: inset(0 100% 0 0); }
.js [data-media][data-wipe="right"] > img,
.js [data-media][data-wipe="right"] > picture > img { clip-path: inset(0 0 0 100%); }

/* Landed — last word, and specific enough to outrank both directions. */
.js [data-media][data-wipe].is-in > img,
.js [data-media][data-wipe].is-in > picture > img {
    clip-path: inset(0 0 0 0);
    transform: scale(1);
}

/* A wipe that comes from the side reads better with a matching drift. */
.js [data-media][data-wipe="left"]  > picture > img { transform: scale(1.09) translateX(-2.5%); }
.js [data-media][data-wipe="right"] > picture > img { transform: scale(1.09) translateX(2.5%); }

@media (prefers-reduced-motion: reduce) {
    .js [data-media][data-wipe] > img,
    .js [data-media][data-wipe] > picture > img {
        clip-path: none !important;
        transform: none !important;
    }
}

/* ==========================================================================
   PART 22 — A cleaner, more editorial homepage
   --------------------------------------------------------------------------
   Three pieces reworked so the page reads as image-led and calm rather than
   as a stack of bordered boxes: the snapshot numbers, the purpose block, and
   the therapeutic-area tiles. No content was removed to get there.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Numbered rows — a list of routes to market, not a grid of cards.
   -------------------------------------------------------------------------- */
.rows { border-top: 1px solid var(--line); margin-top: 54px; }
.row {
    position: relative;
    display: grid;
    grid-template-columns: 56px minmax(200px, 1.05fr) 1.5fr 40px;
    align-items: center;
    gap: 28px;
    padding: 30px 12px 30px 0;
    border-bottom: 1px solid var(--line);
    text-decoration: none;
}
.row::before {
    content: '';
    position: absolute; left: 0; bottom: -1px;
    width: 100%; height: 1px;
    background: var(--red);
    transform: scaleX(0);
    transform-origin: 0;
    transition: transform .45s var(--ease-soft);
}
.row:hover::before { transform: scaleX(1); }
.row__n {
    font-size: .8rem; font-weight: 600; letter-spacing: .04em;
    font-variant-numeric: tabular-nums;
    color: var(--faint);
    transition: color .3s var(--ease-soft), transform .32s var(--ease-soft);
}
.row:hover .row__n { color: var(--red); transform: translateX(5px); }
.row__t {
    color: var(--ink);
    font-size: clamp(1.15rem, 1.9vw, 1.5rem);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -.02em;
    transition: color .3s var(--ease-soft);
}
.row:hover .row__t { color: var(--red); }
.row__tag {
    display: inline-block;
    margin-left: 12px;
    font-size: .66rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
    color: var(--red);
    vertical-align: 3px;
}
.row__d { color: var(--muted); font-size: 1rem; line-height: 1.5; }
.row__a {
    justify-self: end;
    color: var(--faint);
    transition: color .3s var(--ease-soft), transform .3s var(--ease-soft);
}
.row:hover .row__a { color: var(--red); transform: translateX(5px); }

@media (max-width: 760px) {
    .row {
        grid-template-columns: 40px 1fr 28px;
        align-items: start;
        gap: 16px;
        padding: 26px 0;
    }
    .row__d { grid-column: 2 / 3; }
    .row__a { grid-area: 1 / 3; align-self: center; }
}

/* --------------------------------------------------------------------------
   Hairline grid — photo, rule, heading, one line. No badges, no shadows: the
   1px gap over a --line background draws every divider for free.
   -------------------------------------------------------------------------- */
.hairgrid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    margin-top: 54px;
}
@media (max-width: 1000px) { .hairgrid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px)  { .hairgrid { grid-template-columns: 1fr; } }

.hairtile { background: var(--paper); text-decoration: none; display: block; }
.hairtile__fig { display: block; aspect-ratio: 4 / 5; overflow: hidden; background: var(--paper-3); }
.hairtile__fig img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease-soft); }
.hairtile:hover .hairtile__fig img { transform: scale(1.04); }
.hairtile__body { display: block; padding: 26px 28px 32px; }
.hairtile__rule { display: block; width: 32px; height: 2px; background: var(--red); margin-bottom: 16px; }
.hairtile__body h3 { font-size: 1.0625rem; margin-bottom: .4rem; }
.hairtile__body p { color: var(--muted); font-size: .9375rem; line-height: 1.5; }

@media (prefers-reduced-motion: reduce) {
    .hairtile:hover .hairtile__fig img { transform: none; }
}

/* --------------------------------------------------------------------------
   Partner teaser — copy and CTA on one side, a numbered list of what an
   appointment includes on the other.
   -------------------------------------------------------------------------- */
.partner-teaser { display: grid; gap: 3rem; }
@media (min-width: 900px) { .partner-teaser { grid-template-columns: 1fr 1fr; align-items: start; } }

.partner-list { display: grid; gap: 1.75rem; margin-top: .5rem; }
.partner-list li { display: flex; gap: 1.1rem; align-items: flex-start; }
.partner-list b {
    flex: none;
    font-size: 1.125rem; font-weight: 800; color: var(--red);
    font-variant-numeric: tabular-nums;
}
.partner-list h3 { font-size: 1rem; margin-bottom: .3rem; }
.partner-list p { color: var(--muted); font-size: .9375rem; line-height: 1.55; }

/* --------------------------------------------------------------------------
   Capability grid — a plain icon, heading and line, in a hairline grid.
   For a set of functions or steps where a photograph would just be filler.
   -------------------------------------------------------------------------- */
.cap__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    margin-top: 3.5rem;
}
.cap__cell {
    display: block;
    background: var(--paper);
    padding: 34px 32px 38px;
    text-decoration: none;
    transition: background-color .25s var(--ease-soft);
}
a.cap__cell:hover { background: var(--paper-2); }
.cap__ico { display: block; width: 30px; height: 30px; color: var(--red); margin-bottom: 22px; }
.cap__cell h2, .cap__cell h3 { font-size: 1.0625rem; margin-bottom: .5rem; }
.cap__cell p { color: var(--muted); font-size: .9375rem; line-height: 1.5; }
.cap__cell .card__kicker { display: block; font-size: .75rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--faint); margin-bottom: .5rem; }
.cap__cell .tlink { display: inline-block; margin-top: 1rem; }

.cap__grid--2 { grid-template-columns: repeat(2, 1fr); }

@media (max-width: 900px) { .cap__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .cap__grid { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   Process — one photograph, then the steps as plain text, not cards.
   -------------------------------------------------------------------------- */
.section--rule { background: var(--paper-2); border-block: 1px solid var(--line); }

.proc__fig { max-height: 340px; margin-top: 52px; overflow: hidden; }
.proc__fig img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 45%; }

.proc__steps {
    display: grid;
    grid-template-columns: 1.15fr 1fr 1fr;
    gap: 0;
    margin-top: 48px;
    border-top: 1px solid var(--line-2);
}
.step { position: relative; padding: 34px 34px 8px 0; }
.step::before {
    content: '';
    position: absolute; top: -1px; left: 0;
    width: 44px; height: 3px;
    background: var(--red);
}
.step + .step { padding-left: 34px; border-left: 1px solid var(--line); }
.step + .step::before { left: 34px; }
.step h3 { font-size: 1.2rem; font-weight: 600; letter-spacing: -.02em; margin-bottom: 12px; }
.step p { color: var(--muted); font-size: .97rem; line-height: 1.55; }

@media (max-width: 760px) {
    .proc__steps { grid-template-columns: 1fr; border-top: 0; }
    .step { padding: 30px 0 8px; border-top: 1px solid var(--line); }
    .step + .step { padding-left: 0; border-left: 0; }
    .step::before, .step + .step::before { left: 0; }
}

/* --------------------------------------------------------------------------
   Publish grid — five plain commitments, no cards, no badges. The hairline
   dividers come from the 1px gap over a --line background, same trick as
   the therapeutic-areas grid.
   -------------------------------------------------------------------------- */
.publish__grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 1px;
    background: var(--line);
    border-block: 1px solid var(--line);
    margin-top: 54px;
}
.publish__cell { background: var(--paper); grid-column: span 2; padding: 34px 30px 38px; }
.publish__cell:first-child, .publish__cell:nth-child(2) { grid-column: span 3; }
.publish__cell p {
    max-width: 30ch;
    color: var(--ink-2);
    font-size: 1.06rem;
    font-weight: 500;
    line-height: 1.45;
    letter-spacing: -.011em;
}
.publish__ico { display: block; width: 28px; height: 28px; color: var(--red); margin-bottom: 20px; }

@media (max-width: 1000px) {
    .publish__grid { grid-template-columns: repeat(4, 1fr); }
    .publish__cell, .publish__cell:first-child, .publish__cell:nth-child(2) { grid-column: span 2; }
    .publish__cell:nth-child(5) { grid-column: span 4; }
}
@media (max-width: 640px) {
    .publish__grid { grid-template-columns: 1fr; }
    .publish__cell,
    .publish__cell:first-child,
    .publish__cell:nth-child(2),
    .publish__cell:nth-child(5) { grid-column: span 1; }
}

/* --------------------------------------------------------------------------
   Statement band — a light panel on its own half, the photograph on the
   other, undimmed. No scrim: type never sits on top of the picture. Was a
   solid --ink (near-black) panel; simplified to match the rest of the
   site's paper-and-line language instead of standing out as a dark slab.
   -------------------------------------------------------------------------- */
.statement {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    background: var(--paper-2);
}
.statement__copy {
    width: 100%;
    /* Was a fixed 560px pinned to the column's right edge with
       margin-left:auto — on very wide screens the column grows but the text
       does not, so the gap in front of it grows with it, reading as
       off-centre/misaligned. Scaling the cap with viewport width and
       centring in the column keeps the block anchored sensibly at any
       width instead of drifting into empty space. */
    max-width: clamp(420px, 30vw + 200px, 720px);
    margin-inline: auto;
    padding: clamp(28px, 4vh, 52px) clamp(28px, 5vw, 76px);
}
.statement__copy .eyebrow { color: var(--red); }
.statement__copy h2 {
    color: var(--ink);
    max-width: 15ch;
    font-size: clamp(1.85rem, 1.4rem + 2.2vw, 2.7rem);
    letter-spacing: -.028em;
}
.statement__copy .stack { margin-top: 1.5rem; }
.statement__copy .stack p { color: var(--muted); font-size: 1.0625rem; line-height: 1.6; }
.statement__copy .alink { margin-top: 2.35rem; }

.statement__fig { align-self: stretch; min-height: 220px; overflow: hidden; }
.statement__fig img { width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 900px) {
    .statement { grid-template-columns: 1fr; }
    .statement__copy { max-width: none; margin: 0; padding: clamp(24px, 4vh, 40px) var(--gut); }
    .statement__fig { order: -1; height: min(24vh, 200px); }
}

/* --------------------------------------------------------------------------
   Text link with a hairline underline — quieter than a button, for a
   secondary path out of a section.
   -------------------------------------------------------------------------- */
.alink {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--line-2);
    color: var(--ink);
    font-size: .95rem;
    font-weight: 600;
    text-decoration: none;
    transition: color .25s var(--ease-soft), border-color .25s var(--ease-soft);
}
.alink svg { flex: none; transition: transform .3s var(--ease-soft); }
.alink:hover { color: var(--red); border-color: var(--red); }

/* --------------------------------------------------------------------------
   Plain statement — a heading and a lede with nowhere else to sit, and no
   photograph forced in just to fill the section.
   -------------------------------------------------------------------------- */
.plain-cta { text-align: center; }
.plain-cta .eyebrow { display: block; }
.plain-cta h2 { max-width: 22ch; margin-inline: auto; }
.plain-cta p { max-width: 52ch; margin: 1rem auto 0; color: var(--muted); font-size: 1.0625rem; }
.plain-cta__links { display: flex; justify-content: center; gap: 2.25rem; margin-top: 2rem; flex-wrap: wrap; }

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

/* ==========================================================================
   PART 23 — Full-width photographic bands
   --------------------------------------------------------------------------
   The picture runs the full width of the page and the copy sits on a frosted
   white card over it. The photograph itself is never darkened — the card is
   what carries the contrast, so a light image stays light.
   ========================================================================== */
.imgband {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: center;
    min-height: clamp(420px, 62vh, 620px);
    padding-block: clamp(3rem, 2rem + 4vw, 5.5rem);
    background: var(--paper-2);
}

.imgband picture { display: contents; }
.imgband > picture > img {
    position: absolute;
    inset: 0;
    z-index: -2;
    width: 100%;
    height: 112%;
    top: -6%;
    object-fit: cover;
    transform: translate3d(0, var(--par, 0px), 0);
    will-change: transform;
}

/* A whisper of white at the very edges so the band meets the sections above
   and below cleanly. Not a scrim — it never reaches the middle of the frame. */
.imgband::before {
    content: '';
    position: absolute; inset: 0; z-index: -1;
    background: linear-gradient(180deg, rgba(255,255,255,.55) 0%, rgba(255,255,255,0) 18%,
                                        rgba(255,255,255,0) 82%, rgba(255,255,255,.55) 100%);
    pointer-events: none;
}

.imgband .wrap { width: 100%; }

.imgband__card {
    max-width: 540px;
    padding: clamp(1.5rem, 1rem + 2vw, 2.5rem);
    background: var(--paper);
    border: 1px solid var(--line);
}
.imgband--right .imgband__card { margin-left: auto; }

.imgband__card h2 { letter-spacing: -.02em; }
.imgband__card p { margin-top: .85rem; color: var(--body); }
.imgband__links { display: flex; flex-wrap: wrap; gap: .4rem 1.5rem; margin-top: 1.25rem; }

@media (max-width: 700px) {
    .imgband { min-height: 0; }
    .imgband__card { max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
    .imgband > picture > img { transform: none !important; }
}

/* ==========================================================================
   PART 24 — Header and menus, rebuilt
   --------------------------------------------------------------------------
   The bar gains a little more air, the current section is marked, and each
   menu item now carries an icon and its own description. A menu always ends
   with the section's own page, so a top-level item is never a dead end.
   ========================================================================== */

/* --- The bar --------------------------------------------------------------
   Eight top-level items, a lockup and a button have to share one line. The
   type is small and the padding tight on purpose; below 1200px the drawer
   takes over rather than letting the row crush itself.
   -------------------------------------------------------------------------- */
:root { --header-h: 66px; }

.hdr__bar { gap: .75rem; }
.hdr__brand img, .hdr__brand svg { height: 34px; }

/* The desktop nav only exists from 1200px up — below that the drawer serves.
   Declaring it as a flex row unconditionally (as this once did) left the whole
   menu, and every dropdown panel, laid out off the side of a phone: hundreds of
   pixels of horizontal scroll on every page. */
.nav { display: none; }
@media (min-width: 1200px) { .nav { display: flex; align-items: center; gap: 0; } }

.nav__link {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: .22rem;
    padding: .45rem .52rem;
    border-radius: 0;
    font-size: .8125rem;
    font-weight: 600;
    letter-spacing: -.002em;
    white-space: nowrap;
    color: var(--ink-2);
    background: transparent;
    border: 0;
    cursor: pointer;
    text-decoration: none;
    transition: color .18s, background-color .18s;
}
@media (min-width: 1320px) {
    .hdr__bar { gap: 1rem; }
    .nav__link { font-size: .875rem; padding: .5rem .68rem; }
    .hdr__brand img, .hdr__brand svg { height: 38px; }
}
.nav__link:hover { color: var(--ink); background: rgba(16, 28, 52, .05); }

/* The section you are in keeps a short rule under it. */
.nav__link.is-current::after {
    content: '';
    position: absolute; left: .52rem; right: .52rem; bottom: .12rem;
    height: 2px; border-radius: 0;
    background: var(--red-bright);
}
.nav__caret { width: 10px; height: 10px; opacity: .5; transition: transform .25s var(--ease-out); }
.nav__link[aria-expanded="true"] { color: var(--ink); background: rgba(16, 28, 52, .06); }
.nav__link[aria-expanded="true"] .nav__caret { transform: rotate(180deg); opacity: .9; }

.hdr__login {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .48rem .9rem;
    font-size: .8125rem;
    white-space: nowrap;
    border: 1.5px solid var(--line-2);
    border-radius: 999px;
    font-size: .875rem; font-weight: 650;
    color: var(--ink);
    text-decoration: none;
    transition: border-color .18s, background-color .18s, color .18s;
}
.hdr__login:hover { border-color: var(--ink); background: var(--ink); color: #fff; }
.hdr__login .ico { width: 15px; height: 15px; }

/* --- The panel ------------------------------------------------------------ */
.drop {
    position: absolute;
    top: calc(100% - 6px);
    left: 0;
    z-index: 60;
    min-width: 320px;
    padding: .6rem;
    background: var(--paper);
    border: 1px solid var(--line);
    box-shadow: var(--sh-md);

    opacity: 0;
    transform: translateY(-8px) scale(.985);
    visibility: hidden;
    pointer-events: none;
    transition: opacity .22s var(--ease-out), transform .28s var(--ease-out), visibility .22s;
}
.drop[data-open="true"] {
    opacity: 1;
    transform: none;
    visibility: visible;
    pointer-events: auto;
}

/* A small nib pointing back at the trigger. */
.drop::before {
    content: '';
    position: absolute; top: -6px; left: var(--nib, 26px);
    width: 12px; height: 12px;
    background: inherit;
    border-left: 1px solid var(--line);
    border-top: 1px solid var(--line);
    transform: rotate(45deg);
    border-radius: 0;
}

.drop--wide { min-width: 620px; }
.drop__grid { display: grid; gap: 2px; }
.drop--wide .drop__grid { grid-template-columns: 1fr 1fr; column-gap: 6px; }

/* A separator in a two-column menu would cut one column in half. */
.drop__sep { height: 1px; background: var(--line); margin: .35rem .5rem; }
.drop--wide .drop__sep { grid-column: 1 / -1; }

.drop__link {
    display: flex;
    align-items: flex-start;
    gap: .7rem;
    padding: .6rem .7rem;
    border-radius: 0;
    text-decoration: none;
    transition: background-color .16s, transform .16s;
}
.drop__link:hover { background: var(--paper-2); transform: translateX(2px); }

.drop__icon {
    flex: none;
    display: grid; place-items: center;
    width: 34px; height: 34px;
    border-radius: 0;
    background: var(--red-wash);
    border: 1px solid #f6dade;
    color: var(--red);
    transition: background-color .16s, color .16s, border-color .16s;
}
.drop__link:hover .drop__icon { background: var(--red); border-color: var(--red); color: #fff; }

.drop__text { display: grid; gap: .1rem; min-width: 0; }
.drop__text b {
    display: block;
    font-size: .875rem; font-weight: 600; color: var(--ink);
    line-height: 1.35;
}
.drop__text span { font-size: .75rem; color: var(--muted); line-height: 1.45; }

.drop__all {
    display: flex; align-items: center; gap: .4rem;
    margin: .45rem .2rem .1rem;
    padding: .6rem .7rem;
    border-top: 1px solid var(--line);
    padding-top: .75rem;
    font-size: .8125rem; font-weight: 700;
    letter-spacing: .02em;
    color: var(--red);
    text-decoration: none;
}
.drop__all .ico { transition: transform .18s; }
.drop__all:hover .ico { transform: translateX(3px); }

/* Menus used to be right-aligned by position in the bar, which made them jump
   between edges as you moved along the nav. They are all anchored to their own
   trigger now, and the script nudges one back on screen only if it would
   actually run off — see PART 11 of corporate.js. */
.drop { max-width: calc(100vw - 32px); }

/* Over a photographic hero the bar's type is white — the caret follows. */
.hdr--over:not(.is-stuck) .nav__caret { opacity: .8; }

@media (prefers-reduced-motion: reduce) {
    .drop { transition: opacity .01ms, visibility .01ms; transform: none; }
    .drop__link:hover { transform: none; }
}

/* ==========================================================================
   PART 24b — Header as three floating capsules
   --------------------------------------------------------------------------
   Logo, nav and login stop being one continuous bar and become three
   independent pills, with page content visible in the gaps between them.
   .hdr keeps the position/top/margin-inline that make the whole row float
   (see PART 14) but no longer paints a background of its own — each capsule
   below carries its own fill, radius and shadow instead.
   ========================================================================== */

.hdr,
.hdr--over:not(.is-stuck),
.hdr--glass {
    background: none;
}
.hdr,
.hdr.is-stuck,
.hdr--over.is-stuck,
.hdr--glass.is-stuck {
    box-shadow: none;
    border-radius: 0;
}

:root { --cap-h: 64px; --header-h: 80px; }

/* At rest, the gaps between capsules are the point — page content shows
   through them on purpose. But once the header is stuck (scrolled), that
   same page content is now scrolling past underneath it, and shows through
   those gaps too — which reads as the header and page content overlapping
   into a jumble, not as a deliberate design. A backdrop behind the capsules
   (not on them — they keep their own separate pill fills) fixes that: it is
   invisible until is-stuck, then blocks whatever is scrolling underneath. */
/* Sized to .hdr__bar (not .hdr) so it only covers the actual capsule row —
   .hdr__bar caps out at max-width:1720px and centres itself, so on very wide
   screens .hdr is much wider than the row of capsules; a backdrop on .hdr
   itself would paint a full-viewport-wide bar instead of just sitting behind
   the three pills. */
.hdr__bar { gap: clamp(10px, 1.6vw, 18px); position: relative; }
.hdr__bar::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: 16px;
    background: var(--paper);
    opacity: 0;
    transition: opacity .2s;
    pointer-events: none;
}
/* A positioned element (even at z-index:auto) paints above static in-flow
   content regardless of DOM order — the backdrop above is absolutely
   positioned, so without this the brand and login capsules (both plain
   static-flow boxes) render UNDER it once it turns opaque, and disappear.
   .nav happened to survive that because .nav__item is already positioned
   for its own dropdown. Pin every capsule above the backdrop explicitly. */
.hdr__brand,
.nav,
.hdr__login,
.burger {
    position: relative;
    z-index: 1;
}
.hdr.is-stuck .hdr__bar::before,
.hdr--over.is-stuck .hdr__bar::before,
.hdr--glass.is-stuck .hdr__bar::before {
    opacity: 1;
}

/* All four capsules share one fixed height so they line up exactly — each
   just centres its own content (logo / links / label / icon) inside it,
   rather than sizing itself from padding + content like before. Display is
   deliberately NOT set here: .nav and .burger toggle display responsively
   elsewhere (nav only from 1200px up), and redeclaring it here at equal
   specificity would win by source order and make nav show on mobile. */
.hdr__brand,
.nav,
.hdr__login,
.burger {
    height: var(--cap-h);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 999px;
    box-shadow: 0 2px 4px rgba(16, 28, 52, .1), 0 16px 34px -14px rgba(16, 28, 52, .4);
}
/* Not .burger: its three lines rely on the default align-items: stretch to
   span the button's width — centering them here would collapse them. */
.hdr__brand,
.hdr__login {
    align-items: center;
}
/* A little more lift once the row has scrolled, matching what the single
   bar used to do — applied per capsule now that .hdr itself is invisible. */
.is-stuck .hdr__brand,
.is-stuck .nav,
.is-stuck .hdr__login,
.is-stuck .burger {
    border-color: var(--line-2);
    box-shadow: 0 3px 6px rgba(16, 28, 52, .12), 0 20px 40px -14px rgba(16, 28, 52, .46);
}

.hdr__brand { padding: 0 16px; }
.hdr__login:hover { background: var(--ink); border-color: var(--ink); }

/* Logo sized to sit comfortably inside the fixed-height brand capsule. */
.hdr__brand img, .hdr__brand svg { height: 44px; }
@media (max-width: 420px)  { .hdr__brand img, .hdr__brand svg { height: 34px; } }

.nav { padding: 0 6px; }
/* Seven top-level items have to share the row from 1200px, the same width
   the drawer hands off at — kept tight here on purpose. Comfortable padding
   only kicks in once there is real room for it, at 1400px. */
.nav__link { padding: .45rem .5rem; font-size: .8125rem; }
.hdr__login { padding: 0 1rem; font-size: .875rem; gap: .4rem; }
.hdr__login .ico { width: 15px; height: 15px; }
.burger { width: var(--cap-h); height: var(--cap-h); padding: 0 14px; }

@media (min-width: 1400px) {
    .hdr__brand { padding: 0 24px; }
    .nav__link { padding: .6rem .8rem; font-size: .875rem; }
    .hdr__login { padding: 0 1.3rem; font-size: .9375rem; gap: .5rem; }
    .hdr__login .ico { width: 16px; height: 16px; }
}

@media (max-width: 420px) {
    :root { --cap-h: 52px; --header-h: 68px; }
}

/* ==========================================================================
   PART 25 — The hero deck
   --------------------------------------------------------------------------
   A full-bleed photograph per slide, whitened on the left under a gradient
   so ink type sits on it directly — no dark scrim, no card. The copy is
   vertically centred and held to the same content width as the header.
   ========================================================================== */
.hero-deck {
    position: relative;
    isolation: isolate;
    background: var(--paper);
    display: grid;
    grid-template-rows: 1fr auto;
    min-height: calc(100vh - var(--header-h) - var(--marquee-h));
}
.hero-deck__stage { position: relative; isolation: isolate; overflow: hidden; min-width: 0; }

.slide {
    position: absolute; inset: 0;
    display: flex;
    align-items: center;
    opacity: 0;
    visibility: hidden;
    transition: opacity .9s var(--ease-soft), visibility 0s linear .9s;
}
.slide.is-active { opacity: 1; visibility: visible; transition: opacity .9s var(--ease-soft); z-index: 1; }

.slide__fig { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.slide__fig img {
    width: 100%; height: 100%;
    object-fit: cover; object-position: 62% 50%;
    animation: slideKenburns 11s linear both;
}
@keyframes slideKenburns { from { transform: scale(1); } to { transform: scale(1.085); } }

/* White fade from the left, where the copy sits, easing off by three-quarters
   across — the photograph on the right is left alone. */
.slide__fig::after {
    content: '';
    position: absolute; inset: 0;
    background:
        linear-gradient(90deg, rgba(255,255,255,.97) 0%, rgba(255,255,255,.92) 26%,
                                rgba(255,255,255,.4) 50%, rgba(255,255,255,0) 72%),
        linear-gradient(rgba(255,255,255,0) 70%, rgba(255,255,255,.6) 100%);
}

.slide__count { display: none; }

.slide__body {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: var(--wrap);
    margin-inline: auto;
    padding: clamp(48px, 8vh, 96px) var(--gut) clamp(96px, 13vh, 150px);
}

.slide__mark { display: block; width: 44px; height: 3px; background: var(--red); margin-bottom: 26px; }

.slide__eyebrow {
    font-size: .72rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
    color: var(--red);
    margin-bottom: 18px;
}
.slide__body h1, .slide__body h2 {
    color: var(--ink);
    font-size: clamp(2.15rem, 4.9vw, 4.3rem);
    font-weight: 600;
    line-height: 1.04;
    letter-spacing: -.034em;
    max-width: 19ch;
    padding-bottom: 4px;
}
.slide__body .nb {
    color: var(--red);
    font-style: italic;
    font-weight: 500;
    white-space: nowrap;
}
.slide__lede {
    color: var(--muted);
    max-width: 46ch;
    margin-top: 24px;
    font-size: clamp(1.02rem, 1.35vw, 1.19rem);
    line-height: 1.55;
}
.slide__cta { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 38px; }

/* --- Deck controls: a full-width bar at the foot of the stage, numbers left,
       arrows right, matching the header's content measure. --- */
.hero-deck__ui {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
    max-width: var(--wrap);
    margin-inline: auto;
    padding: 0 var(--gut) clamp(26px, 4vh, 40px);
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 24px;
    pointer-events: none;
}
.hero-deck__ui > * { pointer-events: auto; }

.deck-nums { display: flex; gap: 28px; list-style: none; }
.deck-nums button {
    position: relative;
    background: none; border: 0;
    padding: 14px 7px 16px;
    font-size: .76rem; font-weight: 600; letter-spacing: .1em;
    font-variant-numeric: tabular-nums;
    color: var(--faint);
    cursor: pointer;
    transition: color .3s var(--ease-soft);
}
.deck-nums button::before {
    content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 2px;
    background: var(--line-2);
}
.deck-nums button::after {
    content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 2px;
    background: var(--pulse);
    transform: scaleX(0);
    transform-origin: 0;
}
.deck-nums button:hover, .deck-nums button[aria-current="true"] { color: var(--ink); }
.deck-nums button[aria-current="true"]::after { animation: deckClock 7s linear both; }
@keyframes deckClock { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.deck-arrows { display: flex; gap: 10px; }
.deck-arrows button {
    display: grid; place-items: center;
    width: 50px; height: 50px;
    background: var(--paper);
    border: 1px solid var(--line-2);
    color: var(--ink);
    cursor: pointer;
    transition: background-color .25s var(--ease-soft), border-color .25s var(--ease-soft), color .25s;
}
.deck-arrows button:hover { background: var(--ink); border-color: var(--ink); color: #fff; }
.ico--flip { transform: scaleX(-1); }

/* --- Focus-area index, under the deck --- */
.hero-deck__index { border-top: 1px solid var(--line); background: var(--paper); }
.hero-deck__index ol {
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--gut);
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    list-style: none;
}
.hero-deck__index li + li { border-left: 1px solid var(--line); }
.hero-deck__index a {
    display: flex; align-items: baseline; gap: 12px;
    padding: 22px 20px 24px 0;
    text-decoration: none;
    transition: color .28s var(--ease-soft);
}
.hero-deck__index li + li a { padding-left: 24px; }
.hero-deck__index a b {
    font-size: .72rem; font-weight: 600; letter-spacing: .08em;
    font-variant-numeric: tabular-nums;
    color: var(--faint);
    transition: color .28s var(--ease-soft);
}
.hero-deck__index a span { font-size: 1rem; font-weight: 600; letter-spacing: -.015em; color: var(--ink); }
.hero-deck__index a:hover, .hero-deck__index a:hover b, .hero-deck__index a:hover span { color: var(--red); }

@media (max-width: 900px) {
    .hero-deck { min-height: 0; }
    .hero-deck__stage { min-height: calc(100vh - var(--header-h) - var(--marquee-h)); display: flex; }
    .slide { flex-direction: column; align-items: stretch; }
    .slide__fig { flex: none; height: clamp(210px, 34vh, 380px); position: relative; overflow: hidden; }
    .slide__fig::after { display: none; }
    .slide__fig img {
        object-position: 60% 44%;
        -webkit-mask-image: linear-gradient(#000 0% 62%, rgba(0,0,0,.4) 86%, transparent 100%);
                mask-image: linear-gradient(#000 0% 62%, rgba(0,0,0,.4) 86%, transparent 100%);
    }
    .slide__count {
        display: flex; align-items: baseline; gap: 5px;
        position: absolute; top: 14px; right: var(--gut); z-index: 1;
        font-size: .72rem; font-weight: 600; letter-spacing: .1em;
        font-variant-numeric: tabular-nums;
        color: var(--ink);
    }
    .slide__body {
        width: auto; max-width: none;
        margin: 0;
        padding: clamp(24px, 4vh, 38px) var(--gut) clamp(78px, 10vh, 96px);
        display: flex; flex-direction: column; flex: 1;
        justify-content: center; align-items: flex-start;
    }
    .slide__mark { margin-bottom: 18px; }
    .slide__eyebrow { margin-bottom: 14px; }
    .slide__body h1, .slide__body h2 { font-size: clamp(1.95rem, 8.4vw, 2.5rem); max-width: 19ch; }
    .slide__lede { max-width: none; margin-top: 16px; }
    .slide__cta { width: 100%; gap: 12px; margin-top: 26px; }
    .slide__cta .btn { justify-content: center; width: 100%; }

    .hero-deck__ui { padding: 0 0 12px; display: block; top: auto; bottom: 0; }
    .deck-nums { gap: 0; }
    .deck-nums li { flex: 1; }
    .deck-nums button { width: 100%; text-align: left; padding: 13px 0 15px var(--gut); }
    .deck-arrows { display: none; }

    .hero-deck__index ol { grid-template-columns: repeat(2, 1fr); }
    .hero-deck__index li:nth-child(2n+1) { border-left: 0; }
    .hero-deck__index li:nth-child(n+3) { border-top: 1px solid var(--line); }
    .hero-deck__index li:nth-child(2n+1) a { padding-left: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .slide { transition: none; }
    .slide__fig img { animation: none; }
    .deck-nums button[aria-current="true"]::after { animation: none; transform: scaleX(1); }
}

/* ==========================================================================
   PART 26 — The page below the hero
   --------------------------------------------------------------------------
   Every section below the hero sits on its own floor. Tinted, navy and
   photographic sections already carry a background.
   ========================================================================== */
main > * { position: relative; z-index: 1; }
main > .section:not(.section--tint):not(.section--navy):not(.section--photo),
main > .pulse-rule,
main > div:has(> .pulse-rule) { background-color: var(--paper); }

/* --------------------------------------------------------------------------
   Full-width bands breathe as they cross
   -------------------------------------------------------------------------- */
.js .imgband > picture > img {
    transform: translate3d(0, var(--par, 0px), 0) scale(var(--zoom, 1.06));
    transform-origin: 50% 50%;
}

@media (prefers-reduced-motion: reduce) {
    .js .imgband > picture > img { transform: none !important; }
}

/* ==========================================================================
   PART 27 — Fixed band photographs
   --------------------------------------------------------------------------
   The picture holds still while the words travel over it.

   Done with clip-path, not background-attachment: fixed. A clip-path on the
   band clips anything inside it without becoming a containing block for a
   fixed child — so the photograph can be anchored to the viewport and still be
   cut to the exact shape of its band. background-attachment: fixed is ignored
   outright on iOS, which is where half the traffic is.
   ========================================================================== */
@media (min-width: 900px) {
    .js .imgband {
        clip-path: inset(0);
        /* The card needs room to travel while the picture stays put. */
        min-height: clamp(560px, 78vh, 760px);
    }

    .js .imgband > picture > img {
        position: fixed;
        top: 0;
        left: 0;
        width: 100vw;
        height: 100vh;
        /* Held still: no drift, no breathing — that is the whole point. */
        transform: none;
        will-change: auto;
        object-fit: cover;
        z-index: -2;
    }

    /* The white edge fade travels with the band, not with the picture. */
    .js .imgband::before { z-index: -1; }
}

/* A phone scrolls too fast for a held picture to read as anything but a jump,
   and a viewport-sized fixed image is a memory cost it should not pay. */
@media (max-width: 899px), (prefers-reduced-motion: reduce) {
    .js .imgband { clip-path: none; }
    .js .imgband > picture > img { position: absolute; width: 100%; height: 112%; }
}

/* ==========================================================================
   PART 29 — Responsive corrections
   --------------------------------------------------------------------------
   Found by walking every page at 360, 390, 768, 1024 and 1280 and measuring
   what stuck out, what was too small to read and what was too small to hit.
   ========================================================================== */

/* A tick box has to be big enough to hit — 24px is the floor WCAG 2.5.8 sets. */
.check input[type=checkbox], .check input[type=radio] { width: 22px; height: 22px; }
@media (pointer: coarse) {
    .check input[type=checkbox], .check input[type=radio] { width: 24px; height: 24px; }
    /* Standalone text links get a thumb-sized row on touch. */
    .tlink { min-height: 34px; align-items: center; }
    .card__foot .tlink, .imgband__links .tlink { min-height: 40px; }
}

/* --------------------------------------------------------------------------
   The purpose board on a small screen
   -------------------------------------------------------------------------- */
@media (max-width: 1079px) {
    .board__media { min-height: 0; padding-block: 2rem; }
    .board__copy { max-width: none; }
}
@media (max-width: 560px) {
    .board__media { border-radius: 0; }
}

/* --------------------------------------------------------------------------
   Full-width bands
   -------------------------------------------------------------------------- */
@media (max-width: 899px) {
    .imgband { min-height: 0; padding-block: clamp(2.5rem, 2rem + 4vw, 4rem); }
    .imgband__card { max-width: none; }
}

/* --------------------------------------------------------------------------
   Forms and tables on a phone
   -------------------------------------------------------------------------- */
@media (max-width: 560px) {
    .formbox { border-radius: 0; }
    .form__actions { flex-direction: column; align-items: stretch; }
    .form__actions .btn { width: 100%; }
    .form__actions .form__note { text-align: center; }
    .filefield { flex-wrap: wrap; }
    .filefield__text { min-width: 0; flex: 1 1 60%; }
}

/* Wide tables keep their own scroller; make it obvious it is one. */
@media (max-width: 700px) {
    .tablewrap { border-radius: 0; }
    table.data { min-width: 520px; }
}

/* --------------------------------------------------------------------------
   Section rhythm tightens on small screens rather than staying desktop-sized
   -------------------------------------------------------------------------- */
@media (max-width: 560px) {
    .section { padding-block: 2.25rem; }
    .purpose__points { border-radius: 0; }
    .snap { gap: 10px; }
    .snap__cell { padding: 1rem .9rem 1.1rem; border-radius: 0; }
    .nextsteps__card { padding: 1.15rem 1.1rem; }
}

/* --------------------------------------------------------------------------
   PART 29b — Small-screen corrections found in the second pass
   -------------------------------------------------------------------------- */

/* A sideways entrance pushes an element past the edge while it waits, which on
   a phone is most of the screen width. Below 700px everything rises instead. */
@media (max-width: 700px) {
    .js .reveal[data-reveal="left"],
    .js .reveal[data-reveal="right"],
    .js .reveal[data-reveal="swing"] { transform: translate3d(0, 24px, 0); }
    .js .reveal[data-reveal="zoom"]  { transform: scale(.97); }
}

/* Tick boxes at the size a thumb needs, on every device. */
.check input[type=checkbox], .check input[type=radio] { width: 24px; height: 24px; }

/* Emulators do not always report a coarse pointer, so the touch-sized link row
   is set by width as well. */
@media (max-width: 900px) {
    .tlink { min-height: 34px; align-items: center; }
    .card__foot .tlink { min-height: 40px; }
}

/* Nothing on the site sits below 12px any more. */
.hero__cue, .chapters__item, .chapters__n, .chapters__l { font-size: .75rem; }

/* The bar itself has to fit a 360px phone. */
@media (max-width: 420px) {
    .hdr__bar { gap: .5rem; }
    .hdr__brand img, .hdr__brand svg { height: 30px; }
    .brand-lockup__text i { display: none; }
}

/* ==========================================================================
   PART 31 — FAQ accordion
   --------------------------------------------------------------------------
   Native <details>/<summary>, no JS required to open or close. A plus sign
   that rotates into a minus on [open].
   ========================================================================== */
.faq__list { display: grid; margin-top: 2.5rem; border-top: 1px solid var(--line); }
.faq__list details { border-bottom: 1px solid var(--line); }
.faq__list summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.4rem .25rem;
    font-size: 1.0625rem;
    font-weight: 600;
    color: var(--ink);
    cursor: pointer;
    list-style: none;
}
.faq__list summary::-webkit-details-marker { display: none; }
.faq__list summary:hover { color: var(--red); }

.faq__sign { position: relative; flex: none; width: 18px; height: 18px; color: var(--ink-2); }
.faq__sign::before, .faq__sign::after {
    content: '';
    position: absolute; top: 50%; left: 50%;
    background: currentColor;
    transition: transform .2s var(--ease-out), opacity .2s;
}
.faq__sign::before { width: 14px; height: 1.7px; transform: translate(-50%, -50%); }
.faq__sign::after { width: 1.7px; height: 14px; transform: translate(-50%, -50%); }
details[open] .faq__sign::after { transform: translate(-50%, -50%) rotate(90deg); opacity: 0; }
details[open] summary { color: var(--red); }

.faq__list p { max-width: 68ch; padding: 0 .25rem 1.5rem; color: var(--muted); font-size: .9375rem; line-height: 1.6; }
.faq__list p a { color: var(--red); }

@media (prefers-reduced-motion: reduce) {
    .faq__sign::before, .faq__sign::after { transition: none; }
}

/* ==========================================================================
   PART 32 — Mobile
   --------------------------------------------------------------------------
   Everything below 1200px, where the drawer takes over from the desktop nav.
   This part is last on purpose: it corrects the earlier desktop-first rules
   rather than being corrected by them.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Nothing scrolls sideways
   --------------------------------------------------------------------------
   html already clips, but a clipped html still lets a too-wide child set the
   layout width for everything under it — which is how one over-long header
   pushed body copy off the right edge of a 320px phone. Clipping the body as
   well contains the damage to the element that caused it.
   -------------------------------------------------------------------------- */
body { overflow-x: clip; }

/* Grid and flex children default to min-width:auto, so a long word, a wide
   table or a nowrap label stretches its whole track. These are the containers
   that actually hold such content. */
.split > *,
.grid > *,
.wrap > *,
.mapbox > *,
.ftr__top > * { min-width: 0; }

/* --------------------------------------------------------------------------
   2. The header capsules
   --------------------------------------------------------------------------
   The three capsules are nowrap boxes in a flex row. Left shrinkable, the
   brand capsule was squeezed narrower than its own lockup and clipped the
   "PHARMA PRIVATE LIMITED" descriptor mid-word — the bug this part starts
   from. flex:none stops the squeeze; the sizing steps below make sure the
   row genuinely fits instead, all the way down to a 320px phone.
   -------------------------------------------------------------------------- */
@media (max-width: 1199px) {
    .hdr__brand,
    .hdr__login,
    .burger { flex: none; }

    /* The nav is gone below 1200px, so the brand is what pushes the login and
       burger capsules over to the right. */
    .hdr__brand { margin-right: auto; }
}

/* The descriptor needs ~150px of its own and is the first thing to go. Below
   this width the wordmark carries the lockup on its own. */
@media (max-width: 560px) {
    .hdr .brand-lockup__text i { display: none; }
    .hdr .brand-lockup__text { align-content: center; }
}

/* Phone-sized capsules. One step, not a slow taper, so the row has real
   breathing room rather than only just fitting. */
@media (max-width: 560px) {
    :root { --cap-h: 50px; --header-h: 64px; --hdr-gap: 12px; }

    .hdr__bar { padding-inline: 12px; gap: 8px; }
    .hdr__brand { padding: 0 14px; }
    .hdr__brand img, .hdr__brand svg { height: 30px; }
    .brand-lockup { gap: 9px; }
    .brand-lockup__text b { font-size: 17px; }

    .hdr__login { padding: 0 .85rem; font-size: .8125rem; gap: .35rem; }
    .hdr__login .ico { width: 14px; height: 14px; }

    .burger { width: var(--cap-h); height: var(--cap-h); padding: 0 13px; }
}

/* Under ~375px the word "Login" is the difference between fitting and not.
   The lock alone carries it (the link is aria-labelled), and the drawer still
   offers a full-width button that says Login in words. */
@media (max-width: 374px) {
    :root { --cap-h: 46px; --header-h: 60px; --hdr-gap: 10px; }

    .hdr__bar { padding-inline: 10px; gap: 6px; }
    .hdr__brand { padding: 0 12px; }
    .hdr__brand img, .hdr__brand svg { height: 28px; }
    .brand-lockup { gap: 8px; }
    .brand-lockup__text b { font-size: 16px; }

    .hdr__login-txt { display: none; }
    .hdr__login { width: var(--cap-h); padding: 0; justify-content: center; gap: 0; }
    .burger { padding: 0 12px; }
}

/* --------------------------------------------------------------------------
   3. The drawer
   --------------------------------------------------------------------------
   It used to start at header-height + gap, measured from the viewport top —
   correct only once the page is scrolled and the header has stuck. At the top
   of a page the header still sits in flow, so the drawer began ~16px too low
   and a strip of the hero showed through between the two. Covering the whole
   viewport and pushing the menu down with padding is right at every scroll
   position; the header floats above it on its own z-index either way.
   -------------------------------------------------------------------------- */
.mnav {
    inset: 0;
    padding-top: calc(var(--marquee-h) + var(--header-h) + var(--hdr-gap) + 6px);
    padding-bottom: max(40px, env(safe-area-inset-bottom));
}
.mnav__cta { padding-inline: 20px; }

/* The marquee is a sibling of the header rather than a child of it — the
   comments upstream describe the arrangement it was refactored away from —
   so it has no stacking context and the now full-height drawer painted
   straight over it. Lift it above both. */
.marquee { position: relative; z-index: 101; }

/* --------------------------------------------------------------------------
   4. Forms
   --------------------------------------------------------------------------
   iOS Safari zooms the whole page in when a focused field's type is under
   16px, and never zooms back out. Every field on the site was 15px.
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
    .field input[type=text], .field input[type=email], .field input[type=tel],
    .field input[type=password], .field input[type=search], .field input[type=url],
    .field input[type=number], .field input[type=date], .field input[type=file],
    .field select, .field textarea { font-size: 16px; }
}

/* --------------------------------------------------------------------------
   5. Prose tables
   --------------------------------------------------------------------------
   Data tables already sit in a .tablewrap that scrolls. A table written
   straight into prose (the privacy policy's "what we collect") had nothing,
   and set the page width on a small phone. display:block turns the table
   itself into the scroller without needing a wrapper element around it.
   -------------------------------------------------------------------------- */
@media (max-width: 700px) {
    .prose table {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .prose table thead th,
    .prose table td { min-width: 8.5rem; }
    .prose th, .prose td { padding: .55rem .7rem; }
}

/* --------------------------------------------------------------------------
   6. Touch targets
   --------------------------------------------------------------------------
   Link lists set tight for a desktop sidebar are hard to hit with a thumb.
   Padding (not height) so the text stays where the design puts it.
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
    .ftr__col a,
    .ftr__legal a,
    .mnav__panel a {
        display: block;
        padding-block: .45rem;
    }
    .mnav__panel a { padding-block: .6rem; }
}

/* --------------------------------------------------------------------------
   7. Odds and ends
   -------------------------------------------------------------------------- */
/* The cookie bar is the widest fixed element on the page; give it the same
   inset as the header rather than a fixed 16px that a 320px screen cannot
   spare. */
@media (max-width: 560px) {
    .cookie { left: 12px; right: 12px; width: auto; }
    .cookie__row { flex-wrap: wrap; }
    .cookie__row .btn { flex: 1 1 auto; }
}

/* The scroll-to-top button sat over body copy on a narrow column. */
@media (max-width: 560px) {
    .totop { right: 12px; bottom: 12px; }
}

/* --------------------------------------------------------------------------
   8. The hero deck
   --------------------------------------------------------------------------
   The deck is a grid whose single column is auto-sized. The focus-area index
   in the second row has a two-column list inside it, and each 1fr track takes
   its own min-content as a floor — so on a 320px phone the list demanded
   357px, the track grew to match, and the stage (sharing that track) reached
   37px past the screen and clipped the headline and the CTA against its own
   overflow:hidden. Let the tracks shrink, and give the list one column where
   two will not fit.
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
    .hero-deck__index,
    .hero-deck__index ol,
    .hero-deck__index li { min-width: 0; }
}
@media (max-width: 480px) {
    .hero-deck__index ol { grid-template-columns: 1fr; }
    .hero-deck__index li + li { border-left: 0; border-top: 1px solid var(--line); }
    .hero-deck__index li:nth-child(n+3) { border-top: 1px solid var(--line); }
    .hero-deck__index li a,
    .hero-deck__index li + li a { padding-left: 0; }
}
