/* Ship for Good.
   The system is documented in DESIGN.md. A calm, centred dark interface with one
   piece of loud artwork behind it: the Earth. */

/* ------------------------------------------------------------------ fonts -- */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/archivo.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212;
}

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

:root {
  --void: #f2f6fc;
  --surface: #ffffff;
  --surface-2: #eef3fa;
  --surface-3: #dfe8f4;
  --line: #d5dfee;
  --line-bright: #adbdd6;
  --sep: #7d90ad;

  /* Money. One accent, used for nothing else. */
  /* TWO oranges, and the split is load-bearing.
     --coin is the vivid fill: buttons, the rank-1 badge, the wordmark plate.
     --coin-ink is for orange TEXT. The brand orange measures 2.58:1 on white,
     so every price and link on this page would have failed outright. Anything
     that sets `color:` uses --coin-ink; anything that sets `background:` uses
     --coin. Do not collapse them back into one. */
  --coin: #f4622c;
  --coin-ink: #b03c0b;
  --coin-bright: #d94d15;
  --on-coin: #1a0d06;
  /* Gold is RANK, orange is MONEY. Keeping them separate means first place can be
     as loud as it likes without the page having two competing ideas of what an
     orange thing means. */
  --gold: #e8b23c;
  --gold-light: #ffd97a;
  --gold-deep: #b8860d;
  /* Dark enough to clear the DARKEST stop of the badge gradient (4.48:1 at
     #b8860d would have been a hair under), not just the mid-tone the text
     happens to sit on. A sweep cannot check this: it reads background-color,
     and the badge's colour comes from a background-image. */
  --on-gold: #2a1a04;

  --coin-tint: rgba(244, 98, 44, 0.10);
  --coin-edge: rgba(244, 98, 44, 0.45);

  --alive: #15803d;
  --warn: #dc2626;

  /* Sampled from the globe artwork so the interface and the Earth agree. */
  /* Sampled straight from the artwork so chrome and Earth agree. */
  --sea: #3fa4e0;
  --sea-lit: #7dd2f5;
  --land: #74cb6d;
  --sand: #efcd88;

  --ink: #14223c;
  --ink-dim: #3b4a68;
  --ink-faint: #56647d;

  --body: 'Archivo', ui-sans-serif, system-ui, sans-serif;

  /* How loud the Earth is. One knob — turn it down to 0.25 for a whisper, up to
     0.6 to make it the loudest thing on the page. */
  --world-strength: 0.55;

  --r: 14px;
  --r-sm: 10px;
  --page: 900px;
  --shadow: 0 1px 2px rgba(20, 34, 60, 0.06), 0 2px 8px rgba(20, 34, 60, 0.05);
  --shadow-lift: 0 10px 30px rgba(20, 34, 60, 0.13);
}

/* ------------------------------------------------------------------ reset -- */

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

html {
  -webkit-text-size-adjust: 100%;
  scrollbar-color: var(--line-bright) var(--void);
}

body {
  margin: 0;
  background: var(--void);
  color: var(--ink);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.55;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

a {
  color: var(--coin-ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: rgba(184, 64, 12, 0.4);
}
a:hover {
  text-decoration-color: var(--coin-ink);
}

button {
  font: inherit;
  color: inherit;
}

/* ------------------------------------------- surfaces the browser owns -- */

::selection {
  background: var(--coin);
  color: var(--on-coin);
}

:focus-visible {
  outline: 2px solid var(--coin);
  outline-offset: 2px;
  border-radius: 4px;
}

::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}
::-webkit-scrollbar-track {
  background: var(--void);
}
::-webkit-scrollbar-thumb {
  background: var(--line-bright);
  border: 3px solid var(--void);
  border-radius: 8px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--coin);
}

::marker {
  color: var(--coin-ink);
}

input,
textarea,
select {
  caret-color: var(--coin-ink);
}

/* ------------------------------------------------------------- the world -- */

/*
 * The Earth sits behind the ranking column and reaches out past it on both sides.
 * Fixed, so it stays put while the board scrolls over it — the board is the thing
 * that moves, the world is the thing that does not.
 */
