/* ═══════════════════════════════════════════════════════════════════════
 * Site-wide stylesheet — reset, typography, chrome.
 *
 * (This file previously carried a comment saying it was intentionally
 * empty pending D17. D17 is now decided — handwritten CSS, no framework,
 * mobile and desktop — so that comment has been replaced by this one
 * rather than left to mislead.)
 *
 * Everything here is site chrome: the reset, the type, the page column,
 * buttons, header and footer. The home page's individual sections live in
 * sections.css, so a change to one section cannot accidentally restyle
 * the whole site.
 *
 * Mobile first. Base rules are the phone layout; `min-width` queries add
 * the wider ones. That ordering is not a style preference — a phone then
 * only parses the rules it needs, and the narrow layout is the one that
 * cannot be skipped, so it is the one written first.
 *
 * Every value resolves to a token from tokens.css. If you are about to
 * type a hex code or a pixel value here, it probably belongs there.
 * ═══════════════════════════════════════════════════════════════════════ */

/* ── Reset ─────────────────────────────────────────────────────────────
   Deliberately small. A full normalise.css mostly corrects browsers this
   site does not support; these are the handful of defaults that actually
   get in the way. */

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

body,
h1, h2, h3, h4, h5, h6,
p, figure, blockquote, dl, dd, ul, ol {
    margin: 0;
}

ul[class],
ol[class] {
    /* Only lists that are being used as layout — nav, card grids. A list
       inside editor rich text keeps its bullets.

       Anything relying on this has to actually carry a class; `.list-reset`
       exists for lists that need the reset and have nothing else to say.
       A bare <ul> in a nav quietly keeps its markers, which is how a
       stray bullet appeared in front of the footer's legal links. */
    padding: 0;
    list-style: none;
}

img,
picture,
svg {
    display: block;
    max-width: 100%;
    height: auto;
}

/* A <picture> (D98: the WebP version in front of the original) must not
   change the layout: with no box of its own, the <img> inside lays out
   exactly as if it were the element's direct child, so every rule that
   sizes or positions a picture keeps working through it. Selectors that
   name `> img` still need `> picture > img` beside them, because
   `display: contents` changes boxes, not the DOM. It comes after the
   reset above, which lists `picture` as a block, so that it wins. */
picture {
    display: contents;
}

button,
input,
select,
textarea {
    font: inherit;
    color: inherit;
}

/* Honour a visitor who has asked their OS for less motion. Not optional:
   vestibular disorders make parallax and long transitions genuinely
   unpleasant, and this is the one line that respects that. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ── Page ──────────────────────────────────────────────────────────── */

html {
    /* An in-page anchor lands below the sticky header rather than under
       it. Kept next to the header's own height token so the two cannot
       drift apart. */
    scroll-padding-top: 6rem;
}

body {
    margin: 0;
    background: var(--colour-white);
    color: var(--colour-text);
    font-family: var(--font-body);
    font-size: var(--text-base);
    font-weight: var(--weight-normal);
    line-height: var(--leading-normal);
    -webkit-font-smoothing: antialiased;

    /* Required by gridlayout's full-bleed bands: they use `100vw`, which
       includes the scrollbar, so a band can overshoot by a scrollbar's
       width. `clip` absorbs that. NOT `hidden`, which would create a
       scroll container and break `position: sticky` on the header — the
       vendored grid.css says so explicitly and it is right. */
    overflow-x: clip;
}

/* ── The page column ───────────────────────────────────────────────────
   One class, used by the header, the footer and every section, so the
   left edge of the logo lines up with the left edge of the hero text and
   of the footer nav. Sections that need a full-width background put the
   background on the section and this container on its inner wrapper. */

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

/* The wider measure, for the header and footer.

   The design lines the wordmark up with the card rows below it, not with
   the narrower reading column — so with the page's sections widened
   (D64) the chrome had to follow or the logo would sit 200px inside the
   content it sits above. It is a separate class rather than a change to
   `.container` because the reading column is still the right width for
   prose: a StandardPage's body should not stretch to 1760px. */
