/*
    Theme Name: Cape26
    Author: Egloo
    Author URI: https://egloo.it
    Version: 1.0.0
    Text Domain: eg-cape26
    Description: A custom WordPress theme for Cape26, designed by Egloo.
    License: GNU General Public License v2 or later
    License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

@font-face {
    font-family: "Degular Mono";
    src: url("assets/fonts/degular-mono/degular-mono-400.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Degular Mono";
    src: url("assets/fonts/degular-mono/degular-mono-500.woff2") format("woff2");
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-200.woff2") format("woff2");
    font-weight: 200;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-200-italic.woff2") format("woff2");
    font-weight: 200;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-300.woff2") format("woff2");
    font-weight: 300;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-300-italic.woff2") format("woff2");
    font-weight: 300;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-400.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-400-italic.woff2") format("woff2");
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-500.woff2") format("woff2");
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-500-italic.woff2") format("woff2");
    font-weight: 500;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-600.woff2") format("woff2");
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-600-italic.woff2") format("woff2");
    font-weight: 600;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-700.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-700-italic.woff2") format("woff2");
    font-weight: 700;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-800.woff2") format("woff2");
    font-weight: 800;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-800-italic.woff2") format("woff2");
    font-weight: 800;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-900.woff2") format("woff2");
    font-weight: 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-900-italic.woff2") format("woff2");
    font-weight: 900;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-200.woff2") format("woff2");
    font-weight: 200;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk";
    src: url("assets/fonts/aktiv-grotesk/aktiv-grotesk-200-italic.woff2") format("woff2");
    font-weight: 200;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk Ex";
    src: url("assets/fonts/aktiv-grotesk-ex/aktiv-grotesk-ex-400.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk Ex";
    src: url("assets/fonts/aktiv-grotesk-ex/aktiv-grotesk-ex-500.woff2") format("woff2");
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk Ex";
    src: url("assets/fonts/aktiv-grotesk-ex/aktiv-grotesk-ex-600.woff2") format("woff2");
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk Ex";
    src: url("assets/fonts/aktiv-grotesk-ex/aktiv-grotesk-ex-700.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Aktiv Grotesk Ex";
    src: url("assets/fonts/aktiv-grotesk-ex/aktiv-grotesk-ex-700-italic.woff2") format("woff2");
    font-weight: 700;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Aptos";
    src: url("assets/fonts/aptos/aptos-400.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

* {
    box-sizing: border-box;
    padding: 0;
    margin: 0;
}

dialog {
    margin: auto;
}

a,
input,
textarea,
select,
button,
h1,
h2,
h3,
h4,
h5,
h6 {
    font: inherit;
    color: inherit;
}

a {
    text-decoration: none;
}

img,
video,
iframe {
    display: block;
    inline-size: 100%;
    block-size: auto;
}

button,
label,
input {
    cursor: pointer;
}

input[type="reset"],
input[type="submit"],
button {
    border: none;
    background-color: transparent;
}

span:has(> svg:only-child),
svg {
    line-height: 0;
}

ul {
    list-style-type: none;
}

html {
    /* the canvas colour, not just a background: nothing painted it before, so the white default
       showed through wherever a box did not land on a whole pixel — a hairline on the right of
       the footer and one under it. It is the footer gradient's end colour, which is also the
       colour the page overscrolls into at the bottom. */
    background-color: #020c16;
    /* the page scroll is the browser's own — there is no smoothing library. This only softens
       the jump of the in-page menu anchors; `scroll-padding` is what clears the fixed header */
    scroll-behavior: smooth;
    scroll-padding: 6.25rem;
    -webkit-tap-highlight-color: transparent;
}

body:has(dialog[open]) {
    overflow: hidden;
}

:focus-visible {
    outline-offset: 4px;
    outline: 0px solid var(--on-surface, currentColor);
    animation:
        focus-ring-in 0.2s forwards,
        focus-ring-out 0.2s 0.2s forwards;
}

@keyframes focus-ring-in {
    to {
        outline-width: 8px;
    }
}

@keyframes focus-ring-out {
    to {
        outline-width: 4px;
    }
}

/* ======================================== */
/* UTILS */
/* ======================================== */

nav.breadcrumbs ul {
    --_gap: 1.25rem;
    display: block;
}

nav.breadcrumbs li {
    display: inline-block;
    position: relative;
}

nav.breadcrumbs li:not(:last-child) {
    margin-inline-end: var(--_gap);
}

nav.breadcrumbs li svg {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-end: calc((var(--_gap) * -1) / 2);
    translate: 50% -50%;
}

nav.breadcrumbs [aria-current] {
    color: rgb(from currentColor r g b / 0.3);
}

.rich-text > *:not(:last-child) {
    margin-block-end: 1lh;
}

.rich-text strong {
    font-weight: 700;
}

.rich-text ul {
    list-style-type: disc;
}

.rich-text ol {
    list-style-type: decimal;
}

.rich-text ul,
.rich-text ol {
    padding-inline-start: 1rem;
}

.rich-text a {
    text-decoration: underline;
}

.sr-only {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border-width: 0;
    inset-inline-end: 0;
    inset-block-end: 0;
}

.skip-link:focus {
    position: fixed;
    inset-block-start: 1rem;
    inset-inline-start: 1rem;
    z-index: 9999;
    inline-size: fit-content;
    block-size: fit-content;
    padding: 0.75rem 1.25rem;
    overflow: visible;
    clip-path: none;
    white-space: normal;
    background-color: var(--on-surface, #000);
    color: var(--surface, #fff);
    border-radius: 0.25rem;
    outline: 2px solid transparent;
}

.img-wrapper.img-wrapper-ratio > picture,
.img-wrapper.img-wrapper-ratio {
    overflow: hidden;
    position: relative;
}

.img-wrapper.img-wrapper-ratio > picture {
    block-size: 100%;
    display: block;
}

.img-wrapper.img-wrapper-ratio > video,
.img-wrapper.img-wrapper-ratio > picture > video,
.img-wrapper.img-wrapper-ratio > picture > img,
.img-wrapper.img-wrapper-ratio > img {
    inline-size: 100%;
    block-size: 100%;
    position: absolute;
    object-fit: cover;
    inset: 0;
}

.layers {
    display: grid;
}

.layers > .layer {
    grid-column: -1/1;
    grid-row: -1/1;
}

.layers > .layer.layer-bg {
    position: relative;
}

.layers > .layer.layer-bg > .img-wrapper.img-wrapper-ratio:only-child {
    block-size: 100%;
}

.layers > .layer.layer-bg::before,
.layers > .layer.layer-bg::after {
    content: "";
    pointer-events: none;
    inset-block-start: 0;
    inset-inline-start: 0;
    inline-size: 100%;
    block-size: 100%;
    position: absolute;
}

.layers > .layer.layer-fg {
    position: relative;
    z-index: 1;
}

:root {
    --container-columns: 12;
    --container-gap: 1.25rem;
    --container-column-width: 5.3125rem;
    --container-x-padding: 2rem;

    --form-gap-row: 1.875rem;
    --form-gap-col: var(--container-gap);
    --form-field-min-width: 14.375rem;
    --form-checkbox-size: 0.8125rem;
    --form-checkbox-bg: #ebebeb;
    --form-checkbox-checked-bg: var(--accent);
    --form-input-bg: #eff9f9;
    --form-input-border: transparent;
    --form-input-font-size: 1rem;
    --form-input-weight: 400;
    --form-input-padding-block: 0.9375rem 0.875rem;
    --form-input-padding-inline: 1.25rem;
    --form-label-weight: 500;
    --form-border-radius-input: 0.625rem;
    --form-border-radius-checkbox: 0.125rem;
    --form-border-radius-radio: 50%;
    --form-label-field-gap: 0.625rem;
    --form-icon-check: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMC44NzUiIGhlaWdodD0iNy4xOTciIHZpZXdCb3g9IjAgMCAxMC44NzUgNy4xOTciPgogIDxwYXRoIGlkPSJUcmFjY2lhdG9fMjA4ODUiIGRhdGEtbmFtZT0iVHJhY2NpYXRvIDIwODg1IiBkPSJNLTE1NjA2LjA3Niw2ODc4LjMwN2wzLjI2MywzLjI2Myw0Ljc4NC00Ljc4NCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTU2MDcuNDkgLTY4NzUuMzczKSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMiIvPgo8L3N2Zz4K");
    --form-icon-file: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMy4zNjIiIGhlaWdodD0iMTkuNzQ4IiB2aWV3Qm94PSIwIDAgMjMuMzYyIDE5Ljc0OCI+CiAgPGcgaWQ9IlJhZ2dydXBwYV8xNTc4IiBkYXRhLW5hbWU9IlJhZ2dydXBwYSAxNTc4IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzM4LjA4NiAtNjU0Mi41MDEpIj4KICAgIDxwYXRoIGlkPSJUcmFjY2lhdG9fMjA5MDkiIGRhdGEtbmFtZT0iVHJhY2NpYXRvIDIwOTA5IiBkPSJNMzQuMzM2LDU3LjQ1N2EuNjE2LjYxNiwwLDAsMC0uNjIyLjYyMnYyLjk2NUEyLjMyLDIuMzIsMCwwLDEsMzEuNCw2My4zNjJIMTYuMTQ4YTIuMzEyLDIuMzEyLDAsMCwxLTIuMzE3LTIuMzE3VjU4LjA3OWEuNjIyLjYyMiwwLDAsMC0xLjI0NSwwdjIuOTY1YTMuNTYzLDMuNTYzLDAsMCwwLDMuNTYzLDMuNTYzSDMxLjM4NWEzLjU2MywzLjU2MywwLDAsMCwzLjU2My0zLjU2M1Y1OC4wNzlhLjYuNiwwLDAsMC0uNjEyLS42MjJaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3MjYgNjQ5Ny4xNDEpIiBmaWxsPSIjYmI4ZWY4IiBzdHJva2U9IiNiYjhlZjgiIHN0cm9rZS13aWR0aD0iMSIvPgogICAgPHBhdGggaWQ9IlRyYWNjaWF0b18yMDkxMCIgZGF0YS1uYW1lPSJUcmFjY2lhdG8gMjA5MTAiIGQ9Ik0zOS43NTcsMzIuMTZhLjYxNi42MTYsMCwwLDAsLjYyMi0uNjIyVjIwLjg2MWwyLjY2NiwyLjgyN2EuNjQ1LjY0NSwwLDAsMCwuNDQ4LjIuNTY4LjU2OCwwLDAsMCwuNDI0LS4xNzQuNjI4LjYyOCwwLDAsMCwuMDI1LS44ODRsLTMuNzM3LTMuOTc0YS42NDguNjQ4LDAsMCwwLS45MSwwTDM1LjU1OCwyMi44M2EuNjI1LjYyNSwwLDEsMCwuOTA5Ljg2bDIuNjY2LTIuODI3VjMxLjUzOGEuNjE4LjYxOCwwLDAsMCwuNjI0LjYyMloiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcxMC4wMTYgNjUyNC4zMzIpIiBmaWxsPSIjYmI4ZWY4IiBzdHJva2U9IiNiYjhlZjgiIHN0cm9rZS13aWR0aD0iMSIvPgogIDwvZz4KPC9zdmc+Cg==");
    --form-icon-select: url("data:image/svg+xml,%3Csvg width='8' height='5' viewBox='0 0 8 5' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M3.02359 2.04426C3.41412 2.43477 4.04727 2.43476 4.43779 2.04424L6.27879 0.203241C6.54961 -0.0675785 6.98869 -0.067596 7.25953 0.203202C7.5304 0.47403 7.53042 0.91317 7.25957 1.18402L4.43781 4.00578C4.04728 4.39631 3.41412 4.39631 3.02359 4.00578L0.201758 1.18395C-0.069058 0.913131 -0.0690589 0.474051 0.201757 0.203234C0.472569 -0.0675773 0.911639 -0.0675829 1.18246 0.203222L3.02359 2.04426Z' fill='%23181818'/%3E%3C/svg%3E");
}

.container {
    inline-size: 100%;
    max-inline-size: calc((var(--container-x-padding) * 2) + ((var(--container-columns) - 1) * var(--container-gap)) + (var(--container-columns) * var(--container-column-width)));
    margin-inline: auto;
    padding-inline: var(--container-x-padding);
}
.container.container-10 {
    --container-columns: 10;
}
.container.container-8 {
    --container-columns: 8;
}
.container.container-6 {
    --container-columns: 6;
}
.container.container-5 {
    --container-columns: 5;
}
.container.container-4 {
    --container-columns: 4;
}

/* mobile page gutter: the 375 Figma frame puts content at x=30 */
@media (max-width: 768px) {
    :root {
        --container-x-padding: 1.875rem;
    }
}

/* ======================================== */
/* WPCF7 */
/* ======================================== */

input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration,
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
    display: none;
}

input[type="checkbox"],
input[type="radio"] {
    appearance: none;
    inline-size: var(--form-checkbox-size);
    block-size: var(--form-checkbox-size);
    background-color: var(--form-checkbox-bg);
    flex-shrink: 0;
    cursor: pointer;
}

input[type="checkbox"] {
    border-radius: var(--form-border-radius-checkbox);
}

input[type="radio"] {
    border-radius: var(--form-border-radius-radio);
}

input[type="checkbox"]:checked,
input[type="radio"]:checked {
    background-color: var(--form-checkbox-checked-bg);
    background-image: var(--form-icon-check);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 72%;
}

input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible {
    outline: 2px solid var(--on-surface);
    outline-offset: 2px;
}

input:is([type="text"], [type="number"], [type="email"], [type="tel"]),
.wpcf7-styled select,
.wpcf7-styled textarea {
    inline-size: 100%;
    padding-block: var(--form-input-padding-block);
    padding-inline: var(--form-input-padding-inline);
    border: 1px solid var(--form-input-border);
    background-color: var(--form-input-bg);
    border-radius: var(--form-border-radius-input);
    font-size: var(--form-input-font-size);
    font-weight: var(--form-input-weight);
    outline: none;
}

.wpcf7-styled select {
    appearance: none;
    background-image: var(--form-icon-select);
    background-repeat: no-repeat;
    background-position: calc(100% - var(--form-input-padding-inline)) center;
    padding-inline-end: calc(var(--form-input-padding-inline) + 1.5rem);
}

input::placeholder,
textarea::placeholder,
.wpcf7-styled label:has(input[type="file"]) > span:first-child {
    color: rgb(from var(--on-surface) r g b / 0.4);
}

.wpcf7-styled textarea {
    min-block-size: 6.875rem;
    field-sizing: content;
    resize: vertical;
}

input:is([type="text"], [type="number"], [type="email"], [type="tel"]):focus-visible,
.wpcf7-styled select:focus-visible,
.wpcf7-styled textarea:focus-visible {
    border-color: var(--accent);
    outline: 1px solid var(--accent);
    outline-offset: 0;
}

.wpcf7-styled label {
    font-size: 0.875rem;
    line-height: 1.571;
    letter-spacing: -0.01em;
    font-weight: var(--form-label-weight);
    display: flex;
    flex-direction: column;
    gap: var(--form-label-field-gap);
}

.wpcf7-styled .align-center {
    text-align: center;
}

.wpcf7-styled label:has(input[type="file"]) {
    overflow: hidden;
    display: grid;
    background-image: var(--form-icon-file);
    background-repeat: no-repeat;
    background-position: calc(100% - 1rem) center;
    background-color: rgb(from currentColor r g b / 0.1);
    border: 1px solid transparent;
    border-radius: var(--form-border-radius-input);
    padding-block: var(--form-input-padding-block);
    padding-inline: var(--form-input-padding-inline);
    cursor: pointer;
}

.wpcf7-styled label:has(input[type="file"]) > span:first-child {
    overflow: hidden;
    max-inline-size: calc(100% - 3rem);
    white-space: nowrap;
    text-overflow: ellipsis;
    display: block;
}

.wpcf7-styled label:has(input[type="file"]) input[type="file"] {
    opacity: 0;
    width: 0.1px;
    height: 0.1px;
    position: absolute;
    z-index: -1;
}

.wpcf7-styled label:has([aria-required="true"]) .label-title::after {
    content: " *";
    color: currentColor;
}

.wpcf7-styled :is([data-class="wpcf7cf_group"], form) > p {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(var(--form-field-min-width), 100%), 1fr));
    row-gap: var(--form-gap-row);
    column-gap: var(--form-gap-col);
}

