/* #region Color variables */

/* Flock brand palette, from the Flock Brand Identity Guardrails (September 2026). */

:root {
    /* Primary */
    --color--white:             #fff;
    --color--navy:              hsl(206.5, 60.7%, 11%); /* #0B1E2D logo ink */
    --color--chalk:             hsl(42, 35.7%, 94.5%); /* #F6F3EC primary ground */
    --color--sky-wash:          hsl(207, 40%, 90.2%); /* #DCE7F0 primary ground */

    /* Secondary */
    --color--denim:             hsl(212.4, 32.7%, 44.3%); /* #4C6E96 */
    --color--orange:            hsl(20.2, 89.4%, 48.2%); /* #E9570D Flock orange */

    /* Support */
    --color--rust:              hsl(19.2, 90.2%, 40%); /* #C2450A text on light */
    --color--peach:             hsl(22.6, 86.9%, 79%); /* #F8BE9B text on dark */

    /* Derived */
    --color--grey:              color-mix(in srgb, var(--color--navy) 48%, var(--color--chalk));
    --color--grey-lighten-1:    color-mix(in srgb, var(--color--navy) 15%, var(--color--chalk));
    --color--navy-fade-55:      color-mix(in srgb, var(--color--navy) 55%, transparent);
    --color--chalk-darken-1:    color-mix(in srgb, var(--color--chalk), var(--color--navy) 7%);
    --color--sky-wash-shade-1:  color-mix(in srgb, var(--color--sky-wash), var(--color--denim) 12%); /* a slightly darker sky wash */

    /* Photography: the average sky of images/003-birds.jpg behind the navigation. */
    --color--photo-sky:         hsl(212.5, 64.1%, 63.9%); /* #689EDE */
    --color--photo-sky-lighten-1: color-mix(in srgb, var(--color--photo-sky), var(--color--white) 30%);
    --color--photo-sky-lighten-1-fade-98: color-mix(in srgb, var(--color--photo-sky-lighten-1) 98%, transparent);
    --color--navy-fade-7:        color-mix(in srgb, var(--color--navy) 7%, transparent);
    --color--photo-sky-lighten-1-fade-0: color-mix(in srgb, var(--color--photo-sky-lighten-1) 0%, transparent);

    /* The homepage intro fades to these as it scrolls away: a mid light blue
       ground and a soft blue ink, for a low-contrast blue-on-blue look. */
    --color--sky-wash-darken-1: color-mix(in srgb, var(--color--sky-wash), var(--color--photo-sky) 45%);
    --color--denim-lighten-1:   color-mix(in srgb, var(--color--denim), var(--color--photo-sky) 45%);

    /* A phone screen that is switched off: near-black with a hint of navy. */
    --color--screen-off:        hsl(206.5, 20%, 9%); /* #121820 */

    /* Navy with the same hue, a few steps lighter and slightly less saturated. */
    --color--navy-lighten-1:    hsl(206.5, 45%, 25%); /* #23435C */
    --color--chalk-muted:       color-mix(in srgb, var(--color--chalk) 60%, var(--color--navy-lighten-1)); /* quieter chalk text on navy, tinted towards its borders */
}

/* #endregion */

/* #region Text colors */

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

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

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

.color--sky-wash {
    color: var(--color--sky-wash);
}

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

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

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

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

.color--chalk-muted {
    color: var(--color--chalk-muted);
}

/* #endregion */

/* #region Background and border colors */

.backgroundborder--white {
    background-color: var(--color--white);
    border-color: var(--color--white);
}

.backgroundborder--navy {
    background-color: var(--color--navy);
    border-color: var(--color--navy);
}

.backgroundborder--chalk {
    background-color: var(--color--chalk);
    border-color: var(--color--chalk);
}

.backgroundborder--sky-wash {
    background-color: var(--color--sky-wash);
    border-color: var(--color--sky-wash);
}

.backgroundborder--denim {
    background-color: var(--color--denim);
    border-color: var(--color--denim);
}

.backgroundborder--orange {
    background-color: var(--color--orange);
    border-color: var(--color--orange);
}

.backgroundborder--rust {
    background-color: var(--color--rust);
    border-color: var(--color--rust);
}

.backgroundborder--peach {
    background-color: var(--color--peach);
    border-color: var(--color--peach);
}

/* #endregion */

/* #region Navigation surfaces */

/*
 * Each surface class tells the floating site navigation which colour to use
 * while it sits over that area. The value inherits, so a class on a section
 * applies to everything inside it; the page body sets the default. To support
 * a new background, add a class here and put it on the element that paints
 * that background. See docs/css/units-and-tokens.md#navigation-surfaces.
 */

:root {
    --nav-surface-text: var(--color--navy); /* navigation link colour unless a surface sets its own */
}

.nav-surface--chalk {
    --nav-surface: var(--color--chalk-darken-1);
}

/* Sky-wash areas: a slightly darker shade of the same blue. */
.nav-surface--sky-wash {
    --nav-surface: var(--color--sky-wash-shade-1);
}

/* Dark navy areas: a slightly lighter navy pill with stone (chalk) links. */
.nav-surface--navy {
    --nav-surface: var(--color--navy-lighten-1);
    --nav-surface-text: var(--color--chalk);
}

/* Sky photography, such as the hero birds photo: a brighter shade of the sky. */
.nav-surface--sky {
    --nav-surface: var(--color--photo-sky-lighten-1);
}

/* #endregion */

/* #region Font faces */

/*
 * The draft main site uses Manrope for headings and body copy, loaded from
 * Google Fonts by the <link> in the shared page <head> at weights 400-700.
 */

/* #endregion */

/* #region Type roles */

/*
 * Every text style on the site is one of these roles. Each role is a complete
 * set of five tokens, named --<role>-fontfamily, -fontsize, -lineheight,
 * -fontweight and -letterspacing (plus -texttransform), and is applied by one
 * rule below that sets all of them together. Responsive changes override the
 * tokens, never the rules. Keep the list short: reuse a role before adding one.
 *
 *   bodytext  running text, card titles (at the strong weight), footer links
 *   display   the all-caps display line of the hero
 *   section   the smaller all-caps line that opens each later homepage section
 *   feature   the all-caps page title (h1)
 *   subtitle  the large sentence-case line under a display heading, and the mobile menu
 *   small     section headings in long documents (h2), such as the legal pages
 *   nav       navigation links and buttons
 */

:root {
    --font-family--display:      "Manrope", sans-serif;
    --font-family--body:         "Manrope", sans-serif;

    --bodytext-fontfamily:       var(--font-family--body);
    --bodytext-fontsize:         1.05rem;
    --bodytext-lineheight:       1.5rem;
    --bodytext-fontweight:       515; /* a hair above Medium; Manrope is variable (400-700) */
    --bodytext-fontweight-strong: 600;
    --bodytext-letterspacing:    0.01em; /* tracking 10 */
    --bodytext-texttransform:    none;

    /* Display and subtitle sizes shrink with the viewport so the hero text fits
       its half-width column, capped at 72px and about 29px. */
    --display-fontfamily:        var(--font-family--display);
    --display-fontsize:          min(4.5rem, 5vw); /* max 72px */
    --display-lineheight:        calc(var(--display-fontsize) * 1.06);
    --display-fontweight:        400;
    --display-letterspacing:     0.07em;
    --display-texttransform:     uppercase;

    /* A smaller all-caps display line for section openers: 70% of the display
       size, a touch heavier so the strokes look as thick as the hero's. */
    --section-fontfamily:        var(--font-family--display);
    --section-fontsize:          3.15rem; /* 70% of the 72px display size */
    --section-lineheight:        calc(var(--section-fontsize) * 1.08);
    --section-fontweight:        450;
    --section-letterspacing:     0.06em;
    --section-texttransform:     uppercase;

    --feature-fontfamily:        var(--font-family--display);
    --feature-fontsize:          3.3rem;
    --feature-lineheight:        3.3rem;
    --feature-fontweight:        400;
    --feature-letterspacing:     0.07em;
    --feature-texttransform:     uppercase;

    --subtitle-fontfamily:       var(--font-family--display);
    --subtitle-fontsize:         min(1.84rem, 2.116vw); /* max 29.4px; line height follows at 1.45x */
    --subtitle-lineheight:       calc(var(--subtitle-fontsize) * 1.45);
    --subtitle-fontweight:       500;
    --subtitle-letterspacing:    0.01em; /* tracking 10, matching body text */
    --subtitle-texttransform:    none;

    --small-fontfamily:          var(--font-family--display);
    --small-fontsize:            1.65rem;
    --small-lineheight:          2rem;
    --small-fontweight:          700;
    --small-letterspacing:       0.015em;
    --small-texttransform:       none;

    /* Body text at a heavier weight: between SemiBold and Bold. */
    --nav-fontfamily:            var(--bodytext-fontfamily);
    --nav-fontsize:              var(--bodytext-fontsize);
    --nav-lineheight:            var(--bodytext-lineheight);
    --nav-fontweight:            650;
    --nav-letterspacing:         var(--bodytext-letterspacing);
    --nav-texttransform:         none;
}

