@import url('/assets/tokens.css');

/* Alud hub. Habitat's visual system in its three appearances.

   Editorial (default) follows find-house-switzerland docs/design-system.md:
   structure from rules, alignment and whitespace; no cards, shadows or
   gradients; one corner radius, 0; a light grotesque for what people read and
   uppercase mono for what the system asserts. It has no motion vocabulary.

   Alpine (`:root[data-design="b"]`) follows docs/design-system-alpine.md:
   layered surfaces, glacier accent, confident display weight, key-lit
   controls and one arrival sequence. Its rules restate only shape, elevation
   and weight; colours arrive through the re-pointed tokens. */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; --header-h: 76px; }
body { margin: 0; min-height: 100vh; display: flex; flex-direction: column; background: var(--paper); color: var(--ink); font-family: var(--sans); font-size: 16px; line-height: 1.55; -webkit-font-smoothing: antialiased; }
main { flex: 1; }
[hidden] { display: none !important; }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 4px; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
h1, h2, h3 { text-wrap: balance; }
.frame { width: min(100% - 2 * var(--gutter), var(--frame)); margin-inline: auto; }
.skip { position: absolute; left: 12px; top: -100px; z-index: 10; padding: 12px 16px; background: var(--paper); color: var(--ink); }
.skip:focus { top: 12px; }

/* ---------- type roles ---------------------------------------------------- */

.eyebrow { margin: 0; color: var(--faint); font-family: var(--mono); font-size: 10.5px; font-weight: 400; letter-spacing: 0.14em; line-height: 1.5; text-transform: uppercase; }
.figure { font-family: var(--mono); font-size: 13px; font-variant-numeric: tabular-nums; }
.note { display: block; margin-top: 4px; color: var(--muted); font-size: 13px; }
.footnote { margin: 28px 0 0; color: var(--muted); font-size: 13px; line-height: 1.5; }
.text-link { display: inline-flex; align-items: center; min-height: 44px; font-size: 14px; }

/* State marks: shape carries the state. A hollow circle is uncertain or
   pending, never a failure. */
.state { display: inline-flex; align-items: center; gap: 9px; color: var(--muted); font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em; line-height: 1.5; text-transform: uppercase; }
.mark { flex: none; width: 7px; height: 7px; border: 1px solid currentColor; border-radius: 50%; }

/* ---------- header and navigation ----------------------------------------- */

.site-header { position: relative; z-index: 2; border-bottom: 1px solid var(--rule); }
.site-header__row { display: flex; align-items: center; gap: 36px; height: var(--header-h); }
/* The name, set in the product's own face rather than drawn as a logo. */
.brand { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink); font-family: var(--display); font-size: 22px; font-weight: 500; letter-spacing: -0.025em; text-decoration: none; }
.site-nav { display: flex; align-items: center; gap: 28px; margin-left: auto; }
.site-nav a { position: relative; display: inline-flex; align-items: center; min-height: 44px; color: var(--muted); font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em; text-decoration: none; text-transform: uppercase; }
.site-nav a:hover, .site-nav a[aria-current] { color: var(--ink); }
/* The active destination carries Habitat's 2px oxblood bar under its label. */
.site-nav a[aria-current]::after { position: absolute; right: 0; bottom: 6px; left: 0; height: 2px; background: var(--oxblood); content: ""; }

/* The design switch: chrome, not an action. Mono, small and quiet until it is
   the active choice; the active option is filled, so it reads without colour. */
.design-switch { display: flex; align-items: center; gap: 8px; }
.design-switch__group { display: flex; border: 1px solid var(--rule); }
.design-switch__option { min-height: 28px; margin: 0; padding: 4px 10px; border: 0; border-radius: 0; background: transparent; color: var(--faint); cursor: pointer; font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; }
.design-switch__option + .design-switch__option { border-left: 1px solid var(--rule); }
.design-switch__option:hover { color: var(--ink); }
.design-switch__option[aria-pressed="true"] { background: var(--ink); color: var(--paper); }

/* ---------- home: the contour sheet --------------------------------------- */

.home .site-header { border-bottom: 0; }
.hero { position: relative; isolation: isolate; padding: clamp(56px, 7vw, 104px) 0 clamp(96px, 10vw, 144px); border-bottom: 1px solid var(--rule); }
/* The field starts at the top of the page, under the transparent header, and
   stops at the hairline above the projects like the edge of a map sheet. The
   stroke colour is the canvas's `color`. */