.world {
  position: fixed;
  top: 96px;
  left: 50%;
  width: min(1300px, 148vw);
  aspect-ratio: 1;
  transform: translateX(-50%);
  z-index: 0;
  pointer-events: none;
  opacity: var(--world-strength);
  /* Fade the rim so the sphere does not end on a hard circle against the page. */
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 58%, rgba(0, 0, 0, 0.55) 78%, transparent 92%);
  mask-image: radial-gradient(circle at 50% 50%, #000 58%, rgba(0, 0, 0, 0.55) 78%, transparent 92%);
}

.world img {
  width: 100%;
  height: 100%;
  image-rendering: pixelated;
}

/* Everything else rides above it. */
.hud,
main,
.footer {
  position: relative;
  z-index: 1;
}

/* --------------------------------------------------------------- top bar -- */

.hud {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(242, 246, 252, 0.86);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}

.hud__inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 7px 24px;
  display: flex;
  align-items: center;
  gap: 16px;
}

.hud__mark {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 15.5px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--coin-ink);
  text-decoration: none;
  flex: 0 0 auto;
}

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

.tabs {
  display: flex;
  gap: 2px;
  padding: 3px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  flex: 0 0 auto;
}

.tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 15px;
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-dim);
  text-decoration: none;
  white-space: nowrap;
  transition: background 140ms ease, color 140ms ease;
}
.tab:hover {
  color: var(--ink);
  background: var(--surface-2);
}
.tab[aria-current='page'] {
  background: var(--surface-3);
  color: var(--ink);
}
.tab__count {
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

.hud__nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 2px;
}
.hud__nav a {
  position: relative;
  padding: 9px 12px;
  font-size: 14px;
  color: var(--ink-dim);
  text-decoration: none;
  transition: color 140ms ease;
}
.hud__nav a:hover {
  color: var(--ink);
}
/* The current page is marked by a rule under the label rather than a filled
   pill. A pill in a bar this short reads as a button and competes with the
   claim button below it. */
.hud__nav a[aria-current='page'] {
  color: var(--ink);
  font-weight: 600;
}
.hud__nav a[aria-current='page']::after {
  content: '';
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 2px;
  height: 2px;
  border-radius: 2px;
  background: var(--coin);
}
/* Separates the two board views from the rest without drawing a divider. */
.hud__gap {
  width: 18px;
}

/* ------------------------------------------------------------ live strip -- */

.live {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0 auto;
  padding: 7px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 13.5px;
  color: var(--ink-dim);
}
.live b {
  color: var(--ink);
  font-weight: 600;
}
.live a {
  color: var(--ink-dim);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.live a:hover {
  color: var(--coin-ink);
}
.live__sep {
  color: var(--sep);
}

.blip {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--alive);
  flex: 0 0 auto;
  box-shadow: 0 0 0 3px rgba(21, 128, 61, 0.15);
}
@media (prefers-reduced-motion: no-preference) {
  .blip {
    animation: blip 2.4s ease-in-out infinite;
  }
}
@keyframes blip {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* A number we could not read says so. It never falls back to zero. */
.unknown {
  color: var(--ink-faint);
}

/* ------------------------------------------------------------------ shell -- */

.wrap {
  max-width: var(--page);
  margin: 0 auto;
  padding: 0 20px;
}
.wrap--wide {
  max-width: 1180px;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  position: fixed;
  left: 16px;
  top: 16px;
  z-index: 100;
  background: var(--coin);
  color: var(--on-coin);
  padding: 12px 20px;
  border-radius: var(--r-sm);
  font-weight: 600;
}

/* ------------------------------------------------------------------- bid -- */

/* The bid page was a 640px stack of full-width fields inside an 860px card, with
   a dead column down the right and every short field eating a whole row. It is a
   single decision — how much, and for what — so it gets a single narrow column. */
.bid {
  max-width: 620px;
}
.bid__title {
  text-align: center;
  font-size: clamp(28px, 4.4vw, 40px);
}
.bid__lede {
  text-align: center;
  margin: 12px auto 0;
  font-size: 15.5px;
}
.panel--form {
  margin-top: 22px;
  padding: 24px 24px 26px;
}
.panel--form .field + .field,
.panel--form .field-row + .field,
.panel--form .field + .field-row {
  margin-top: 16px;
}
/* Two short fields share a row rather than each taking one. */
.field-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 14px;
  align-items: start;
}
/* The stack rule above is a sibling selector, so it also fired on the SECOND
   field inside this row and pushed it 16px lower than the first. Inside a row
   the grid gap is the spacing; the sibling margin has to be cancelled. */
