/*
 * ============================================================================
 * PARKLAND — the destination pack. ADR-0021's second.
 * ============================================================================
 *
 * Who it suits: an organization whose subject is a PLACE somebody is being invited to
 * visit, rather than an organization asking to be supported. Parks, trails, gardens,
 * campuses, preserves.
 *
 * The language is the national-park poster. A park poster is not a photograph with a
 * caption — it is four or five flat inks, cut into horizontal strata by a hard-edged
 * ridgeline, with one line of type set large enough to read from across a road. That is
 * the whole design, and it is why this pack can finish a page with NO PHOTOGRAPHY AT ALL:
 * a poster's landscape is drawn, not shot.
 *
 * It is Direction B's bones — flat fields, hard edges, colour doing structural work rather
 * than tinting white cards — re-voiced away from the civic poster's straight seam. Where
 * that pack cut its fields apart with a ruled line, this one cuts them with a horizon.
 *
 * ----------------------------------------------------------------------------
 * THE FOUR LAWS. EVERY RULE BELOW OBEYS THEM.
 *
 * 1. THE RIDGE. A field never begins on a straight edge. Every section that carries a
 *    ground of its own draws a RIDGELINE at its top — a hard-edged organic silhouette,
 *    flat-filled in that section's OWN ground, biting upwards into whatever is above it.
 *    It belongs to the section starting the field, never to the one ending it, so the
 *    device is self-contained: any two sections in any order still interlock. That is the
 *    signature and it is the one memorable thing on the page.
 *
 *    It is drawn as an ALPHA MASK, never as a coloured SVG. A data-URI carrying a fill
 *    would be a colour this pack owns, and law 4 forbids that. A mask is colourless; the
 *    paint underneath it is always a tenant token.
 *
 * 2. ONE RHYTHM. `--park-band` is the only vertical space between two sections, and each
 *    pays half of it at each end so that any two neighbours add up to exactly one. A
 *    section carrying a field pays the whole band instead, because that padding is the
 *    margin inside a printed panel rather than a gap. `--k1` … `--k13` is the one spacing
 *    scale inside them: 8px times {1, 2, 3, 5, 8, 13}. No rule below invents a length.
 *
 * 3. THE INK LAW. A field of colour is paired here, once, with the ink that reads on it.
 *    Measured on The Dakota Rogers Project's own palette, which is the brand this pack was
 *    cut for:
 *
 *      paper  field -> --park-ink      15.74:1     (warm white / warm black)
 *      deep   field -> --park-paper    13.15:1
 *      deep   field -> --park-golden    6.81:1     labels and small caps
 *      deep   field -> --park-sage      6.47:1     secondary prose
 *      sage   field -> --park-deep      6.47:1
 *      golden field -> --park-deep      6.81:1
 *      sky    field -> --park-deep      8.44:1
 *      forest field -> --park-paper     8.14:1
 *      spot   field -> NO TEXT, EVER    (3.93:1 on paper, 4.01:1 on ink, 3.35:1 on deep —
 *                                        every one of them too tight to read a sentence
 *                                        off, and the colour is too loud to be quietened)
 *
 *    The spot is the loudest ink in the palette and it is spent on ridges, rules, trail
 *    markers and the focus ring, where the bar is 3:1 against adjacent colour. It is never
 *    a ground somebody has to read words on.
 *
 * 4. NO COLOURS OF ITS OWN. Every colour below is a token the tenant's theme fills. This
 *    pack on a forest-green park and on a desert-ochre one are the same design wearing two
 *    brands. Every `var()` carries the base stylesheet's own value as its fallback, so a
 *    tenant who has saved nothing gets a coherent page rather than a transparent one.
 * ----------------------------------------------------------------------------
 *
 * WHAT A PACK IS ALLOWED TO BE, unchanged from `civic.css`:
 *
 * It OVERRIDES ONLY (ADR-0021 decision 3). `site.css` is loaded first and is complete on
 * its own; everything here assumes a finished page underneath and changes how it carries
 * itself. A section this pack never mentions still renders sanely.
 *
 * It owns appearance AND EVERYTHING CSS CAN DO (decision 2): hover treatments, reveals,
 * transitions. Nothing here is scripted.
 */

/*
 * ---------------------------------------------------------------------------
 * THE INKS.
 *
 * Eight names for eight tenant tokens, so every rule below reads as a composition decision
 * ("this field is the deep one") rather than as a token lookup.
 *
 * FOUR OF THESE SLOTS HAD NO CONSUMER BEFORE THIS PACK. `--brand-quinary`, `--brand-white`,
 * `--brand-black` and `--brand-free` reach the page on the `.site` wrapper
 * (`themeVariables`, `apps/sites/src/render/theme-style.ts`) and that file says in writing
 * that nothing reads them yet. Spending them is a PACK's decision to make and this is the
 * precedent it follows: `civic.css` gave `--brand-quinary` a job the same way. Nothing in
 * core changes, no tenant who has not chosen them is affected — every fallback below is the
 * value `site.css` already paints.
 * ---------------------------------------------------------------------------
 */
