/* The public pages: landing, gallery, project, terms. Print register: warm cream ink on the dark ground, hairline
 * rules, the WIF Par face for everything (figures included), no glow, no gradient, no stroke for weight. */

.site {
  padding-bottom: 48px;
}

/* the footer row: terms, quietly */
.footer .rail {
  padding-block: 20px;
}

.lead {
  font-size: var(--t-lead);
  line-height: 1.45;
  max-width: 62ch;
}

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

.mono {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  overflow-wrap: anywhere;
}

.prose {
  white-space: pre-line;
  overflow-wrap: anywhere;
  max-width: 68ch;
  margin: 0;
}

/* the front page (docs/UI-STEP-1-ROUND-3.md) ------------------------------------------------------------------- */

/* row 3, the hero cell (section 6): the banner edge to edge inside the guides, in its own proportions (the designer
   bakes the line and the prize into it, so it is never cropped), then the phase's button and "read the rules" */
.hero__rail {
  padding: 0;
}

.banner__img {
  display: block;
  width: 100%;
  height: auto;
  background: var(--surface);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 12px 28px;
  padding: 28px var(--pad) 32px;
}

@media (min-width: 1150px) {
  .hero__actions {
    padding-block: 36px 40px;
  }
}

.hero__note {
  flex: 1 0 100%;
  margin: 0;
  text-align: center;
  color: var(--ink-muted);
  overflow-wrap: anywhere;
}

.hero__rules,
.fleet__all {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--green);
  text-decoration: none;
  letter-spacing: 0.02em;
}

/* row 4, the projects, "on the map" (docs/UI-STEP-1-ROUND-4.md, section 6) */
.fleet__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 24px;
  margin-bottom: 20px;
}

.fleet__head .section__title {
  margin: 0;
}

.fleet__line {
  margin: 0;
  color: var(--ink-muted);
}

.fleet__wif {
  color: var(--green);
}

/* the search: a well in the plate, with the light edge and the dark ring every field has */
.psearch {
  display: block;
  width: 100%;
  max-width: 480px;
  min-height: 44px;
  margin-bottom: 16px;
  padding: 10px 14px;
  border: 1px solid var(--edge-light);
  border-radius: 10px;
  background: var(--ground);
  box-shadow: var(--ring);
}

/* the categories: a card each, with gaps between and no dividers. The chosen one is lighter and raised. They wrap
   onto two lines where there's room; on phones they keep to one line that scrolls sideways */
/* the search and the sort on one row over the category cards (docs/SORT-AND-VOTE-LINK.md); on a phone the sort
   goes under the search */
.fleet__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 16px;
  margin-bottom: 16px;
}

.fleet__bar .psearch {
  flex: 1 1 260px;
  margin-bottom: 0;
}

.psort {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

/* no emblem in a sort button: the same padding both sides */
.psort__item {
  padding-inline: 14px;
}

.pfilters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 24px;
}

@media (max-width: 719px) {
  .pfilters {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    /* room for the raised card's shadow and lift, which the scroller would clip; the row keeps to the rail's
       padding, so the cards are cut at the gutter, never at the frame's edge */
    margin: -6px -4px 18px;
    padding: 6px 4px 8px;
  }
  .pfilters::-webkit-scrollbar {
    display: none;
  }
}

.pfilter {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 6px 14px 6px 8px;
  border: 1px solid var(--edge-light);
  border-radius: 10px;
  background: rgb(var(--warm-ink) / 0.03);
  box-shadow: var(--ring);
  color: rgb(var(--warm-ink) / 0.74);
  font-size: 15px;
  letter-spacing: 0.02em;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color 160ms,
    color 160ms,
    transform 180ms,
    box-shadow 180ms;
}

.pfilter:hover {
  background: rgb(var(--warm-ink) / 0.07);
  color: var(--ink);
}

.pfilter[aria-pressed="true"] {
  background: rgb(var(--warm-ink) / 0.12);
  border-color: rgb(var(--warm-ink) / 0.18);
  color: var(--ink);
  transform: translateY(-1px);
  box-shadow:
    var(--ring),
    inset 0 1px 0 rgb(var(--warm-ink) / 0.12),
    0 6px 14px rgb(0 0 0 / 0.38);
}

.pfilter__tile {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 6px;
  background: var(--ground);
  box-shadow: 0 0 0.5px 1px var(--edge-light);
  color: var(--ink);
}

/* the finalists, at the top of the all projects page once published */
.fleet__finalists {
  margin-bottom: 32px;
  padding-bottom: 32px;
  border-bottom: 1px solid var(--line-dark);
  box-shadow: 0 1px 0 rgb(var(--warm-ink) / 0.08);
}

.fleet__sub {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 18px;
  font-size: var(--t-subhead);
  font-weight: 400;
}

.fleet__none {
  margin: 0 0 16px;
  overflow-wrap: anywhere;
}

.fleet__more {
  display: flex;
  margin: 8px auto 16px;
}

/* the grid of tiles (docs/UI-STEP-2.md, section 1): 2 a row on phones, 3 from 600px, 4 from 1024px, 5 from 1440px.
   At those widths a tile is never under 200px wide on a desktop */
.ptiles {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 22px 12px;
}

@media (min-width: 600px) {
  .ptiles {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 26px 16px;
  }
}