.wpcf7-styled :is([data-class="wpcf7cf_group"], form) > p .wide {
    grid-column: 1 / -1;
}

.wpcf7-styled :is([data-class="wpcf7cf_group"], form) .wpcf7-submit {
    inline-size: 100%;
    margin-inline: auto;
    border-radius: var(--form-border-radius-input);
}

.wpcf7-styled :is([data-class="wpcf7cf_group"], form) > p br,
.wpcf7-styled :is([data-class="wpcf7cf_group"], form) .wpcf7-spinner {
    display: none;
}

.wpcf7-styled :is([data-class="wpcf7cf_group"], form) .wpcf7-not-valid-tip {
    font-size: 0.75rem;
    margin-top: 0.25rem;
}

.wpcf7-styled .wpcf7-acceptance label {
    flex-direction: row;
    align-items: flex-start;
    gap: 0.75rem;
}

.wpcf7-styled .wpcf7-acceptance label span {
    text-box: trim-both cap alphabetic;
}

.wpcf7-styled .wpcf7-acceptance label span a {
    text-decoration: underline;
}

.wpcf7-styled .wide [data-name="acceptance"] {
    display: block;
    margin-block: var(--form-gap-row);
}

.wpcf7-styled [data-name="acceptance"] .wpcf7-list-item {
    margin-inline-start: 0;
}

.wpcf7-styled .wpcf7-response-output {
    padding: 1rem;
    text-wrap: balance;
    font-size: 0.875rem;
    inline-size: 100%;
    border: 1px solid transparent;
    margin-block-start: 3rem;
    border-radius: var(--form-border-radius-input);
}

.wpcf7-styled form.sent .wpcf7-response-output {
    background-color: #5ad66521;
    border-color: #5ad6659e;
}

.wpcf7-styled form.invalid .wpcf7-response-output {
    border-color: #ffb900cc;
}

.eg-pagination ul {
    display: flex;
    gap: 0.5rem;
    justify-content: center;
    align-items: center;
}

.eg-pagination .page-btn:disabled,
.eg-pagination .page-separator,
.eg-pagination .page:not(.page-current) {
    opacity: 0.4;
}

.eg-pagination :disabled {
    pointer-events: none;
}

/* ======================================== */
/* THEME */
/* ======================================== */

:root {
    --z-header: 9999;
    --header-height: 6.125rem;

    --c-red: #fe1f20;
    --c-black: #101010;
    --c-white: #ffffff;
    --grey-text: #666666;

    --ff-primary: "Aktiv Grotesk", system-ui, sans-serif;
    --ff-secondary: "Aktiv Grotesk Ex", var(--ff-primary);
    --ff-tertiary: "Degular Mono", ui-monospace, monospace;
    --ff-quaternary: "Aptos", var(--ff-primary);
}

[data-theme="light"] {
    --surface: var(--c-white);
    --on-surface: var(--c-black);
    --accent: var(--c-red);
    --on-accent: var(--c-white);
    background-color: var(--surface);
    color: var(--on-surface);
}

[data-theme="dark"] {
    --surface: var(--c-black);
    --on-surface: var(--c-white);
    --accent: var(--c-red);
    --on-accent: var(--c-white);
    background-color: var(--surface);
    color: var(--on-surface);
}

.ff-primary {
    font-family: var(--ff-primary);
}

.ff-secondary {
    font-family: var(--ff-secondary);
}

.ff-tertiary {
    font-family: var(--ff-tertiary);
}

.color-accent {
    color: var(--accent);
}

/* ======================================== */
/* BUTTONS */
/* ======================================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    font-family: var(--ff-secondary);
    font-weight: 600;
    font-size: 1rem;
    line-height: 1;
    letter-spacing: 0.01em;
    text-transform: uppercase;
    padding-block: 0.625rem;
    padding-inline: 0.8125rem;
    border: 2px solid transparent;
    border-radius: 6.25rem;
    cursor: pointer;
    transition:
        color 0.2s ease,
        background-color 0.2s ease,
        border-color 0.2s ease;
}

.btn.btn-primary {
    background-color: var(--accent);
    border-color: var(--accent);
    color: var(--c-white);
}

.btn.btn-primary:is(:hover, :focus-visible) {
    background-color: rgb(from var(--accent) r g b / 0.55);
}

.btn.btn-outline {
    border-color: currentColor;
    color: currentColor;
    background-color: rgb(255 255 255 / 0.01);
    backdrop-filter: blur(2px);
}

.btn.btn-outline:is(:hover, :focus-visible) {
    background-color: var(--c-white);
    border-color: var(--c-white);
    color: var(--c-black);
}

/* ======================================== */
/* SITE HEADER */
/* ======================================== */

/* transparent bar laid over the hero (the hero is full-height, so the header never
   pushes content down); 30/4 block padding + a 38px CTA = the 72px Figma bar */
header.site-header {
    position: fixed;
    inset-block-start: 0;
    inset-inline: 0;
    z-index: var(--z-header);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.25rem;
    padding-block: 1.875rem 0.25rem;
    padding-inline: 3.125rem;
    color: var(--c-white);
    transition:
        padding-block 0.3s ease,
        background-color 0.3s ease;
}

/* scrolled state (Figma "sticky header"): solid black, and the bar shrinks to 50px —
   6px of block padding around the 38px CTA. JS toggles the class (see initStickyHeader) */
header.site-header.is-stuck {
    padding-block: 0.375rem;
    background-color: var(--c-black);
}

/* past the hero the bar only comes back when you scroll up */
header.site-header {
    transition:
        translate 0.35s var(--reveal-ease),
        padding-block 0.25s ease,
        background-color 0.25s ease;
}

header.site-header.is-hidden {
    translate: 0 -100%;
}

header.site-header .site-header-logo {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    inline-size: 12.5rem;
    flex: none;
    text-decoration: none;
    color: inherit;
}

header.site-header .site-header-logo-mark {
    display: block;
    inline-size: 2.375rem;
    flex: none;
    transition: inline-size 0.3s ease;
}

header.site-header .site-header-logo-mark svg {
    display: block;
    inline-size: 100%;
    block-size: auto;
}

/* the mark turns white over the open menu — fade it, don't snap it */
header.site-header .site-header-logo-mark svg path {
    transition: fill 0.35s var(--cut-ease);
}

header.site-header .site-header-logo-text {
    font-family: var(--ff-secondary);
    font-weight: 700;
    font-size: 0.875rem;
    line-height: 1;
    letter-spacing: 0.01em;
    text-transform: uppercase;
    white-space: nowrap;
}

/* ---- menu ---- */

header.site-header .site-header-menu {
    display: flex;
    align-items: center;
    gap: 2.0625rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

header.site-header .site-header-menu a {
    display: block;
    color: inherit;
    text-decoration: none;
    white-space: nowrap;
    transition: opacity 0.2s ease;
}

header.site-header .site-header-menu a:is(:hover, :focus-visible) {
    opacity: 0.6;
}

header.site-header .site-header-menu .current-menu-item a {
    opacity: 0.6;
}

/* ---- cta ---- */

/* Figma's pill has no stroke, while .btn carries a 2px border — keeping it would eat 4px of
   the 170px the label needs inside the 200px pill and wrap it onto two lines */
header.site-header .site-header-cta {
    flex: none;
    inline-size: 12.5rem;
    border-width: 0;
    font-size: 0.875rem;
    line-height: 1;
    padding-block: 0.75rem;
    padding-inline: 0.9375rem;
    white-space: nowrap;
}

/* ---- mobile toggle ---- */

/* the red pill from Figma (60px wide, fully rounded). Its two bars are absolutely placed
   against the icon box, so growing the box (8px → 17px) is what carries them apart while
   they rotate into the cross — one transition, no separate translate bookkeeping */
header.site-header .site-header-toggle {
    display: none;
    flex: none;
    align-items: center;
    justify-content: center;
    inline-size: 3.75rem;
    padding-block: 0.625rem;
    padding-inline: 0.625rem;
    border: none;
    border-radius: 6.25rem;
    background-color: var(--c-red);
    color: var(--c-white);
    cursor: pointer;
}

header.site-header .site-header-toggle-icon {
    position: relative;
    display: block;
    inline-size: 2.125rem;
    /* the icon is 34x8: two 2px bars with 4px between them (client's SVG) */
    block-size: 0.5rem;
    transition: block-size 0.35s var(--cut-ease);
}

header.site-header .site-header-toggle-bar {
    position: absolute;
    inset-inline: 0;
    block-size: 2px;
    background-color: currentColor;
    transition:
        translate 0.35s var(--cut-ease),
        rotate 0.35s var(--cut-ease);
}

header.site-header .site-header-toggle-bar:first-child {
    inset-block-start: 0;
}

header.site-header .site-header-toggle-bar:last-child {
    inset-block-end: 0;
}

/* 26.57deg = atan(17 / 34): the cross ends up exactly as wide and as tall as Figma's */
header.site-header .site-header-toggle[aria-expanded="true"] .site-header-toggle-icon {
    block-size: 1.0625rem;
}

header.site-header .site-header-toggle[aria-expanded="true"] .site-header-toggle-bar:first-child {
    translate: 0 0.46875rem;
    rotate: 26.57deg;
}

header.site-header .site-header-toggle[aria-expanded="true"] .site-header-toggle-bar:last-child {
    translate: 0 -0.46875rem;
    rotate: -26.57deg;
}

/* the desktop bar needs room for logo + 6 menu items + a 200px CTA; below 1110px it
   switches to the mobile treatment, ahead of the 768px page breakpoint */
@media (max-width: 1110px) {
    /* mobile: the logo on the inline start, the burger pill on the inline end */
    header.site-header {
        justify-content: space-between;
        padding-block: 1.375rem 0;
        padding-inline: var(--container-x-padding) 1.375rem;
    }

    header.site-header .site-header-nav,
    header.site-header .site-header-cta {
        display: none;
    }

    header.site-header .site-header-toggle {
        display: inline-flex;
    }

    header.site-header .site-header-logo {
        inline-size: auto;
    }

    header.site-header .site-header-logo-mark {
        inline-size: 3.125rem;
    }

    header.site-header.is-stuck {
        padding-block: 0.5rem;
    }

    header.site-header.is-stuck .site-header-logo-mark {
        inline-size: 2.375rem;
    }

    /* with the panel open the bar goes back to its resting layout: no black background, no
       hide-on-scroll, and the logo turns white over the red */
    header.site-header.is-menu-open {
        translate: none;
        padding-block: 1.375rem 0;
        background-color: transparent;
    }

    header.site-header.is-menu-open .site-header-logo-mark {
        inline-size: 3.125rem;
    }

    /* the mark's paths carry a fill attribute — a CSS fill still wins over it */
    header.site-header.is-menu-open .site-header-logo-mark svg path {
        fill: var(--c-white);
    }
}

/* ======================================== */
/* SITE MENU (mobile panel) */
/* ======================================== */

.site-menu {
    position: fixed;
    inset: 0;
    /* under the header, so the logo and the toggle stay on top of it */
    z-index: calc(var(--z-header) - 1);
    display: none;
    background-color: var(--c-red);
    color: var(--c-white);
    opacity: 0;
    visibility: hidden;
    transition:
        opacity 0.35s var(--cut-ease),
        visibility 0.35s var(--cut-ease);
}

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

.site-menu.is-open {
    opacity: 1;
    visibility: visible;
}

body:has(.site-menu.is-open) {
    overflow: hidden;
}

.site-menu .site-menu-inner {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.875rem;
    block-size: 100%;
    padding-block: 7.5625rem 3.125rem;
    padding-inline: var(--container-x-padding);
    overflow-y: auto;
}

.site-menu .site-menu-label {
    color: var(--c-black);
}

.site-menu .site-menu-list {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.site-menu .site-menu-list a {
    display: block;
    color: inherit;
    text-decoration: none;
    transition: opacity 0.2s ease;
}

.site-menu .site-menu-list a:is(:hover, :focus-visible),
.site-menu .site-menu-list .current-menu-item a {
    opacity: 0.6;
}

.site-menu .site-menu-socials {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    margin: 0;
    margin-block-start: auto;
    padding: 0;
    list-style: none;
}

.site-menu .site-menu-social {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2.8125rem;
    block-size: 2.8125rem;
    border: 1px solid rgb(from var(--c-white) r g b / 0.4);
    border-radius: 50%;
    color: var(--c-white);
    transition:
        background-color 0.2s ease,
        border-color 0.2s ease;
}

.site-menu .site-menu-social-icon {
    inline-size: 1.0625rem;
    block-size: 1.0625rem;
    object-fit: contain;
}

.site-menu .site-menu-social:is(:hover, :focus-visible) {
    background-color: rgb(from var(--c-white) r g b / 0.15);
    border-color: var(--c-white);
}

/* the panel's contents rise in one after the other; `--menu-i` is set by initMobileMenu.
   The socials are deliberately left out — they only fade with the panel */
@media (prefers-reduced-motion: no-preference) {
    html[data-reveal-ready] .site-menu :is(.site-menu-label, .site-menu-list li) {
        opacity: 0.6;
        translate: 0 0.5rem;
        transition:
            opacity 0.35s var(--cut-ease),
            translate 0.35s var(--cut-ease);
    }

    /* no lead-in delay: the texts start with the panel itself, and the stagger is tight */
    html[data-reveal-ready] .site-menu.is-open :is(.site-menu-label, .site-menu-list li) {
        opacity: 1;
        translate: none;
        transition-delay: calc(var(--menu-i, 0) * 0.035s);
    }
}

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

section.hero.hero-banner {
    position: relative;
    /* the heading gap and the band's own block size (9 + 13 + 9). The intro starts with the
       band rolled up and the two title lines stacked over the room it takes: each line is
       shifted by half of band + gap (see "page intro") */
    --hero-heading-gap: clamp(0.625rem, 1.2vw, 1rem);
    --hero-band-block: 1.9375rem;
    --hero-band-collapse: calc((var(--hero-band-block) + var(--hero-heading-gap)) / 2);
}

section.hero.hero-banner .layers {
    min-block-size: 100svh;
}

section.hero.hero-banner .layer-bg::after {
    background: linear-gradient(180deg, rgb(0 0 0 / 0.5) 0%, rgb(0 0 0 / 0.3) 54%, rgb(0 0 0 / 0.3) 96%);
}

section.hero.hero-banner .layer-fg {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: calc(var(--header-height) + 1.5rem) 2.5rem;
    text-align: center;
}

section.hero.hero-banner .layer-fg .container {
    max-inline-size: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2.5rem;
}

section.hero.hero-banner .hero-heading {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--hero-heading-gap);
    inline-size: 100%;
}

section.hero.hero-banner .hero-line {
    display: block;
    inline-size: 100%;
}

section.hero.hero-banner .hero-line svg {
    display: block;
    inline-size: 100%;
    block-size: auto;
}

section.hero.hero-banner .hero-line-fill {
    max-inline-size: 41.6875rem;
}

section.hero.hero-banner .hero-line-outline {
    max-inline-size: 38.0625rem;
    position: relative;
}

/* glass inside the outlined word. Figma exports this as a <foreignObject> holding a div with
   backdrop-filter + clip-path: url(#bgblur…) — Safari ignores BOTH the foreignObject's x/y and
   that clip-path, so it painted an unclipped rectangle larger than the word. The foreignObject
   is out of the SVG; the blur is a pseudo-element masked by a solid-fill copy of the same
   letters instead. The pseudo is absolutely positioned, so it paints ABOVE the static SVG no
   matter the DOM order — the SVG is lifted with its own z-index to get the stroke back on top.
   It has to stay above rather than the blur going to z-index: -1, or the blur would sink
   behind the line's own box. */
@supports ((-webkit-mask-image: url("assets/images/hero-title-outline-mask.svg")) or (mask-image: url("assets/images/hero-title-outline-mask.svg"))) {
    section.hero.hero-banner .hero-line-outline::before {
        content: "";
        position: absolute;
        inset: 0;
        pointer-events: none;
        -webkit-backdrop-filter: blur(10px);
        backdrop-filter: blur(10px);
        -webkit-mask: url("assets/images/hero-title-outline-mask.svg") no-repeat center / 100% 100%;
        mask: url("assets/images/hero-title-outline-mask.svg") no-repeat center / 100% 100%;
    }

    section.hero.hero-banner .hero-line-outline svg {
        position: relative;
        z-index: 1;
    }
}

/* edge to edge: the hero container is full width, so growing by its padding on both sides and
   pulling it back with negative margins lands exactly on the viewport edges — same trick the
   mobile marquee uses, and unlike a box-shadow it survives being clipped by the intro */
section.hero.hero-banner .hero-band {
    inline-size: calc(100% + 2 * var(--container-x-padding));
    margin-inline: calc(-1 * var(--container-x-padding));
    display: flex;
    justify-content: center;
    padding-block: 0.5625rem;
    background-color: var(--c-black);
}

section.hero.hero-banner .hero-caption {
    font-family: var(--ff-tertiary);
    font-weight: 500;
    font-size: 0.8125rem;
    line-height: 1;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--c-white);
    padding-inline: 1rem;
    text-wrap: balance;
}