.hero__terrain { position: absolute; z-index: -1; top: calc(-1 * var(--header-h)); left: 0; width: 100%; height: calc(100% + var(--header-h)); color: var(--contour); opacity: var(--contour-opacity); pointer-events: none; }
.hero__content { position: relative; }
/* A clearing of the page ground behind the copy keeps the smallest text off the
   contour lines; the blur lets the lines fade toward it instead of stopping. */
.hero__content::before { position: absolute; z-index: -1; inset: -32px -48px; max-width: 760px; border-radius: 64px; background: var(--paper); content: ""; filter: blur(32px); pointer-events: none; }
.hero__title { max-width: 19ch; margin: 0; font-family: var(--display); font-size: clamp(40px, 5.6vw, 72px); font-weight: 200; letter-spacing: -0.028em; line-height: 1.04; }

/* The index: one ruled row per project, the task in the reading face and the
   project's name in mono beneath it. It grows by adding rows. */
.hero__index { max-width: 460px; margin: 44px 0 0; padding: 0; border-bottom: 1px solid var(--rule); list-style: none; }
.hero__index li { border-top: 1px solid var(--rule); }
.hero__line { position: relative; display: block; padding: 16px 40px 16px 0; color: inherit; text-decoration: none; }
.hero__task { display: block; width: fit-content; font-family: var(--display); font-size: clamp(24px, 2.4vw, 30px); font-weight: 300; letter-spacing: -0.026em; line-height: 1.15; }
.hero__name { display: block; margin-top: 7px; color: var(--faint); font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; }
.hero__arrow { position: absolute; top: 50%; right: 4px; font-size: 20px; transform: translateY(-50%); transition: transform var(--dur-2) var(--ease); }
.hero__line:hover .hero__task, .hero__line:focus-visible .hero__task { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; }
.hero__line:hover .hero__name, .hero__line:focus-visible .hero__name { color: var(--ink); }
.hero__line:hover .hero__arrow { transform: translate(4px, -50%); }
/* With the map marks beside it, the leader is the pointer; the arrow stands in
   on screens too narrow for them. */
@media (min-width: 900px) { .hero__arrow { display: none; } .hero__line { padding-right: 0; } }

/* Survey marks: each headline line is annotated like a map, with a leader to a
   mark on the field. site.js places them; narrow screens leave them out. */
.survey { position: absolute; z-index: 0; inset: 0; display: none; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.survey.is-ready { display: block; }
.survey__leader { fill: none; stroke: var(--ink); stroke-width: 1; opacity: 0.45; transition: opacity var(--dur-2) var(--ease); }
.survey__mark { transform-box: fill-box; transform-origin: center; transition: transform var(--dur-3) var(--ease); }
.survey__shape { fill: var(--paper); stroke: var(--ink); stroke-width: 1.4; }
.survey__dot { fill: var(--ink); }
.survey__halo { fill: none; stroke: var(--ink); stroke-width: 1; stroke-dasharray: 2 3; opacity: 0; transition: opacity var(--dur-2) var(--ease); }
.survey__item[data-tone="signal"] :is(.survey__shape, .survey__halo) { stroke: var(--oxblood); }
.survey__item[data-tone="signal"] .survey__dot { fill: var(--oxblood); }
.survey__item.is-active .survey__leader { opacity: 1; }
.survey__item.is-active .survey__halo { opacity: 1; }
.survey__item.is-active .survey__mark { transform: scale(1.15); }


/* ---------- home: projects ------------------------------------------------- */

.projects { padding: 56px 0 88px; scroll-margin-top: 16px; }
.project-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px; margin: 0; padding: 0; list-style: none; }
.project { min-width: 0; }
.project__link { display: flex; flex-direction: column; height: 100%; color: inherit; text-decoration: none; }
.project__cover { display: block; overflow: hidden; aspect-ratio: 3 / 2; background: var(--art-ground); }
.project__body { display: flex; flex: 1; flex-direction: column; padding-top: 22px; }
.project__kind { color: var(--faint); font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; }
.project__title { display: block; margin-top: 10px; font-family: var(--display); font-size: clamp(24px, 2.3vw, 30px); font-weight: 300; letter-spacing: -0.026em; line-height: 1.15; }
.project__link:hover .project__title { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; }
.project__summary { max-width: 46ch; margin: 12px 0 0; color: var(--muted); font-size: 15px; font-weight: 300; line-height: 1.55; }

/* ---------- subpages ------------------------------------------------------- */

