/* ==========================================================================
   SPplus! Orpund — site styles
   Hand-written, layered on top of Bootstrap 5. No build step.

   The design brief: SPplus! is a village party. It carries the SP name and
   the SP red, but the people in it would vote Green, GLP or centre in a
   national election. The old design said "SP" very loudly -- half of every
   page was a flat #bb261a band -- and said nothing about the rest.

   So: the red stays as the mark, and stops being the wallpaper. It is now an
   accent on a light, quiet canvas, with a green as its counterweight. Colour
   carries meaning again because there is less of it.
   ========================================================================== */

:root {
  /* ---- brand ---------------------------------------------------------- */

  /* Unchanged: this is the red in logo.png, measured 6.17:1 on white. */
  --sp-red: #bb261a;
  --sp-red-strong: #a51f14;
  --sp-red-tint: #fdf2f0;

  /* The "plus". SPplus! is broader than the SP, and a single red said
     otherwise. 5.26:1 on white, 7.19:1 in its darker step. */
  --sp-green: #1f7a5a;
  --sp-green-strong: #186349;
  --sp-green-tint: #eef7f3;

  /* ---- neutrals ------------------------------------------------------- */

  /* Warm, to sit with a warm red. #c0c0c0 is gone: it was never a design
     decision, it was the colour baked into the logo's background plate. */
  --sp-ink: #17161a;
  --sp-canvas: #ffffff;
  --sp-canvas-tint: #f7f5f2;
  --sp-canvas-deep: #efece7;

  /* ---- contextual tokens ---------------------------------------------- */

  /* Sections remap these, so a component written once looks right on the
     light canvas, on the ink band and on the red band. Always reach for
     these in component rules, never for the raw brand values above. */
  --text: var(--sp-ink);
  --text-muted: #55525c;
  --accent: var(--sp-red);
  --accent-contrast: #fff;
  --line: #e6e2dd;
  --surface: #fff;
  --surface-hover: var(--sp-canvas-tint);

  /* ---- shape and motion ----------------------------------------------- */

  --sp-radius-sm: 0.375rem;
  --sp-radius: 0.75rem;
  --sp-radius-lg: 1.25rem;

  --sp-shadow: 0 1px 2px rgba(23, 22, 26, .04), 0 2px 8px rgba(23, 22, 26, .05);
  --sp-shadow-lifted: 0 2px 6px rgba(23, 22, 26, .06), 0 14px 32px rgba(23, 22, 26, .12);

  --sp-transition: 180ms cubic-bezier(.2, .7, .3, 1);

  /* The header is sticky, so its height is only needed to keep in-page
     anchor targets clear of it. */
  --sp-nav-height: 68px;

  /* One vertical rhythm for every section on the site. */
  --sp-section-y: clamp(3rem, 1.75rem + 5vw, 6.5rem);
}

/* ---------- base ---------------------------------------------------------- */

html {
  scroll-behavior: smooth;
}

body,
.body {
  background-color: var(--sp-canvas);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
               Arial, sans-serif;
  font-size: clamp(1rem, 0.96rem + 0.18vw, 1.0625rem);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;

  /* Keeps the footer at the bottom of short pages -- the search page with no
     results is a header, three lines and then a footer floating mid-screen. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* The slack goes to the last section rather than to <main> itself, so a short
   page that ends on the dark band does not show a white strip above the
   footer. Nothing may shrink: the hero holds its height by min-height. */
body > main {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
}

body > main > * {
  flex: 0 0 auto;
}

body > main > :last-child {
  flex: 1 0 auto;
}

a {
  color: inherit;
}

img {
  max-width: 100%;
}

/* Visible keyboard focus everywhere, including on the dark and red bands
   where the browser default outline nearly disappears. */
:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 3px;
  border-radius: 2px;
}

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

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------- typography ---------------------------------------------------- */