@media (min-width: 1024px) {
  .ptiles {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (min-width: 1440px) {
  .ptiles {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

.ptiles > li {
  min-width: 0;
}

/* a tile: the square plate, then under it the name and the chips. The link holds the plate and the name, and its
   ::after covers the whole tile, chips too, so the tile opens its project wherever it's pressed; only the "vote"
   sits above it */
.ptile {
  position: relative;
  display: grid;
  gap: 10px;
  align-content: start;
  min-width: 0;
}

.ptile__link {
  display: grid;
  gap: 10px;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}

.ptile__link::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* while the project can be voted on: a small "vote" beside its total, chip height, with a 44px target round it */
.ptile__vote {
  position: relative;
  z-index: 1;
  min-height: 26px;
  padding: 0 10px;
  border-radius: 6px;
  font-size: 12px;
  letter-spacing: 0.02em;
}

.ptile__vote::before {
  content: "";
  position: absolute;
  inset: -9px -4px;
}

/* the engraved plate: a thick frame raised by a bevel (light along its top and left, dark along its bottom and
   right), a thin inner rule cut in, a small gap, then the logo filling a square. The judges' plates are the same
   make (row 5) */
.lplate {
  display: block;
  padding: 8px;
  border-radius: 4px;
  background: rgb(56 56 55);
  box-shadow:
    inset 1px 1px 0 rgb(var(--warm-ink) / 0.24),
    inset -1px -1px 0 rgb(0 0 0 / 0.5),
    var(--ring),
    0 6px 14px rgb(0 0 0 / 0.36);
  transition:
    transform 180ms,
    box-shadow 180ms;
}

.lplate__inner {
  display: block;
  padding: 3px;
  border: 1px solid rgb(var(--warm-ink) / 0.42);
  box-shadow:
    -1px -1px 0 rgb(0 0 0 / 0.45),
    1px 1px 0 rgb(var(--warm-ink) / 0.1);
}

.lplate__face {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  overflow: hidden;
  background: var(--ground);
}

.lplate__face img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* no logo: the first letter, set large on the plain plate */
.lplate__letter {
  color: var(--ink-muted);
  font-size: clamp(56px, 6vw, 96px);
  line-height: 1;
  text-transform: lowercase;
}

.ptile:hover:not(:has(.ptile__vote:hover)) .lplate,
.ptile:has(.ptile__link:focus-visible) .lplate {
  transform: translateY(-2px);
  box-shadow:
    inset 1px 1px 0 rgb(var(--warm-ink) / 0.24),
    inset -1px -1px 0 rgb(0 0 0 / 0.5),
    var(--ring),
    0 12px 24px rgb(0 0 0 / 0.46);
}

.ptile__link:focus-visible {
  outline-offset: 4px;
}

.ptile__name {
  display: block;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--t-label);
  line-height: 1.25;
}

.ptile__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}

/* the category and its "+n" together on their own row: the "+n" never wraps away to the total's row */
.ptile__cats {
  display: flex;
  flex: 1 0 100%;
  gap: 6px;
  min-width: 0;
}

.ptile__cats .chip--more {
  flex: none;
}

/* on a narrow tile a long category wraps inside its chip, whole, so the +2 keeps its place beside it */
.ptile__cats .chip--cat {
  min-width: 0;
  flex: 0 1 auto;
  padding-block: 4px;
}

.ptile__cats .chip--cat .chip__text {
  overflow: visible;
  white-space: normal;
}

.ptile__cats:empty {
  display: none;
}

/* the winner: its plate in a laurel frame, a sage bevel round it and the laurel on its foot */
.ptile--winner .lplate {
  background: rgb(62 66 52);
  box-shadow:
    inset 1px 1px 0 rgb(var(--warm-ink) / 0.3),
    inset -1px -1px 0 rgb(0 0 0 / 0.5),
    0 0 0 1px var(--green-muted),
    var(--ring),
    0 6px 14px rgb(0 0 0 / 0.36);
}

.ptile__laurel {
  position: absolute;
  left: 50%;
  top: 0;
  translate: -50% -50%;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgb(62 66 52);
  box-shadow:
    0 0 0 1px var(--green-muted),
    var(--ring);
  color: var(--green);
}

/* a small framed chip: an emblem, a thin divider, the words */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 26px;
  max-width: 100%;
  padding: 0 8px;
  border: 1px solid var(--edge-light);
  border-radius: 6px;
  background: rgb(var(--warm-ink) / 0.04);
  box-shadow: var(--ring);
  color: rgb(var(--warm-ink) / 0.85);
  font-size: 12px;
  line-height: 1.2;
  letter-spacing: 0.02em;
}

.chip__rule {
  flex: none;
  width: 1px;
  height: 12px;
  background: var(--line-light);
}

.chip__text {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.chip--cat .chip__text {
  color: var(--green-muted);
}

.chip--winner {
  color: var(--green);
}

/* the total is never cut: on a narrow tile its round goes under the amount instead */
.chip--wif {
  flex-wrap: wrap;
  row-gap: 0;
  padding-block: 4px;
}

.chip--wif .chip__text {
  flex: none;
  overflow: visible;
  font-variant-numeric: tabular-nums;
}

/* its round, after the amount, quieter */
.chip__round {
  color: var(--ink-muted);
  white-space: nowrap;
}

.chip__round:empty {
  display: none;
}

/* row 5, the judges (docs/UI-STEP-1-ROUND-4.md, section 8): one row, sideways on narrow screens */
.jstrip {
  list-style: none;
  margin: 0;
  /* room for a plate's lift and shadow, which the scroller would clip */
  padding: 6px 2px 12px;
  display: flex;
  gap: clamp(14px, 2vw, 28px);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  overscroll-behavior-x: contain;
}

/* an engraved museum plate: a thick frame raised from the page by a bevel (light along its top and left, dark
   along its bottom and right), a thin inner rule, a small gap, then the picture; under it the handle on a small
   plate of the same make. Hover lifts it a little */
.jplate {
  flex: 0 0 clamp(132px, 15vw, 172px);
  display: grid;
  justify-items: center;
  gap: 10px;
  align-content: start;
  scroll-snap-align: start;
  min-width: 0;
  transition: transform 180ms;
}

.jplate:hover {
  transform: translateY(-2px);
}

.jplate__frame,
.jplate__label {
  background: rgb(56 56 55);
  box-shadow:
    inset 1px 1px 0 rgb(var(--warm-ink) / 0.24),
    inset -1px -1px 0 rgb(0 0 0 / 0.5),
    var(--ring),
    0 6px 14px rgb(0 0 0 / 0.36);
  transition: box-shadow 180ms;
}

.jplate:hover .jplate__frame {
  box-shadow:
    inset 1px 1px 0 rgb(var(--warm-ink) / 0.24),
    inset -1px -1px 0 rgb(0 0 0 / 0.5),
    var(--ring),
    0 12px 24px rgb(0 0 0 / 0.46);
}

.jplate__frame {
  display: block;
  width: 100%;
  padding: 9px;
  border-radius: 4px;
}

/* the thin inner rule, cut in: a dark line outside it and a light one inside, then the gap */
.jplate__inner {
  display: block;
  padding: 3px;
  border: 1px solid rgb(var(--warm-ink) / 0.42);
  box-shadow:
    -1px -1px 0 rgb(0 0 0 / 0.45),
    1px 1px 0 rgb(var(--warm-ink) / 0.1);
}

.jplate__face {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  overflow: hidden;
  background: var(--ground);
  color: var(--ink-muted);
}

.jplate__face img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.jplate__label {
  display: inline-block;
  max-width: 100%;
  padding: 4px 10px;
  border-radius: 3px;
  font-size: 13px;
  line-height: 1.3;
  letter-spacing: 0.03em;
  text-align: center;
  overflow-wrap: anywhere;
}

/* under the label plate: the handle, then the role as written, on the plate's width */
.jplate__about {
  display: grid;
  gap: 4px;
  max-width: 100%;
  margin-top: -2px;
  font-size: 12px;
  line-height: 1.4;
  text-align: center;
  overflow-wrap: anywhere;
}

.jplate__handle {
  color: rgb(var(--warm-ink) / 0.6);
  letter-spacing: 0.03em;
}

.jplate__role {
  color: var(--ink-muted);
}

/* the handle is the label's link: a 44px tap height from padding that doesn't move the plate */
.jplate__label a {
  text-decoration: none;
  padding-block: max(0px, calc(23px - 0.5em));
}

.jplate--soon .jplate__label {
  color: var(--ink-muted);
}

.rules__terms a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.feed__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 12px;
  align-items: baseline;
}

.feed__meta a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

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

.section {
  padding: clamp(32px, 5vw, 64px) 0;
  border-bottom: 1px solid var(--rule);
}

/* a page's first section starts at the rail's own padding */
.rail > .section:first-child,
.rail > h1 + .section {
  padding-top: 0;
}

.rail > .section:last-child {
  padding-bottom: 0;
}

.section:last-child {
  border-bottom: 0;
}

.section__title {
  margin: 0 0 20px;
  font-size: var(--t-section);
  font-weight: 400;
  line-height: 1.1;
  overflow-wrap: anywhere;
}

.section p {
  max-width: 68ch;
}

.numbered {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: item;
  display: grid;
  gap: 14px;
  max-width: 72ch;
}

.numbered li {
  counter-increment: item;
  display: grid;
  grid-template-columns: 2.4em 1fr;
  gap: 8px;
}

.numbered li::before {
  content: counter(item);
  color: var(--green-muted);
  font-variant-numeric: tabular-nums;
}

.categories {
  list-style: none;
  margin: 24px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  box-shadow: var(--ring);
}

.category {
  background: var(--ground);
  padding: 18px 20px;
  display: grid;
  gap: 6px;
}

.category__name {
  font-size: var(--t-label);
}

.category__desc {
  color: var(--ink-muted);
}

.timeline {
  border-collapse: collapse;
  width: 100%;
  max-width: 640px;
}

.timeline th,
.timeline td {
  text-align: left;
  font-weight: 400;
  padding: 12px 0;
  border-bottom: 1px solid var(--hairline);
  vertical-align: top;
}

.timeline td {
  text-align: right;
  padding-left: 16px;
}

.judges {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 180px), 1fr));
  gap: 24px;
}

.judge {
  display: grid;
  gap: 8px;
  justify-items: start;
}

.judge__face {
  width: 100%;
  aspect-ratio: 1;
  display: block;
  border: 1px solid var(--hairline);
  background: var(--surface);
  overflow: hidden;
}

.judge__face img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.judge__letter {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(40px, 6vw, 72px);
  color: var(--ink-muted);
}

.judge__name {
  color: var(--ink-muted);
}

.judge--soon {
  align-content: center;
  justify-items: center;
  border: 1px dashed var(--hairline);
  aspect-ratio: 1;
  color: var(--ink-muted);
}

.faq {
  margin: 0;
  display: grid;
  gap: 8px;
  max-width: 72ch;
}

.faq dt {
  font-size: var(--t-label);
  margin-top: 16px;
}

.faq dd {
  margin: 0;
  color: var(--ink-muted);
}

.footer a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.footer {
  color: var(--ink-muted);
}

/* a section the menus link to clears the sticky nav row when it is scrolled to */
.section[id],
.panel[id] {
  scroll-margin-top: 140px;
}

/* a submission's details (judge and admin pages) ------------------------------------------------------------- */

.detail {
  margin: 0;
  display: grid;
  gap: 20px;
}

.detail__row {
  display: grid;
  grid-template-columns: minmax(0, 220px) minmax(0, 1fr);
  gap: 16px;
}

.detail__row dt {
  color: var(--ink-muted);
}

.detail__row dd {
  margin: 0;
  min-width: 0;
}

@media (max-width: 640px) {
  .detail__row {
    grid-template-columns: 1fr;
    gap: 6px;
  }
}

.hexlist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.out {
  overflow-wrap: anywhere;
}

.video--x iframe {
  max-width: 550px;
  aspect-ratio: auto;
}

.video iframe {
  width: 100%;
  max-width: 720px;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--hairline);
  box-shadow: var(--ring);
  background: var(--surface);
}

.updates {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 20px;
}

.updates li {
  min-width: 0;
}

.updates p {
  margin: 0 0 4px;
  overflow-wrap: anywhere;
}

.share {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 28px 0;
}

/* voting -------------------------------------------------------------------------------------------------------- */