/* Habitat's workspace opening: eyebrow, editorial title, description and a
   firm divider; the body keeps a readable measure below it. */
.page-head { padding: clamp(40px, 6vw, 72px) 0 32px; border-bottom: 1px solid var(--rule-firm); }
.page-head h1 { margin: 14px 0 0; font-family: var(--display); font-size: clamp(34px, 4.4vw, 46px); font-weight: 200; letter-spacing: -0.035em; line-height: 1.06; }
.page-head__lede { max-width: 62ch; margin: 16px 0 0; color: var(--muted); font-size: 15px; font-weight: 300; line-height: 1.6; }
.page-head .actions { margin-top: 24px; }
.page-body { padding: 32px 0 96px; }
.page-body > * { max-width: 860px; }
/* Project pages: the drawing holds the right column while the facts scroll. */
.page-body--project { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr); gap: 0 56px; align-items: start; }
.page-body--project > * { grid-column: 1; max-width: none; }
.page-body--project > .page-cover { position: sticky; top: 24px; grid-column: 2; grid-row: 1 / span 12; }
.page-cover { margin: 0; }
.page-cover > .art { aspect-ratio: 3 / 2; height: auto; background: var(--art-ground); }
.section { padding: 32px 0 4px; }
.section h2 { margin: 0 0 14px; font-family: var(--display); font-size: 21px; font-weight: 300; letter-spacing: -0.02em; line-height: 1.25; }
.section p { max-width: 68ch; margin: 0 0 16px; font-size: 15px; line-height: 1.6; }
.section .ledger { margin-top: 4px; }

/* Ledger: a short label beside its content, ruled, never a card. */
.ledger { margin: 0; border-top: 1px solid var(--rule); }
.ledger > div { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: 24px; padding: 14px 0; border-bottom: 1px solid var(--rule); }
.ledger dt { padding-top: 3px; color: var(--faint); font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.12em; line-height: 1.5; text-transform: uppercase; }
.ledger dd { margin: 0; font-size: 15px; line-height: 1.55; overflow-wrap: anywhere; }
.ledger .state { text-transform: none; letter-spacing: 0; font-family: var(--sans); font-size: 15px; color: var(--ink); align-items: baseline; }
.ledger .state .mark { transform: translateY(-1px); }

/* Principles, as on Habitat's landing: ruled, the claim set in ink. */
.points { margin: 0; padding: 0; list-style: none; }
.points li { padding: 14px 0; border-top: 1px solid var(--rule); color: var(--muted); font-size: 15px; font-weight: 300; line-height: 1.55; }
.points strong { color: var(--ink); font-weight: 500; }

/* Order is information here, so the steps are numbered. */
.steps { margin: 0; padding: 0; list-style: none; counter-reset: step; }
.steps li { display: grid; grid-template-columns: 40px minmax(0, 1fr); padding: 14px 0; border-top: 1px solid var(--rule); font-size: 15px; line-height: 1.55; counter-increment: step; }
.steps li::before { padding-top: 3px; color: var(--faint); content: counter(step, decimal-leading-zero); font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em; }

table { width: 100%; margin: 4px 0 0; border-collapse: collapse; font-size: 14px; }
th { padding: 10px 12px 10px 0; border-bottom: 1px solid var(--rule-firm); color: var(--faint); font-family: var(--mono); font-size: 10.5px; font-weight: 400; letter-spacing: 0.12em; text-align: left; text-transform: uppercase; }
td { padding: 12px 12px 12px 0; border-bottom: 1px solid var(--rule); }
progress { display: block; width: 100%; max-width: 360px; height: 6px; margin-top: 10px; accent-color: var(--ink); }

/* Actions: sans, sentence case, never mono. Primary is filled, peers outlined. */
.actions { display: flex; flex-wrap: wrap; gap: 12px; }
.button { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 18px; border: 1px solid var(--action); border-radius: var(--r-sm); background: var(--action); box-shadow: var(--shadow-key-accent); color: var(--action-ink); font-size: 14px; text-decoration: none; transition: background var(--dur-1) var(--ease); }
.button:hover { border-color: var(--action-hover); background: var(--action-hover); }

/* The Alpine backdrop: the same range, drawn once, faint. Editorial is paper. */
.terrain-backdrop { display: none; }

/* ---------- footer --------------------------------------------------------- */