.container--wide {
    max-width: var(--container-wide);
}

/* ── Typography ────────────────────────────────────────────────────── */

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-heading);
    font-weight: var(--weight-black);
    line-height: var(--leading-tight);
    color: var(--colour-navy);
    /* Stops a two-word line breaking into one word on a phone. */
    text-wrap: balance;
}

h1 { font-size: var(--text-4xl); }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-2xl); }
h4 { font-size: var(--text-xl); }

p {
    /* Caps the measure at roughly 70 characters wherever a paragraph is
       not already inside a narrow column. Long lines are the single most
       common readability failure on a wide screen. */
    max-width: 68ch;
}

p + p {
    margin-top: var(--space-4);
}

a {
    color: var(--colour-navy);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
    transition: color var(--transition);
}

a:hover {
    color: var(--colour-navy-dark);
}

/* A visible, high-contrast focus ring everywhere, including on elements
   whose own styling removes the default outline. Keyboard users cannot
   use a site whose focus is invisible, and `:focus-visible` means mouse
   users never see it. */
:focus-visible {
    outline: 3px solid var(--colour-accent);
    outline-offset: 2px;
    border-radius: 2px;
}

/* ── Rich text ─────────────────────────────────────────────────────────
   Editor-written prose inside a `.rich-text` wrapper. The About page's
   sections and the team bios offer Wagtail's full toolbar (D80), so as
   well as paragraphs and lists this has to hold what that toolbar can
   insert: images placed left, right or full width, embedded video,
   quotations and code. Only those need rules; everything else is the
   site's ordinary type. */

.rich-text > * + * {
    margin-top: var(--space-4);
}

.rich-text :is(ul, ol) {
    padding-left: 1.25em;
}

/* Wagtail's image formats. A floated picture takes at most half the
   column, so the text beside it is never a sliver; the clearfix below
   stops it hanging out of the bottom of its section. */
.rich-text .richtext-image.left {
    float: left;
    max-width: 50%;
    margin: 0 var(--space-4) var(--space-3) 0;
}

.rich-text .richtext-image.right {
    float: right;
    max-width: 50%;
    margin: 0 0 var(--space-3) var(--space-4);
}

.rich-text .richtext-image.full-width {
    width: 100%;
}

.rich-text::after {
    content: "";
    display: table;
    clear: both;
}

/* Embedded video arrives as a fixed-size iframe. Never wider than the
   column, and when Wagtail wraps it for responsive sizing, fill that. */
.rich-text iframe {
    max-width: 100%;
}

.rich-text .responsive-object {
    position: relative;
}

.rich-text .responsive-object iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

.rich-text blockquote {
    padding-left: var(--space-4);
    border-left: 3px solid var(--colour-accent);
    font-style: italic;
}

.rich-text code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.9em;
}

/* ── Shared section furniture ──────────────────────────────────────────
   The design repeats one heading pattern on every section: a small
   letter-spaced label above a large headline. Defined once here because
   six sections use it. */

.eyebrow {
    margin: 0 0 var(--space-3);
    font-family: var(--font-heading);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--colour-navy);
}

.section-heading {
    margin: 0;
    font-size: var(--text-3xl);
}

.section-intro {
    margin-top: var(--space-4);
    color: var(--colour-text-muted);
    font-size: var(--text-lg);
}

/* ── Buttons ───────────────────────────────────────────────────────────
   `.btn` is applied to <a> and <button> alike, so it sets the things an
   anchor does not inherit (display, cursor) rather than assuming either. */

.btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5);
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    font-family: var(--font-heading);
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--transition), color var(--transition);
}

/* The chevron after the label in the design. A pseudo-element rather than
   a character in the copy, so an editor cannot accidentally delete it and
   a screen reader does not read "greater-than" after every button. */
.btn::after {
    content: "\203A";           /* › */
    font-size: 1.25em;
    line-height: 0;
    transform: translateY(-0.05em);
}

.btn--primary {
    background: var(--colour-navy);
    color: var(--colour-text-invert);
}

