/* mapindex site styles. Colours come only from the --color-* roles of
   design/tokens.css; this file adds type, spacing and components on top. */

/* Figtree for text, Plus Jakarta Sans for headings; each in a Latin and a
   Latin Extended file, so most pages load only the first. */
@font-face {
  font-family: "Figtree";
  src: url("../vendor/figtree/figtree-latin-wght-normal.202cfb54d4e6.woff2") format("woff2");
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Figtree";
  src: url("../vendor/figtree/figtree-latin-ext-wght-normal.eca8d8b337ff.woff2") format("woff2");
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../vendor/plus-jakarta-sans/plus-jakarta-sans-latin-wght-normal.7660bd9909fb.woff2")
    format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../vendor/plus-jakarta-sans/plus-jakarta-sans-latin-ext-wght-normal.341687eeeb6a.woff2")
    format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Geist Mono";
  src: url("../vendor/geist/GeistMono-Variable.308360d8a547.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --z-tooltip: 1000;
  --font-sans: "Figtree", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Plus Jakarta Sans", "Figtree", ui-sans-serif, system-ui, sans-serif;
  /* Only for code and identifiers, never for labels, dates or counts. */
  --font-mono: "Geist Mono", ui-monospace, "SFMono-Regular", monospace;

  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;

  --radius-s: 8px;
  --radius-m: 12px;
  --radius-l: 18px;
  --radius-xl: 24px;
  --radius-pill: 999px;

  --gutter: clamp(1rem, 0.5rem + 2vw, 2rem);
  --masthead-height: 4rem;
  --heading-size: clamp(1.75rem, 1.35rem + 1.6vw, 2.5rem);
  --row-head-height: 1.5rem;
  --page-width: 105rem;
  --shadow-card:
    0 1px 2px color-mix(in srgb, var(--color-shadow) 10%, transparent),
    0 6px 18px -8px color-mix(in srgb, var(--color-shadow) 24%, transparent);
  --shadow-lift:
    0 2px 4px color-mix(in srgb, var(--color-shadow) 8%, transparent),
    0 14px 30px -12px color-mix(in srgb, var(--color-shadow) 26%, transparent);
  --shadow-float:
    0 16px 40px -14px color-mix(in srgb, var(--color-shadow) 35%, transparent),
    0 2px 6px color-mix(in srgb, var(--color-shadow) 14%, transparent);
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  /* Where the 2400 px contour landscape is centred; narrow screens move its summit
     into view. Opacities per layer, a little stronger at night where lines glow. */
  --terrain-shift: 0px;
  --terrain-x: calc(50% + var(--terrain-shift));
  --terrain-size: max(2400px, 100%);
  /* The landscape is square; tall enough for any viewport plus the whole drift. */
  --terrain-height: max(2400px, 100vw);
  --drift-range: 4000px;
  --drift-max: 600px;
  --card-mat: 5px;
  --chevron-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 8.5 7 7 7-7'/%3E%3C/svg%3E");
  --color-surface-veil: color-mix(in srgb, var(--color-surface) 86%, transparent);
  /* Light keeps its line work quiet, so the page stays restful. */
  --contour-minor-hero: 0.18;
  --contour-index-hero: 0.3;
  --contour-minor-page: 0.1;
  --contour-index-page: 0.17;
  /* By day a white highlight below each index line crisps it like print. */
  --contour-filter: drop-shadow(0 1px 0 var(--color-contour-glow));
}

@media (max-width: 47.99rem) {
  :root {
    --terrain-shift: -300px;
  }
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --contour-minor-hero: 0.12;
    --contour-index-hero: 0.3;
    --contour-minor-page: 0.1;
    --contour-index-page: 0.26;
    --contour-filter: drop-shadow(0 0 4px var(--color-contour-glow));
  }
}

:root[data-theme="dark"] {
  --contour-minor-hero: 0.12;
  --contour-index-hero: 0.3;
  --contour-minor-page: 0.1;
  --contour-index-page: 0.26;
  --contour-filter: drop-shadow(0 0 4px var(--color-contour-glow));
}

/* --- Base ------------------------------------------------------------------ */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--masthead-height) + var(--space-4));
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--color-canvas);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--font-display);
  line-height: 1.2;
  font-weight: 650;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

h1 {
  font-size: var(--heading-size);
  font-weight: 700;
  letter-spacing: -0.025em;
}

h2 {
  font-size: 1.125rem;
}

h3 {
  font-size: 1rem;
}

p {
  margin: 0;
  text-wrap: pretty;
}

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

a:hover {
  color: var(--color-accent-hover);
}

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

:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

::selection {
  background: var(--color-accent-soft);
  color: var(--color-text);
}

[hidden] {
  display: none !important;
}

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

.skip-link {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  z-index: 100;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-m);
  background: var(--color-accent);
  color: var(--color-on-accent);
  font-weight: 600;
  transform: translateY(-200%);
}

.skip-link:focus-visible {
  transform: none;
}

.icon {
  width: 1.125rem;
  height: 1.125rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.85;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mono {
  font-family: var(--font-mono);
}

/* Short labels and figures speak in the text face; tabular digits keep counts steady. */
.eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-earth);
}

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

/* --- Masthead -------------------------------------------------------------- */

/* Nearly solid, like the footer: the page's landscape shows through only as a trace,
   so it always lines up without a copy of its own. */
.masthead {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--color-surface) 96%, transparent);
  box-shadow: 0 1px 0 color-mix(in srgb, var(--color-shadow) 8%, transparent);
}

/* The contour landscape, the brand's signature: minor lines in blue-grey ink, every
   fifth an index line in the accent, six summits in pools of light; generated by
   design/export_contours.py in six elevation bands (components/terrain.html).
   One fixed layer behind every page (.terrain) shows it in the gaps between cards
   and columns and faintly through panels; a fixed element rather than
   background-attachment: fixed, which mobile Safari ignores. The nearly solid
   masthead and footer let it through only as a trace.
   - Drift: the land moves up gently as the page scrolls (0.15 times the scroll, at
     most --drift-max), through a scroll-driven animation. Browsers without one
     (Firefox) keep the land still: a script would follow the compositor's scroll a
     frame late, which reads as lag.
   - Rise: on every page load (.terrain-rise, set in base.html) the bands appear from
     the lowest to the highest, each lifting a little, and the summits light up last,
     like a range growing out of a flat sheet.
   Both stay still under reduced motion; without JavaScript the land is just there. */
.terrain {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

.terrain__land {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--terrain-height);
}

.terrain__band,
.terrain__lines,
.terrain__glow,
.terrain__index,
.terrain__light {
  position: absolute;
  inset: 0;
}

