/* =============================================================================
   The public homepage.
   -----------------------------------------------------------------------------
   Loaded after app.css, so it inherits the portal's tokens rather than inventing
   a second palette, a visitor who signs in should not feel they have crossed
   into different software.

   The visual idea is the thing the portal actually produces: a controlled
   document. Hairline rules instead of boxes and shadows, a serif for anything
   that speaks, a monospace for anything that identifies, and a lot of paper
   between them. Nothing here glows, floats or gradients; a regulator's homepage
   should read like a published instrument, not a software launch.
   ========================================================================== */

.site {
    scroll-behavior: smooth;
    /* Anchored sections must clear the sticky header, or a jump lands with the
       heading hidden behind it. */
    scroll-padding-top: 88px;
}

@media (prefers-reduced-motion: reduce) {
    .site { scroll-behavior: auto; }
}

.site__body {
    background: var(--paper);
    color: var(--ink);
    font-family: var(--sans);
    -webkit-font-smoothing: antialiased;
}

.site-shell {
    width: 100%;
    max-width: 1160px;
    margin-inline: auto;
    padding-inline: var(--s5);
}

@media (max-width: 620px) {
    .site-shell { padding-inline: var(--s4); }
}

.site-skip {
    position: absolute;
    left: -9999px;
    top: var(--s3);
    z-index: 100;
    padding: var(--s2) var(--s4);
    background: var(--ink);
    color: var(--paper);
    border-radius: var(--radius);
}
.site-skip:focus { left: var(--s4); }

/* --- Masthead ------------------------------------------------------------- *
   The band of state identity above everything. Deliberately plain and slightly
   cramped: it is a label, not a banner, and its job is to say whose portal this
   is before the page starts talking.                                          */

.site-masthead {
    background: var(--brand-ink);
    color: color-mix(in srgb, #fff 82%, transparent);
    font-size: 13px;
    letter-spacing: .01em;
}

.site-masthead__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--s2) var(--s3);
    min-height: 34px;
    padding-block: var(--s2);
}

.site-masthead__authority {
    font-weight: 600;
    color: #fff;
    letter-spacing: .04em;
    text-transform: uppercase;
    font-size: 13px;
}