/* the vote form (docs/COMMUNITY-VOTING-UI.md), on the spacing system's steps: 24px between its blocks (the wallet,
   the amount, the steps, the button), the field's own 12px label to field and 8px field to its line, 12px between
   steps and between the rows of the wallet */
.vote {
  display: grid;
  gap: 24px;
  max-width: 420px;
  /* the steps go side by side when the form is wide enough for two (below) */
  container-type: inline-size;
}

.vote[hidden],
.vote__wallet[hidden] {
  display: none;
}

.vote__wallet {
  display: grid;
  gap: 12px;
  margin: 0;
}

.vote__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
}

.vote__row dt {
  color: var(--ink-muted);
}

.vote__row dd {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
  text-align: right;
}

.field > * + .vote__amount {
  margin-top: 12px;
}

.vote__amount {
  display: flex;
  gap: 8px;
}

.vote__amount input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  background: var(--ground);
  box-shadow: var(--ring);
}

.vote__max {
  flex: none;
  min-width: 56px;
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--line-light);
  border-radius: 10px;
  background: transparent;
  color: var(--ink-muted);
  font: inherit;
  cursor: pointer;
  transition:
    color 150ms,
    border-color 150ms;
}

.vote__max:hover:not(:disabled) {
  color: var(--ink);
  border-color: rgb(var(--warm-ink) / 0.4);
}

.vote__max:disabled {
  opacity: 0.45;
  cursor: default;
}

.field > * + .vote__line {
  margin-top: 8px;
}

.vote__line {
  min-height: 1.5em;
  color: var(--ink-muted);
}

.vote__line[data-tone="alert"],
.vote__status[data-tone="alert"] {
  color: var(--alert);
}

/* the two steps: a numbered tile (as the rules and the ballot number theirs), the step, and what it is waiting on or
   its transaction, in fixed columns, so a link appearing moves nothing */
/* the two steps side by side, "1 approve" then "2 vote", each with what it waits on and its transaction under it
   (docs/VOTE-FORK-FIXES.md). A step needs 118px (the 32px tile, 10px, "approve"), so two need 248px: the side
   panel has that from 1280 and the phone's sheet at 375; narrower (the side panel at 1024) they stack */
.vote__steps {
  list-style: none;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
  margin: 0;
  padding: 0;
}