.terrain__light {
  background:
    radial-gradient(28rem 14rem at calc(50% + 290px + var(--terrain-shift)) 140px, var(--color-summit), transparent),
    radial-gradient(20rem 12rem at calc(50% - 500px + var(--terrain-shift)) 700px, var(--color-summit), transparent),
    radial-gradient(20rem 12rem at calc(50% + 620px + var(--terrain-shift)) 1150px, var(--color-summit), transparent),
    radial-gradient(18rem 10rem at calc(50% - 150px + var(--terrain-shift)) 1600px, var(--color-summit), transparent),
    radial-gradient(20rem 12rem at calc(50% - 720px + var(--terrain-shift)) 2080px, var(--color-summit), transparent),
    radial-gradient(18rem 11rem at calc(50% + 400px + var(--terrain-shift)) 2240px, var(--color-summit), transparent),
    radial-gradient(64rem 30rem at calc(50% + 290px + var(--terrain-shift)) 140px, var(--color-summit-halo), transparent 75%),
    radial-gradient(44rem 26rem at calc(50% - 500px + var(--terrain-shift)) 700px, var(--color-summit-halo), transparent 75%),
    radial-gradient(44rem 26rem at calc(50% + 620px + var(--terrain-shift)) 1150px, var(--color-summit-halo), transparent 75%),
    radial-gradient(44rem 26rem at calc(50% - 720px + var(--terrain-shift)) 2080px, var(--color-summit-halo), transparent 75%);
}

/* Separate from the masked index lines: a filter applies before the mask would. */
.terrain__glow {
  filter: var(--contour-filter);
}

.terrain__lines,
.terrain__index {
  -webkit-mask-position: var(--terrain-x) 0;
  mask-position: var(--terrain-x) 0;
  -webkit-mask-size: var(--terrain-size) auto;
  mask-size: var(--terrain-size) auto;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

.terrain__lines {
  background: var(--color-contour);
  opacity: var(--contour-minor-page);
}

.terrain__index {
  background: var(--color-contour-index);
  opacity: var(--contour-index-page);
}

.terrain__band--0 {
  --band: 0;
}

.terrain__band--0 .terrain__lines {
  -webkit-mask-image: url("../patterns/contours-0.264f59befefc.svg");
  mask-image: url("../patterns/contours-0.264f59befefc.svg");
}

.terrain__band--1 {
  --band: 1;
}

.terrain__band--1 .terrain__lines {
  -webkit-mask-image: url("../patterns/contours-1.467f9b758bc0.svg");
  mask-image: url("../patterns/contours-1.467f9b758bc0.svg");
}

.terrain__band--1 .terrain__index {
  -webkit-mask-image: url("../patterns/contours-index-1.c36db2b610a7.svg");
  mask-image: url("../patterns/contours-index-1.c36db2b610a7.svg");
}

.terrain__band--2 {
  --band: 2;
}

.terrain__band--2 .terrain__lines {
  -webkit-mask-image: url("../patterns/contours-2.c39a945167f9.svg");
  mask-image: url("../patterns/contours-2.c39a945167f9.svg");
}

.terrain__band--2 .terrain__index {
  -webkit-mask-image: url("../patterns/contours-index-2.2b85b2cc00d3.svg");
  mask-image: url("../patterns/contours-index-2.2b85b2cc00d3.svg");
}

.terrain__band--3 {
  --band: 3;
}

.terrain__band--3 .terrain__lines {
  -webkit-mask-image: url("../patterns/contours-3.86457b84ae83.svg");
  mask-image: url("../patterns/contours-3.86457b84ae83.svg");
}

.terrain__band--3 .terrain__index {
  -webkit-mask-image: url("../patterns/contours-index-3.6c11d57cdbb2.svg");
  mask-image: url("../patterns/contours-index-3.6c11d57cdbb2.svg");
}

.terrain__band--4 {
  --band: 4;
}

.terrain__band--4 .terrain__lines {
  -webkit-mask-image: url("../patterns/contours-4.f33b3f4aba08.svg");
  mask-image: url("../patterns/contours-4.f33b3f4aba08.svg");
}

.terrain__band--4 .terrain__index {
  -webkit-mask-image: url("../patterns/contours-index-4.7f094367fce4.svg");
  mask-image: url("../patterns/contours-index-4.7f094367fce4.svg");
}

.terrain__band--5 {
  --band: 5;
}

.terrain__band--5 .terrain__lines {
  -webkit-mask-image: url("../patterns/contours-5.4a5ab8b62415.svg");
  mask-image: url("../patterns/contours-5.4a5ab8b62415.svg");
}

.terrain__band--5 .terrain__index {
  -webkit-mask-image: url("../patterns/contours-index-5.181030f9e250.svg");
  mask-image: url("../patterns/contours-index-5.181030f9e250.svg");
}

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: scroll()) {
    .terrain__land {
      animation: terrain-drift linear both;
      animation-timeline: scroll(root);
      animation-range: 0 var(--drift-range);
    }
  }

  .terrain-rise .terrain__band {
    animation: terrain-rise 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both;
    animation-delay: calc(0.1s + var(--band) * 0.16s);
  }

  .terrain-rise .terrain__light {
    animation: terrain-light 1.1s 0.8s ease-out both;
  }
}

@keyframes terrain-drift {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(calc(-1 * var(--drift-max)));
  }
}

@keyframes terrain-rise {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
}

@keyframes terrain-light {
  from {
    opacity: 0;
  }
}

/* --- Masthead layout ------------------------------------------------------- */

.masthead__inner {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  max-width: var(--page-width);
  min-height: var(--masthead-height);
  margin: 0 auto;
  padding: var(--space-2) var(--gutter);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--color-text);
  text-decoration: none;
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  border-radius: var(--radius-m);
}

.brand:hover {
  color: var(--color-text);
}

.brand img,
.brand svg {
  width: 2rem;
  height: 2rem;
}

/* An animated brand logo is the loader at rest; site.js plays the wave while it is
   waving. It keeps the logo's own colour, never the theme's accent. */
.brand--animated .mapindex-loader path {
  fill: var(--color-logo);
  animation-name: none;
}

@media (prefers-reduced-motion: no-preference) {
  .brand--animated[data-waving] .mapindex-loader path {
    animation-name: mapindex-loader-wave;
  }
}

.masthead__search {
  flex: 1;
  max-width: 34rem;
  margin-inline: auto var(--space-2);
}

.masthead__nav {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-left: auto;
}

.masthead__search + .masthead__nav {
  margin-left: 0;
}

/* The theme switch offers the theme not in effect. */
.theme-switch .theme-switch__light {
  display: none;
}

:root[data-theme="dark"] .theme-switch .theme-switch__light {
  display: inline-flex;
}

:root[data-theme="dark"] .theme-switch .theme-switch__dark {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-switch .theme-switch__light {
    display: inline-flex;
  }

  :root:not([data-theme="light"]) .theme-switch .theme-switch__dark {
    display: none;
  }
}

