@charset "UTF-8";
/**
 * components.css
 *
 * Reusable components used across blocks and templates: buttons,
 * navigation, cards, form controls. Component selectors use BEM with
 * the .tif- prefix (.tif-card, .tif-card__title); button modifiers use
 * .btn--{style} keyed to tif_button_styles().
 *
 * One file for every cross-block component. Block-specific layout
 * styles live in blocks.css.
 *
 * Tokens (--color-*, --space-*, --font-*) are defined once in base.css.
 * Don't re-declare them here.
 */

/* ============================================================
   Site header (header.php) + primary navigation
   Fixed, dark, translucent bar over the hero. Mirrors the mockup
   `header.site` / `.logo` / `nav.primary`. The WordPress nav markup
   uses .menu / .menu-item / .sub-menu (not the mockup's hand-rolled
   .has-dropdown / .dropdown), so the selectors below target those.
   ============================================================ */

.site-header {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 1000;
    background: color-mix(in srgb, var(--color-teal-dark) 92%, transparent);
    backdrop-filter: saturate(180%) blur(16px);
    -webkit-backdrop-filter: saturate(180%) blur(16px);
    border-bottom: 1px solid rgba(122, 197, 205, 0.14);
}

.site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    min-height: var(--tif-header-height);
    padding-block: 14px;
}

/* Skip link — visible on focus, sits above the fixed header. */
.skip-link:focus {
    position: fixed;
    top: 8px;
    left: 8px;
    z-index: 1100;
    width: auto;
    height: auto;
    margin: 0;
    padding: 10px 18px;
    clip: auto;
    clip-path: none;
    background: var(--color-teal-accent);
    color: var(--color-teal-dark);
    font-weight: 600;
    text-decoration: none;
}

/* Push the first block of every page below the fixed header — except the
   hero, which is designed to sit behind the translucent bar. */
.site-main > *:first-child:not(.layout-hero) {
    padding-top: calc(var(--tif-header-height) + var(--space-lg));
}

/* Logo lockup */
.logo {
    display: inline-flex;
    align-items: center;
    gap: 14px;
    font-family: var(--font-serif);
    font-size: 1.3rem;
    font-weight: 500;
    letter-spacing: -0.01em;
    line-height: 1.15;
    color: var(--color-white);
    text-decoration: none;
}

.logo small {
    display: block;
    margin-top: 2px;
    font-family: var(--font-sans);
    font-size: 0.5625rem;
    font-weight: 500;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--color-teal-accent);
}

.logo-mark {
    position: relative;
    flex: none;
    width: 36px;
    height: 36px;
    border-radius: 2px;
    background: linear-gradient(135deg, var(--color-teal-accent), var(--color-teal-mid));
}

.logo-mark::before,
.logo-mark::after {
    content: "";
    position: absolute;
    top: 8px;
    left: 8px;
    background: var(--color-teal-dark);
}

.logo-mark::before { width: 20px; height: 2px; }
.logo-mark::after  { width: 2px;  height: 20px; }

/* Uploaded logo image (Company Info → Logo) — replaces the text logo in the
   header and footer. Fixed height keeps it aligned and prevents layout shift
   even for SVGs that report no intrinsic width/height. */
.logo__img {
    display: block;
    width: auto;
    height: 40px;
    max-width: 220px;
}

/* Primary nav — desktop horizontal list. */
.site-nav .menu {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 2px;
    list-style: none;
    margin: 0;
    padding: 0;
}

.site-nav .menu-item {
    position: relative;
}

.site-nav .menu-item > a {
    display: block;
    padding: 12px 13px;
    font-family: var(--font-sans);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    color: rgba(255, 255, 255, 0.85);
    text-decoration: none;
    transition: color 0.3s var(--ease), background-color 0.3s var(--ease);
}

.site-nav .menu-item > a:hover,
.site-nav .menu-item > a:focus-visible,
.site-nav .menu-item.has-dropdown:hover > a,
.site-nav .menu-item:focus-within > a {
    color: var(--color-teal-accent);
    background: rgba(122, 197, 205, 0.06);
}

/* Current page / ancestor marker (WordPress emits .current-menu-item etc.) */
.site-nav .current-menu-item > a,
.site-nav .current-menu-ancestor > a,
.site-nav .current_page_item > a {
    color: var(--color-teal-accent);
}