.site-footer { border-top: 1px solid var(--rule); }
.site-footer__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 24px; padding: 14px 0; color: var(--muted); font-size: 12.5px; }
.site-footer nav { display: flex; gap: 24px; }
.site-footer a { display: inline-flex; align-items: center; min-height: 44px; font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em; text-decoration: none; text-transform: uppercase; }
.site-footer a:hover, .site-footer a[aria-current] { color: var(--ink); text-decoration: underline; }

/* ========== Alpine ========================================================== */

:root[data-design="b"] :focus-visible { outline: 2px solid var(--b-accent); outline-offset: 2px; }
:root[data-design="b"] .eyebrow { display: flex; align-items: center; gap: 10px; color: var(--b-accent); font-size: 11px; letter-spacing: 0.12em; }
:root[data-design="b"] .eyebrow::before { width: 14px; height: 1px; background: currentColor; content: ""; }

:root[data-design="b"] .site-header { background: color-mix(in srgb, var(--b-bg) 82%, transparent); -webkit-backdrop-filter: saturate(1.4) blur(12px); backdrop-filter: saturate(1.4) blur(12px); }
:root[data-design="b"] .home .site-header { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
:root[data-design="b"] .site-nav { gap: 6px; }
:root[data-design="b"] .site-nav a { min-height: 36px; padding: 0 14px; border-radius: var(--r-full); color: var(--b-ink-2); font-family: var(--b-sans); font-size: 13.5px; font-weight: 500; letter-spacing: normal; text-transform: none; transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease); }
:root[data-design="b"] .site-nav a:hover { background: var(--b-sunk); color: var(--b-ink); }
/* The active item is the only filled one, so it reads without colour. */
:root[data-design="b"] .site-nav a[aria-current] { background: var(--b-accent); color: var(--b-accent-ink); }
:root[data-design="b"] .site-nav a[aria-current]::after { content: none; }

:root[data-design="b"] .design-switch__group { gap: 2px; padding: 2px; border: 1px solid var(--b-line); border-radius: var(--r-full); background: var(--b-sunk); }
:root[data-design="b"] .design-switch__option { min-height: 26px; padding: 3px 12px; border-radius: var(--r-full); color: var(--b-ink-3); font-family: var(--b-sans); font-size: 11.5px; font-weight: 500; letter-spacing: normal; text-transform: none; }
:root[data-design="b"] .design-switch__option + .design-switch__option { border-left: 0; }
:root[data-design="b"] .design-switch__option:hover { color: var(--b-ink); }
:root[data-design="b"] .design-switch__option[aria-pressed="true"] { background: var(--b-surface); box-shadow: var(--b-shadow-valley); color: var(--b-ink); font-weight: 600; }

/* The range is scenery here, the one place the accent may be. A clearing of
   the ground behind the copy keeps the smallest text on a clean ground. */
:root[data-design="b"] .hero { border-bottom-color: var(--b-line); }
:root[data-design="b"] .hero__title { font-size: clamp(38px, 5.4vw, 68px); font-weight: 700; letter-spacing: -0.026em; }
:root[data-design="b"] .brand { font-weight: 700; letter-spacing: -0.02em; }
:root[data-design="b"] .hero__index, :root[data-design="b"] .hero__index li { border-color: var(--b-line); }
:root[data-design="b"] .hero__task { font-size: clamp(22px, 2.1vw, 26px); font-weight: 600; letter-spacing: -0.018em; }
:root[data-design="b"] .hero__name { color: var(--b-accent); font-size: 11px; letter-spacing: 0.12em; }
:root[data-design="b"] .hero__line:hover .hero__task { text-decoration: none; }
:root[data-design="b"] .hero__line:hover .hero__name { color: var(--b-accent-strong); }

:root[data-design="b"] .project-list { gap: 28px; }
/* Surface recipe: raised off the ground, ridge on hover only because the
   whole surface is a link. */
:root[data-design="b"] .project__link { overflow: hidden; border-radius: var(--r-lg); background: var(--b-surface); box-shadow: var(--b-shadow-valley); transition: box-shadow var(--dur-2) var(--ease), transform var(--dur-2) var(--ease); }
:root[data-design="b"] .project__link:hover { box-shadow: var(--b-shadow-ridge); transform: translateY(-2px); }
:root[data-design="b"] .project__body { padding: 22px 24px 24px; }
:root[data-design="b"] .project__kind { color: var(--b-accent); font-size: 11px; letter-spacing: 0.1em; }
:root[data-design="b"] .project__title { font-size: 24px; font-weight: 650; letter-spacing: -0.018em; }
:root[data-design="b"] .project__link:hover .project__title { text-decoration: none; }
:root[data-design="b"] .project__summary { font-size: 14.5px; font-weight: 400; }
/* Pending is a chip with the dashed unknown edge: no hue. */