.field-row .field + .field {
  margin-top: 0;
}
.panel--form .input {
  height: 44px;
}
.panel--form .field__hint {
  margin-top: 5px;
  font-size: 12px;
}
.btn--block {
  display: block;
  width: 100%;
  text-align: center;
}
@media (max-width: 560px) {
  .field-row {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}

/* ------------------------------------------------------------------- vote -- */

.vote {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 18px 20px 20px;
  margin-bottom: 14px;
}
.vote__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 16px;
  margin-bottom: 14px;
}
.vote__title {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
}
.vote__meta {
  margin: 0;
  font-size: 12.5px;
  color: var(--ink-faint);
}
.vote__opts {
  display: grid;
  gap: 8px;
}

/* Each option is a button with a fill behind it showing the running share. The
   fill is a positioned span rather than a background gradient so the width can
   be a plain percentage and the text never sits on a moving colour edge. */
.vote__opt {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  text-align: left;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  overflow: hidden;
  transition: border-color 140ms ease, background 140ms ease;
}
.vote__opt:hover {
  border-color: var(--coin-edge);
}
/* No transition on the width. The bar is server-rendered at its final size, so
   there is nothing to animate from, and DESIGN.md allows exactly one authored
   moment on this site — the world arriving. Animating width would also be layout
   thrash for a value that never changes after paint. */
.vote__bar {
  position: absolute;
  inset: 0 auto 0 0;
  background: var(--coin-tint);
}
.vote__body {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
}
.vote__name {
  display: block;
  font-weight: 600;
  font-size: 14.5px;
}
.vote__blurb {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--ink-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vote__count {
  position: relative;
  flex: 0 0 auto;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.vote__count b {
  display: block;
  font-size: 15px;
  color: var(--coin-ink);
}
.vote__count span {
  display: block;
  font-size: 11.5px;
  color: var(--ink-faint);
}

/* After voting. The buttons stay legible - they are still the result - they
   simply stop being pressable. */
.vote--done .vote__opt {
  cursor: default;
  pointer-events: none;
}
.vote--done .vote__opt[data-mine] {
  border-color: var(--coin);
  background: var(--coin-tint);
}
.vote--done .vote__done {
  display: block;
}
.vote__done {
  margin: 12px 0 0;
  font-size: 12.5px;
  color: var(--alive);
  font-weight: 600;
}

@media (max-width: 560px) {
  .vote__blurb {
    display: none;
  }
}

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

.hero {
  text-align: center;
  padding: 28px 0 8px;
}

.hero__title {
  font-size: clamp(30px, 5.4vw, 52px);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin: 20px 0 0;
  text-wrap: balance;
}
.hero__title em {
  font-style: normal;
  color: var(--coin-ink);
}

.hero__lede {
  font-size: 16.5px;
  line-height: 1.6;
  color: var(--ink-dim);
  max-width: 56ch;
  margin: 14px auto 0;
}
.hero__lede strong {
  color: var(--ink);
  font-weight: 600;
}

/* The charity's name, everywhere it is said. It is the answer to "where does my
   money go", so it always carries the money colour. --coin-ink, not --coin: this
   is text, and the fill orange is 2.58:1 on white.

   The selectors are listed rather than left as a bare `.charity`, because every
   context here already styles its own descendants — `.hero__lede strong` and
   `.prose strong` are both 0,1,1 and a lone class is 0,1,0. Twice today a bare
   class silently lost that fight and did nothing at all. */
.charity,
.hero__lede .charity,
.prose .charity,
.cause .charity,
.empty .charity,
.footer .charity,
.notice .charity {
  color: var(--coin-ink);
  font-weight: 700;
}


/* The claim price, with steppers, exactly where the eye lands first. */
.claim {
  white-space: nowrap;
}

.claim__amount {
  /* inline-block, not inline: min-width does nothing on a non-replaced inline
     box, and without it the heading reflows every time a digit is added. An
     inline-block still takes its baseline from its own text, so the amount stays
     on the heading's baseline. */
  display: inline-block;
  font: inherit;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--coin-ink);
  font-variant-numeric: tabular-nums;
  min-width: 4ch;
  text-align: center;
}

.step {
  width: 34px;
  height: 34px;
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--line-bright);
  color: var(--ink);
  box-shadow: var(--shadow);
  cursor: pointer;
  padding: 0;
  margin: 0 6px;
  vertical-align: middle;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.step:hover {
  background: var(--coin);
  border-color: var(--coin);
  color: var(--on-coin);
}
/* Disabled keeps the same white circle as the live one, so the control is
   plainly THERE; only the glyph is muted. Recessing the surface too made it
   read as a smudge on the page rather than as a button you cannot press yet. */
.step:disabled {
  color: var(--ink-faint);
  background: var(--surface);
  border-color: var(--line-bright);
  box-shadow: none;
  cursor: not-allowed;
}
.step:disabled:hover {
  background: var(--surface);
  border-color: var(--line-bright);
  color: var(--ink-faint);
}

/* ------------------------------------------------------------- claim form -- */

.claimbar {
  display: flex;
  gap: 10px;
  margin: 26px auto 0;
  max-width: 760px;
}
.claimbar .input,
.claimbar .select {
  margin: 0;
}
.claimbar .input {
  flex: 1 1 auto;
}
.claimbar .select {
  flex: 0 0 190px;
}
.claimbar .btn {
  flex: 0 0 auto;
}

/* ------------------------------------------------------------------ chips -- */

.chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin: 22px 0 30px;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ink-dim);
  font-size: 13.5px;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.chip:hover {
  color: var(--ink);
  border-color: var(--line-bright);
}
.chip[aria-pressed='true'],
.chip[aria-current='page'] {
  background: var(--coin);
  border-color: var(--coin);
  color: var(--on-coin);
}
.chip svg {
  opacity: 0.8;
}