.site-masthead__strap { color: color-mix(in srgb, #fff 66%, transparent); }

/* A hairline of gold under the band, taken from the crest's own border. */
.site-masthead { border-bottom: 2px solid var(--accent); }

/* --- Header --------------------------------------------------------------- *
   Sticky, but weightless until the page moves under it: the rule and the blur
   arrive only once there is something above to separate from.                 */

/* The header stays on the dark ground throughout rather than changing colour
   when the page moves under it. A header that swaps plane mid-scroll draws
   attention to itself at the exact moment the reader is trying to read
   something else, and the masthead directly above it is dark already: together
   they read as one band of state identity rather than two strips. */
.site-header {
    position: sticky;
    top: 0;
    z-index: 40;
    background: var(--ground);
    color: var(--on-ink);
    border-bottom: 1px solid transparent;
    transition: border-color var(--t-enter) ease;
}

.site-header[data-scrolled] { border-bottom-color: var(--ink-rule); }

.site-header__inner {
    display: flex;
    align-items: center;
    gap: var(--s5);
    min-height: 68px;
}

.site-mark {
    display: inline-flex;
    align-items: center;
    gap: var(--s3);
    text-decoration: none;
    color: inherit;
    flex-shrink: 0;
}

.site-mark__crest,
.site-mark__img {
    width: auto;
    height: 40px;
    flex-shrink: 0;
    object-fit: contain;
}

/* The crest carries its own colour, so it needs no plate behind it. */
.site-mark__crest { display: block; }

.site-mark__text { display: flex; flex-direction: column; line-height: 1.15; }

.site-mark__name {
    font-weight: 600;
    font-size: 15px;
    letter-spacing: -.01em;
    color: #fff;
}

.site-mark__tag {
    font-size: 13px;
    color: var(--on-ink-2);
    letter-spacing: .01em;
}

.site-nav {
    display: flex;
    align-items: center;
    gap: var(--s1);
    margin-inline-start: auto;
}

.site-nav__link {
    position: relative;
    /* 44px tall, which is the smallest target a finger hits reliably. It was
       39px, which is the sort of miss that gets blamed on the person. */
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: var(--s2) var(--s3);
    border-radius: var(--radius);
    font-size: 15px;
    color: var(--on-ink-2);
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--t-quick) ease, background var(--t-quick) ease;
}

@media (hover: hover) and (pointer: fine) {
    .site-nav__link:hover { color: #fff; background: rgba(255, 255, 255, .07); }
}

/* The rule under the section currently on screen. Scaled rather than resized,
   so it animates on the compositor and cannot reflow the header. */
.site-nav__link::after {
    content: "";
    position: absolute;
    left: var(--s3);
    right: var(--s3);
    bottom: 4px;
    height: 1.5px;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--t-enter) var(--ease-out);
}

.site-nav__link[aria-current="true"] { color: #fff; }
.site-nav__link[aria-current="true"]::after { transform: scaleX(1); }

.site-header__actions {
    display: flex;
    align-items: center;
    gap: var(--s2);
    margin-inline-start: auto;
}

.site-nav + .site-header__actions { margin-inline-start: 0; }

.site-nav__toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 38px;
    height: 38px;
    padding: 0 9px;
    border: 1px solid var(--rule-strong);
    border-radius: var(--radius);
    background: var(--paper-raised);
    cursor: pointer;
}

.site-nav__toggle span {
    display: block;
    height: 1.5px;
    background: var(--on-ink);
    transition: transform var(--t-quick) var(--ease-out), opacity var(--t-quick) ease;
}

.site-nav__toggle[aria-expanded="true"] span:first-child { transform: translateY(3.25px) rotate(45deg); }
.site-nav__toggle[aria-expanded="true"] span:last-child { transform: translateY(-3.25px) rotate(-45deg); }

/* --- Hero ----------------------------------------------------------------- */

/* The hero is the one dark plane at the top of the page, and it is the change
   that does most of the work. The old page was a single sheet of cream from the
   masthead to the footer: well set, but with nothing for the eye to travel
   across, which is what "flat" actually means. Putting the opening on ink gives
   the paper below it something to be, and it suits the subject, a controlled
   document opens on its cover, not on its first paragraph. */

.site-hero {
    position: relative;
    padding-block: clamp(var(--s8), 11vw, 148px) clamp(var(--s8), 10vw, 132px);
    overflow: hidden;
    isolation: isolate;
    background: var(--ground);
    color: var(--on-ink);
}

/* A very faint gold wash from the top left, the angle a page catches light
   from. Two stops only: a gradient with more than that starts to announce
   itself, and this one should never be noticed, only felt. */
.site-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -2;
    background:
        radial-gradient(90rem 40rem at 8% -20%,
            color-mix(in srgb, var(--accent) 11%, transparent), transparent 62%),
        radial-gradient(60rem 40rem at 100% 120%,
            color-mix(in srgb, var(--brand) 24%, transparent), transparent 60%);
    pointer-events: none;
}

/* The crest, large and nearly invisible, anchoring the composition. It is set
   past the right edge on purpose: something that runs off the page tells the eye
   the page is bigger than the screen, which a grid of centred boxes never does. */