@container (min-width: 248px) {
  .vote__steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.vote__step {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  align-items: center;
  /* a step beside a taller one keeps its tile and name on the same line as the other's */
  align-content: start;
  column-gap: 10px;
  row-gap: 2px;
  min-height: 32px;
  min-width: 0;
  color: var(--ink-subtle);
}

.vote__n {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 1px solid var(--edge-light);
  border-radius: 6px;
  background: var(--surface);
  box-shadow:
    inset 0 1px 0 rgb(var(--warm-ink) / 0.1),
    var(--ring);
  color: var(--green-muted);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.vote__step:is([data-state="wallet"], [data-state="chain"]) {
  color: var(--ink);
}

.vote__step:is([data-state="wallet"], [data-state="chain"]) .vote__n {
  border-color: rgb(var(--warm-ink) / 0.45);
  color: var(--ink);
}

.vote__step[data-state="done"] {
  color: var(--ink);
}

.vote__step[data-state="done"] .vote__n {
  color: var(--green);
}

.vote__step[data-state="failed"] .vote__n {
  color: var(--alert);
}

/* what a step waits on, then its transaction: under the step's name, and nothing at all while there is neither */
.vote__detail {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 8px;
  min-width: 0;
  font-size: 13px;
  line-height: 1.35;
  color: var(--ink-muted);
}

.vote__detail:empty {
  display: none;
}

/* the transaction link: a line of text, with a 44px target round it that doesn't add to the step's height */
.vote__tx {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.vote__tx::before {
  content: "";
  position: absolute;
  inset: -12px -4px;
}

.vote__go {
  width: 100%;
}

.vote__after {
  display: grid;
  gap: 12px;
}

.vote__after:not(:has(.vote__status:not(:empty), .vote__retry:not([hidden]))) {
  display: none;
}

.vote__status {
  margin: 0;
}

.vote__retry {
  justify-self: start;
}

.team__members {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

/* the project page (docs/UI-STEP-2.md, section 3) ---------------------------------------------------------------- */

.pp__back {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin: -8px 0 12px;
  color: var(--ink-muted);
  text-decoration: none;
  letter-spacing: 0.02em;
}

.pp__back:hover,
.pp__back:focus-visible {
  color: var(--ink);
}

/* the header in its ornamental frame: a double engraved border (the outer line and an inner one 7px in, each a
   dark core with a light edge) and an engraved bracket at each corner, sitting over both lines */
.ornate {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 20px 28px;
  margin-bottom: 36px;
  padding: 32px 36px;
  border: 1px solid var(--line-dark);
  border-radius: 6px;
  background: rgb(var(--warm-ink) / 0.025);
  box-shadow:
    inset 0 0 0 1px var(--line-light),
    0 0 0 1px rgb(var(--warm-ink) / 0.05);
}

.ornate::before {
  content: "";
  position: absolute;
  inset: 7px;
  border: 1px solid var(--line-dark);
  border-radius: 3px;
  box-shadow: inset 0 0 0 1px rgb(var(--warm-ink) / 0.12);
  pointer-events: none;
}

.ornate__corner {
  position: absolute;
  z-index: 1;
  display: grid;
  width: 22px;
  height: 22px;
  color: rgb(var(--warm-ink) / 0.72);
  pointer-events: none;
}

.ornate__corner--tl {
  top: 2px;
  left: 2px;
}

.ornate__corner--tr {
  top: 2px;
  right: 2px;
  rotate: 90deg;
}

.ornate__corner--br {
  bottom: 2px;
  right: 2px;
  rotate: 180deg;
}

.ornate__corner--bl {
  bottom: 2px;
  left: 2px;
  rotate: 270deg;
}

/* the vote link with voting closed: when it opens, or that it's closed, between the header and the page */
.pp__voting {
  margin: -12px 0 32px;
}

.lplate--head {
  width: clamp(96px, 11vw, 148px);
}

.pp__title {
  display: grid;
  gap: 10px;
  min-width: 0;
}

.pp__name {
  margin: 0;
  font-size: clamp(34px, calc(2.6vw + 16px), 60px);
  font-weight: 400;
  line-height: 1.04;
  overflow-wrap: anywhere;
}

.pp__line {
  margin: 0;
  font-size: var(--t-lead);
  line-height: 1.4;
  color: var(--ink-muted);
  overflow-wrap: anywhere;
}

.pp__share {
  align-self: start;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

/* phones: the plate and the name side by side, the line, the chips and share under them across the card */
@media (max-width: 719px) {
  .ornate {
    grid-template-columns: 84px minmax(0, 1fr);
    gap: 14px 16px;
    padding: 26px 22px;
  }
  .pp__title {
    display: contents;
  }
  .lplate--head {
    width: 84px;
  }
  .pp__name {
    grid-column: 2;
    grid-row: 1;
    align-self: center;
  }
  .pp__line,
  .pp__title > .ptile__chips,
  .pp__share {
    grid-column: 1 / -1;
  }
}

/* share: a small menu of the panel's make */
.share {
  position: relative;
}

.share__menu {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  z-index: 20;
  display: grid;
  min-width: 190px;
  padding: 6px;
  border-radius: 12px;
  background: var(--panel);
  box-shadow: var(--panel-shadow);
}

@media (max-width: 719px) {
  .share__menu {
    left: 0;
    right: auto;
  }
}

.share__menu a,
.share__menu button {
  appearance: none;
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--ink);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.share__menu a:hover,
.share__menu button:hover,
.share__menu a:focus-visible,
.share__menu button:focus-visible {
  background: rgb(var(--warm-ink) / 0.06);
}

/* the main column and the side column: side by side from 1024px, the side one sticky; narrower, the side column
   comes first, under the header */
.pp__body {
  display: grid;
  gap: 32px;
}

@media (min-width: 1024px) {
  .pp__body:not(.pp__body--solo) {
    grid-template-columns: minmax(0, 1fr) clamp(280px, 24vw, 340px);
    align-items: start;
    gap: 40px;
  }
  .pp__side {
    position: sticky;
    top: 124px;
  }
}

@media (max-width: 1023px) {
  .pp__side {
    order: -1;
  }
}

.pp__main {
  min-width: 0;
}

.pp__section {
  margin-bottom: 44px;
}

/* a section heading: the emblem, the words, a rule to the right edge (a dark core with its light edge, like the
   frame's) and the flat disc where it ends */
.sh {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 20px;
  font-size: var(--t-subhead);
  font-weight: 400;
  line-height: 1.2;
}

.sh__mark,
.sh__disc {
  display: inline-flex;
  flex: none;
}

.sh__disc {
  color: rgb(var(--warm-ink) / 0.7);
}

.sh__rule {
  flex: 1 1 auto;
  min-width: 24px;
  height: 1px;
  background: var(--line-dark);
  box-shadow: 0 1px 1px var(--line-light);
}

.pp__block {
  margin-bottom: 20px;
}

.pp__block:last-child {
  margin-bottom: 0;
}

.pp__label {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.08em;
  color: var(--green-muted);
}

.pp__chips {
  margin: 16px 0;
}

/* the demo video: our own poster first, in a frame; the sandboxed embed only once it is played */
.vframe {
  aspect-ratio: 16 / 9;
  margin-bottom: 16px;
  overflow: hidden;
  border: 1px solid var(--edge-light);
  border-radius: 10px;
  background: var(--ground);
  box-shadow: var(--ring);
}

.vframe--x {
  aspect-ratio: auto;
  max-width: 550px;
  height: 640px;
}

.vframe .video,
.vframe iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  margin: 0;
}

.vposter {
  appearance: none;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 14px;
  width: 100%;
  height: 100%;
  border: 0;
  background: #161616;
  box-shadow:
    inset 0 0 0 10px #0d0d0d,
    inset 0 0 0 11px var(--line-light);
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
}

.vposter__mark {
  display: grid;
  color: rgb(var(--warm-ink) / 0.86);
  transition: transform 180ms;
}

.vposter:hover .vposter__mark {
  transform: scale(1.06);
}

.vposter__label {
  font-size: 14px;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
}

.pp__live {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  min-width: 0;
}

/* the flywheel: three connected steps */
.flywheel {
  list-style: none;
  display: grid;
  gap: 28px;
  margin: 20px 0;
  padding: 0;
}

@media (min-width: 720px) {
  .flywheel {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.flywheel__step {
  position: relative;
  display: grid;
  align-content: start;
  gap: 6px;
  padding: 16px;
  border: 1px solid var(--edge-light);
  border-radius: 10px;
  background: rgb(var(--warm-ink) / 0.03);
  box-shadow: var(--ring);
}

/* the connection to the next step: an engraved line across the gap, the flat disc's line, ending in a small dot */
.flywheel__step:not(:last-child)::after {
  content: "";
  position: absolute;
  background: var(--line-light);
}

@media (min-width: 720px) {
  .flywheel__step:not(:last-child)::after {
    top: 50%;
    right: -29px;
    width: 30px;
    height: 1px;
  }
}

@media (max-width: 719px) {
  .flywheel__step:not(:last-child)::after {
    left: 50%;
    bottom: -29px;
    width: 1px;
    height: 30px;
  }
}

.flywheel__n {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--ground);
  box-shadow: 0 0 0.5px 1px var(--edge-light);
  font-size: 13px;
}

/* the team: two columns of cards, each a plate with an engraved notch at each corner */
.tcards {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 0;
  padding: 0;
}

@media (max-width: 479px) {
  .tcards {
    grid-template-columns: minmax(0, 1fr);
  }
}

.tcard {
  position: relative;
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--edge-light);
  border-radius: 3px;
  background: var(--surface);
  box-shadow: var(--ring);
  text-decoration: none;
  transition: background-color 160ms;
}

.tcard:hover {
  background: var(--elevated);
}

.notch {
  position: absolute;
  width: 9px;
  height: 9px;
  border-color: rgb(var(--warm-ink) / 0.42);
  border-style: solid;
  border-width: 0;
  pointer-events: none;
}

.notch--tl {
  top: 5px;
  left: 5px;
  border-top-width: 1px;
  border-left-width: 1px;
}

.notch--tr {
  top: 5px;
  right: 5px;
  border-top-width: 1px;
  border-right-width: 1px;
}

.notch--br {
  bottom: 5px;
  right: 5px;
  border-bottom-width: 1px;
  border-right-width: 1px;
}

.notch--bl {
  bottom: 5px;
  left: 5px;
  border-bottom-width: 1px;
  border-left-width: 1px;
}

.tcard__text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.tcard__name {
  font-size: var(--t-label);
  overflow-wrap: anywhere;
}

.tcard__handle {
  font-size: 13px;
  color: var(--green-muted);
  overflow-wrap: anywhere;
}

/* a small framed square picture (a team card, a comment): the plates' make, smaller */
.cplate {
  display: block;
  padding: 4px;
  border-radius: 3px;
  background: rgb(56 56 55);
  box-shadow:
    inset 1px 1px 0 rgb(var(--warm-ink) / 0.24),
    inset -1px -1px 0 rgb(0 0 0 / 0.5),
    var(--ring);
}

.cplate__inner {
  display: block;
  padding: 2px;
  border: 1px solid rgb(var(--warm-ink) / 0.42);
}

.avatar--fill {
  display: grid;
  place-items: center;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  border: 0;
  border-radius: 0;
  object-fit: cover;
}

.avatar--fill.avatar--letter {
  font-size: 18px;
  color: var(--ink);
}

/* the links: framed square icon buttons, each with its tooltip */
.ilinks {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.ilink {
  position: relative;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  padding: 6px;
  border-radius: 6px;
  background: rgb(56 56 55);
  box-shadow:
    inset 1px 1px 0 rgb(var(--warm-ink) / 0.24),
    inset -1px -1px 0 rgb(0 0 0 / 0.5),
    var(--ring);
  color: var(--ink);
  transition: transform 180ms;
}

.ilink:hover,
.ilink:focus-visible {
  transform: translateY(-2px);
}

.ilink .avatar--fill {
  height: 100%;
  box-shadow: 0 0 0 1px rgb(var(--warm-ink) / 0.42);
}

.ilink::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  translate: -50% 0;
  z-index: 5;
  padding: 6px 10px;
  border-radius: 6px;
  background: var(--panel);
  box-shadow: var(--panel-shadow);
  font-size: 13px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 150ms;
}

.ilink:hover::after,
.ilink:focus-visible::after {
  opacity: 1;
}

/* the updates: a timeline, newest first, along an engraved line */
.timeline-up {
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0 0 0 26px;
}

.timeline-up::before {
  content: "";
  position: absolute;
  top: 6px;
  bottom: 6px;
  left: 7px;
  width: 1px;
  background: var(--line-dark);
  box-shadow: 1px 0 1px var(--line-light);
}

.timeline-up__item {
  position: relative;
  padding-bottom: 20px;
}

.timeline-up__dot {
  position: absolute;
  top: 4px;
  left: -26px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--frame-fill);
  box-shadow:
    0 0 0 1px var(--line-light),
    inset 0 0 0 4px var(--frame-fill),
    inset 0 0 0 9px rgb(var(--warm-ink) / 0.5);
}

.timeline-up__meta {
  margin: 0 0 4px;
  font-size: 13px;
  color: var(--ink-subtle);
  overflow-wrap: anywhere;
}

/* the comments (section 4) */
.cbox {
  display: grid;
  gap: 8px;
  margin-bottom: 24px;
}

.cbox__field {
  width: 100%;
  min-height: 96px;
  padding: 12px 14px;
  border: 1px solid var(--edge-light);
  border-radius: 10px;
  background: var(--ground);
  box-shadow: var(--ring);
  line-height: 1.5;
  resize: vertical;
}

.cbox__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
}

.cbox__count {
  margin-right: auto;
  font-size: 12px;
  color: var(--ink-subtle);
}

.cbox__status {
  margin: 0;
  color: var(--alert);
}

.cbox__status:empty {
  display: none;
}

.cbox--out {
  justify-items: start;
}

.clist {
  list-style: none;
  display: grid;
  gap: 20px;
  margin: 0;
  padding: 0;
}

.clist--replies {
  margin-top: 14px;
  padding-left: 14px;
  border-left: 1px solid var(--line-dark);
  box-shadow: inset 1px 0 0 rgb(var(--warm-ink) / 0.08);
}

.comment {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
}

.comment--hidden {
  opacity: 0.5;
}

.comment__body {
  min-width: 0;
}

.comment__who {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
  margin: 0;
  font-size: 14px;
}

.comment__name {
  color: var(--ink);
  text-decoration: none;
  overflow-wrap: anywhere;
}

.comment__handle {
  font-size: 13px;
  color: var(--green-muted);
}

.comment__when {
  font-size: 12px;
  color: var(--ink-subtle);
}

/* what they wrote: text only, line breaks kept, long runs wrapped */
.comment__text {
  margin: 6px 0 2px;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.comment__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin-left: -10px;
}

.comment__act {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-muted);
  font-size: 13px;
  cursor: pointer;
}

.comment__act:hover:not(:disabled) {
  background: rgb(var(--warm-ink) / 0.06);
  color: var(--ink);
}

.comment__act[aria-pressed="true"] {
  color: var(--green);
}

.comment__act:disabled {
  cursor: default;
}

.comment__act--staff {
  color: var(--alert);
}

.clist__empty {
  list-style: none;
}

/* the side column: the vote panel during a vote, else the status card. 8px from the label to the total, 12px to
   the rest, 24px to the vote (docs/COMMUNITY-VOTING-UI.md: the spacing system's steps) */
.vpanel {
  display: grid;
  gap: 12px;
  padding: 24px;
  border: 1px solid var(--edge-light);
  border-radius: 12px;
  background: var(--surface);
  box-shadow: var(--ring);
}

.vpanel__label {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
  font-size: 13px;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
}

.vpanel__head {
  display: grid;
  gap: 8px;
}

.vpanel__round:empty,
.vbar__round:empty {
  display: none;
}

.vpanel__note {
  margin: 0;
  color: var(--ink-muted);
}

.vpanel__total {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  margin: 0;
}

.vpanel__amount {
  font-size: clamp(32px, calc(1.6vw + 18px), 46px);
  line-height: 1.05;
  overflow-wrap: anywhere;
}

.vpanel__wif {
  color: var(--green);
}

.vpanel__row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
}

