@layer components {
  /* Avatars

     A face against a name, and initials until there is one. No colour: the
     palette carries one accent and three signals and nothing else, so a rainbow
     of tinted circles would be the loudest thing in a calm list. The letters do
     the identifying. */

  .avatar {
    display: inline-grid;
    place-items: center;
    flex: none;
    overflow: hidden;
    border-radius: var(--radius-pill);
    background: var(--surface-sunk);
    color: var(--ink-muted);
    font-weight: var(--weight-bold);
    letter-spacing: 0.02em;
    line-height: 1;
    user-select: none;
  }

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

  /* Initials are set on the scale like everything else. The small one used to
     carry a raw 0.6875rem — 11px, the only hard-coded font size in the product
     and a third of the way below the floor the tokens set. Two letters do not
     need to be large to be recognised, but they do need to be on the scale:
     the moment one thing is allowed off it, the scale is a suggestion. */
  .avatar--small  { width: 1.75rem; height: 1.75rem; font-size: var(--text-xs); }
  .avatar--medium { width: 2.25rem; height: 2.25rem; font-size: var(--text-sm); }
  .avatar--large  { width: 6rem;    height: 6rem;    font-size: var(--text-lg); }

  /* A person in a list: face then name, never one without the other. */
  .person {
    display: inline-flex;
    align-items: center;
    gap: var(--space);
    min-width: 0;
  }

  .person__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Two faces where there is room for one and a bit. The assignee is the one
     being read, so it is in front and fully drawn; the supporter is the second
     fact this rail carries (D-03 gives Waiting On its own colour and support
     its own slot), and it says so by being visible enough to count and quiet
     enough not to be mistaken for the owner.

     The ring is the row's own background, so the overlap reads as one in front
     of the other rather than as two circles touching. */
  .faces {
    display: inline-flex;
    align-items: center;
    /* Reversed, so the assignee — first in the markup, because it is the fact
       being read — ends up on the right, flush with the column. The supporter
       tucks in behind it on the left rather than hanging off the edge of the
       row. */
    flex-direction: row-reverse;
  }

  .faces > .avatar,
  .faces > .faces__empty { position: relative; z-index: 1; }

  /* The ring that makes the overlap legible, and it has to be on the face in
     front. The one behind carries one too, but a ring on the back of a stack
     is covered by whatever is on top of it — it can only ever draw against
     the page, where it is the same colour as the page and invisible. The
     separation people actually see is this one: the front face holding the
     row's own background between itself and the face it sits on. */
  .faces > .avatar { box-shadow: 0 0 0 2px var(--canvas); }

  .faces__support {
    display: inline-flex;
    position: relative;
    z-index: 0;
    margin-right: calc(var(--space) * -1.25);
  }

  .faces__support .avatar {
    box-shadow: 0 0 0 2px var(--canvas);
    opacity: 0.85;
  }

  /* Both rings are the surface they are drawn on, so both follow it when the
     row tints under the pointer. A ring left on --canvas over a hovered row is
     a pale outline around the face, which is the artefact this is here to
     avoid in the first place. */
  .task:hover .faces__support .avatar,
  .menu__item:hover .faces__support .avatar,
  .task:hover .faces > .avatar { box-shadow: 0 0 0 2px var(--surface-hover); }

  /* Nobody yet. Dashed, like the status that has not started. */
  .faces__empty {
    display: inline-grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    color: var(--ink-faint);
    transition: color var(--transition);
  }
}
