:root {
    --ink: #17252d;
    --muted: #5f6f77;
    --paper: #fff;
    --mist: #f3f6f6;
    --line: #d9e1e3;
    --teal: #0e736d;
    --teal-dark: #095852;
    --yellow: #f0c85a;
    --footer: #111d23;
    --max: 1180px;
    --focus: #e5a900;

    /* Semantic aliases added for the banner work. The theme previously carried colours and
       one content width only, so spacing, radii, the font stack and button surfaces were
       repeated as literals wherever they were needed. Naming them here is what lets a banner
       reuse the site's look instead of approximating it. */
    --font-sans: "Poppins", sans-serif;

    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;

    --radius-sm: 2px;
    --radius-md: 4px;
    --radius-lg: 8px;
    --radius-pill: 999px;

    --btn-primary-bg: var(--teal);
    --btn-primary-fg: var(--paper);
    --btn-primary-bg-hover: var(--teal-dark);
    --btn-secondary-bg: var(--paper);
    --btn-secondary-fg: var(--ink);
    --btn-secondary-border: var(--line);
    --btn-ghost-fg: var(--paper);

    --control-min-target: 44px;
}

* { box-sizing: border-box; }
html {
    scroll-behavior: smooth;
    font-family: var(--font-sans);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}
body { margin: 0; color: var(--ink); background: var(--paper); font-family: inherit; font-weight: 400; line-height: 1.6; }
body.nav-open { overflow: hidden; }
a { color: inherit; }
img, video { max-width: 100%; }
button, input, textarea, select { font: inherit; }
/* CMS HTML and banner documents may still name another family. Keep the public site on one. */
.prose *,
.site-footer *,
.cms-banner__text,
.cms-banner__btn,
[class^="ql-font-"],
[class*=" ql-font-"] { font-family: inherit !important; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.site-shell { width: min(calc(100% - 40px), var(--max)); margin-inline: auto; }
.skip-link { position: fixed; z-index: 100; top: 8px; left: 8px; padding: 10px 14px; background: var(--ink); color: #fff; transform: translateY(-150%); }
.skip-link:focus { transform: translateY(0); }

.site-header { position: sticky; top: 0; z-index: 30; background: rgba(255,255,255,.97); border-bottom: 1px solid var(--line); backdrop-filter: blur(12px); }
.header-inner { min-height: var(--header-min-h, 72px); display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.brand { display: inline-flex; align-items: center; min-width: 120px; max-width: 260px; color: var(--ink); font-size: 1.35rem; font-weight: 800; text-decoration: none; }
.brand img { display: block; width: auto; max-width: 100%; height: 44px; object-fit: contain; object-position: left center; }
.header-inner { position: relative; }
/* ---------------------------------------------------------------------------
   Primary navigation.

   Three open mechanisms live here and exactly one is ever in charge.

   Below 901px the drawer opens submenus with .open, set by the "+" buttons.
   At 901px and up the bar opens them on hover. The plain :hover rule is the
   no-script fallback only: once site.js starts it marks the nav .is-enhanced,
   takes ownership through .is-open, and animates a single shared card between
   triggers.

   Whichever is in charge, a panel is docked to the BOTTOM EDGE OF THE BAR and
   the trigger is stretched to reach it. The nav row is shorter than the bar -
   an editor can size the bar anywhere from 40px to 200px - so a panel offset
   from the list item instead leaves bare header between the two, and a pointer
   crossing that band drops :hover and closes the panel before it is reached.
   --------------------------------------------------------------------------- */
.public-nav > ul, .public-nav ul { display: flex; align-items: center; gap: 2px; margin: 0; padding: 0; list-style: none; }
.public-nav > ul { flex-wrap: wrap; justify-content: flex-end; }
.public-nav a { display: block; padding: 10px 11px; font-weight: 600; text-decoration: none; white-space: nowrap; }
.public-nav a:hover, .public-nav a[aria-current="page"] { color: var(--teal); }
.public-nav li { position: relative; }
.public-nav li.has-children { display: flex; align-items: center; }
.public-nav li > ul { display: none; position: absolute; top: 100%; left: 0; min-width: 230px; padding: 8px; background: #fff; border: 1px solid var(--line); box-shadow: 0 18px 42px rgba(23,37,45,.14); }
.public-nav li > ul li { width: 100%; }
.public-nav li > ul li.has-children { align-items: stretch; }
/* The script builds these two unconditionally. Outside the bar's range they
   have no rules of their own, so without this they sit in the drawer header as
   two extra zero-width flex items and eat two of .header-inner's 24px gaps. */
.nav-stage, .nav-pill { display: none; }

@media (min-width: 901px) {
    /* Stretch the trigger to the full height of the bar so its bottom edge and
       the panel's top edge touch. This is what removes the dead band. */
    .public-nav { align-self: stretch; display: flex; align-items: stretch; }
    /* Deliberately NOT position:relative. The pill, the card and the panels are
       all placed by the script in .header-inner's coordinate space, and a
       positioned list here would silently re-anchor the panels to itself. */
    .public-nav > ul { align-items: stretch; align-content: stretch; }
    /* Stretched items are as tall as the bar, so the label has to re-centre
       itself. Items without children need this as much as parents do. */
    .public-nav > ul > li { display: flex; align-items: center; }

    /* Parents open on hover, focus or tap - never from a visible control, so
       the drawer's "+" button has no job on the bar. */
    .public-nav .submenu-toggle { display: none; }

    .public-nav li > ul li > ul { top: -9px; left: 100%; }
    .public-nav li:hover > ul, .public-nav li:focus-within > ul { display: block; }

    .public-nav > ul > li.mega { position: static; }
    .public-nav > ul > li.mega > ul { left: 0; right: 0; width: auto; min-width: 0; padding: 22px 18px 18px; align-items: start; gap: 10px 22px; }
    .public-nav > ul > li.mega:hover > ul, .public-nav > ul > li.mega:focus-within > ul { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
    .public-nav > ul > li.mega > ul > li { display: block; width: auto; }
    .public-nav > ul > li.mega > ul > li > a { padding: 4px 8px 10px; color: var(--teal); font-size: .72rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; white-space: normal; }
    .public-nav > ul > li.mega > ul > li > ul { position: static; display: block; min-width: 0; padding: 0; border: 0; box-shadow: none; }
    .public-nav > ul > li.mega > ul > li > ul a { padding: 6px 8px; font-size: .92rem; font-weight: 600; white-space: normal; }

    /* ---- Enhanced: the morphing spotlight panel ---------------------------
       Every rule below has to out-rank one of the :hover rules above it. Some
       win on specificity and some only on document order, so keep this block
       after those rules if you move anything.

       Panels stay laid out and are hidden with visibility rather than display,
       for two reasons: the script has to measure one before revealing it, and
       visibility:hidden still removes it from the accessibility tree and the
       tab order. They are absolutely positioned, so they never affect layout.

       The panels also give up their own background, border and shadow. That
       chrome is drawn once by .nav-stage__surface and animated between
       triggers, which is what makes the card appear to morph instead of one
       vanishing and another appearing.
       ---------------------------------------------------------------------- */
    /* Every panel resolves against .header-inner, not against its own list
       item, so the script can place them all on one coordinate system and so
       a 230px dropdown is measured against the shell rather than against a
       117px trigger. */
    .public-nav.is-enhanced > ul > li.has-children { position: static; }
    /* A static list item paints its label in the in-flow layer, underneath the
       pill. Lifting the label is what keeps it readable. */
    .public-nav.is-enhanced > ul > li > a { position: relative; z-index: 1; }
    /* Root panels only. A descendant selector here would also catch the column
       lists inside a mega panel, which are static, always shown, and would be
       hidden and made unclickable along with their parent. */
    .public-nav.is-enhanced > ul > li > ul {
        display: block;
        visibility: hidden;
        opacity: 0;
        pointer-events: none;
        z-index: 2;
        left: var(--panel-x, 0px);
        max-height: calc(100vh - var(--header-offset, 72px) - 24px);
        overflow-y: auto;
        overscroll-behavior: contain;
        background: transparent;
        border-color: transparent;
        box-shadow: none;
        transition: opacity .2s ease, transform .2s ease, visibility 0s linear .2s;
    }
    /* The entry offset is declared once, on the closed state only. Setting it
       on the panel and then cancelling it on .is-open leaves two competing
       transform declarations, which is one cascade surprise away from a panel
       stranded 6px below its own card. */
    .public-nav.is-enhanced > ul > li:not(.is-open) > ul { transform: translateY(6px); }
    .public-nav.is-enhanced > ul > li.mega > ul {
        display: grid;
        right: auto;
        width: max-content;
        max-width: 100%;
        grid-template-columns: repeat(var(--mega-cols, 3), minmax(180px, 232px));
    }
    /* Switching between two triggers is a cross-fade only. The travel is the
       card's job, and a panel sliding at the same time reads as two things
       moving against each other. */
    .public-nav.is-enhanced > ul > li.is-open > ul {
        visibility: visible;
        opacity: 1;
        pointer-events: auto;
        transition: opacity .22s ease, transform .26s cubic-bezier(.22, 1, .36, 1);
    }

    .nav-stage { display: block; position: absolute; z-index: 1; top: 100%; right: 0; left: 0; height: 0; pointer-events: none; }
    .nav-stage__surface {
        position: absolute; top: 0; left: 0;
        width: var(--stage-w, 0px); height: var(--stage-h, 0px);
        background: var(--paper);
        border: 1px solid var(--line);
        border-radius: var(--radius-lg);
        box-shadow: 0 18px 42px rgba(23, 37, 45, .14);
        transform: translateX(var(--stage-x, 0px));
        opacity: 0;
        visibility: hidden;
        transition: opacity .18s ease, visibility 0s linear .18s,
                    transform .3s cubic-bezier(.22, 1, .36, 1),
                    width .3s cubic-bezier(.22, 1, .36, 1),
                    height .3s cubic-bezier(.22, 1, .36, 1);
    }
    .nav-stage.is-open .nav-stage__surface { opacity: 1; visibility: visible; transition-delay: 0s; }
    /* First open of a run lands on the trigger instead of sliding in from
       wherever the previous run left the card. Geometry jumps; the fade that
       makes it look deliberate is kept. */
    .nav-stage.is-placing .nav-stage__surface { transition-property: opacity, visibility; }

    .nav-pill {
        display: block;
        position: absolute; z-index: 0;
        top: var(--pill-y, 0px); left: 0;
        width: var(--pill-w, 0px); height: var(--pill-h, 0px);
        background: var(--mist);
        border-radius: var(--radius-pill);
        transform: translateX(var(--pill-x, 0px));
        opacity: 0;
        pointer-events: none;
        transition: opacity .18s ease,
                    transform .26s cubic-bezier(.22, 1, .36, 1),
                    width .26s cubic-bezier(.22, 1, .36, 1);
    }
    .nav-pill.is-on { opacity: 1; }
    .site-header.is-transparent .nav-pill { background: rgba(255, 255, 255, .16); }
    .site-header.is-transparent.is-opaque .nav-pill { background: var(--mist); }
}
.submenu-toggle { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; background: transparent; cursor: pointer; }
.submenu-toggle span { display: block; font-size: 1.2rem; line-height: 1; transition: transform .2s ease; }
.public-nav li.open > .submenu-toggle span { transform: rotate(45deg); }
.nav-toggle { display: none; width: 44px; height: 44px; padding: 9px; border: 1px solid var(--line); background: #fff; cursor: pointer; }
.nav-toggle span { display: block; width: 22px; height: 2px; margin: 5px auto; background: var(--ink); transition: transform .2s ease, opacity .2s ease; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.hero-band { min-height: min(680px, 82vh); display: flex; align-items: center; color: #fff; background: #12303a center/cover no-repeat; }
.hero-content { padding-block: 90px; }
.hero-content .hero-title { max-width: 850px; margin: .15em 0; font-size: clamp(2.7rem, 5.8vw, 5.3rem); font-weight: 700; line-height: 1.03; letter-spacing: -.03em; overflow-wrap: anywhere; }
.hero-content > p:not(.eyebrow) { max-width: 680px; font-size: 1.15rem; }
.eyebrow { color: var(--teal); font-size: .76rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
.hero-band .eyebrow { color: var(--yellow); }
.button { display: inline-flex; align-items: center; justify-content: center; min-height: 46px; padding: 10px 18px; border: 1px solid transparent; background: var(--teal); color: #fff; font-weight: 700; text-decoration: none; cursor: pointer; }
.button:hover { background: var(--teal-dark); }

.content-band { padding: 76px 0; }
.content-band h2, .cta-band h2 { margin: 0 0 18px; font-size: clamp(1.8rem, 3vw, 2.5rem); font-weight: 700; line-height: 1.2; letter-spacing: -.02em; }
.section-intro { max-width: 760px; margin: -6px 0 30px; color: var(--muted); font-size: 1.05rem; }
.prose { max-width: 820px; }
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }
.prose img, .media-block img { max-width: 100%; height: auto; }
.prose table { width: 100%; border-collapse: collapse; margin: 1.2em 0; }
.prose th, .prose td { border: 1px solid var(--line); padding: 8px 10px; vertical-align: top; }
.prose th { background: var(--mist); font-weight: 700; }
.prose iframe, .prose .ql-video, .prose video { display: block; width: 100%; aspect-ratio: 16 / 9; border: 0; margin: 1.2em 0; background: #0d1519; }
.media-block { padding-block: 40px; }
.media-block img { display: block; width: 100%; max-height: 720px; object-fit: cover; }
.media-block figcaption, .gallery-grid figcaption { padding-top: 8px; color: var(--muted); font-size: .9rem; }
.cta-band { padding: 56px 0; background: var(--yellow); }
.cta-inner { display: flex; align-items: center; justify-content: space-between; gap: 30px; }
.cta-inner p { margin-bottom: 0; }
.cta-band .button { flex: 0 0 auto; }

.cards-grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 20px; }
.content-card { padding: 26px; border: 1px solid var(--line); border-top: 4px solid var(--teal); background: #fff; }
.content-card h3 { margin: 0 0 10px; font-size: 1.25rem; }
.content-card p { color: var(--muted); }
.text-link { color: var(--teal); font-weight: 700; }
.accordion-section { max-width: 900px; }
.accordion-section details { border-top: 1px solid var(--line); }
.accordion-section details:last-child { border-bottom: 1px solid var(--line); }
.accordion-section summary { position: relative; padding: 20px 46px 20px 0; font-weight: 700; cursor: pointer; list-style: none; }
.accordion-section summary::-webkit-details-marker { display: none; }
.accordion-section summary::after { content: "+"; position: absolute; right: 12px; font-size: 1.35rem; font-weight: 400; }
.accordion-section details[open] summary::after { content: "-"; }
.accordion-body { padding: 0 48px 22px 0; color: var(--muted); }

.gallery-grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 18px; }
.gallery-grid figure { margin: 0; }
.gallery-open { display: block; width: 100%; padding: 0; border: 0; background: #e8edef; cursor: zoom-in; aspect-ratio: 4 / 3; overflow: hidden; }
.gallery-open img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .25s ease; }
.gallery-open:hover img { transform: scale(1.025); }
.gallery-dialog { width: min(94vw, 1100px); max-height: 92vh; padding: 0; border: 0; background: #0c1114; color: #fff; }
.gallery-dialog::backdrop { background: rgba(8,14,17,.84); }
.gallery-dialog img { display: block; width: 100%; max-height: 88vh; object-fit: contain; }
.gallery-close { position: absolute; top: 10px; right: 10px; width: 42px; height: 42px; border: 1px solid rgba(255,255,255,.55); background: rgba(0,0,0,.65); color: #fff; font-size: 1.5rem; cursor: pointer; }
.video-block { max-width: 1000px; }
.video-frame { overflow: hidden; background: #0d1519; aspect-ratio: 16 / 9; }
.video-frame iframe, .video-frame video { display: block; width: 100%; height: 100%; border: 0; object-fit: contain; }

.listing-page, .not-found { padding-block: 90px; min-height: 60vh; }
.listing-page h1, .not-found h1 { margin-top: 0; font-size: clamp(2.5rem, 5vw, 4.2rem); font-weight: 700; line-height: 1.1; letter-spacing: -.025em; overflow-wrap: anywhere; }
.post-list { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); margin-top: 40px; border-top: 1px solid var(--line); }
.post-list article { padding: 30px 24px; border-bottom: 1px solid var(--line); }
.post-list article:nth-child(odd) { border-right: 1px solid var(--line); }
.post-list h2 { margin: 8px 0; font-size: 1.5rem; }
.post-list h2 a { text-decoration-thickness: 1px; text-underline-offset: 4px; }
.post-list time, .muted { color: var(--muted); }

.cms-public-form { display: grid; gap: 1rem; max-width: 720px; }
.form-field { display: grid; gap: .4rem; }
.form-field label { font-weight: 700; }
.form-field input, .form-field textarea, .form-field select { width: 100%; padding: .75rem; border: 1px solid #9eacb2; background: #fff; color: var(--ink); }
.form-field textarea { min-height: 130px; resize: vertical; }
.cms-honeypot { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.form-message { max-width: 720px; margin-bottom: 1rem; padding: .85rem 1rem; border-left: 4px solid; }
.form-message.success { border-color: #16834b; background: #edf8f2; }
.form-message.error { border-color: #bd2c2c; background: #fff1f1; }

.site-footer { padding: 54px 0; background: var(--footer); color: #fff; }
.footer-inner { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; }
.footer-inner > div strong { font-size: 1.25rem; }
.footer-inner > div p { color: #afbdc3; }
.footer-inner small { grid-column: 1 / -1; padding-top: 20px; border-top: 1px solid #304047; color: #a9b6bc; }
.site-footer ul { margin: 0; padding: 0; list-style: none; }
.site-footer nav > ul { columns: 2; }
.site-footer li { break-inside: avoid; margin-bottom: 7px; }
.site-footer li ul { margin: 6px 0 10px 14px; color: #b8c4c9; }
.site-footer .submenu-toggle { display: none; }
.site-footer a { text-decoration: none; }
.site-footer a:hover { text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 900px) {
    .cards-grid, .gallery-grid { grid-template-columns: repeat(2,minmax(0,1fr)); }
    .nav-toggle { display: block; }
    .public-nav { display: none; position: fixed; top: var(--header-offset, 72px); right: 0; bottom: 0; left: 0; overflow-y: auto; padding: 14px 20px 34px; background: #fff; border-top: 1px solid var(--line); }
    .public-nav.open { display: block; }
    .public-nav > ul, .public-nav ul { display: block; }
    .public-nav li.has-children { display: grid; grid-template-columns: 1fr 44px; align-items: center; }
    .public-nav li > ul, .public-nav li > ul li > ul { position: static; grid-column: 1 / -1; padding: 0 0 6px 14px; margin-left: 12px; border: 0; border-left: 2px solid var(--line); box-shadow: none; }
    /* Nothing to cancel here any more: hover, the shared card and the pill all
       live inside (min-width: 901px), so the drawer is the only mechanism in
       range and .open is the only thing that opens a panel. */
    .public-nav li.open > ul { display: block; }
    .public-nav > ul > li.mega > ul > li > ul { display: none; }
    .public-nav > ul > li.mega > ul > li.open > ul { display: block; }
    .public-nav > ul > li.mega > ul > li > a { padding: 12px; color: inherit; font-size: inherit; font-weight: 600; letter-spacing: 0; text-transform: none; }
    .public-nav a { padding: 12px; }
}

@media (max-width: 640px) {
    .site-shell { width: min(calc(100% - 28px), var(--max)); }
    .brand { max-width: 210px; }
    .hero-band { min-height: 590px; }
    .hero-content { padding-block: 70px; }
    .hero-content .hero-title { font-size: clamp(2.5rem, 13vw, 4rem); }
    .content-band { padding: 58px 0; }
    .cta-inner, .footer-inner { display: block; }
    .cta-inner .button { margin-top: 24px; }
    .cards-grid, .gallery-grid, .post-list { grid-template-columns: 1fr; }
    .post-list article:nth-child(odd) { border-right: 0; }
    .gallery-grid { gap: 24px; }
    .site-footer nav { margin-block: 28px; }
    .site-footer nav > ul { columns: 1; }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after { scroll-behavior: auto !important; transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

/* ---------------------------------------------------------------------------
   CMS banner. Scoped to .cms-banner so it cannot reach unrelated components.
   Per-instance geometry is emitted inline by the view; this is the shared shell.
   --------------------------------------------------------------------------- */
.cms-banner { position: relative; margin: 0 auto; max-width: var(--max); }
.cms-banner--full { max-width: none; }
.cms-banner__viewport { position: relative; width: 100%; }
.cms-banner__slide { position: relative; width: 100%; height: 100%; display: flex; overflow: hidden; }
.cms-banner__slide[hidden] { display: none; }
.cms-banner__bg { position: absolute; inset: 0; }
.cms-banner__bg img { width: 100%; height: 100%; object-position: var(--focal-x, 50%) var(--focal-y, 50%); }
.cms-banner__bg[data-fit="cover"] img { object-fit: cover; }
.cms-banner__bg[data-fit="contain"] img { object-fit: contain; }
.cms-banner__bg[data-fit="fill"] img { object-fit: fill; }
.cms-banner__overlay { position: absolute; inset: 0; pointer-events: none; }
.cms-banner__stage { position: relative; width: 100%; margin: 0 auto; }
.cms-banner__el { position: absolute; display: flex; }
.cms-banner__el > * { max-width: 100%; }
/* An image element's <img> carries the source's raw width/height attributes (so the layout
   reserves space before it loads), which otherwise wins over the flex box sizing above and
   renders the image at its native pixel size instead of the authored box. data-fit is only
   present on image elements, so this never touches text, buttons or shapes. */
.cms-banner__el[data-fit] img { width: 100%; height: 100%; object-position: var(--focal-x, 50%) var(--focal-y, 50%); }
.cms-banner__el[data-fit="cover"] img { object-fit: cover; }
.cms-banner__el[data-fit="contain"] img { object-fit: contain; }
.cms-banner__el[data-fit="fill"] img { object-fit: fill; }
/* Marks whichever jump-to-slide link points at the slide it's already on - see banner.js. */
.cms-banner__el--nav-current { outline: 2px solid rgba(255, 255, 255, .75); outline-offset: 4px; border-radius: var(--radius-md); }
.cms-banner__text { margin: 0; overflow-wrap: anywhere; }
.cms-banner__shape { width: 100%; height: 100%; }
.cms-banner__btn { display: inline-flex; align-items: center; justify-content: center;
    text-decoration: none; font-family: var(--font-sans); font-weight: 600;
    padding: var(--space-3) var(--space-5); border-radius: var(--radius-md);
    min-height: var(--control-min-target); }
.cms-banner__btn--primary { background: var(--btn-primary-bg); color: var(--btn-primary-fg); }
.cms-banner__btn--primary:hover { background: var(--btn-primary-bg-hover); }
.cms-banner__btn--secondary { background: var(--btn-secondary-bg); color: var(--btn-secondary-fg);
    border: 1px solid var(--btn-secondary-border); }
.cms-banner__btn--ghost { color: var(--btn-ghost-fg); border: 1px solid currentColor; }

/* The stretched whole-slide link sits beneath the interactive elements, so buttons
   and image links keep working and no anchor is ever nested inside another. */
.cms-banner__slide-link { position: absolute; inset: 0; z-index: 0; }
.cms-banner__stage, .cms-banner__el { z-index: 1; }
.cms-banner__sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.cms-banner__nav { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
    border: 0; background: rgba(255,255,255,.85); color: var(--ink); cursor: pointer;
    width: var(--control-min-target); height: var(--control-min-target);
    border-radius: var(--radius-pill); font-size: 1.5rem; line-height: 1; }
.cms-banner__nav--prev { left: var(--space-3); }
.cms-banner__nav--next { right: var(--space-3); }
.cms-banner__dots { position: absolute; bottom: var(--space-3); left: 50%; transform: translateX(-50%);
    z-index: 2; display: flex; gap: var(--space-2); }
/* The dot is 12px but the hit area is a full touch target, so the control is easy to
   press without making the visual indicator clumsy. */
.cms-banner__dots button { width: 12px; height: 12px; padding: 0; border-radius: var(--radius-pill);
    border: 1px solid var(--paper); background: transparent; cursor: pointer; position: relative; }
.cms-banner__dots button::after { content: ""; position: absolute; top: 50%; left: 50%;
    width: var(--control-min-target); height: var(--control-min-target); transform: translate(-50%,-50%); }
.cms-banner__dots button[aria-selected="true"] { background: var(--paper); }
.cms-banner__pause { position: absolute; bottom: var(--space-3); right: var(--space-3); z-index: 2;
    cursor: pointer; border: 0; background: rgba(255,255,255,.85); color: var(--ink);
    border-radius: var(--radius-md); padding: var(--space-2) var(--space-3);
    min-height: var(--control-min-target); }

.cms-banner__video { position: relative; width: 100%; height: 100%; }
.cms-banner__video img, .cms-banner__video video, .cms-banner__video iframe {
    width: 100%; height: 100%; object-fit: cover; border: 0; }
.cms-banner__play { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);
    width: 64px; height: 64px; border-radius: var(--radius-pill); border: 0; cursor: pointer;
    background: rgba(255,255,255,.9); color: var(--ink); font-size: 1.5rem; }

.cms-banner :focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
    .cms-banner__slide { transition: none !important; animation: none !important; }
}

/* Banner motion. Everything here is opt-in: the defaults in the editor are "none", and
   a visitor who asks for reduced motion gets the static result regardless. */
@keyframes cmsBannerFadeIn { from { opacity: 0 } to { opacity: 1 } }
@keyframes cmsBannerRiseIn { from { opacity: 0; transform: translateY(16px) } to { opacity: 1; transform: none } }
@keyframes cmsBannerSlideEnter { from { opacity: 0; transform: translateX(24px) } to { opacity: 1; transform: none } }
@keyframes cmsBannerSlideInLeft { from { opacity: 0; transform: translateX(-40px) } to { opacity: 1; transform: none } }

/* Element entrance runs only once its slide is the active one. The server marks the first
   slide active, so with JavaScript disabled that slide still animates in and, more
   importantly, still ends up visible. */
.cms-banner__el[data-anim]:not([data-anim=""]) { animation-fill-mode: both; animation-play-state: paused; }
.cms-banner__slide[data-active="true"] .cms-banner__el[data-anim] { animation-play-state: running; }
.cms-banner__el[data-anim="fadeIn"] { animation-name: cmsBannerFadeIn; }
.cms-banner__el[data-anim="riseIn"] { animation-name: cmsBannerRiseIn; }
.cms-banner__el[data-anim="slideInLeft"] { animation-name: cmsBannerSlideInLeft; }

.cms-banner[data-transition="fade"] .cms-banner__slide[data-active="true"] { animation: cmsBannerFadeIn var(--cms-banner-transition, 400ms) both; }
.cms-banner[data-transition="slide"] .cms-banner__slide[data-active="true"] { animation: cmsBannerSlideEnter var(--cms-banner-transition, 400ms) both; }

@media (prefers-reduced-motion: reduce) {
    /* Not just "slower" - no entrance at all, and nothing left mid-animation. */
    .cms-banner__slide[data-active="true"],
    .cms-banner__el[data-anim]:not([data-anim=""]) { animation: none !important; opacity: 1 !important; transform: none !important; }
}

/* Vertical navigation. The controls move to the right edge and the arrows sit above and
   below, so the affordance matches the direction the carousel actually travels. */
.cms-banner[data-nav="vertical"] .cms-banner__nav { top: auto; left: auto; right: var(--space-3); transform: none; }
.cms-banner[data-nav="vertical"] .cms-banner__nav--prev { top: var(--space-3); }
.cms-banner[data-nav="vertical"] .cms-banner__nav--next { bottom: var(--space-3); }
.cms-banner[data-nav="vertical"] .cms-banner__dots {
    flex-direction: column; left: auto; bottom: auto; right: var(--space-3);
    top: 50%; transform: translateY(-50%);
}
/* Dots clear the arrows when both are shown. */
.cms-banner[data-nav="vertical"] .cms-banner__pause { bottom: var(--space-3); left: var(--space-3); right: auto; }

.cms-banner[data-nav="horizontal"][data-dots-align="start"] .cms-banner__dots { left: var(--space-4); transform: none; }
.cms-banner[data-nav="horizontal"][data-dots-align="end"] .cms-banner__dots { left: auto; right: var(--space-4); transform: none; }
.cms-banner[data-nav="vertical"][data-dots-align="start"] .cms-banner__dots { top: var(--space-6); transform: none; }
.cms-banner[data-nav="vertical"][data-dots-align="end"] .cms-banner__dots { top: auto; bottom: var(--space-6); transform: none; }

/* Indicator styles. Dots stay the compact default; numbers, labels and thumbnails need real
   boxes, so they drop the circular treatment rather than trying to squeeze into it. */
.cms-banner__dots[data-style="numbers"] button,
.cms-banner__dots[data-style="labels"] button,
.cms-banner__dots[data-style="thumbnails"] button {
    width: auto; height: auto; border-radius: var(--radius-md);
    background: rgba(255,255,255,.85); color: var(--ink);
    padding: var(--space-1) var(--space-3); min-height: var(--control-min-target);
    font: 600 .85rem/1 var(--font-sans); overflow: hidden;
}
.cms-banner__dots[data-style="numbers"] button { min-width: var(--control-min-target); }
.cms-banner__dots[data-style="labels"] button { max-width: 180px; white-space: nowrap;
    text-overflow: ellipsis; display: inline-block; }
.cms-banner__dots[data-style="thumbnails"] button { padding: 0; line-height: 0; border: 2px solid transparent; }
.cms-banner__dots[data-style="thumbnails"] button img { width: 64px; height: 40px; object-fit: cover; display: block; }

.cms-banner__dots[data-style="numbers"] button[aria-selected="true"],
.cms-banner__dots[data-style="labels"] button[aria-selected="true"] { background: var(--ink); color: var(--paper); }
.cms-banner__dots[data-style="thumbnails"] button[aria-selected="true"] { border-color: var(--paper); }

/* The oversized invisible hit area only makes sense for the small round dots. */
.cms-banner__dots:not([data-style="dots"]) button::after { display: none; }

/* Entrance presets. Each maps to one named animation the editor can pick; the stylesheet
   owns what the motion actually is, so no CSS ever comes from content. */
@keyframes cmsBannerSlideInRight { from { opacity: 0; transform: translateX(40px) } to { opacity: 1; transform: none } }
@keyframes cmsBannerSlideInUp    { from { opacity: 0; transform: translateY(40px) } to { opacity: 1; transform: none } }
@keyframes cmsBannerSlideInDown  { from { opacity: 0; transform: translateY(-40px) } to { opacity: 1; transform: none } }
@keyframes cmsBannerZoomIn       { from { opacity: 0; transform: scale(.86) } to { opacity: 1; transform: none } }
@keyframes cmsBannerZoomOut      { from { opacity: 0; transform: scale(1.14) } to { opacity: 1; transform: none } }

.cms-banner__el[data-anim="slideInRight"] { animation-name: cmsBannerSlideInRight; }
.cms-banner__el[data-anim="slideInUp"]    { animation-name: cmsBannerSlideInUp; }
.cms-banner__el[data-anim="slideInDown"]  { animation-name: cmsBannerSlideInDown; }
.cms-banner__el[data-anim="zoomIn"]       { animation-name: cmsBannerZoomIn; }
.cms-banner__el[data-anim="zoomOut"]      { animation-name: cmsBannerZoomOut; }
.cms-banner__el[data-anim="slideInLeft"]  { animation-name: cmsBannerSlideInLeft; }

/* Named curves, resolved here so a document never carries a raw cubic-bezier. */
.cms-banner__el[data-ease="ease"]      { animation-timing-function: ease; }
.cms-banner__el[data-ease="linear"]    { animation-timing-function: linear; }
.cms-banner__el[data-ease="easeOut"]   { animation-timing-function: cubic-bezier(.16,.84,.44,1); }
.cms-banner__el[data-ease="easeInOut"] { animation-timing-function: cubic-bezier(.65,.05,.36,1); }
.cms-banner__el[data-ease="back"]      { animation-timing-function: cubic-bezier(.34,1.56,.64,1); }

/* ---------------------------------------------------------------------------
   CMS site layout: announcement bar, header slots, footer regions.

   Values come from the two CmsLayouts documents as custom properties emitted by
   _LayoutStyles.cshtml. The rules live here so nothing an editor types can
   reach a selector.

   Two numbers deliberately stay in CSS. The 900px breakpoint is declared once,
   in the media query above, and site.js reads drawer mode from the toggle's
   computed display rather than repeating the number. And --header-offset is
   MEASURED from the rendered header at runtime: min-height does not describe
   the real height once branding or a wrapped announcement makes it taller.
   --------------------------------------------------------------------------- */

.site-announce { background: var(--announce-bg, #12333f); color: var(--announce-fg, #fff); font-size: .92rem; }
.announce-inner { display: flex; align-items: center; justify-content: center; gap: 14px; min-height: 40px; padding-block: 8px; }
.announce-inner p { margin: 0; text-align: center; }
.site-announce a { color: inherit; text-decoration: underline; text-underline-offset: 3px; margin-left: 8px; }
.announce-close { margin-left: auto; padding: 4px 10px; background: none; border: 0; color: inherit; font-size: 1.2rem; line-height: 1; cursor: pointer; }
.announce-close:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.site-announce[hidden] { display: none; }

.site-header:not(.has-border) { border-bottom: 0; }
.site-header:not(.is-sticky) { position: static; }
.brand img { height: var(--brand-logo-h, 40px); width: auto; }
.brand-tagline { display: block; color: var(--muted, #5b6b72); font-size: .78rem; }

/* Transparency is opt-in AND script-confirmed. The default here is opaque, so a
   visitor without JavaScript never lands on unreadable text over a pale hero. */
.site-header.is-transparent { position: fixed; inset-inline: 0; top: 0; background: var(--header-overlay, rgba(0,0,0,.45)); border-bottom-color: transparent; backdrop-filter: none; }
.site-header.is-transparent .brand span,
.site-header.is-transparent .public-nav > ul > li > a { color: #fff; }
.site-header.is-transparent.is-opaque { position: sticky; background: rgba(255,255,255,.97); }
.site-header.is-transparent.is-opaque .brand span,
.site-header.is-transparent.is-opaque .public-nav > ul > li > a { color: inherit; }

.header-actions { display: flex; align-items: center; gap: 10px; }
.header-action { padding: 9px 18px; border-radius: 6px; font-weight: 600; text-decoration: none; white-space: nowrap; }
.header-action.action-primary { background: var(--accent, #12333f); color: #fff; }
.header-action.action-outline { border: 1px solid currentColor; }
.header-action.action-text { padding-inline: 4px; text-decoration: underline; text-underline-offset: 4px; }
.drawer-actions { display: none; }

.site-header.preset-logoleftmenucentre .public-nav { margin-inline: auto; }
.site-header.preset-logocentred .header-inner { display: grid; grid-template-columns: 1fr auto 1fr; }
.site-header.preset-logocentred .brand { grid-column: 2; justify-self: center; }
.site-header.width-full .header-inner,
.site-footer.width-full .footer-inner { width: 100%; max-width: none; padding-inline: 24px; }
.site-header.width-wide .header-inner,
.site-footer.width-wide .footer-inner { width: min(calc(100% - 48px), 1560px); }

/* The footer grid is now driven by the document's column weights, set inline. */
.footer-inner { display: block; }
.footer-columns { display: grid; gap: 30px; }
.footer-column { min-width: 0; }
.footer-heading { margin: 0 0 12px; font-size: .95rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }
.footer-brand { display: block; font-size: 1.25rem; }
.footer-logo { height: 38px; width: auto; margin-bottom: 10px; }
.footer-tagline { color: #afbdc3; }
.site-footer .footer-columns nav > ul { columns: 1; }

.footer-contact { display: flex; flex-direction: column; gap: 8px; font-style: normal; }
.footer-contact a { color: inherit; }

.footer-social { display: flex; flex-wrap: wrap; gap: 12px; margin: 0; padding: 0; list-style: none; }
.footer-social a { display: inline-flex; align-items: center; gap: 8px; }
.footer-social.style-icon a { width: 38px; height: 38px; justify-content: center; border: 1px solid #304047; border-radius: 50%; }

.footer-legal { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; margin-top: 34px; color: #a9b6bc; }
.site-footer.has-border .footer-legal { padding-top: 20px; border-top: 1px solid #304047; }
.footer-legal.align-centre { justify-content: center; text-align: center; }
.footer-legal.align-right { justify-content: flex-end; }
.legal-links ul { display: flex; flex-wrap: wrap; gap: 18px; }
.legal-links li { margin-bottom: 0; }

@media (max-width: 900px) {
    /* Header actions move into the drawer, where the document asks for it. */
    .header-actions { display: none; }
    .drawer-actions { display: grid; gap: 10px; margin-top: 18px; }
    .site-header.preset-logocentred .header-inner { display: flex; }

    /* A transparent header must not stay fixed over an open drawer. */
    .site-header.is-transparent { position: sticky; background: rgba(255,255,255,.97); }
    .site-header.is-transparent .brand span { color: inherit; }
}

@media (max-width: 640px) {
    .footer-columns { grid-template-columns: 1fr !important; }
    .footer-legal { margin-top: 26px; }
}

/* ---------------------------------------------------------------------------
   Page bands.

   A band sits INSIDE the page content, above and below the body - not in the
   site chrome, which is identical everywhere. Its colours and background vary
   per page, so each band writes them inline on its own element; only the
   structural rules live here.

   --band-pad is set inline from the design's PaddingY.
   --------------------------------------------------------------------------- */

.page-band { display: block; }
.page-band-inner { padding-block: var(--band-pad, 34px); }
.page-band h1, .page-band h2 { margin: 0; line-height: 1.15; }
.page-band--header h1 { font-size: clamp(1.7rem, 4vw, 2.5rem); }
.page-band--footer h2 { font-size: clamp(1.3rem, 3vw, 1.9rem); }
.page-band .band-subtitle { margin: 10px 0 0; max-width: 70ch; opacity: .85; }

.band-breadcrumb { margin-bottom: 10px; font-size: .84rem; opacity: .8; }
.band-breadcrumb a { color: inherit; }
.band-breadcrumb span { margin-inline: 6px; }
.band-breadcrumb span[aria-current] { margin-inline: 0; }

.page-band.align-centre .page-band-inner { text-align: center; }
.page-band.align-centre .band-subtitle { margin-inline: auto; }
.page-band.align-right .page-band-inner { text-align: right; }
.page-band.align-right .band-subtitle { margin-inline-start: auto; }

.page-band.width-full .page-band-inner { width: 100%; max-width: none; padding-inline: 24px; }
.page-band.width-wide .page-band-inner { width: min(calc(100% - 48px), 1560px); }

/* The footer band pairs copy with one button, so it needs a row rather than a stack. */
.band-cta-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 20px 32px; }
.page-band--footer .band-copy { min-width: 0; }
.page-band--footer .header-action.action-primary { background: #fff; color: #12333f; }
.page-band--footer .header-action.action-outline { border-color: currentColor; color: inherit; }
.page-band--footer .header-action.action-text { color: inherit; }
.page-band--footer.align-centre .band-cta-inner { flex-direction: column; text-align: center; }
.page-band--footer.align-right .band-cta-inner { flex-direction: row-reverse; }

/* The Hero and blog headings step down to h2 when a band owns the page h1. Their existing
   rules were retargeted from the element to a .hero-title class above, so both levels look
   identical - the change is semantic, not visual. */

@media (max-width: 640px) {
    .band-cta-inner { flex-direction: column; align-items: stretch; text-align: center; }
    .band-cta-inner .header-action { text-align: center; }
}