.vpanel__action {
  margin-top: 12px; /* with the grid's 12px: 24px to the vote */
}

.vpanel__action > .btn {
  width: 100%;
}

.standing {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  font-size: var(--t-subhead);
}

.standing--winner {
  color: var(--green);
}

@media (max-width: 1023px) {
  .vpanel__action {
    display: none;
  }
}

/* phones and tablets: the vote as a bar fixed at the bottom, above the tab bar */
.vbar {
  position: fixed;
  left: 8px;
  right: 8px;
  bottom: calc(80px + env(safe-area-inset-bottom, 0px));
  z-index: 39;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 8px 8px 16px;
  border: 1px solid var(--edge-light);
  border-radius: 14px;
  background: rgb(36 35 31 / 0.97);
  box-shadow:
    var(--ring),
    0 10px 24px rgb(0 0 0 / 0.5);
}

.vbar__total {
  display: grid;
  margin: 0;
  min-width: 0;
}

/* "community votes", then its round: each stays whole, the round under it when the bar is narrow */
.vbar__label {
  display: flex;
  flex-wrap: wrap;
  column-gap: 8px;
  font-size: 12px;
  color: var(--ink-muted);
}

.vbar__label > span {
  white-space: nowrap;
}

.vbar__amount {
  font-size: 18px;
  overflow-wrap: anywhere;
}

@media (min-width: 1024px) {
  .vbar {
    display: none;
  }
}

body:has(.vbar) {
  padding-bottom: calc(152px + env(safe-area-inset-bottom, 0px));
}

@media (min-width: 1024px) {
  body:has(.vbar) {
    padding-bottom: 0;
  }
}

.vsheet {
  display: grid;
  gap: 24px;
  padding: 8px 16px 24px;
}

.vsheet__title {
  margin: 0;
  font-size: var(--t-subhead);
  font-weight: 400;
}

/* my project, /build/me (docs/UI-STEP-3.md, section 2) ------------------------------------------------------------ */

.me__closed {
  margin-bottom: 24px;
}

/* the header card: the project page's ornamental frame, with the countdown and the public page on the right */
.me__head {
  margin-bottom: 28px;
}

.me__side {
  display: grid;
  justify-items: end;
  align-content: start;
  gap: 14px;
}

@media (max-width: 719px) {
  .me__side {
    grid-column: 1 / -1;
    justify-items: start;
  }
}

/* the tabs: separate cards, like the category cards; the open one raised */
.me__tabs {
  margin-bottom: 32px;
}

.me__tabs .pfilter {
  text-decoration: none;
}

.me__tabs .pfilter[aria-current="page"] {
  background: rgb(var(--warm-ink) / 0.12);
  border-color: rgb(var(--warm-ink) / 0.18);
  color: var(--ink);
  transform: translateY(-1px);
  box-shadow:
    var(--ring),
    inset 0 1px 0 rgb(var(--warm-ink) / 0.12),
    0 6px 14px rgb(0 0 0 / 0.38);
}

/* the overview's checklist: a card per step, its emblem, its name, its state */
.checklist {
  list-style: none;
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
}

.checklist__item {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  min-height: 52px;
  padding: 10px 16px;
  border: 1px solid var(--edge-light);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--ring);
  color: var(--ink);
  text-decoration: none;
  transition: background-color 160ms;
}

.checklist__item:hover {
  background: var(--elevated);
}

.checklist__mark {
  display: grid;
  color: rgb(var(--warm-ink) / 0.8);
}

.checklist__name {
  overflow-wrap: anywhere;
}

.checklist__state {
  font-size: 13px;
  text-align: right;
  color: var(--ink-muted);
}

.checklist__item[data-state="complete"] .checklist__state {
  color: var(--green-muted);
}

.checklist__item[data-state="not_started"] .checklist__state {
  color: var(--ink-subtle);
}

.me__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* the team tab: the project page's member plates, the lead marked, remove on the right */
.tcards li.tcard {
  grid-template-columns: 64px minmax(0, 1fr) auto;
}

.tcard__remove {
  align-self: center;
}

.chip--lead {
  justify-self: start;
  margin-top: 4px;
}

.invite__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin: 0 0 8px;
}

.invite__code {
  padding: 10px 14px;
  border: 1px solid var(--line-dark);
  border-radius: 8px;
  background: var(--ground);
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.45),
    0 1px 0 var(--line-light);
  font-size: 16px;
  letter-spacing: 0.06em;
}

.me__leave {
  padding-top: 8px;
}

/* phones: the four tabs two by two, all in view, rather than the category cards' sideways scroll */
@media (max-width: 719px) {
  .pfilters.me__tabs {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    overflow: visible;
    margin: 0 0 28px;
    padding: 0;
  }
}

/* a project's other categories, after its main chip: "+n" */
.chip--more {
  color: var(--green-muted);
  font-variant-numeric: tabular-nums;
}

/* a total that is unavailable (no round open) is cleared, not left stale: its chip goes (live-totals.js) */
.chip--wif:has([data-unavailable]) {
  display: none;
}

/* ---- dispatches, /build/updates (docs/UI-STEP-4.md) ------------------------------------------------------------ */

/* the header: the flat-disc heading across the rail, then the line, with the button on the right */
.sh--page {
  margin-bottom: 10px;
  font-size: var(--t-section);
  line-height: 1.1;
}

.disp-head {
  margin-bottom: 24px;
}

.disp-head__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 24px;
}

.disp-head__row .fleet__line {
  flex: 1 1 280px;
}

/* the filters: the category cards' make, with "newest first" quietly on the right */
.disp-filters {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px 24px;
  margin-bottom: 24px;
}

.disp-filters .pfilters {
  margin-bottom: 0;
  min-width: 0;
}

.disp-filters__order {
  flex: none;
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--ink-subtle);
}

@media (max-width: 719px) {
  .disp-filters {
    flex-direction: column;
    align-items: stretch;
  }
  .disp-filters .pfilters {
    margin-bottom: 0;
  }
  .disp-filters__order {
    align-self: flex-end;
  }
}

/* the feed: a card each, in the line system (a light inner edge in a dark ring, the engraved notches) */
.disps {
  list-style: none;
  display: grid;
  gap: 16px;
  margin: 0 0 24px;
  padding: 0;
}

.disp {
  position: relative;
  display: grid;
  gap: 16px;
  padding: 20px 22px;
  border: 1px solid var(--edge-light);
  border-radius: 3px;
  background: var(--surface);
  box-shadow: var(--ring);
}

.disp--pinned {
  border-color: rgb(var(--warm-ink) / 0.2);
}

.disp__head {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
}

.disp__logo {
  display: block;
}

.lplate--small {
  padding: 4px;
  border-radius: 3px;
  box-shadow:
    inset 1px 1px 0 rgb(var(--warm-ink) / 0.24),
    inset -1px -1px 0 rgb(0 0 0 / 0.5),
    var(--ring);
}

.lplate--small .lplate__inner {
  padding: 2px;
}

.lplate--small .lplate__letter {
  font-size: 22px;
}

/* the name and the author: each a 44px tap target, stacked with no overlap; the outer edges hang over the card's
   padding so the pair still sits level with the logo */
.disp__who {
  display: grid;
  min-width: 0;
  margin-block: -13px -10px;
}

.disp__project {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  min-width: 44px;
  min-height: 44px;
  max-width: 100%;
  color: var(--ink);
  font-size: var(--t-label);
  line-height: 1.2;
  overflow-wrap: anywhere;
}

.disp__author {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  justify-self: start;
  max-width: 100%;
  min-width: 44px;
  min-height: 44px;
  color: var(--ink-muted);
  font-size: 13px;
}

.cplate--tiny {
  flex: none;
  width: 24px;
  padding: 2px;
  border-radius: 2px;
}

.cplate--tiny .cplate__inner {
  padding: 1px;
}

.cplate--tiny .avatar--letter {
  font-size: 11px;
}