/* Fluid headings. Each heading is one element scaled with clamp(); the old
   markup wrote every heading twice -- an <h1> and an <h3> of the same text --
   and hid one per breakpoint. */
h1,
.h1,
h2,
.h2,
h3,
.h3,
h4,
.h4 {
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

h1,
.h1 {
  font-size: clamp(2rem, 1.4rem + 2.8vw, 3.25rem);
  letter-spacing: -0.03em;
}

h2,
.h2 {
  font-size: clamp(1.5rem, 1.15rem + 1.7vw, 2.25rem);
}

h3,
.h3 {
  font-size: clamp(1.2rem, 1.05rem + 0.7vw, 1.5rem);
}

h4,
.h4 {
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
}

/* A short label above a heading, in the accent colour. Gives a section a
   second line of hierarchy without a second heading level. */
.eyebrow {
  display: block;
  margin-bottom: 0.75rem;
  color: var(--accent);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.section-head {
  max-width: 44rem;
  margin-bottom: clamp(2rem, 1.5rem + 1.5vw, 3rem);
}

.section-head--center {
  margin-inline: auto;
  text-align: center;
}

.section-head p {
  margin-bottom: 0;
  color: var(--text-muted);
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.25rem);
  line-height: 1.55;
  text-wrap: pretty;
}

/* Long-form text is easier to read when the line length is capped, whatever
   the column happens to be. */
.prose {
  max-width: 66ch;
}

.prose--center {
  margin-inline: auto;
}

.prose > :last-child {
  margin-bottom: 0;
}

.prose p,
.prose ul,
.prose ol {
  margin-bottom: 1.15em;
}

.prose h2,
.prose h3,
.prose h4 {
  margin-top: 2em;
  margin-bottom: 0.6em;
}

.prose > :first-child {
  margin-top: 0;
}

/* Editors paste photos straight into the rich text. Left alone they render
   at their natural size, which on the homepage meant a column of unscaled
   snapshots at whatever width each rendition happened to be. Centred, so a
   narrow one does not read as a mistake next to a wide one. */
.prose img {
  display: block;
  height: auto;
  margin: 1.75rem auto;
  border-radius: var(--sp-radius);
  box-shadow: var(--sp-shadow);
}

.prose :where(p, li) a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

.prose :where(p, li) a:hover {
  text-decoration-thickness: 2px;
}

.prose blockquote {
  margin: 1.75rem 0;
  padding-left: 1.25rem;
  border-left: 3px solid var(--accent);
  color: var(--text-muted);
  font-size: 1.0625em;
}

/* Editors write the subtitle as rich text, so .lead wraps a <p> rather than
   being one. Font size inherits; the trailing margin has to be cleared. */
.lead {
  font-size: clamp(1.125rem, 1rem + 0.6vw, 1.375rem);
  font-weight: 400;
  line-height: 1.5;
  color: var(--text-muted);
  text-wrap: pretty;
}

.lead > :last-child {
  margin-bottom: 0;
}

/* ---------- skip link ----------------------------------------------------- */

.skip-link {
  position: fixed;
  left: 0.75rem;
  top: -5rem;
  z-index: 1100;
  padding: 0.7rem 1.15rem;
  background: var(--sp-ink);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
  border-radius: var(--sp-radius-sm);
  box-shadow: var(--sp-shadow-lifted);
  transition: top var(--sp-transition);
}

.skip-link:focus {
  top: 0.75rem;
}

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

/* Light and sticky rather than solid red and fixed. The red bar was the
   single largest block of colour on every page; as a thin white rule it lets
   the hero photograph start the page instead. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 1030;
  background-color: rgba(255, 255, 255, .88);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}

@supports not (backdrop-filter: blur(1px)) {
  .site-header {
    background-color: #fff;
  }
}

.site-header .navbar {
  min-height: var(--sp-nav-height);
  padding-block: 0.5rem;
  font-weight: 600;
  background: none;
  box-shadow: none;
}

.navbar-brand-sp {
  display: inline-flex;
  align-items: center;
  padding: 0;
  margin-right: 1.5rem;
}

.logo {
  height: 46px;
  width: auto;
  display: block;
}

.site-header .navbar-nav {
  gap: 0.15rem;
}

.site-header .nav-link {
  position: relative;
  padding: 0.4rem 0.75rem;
  color: var(--text-muted);
  border-radius: var(--sp-radius-sm);
  transition: color var(--sp-transition), background-color var(--sp-transition);
}

.site-header .nav-link:hover,
.site-header .nav-link:focus-visible {
  color: var(--sp-ink);
  background-color: var(--sp-canvas-tint);
}

.site-header .nav-link.active {
  color: var(--sp-red);
}

/* Marks the current page with the brand red rather than a colour swap alone,
   which was invisible to anyone who does not perceive the red. */
.site-header .nav-link.active::after {
  content: "";
  position: absolute;
  left: 0.75rem;
  right: 0.75rem;
  bottom: 0.05rem;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
}

.navbar-toggler {
  border-color: var(--line);
  color: var(--sp-ink);
}

@media (max-width: 767.98px) {
  .site-header .navbar-collapse {
    padding-block: 0.5rem 0.75rem;
  }

  .site-header .nav-link {
    padding-inline: 0.5rem;
  }

  .site-header .nav-link.active::after {
    left: 0.5rem;
    right: auto;
    width: 1.25rem;
  }
}

/* ---------- sections ------------------------------------------------------ */

.section {
  padding-block: var(--sp-section-y);
}

.section--tight {
  padding-block: clamp(2rem, 1.25rem + 3vw, 3.5rem);
}

.section--tint {
  background-color: var(--sp-canvas-tint);
  --surface-hover: #fff;
}

/* Deep neutral rather than deep red: it frames photographs and agenda rows
   without shouting, and keeps the red available as an accent inside it. */
.section--ink {
  background-color: var(--sp-ink);
  --text: #ffffff;
  --text-muted: #c9c6cf;
  --accent: #ff8578;
  --accent-contrast: var(--sp-ink);
  --line: rgba(255, 255, 255, .16);
  --surface: rgba(255, 255, 255, .05);
  --surface-hover: rgba(255, 255, 255, .1);
  color: var(--text);
}

/* Kept for the one moment a page should be unmistakably the party's: used
   sparingly, never as a page's main body. */
.section--accent {
  background-color: var(--sp-red);
  --text: #ffffff;
  --text-muted: rgba(255, 255, 255, .82);
  --accent: #ffffff;
  --accent-contrast: var(--sp-red);
  --line: rgba(255, 255, 255, .24);
  --surface: rgba(255, 255, 255, .1);
  --surface-hover: rgba(255, 255, 255, .16);
  color: var(--text);
}

/* A hairline between two sections that share a background, so they read as
   two things without a colour change. */
.section--ruled + .section--ruled {
  border-top: 1px solid var(--line);
}

.measure {
  max-width: 46rem;
}

.measure--center {
  margin-inline: auto;
}

/* A list beside a detail panel: the agenda on the homepage. One column until
   there is room for the panel to sit next to the list rather than under it. */
.split {
  display: grid;
  gap: clamp(1.5rem, 1rem + 2.5vw, 3rem);
  align-items: start;
}

@media (min-width: 992px) {
  .split {
    grid-template-columns: minmax(0, 21rem) minmax(0, 1fr);
  }
}

/* ---------- hero ---------------------------------------------------------- */

.hero {
  position: relative;
  display: grid;
  isolation: isolate;
  min-height: clamp(20rem, 12rem + 26vw, 32rem);
  max-height: min(82vh, 36rem);
  overflow: hidden;
}

.hero__scrim,
.hero__inner {
  grid-area: 1 / 1;
}

/* Taken out of flow deliberately. As a grid item the picture sized the row to
   its own aspect ratio, so on an ultra-wide screen a 3000x1300 rendition
   stretched the hero to about 1500px tall and swallowed the viewport --
   min-height is a floor, and nothing was acting as a ceiling. Positioned
   absolutely it fills whatever height the hero decides on and crops. */
.hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero__media,
.hero__media img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  /* The old rule was filter: contrast(50%) brightness(120%), which washed
     every photograph out to make white text readable. The scrim below does
     that job where it is needed and leaves the rest of the picture alone. */
  filter: none;
}