/* ------------------------------------------------------------------ board -- */

.board {
  list-style: none;
  margin: 0 0 32px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.card {
  display: grid;
  grid-template-columns: 44px 52px minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
  padding: 16px 20px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  transition: border-color 160ms ease, background 160ms ease, transform 160ms ease;
}
.card:hover {
  background: var(--surface-2);
  border-color: var(--line-bright);
}

/* Rank 1 is the thing being bought. It gets the accent and nothing else does. */
/* Opaque base, tint layered ON it. Setting `background` to a translucent gradient
   replaced the surface colour entirely, so the top card was see-through and its text
   sat on whatever the globe was doing underneath — the brighter Earth made it
   obvious. Contrast checks miss this: they walk up to the nearest opaque ancestor. */
/* This caption is about the globe, so it deliberately sits ON the globe with no
   surface under it — which means --ink-faint cannot carry it. Over deep ocean it
   measured 2.65:1. Text with the artwork as its only background needs --ink-dim,
   which clears the worst pixel (ocean AND ice) with room to spare. */
.field__hint.hint--onworld,
.hint--onworld {
  color: var(--ink-dim);
}

/* First place, and it should look like it. Opaque base with the gold layered on
   top — a translucent `background` shorthand would replace the surface and put
   the globe back through the row. */
.card--first {
  background-color: var(--surface);
  background-image: linear-gradient(180deg, rgba(232, 178, 60, 0.20), rgba(232, 178, 60, 0.05));
  border-color: rgba(184, 134, 13, 0.45);
  box-shadow: 0 1px 2px rgba(20, 34, 60, 0.06), 0 6px 20px rgba(184, 134, 13, 0.16);
}
.card--first:hover {
  border-color: var(--gold-deep);
  box-shadow: 0 1px 2px rgba(20, 34, 60, 0.06), 0 8px 26px rgba(184, 134, 13, 0.26);
}

.card__rank {
  display: inline-grid;
  place-items: center;
  min-width: 38px;
  height: 26px;
  padding: 0 8px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  font-size: 11.5px;
  font-weight: 700;
  color: var(--ink-dim);
}
/* The badge is the one place the gold is allowed to be a gradient: a metal reads
   as metal because it has a light edge and a dark one. The inset highlight is
   what does that, not the gradient on its own. */
.card--first .card__rank {
  background-image: linear-gradient(180deg, var(--gold-light) 0%, var(--gold) 46%, var(--gold-deep) 100%);
  border-color: var(--gold-deep);
  color: var(--on-gold);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), 0 1px 3px rgba(184, 134, 13, 0.4);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.35);
}

