/*
 * NCE theme styles, loaded after Bootstrap 5.3.
 * Mobile-first: base rules target xs, larger breakpoints use Bootstrap min-width values.
 * Bootstrap is compiled CSS, so branding is applied by overriding its CSS variables.
 */

/* Inter variable font, subset to Latin and weights 400 to 700 */
@font-face {
    font-family: "Inter";
    src: url("../fonts/Inter-Variable-Latin.woff2") format("woff2");
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
}

/* Brand tokens + Bootstrap variable overrides */
:root {
    --nce-blue: #0D9DD9;
    --nce-blue-dark: #087DB0;
    --nce-blue-darker: #066A96;
    --nce-navy: #123247;

    --nce-text-primary: #2E2F2F;
    --nce-text-secondary: #5B6B75;

    --nce-bg-light: #F3F8FA;
    --nce-bg-blue-light: #EAF7FC;
    --nce-blue-pale: #D7EEF7;

    --nce-border: #DCE5E9;
    --nce-white: #FFFFFF;

    /* Two-tone ring stays visible on white, tinted, blue and navy surfaces */
    --nce-focus-ring: 0 0 0 0.125rem var(--nce-white), 0 0 0 0.25rem var(--nce-blue-dark);
    --nce-focus-color: var(--nce-blue-dark);
    --nce-eyebrow-color: var(--nce-blue-dark);

    /* #0D9DD9 fails AA for text on white, so Bootstrap "primary" maps to the dark blue */
    --bs-primary: var(--nce-blue-dark);
    --bs-primary-rgb: 8, 125, 176;
    --bs-primary-text-emphasis: var(--nce-navy);
    --bs-primary-bg-subtle: var(--nce-bg-blue-light);
    --bs-primary-border-subtle: var(--nce-border);

    --bs-light: var(--nce-bg-light);
    --bs-light-rgb: 243, 248, 250;
    --bs-dark: var(--nce-navy);
    --bs-dark-rgb: 18, 50, 71;

    --bs-font-sans-serif: "Inter", Arial, sans-serif;
    --bs-body-line-height: 1.625;
    --bs-body-color: var(--nce-text-primary);
    --bs-body-color-rgb: 46, 47, 47;
    --bs-secondary-color: var(--nce-text-secondary);
    --bs-secondary-color-rgb: 91, 107, 117;
    --bs-tertiary-bg: var(--nce-bg-light);
    --bs-tertiary-bg-rgb: 243, 248, 250;
    --bs-heading-color: var(--nce-navy);

    --bs-link-color: var(--nce-blue-dark);
    --bs-link-color-rgb: 8, 125, 176;
    --bs-link-hover-color: var(--nce-blue-darker);
    --bs-link-hover-color-rgb: 6, 106, 150;

    --bs-border-color: var(--nce-border);
    /* Restrained radius: 6px buttons, fields, callouts; 8px cards */
    --bs-border-radius: 0.375rem;
    --bs-border-radius-sm: 0.25rem;
    --bs-border-radius-lg: 0.5rem;
    --bs-border-radius-xl: 0.625rem;

    /* Soft navy elevation, used by .shadow for raised cards only */
    --bs-box-shadow: 0 0.625rem 1.875rem rgba(var(--bs-dark-rgb), 0.07);

    --bs-focus-ring-color: rgba(13, 157, 217, 0.35);
}

/* Surfaces. Cards come first so .bg-* surfaces below can recolour them; a plain white card
   restores the light-surface colours when placed inside a navy section. */
.card {
    --bs-card-border-color: var(--bs-border-color);
    --bs-card-title-color: var(--bs-heading-color);
    --bs-card-border-radius: var(--bs-border-radius-lg);
    --bs-card-inner-border-radius: calc(var(--bs-border-radius-lg) - var(--bs-border-width));
    --bs-card-spacer-y: 1.5rem;
    --bs-card-spacer-x: 1.5rem;
    --bs-heading-color: var(--nce-navy);
    --bs-secondary-color: var(--nce-text-secondary);
    --bs-link-color-rgb: 8, 125, 176;
    --bs-link-hover-color-rgb: 6, 106, 150;
    --nce-focus-color: var(--nce-blue-dark);
    --nce-eyebrow-color: var(--nce-blue-dark);
}

/* Darker blue keeps AA contrast for links and eyebrows on the tinted backgrounds */
.bg-light,
.bg-body-tertiary,
.bg-primary-subtle,
.bg-overlay-light,
.callout {
    --bs-link-color-rgb: 6, 106, 150;
    --bs-link-hover-color-rgb: 18, 50, 71;
    --nce-eyebrow-color: var(--nce-blue-darker);
}

/* Navy surfaces: white headings and links, light-blue supporting text (.text-body-secondary).
   Pair .bg-dark with .text-white; .bg-overlay sets its own text colour. */
.bg-dark,
.bg-overlay {
    --bs-heading-color: var(--nce-white);
    --nce-subtitle-color: var(--nce-blue-pale);
    --bs-secondary-color: var(--nce-bg-blue-light);
    --bs-link-color-rgb: 255, 255, 255;
    --bs-link-hover-color-rgb: 234, 247, 252;
    --nce-focus-color: var(--nce-white);
    --nce-eyebrow-color: var(--nce-bg-blue-light);
}

/* Navy band with an optional photo, e.g. page heroes and selective feature sections.
   Set the image with style="--nce-bg-image: url(...)". The overlay is solid where text spans
   the full width, and fades to the right from lg where text sits in the left 2/3. */
.bg-overlay {
    background-color: var(--nce-navy);
    background-image: linear-gradient(rgba(var(--bs-dark-rgb), 0.88), rgba(var(--bs-dark-rgb), 0.88)), var(--nce-bg-image, none);
    background-position: center;
    background-size: cover;
    color: var(--nce-white);
}