/* #endregion */

/* #region Body text */

body,
.body-text {
    font-family: var(--bodytext-fontfamily);
    font-size: var(--bodytext-fontsize);
    line-height: var(--bodytext-lineheight);
    font-weight: var(--bodytext-fontweight);
    letter-spacing: var(--bodytext-letterspacing);
    text-transform: var(--bodytext-texttransform);
}

strong,
b {
    font-weight: var(--bodytext-fontweight-strong);
}

/* Body text at the strong weight, for short headings in running text, such as card titles. */
.body-text--strong {
    font-weight: var(--bodytext-fontweight-strong);
}

/* #endregion */

/* #region Headings */

h1,
h2,
h3,
.heading {
    font-style: normal;
}

.heading--display {
    font-family: var(--display-fontfamily);
    font-size: var(--display-fontsize);
    line-height: var(--display-lineheight);
    font-weight: var(--display-fontweight);
    letter-spacing: var(--display-letterspacing);
    text-transform: var(--display-texttransform);
}

.heading--section {
    font-family: var(--section-fontfamily);
    font-size: var(--section-fontsize);
    line-height: var(--section-lineheight);
    font-weight: var(--section-fontweight);
    letter-spacing: var(--section-letterspacing);
    text-transform: var(--section-texttransform);
}

h1,
.heading--feature {
    font-family: var(--feature-fontfamily);
    font-size: var(--feature-fontsize);
    line-height: var(--feature-lineheight);
    font-weight: var(--feature-fontweight);
    letter-spacing: var(--feature-letterspacing);
    text-transform: var(--feature-texttransform);
}

.heading--subtitle {
    font-family: var(--subtitle-fontfamily);
    font-size: var(--subtitle-fontsize);
    line-height: var(--subtitle-lineheight);
    font-weight: var(--subtitle-fontweight);
    letter-spacing: var(--subtitle-letterspacing);
    text-transform: var(--subtitle-texttransform);
}

h2,
h3,
.heading--small {
    font-family: var(--small-fontfamily);
    font-size: var(--small-fontsize);
    line-height: var(--small-lineheight);
    font-weight: var(--small-fontweight);
    letter-spacing: var(--small-letterspacing);
    text-transform: var(--small-texttransform);
}

/* #endregion */

/* #region Accent dot */

/*
 * Replaces a full stop with a larger Flock-orange dot, sized to the text.
 * Wrap the full stop, and keep it with its word so the dot can never wrap
 * onto a line of its own:
 * <span class="keep-together">word<span class="accent-dot">.</span></span>.
 * The character stays
 * in the markup (transparent and clipped), so it is still read and copied as
 * punctuation.
 */

.accent-dot {
    display: inline-block;
    width: 0.2em;
    height: 0.2em;
    margin-inline-start: 0.06em;
    overflow: hidden; /* also puts the inline-block's baseline at its bottom edge */
    border-radius: 50%;
    /* --accent-dot-fade (0 to 1, set by a parent such as .hero) blends the dot
       from orange into the surrounding text colour. */
    background-color: color-mix(in srgb, var(--color--orange), currentColor calc(var(--accent-dot-fade, 0) * 100%));
    -webkit-text-fill-color: transparent; /* hides the glyph but keeps currentColor as the text colour */
    letter-spacing: 0;
}

/* #endregion */

/* #region Navigation typography */

.site-nav__link,
.site-nav__button,
.button {
    font-family: var(--nav-fontfamily);
    font-size: var(--nav-fontsize);
    line-height: var(--nav-lineheight);
    font-weight: var(--nav-fontweight);
    letter-spacing: var(--nav-letterspacing);
    text-transform: var(--nav-texttransform);
}

/* In the full-screen mobile menu, the links take the section heading role:
   large capitals, as the homepage section titles. */
@media (max-width: 48rem) {
    .site-nav__link {
        font-family: var(--section-fontfamily);
        font-size: min(var(--section-fontsize), calc(var(--max-width) / 9.7)); /* "What's included" (9.6em) always fits */
        line-height: var(--section-lineheight);
        font-weight: var(--section-fontweight);
        letter-spacing: var(--section-letterspacing);
        text-transform: var(--section-texttransform);
    }
}

/* #endregion */

/* #region Responsive type */

/* Below 60rem the hero stacks, so its text can use the full width again. */
@media (max-width: 60rem) {
    :root {
        --display-fontsize: 4.5rem; /* 72px */
        --subtitle-fontsize: 1.84rem; /* 29.4px */
    }
}

@media (max-width: 40rem) {
    :root {
        --bodytext-fontsize: 1.0625rem; /* 17px */
        --bodytext-lineheight: 1.625rem; /* 26px */
        --display-fontsize: 2.75rem; /* 44px */
        --section-fontsize: 2.325rem; /* 33px, 20% up on the 31px the section role had on phones */
        --feature-fontsize: 2.25rem; /* 36px */
        --feature-lineheight: 2.625rem; /* 42px */
        --subtitle-fontsize: 1.265rem; /* 20.2px */
        --small-fontsize: 1.5rem; /* 24px */
        --small-lineheight: 2rem; /* 32px */
    }
}

/* #endregion */

/* #region Variables and units */

:root {
    --max-width: min(81.25rem, calc(100vw - 12rem));
    --interval: 8rem;
    --border-radius: 0.75rem; /* 12px: the one corner radius for photos, cards and panels (pill buttons stay fully round) */
    --border-width: 0.125rem; /* 2px */
    --screen-height: max(100vh, 48rem); /* full-screen sections fill the window, but never shrink below 48rem on short windows */
    --underline-width: 0.09375rem; /* 1.5px */
}

/* Fluid on desktop: grows with the viewport width from 14px to 15.5px (reached
   at about 1435px wide); only a very short window (under about 675px tall) holds it back. */
html {
    overflow-x: clip; /* no sideways scrolling, even if something overhangs the viewport */
    font-size: clamp(0.875rem, min(1.08vw, 2.30vh), 0.96875rem);
}

/* In-page links, such as the hero's scroll arrow, glide to their target. */
@media (prefers-reduced-motion: no-preference) {
    html {
        scroll-behavior: smooth;
    }
}

/* On phones the whole rem scale is fixed at about 1.5% above the 14px minimum above. */
@media (max-width: 40rem) {
    html {
        font-size: 0.888rem; /* 14.21px, 6% below the previous 15.12px */
    }
}

/* #endregion */

/* #region Responsive page width */

@media (min-width: 115rem) {
    :root {
        --max-width: 85rem;
    }

    html {
        font-size: 0.96875rem;
    }
}

@media (max-width: 82rem) {
    :root {
        --max-width: calc(100vw - 11.5rem);
    }
}

@media (max-width: 70rem) {
    :root {
        --max-width: calc(100vw - 6rem);
    }
}

@media (max-width: 50rem) {
    :root {
        --max-width: calc(100vw - 3rem);
    }
}

/* The interval steps down with the screen: 8rem on desktop, 6rem on
   portrait tablets, where the page still needs room to breathe, and 4rem on
   phones. */
@media (max-width: 60rem) {
    :root {
        --interval: 6rem;
    }
}

@media (max-width: 40rem) {
    :root {
        --interval: var(--gap-l);
    }
}

/* #endregion */

/* #region Reset */

*,
*::before,
*::after {
    box-sizing: border-box;
}

body {
    margin: 0;
    min-height: 100vh;
}

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

/* #endregion */

/* #region Accessibility utilities */

/* Read by screen readers but not shown. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* #endregion */

/* #region Text utilities */