.card__logo {
  width: 44px;
  height: 44px;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  border: 1px solid var(--line);
  object-fit: contain;
  padding: 6px;
}

.card__main {
  min-width: 0;
}

.card__name {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink);
}
.card__name a {
  color: inherit;
  text-decoration: none;
}
.card__name a:hover {
  color: var(--coin-ink);
}

.card__desc {
  margin: 4px 0 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-dim);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card__meta {
  margin: 8px 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  font-size: 12.5px;
  color: var(--ink-faint);
}
.card__meta span {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.card__meta svg {
  opacity: 0.75;
}
.card__meta a {
  color: var(--ink-faint);
  text-decoration: none;
}
.card__meta a:hover {
  color: var(--coin-ink);
}
.card__dot {
  color: var(--sep);
}

.card__right {
  text-align: right;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}

.card__amount {
  font-size: 19px;
  font-weight: 700;
  color: var(--coin-ink);
  white-space: nowrap;
  letter-spacing: -0.02em;
}
.card--first .card__amount {
  font-size: 23px;
}

.card__cta {
  opacity: 0;
  transition: opacity 140ms ease;
}
.card:hover .card__cta,
.card:focus-within .card__cta {
  opacity: 1;
}
@media (hover: none) {
  .card__cta {
    opacity: 1;
  }
}

/* ----------------------------------------------------------------- strips -- */

.section {
  margin: 36px 0;
}

.section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}

.section__title {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  margin: 0;
}

.section__more {
  font-size: 13.5px;
  color: var(--ink-dim);
  text-decoration: none;
}
.section__more:hover {
  color: var(--coin-ink);
}

.strip {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(210px, 1fr);
  gap: 10px;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: thin;
}

.strip__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 13px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  text-decoration: none;
  min-width: 0;
}
.strip__item:hover {
  border-color: var(--line-bright);
}
.strip__logo {
  width: 30px;
  height: 30px;
  border-radius: 7px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  object-fit: contain;
  padding: 4px;
  flex: 0 0 auto;
}
.strip__body {
  min-width: 0;
}
.strip__name {
  margin: 0;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.strip__meta {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--ink-faint);
  white-space: nowrap;
}
.strip__meta b {
  color: var(--coin-ink);
  font-weight: 600;
}

/* ------------------------------------------------------------------ cause -- */

/* Deliberately the smallest card on the page. It states a fact; the board is
   what people came for, and this used to be almost as tall as a listing row. */
.cause {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 11px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  margin: 0 0 16px;
}

.cause__logo {
  width: 46px;
  height: 46px;
  flex: 0 0 auto;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  border: 1px solid var(--line);
  object-fit: contain;
  padding: 5px;
}

.cause__body {
  flex: 1 1 auto;
  min-width: 0;
}

.cause__who {
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 1px;
  font-weight: 600;
}

.cause__name {
  font-size: 15px;
  font-weight: 700;
  margin: 0 0 3px;
  /* Same rule as everywhere else the charity is named: it carries the money
     colour. Edited here rather than overridden earlier in the file, because this
     rule is the later one and would have won. */
  color: var(--coin-ink);
  line-height: 1.3;
}

.cause__blurb {
  margin: 0;
  color: var(--ink-dim);
  font-size: 13px;
  line-height: 1.45;
}

.cause__clock {
  flex: 0 0 auto;
  text-align: right;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}
.cause__clock span {
  display: block;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--ink-faint);
  margin-bottom: 2px;
}

.cause--missing {
  border-color: var(--warn);
  background: rgba(220, 38, 38, 0.06);
}
.cause--missing .cause__name {
  color: var(--warn);
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 14.5px;
  font-weight: 600;
  padding: 13px 20px;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--ink);
  border: 1px solid var(--line-bright);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background 140ms ease, border-color 140ms ease, transform 90ms ease;
}
.btn:hover {
  background: var(--surface-3);
  color: var(--ink);
}
.btn:active {
  transform: translateY(1px);
}