/* Dropdown (WordPress .sub-menu) */
.site-nav .sub-menu {
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 250px;
    margin: 0;
    padding: 10px 0;
    list-style: none;
    background: var(--color-teal-dark);
    border: 1px solid rgba(122, 197, 205, 0.18);
    border-top: 2px solid var(--color-teal-accent);
    box-shadow: 0 24px 48px -12px rgba(0, 0, 0, 0.4);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition: opacity 0.3s var(--ease), transform 0.3s var(--ease), visibility 0.3s var(--ease);
    z-index: 1001;
}

.site-nav .menu-item-has-children:hover > .sub-menu,
.site-nav .menu-item-has-children:focus-within > .sub-menu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.site-nav .sub-menu a {
    display: block;
    padding: 10px 22px;
    font-size: 0.75rem;
    letter-spacing: 0.02em;
    color: rgba(255, 255, 255, 0.78);
    text-decoration: none;
    border-left: 2px solid transparent;
    transition: color 0.25s var(--ease), background-color 0.25s var(--ease),
                border-color 0.25s var(--ease), padding-left 0.25s var(--ease);
}

.site-nav .sub-menu a:hover,
.site-nav .sub-menu a:focus-visible {
    color: var(--color-teal-accent);
    background: rgba(122, 197, 205, 0.08);
    border-left-color: var(--color-teal-accent);
    padding-left: 26px;
}

/* Contact item rendered as a CTA button. Add the `nav-cta` CSS class to
   the menu item in Appearance → Menus. */
.site-nav .nav-cta > a {
    margin-left: 8px;
    padding: 12px 22px;
    border-radius: 2px;
    background: var(--color-teal-accent);
    color: var(--color-teal-dark);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.site-nav .nav-cta > a:hover,
.site-nav .nav-cta > a:focus-visible {
    background: var(--color-white);
    color: var(--color-teal-dark);
}

/* Mobile menu toggle — hidden on desktop. */
.menu-toggle {
    display: none;
    flex: none;
    padding: 10px;
    background: none;
    border: 0;
    cursor: pointer;
}

.menu-toggle span {
    display: block;
    width: 24px;
    height: 2px;
    margin: 5px 0;
    background: var(--color-white);
    transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}

.menu-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 1200px) {
    .site-nav .menu-item > a { padding: 11px 9px; }
    .site-nav .nav-cta > a { padding: 11px 16px; }
}

@media (max-width: 1024px) {
    .menu-toggle { display: block; }

    .site-nav {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        display: none;
        background: var(--color-teal-dark);
        border-bottom: 1px solid rgba(122, 197, 205, 0.18);
        max-height: calc(100vh - var(--tif-header-height));
        overflow-y: auto;
    }

    .site-nav.is-open {
        display: block;
    }

    .site-nav .menu {
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        padding: 12px 5%;
    }

    .site-nav .menu-item > a {
        padding: 14px 0;
        border-bottom: 1px solid rgba(122, 197, 205, 0.1);
    }

    /* Dropdowns become static, always-open sub-lists on mobile. */
    .site-nav .sub-menu {
        position: static;
        min-width: 0;
        padding: 4px 0 12px 16px;
        background: transparent;
        border: 0;
        box-shadow: none;
        opacity: 1;
        visibility: visible;
        transform: none;
    }

    .site-nav .sub-menu a {
        padding: 8px 0;
        font-size: 0.6875rem;
        border-left: 0;
    }

    .site-nav .sub-menu a:hover,
    .site-nav .sub-menu a:focus-visible {
        padding-left: 4px;
        background: transparent;
    }

    .site-nav .nav-cta > a {
        display: inline-block;
        margin: 12px 0 4px;
        padding-inline: 16px;
    }
}

/* ============================================================
   Buttons (parts/partials/buttons.php)
   ============================================================ */

.tif-buttons {
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 16px 30px;
    font-family: var(--font-sans);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    line-height: 1.6;
    border: 1px solid transparent;
    border-radius: 2px;
    cursor: pointer;
    transition: background-color 0.3s var(--ease),
                color 0.3s var(--ease),
                border-color 0.3s var(--ease),
                box-shadow 0.3s var(--ease),
                transform 0.3s var(--ease);
}

/* Forward-action arrow, toggled per-button in ACF (parts/partials/buttons.php).
   Nudges on hover, matching the mockup's .btn .arrow. */
