/* Self-hosted, so the display face does not depend on a roadside connection to
   Google Fonts. WOFF2 only — it is a third the size of the OTF it was built
   from, and every browser that can run this page reads it. Only the DemiBold
   cut is here; it is declared at 400 because that is the weight every display
   rule asks for, which keeps the browser from synthesising a bold on top. */
@font-face {
  font-family: "TT Modernoir";
  src: url("../fonts/tt-modernoir-demibold.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --field: #CADFC1;
  --field-opaque: #cadfc1f2;
  --field-deep: #B5CFAA;
  --field-soft: #D9E9D2;
  --ink: #17281B;
  --ink-dim: #4C6350;
  --devil: #C0305B;
  --devil-ink: #9B2247;
  --brass: #6F5316;
  --road: #2F4A36;
  --rule: rgba(23, 40, 27, .18);
  --facebook: #1877F2;

  --display: "TT Modernoir", "Copperplate", Georgia, serif;
  --text: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;

  --site-width: 1180px;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

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

body {
  margin: 0;
  background-color: var(--field);
  background-image: url("../img/latajace-diablice-bg.png"), url("../img/chain-pattern.png");
  background-position: right 80px, 0 0;
  background-size: 40vw auto, 120px 120px;
  background-repeat: no-repeat, repeat;
  background-blend-mode: normal, normal;
  color: var(--ink);
  font-family: var(--text);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--devil);
  text-decoration-color: var(--brass);
  text-underline-offset: 3px;
}

a:focus-visible,
button:focus-visible,
.row:focus-visible {
  outline: 3px solid var(--devil-ink);
  outline-offset: 3px;
}

main {
  max-width: var(--site-width);
  margin: 0 auto;
  padding: 0 24px 80px;
}

/* --- rider banner --------------------------------------------------------- */

.rider {
  padding: 20px 24px 10px 24px;
  background: var(--field-opaque);
  border-bottom: 1px dashed var(--rule);
  position: sticky;
  top: 0;
  z-index: 1500;
}

.rider > div {
  display: flex;
  align-items: center;
  gap: 18px;
  max-width: var(--site-width);
  margin-inline: auto;
}

/* At the top of the page the banner sits directly on the artwork with no field
   and no rule; it only lays down a solid sheet once you have scrolled past it.
   Where scroll-driven animations are unsupported the rules above stand, so the
   banner is simply always solid. */
@supports (animation-timeline: scroll()) {
  .rider {
    background: transparent;
    border-bottom-color: transparent;
    animation: rider-settle linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 64px;
  }

  @keyframes rider-settle {
    to {
      background: var(--field);
      border-bottom-color: var(--rule);
    }
  }
}

.rider__portrait {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center 28%;
  flex: none;
}

.rider__id {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
  min-width: 0;
}

.rider__name {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(16px, 2.6vw, 24px);
  letter-spacing: .01em;
  display: flex;
  gap: .6ch;
  align-items: center;
}

.rider__alias {
  margin: 3px 0 0;
  font-size: clamp(12px, 2vw, 15px);
  color: var(--devil);
}

/* The mark carries its own disc and its own white glyph, so the link draws
   nothing: no ring, no plate. Blue, not raspberry — the CTA next to it owns the
   loud colour, and two raspberry blobs in one banner would split the eye. */
.rider__fb {
  flex: none;
  display: grid;
  place-items: center;
  /* Sized in em, so it rides the name's clamp instead of holding one pixel
     size while the type beside it shrinks. */
  width: .9em;
  height: .9em;
  color: var(--facebook);
  text-decoration: none;
  transition: opacity .12s ease;
}

.rider__fb svg {
  display: block;
  width: 100%;
  height: 100%;
}

.rider__fb:hover {
  opacity: .75;
}

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

.rider__cta {
  margin-left: auto;
  flex: none;
  padding: 11px 20px;
  background: var(--devil);
  color: #fff;
  font-weight: 700;
  text-decoration: none;
  border-radius: 2px;
  transition: transform .12s ease, background .12s ease;
}

.rider__cta:hover {
  background: #a8264c;
  transform: translateY(-1px);
}

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

/* --- road section --------------------------------------------------------- */

.road__head {
  padding: 44px 0 26px;
  max-width: min(64ch, 50vw);
}

h1 {
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(30px, 6.2vw, 64px);
  line-height: 1.05;
  letter-spacing: .005em;
}

.h1__arrow {
  font-family: var(--text);
  font-weight: 400;
  color: var(--devil);
}

/* --- intro (the fundraiser's own copy, three lines until asked) ------------ */

.intro {
  margin: 20px 0 0;
}

/* The whole text is always in the markup; collapsing is the box being short and
   clipping it, never the children being hidden. That is what lets the fold
   animate at all — app.js measures the two heights and glides between them. */
.intro__text {
  color: var(--ink-dim);
  overflow: hidden;
}

.intro__text p,
.intro__text ul {
  margin: 0 0 1em;
}

.intro__text ul {
  padding-left: 1.15em;
}

.intro__text li {
  margin: 0 0 .3em;
}

.intro__h {
  margin: 1.6em 0 .5em;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(17px, 2.4vw, 22px);
  line-height: 1.25;
  letter-spacing: .01em;
  color: var(--ink);
}

/* Collapsed: six lines of the opening paragraph, fading out at the cut so it
   reads as "there is more" rather than as a paragraph that simply stops. */
.intro:not(.is-open) .intro__text {
  height: 9.3em;  /* 6 lines at the inherited 1.55 line-height */
  -webkit-mask-image: linear-gradient(to bottom, #000 64%, transparent);
  mask-image: linear-gradient(to bottom, #000 64%, transparent);
}

.intro.is-open .intro__text > :last-child {
  margin-bottom: 0;
}

.intro__fig {
  margin: 1.7em 0;
}

.intro__fig img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--rule);
  border-radius: 2px;
}

.intro__more {
  margin: 10px 0 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-weight: 600;
  color: var(--devil);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  cursor: pointer;
}

.intro__more:hover {
  color: var(--devil-ink);
}

/* --- tally ---------------------------------------------------------------- */

.tally {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 48px;
  margin: 30px 0 0;
}

.tally dt {
  font-size: 13px;
  color: var(--ink-dim);
}

.tally dd {
  margin: 4px 0 0;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(22px, 3.4vw, 34px);
  line-height: 1;
  letter-spacing: .01em;
  color: var(--devil);
}

/* Only the sponsored figure is loud; the goal it is measured against is ink. */
.tally__goal {
  color: var(--ink);
}

#map {
  height: min(50vh, 620px);
  min-height: 380px;
  background: var(--field-deep);
  border: 1px solid var(--rule);
}