.btn--coin {
  background: var(--coin);
  color: var(--on-coin);
  border-color: var(--coin);
}
.btn--coin:hover {
  background: var(--coin-bright);
  color: var(--on-coin);
}

.btn--small {
  padding: 8px 13px;
  font-size: 13px;
}

.btn--ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--ink-dim);
}
.btn--ghost:hover {
  border-color: var(--line-bright);
  color: var(--ink);
  background: var(--surface);
}

.btn[disabled],
.btn[aria-disabled='true'] {
  opacity: 0.45;
  cursor: not-allowed;
}

/* ------------------------------------------------------------------ forms -- */

.form {
  max-width: 640px;
}

.field {
  margin-bottom: 22px;
}

.field__label {
  display: block;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 7px;
}

.field__hint {
  margin: 7px 0 0;
  font-size: 13px;
  color: var(--ink-faint);
  line-height: 1.5;
}

.input,
.select,
.textarea {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--ink);
  font-family: var(--body);
  font-size: 15.5px;
  padding: 13px 15px;
  appearance: none;
  transition: border-color 140ms ease, background 140ms ease;
}
.input::placeholder,
.textarea::placeholder {
  color: var(--ink-faint);
}
.input:hover,
.select:hover,
.textarea:hover {
  border-color: var(--line-bright);
}
.input:focus,
.select:focus,
.textarea:focus {
  border-color: var(--coin);
  outline: none;
  background: var(--surface-2);
}

.select {
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-faint) 50%),
    linear-gradient(135deg, var(--ink-faint) 50%, transparent 50%);
  background-position: calc(100% - 19px) 50%, calc(100% - 14px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 38px;
}

.input--money {
  font-size: 20px;
  font-weight: 700;
  padding-left: 34px;
}

.money-field {
  position: relative;
}
.money-field::before {
  content: '$';
  position: absolute;
  left: 15px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 19px;
  font-weight: 700;
  color: var(--coin-ink);
  pointer-events: none;
}

.error {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 0 0 22px;
  padding: 13px 16px;
  background: rgba(220, 38, 38, 0.07);
  border: 1px solid var(--warn);
  border-radius: var(--r-sm);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.5;
  text-align: left;
}
.error svg {
  flex: 0 0 auto;
  color: var(--warn);
  margin-top: 3px;
}

.amounts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}

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

.slab {
  padding: 44px 0;
  border-top: 1px solid var(--line);
  margin-top: 40px;
}

.prose {
  max-width: 68ch;
  color: var(--ink-dim);
  font-size: 16px;
  line-height: 1.7;
}
.prose p {
  margin: 0 0 18px;
}
.prose strong {
  color: var(--ink);
  font-weight: 600;
}
.prose h2 {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0 0 16px;
}
.prose h3 {
  font-size: 16.5px;
  font-weight: 600;
  color: var(--ink);
  margin: 32px 0 8px;
  line-height: 1.4;
}

/* ----------------------------------------------------------------- ticker -- */

/* The planet is the board's backdrop. On a form or a page of prose it is
   decoration competing with the words, and it was winning: text crossing the
   ship's dark hull measured 1.41:1. Everywhere that is not the board, the world
   drops to a whisper. */
body[data-quiet-world] {
  --world-strength: 0.16;
}

/* /how-it-works is a page of prose with no card to sit in, and left-aligned
   against a full-bleed globe it had nothing to anchor to. Centred, measured and
   given air, it reads as a document rather than as text floating on artwork. */
/* The headline stat. A listing is bought on the strength of how many people see
   it, so that number leads /stats and is the biggest thing on the page. */