/* Keeps its contents on one line, such as a final word and its .accent-dot. */
.keep-together {
    white-space: nowrap;
}

/* #endregion */

/* #region Main site shell */

:root {
    --gap-xs: 1rem;
    --gap-s: 1.5rem;
    --gap-m: 2rem;
    --gap-ml: 3rem;
    --gap-l: 4rem;
}

.layout {
    width: 100%;
    max-width: var(--max-width);
    margin-inline: auto;
}

/* #region Cookie notice */

.cookie-notice-backdrop {
    position: fixed;
    inset: 0;
    z-index: 19;
    pointer-events: none;
    background: linear-gradient(0deg, var(--color--photo-sky-lighten-1-fade-98) 20%, var(--color--photo-sky-lighten-1-fade-0) 55%);
}

.cookie-notice-backdrop[hidden] {
    display: none;
}

.cookie-notice {
    position: fixed;
    z-index: 20;
    inset-inline-start: calc((100vw - var(--max-width)) / 2);
    inset-block-end: 0;
    width: min(30rem, var(--max-width));
    max-height: calc(100dvh - 2 * var(--gap-s));
    overflow-y: auto;
    padding: var(--gap-m);
    padding-block-start: var(--gap-s);
    border: 0;
    border-radius: var(--border-radius) var(--border-radius) 0 0;
    box-shadow:
        0 2rem 2.8rem 1.4rem var(--color--navy-fade-7),
        0 -0.5rem var(--gap-l) var(--color--navy-fade-7),
        0 0 0 0.0625rem var(--color--navy-fade-7);
}

.cookie-notice[hidden] {
    display: none;
}

.cookie-notice__title {
    margin: 0 0 var(--gap-xs);
}

.cookie-notice__copy {
    margin: 0 0 var(--gap-s);
}

.cookie-notice__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gap-s);
}

.cookie-notice__dismiss {
    border: 0;
    cursor: pointer;
}

.cookie-notice__link {
    text-decoration: none;
    text-underline-offset: 0.25rem;
}

.cookie-notice__link:hover {
    text-decoration: underline;
}

.cookie-notice__dismiss:focus-visible,
.cookie-notice__link:focus-visible {
    outline: var(--border-width) solid var(--color--rust);
    outline-offset: 0.25rem;
}

/* #endregion */

/* #region Photo strip */

.photo-strip {
    --photo-strip-columns: 5;

    display: grid;
    grid-template-columns: repeat(var(--photo-strip-columns), minmax(0, 1fr));
    overflow: hidden;
    border-radius: var(--border-radius);
    margin-block: var(--gap-xs) var(--gap-m);
}

.photo-strip__image {
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
}

@media (max-width: 40rem) {
    .photo-strip {
        --photo-strip-columns: 3;
    }

    .photo-strip__image--wide-only {
        display: none;
    }
}

/* #endregion */

.page-shell {
    --site-header-height: 7.5rem; /* 3rem + 2.5rem logo + 2rem padding */

    position: relative;
    overflow-x: clip; /* full-bleed 100vw elements must not add a horizontal scrollbar */
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.site-header {
    padding-block: 3rem 2rem;
}

/*
 * Stacking: the header itself stays unpositioned so it creates no stacking
 * context. The logo is lifted just above the hero (which reaches up behind the
 * header) but stays below the homepage .panel, so the panel covers it as it
 * scrolls up. The fixed .site-nav (z-index 10) sits above everything.
 */
.site-header__brand {
    position: relative;
    z-index: 1;
    display: flex; /* no inline line box, so the header is exactly --site-header-height tall */
    width: fit-content;
    color: inherit;
    text-decoration: none;
}

.site-header__logo {
    width: auto;
    height: 2.5rem;
}

/*
 * Main navigation: a solid pill in the top-right corner. On desktop it is
 * fixed, floating over the hero image and staying in view as the page
 * scrolls. Its top aligns with the logo, its right edge with the content
 * column. Its colour follows the background beneath it: js/nav-surface.js
 * reads the --nav-surface value (see the .nav-surface--* classes in
 * /css/colors.01e03d64862d7c76.css) under the pill and sets --site-nav-background, blending two
 * surfaces while a boundary passes behind it. Without JavaScript it uses the
 * inherited --nav-surface. Below 60rem it sits in the header flow. Below
 * 48rem it becomes a floating burger toggle in the top-right corner that
 * opens the links as a full-screen menu (see the mobile menu region below).
 */

.site-nav {
    position: fixed;
    top: 2.625rem; /* centres the pill on the logo */
    right: calc((100vw - var(--max-width)) / 2);
    z-index: 10;
    transform: translateY(calc(-1 * var(--site-nav-offset, 0px))); /* set by js/nav-surface.js as the footer pushes it away */
}

.site-nav__list {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin: 0;
    padding: 0.375rem;
    border-radius: 99rem;
    background-color: var(--site-nav-background, var(--nav-surface, var(--color--chalk-darken-1)));
    list-style: none;
    transition: background-color 120ms linear;
}

.site-nav__link,
.site-nav__button {
    display: inline-block;
    padding: 0.5rem 1.125rem;
    border-radius: 99rem;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color 180ms ease, color 180ms ease;
}

.site-nav__link {
    color: var(--site-nav-text, var(--nav-surface-text, var(--color--navy)));
}

/* Hover nudges the pill colour towards the link colour, so it works on light and dark surfaces. */
.site-nav__link:hover,
.site-nav__link:focus-visible {
    background-color: color-mix(in srgb, var(--site-nav-background, var(--nav-surface, var(--color--chalk-darken-1))), var(--site-nav-text, var(--nav-surface-text, var(--color--navy))) 9%);
}

.site-nav__button {
    background-color: var(--color--orange);
    color: var(--color--white);
}

.site-nav__button:hover,
.site-nav__button:focus-visible {
    background-color: var(--color--rust);
}

@media (prefers-reduced-motion: reduce) {
    .site-nav__list,
    .site-nav__link,
    .site-nav__button {
        transition: none;
    }
}

@media (max-width: 60rem) {
    .site-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--gap-s);
    }

    .site-nav {
        position: static;
    }

    .site-nav__list {
        background-color: var(--nav-surface, var(--color--chalk-darken-1));
    }
}

/* The menu toggle, the Home link and the fallback close link only appear in the mobile menu. */
.site-nav__toggle,
.site-nav__item--menu-only,
.site-nav__item--close {
    display: none;
}

/* #endregion */

/* #region Mobile menu */

/*
 * Below 48rem the navigation is a burger toggle that floats in the top-right
 * corner, its colours set by js/nav-surface.js like the desktop pill. It opens the
 * navigation list as a full-screen sky-wash menu: the list fades in, its links
 * rise into place one after another, and the toggle's two bars turn into a
 * cross. js/site-menu.js sets .is-open on the list, aria-expanded on the
 * toggle and .has-menu-open on <html>. Without JavaScript the toggle links to
 * #site-menu, so :target opens the menu, and a close link inside it closes it.
 * The logo stays visible above the open menu.
 */