.btn__arrow {
    display: inline-block;
    /* Match the mockup's arrow weight: Montserrat has no U+2192 glyph, and the
       inherited stack's Arial fallback draws a noticeably thinner arrow than the
       system sans-serif the mockup falls back to. Drop Arial for the glyph. */
    font-family: "Montserrat", "Helvetica Neue", sans-serif;
    transition: transform 0.3s var(--ease);
}

.btn:hover .btn__arrow {
    transform: translateX(4px);
}

/* Padlock on a button whose link is protected (inc/buttons.php). Inherits the
   label colour, so it follows every variant and hover state. */
.btn__lock {
    display: inline-flex;
    flex: none;
}

/* Core Buttons block row — match the theme's button-row spacing (.tif-buttons). */
.wp-block-buttons {
    gap: var(--space-sm);
}

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

/* Buttons never underline — override the global a:hover/a:focus underline. */
.btn:hover,
.btn:focus {
    text-decoration: none;
}

/*
 * Primary + secondary are CONTEXT-AWARE, matching the mockup's dark/light
 * button system. Default styles target dark sections (hero, teal-dark/deep);
 * the `.bg-white/.bg-cream/.bg-pale` ancestor overrides re-skin them for light
 * sections. Other styles (tertiary/ghost/link) are context-neutral.
 *
 * Core Button blocks (inc/buttons.php adds .btn--primary / --secondary) join
 * the light lists: Gutenberg content only renders on the light content
 * templates. `.wp-block-button` also lifts them above the prose link colour
 * (e.g. `.tif-page__content a`).
 */

/* Primary — filled. Dark sections: teal accent on the deepest ink. */
.btn--primary {
    background: var(--color-teal-accent);
    color: var(--color-teal-darker);
    border-color: var(--color-teal-accent);
}

.btn--primary:hover {
    background: var(--color-white);
    border-color: var(--color-white);
    color: var(--color-teal-darker);
    transform: translateY(-2px);
    box-shadow: 0 14px 30px -12px rgba(0, 0, 0, 0.4);
}

/* Primary on light sections: deep-teal fill, white text. */
.bg-white .btn--primary,
.bg-cream .btn--primary,
.bg-pale .btn--primary,
.bg-teal-pale .btn--primary,
.wp-block-button .btn--primary {
    background: var(--color-teal-deep);
    color: var(--color-white);
    border-color: var(--color-teal-deep);
}

.bg-white .btn--primary:hover,
.bg-cream .btn--primary:hover,
.bg-pale .btn--primary:hover,
.bg-teal-pale .btn--primary:hover,
.wp-block-button .btn--primary:hover {
    background: var(--color-teal-darker);
    border-color: var(--color-teal-darker);
    color: var(--color-white);
}

/* Secondary — outlined. Dark sections: soft white outline, fills white on hover. */
.btn--secondary {
    background: transparent;
    color: var(--color-white);
    border-color: rgba(255, 255, 255, 0.4);
}

.btn--secondary:hover {
    background: var(--color-white);
    color: var(--color-teal-darker);
    border-color: var(--color-white);
}

/* Secondary on light sections: deep-teal outline, fills deep-teal on hover. */
.bg-white .btn--secondary,
.bg-cream .btn--secondary,
.bg-pale .btn--secondary,
.bg-teal-pale .btn--secondary,
.wp-block-button .btn--secondary {
    color: var(--color-teal-deep);
    border-color: var(--color-teal-deep);
}

.bg-white .btn--secondary:hover,
.bg-cream .btn--secondary:hover,
.bg-pale .btn--secondary:hover,
.bg-teal-pale .btn--secondary:hover,
.wp-block-button .btn--secondary:hover {
    background: var(--color-teal-deep);
    color: var(--color-white);
    border-color: var(--color-teal-deep);
}

/* Tertiary — quieter solid, low-emphasis CTA. */
.btn--tertiary {
    background: var(--color-cream);
    color: var(--color-teal-dark);
    border-color: var(--color-cream);
}

.btn--tertiary:hover {
    background: var(--color-pale);
    border-color: var(--color-pale);
}

/* Ghost — borderless, used for tertiary actions on busy backgrounds. */
.btn--ghost {
    background: transparent;
    color: currentColor;
    border-color: transparent;
}