/* z-index applies to grid items even when their position is static, so the
   scrim and the caption stack over the absolutely positioned photograph
   without needing to be positioned themselves. */
.hero__scrim {
  z-index: 1;
  background:
    linear-gradient(to top, rgba(10, 9, 12, .78) 0%, rgba(10, 9, 12, .35) 42%,
                    rgba(10, 9, 12, .06) 72%, rgba(10, 9, 12, 0) 100%);
}

.hero__inner {
  position: relative;
  z-index: 2;
  align-self: end;
  width: 100%;
  padding-block: clamp(2rem, 1.25rem + 3vw, 3.5rem);
  color: #fff;
}

.hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.9rem;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .92);
}

/* ---------- brand mark --------------------------------------------------- */

/* The "plus" of SPplus!, as a mark. It replaces a red/white/green rule that was
   meant to stand for the parties the group draws from and instead read as an
   Italian flag -- which is what three vertical bands in those colours are.
   A plus cannot be mistaken for a flag, and it is the party's own name.
   The green sits behind it as an offset block, so both brand colours are
   present without ever forming a tricolour. */
.brand-mark {
  position: relative;
  display: inline-block;
  flex: 0 0 auto;
  width: 1.375rem;
  height: 1.375rem;
  border-radius: 0.375rem;
  background: var(--sp-red);
  box-shadow: 0.1875rem 0.1875rem 0 var(--sp-green);
}