.site-hero__crest {
    position: absolute;
    z-index: -1;
    top: 52%;
    right: -14%;
    width: clamp(320px, 34vw, 560px);
    /* Moved by the scroll position, set from script as a single custom property
       so the transform below stays on the compositor. A watermark that sits
       perfectly still is a background image; one that lags the page by a few
       dozen pixels reads as something printed on a sheet behind the words. */
    /* Upright. It was tilted seven degrees, which looked considered and is the
       one thing a coat of arms should not be: an emblem of state is presented
       square, and a faint upright crest behind a masthead is a device official
       stationery already uses. Tilting it turns it into decoration. */
    transform: translate3d(0, calc(-50% + var(--drift, 0px)), 0);
    /* Faint enough that the headline crossing it loses nothing. A watermark is
       felt, not looked at; at the opacity this started on it was competing with
       the words, which on a page about legibility is the wrong way round. */
    opacity: .05;
    pointer-events: none;
    user-select: none;
    will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
    .site-hero__crest { transform: translate3d(0, -50%, 0); }
}

/* On a narrow screen the crest ends up directly behind the paragraph rather
   than beside it, so it drops back and sits low, where only the buttons and the
   rule cross it. Body copy has to win. */
@media (max-width: 940px) {
    .site-hero__crest {
        top: auto;
        bottom: -6%;
        right: -30%;
        width: 520px;
        opacity: .06;
        transform: none;
    }
}

/* A single hairline running the width of the page, the way a masthead rule
   does. It is the only decoration in the hero. */
.site-hero::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 2px;
    background: linear-gradient(90deg,
        var(--accent) 0%, var(--accent) 22%,
        var(--brand) 22%, var(--brand) 46%,
        transparent 46%);
}

.site-hero__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(var(--s6), 5vw, 56px);
}

.site-eyebrow {
    margin: 0 0 var(--s4);
    font-family: var(--mono);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--brand);
}

.site-hero .site-eyebrow { color: var(--accent); }

.site-hero__title {
    margin: 0;
    font-family: var(--display);
    font-weight: 400;
    font-optical-sizing: none;
    font-variation-settings: "opsz" 30;
    /* Roughly five times the body copy at the top of the range. The previous
       setting was closer to two and a half, which is why the page read as flat
       however carefully it was spaced: there was no distance for the eye to
       travel. Timid display type is what makes a page look like a template. */
    font-size: var(--t-display);
    line-height: .94;
    letter-spacing: -.03em;
    text-wrap: balance;
    color: #fff;
}

/* The second line set in italic. One word of contrast in a title carries more
   than another weight would, and this face has a genuine italic rather than a
   slanted roman. */
.site-hero__title em {
    font-style: italic;
    color: var(--accent);
}

.site-hero__lead {
    margin: var(--s6) 0 0;
    max-width: 52ch;
    font-size: clamp(1.02rem, 1.5vw, 1.2rem);
    line-height: 1.62;
    color: var(--on-ink-2);
    text-wrap: pretty;
}

.site-hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s3);
    margin-top: var(--s6);
}

/* On the dark plane the default button is invisible: it inherits paper for its
   fill and ink for its text, and both disappear. It is restated here rather
   than made transparent, which was the bug. */
.site-hero__secondary {
    background: transparent;
    border-color: rgba(244, 241, 232, .34);
    color: var(--on-ink);
}

@media (hover: hover) and (pointer: fine) {
    .site-hero__secondary:hover {
        background: rgba(244, 241, 232, .08);
        border-color: var(--on-ink);
        color: #fff;
    }
}

.site-hero__secondary:active { transform: scale(.985); }

.site-hero__stats {
    display: flex;
    flex-wrap: wrap;
    gap: clamp(var(--s5), 4vw, var(--s7));
    margin-top: var(--s7);
    padding-top: var(--s5);
    border-top: 1px solid var(--ink-rule);
}

.site-stat { display: flex; flex-direction: column; gap: 2px; }

.site-stat__value {
    font-family: var(--display);
    font-size: 2.4rem;
    font-weight: 500;
    font-optical-sizing: none;
    font-variation-settings: "opsz" 24;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: #fff;
}

.site-stat__label {
    font-family: var(--mono);
    font-size: 13px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--on-ink-3);
}