:root[data-design="b"] .terrain-backdrop { position: fixed; z-index: -1; inset: 0; display: block; width: 100%; height: 100%; color: var(--b-accent); opacity: 0.09; pointer-events: none; }
:root[data-design="b"] .page-head { border-bottom-color: var(--b-line); }
:root[data-design="b"] .page-head h1 { margin-top: 16px; font-size: clamp(32px, 4vw, 42px); font-weight: 650; letter-spacing: -0.028em; }
:root[data-design="b"] .page-head__lede { font-size: 16px; font-weight: 400; }
:root[data-design="b"] .section h2 { font-size: 20px; font-weight: 650; letter-spacing: -0.014em; }
:root[data-design="b"] .ledger { overflow: hidden; border: 0; border-radius: var(--r-lg); background: var(--b-surface); box-shadow: var(--b-shadow-valley); }
:root[data-design="b"] .ledger > div { padding: 14px 20px; border-bottom-color: var(--b-line-soft); }
:root[data-design="b"] .ledger > div:last-child { border-bottom: 0; }
:root[data-design="b"] .ledger dt { color: var(--b-ink-3); font-size: 11px; }
:root[data-design="b"] .ledger dd, :root[data-design="b"] .section p, :root[data-design="b"] .points li, :root[data-design="b"] .steps li { font-size: 14.5px; font-weight: 400; }
:root[data-design="b"] .points strong { font-weight: 600; }
:root[data-design="b"] .steps li::before { display: grid; place-items: center; width: 22px; height: 22px; padding: 0; border: 1px solid var(--b-accent); border-radius: var(--r-full); color: var(--b-accent); font-size: 10px; letter-spacing: 0; }
:root[data-design="b"] th { background: var(--b-sunk); border-bottom-color: var(--b-line-strong); padding-left: 12px; }
:root[data-design="b"] td { border-bottom-color: var(--b-line-soft); padding-left: 12px; }
:root[data-design="b"] progress { accent-color: var(--b-accent); }
:root[data-design="b"] .button { border: 0; font-weight: 600; }

:root[data-design="b"] .site-footer { border-top-color: var(--b-line); background: var(--b-bg); }
:root[data-design="b"] .site-footer a { font-family: var(--b-sans); font-size: 13px; letter-spacing: normal; text-transform: none; }

/* One arrival, once, on load: each element inside the 420ms ceiling, staggered
   so it reads as a sequence. Every end state is the resting state. */
@media (prefers-reduced-motion: no-preference) {
  :root[data-design="b"] .project, :root[data-design="b"] .page-head > *, :root[data-design="b"] .page-body > * { animation: rise var(--dur-3) var(--ease) both; }
  :root[data-design="b"] .page-head > :nth-child(2) { animation-delay: 60ms; }
  :root[data-design="b"] .page-head > :nth-child(3) { animation-delay: 120ms; }
  :root[data-design="b"] .project:nth-child(1), :root[data-design="b"] .page-head > :nth-child(4), :root[data-design="b"] .page-body > :nth-child(1) { animation-delay: 180ms; }
  :root[data-design="b"] .project:nth-child(2), :root[data-design="b"] .page-body > :nth-child(n + 2) { animation-delay: 240ms; }
}

/* ========== narrow screens ================================================== */