@media (max-width: 48rem) {
    .site-header__brand {
        z-index: 11; /* above the open menu */
    }

    .site-nav {
        position: fixed;
        top: round(2.75rem, 1px); /* centres the toggle on the logo, on a whole pixel so its bars stay crisp */
        right: calc((100vw - var(--max-width)) / 2);
        transform: none; /* a transform would stop the menu inside it from filling the viewport */
    }

    .site-nav__toggle {
        --site-menu-toggle-open: 0;

        position: relative;
        z-index: 1; /* above the open menu */
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        /* Pixel sizes are a deliberate exception to rem units: the toggle and its
           bars sit on whole pixels, so both bars render at the same weight. */
        gap: 6px;
        width: 46px;
        height: 46px;
        border-radius: 99rem;
        color: var(--site-nav-text, var(--nav-surface-text, var(--color--navy)));
        transition: background-color 180ms ease, color 180ms ease;
    }

    /* No background at rest; hover shows a faint circle in the surface colour the desktop pill would use. */
    .site-nav__toggle:hover,
    .site-nav__toggle:focus-visible {
        background-color: var(--site-nav-background, var(--nav-surface, var(--color--chalk-darken-1)));
    }

    .site-nav__toggle[aria-expanded="true"] {
        --site-menu-toggle-open: 1;

        color: var(--color--navy);
    }

    .site-nav__toggle[aria-expanded="true"]:hover,
    .site-nav__toggle[aria-expanded="true"]:focus-visible {
        background-color: color-mix(in srgb, var(--color--sky-wash), var(--color--navy) 6%);
    }

    /* The two bars meet in the middle and rotate into a cross. */
    .site-nav__toggle-bar {
        --site-menu-toggle-bar-direction: 1;

        display: block;
        width: 20px;
        height: 2px;
        border-radius: 99rem;
        background-color: currentColor;
        transform:
            translateY(calc(var(--site-menu-toggle-open) * var(--site-menu-toggle-bar-direction) * 4px))
            rotate(calc(var(--site-menu-toggle-open) * var(--site-menu-toggle-bar-direction) * 45deg));
        transition: transform 300ms ease;
    }

    .site-nav__toggle-bar:last-child {
        --site-menu-toggle-bar-direction: -1;
    }

    .site-nav__list {
        --site-menu-open: 0;

        position: fixed;
        inset: 0;
        flex-direction: column;
        align-items: flex-start;
        gap: 0;
        padding: calc(var(--site-header-height) + var(--gap-l)) calc((100vw - var(--max-width)) / 2) var(--gap-l);
        overflow-y: auto;
        border-radius: 0;
        background-color: var(--color--sky-wash);
        visibility: hidden;
        opacity: 0;
        transition: opacity 300ms ease, visibility 0s linear 300ms;
    }

    .site-nav__list:target,
    .site-nav__list.is-open {
        --site-menu-open: 1;

        visibility: visible;
        opacity: 1;
        transition: opacity 300ms ease;
    }

    /* Each item rises into place as the menu opens, one after another. */
    .site-nav__item {
        opacity: var(--site-menu-open);
        transform: translateY(calc((1 - var(--site-menu-open)) * 1.5rem));
        transition: opacity 400ms ease, transform 600ms cubic-bezier(0.2, 0.7, 0.2, 1);
    }

    .site-nav__item:nth-child(2) {
        transition-delay: 50ms;
    }

    .site-nav__item:nth-child(3) {
        transition-delay: 100ms;
    }

    .site-nav__item:nth-child(4) {
        transition-delay: 150ms;
    }

    .site-nav__item--menu-only {
        display: block;
    }

    .site-nav__link {
        display: block;
        padding: 0.5rem 0;
        border-radius: 0;
        color: var(--color--navy);
    }

    .site-nav__link:hover,
    .site-nav__link:focus-visible {
        background-color: transparent;
        color: var(--color--rust);
    }

    .site-nav__button {
        margin-block-start: var(--gap-m);
    }

    /* The no-JavaScript close link, under the menu links. */
    .site-nav__item--close {
        display: block;
        margin-block-start: var(--gap-l);
    }

    .site-nav__item--close[hidden] {
        display: none;
    }

    .site-nav__close {
        color: var(--color--navy);
        text-underline-offset: 0.25rem;
    }
}

/* The page behind the open menu does not scroll. */
.has-menu-open {
    overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
    .site-nav__toggle,
    .site-nav__toggle-bar,
    .site-nav__list,
    .site-nav__item {
        transition: none;
    }
}

/* #endregion */

/* #region Buttons */

/* A solid Flock-orange call to action, such as "Join the Flock". */
.button {
    display: inline-block;
    padding: 0.875rem 1.5rem;
    border-radius: 99rem;
    background-color: var(--color--orange);
    color: var(--color--white);
    text-decoration: none;
    white-space: nowrap;
    transition: background-color 180ms ease;
}

.button:hover,
.button:focus-visible {
    background-color: var(--color--rust);
}

/*
 * A button with a leading plus sign, showing it opens more detail. Pair it
 * with .button--compact for the navigation's Join the Flock size.
 */
.button--plus {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    align-self: flex-start;
    border: 0;
    cursor: pointer;
}

/* The navigation's Join the Flock size, for buttons that sit beside body text. */
.button--compact {
    padding: 0.5rem 1.125rem;
}

.button--navy {
    background-color: var(--color--navy);
}

.button--navy:hover,
.button--navy:focus-visible {
    background-color: var(--color--navy-lighten-1);
}

/* A plus sign drawn in the button's text colour. */
.button__plus {
    position: relative;
    flex: none;
    width: 0.75rem;
    height: 0.75rem;
}

.button__plus::before,
.button__plus::after {
    position: absolute;
    top: 50%;
    left: 0;
    width: 100%;
    height: var(--border-width);
    background-color: currentColor;
    content: "";
    transform: translateY(-50%);
}

.button__plus::after {
    transform: translateY(-50%) rotate(90deg);
}

/*
 * Revealing buttons (set up by js/button-reveal.js, which adds
 * .button--reveal, splits the label into .button__char letters and toggles
 * .is-revealed as the button scrolls up the viewport). Collapsed, the button
 * is a circle holding the plus; revealed, it widens to the right and the
 * letters fade in one after another. --button-reveal (0 or 1) drives every
 * part, and delays apply only while revealing, so collapsing is quick.
 * Without JavaScript or with reduced motion it stays a normal button.
 */
.button--reveal {
    --button-reveal: 0;

    gap: calc(var(--button-reveal) * 0.5rem);
    padding-inline: 0.875rem calc(0.875rem + var(--button-reveal) * 0.25rem); /* a 2.5rem circle when collapsed */
    transition: background-color 180ms ease, opacity 180ms ease, gap 300ms cubic-bezier(0.2, 0.8, 0.2, 1), padding 300ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.button--reveal.is-revealed {
    --button-reveal: 1;
}

.button__label {
    display: block;
    max-width: calc(var(--button-reveal, 1) * var(--button-label-width, 20rem));
    overflow: hidden;
    white-space: nowrap;
    transition: max-width 320ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.button__char {
    display: inline-block;
    white-space: pre;
    opacity: var(--button-reveal, 1);
    transition: opacity 450ms ease;
    transition-delay: calc(var(--button-reveal, 1) * (120ms + var(--button-char-index, 0) * 45ms));
}

@media (prefers-reduced-motion: reduce) {
    .button,
    .button__label,
    .button__char {
        transition: none;
    }
}

/* #endregion */

/* #region Page structure */

.site-main {
    flex: 1;
    min-height: 100vh;
}

.site-footer {
    padding-block: var(--interval) 37.125rem; /* deliberately spacious below the footer on desktop */
}

.site-footer__grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    column-gap: calc(var(--gap-l) + 1rem); /* 5rem */
    row-gap: calc(var(--gap-l) - 0.5rem);
    align-items: start;
}

.site-footer__intro {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--gap-s);
}

.site-footer__intro {
    grid-column: 1 / span 2; /* the first two of five columns; the third stays empty */
    align-self: stretch; /* full row height, so the social links can sit at the bottom */
    row-gap: var(--gap-xs);
}

.site-footer__social {
    display: flex;
    flex-wrap: nowrap;
    width: 8.976rem;
    justify-content: space-between;
    align-items: center;
}

.site-footer__social--bottom {
    margin-top: auto;
    /* Centres the icons on the lettering of the last link row, and keeps the
       first icon's left edge in line with the text above. */
    transform: translate(0.08rem, 0.3rem);
}

.site-footer__social-item {
    --site-footer-social-translate-x: 0rem;
    display: inline-grid;
    width: 2rem;
    height: 2rem;
    place-items: center;
    color: inherit;
    opacity: 0.88;
    text-decoration: none;
    transform: translateX(var(--site-footer-social-translate-x)) scale(1.38);
}

.site-footer__social-item:hover,
.site-footer__social-item:focus-visible {
    color: var(--color--rust);
    opacity: 1;
}

.site-footer__social-item--instagram {
    --site-footer-social-translate-x: -0.4735rem;
}

.site-footer__social-item--facebook {
    --site-footer-social-translate-x: -0.2249rem;
}

.site-footer__social-item--linkedin {
    --site-footer-social-translate-x: 0.0238rem;
}

.site-footer__social-item--email {
    --site-footer-social-translate-x: 0.2725rem;
}

.site-footer__social-icon {
    display: block;
    width: 1.35rem;
    height: 1.35rem;
    transform: scale(0.833333);
}

.site-footer__social-icon--instagram {
    width: 1.404rem;
    height: 1.404rem;
}