.btn--primary:hover {
    background: var(--colour-navy-dark);
    color: var(--colour-text-invert);
}

/* Used on the navy CTA band, where the primary button would disappear. */
.btn--light {
    background: var(--colour-white);
    color: var(--colour-navy);
}

.btn--light:hover {
    background: var(--colour-surface);
    color: var(--colour-navy);
}

/* Outline: the secondary look an editor can pick per button (D67). The
   border is the button's colour and the fill is left to what it sits on,
   so the same button reads as secondary beside a solid one. */
.btn--outline {
    background: transparent;
    border-color: var(--colour-navy);
    color: var(--colour-navy);
}

.btn--outline:hover {
    background: var(--colour-navy);
    color: var(--colour-text-invert);
}

/* The outline version for the navy CTA band. */
.btn--outline-light {
    background: transparent;
    border-color: var(--colour-white);
    color: var(--colour-white);
}

.btn--outline-light:hover {
    background: var(--colour-white);
    color: var(--colour-navy);
}

/* A row of buttons — the hero's and the CTA band's. Wraps rather than
   squeezing, so three long labels stack on a phone instead of shrinking. */
.hero__actions,
.cta-band__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}

/* ── Placeholder media ─────────────────────────────────────────────────
   Every image and icon in the design is currently unavailable (the
   supplied archive is flattened mockups, not assets), so every image
   field on every block is optional and renders one of these when empty.

   It is deliberately obvious rather than invisible: a missing asset that
   looks like a design choice is one nobody remembers to replace. The
   label names what belongs there, so the gap is self-documenting in the
   browser as well as in the admin. */

.placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
    background: var(--colour-card);
    border: 1px dashed var(--colour-border);
    border-radius: var(--radius-md);
    color: var(--colour-text-muted);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    letter-spacing: 0.04em;
    text-align: center;
    text-transform: uppercase;
}

/* Icon-sized: the round pale disc the design puts every line icon on. */
.placeholder--icon {
    width: 4rem;
    height: 4rem;
    padding: 0;
    border-radius: var(--radius-pill);
    font-size: 0;            /* the label is for assistive tech only here */
}

.placeholder--icon::before {
    content: "";
    width: 1.5rem;
    height: 1.5rem;
    border: 2px solid var(--colour-border);
    border-radius: var(--radius-sm);
}

/* Image-sized: keeps the design's aspect ratio so the surrounding layout
   is the real layout, not one that shifts when the photo lands. */
.placeholder--image {
    aspect-ratio: 3 / 4;
    width: 100%;
    border-radius: var(--radius-lg);
}

.placeholder--hero {
    aspect-ratio: 4 / 3;
}

/* A team member's portrait (D79): the card's own 7:10 shape. No border or
   corners of its own — the card's frame supplies both and clips it. */
.placeholder--portrait {
    aspect-ratio: 7 / 10;
    width: 100%;
    border: 0;
    border-radius: 0;
}

/* ── Skip link ─────────────────────────────────────────────────────────
   Off-screen until focused. The first thing a keyboard user meets, and
   the only way past a nav that is otherwise ten tab stops deep. */

.skip-link {
    position: absolute;
    top: var(--space-2);
    left: var(--space-2);
    z-index: 100;
    padding: var(--space-3) var(--space-4);
    background: var(--colour-navy);
    color: var(--colour-text-invert);
    border-radius: var(--radius-sm);
    text-decoration: none;
    transform: translateY(-200%);
}

.skip-link:focus {
    transform: translateY(0);
    color: var(--colour-text-invert);
}

/* ── Header ────────────────────────────────────────────────────────── */

.site-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--colour-white);
    border-bottom: 1px solid var(--colour-border);
}

.site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    min-height: 4.5rem;
}

/* The wordmark. An <img> once SiteSettings has a logo; the text below is
   the fallback until then, styled to at least look deliberate. */
.site-logo {
    flex: 0 0 auto;
    font-family: var(--font-heading);
    font-size: var(--text-xl);
    font-weight: var(--weight-black);
    line-height: 1;
    color: var(--colour-navy);
    text-decoration: none;
}