/* --- The plate ------------------------------------------------------------ *
   What used to be a bordered, rounded, shadowed card. The content is identical
   and still read live from the database; only the container is gone. Two ruled
   rows now hold it, which is how a figure sits in a printed document, and the
   page stops reading as rectangles stacked on rectangles.                      */

.site-plate {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: clamp(var(--s5), 4vw, var(--s7));
    max-width: 940px;
    padding-top: var(--s5);
    border-top: 1px solid var(--ink-rule);
}

.site-plate__legend {
    display: block;
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--on-ink-3);
}

.site-plate__ref {
    margin: var(--s3) 0 0;
    font-family: var(--mono);
    font-size: clamp(1.1rem, 2.4vw, 1.7rem);
    font-weight: 500;
    letter-spacing: -.02em;
    /* Gold on ink, because on this ground the maroon of the crest goes muddy
       and a reference number is the one thing on the page that must be read
       exactly. */
    color: var(--accent);
    word-break: break-word;
}

/* The reference stamps itself in, character by character, on first view. It is
   the one piece of motion on the page that is about the subject rather than
   about arrival: issuing a number is what this portal does to every report that
   reaches it, and the specimen is that act. The width is reserved by the text
   itself, so nothing reflows while it runs. */
.site-plate__ref span {
    display: inline-block;
    opacity: 0;
}

[data-js] .site-plate[data-stamping] .site-plate__ref span {
    animation: stamp-in 260ms var(--ease-out) forwards;
    animation-delay: calc(var(--i) * 34ms);
}

@keyframes stamp-in {
    from { opacity: 0; transform: translateY(-.18em) scale(1.35); filter: blur(3px); }
    to   { opacity: 1; transform: none; filter: none; }
}

@media (prefers-reduced-motion: reduce) {
    .site-plate__ref span { opacity: 1; }
    [data-js] .site-plate[data-stamping] .site-plate__ref span { animation: none; }
}

.site-plate__pattern {
    margin: var(--s2) 0 0;
    font-family: var(--mono);
    font-size: 13px;
    color: var(--on-ink-3);
    word-break: break-word;
}

/* Sector codes. The full name is carried on the element rather than in a
   tooltip alone, so it is available to a screen reader and on a touch screen,
   where hovering is not a thing. */
.site-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: var(--s3) 0 0;
    padding: 0;
    list-style: none;
}

.site-chip {
    position: relative;
    padding: 3px 9px;
    border: 1px solid var(--ink-rule);
    font-family: var(--mono);
    font-size: 13px;
    color: var(--on-ink-2);
    background: rgba(255, 255, 255, .04);
    transition: border-color var(--t-quick) ease, color var(--t-quick) ease,
                background var(--t-quick) ease;
}

.site-chip abbr { text-decoration: none; border: 0; }

/* The name is hidden until it is wanted, rather than absent. */
.site-chip > span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

@media (hover: hover) and (pointer: fine) {
    .site-chip:hover {
        border-color: var(--accent);
        color: var(--accent);
        background: rgba(255, 255, 255, .08);
    }
}

/* --- The compliance scale ------------------------------------------------- *
   One continuous range rather than four cards, because a score is a position on
   a scale and four boxes said these were four separate things. Segment widths
   come from the bands' own numbers.                                            */

.site-scale { margin-top: clamp(var(--s6), 5vw, var(--s7)); }

.site-scale__track {
    display: flex;
    height: 20px;
    overflow: hidden;
    border: 1px solid var(--ink-rule);
}

/* The bar is revealed left to right on the way in, as a measurement being
   taken. clip-path rather than width, so the segments never reflow and the
   whole thing stays on the compositor. */
[data-js] [data-scale] .site-scale__track {
    clip-path: inset(0 100% 0 0);
    transition: clip-path 900ms var(--ease-out);
}

[data-js] [data-scale][data-shown] .site-scale__track { clip-path: inset(0 0 0 0); }