.site {
  --park-forest: var(--accent);
  --park-sage: var(--accent-teal);
  --park-golden: var(--accent-gold);
  --park-deep: var(--ground-dark);
  --park-sky: var(--brand-quinary, #a9c9dc);
  --park-paper: var(--brand-white, #f4f6fa);
  --park-ink: var(--brand-black, #141828);
  --park-spot: var(--brand-free, var(--accent-gold));

  /*
   * The base's own neutrals, re-pointed at the tenant's paper and ink. `site.css` declares
   * these at `:root` as literal greys chosen for one chamber's brand; a park's warm white
   * is a different substance from #f4f6fa and the difference is most of the personality.
   */
  --paper: var(--park-paper);
  --card: var(--park-paper);
  --ink: var(--park-ink);
  --ink-soft: color-mix(in srgb, var(--park-ink) 78%, var(--park-paper));
  --ink-mute: color-mix(in srgb, var(--park-ink) 60%, var(--park-paper));
  --on-ink: var(--park-paper);
  --on-ink-mute: color-mix(in srgb, var(--park-paper) 72%, var(--park-deep));
  --tint: color-mix(in srgb, var(--park-sage) 22%, var(--park-paper));
  --rule: color-mix(in srgb, var(--park-ink) 16%, var(--park-paper));

  /* The base's teal kicker is one chamber's literal. A park's small caps are its own ink. */
  --kicker: var(--park-forest);
  --kicker-ink: var(--park-forest);
  --kicker-on-ink: var(--park-golden);

  /* 8px, times 1, 2, 3, 5, 8, 13. Nothing below picks a length outside this list. */
  --k1: 0.5rem;
  --k2: 1rem;
  --k3: 1.5rem;
  --k5: 2.5rem;
  --k8: 4rem;
  --k13: 6.5rem;

  /* The one band between sections: 64px on a phone, 104px on a wide window. */
  --park-band: clamp(var(--k8), 7vw, var(--k13));

  /*
   * How far a ridgeline bites up into the field above it, and it is deliberately no deeper
   * than HALF A BAND — which is what a paper section pays at its bottom end. A ridge draws
   * entirely above its own section and takes no space of its own, so a deeper one would
   * reach past the neighbour's padding and its crowns would land on the last line of that
   * neighbour's text. Capped here rather than checked at each use.
   */
  --park-ridge: clamp(1.75rem, 3.5vw, 3rem);

  --park-rule: 3px;

  /*
   * A poster has no rounded corners and nothing floats. The organic geometry in this design
   * is in the ridgelines and the ornaments, never in a corner radius — a park poster with
   * 14px corners is a web page wearing a poster's colours.
   */
  --radius: 0;
  --radius-card: 0;
  --lift: none;
  --lift-raised: none;
}

/*
 * ---------------------------------------------------------------------------
 * THE RIDGELINE ITSELF.
 *
 * Two silhouettes, both `preserveAspectRatio="none"` so they stretch to any width without
 * a media query, both percent-encoded so the URL survives every parser.
 *
 * `--park-ridge-hills` is the far horizon: three long shallow crests. It is what a field
 * of open ground begins on.
 *
 * `--park-ridge-canopy` is the near one: a tighter, taller row of rounded crowns, the
 * silhouette of a treeline rather than a landform. It is what a dark field begins on, so
 * that the darkest strata of the page read as woodland rather than as a block.
 *
 * Both are ALPHA MASKS (law 1) — black is opaque, everything outside the path is nothing.
 *
 * EACH PATH REACHES x=1200, WHICH IS THE WHOLE VIEWBOX. The first cut of the canopy was
 * written as a chain of relative curves that summed short, so with `preserveAspectRatio`
 * off the silhouette ran out before the right-hand edge and the last two hundred pixels of
 * every dark band arrived as a straight-topped block. Absolute quadratics are used for
 * exactly that reason: the last control point is written down rather than accumulated.
 * ---------------------------------------------------------------------------
 */
.site {
  --park-ridge-hills: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 100' preserveAspectRatio='none'%3E%3Cpath d='M0 100V62Q120 26 260 48Q400 70 540 40Q680 10 820 44Q960 78 1090 42Q1160 22 1200 34V100Z' fill='%23000'/%3E%3C/svg%3E");
  --park-ridge-canopy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 100' preserveAspectRatio='none'%3E%3Cpath d='M0 100V72Q40 22 80 66Q120 18 160 68Q200 24 240 64Q280 14 320 70Q360 26 400 66Q440 16 480 68Q520 22 560 64Q600 12 640 70Q680 28 720 66Q760 18 800 68Q840 24 880 62Q920 14 960 70Q1000 26 1040 66Q1080 16 1120 68Q1160 30 1200 60V100Z' fill='%23000'/%3E%3C/svg%3E");
}

/*
 * LAW 2, STATED ONCE. `--park-band` is the gap BETWEEN two sections, so a section pays
 * half of it at each end and any two neighbours add up to exactly one band. Paying the
 * whole band at both ends — which is what the first cut of this pack did — makes the gap
 * two bands, and measured at 1440 that put 208px of nothing between a heading and the
 * cards belonging to it.
 *
 * A section carrying a FIELD is the exception and pays the whole band at each end: that
 * padding is not a gap, it is the margin inside a printed panel, and a colour band with
 * 52px of air in it reads as a stripe rather than a stratum. Those rules are further down,
 * with the fields.
 *
 * The list is `site.css`'s own, verbatim, so a section the base knows about cannot be left
 * out of the rhythm by accident. Every other exception below is deliberate and named.
 */
.hero,
.text,
.feature-row,
.split,
.card-list,
.gallery,
.video,
.faq,
.contact,
.join,
.directory,
.events,
.posts,
.plans,
.board,
.sponsors,
.showcase,
.stat-band,
.cta-band,
.recognition,
.event-detail,
.post-detail,
.empty-state {
  padding-block: calc(var(--park-band) / 2);
}

/*
 * A heading block and the list under it are ONE section wearing two blocks, and the
 * renderer has no way to say so — `card-list` carries a heading slot but no body, so an
 * intro sentence has to arrive as the `text` block before it. Welding them here is what
 * lets an author compose that pairing without a gap opening between a heading and the
 * things it is heading.
 */
.text + .card-list,
.text + .feature-row,
.text + .gallery {
  padding-block-start: 0;
}

.text:has(+ .card-list),
.text:has(+ .feature-row),
.text:has(+ .gallery) {
  padding-block-end: var(--k3);
}

/*
 * THE FIELDS, assigned by what a section IS rather than by where it sits.
 *
 * `--park-field` is the ground, `--park-on-field` the ink law 3 pairs with it, and
 * `--park-crest` which of the two silhouettes cuts it in. Three declarations name the
 * stratum; the two rules after them build every coloured band on every page of this pack.
 *
 * A field paints edge to edge — `.site-main` insets the page column, so a field escapes it
 * with a negative margin and pays it back as padding, without ever measuring the gutter.
 *
 * A pack decides appearance once (decision 2) and an author must not have to remember which
 * band number they are on. So the ground follows the section's own declared meaning: a bold
 * call to action is the deep woodland, a quiet one is the golden hour, a contact block is
 * the sky, and a picture-beside-words band takes its ground from the side its picture is on
 * — which is the setting an author already alternates to give a page its rhythm.
 */
.cta-band[data-tone='bold'] {
  --park-field: var(--park-deep);
  --park-on-field: var(--park-paper);
  --park-crest: var(--park-ridge-canopy);
}

.cta-band[data-tone='quiet'] {
  --park-field: var(--park-golden);
  --park-on-field: var(--park-deep);
}

/*
 * THE SKY IS THE HERO'S AND NOBODY ELSE'S. This band was the sky first, and on the contact
 * page — where the hero is the only thing above it — that put two identical fields either
 * side of one treeline, so the treeline floated instead of dividing anything. A stratum
 * that repeats immediately is not a stratum.
 */
.contact {
  --park-field: var(--park-sage);
  --park-on-field: var(--park-deep);
}

.split[data-side='right'] {
  --park-field: var(--park-sage);
  --park-on-field: var(--park-deep);
}

.cta-band,
.contact,
.split[data-side='right'] {
  position: relative;
  background: var(--park-field);
  color: var(--park-on-field);
  margin-inline: calc(50% - 50vw);
  padding-inline: max(var(--gutter), calc(50vw - var(--page) / 2));
  /* The whole band at each end, not half: see law 2. This padding is the panel's margin. */
  padding-block: var(--park-band);

  /*
   * NO MARGIN AT ALL, and that is the whole trick. The ridge is drawn above the section and
   * bites straight into the previous one's padding, which is where the interlock comes
   * from. The first cut reserved half a ridge here, and it opened a strip of PAGE between
   * two neighbouring fields — so where a dark band met the dark footer, the gaps between
   * the crowns showed warm white and the treeline came out as a row of white teeth against
   * two greens that should have read as one wood. Measured on /build-the-park before this.
   */
  margin-top: 0;
}

.cta-band::before,
.contact::before,
.split[data-side='right']::before {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: 100%;
  height: var(--park-ridge);
  margin-bottom: -1px;
  background: var(--park-field);
  -webkit-mask-image: var(--park-crest, var(--park-ridge-hills));
  mask-image: var(--park-crest, var(--park-ridge-hills));
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  pointer-events: none;
}

/*
 * EDIT MODE LAYS THE PAGE OUT IDENTICALLY, and the first cut of `civic.css` proved what
 * happens when a pack forgets: `EditableSection` wraps every declared block in a
 * `div[data-cf-edit-section]`, so a rule keyed on the section's relationship to the page
 * column silently stops matching and the fields lose their bleed. The escape above is
 * measured from the element's own containing block, so a wrapped section escapes the
 * WRAPPER instead of the page — which is the same distance, because the wrapper is what
 * carries the frame's side padding in edit mode. Both spellings are given a full-bleed
 * wrapper so the two arrangements agree.
 */
[data-cf-edit-section]:has(> .cta-band),
[data-cf-edit-section]:has(> .contact),
[data-cf-edit-section]:has(> .split[data-side='right']) {
  padding-inline: 0;
}

/*
 * A `split` is the one section the renderer wraps on an ORDINARY visit too: `Split` renders
 * inside `InView`'s `div.reveal`, so the page's own gutter lands on the wrapper and a field
 * that bleeds would start inside it. `site.css` pays exactly this exemption for the numbers
 * band and says why; this is the same exemption for the same reason.
 */
.site-main > .reveal:has(> .split[data-side='right']),
.site-main > [data-cf-edit-section]:has(> .reveal > .split[data-side='right']) {
  padding-inline: 0;
}

/*
 * Two `split` bands in a row get one and six tenths of a band from the base, which is a
 * second rhythm beside law 2's. On a page built out of stacked splits — a park's feature
 * list is exactly that — it is the rhythm every band uses, so law 2 would hold nowhere.
 */
.reveal:has(> .split) + .reveal:has(> .split) > .split {
  padding-block-start: var(--park-band);
}

/*
 * ---------------------------------------------------------------------------
 * TYPE. THE PARK-ENTRANCE SIGN.
 *
 * Two faces, and they do not share a job.
 *
 * The DISPLAY face is set large and stops at `h2`. It is a high-contrast old-style serif,
 * which is a carved letterform rather than a poster slab — so it is used the way carved
 * letters are used: enormous, tight, and nowhere else. Below `h2` it would go weedy, and a
 * weedy serif at 15px is the single fastest way to make a considered page look default.
 *
 * Everything smaller is the BODY face in the map-legend voice: uppercase, tracked out,
 * semibold, small. A national park's own signage does exactly this — the place name is
 * carved, the trail names are stencilled — and it means the two faces never compete.
 * ---------------------------------------------------------------------------
 */
.site h1,
.site h2 {
  font-family: var(--site-font-display, Georgia, 'Times New Roman', serif);
  font-weight: 600;
  line-height: 0.98;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

.site h1 {
  font-size: clamp(2.75rem, 9vw, 6rem);
}

.site h2 {
  font-size: clamp(2rem, 5.5vw, 3.5rem);
}

.site h3,
.site h4,
.site h5,
.site h6 {
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.3;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/*
 * The eyebrow. Every small label on the page is the same object — a stencilled line with a
 * short spot-coloured rule in front of it — and it is what tells a reader which stratum
 * they are standing in.
 */
.site .kicker,
.site .showcase-kicker,
.site .event-venue,
.site .post-date,
.site .directory-count {
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/*
 * ---------------------------------------------------------------------------
 * THE MASTHEAD. A sign at the trailhead: the deep field, the name carved into it, the
 * trails stencilled beside it, and a golden rule along the bottom edge.
 * ---------------------------------------------------------------------------
 */
.site-header {
  background: var(--park-deep);
  color: var(--park-paper);
  border-bottom: var(--park-rule) solid var(--park-golden);
  box-shadow: none;
}

.site-header .site-name {
  font-family: var(--site-font-display, Georgia, serif);
  font-weight: 600;
  font-size: clamp(1.35rem, 3vw, 1.75rem);
  letter-spacing: 0;
  color: var(--park-paper);
  text-transform: none;
}

.site-header .site-nav .menu > li > a,
.site-header .site-nav .menu > .menu-heading > span {
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--park-paper);
  border-radius: 0;
  background: none;
  position: relative;
  padding-block: var(--k1);
}

/*
 * The trail marker under a hovered entry. A poster's hover is a mark being made, not a
 * surface lifting — so it is a spot-coloured rule appearing under the entry, the same
 * object as the rule over every card on the site.
 *
 * IT IS THE ANCHOR'S OWN BORDER, not a pseudo-element. The first cut drew an `::after` bar
 * and scaled it in from the left; on the rendered page the pseudo painted nothing and
 * `getComputedStyle(a, '::after').transform` came back `none`, so the affordance was dead
 * at rest and dead on hover. The `tabs` format already reserves `border-bottom: 2px solid
 * transparent` on this exact element for exactly this purpose — colouring what the base
 * already reserved is one declaration instead of six, and it cannot be painted over.
 */
.site-header .site-nav .menu > li > a {
  border-bottom: var(--park-rule) solid transparent;
  transition:
    border-color 160ms ease-out,
    color 160ms ease-out;
}

.site-header .site-nav .menu > li > a:hover,
.site-header .site-nav .menu > li > a:focus-visible,
.site-header[data-nav-format='tabs'] .menu > li > a[aria-current='page'] {
  border-bottom-color: var(--park-spot);
}

.site-header .site-nav .menu > li > a:hover {
  color: var(--park-golden);
  background: none;
}

/*
 * THE PAGE YOU ARE ON. `tabs` is the format this site wears — a flat row of trails, no
 * dropdowns, and a real disclosure on a phone, which is what the blueprint's "simple, no
 * dropdowns" asks for and what `inline` cannot give (the base puts `inline` in the group
 * that never grows a hamburger, so eight entries stacked above the hero at 390 was the
 * whole of the mobile masthead until this was changed).
 *
 * The base marks the current tab in `--accent`, which on this masthead is the forest green
 * on the deep forest ground — measured 1.62:1, and caught on seven pages. The current tab
 * takes the gold instead (6.81:1) and its rule takes the spot ink, which is the same trail
 * marker every other entry grows on hover.
 */
.site-header[data-nav-format='tabs'] .menu > li > a[aria-current='page'] {
  color: var(--park-golden);
  border-bottom-color: var(--park-spot);
}

@media (width < 720px) {
  .site-header[data-nav-format='tabs'] .menu > li > a[aria-current='page'] {
    border-left-color: var(--park-spot);
    background: none;
  }
}

/* The burger's bars are painted `--ink` by the base, which is invisible on this masthead. */
.site-header .site-menu > summary .burger,
.site-header .site-menu > summary .burger::before,
.site-header .site-menu > summary .burger::after {
  background: var(--park-paper);
}

.site-header .site-menu[open] > summary {
  background: none;
  color: var(--park-golden);
}

/*
 * The phone's open menu is the same sign, continued: the deep field carries on down the
 * page and the trails stack inside it. The base already drops the nav into a panel under
 * the header at narrow widths; this only re-grounds it.
 */
@media (max-width: 60rem) {
  .site-header .site-nav {
    background: var(--park-deep);
    border-top: 1px solid color-mix(in srgb, var(--park-paper) 22%, transparent);
  }

  .site-header .site-nav .menu > li > a {
    padding-block: var(--k2);
    display: block;
  }
}

/*
 * ---------------------------------------------------------------------------
 * THE OPENING. THE ONE RISK THIS DIRECTION TAKES.
 *
 * There is no photograph in this hero and there is not meant to be one. A park that does
 * not exist yet has no photograph of itself, and a stock meadow would be a lie about a
 * place. So the hero IS the poster: four flat strata — sky, far ridge, near ridge, ground —
 * cut by the same silhouettes the rest of the page is cut by, with the display line sitting
 * on the sky where a poster's title sits.
 *
 * Every stratum is a background layer on one element rather than four nested divs, because
 * the markup is the renderer's and this pack may not add to it.
 *
 * WHEN A PICTURE IS EVENTUALLY GIVEN, the strata stay and the photograph lands in
 * `.hero-picture` as a hard-edged block hanging over them — see below. Nothing has to be
 * redesigned the day the rendering arrives.
 * ---------------------------------------------------------------------------
 */
.hero,
.hero[data-align='full-bleed'] {
  position: relative;
  isolation: isolate;
  overflow: visible;
  min-height: 0;
  margin-inline: calc(50% - 50vw);
  padding-inline: max(var(--gutter), calc(50vw - var(--page) / 2));
  padding-block: clamp(var(--k8), 11vw, calc(var(--k13) * 1.6)) 0;
  border-bottom: none;
  color: var(--park-deep);
  background: linear-gradient(var(--park-sky), var(--park-sky));
  align-content: start;
  gap: var(--k3);
}

[data-cf-edit-section]:has(> .hero) {
  padding-inline: 0;
}

/*
 * The far ridge and the near ridge, stacked at the foot of the sky. Two pseudo-elements,
 * two silhouettes, two inks — sage behind, forest in front — and the ground below them is
 * the deep field the doors are welded onto.
 */
.hero::before,
.hero::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  pointer-events: none;
  z-index: -1;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

.hero::before {
  bottom: clamp(3rem, 7vw, 6rem);
  height: clamp(5rem, 13vw, 11rem);
  background: var(--park-sage);
  -webkit-mask-image: var(--park-ridge-hills);
  mask-image: var(--park-ridge-hills);
}

.hero::after {
  bottom: 0;
  height: clamp(5rem, 11vw, 9rem);
  background: var(--park-forest);
  -webkit-mask-image: var(--park-ridge-canopy);
  mask-image: var(--park-ridge-canopy);
}

/*
 * Written at `[data-align='full-bleed']` strength, not at `.hero` strength, and that is
 * not decoration. The base gives the full-bleed arrangement its own block of rules — words
 * at the BOTTOM of the band, an extra gutter inside `.hero-words`, and a sub-line forced to
 * `--on-ink` because it is meant to be read over a photograph. Every one of those is right
 * for a photographic hero and wrong for a drawn one, and every one of them is a `(0,2,1)`
 * selector that a `.hero .hero-sub` rule loses to. Matching the strength is the only honest
 * fix; the alternative is an `!important`, which is a note saying the cascade was not read.
 */
.hero .hero-words,
.hero[data-align='full-bleed'] .hero-words {
  position: relative;
  z-index: 1;
  max-width: min(100%, 40rem);
  padding-inline: 0;
  padding-bottom: clamp(var(--k13), 18vw, 16rem);
}

/*
 * The measure goes on the HEADING, in `em`, so it is counted in the display face's own
 * letters and stays the same number of words a line at every size. Put on `.hero-words` in
 * `ch` it was counted in the 16px body face — 22ch resolved to 175px and the poster title
 * came out one word per line, measured before this rule.
 */
.hero h1,
.hero[data-align='full-bleed'] h1 {
  color: var(--park-deep);
  max-width: 11em;
  font-size: clamp(2.75rem, 9vw, 6rem);
  line-height: 0.98;
  letter-spacing: -0.015em;
}

.hero .hero-sub,
.hero[data-align='full-bleed'] .hero-sub {
  color: var(--park-deep);
  font-size: clamp(1.0625rem, 0.95rem + 0.6vw, 1.3125rem);
  max-width: 34ch;
  margin-top: var(--k2);
}

/*
 * The base's one orchestrated load moment belongs to a photograph settling behind rising
 * words. There is no photograph here and the strata are painted by this section itself, so
 * the words arrive with the poster rather than after it.
 */
.hero[data-align='full-bleed'] .hero-words > * {
  animation: none;
}

/*
 * A photograph, the day there is one: a hard-edged block laid over the strata on the right,
 * squared off, no radius, no shadow. It does not become the hero; it sits IN the poster.
 */
.hero-picture,
.hero[data-align='full-bleed'] .hero-picture {
  position: relative;
  inset: auto;
  z-index: 1;
  border-top: var(--park-rule) solid var(--park-spot);
}

.hero-picture img,
.hero[data-align='full-bleed'] .hero-picture img {
  border-radius: 0;
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  animation: none;
}

/* The base darkens a photograph with a scrim so white words read on it. Nothing here is
   written over the picture, so the scrim would only be mud. */
.hero[data-align='full-bleed'] .hero-picture::after,
.hero[data-align='full-bleed'] .hero-picture::before {
  display: none;
}

@media (min-width: 62rem) {
  .hero:has(.hero-picture) {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: end;
    column-gap: var(--k5);
  }

  .hero:has(.hero-picture) .hero-words {
    padding-bottom: clamp(var(--k8), 10vw, 9rem);
  }
}

/*
 * ---------------------------------------------------------------------------
 * THE DOORS. A card list that FOLLOWS a hero, and only there.
 *
 * The renderer's hero carries ONE link slot and a destination page needs two openings —
 * "come and look" and "come and help". So the two are composed rather than declared: a
 * hero with an empty link slot, and a two-card list under it welded to the hero's foot as
 * one object. No new section, no new slot; an author builds it by putting one familiar
 * thing under another.
 *
 * WHAT MAKES IT THE DOORS AND NOT JUST A LIST: no heading of its own, and exactly two
 * cards. Both conditions are in every selector below. Keyed on "a card list after a hero"
 * alone — which is what the first cut did — the treatment fired on /build-the-park's
 * thirteen ways to help, painting them all as golden panels and hiding the section's own
 * heading behind them. Two headless panels under a hero is a composition; three is a list,
 * and the shape of the content is what says which.
 *
 * Written twice throughout, once for an ordinary visit and once through
 * `[data-cf-edit-section]`, for the reason `civic.css` records: in edit mode the hero and
 * the list are no longer siblings and every `+` rule silently stops matching.
 * ---------------------------------------------------------------------------
 */
.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child),
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) > .card-list {
  margin-top: 0;
  padding-block: 0 var(--k5);
  background: var(--park-deep);
  color: var(--park-paper);
  margin-inline: calc(50% - 50vw);
  padding-inline: max(var(--gutter), calc(50vw - var(--page) / 2));
}

.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child)::before,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) > .card-list::before {
  display: none;
}

[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section]:has(> .card-list > .cards > .card:nth-child(2):last-child) {
  padding-inline: 0;
  margin-top: 0;
}

.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .cards,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  margin-top: calc(var(--k5) * -1);
  position: relative;
  z-index: 2;
}