.site-logo img {
    width: auto;
    max-height: 3rem;
}

/* The hamburger. Hidden in the markup and revealed by simplelaw.js, so a
   visitor without JavaScript gets the plain stacked nav below rather than
   a button that does nothing. */
.nav-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    background: none;
    border: 1px solid var(--colour-border);
    border-radius: var(--radius-sm);
    color: var(--colour-navy);
    cursor: pointer;
}

.nav-toggle[hidden] {
    display: none;
}

/* Three bars drawn in CSS rather than an icon file, because the icon set
   has not been supplied and this one is two rules. */
.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
    display: block;
    width: 1.25rem;
    height: 2px;
    background: currentColor;
    border-radius: 2px;
}

.nav-toggle__bars {
    position: relative;
}

.nav-toggle__bars::before,
.nav-toggle__bars::after {
    content: "";
    position: absolute;
    left: 0;
}

.nav-toggle__bars::before { top: -6px; }
.nav-toggle__bars::after  { top: 6px; }

.main-nav__list {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin: 0;
}

.main-nav__link {
    display: block;
    padding: var(--space-2) 0;
    font-family: var(--font-heading);
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    color: var(--colour-text);
    text-decoration: none;
}

.main-nav__link:hover {
    color: var(--colour-navy);
}

/* The design marks the current page with a short underline. Hung off
   aria-current rather than a separate class: the attribute has to be
   there for screen readers anyway, so styling it means the visual state
   and the announced state cannot disagree. */
/* Step 6: also a link to the part of the site the page sits in —
   "Services" while a service page is open, as the service page designs
   underline it. aria-current="true" rather than "page", so a screen
   reader can tell "you are here" from "you are in here". */
.main-nav__link[aria-current="page"],
.main-nav__link[aria-current="true"] {
    color: var(--colour-navy);
    position: relative;
}

.main-nav__link[aria-current="page"]::after,
.main-nav__link[aria-current="true"]::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 1.75rem;
    height: 3px;
    background: var(--colour-navy);
    border-radius: 2px;
}

/* ── Footer ────────────────────────────────────────────────────────────
   The footer's structure is editor-built now (Snippets ▸ Site footer):
   any number of sections, each with a heading and one or more columns of
   links. So these rules size and space whatever arrives rather than
   assuming a fixed set of blocks. */

.site-footer {
    padding-block: var(--space-7) var(--space-5);
    background: var(--colour-white);
}

.site-footer__main {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
    padding-bottom: var(--space-6);
}

/* Sections sit side by side and wrap. auto-fit/minmax rather than a
   column count, because the count is now an editorial decision and the
   CSS cannot know it. */
.site-footer__nav {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10rem, auto));
    gap: var(--space-5) var(--space-7);
}

.footer-section__heading {
    margin: 0 0 var(--space-3);
    font-size: var(--text-base);
    font-weight: var(--weight-bold);
    color: var(--colour-navy);
}

/* A section's columns sit beside each other — that is the only reason a
   second column exists. */
.footer-section__columns {
    display: flex;
    gap: var(--space-6);
}

.footer-section__column {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin: 0;
}

/* A section an editor has set to "In a row". The design's main footer
   navigation is horizontal; a headed section like "Company" is not, which
   is why this is a choice on the section rather than a global rule. */
.footer-section--inline .footer-section__column {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-3) var(--space-6);
}

.footer-link {
    font-family: var(--font-heading);
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    color: var(--colour-text);
    text-decoration: none;
}

.footer-link:hover {
    color: var(--colour-navy);
}

/* A link whose editor has not chosen a destination yet. Rendered as a
   <span>, so it is not focusable and not clickable; dimmed so the gap is
   visible on the page rather than looking like a working link.

   One fixed class, applied alongside whatever the link's normal class is,
   so it works on a plain link and on a button alike. The button case also
   drops the fill: a solid navy button that does nothing looks like a bug
   rather than like an unfinished entry. */