@media (prefers-reduced-motion: reduce) {
    [data-js] [data-scale] .site-scale__track { clip-path: none; transition: none; }
}

.site-scale__band {
    --band: var(--ink-4);
    flex-basis: 0;
    background: var(--band);
    transition: filter var(--t-quick) ease;
}

.site-scale__band + .site-scale__band { border-left: 1px solid var(--ground); }

@media (hover: hover) and (pointer: fine) {
    .site-scale__track:hover .site-scale__band { filter: saturate(.35) opacity(.5); }
    .site-scale__track .site-scale__band:hover { filter: none; }
}

/* The keys share the segments' growth factors, so each one sits under the part
   of the bar it describes. A row of equal columns underneath a proportional bar
   is worse than no bar at all: it invites the eye to match them up and then
   defeats it. */
.site-scale__keys {
    display: flex;
    gap: var(--s4);
    margin: var(--s4) 0 0;
    padding: 0;
    list-style: none;
}

/* On the dark plane the band colours cannot carry text: the mid green measures
   under 4 to 1 there and the deep red under 3. The colour stays where it can be
   seen, in the rule above each key, and the words take the plane's own text
   colour. Nothing is lost: the rule and the segment above already say which
   band is which. */
.site-section--ink .site-scale__range { color: var(--on-ink); }
.site-section--ink .site-scale__label { color: var(--on-ink-2); }

.site-scale__key {
    --band: var(--ink-3);
    flex-basis: 0;
    min-width: 0;
    padding-top: var(--s3);
    border-top: 3px solid var(--band);
}

/* Below this the segments are too narrow to label in place, so the keys become
   an ordinary list and stop pretending to align. */
@media (max-width: 780px) {
    .site-scale__keys { flex-wrap: wrap; }
    .site-scale__key { flex: 1 1 168px; }
}

/* Sized to survive the narrowest band. A ten-point band is a tenth of the bar,
   which at this measure is about 110px, and anything larger than this wraps
   "50 to 59.99%" onto two lines and undoes the alignment it was sized for. */