@media (min-width: 48rem) {
  .hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .cards,
  [data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .cards {
    grid-template-columns: 1fr 1fr;
    gap: var(--park-rule);
  }
}

/*
 * A door is a flat golden panel with the deep ink on it — 6.81:1, law 3 — and its label is
 * the stencilled voice. Not a button, not a card: a panel the width of half the page, which
 * is what a poster does with a call to action.
 */
.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card {
  background: var(--park-golden);
  color: var(--park-deep);
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: var(--k3) var(--k3) var(--k5);
  display: grid;
  align-content: start;
  gap: var(--k1);
  transition: background 160ms ease-out;

  /*
   * The positioning context the stretched anchor below needs. Without it the `::before`
   * that covers the panel resolves against some ancestor further up, and the door reads as
   * a target while only the six words of its label actually are one — clicked dead centre
   * at 1440, the first cut navigated nowhere.
   */
  position: relative;
}

.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card:nth-child(2),
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card:nth-child(2) {
  background: var(--park-sage);
}

.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card:hover,
.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card:focus-within,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card:hover,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card:focus-within {
  background: var(--park-paper);
}

.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card h2,
.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card h3,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card h2,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card h3 {
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-size: clamp(1rem, 2.2vw, 1.25rem);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--park-deep);
  margin: 0;
}