@media (min-width: 992px) {
    .bg-overlay {
        background-image: linear-gradient(90deg, rgba(var(--bs-dark-rgb), 0.96) 0%, rgba(var(--bs-dark-rgb), 0.88) 45%, rgba(var(--bs-dark-rgb), 0.55) 100%), var(--nce-bg-image, none);
    }
}

/* Light-blue alternative to .bg-overlay (editor choice on page heroes), with light-surface text.
   At least 0.92 wherever text sits keeps links above 4.5:1 even over black image areas; supporting
   text (e.g. the breadcrumb's current page) uses the body colour, as grey would drop below AA. */
.bg-overlay-light {
    --nce-overlay-light-rgb: 234, 247, 252;
    --bs-secondary-color: var(--nce-text-primary);
    /* Lighter than the navy title, still 4.6:1 over the darkest image areas */
    --nce-subtitle-color: var(--nce-blue-darker);
    background-color: var(--nce-bg-blue-light);
    background-image: linear-gradient(rgba(var(--nce-overlay-light-rgb), 0.92), rgba(var(--nce-overlay-light-rgb), 0.92)), var(--nce-bg-image, none);
    background-position: center;
    background-size: cover;
}

@media (min-width: 992px) {
    .bg-overlay-light {
        background-image: linear-gradient(90deg, rgba(var(--nce-overlay-light-rgb), 0.96) 0%, rgba(var(--nce-overlay-light-rgb), 0.92) 67%, rgba(var(--nce-overlay-light-rgb), 0.6) 100%), var(--nce-bg-image, none);
    }
}

/* Hero (template-parts/sections/hero.php) on the navy .bg-dark surface. The overlay is flat (Figma),
   so left, centred and right-aligned text all get the same contrast: white text stays above 4.5:1
   even over pure white image areas. */
.hero-media::after {
    content: "";
    position: absolute;
    inset: 0;
    background-color: rgba(var(--bs-dark-rgb), 0.68);
}

/* Content sets the height on phones; 552px from lg, per Figma */
@media (min-width: 768px) {
    .hero-body {
        min-height: 30rem;
    }
}

@media (min-width: 992px) {
    .hero-body {
        min-height: 34.5rem;
    }
}

/* Front page hero (landing arg): fills the screen below the sticky header and admin bar from lg, never
   shorter than the standard 552px. --nce-header-height is the header's rendered height (header.php). */
@media (min-width: 992px) {
    .hero-landing .hero-body {
        min-height: max(34.5rem, calc(100svh - var(--nce-header-height) - var(--wp-admin--admin-bar--height, 0px)));
    }
}

/* Slider: room for the indicators under the text, which sit at the bottom of the section padding */
.hero.carousel .hero-body {
    padding-bottom: calc(var(--nce-section-y) + 3rem);
}

.hero .carousel-indicators {
    justify-content: flex-start;
    margin-inline: auto;
    margin-bottom: calc(var(--nce-section-y) - 0.5rem);
    /* The first dot lines up with the text; its tap target reaches 0.5rem into the gutter */
    padding-inline: calc(var(--bs-gutter-x) * 0.5 - 0.5rem);
}

/* Dots with an NCE-blue pill for the active slide (Figma), on 24px tap targets */
.hero .carousel-indicators [data-bs-target] {
    position: relative;
    width: 1.5rem;
    height: 1.5rem;
    margin: 0;
    border: 0;
    background: none;
    opacity: 1;
}

.hero .carousel-indicators [data-bs-target]::after {
    content: "";
    position: absolute;
    inset: 0.5rem;
    border-radius: 50rem;
    background-color: rgba(var(--bs-white-rgb), 0.5);
}

.hero .carousel-indicators .active {
    width: 2.5rem;
}

.hero .carousel-indicators .active::after {
    background-color: var(--nce-blue);
}

/* Typography */
a {
    text-underline-offset: 0.5rem;
}

/* Card titles can wrap, and the 0.5rem offset would put the hover underline into the next line */
.card-title a {
    text-underline-offset: 0.2em;
}

:focus-visible {
    outline: 2px solid var(--nce-focus-color);
    outline-offset: 2px;
}

h1, .h1,
h2, .h2 {
    font-weight: 700;
}

h3, .h3,
h4, .h4,
h5, .h5,
h6, .h6 {
    font-weight: 600;
    line-height: 1.3;
}

h1, .h1 {
    font-size: 2.25rem;
    line-height: 1.15;
    letter-spacing: -0.02em;
}

h2, .h2 {
    font-size: 1.875rem;
    line-height: 1.2;
    letter-spacing: -0.01em;
}

h3, .h3 {
    font-size: 1.5rem;
}

h4, .h4 {
    font-size: 1.25rem;
}

h5, .h5 {
    font-size: 1.125rem;
}

h6, .h6 {
    font-size: 1rem;
}

.lead {
    font-size: 1.125rem;
    font-weight: 400;
    line-height: 1.6;
}

/* Hero subheading / page hero subtitle: pale blue on navy (11:1), dark blue on .bg-overlay-light, the muted
   text colour elsewhere */
.subtitle {
    color: var(--nce-subtitle-color, var(--bs-secondary-color));
}