.site-scale__range {
    display: block;
    font-family: var(--mono);
    font-size: .95rem;
    font-weight: 500;
    line-height: 1.25;
    color: var(--band);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.site-scale__label {
    display: block;
    margin-top: 3px;
    font-size: .875rem;
    line-height: 1.35;
    color: var(--ink-2);
    text-wrap: balance;
}

/* --- Sections ------------------------------------------------------------- */

.site-section {
    position: relative;
    padding-block: clamp(var(--s8), 9vw, 132px);
    border-bottom: 1px solid var(--rule);
}

.site-section:last-of-type { border-bottom: 0; }

.site-section--steps,
.site-section--audience { background: var(--paper-sunk); }

/* One section carries the argument rather than describing it, and it goes back
   onto ink. The old page gave all six sections the same cadence, eyebrow, title,
   body, items, six times over, which is the real reason it read as flat: not
   that any one section was wrong, but that nothing ever changed. */
.site-section--ink {
    background: var(--ground);
    color: var(--on-ink);
    border-bottom-color: transparent;
}

.site-section--ink .site-head__title { color: #fff; }
.site-section--ink .site-head__body  { color: var(--on-ink-2); }
.site-section--ink .site-eyebrow     { color: var(--accent); }

/* The section number, in the margin. A controlled document numbers its parts,
   and it gives the eye somewhere to register that a new one has begun without
   another rule across the page. */
.site-head {
    max-width: 62ch;
    position: relative;
}

.site-head__index {
    display: block;
    margin: 0 0 var(--s4);
    font-family: var(--mono);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: .16em;
    color: var(--ink-3);
}

.site-section--ink .site-head__index { color: var(--on-ink-3); }

.site-head__title {
    margin: 0;
    font-family: var(--display);
    font-weight: 400;
    font-optical-sizing: none;
    font-variation-settings: "opsz" 30;
    font-size: var(--t-title);
    line-height: 1.0;
    letter-spacing: -.028em;
    text-wrap: balance;
}

.site-head__title em { font-style: italic; color: var(--brand); }
.site-section--ink .site-head__title em { color: var(--accent); }

.site-head__body {
    margin: var(--s5) 0 0;
    max-width: 56ch;
    font-size: 1.05rem;
    line-height: 1.66;
    color: var(--ink-2);
    text-wrap: pretty;
}

/* --- Steps ---------------------------------------------------------------- */

.site-steps {
    counter-reset: step;
    list-style: none;
    margin: clamp(var(--s6), 5vw, var(--s7)) 0 0;
    padding: 0;
    display: grid;
    gap: 0;
    /* Capped so the rules end with the text rather than running on across empty
       page, which is what makes a ledger look like an unfinished table. */
    max-width: 940px;
}

.site-step {
    display: grid;
    grid-template-columns: 76px minmax(0, 1fr);
    gap: var(--s5);
    padding-block: var(--s5);
    border-top: 1px solid var(--rule-strong);
    align-items: start;
}

.site-step:last-child { border-bottom: 1px solid var(--rule-strong); }

.site-step__num {
    font-family: var(--mono);
    font-size: 15px;
    font-weight: 600;
    /* The maroon, not the gold. Gold on paper measures 1.5 to 1: a
       decoration pretending to be a number, legible to whoever chose it
       and to nobody reading the page. The maroon is 7.1 to 1. */
    color: var(--brand);
    padding-top: 3px;
}

.site-step__body h3 {
    margin: 0;
    font-family: var(--serif);
    font-size: 1.22rem;
    font-weight: 500;
    letter-spacing: -.012em;
}

.site-step__body p {
    margin: var(--s2) 0 0;
    max-width: 66ch;
    line-height: 1.66;
    color: var(--ink-2);
    text-wrap: pretty;
}

@media (max-width: 620px) {
    .site-step { grid-template-columns: minmax(0, 1fr); gap: var(--s2); }
    .site-step__num { padding-top: 0; }
}

/* --- Cards ---------------------------------------------------------------- *
   Ruled cells rather than floating cards: the grid lines are the structure, so
   there is nothing to raise, round or shadow.                                 */

/* The rules are drawn by the cells themselves rather than by a gap over a
   coloured container. The container trick is tidier to write, but when the last
   row is short, six cards in a four-column grid, the empty tracks show the
   container through and read as two broken cells. Borders belong to cells that
   exist. */
.site-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(272px, 1fr));
    gap: clamp(var(--s5), 3vw, var(--s6)) clamp(var(--s5), 4vw, var(--s7));
    margin-top: clamp(var(--s6), 5vw, var(--s7));
}

/* Columns of a page, not cells of a table. Each point is held by a short rule
   above it rather than by a box around it, which is the single change that
   stops this section reading as a grid of tiles. */
.site-card {
    padding-top: var(--s4);
    border-top: 1px solid var(--rule-strong);
    transition: border-color var(--t-quick) ease;
}

@media (hover: hover) and (pointer: fine) {
    .site-card:hover { border-top-color: var(--brand); }
}

.site-card__title {
    margin: 0;
    font-family: var(--serif);
    font-size: 1.1rem;
    font-weight: 500;
    letter-spacing: -.01em;
}

.site-card__body {
    margin: var(--s3) 0 0;
    font-size: .94rem;
    line-height: 1.62;
    color: var(--ink-2);
    text-wrap: pretty;
}

/* --- Audience ------------------------------------------------------------- */

.site-audiences {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
    gap: clamp(var(--s5), 3vw, var(--s6));
    margin-top: clamp(var(--s6), 5vw, var(--s7));
}

.site-audience { padding-top: var(--s4); border-top: 2px solid var(--ink); }