.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card .card-body,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card .card-body {
  color: var(--park-deep);
  font-size: 0.9375rem;
}

/*
 * The whole panel is the target. A door with a small blue link in the corner of it is two
 * things pretending to be one; the anchor is stretched over the panel and the label under
 * it becomes an arrow, which is the only ornament a poster's call to action gets.
 */
.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card-action,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card-action {
  margin: var(--k2) 0 0;
}

.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card-action a,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card-action a {
  position: static;
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--park-deep);
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
  box-shadow: none;
  text-decoration: none;
}

.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card-action a::before,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card-action a::before {
  content: '';
  position: absolute;
  inset: 0;
}

.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card-action a::after,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card-action a::after {
  content: ' \2192';
  display: inline-block;
  transition: transform 160ms ease-out;
}

.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card:hover .card-action a::after,
[data-cf-edit-section]:has(> .hero) + [data-cf-edit-section] > .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child) .card:hover .card-action a::after {
  transform: translateX(var(--k1));
}

/*
 * ---------------------------------------------------------------------------
 * ORDINARY CARDS. Flat panels on the paper, ruled at the top in the spot ink.
 *
 * The base's card is a white tile with a radius and a shadow, floating on a grey page. This
 * design has no tiles and nothing floats: a card is a region of the paper with a rule drawn
 * across the top of it, which is how a printed programme separates one entry from the next.
 * ---------------------------------------------------------------------------
 */