.btn--ghost:hover {
    background: rgba(122, 197, 205, 0.12);
}

/* Inline link — looks like an arrow-led text link, not a button block. */
.btn--link {
    padding: 0;
    background: transparent;
    border: 0;
    color: var(--color-teal-accent);
    text-transform: none;
    letter-spacing: 0;
    font-size: 0.95rem;
    font-weight: 500;
}

.btn--link:hover {
    color: var(--color-teal-deep);
    text-decoration: underline;
    text-underline-offset: 0.18em;
}

/* Two-tone keyboard focus ring (matches the global :focus-visible in base.css).
   Declared after the variant rules — including .btn--primary:hover, which also
   sets box-shadow — so a button that is hovered AND keyboard-focused still shows
   the focus ring rather than only the hover lift-shadow. */
.btn:focus-visible {
    outline: 2px solid transparent;
    outline-offset: 2px;
    box-shadow: 0 0 0 2px var(--color-teal-accent), 0 0 0 4px var(--color-teal-deep);
}

/* ============================================================
   Badges (parts/partials/members-badge.php)
   Reusable card marker. Used on archive cards and the Resources
   grid (Phase 14). The members variant flags gated content to
   users without access.
   ============================================================ */

.tif-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    padding: 0.3em 0.7em;
    /* Explicit, so a badge set inside a serif heading (the news-list title)
       doesn't inherit the serif. */
    font-family: var(--font-sans);
    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    line-height: 1;
    border-radius: 0;
}

.tif-badge__icon {
    display: inline-flex;
}

.tif-badge--members {
    background: var(--color-teal-deep);
    color: var(--color-white);
}

/* Type marker — labels a search result with its post type. Quieter than
   the members variant: it's a wayfinding label, not an access flag. */
.tif-badge--type {
    background: var(--color-pale);
    color: var(--color-teal-deep);
    border: 1px solid var(--color-grey-soft);
}

/* ============================================================
   Search results (search.php)
   Multi-post-type results: post-type badge, featured image, excerpt.
   ============================================================ */

.tif-search {
    padding-block: clamp(var(--space-lg), 8vw, var(--space-xl));
}

.tif-search__header {
    margin-bottom: var(--space-lg);
}

.tif-search__title {
    margin-bottom: var(--space-sm);
}

.tif-search__title span {
    font-style: italic;
    color: var(--color-teal-deep);
}

.tif-search__count {
    margin-bottom: var(--space-md);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--color-grey-mid);
}

.tif-search__list {
    list-style: none;
    display: grid;
    gap: var(--space-md);
}

.tif-search__item {
    margin: 0;
}

.tif-search__card {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-md);
    align-items: start;
    padding-bottom: var(--space-md);
    border-bottom: 1px solid var(--color-grey-soft);
}

/* Two-column only when a result has a featured image, so text-only
   results don't leave a hanging empty thumbnail column. */
.tif-search__card:has(.tif-search__thumb) {
    grid-template-columns: 200px 1fr;
}

.tif-search__item:last-child .tif-search__card {
    border-bottom: 0;
    padding-bottom: 0;
}

.tif-search__thumb {
    display: block;
}

.tif-search__thumb img {
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    object-fit: cover;
}

.tif-search__body {
    min-width: 0; /* let long titles/excerpts wrap inside the grid track */
}

.tif-search__item-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-bottom: var(--space-xs);
}

.tif-search__item-date {
    font-size: 0.7rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-grey-mid);
}

.tif-search__item-title {
    margin-bottom: var(--space-xs);
    font-size: clamp(1.3rem, 2vw, 1.6rem);
}

.tif-search__item-title a {
    text-decoration: none;
}

.tif-search__item-title a:hover,
.tif-search__item-title a:focus-visible {
    text-decoration: underline;
    text-underline-offset: 0.18em;
}

.tif-search__item-excerpt {
    color: var(--color-grey-mid);
}

.tif-search__empty {
    font-family: var(--font-serif);
    font-size: 1.4rem;
    color: var(--color-teal-deep);
}

@media (max-width: 768px) {
    .tif-search__card:has(.tif-search__thumb) {
        grid-template-columns: 1fr;
        gap: var(--space-sm);
    }
}

/* ============================================================
   Topic tags (single-publication.php and any "filed under" surface)
   Non-interactive wayfinding chips. The interactive filter look is
   .tif-chip in blocks.css; these are quieter and never links.
   ============================================================ */