.brand-mark::before,
.brand-mark::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: #fff;
  border-radius: 1px;
  transform: translate(-50%, -50%);
}

.brand-mark::before {
  width: 0.6875rem;
  height: 2px;
}

.brand-mark::after {
  width: 2px;
  height: 0.6875rem;
}

/* Over a photograph the red needs a little separation from whatever is behind
   it; on the footer's flat ink it does not. */
.hero__eyebrow .brand-mark {
  box-shadow: 0.1875rem 0.1875rem 0 var(--sp-green),
              0 1px 10px rgba(0, 0, 0, .45);
}

.hero__slogan {
  max-width: 20ch;
  margin: 0;
  font-size: clamp(1.75rem, 1.1rem + 3.4vw, 4rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.03em;
  text-wrap: balance;
  text-shadow: 0 2px 24px rgba(0, 0, 0, .35);
}

/* Pages other than the homepage get a shorter crop -- enough to set the
   scene, not enough to push the content below the fold. */
.hero--compact {
  min-height: clamp(12rem, 8rem + 18vw, 20rem);
}

/* ---------- page header (pages without a hero photo) ---------------------- */

.page-header {
  padding-block: clamp(2.5rem, 1.5rem + 4vw, 4.5rem) 0;
}

/* ---------- buttons ------------------------------------------------------- */

.btn-sp {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.4rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background-color: var(--accent);
  color: var(--accent-contrast);
  font-weight: 600;
  line-height: 1.3;
  text-decoration: none;
  transition: background-color var(--sp-transition), transform var(--sp-transition),
              box-shadow var(--sp-transition);
}

.btn-sp:hover,
.btn-sp:focus-visible {
  background-color: var(--sp-red-strong);
  color: #fff;
  transform: translateY(-1px);
  box-shadow: var(--sp-shadow);
}

.btn-sp--ghost {
  background-color: transparent;
  border-color: var(--line);
  color: var(--text);
}

.btn-sp--ghost:hover,
.btn-sp--ghost:focus-visible {
  background-color: var(--surface-hover);
  border-color: var(--text-muted);
  color: var(--text);
  box-shadow: none;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}

.hero .btn-row {
  margin-top: 1.75rem;
}

.hero .btn-sp--ghost {
  border-color: rgba(255, 255, 255, .55);
  color: #fff;
}

.hero .btn-sp--ghost:hover,
.hero .btn-sp--ghost:focus-visible {
  background-color: rgba(255, 255, 255, .16);
  border-color: #fff;
}

/* ---------- badges -------------------------------------------------------- */

.badge-sp {
  display: inline-block;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background-color: var(--sp-canvas-deep);
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.badge-sp--accent {
  background-color: var(--sp-red-tint);
  color: var(--sp-red-strong);
}

.badge-sp--green {
  background-color: var(--sp-green-tint);
  color: var(--sp-green-strong);
}

.section--ink .badge-sp,
.section--accent .badge-sp {
  background-color: var(--surface);
  color: var(--text);
}

/* ---------- card grids ---------------------------------------------------- */

/* Replaces the Bootstrap row/col pairs the card sections used. auto-fill
   means the number of columns follows the available width instead of a
   breakpoint table, so a section with three people and one with twelve both
   look deliberate. */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  gap: clamp(1rem, 0.5rem + 1.5vw, 2rem);
}

.card-grid--wide {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
}

@media (max-width: 575.98px) {
  /* minmax(0, 1fr) rather than 1fr. A bare 1fr is minmax(auto, 1fr), and when
     the cards' content minimums do not fit, the tracks keep those minimums and
     the grid runs off the side of the phone -- which is what the album cards
     did, at unequal widths, because each card's minimum differed. */
  .card-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
  }

  /* Album thumbnails are landscape; two of them on a phone are postage stamps. */
  .card-grid--wide {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------- person and album cards ---------------------------------------- */

.tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100%;
  padding: 1.5rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--sp-radius-lg);
  background-color: var(--surface);
  color: inherit;
  text-align: center;
  text-decoration: none;
  transition: transform var(--sp-transition), box-shadow var(--sp-transition),
              border-color var(--sp-transition);
}