.card-list .card {
  background: none;
  border: 0;
  border-top: var(--park-rule) solid var(--park-spot);
  border-radius: 0;
  box-shadow: none;
  padding: var(--k2) 0 0;
  display: grid;
  align-content: start;
  gap: var(--k1);
  transition: border-color 160ms ease-out;
}

.card-list .card:hover,
.card-list .card:focus-within {
  border-top-color: var(--park-forest);
}

.card-list .card h3 {
  color: inherit;
  margin: 0;
}

.card-list .card h2 {
  font-size: clamp(1.5rem, 3vw, 2rem);
  margin: 0;
}

.card-picture img {
  border-radius: 0;
}

.card-list .cards {
  gap: var(--k5) var(--k3);
}

/*
 * A card's two answers. The blueprint's own rule for the wellness features is that each
 * card answers two questions — what is it, and why does it matter — so a card's body is two
 * paragraphs and they are NOT the same weight. The first is the description; the second is
 * the reason, and it is set smaller with a rule above it so a reader can take one card at a
 * glance and still find the reason when they want it.
 *
 * Keyed on the paragraph's position inside the card, which is structural rather than
 * content-aware: a one-paragraph card renders as one paragraph and loses nothing.
 *
 * SECOND OF EXACTLY TWO, and that precision is the point. Written as `p + p` it fired on
 * every paragraph after the first, so a card carrying four — a park feature with its
 * purpose, its outcome, its activities and its builder jobs — came out as three ruled
 * stripes. Two paragraphs is a question answered; four is prose, and prose is left alone.
 */