.tif-tags {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: var(--space-sm);
}

.tif-tag {
    padding: 5px 12px;
    background: var(--color-pale);
    border: 1px solid var(--color-grey-soft);
    color: var(--color-teal-deep);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    line-height: 1.2;
}

/* ============================================================
   Pagination (the_posts_pagination — archive.php, archive-publication.php,
   taxonomy-publication_type.php). WordPress emits nav.pagination with
   .page-numbers links; .current is the active page.
   ============================================================ */

.pagination {
    margin-top: var(--space-lg);
}

.pagination .nav-links {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    justify-content: center;
}

.pagination .page-numbers {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0 12px;
    border: 1px solid var(--color-grey-soft);
    background: var(--color-white);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--color-teal-deep);
    transition: background-color 0.25s var(--ease),
                color 0.25s var(--ease),
                border-color 0.25s var(--ease);
}

.pagination a.page-numbers:hover,
.pagination a.page-numbers:focus-visible {
    background: var(--color-teal-deep);
    border-color: var(--color-teal-deep);
    color: var(--color-white);
    text-decoration: none;
}

.pagination .page-numbers.current {
    background: var(--color-teal-deep);
    border-color: var(--color-teal-deep);
    color: var(--color-white);
}

.pagination .page-numbers.dots {
    border-color: transparent;
    background: transparent;
}

/* ============================================================
   Contact form — Contact Form 7
   Markup spec lives in claude/session-notes.md (Phase 10). CF7's own
   stylesheet is disabled in inc/forms.php so these rules own the layout.
   Mirrors the mockup's `form.contact-form` styling.
   ============================================================ */

