:root {
  --paper: #e7e8e2;
  --panel: #dddfd7;
  --ink: #0e1013;
  --ink-soft: #52565a;
  --rule: #c3c6bc;
  --stamp: #1b2ecc;
  --alarm: #a3241b;

  --mono: ui-monospace, "SFMono-Regular", "SF Mono", "DejaVu Sans Mono",
    "Liberation Mono", Menlo, Consolas, monospace;
  --sans: ui-sans-serif, system-ui, "Helvetica Neue", Helvetica,
    "Liberation Sans", Arial, sans-serif;

  --edge: clamp(1.25rem, 5vw, 3rem);
  /* The amount a customer types and the one they are quoted are set at
     the same size, and the tickers beside them are derived from it. */
  --figure: clamp(1.5rem, 4.5vw, 2.1rem);
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #0e1013;
    --panel: #171a1e;
    --ink: #e7e8e2;
    --ink-soft: #9aa0a6;
    --rule: #2b3036;
    --stamp: #7b88ff;
    --alarm: #ff8f84;
  }
}

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

/* Author rules beat the browser's own [hidden] rule, so say it once here and
   never wonder why a hidden block is still on screen. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

/* The footer belongs at the bottom of the window, not under the last
   paragraph: the status page is short, and a footer riding up to the middle of
   an empty screen reads as a page that failed to load the rest of itself. */
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--ink);
  font: 400 1rem/1.6 var(--mono);
}

main { flex: 1 0 auto; }
footer { flex-shrink: 0; }

.wrap {
  max-width: 34rem;
  margin: 0 auto;
  padding: 0 var(--edge);
}

a { color: var(--stamp); text-underline-offset: 0.25em; }

a:focus-visible,
button:focus-visible,
input:focus-visible { outline: 2px solid var(--stamp); outline-offset: 3px; }

.skip { position: absolute; left: -9999px; }
.skip:focus {
  left: var(--edge);
  top: 0.75rem;
  z-index: 10;
  background: var(--stamp);
  color: #fff;
  padding: 0.5rem 0.9rem;
}

/* ---------- the erasure, down at the bottom ---------- */

/* Full height so there is always something below the fold to scroll to. */
.reveal {
  --doss: clamp(0.72rem, 2.2vw, 1.55rem);
  display: grid;
  min-height: 100vh;
  padding: clamp(2.5rem, 8vw, 5rem) var(--edge);
  overflow: hidden;
}

.reveal > * { grid-area: 1 / 1; place-self: center; }

.dossier {
  font-size: var(--doss);
  line-height: 1.5;
  letter-spacing: -0.01em;
}

/* Resting state — also what a visitor without JS sees: the data is already
   gone and only the logo is left. */
.dossier p {
  position: relative;
  margin: 0;
  width: max-content;
  max-width: 100%;
  color: transparent;
}

.dossier p::after {
  content: "";
  position: absolute;
  left: -0.3em;
  right: -0.6em;
  top: -0.05em;
  bottom: -0.05em;
  background: var(--ink);
  transform-origin: left center;
  transform: scaleX(0);
}

.mark {
  margin: 0;
  font-family: var(--sans);
  font-weight: 800;
  font-size: calc(var(--doss) * 2.6);
  letter-spacing: -0.045em;
  color: var(--ink);
}

.js .dossier p { color: var(--ink); }
.js .mark { opacity: 0; }

/* The marker lays down line by line, then wipes back the way it came —
   taking the text with it. */
.js .reveal.struck .dossier p {
  animation: vanish 1ms linear calc(var(--i) * 110ms + 360ms) forwards;
}

.js .reveal.struck .dossier p::after {
  animation:
    strike 380ms cubic-bezier(0.3, 0.75, 0.25, 1) calc(var(--i) * 110ms) forwards,
    erase 190ms cubic-bezier(0.55, 0, 0.7, 0.35) calc(1260ms + var(--i) * 55ms) forwards;
}

.js .reveal.struck .mark {
  animation: surface 550ms ease-out 1980ms forwards;
}