section.hero.hero-banner .hero-ctas {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 1.25rem;
    padding-inline: 1.5rem;
}

/* the load-in cover only exists for the intro animation (see "page intro") */
.page-intro {
    display: none;
}

/* HERO BANNER — mobile */
@media (max-width: 768px) {
    /* the marquee track is `inline-size: max-content`, and an auto grid track sizes to its
       item's max-content — without this the whole hero (and the page) overflows sideways */
    section.hero.hero-banner .layers {
        grid-template-columns: minmax(0, 1fr);
    }

    /* the fixed CTA lives inside .layer-fg, which is a stacking context (z-index: 1) — without
       lifting the whole hero the button is trapped at that level and later positioned content
       in .inner-content paints over it */
    section.hero.hero-banner {
        z-index: 900;
    }

    /* --header-height is the desktop bar (98px); the mobile one is 56px, so the desktop
       padding pushed the heading ~82px below centre */
    section.hero.hero-banner .layer-fg {
        padding-block: 3.5rem;
    }

    section.hero.hero-banner .layer-fg .container {
        gap: 0;
    }

    section.hero.hero-banner {
        --hero-heading-gap: 0.9375rem;
        /* the mobile band is 8 + 13 + 8 */
        --hero-band-block: 1.8125rem;
    }

    /* ---------------------------------------- */
    /* Black band → edge-to-edge marquee */
    /* ---------------------------------------- */

    section.hero.hero-banner .hero-band {
        display: block;
        position: relative;
        overflow: hidden;
        inline-size: calc(100% + 2 * var(--container-x-padding));
        margin-inline: calc(-1 * var(--container-x-padding));
        padding-block: 0.5rem;
    }

    section.hero.hero-banner .hero-band .hero-marquee {
        display: flex;
        inline-size: max-content;
        animation: hero-marquee-scroll var(--hero-marquee-duration, 20s) linear infinite;
    }

    section.hero.hero-banner .hero-band .hero-caption {
        flex: 0 0 auto;
        display: block;
        white-space: nowrap;
        text-wrap: nowrap;
        padding-inline: 1rem;
    }

    /* Pause on interaction so the text can be read */
    section.hero.hero-banner .hero-band:is(:hover, :focus-within) .hero-marquee {
        animation-play-state: paused;
    }

    @keyframes hero-marquee-scroll {
        from {
            transform: translateX(0);
        }

        to {
            transform: translateX(-50%);
        }
    }

    /* ---------------------------------------- */
    /* CTAs: only the "Register your interest" bar, pinned to the viewport */
    /* ---------------------------------------- */

    section.hero.hero-banner .hero-ctas {
        display: contents;
    }

    section.hero.hero-banner .hero-ctas .btn.btn-primary {
        display: none;
    }

    section.hero.hero-banner .hero-ctas .btn.btn-outline {
        position: fixed;
        z-index: 900;
        inset-inline: 0;
        inset-block-end: 0;
        display: flex;
        inline-size: 100%;
        font-size: 0.875rem;
        line-height: 1;
        letter-spacing: 0.01em;
        padding-block: 0.75rem calc(0.75rem + env(safe-area-inset-bottom, 0px));
        padding-inline: 0.9375rem;
        border-width: 0;
        border-radius: 0;
        background-color: var(--accent);
        color: var(--c-white);
        backdrop-filter: none;
        transition:
            transform 0.35s ease,
            opacity 0.35s ease;
    }

    section.hero.hero-banner .hero-ctas .btn.btn-outline:is(:hover, :focus-visible) {
        background-color: rgb(from var(--accent) r g b / 0.85);
        color: var(--c-white);
    }

    /* Un-pinned once the site footer comes into view (toggled by JS) */
    section.hero.hero-banner .hero-ctas .btn.btn-outline.is-unpinned {
        transform: translateY(100%);
        opacity: 0;
        pointer-events: none;
    }
}

@media (max-width: 768px) and (prefers-reduced-motion: reduce) {
    section.hero.hero-banner .hero-band {
        overflow-x: auto;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }

    section.hero.hero-banner .hero-band::-webkit-scrollbar {
        display: none;
    }

    section.hero.hero-banner .hero-band .hero-marquee {
        animation: none;
    }

    section.hero.hero-banner .hero-ctas .btn.btn-outline {
        transition: none;
    }
}


/* ======================================== */
/* TYPOGRAPHY */
/* ======================================== */

.fs-body {
    font-family: var(--ff-primary);
    font-weight: 400;
    font-size: 1rem;
    line-height: 1.35;
    letter-spacing: -0.005em;
}

.fs-big-title {
    font-family: var(--ff-secondary);
    font-weight: 700;
    font-size: 9.375rem;
    line-height: 1.1;
    letter-spacing: -0.04em;
}

.fs-title-1 {
    font-family: var(--ff-secondary);
    font-weight: 600;
    font-size: 4.375rem;
    line-height: 0.95;
    letter-spacing: -0.03em;
}

/* mobile display size — shared by rules, circuit, partners and proof */
@media (max-width: 768px) {
    .fs-title-1 {
        font-size: 2.6875rem;
    }
}

.fs-title-2-semibold,
.fs-title-2-medium {
    font-family: var(--ff-secondary);
    font-weight: 500;
    font-size: 2.1875rem;
    line-height: 1.1;
    letter-spacing: -0.03em;
}

.fs-title-2-semibold {
    font-weight: 600;
}

.fs-title-3 {
    font-family: var(--ff-secondary);
    font-weight: 600;
    font-size: 1.875rem;
    line-height: 1.1;
    letter-spacing: -0.03em;
}

.fs-numbers {
    font-family: var(--ff-secondary);
    font-weight: 600;
    font-size: 2.5rem;
    line-height: 1.1;
    letter-spacing: -0.03em;
}

.fs-label {
    font-family: var(--ff-tertiary);
    font-weight: 500;
    font-size: 0.8125rem;
    line-height: 1;
    letter-spacing: 0;
    text-transform: uppercase;
}

/* ======================================== */
/* INNER CONTENT (page gradient wrapper) */
/* ======================================== */

.inner-content {
    background: linear-gradient(180deg, #020c16 0%, #071f36 100%);
    overflow-x: clip;
}

/* ======================================== */
/* TEXT + INFO */
/* ======================================== */

section.text-info {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

section.text-info .deco {
    position: absolute;
    z-index: 0;
    inset-block-start: 3.9375rem;
    inset-inline-start: -31.4375rem;
    inline-size: 50.875rem;
    block-size: 50.75rem;
    pointer-events: none;
    /* the individual `rotate` property runs before `transform`, so it turns the arc in the
       parent's space: -13deg reads as 13deg counter-clockwise on screen, mirror or not.
       This is the resting state — the reveal animates into it (see `data-reveal="turn"`) */
    --reveal-turn: -13deg;
    rotate: var(--reveal-turn);
    transform: scaleX(-1);
}

section.text-info .deco svg {
    display: block;
    inline-size: 100%;
    block-size: 100%;
}

section.text-info .text,
section.text-info .info {
    position: relative;
    z-index: 1;
}

section.text-info .text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3.125rem;
    padding-block: 6.25rem;
    text-align: center;
}

section.text-info .fs-label {
    color: var(--accent);
}

section.text-info .info {
    border-block-start: 1px solid rgb(from var(--on-surface) r g b / 0.14);
}

section.text-info .info-cols {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
}

section.text-info .info-col {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 2.125rem;
    padding-block: 1.25rem;
    padding-inline: 1.875rem;
}

section.text-info .info-col + .info-col {
    border-inline-start: 1px solid rgb(from var(--on-surface) r g b / 0.14);
}

section.text-info .info-col:first-child {
    padding-inline-start: 0;
}

section.text-info .info-col:last-child {
    padding-inline-end: 0;
}

/* INTRO (.text-info) — mobile */
@media (max-width: 768px) {
    /* Deco arc: same size as desktop, pushed further off-canvas to the inline-start */
    section.text-info .deco {
        inset-block-start: 3.96875rem;
        inset-inline-start: -40.1875rem;
    }

    /* Statement block: left-aligned on mobile, 90px top / 80px bottom rhythm */
    section.text-info .text {
        align-items: flex-start;
        gap: 3.125rem;
        padding-block: 5.625rem 5rem;
        text-align: start;
    }

    section.text-info .text .fs-title-2-medium {
        font-size: 2.0625rem;
    }

    /* Info rows go full-bleed: the container stops constraining, each row carries its own inline padding */
    section.text-info .info {
        border-block-start: none;
    }

    section.text-info .info-cols {
        grid-template-columns: minmax(0, 1fr);
        max-inline-size: none;
        inline-size: 100%;
        padding-inline: 0;
    }

    section.text-info .info-col,
    section.text-info .info-col:first-child,
    section.text-info .info-col:last-child {
        gap: 1.5rem;
        min-block-size: 7.5rem;
        padding-block: 1.25rem;
        padding-inline: var(--container-x-padding);
        border-block-start: 1px solid rgb(from var(--on-surface) r g b / 0.14);
        background-color: rgb(6 27 47 / 0.01);
        backdrop-filter: blur(5px);
    }

    /* MANAGER FIX: the desktop rule is `.info-col + .info-col` (0,3,1) and outranks the
       grouped `.info-col` selector above (0,2,1) — the vertical divider must be killed at
       matching specificity or columns 2/3 keep it. */
    section.text-info .info-col + .info-col {
        border-inline-start: none;
    }

    section.text-info .info-col:last-child {
        /* Figma gives the last cell 50px of breathing room before the next section */
        padding-block-end: 3.125rem;
        border-block-end: 1px solid rgb(from var(--on-surface) r g b / 0.14);
    }
}


/* ======================================== */
/* SHOWCASE */
/* ======================================== */

section.showcase {
    position: relative;
    padding-block-start: 6.25rem;
    /* White surface that fades to transparent for the last 104px, so the dark
       page wrapper shows through as a strip the section below sits under. */
    background-color: transparent;
    background-image: linear-gradient(var(--surface) 0%, var(--surface) calc(100% - 6.5rem), transparent calc(100% - 6.5rem));
}

section.showcase .showcase-heading {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2.5rem;
    text-align: center;
    padding-block-end: 6.25rem;
}

section.showcase .showcase-title-big {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(1.5rem, 4.5vw, 4rem);
    color: var(--on-surface);
}

section.showcase .showcase-title-word:nth-of-type(1) {
    order: 1;
}

section.showcase .showcase-title-label {
    order: 2;
    flex: none;
    inline-size: 8.625rem;
    color: var(--accent);
    text-align: start;
}

section.showcase .showcase-title-word:nth-of-type(2) {
    order: 3;
}

section.showcase .showcase-intro {
    max-inline-size: 64.375rem;
    color: var(--grey-text);
}

section.showcase .showcase-cols {
    display: flex;
    align-items: flex-start;
    overflow: visible;
}

section.showcase .showcase-panels {
    inline-size: 31.5625rem;
    flex: none;
    display: flex;
    flex-direction: column;
    gap: 2.5625rem;
}

section.showcase .showcase-nav {
    display: inline-flex;
    align-self: flex-start;
    align-items: center;
    justify-content: center;
    gap: 1.875rem;
    padding: 0.25rem;
    border: 1px solid #d9d9d9;
    border-radius: 6.25rem;
    backdrop-filter: blur(2px);
}

section.showcase .showcase-arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2.5rem;
    block-size: 2.5rem;
    flex: none;
    /* the border is kept (it holds the 40px box) but painted like the fill, so the puck
       reads as a solid red disc with a white chevron */
    border: 2px solid var(--c-red);
    border-radius: 50%;
    background-color: var(--c-red);
    color: var(--c-white);
    /* hovering only grows the disc — the colours never change */
    transition: scale 0.2s ease;
}

section.showcase .showcase-arrow svg {
    inline-size: 0.375rem;
    block-size: 0.625rem;
    /* counter-scale, so the chevron keeps its size while the disc grows */
    transition: scale 0.2s ease;
}