.bignum {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: 24px;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 26px 28px;
  margin-bottom: 28px;
}
.bignum__val {
  display: block;
  font-size: clamp(40px, 7vw, 68px);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.bignum__key {
  display: block;
  margin-top: 8px;
  font-size: 14px;
  color: var(--ink-dim);
}
.bignum__side {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  border-left: 1px solid var(--line);
  padding-left: 24px;
}
.bignum__n {
  display: block;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.bignum__n--coin {
  color: var(--coin-ink);
}
.bignum__l {
  display: block;
  margin-top: 4px;
  font-size: 13px;
  color: var(--ink-faint);
}
@media (max-width: 760px) {
  .bignum {
    grid-template-columns: 1fr;
    gap: 20px;
  }
  .bignum__side {
    border-left: 0;
    border-top: 1px solid var(--line);
    padding-left: 0;
    padding-top: 18px;
  }
}

.prose--centred {
  max-width: 64ch;
  margin: 26px auto 0;
  text-align: center;
  padding: 30px 34px 34px;
}
/* The rules read as terms, so they are quieter than the explanation above them
   and left-aligned: centred prose is fine for six short paragraphs and wrong for
   a list of things you are not allowed to do. */
/* Chained to `.panel` (0,2,0) on purpose. `.panel` sets the background and is
   defined later in this file, so a lone `.prose--rules` at 0,1,0 loses on source
   order and the tint silently does nothing. That has now caught me three times
   today; when a rule is overriding a component, out-specify it rather than
   relying on where it happens to sit. */
.panel.prose--rules {
  text-align: left;
  margin-top: 18px;
  background: var(--surface-2);
}
.prose--rules p {
  margin-left: 0;
  margin-right: 0;
  font-size: 14px;
}
.prose--rules strong {
  color: var(--ink);
}
.prose--centred h3 {
  margin-top: 30px;
}
.prose--centred p {
  margin: 8px auto 0;
}

.panel--form {
  padding: 26px 28px 30px;
}
.panel--form .field:first-child {
  margin-top: 0;
}

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 20px;
}
.panel h2 {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 14px;
}

.ticker__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 11px;
}

.ticker__item {
  display: flex;
  gap: 12px;
  align-items: baseline;
  font-size: 14px;
  color: var(--ink-dim);
  line-height: 1.4;
}
.ticker__amount {
  font-weight: 700;
  color: var(--alive);
  flex: 0 0 auto;
  font-size: 14px;
}
.ticker__when {
  margin-left: auto;
  font-size: 12.5px;
  color: var(--ink-faint);
  flex: 0 0 auto;
}

/* ------------------------------------------------------------------ empty -- */

.empty {
  border: 1px dashed var(--line-bright);
  border-radius: var(--r);
  padding: 48px 24px;
  text-align: center;
  color: var(--ink-dim);
  background: rgba(255, 255, 255, 0.92);
}
.empty h3 {
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 8px;
}
.empty p {
  margin: 0 auto 22px;
  max-width: 46ch;
  line-height: 1.6;
}

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

.detail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 28px;
  align-items: start;
}