.nav-unlinked {
    color: var(--colour-text-muted);
    cursor: default;
}

.btn.nav-unlinked {
    background: none;
    border-color: var(--colour-border);
    color: var(--colour-text-muted);
}

/* The same dimmed state on the navy CTA band (D67), where the muted grey
   above would be navy-on-navy. Translucent white keeps it clearly
   inactive but still readable: ≈6:1 on the band's navy. */
.cta-band .btn.nav-unlinked {
    border-color: rgba(255, 255, 255, 0.45);
    color: rgba(255, 255, 255, 0.75);
}

.site-footer__about {
    margin-bottom: var(--space-5);
    color: var(--colour-text-muted);
    font-size: var(--text-sm);
}

.site-footer__contact {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin-bottom: var(--space-5);
    font-style: normal;
    color: var(--colour-text-muted);
}

/* Revised (D103, Abhijith: "One row multiple columns as per the design"):
   a single row with one column per profile, rather than a wrapping row.
   Columns sized to their content, so the row is as wide as its icons. */
.site-footer__social ul {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    gap: var(--space-4);
    margin: 0;
}

/* Text labels until the social icon set arrives (D57). Boxed so the row
   reads as a group of controls rather than a sentence. */
.site-footer__social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.5rem;
    min-height: 2.5rem;
    padding-inline: var(--space-3);
    border: 1px solid var(--colour-border);
    border-radius: var(--radius-pill);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    text-decoration: none;
}

/* A profile with an uploaded icon (D103) shows the icon as uploaded (14 A):
   no box around it — the icon is the design's own mark. The link is as
   wide as its icon, so the first one lines up with the text beside it,
   and keeps the 2.5rem height as its target to tap (WCAG 2.5.8 asks for
   24px each way). */
.site-footer__social a.social-icon-link {
    min-width: 0;
    padding-inline: 0;
    border: 0;
}

/* The icon at the site's size, whatever size it was uploaded at; an icon
   that is not square fits inside that box rather than being stretched.
   Shared with the team cards (sections.css). */
.social-icon {
    display: block;
    width: var(--social-icon-size);
    height: var(--social-icon-size);
    object-fit: contain;
}

.site-footer__legal {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding-top: var(--space-5);
    border-top: 1px solid var(--colour-border);
    color: var(--colour-text-muted);
    font-size: var(--text-sm);
}

.site-footer__legal ul {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin: 0;
}

.site-footer__legal .footer-link {
    font-size: var(--text-sm);
    font-weight: var(--weight-normal);
    color: var(--colour-text-muted);
}

/* ── Analytics consent (D104) ──────────────────────────────────────────
   The consent banner, the full notice page and the footer link.

   The banner is short and does not block the page ("don't make the
   banner a wall", 19): a card at the bottom of the screen, across the
   width on a phone and in the corner on a desktop, over the page rather
   than pushing it about. Above the sticky header's layer (50) so it is
   never hidden under it; below the skip link (100), which is only ever
   visible at the top. */

.consent-banner {
    position: fixed;
    inset-inline: var(--space-3);
    bottom: var(--space-3);
    z-index: 90;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    background: var(--colour-white);
    color: var(--colour-text);
    border: 1px solid var(--colour-border);
    border-radius: var(--radius-md);
    /* Stronger than --shadow-card: the banner floats over whatever the
       page has under it, white included, and must read as separate. */
    box-shadow: 0 8px 32px rgba(31, 42, 77, 0.18);
    font-size: var(--text-sm);
    /* Never taller than the screen: zoomed in far enough, the banner
       scrolls inside itself, so its first line can always be read. */
    max-height: calc(100dvh - 2 * var(--space-3));
    overflow-y: auto;
}

/* Room at the end of the page for the banner, so the footer — the privacy
   links, "Analytics preferences" — and anything focused there can always
   be scrolled clear of it (WCAG 2.4.11). The page script keeps
   --consent-banner-space equal to the banner's height; the fallback is a
   typical phone-sized banner, for the moment before the script runs. */