section.showcase .showcase-arrow[data-showcase-prev] svg {
    transform: rotate(180deg);
}

/* on hover the disc grows over the pill's 4px of padding, stopping just short of its
   border: (40 + 2 * 4) / 40 = 1.2 (not 1.25, which would eat the 1px border too) */
section.showcase .showcase-arrow:is(:hover, :focus-visible) {
    scale: 1.2;
}

section.showcase .showcase-arrow:is(:hover, :focus-visible) svg {
    scale: calc(1 / 1.2);
}

/* all labels share one grid cell, so the pill is sized by the longest of them and stays put
   while paging. Only opacity hides the inactive ones — no visibility: Safari does not
   interpolate the discrete visibility step reliably and the label flickered / stayed blank
   through the transition. The box has to survive anyway (it is what sizes the pill), so the
   inactive labels are kept out of the a11y tree with aria-hidden (set by initShowcase) and
   out of hit-testing with pointer-events. */
section.showcase .showcase-nav-label {
    display: grid;
    color: var(--c-black);
    white-space: nowrap;
    /* the cell is as wide as the longest label — the shorter ones sit centred in it */
    text-align: center;
}

section.showcase .showcase-nav-label-item {
    grid-area: 1 / 1;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

section.showcase .showcase-nav-label-item.is-active {
    opacity: 1;
}

section.showcase .showcase-panel {
    display: none;
    flex-direction: column;
    gap: 2.5625rem;
}

section.showcase .showcase-panel.is-active {
    display: flex;
}

section.showcase .showcase-panel-title {
    color: var(--on-surface);
}

section.showcase .showcase-panel-text {
    font-family: var(--ff-quaternary);
    font-size: 1.125rem;
    line-height: 1.3;
    letter-spacing: -0.005em;
    color: var(--grey-text);
}

section.showcase .showcase-panel-text strong {
    font-weight: 400;
    color: var(--on-surface);
}

section.showcase .showcase-thumbs {
    inline-size: 5.3125rem;
    flex: none;
    margin-inline-start: 7.8125rem;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.3125rem;
}

section.showcase .showcase-thumb {
    inline-size: 4.375rem;
    block-size: 2.9375rem;
    flex: none;
    overflow: hidden;
    background-color: #d9d9d9;
    cursor: pointer;
    transition: opacity 0.2s ease;
}

section.showcase .showcase-thumb img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
}

section.showcase .showcase-thumb.is-active {
    opacity: 0.5;
}

section.showcase .showcase-images {
    inline-size: min(37.8125rem, 42vw);
    aspect-ratio: 605 / 682;
    flex: none;
    margin-inline-start: 1.25rem;
    position: relative;
}

section.showcase .showcase-image {
    position: absolute;
    inset: 0;
    /* it is a parallax frame now, so it has to clip what drifts inside it */
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.4s ease;
}

section.showcase .showcase-image.is-active {
    opacity: 1;
}

section.showcase .showcase-image img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
}

@media (max-width: 1280px) {
    section.showcase .showcase-title-big {
        font-size: clamp(3rem, 11vw, 9.375rem);
    }

    section.showcase .showcase-cols {
        flex-direction: column;
        gap: 2.5rem;
    }

    section.showcase .showcase-panels {
        inline-size: 100%;
    }

    section.showcase .showcase-thumbs {
        inline-size: 100%;
        margin-inline-start: 0;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: flex-start;
    }

    section.showcase .showcase-images {
        inline-size: 100%;
        block-size: auto;
        aspect-ratio: 605 / 682;
        margin-inline-start: 0;
    }
}

/* SHOWCASE — mobile */
@media (max-width: 768px) {
    /* The desktop white->transparent fade (last 6.5rem) does not exist on the mobile
       frame: Block 4 stays white to the very bottom of the section. */
    section.showcase {
        padding-block-start: 6.25rem;
        background-color: var(--surface);
        background-image: none;
    }

    /* ---- heading ---- */

    section.showcase .showcase-heading {
        gap: 2.5rem;
        padding-block-end: 6.25rem;
    }

    /* THE / (label) / BOAT stacked. 90px at line-height 0.7 = 63px per line;
       the label sits in the middle line box (18px above + below). */
    section.showcase .showcase-title-big {
        flex-direction: column;
        gap: 1.125rem;
        font-size: 5.625rem;
        line-height: 0.7;
        letter-spacing: -0.04em;
    }

    section.showcase .showcase-title-label {
        inline-size: 8.625rem;
        text-align: center;
    }

    section.showcase .showcase-intro {
        max-inline-size: none;
    }

    /* ---- viewer: image, then thumb strip, then panels ---- */

    /* .showcase-cols is a .container: drop its inline padding so the image and the
       thumb strip go full-bleed. The 1.875rem page gutter moves onto .showcase-panels. */
    section.showcase .showcase-cols {
        flex-direction: column;
        gap: 0;
        padding-inline: 0;
        max-inline-size: none;
    }

    section.showcase .showcase-images {
        order: 1;
        inline-size: 100%;
        block-size: auto;
        aspect-ratio: 605 / 682;
        margin-inline-start: 0;
        /* it is a track now, so the slides waiting off-frame have to be clipped — and clipped
           here, not on the page, or they would widen the document */
        overflow: hidden;
    }

    /* The slides really travel on mobile, they do not just crossfade (client). The stack stays
       absolutely positioned; each slide is simply pushed aside by its own distance from the
       active one (`--showcase-offset`, set in `initShowcase`), which makes the whole set move
       together like a carousel. They also stay fully opaque — a slide that fades out while it
       leaves is a slide you cannot see sliding, which was the whole point. */
    section.showcase .showcase-image,
    section.showcase .showcase-image.is-active {
        opacity: 1;
        translate: calc(var(--showcase-offset, 0) * 100%) 0;
        /* `--cut-ease`, not `--reveal-ease`: the latter is front-loaded, and on a sweep like this
           that reads as a snap followed by a crawl (same note as the intro cut) */
        transition: translate 0.55s var(--cut-ease);
    }

    section.showcase .showcase-thumbs {
        order: 2;
        inline-size: 100%;
        margin-inline-start: 0;
        flex-direction: row;
        flex-wrap: nowrap;
        align-items: stretch;
        justify-content: flex-end;
        gap: 0.3125rem;
        padding-block-end: 0.3125rem;
    }

    section.showcase .showcase-thumb {
        position: relative;
        inline-size: auto;
        block-size: auto;
        flex: 1 1 0;
        min-inline-size: 0;
        aspect-ratio: 85 / 57;
        overflow: visible;
        touch-action: manipulation;
    }

    /* The thumbs are 42.5x28.5 in the design — below the 44px touch target.
       Extend the hit area vertically without shifting the layout. */
    section.showcase .showcase-thumb::after {
        content: "";
        position: absolute;
        inset-block: -0.5rem;
        inset-inline: 0;
    }

    section.showcase .showcase-panels {
        order: 3;
        inline-size: 100%;
        padding-inline: 1.875rem;
        padding-block: 3.75rem;
        gap: 2.5rem;
    }

    /* ---- nav pill ---- */

    /* Figma hugs at 310 of 315 available; going full-width is visually identical and
       stays safe for the longer item labels in the set. */
    section.showcase .showcase-nav {
        align-self: center;
        inline-size: 100%;
        justify-content: space-between;
        gap: 0.625rem;
        padding: 0.3125rem;
    }

    section.showcase .showcase-nav-label {
        flex: 1 1 auto;
        min-inline-size: 0;
        white-space: normal;
        text-align: center;
    }

    /* no crossfade on mobile: Safari mishandles the opacity transition on these stacked labels
       (they flicker / stay blank), so the label just swaps instantly */
    section.showcase .showcase-nav-label-item {
        transition: none;
    }

    /* ---- panel ---- */

    section.showcase .showcase-panel {
        gap: 2.5rem;
    }

    section.showcase .showcase-panel-title {
        font-size: 2.0625rem;
        line-height: 1.1;
        letter-spacing: -0.03em;
    }
}

/* Touch devices keep :hover painted after a tap — neutralise it on the arrows and
   thumbs, keep :focus-visible and add a press state instead. */
@media (max-width: 768px) and (hover: none) {
    section.showcase .showcase-arrow:hover {
        scale: 1;
    }

    section.showcase .showcase-arrow:hover svg {
        scale: 1;
    }

    section.showcase .showcase-arrow:active {
        scale: 1.2;
    }

    section.showcase .showcase-arrow:active svg {
        scale: calc(1 / 1.2);
    }
}

/* ======================================== */
/* SPEC-SCROLL */
/* ======================================== */

/* ======================================== */
/* SPEC SCROLL (Block 2 + spec numbers) */
/* ======================================== */

section.spec-scroll {
    /* Container inner-edge inset: matches where .container content begins.
       --container-max = (x-padding * 2) + ((cols - 1) * gap) + (cols * col-width)
       = (2rem*2) + (11*1.25rem) + (12*5.3125rem) = 81.5rem */
    --spec-inset: max(var(--container-x-padding), calc((100vw - 81.5rem) / 2 + var(--container-x-padding)));
    --spec-border: #2c4154;
    --spec-muted: #69747e;
    --spec-cell-bg: rgb(6 27 47 / 0.01);
    --spec-fade: #061b2f;

    position: relative;
}

section.spec-scroll .spec-scroll-heading {
    display: flex;
    flex-direction: column;
    gap: 3.125rem;
    padding-block: 2.5rem 3.75rem;
}

section.spec-scroll .spec-scroll-pretitle {
    color: var(--accent);
}

section.spec-scroll .spec-scroll-title {
    color: var(--on-surface);
}

section.spec-scroll .spec-scroll-sublabel {
    font-family: var(--ff-secondary);
    font-weight: 600;
    font-size: 1.25rem;
    line-height: 1.1;
    letter-spacing: -0.03em;
    color: var(--on-surface);
}

/* ---- scroller ---- */

section.spec-scroll .spec-scroll-viewport {
    position: relative;
}