/* Section label, e.g. "Upcoming events" */
.eyebrow {
    display: block;
    margin-bottom: 0.5rem;
    color: var(--nce-eyebrow-color);
    font-size: 0.8125rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

@media (min-width: 768px) {
    h1, .h1 {
        font-size: 2.5rem;
    }

    h2, .h2 {
        font-size: 2.125rem;
    }

    h3, .h3 {
        font-size: 1.625rem;
    }
}

@media (min-width: 992px) {
    h4, .h4 {
        font-size: 1.375rem;
    }

    .lead {
        font-size: 1.1875rem;
    }

    .eyebrow {
        font-size: 0.875rem;
    }
}

@media (min-width: 1200px) {
    h1, .h1 {
        font-size: 2.75rem;
    }

    h2, .h2 {
        font-size: 2.25rem;
    }
}

/* Front page hero headings (landing arg): a display size above the h1 scale, owner-approved for the
   homepage only */
.hero-landing :is(h1, .h1) {
    line-height: 1.1;
}

/* Below 576px the h1 size (36px) keeps the two-line homepage title on two lines */
@media (min-width: 576px) {
    .hero-landing :is(h1, .h1) {
        font-size: 2.5rem;
    }
}

@media (min-width: 768px) {
    .hero-landing :is(h1, .h1) {
        font-size: 3.25rem;
    }
}

@media (min-width: 1200px) {
    .hero-landing :is(h1, .h1) {
        font-size: 4rem;
    }
}

/* Vertical rhythm for page sections; Bootstrap spacers stop at 3rem */
:root {
    --nce-section-y: 3rem;
}

.section {
    padding-block: var(--nce-section-y);
}

@media (min-width: 768px) {
    :root {
        --nce-section-y: 4rem;
    }
}

@media (min-width: 992px) {
    :root {
        --nce-section-y: 5rem;
    }
}

/* 20px side padding on phones, where Bootstrap's 12px crowds the screen edge. From sm the container's
   max-width already leaves 28px or more, so the default returns. Rows set their own gutter, so only the
   container edge changes. */
.container {
    --bs-gutter-x: 2.5rem;
}

@media (min-width: 576px) {
    .container {
        --bs-gutter-x: 1.5rem;
    }
}

/* Buttons: default 12px / 20px padding (50px tall), .btn-lg 14px / 24px (54px). The system has no
   .btn-sm; this rule loads after Bootstrap and would override its padding. */
.btn {
    --bs-btn-padding-y: 0.75rem;
    --bs-btn-padding-x: 1.25rem;
    --bs-btn-font-weight: 600;
    --bs-btn-focus-box-shadow: var(--nce-focus-ring);
}

.btn-primary {
    --bs-btn-bg: var(--nce-blue-dark);
    --bs-btn-border-color: var(--nce-blue-dark);
    --bs-btn-hover-bg: var(--nce-blue-darker);
    --bs-btn-hover-border-color: var(--nce-blue-darker);
    --bs-btn-active-bg: var(--nce-blue-darker);
    --bs-btn-active-border-color: var(--nce-blue-darker);
    --bs-btn-disabled-bg: var(--nce-blue-dark);
    --bs-btn-disabled-border-color: var(--nce-blue-dark);
}

/* Page-level calls to action; text stays 16px */
.btn-lg {
    --bs-btn-padding-y: 0.875rem;
    --bs-btn-padding-x: 1.5rem;
    --bs-btn-font-size: 1rem;
    --bs-btn-border-radius: var(--bs-border-radius);
}

.btn-outline-primary {
    --bs-btn-bg: var(--nce-white);
    --bs-btn-color: var(--nce-blue-dark);
    --bs-btn-border-color: var(--nce-blue-dark);
    --bs-btn-hover-bg: var(--nce-bg-blue-light);
    --bs-btn-hover-color: var(--nce-blue-darker);
    --bs-btn-hover-border-color: var(--nce-blue-darker);
    --bs-btn-active-bg: var(--nce-bg-blue-light);
    --bs-btn-active-color: var(--nce-blue-darker);
    --bs-btn-active-border-color: var(--nce-blue-darker);
    --bs-btn-disabled-color: var(--nce-blue-dark);
    --bs-btn-disabled-border-color: var(--nce-blue-dark);
}

/* White outline button for navy surfaces and hero media, next to .btn-primary */
.btn-outline-light {
    --bs-btn-color: var(--nce-white);
    --bs-btn-border-color: var(--nce-white);
    --bs-btn-hover-color: var(--nce-navy);
    --bs-btn-hover-bg: var(--nce-white);
    --bs-btn-hover-border-color: var(--nce-white);
    --bs-btn-active-color: var(--nce-navy);
    --bs-btn-active-bg: var(--nce-bg-blue-light);
    --bs-btn-active-border-color: var(--nce-bg-blue-light);
    --bs-btn-disabled-color: var(--nce-white);
    --bs-btn-disabled-border-color: var(--nce-white);
}

/* Components whose active/focus colours Bootstrap hard-codes */
.nav,
.navbar-nav {
    --bs-nav-link-font-weight: 600;
    --bs-nav-pills-link-active-bg: var(--nce-blue-dark);
}

.nav-link:focus-visible {
    box-shadow: var(--nce-focus-ring);
}

.dropdown-menu {
    --bs-dropdown-border-color: var(--nce-border);
    --bs-dropdown-link-active-bg: var(--nce-blue-dark);
}

/* No ring on click; keyboard focus keeps the brand ring (.page-link:focus-visible below) */
.pagination {
    --bs-pagination-active-bg: var(--nce-blue-dark);
    --bs-pagination-active-border-color: var(--nce-blue-dark);
    --bs-pagination-focus-box-shadow: none;
    /* ~46px tap targets */
    --bs-pagination-padding-x: 1rem;
    --bs-pagination-padding-y: 0.625rem;
}
.page-link:focus-visible {
    box-shadow: var(--nce-focus-ring);
}

/* Meta size (14px); .small alone loses to Bootstrap's var(--bs-breadcrumb-font-size) */
.breadcrumb {
    --bs-breadcrumb-font-size: 0.875rem;
}

/* A long current page (e.g. an article title, shown in full in the h1 below) is shortened with an ellipsis
   instead of wrapping onto a line under its separator; parents never shorten, and the item only moves to a
   new line when less than 6rem is left */
.breadcrumb-item.active {
    flex: 1 1 0;
    min-width: 6rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.list-group {
    --bs-list-group-active-bg: var(--nce-blue-dark);
    --bs-list-group-active-border-color: var(--nce-blue-dark);
}

@media (min-width: 992px) {
    .card {
        --bs-card-spacer-y: 1.75rem;
        --bs-card-spacer-x: 1.75rem;
    }
}

/* Important notice or deadline, not for ordinary paragraphs */
.callout {
    padding: 1.5rem;
    background-color: var(--nce-bg-blue-light);
    border-left: 4px solid var(--nce-blue);
    border-radius: var(--bs-border-radius);
}

.callout > :last-child {
    margin-bottom: 0;
}

/* Closed or expired notice (e.g. applications closed): Bootstrap's danger colour, kept pale so it
   doesn't read as an error. Dark red heading on the tint is well above AA. */
.callout-closed {
    --bs-heading-color: var(--bs-danger-text-emphasis);
    background-color: rgba(var(--bs-danger-rgb), 0.06);
    border-left-color: var(--bs-danger);
}

/* Forms */
.form-label {
    font-weight: 500;
}

/* Fields: 10px / 14px padding (46px tall), a comfortable touch target next to the 50px buttons.
   Loads after Bootstrap, so it would override .form-control-sm/-lg, which the system doesn't use. */
.form-control {
    padding: 0.625rem 0.875rem;
}

.form-select {
    padding: 0.625rem 2.5rem 0.625rem 0.875rem;
    background-position: right 0.875rem center;
}

.form-control:focus,
.form-select:focus,
.form-check-input:focus {
    border-color: var(--nce-blue);
    box-shadow: 0 0 0 0.25rem var(--bs-focus-ring-color);
}

.form-check-input:checked,
.form-check-input[type=checkbox]:indeterminate {
    background-color: var(--nce-blue-dark);
    border-color: var(--nce-blue-dark);
}

/* Contact Form 7: fields get Bootstrap classes in the form template (class:form-control); CF7's
   hard-coded feedback colours are swapped for Bootstrap's invalid-feedback and alert colours */
.wpcf7-not-valid-tip {
    margin-top: 0.25rem;
    color: var(--bs-form-invalid-color);
    font-size: 0.875em;
}

.form-control.wpcf7-not-valid {
    border-color: var(--bs-form-invalid-border-color);
}

.wpcf7 form .wpcf7-response-output {
    margin: 1.5rem 0 0;
    padding: 1rem;
    color: var(--bs-primary-text-emphasis);
    background-color: var(--bs-primary-bg-subtle);
    border: var(--bs-border-width) solid var(--bs-primary-border-subtle);
    border-radius: var(--bs-border-radius);
}

.wpcf7 form.sent .wpcf7-response-output {
    color: var(--bs-success-text-emphasis);
    background-color: var(--bs-success-bg-subtle);
    border-color: var(--bs-success-border-subtle);
}

.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.unaccepted .wpcf7-response-output {
    color: var(--bs-warning-text-emphasis);
    background-color: var(--bs-warning-bg-subtle);
    border-color: var(--bs-warning-border-subtle);
}

.wpcf7 form.failed .wpcf7-response-output,
.wpcf7 form.aborted .wpcf7-response-output,
.wpcf7 form.spam .wpcf7-response-output {
    color: var(--bs-danger-text-emphasis);
    background-color: var(--bs-danger-bg-subtle);
    border-color: var(--bs-danger-border-subtle);
}

.wpcf7-spinner {
    background-color: var(--nce-navy);
}

/* Phone fields (intl-tel-input, see js/main.js). The input keeps .form-control; the library sets its left
   padding to clear the flag and dial code. The library stylesheet loads before this file. */
.iti {
    --iti-border-color: var(--nce-border);
    --iti-hover-color: var(--nce-bg-blue-light);
    --iti-icon-color: var(--nce-text-secondary);
    --iti-spacer-horizontal: 0.875rem;
}

.iti .iti__selected-country,
.iti .iti__selected-country-primary {
    border-radius: var(--bs-border-radius) 0 0 var(--bs-border-radius);
}

/* Country list: like .dropdown-menu */
.iti .iti__country-selector {
    color: var(--bs-body-color);
    border-radius: var(--bs-border-radius);
    box-shadow: none;
}

/* Rounded corners clip the list; not in the fullscreen picker, whose close button sits outside it */
.iti--inline-country-selector .iti__country-selector {
    overflow: hidden;
}

/* One message per field: the country-aware error replaces CF7's generic one */
.wpcf7-form-control-wrap:has(> .invalid-feedback) .wpcf7-not-valid-tip {
    display: none;
}

.iti .iti__search-input:focus-visible {
    outline-offset: -2px;
}

/* Detached list and the fullscreen picker (narrow screens) sit above the sticky header, Bootstrap modals
   and the WordPress admin bar (99999) */
.iti.iti--detached-country-selector {
    z-index: 100000;
}

/* Contact page map: a fixed, modest height so it doesn't dominate the page */
.contact-map {
    height: 20rem;
}

@media (min-width: 992px) {
    .contact-map {
        height: 24rem;
    }
}

/* Publication cards (template-parts/components/publication-card.php): a portrait cover area where the
   artwork is contained, never cropped, whatever its proportions */
.publication-cover {
    --bs-aspect-ratio: 133.333%;
}

.publication-cover-icon {
    color: var(--nce-blue);
    font-size: 2.5rem;
}

/* Person cards (template-parts/components/person-card.php): a 4:5 portrait cropped towards the top,
   so heads stay in frame whatever the photo's own proportions. Beside the text on phones, it fills the
   card when the text runs taller than the portrait. */
.person-portrait {
    --bs-aspect-ratio: 125%;
    height: 100%;
}

@media (min-width: 576px) {
    .person-portrait {
        height: auto;
    }
}

.person-portrait img {
    object-position: 50% 20%;
}

.person-portrait-icon {
    color: var(--nce-blue);
    font-size: 3rem;
}

/* Consultant cards (template-parts/components/consultant-card.php): a fixed small square, as the legacy portraits are only 300px */
.consultant-portrait {
    flex-shrink: 0;
    width: 6rem;
    height: 6rem;
}

.consultant-portrait img {
    object-position: 50% 20%;
}

/* News (home.php, template-parts/components/news-card.php): an NCE-blue mark when a post has no featured image.
   The front page's service cards use it too, for a card without an image. */
.news-placeholder-icon {
    color: var(--nce-blue);
    font-size: 2.5rem;
}

/* Lead story image: 16:9 above the text below lg, filling the card's height beside it from lg */
.news-lead-media {
    aspect-ratio: 16 / 9;
}

@media (min-width: 992px) {
    .news-lead-media {
        aspect-ratio: auto;
        height: 100%;
        min-height: 22rem;
    }
}

/* Editor content (pages, news articles): images and tables stay within the reading column; wide tables scroll */
.entry-content img {
    max-width: 100%;
    height: auto;
}

.entry-content table {
    display: block;
    overflow-x: auto;
    margin-bottom: 1rem;
    border-collapse: collapse;
}

.entry-content :is(th, td) {
    padding: 0.5rem 0.75rem;
    border: var(--bs-border-width) solid var(--bs-border-color);
}

.entry-content > :last-child {
    margin-bottom: 0;
}

/* Front page key figures: equal-width digits so a figure doesn't jitter while js/counters.js counts it up */
.stat-value {
    font-variant-numeric: tabular-nums;
}

/* Events (template-events.php, front page): a square date block beside the title; white so it stays distinct
   on the light-blue header of an open accordion item */
.event-date {
    width: 4.5rem;
    height: 4.5rem;
}

.accordion {
    --bs-accordion-border-color: var(--nce-border);
    --bs-accordion-border-radius: var(--bs-border-radius-lg);
    --bs-accordion-inner-border-radius: calc(var(--bs-border-radius-lg) - var(--bs-border-width));
    --bs-accordion-btn-focus-box-shadow: var(--nce-focus-ring);
    --bs-accordion-active-bg: var(--nce-bg-blue-light);
    --bs-accordion-active-color: var(--bs-body-color);
}

/* An event with nothing more to show: the row's look without the toggle */
.event-static::after {
    content: none;
}

.event-body > :last-child {
    margin-bottom: 0;
}

/* Front page featured band (front-page.php): a 16:9 image above the text on phones and tablets; from lg it fills
   the band's left half to the screen edge, beside text in the container's right half */
.feature-media {
    aspect-ratio: 16 / 9;
}

@media (min-width: 992px) {
    .feature-media {
        position: absolute;
        inset: 0 50% 0 0;
        aspect-ratio: auto;
    }

    /* Enough height that the image reads as a photo rather than a strip */
    .feature-body {
        min-height: 28rem;
    }
}

/* Trade affiliation cards (template-affiliations.php): a fixed square beside the name, so logos of any shape
   are shown whole and every card lines up, with or without a logo */
.affiliation-logo {
    flex-shrink: 0;
    width: 5rem;
    height: 5rem;
}

.affiliation-logo-icon {
    color: var(--nce-blue);
    font-size: 2rem;
}

/* SCF rich text blocks (About, CET, Membership) end without a trailing paragraph margin */
.about-copy > :last-child,
.cet-copy > :last-child,
.membership-copy > :last-child {
    margin-bottom: 0;
}

/* Intro image (template-parts/components/intro-media.php): a wide crop on phones so it doesn't dominate, 4:3 beside the text from lg */
.intro-media {
    --bs-aspect-ratio: 56.25%;
}

@media (min-width: 992px) {
    .intro-media {
        --bs-aspect-ratio: 75%;
    }
}

/* Mark in the quality policy's key fact card, shown whole at its own proportions */
.about-fact-image {
    width: 5rem;
    height: auto;
}

@media (min-width: 992px) {
    .about-fact-image {
        width: 6rem;
    }
}

/* Vision and mission on navy, with the callout's NCE-blue rule */
.about-statement {
    padding-left: 1.5rem;
    border-left: 4px solid var(--nce-blue);
}

/* Milestone timeline: vertical on phones, horizontal from md. The row has no gutters, so the line
   runs unbroken through the markers (rows that wrap get a gap from md); the ring, matching
   the .bg-light section, separates each marker from the line. */
.milestone {
    position: relative;
    padding: 0 0 2rem 2rem;
    border-left: 2px solid var(--nce-border);
}

.milestone:last-child {
    padding-bottom: 0;
    border-left-color: transparent;
}

.milestone::before {
    content: "";
    position: absolute;
    top: 0.5rem;
    left: -0.5625rem;
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    background-color: var(--nce-blue);
    box-shadow: 0 0 0 0.25rem var(--nce-bg-light);
}

@media (min-width: 768px) {
    .milestone,
    .milestone:last-child {
        padding: 2rem 1.5rem 0 0;
        border-left: 0;
        border-top: 2px solid var(--nce-border);
    }

    .milestone::before {
        top: -0.5625rem;
        left: 0;
    }
}

/* Standards principle icon tile (template-standards.php): a fixed square so every card's text starts at the same point */
.principle-icon {
    width: 3.5rem;
    height: 3.5rem;
    color: var(--nce-blue);
    font-size: 1.75rem;
}

/* Numbered items (numbered-steps.php, Standards principles, Certificate of Origin steps, Women's Wing objectives):
   equal-width figures keep the text beside 01 to 10 aligned */
.principle-number {
    font-variant-numeric: tabular-nums;
}

/* Directory results loading in place (js/directory.js) */
[data-directory][aria-busy="true"] .table,
[data-directory][aria-busy="true"] .list-group {
    opacity: 0.6;
    transition: opacity 0.15s;
}

/* The result count only receives focus from the script (tabindex="-1", not a tab stop) so screen readers
   announce the new results; it isn't a control, so it needs no focus ring. */
[data-directory-status]:focus {
    outline: 0;
}

/* Certificate of Ethical Trading page (template-cet.php): the logo shown whole beside the intro */
.cet-mark {
    width: 10rem;
    height: auto;
}

@media (min-width: 992px) {
    .cet-mark {
        width: 100%;
        max-width: 15rem;
    }
}

/* Donut chart (template-parts/components/donut-chart.php): ring segments are SVG circle strokes, coloured
   through --nce-chart-color; the white centre holds the total. Both colours pass 3:1 against white. */
.donut-chart {
    position: relative;
    flex-shrink: 0;
    width: 11rem;
    height: 11rem;
}

.donut-chart svg {
    display: block;
    width: 100%;
    height: 100%;
}

.donut-chart circle {
    fill: none;
    stroke: var(--nce-chart-color);
    stroke-width: 6;
}

/* Inside the ring's hole at both sizes */
.donut-chart-total {
    width: 6.5rem;
}

.donut-chart-swatch {
    flex-shrink: 0;
    width: 1rem;
    height: 1rem;
    margin-top: 0.5rem;
    border-radius: var(--bs-border-radius-sm);
    background-color: var(--nce-chart-color);
}

@media (min-width: 992px) {
    .donut-chart {
        width: 12rem;
        height: 12rem;
    }
}

/* Membership page (template-membership.php): room between long eligibility criteria */
.membership-copy li + li {
    margin-top: 0.75rem;
}

/* Membership categories tree: nested lists joined by connector lines drawn with pseudo-elements. Below lg an
   indented tree with the line on the left; from lg a left-to-right tree centred in the section. Each child
   draws its own stub and its share of the vertical line, so the line stops at the first and last child. */
.membership-tree,
.membership-tree ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.membership-tree {
    --nce-tree-line: 2px solid var(--nce-blue);
    --nce-tree-stub: 1.25rem;
    /* Middle of a one-line node below lg: padding-top + half the node's height */
    --nce-tree-mid: 2rem;
    /* Centred under the section heading at every size */
    width: fit-content;
    max-width: 100%;
    margin-inline: auto;
}

.membership-tree ul {
    padding-left: 1rem;
}

.membership-tree ul > li {
    position: relative;
    padding: 0.75rem 0 0 var(--nce-tree-stub);
}

.membership-tree ul > li::before,
.membership-tree ul > li::after {
    content: "";
    position: absolute;
    left: 0;
}

.membership-tree ul > li::before {
    top: var(--nce-tree-mid);
    width: var(--nce-tree-stub);
    border-top: var(--nce-tree-line);
}

.membership-tree ul > li::after {
    top: 0;
    bottom: 0;
    border-left: var(--nce-tree-line);
}

.membership-tree ul > li:last-child::after {
    bottom: auto;
    height: var(--nce-tree-mid);
}

.membership-tree-node {
    display: inline-block;
    padding: 0.5rem 1rem;
    border-radius: var(--bs-border-radius);
    font-weight: 600;
}

@media (min-width: 992px) {
    .membership-tree {
        --nce-tree-stub: 1.5rem;
        display: flex;
    }

    .membership-tree li {
        display: flex;
        align-items: center;
    }

    .membership-tree ul {
        position: relative;
        display: flex;
        flex-direction: column;
        padding-left: var(--nce-tree-stub);
    }

    /* From the parent node to the children's vertical line */
    .membership-tree ul::before {
        content: "";
        position: absolute;
        top: 50%;
        left: 0;
        width: var(--nce-tree-stub);
        border-top: var(--nce-tree-line);
    }

    .membership-tree ul > li {
        padding: 0.5rem 0 0.5rem var(--nce-tree-stub);
    }

    .membership-tree ul > li::before {
        top: 50%;
    }

    .membership-tree ul > li:first-child::after {
        top: 50%;
    }

    .membership-tree ul > li:last-child::after {
        height: auto;
        bottom: 50%;
    }

    .membership-tree ul > li:only-child::after {
        content: none;
    }

    /* Equal widths line each level up as a column */
    .membership-tree-node {
        width: 15rem;
        padding: 0.75rem 1rem;
        text-align: center;
    }

    .membership-tree > li > .membership-tree-node {
        width: 10rem;
    }
}

/* Awards page (template-awards.php): the key detail cards overlap the hero's bottom edge by half its
   padding (48 / 64 / 80px), leaving the other half as clear space below the hero text. The row's own
   gutter offset is kept. */
.awards-details {
    position: relative;
    margin-top: calc(-1 * var(--bs-gutter-y) - 1.5rem);
}

@media (min-width: 768px) {
    .awards-details {
        margin-top: calc(-1 * var(--bs-gutter-y) - 2rem);
    }
}

@media (min-width: 992px) {
    .awards-details {
        margin-top: calc(-1 * var(--bs-gutter-y) - 2.5rem);
    }
}

/* Milestone timeline (template-parts/components/timeline.php): line on the left with the date above
   each milestone below lg; from lg a right-aligned date column beside the line. Each item draws the line
   down to the next dot, so it stops at the last one. The dot's ring, in the white page background,
   covers the joins; change it if the timeline ever sits on another surface. */
.timeline {
    --nce-timeline-gap: 2.5rem;
    --nce-timeline-dot: 1rem;
    --nce-timeline-indent: 2.5rem; /* content offset from the item's left edge */
    --nce-timeline-line: 0.5rem; /* the line's x position, from the item's left edge */
    display: grid;
    row-gap: var(--nce-timeline-gap);
}

.timeline-item {
    position: relative;
    padding-left: var(--nce-timeline-indent);
}

.timeline-item:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 0.75rem;
    bottom: calc(-1 * var(--nce-timeline-gap));
    left: calc(var(--nce-timeline-line) - 1px);
    width: 2px;
    background-color: var(--nce-border);
}

.timeline-date {
    position: relative;
    font-variant-numeric: tabular-nums;
}

/* Centred on the date's line, whatever its size or wrapping */
.timeline-date::before {
    content: "";
    position: absolute;
    z-index: 1;
    top: 50%;
    left: calc(var(--nce-timeline-line) - var(--nce-timeline-dot) / 2 - var(--nce-timeline-indent));
    width: var(--nce-timeline-dot);
    height: var(--nce-timeline-dot);
    border-radius: 50%;
    background-color: var(--nce-blue);
    box-shadow: 0 0 0 0.25rem var(--nce-white);
    transform: translateY(-50%);
}

/* Media: a wide frame on phones so it doesn't dominate, 4:3 beside the text from md, growing to the
   card's height if the text runs taller */
.timeline-media {
    --bs-aspect-ratio: 56.25%;
}

@media (min-width: 768px) {
    .timeline-media {
        --bs-aspect-ratio: 75%;
        height: 100%;
    }
}

@media (min-width: 992px) {
    .timeline {
        --nce-timeline-gap: 3rem;
        --nce-timeline-date: 9rem;
        --nce-timeline-column-gap: 4rem;
        --nce-timeline-line: calc(var(--nce-timeline-date) + var(--nce-timeline-column-gap) / 2);
    }

    .timeline-item {
        display: grid;
        grid-template-columns: var(--nce-timeline-date) minmax(0, 46rem);
        column-gap: var(--nce-timeline-column-gap);
        align-items: start;
        padding-left: 0;
    }

    .timeline-date {
        text-align: right;
    }

    .timeline-date::before {
        left: calc(var(--nce-timeline-line) - var(--nce-timeline-dot) / 2);
    }
}

/* Header: Bootstrap navbar, offcanvas below lg (see header.php) */

/* Sticky (.sticky-top); js/main.js adds .is-hidden while scrolling down. The transform is only
   applied when hidden: on the header itself it would pin the fixed offcanvas drawer to the header. */
/* Rendered header height (logo + navbar padding), for layouts that fill the screen below it */
:root {
    --nce-header-height: 5.1875rem;
}

@media (min-width: 1200px) {
    :root {
        --nce-header-height: 6.3125rem;
    }
}

.site-header {
    transition: transform 0.25s ease-in-out;
}

.site-header.is-hidden {
    transform: translateY(-100%);
}

/* Keep it in view for keyboard users, and while the drawer is open */
.site-header:has(:focus-visible),
.site-header:has(.offcanvas.showing, .offcanvas.show, .offcanvas.hiding) {
    transform: none;
}

/* The drawer lives inside the sticky header's stacking context, so lift the header above
   Bootstrap's backdrop (1040) and the WordPress admin bar (99999) while it is open */
.site-header:has(.offcanvas.showing, .offcanvas.show, .offcanvas.hiding) {
    z-index: 100000;
}

/* Sit below the WordPress admin bar; it scrolls away below 600px (WordPress breakpoint) */
@media (min-width: 600px) {
    .admin-bar .site-header {
        top: var(--wp-admin--admin-bar--height, 0);
    }
}

.custom-logo {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 3rem;
}

.navbar {
    --bs-navbar-color: var(--nce-navy);
    --bs-navbar-hover-color: var(--nce-blue-dark);
    --bs-navbar-active-color: var(--nce-blue-dark);
    --bs-navbar-toggler-padding-x: 0.5rem;
    --bs-navbar-toggler-padding-y: 0.375rem;
    --bs-navbar-toggler-border-color: transparent;
    /* Bootstrap rings the toggler on any :focus (mouse clicks too); keyboard ring is below */
    --bs-navbar-toggler-focus-width: 0;
}

/* Same for the offcanvas close button: no ring on click, brand ring for keyboard */
.btn-close {
    --bs-btn-close-focus-shadow: none;
}

.btn-close:focus-visible,
.navbar-toggler:focus-visible {
    box-shadow: var(--nce-focus-ring);
}

/* Fit narrow phones; sit above the WordPress admin bar (z-index 99999) */
.navbar .offcanvas {
    --bs-offcanvas-width: 20rem;
    --bs-offcanvas-zindex: 100000;
}

/* Roomy tap targets in the drawer (~46px) */
.navbar-nav {
    --bs-nav-link-padding-y: 0.625rem;
}

/* Drawer (below lg): full-width rows split by rules, with the chevron at the row's end. Submenus open
   inline as an indented list rather than a boxed dropdown; lg restores the dropdown. */
.navbar-nav > .nav-item + .nav-item {
    border-top: var(--bs-border-width) solid var(--bs-border-color);
}

.navbar-nav .dropdown-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
}