.site-audience__title {
    margin: 0;
    font-family: var(--serif);
    font-size: 1.16rem;
    font-weight: 500;
}

.site-audience__body {
    margin: var(--s3) 0 0;
    font-size: .94rem;
    line-height: 1.64;
    color: var(--ink-2);
    text-wrap: pretty;
}

/* --- Prose ---------------------------------------------------------------- */

.site-prose .site-head { max-width: 66ch; }
.site-prose .site-head__body { font-size: 1.06rem; }

/* --- Contact -------------------------------------------------------------- */

.site-contact {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
    gap: clamp(var(--s6), 5vw, var(--s7));
    align-items: start;
}

@media (max-width: 820px) {
    .site-contact { grid-template-columns: minmax(0, 1fr); }
}

.site-contact .site-head { margin-bottom: var(--s5); }

.site-contact__list { margin: 0; }

.site-contact__row {
    display: grid;
    grid-template-columns: 104px minmax(0, 1fr);
    gap: var(--s3);
    padding-block: var(--s3);
    border-top: 1px solid var(--rule);
}

.site-contact__row dt {
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--ink-3);
    padding-top: 2px;
}

.site-contact__row dd {
    margin: 0;
    line-height: 1.6;
    white-space: pre-line;
}

.site-contact__row a { color: var(--brand); text-decoration-thickness: 1px; text-underline-offset: 2px; }

/* --- Footer --------------------------------------------------------------- */

.site-footer {
    padding-block: clamp(var(--s6), 4vw, var(--s7));
    background: var(--brand-ink);
    color: color-mix(in srgb, #fff 74%, transparent);
    border-top: 3px solid var(--accent);
}

.site-footer__inner {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--s5);
    align-items: start;
}

@media (max-width: 820px) {
    .site-footer__inner { grid-template-columns: minmax(0, 1fr); }
}

.site-footer__lockup {
    display: block;
    width: auto;
    height: 52px;
    margin-bottom: var(--s4);
}

.site-footer__name {
    margin: 0;
    font-family: var(--serif);
    font-size: 1.05rem;
    color: var(--paper);
}

.site-footer__legal {
    margin: var(--s2) 0 0;
    font-size: 14px;
    line-height: 1.6;
    max-width: 52ch;
}

.site-footer__contact { display: flex; flex-direction: column; gap: var(--s1); }

.site-footer a {
    color: color-mix(in srgb, var(--paper) 88%, transparent);
    font-size: 14px;
    text-decoration: none;
    border-bottom: 1px solid color-mix(in srgb, var(--paper) 26%, transparent);
    align-self: flex-start;
    transition: border-color var(--t-quick) ease, color var(--t-quick) ease;
}

@media (hover: hover) and (pointer: fine) {
    .site-footer a:hover { color: var(--paper); border-bottom-color: var(--paper); }
}

.site-footer__meta {
    display: flex;
    flex-direction: column;
    gap: var(--s1);
    font-size: 14px;
}

/* --- Scroll reveal -------------------------------------------------------- *
   Opacity plus a few pixels of travel, once, on the way in. The delay is set
   per element in the markup so a run of steps arrives in sequence rather than
   all at once, 60ms apart, which reads as considered; much more reads as slow. */

/* Visible by default, and hidden only once the document has said JavaScript is
   running, a flag set by an inline script in the head, before first paint.
   The other way round (hidden by default, revealed by script) means a visitor
   whose JavaScript fails or is switched off reads a blank page, which for a
   public information page is not a degraded experience but a broken one. */
[data-js] .site-reveal {
    opacity: 0;
    transform: translateY(12px);
    transition:
        opacity var(--t-enter) var(--ease-out),
        transform var(--t-enter) var(--ease-out);
}

[data-js] .site-reveal[data-shown] { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
    [data-js] .site-reveal { opacity: 1; transform: none; transition: none; }
}

/* --- Small screens -------------------------------------------------------- */