section.spec-scroll .spec-scroll-track {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

section.spec-scroll .spec-scroll-track::-webkit-scrollbar {
    display: none;
}

section.spec-scroll .spec-scroll-cell {
    flex: none;
    inline-size: 19.375rem;
    scroll-snap-align: start;
    display: flex;
    flex-direction: column;
    gap: 2.5rem;
    padding-block: 1.25rem;
    padding-inline: 1.875rem;
    background-color: var(--spec-cell-bg);
    backdrop-filter: blur(5px);
    border-block: 1px solid var(--spec-border);
    border-inline-end: 1px solid var(--spec-border);
}

/* First / last cell push their content to the container edge (like Figma's
   100px outer margin) while their top/bottom borders stay full-bleed. */
section.spec-scroll .spec-scroll-cell:first-child {
    inline-size: calc(19.375rem + var(--spec-inset) - 1.875rem + var(--container-x-padding));
    padding-inline-start: var(--spec-inset);
}

section.spec-scroll .spec-scroll-cell:last-child {
    inline-size: calc(19.375rem + var(--spec-inset) - 1.875rem);
    padding-inline-end: var(--spec-inset);
}

section.spec-scroll .spec-scroll-caption {
    color: var(--accent);
}

section.spec-scroll .spec-scroll-figure {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

section.spec-scroll .spec-scroll-value {
    display: flex;
    align-items: flex-end;
    gap: 0.5rem;
    color: var(--on-surface);
}

section.spec-scroll .spec-scroll-unit {
    font-family: var(--ff-primary);
    font-weight: 400;
    font-size: 0.9375rem;
    line-height: 1.1;
    letter-spacing: -0.01em;
    padding-block-end: 0.3125rem;
}

section.spec-scroll .spec-scroll-desc {
    font-family: var(--ff-primary);
    font-weight: 400;
    font-size: 0.9375rem;
    line-height: 1.1;
    letter-spacing: -0.01em;
    color: var(--spec-muted);
}

/* ---- right-edge fade + next control ---- */
/* the chrome (fades + arrows) is shared with the statement info row when it has to
   become a scroller (see "STATEMENT INFO ROW — scroller fallback"), so these rules are
   scoped to both hosts and read their colour from --spec-fade instead of a literal */

:is(section.spec-scroll, .statement-info) .spec-scroll-fade {
    position: absolute;
    inset-block: 0;
    inset-inline-end: 0;
    inline-size: 20.875rem;
    pointer-events: none;
    background: linear-gradient(90deg, rgb(from var(--spec-fade) r g b / 0) 0%, var(--spec-fade) 70%);
    transition: opacity 0.3s ease;
}

/* mirror fade behind the prev arrow (scrolling back) */
:is(section.spec-scroll, .statement-info) .spec-scroll-fade-start {
    inset-inline: 0 auto;
    background: linear-gradient(270deg, rgb(from var(--spec-fade) r g b / 0) 0%, var(--spec-fade) 70%);
}

:is(section.spec-scroll, .statement-info) .spec-scroll-fade[hidden] {
    display: block;
    opacity: 0;
}

:is(section.spec-scroll, .statement-info) .spec-scroll-controls {
    position: absolute;
    inset-block: 0;
    inset-inline: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-inline: var(--container-x-padding);
    pointer-events: none;
}

:is(section.spec-scroll, .statement-info) .spec-scroll-arrow {
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2.5rem;
    block-size: 2.5rem;
    flex: none;
    border: 2px solid var(--on-surface);
    border-radius: 50%;
    color: var(--on-surface);
    transition:
        color 0.2s ease,
        background-color 0.2s ease,
        opacity 0.2s ease;
}

:is(section.spec-scroll, .statement-info) .spec-scroll-arrow svg {
    inline-size: 0.375rem;
    block-size: 0.625rem;
}

:is(section.spec-scroll, .statement-info) .spec-scroll-arrow[data-spec-scroll-prev] svg {
    transform: rotate(180deg);
}

:is(section.spec-scroll, .statement-info) .spec-scroll-arrow:is(:hover, :focus-visible) {
    background-color: var(--on-surface);
    color: var(--surface);
}

/* keep the arrow's box (no flex shift) and fade it out via opacity */
:is(section.spec-scroll, .statement-info) .spec-scroll-arrow[hidden] {
    display: inline-flex;
    opacity: 0;
    pointer-events: none;
}

/* SPEC-SCROLL — mobile */
@media (max-width: 768px) {
    section.spec-scroll {
        /* the track is full-bleed and every cell pads itself, so the desktop
           edge-inset computation is not used any more */
        --spec-inset: var(--container-x-padding);

        padding-block-end: 3.75rem;
    }

    section.spec-scroll .spec-scroll-heading {
        gap: 1.875rem;
        padding-block: 5.625rem 2.5rem;
    }

    section.spec-scroll .spec-scroll-title {
        font-size: 2.0625rem;
    }

    /* ---- scroller: horizontal pages of 4 stacked cells ---- */

    section.spec-scroll .spec-scroll-track {
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: 100%;
        grid-template-rows: repeat(4, auto);
        scroll-snap-type: x mandatory;
        overscroll-behavior-inline: contain;
    }

    section.spec-scroll .spec-scroll-cell,
    section.spec-scroll .spec-scroll-cell:first-child,
    section.spec-scroll .spec-scroll-cell:last-child {
        inline-size: auto;
        min-inline-size: 0;
        padding-inline: var(--container-x-padding);
        border-block: none;
        border-inline-end: none;
        border-block-start: 1px solid var(--spec-border);
    }

    /* close the bottom of each page (and of a short final page) */
    section.spec-scroll .spec-scroll-cell:nth-child(4n),
    section.spec-scroll .spec-scroll-cell:last-child {
        border-block-end: 1px solid var(--spec-border);
    }

    /* no edge gradients on mobile — the stack is paged, not free-scrolled */
    section.spec-scroll .spec-scroll-fade,
    section.spec-scroll .spec-scroll-fade[hidden] {
        display: none;
    }

    /* ---- controls: page counter + arrow, in flow under the stack ---- */

    section.spec-scroll .spec-scroll-controls {
        position: static;
        justify-content: flex-start;
        padding-inline: var(--container-x-padding);
        margin-block-start: 1.25rem;
        pointer-events: auto;
    }

    section.spec-scroll .spec-scroll-counter {
        margin-inline-end: auto;
        color: var(--on-surface);
    }

    section.spec-scroll .spec-scroll-next {
        margin-inline-start: 0.625rem;
    }

    /* the inactive arrow keeps its box on desktop; on mobile it collapses so the
       active one always sits on the container edge (opacity + pointer-events stay) */
    /* no animation: the arrow is simply there or not. The counter's `margin-inline-end: auto`
       keeps the remaining arrow pinned to the container edge, so nothing shifts. */
    section.spec-scroll .spec-scroll-arrow[hidden] {
        display: none;
    }
}


/* ======================================== */
/* PROOF */
/* ======================================== */

/* ======================================== */
/* PROOF (Block 4 - sea trials banner) */
/* ======================================== */

section.proof {
    position: relative;
    /* the gap of the copy column — it also drives its reveal (see `data-reveal-group="gap"`),
       and the red card follows the last of its four children, 1.5 gaps above its place */
    --proof-gap: 2.5rem;
    --proof-quote-rise: calc(-1.5 * var(--proof-gap) * var(--reveal-collapse));
}

section.proof .layer-fg {
    padding-block: 15.8125rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

section.proof .proof-container {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 2.5rem;
}

section.proof .layer-bg::after {
    background: linear-gradient(180deg, rgb(5 25 43) 0%, rgb(5 25 43 / 0) 25.65%), linear-gradient(269.3deg, rgb(0 0 0 / 0) 0.4%, rgb(0 0 0 / 0.2) 44.75%, rgb(0 0 0 / 0.6) 99.58%);
}

section.proof .proof-container {
    position: relative;
}

section.proof .proof-content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    --reveal-gap: var(--proof-gap);
    gap: var(--reveal-gap);
    max-inline-size: 31.5625rem;
    color: var(--c-white);
}

section.proof .proof-eyebrow {
    line-height: 1;
}

section.proof .proof-eyebrow-title {
    color: var(--c-red);
}

section.proof .proof-eyebrow-location {
    color: var(--c-white);
}

section.proof .proof-title {
    inline-size: 100%;
    color: var(--c-white);
}

section.proof .proof-text {
    inline-size: 100%;
    color: var(--c-white);
}

/* Red pull-quote card, sits in flow at the end of the content row */
section.proof .proof-quote {
    /* it rides with the last child of .proof-content — see `data-reveal-group="rise"` */
    --reveal-rise: var(--proof-quote-rise);
    flex: none;
    inline-size: 19.125rem;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    padding: 0.3125rem;
    background-color: var(--c-red);
    color: var(--c-white);
}

section.proof .proof-quote-text {
    font-family: var(--ff-secondary);
    font-weight: 600;
    font-style: italic;
    font-size: 1.5625rem;
    line-height: 1;
    letter-spacing: -0.03em;
}

section.proof .proof-quote-author {
    line-height: 1;
}

@media (max-width: 1024px) {
    section.proof .layer-fg {
        padding-block: 6rem;
    }

    section.proof .proof-container {
        flex-direction: column;
        align-items: flex-start;
        gap: 3.125rem;
    }

    section.proof .proof-content {
        max-inline-size: none;
    }

    section.proof .proof-quote {
        inline-size: 100%;
        max-inline-size: 19.125rem;
    }
}

/* PROOF — mobile */
@media (max-width: 768px) {
    /* The stacked desktop layer cake is un-stacked: the copy sits on the page
       gradient, the photo becomes a tall block below it, and the red quote card
       overlaps the top of the photo. `display: contents` promotes .proof-content
       and .proof-quote to grid items of .layers so they can be placed independently. */
    section.proof {
        padding-block: 3.75rem 0;
        --proof-gap: 1.875rem;
    }

    section.proof .layers {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto auto;
        row-gap: 3.75rem;
    }

    section.proof .layers > .layer.layer-fg {
        display: contents;
    }

    section.proof .proof-container {
        display: contents;
    }

    section.proof .proof-content {
        grid-row: 1;
        grid-column: 1;
        inline-size: 100%;
        max-inline-size: none;
        padding-inline: var(--container-x-padding);
    }

    /* the mobile frame (165:1733) has no button — pretitle, title and copy only */
    section.proof .proof-cta {
        display: none;
    }

    /* Photo block: row 2, portrait 375x800 ratio from the mobile artboard, capped at 800px. */
    section.proof .layers > .layer.layer-bg {
        grid-row: 2;
        grid-column: 1;
        block-size: min(50rem, 213vw);
    }

    /* Red pull-quote: overlaps the top of the photo, full container width. */
    section.proof .proof-quote {
        grid-row: 2;
        grid-column: 1;
        align-self: start;
        position: relative;
        z-index: 1;
        inline-size: auto;
        max-inline-size: 26.25rem;
        margin-block-start: 1.875rem;
        margin-inline: var(--container-x-padding);
    }
}

/* ======================================== */
/* RULES */
/* ======================================== */

/* ======================================== */
/* RULES (One design & rules) */
/* ======================================== */

section.rules {
    position: relative;
    overflow: hidden;
    padding-block-start: 6.25rem; /* 100 - bottom padding lives on .rules-media-fg */
}

/* --- Top: heading --- */

section.rules .rules-heading {
    display: flex;
    flex-direction: column;
    gap: 3.125rem;
}

section.rules .rules-pretitle {
    color: var(--accent);
}

section.rules .rules-title {
    color: var(--on-surface);
}

/* --- Media: image (col 1) + intro (col 2) + cards carousel below --- */

section.rules .rules-media {
    margin-block-start: 6.25rem;
    /* keep the single layers track at the container width so the carousel's
       intrinsic width can't stretch it (cards bleed via overflow instead) */
    grid-template-columns: minmax(0, 1fr);
}

/* foreground grid: image in col 1, intro paragraph in col 2 */
section.rules .rules-media-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--container-gap);
    align-items: start;
    block-size: 100%;
}

section.rules .rules-media-img {
    /* it drifts in from a little below and a little to the inline-start */
    --reveal-shift-x: -2.5rem;
    --reveal-shift: 2.5rem;
    grid-column: 1;
    block-size: 100%;
    inline-size: calc(100% - var(--container-x-padding) - var(--container-column-width));
}

/* layer-fg: image/intro grid, then carousel, stacked; bottom padding lives here */
section.rules .rules-media-fg {
    display: flex;
    flex-direction: column;
    gap: 8.75rem; /* 140px */
    padding-block-end: 12.9375rem; /* 207 */
}

section.rules .rules-intro {
    /* it is not a sibling of the heading, but it comes in as the third beat of that chain */
    --reveal-i: 2;
    grid-column: 2;
    max-inline-size: 25rem; /* 400px */
    color: var(--grey-text);
}

/* carousel: sits in a .container, bleeds past it (clipped by the section) */
section.rules .rules-carousel {
    inline-size: 100%;
    overflow: visible;
}

/* ---- drag cursor ---- */

/* the native cursor is replaced by the red 82px puck only once JS has hooked it up
   (and only on a fine pointer), so a touch device never loses its cursor */
.has-drag-cursor {
    cursor: none;
}

.drag-cursor {
    display: block;
    position: fixed;
    inset-block-start: 0;
    inset-inline-start: 0;
    inline-size: 5.125rem;
    block-size: 5.125rem;
    /* half its own size, so the puck is centred on the pointer */
    margin-block-start: -2.5625rem;
    margin-inline-start: -2.5625rem;
    z-index: var(--z-header);
    pointer-events: none;
    opacity: 0;
    scale: 0.4;
    transition:
        opacity 0.25s var(--reveal-ease),
        scale 0.25s var(--reveal-ease);
}

.drag-cursor.is-visible {
    opacity: 1;
    scale: 1;
}

.drag-cursor svg {
    display: block;
    inline-size: 100%;
    block-size: auto;
}

section.rules .rules-card {
    inline-size: 22.5625rem;
    min-block-size: 15.3125rem;
    block-size: auto;
    flex: none;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    padding: 1.875rem;
    overflow: clip;
    background-color: rgb(236 236 236 / 0.8);
    backdrop-filter: blur(0.78125rem);
}

section.rules .rules-card-label {
    color: var(--accent);
}

section.rules .rules-card-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 1.25rem;
}

section.rules .rules-card-title {
    color: var(--on-surface);
}

section.rules .rules-card-text {
    color: var(--grey-text);
}

/* RULES — mobile */
@media (max-width: 768px) {
    section.rules {
        padding-block: 5.625rem; /* 90 top + 90 bottom (desktop keeps the bottom padding on .rules-media-fg, which is display:contents here) */
    }

    /* --- Heading: pretitle + title, 30px rhythm --- */

    section.rules .rules-heading {
        gap: 1.875rem; /* 30 */
    }

    /* --- Unstack the layers: intro, then full-bleed image, then carousel --- */

    section.rules .rules-media {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        row-gap: 3.125rem; /* 50 */
        margin-block-start: 1.875rem; /* 30 — the intro keeps the heading rhythm */
    }

    /* the foreground layer stops being a box so its two children can be placed
       around the image in the same grid (intro above it, carousel below it) */
    section.rules .rules-media > .layer.layer-fg {
        display: contents;
    }

    section.rules .rules-media-fg > .rules-media-grid {
        grid-row: 1;
        grid-column: 1;
        padding-inline: var(--container-x-padding);
    }

    section.rules .rules-media > .layer.layer-bg {
        grid-row: 2;
        grid-column: 1;
    }

    section.rules .rules-carousel {
        grid-row: 3;
        grid-column: 1;
        padding-inline: var(--container-x-padding);
    }

    /* --- Media: edge-to-edge, no container inset --- */

    section.rules .rules-media-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    section.rules .rules-media-img {
        grid-column: 1;
        inline-size: 100%;
        block-size: clamp(18rem, 120vw, 28.25rem); /* 452 at 375 wide */
    }

    section.rules .rules-intro {
        grid-column: auto;
        max-inline-size: none;
    }

    /* --- Cards --- */

    section.rules .rules-card {
        inline-size: 16.5625rem; /* 265 */
        min-block-size: 0;
        gap: 1.25rem;
        padding-block: 1.25rem; /* 20 */
        padding-inline: 1.5625rem; /* 25 */
    }

    section.rules .rules-card-title {
        font-size: 1.6875rem; /* 27 */
    }
}


/* ======================================== */
/* CIRCUIT */
/* ======================================== */

/* ======================================== */
/* CIRCUIT (Block 6 - The Mediterranean circuit) */
/* ======================================== */

section.circuit {
    position: relative;
    overflow: hidden;
    background: linear-gradient(180deg, #03101c 0%, #051626 100%);
    color: var(--c-white);
}

section.circuit .circuit-deco {
    /* mirror of the intro arc, on the opposite side of the page, so it turns the other way */
    --reveal-turn: 13deg;
    rotate: var(--reveal-turn);
    position: absolute;
    z-index: 0;
    inset-block-start: 3.9375rem;
    inset-inline-end: -29.625rem;
    inline-size: 50.875rem;
    block-size: 50.75rem;
    pointer-events: none;
}

section.circuit .circuit-deco svg {
    display: block;
    inline-size: 100%;
    block-size: 100%;
}

section.circuit .circuit-head,
section.circuit .circuit-rows,
section.circuit .circuit-foot {
    position: relative;
    z-index: 1;
}

section.circuit .circuit-head {
    display: flex;
    flex-direction: column;
    gap: 3.125rem;
    padding-block: 9.375rem 3.75rem;
}

section.circuit .circuit-pretitle {
    color: var(--c-red);
}

section.circuit .circuit-head-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 2.5rem;
}

section.circuit .circuit-title {
    /* barely there, and from above rather than from below */
    --reveal-shift: -0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    color: var(--c-white);
}

section.circuit .circuit-title-outline {
    font-style: italic;
    text-transform: uppercase;
    -webkit-text-fill-color: transparent;
    -webkit-text-stroke: 2px var(--on-surface);
}

section.circuit .circuit-lead {
    flex: none;
    max-inline-size: 18.375rem;
    color: #828a92;
}

section.circuit .circuit-lead strong {
    font-weight: inherit;
    color: var(--c-white);
}

/* Rows */

section.circuit .circuit-row-inner {
    display: flex;
    align-items: flex-start;
    gap: 1.25rem;
    padding-block: 1.875rem;
}

/* Separators: one above every row plus one under the last, so the list is closed at both
   ends. They are pseudo-elements rather than borders because each one wipes in from the
   inline-start as its own row is scrolled into (see `data-reveal-self`). */
section.circuit .circuit-row {
    position: relative;
}

section.circuit .circuit-row::before,
section.circuit .circuit-row:last-child::after {
    content: "";
    position: absolute;
    z-index: 1;
    inset-inline: 0;
    block-size: 1px;
    background-color: #2c4154;
}

section.circuit .circuit-row::before {
    inset-block-start: 0;
}

section.circuit .circuit-row:last-child::after {
    inset-block-end: 0;
}

/* the list starts tighter than it will be and settles as you scroll to it — the rows are
   pulled towards the middle of the list by their own padding, nothing else moves */
section.circuit .circuit-rows {
    --reveal-gap: 1.875rem;
    /* lighter than the proof block: the rows barely draw together */
    --reveal-collapse: 0.2;
}

section.circuit .circuit-row-num {
    flex: none;
    inline-size: 1.875rem;
    padding-block-start: 0.1875rem;
    color: var(--c-red);
}

section.circuit .circuit-row-body {
    flex: 1 1 0;
    min-inline-size: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3125rem;
}

section.circuit .circuit-row-title {
    color: var(--c-white);
}

section.circuit .circuit-row-location {
    color: var(--c-white);
    opacity: 0.6;
}

section.circuit .circuit-row-badge {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    block-size: 1.25rem;
    padding-inline: 0.5rem;
    margin-block-start: 0.375rem;
    background-color: var(--c-red);
    color: var(--c-white);
    font-family: var(--ff-primary);
    font-weight: 500;
    font-size: 0.8125rem;
    line-height: 1.4;
    letter-spacing: -0.01em;
    text-transform: uppercase;
    white-space: nowrap;
}

section.circuit .circuit-row-date {
    flex: none;
    margin-block-start: 0.375rem;
    font-family: var(--ff-secondary);
    font-weight: 600;
    font-size: 1.125rem;
    line-height: 1.1;
    letter-spacing: -0.03em;
    color: var(--c-white);
    white-space: nowrap;
}