.site-footer__social-icon--linkedin,
.site-footer__social-icon--email {
    width: 1.0125rem;
    height: 1.0125rem;
}

.site-footer__intro p,
.site-footer__copyright {
    margin-block: 0;
}

.site-footer__group {
    min-width: 0;
}

.site-footer__group--offset {
    grid-column-start: 4; /* after the empty third column */
}

.site-footer__heading {
    margin: 0;
}

.site-footer__list {
    display: grid;
    gap: var(--gap-xs);
    margin: var(--gap-xs) 0 0;
    padding: 0;
    list-style: none;
}

.site-footer__copyright {
    margin-top: var(--gap-xs);
}

.site-footer__legal-links {
    white-space: nowrap;
}

.site-footer__link {
    position: relative;
    display: inline-block;
    color: inherit;
    text-decoration: none;
    white-space: nowrap;
    transition: color 180ms ease;
}

.site-footer__link::after {
    position: absolute;
    right: 0;
    bottom: 0.0375rem;
    left: 0;
    height: var(--underline-width);
    background-color: currentColor;
    content: "";
    opacity: 0;
    pointer-events: none;
    transition: opacity 180ms ease;
}

.site-footer__link:hover,
.site-footer__link:focus-visible {
    color: var(--color--rust);
}

.site-footer__link:hover::after,
.site-footer__link:focus-visible::after {
    opacity: 1;
}

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

@media (max-width: 70rem) {
    .site-footer__grid {
        column-gap: calc(var(--gap-m) + 1.5rem); /* 3.5rem */
    }
}

@media (max-width: 60rem) {
    .site-footer__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .site-footer__intro {
        grid-column: 1 / -1;
    }

    .site-footer__group--offset {
        grid-column-start: auto;
    }
}

@media (max-width: 40rem) {
    .site-footer {
        padding-block-end: var(--gap-l);
    }

    .site-footer__grid {
        grid-template-columns: minmax(0, 1fr);
        row-gap: 0;
    }

    .site-footer__intro {
        position: relative;
        grid-column: 1 / -1;
        padding-block: var(--gap-s) calc(var(--gap-s) + 0.5rem);
    }

    .site-footer__group {
        position: relative;
        padding-block: var(--gap-s);
    }

    .site-footer__group::before {
        position: absolute;
        top: 0;
        right: 0;
        left: 0;
        height: var(--border-width);
        background-color: var(--color--grey-lighten-1);
        content: "";
    }
}

@media (min-width: 26rem) and (max-width: 40rem) {
    .site-footer__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: 2rem;
        justify-content: space-between;
    }

    .site-footer__intro {
        grid-column: 1 / -1;
    }
}

/* #endregion */

/* #region Hero */

/*
 * Large left-aligned text beside a full-height image.
 *
 * On desktop the hero is the page intro: it reaches up behind the site header
 * so its full-bleed background and its image (the right half of the viewport,
 * 50vw by the hero's full height) start at the top of the page. It is marked
 * data-scroll-progress="intro", so js/scroll-progress.js sets
 * --scroll-progress-intro on :root from 0 (top of page) to 1 (scrolled one
 * hero height). As it rises, the hero and the header logo lag behind at
 * half speed (.scroll-lag) while the next section scrolls up over them, and the hero
 * fades to a soft blue on a mid light blue: a low-contrast version of itself.
 *
 * Below 60rem the text comes first and the image spans the full width
 * beneath it, with no lag or fade.
 */

.hero {
    --hero-fade: min(1, calc(var(--scroll-progress-intro, 0) * 3)); /* fully faded a third of the way through */
    --accent-dot-fade: min(1, calc(var(--scroll-progress-intro, 0) * 4)); /* the orange dot goes early */

    position: relative;
    isolation: isolate;
    display: flex;
    align-items: center;
    min-height: var(--screen-height);
    margin-block-start: calc(-1 * var(--site-header-height));
    padding-block: calc(var(--site-header-height) + var(--gap-l)) calc(var(--gap-l) + var(--interval)); /* extra bottom padding lifts the text above centre */
    color: color-mix(in srgb, var(--color--navy), var(--color--denim-lighten-1) calc(var(--hero-fade) * 100%));
}

.hero::before {
    position: absolute;
    z-index: -1;
    inset-block: 0;
    inset-inline: calc(50% - 50vw);
    background-color: color-mix(in srgb, var(--color--chalk), var(--color--sky-wash-darken-1) calc(var(--hero-fade) * 100%));
    content: "";
}

.hero__content {
    display: flex;
    flex-direction: column;
    gap: var(--gap-m);
    max-width: calc(var(--max-width) / 2 - var(--gap-l));
}

.hero__title,
.hero__subtitle {
    margin: 0;
}

/* A call to action under the hero text, shown only on phones and small
   tablets, where the navigation's button moves into the menu. */
.hero__action {
    display: none;
    align-self: flex-start;
}

/* A hero action shown at every width, such as the thank-you page's link home. */
.hero__action--always {
    display: inline-block;
}

/* A title whose longer line is wider than the homepage's (see the phone
   sizing below), such as "getting in touch." at 10.27em. */
.hero__title--long {
    --hero-title-ems: 10.4;
}

@media (max-width: 48rem) {
    .hero__action {
        display: inline-block;
    }

    /* On phones the title is always two lines, "You're going to / run a
       great pub.", as large as the width allows: the longer line measures
       9.62em with its accent dot, so the size is the content width over 9.7
       (a hair of slack). A page with a longer line sets --hero-title-ems on
       the title to that line's width in ems. */
    .hero__title {
        --display-fontsize: calc(var(--max-width) / var(--hero-title-ems, 9.7));
    }

    .hero__line {
        display: block;
        white-space: nowrap;
    }
}

.hero__media {
    position: absolute;
    top: 0;
    right: calc(50% - 50vw);
    width: 50vw;
    max-width: none;
    height: 100%; /* the hero's full height, however tall its text makes it */
    object-fit: cover;
    -webkit-user-drag: none; /* the photo cannot be dragged out of the page */
    user-select: none;
    opacity: calc(1 - var(--hero-fade) * 0.75); /* fades into the hero background */

    /* The navigation over the photo fades with it, staying a slightly brighter
       shade of the sky, on the same curve as the photo's opacity. */
    --nav-surface: color-mix(in srgb, var(--color--photo-sky-lighten-1), color-mix(in srgb, var(--color--sky-wash-darken-1), var(--color--white) 30%) calc(var(--hero-fade) * 75%));
}

/* Paint the photo's sky even before its pixels arrive. */
.hero__media--sky {
    background-color: var(--color--photo-sky);
}

/* The navigation over a warm (peach) hero photo takes a pale peach pill
   rather than the sky one. */
.hero__media--warm {
    --nav-surface: color-mix(in srgb, var(--color--peach), var(--color--white) 45%);
}

/* A down arrow in the hero's lower left that bobs to invite scrolling and
   jumps to the next section when clicked. It fades with the hero. */
.hero__scroll {
    position: absolute;
    bottom: calc(var(--gap-l) + var(--gap-m) - 0.5rem);
    left: -0.5rem; /* the arrowhead's outer edge starts about 3 of 18 units in; line it up with the text */
    display: block;
    padding: 0.5rem;
    margin: -0.5rem; /* a larger click target without moving the arrow */
    opacity: calc(1 - var(--hero-fade));
    transition: opacity 180ms ease;
}

.hero__scroll:hover {
    opacity: 0.7;
}

.hero__scroll-icon {
    display: block;
    width: 3rem;
    height: 3rem;
}

.hero__scroll-strip {
    position: absolute;
    bottom: 0;
    inset-inline: calc(50% - 50vw);
    height: 2.25rem;
    pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
    .hero__scroll-icon {
        animation: hero-scroll-bob 8.3s ease-in-out infinite;
    }

    .hero__scroll-strip {
        transform-origin: bottom;
        animation: hero-strip-bob 8.3s ease-in-out infinite;
    }
}

@keyframes hero-scroll-bob {
    /* Two 0.8-second bounces; the strip reveals during the second. */
    0%,
    9.638554%,
    19.277108%,
    100% {
        transform: translateY(0);
    }

    4.819277%,
    14.457831% {
        transform: translateY(1.75rem);
    }
}