/* Muted, greened-off tiles so the sponsored road is the only loud thing. */
.leaflet-tile-pane {
  filter: saturate(.3) sepia(.3) hue-rotate(48deg) brightness(1.04) contrast(.9);
}

.leaflet-container {
  background: var(--field-deep);
  font-family: var(--text);
}

.leaflet-control-attribution {
  background: rgba(217, 233, 210, .86) !important;
  color: var(--ink-dim) !important;
}

.leaflet-control-attribution a {
  color: var(--ink-dim) !important;
}

/* Handover ticks. The icon box is only a hinge: the bar inside carries the
   rotation, since Leaflet owns the box's own transform for positioning. */
.km-tick {
  display: flex;
  align-items: center;
  justify-content: center;
}

.km-tick i {
  width: 2px;
  height: 13px;
  background: var(--ink);
}

.leaflet-tooltip.seg-tip {
  background: var(--field-soft);
  border: 1px solid var(--ink);
  color: var(--ink);
  box-shadow: none;
  font-size: 14px;
  padding: 7px 10px;
  border-radius: 2px;
}

.leaflet-tooltip.seg-tip::before {
  display: none;
}

.seg-tip b {
  font-family: var(--display);
  font-weight: 400;
  font-size: 15px;
  letter-spacing: .01em;
}

.seg-tip span {
  color: var(--devil-ink);
  font-variant-numeric: tabular-nums;
}

/* --- ledger --------------------------------------------------------------- */

.ledger {
  padding-top: max(35px, 4vw);
}

.ledger h2 {
  margin: 0 0 20px 0;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(24px, 4.2vw, 40px);
  line-height: 1.05;
  letter-spacing: .01em;
  text-align: center;
}

/* The dashed red rule down the left is the road again, stood on its end — and
   roads bend, so it weaves. One 64px period of the wave tiles down the list;
   pathLength='64' makes the dashes divide the period exactly, so tiles join
   without a stutter. The stroke cannot read a custom property inside a data
   URI: keep it in step with --devil by hand. */