.card-list .card .card-body p:nth-child(2):last-child {
  margin-top: var(--k2);
  padding-top: var(--k2);
  border-top: 1px solid var(--rule);
  font-size: 0.9375rem;
  color: var(--ink-mute);
}

/*
 * ---------------------------------------------------------------------------
 * THE TRAIL. `card-list` in its `rows` arrangement.
 *
 * A list of cards in a row is a list. A list of cards that is a SEQUENCE — a build
 * programme, the stages of a project — is a path, and the blueprint asks for exactly that:
 * "Visitors should see that progress is happening." So the rows arrangement becomes a
 * walking trail: a dashed spot-coloured line with a marker at every stop, and the stops
 * numbered — the numbering earns its place here because the order is the information.
 * ---------------------------------------------------------------------------
 */
.card-list[data-align='rows'] .cards {
  counter-reset: park-stop;
  display: grid;
  /* One stop per row, always. The base auto-fits rows into columns, which turns a
     sequence back into a set — measured before this rule: three 400px columns. */
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  position: relative;
  max-width: 44rem;
}

.card-list[data-align='rows'] .card {
  counter-increment: park-stop;
  border-top: 0;
  position: relative;
  padding: var(--k3) 0 var(--k3) var(--k8);
  gap: var(--k1);
}

/* The trail itself: a dashed line running down the left of the stops. */
.card-list[data-align='rows'] .card::before {
  content: '';
  position: absolute;
  left: calc(var(--k3) - 1.5px);
  top: 0;
  bottom: 0;
  width: var(--park-rule);
  background: repeating-linear-gradient(
    var(--park-spot) 0 10px,
    transparent 10px 20px
  );
}

.card-list[data-align='rows'] .card:first-child::before {
  top: 50%;
}

.card-list[data-align='rows'] .card:last-child::before {
  bottom: 50%;
}

/* The marker: a filled stop with its number stencilled in it. */
.card-list[data-align='rows'] .card::after {
  content: counter(park-stop, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: calc(50% - var(--k3));
  width: var(--k5);
  height: var(--k5);
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--park-forest);
  color: var(--park-paper);
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
}

.card-list[data-align='rows'] .card h3 {
  color: var(--park-forest);
}

/*
 * ---------------------------------------------------------------------------
 * THE THREE ORNAMENTS: A LEAF, A TREE RING, A PATH.
 *
 * The blueprint's own graphic vocabulary, drawn rather than downloaded, and assigned BY
 * POSITION rather than by what a feature says — a pack that drew a dog for the second
 * column would be a stylesheet that knows the tenant's content, which is the line a pack
 * may not cross. Three positions, three marks, and they mean "first, second, third" the way
 * a printed key's symbols do.
 *
 * They appear only where the feature has no picture of its own. The day real artwork
 * arrives it takes the slot and the ornament stands down.
 * ---------------------------------------------------------------------------
 */
.feature-row .features {
  gap: var(--k5) var(--k3);
}

.feature-row .feature {
  border-top: var(--park-rule) solid var(--park-spot);
  padding-top: var(--k2);
}

/*
 * The mark carries on into a grid of cards, which is where most of this site's lists
 * actually live. NOT into the doors under the hero — those are two panels, not a key — and
 * not into the trail, whose marks are numbered stops.
 */
.feature-row .feature:not(:has(.feature-picture))::before,
.card-list[data-align='grid']:not(:where(.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child))) .card:not(:has(.card-picture))::before {
  content: '';
  display: block;
  width: var(--k5);
  height: var(--k5);
  margin-bottom: var(--k1);
  background: var(--park-forest);
}

/* A leaf: two opposite corners rounded all the way, which is exactly a leaf. */
.feature-row .feature:nth-child(3n + 1):not(:has(.feature-picture))::before,
.card-list[data-align='grid']:not(:where(.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child)))
  .card:nth-child(3n + 1):not(:has(.card-picture))::before {
  border-radius: 0 100% 0 100%;
}

/* Tree rings: concentric hairlines, growth read as a stack of years. */
.feature-row .feature:nth-child(3n + 2):not(:has(.feature-picture))::before,
.card-list[data-align='grid']:not(:where(.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child)))
  .card:nth-child(3n + 2):not(:has(.card-picture))::before {
  background: repeating-radial-gradient(
    circle at 50% 50%,
    var(--park-forest) 0 2px,
    transparent 2px 7px
  );
  border-radius: 50%;
  box-shadow: inset 0 0 0 2px var(--park-forest);
}