.readout {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.readout__item {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}
.readout__item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
.readout__key {
  font-size: 13.5px;
  color: var(--ink-dim);
}
.readout__val {
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
}
.readout__val--coin {
  color: var(--coin-ink);
}

/* ---------------------------------------------------------------- waiting -- */

.waiting {
  display: flex;
  gap: 14px;
  align-items: center;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
}
.waiting__dots {
  font-weight: 700;
  color: var(--coin-ink);
  font-size: 18px;
  width: 3ch;
}

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

.footer {
  border-top: 1px solid var(--line);
  padding: 20px 0 26px;
  margin-top: 56px;
  color: var(--ink-faint);
  font-size: 13px;
  line-height: 1.6;
  background: var(--void);
}
/* One line: the rail on the left, the nav on the right, both on the same
   baseline. It was two stacked paragraphs and a wrapping nav, which made the
   footer taller than the section above it. */
.footer__grid {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px 28px;
  justify-content: space-between;
}
/* Each statement is its own line so none of them breaks across two. "Ship for
   Good takes nothing" reading as "Ship for / Good takes nothing" was the whole
   complaint. */
.footer__rail {
  margin: 0;
  max-width: 60ch;
}
.footer__rail p {
  margin: 0 0 2px;
}
.footer__rail p:last-child {
  margin-bottom: 0;
}
.footer a {
  color: var(--ink-dim);
  text-decoration-color: var(--line-bright);
}
.footer a:hover {
  color: var(--coin-ink);
}
.footer nav {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
.footer nav a {
  text-decoration: none;
}

/* ----------------------------------------------------------------- motion -- */

/* One authored moment: the world turns up once, then stays put. */
@media (prefers-reduced-motion: no-preference) {
  .world {
    animation: world-in 900ms cubic-bezier(0.16, 1, 0.3, 1) both;
  }
  @keyframes world-in {
    from {
      opacity: 0;
      transform: translateX(-50%) scale(1.04);
    }
    to {
      opacity: var(--world-strength);
      transform: translateX(-50%) scale(1);
    }
  }

  .slam {
    animation: slam 460ms cubic-bezier(0.16, 1, 0.3, 1) both;
  }
  @keyframes slam {
    0% { transform: translateY(-18px); opacity: 0; }
    70% { transform: translateY(2px); opacity: 1; }
    100% { transform: translateY(0); }
  }
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------------- responsive -- */

@media (max-width: 900px) {
  .detail {
    grid-template-columns: minmax(0, 1fr);
  }
  .claimbar {
    flex-wrap: wrap;
  }
  .claimbar .input {
    flex: 1 1 100%;
  }
  .claimbar .select {
    flex: 1 1 auto;
  }
  .claimbar .btn {
    flex: 1 1 auto;
  }
}

@media (max-width: 760px) {
  .hud__inner {
    padding: 10px 16px;
    gap: 10px;
  }
  .hud__nav {
    display: none;
  }
  .world {
    top: 70px;
    width: 180vw;
    opacity: calc(var(--world-strength) * 0.85);
  }

  .card {
    grid-template-columns: 38px 42px minmax(0, 1fr);
    grid-template-areas:
      'rank logo main'
      '.    .    right';
    gap: 12px;
    padding: 14px;
  }
  .card__rank { grid-area: rank; }
  .card__logo { grid-area: logo; width: 38px; height: 38px; }
  .card__main { grid-area: main; }
  .card__right {
    grid-area: right;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    margin-top: 4px;
  }
  .card__desc {
    -webkit-line-clamp: 3;
  }
  .footer__grid {
    gap: 22px;
  }
}

@media (max-width: 480px) {
  .hero__title {
    font-size: 27px;
  }
  .claimbar .btn {
    width: 100%;
  }
}

/* Lit cells for the countries donations have come from. Positioned as a percentage
   of the globe so they track the artwork at any size, and sized by that country's
   share of the total. These are data, which is why they are not baked into the PNG. */
.world__lit {
  position: absolute;
  inset: 0;
}
.world__lit i {
  position: absolute;
  transform: translate(-50%, -50%);
  background: #d97706;
  border-radius: 1px;
  box-shadow: 0 0 0 1px rgba(217, 119, 6, 0.35);
}


/* The hero is the only text that sits on the artwork rather than on a card, so it
   gets its own scrim. Without it the headline lands on whatever continent happens
   to be behind it and the contrast is luck. */
.hero {
  position: relative;
}
.hero::before {
  content: '';
  position: absolute;
  inset: -40px -80px -20px;
  z-index: -1;
  background: radial-gradient(
    ellipse 62% 70% at 50% 46%,
    rgba(242, 246, 252, 0.94) 0%,
    rgba(242, 246, 252, 0.82) 45%,
    rgba(242, 246, 252, 0) 100%
  );
  pointer-events: none;
}

/* ------------------------------------------------ mobile corrections -- */

/* The hero scrim reaches 80px past the column on each side, which is fine at
   desktop width and pushes 60px of horizontal scroll onto a phone. Clip it to the
   viewport rather than letting the page grow. */
@media (max-width: 760px) {
  .hero::before {
    inset: -32px -20px -16px;
  }
}

/* Tap targets. Card names, "see details" and the footer links are all text links
   sitting under the 24px WCAG 2.5.8 floor. Padding buys the hit area back and the
   negative margin means nothing moves on screen. */
.card__name a,
.card__meta a,
.footer nav a,
.section__more {
  display: inline-block;
  padding: 5px 0;
  margin: -5px 0;
}

/* The mark stays flex — it lays the globe out beside the name. Folding it into the
   rule above set display:inline-block and the block-level img broke onto its own
   line, stacking the logo above the wordmark. */
.hud__mark {
  padding: 5px 0;
  margin: -5px 0;
}

.card__name a {
  padding: 6px 0;
  margin: -6px 0;
}

/* The inline Every.org link inside a sentence is exempt from the target-size rule
   and is left alone rather than padded into something that breaks the paragraph. */