@media (max-width: 760px) {
  html { --header-h: 108px; }
  /* The switch releases into its own strip at the top, as Habitat's dock does. */
  .site-header__row { flex-wrap: wrap; align-content: stretch; gap: 0 20px; }
  .design-switch { order: -1; justify-content: flex-end; width: calc(100% + 2 * var(--gutter)); height: 48px; margin: 0 calc(-1 * var(--gutter)); padding: 0 var(--gutter); border-bottom: 1px solid var(--rule); }
  .site-header__row > .brand, .site-header__row > .site-nav { height: 59px; }
  .site-nav { gap: 20px; }
  :root[data-design="b"] .site-nav { gap: 2px; }
  :root[data-design="b"] .site-nav a { padding: 0 12px; }
  .brand { font-size: 20px; }
  .hero { padding: 44px 0 72px; }
  .hero__index { max-width: none; margin-top: 32px; }
  .project-list { grid-template-columns: minmax(0, 1fr); gap: 48px; }
  :root[data-design="b"] .project-list { gap: 20px; }
  .ledger > div { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .page-body { padding-bottom: 64px; }
  .hero__content::before { inset: -24px -20px; }
  .page-body--project { display: block; }
  .page-body--project > .page-cover { position: static; margin-bottom: 28px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ========== project drawings ================================================
   Survey sheets drawn by scripts/art.mjs. Each appearance gives them its own
   palette: ink on warm paper, glacier on mist, light on the night valley. */

.art {
  --art-ground: #f2efeb; --art-contour: #b9b0a6; --art-water: #e6e0d9; --art-hatch: #c4bbb1;
  --art-ink: #131110; --art-key: #131110; --art-mark: #7d2620; --art-paper: #fcfbfa;
  --art-block: #e8e3dc; --art-block-edge: #c9c1b8; --art-text: #cbc3ba; --art-shadow: transparent;
  --art-building: #4f4944; --art-forest: #e6e1d8;
  display: block; width: 100%; height: 100%;
}
:root { --art-ground: #f2efeb; }
:root[data-design="b"] { --art-ground: #eef3f6; }
:root[data-design="b"][data-design-mode="dark"] { --art-ground: #0d141b; }
:root[data-design="b"] .art {
  --art-ground: #eef3f6; --art-contour: #7fbcc6; --art-water: #d8edf1; --art-hatch: #93c9d2;
  --art-ink: #0b1015; --art-key: #0e6f7d; --art-mark: #b42318; --art-paper: #ffffff;
  --art-block: #dfe7ed; --art-block-edge: #c3cfd9; --art-text: #c9d4dd; --art-shadow: rgb(11 16 21 / 9%);
  --art-building: #4c5a67; --art-forest: #dfeae6;
}
:root[data-design="b"][data-design-mode="dark"] .art {
  --art-ground: #0d141b; --art-contour: #2a6670; --art-water: #0f252b; --art-hatch: #1f5058;
  --art-ink: #dfe7ee; --art-key: #3fc6d8; --art-mark: #ff8b80; --art-paper: #131c25;
  --art-block: #16212b; --art-block-edge: #27343f; --art-text: #33424f; --art-shadow: rgb(0 0 0 / 45%);
  --art-building: #8a9aa8; --art-forest: #112019;
}
.art-ground { fill: var(--art-ground); }
.art-frame, .art-tick { fill: none; stroke: var(--art-ink); stroke-width: 0.8; opacity: 0.45; }
.art-contour { fill: none; stroke: var(--art-contour); stroke-width: 0.7; opacity: 0.6; }
.art-contour.is-index { stroke-width: 1.15; opacity: 1; }
.art-water { fill: var(--art-water); }
.art-hatch { fill: none; stroke: var(--art-hatch); stroke-width: 0.7; }
.art-shore { fill: none; stroke: var(--art-ink); stroke-width: 0.9; opacity: 0.5; }
.art-rail { fill: none; stroke: var(--art-ink); stroke-width: 3; }
.art-rail-gap { fill: none; stroke: var(--art-ground); stroke-width: 1.4; stroke-dasharray: 7 7; }
.art-reach { fill: none; stroke: var(--art-key); stroke-width: 0.9; stroke-dasharray: 1 4; stroke-linecap: round; opacity: 0.8; }
.art-parcel { fill: var(--art-paper); fill-opacity: 0.7; stroke: var(--art-ink); stroke-width: 0.9; stroke-dasharray: 5 3; }
.art-tree { fill: none; stroke: var(--art-ink); stroke-width: 0.8; }
.art-key-fill { fill: var(--art-key); }
.art-house { fill: var(--art-key); }
.art-route { fill: none; stroke: var(--art-key); stroke-width: 2.2; stroke-linecap: round; stroke-dasharray: 0.1 6; }
.art-station-mark { fill: var(--art-ink); stroke: var(--art-ground); stroke-width: 1.5; }
.art-label { fill: var(--art-ink); font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.14em; }
.art-label--end { text-anchor: end; }
/* The in-map credit the data licences ask for, kept as quiet as a map's. */
.art-credit { fill: var(--art-ink); font-family: var(--sans); font-size: 6.5px; opacity: 0.6; paint-order: stroke; stroke: var(--art-ground); stroke-width: 2.5px; stroke-linejoin: round; }
.art-label--map { paint-order: stroke; stroke: var(--art-ground); stroke-width: 4px; stroke-linejoin: round; }
.art-leader { fill: none; stroke: var(--art-ink); stroke-width: 0.8; opacity: 0.7; }
.art-card-face { fill: var(--art-paper); stroke: var(--art-ink); stroke-width: 0.9; }
.art-card-shadow { fill: var(--art-shadow); }
.art-card-rule { stroke: var(--art-ink); stroke-width: 0.6; opacity: 0.35; }
.art-pass, .art-unknown, .art-check-box { fill: none; stroke: var(--art-ink); stroke-width: 1.1; }
.art-bar { fill: var(--art-text); }
.art-ink-line { fill: none; stroke: var(--art-ink); stroke-width: 1.1; stroke-linecap: round; stroke-linejoin: round; }
.art-block { fill: var(--art-block); stroke: var(--art-block-edge); stroke-width: 0.7; }
/* Road widths come from the drawing (by road class); CSS sets only colour. */
.art-road-edge { fill: none; stroke: var(--art-ink); stroke-linecap: round; stroke-linejoin: round; opacity: 0.4; }
.art-road { fill: none; stroke: var(--art-paper); stroke-linecap: round; stroke-linejoin: round; }
.art-lane { fill: none; stroke: var(--art-ink); stroke-width: 0.8; opacity: 0.5; }
.art-building { fill: var(--art-building); }
/* City blocks are hatched, as on the national map at town scale. */
.art--civic .art-building--hatched { fill: url(#civic-hatch); stroke: var(--art-ink); stroke-width: 0.6; stroke-opacity: 0.75; }
.art-hatch-ground { fill: var(--art-paper); }
.art-hatch-line { stroke: var(--art-ink); stroke-width: 0.75; opacity: 0.5; }
.art-forest, .art-park { fill: var(--art-forest); }
.art--habitat .art-contour { opacity: 0.85; }
.art-rail-thin { fill: none; stroke: var(--art-ink); stroke-width: 1.4; }
.art-tram { fill: none; stroke: var(--art-ink); stroke-width: 0.8; opacity: 0.7; }
.art-disused { fill: none; stroke: var(--art-ink); stroke-width: 0.8; opacity: 0.55; }
.art-street { fill: var(--art-ink); font-family: var(--mono); font-size: 6.4px; letter-spacing: 0.12em; paint-order: stroke; stroke: var(--art-paper); stroke-width: 2.5px; stroke-linejoin: round; }
.art-place { fill: var(--art-ink); font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.28em; paint-order: stroke; stroke: var(--art-ground); stroke-width: 3.5px; stroke-linejoin: round; }
.art-elevation { fill: var(--art-contour); font-family: var(--mono); font-size: 6.5px; letter-spacing: 0.06em; paint-order: stroke; stroke: var(--art-ground); stroke-width: 3px; }
.art-send { fill: var(--art-key); }
.art-send-label { fill: var(--art-paper); font-family: var(--mono); font-size: 7.5px; letter-spacing: 0.12em; }
.art-ping { fill: none; stroke: var(--art-mark); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0.8; transform-box: fill-box; transform-origin: center; }
.art-mark-ring { fill: var(--art-paper); stroke: var(--art-mark); stroke-width: 1.6; }
.art-mark-fill { fill: var(--art-mark); }
.art-mark-line { fill: none; stroke: var(--art-mark); stroke-width: 1.3; }
.art-photo-inner { fill: var(--art-block); }
.art-check { fill: none; stroke: var(--art-key); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.art-photo, .art-card, .art-site, .art-incident { transform-box: fill-box; transform-origin: center; transition: transform 0.5s var(--ease); }
:root[data-design="b"] .project__cover { background: var(--art-ground); }
:root[data-design="b"] .page-cover > .art { border-radius: var(--r-lg); box-shadow: var(--b-shadow-valley); }

/* Survey marks in Alpine: glacier for the home, the urgent hue for the report. */
:root[data-design="b"] .survey__leader { stroke: var(--b-accent); }
:root[data-design="b"] .survey__shape { fill: var(--b-surface); stroke: var(--b-accent); }
:root[data-design="b"] .survey__dot { fill: var(--b-accent); }
:root[data-design="b"] .survey__halo { stroke: var(--b-accent); }
:root[data-design="b"] .survey__item[data-tone="signal"] .survey__leader { stroke: var(--b-urgent); }
:root[data-design="b"] .survey__item[data-tone="signal"] :is(.survey__shape, .survey__halo) { stroke: var(--b-urgent); }
:root[data-design="b"] .survey__item[data-tone="signal"] .survey__dot { fill: var(--b-urgent); }

/* ========== motion ===========================================================
   The homepage tells one short story: the range rises out of the flat sheet,
   the title and index arrive, and survey leaders run from each row to its mark.
   The drawings assemble once when they come into view: ground, contours from
   the lowest up, then the subject and its annotations. Every end state is the
   resting state, and reduced motion shows it immediately. */

@media (prefers-reduced-motion: no-preference) {
  .js .hero__content > * { animation: rise 0.8s var(--ease) backwards; }
  .js .hero__content > :nth-child(1) { animation-delay: 0.3s; }
  .js .hero__content > :nth-child(2) { animation-delay: 0.55s; }
  .survey.is-ready .survey__leader { stroke-dasharray: 1 1; animation: draw 0.9s var(--ease) 1.05s backwards; }
  .survey.is-ready .survey__item:nth-child(2) .survey__leader { animation-delay: 1.2s; }
  .survey.is-ready .survey__item:nth-child(3) .survey__leader { animation-delay: 1.35s; }
  .survey.is-ready .survey__mark { animation: settle 0.7s cubic-bezier(0.34, 1.4, 0.64, 1) 1.7s backwards; }
  .survey.is-ready .survey__item:nth-child(2) .survey__mark { animation-delay: 1.85s; }
  .survey.is-ready .survey__item:nth-child(3) .survey__mark { animation-delay: 2s; }

  .js .art:not(.is-visible) [pathLength] { stroke-dasharray: 1 1; stroke-dashoffset: 1; }
  .js .art:not(.is-visible) .art-in { opacity: 0; }
  .js .art.is-visible [pathLength] { stroke-dasharray: 1 1; animation: draw 1.5s var(--ease) backwards; }
  .js .art.is-visible .art-in { animation: rise 0.7s var(--ease) backwards; }
  .js .art.is-visible .art-ping { animation: ping 2.4s ease-out 2 backwards; }
  /* A drawing already in view at load waits for the headline (site.js sets the
     offset), so the page tells one story at a time. */
  .js .art.is-visible :is([pathLength], .art-in) { animation-delay: var(--reveal-offset, 0s); }
  .js .art.is-visible .d2 { animation-delay: calc(var(--reveal-offset, 0s) + 0.18s); }
  .js .art.is-visible .d3 { animation-delay: calc(var(--reveal-offset, 0s) + 0.38s); }
  .js .art.is-visible .d4 { animation-delay: calc(var(--reveal-offset, 0s) + 0.6s); }
  .js .art.is-visible .d5 { animation-delay: calc(var(--reveal-offset, 0s) + 0.85s); }
  .js .art.is-visible .d6 { animation-delay: calc(var(--reveal-offset, 0s) + 1.1s); }
  .js .art.is-visible .d7 { animation-delay: calc(var(--reveal-offset, 0s) + 1.35s); }
  .js .art.is-visible .d8 { animation-delay: calc(var(--reveal-offset, 0s) + 1.6s); }
  .js .art.is-visible .art-ping { animation-delay: calc(var(--reveal-offset, 0s) + 1.7s); }

  /* On hover the drawing shows what the project does: the walk to the station
     moves; the three photos spread around the one incident. */
  .js .project__link:is(:hover, :focus-visible) .art.is-visible .art-route { animation: march 0.9s linear infinite; }
  .js .project__link:is(:hover, :focus-visible) .art.is-visible .art-ping { animation: ping 1.8s ease-out infinite; }
  .project__link:hover .art-site { transform: translateY(-2px); }
  .project__link:hover .art-photo.d5 { transform: translate(-7px, -4px) rotate(-3deg); }
  .project__link:hover .art-photo.d6 { transform: translate(6px, -6px) rotate(3deg); }
  .project__link:hover .art-photo.d7 { transform: translate(4px, 6px) rotate(4deg); }
  .project__link:hover .art-card { transform: translateY(-3px); }

  @keyframes rise { from { opacity: 0; transform: translateY(10px); } }
  @keyframes fade { from { opacity: 0; } }
  @keyframes draw { from { stroke-dashoffset: 1; } }
  @keyframes settle { from { opacity: 0; transform: translateY(-14px) scale(0.6); } }
  @keyframes march { to { stroke-dashoffset: -6.1; } }
  @keyframes ping { 0% { opacity: 0.9; transform: scale(0.5); } 80%, 100% { opacity: 0; transform: scale(1.7); } }
}