/* Foot */

section.circuit .circuit-foot {
    padding-block: 3.75rem 7.5rem;
}

/* CIRCUIT — mobile */
@media (max-width: 768px) {
    section.circuit {
        padding-block-end: 5.625rem;
    }

    /* the deco vector sits fully off-frame in the mobile design */
    section.circuit .circuit-deco {
        display: none;
    }

    /* Head */

    section.circuit .circuit-head {
        gap: 1.875rem;
        padding-block: 5.625rem 3.75rem;
    }

    section.circuit .circuit-head-row {
        flex-direction: column;
        align-items: stretch;
        gap: 1.875rem;
    }

    section.circuit .circuit-title {
        gap: 0.3125rem;
    }

    /* "THE MEDITERRANEAN" is one 426px word at the mobile display size and would be clipped by
       the section's overflow: hidden. The break itself comes from a soft hyphen (U+00AD) in the
       ACF value, matching Figma's "MEDITER-RANEAN"; hyphens: auto is unreliable (Chrome needs a
       hyphenation dictionary). This is only the safety net for any other long word. */
    section.circuit .circuit-title-solid {
        overflow-wrap: break-word;
    }

    section.circuit .circuit-lead {
        max-inline-size: none;
    }

    /* Rows: stacked (number / title + location / date + badge), full-bleed separators */

    section.circuit .circuit-row-inner {
        display: flex;
        flex-wrap: wrap;
        align-items: flex-start;
        gap: 1.25rem 0.625rem;
        padding-block: 1.25rem;
    }

    section.circuit .circuit-row-num {
        flex: 0 0 100%;
        inline-size: auto;
        padding-block-start: 0.1875rem;
    }

    section.circuit .circuit-row-body {
        flex: 0 0 100%;
        gap: 0.3125rem;
    }

    section.circuit .circuit-row-location {
        line-height: 1.4;
        letter-spacing: -0.01em;
    }

    /* the date comes before the badge on mobile (DOM order is badge → date) */
    section.circuit .circuit-row-date {
        order: 1;
        margin-block-start: 0;
    }

    section.circuit .circuit-row-badge {
        order: 2;
        block-size: 1.5rem;
        padding-block-start: 0.125rem;
        padding-inline: 0.5rem;
        margin-block-start: 0;
        border-radius: 6.25rem;
    }

    /* the mobile frame (167:2422) ends with the venue rows — no CTA */
    section.circuit .circuit-foot {
        display: none;
    }

    /* the outline word is drawn at 1px on mobile (2px only on the desktop display size) */
    section.circuit .circuit-title-outline {
        -webkit-text-stroke-width: 1px;
        text-stroke-width: 1px;
    }
}


/* ======================================== */
/* STATEMENT */
/* ======================================== */

/* ======================================== */
/* STATEMENT (unified text-info family)      */
/* Serves: section-after-hero (.text-info),  */
/* Block 2 heading, Block 7 (1833), Block 9 (787) */
/* ======================================== */

section.statement {
    position: relative;
    display: flex;
    flex-direction: column;

    /* edge padding of the design (100px), not the container grid */
    --statement-px: 6.25rem;
    /* muted text/label color, flips with the theme */
    --statement-muted: var(--grey-text);
    --statement-border: rgb(from var(--on-surface) r g b / 0.1);
    --statement-pt: 3.75rem; /* 60px */
    --statement-gap: 3.125rem; /* 50px between head and info */
}

section.statement[data-theme="dark"] {
    --statement-muted: rgb(255 255 255 / 0.6);
}

/* --- with background media (Block 7): content over .layers --- */

section.statement.has-media {
    --statement-pt: 7.5rem; /* 120px */
    --statement-gap: 6.25rem; /* 100px */
    overflow: hidden;
}

/* the background frame eases in (see `data-reveal="media"`) */
section.statement.has-media .layer-bg .img-wrapper {
    --reveal-media-scale: 1.1;
    --reveal-shift: 1.875rem;
}

section.statement.has-media .layer-fg {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: var(--statement-gap);
    padding-block-start: var(--statement-pt);
    min-block-size: 100%;
}

/* --- without media (Block 9): plain stacked section --- */

section.statement:not(.has-media) {
    gap: var(--statement-gap);
    padding-block-start: var(--statement-pt);
}

/* ======================================== */
/* HEAD (pretitle + title + text)            */
/* ======================================== */

/* head + info are each their own .container (like .text-info) so they stay
   contained on wide screens instead of bleeding to the page edge */
section.statement .statement-head {
    display: flex;
    flex-direction: column;
    /* it opens from its own gap — see `data-reveal-group="gap"` */
    --reveal-gap: 2.5rem; /* 40px */
    gap: var(--reveal-gap);
}

section.statement.has-media .statement-title,
section.statement.has-media .statement-pretitle {
    max-inline-size: 44.625rem; /* 714px - keeps the boat headline on the left */
}

section.statement .statement-pretitle {
    color: var(--accent);
}

section.statement .statement-title {
    text-wrap: balance;
}

section.statement .statement-text {
    max-inline-size: 38.375rem; /* keeps the paragraph measure of Block 7 */
    color: var(--on-surface);
}

section.statement.has-media .statement-head,
section.statement.has-media .statement-title,
section.statement.has-media .statement-text {
    color: var(--c-white);
}

/* ======================================== */
/* INFO ROW - bordered variant (Block 7/9)   */
/* ======================================== */

section.statement.info-bordered .info-row {
    display: flex;
    align-items: stretch;
}

/* blur band + top rule run the FULL section width (on .statement-info),
   the cells stay contained inside the .container info-row */
section.statement.info-bordered .statement-info {
    border-block-start: 1px solid var(--statement-border);
}

section.statement.has-media.info-bordered .statement-info {
    backdrop-filter: blur(5px);
    background-color: rgb(5 22 38 / 0.2);
}

section.statement.info-bordered .info-col {
    flex: 0 0 15.5rem; /* 248px middle cells */
    min-inline-size: 0;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 0.125rem; /* 20px */
    padding-block: 1.25rem;
    padding-inline: 1.875rem; /* 30px */
    border-block-end: 1px solid var(--statement-border);
}

section.statement.info-bordered .info-col + .info-col {
    border-inline-start: 1px solid var(--statement-border);
}

/* first / last cells stretch and bleed to the page edge */
section.statement.info-bordered .info-col:first-child,
section.statement.info-bordered .info-col:last-child {
    flex: 1 1 0;
}

section.statement.info-bordered .info-col:first-child {
    padding-inline-start: 0;
}

section.statement.info-bordered .info-col:last-child {
    padding-inline-end: 0;
}

/* ---------------------------------------- */
/* INFO ROW — scroller fallback              */
/* ---------------------------------------- */
/* The cells are sized by the design (248px) and their copy is client-editable: a long
   unbreakable string (an e-mail address) is wider than the cell and spills across the next
   divider. `initInfoScroller` (js/main.js) measures that at runtime and, ONLY when it
   happens, turns the row into a spec-scroll-style track: every cell the same content width,
   wide enough for the longest word, with the spec-scroll fades and arrows. Desktop only —
   below 769px the cells already stack full-bleed and nothing can overflow. */

section.statement .statement-info.is-scroller {
    /* same container inner-edge inset as section.spec-scroll */
    --spec-inset: max(var(--container-x-padding), calc((100vw - 81.5rem) / 2 + var(--container-x-padding)));
    --spec-fade: var(--surface);

    position: relative;
    min-inline-size: 0;
}

/* the .layers grid track is auto-sized, so the intrinsically wide track would stretch the
   whole layer past the section instead of scrolling inside it (see the .layers gotcha) */
section.statement.has-media:has(.statement-info.is-scroller) .layers {
    grid-template-columns: minmax(0, 1fr);
}

section.statement.has-media:has(.statement-info.is-scroller) .layer-fg {
    min-inline-size: 0;
}

/* the chrome is injected once and stays: it must disappear when a wider window (or an
   edited text) drops the row back to the plain flex layout */
section.statement .statement-info:not(.is-scroller) :is(.spec-scroll-fade, .spec-scroll-controls) {
    display: none;
}

section.statement.has-media .statement-info.is-scroller {
    /* over the media there is no solid surface to fade into: match the band's own tint */
    --spec-fade: rgb(5 22 38 / 0.9);
}

/* the track bleeds full width (the .container constraints are dropped) and scrolls; the top
   border and the blur stay on .statement-info, so they still run the whole section width */
section.statement.info-bordered .statement-info.is-scroller .info-row {
    inline-size: 100%;
    max-inline-size: none;
    margin-inline: 0;
    padding-inline: 0;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

section.statement .statement-info.is-scroller .info-row::-webkit-scrollbar {
    display: none;
}

/* every cell the same width — --info-col-size is measured by the JS */
section.statement.info-bordered .statement-info.is-scroller .info-col {
    flex: none;
    inline-size: var(--info-col-size);
    scroll-snap-align: start;
}

/* first / last cell keep their content on the container edge while the track bleeds past it;
   the extra box width is exactly the extra padding, so the CONTENT width stays identical */
section.statement.info-bordered .statement-info.is-scroller .info-col:first-child {
    inline-size: calc(var(--info-col-size) + var(--spec-inset) - 1.875rem);
    padding-inline-start: var(--spec-inset);
}

section.statement.info-bordered .statement-info.is-scroller .info-col:last-child {
    inline-size: calc(var(--info-col-size) + var(--spec-inset) - 1.875rem);
    padding-inline-end: var(--spec-inset);
}

/* info cell contents */
section.statement .info-col-head {
    display: flex;
    flex-direction: column;
    gap: 1.25rem; /* 20px */
}

section.statement .info-label {
    color: var(--accent);
}

section.statement .info-title {
    min-block-size: 2lh;
    font-family: var(--ff-secondary);
    font-weight: 600;
    font-size: 1.125rem; /* 18px - no utility exists at this size */
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--on-surface);
}

/* no font-family override: Figma sets these cells in Aktiv Grotesk Regular, which is what the
   element's own .fs-body gives. The old --ff-quaternary (Aptos) is narrower and cost a line. */
section.statement .info-text {
    color: var(--statement-muted);
}

section.statement .info-col.is-muted .info-title {
    color: var(--statement-muted);
}

section.statement.has-media .info-title {
    color: var(--c-white);
}

/* ======================================== */
/* INFO ROW - divider variant (.text-info)   */
/* mirrors the existing section-after-hero;  */
/* main agent reconciles with intro.php CSS  */
/* ======================================== */

section.statement.info-divider .statement-head {
    align-items: center;
    text-align: center;
    margin-inline: auto;
    max-inline-size: 46.875rem;
    padding-block: 6.25rem;
    padding-inline: var(--container-x-padding);
}

section.statement.is-centered .statement-title {
    font-weight: 500; /* text-info uses the medium weight */
}

section.statement.info-divider .info-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    max-inline-size: calc((var(--container-x-padding) * 2) + (7 * var(--container-gap)) + (8 * var(--container-column-width)));
    margin-inline: auto;
    inline-size: 100%;
    padding-inline: var(--container-x-padding);
    border-block-start: 1px solid var(--statement-border);
}

section.statement.info-divider .info-col {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 2.125rem;
    padding-block: 1.25rem;
    padding-inline: 1.875rem;
}

section.statement.info-divider .info-col + .info-col {
    border-inline-start: 1px solid var(--statement-border);
}

section.statement.info-divider .info-col:first-child {
    padding-inline-start: 0;
}

section.statement.info-divider .info-col:last-child {
    padding-inline-end: 0;
}

/* deco arc (centered variant only) */
section.statement .deco {
    position: absolute;
    z-index: 0;
    inset-block-start: 3.9375rem;
    inset-inline-start: -31.4375rem;
    inline-size: 50.875rem;
    block-size: 50.75rem;
    pointer-events: none;
    transform: scaleX(-1);
}

section.statement .deco svg {
    display: block;
    inline-size: 100%;
    block-size: 100%;
}

section.statement.is-centered .statement-head,
section.statement.is-centered .info-row {
    position: relative;
    z-index: 1;
}

/* ======================================== */
/* RESPONSIVE                                */
/* ======================================== */

/* STATEMENT (both variants) — mobile */
@media (max-width: 768px) {
    section.statement {
        --statement-px: var(--container-x-padding);
    }

    /* --- info row: cells stack full-bleed (shared by both variants) --- */

    section.statement.info-bordered .info-row {
        flex-direction: column;
        flex-wrap: nowrap;
        align-items: stretch;
        padding-inline: 0;
    }

    section.statement.info-bordered .info-col,
    section.statement.info-bordered .info-col:first-child,
    section.statement.info-bordered .info-col:last-child {
        flex: 0 0 auto;
        padding-block: 1.25rem;
        padding-inline: var(--container-x-padding);
    }

    section.statement.info-bordered .info-col + .info-col {
        border-inline-start: none;
    }

    /* --- divider variant (unchanged from the previous mobile block) --- */

    section.statement.info-divider .info-row {
        grid-template-columns: 1fr 1fr;
    }

    section.statement.info-divider .info-col:nth-child(odd) {
        padding-inline-start: 0;
        border-inline-start: none;
    }

    section.statement.info-divider .info-col:nth-child(even) {
        padding-inline-end: 0;
    }

    /* ---------------------------------------- */
    /* has-media variant (home_boat)             */
    /* ---------------------------------------- */

    section.statement.has-media {
        /* the image band is a fixed-height "hero" block on mobile (Figma: 800px);
           the same value drives the head min-height and the background layer so
           the image stops exactly where the head ends */
        --statement-media-block: 50rem; /* 800px */
        --statement-pt: 7.5rem; /* 120px */
        --statement-gap: 0rem;
    }

    /* --- foreground column: head band, then the full-width info band --- */

    section.statement.has-media .layer-fg {
        justify-content: flex-start;
        gap: var(--statement-gap);
        padding-block-start: 0;
        min-block-size: 0;
    }

    section.statement.has-media .statement-head {
        min-block-size: var(--statement-media-block);
        justify-content: flex-end;
        gap: 2.5rem; /* 40px */
        padding-block: var(--statement-pt) 3.75rem; /* 120px / 60px */
    }

    section.statement.has-media .statement-title,
    section.statement.has-media .statement-pretitle,
    section.statement.has-media .statement-text {
        max-inline-size: none;
    }

    /* --- background image: only behind the head band, fading into the page --- */

    section.statement.has-media .layer-bg {
        align-self: start;
        block-size: var(--statement-media-block);
        -webkit-mask-image: linear-gradient(180deg, rgb(0 0 0 / 1) 0%, rgb(0 0 0 / 1) 72%, rgb(0 0 0 / 0) 100%);
        mask-image: linear-gradient(180deg, rgb(0 0 0 / 1) 0%, rgb(0 0 0 / 1) 72%, rgb(0 0 0 / 0) 100%);
    }

    /* darkening ramp so the headline stays legible over the sail (Figma overlay) */
    section.statement.has-media .layer-bg::after {
        background-image: linear-gradient(180deg, rgb(0 0 0 / 0) 0%, rgb(0 0 0 / 0.3) 45%, rgb(0 0 0 / 0.65) 100%);
    }

    section.statement.has-media.info-bordered .info-col,
    section.statement.has-media.info-bordered .info-col:first-child,
    section.statement.has-media.info-bordered .info-col:last-child {
        flex: 0 0 auto;
        min-block-size: 9.375rem; /* 150px */
        gap: 1.25rem; /* 20px */
        padding-block: 1.25rem; /* 20px */
        padding-inline: var(--container-x-padding);
    }

    section.statement.has-media .info-title {
        min-block-size: 0;
    }

    /* ---------------------------------------- */
    /* no-media variant (home_network)           */
    /* ---------------------------------------- */

    /* section: 60px top / 90px bottom, 50px between head and info band (Figma 167:2966).
       --statement-pt (3.75rem) and --statement-gap (3.125rem) already match, only the
       bottom padding is new on mobile */
    section.statement:not(.has-media) {
        padding-block-end: 5.625rem; /* 90px */
    }

    /* ---------------------------------------- */
    /* HEAD                                      */
    /* ---------------------------------------- */

    section.statement:not(.has-media) .statement-title {
        font-size: 2.0625rem; /* 33px */
        text-wrap: initial; /* balance would leave a 1-word last line on 315px */
    }

    /* ---------------------------------------- */
    /* INFO ROW — one full-bleed cell per row    */
    /* ---------------------------------------- */

    section.statement:not(.has-media).info-bordered .info-col,
    section.statement:not(.has-media).info-bordered .info-col:first-child,
    section.statement:not(.has-media).info-bordered .info-col:last-child {
        flex: 0 0 auto;
        min-block-size: 8.125rem; /* 130px */
        padding-block: 1.25rem; /* 20px */
        padding-inline: var(--container-x-padding);
    }

    section.statement:not(.has-media) .info-text {
        line-height: 1.2;
    }
}