.disp__name {
  min-width: 0;
  overflow-wrap: anywhere;
}

.disp__side {
  display: grid;
  justify-items: end;
  gap: 8px;
}

.disp__when {
  font-size: 12px;
  color: var(--ink-subtle);
  white-space: nowrap;
}

.follow[aria-pressed="true"] {
  color: var(--green);
}

/* the body: the text cut at 4 lines, the image on the right */
.disp__body {
  display: grid;
  gap: 16px;
}

.disp__body--image {
  grid-template-columns: minmax(0, 1fr) 176px;
  align-items: start;
}

.disp__words {
  min-width: 0;
}

.disp__text {
  display: -webkit-box;
  margin: 0;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  white-space: pre-line;
  overflow-wrap: anywhere;
  line-height: 1.55;
}

.disp__text--open {
  display: block;
  -webkit-line-clamp: none;
  line-clamp: none;
}

.disp__more {
  appearance: none;
  min-height: 44px;
  margin: 0 0 -10px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--green-muted);
  font-size: 14px;
  cursor: pointer;
}

.disp__more:hover {
  color: var(--green);
}

.disp__more[hidden] {
  display: none;
}

.disp__thumb {
  appearance: none;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}

.disp__thumb img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.disp__thumb:hover .cplate {
  box-shadow:
    inset 1px 1px 0 rgb(var(--warm-ink) / 0.3),
    inset -1px -1px 0 rgb(0 0 0 / 0.5),
    var(--ring),
    0 6px 14px rgb(0 0 0 / 0.36);
}

.disp__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.chip--pinned {
  color: var(--green);
}

.disp__pin {
  margin-left: auto;
}

.disp__private {
  margin: 0;
  font-size: 13px;
}

.disp-empty {
  display: grid;
  justify-items: start;
  gap: 12px;
  margin-bottom: 24px;
}

.disp-empty p {
  margin: 0;
}

/* phones: the image under the text, follow next to the time */
@media (max-width: 599px) {
  .disp {
    padding: 16px;
  }
  .disp__head {
    grid-template-columns: 48px minmax(0, 1fr);
  }
  .disp__side {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .disp__body--image {
    grid-template-columns: minmax(0, 1fr);
  }
  .disp__thumb {
    max-width: 320px;
  }
}

/* the lightbox: the larger image over a scrim */
.lightbox {
  width: 100vw;
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
}

.lightbox::backdrop {
  background: rgb(0 0 0 / 0.78);
}

.lightbox__frame {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 12px;
  width: 100%;
  height: 100%;
  padding: 16px;
}

.lightbox__close {
  justify-self: end;
}

.lightbox__plate {
  max-width: min(1200px, 100%);
}

.lightbox__img {
  display: block;
  max-width: 100%;
  max-height: calc(100dvh - 120px);
  width: auto;
  height: auto;
}

/* the composer (composer.js): in the sheet on phones, the centered panel from 720px */
/* the spacing system (forms.css): the title 24px to the first field, fields 32px apart, the buttons 16px below */
.compose {
  display: block;
  padding: 8px 8px 16px;
}

.compose > .field + .field {
  margin-top: 32px;
}

.compose > .compose__error {
  margin-top: 16px;
}

@media (min-width: 720px) {
  .compose {
    padding: 28px 28px 24px;
  }
}

.compose__title {
  margin: 0 0 24px;
  font-size: var(--t-subhead);
  font-weight: 400;
}

.compose__text {
  display: block;
  width: 100%;
  min-height: 144px;
  resize: vertical;
}

.compose__left {
  font-size: 12px;
}

.compose__file {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.compose__image {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
}

.compose__pick[hidden],
.compose__hint[hidden] {
  display: none;
}

.compose__file:focus-visible + .compose__pick {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.compose__hint {
  font-size: 13px;
  color: var(--ink-subtle);
}

.compose__preview {
  display: flex;
  align-items: center;
  gap: 14px;
}

.compose__preview[hidden] {
  display: none;
}

.compose__thumb {
  width: 120px;
}

.compose__thumb img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.compose__off {
  appearance: none;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-muted);
  font-size: 14px;
  cursor: pointer;
}

.compose__off:hover {
  color: var(--green);
}

.compose__error:empty {
  display: none;
}

.compose__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 16px;
}

/* a switch: a track in the field's well, a knob that moves across; on, the knob is green */
.switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  cursor: pointer;
}

.switch__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.switch__track {
  flex: none;
  position: relative;
  width: 40px;
  height: 22px;
  border: 1px solid var(--edge-light);
  border-radius: 11px;
  background: var(--ground);
  box-shadow: var(--ring);
}

.switch__knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: rgb(var(--warm-ink) / 0.6);
  transition:
    transform 160ms var(--ease),
    background-color 160ms;
}

.switch__input:checked + .switch__track .switch__knob {
  transform: translateX(18px);
  background: var(--green);
}

.switch__input:focus-visible + .switch__track {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

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

/* a builder's profile, /build/builders/<id>, and settings, /build/profile (docs/UI-STEP-5.md) ---------------------- */

/* the page flows like the project page's: each part sets its own space below it, the grid's gap adds none */
.page[data-user],
.page[data-profile] {
  display: block;
}

/* only you can see it yet: a quiet line over the header */
.bp__quiet {
  margin: 0 0 16px;
  font-size: 14px;
}

.bp__title {
  display: grid;
  gap: 8px;
  min-width: 0;
}

.bp__name {
  margin: 0;
  font-size: clamp(34px, calc(2.6vw + 16px), 60px);
  font-weight: 400;
  line-height: 1.04;
  overflow-wrap: anywhere;
}

.bp__handle {
  margin: 0;
  color: var(--green-muted);
  font-size: var(--t-label);
}

/* the tagline, the location, the languages: each with its emblem */
.bp__meta {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  margin: 6px 0 0;
  padding: 0;
  color: var(--ink-muted);
}

.bp__fact {
  display: inline-flex;
  align-items: flex-start;
  gap: 8px;
  min-width: 0;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.bp__fact .emblem {
  flex: none;
  margin-top: 1px;
  color: rgb(var(--warm-ink) / 0.72);
}

.bp__side {
  align-self: start;
  display: grid;
  justify-items: end;
  gap: 14px;
}

.bp__links {
  flex-wrap: nowrap;
}

/* the links stand 44px tall to tap, their words where they were */
.bp__view,
.bp__feed {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-block: -12px;
  color: var(--green);
  text-decoration: none;
  white-space: nowrap;
}

/* phones: the picture and the name side by side, then everything stacked across the card; the icon buttons stay in
   one row */
@media (max-width: 719px) {
  .bp__title {
    display: contents;
  }
  .bp__name {
    grid-column: 2;
    grid-row: 1;
    align-self: center;
  }
  .bp__handle,
  .bp__meta,
  .bp__side {
    grid-column: 1 / -1;
  }
  .bp__handle {
    margin-top: -6px;
  }
  .bp__side {
    justify-items: start;
  }
}

/* the about panel: a framed panel with a row of chips per label */
.bp__about {
  display: grid;
  gap: 18px;
  margin-bottom: 44px;
  padding: 24px;
  border: 1px solid var(--edge-light);
  border-radius: 14px;
  background: rgb(var(--warm-ink) / 0.025);
  box-shadow: var(--ring);
}

@media (max-width: 479px) {
  .bp__about {
    padding: 18px 16px;
  }
}

.bp__row {
  display: grid;
  grid-template-columns: 140px minmax(0, 1fr);
  align-items: baseline;
  gap: 10px 20px;
}

@media (max-width: 599px) {
  .bp__row {
    grid-template-columns: minmax(0, 1fr);
  }
}

.bp__label {
  margin: 0;
  font-size: var(--t-label);
  font-weight: 400;
  color: var(--green-muted);
}

/* the profile's chips: the tile chip, a size up so a row of them reads */
.bp__chips {
  gap: 8px;
}

.bp__chips .chip,
.tags__tag {
  min-height: 32px;
  padding: 0 12px;
  font-size: 14px;
}

.bp__chips .chip .emblem {
  width: 16px;
  height: 16px;
}

.bp__bio {
  max-width: 64ch;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* one tile, the size it has in a row of them, never the whole width */
.bp__project {
  grid-template-columns: minmax(0, 240px);
}

.bp__feed {
  margin-top: 4px;
}

/* settings: the cards one under the other, sign out at the foot */
.ps__cards {
  display: grid;
  gap: 24px;
}

.ps__pic {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 20px 24px;
}

.ps__plate {
  width: 112px;
}

.ps__pic-actions {
  display: grid;
  gap: 10px;
  justify-items: start;
}

.ps__pic-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.ps__out {
  display: flex;
  justify-content: flex-end;
  margin-top: 32px;
}

/* the lists you pick from: chips, picked the way the category cards are */
.choices--chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.choice--chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
}

.choice--chip .choice__mark {
  grid-row: auto;
  padding-top: 0;
}

.choice--chip .choice__name {
  font-size: 14px;
}

/* picked: the sage edge, the words in full ink */
.choice--chip:has(.choice__radio:checked) {
  border-color: var(--green-muted);
}

.choice--chip:has(.choice__radio:checked) .choice__name {
  color: var(--ink);
}

.choice--chip:has(.choice__radio:disabled:not(:checked)) {
  opacity: 0.5;
}

/* skills: the tags, then the input, in one recessed field */
.tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-height: 52px;
  padding: 7px 10px;
  border: 1px solid var(--line-dark);
  border-radius: 8px;
  background: var(--ground);
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.45),
    0 1px 0 var(--line-light);
  cursor: text;
}