.tile:hover,
.tile:focus-visible {
  transform: translateY(-4px);
  border-color: transparent;
  box-shadow: var(--sp-shadow-lifted);
  color: inherit;
}

.tile-name {
  margin-bottom: 0.2rem;
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.tile-meta {
  margin-bottom: 0;
  color: var(--text-muted);
  font-size: 0.9375rem;
  line-height: 1.4;
}

.tile-meta + .tile-meta {
  margin-top: 0.1rem;
}

.tile .badge-sp {
  margin-top: 0.6rem;
}

/* Circular portrait that scales with the card instead of staying a fixed
   200px block. */
.image-cropper {
  width: min(11rem, 60%);
  aspect-ratio: 1;
  margin-inline: auto;
  margin-bottom: 1rem;
  position: relative;
  overflow: hidden;
  border-radius: 50%;
  background-color: var(--sp-canvas-deep);
}

.image-cropper img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 320ms cubic-bezier(.2, .7, .3, 1);
}

.tile:hover .image-cropper img,
.tile:focus-visible .image-cropper img {
  transform: scale(1.05);
}

/* Albums are landscape photographs; a circular crop threw most of them away. */
.tile--album .image-cropper {
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: var(--sp-radius);
}

.tile--album {
  padding: 0.75rem 0.75rem 1.15rem;
}

/* ---------- person detail ------------------------------------------------- */

/* Capped and centred: the prose beside the portrait stops at its own measure,
   so on a wide screen an uncapped grid left the pair pinned to the left with
   a third of the band empty beside it. */
.person-detail {
  display: grid;
  gap: clamp(1.5rem, 1rem + 3vw, 3.5rem);
  align-items: start;
  max-width: 60rem;
  margin-inline: auto;
}