.tif-contact-form {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

.tif-contact-form .field {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

.tif-contact-form label {
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--color-teal-deep);
}

/* CF7 wraps each control in a span; make it block so the field's
   underline and the control fill the column width. */
.tif-contact-form .wpcf7-form-control-wrap {
    display: block;
}

/* CF7 wraps its housekeeping inputs (_wpcf7, _wpcf7_version, _wpcf7_unit_tag,
   …) in <fieldset class="hidden-fields-container">, injected as a direct child
   of <form.wpcf7-form> — a sibling of our .tif-contact-form content div, not a
   descendant — so scope the hide to the form wrapper. The inputs are
   type="hidden", so the fieldset only contributes default fieldset chrome and a
   stray row; hide it. Hidden inputs still submit when their container is
   display:none (only `disabled` blocks submission). */
.tif-contact__form .hidden-fields-container {
    display: none;
}

.tif-contact-form input:not([type="submit"]):not([type="checkbox"]):not([type="radio"]),
.tif-contact-form textarea,
.tif-contact-form select {
    width: 100%;
    background: transparent;
    border: 0;
    /* grey-mid (not the lighter grey-soft) so the field's only boundary clears
       the 3:1 non-text-contrast floor on the light page backgrounds (grey-soft
       was ~1.3-1.5:1 on cream/white — WCAG 2.2 SC 1.4.11). */
    border-bottom: 1px solid var(--color-grey-mid);
    padding: 0.75rem 0;
    font-family: var(--font-sans);
    font-size: 1rem;
    color: var(--color-navy-text);
    transition: border-color 0.25s var(--ease);
}

/* The base field rule carries a three-:not() chain (specificity 0,4,1); the
   :focus / .wpcf7-not-valid states must match that chain to outrank it on
   inputs, or the focus underline never darkens and the invalid underline never
   reds (textarea/select win on their own — only inputs need the full chain). */
.tif-contact-form input:not([type="submit"]):not([type="checkbox"]):not([type="radio"]):focus,
.tif-contact-form textarea:focus,
.tif-contact-form select:focus {
    outline: none;
    border-bottom-color: var(--color-teal-deep);
}

.tif-contact-form textarea {
    resize: vertical;
    min-height: 130px;
}

.tif-contact-form .btn {
    align-self: flex-start;
}

/* Validation + response states. CF7 toggles these classes during
   submission; the error/success colours mirror .tif-form-notice in
   members.css (semantic states, deliberately not palette tokens). */
.tif-contact-form input:not([type="submit"]):not([type="checkbox"]):not([type="radio"]).wpcf7-not-valid,
.tif-contact-form textarea.wpcf7-not-valid,
.tif-contact-form select.wpcf7-not-valid {
    border-bottom-color: #8a2018;
}

.tif-contact-form .wpcf7-not-valid-tip {
    display: block;
    margin-top: var(--space-xs);
    font-size: 0.85rem;
    color: #8a2018;
}

/* The submit-status notice. Refined to the theme's restrained, left-ruled panel
   language (cf. the pull-quote): a thin accent rule, the message at the form's
   small-text scale (the base inherits 1rem otherwise — too loud), and a faint
   wash derived from the state colour itself rather than a saturated alert fill.
   Box styling lives on the state classes only, so an empty response output (no
   submission yet) stays invisible. Mirrors .tif-form-notice in members.css. */
.wpcf7 .wpcf7-response-output {
    margin: var(--space-md) 0 0;
    font-size: 0.9rem;
    line-height: 1.6;
}

.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.unaccepted .wpcf7-response-output,
.wpcf7 form.payment-required .wpcf7-response-output,
.wpcf7 form.spam .wpcf7-response-output,
.wpcf7 form.aborted .wpcf7-response-output {
    padding: 0.85rem 1.15rem;
    border-left: 3px solid currentColor;
    color: #8a2018;
    background: rgba(138, 32, 24, 0.07);
}

.wpcf7 form.sent .wpcf7-response-output {
    padding: 0.85rem 1.15rem;
    border-left: 3px solid currentColor;
    color: var(--color-teal-deep);
    background: rgba(20, 72, 84, 0.07);
}

.wpcf7 .wpcf7-spinner {
    margin-inline-start: var(--space-sm);
}

/* ============================================================
   Site footer (footer.php)
   Brand column + footer menu rendered as link columns (top-level
   menu items become column headings, their children the links) +
   a credits row. Mirrors the mockup `footer.site`.
   ============================================================ */

.site-footer {
    background: var(--color-teal-dark);
    color: var(--color-white);
    padding: clamp(var(--space-lg), 7vw, 4.375rem) 0 2.25rem;
}

.footer-grid {
    display: grid;
    grid-template-columns: 1.5fr repeat(3, 1fr);
    gap: clamp(var(--space-md), 4vw, 3.125rem);
    padding-bottom: clamp(var(--space-md), 4vw, 3.125rem);
    border-bottom: 1px solid rgba(168, 219, 226, 0.2);
}

.footer-brand .logo {
    margin-bottom: var(--space-md);
}

.footer-brand .logo small {
    color: var(--color-teal-light);
}

.footer-brand__desc,
.footer-brand .footer-widget {
    max-width: 320px;
    font-size: 0.88rem;
    line-height: 1.7;
    color: rgba(255, 255, 255, 0.7);
}

/* The footer menu is a 3-column grid; each top-level item is a column. */
/* Footer nav columns (widgetised — inc/widgets.php). Each Footer Column widget
   area is a direct grid item of .footer-grid; a Navigation Menu widget's Title
   renders as the column heading and its list as the links. Selectors stay
   generic (.footer-col / .footer-widget__title, not menu-specific classes) so
   any list-based nav widget renders identically to the old hardcoded columns. */

/* Widget title = column heading. */
.footer-widget__title {
    margin: 0 0 var(--space-sm);
    font-family: var(--font-sans);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--color-teal-light);
}

/* Link list. */
.footer-col ul {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin: 0;
    padding: 0;
}

.footer-col a {
    font-size: 0.88rem;
    color: rgba(255, 255, 255, 0.8);
    text-decoration: none;
    transition: color 0.3s var(--ease);
}

.footer-col a:hover,
.footer-col a:focus-visible {
    color: var(--color-teal-accent);
}

.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-sm);
    padding-top: var(--space-md);
    font-size: 0.76rem;
    color: rgba(255, 255, 255, 0.6);
}

/* Footer legal links (footer-bottom, right side). Driven by the `legals`
   nav-menu location; replaces the old hardcoded "Privacy · Cookies · Terms"
   text. Inline list with middot separators, links inherit the muted
   footer-bottom colour and pick up teal-accent on hover/focus like the rest of
   the footer nav. */
.footer-legal-menu {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.5em;
    margin: 0;
    padding: 0;
}

.footer-legal-menu li {
    display: flex;
    align-items: center;
    gap: 0.5em;
}