@keyframes strike { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes erase { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@keyframes vanish { to { color: transparent; } }

@keyframes surface {
  from { opacity: 0; transform: translateY(0.25em); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .js .dossier p { color: transparent; }
  .js .mark { opacity: 1; }
  .js .reveal.struck .dossier p,
  .js .reveal.struck .dossier p::after,
  .js .reveal.struck .mark { animation: none; }
}

/* ---------- the one line ---------- */

.pitch { padding: clamp(2.5rem, 7vw, 4rem) 0 clamp(1.5rem, 4vw, 2.5rem); }

h1 {
  font-family: var(--sans);
  font-weight: 800;
  font-size: clamp(1.9rem, 5.5vw, 3.2rem);
  line-height: 1.05;
  letter-spacing: -0.04em;
  margin: 0;
  text-align: center;
  text-wrap: balance;
}

.sub {
  margin: 1rem auto 0;
  max-width: 56ch;
  text-align: center;
  text-wrap: balance;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

/* ---------- the gate ---------- */

/* The form stays in the layout the whole time and the gate lies on top of it,
   so the page is exactly as tall before the check as after. Nothing below
   shifts, and the block at the foot of the page stays where it belongs —
   off screen until someone scrolls to it. */
.swap-box { position: relative; }

.swap-box .ticket {
  transition: opacity 320ms ease;
}

.swap-box:not(.unlocked) .ticket {
  opacity: 0;
  visibility: hidden;
}

.swap-box .ticket { transition: opacity 320ms ease; }

/* The frame stands there from the first paint; what goes inside it waits for
   the answer about the pass. A visitor who still has one never sees the bar
   flash past on its way out. */
.js .gate .bar { opacity: 0; transition: opacity 200ms ease; }
.js .gate.gate-live .bar { opacity: 1; }

.gate {
  position: absolute;
  inset: 0;
  display: grid;
  align-content: center;
  gap: 1.1rem;
  padding: 1.5rem;
  background: var(--panel);
  border: 1px solid var(--rule);
  transition: opacity 300ms ease, visibility 0s linear 300ms;
}

.swap-box.unlocked .gate {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.bar {
  position: relative;
  height: 4.25rem;
  border: 1px solid var(--ink);
  background: var(--paper);
  overflow: hidden;
}

.bar-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  background: var(--rule);
  transition: width 260ms linear;
}

.bar-text {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  height: 100%;
  padding: 0 0.85rem;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.bar-text b {
  font-weight: 400;
  font-size: 0.95rem;
  letter-spacing: 0;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.gate-note:empty { display: none; }

.gate-note {
  margin: 0 auto;
  max-width: 42ch;
  text-align: center;
  font-size: 0.75rem;
  color: var(--ink-soft);
}

.gate-failed .bar-fill { background: var(--stamp); }

.retry {
  font: inherit;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: none;
  color: var(--ink);
  border: 1px solid var(--ink);
  padding: 0.45rem 0.9rem;
  cursor: pointer;
}

.retry:hover { background: var(--ink); color: var(--paper); }

/* ---------- the swap form ---------- */

.swap-section { padding-bottom: clamp(3rem, 8vw, 5rem); }

.swap-section .wrap { max-width: 48rem; }

/* Send on the left, receive on the right — the swap reads across the form. */
.trade {
  display: grid;
  gap: 1.4rem;
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 46rem) {
  .trade {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2rem;
  }
}

.trade .picker { margin: 0; }

.ticket {
  background: var(--panel);
  border: 1px solid var(--rule);
  padding: 1.5rem;
}

.picker { border: 0; margin: 0 0 1.5rem; padding: 0; min-width: 0; }

.picker legend,
.field > label {
  display: block;
  padding: 0;
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.45rem;
}

/* Two per row on narrow screens: four coins land as a tidy 2×2 instead of
   a three-plus-orphan. */
.chips {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
  margin-top: 0.6rem;
}

@media (min-width: 26rem) {
  .chips[data-cols="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.chips input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.chip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.7rem 0.5rem;
  border: 1px solid var(--ink);
  cursor: pointer;
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  user-select: none;
}

.coin {
  width: 1.15rem;
  height: 1.15rem;
  flex: none;
  fill: currentColor;
}

.tick {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
  text-align: left;
}

.tick small {
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  opacity: 0.6;
}

.chips input:checked + .chip { background: var(--ink); color: var(--paper); }
.chips input:focus-visible + .chip { outline: 2px solid var(--stamp); outline-offset: 2px; }
.chips input:not(:checked) + .chip:hover { border-color: var(--stamp); color: var(--stamp); }

.payout-amount {
  margin: 0;
  font-family: var(--sans);
  font-weight: 800;
  font-size: var(--figure);
  letter-spacing: -0.03em;
  line-height: 1.35;
  /* Same box as the amount field, in a lighter frame: readable as a field,
     but plainly not one you type into. */
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--rule);
  background: var(--paper);
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.payout-amount output { color: var(--ink); }

.field { margin: 1.6rem 0; }

/* An address is the longest thing on the form and the one a customer actually
   proof-reads, so it gets the full width of the ticket to itself, below the
   two columns rather than squeezed alongside them. The type is set just small
   enough that a bech32 address fits on one line without wrapping mid-string. */
.ticket > .field {
  margin: 1.9rem 0 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}

.ticket > .field .combo input {
  font-size: 0.92rem;
  letter-spacing: -0.01em;
  padding: 0.8rem;
}

.field-error {
  margin: 0.5rem 0 0;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--stamp);
}

.combo.over { border-color: var(--stamp); }

.combo {
  display: flex;
  border: 1px solid var(--ink);
  background: var(--paper);
}

.combo input {
  flex: 1;
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0.7rem 0.8rem;
  min-width: 0;
}

/* The editable amount and the computed one sit side by side, so they have to
   be exactly the same height. */
.combo-big,
.payout-amount {
  min-height: 4.25rem;
  align-items: center;
  position: relative;
}

/* The dollar figure sits in the corner of the field it belongs to. Both fields
   reserve room for it, so a long amount scrolls inside instead of running into it. */
/* Small enough to read as a unit rather than as part of the figure, but on the
   same baseline so the two are plainly one statement. */
.combo-big .unit,
.payout-amount .unit {
  /* In the unit's own em, which is small — so this has to be generous or the
     ticker reads as the last digits of the figure. */
  margin-left: 0.5em;
  font-size: calc(var(--figure) * 0.4);
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}

.usd {
  position: absolute;
  right: 0.7rem;
  bottom: 0.3rem;
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

.payout-amount output {
  display: block;
  max-width: calc(100% - 4.5rem);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.payout-amount { display: flex; }

/* Width comes from the script, measured against what has been typed, so the
   ticker sits against the number the way it does on the quoted side instead of
   drifting to the edge of the field. The same room is reserved on both sides
   for the ticker, so a long figure stops in the same place either way. */
.combo input.big {
  flex: 0 1 auto;
  min-width: 4ch;
  max-width: calc(100% - 4.5rem);
  font-family: var(--sans);
  font-weight: 800;
  font-size: var(--figure);
  letter-spacing: -0.03em;
  padding: 0.35rem 0.7rem;
  padding-right: 0;
  font-variant-numeric: tabular-nums;
}

input::placeholder { color: var(--ink-soft); opacity: 0.7; }

.rate-line {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.78rem;
  color: var(--ink-soft);
  border-top: 1px solid var(--rule);
  padding-top: 0.9rem;
  margin: 0;
}

.rate-line.stale span,
.rate-line.stale b,
.rate-line.over span,
.rate-line.over b { color: var(--stamp); }

.combo-big.over { border-color: var(--stamp); }

.rate-line b {
  font-weight: 400;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.go {
  display: block;
  width: 100%;
  margin-top: 1.2rem;
  padding: 1rem;
  font: 700 0.95rem/1 var(--sans);
  color: var(--paper);
  background: var(--ink);
  border: 1px solid var(--ink);
  cursor: pointer;
}

.go:hover { background: var(--stamp); border-color: var(--stamp); color: #fff; }

.go:disabled,
.go:disabled:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
  opacity: 0.4;
  cursor: not-allowed;
}

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

footer {
  border-top: 1px solid var(--rule);
  padding-block: 2.5rem 3rem;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.foot-wrap { max-width: 60rem; }

/* The prose and the two addresses sit side by side while there is room, and
   stack when there is not. The addresses keep to the right either way: the
   status page carries them with no prose beside them, and they belong in the
   same corner of both pages. */
.foot {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 2rem 3rem;
}

/* Prose set to sixty rems is a page nobody finishes a line of. It gives way
   first, because the addresses beside it cannot be made narrower than they are. */
.foot .prose {
  flex: 1 1 16rem;
  min-width: 0;
  max-width: 46rem;
}

.where {
  flex: 0 0 auto;
  margin-left: auto;
  text-align: right;
}

/* Where there is no room beside the prose, the block takes its own row and is
   allowed to shrink: holding it at its natural width pushed an onion address
   off the side of the screen and put a horizontal scrollbar on the page. */
@media (max-width: 46rem) {
  .where {
    flex: 1 1 100%;
    min-width: 0;
  }
}

.where p {
  margin: 0 0 0.55rem;
}

/* The label reads as a label, not as part of the address under it. */
.where span {
  display: block;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.15rem;
}

/* An onion address is sixty-two characters of nothing memorable, so it is set
   in the same face as every other address on the site and allowed to break. */
.where a {
  font-family: var(--mono);
  font-size: 0.7rem;
  word-break: break-all;
}

.foot h2 {
  font: inherit;
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 0.75rem;
}

.foot p {
  margin: 0 0 0.7rem;
  max-width: 62ch;
  line-height: 1.6;
}

.foot p:last-child { margin-bottom: 0; }

.foot ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.foot li + li { margin-top: 0.45rem; }

/* ---------- status page ---------- */

.masthead { border-bottom: 1px solid var(--rule); }

.masthead .wrap {
  padding-block: 1.25rem;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 1.5rem;
  flex-wrap: wrap;
}

/* Support sits in the masthead rather than at the foot of the page. On a swap
   in progress there is nothing below the fold to scroll to, and the moment
   somebody wants to reach us is the moment something has gone oddly — not a
   moment to go looking. */
.help {
  display: flex;
  gap: 1.1rem;
  font-size: 0.78rem;
}

.help a { color: var(--ink-soft); text-decoration: none; border-bottom: 1px solid var(--rule); }
.help a:hover { color: var(--ink); border-bottom-color: var(--stamp); }

.wordmark {
  font-family: var(--sans);
  font-weight: 800;
  font-size: 1.15rem;
  letter-spacing: -0.03em;
  color: var(--ink);
  text-decoration: none;
}

.order {
  max-width: 42rem;
  padding-block: clamp(2.5rem, 7vw, 4rem);
}

.order-id {
  font-size: 0.78rem;
  color: var(--ink-soft);
  letter-spacing: 0.08em;
  margin: 0 0 1.75rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.copy-icon {
  display: inline-flex;
  padding: 0.2rem;
  border: 0;
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
  line-height: 0;
}

.copy-icon svg { width: 1rem; height: 1rem; }
.copy-icon:hover { color: var(--ink); }
.copy-icon .tick { display: none; }

/* Shown only once the text has really reached the clipboard. Over plain http
   there is no clipboard to reach, and a tick that appears anyway would be a
   lie about where somebody's swap id went. */
.copy-icon.done { color: var(--stamp); }
.copy-icon.done .sheet { display: none; }
.copy-icon.done .tick { display: inline; animation: ticked 260ms ease-out; }

@keyframes ticked {
  from { transform: scale(0.6); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .copy-icon.done .tick { animation: none; }
}

.eyebrow {
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 0.75rem;
}

.state {
  font-family: var(--sans);
  font-weight: 800;
  font-size: clamp(1.9rem, 5vw, 2.9rem);
  letter-spacing: -0.03em;
  line-height: 1;
  margin: 0;
  text-align: left;
}

.track {
  list-style: none;
  margin: 2rem 0 2.5rem;
  padding: 0;
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  background: var(--rule);
  border: 1px solid var(--rule);
}

.track li { background: var(--paper); padding: 0.85rem 0.9rem 1rem; }

/* Four steps need about 28rem to stand in a row. Below that they wrap into a
   ragged second line that repeats what the headline and the bar already say,
   so on a narrow screen they are dropped rather than folded.

   What sits below it is pulled up towards it by negative margins; those are
   given back further down this file, after the rules that set them — at equal
   specificity the last one wins, and overriding them from here does nothing. */
@media (max-width: 32rem) {
  .track { display: none; }
}

.track .tick {
  display: block;
  height: 4px;
  background: var(--rule);
  margin-bottom: 0.7rem;
}

.track li[data-done] .tick { background: var(--ink); }

/* The step in hand breathes, so a long wait still looks like something is
   happening. */
.track li[data-now] .tick {
  background: var(--stamp);
  animation: breathe 1.8s ease-in-out infinite;
}

@keyframes breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.28; }
}

@media (prefers-reduced-motion: reduce) {
  .track li[data-now] .tick { animation: none; }
}


.held {
  margin: 1.25rem 0 0;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--stamp);
  border-radius: 4px;
  background: color-mix(in srgb, var(--stamp) 5%, transparent);
}

.held p { margin: 0; font-size: 0.85rem; line-height: 1.55; color: var(--ink-soft); }
.held p + p { margin-top: 0.6rem; }

.stopped {
  margin: 1.25rem 0 0;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--alarm);
  border-radius: 4px;
  background: color-mix(in srgb, var(--alarm) 6%, transparent);
}

.stopped h2 {
  margin: 0 0 0.6rem;
  font-size: 0.95rem;
  color: var(--alarm);
}

.stopped p { margin: 0 0 0.6rem; font-size: 0.85rem; line-height: 1.55; color: var(--ink-soft); }
.stopped p:last-of-type { margin-bottom: 0; }

.stopped-id {
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--ink);
  word-break: break-all;
}

/* An ending that a person arranged, not a fault. Same shape as the stopped
   panel so it reads as a final word, but in the ordinary accent: nothing here
   asks the customer to act. */
.settled {
  margin: 1.25rem 0 0;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--stamp);
  border-radius: 4px;
  background: color-mix(in srgb, var(--stamp) 5%, transparent);
}

.settled h2 { margin: 0 0 0.6rem; font-size: 0.95rem; color: var(--ink); }
.settled p { margin: 0 0 0.6rem; font-size: 0.85rem; line-height: 1.55; color: var(--ink-soft); }
.settled p:last-of-type { margin-bottom: 0; }
.settled-tx { font-family: var(--mono); font-size: 0.78rem; word-break: break-all; }

.queue {
  margin: -1rem 0 2.5rem;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.payin-note {
  margin: 0.9rem 0 0;
  font-size: 0.76rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.progress { margin: -0.5rem 0 1.75rem; }

.progress-bar {
  height: 0.3rem;
  background: var(--rule);
  overflow: hidden;
}

.progress-fill {
  display: block;
  height: 100%;
  width: 0;
  background: var(--stamp);
  transition: width 600ms ease;
}

.progress-text {
  margin: 0.5rem 0 0;
  font-size: 0.76rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* Says how long the wait is, so nobody sits watching a page that has an hour
   left to run. Deliberately quiet: it is reassurance, not an instruction. */
.how-long {
  margin: 1rem 0 0;
  font-size: 0.76rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.order .how-long { margin: -0.5rem 0 2.5rem; }

.track .label {
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.track li[data-now] .label,
.track li[data-done] .label { color: var(--ink); }

.payin {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: minmax(0, 1fr);
  background: var(--panel);
  border: 1px solid var(--rule);
  padding: 1.5rem;
}

@media (min-width: 44rem) {
  .payin { grid-template-columns: 10rem minmax(0, 1fr); }
}

.qr {
  display: block;
  width: 100%;
  max-width: 10rem;
  aspect-ratio: 1;
  background: #fff;
  border: 0.5rem solid #fff;
}

.payin h2 {
  font: inherit;
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 0.4rem;
}

.addr {
  font-size: 0.95rem;
  word-break: break-all;
  line-height: 1.45;
  margin: 0;
}

.copy {
  margin-top: 0.9rem;
  font: inherit;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: none;
  color: var(--ink);
  border: 1px solid var(--ink);
  padding: 0.45rem 0.8rem;
  cursor: pointer;
}

.copy:hover { background: var(--ink); color: var(--paper); }

dl.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: 1.5rem 2rem;
  margin: 2.5rem 0 0;
}

/* Takes the whole row rather than a share of one: the two figures above it are
   a dozen characters, an address is four times that. */
dl.facts .fact-wide { grid-column: 1 / -1; }

dl.facts dt {
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.35rem;
}

dl.facts dd { margin: 0; font-variant-numeric: tabular-nums; }

dl.facts small {
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
}

.note.bad { color: var(--ink); }

.note {
  border-left: 3px solid var(--stamp);
  padding: 0.25rem 0 0.25rem 1rem;
  margin: 2.5rem 0 0;
  color: var(--ink-soft);
  font-size: 0.85rem;
}

/* With the track hidden on a narrow screen, nothing is left above these for
   their negative margins to close the gap to — the bar ends up climbing into
   the headline. Stated here, after the rules being undone, because at equal
   specificity the later rule is the one that applies. */
@media (max-width: 32rem) {
  .progress { margin-top: 1.5rem; }
  .order .how-long { margin-top: 1rem; }
  .queue { margin-top: 1.25rem; }
}