.navbar-nav .dropdown-menu {
    --bs-dropdown-border-width: 0;
    --bs-dropdown-bg: transparent;
    --bs-dropdown-padding-y: 0;
    --bs-dropdown-item-padding-y: 0.625rem;
    --bs-dropdown-item-border-radius: var(--bs-border-radius);
    /* A tint rather than the solid blue bar, which is heavy in a list; the weight keeps it from being colour alone */
    --bs-dropdown-link-active-bg: var(--nce-bg-blue-light);
    --bs-dropdown-link-active-color: var(--nce-blue-darker);
    margin-bottom: 0.75rem;
}

.navbar-nav .dropdown-item.active {
    font-weight: 600;
}

/* Active state is not colour alone. On the label, so the underline stays off the chevron in the drawer's
   flex rows. */
.navbar-nav .nav-link.active > span {
    text-decoration: underline;
    text-underline-offset: 0.5rem;
}

/* Chevron (Bootstrap Icons chevron-down) instead of Bootstrap's caret */
.navbar .dropdown-toggle::after {
    border: 0;
    margin-left: 0.5rem;
    font-family: "bootstrap-icons";
    font-size: 0.75em;
    content: "\f282";
    content: "\f282" / "";
    vertical-align: -0.0625em;
}

.navbar .dropdown-toggle[aria-expanded="true"]::after {
    transform: rotate(180deg);
}