@media (max-width: 47.99rem) {
  .masthead__inner {
    flex-wrap: wrap;
  }

  .masthead__search {
    order: 3;
    flex-basis: 100%;
    max-width: none;
    margin: 0 0 var(--space-1);
  }

  .masthead__nav .button {
    padding-inline: 0;
    width: 2.5rem;
  }
}

/* --- Page and explorer layout -------------------------------------------- */

.page {
  flex: 1;
  width: 100%;
  max-width: var(--page-width);
  margin: 0 auto;
  padding: var(--space-6) var(--gutter) var(--space-16);
}

.explorer {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "filters"
    "content"
    "noticeboard";
}

.explorer__filters {
  grid-area: filters;
}

.explorer__filters,
.explorer__noticeboard {
  display: grid;
  align-content: start;
  gap: var(--space-4);
}

.explorer__content {
  grid-area: content;
  min-width: 0;
}

/* The side columns' headings are for screen readers only. */
.explorer__filters,
.explorer__noticeboard {
  position: relative;
}

.explorer__filters > .section-head,
.explorer__noticeboard > .section-head {
  position: absolute;
  top: calc(-1 * var(--space-5));
  right: var(--space-2);
  min-height: 0;
}

.explorer__noticeboard {
  grid-area: noticeboard;
}

@media (min-width: 64rem) {
  .explorer {
    grid-template-columns: 16.5rem minmax(0, 1fr);
    grid-template-areas:
      "filters content"
      "filters noticeboard";
    align-items: start;
  }

  /* The side columns have no visible headings: their boxes start level with the
     first map, below the results heading where there is one. */
  .explorer:has(.results__head) {
    --explorer-lead: calc(var(--heading-size) * 1.2 + var(--space-6));
  }

  .explorer:has(.active-filters) {
    --explorer-lead: calc(var(--heading-size) * 1.2 + 1.75rem + 2 * var(--space-6));
  }

  .explorer__filters {
    margin-top: var(--explorer-lead, 0px);
  }
}

@media (min-width: 80rem) {
  .explorer {
    grid-template-columns: 17rem minmax(0, 1fr) 19rem;
    grid-template-areas: "filters content noticeboard";
  }

  .explorer__noticeboard {
    margin-top: var(--explorer-lead, 0px);
  }
}

/* --- Panels ---------------------------------------------------------------- */

/* Panels let the landscape show faintly through; cards stay opaque so maps lead. */
.panel {
  display: grid;
  gap: var(--space-5);
  padding: var(--space-5);
  border-radius: var(--radius-l);
  background: var(--color-surface-veil);
}

.panel__title {
  font-size: 0.9375rem;
  font-weight: 600;
}

/* --- Buttons --------------------------------------------------------------- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 2.5rem;
  padding: 0 var(--space-5);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--color-accent-soft);
  color: var(--color-accent-soft-ink);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  position: relative;
  transition:
    background-color 0.15s var(--ease),
    color 0.15s var(--ease);
}

.button:hover {
  background: color-mix(in srgb, var(--color-accent-soft) 82%, var(--color-accent));
  color: var(--color-accent-soft-ink);
}

.button--primary {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.button--primary:hover {
  background: var(--color-accent-hover);
  color: var(--color-on-accent);
}

.button--quiet {
  background: transparent;
  color: var(--color-text-muted);
}

.button--quiet:hover {
  background: var(--color-raised);
  color: var(--color-text);
}

.button--icon {
  width: 2.5rem;
  padding: 0;
}

.button--small {
  min-height: 2rem;
  padding: 0 var(--space-4);
  font-size: 0.8125rem;
}

.button--block {
  width: 100%;
}

.button[aria-pressed="true"] {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.button:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.button--small.button--icon {
  width: 2rem;
}

/* An icon button names its action, and a chip its figure, in a tooltip on hover
   and keyboard focus. The tooltip is also the accessible name, so it fades
   instead of hiding.
   It is fixed to the viewport so no scrolling or clipping container can hide
   it, and site.js places it beside its anchor, flipped and kept on screen. */
.tip {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-tooltip);
  max-width: calc(100vw - 2 * var(--space-2));
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-s);
  background: var(--color-text);
  color: var(--color-canvas);
  font-size: 0.75rem;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s var(--ease);
}

@media (prefers-reduced-motion: reduce) {
  .tip {
    transition: none;
  }
}

.button:focus-visible .tip,
.button[data-tip-shown] .tip {
  opacity: 1;
}

@media (hover: hover) {
  .button:hover .tip,
  .chip:hover .tip,
  .fact:hover .tip {
    opacity: 1;
  }
}

/* --- Forms ----------------------------------------------------------------- */

.field {
  display: grid;
  gap: var(--space-2);
}

.field__label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-text-muted);
}

.input,
.select,
.textarea {
  width: 100%;
  min-height: 2.75rem;
  padding: 0.625rem var(--space-3);
  border: 0;
  border-radius: var(--radius-m);
  background: var(--color-field);
  color: var(--color-text);
  font-size: 0.9375rem;
}

.textarea {
  min-height: 6rem;
  resize: vertical;
  line-height: 1.5;
}

.select {
  appearance: none;
  padding-right: 2.25rem;
}

/* The chevron of a select or dropdown: one stroke with a round join, drawn in the
   text colour through a mask. A native select takes no pseudo-elements, so it sits
   in a `.select-box`. */
.select-box {
  position: relative;
  display: block;
}

.select-box::after,
.dropdown__summary::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0.85rem;
  width: 0.8rem;
  height: 0.8rem;
  translate: 0 -50%;
  background: currentColor;
  pointer-events: none;
  -webkit-mask: var(--chevron-down) center / contain no-repeat;
  mask: var(--chevron-down) center / contain no-repeat;
}

.input::placeholder,
.textarea::placeholder {
  color: var(--color-text-subtle);
}

.search-box {
  position: relative;
  display: flex;
  align-items: center;
}

.search-box .input {
  padding-left: 2.75rem;
  padding-right: 3rem;
  border-radius: var(--radius-pill);
}

.search-box__submit {
  position: absolute;
  right: var(--space-1);
  display: inline-grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
}

.search-box__submit:hover,
.search-box__submit:focus-visible {
  background: var(--color-raised);
  color: var(--color-accent);
}

/* While a search loads (htmx marks the button), the loader takes the
   magnifier's place; a short delay keeps quick answers from flickering. */
.search-box__submit > * {
  grid-area: 1 / 1;
  transition: opacity 0.2s var(--ease);
}

.search-box__loader {
  display: inline-grid;
  opacity: 0;
}

.search-box__loader svg {
  width: 1.375rem;
  height: 1.375rem;
}

.search-box__submit.htmx-request > .icon {
  opacity: 0;
  transition-delay: 0.15s;
}