/* A path: two lanes of dashes going away from the reader. */
.feature-row .feature:nth-child(3n + 3):not(:has(.feature-picture))::before,
.card-list[data-align='grid']:not(:where(.hero + .card-list:not(:has(> h2)):has(> .cards > .card:nth-child(2):last-child)))
  .card:nth-child(3n + 3):not(:has(.card-picture))::before {
  background: repeating-linear-gradient(
    var(--park-forest) 0 5px,
    transparent 5px 11px
  );
  clip-path: polygon(38% 0, 62% 0, 100% 100%, 0 100%);
}

.feature-row .feature h2 {
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
}

.feature-picture img {
  border-radius: 0;
}

/*
 * ---------------------------------------------------------------------------
 * WORDS. The prose column, and the one place tree rings are spent large.
 * ---------------------------------------------------------------------------
 */
.text {
  max-width: none;
}

.text .prose,
.split .split-body,
.cta-band .cta-band-body {
  font-size: 1.0625rem;
  line-height: 1.65;
}

.text > h2 + .prose {
  margin-top: var(--k3);
}

/*
 * ---------------------------------------------------------------------------
 * A PICTURE-BESIDE-WORDS BAND WITH NO PICTURE, WHICH ON A SITE FOR A PLACE THAT DOES NOT
 * EXIST YET IS MOST OF THEM.
 *
 * The renderer draws no `.split-picture` at all when the slot is empty, so the band would
 * otherwise collapse into a single column of prose and stop being a composition.
 *
 * The first cut filled the empty half with a large disc of tree rings. It was cut after
 * looking at the result: seven feature bands down one page produced seven identical discs,
 * and a signature used seven times is wallpaper. The mark survives at the size it is
 * legible as a mark — the small ornament on a card — and nowhere else.
 *
 * What replaces it is not an ornament. The heading takes the left column at display size
 * and the prose takes the right, which is what an interpretive sign does with a feature
 * name, and it holds however many times it repeats because it is a layout rather than a
 * decoration.
 * ---------------------------------------------------------------------------
 */
/*
 * The band itself first. The base lays `.split` out as two columns — words, picture — and
 * with the picture slot empty the words keep column one and the page keeps a half-width
 * band with nothing beside it. Measured before this rule: every feature on The Park came
 * back at 45% of the column, breaking "Reflection Garden" across a line mid-word.
 */
.split:not(:has(.split-picture)) {
  display: block;
}

@media (min-width: 62rem) {
  .split:not(:has(.split-picture)) .split-words {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    column-gap: var(--k8);
    align-items: start;
  }

  .split:not(:has(.split-picture)) .split-words > h2 {
    grid-row: 1 / span 3;
    margin: 0;
  }

  .split:not(:has(.split-picture)) .split-body,
  .split:not(:has(.split-picture)) .split-action {
    grid-column: 2;
  }

  /* The rule that ties the two columns together, in the ink of whichever field it is on. */
  .split:not(:has(.split-picture)) .split-words > h2 {
    padding-top: var(--k2);
    border-top: var(--park-rule) solid var(--park-spot);
  }
}

.split-picture img {
  border-radius: 0;
}

.split[data-side='right'] .split-body,
.split[data-side='right'] h2 {
  color: var(--park-deep);
}

/*
 * ---------------------------------------------------------------------------
 * THE CALL TO ACTION, AND THE BUTTON THIS DESIGN USES EVERYWHERE.
 *
 * A poster's button is a rectangle of ink with stencilled letters in it. No gradient, no
 * radius, no shadow, no shift on hover — the hover inverts the block, which is what a
 * two-colour press does.
 * ---------------------------------------------------------------------------
 */
.hero-action a,
.hero[data-align='full-bleed'] .hero-action a,
.split-action a,
.cta-band-action a,
.text .prose a.button,
.contact form button,
.contact form [type='submit'] {
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-radius: 0;
  box-shadow: none;
  background: var(--park-forest);
  background-image: none;
  border: var(--park-rule) solid var(--park-forest);
  color: var(--park-paper);
  padding: var(--k2) var(--k3);
  transition:
    background 160ms ease-out,
    color 160ms ease-out;
}

.hero-action a:hover,
.hero[data-align='full-bleed'] .hero-action a:hover,
.split-action a:hover,
.cta-band-action a:hover,
.contact form button:hover,
.contact form [type='submit']:hover {
  background: transparent;
  color: var(--park-forest);
  /* The base lifts and shadows its buttons. Nothing in this design leaves the page. */
  transform: none;
  box-shadow: none;
}

.cta-band[data-tone='bold'] .cta-band-action a {
  background: var(--park-golden);
  border-color: var(--park-golden);
  color: var(--park-deep);
}

.cta-band[data-tone='bold'] .cta-band-action a:hover {
  background: transparent;
  color: var(--park-golden);
}

.cta-band[data-tone='quiet'] .cta-band-action a {
  background: var(--park-deep);
  border-color: var(--park-deep);
  color: var(--park-golden);
}

.cta-band[data-tone='quiet'] .cta-band-action a:hover {
  background: transparent;
  color: var(--park-deep);
}

.cta-band {
  display: grid;
  gap: var(--k3);
}

.cta-band h2 {
  max-width: 16ch;
}

.cta-band[data-tone='bold'] h2,
.cta-band[data-tone='bold'] .cta-band-body {
  color: var(--park-paper);
}

.cta-band[data-tone='quiet'] h2,
.cta-band[data-tone='quiet'] .cta-band-body {
  color: var(--park-deep);
}

@media (min-width: 62rem) {
  .cta-band {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    column-gap: var(--k8);
  }

  .cta-band-words {
    display: contents;
  }

  .cta-band h2 {
    grid-row: span 2;
  }
}

/*
 * ---------------------------------------------------------------------------
 * CONTACT, ON THE SKY FIELD. The form's inputs are hard-edged plates on it.
 * ---------------------------------------------------------------------------
 */
/*
 * Two columns on a wide window: what you might be getting in touch about on the left, the
 * form on the right. The base stacks all four children, which on a 1200px column leaves a
 * 544px form with 650px of empty field beside it.
 */