@media (max-width: 880px) {
    .site-nav {
        position: fixed;
        inset: 68px 0 auto;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        padding: var(--s2) var(--s4) var(--s4);
        background: var(--paper);
        border-bottom: 1px solid var(--rule);
        /* Clipped rather than hidden, so it can animate open without the layout
           of the page underneath it moving. */
        clip-path: inset(0 0 100% 0);
        transition: clip-path var(--t-enter) var(--ease-out);
    }

    .site-nav[data-open] { clip-path: inset(0 0 0 0); }

    .site-nav__link {
        padding: var(--s3) var(--s2);
        border-bottom: 1px solid var(--rule);
        font-size: 15px;
    }

    .site-nav__link::after { display: none; }
    .site-nav__toggle { display: flex; }
    .site-header__actions { margin-inline-start: auto; }
}

@media (max-width: 420px) {
    .site-mark__tag { display: none; }
    .site-header__cta { padding-inline: var(--s3); }
}

/* --- Reach, and the statement ---------------------------------------------- *
   What replaced the reference specimen and the drawing of a stamped page. Both
   described the filing; these describe what the scheme reaches and what it
   guarantees, which is what a visitor came for.                                */

.site-reach {
    max-width: 940px;
    padding-top: var(--s5);
    border-top: 1px solid var(--ink-rule);
}

.site-reach__legend {
    display: block;
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--on-ink-3);
}

/* Named places, set large enough to read as a claim about coverage rather than
   as a row of tags. The separators are drawn rather than typed, so a screen
   reader hears a list and not a run of punctuation. */
.site-reach__list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s2) 0;
    margin: var(--s4) 0 0;
    padding: 0;
    list-style: none;
}

.site-reach__item {
    font-size: clamp(1rem, 1.5vw, 1.2rem);
    color: var(--on-ink);
    white-space: nowrap;
}

.site-reach__item + .site-reach__item::before {
    content: "";
    display: inline-block;
    width: 4px;
    height: 4px;
    margin: 0 var(--s3) .22em;
    border-radius: 50%;
    background: var(--accent);
}

/* The one section on the page carried entirely by its own sentence. Wider
   measure and larger type than a section head normally gets, because there is
   nothing beside it to share the reader's attention with. */
/* Paper, not the sunk tone: the section below it is sunk, and two sunk
   sections in a row run together into one long field with a hairline in it. */
.site-section--statement { background: var(--paper); }

.site-statement {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s5);
}

.site-statement .site-head__title {
    margin: 0;
    font-size: clamp(2.1rem, 4.6vw, 3.4rem);
    /* The measure belongs on the heading, not on the box around it: a ch is
       relative to the element's own font size, and on the wrapper it was being
       counted in 17px body characters, which broke a nine-word sentence over
       eight lines. */
    max-width: 15ch;
}

.site-statement .site-head__body {
    max-width: 46ch;
    font-size: clamp(1.05rem, 1.6vw, 1.2rem);
    line-height: 1.62;
}

.site-statement .site-head__body:last-child { margin-bottom: 0; }

@media (min-width: 900px) {
    /* Title and explanation side by side, which is what makes this read as a
       statement being explained rather than as one more column of prose. */
    .site-statement {
        grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
        gap: clamp(var(--s6), 5vw, var(--s8));
        align-items: start;
    }

    .site-statement__body { padding-top: var(--s5); }
}

/* The builder's own mark, sized to sit under the state's rather than beside it:
   the Ministry publishes this portal and ENVGREEN built it, and the footer
   should say so in that order. */
.site-footer__builder { display: block; margin-top: var(--s3); }

.site-footer__builder img {
    display: block;
    width: clamp(160px, 18vw, 200px);
    height: auto;
    /* The reversed cut is drawn at full strength for a green ground. On the
       maroon it is a credit, not a second logo, so it is held back a little. */
    opacity: .82;
}