.search-box__submit.htmx-request > .search-box__loader {
  opacity: 1;
  transition-delay: 0.15s;
}

.search-box__shortcut {
  position: absolute;
  left: var(--space-2);
  display: inline-grid;
  place-items: center;
  min-width: 1.5rem;
  height: 1.5rem;
  padding: 0 0.3rem;
  border-radius: var(--radius-pill);
  background: var(--color-raised);
  color: var(--color-text-subtle);
  font-size: 0.75rem;
  font-weight: 600;
}

.search-box__shortcut {
  left: 0.6rem;
}

.search-box .input:focus + .search-box__shortcut {
  display: none;
}

@media (pointer: coarse) {
  .search-box__shortcut {
    display: none !important;
  }

  .search-box .input {
    padding-left: var(--space-3);
  }
}

.search-box--large .input {
  min-height: 3rem;
  font-size: 1rem;
}

.choice-list {
  display: grid;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  border: 0;
}

.choice {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 2.25rem;
  padding: 0 var(--space-3);
  border-radius: var(--radius-m);
  font-size: 0.9375rem;
  cursor: pointer;
}

.choice:hover {
  background: var(--color-raised);
}

.choice input {
  width: 1rem;
  height: 1rem;
  margin: 0;
  accent-color: var(--color-accent);
}

.choice__count {
  margin-left: auto;
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-subtle);
}

.choice:has(input:checked:not([value=""])) {
  background: var(--color-accent-soft);
  color: var(--color-accent-soft-ink);
}

.lucky {
  gap: var(--space-3);
}

.lucky__prompt {
  font-size: 0.875rem;
  color: var(--color-text-muted);
}

.filters__body {
  display: grid;
  gap: var(--space-5);
}

/* On small screens a dice button (the lucky panel, folded) sits left of the search
   box and the filters toggle right of it, the folded body below all three. */
.filters__lucky {
  display: none;
}

@media (max-width: 63.99rem) {
  .filters {
    grid-template-columns: auto minmax(0, 1fr) auto;
    column-gap: var(--space-2);
  }

  .filters__lucky {
    display: inline-flex;
    min-width: 3rem;
    min-height: 3rem;
    padding: 0;
    justify-content: center;
  }

  .filters__body {
    grid-column: 1 / -1;
  }

  .lucky {
    display: none;
  }

  /* Phones keep the search box wide: no keyboard hint, the toggle shows its icon only. */
  .filters .search-box__shortcut {
    display: none;
  }

  .filters .search-box .input {
    padding-left: var(--space-4);
  }
}

@media (max-width: 40rem) {
  .filters__toggle {
    position: relative;
    min-width: 3rem;
    padding: 0;
    justify-content: center;
  }

  .filters__toggle-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .filters__toggle .filters__dot {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
  }
}

.filters__toggle {
  min-height: 3rem;
}

.filters__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--color-accent);
}

.filters__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.filters__actions:empty {
  display: none;
}

.dropdown {
  position: relative;
}

.dropdown__summary {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  list-style: none;
}

.dropdown__summary::-webkit-details-marker {
  display: none;
}

.dropdown__summary .icon,
.dropdown .choice .icon {
  flex: none;
  width: 1rem;
  height: 1rem;
}

.dropdown__label {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.dropdown__menu {
  display: grid;
  max-height: 18rem;
  overflow-y: auto;
  gap: var(--space-1);
  margin-top: var(--space-1);
  padding: var(--space-1);
  border-radius: var(--radius-m);
  background: var(--color-field);
}

.dropdown__loader {
  justify-content: center;
  padding: var(--space-1);
}

.honeypot {
  position: absolute;
  left: -100vw;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --- Chips ----------------------------------------------------------------- */

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 1.75rem;
  padding: 0 0.65rem;
  border-radius: var(--radius-pill);
  background: var(--color-raised);
  color: var(--color-text-muted);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
}

a.chip:hover {
  background: var(--color-hover);
  color: var(--color-text);
}

.chip--tag {
  background: var(--color-accent-soft);
  color: var(--color-accent-soft-ink);
}

a.chip--tag:hover {
  background: color-mix(in srgb, var(--color-accent-soft) 80%, var(--color-accent));
  color: var(--color-accent-soft-ink);
}

/* A folding list keeps to one row; its last chip counts the rest and unfolds them.
   Until the script has folded it, the list is cut to one row, so it never jumps. */
.js .chips[data-fold]:not([data-fold-ready]) {
  max-height: 1.75rem;
  overflow: hidden;
}

.chip--more {
  border: 0;
  font: inherit;
  font-size: 0.8125rem;
  cursor: pointer;
}

.chip--more:hover {
  background: var(--color-hover);
  color: var(--color-text);
}

.chip__flag {
  width: 1.125rem;
  height: auto;
  aspect-ratio: 4 / 3;
  border-radius: 2px;
}

.chip__code {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.03em;
}

.chip .icon {
  width: 0.875rem;
  height: 0.875rem;
}

/* --- Map cards ------------------------------------------------------------- */

.map-card {
  position: relative;
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  border-radius: var(--radius-l);
  background: var(--color-card);
  box-shadow: var(--shadow-card);
  transition:
    background-color 0.18s var(--ease),
    box-shadow 0.18s var(--ease),
    transform 0.18s var(--ease);
}

.map-card:hover {
  background: var(--color-raised);
  box-shadow: var(--shadow-lift);
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  .map-card,
  .map-card:hover {
    transition: none;
    transform: none;
  }
}

.map-card:has(.map-card__link:focus-visible) {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

/* The thumbnail sits in the card like a print in its mat: a narrow frame of card
   colour, its own rounded corners and a hairline that keeps a pale map off pale paper. */
.map-card__preview {
  position: relative;
  aspect-ratio: 4 / 3;
  margin: var(--card-mat) var(--card-mat) 0;
  overflow: hidden;
  border-radius: calc(var(--radius-l) - var(--card-mat));
  background: var(--color-raised);
}

.map-card__preview::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-shadow) 12%, transparent);
  pointer-events: none;
}

/* Clicks pass through the picture to the card's stretched link. */
.map-card__preview > * {
  pointer-events: none;
}

.map-card__preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* With JavaScript a thumbnail fades in once it has loaded (site.js marks it), so
   the grid fills softly instead of in hard jumps; without it, images just appear. */
.js .map-card__preview img {
  opacity: 0;
  transition: opacity 0.45s ease-out;
}

.js .map-card__preview img.is-loaded {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .js .map-card__preview img {
    transition: none;
  }
}

.preview-placeholder {
  position: relative;
  display: grid;
  place-items: center;
  align-content: center;
  gap: var(--space-2);
  width: 100%;
  height: 100%;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 45%, var(--color-summit), transparent 55%),
    var(--color-raised);
  color: var(--color-text-subtle);
  font-size: 0.8125rem;
  font-weight: 600;
}