/* ======================================== */
/* PARTNERS */
/* ======================================== */

/* ======================================== */
/* PARTNERS (Block 11) */
/* ======================================== */

section.partners {
    /* full-bleed strip start aligned to the .container inner edge */
    --partners-gutter: max(var(--container-x-padding), calc((100% - 81.5rem) / 2 + var(--container-x-padding)));
    padding-block: 7.5rem;
    overflow: hidden;
}

section.partners .partners-top {
    display: flex;
    flex-direction: column;
    gap: 4.375rem; /* 70px between heading block and tabs */
    margin-block-end: 5rem; /* 80px to the logo strip */
}

section.partners .partners-heading {
    display: flex;
    flex-direction: column;
    gap: 3.125rem; /* 50px between pretitle and title */
}

section.partners .partners-pretitle {
    color: var(--accent);
}

section.partners .partners-title {
    text-transform: uppercase;
    color: var(--on-surface);
}

section.partners .partners-title-line {
    display: block;
}

/* outlined italic word - CSS text-stroke, not an SVG */
section.partners .partners-title-outline {
    font-style: italic;
    -webkit-text-fill-color: transparent;
    -webkit-text-stroke: 2px var(--on-surface);
    text-stroke: 2px var(--on-surface);
}

/* ---- filter tabs ---- */

section.partners .partners-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
}

section.partners .partners-tab {
    font-family: var(--ff-primary);
    font-weight: 500;
    font-size: 1rem;
    line-height: 1.4;
    letter-spacing: -0.01em;
    color: var(--on-surface);
    /* figma pad (10/7 block, 20 inline) minus the 1px border it shares */
    padding-block: 0.5625rem 0.375rem;
    padding-inline: 1.1875rem;
    border: 1px solid #d9d9d9;
    border-radius: 6.25rem;
    background-color: rgb(255 255 255 / 0.01);
    backdrop-filter: blur(2px);
    transition:
        background-color 0.2s ease,
        border-color 0.2s ease;
}

section.partners .partners-tab:is(:hover, :focus-visible) {
    border-color: var(--on-surface);
}

section.partners .partners-tab.is-active {
    background-color: rgb(236 236 236 / 0.8);
    border-color: transparent;
}

/* ---- logo strip / carousel ---- */

section.partners .partners-strip {
    inline-size: 100%;
    /* Sits in a .container; overflow visible lets the strip bleed past the
       container to the right, clipped by the section's overflow: hidden. */
    overflow: visible;
}

section.partners .partners-strip .swiper-wrapper {
    align-items: stretch;
}

section.partners .partners-cell {
    inline-size: 10.3125rem; /* 165px = 125 logo + 20 pad each side */
    block-size: auto;
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.625rem;
    padding-block: 0.625rem 1.25rem;
    padding-inline: 1.25rem;
    background-color: rgb(244 244 244 / 0.8);
    border-radius: 0.3125rem;
}

section.partners .partners-cell[hidden] {
    display: none;
}

section.partners .partners-logo {
    inline-size: 7.8125rem; /* 125px */
    block-size: 5rem; /* 80px */
    display: flex;
    align-items: center;
    justify-content: center;
}

section.partners .partners-logo-img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: contain;
    /* blend white logo boxes into the grey cell */
    mix-blend-mode: darken;
}

section.partners .partners-cell-label {
    color: var(--grey-text);
    text-align: center;
}

/* PARTNERS — mobile */
@media (max-width: 768px) {
    section.partners {
        padding-block: 5rem; /* 80px */
    }

    section.partners .partners-top {
        gap: 3.125rem; /* 50px heading block -> tabs */
        margin-block-end: 3.125rem; /* 50px tabs -> logo strip */
    }

    section.partners .partners-heading {
        gap: 3.125rem; /* 50px pretitle -> title */
    }

    /* the two title lines are 5px apart in Figma; line-height alone can't express it */
    section.partners .partners-title {
        display: flex;
        flex-direction: column;
        gap: 0.3125rem; /* 5px */
    }

    /* the outline word is drawn at 1px on mobile (2px only on the desktop display size) */
    section.partners .partners-title-outline {
        -webkit-text-stroke-width: 1px;
        text-stroke-width: 1px;
    }

    /* ---- filter tabs ---- */
    /* they stay a wrapping pill row (Figma wraps to 2 rows at 375px), not a scroller */

    section.partners .partners-tabs {
        gap: 0.625rem; /* 10px */
    }

    section.partners .partners-tab {
        font-size: 0.875rem; /* 14px */
    }

    /* ---- logo strip / carousel ---- */
    /* stays a Swiper (slidesPerView auto, spaceBetween 20) bleeding past the
       container to the inline-end edge, clipped by the section's overflow: hidden */

    section.partners .partners-cell {
        inline-size: 8.125rem; /* 130px */
        min-block-size: 6.0625rem; /* 97px — uniform cell height with or without label */
        gap: 0.375rem; /* 6px */
    }

    section.partners .partners-logo {
        inline-size: 100%;
        block-size: 3rem; /* 48px + 6 gap + 13 label = 67px content box */
    }

    section.partners .partners-cell:not(:has(.partners-cell-label)) .partners-logo {
        block-size: 4.1875rem; /* 67px — fills the whole content box when there is no label */
    }
}


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

/* ======================================== */
/* SITE FOOTER (Block 12) */
/* ======================================== */

footer.site-footer {
    position: relative;
    background: linear-gradient(180deg, #071f36 0%, #020c16 100%);
}

/* Red band with centered mono caption */
footer.site-footer .site-footer-band {
    position: relative;
    z-index: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    min-block-size: 1.875rem;
    padding-block: 1px;
    background-color: var(--accent);
}

footer.site-footer .site-footer-band-text {
    color: var(--c-white);
    text-align: center;
    padding-inline: 1rem;
    text-wrap: balance;
}

footer.site-footer .site-footer-inner {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 6.25rem;
    padding-block: 7.5rem 2.5rem;
    overflow: clip;
}

/* Decorative media: pinned to the top-inline-end corner of the whole footer,
   overlapping the red band (476 / 578 on a 1440 canvas) */
footer.site-footer .site-footer-media {
    /* it comes up from under the red band — far enough not to cover it at rest */
    --reveal-shift: 2.5rem;
    position: absolute;
    inset-block-start: 0;
    /* stays where it lands on the 1440 canvas instead of following the viewport edge */
    inset-inline-end: calc(max(0px, 100% - 90rem) / 2);
    z-index: 2;
    inline-size: 33.0556%;
    max-inline-size: 29.75rem;
    aspect-ratio: 476 / 578;
    pointer-events: none;
}

footer.site-footer .site-footer-media .img-wrapper {
    block-size: 100%;
}

/* ---- CTA block ---- */
footer.site-footer .site-footer-cta {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 3.75rem;
}

/* keep the CTA copy above the decorative media */
footer.site-footer .site-footer-cta-text,
footer.site-footer .site-footer-cta-actions {
    position: relative;
    z-index: 1;
}

footer.site-footer .site-footer-cta-text {
    display: flex;
    flex-direction: column;
    gap: 1.875rem;
    /* 60% keeps the copy clear of the 33% media pinned to the inline-end corner */
    max-inline-size: min(44.6875rem, 60%);
}

footer.site-footer .site-footer-cta-label {
    color: var(--accent);
}

footer.site-footer .site-footer-cta-para {
    color: var(--on-surface);
}

footer.site-footer .site-footer-cta-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
}

footer.site-footer .site-footer-btn {
    inline-size: 18.75rem;
    max-inline-size: 100%;
}

/* ---- Bottom (brand + socials + legal) ---- */
footer.site-footer .site-footer-bottom {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 2.5rem;
}

footer.site-footer .site-footer-main {
    display: flex;
    align-items: flex-end;
    gap: 2.5rem;
}

footer.site-footer .site-footer-brand {
    flex: 1 0 0;
    min-inline-size: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.875rem;
}

footer.site-footer .site-footer-logo {
    display: block;
    inline-size: 6.25rem;
    color: var(--c-white);
}

footer.site-footer .site-footer-logo svg {
    display: block;
    inline-size: 100%;
    block-size: auto;
}

footer.site-footer .site-footer-brand-label {
    color: var(--accent);
}

footer.site-footer .site-footer-credits {
    font-family: var(--ff-quaternary);
    font-weight: 300;
    font-size: 1rem;
    line-height: 1.4;
    letter-spacing: -0.005em;
    color: var(--c-white);
}

footer.site-footer .site-footer-credits strong,
footer.site-footer .site-footer-credits b {
    font-weight: 600;
}

/* ---- Social icons ---- */
footer.site-footer .site-footer-socials {
    flex: none;
    display: flex;
    align-items: center;
    gap: 1.25rem;
}

footer.site-footer .site-footer-social {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2.8125rem;
    block-size: 2.8125rem;
    border: 1px solid rgb(from var(--c-white) r g b / 0.25);
    border-radius: 50%;
    color: var(--c-white);
    transition:
        color 0.2s ease,
        background-color 0.2s ease,
        border-color 0.2s ease;
}

footer.site-footer .site-footer-social svg,
footer.site-footer .site-footer-social-icon {
    inline-size: 1.0625rem;
    block-size: 1.0625rem;
    object-fit: contain;
    transition: filter 0.2s ease;
}

footer.site-footer .site-footer-social:is(:hover, :focus-visible) {
    background-color: var(--c-white);
    border-color: var(--c-white);
    color: var(--c-black);
}

/* uploaded icons render as <img>, so currentColor can't flip them on hover */
footer.site-footer .site-footer-social:is(:hover, :focus-visible) .site-footer-social-icon {
    filter: invert(1);
}

/* ---- Divider + legal ---- */
footer.site-footer .site-footer-divider {
    border: none;
    block-size: 1px;
    inline-size: 100%;
    background-color: rgb(from var(--c-white) r g b / 0.14);
}


footer.site-footer .site-footer-copyright {
    color: #828a92;
}