body:has(> .consent-banner) {
    padding-bottom: calc(var(--consent-banner-space, 15rem) + var(--space-3));
}

html:has(.consent-banner) {
    scroll-padding-bottom: calc(var(--consent-banner-space, 15rem) + var(--space-3));
}

/* On a very short screen — a phone held sideways, a high zoom — a fixed
   banner would cover most of the page. There it sits at the top of the
   page instead, where it is in the reading order anyway, and scrolls away
   with it. */
@media (max-height: 30rem) {
    .consent-banner {
        position: static;
        max-height: none;
        margin: var(--space-3);
    }

    body:has(> .consent-banner) {
        padding-bottom: 0;
    }

    html:has(.consent-banner) {
        scroll-padding-bottom: 0;
    }
}

.consent-banner__heading {
    margin: 0;
    font-size: var(--text-base);
    font-weight: var(--weight-bold);
    color: var(--colour-navy);
}

.consent-banner__summary {
    margin: var(--space-1) 0 0;
    max-width: none;
}

.consent-banner__summary a {
    font-weight: var(--weight-semibold);
}

.consent-banner__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin: 0;
}

/* Accept and Decline the same size and the same look, so neither is the
   obvious one to press. They share the row equally on a phone. */
.consent-banner__button {
    flex: 1 1 8rem;
    justify-content: center;
}

/* No chevron: these answer a question, they do not lead anywhere. */
.consent-banner__button::after,
.analytics-notice__actions .btn::after {
    content: none;
}

/* The full notice page: a reading column, then the choice. */
.analytics-notice {
    padding-block: var(--space-7) var(--space-section);
}

.analytics-notice .rich-text {
    max-width: 68ch;
}

.analytics-notice__choice {
    margin-top: var(--space-6);
    padding: var(--space-5);
    background: var(--colour-surface);
    border-radius: var(--radius-md);
    max-width: 68ch;
}

.analytics-notice__status {
    margin: 0 0 var(--space-4);
    font-weight: var(--weight-semibold);
}

.analytics-notice__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}

/* The footer link sits in the bottom bar with the copyright line. */
.site-footer__preferences {
    margin: 0;
}

/* ── Tablet and up ─────────────────────────────────────────────────────
   1024px is gridlayout's own tablet boundary (BREAKPOINT_MAX_WIDTH in
   layout.py). Reusing it rather than inventing a third number keeps the
   chrome and the section grid changing shape at the same moment. */

@media (min-width: 1025px) {
    .nav-toggle {
        display: none;
    }

    /* Whatever the toggle did on a phone is irrelevant here: the nav is
       always shown. `display` wins over the inline `hidden` attribute the
       script sets, which is why this is a rule and not left to the JS. */
    .main-nav[hidden] {
        display: block;
    }

    .main-nav__list {
        flex-direction: row;
        align-items: center;
        gap: var(--space-6);
    }

    .site-header__inner {
        min-height: 5.5rem;
    }

    .site-footer__main {
        flex-direction: row;
        align-items: flex-start;
        justify-content: space-between;
        gap: var(--space-7);
    }

    .site-footer__legal {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }

    /* The consent banner in the bottom corner rather than across the
       screen, and its buttons at their own width beside the text. */
    .consent-banner {
        inset-inline: var(--space-5) auto;
        bottom: var(--space-5);
        max-width: 44rem;
        flex-direction: row;
        align-items: center;
        gap: var(--space-5);
    }

    .consent-banner__actions {
        flex-wrap: nowrap;
    }

    .consent-banner__button {
        flex: 0 0 auto;
    }
}

/* ── Visually hidden ───────────────────────────────────────────────────
   Removed from the page but not from the accessibility tree — the text
   is still announced by a screen reader. Used where a control's visible
   content is an icon or an arrow and its accessible name has to come from
   somewhere ("→" alone is announced as "link" and nothing else).

   `clip-path` rather than `display: none` or `visibility: hidden`, both of
   which hide it from assistive technology too and so defeat the point. */

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}