/* A lone hill behind the icon: its minor lines in the ink, its index lines in the accent. */
.preview-placeholder::before,
.preview-placeholder::after {
  content: "";
  position: absolute;
  inset: -20%;
  pointer-events: none;
}

.preview-placeholder::before {
  background: var(--color-contour);
  opacity: calc(var(--contour-minor-hero) * 0.8);
  -webkit-mask: url("../patterns/summit.7d622108d3fb.svg") center / contain no-repeat;
  mask: url("../patterns/summit.7d622108d3fb.svg") center / contain no-repeat;
}

.preview-placeholder::after {
  background: var(--color-contour-index);
  opacity: calc(var(--contour-index-hero) * 0.75);
  -webkit-mask: url("../patterns/summit-index.3a1460aa3eb5.svg") center / contain no-repeat;
  mask: url("../patterns/summit-index.3a1460aa3eb5.svg") center / contain no-repeat;
}

.preview-placeholder > * {
  position: relative;
  z-index: 1;
}

.preview-placeholder .icon {
  width: 1.75rem;
  height: 1.75rem;
  color: var(--color-accent);
  stroke-width: 1.5;
}

/* Hovering a card reveals a soft hill of contour lines in its corner. */
.map-card__body {
  position: relative;
  isolation: isolate;
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3) var(--space-3);
}

/* The hill fills only the text area below the thumbnail: the layer covers the body
   exactly and the hill is placed inside it by its mask, so it never reaches the map. */
.map-card__body::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--color-contour-index);
  opacity: 0;
  -webkit-mask: url("../patterns/summit.7d622108d3fb.svg") right -3.5rem bottom -5.5rem / 13rem no-repeat;
  mask: url("../patterns/summit.7d622108d3fb.svg") right -3.5rem bottom -5.5rem / 13rem no-repeat;
  transition: opacity 0.35s var(--ease);
  pointer-events: none;
}

.map-card:hover .map-card__body::before {
  opacity: 0.28;
}

/* Clamped text wraps plainly: Firefox balances or prettifies over every line, the
   hidden ones too, and then shows only a word or two per visible line. */
.map-card__title {
  display: -webkit-box;
  overflow: hidden;
  overflow-wrap: anywhere;
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.3;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  text-wrap: wrap;
}

.map-card__link {
  color: var(--color-text);
  text-decoration: none;
}

/* The whole card opens the map. The link sits in the body, which is positioned for
   its hill, so its hit area reaches up over the mat and the thumbnail from there:
   the preview is (card width - 2 mats) * 3/4 high, plus the mat above it. */
.map-card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  top: calc(-1 * ((100cqw - 2 * var(--card-mat)) * 3 / 4 + var(--card-mat)));
}

.map-card__link:focus-visible {
  outline: none;
}

.map-card:hover .map-card__link {
  color: var(--color-text);
}

.map-card__description {
  display: -webkit-box;
  overflow: hidden;
  overflow-wrap: anywhere;
  color: var(--color-text-muted);
  font-size: 0.8125rem;
  line-height: 1.45;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  text-wrap: wrap;
}

/* Above the card's stretched link, so each chip can show its tooltip. */
.map-card__chips {
  position: relative;
  z-index: 1;
  flex-wrap: nowrap;
  gap: var(--space-1);
  margin-top: auto;
}

.map-card__chips .chip {
  min-height: 1.375rem;
  padding: 0 0.45rem;
  gap: 0.3rem;
  background: var(--color-canvas);
  font-size: 0.75rem;
}

.map-card__chips .chip .icon {
  width: 0.8125rem;
  height: 0.8125rem;
}

/* Centre digits on their cap height rather than the font's line box. */
.map-card__chips .chip > span:not(.tip) {
  line-height: 1;
  font-variant-numeric: lining-nums tabular-nums;
}

@supports (text-box: trim-both cap alphabetic) {
  .map-card__chips .chip > span:not(.tip) {
    text-box: trim-both cap alphabetic;
  }
}

/* --- Explore rows ---------------------------------------------------------- */

.row {
  container-type: inline-size;
  display: grid;
  gap: var(--space-4);
}

.row__head,
.section-head {
  display: flex;
  align-items: center;
  min-height: var(--row-head-height);
  gap: var(--space-3);
}

.row__head h2,
.section-head h2 {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 var(--space-3);
  margin-right: auto;
}

.row__more {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: 0.875rem;
  font-weight: 550;
  text-decoration: none;
  white-space: nowrap;
}

.row__viewport {
  position: relative;
  min-width: 0;
}

.row__arrow {
  position: absolute;
  top: calc(50% - var(--space-3) / 2);
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--color-raised);
  color: var(--color-text);
  box-shadow: var(--shadow-float);
  cursor: pointer;
  opacity: 0;
  transform: translateY(-50%);
  transition:
    opacity 0.15s var(--ease),
    background-color 0.15s var(--ease),
    transform 0.15s var(--ease);
}

.row__arrow[hidden] {
  display: none;
}

.row__arrow--previous {
  left: var(--space-2);
}

.row__arrow--next {
  right: var(--space-2);
}

.row__arrow .icon {
  width: 1.5rem;
  height: 1.5rem;
}

.row__arrow:hover {
  background: var(--color-hover);
}

.row__arrow--next {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.row__arrow--next:hover {
  background: var(--color-accent-hover);
}

.row__arrow:focus-visible,
.row__viewport:hover .row__arrow,
.row__viewport:focus-within .row__arrow {
  opacity: 1;
}

.row__arrow:active {
  transform: translateY(-50%) scale(0.94);
}

@media (hover: none), (pointer: coarse) {
  .row__arrow {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .row__arrow {
    transition: none;
  }
}

.row__track {
  --row-gap: var(--space-3);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 62%;
  gap: var(--row-gap);
  margin: 0;
  padding: 0 0 var(--space-2);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  list-style: none;
}

.row__track::-webkit-scrollbar {
  display: none;
}

.row__track:focus {
  outline: none;
}

.row__track > li {
  scroll-snap-align: start;
}

/* Dense rows: two cards on phones' larger sizes, four from a typical laptop's
   content column, five and six on wide screens. */
@container (min-width: 30rem) {
  .row__track {
    grid-auto-columns: calc((100% - var(--row-gap)) / 2);
  }
}

@container (min-width: 38rem) {
  .row__track {
    grid-auto-columns: calc((100% - 2 * var(--row-gap)) / 3);
  }
}

@container (min-width: 46rem) {
  .row__track {
    grid-auto-columns: calc((100% - 3 * var(--row-gap)) / 4);
  }
}

@container (min-width: 58rem) {
  .row__track {
    grid-auto-columns: calc((100% - 4 * var(--row-gap)) / 5);
  }
}

@container (min-width: 70rem) {
  .row__track {
    grid-auto-columns: calc((100% - 5 * var(--row-gap)) / 6);
  }
}

.row__placeholder {
  display: grid;
  place-items: center;
  min-height: 14rem;
  border-radius: var(--radius-l);
  background: var(--color-surface);
}

/* --- Search results ------------------------------------------------------- */

.results {
  container-type: inline-size;
  display: grid;
  gap: var(--space-6);
}

.results__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-4);
}