/* SITE FOOTER — mobile */
@media (max-width: 768px) {
    /* ---- Decorative media: becomes a full-bleed 375x500 banner at the top of the footer ---- */
    footer.site-footer .site-footer-media {
        position: relative;
        inset-block-start: auto;
        inset-inline-end: auto;
        z-index: 0;
        inline-size: 100%;
        max-inline-size: none;
        aspect-ratio: 375 / 500;
    }

    /* fade the banner into the footer gradient (Figma: transparent -> #020e19) */
    footer.site-footer .site-footer-media::after {
        content: "";
        position: absolute;
        inset-block: 0;
        inset-inline: 0;
        z-index: 1;
        background-image: linear-gradient(180deg, rgb(2 14 25 / 0) 0%, rgb(2 14 25 / 0.1) 52.885%, rgb(2 14 25 / 1) 100%);
        pointer-events: none;
    }

    /* ---- Red band sits ON TOP of the banner's first 30px ---- */
    footer.site-footer .site-footer-band {
        position: absolute;
        inset-block-start: 0;
        inset-inline: 0;
        z-index: 3;
    }

    /* ---- Footer body: gradient runs dark -> blue on mobile (reversed vs desktop) ---- */
    footer.site-footer .site-footer-inner {
        gap: 6.25rem;
        padding-block: 5rem 2.5rem;
        background-image: linear-gradient(180deg, #030e19 0%, #020c16 25%, #071f36 100%);
    }

    /* ---- CTA ---- */
    footer.site-footer .site-footer-cta {
        gap: 3.75rem;
    }

    footer.site-footer .site-footer-cta-text {
        max-inline-size: none;
    }

    footer.site-footer .site-footer-cta-para {
        font-size: 2.0625rem;
    }

    footer.site-footer .site-footer-cta-actions {
        flex-direction: column;
        flex-wrap: nowrap;
        align-items: stretch;
        gap: 1.25rem;
    }

    footer.site-footer .site-footer-btn {
        inline-size: 100%;
    }

    /* ---- Bottom (brand + socials + legal) ---- */
    footer.site-footer .site-footer-bottom {
        gap: 1.875rem;
    }

    footer.site-footer .site-footer-main {
        flex-direction: column;
        align-items: flex-start;
        gap: 1.875rem;
    }

    footer.site-footer .site-footer-socials {
        flex-wrap: wrap;
    }
}



/* ======================================== */
/* REVEAL */
/* ======================================== */

/* Rebuilt from the "animated" variant of each Figma block, where the animated state is
   captured mid-flight: the text blocks sit at opacity .4, the red bands have zero width,
   and the showcase word sits below its own clipping mask.

   `data-reveal`         -> fade + short rise (the opacity .4 blocks)
   `data-reveal="band"`  -> the band opens from a zero-width slit, its text fades in after
   `data-reveal="clip"`  -> the word rises out of its own mask

   Everything is CSS; JS only flips `.is-revealed` once per element. The `data-reveal-ready`
   flag is set inline in <head>, so nothing is ever hidden when JS is off. */

:root {
    --reveal-duration: 1.1s;
    --reveal-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
    /* --reveal-ease is heavily front-loaded (a third of the way in the first tenth of the
       time): fine for something arriving, wrong for a wipe, which then reads as a snap
       followed by a crawl. Sweeps use this symmetric one instead. */
    --cut-ease: cubic-bezier(0.65, 0, 0.35, 1);
    --reveal-shift: 1.5rem;
    /* how much of the collapsed state the "gap" variant actually travels — the full gap read
       as far too heavy a move, this keeps the same shape with a fraction of the distance */
    --reveal-collapse: 0.4;
}

@media (prefers-reduced-motion: no-preference) {
    html[data-reveal-ready] [data-reveal] {
        opacity: var(--reveal-opacity, 0.4);
        /* --reveal-shift-x lets a block come in from the side as well (rules image) */
        translate: var(--reveal-shift-x, 0) var(--reveal-shift);
        transition:
            opacity var(--reveal-duration) var(--reveal-ease),
            translate var(--reveal-duration) var(--reveal-ease);
    }

    html[data-reveal-ready] [data-reveal].is-revealed {
        opacity: 1;
        translate: none;
    }

    /* ---- group + stagger ---- */

    /* a group is observed as one block; its items come in one after the other.
       --reveal-i is the item's index, set by initReveal — but any [data-reveal] can carry one
       from CSS to keep the beat of a chain it is not a DOM sibling of (see .rules-intro) */
    html[data-reveal-ready] [data-reveal] {
        transition-delay: calc(var(--reveal-i, 0) * 0.1s);
    }

    /* a button carrying a reveal would otherwise lose the .btn hover transition — the reveal
       rule replaces the whole `transition` — and change colour instantly on hover, unlike
       every other CTA. Its own stagger delay is written per property so the later
       transition-delay rule cannot push the hover fade too */
    html[data-reveal-ready] .btn[data-reveal] {
        transition:
            opacity var(--reveal-duration) var(--reveal-ease) calc(var(--reveal-i, 0) * 0.1s),
            translate var(--reveal-duration) var(--reveal-ease) calc(var(--reveal-i, 0) * 0.1s),
            color 0.2s ease,
            background-color 0.2s ease,
            border-color 0.2s ease;
    }

    html[data-reveal-ready] [data-reveal-group].is-revealed [data-reveal] {
        opacity: 1;
        translate: none;
    }

    /* ---- band ---- */

    /* wipes from the inline-start to the inline-end; clipped to -100vw rather than 0 so the
       band's side box-shadow survives the reveal */
    html[data-reveal-ready] [data-reveal="band"] {
        opacity: 1;
        translate: none;
        clip-path: inset(0 100% 0 -100vw);
        transition: clip-path 1.3s var(--cut-ease);
    }

    html[data-reveal-ready] [data-reveal="band"] > * {
        opacity: var(--reveal-opacity, 0.4);
        transition: opacity 0.8s var(--reveal-ease) 0.6s;
    }

    html[data-reveal-ready] [data-reveal="band"].is-revealed {
        clip-path: inset(0 -100vw 0 -100vw);
    }

    html[data-reveal-ready] [data-reveal="band"].is-revealed > * {
        opacity: 1;
    }

    /* ---- turn ---- */

    /* a deco arc turns into its resting angle as it comes into view. That angle lives on the
       element itself as --reveal-turn (and is its plain `rotate`), so with reduced motion or no
       JS the arc is simply already there — this variant only supplies the 0deg start and the
       transition. */
    html[data-reveal-ready] [data-reveal="turn"] {
        opacity: 1;
        translate: none;
        rotate: 0deg;
        transition: rotate 1.4s var(--reveal-ease);
    }

    html[data-reveal-ready] [data-reveal="turn"].is-revealed {
        rotate: var(--reveal-turn, 0deg);
    }

    /* ---- gap ---- */

    /* The block reads as starting contracted and expanding, but nothing about the layout
       moves: the gaps stay where they are and each item is instead offset by the gaps that
       separate it from the centre of the block, then released. With four children that is
       +1.5, +0.5, -0.5, -1.5 gaps — the top half starts from below, the bottom half from
       above, so the block opens from its middle instead of sliding down as a whole.
       --reveal-n is the child count, set by initReveal next to --reveal-i. */
    html[data-reveal-ready] :is([data-reveal-group="gap"], [data-reveal-group="compact"]) > [data-reveal] {
        translate: 0 calc(((var(--reveal-n, 1) - 1) / 2 - var(--reveal-i, 0)) * var(--reveal-gap) * var(--reveal-collapse));
    }

    html[data-reveal-ready] :is([data-reveal-group="gap"], [data-reveal-group="compact"]).is-revealed > [data-reveal] {
        translate: none;
    }

    /* each separator wipes in from the inline-start when its own row is scrolled into — the
       rows carry `data-reveal-self`, so they are observed one by one even though they also
       belong to a group */
    html[data-reveal-ready] section.circuit .circuit-row::before,
    html[data-reveal-ready] section.circuit .circuit-row:last-child::after {
        scale: 0 1;
        transform-origin: left;
        transition: scale 0.9s var(--cut-ease);
    }

    html[data-reveal-ready] section.circuit .circuit-row.is-revealed::before,
    html[data-reveal-ready] section.circuit .circuit-row.is-revealed:last-child::after {
        scale: 1 1;
    }

    /* "compact" is the same move without the reveal: the block is simply tighter than it will
       be and settles as you scroll to it — nothing fades, nothing is staggered (used on the
       circuit rows, where a per-row cascade over eight rows read as sloppy) */
    html[data-reveal-ready] [data-reveal-group="compact"] > [data-reveal] {
        opacity: 1;
        transition-delay: 0s;
    }

    /* ---- rise ---- */

    /* The block moves as one — only the wrapper is translated, its texts stay put inside it
       and just fade in. Used on the red pull-quote card. */
    html[data-reveal-ready] [data-reveal-group="rise"] {
        translate: 0 var(--reveal-rise, var(--reveal-shift));
        transition: translate var(--reveal-duration) var(--reveal-ease);
    }

    html[data-reveal-ready] [data-reveal-group="rise"].is-revealed {
        translate: none;
    }

    html[data-reveal-ready] [data-reveal-group="rise"] > [data-reveal] {
        translate: none;
    }

    /* ---- media ---- */

    /* a background frame that settles: it starts slightly zoomed in and pushed down, and
       eases back into place. It rides the .img-wrapper, not the image inside it, so the
       scroll-driven parallax on the <img> keeps its own scale/translate. */
    html[data-reveal-ready] [data-reveal="media"] {
        opacity: 1;
        scale: var(--reveal-media-scale, 1.12);
        translate: 0 var(--reveal-shift);
        transition:
            scale 1.6s var(--reveal-ease),
            translate 1.6s var(--reveal-ease);
    }

    html[data-reveal-ready] [data-reveal="media"].is-revealed {
        scale: 1;
        translate: none;
    }

    /* ---- clip ---- */

    /* The mask is the line box, so `translate: 0 100%` parks the word precisely one mask below
       its place. But a tight line-height makes that box SHORTER than the glyphs — the mobile
       showcase title runs at 0.7, which puts the baseline exactly on the bottom edge, and the
       caps were cut 3px at the top and the descent 2px at the bottom. `--clip-bleed` gives the
       mask the missing room as padding (overflow clips at the padding box) and takes the same
       amount back out of the layout as a negative margin, so nothing moves; the child's travel
       grows by the same amount so it still parks fully out of sight.
       `overflow: hidden` rather than `clip` for the wider support; nothing here scrolls, so the
       two behave the same. */
    html[data-reveal-ready] [data-reveal="clip"] {
        --clip-bleed: 0.15em;
        opacity: 1;
        translate: none;
        display: inline-block;
        overflow: hidden;
        padding-block: var(--clip-bleed);
        margin-block: calc(-1 * var(--clip-bleed));
    }

    html[data-reveal-ready] [data-reveal="clip"] > * {
        display: inline-block;
        translate: 0 calc(100% + var(--clip-bleed));
        transition: translate 1.3s var(--reveal-ease);
    }

    html[data-reveal-ready] [data-reveal="clip"].is-revealed > * {
        translate: none;
    }
}

/* ---- page intro ---- */

/* The page loads under a red curtain with the C26 mark centred on it, in five beats:

     0    → 1s     a 30px slit is cut through the curtain AND through the mark, left to right
     1.05 → 1.45s  the mark, already cut, fades out — the curtain opens on plain red
     1.55 → 2.75s  the two red halves leave, up and down, slowly
     3.25 → 4.15s  half a second after the curtain is fully open, the two title lines fade in,
                   stacked, and take their time doing it
     4.15 → 4.85s  the two title lines part, giving the band its room back
     4.85 → 5.55s  the band grows from the centre to the sides

   Runs on load — no observer, no JS. The curtain lives at the end of <body>, outside <main>,
   and is fixed to the viewport: it is a page-level load-in, not part of the hero, so it
   covers the site header too.

   The cut is ONE mask on the curtain itself, not a clip-path per layer. Two mask layers,
   unioned: the first is everything outside the slit, the second everything ahead of the sweep
   front — so what stays painted is (outside the slit) OR (not cut yet). Only the second
   layer's `mask-position` animates, sliding a hard edge from right to left. The red halves
   and the mark are simply children of the masked curtain, so the mark takes the very same cut
   in the very same second — it is cut, never faded in place; it only fades once the cut has
   gone all the way through it.

   It has to be a mask, and the slit has to be a percentage away from the edge of the sweep:
   inside an ANIMATED `clip-path: polygon()` Chrome resolves the percentage part of a vertex in
   device pixels but applies the absolute part (the 15px) without the device scale factor, so
   at dpr 2 the slit came out 30 device px instead of 60 — half — for as long as the animation
   ran, then snapped to the right size when it ended. Measured, not guessed: reproduced at
   dpr 2, and gone both with the offset written as a percentage and with this mask. Here the
   15px only ever appears in a STATIC gradient stop, which is scaled correctly. */

@media (prefers-reduced-motion: no-preference) {
    section.hero.hero-banner {
        background-color: var(--c-red);
    }

    /* above the site header (fixed, --z-header), so the curtain really covers everything */
    .page-intro {
        --page-intro-slit: 0.9375rem;

        display: block;
        position: fixed;
        inset: 0;
        z-index: calc(var(--z-header) + 1);
        pointer-events: none;
        overflow: clip;
        mask-image:
            linear-gradient(
                to bottom,
                #000 0 calc(50% - var(--page-intro-slit)),
                transparent calc(50% - var(--page-intro-slit)) calc(50% + var(--page-intro-slit)),
                #000 calc(50% + var(--page-intro-slit)) 100%
            ),
            linear-gradient(to right, transparent 0 50%, #000 50% 100%);
        /* the sweep layer is twice as wide as the curtain and carries a single hard edge in
           its middle, so sliding it from one end to the other walks that edge across */
        mask-size: 100% 100%, 200% 100%;
        mask-repeat: no-repeat;
        mask-composite: add;
        animation: page-intro-cut 1s var(--cut-ease) both;
    }

    /* without the mask the curtain would never open — better no curtain at all than a page
       stuck behind a red screen */
    @supports not (mask-composite: add) {
        .page-intro {
            display: none;
        }
    }

    @keyframes page-intro-cut {
        from {
            mask-position: 0 0, 100% 0;
        }

        to {
            mask-position: 0 0, 0 0;
        }
    }

    /* Both halves are the whole screen and keep only their own half — the mask takes care of
       the slit, so these clips are static and need no length of their own. They slide away
       once the cut is through; the mark only fades, and does it first. */
    .page-intro-layer {
        position: absolute;
        inset: 0;
        background-color: var(--c-red);
        animation: 1.2s var(--cut-ease) 1.55s both;
    }

    .page-intro-red-top {
        clip-path: inset(0 0 50% 0);
        animation-name: page-intro-exit-top;
    }

    .page-intro-red-bottom {
        clip-path: inset(50% 0 0 0);
        animation-name: page-intro-exit-bottom;
    }

    .page-intro-mark {
        display: block;
        position: absolute;
        inset-block-start: 50%;
        inset-inline-start: 50%;
        translate: -50% -50%;
        inline-size: 12.5rem;
        color: var(--c-white);
        animation: page-intro-mark-out 0.4s var(--cut-ease) 1.05s both;
    }

    .page-intro-mark svg {
        display: block;
        inline-size: 100%;
        block-size: auto;
    }

    @keyframes page-intro-mark-out {
        from {
            opacity: 1;
        }

        to {
            opacity: 0;
        }
    }

    /* -50%/50% of its own height is exactly the visible band of each layer */
    @keyframes page-intro-exit-top {
        to {
            translate: 0 -50%;
        }
    }

    @keyframes page-intro-exit-bottom {
        to {
            translate: 0 50%;
        }
    }

    /* The two title lines wait for the curtain: they only start half a second after the red
       has fully left (2.75s + 0.5s), and they take their time coming up.
       They come in stacked, each shifted over half of the room the band and its gap take in
       the layout, and part later, with the band. */
    section.hero.hero-banner .hero-line-fill {
        animation:
            hero-line-in 0.9s var(--cut-ease) 3.25s backwards,
            hero-line-part-fill 0.7s var(--cut-ease) 4.15s backwards;
    }

    section.hero.hero-banner .hero-line-outline {
        animation:
            hero-line-in 0.9s var(--cut-ease) 3.25s backwards,
            hero-line-part-outline 0.7s var(--cut-ease) 4.15s backwards;
    }

    @keyframes hero-line-in {
        from {
            opacity: 0;
        }
    }

    @keyframes hero-line-part-fill {
        from {
            translate: 0 var(--hero-band-collapse);
        }
    }

    @keyframes hero-line-part-outline {
        from {
            translate: 0 calc(-1 * var(--hero-band-collapse));
        }
    }

    /* the band grows from the centre out, once the lines have finished making room for it */
    section.hero.hero-banner .hero-band {
        animation: hero-band-open 0.7s var(--cut-ease) 4.85s backwards;
    }

    /* both keyframes have to be written out: with only a `from`, the implicit `to` is the
       element's own value — `clip-path: none` — and inset() → none is not interpolatable, so
       the band snapped open half way through instead of unrolling */
    @keyframes hero-band-open {
        from {
            clip-path: inset(0 50% 0 50%);
        }

        to {
            clip-path: inset(0 0 0 0);
        }
    }

    section.hero.hero-banner .hero-caption {
        animation: hero-caption-in 0.6s var(--reveal-ease) 5.45s backwards;
    }

    @keyframes hero-caption-in {
        from {
            opacity: 0;
        }
    }

    /* the bar and the buttons are last: when the curtain leaves, only the two lines show */
    @keyframes hero-rise {
        from {
            opacity: 0;
            translate: 0 2.5rem;
        }
    }

    body:has(section.hero-banner) .site-header {
        animation: hero-rise 1.1s var(--reveal-ease) 4.6s backwards;
    }

    section.hero.hero-banner .hero-ctas {
        animation: hero-rise 1.1s var(--reveal-ease) 4.75s backwards;
    }

    /* ---- image parallax ---- */

    /* The drift itself is driven by initParallax (js/main.js): scroll-driven animations with
       animation-range are not supported widely enough, and animating the frames themselves
       blew the media out of their wrappers and gave the page a giant overflow. So only the
       media inside a frame moves, and only its `transform` — the reveals own `translate` and
       `scale` on the wrappers, and the scale below is the room the drift needs. */
    .img-wrapper.img-wrapper-ratio > :is(img, video, picture),
    section.showcase .showcase-image > :is(img, picture) {
        scale: 1.12;
        transition: transform 0.1s linear;
    }
}