.tags:focus-within {
  border-color: rgb(var(--warm-ink) / 0.4);
}

.tags__list {
  display: contents;
  list-style: none;
}

.tags__tag {
  gap: 4px;
  padding-right: 2px;
}

.tags__remove {
  appearance: none;
  display: grid;
  place-items: center;
  /* a 44px target over the 32px chip, reaching into its padding and the gap after it; a long tag shrinks its
     words, never the button */
  flex: none;
  width: 44px;
  height: 44px;
  margin: -6px -10px -6px -8px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--ink-muted);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition:
    color 160ms,
    background-color 160ms;
}

.tags__remove:hover,
.tags__remove:focus-visible {
  color: var(--ink);
  background: rgb(var(--warm-ink) / 0.08);
}

.tags__input,
.step .field .tags__input[type="text"] {
  flex: 1 1 140px;
  min-width: 120px;
  min-height: 44px;
  margin: -4px 0;
  padding: 0 4px;
  border: 0;
  background: none;
  box-shadow: none;
  border-radius: 0;
  color: var(--ink);
  font: inherit;
}

/* the final ui pass (docs/UI-FINAL-PASS.md) --------------------------------------------------------------------- */

/* a page's header card: the ornamental frame with the page's name */
.doc__head {
  grid-template-columns: minmax(0, 1fr);
}

.doc__title {
  margin: 0;
  font-size: clamp(34px, calc(2.6vw + 16px), 60px);
  font-weight: 400;
  line-height: 1.04;
}

/* the contents on the left from 1024px, sticky; above the cards, a dropdown, on narrower screens */
.doc {
  display: grid;
  gap: 24px;
}

@media (min-width: 1024px) {
  .doc {
    grid-template-columns: 220px minmax(0, 1fr);
    align-items: start;
    gap: 40px;
  }
  .toc {
    position: sticky;
    top: 124px;
  }
  .toc .toc__summary {
    display: none;
  }
}

.doc__main {
  display: grid;
  gap: 24px;
  min-width: 0;
}

.toc__box {
  border: 1px solid var(--edge-light);
  border-radius: 12px;
  background: rgb(var(--warm-ink) / 0.025);
  box-shadow: var(--ring);
}

@media (min-width: 1024px) {
  .toc__box {
    padding: 10px;
  }
}

.toc__summary {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 52px;
  padding: 0 16px;
  list-style: none;
  cursor: pointer;
}

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

.toc__label {
  color: var(--green-muted);
}

.toc__current {
  margin-left: auto;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--ink-muted);
}

.toc__current::after {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin: 0 2px 3px 10px;
  border: solid currentColor;
  border-width: 0 1.25px 1.25px 0;
  rotate: 45deg;
  transition: rotate 180ms;
}

.toc__box[open] .toc__current::after {
  rotate: 225deg;
  margin-bottom: -1px;
}

.toc__list {
  list-style: none;
  display: grid;
  gap: 2px;
  margin: 0;
  padding: 0 6px 8px;
}

@media (min-width: 1024px) {
  .toc__list {
    padding: 0;
  }
}

.toc__link {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 8px;
  color: var(--ink-muted);
  text-decoration: none;
  transition:
    color 160ms,
    background-color 160ms;
}

.toc__link .emblem {
  flex: none;
  color: rgb(var(--warm-ink) / 0.72);
}

.toc__link:hover,
.toc__link:focus-visible {
  color: var(--ink);
  background: rgb(var(--warm-ink) / 0.05);
}

.toc__link[aria-current] {
  color: var(--ink);
  background: rgb(var(--warm-ink) / 0.08);
}

/* a section as a card under its flat-disc heading, the submission steps' card */
.doc__card {
  padding: 24px;
  border: 1px solid var(--edge-light);
  border-radius: 14px;
  background: rgb(var(--warm-ink) / 0.025);
  box-shadow: var(--ring);
  scroll-margin-top: 140px;
}

@media (max-width: 479px) {
  .doc__card {
    padding: 18px 16px;
  }
}

.doc__card > .sh {
  margin-bottom: 24px;
}

.doc__card > * + :is(p, .tiled, .trows, .choices, .accs) {
  margin-top: 16px;
}

.doc__card > .lead {
  max-width: 64ch;
  margin: 0;
}

.doc__under {
  margin-bottom: 0;
}

.doc__foot {
  margin: 8px 0 0;
}

.doc__terms {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--green);
  text-decoration: none;
}

/* a numbered list, each number in a framed tile */
.tiled {
  list-style: none;
  display: grid;
  gap: 14px;
  max-width: 72ch;
  margin: 0;
  padding: 0;
}

.tiled__item {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  align-items: start;
  gap: 14px;
}

.tiled__n {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 1px solid var(--edge-light);
  border-radius: 6px;
  background: var(--surface);
  box-shadow:
    inset 0 1px 0 rgb(var(--warm-ink) / 0.1),
    var(--ring);
  color: var(--green-muted);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.tiled__text {
  padding-top: 5px;
  overflow-wrap: anywhere;
}

/* the timeline: rows on the line system, the dates in tabular figures */
.trows {
  display: grid;
  max-width: 640px;
  margin: 0;
}

.trows__row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 4px 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--line-dark);
  box-shadow: 0 1px 0 var(--line-light);
}

.trows dt,
.trows dd {
  margin: 0;
}

.trows dd {
  color: var(--ink-muted);
}

.trows__date {
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* the categories: the picker's cards, to read, not to pick */
.rcats {
  list-style: none;
  margin-bottom: 0;
  padding: 0;
}

.rcat:hover {
  background: var(--surface);
}

/* the faq: accordions, one open at a time; a plus that turns into a minus */
.accs {
  display: grid;
  max-width: 72ch;
}

.acc {
  border-bottom: 1px solid var(--line-dark);
  box-shadow: 0 1px 0 var(--line-light);
  scroll-margin-top: 140px;
}

.acc__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 52px;
  padding: 8px 0;
  list-style: none;
  cursor: pointer;
  font-size: var(--t-label);
  transition: color 160ms;
}

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

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

.acc__mark {
  display: grid;
  flex: none;
  color: rgb(var(--warm-ink) / 0.72);
}

.acc__minus,
.acc[open] .acc__plus {
  display: none;
}

.acc[open] .acc__minus {
  display: block;
}

.acc__a {
  margin: 0;
  padding: 0 40px 18px 0;
  color: var(--ink-muted);
  max-width: 68ch;
}

/* the terms: one card, the numbered tiles */
.doc__card--terms .tiled {
  gap: 18px;
}

/* the judge panel: the header card with the round, the votes left in ivory tiles and the countdown */
.jhead {
  grid-template-columns: minmax(0, 1fr) auto;
}

.jhead__title {
  display: grid;
  gap: 14px;
  min-width: 0;
}

.jhead__round {
  margin: 0;
  font-size: clamp(34px, calc(2.6vw + 16px), 60px);
  font-weight: 400;
  line-height: 1.04;
}

.jhead__line {
  margin: 0;
}

.jhead__line:empty {
  display: none;
}

.jhead__side {
  align-self: start;
}