.results__count {
  color: var(--color-text-subtle);
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
}

.results__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

@container (min-width: 30rem) {
  .results__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@container (min-width: 38rem) {
  .results__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@container (min-width: 46rem) {
  .results__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Five columns at most: wider screens get larger cards, not more of them. */
@container (min-width: 58rem) {
  .results__grid {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

.active-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.empty-state {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: grid;
  justify-items: start;
  gap: var(--space-3);
  padding: var(--space-8);
  padding-right: max(var(--space-8), 30%);
  border-radius: var(--radius-l);
  background: var(--color-surface);
}

/* Uncharted ground: a lone hill on the empty state's right. */
.empty-state::before,
.empty-state::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -4rem;
  z-index: -1;
  width: 20rem;
  aspect-ratio: 1;
  translate: 0 -50%;
  pointer-events: none;
}

.empty-state::before {
  background: var(--color-contour);
  opacity: var(--contour-minor-hero);
  -webkit-mask: url("../patterns/summit.7d622108d3fb.svg") center / contain no-repeat;
  mask: url("../patterns/summit.7d622108d3fb.svg") center / contain no-repeat;
}

.empty-state::after {
  background: var(--color-contour-index);
  opacity: var(--contour-index-hero);
  -webkit-mask: url("../patterns/summit-index.3a1460aa3eb5.svg") center / contain no-repeat;
  mask: url("../patterns/summit-index.3a1460aa3eb5.svg") center / contain no-repeat;
}

/* Three fixed columns: the label keeps its place on the first and last page, where
   one arrow is missing and its column stays empty. */
.pagination {
  display: grid;
  grid-template-columns: 2.5rem auto 2.5rem;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
}

.pagination__previous {
  grid-column: 1;
}

.pagination__label {
  grid-column: 2;
}

.pagination__next {
  grid-column: 3;
}

/* --- Noticeboard ----------------------------------------------------------- */

.noticeboard {
  display: grid;
  gap: var(--space-4);
}

.reading-list {
  display: grid;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.reading-list a {
  display: block;
  padding: var(--space-1) 0;
  font-weight: 500;
}

.noticeboard-post {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5) var(--space-5);
  border-radius: var(--radius-l);
  background: var(--color-surface-veil);
  font-size: 0.9rem;
}

.noticeboard-post--highlight {
  background: color-mix(in srgb, var(--color-surface) 55%, var(--color-earth-soft));
}

.noticeboard-post__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.noticeboard-post__date {
  color: var(--color-text-subtle);
  font-size: 0.75rem;
}

.noticeboard-post h3 {
  font-size: 0.975rem;
}

.noticeboard-post p {
  color: var(--color-text-muted);
}

.roadmap {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.roadmap li {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-m);
  background: var(--color-card);
}

.status {
  display: inline-flex;
  align-items: center;
  min-height: 1.375rem;
  padding: 0 0.55rem;
  border-radius: var(--radius-pill);
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
}

.status--done {
  background: var(--color-success-bg);
  color: var(--color-success-ink);
}

.status--now {
  background: var(--color-accent-soft);
  color: var(--color-accent-soft-ink);
}

.status--next,
.status--later {
  background: var(--color-raised);
  color: var(--color-text-muted);
}

.survey-results {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.survey-results li {
  display: grid;
  gap: var(--space-1);
}

.survey-results__label {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: 0.875rem;
}

.survey-results__label > span:first-child {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.survey-results__label .icon {
  width: 0.875rem;
  height: 0.875rem;
  color: var(--color-accent);
}

.survey-results__label .mono {
  color: var(--color-text-subtle);
  font-family: inherit;
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

/* The track carries the background, so the meter's fill can grow from zero by
   revealing it; a meter's own fill cannot be animated across browsers. */
.bar-track {
  display: block;
  height: 0.5rem;
  border-radius: 999px;
  background: var(--color-raised);
}

.bar {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 999px;
  background: transparent;
  appearance: none;
  overflow: hidden;
  animation: bar-grow 0.9s var(--ease) both;
}

@keyframes bar-grow {
  from {
    clip-path: inset(0 100% 0 0);
  }

  to {
    clip-path: inset(0 0 0 0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .bar {
    animation: none;
  }
}

.bar::-webkit-meter-bar {
  border: 0;
  border-radius: 999px;
  background: transparent;
}

.bar::-webkit-meter-optimum-value {
  border-radius: 999px;
  background: var(--color-accent);
}

.bar::-moz-meter-bar {
  border-radius: 999px;
  background: var(--color-accent);
}

/* --- Map details ----------------------------------------------------------- */

.map-page {
  display: grid;
  gap: var(--space-6);
}

.map-page__layout {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "map"
    "panel"
    "comments";
}

.map-frame {
  grid-area: map;
}

.map-page__panel {
  grid-area: panel;
}

.map-page__comments {
  grid-area: comments;
  min-width: 0;
}

@media (min-width: 64rem) {
  .map-page__layout {
    grid-template-columns: minmax(0, 1fr) 24rem;
    grid-template-rows: auto 1fr;
    grid-template-areas:
      "map panel"
      "comments panel";
    align-items: start;
  }

}

@media (min-width: 90rem) {
  .map-page__layout {
    grid-template-columns: minmax(0, 1fr) 27rem;
  }
}

/* Rounded by clip-path, not overflow: Chrome clips an overflowing embed layer by
   layer, so at the corners Google's map seams through its dark header. */
.map-frame {
  position: relative;
  clip-path: inset(0 round var(--radius-xl));
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  aspect-ratio: 4 / 3;
}

@media (min-width: 64rem) {
  .map-frame {
    aspect-ratio: auto;
    height: calc(100vh - var(--masthead-height) - var(--space-12));
    min-height: 32rem;
    max-height: 56rem;
  }
}

.map-frame iframe {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: var(--color-raised);
}

/* While the provider's embed loads, the map's thumbnail stands in for it, heavily
   blurred (scaled up so the blur keeps clean edges), or the lone hill without one.
   The embed then fades in over it; without JavaScript it simply shows. */
.map-frame__preview {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

img.map-frame__preview {
  object-fit: cover;
  filter: blur(28px) saturate(1.15);
  transform: scale(1.15);
}

/* The logo's loader waits in the middle of the preview, only with JavaScript, which
   is what can tell when the embed has loaded. */
.map-frame__loader {
  display: none;
}

.js .map-frame__loader {
  position: absolute;
  top: 50%;
  left: 50%;
  display: grid;
  place-items: center;
  width: 4.5rem;
  height: 4.5rem;
  translate: -50% -50%;
  border-radius: 50%;
  background: var(--color-surface-veil);
  box-shadow: var(--shadow-card);
}

.map-frame__loader svg {
  width: 2.5rem;
  height: 2.5rem;
}

.js .map-frame iframe,
.js .map-frame__preview,
.js .map-frame__loader {
  transition: opacity 0.6s var(--ease);
}

.js .map-frame iframe {
  opacity: 0;
}

/* Loaded: the embed fades in as preview and loader fade out. */
.js .map-frame[data-embed-loaded] iframe {
  opacity: 1;
}

.js .map-frame[data-embed-loaded] .map-frame__preview,
.js .map-frame[data-embed-loaded] .map-frame__loader {
  visibility: hidden;
  opacity: 0;
  transition:
    opacity 0.6s var(--ease),
    visibility 0s 0.6s;
}

/* Arriving on a map, its frame, details and comments rise into place one after
   another, and the blurred preview settles. */
@media (prefers-reduced-motion: no-preference) {
  .map-frame,
  .map-page__panel,
  .map-page__comments {
    animation: map-page-enter 0.5s var(--ease) both;
  }

  .map-page__panel {
    animation-delay: 0.08s;
  }

  .map-page__comments {
    animation-delay: 0.16s;
  }

  img.map-frame__preview {
    animation: map-preview-settle 1.2s var(--ease) backwards;
  }
}

@keyframes map-page-enter {
  from {
    opacity: 0;
    transform: translateY(0.75rem);
  }
}

@keyframes map-preview-settle {
  from {
    opacity: 0;
    transform: scale(1.3);
  }
}

.detail-panel {
  display: grid;
  gap: var(--space-5);
  padding: var(--space-6);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
}

.detail-panel__title {
  display: grid;
  gap: var(--space-2);
}

.detail-panel__title h1 {
  overflow-wrap: anywhere;
  font-size: clamp(1.5rem, 1.25rem + 1vw, 1.875rem);
}

/* Views and votes under the title: icon and number, the name is the tooltip. */
.stats,
.stats__group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  margin: 0;
}

.stats {
  color: var(--color-text-subtle);
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
}

.stats__link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: inherit;
  text-decoration: none;
}

.stats__link:hover {
  color: var(--color-text);
}

.fact dd {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
}

.fact .icon {
  flex: none;
  width: 0.875rem;
  height: 0.875rem;
}

/* The map's facts: one labelled line each. */
.facts {
  display: grid;
  margin: 0;
  padding: var(--space-1) var(--space-4);
  border-radius: var(--radius-l);
  background: var(--color-card);
}

.facts > div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) 0;
}

.facts > div + div {
  border-top: 2px solid var(--color-surface);
}

.facts dt {
  flex: none;
  color: var(--color-text-subtle);
  font-size: 0.8125rem;
  font-weight: 600;
}

.facts dd {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere;
  font-size: 0.875rem;
  text-align: right;
}

.facts dd .icon {
  flex: none;
  width: 1rem;
  height: 1rem;
}

.tabs {
  display: grid;
  gap: var(--space-4);
}

.tabs__list {
  display: inline-flex;
  gap: var(--space-1);
  width: fit-content;
  padding: var(--space-1);
  border-radius: var(--radius-pill);
  background: var(--color-card);
}

.tabs__tab {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  min-height: 2rem;
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--color-text-muted);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
}

.tabs__tab[aria-selected="true"] {
  background: var(--color-accent-soft);
  color: var(--color-accent-soft-ink);
}

.tabs__panel {
  display: grid;
  gap: var(--space-3);
}

.tabs__panel h2 {
  font-size: 0.875rem;
}

.tabs__tab .icon,
.tabs__panel h2 .icon {
  width: 0.875rem;
  height: 0.875rem;
}

.tabs__panel h2:has(.icon) {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.author-links {
  display: grid;
  gap: var(--space-2);
}

.author-links h2 {
  font-size: 0.875rem;
}

.author-links ul {
  display: grid;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.author-links a {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  min-width: 0;
  color: var(--color-text);
  font-size: 0.875rem;
  text-decoration: none;
}

.author-links a:hover span:first-of-type {
  text-decoration: underline;
}

.author-links .icon {
  flex: none;
  align-self: center;
  width: 0.875rem;
  height: 0.875rem;
  color: var(--color-text-subtle);
}

.author-links__target {
  overflow: hidden;
  color: var(--color-text-subtle);
  font-size: 0.8125rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.description {
  color: var(--color-text-muted);
  font-size: 0.9375rem;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.original-title {
  font-weight: 600;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.vote-group {
  display: inline-flex;
  gap: var(--space-2);
}

.section {
  display: grid;
  gap: var(--space-5);
}

.section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
}

/* --- Comments -------------------------------------------------------------- */

.comments {
  display: grid;
  gap: var(--space-5);
  max-width: 52rem;
  margin-top: var(--space-4);
}

.comment-list {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.comment {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-l);
  background: var(--color-surface);
}

.comment__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-1) var(--space-3);
}

.comment__author {
  font-weight: 600;
  font-size: 0.9375rem;
}

.comment__date {
  color: var(--color-text-subtle);
  font-size: 0.8125rem;
}

.comment__body {
  color: var(--color-text-muted);
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.comment-form {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-l);
  background: var(--color-surface);
}

.comment-form__name {
  max-width: 16rem;
}

/* A textarea with a round send button in its corner (comments, feedback). */

.compose {
  position: relative;
}

.compose .textarea {
  display: block;
  min-height: 5rem;
  padding-right: 3.75rem;
  resize: vertical;
}

.compose__send {
  position: absolute;
  right: var(--space-2);
  bottom: var(--space-2);
  border-radius: 50%;
}

.compose .loader {
  position: absolute;
  right: 3.5rem;
  bottom: 0.75rem;
}

/* --- Notices --------------------------------------------------------------- */

.notice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-m);
  background: var(--color-info-bg);
  color: var(--color-info-ink);
  font-size: 0.9rem;
}

.notice--success {
  background: var(--color-success-bg);
  color: var(--color-success-ink);
}

.notice--warning {
  background: var(--color-warning-bg);
  color: var(--color-warning-ink);
}

.notice--danger {
  background: var(--color-danger-bg);
  color: var(--color-danger-ink);
}

.notice .icon {
  margin-top: 0.15rem;
}

.messages {
  display: grid;
  gap: var(--space-2);
  margin-bottom: var(--space-6);
}

/* --- Popovers -------------------------------------------------------------- */

.popover {
  width: min(32rem, calc(100vw - 2rem));
  max-height: calc(100vh - 2rem);
  margin: auto;
  padding: 0;
  overflow: auto;
  border: 0;
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow-float);
}

.popover::backdrop {
  background: color-mix(in srgb, var(--color-shadow) 60%, transparent);
}

.popover__body {
  display: grid;
  gap: var(--space-5);
  padding: var(--space-6);
}

.popover__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
}

.popover__head h2 {
  font-size: 1.25rem;
}

.popover__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
}

/* --- Loader ---------------------------------------------------------------- */

.loader {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-muted);
  font-size: 0.8125rem;
}

.loader svg {
  width: 1.5rem;
  height: 1.5rem;
}

.htmx-indicator {
  opacity: 0;
  transition: opacity 0.2s var(--ease) 0.15s;
}

.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  opacity: 1;
}

