@layer components {
  /* The join link

     A URL is a long, unbreakable, monospaced thing and the page it sits on is
     not wide. So it gets a field of its own rather than a line of prose: it
     scrolls inside itself, it can be selected in one gesture, and it cannot
     push the panel around it wider than the column. */

  .joinlink {
    display: flex;
    align-items: center;
    gap: var(--space);
  }

  /* A step below the secondary size, which is one of the few places in this
     product that earns it: the card is on the same 32rem measure the invite
     form beside it uses, and this is a value to be copied rather than prose to
     be read. The smaller type is what fits the whole URL in the field on a
     normal host name instead of cutting it mid-code. It still scrolls if the
     host is long — hence a real input, and hence selecting on click. */
  /* Two classes for the same reason capture.css needs them: this field is an
     .input as well, and on equal specificity the later file wins. joinlink.css
     is read before forms.css, so the smaller type and the sunk background were
     being taken back by .input. */
  .input.joinlink__url {
    flex: 1;
    min-width: 0;
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    background: var(--surface-sunk);
    cursor: text;
  }

  .joinlink__state {
    flex-wrap: wrap;
    gap: var(--space) var(--space-2);
    font-size: var(--text-sm);
    color: var(--ink-faint);
  }

  /* Spent is a fact, not a failure — it is what the limit was for. Said in the
     warning colour rather than the danger one: nothing is broken, the link has
     simply finished. */
  .joinlink__count--spent { color: var(--warn); }

  .joinlink__limit { flex: none; }

  /* Wide enough for the cap and no wider. A number field sized like a text
     field makes the row read as a form somebody has to fill in. */
  .joinlink__number { width: 5rem; }
}