@media (min-width: 768px) {
  .person-detail {
    grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  }
}

.person-detail__aside {
  text-align: center;
}

@media (min-width: 768px) {
  .person-detail__aside {
    position: sticky;
    top: calc(var(--sp-nav-height) + 1.5rem);
  }
}

.person-detail__aside .image-cropper {
  width: min(15rem, 60vw);
}

.person-detail__name {
  margin-bottom: 0.25rem;
}

.person-detail__role {
  margin-bottom: 0;
  color: var(--text-muted);
}

/* ---------- agenda -------------------------------------------------------- */

.agenda {
  list-style: none;
  padding-left: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.agenda__link {
  display: flex;
  gap: 1rem;
  align-items: center;
  padding: 0.85rem 1rem;
  border: 1px solid transparent;
  border-radius: var(--sp-radius);
  color: inherit;
  text-decoration: none;
  transition: background-color var(--sp-transition), border-color var(--sp-transition),
              transform var(--sp-transition);
}

.agenda__link:hover,
.agenda__link:focus-visible {
  background-color: var(--surface-hover);
  border-color: var(--line);
  color: inherit;
  transform: translateX(2px);
}

.agenda__link[aria-current="true"] {
  background-color: var(--surface-hover);
  border-color: var(--line);
}

/* A stacked day/month chip reads faster than 24.10.26, and gives the row a
   fixed left edge to align on. */
.agenda__date {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  padding: 0.35rem 0;
  border-radius: var(--sp-radius-sm);
  background-color: var(--sp-red-tint);
  color: var(--sp-red-strong);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.agenda__day {
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.agenda__month {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.section--ink .agenda__date,
.section--accent .agenda__date {
  background-color: var(--surface);
  color: var(--text);
}

.agenda__title {
  font-weight: 600;
  text-wrap: balance;
}

.agenda__year {
  display: block;
  margin-top: 0.1rem;
  color: var(--text-muted);
  font-size: 0.875rem;
  font-weight: 400;
}

.agenda-empty {
  margin: 0;
  padding: 1.5rem;
  border: 1px dashed var(--line);
  border-radius: var(--sp-radius);
  color: var(--text-muted);
  text-align: center;
}

.event-archive {
  margin-top: 1.5rem;
  border-top: 1px solid var(--line);
  padding-top: 1rem;
}

.event-archive summary {
  cursor: pointer;
  padding: 0.4rem 0;
  color: var(--text-muted);
  font-weight: 600;
}

.event-archive summary:hover {
  color: var(--text);
}

.event-archive[open] summary {
  margin-bottom: 0.75rem;
}

/* ---------- feature panel ------------------------------------------------- */

/* The selected agenda item on the homepage, and anything else that needs to
   sit visibly above the section it is in. */
.panel {
  padding: clamp(1.5rem, 1rem + 2vw, 2.5rem);
  border: 1px solid var(--line);
  border-radius: var(--sp-radius-lg);
  background-color: var(--surface);
}

.panel__date {
  display: inline-block;
  margin-bottom: 0.75rem;
  color: var(--accent);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

.panel__title {
  margin-bottom: 1.25rem;
}

/* ---------- committees ---------------------------------------------------- */

.committee-list {
  display: flex;
  flex-direction: column;
}

.committee {
  padding: 1rem 0;
}

.committee + .committee {
  border-top: 1px solid var(--line);
}

.committee-name {
  margin-bottom: 0.15rem;
  font-weight: 700;
}

.committee-people {
  margin-bottom: 0;
  color: var(--text-muted);
}

@media (min-width: 768px) {
  .committee {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    gap: 1.5rem;
    align-items: baseline;
  }

  .committee-people {
    text-align: right;
  }
}

/* ---------- gallery ------------------------------------------------------- */

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 11rem), 1fr));
  gap: 0.75rem;
}

.gallery-grid a {
  display: block;
  border-radius: var(--sp-radius);
  overflow: hidden;
  transition: transform var(--sp-transition), box-shadow var(--sp-transition);
}

.gallery-grid a:hover,
.gallery-grid a:focus-visible {
  transform: translateY(-3px);
  box-shadow: var(--sp-shadow-lifted);
}

.gallery-grid img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  aspect-ratio: 1;
}