@keyframes hero-strip-bob {
    /* Reveal during the second bounce over 0.8s, hold for 0.5s, collapse over
       1.2s, then remain fully hidden for five seconds. */
    0%,
    9.638554%,
    39.759036%,
    100% {
        transform: scaleY(0);
    }

    19.277108%,
    25.301205% {
        transform: scaleY(1);
    }
}

@media (max-width: 60rem) {
    .hero {
        --hero-fade: 0;
        --accent-dot-fade: 0;

        flex-direction: column;
        align-items: stretch;
        gap: var(--gap-l);
        min-height: 0;
        margin-block-start: 0;
        padding-block: var(--gap-l) 0; /* the image runs straight into the next section */
    }

    .hero__content {
        max-width: none;
    }

    .hero__scroll {
        display: none;
    }

    .hero__scroll-strip {
        display: none;
    }

    .hero__media {
        position: static;
        width: 100vw;
        height: 60vh;
        margin-inline: calc(50% - 50vw);
    }
}

/* #endregion */

/* #region Scroll lag */

/*
 * Elements with .scroll-lag move down at half the scroll speed while the page
 * intro scrolls away, so later content overlaps them. Desktop only, and off
 * for people who prefer reduced motion. Do not put it on an ancestor of the
 * fixed site navigation: a transform would make the navigation scroll too.
 */

@media (min-width: 60.0625rem) and (prefers-reduced-motion: no-preference) {
    .scroll-lag {
        transform: translateY(calc(var(--scroll-progress-intro, 0) * 50vh));
    }
}

/* #endregion */

/* #region Panel */

/*
 * A full-bleed block of page content. It stacks above the page intro, so on
 * desktop it slides up over the lagging hero.
 */

.panel {
    position: relative;
    z-index: 1;
    min-height: var(--screen-height);
    margin-inline: calc(50% - 50vw);
}

/* #endregion */

/* #region Section */

/* A major band of page content, spaced by the section interval. */
.section {
    padding-block: var(--interval);
}

/* Extra room above a section's title, so it clears the floating navigation
   when the section fills the viewport. */
.section--clear-nav {
    padding-block-start: calc(var(--interval) + 1.5rem);
}

/* A full-width opening heading, such as an all-caps display line, above the section's content. */
.section__title {
    max-width: 31.1ch; /* about 31 capitals a line: "From day one, here's what you'll / never have to worry about." and "Independence comes with / hidden costs and stress." */
    margin: 0 0 var(--gap-l);
}

/* #endregion */

/* #region Tiles */

/*
 * A grid of tiles on a dark ground: each is outlined in a lighter navy, with an
 * orange title, a strong lead line and a quieter, muted note. All tiles
 * share the tallest tile's height.
 * A --closing tile is filled with the pale denim photo and carries a closing
 * statement with the navy Flock birds, to finish the set.
 */

.tile-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-auto-rows: 1fr; /* every tile as tall as the tallest */
    gap: var(--gap-m);
    margin-block: calc(var(--interval) - 1.5rem); /* on desktop, a little under an interval after the section title (its smaller margin collapses into this) and after the grid */
    margin-inline: 0;
    padding: 0;
    list-style: none;
}

.tile {
    display: flex;
    flex-direction: column;
    gap: var(--gap-xs);
    min-height: 13rem;
    padding: 1.75rem;
    border: 0.1875rem solid var(--color--navy-lighten-1); /* an outline rather than a fill */
    border-radius: var(--border-radius);
}

.tile__title,
.tile__lead,
.tile__note,
.tile__statement {
    margin: 0;
}

/* Trim the title's line box to its cap height (Manrope: ascent 1.066em, descent
   0.3em, cap height 0.735em), so the tile's top padding reads the same as its
   side padding. */
.tile__title {
    margin-block-start: calc(-1 * ((1lh - 1.366em) / 2 + 0.331em));
}

.tile__statement {
    margin-block-end: calc(-1 * ((1lh - 1.366em) / 2 + 0.3em)); /* the last baseline sits on the bottom padding */
    line-height: 1.15; /* tighter than the subtitle role, as a two-line display line */
}

.tile--closing {
    position: relative;
    justify-content: flex-end;
    border-color: transparent;
    background: linear-gradient(color-mix(in srgb, var(--color--sky-wash) 40%, transparent) 0 0), var(--color--sky-wash) url("/images/processed/denim-4.1d486314252eb482.png") center / cover; /* faded a little into the sky wash */
}

.tile__birds {
    position: absolute;
    top: 1.75rem; /* the tile's padding */
    right: 1.75rem;
    width: auto;
    height: 5rem;
}

@media (max-width: 60rem) {
    .tile-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--gap-m);
        margin-block: var(--interval);
    }
}

/* On phones the tiles pack into two columns and drop their outlines and
   padding, so only the gaps between them separate the text. Titles drop to
   the body text size. The denim tile keeps its padding. Below 22.5rem it is
   one column. */
@media (max-width: 40rem) {
    .tile-grid {
        grid-auto-rows: auto; /* without outlines, rows need only fit their own text */
        gap: 2.5rem var(--gap-s);
    }

    .tile {
        gap: 0.5rem;
        min-height: 0;
        padding: 0;
        border: 0;
    }

    .tile__title {
        font-family: var(--bodytext-fontfamily);
        font-size: var(--bodytext-fontsize);
        line-height: var(--bodytext-lineheight);
        font-weight: var(--bodytext-fontweight-strong);
        letter-spacing: var(--bodytext-letterspacing);
    }

    .tile__lead {
        font-weight: var(--bodytext-fontweight);
    }

    .tile--closing {
        min-height: 15rem; /* room for the birds above the statement */
        padding: var(--gap-s) 1.25rem var(--gap-m); /* a touch wider at the sides, deeper below */
        background: linear-gradient(color-mix(in srgb, var(--color--sky-wash) 40%, transparent) 0 0), var(--color--sky-wash) url("/images/processed/denim-4.1d486314252eb482.png") center / cover; /* faded a little into the sky wash */
    }

    .tile__birds {
        top: var(--gap-s);
        right: 1.25rem;
        height: 4.5rem;
    }

    .tile__statement {
        font-size: calc(var(--bodytext-fontsize) * 1.15);
    }
}

@media (max-width: 22.4375rem) {
    .tile-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* #endregion */

/* #region Split */

/*
 * An introduction beside its content: the introduction takes a little under
 * half the width (5 : 6) and stays in view (sticky) while the content beside
 * it scrolls past. Below 60rem they stack.
 */

.split {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    align-items: start;
    gap: var(--gap-l);
}

.split__intro {
    position: sticky;
    top: var(--gap-l);
    grid-column: 1;
    display: flex;
    flex-direction: column;
    gap: var(--gap-l); /* as between the section title and this text */
}

.split__text {
    margin: 0;
}

.split__content {
    grid-column: 2;
}

/* A section title inside the intro column: the column's gap spaces it. */
.split__title {
    margin: 0;
}

@media (max-width: 70rem) {
    .split {
        gap: var(--gap-m);
    }
}

@media (max-width: 60rem) {
    .split {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--gap-l);
    }

    .split__intro {
        position: static;
    }

    .split__intro,
    .split__content {
        grid-column: auto;
    }
}

/* #endregion */

/* #region Cards */

/* A grid of cards, each a square photo with a heading and short text. */

.card-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gap-l) var(--gap-ml); /* 3rem between columns; phones narrow it below */
    margin: 0;
    padding: 0;
    list-style: none;
}

.card {
    display: flex;
    flex-direction: column;
    gap: var(--gap-xs);
}

.card__media {
    position: relative; /* frames an absolutely placed .tracing */
    aspect-ratio: 1;
    margin-block-end: var(--gap-xs);
    overflow: hidden;
    border-radius: var(--border-radius);
    background-color: var(--color--sky-wash); /* shows until the photo loads */
}

.card__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.card__title,
.card__text {
    margin: 0;
}

@media (max-width: 40rem) {
    /* Two photos per row on medium and large phones, set a little closer together. */
    .card-grid {
        gap: var(--gap-m) var(--gap-xs);
    }
}