/* --- Articles -------------------------------------------------------------- */

/* Long text reads on a sheet of paper laid over the landscape. */
/* One column as wide as the card: a wide table must not widen the text around it. */
.article {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-8);
  max-width: 50rem;
  margin: 0 auto;
  padding: clamp(var(--space-5), 4vw, var(--space-12));
  border-radius: var(--radius-xl);
  background: color-mix(in srgb, var(--color-card) 94%, transparent);
  box-shadow: var(--shadow-card);
}

.article__head {
  display: grid;
  gap: var(--space-3);
}

.article__head .lead {
  color: var(--color-text-muted);
  font-size: 1.125rem;
}

.prose {
  font-size: 1.0625rem;
  line-height: 1.7;
}

.prose > * + * {
  margin-top: 1.1em;
}

.prose h2 {
  margin-top: 2em;
  font-size: 1.375rem;
}

.prose h3 {
  margin-top: 1.6em;
  font-size: 1.125rem;
}

.prose ul,
.prose ol {
  padding-left: 1.4em;
}

.prose li + li {
  margin-top: 0.35em;
}

.prose code {
  padding: 0.1em 0.35em;
  border-radius: var(--radius-s);
  background: var(--color-raised);
  font-family: var(--font-mono);
  font-size: 0.875em;
}