.footer-legal-menu li:not(:last-child)::after {
    content: "·";
    color: rgba(255, 255, 255, 0.4);
    pointer-events: none;
}

.footer-legal-menu a {
    color: inherit;
    text-decoration: none;
    transition: color 0.3s var(--ease);
}

.footer-legal-menu a:hover,
.footer-legal-menu a:focus-visible {
    color: var(--color-teal-accent);
}

@media (max-width: 1024px) {
    /* Brand spans the full width; the three nav columns sit in a row below. */
    .footer-grid {
        grid-template-columns: repeat(3, 1fr);
    }

    .footer-brand {
        grid-column: 1 / -1;
    }
}

@media (max-width: 768px) {
    .footer-grid {
        grid-template-columns: 1fr 1fr;
    }

    .footer-bottom {
        flex-direction: column;
        text-align: center;
    }
}

@media (max-width: 480px) {
    .footer-grid {
        grid-template-columns: 1fr;
    }
}

/* ============================================================
   Plain page — long-form content (Gutenberg / the_content)
   ------------------------------------------------------------
   Shared by the "Plain (Gutenberg)" page template
   (page-templates/template-plain.php) and page.php's text-only
   fallback — both render editor content inside `.tif-page`. The global
   reset (base.css) zeroes margins on headings, paragraphs and lists and
   strips list padding, so the reading rhythm is rebuilt here.

   Scoped under `.tif-page` (the <article> wrapper) so the Contact
   template's bare `.tif-page__header` — which has no `.tif-page`
   ancestor — is left untouched. The `.site-main > :first-child` rule
   above already clears the fixed header off the top of the article;
   this block adds the matching bottom padding the legal pages were
   missing and styles the body copy.
   ============================================================ */

.tif-page {
    padding-bottom: var(--space-xxl);
}

.tif-page__header {
    margin-bottom: var(--space-lg);
}

/* Default flow: even vertical rhythm between consecutive blocks. */
.tif-page__content > * + * {
    margin-top: var(--space-sm);
}

/* Section headings open more space above than the surrounding flow and
   sit tight to the text they introduce. */
.tif-page__content > h2 {
    margin-top: var(--space-lg);
    margin-bottom: var(--space-sm);
}

.tif-page__content > h3,
.tif-page__content > h4,
.tif-page__content > h5,
.tif-page__content > h6 {
    margin-top: var(--space-md);
    margin-bottom: var(--space-xs);
}

/* Never push the very first block down — the header already spaces it. */
.tif-page__content > :first-child {
    margin-top: 0;
}

/* Consecutive headings shouldn't open a full section gap between them. */
.tif-page__content > h2 + :is(h3, h4, h5, h6),
.tif-page__content > h3 + :is(h4, h5, h6) {
    margin-top: var(--space-sm);
}

/* Lists — restore the indent the reset removed and space the items. */
.tif-page__content ul,
.tif-page__content ol {
    padding-left: 1.5em;
}

.tif-page__content ul { list-style: disc; }
.tif-page__content ol { list-style: decimal; }
.tif-page__content ul ul { list-style: circle; }

.tif-page__content li + li {
    margin-top: var(--space-xs);
}

/* Nested lists tuck under their parent item rather than the flow gap. */
.tif-page__content li > ul,
.tif-page__content li > ol {
    margin-top: var(--space-xs);
}

/* Emphasis — the body font is 400, so bold needs a heavier weight. */
.tif-page__content strong,
.tif-page__content b {
    font-weight: 600;
}

/* Links keep the global underline; tint them brand teal so they read as
   links against the light page background. */
.tif-page__content a {
    color: var(--color-teal-deep);
}

.tif-page__content blockquote {
    margin-inline: 0;
    padding: var(--space-xs) var(--space-md);
    border-left: 3px solid var(--color-teal-accent);
    color: var(--color-grey-mid);
    font-style: italic;
}

.tif-page__content hr,
.tif-page__content .wp-block-separator {
    border: 0;
    height: 1px;
    background: var(--color-grey-soft);
    margin-block: var(--space-lg);
}

.tif-page__content figure {
    margin-block: var(--space-md);
}

.tif-page__content figcaption {
    margin-top: var(--space-xs);
    font-size: 0.85rem;
    color: var(--color-grey-mid);
}

.tif-page__content table {
    width: 100%;
    border-collapse: collapse;
}