.ledger__list {
  list-style: none;
  margin: 0;
  padding: 0 0 0 26px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='64' viewBox='0 0 14 64' preserveAspectRatio='none'%3E%3Cpath d='M7 0 C12 10.7 12 21.3 7 32 C2 42.7 2 53.3 7 64' fill='none' stroke='%23C0305B' stroke-width='2' pathLength='64' stroke-dasharray='8 8'/%3E%3C/svg%3E");
  background-repeat: repeat-y;
  background-position: left top;
  background-size: 14px 64px;
  max-width: 750px;
  margin-inline: auto;
}

.row {
  display: grid;
  grid-template-columns: minmax(6ch, 16%) 1fr auto;
  align-items: center;
  gap: 20px;
  padding: 1ch;
  border-top: 1px dashed var(--rule);
  transition: background .12s ease;
}

.row:last-child {
  border-bottom: 1px dashed var(--rule);
}

.row.is-active {
  background: rgba(255, 255, 255, 0.23);
}

.row:focus-visible {
  outline-offset: -3px;
}

/* Past the finish line: on the list, but with nothing on the map to point at. */
.row:not(.row--overflow) {
  cursor: pointer;
}

.row--overflow .row__amount {
  color: var(--devil-ink);
}

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

/* Flush right in its column: the column keeps every name starting on the same
   line down the list, while the figure leans across the gutter so that amount
   and name read as one pair rather than two columns with a hole between. */
.row__amount {
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  line-height: .95;
  letter-spacing: .005em;
  color: var(--devil);
  /* One size for every tier. Keep the figure and its currency on one line and
     let the clamp ease it down on narrow screens. */
  font-size: clamp(26px, 3vw, 34px);
  white-space: nowrap;
}

.row__amount sup {
  font-size: max(10px, .6em);
  margin-left: .3em;
  top: -.9em;
}

.row__body {
  min-width: 0;
}

.row__name {
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(21px, 2.5vw, 28px);
  letter-spacing: .01em;
  line-height: 1.15;
}

.row__meta {
  margin: 0;
  text-align: right;
  font-size: 13px;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.row__stretch {
  display: block;
}

.row__hand {
  display: block;
}

.row__over {
  display: block;
  color: var(--devil-ink);
  font-weight: 600;
}

/* Height tiers: a donation's weight on the road is its weight on the page.
   Type is one size everywhere now, so height alone carries the ladder — the
   floors start above the natural height of a row's content. */
/* .row[data-tier="1"] {
  min-height: 60px;
}

.row[data-tier="2"] {
  min-height: 80px;
} */

.row[data-tier="3"] {
  min-height: 110px;
}

.row[data-tier="4"] {
  min-height: 156px;
}

.row[data-tier="5"] {
  min-height: 210px;
}

.row[data-tier="6"] {
  min-height: max(26vh, 280px);
}

/* --- foot ----------------------------------------------------------------- */

.foot {
  /* border-top: 1px dashed var(--rule); */
  padding: 26px 24px 40px;
  max-width: 1180px;
  margin: 0 auto;
  color: var(--ink-dim);
  font-size: 14px;
  text-align: center;
}

.foot p {
  margin: 4px 0;
}

.foot__stamp {
  opacity: .75;
  font-size: 13px;
}

/* --- narrow screens ------------------------------------------------------- */

@media (max-width: 640px) {
  body {
    font-size: 16px;
  }

  main {
    padding: 0 16px 56px;
  }

  .rider {
    padding: 8px 16px;
    gap: 12px;
  }

  .rider__portrait {
    width: 48px;
    height: 48px;
  }

  .rider__cta {
    padding: 7px 12px;
    font-size: 13px;
    line-height: 1.2;
    max-width: 10.5em;
    text-align: center;
  }

  .road__head {
    padding: 30px 0 20px;
  }

  .ledger__list {
    padding-left: 18px;
  }

  /* Two columns, one band: amount and name stack together on the left, meta
     sits on the right. The left pair is two tracks so the figure and the name
     stay tight, but align-content centres the whole block in a tall row, and
     the meta spans both tracks so it centres against the pair as a whole. */
  .row {
    grid-template-columns: 1fr auto;
    grid-template-rows: auto auto;
    gap: .4ch 14px;
    align-items: start;
    align-content: center;
  }

  .row__amount {
    grid-column: 1;
    grid-row: 1;
  }

  .row__body {
    grid-column: 1;
    grid-row: 2;
  }

  .row__meta {
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: center;
    text-align: right;
  }

  .row[data-tier="6"] {
    min-height: 40vh;
  }
}

@media (max-width: 400px) {
  .rider__alias {
    display: none;
  }
}