@media (min-width: 62rem) {
  .contact {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--k8);
  }

  .contact > h2,
  .contact > .contact-intro {
    grid-column: 1 / -1;
  }

  .contact > .contact-form {
    grid-column: 2;
    grid-row: 3;
    margin-top: 0;
  }
}

.contact h2,
.contact .contact-intro,
.contact .contact-details,
.contact label {
  color: var(--park-deep);
}

.contact input,
.contact textarea,
.contact select {
  border-radius: 0;
  border: 2px solid var(--park-deep);
  background: var(--park-paper);
  color: var(--park-ink);
}

.contact label {
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/*
 * ---------------------------------------------------------------------------
 * QUESTIONS, EVENTS, POSTS. Ruled entries on the paper, never tiles.
 *
 * The events list is here through its own rules now rather than through the shared card
 * object: the rows arrangement this named (`.events .event`) is retired, and the six
 * arrangements that replaced it are not tiles to begin with. The card grid is the one that
 * still is, and it takes the same square edges and the same spot rule below.
 * ---------------------------------------------------------------------------
 */
.faq .faq-item,
.posts .post {
  border: 0;
  border-top: var(--park-rule) solid var(--park-spot);
  border-radius: 0;
  box-shadow: none;
  background: none;
}

.faq .faq-question {
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-weight: 600;
  letter-spacing: 0.06em;
  border-radius: 0;
}

/*
 * The lists take the spot colour on the rule that opens them and square edges on everything,
 * which is the whole of this pack's hand: stencilled small print, a heavy spot rule, no
 * rounded corner anywhere. The rows between them stay hairlines — a spot rule under every
 * entry would be a page of stripes.
 */
.events .event-spine,
.events .event-ledger {
  border-top: var(--park-rule) solid var(--park-spot);
}

.events .event-spine .event-art,
.events .event-card .event-art,
.events .event-strip .event-art {
  border-radius: 0;
}

.events .event-ledger-day,
.events .event-agenda-time {
  color: var(--park-spot);
}

.events .event-agenda-month::after {
  background: var(--park-spot);
}

.events .event-agenda-item::before {
  transform: none;
  width: 0.625rem;
  height: 0.625rem;
  left: calc(var(--agenda-rail) - 0.3125rem);
  background: var(--park-spot);
}

.events .event-agenda-item:hover::before {
  transform: none;
}

.events img,
.posts img,
.gallery-picture img {
  border-radius: 0;
}

/*
 * A calendar with nothing in it yet, and a news page before the first post. Both are the
 * ordinary state of a site for a place that is still being built, so the line the base
 * writes is given the same stencilled voice and the same spot rule as everything else
 * rather than being left as a stray sentence in the middle of the page.
 */
.events-empty,
.posts-empty {
  border-top: var(--park-rule) solid var(--park-spot);
  padding-top: var(--k2);
  max-width: 32rem;
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

/*
 * ---------------------------------------------------------------------------
 * THE FOOT OF THE PAGE. The deep field again, entered over a canopy — so the page closes
 * the way it opened, walking into the trees.
 * ---------------------------------------------------------------------------
 */
.site-footer {
  position: relative;
  background: var(--park-deep);
  color: var(--park-paper);
  border-top: 0;
  margin-top: 0;
}

.site-footer::before {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: 100%;
  height: var(--park-ridge);
  margin-bottom: -1px;
  background: var(--park-deep);
  -webkit-mask-image: var(--park-ridge-canopy);
  mask-image: var(--park-ridge-canopy);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  pointer-events: none;
}

.site-footer .site-name {
  font-family: var(--site-font-display, Georgia, serif);
  color: var(--park-paper);
  text-transform: none;
  letter-spacing: 0;
}

.site-footer .menu > li > a,
.site-footer .menu > .menu-heading > span {
  font-family: var(--site-font-body, system-ui, sans-serif);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--park-paper);
}

.site-footer .menu > li > a:hover {
  color: var(--park-golden);
}

/*
 * ---------------------------------------------------------------------------
 * THE QUALITY FLOOR. Not announced anywhere on the page, and not optional.
 * ---------------------------------------------------------------------------
 */

/*
 * The focus ring is the spot ink — the one job in this design where terracotta at 3.93:1
 * against the paper is not merely allowed but correct, because a focus indicator's bar is
 * 3:1 against what surrounds it and the loudest colour in the palette is the one a keyboard
 * user should be able to find without looking for it. Two rings, so it is visible on the
 * paper AND on every coloured field.
 */
.site :focus-visible,
.hero :focus-visible,
.site-header :focus-visible,
.site-footer :focus-visible {
  outline: var(--park-rule) solid var(--park-spot);
  outline-offset: 2px;
  box-shadow: 0 0 0 calc(var(--park-rule) + 2px) var(--park-paper);
  border-radius: 0;
}

.site-header :focus-visible,
.cta-band[data-tone='bold'] :focus-visible,
.site-footer :focus-visible {
  box-shadow: 0 0 0 calc(var(--park-rule) + 2px) var(--park-deep);
}

/*
 * Nothing in this pack animates a position or a size, so reduced motion has little to take
 * away — but the two transitions that exist (the trail marker under a nav entry, the arrow
 * on a door) are movement, and a reader who has asked for none gets the end state instantly
 * rather than a shorter version of the journey.
 */
@media (prefers-reduced-motion: reduce) {
  .site *,
  .site *::before,
  .site *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/*
 * 390px. The ridge shallows out — a 72px silhouette across a 390px window is a wave, not a
 * horizon — and the hero's strata come down with it so the display line is never pushed off
 * the fold by its own scenery.
 */
@media (max-width: 30rem) {
  .site {
    --park-ridge: 1.75rem;
  }

  .hero {
    padding-top: var(--k5);
  }

  .hero .hero-words {
    max-width: none;
    padding-bottom: clamp(var(--k8), 30vw, var(--k13));
  }

  .card-list[data-align='rows'] .card {
    padding-left: var(--k5);
  }

  .card-list[data-align='rows'] .card::after {
    width: var(--k3);
    height: var(--k3);
    font-size: 0.625rem;
    top: calc(50% - var(--k1) * 1.5);
  }

  .card-list[data-align='rows'] .card::before {
    left: calc(var(--k1) * 1.5 - 1.5px);
  }
}