.tif-page__content th,
.tif-page__content td {
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid var(--color-grey-soft);
    text-align: left;
    vertical-align: top;
}

.tif-page__content th {
    font-weight: 600;
    background: var(--color-pale);
}

/* wp_link_pages() multipage nav, if a plain page is ever split. */
.tif-page__pagination {
    margin-top: var(--space-lg);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
}

/* ============================================================
   404 (404.php)

   Full-height branded fallback. Reuses the hero visual language —
   dark teal gradient, decorative orbs, serif title with an italic
   accent — but lives here rather than in blocks.css because
   blocks.css isn't enqueued on 404 requests (inc/enqueue.php gates
   it to page-builder / template pages).
   ============================================================ */

.tif-404 {
    position: relative;
    overflow: hidden;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    background: linear-gradient(180deg, var(--color-teal-darker) 0%, var(--color-teal-dark) 100%);
    color: var(--color-white);
}

/* Bleed the dark gradient up behind the fixed translucent header (the hero
   does the same), overriding the generic first-child top-padding that clears
   the header on ordinary pages. The inner padding below keeps the centred
   content clear of the header. Matches that rule's specificity and, sitting
   later in the cascade, wins. */
.site-main > .tif-404:first-child {
    padding: calc(var(--tif-header-height) + var(--space-xl)) 0 var(--space-xl);
}

/* Decorative accent orbs — same soft radial glows as .layout-hero. */
.tif-404::before,
.tif-404::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
    z-index: 0;
}

.tif-404::before {
    top: -200px;
    right: -200px;
    width: 700px;
    height: 700px;
    background: radial-gradient(circle, rgba(122, 197, 205, 0.18), transparent 60%);
}

.tif-404::after {
    bottom: -300px;
    left: -200px;
    width: 600px;
    height: 600px;
    background: radial-gradient(circle, rgba(91, 160, 171, 0.16), transparent 60%);
}

/* Oversized "404" flourish sitting faintly behind the copy for depth. */
.tif-404__watermark {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -54%);
    z-index: 0;
    font-family: var(--font-serif);
    font-weight: 500;
    font-size: clamp(14rem, 34vw, 30rem);
    line-height: 1;
    letter-spacing: -0.04em;
    color: var(--color-teal-accent);
    opacity: 0.07;
    pointer-events: none;
    user-select: none;
    white-space: nowrap;
}

.tif-404__inner {
    position: relative;
    z-index: 1;
}

/* Eyebrow — the site's kicker convention: leading rule + spaced caps. */
.tif-404__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 14px;
    margin: 0 0 var(--space-md);
    font-family: var(--font-sans);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--color-teal-accent);
}

.tif-404__eyebrow::before,
.tif-404__eyebrow::after {
    content: "";
    width: 40px;
    height: 1px;
    background: currentColor;
}

.tif-404__title {
    font-family: var(--font-serif);
    font-weight: 400;
    font-size: clamp(2.8rem, 6vw, 5rem);
    line-height: 1.04;
    letter-spacing: -0.02em;
    margin: 0 0 var(--space-md);
}

.tif-404__title em {
    font-style: italic;
    color: var(--color-teal-accent);
}

.tif-404__lede {
    max-width: 34ch;
    margin: 0 auto var(--space-lg);
    font-size: 1.05rem;
    line-height: 1.6;
    color: var(--color-grey-soft);
}

.tif-404__actions {
    display: flex;
    justify-content: center;
}

/* Secondary route — the primary menu rendered as a quiet inline link row,
   replacing the old search box. */
.tif-404__explore {
    margin-top: var(--space-xl);
}

.tif-404__explore-label {
    margin: 0 0 var(--space-sm);
    font-family: var(--font-sans);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.55);
}

.tif-404__menu {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-xs) var(--space-md);
}

.tif-404__menu a {
    display: inline-block;
    padding: 4px 2px;
    font-family: var(--font-sans);
    font-size: 0.9rem;
    font-weight: 500;
    text-decoration: none;
    color: var(--color-white);
    border-bottom: 1px solid transparent;
    transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}

.tif-404__menu a:hover,
.tif-404__menu a:focus {
    color: var(--color-teal-accent);
    border-bottom-color: var(--color-teal-accent);
    text-decoration: none;
}

@media (max-width: 768px) {
    .tif-404__explore {
        margin-top: var(--space-lg);
    }
}