/* Small phones (under 360px wide) show one card per row. */
@media (max-width: 22.4375rem) {
    .card-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* #endregion */

/* #region Tracing */

/*
 * A photo with a hand-drawn SVG tracing registered on top of it. The image
 * and the inline SVG share one wrapper with the photo's own aspect ratio (the
 * SVG viewBox is the photo's pixel size), so the drawing always lines up.
 * Any crop is applied to that wrapper as a whole: inside a square frame such
 * as .card__media, a tall photo is centred vertically, or held near the top
 * with --focus-top. js/photo-tracing.js draws the lines on as the photo
 * scrolls into view and redraws them each time it returns; without
 * JavaScript, or with reduced motion, the drawing is simply shown.
 */

.tracing {
    position: absolute;
    top: 50%;
    left: 0;
    width: 100%;
    transform: translateY(-50%);
}

.tracing--focus-top {
    top: 15%;
    transform: translateY(-15%);
}

.tracing__image {
    width: 100%;
    height: auto;
}

.tracing__lines {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    pointer-events: none;
}

/* #endregion */

/* #region Showcase */

/*
 * A large phone in the middle of the page with short annotations either side.
 * A light blue band runs behind the middle of the section, so the phone
 * overlaps it above and below. The section is marked
 * data-scroll-progress="showcase" with data-scroll-progress-range="pass", so
 * --scroll-progress-showcase runs from 0 as the section enters at the bottom
 * of the viewport, through 0.5 when it is centred, to 1 as it leaves at the
 * top. On desktop, the phone's offset follows a cubic of that progress: it
 * rushes in from far below, much faster than the page scrolls, all but stops
 * while the section is centred, then rushes out upwards. In the stacked
 * mobile layout, it scrolls with the page without an additional offset.
 */

.showcase {
    position: relative;
    isolation: isolate;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    gap: var(--gap-l);
    /* No padding of its own on desktop: the phone sits one interval below the
       previous section's content and one interval above the footer, so the
       usual section spacing reads the same even though the band is tinted. */
    padding-block: 0;
}

.showcase__band {
    position: absolute;
    z-index: -1;
    inset-block: 19%;
    inset-inline: calc(50% - 50vw);
}

/* Trial: a denim photo behind the band instead of the flat sky wash, which
   stays underneath as the colour while it loads. The photo is framed twice,
   once in each half of the band, so its weave is finer and nearer the
   phone's scale. */
.showcase__band--denim::before,
.showcase__band--denim::after {
    position: absolute;
    inset-block: 0;
    width: 50%;
    background-image:
        linear-gradient(color-mix(in srgb, var(--color--sky-wash) 60%, transparent) 0 0), /* mostly faded into the sky wash */
        url("/images/processed/denim-4.1d486314252eb482.png");
    background-position: center;
    background-size: cover;
    content: "";
}

.showcase__band--denim::before {
    left: 0;
}

.showcase__band--denim::after {
    right: 0;
}

.showcase__notes {
    display: flex;
    flex-direction: column;
    gap: var(--gap-l);
    margin: 0;
    padding: 0;
    list-style: none;
}

@media (min-width: 48.0625rem) and (prefers-reduced-motion: no-preference) {
    .showcase__device {
        --showcase-travel: calc(1 - 2 * var(--scroll-progress-showcase, 0.5)); /* 1 → 0 → -1 */

        transform: translateY(calc(var(--showcase-travel) * var(--showcase-travel) * var(--showcase-travel) * 70vh));
    }
}

@media (max-width: 48rem) {
    .showcase {
        grid-template-columns: minmax(0, 1fr);
        justify-items: center;
        padding-block: var(--interval);
    }

    .showcase__band {
        inset-block: 30%;
    }
}

/* #endregion */

/* #region Device */

/*
 * A phone drawn from a transparent frame image, with its screen behind the
 * frame. Put content (such as a UI mockup) inside .device__screen; until it
 * loads, the screen shows as switched off. .device__embed fills the screen
 * with a page, such as the self-contained operator app mockup, whose own
 * styles stay inside the iframe.
 */

.device {
    position: relative;
    width: 24.2rem; /* a little larger than real size on a typical laptop screen */
    aspect-ratio: 971 / 2000;
}

.device__screen {
    position: absolute;
    inset: 1.6% 3.9%;
    overflow: hidden;
    border-radius: 13% / 6.3%;
    background-color: var(--color--screen-off);
}

.device__embed {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
}

/* Set by js/device-fit.js: the iframe keeps the mockup's 402 x 874 design
   viewport (px, as the app inside is drawn for exactly that screen) and is
   scaled to fill the screen, so zooming the page scales the app as one
   piece instead of reflowing it. */
.device__embed--fitted {
    width: 402px;
    height: 874px;
    transform: scale(var(--device-embed-scale, 1));
    transform-origin: 0 0;
}

.device__frame {
    position: relative;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

@media (max-width: 48rem) {
    .device {
        width: min(17rem, 72vw);
    }
}

/* #endregion */

/* #region Annotations */

/*
 * A short note beside a feature image, with a leader line pointing towards it.
 * --start notes sit to the left of the image (right-aligned), --end notes to
 * the right. Below 48rem they stack without lines.
 */

.annotation {
    position: relative;
    max-width: 18rem;
}

.annotation--start {
    justify-self: end;
    margin-inline-start: auto;
    text-align: end;
}

.annotation__title,
.annotation__text {
    margin: 0;
}

.annotation__title {
    margin-block-end: 0.375rem;
    font-weight: 700; /* bolder than the navy text beneath it */
}

.annotation::after {
    position: absolute;
    top: calc((var(--bodytext-lineheight) - 0.1875rem) / 2); /* centred on the title's first line */
    width: calc(var(--gap-l) - 0.75rem);
    height: 0.1875rem; /* 3px, heavy enough to read over the denim */
    background-color: currentColor; /* the same colour as the note's text */
    content: "";
}

.annotation--start::after {
    left: calc(100% + 0.75rem);
}

.annotation--end::after {
    right: calc(100% + 0.75rem);
}

@media (max-width: 48rem) {
    .annotation,
    .annotation--start {
        margin-inline: auto;
        text-align: center;
    }

    .annotation::after {
        content: none;
    }

    /* Stacked, only the first and last notes stay, so each sits right by
       the phone. */
    .annotation--wide-only {
        display: none;
    }
}

/* #endregion */

/* #region Lockup */

/*
 * An oversized wordmark in the middle of the page, hugged by an all-caps
 * headline on its left and supporting text with a call to action on its
 * right. Everything is sized from the wordmark: the flat tops and bottoms of
 * its F, L and K (134 of its 138.61 units, with the round O and C
 * overshooting 2.3 units at each end) set --lockup-height, and the
 * headline's three lines are sized so the first line's cap height starts and
 * the last line's baseline ends exactly on those edges. The supporting
 * text's first line starts on the same top edge; the button follows it.
 *
 * The trims use Manrope's metrics: ascent 1.066em, descent 0.3em and cap
 * height 0.735em. Half the leading, (1lh - 1.366em) / 2, sits above the
 * ascent and below the descent, so a line's cap height starts
 * (1lh - 1.366em) / 2 + 0.331em below its top and its baseline sits
 * (1lh - 1.366em) / 2 + 0.3em above its bottom. Keep the headline to three
 * short lines, one per .lockup__line. The headline is set heavy and wide,
 * well beyond the section headings.
 */

.lockup {
    --lockup-mark-width: calc(var(--max-width) * 0.44);
    --lockup-height: calc(var(--lockup-mark-width) * 134 / 620.66);
    --lockup-overshoot: calc(var(--lockup-height) * 2.3 / 134);
    --lockup-lines: 3;
    --lockup-lineheight: 0.94; /* tight, so the lines sit close and the type grows */
    --lockup-headline-fontsize: calc(var(--lockup-height) / (var(--lockup-lineheight) * (var(--lockup-lines) - 1) + 0.735));

    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: start;
    gap: var(--gap-m);
    padding-block: calc(var(--interval) * 2) var(--interval); /* two intervals of air on each side: the showcase has no padding below, and the footer adds its own interval */
}

.lockup__headline {
    justify-self: end;
    margin-block: calc(var(--lockup-overshoot) - (1lh - 1.366em) / 2 - 0.331em) 0; /* start at the cap height */
    margin-inline: 0 calc(0.5rem - 0.12em); /* drop the last letter's tracking; sit 2.5rem from the wordmark */
    font-family: var(--section-fontfamily);
    font-size: var(--lockup-headline-fontsize);
    line-height: var(--lockup-lineheight);
    font-weight: 760;
    letter-spacing: 0.12em;
    text-align: end;
    text-transform: var(--section-texttransform);
    white-space: nowrap;
}

.lockup__line,
.lockup__text-line {
    display: block;
}

.lockup__mark {
    display: block;
    width: var(--lockup-mark-width);
    height: auto;
}

.lockup__aside {
    display: flex;
    flex-direction: column;
    justify-content: space-between; /* the button's bottom sits on the wordmark's baseline */
    align-items: flex-start;
    gap: var(--gap-xs);
    height: calc(var(--lockup-overshoot) + var(--lockup-height));
}

.lockup__text {
    white-space: nowrap; /* one line per .lockup__line */
    margin: calc(var(--lockup-overshoot) - (1lh - 1.366em) / 2 - 0.331em) 0 0; /* start at the cap height */
}

/* Between 71rem and 80rem the full lockup holds on: the wordmark stays at
   36.75rem, the smallest that still holds the three lines and the button
   beside it, the three parts pack together in the centre, and the lockup may
   run into the page's side margins, up to 1.5rem from the viewport edge. */
@media (min-width: 71rem) and (max-width: 79.9375rem) {
    .lockup {
        --lockup-mark-width: 36.75rem;

        grid-template-columns: auto auto auto;
        justify-content: center;
        margin-inline: calc(50% - 50vw + 1.5rem);
    }
}

/* Below 71rem the wordmark is too short to hold three lines of text and the
   button beside it, so the headline and wordmark stay locked up and the text
   and button drop to a second row. The pair fills the content width: the
   headline's box is 6.72em wide at a size of the lockup height over 2.615,
   about 0.555 of the wordmark's width, so the wordmark takes the width left
   after the gap, over 1.56 (a little slack). */
@media (max-width: 70.9375rem) {
    .lockup {
        --lockup-mark-width: calc((var(--max-width) - 2.5rem) / 1.56);

        grid-template-columns: auto auto;
        row-gap: var(--gap-l);
    }

    /* The text and button join the lockup's grid: the text sits under the
       headline, right-aligned to its last letters (0.5rem in from the column,
       like the headline), and the button sits under the F, its top level
       with the top of the text's capitals. */
    .lockup__aside {
        display: contents;
    }

    .lockup__text {
        grid-column: 1;
        justify-self: end;
        margin: calc(-1 * ((1lh - 1.366em) / 2 + 0.331em)) 0.6rem 0 0; /* start at the cap height; inset by the headline's 0.5rem plus the full stop's overhang */
        text-align: end;
    }

    .lockup__action {
        grid-column: 2;
        align-self: start;
        justify-self: start;
    }
}

/* Below 48rem everything stacks: the wordmark, then the headline as an
   ordinary section heading, then the text and button. */
@media (max-width: 48rem) {
    .lockup {
        grid-template-columns: minmax(0, 1fr);
        justify-items: start;
        gap: var(--gap-m);
    }

    .lockup__mark {
        order: -1;
        margin-block-end: var(--gap-m); /* with the grid gap, 4rem between the wordmark and the words */
    }

    .lockup__headline {
        justify-self: start;
        margin: 0;
        font-size: var(--section-fontsize);
        line-height: var(--section-lineheight);
        font-weight: var(--section-fontweight);
        letter-spacing: var(--section-letterspacing);
        text-align: start;
        white-space: normal;
    }

    .lockup__line {
        display: inline;
        white-space: nowrap; /* wrap between the lines, never inside one */
    }

    .lockup__aside {
        display: flex;
        grid-column: auto;
        gap: var(--gap-s);
        height: auto;
    }

    .lockup__text {
        grid-column: auto;
        justify-self: start;
        margin: 0;
        text-align: start;
        white-space: normal;
    }

    .lockup__action {
        grid-column: auto;
        align-self: flex-start;
    }

    .lockup__text-line {
        display: inline;
    }
}

/* On phones the wordmark runs full bleed: the F starts 0.25rem past the
   viewport's left edge, so no sliver of background shows beside it on any
   device, and the K runs a few pixels past the right edge. */
@media (max-width: 48rem) {
    /* The section spans the viewport and clips the K's overhang itself, so
       the page never scrolls sideways. */
    .lockup {
        --lockup-mark-width: calc(100vw + 0.625rem);

        overflow-x: clip;
        margin-inline: calc(50% - 50vw);
        padding-inline: calc(50vw - 50%);
    }

    .lockup__mark {
        max-width: none;
        margin-inline-start: calc(50% - 50vw - 0.25rem);
    }
}

/* #endregion */

/* #region Tour notch */

/*
 * The countdown "notch" shown only in homepage tour mode (js/tour-mode.js,
 * opened with #tour): an orange tab fixed to the bottom of the screen, its
 * top corners rounded like a phone's notch turned upside down.
 */
:root {
    --tour-notch-colour: var(--color--orange);
    --tour-stripe-height: 1rem;
}

.tour-notch {
    position: fixed;
    z-index: 20;
    bottom: 0;
    left: 50%;
    padding: 0.5rem 2.75rem 0.75rem; /* tight around the numbers */
    border-radius: 3rem 3rem 0 0;
    background-color: var(--tour-notch-colour);
    color: var(--color--white);
    font-family: var(--nav-fontfamily);
    font-size: calc(var(--subtitle-fontsize) * 2.25); /* large enough to read across a room */
    line-height: 1;
    font-weight: var(--nav-fontweight);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.06em;
    transform: translateX(-50%);
}

/* The notch rises out of an orange stripe along the bottom of the screen,
   with inward curves where they meet. */
.tour-notch::before,
.tour-notch::after {
    position: absolute;
    bottom: var(--tour-stripe-height);
    width: 1.5rem;
    height: 1.5rem;
    content: "";
}

.tour-notch::before {
    right: calc(100% - 1px); /* overlaps the notch by a pixel, so no seam shows */
    background: radial-gradient(circle at 0 0, transparent 1.5rem, var(--tour-notch-colour) calc(1.5rem + 0.5px));
}

.tour-notch::after {
    left: calc(100% - 1px);
    background: radial-gradient(circle at 100% 0, transparent 1.5rem, var(--tour-notch-colour) calc(1.5rem + 0.5px));
}

.tour-stripe {
    position: fixed;
    z-index: 20;
    right: 0;
    bottom: 0;
    left: 0;
    height: var(--tour-stripe-height);
    background-color: var(--tour-notch-colour);
}

.tour-notch--done,
.tour-stripe--done {
    --tour-notch-colour: var(--color--rust); /* darkens once the countdown reaches zero */
}

/* #endregion */

/* #region Legal pages */

.legal-page {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    align-items: start;
    gap: var(--gap-l);
    margin-block: var(--interval);
}

.legal-page__introduction {
    position: sticky;
    top: var(--gap-m);
    grid-column: 1 / span 2;
}

.legal-page__heading {
    margin: 0;
}

.legal-page__summary {
    max-width: 24rem;
    margin: var(--gap-m) 0 0;
}

.legal-page__updated {
    margin: var(--gap-s) 0 0;
}

.legal-copy {
    grid-column: 3 / -1;
    width: min(100%, 48rem);
    overflow-wrap: anywhere;
}

.legal-copy__section {
    margin-block-start: calc(var(--bodytext-lineheight) * 2);
}

.legal-copy__section:first-child {
    margin-block-start: 0;
}

.legal-copy__heading {
    margin: 0 0 var(--bodytext-lineheight);
}

.legal-copy__paragraph {
    margin: 0 0 var(--bodytext-lineheight);
}

.legal-copy__paragraph:last-child {
    margin-block-end: 0;
}

.legal-copy__list {
    margin-block: var(--bodytext-lineheight);
    padding-inline-start: var(--gap-s);
}

.legal-copy__link {
    color: var(--color--rust);
    text-decoration-thickness: var(--border-width);
    text-underline-offset: 0.25rem;
}

.legal-copy__link:hover,
.legal-copy__link:focus-visible {
    color: var(--color--navy);
}

@media (max-width: 70rem) {
    .legal-page {
        gap: var(--gap-m);
    }
}

@media (max-width: 60rem) {
    .legal-page {
        grid-template-columns: minmax(0, 1fr);
    }

    .legal-page__introduction {
        position: static;
    }

    .legal-page__introduction,
    .legal-copy {
        grid-column: auto;
    }

    .legal-page__summary {
        max-width: 42rem;
    }
}

/* #endregion */