.header-search-toggle {
    --bs-btn-color: var(--nce-navy);
    --bs-btn-bg: var(--nce-bg-light);
    --bs-btn-border-color: var(--nce-bg-light);
    --bs-btn-hover-color: var(--nce-navy);
    --bs-btn-hover-bg: var(--nce-bg-blue-light);
    --bs-btn-hover-border-color: var(--nce-bg-blue-light);
    --bs-btn-active-color: var(--nce-navy);
    --bs-btn-active-bg: var(--nce-bg-blue-light);
    --bs-btn-active-border-color: var(--nce-bg-blue-light);
    width: 2.75rem;
    height: 2.75rem;
}

/* 992 to 1199px is the tightest fit: the smaller logo, gaps and link padding keep the logo, menu and search
   within the 936px container without wrapping a label (xl restores the larger sizes). */
@media (min-width: 992px) {
    .custom-logo {
        max-height: 3.125rem;
    }

    /* Logo and actions share the leftover width equally, so the menu sits on the header's centre line */
    .header-side {
        flex: 1 0 0;
        min-width: max-content;
    }

    .navbar {
        --bs-navbar-nav-link-padding-x: 0.375rem;
    }

    .navbar .offcanvas {
        flex-grow: 0;
        margin-inline: 0.5rem;
    }

    .navbar-nav {
        --bs-nav-link-font-size: 0.9375rem;
    }

    .navbar-nav > .nav-item + .nav-item {
        border-top: 0;
    }

    .navbar-nav .dropdown-toggle {
        display: block;
        width: auto;
    }

    .navbar-nav .dropdown-menu {
        --bs-dropdown-border-width: var(--bs-border-width);
        --bs-dropdown-bg: var(--bs-body-bg);
        --bs-dropdown-padding-y: 0.5rem;
        --bs-dropdown-font-size: 0.9375rem;
        --bs-dropdown-item-padding-y: 0.5rem;
        --bs-dropdown-item-border-radius: 0;
        --bs-dropdown-link-active-bg: var(--nce-blue-dark);
        --bs-dropdown-link-active-color: var(--nce-white);
        margin-bottom: 0;
    }

    .navbar-nav .dropdown-item.active {
        font-weight: inherit;
    }

    .header-search-toggle {
        width: 2.25rem;
        height: 2.25rem;
    }
}