/* ---------- search -------------------------------------------------------- */

.search-form {
  display: flex;
  gap: 0.75rem;
  max-width: 32rem;
  margin-bottom: 2.5rem;
}

.search-form input[type="search"],
.search-form input[type="text"] {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.7rem 1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background-color: var(--surface);
  color: var(--text);
  font: inherit;
}

.search-form input:focus-visible {
  outline-color: var(--accent);
}

.search-results {
  list-style: none;
  padding-left: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.search-results a {
  display: block;
  padding: 1rem 1.15rem;
  border: 1px solid var(--line);
  border-radius: var(--sp-radius);
  text-decoration: none;
  transition: background-color var(--sp-transition), transform var(--sp-transition);
}

.search-results a:hover,
.search-results a:focus-visible {
  background-color: var(--surface-hover);
  transform: translateX(2px);
}

.search-results h2 {
  margin-bottom: 0.2rem;
  font-size: 1.0625rem;
}

.search-results p {
  margin-bottom: 0;
  color: var(--text-muted);
  font-size: 0.9375rem;
}

.pagination-sp {
  display: flex;
  gap: 0.75rem;
  margin-top: 2rem;
}

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

.site-footer {
  background-color: var(--sp-ink);
  color: #fff;
  padding-block: clamp(2.5rem, 2rem + 2vw, 4rem) 1.5rem;
  --text-muted: #c9c6cf;
  --line: rgba(255, 255, 255, .16);
}

.site-footer__brand .logo {
  height: 54px;
  margin-bottom: 1rem;
}

.site-footer h2 {
  margin-bottom: 0.9rem;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.site-footer address,
.site-footer p {
  color: var(--text-muted);
}

.site-footer address {
  font-style: normal;
  margin-bottom: 0;
}

.site-footer ul {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.site-footer a {
  color: #fff;
  text-decoration: none;
  text-underline-offset: 0.2em;
}

.site-footer a:hover,
.site-footer a:focus-visible {
  color: #fff;
  text-decoration: underline;
}

.site-footer__meta {
  border-top: 1px solid var(--line);
  margin-top: clamp(2rem, 1.5rem + 1.5vw, 3rem);
  padding-top: 1.25rem;
  font-size: 0.875rem;
}

.site-footer__meta p {
  margin-bottom: 0;
}

/* The brand mark again, closing the page as it opened it. */
.site-footer .brand-mark {
  margin-bottom: 1.25rem;
}

/* ---------- in-page detail swap ------------------------------------------ */

/* The region detail-swap.js replaces. It is focused after a swap so the change
   is announced, but it is a container rather than a control -- the focus ring
   belongs on whatever is inside it. */
[data-swap-target]:focus {
  outline: none;
}

[data-swap-target] {
  transition: opacity var(--sp-transition);
}

/* Dimmed only while the replacement is in flight. On a fast connection this
   never becomes visible, which is the intent -- it is there so a slow one does
   not look like the click did nothing. */
[data-swap-target][aria-busy="true"] {
  opacity: 0.45;
}

/* The selected card, so the list still shows which panel is open. */
.tile[aria-current="true"] {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}

/* ---------- misc ---------------------------------------------------------- */

/* Keep in-page anchor targets clear of the sticky header. */
:target,
[id],
.anchor {
  scroll-margin-top: calc(var(--sp-nav-height) + 1.5rem);
}

.anchor {
  display: block;
  position: relative;
  visibility: hidden;
}

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