.jcount {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.jcount:empty {
  display: none;
}

.jcount__label,
.jcount__of {
  color: var(--green-muted);
}

.jcount__tiles {
  display: inline-flex;
  gap: 3px;
}

.jcount .wheel {
  --wh: 34px;
  width: 24px;
  font-size: 22px;
}

.jhead__status:empty {
  display: none;
}

@media (max-width: 719px) {
  .jhead {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* the judge panel (docs/JUDGE-PANEL.md): the list on the left, "your ballot" sticky on the right from 1024px; on
   phones the ballot is a bar at the foot that opens it as a bottom sheet */
.jp {
  display: grid;
  /* an auto column would take the toggles' unwrapped row as its minimum and scroll the page sideways on phones */
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
}

@media (min-width: 1024px) {
  .jp {
    grid-template-columns: minmax(0, 1fr) clamp(280px, 26vw, 340px);
    align-items: start;
    gap: 32px;
  }
  .jp__side {
    position: sticky;
    top: 124px;
  }
}

@media (max-width: 1023px) {
  .jp__side {
    display: none;
  }
}

.jp__main {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
  min-width: 0;
}

/* the tools: search, category, and all / not on my ballot / on my ballot */
.jtools {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 12px 16px;
}

.jtools__field {
  display: grid;
  gap: 6px;
  flex: 1 1 200px;
  min-width: 0;
}

.jtools__search,
.jtools__category {
  /* one height, so the two labels line up */
  box-sizing: border-box;
  height: 44px;
  padding: 0 12px;
  border: 1px solid var(--line-dark);
  border-radius: 8px;
  background: var(--ground);
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.45),
    0 1px 0 var(--line-light);
  color: var(--ink);
  font: inherit;
}

.jtools__toggles {
  flex: 1 1 100%;
  margin: 0;
}

.jtools__toggle {
  padding: 6px 14px;
}

/* the projects: cards in a list */
.jcards {
  list-style: none;
  display: grid;
  gap: 16px;
  margin: 0;
  padding: 0;
}

.jcard {
  padding: 20px;
  border: 1px solid var(--edge-light);
  border-radius: 14px;
  background: rgb(var(--warm-ink) / 0.025);
  box-shadow: var(--ring);
}

.jcard[hidden] {
  display: none;
}

.jcard__head {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  align-items: start;
  gap: 12px 18px;
}

.jcard__plate {
  width: 72px;
}

.jcard__who {
  display: grid;
  gap: 10px;
  min-width: 0;
}

.jcard__who .card__title {
  margin: 0;
}

.jcard__line {
  margin: 0;
  color: var(--ink-muted);
  overflow-wrap: anywhere;
}

.jcard__flag {
  margin: 0;
  color: var(--alert);
  font-size: 13px;
}

.jcard__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 16px;
}

@media (max-width: 599px) {
  .jcard__head {
    grid-template-columns: 56px minmax(0, 1fr);
  }
  .jcard__plate {
    width: 56px;
  }
}

/* the team's pictures, overlapping a little */
.jteam {
  list-style: none;
  display: flex;
  margin: 0;
  padding: 0;
}

.jteam__face + .jteam__face {
  margin-left: -6px;
}

.jteam__face .avatar {
  box-shadow: 0 0 0 2px var(--frame-fill);
}

/* the checks in plain words, each with its mark */
.jchecks {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin: 0;
  padding: 0;
  font-size: 14px;
}

.jcheck {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ink-muted);
  cursor: help;
}

.jcheck--pass .emblem {
  color: var(--green-muted);
}

.jcheck--fail,
.jcheck--fail .emblem {
  color: var(--alert);
}

/* your ballot: framed slots, numbered while empty */
.jballot {
  padding: 20px;
  border: 1px solid var(--edge-light);
  border-radius: 14px;
  background: rgb(var(--warm-ink) / 0.025);
  box-shadow: var(--ring);
}

.sheet .jballot {
  border: 0;
  background: none;
  box-shadow: none;
  padding: 4px 12px 12px;
}

.jballot > .sh {
  margin-bottom: 16px;
}

.jballot__note {
  margin: 12px 0 0;
  font-size: 14px;
}

.jballot__note:empty {
  display: none;
}

.jslots {
  list-style: none;
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
}

.jslot {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) 44px;
  align-items: center;
  gap: 10px;
  min-height: 52px;
  padding: 4px 4px 4px 6px;
  border: 1px solid var(--edge-light);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--ring);
}

.jslot--empty {
  grid-template-columns: 40px;
  border-style: dashed;
  border-color: rgb(var(--warm-ink) / 0.18);
  background: rgb(0 0 0 / 0.12);
  box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.4);
}

.jslot__n {
  display: grid;
  place-items: center;
  width: 40px;
  color: rgb(var(--warm-ink) / 0.4);
  font-variant-numeric: tabular-nums;
}

.jslot__plate {
  width: 40px;
}

.jslot__name {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.jslot__remove {
  appearance: none;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--ink-muted);
  font-size: 18px;
  cursor: pointer;
  transition:
    color 160ms,
    background-color 160ms;
}

.jslot__remove:hover,
.jslot__remove:focus-visible {
  color: var(--ink);
  background: rgb(var(--warm-ink) / 0.08);
}

.jslot__remove:disabled {
  opacity: 0.4;
  cursor: default;
}

/* a project dropped into its slot: in from above, a short settle; with reduced motion it simply appears */
.jslot.is-dropping {
  animation: slot-drop 420ms var(--spring) both;
}

@keyframes slot-drop {
  from {
    opacity: 0;
    transform: translateY(-14px) scale(0.96);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

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

/* phones: the ballot as a bar at the foot, over the tab bar, the vote bar's make */
.jbar {
  position: fixed;
  left: 8px;
  right: 8px;
  bottom: calc(80px + env(safe-area-inset-bottom, 0px));
  z-index: 39;
  border: 1px solid var(--edge-light);
  border-radius: 14px;
  background: rgb(36 35 31 / 0.97);
  box-shadow: var(--panel-shadow);
}

.jbar__open {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 52px;
  padding: 0 16px;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

@media (min-width: 1024px) {
  .jbar {
    display: none;
  }
}

@media (max-width: 1023px) {
  body:has(.jbar) {
    padding-bottom: calc(152px + env(safe-area-inset-bottom, 0px));
  }
}

/* "added to your ballot, n left", with undo for 5 seconds */
.jtoast {
  position: fixed;
  left: 50%;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  z-index: 45;
  display: flex;
  align-items: center;
  gap: 16px;
  max-width: calc(100vw - 32px);
  padding: 4px 6px 4px 16px;
  border: 1px solid var(--edge-light);
  border-radius: 12px;
  background: var(--panel);
  box-shadow: var(--panel-shadow);
  transform: translateX(-50%);
}

.jtoast[hidden] {
  display: none;
}

@media (max-width: 1023px) {
  .jtoast {
    bottom: calc(144px + env(safe-area-inset-bottom, 0px));
  }
}

.jtoast__undo {
  appearance: none;
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--green);
  font: inherit;
  cursor: pointer;
}

.jtoast__undo:hover,
.jtoast__undo:focus-visible {
  background: rgb(var(--warm-ink) / 0.08);
}

/* the details drawer */
/* the drawer (docs/JUDGE-DRAWER.md), on the spacing system's steps: the drawer's padding (24px, 16px on phones) all
   round and in the footer; in the header 16px from the top row to the line, 12px to the chips, 8px between chips;
   32px between blocks, a block's heading 12px over its content */
.jdrawer {
  --jd-pad: 24px;
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
}

.jdrawer__main {
  flex: 1 0 auto;
  display: grid;
  gap: 32px;
  padding: var(--jd-pad) var(--jd-pad) 32px;
  min-width: 0;
}

.jdrawer__head {
  min-width: 0;
}

.jdrawer__head > * {
  margin-block: 0;
}

.jdrawer__top + * {
  margin-top: 16px;
}

.jdrawer__line + *,
.jdrawer__chips + * {
  margin-top: 12px;
}

/* the logo, the name and close on one line, centred; the name gives way, close never wraps */
.jdrawer__top {
  display: flex;
  align-items: center;
  gap: 16px;
  min-width: 0;
}

.jdrawer__plate {
  flex: none;
  width: 48px;
}

.jdrawer__name {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-size: var(--t-subhead);
  font-weight: 400;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.jdrawer__close {
  flex: none;
  white-space: nowrap;
}

.jdrawer__line {
  color: var(--ink-muted);
  overflow-wrap: anywhere;
}

.jdrawer__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.jdrawer__block {
  display: grid;
  gap: 12px;
  min-width: 0;
}

.jdrawer__block .jdrawer__sub {
  margin: 0;
}

/* the drawer's rows, two columns at every width: a narrower label, so the value has the room
   (docs/COPY-SEPARATORS-CATEGORIES.md, sections 2 and 4) */
/* in em, so it grows with the type: the longest one word a label has ("transactions", 12 characters of a font
   whose every character is 0.6em) always fits */
.jdrawer .detail__row {
  grid-template-columns: minmax(0, 8em) minmax(0, 1fr);
  align-items: baseline;
  gap: 16px;
}

@media (max-width: 599px) {
  .jdrawer .detail__row {
    grid-template-columns: minmax(0, 7.4em) minmax(0, 1fr);
    gap: 12px;
  }
}

/* the ballot's button, always at the foot of the drawer while the rest scrolls */
.jdrawer__foot {
  position: sticky;
  bottom: 0;
  z-index: 1;
  padding: 16px var(--jd-pad) calc(16px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--hairline);
  background: var(--panel);
}

@media (max-width: 599px) {
  .jdrawer {
    --jd-pad: 16px;
  }
  .jdrawer__main {
    padding-top: 8px; /* under the sheet's grip */
  }
  .jdrawer__foot .jcard__vote {
    width: 100%;
  }
}