.prose pre {
  overflow-x: auto;
  padding: var(--space-4);
  border-radius: var(--radius-m);
  background: var(--color-surface);
}

.prose pre code {
  padding: 0;
  background: none;
}

.prose blockquote {
  margin-inline: 0;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-m);
  background: var(--color-surface);
  color: var(--color-text-muted);
}

/* Tables keep to the text's width: columns share it, and long words wrap. */
.prose table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  font-size: 0.9375rem;
  overflow-wrap: break-word;
}

.prose th,
.prose td {
  padding: var(--space-2) var(--space-3);
  text-align: left;
}

.prose tr:nth-child(even) td {
  background: var(--color-surface);
}

/* On a phone, columns would split words: each row becomes a block instead, its
   first cell as the title over the others. */
@media (max-width: 40rem) {
  .prose table,
  .prose tbody,
  .prose tr,
  .prose td {
    display: block;
  }

  .prose thead {
    display: none;
  }

  .prose tr {
    padding: var(--space-3);
    border-radius: var(--radius-m);
  }

  .prose tr:nth-child(even),
  .prose tr:nth-child(even) td {
    background: var(--color-surface);
  }

  .prose td {
    padding: 0;
  }

  .prose td:first-child {
    font-weight: 600;
  }
}

/* Credit tables share their column widths, so the sections line up. */
.credits th:first-child {
  width: 42%;
}

.credits th:nth-child(2) {
  width: 30%;
}

/* Without a detail column the licence stays where the other tables have it. */
.credits--short th:first-child {
  width: 72%;
}

.credits--short th:nth-child(2) {
  width: auto;
}

.credits__author {
  display: block;
  color: var(--color-text-muted);
  font-size: 0.875rem;
}

.prose hr {
  height: 2px;
  border: 0;
  background: var(--color-raised);
}

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

/* The footer is nearly solid: the landscape shows through only as a trace. */
.site-footer {
  background: color-mix(in srgb, var(--color-surface) 96%, transparent);
}

.site-footer__inner {
  display: grid;
  justify-items: center;
  gap: var(--space-8);
  max-width: var(--page-width);
  margin: 0 auto;
  padding: var(--space-10) var(--gutter) var(--space-8);
  text-align: center;
}

.site-footer__about {
  display: grid;
  justify-items: center;
  align-content: start;
  gap: var(--space-3);
  max-width: 26rem;
  color: var(--color-text-muted);
  font-size: 0.9rem;
}

.site-footer ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2) var(--space-5);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.9rem;
}

.site-footer a {
  color: var(--color-text-muted);
  text-decoration: none;
}

.site-footer a:hover {
  color: var(--color-text);
  text-decoration: underline;
}

.site-footer .brand:hover {
  text-decoration: none;
}

/* --- Error pages ----------------------------------------------------------- */

/* Lost, but on the map: the logo stands on a summit, rings of contour lines around it. */
.error-page {
  position: relative;
  isolation: isolate;
  display: grid;
  justify-items: center;
  gap: var(--space-4);
  max-width: 34rem;
  margin: var(--space-12) auto;
  padding: var(--space-12) var(--gutter) 0;
  text-align: center;
}

.error-page::before,
.error-page::after {
  content: "";
  position: absolute;
  top: calc(var(--space-12) + 2rem);
  left: 50%;
  z-index: -1;
  width: min(32rem, 115vw);
  aspect-ratio: 1;
  translate: -50% -50%;
  pointer-events: none;
}

.error-page::before {
  background: var(--color-contour);
  opacity: var(--contour-minor-hero);
  -webkit-mask:
    url("../patterns/summit.7d622108d3fb.svg") center / contain no-repeat,
    radial-gradient(closest-side, #000 55%, transparent);
  -webkit-mask-composite: source-in;
  mask:
    url("../patterns/summit.7d622108d3fb.svg") center / contain no-repeat,
    radial-gradient(closest-side, #000 55%, transparent);
  mask-composite: intersect;
}

.error-page::after {
  background: var(--color-contour-index);
  opacity: var(--contour-index-hero);
  -webkit-mask:
    url("../patterns/summit-index.3a1460aa3eb5.svg") center / contain no-repeat,
    radial-gradient(closest-side, #000 55%, transparent);
  -webkit-mask-composite: source-in;
  mask:
    url("../patterns/summit-index.3a1460aa3eb5.svg") center / contain no-repeat,
    radial-gradient(closest-side, #000 55%, transparent);
  mask-composite: intersect;
}

.error-page img {
  width: 4rem;
  height: 4rem;
  margin-bottom: var(--space-8);
}

.error-page h1 {
  margin-top: var(--space-4);
}

.error-page p {
  color: var(--color-text-muted);
}

/* --- Motion ---------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}