@media (min-width: 1200px) {
    .custom-logo {
        max-height: 3.75rem;
    }

    .navbar {
        --bs-navbar-nav-link-padding-x: 0.75rem;
    }
}

/* Footer (footer.php) on the navy .bg-dark surface. #wrapper is a flex column (header.php) with
   #container growing, so the footer sits at the bottom of short pages, below the admin bar if shown. */
.site-wrapper {
    min-height: calc(100vh - var(--wp-admin--admin-bar--height, 0px));
    /* Visible height on phones, where 100vh ignores the browser toolbar */
    min-height: calc(100dvh - var(--wp-admin--admin-bar--height, 0px));
}

.footer-logo {
    display: block;
    width: 18.75rem;
    max-width: 100%;
    height: auto;
}

/* Menu and contact links: light blue, white + underline on hover; padding gives ~30px tap targets */
.footer-links a {
    display: inline-block;
    padding-block: 0.25rem;
    color: var(--bs-secondary-color);
    text-decoration: none;
}

.footer-links a:hover {
    color: var(--nce-white);
    text-decoration: underline;
}

.footer-social-link {
    --bs-btn-color: var(--nce-white);
    --bs-btn-bg: rgba(var(--bs-white-rgb), 0.1);
    --bs-btn-border-color: transparent;
    --bs-btn-hover-color: var(--nce-white);
    --bs-btn-hover-bg: var(--nce-blue-dark);
    --bs-btn-hover-border-color: var(--nce-blue-dark);
    --bs-btn-active-color: var(--nce-white);
    --bs-btn-active-bg: var(--nce-blue-darker);
    --bs-btn-active-border-color: var(--nce-blue-darker);
    width: 2.75rem;
    height: 2.75rem;
}

@media (min-width: 992px) {
    .footer-social-link {
        width: 2.25rem;
        height: 2.25rem;
    }
}

@media (min-width: 1200px) {
    .footer-logo {
        width: 22.5rem;
    }
}

/* Floating back-to-top link, shown by js/main.js after one screen of scrolling */
.back-to-top {
    --bs-btn-font-size: 1.25rem;
    /* White ring separates it from the navy footer; invisible on white pages */
    box-shadow: 0 0 0 1px var(--nce-white);
    z-index: 1030;
    width: 2.75rem;
    height: 2.75rem;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s, visibility 0.2s;
}

.back-to-top.is-visible {
    opacity: 1;
    visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
    .site-header,
    .back-to-top {
        transition: none;
    }
}

/* Search results: navy titles, link blue on hover (Bootstrap's .link-dark hover is hard-coded) */
.search-result-title a {
    color: var(--nce-navy);
    text-decoration: none;
}

.search-result-title a:hover {
    color: var(--nce-blue-dark);
    text-decoration: underline;
}

/* WordPress core output (search form labels, post navigation headings) */
.screen-reader-text {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
