@layer components {
  /* A row standing for a person or a holon in a list.
   *
   * The rule (METIS-pub#399): clicking the row opens that person or holon.
   * Where the viewer may edit the row, a pen sits on it and opens the inline
   * editor. Rows used to swallow the click to open the editor, which meant the
   * only way to reach a person's page from a team list was to know the URL.
   *
   * The row owns all of its own layout — body, avatar, name column. It used to
   * borrow those from `detail.css`, which the styleguide does not load, so the
   * gallery drew the row stacked vertically, looking nothing like any page that
   * ships it: a component whose layout lives in a page stylesheet cannot be
   * reviewed in the one place built for reviewing components.
   *
   * The two flow-edit forms use these same classes for their header rows. That
   * is not borrowing — the editor *is* the row, in its open state, which is why
   * the header carries the same avatar and name beside the fields.
   */
  /* The list a row lives in. It is part of the component because the spacing
   * between rows is: the person page put rows straight into `.membership-group`
   * and they rendered flush against each other, because the only thing that had
   * ever separated them was the holon side's own list wrapper (METIS-pub#399
   * review). */
  .entity-row-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
  }

  /* Inside a disclosure rail the rail is what groups the rows, so their own
   * borders are noise — the "boxes" METIS-pub#416 reported as not obviously
   * belonging to their heading. The border is kept transparent rather than
   * removed so the row does not shift by a pixel when it opens. */
  .entity-row-list--flush {
    gap: 2px;
    margin-bottom: 0;
  }

  .entity-row-list--flush > .entity-row {
    border-color: transparent;
    border-radius: var(--radius-sm);
  }

  .entity-row {
    position: relative;
    padding: var(--space-2);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-md);
    color: inherit;
    transition: background var(--transition-fast), border-color var(--transition-fast);
  }

  .entity-row:hover {
    background: var(--color-surface-2);
    border-color: var(--color-border);
  }

  /* The row's one flex line: avatar, name column, chips, then the pen, which
   * takes the free space with `margin-left: auto`. */
  .entity-row__body {
    display: flex;
    align-items: center;
    gap: var(--space-2);
  }

  /* The name column — a name, optionally with a type chip under it. `min-width:
   * 0` so a long name ellipses instead of pushing the chips off the row. */
  .entity-row__name {
    display: flex;
    flex: 1;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
    min-width: 0;
  }

  /* The avatar: a person's photo or a holon's logo, or a placeholder holding
   * the same 36px circle so names line up down a list either way. */
  .entity-row__photo,
  .entity-row__avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    flex-shrink: 0;
  }

  .entity-row__photo {
    object-fit: cover;
  }

  .entity-row__avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-border-light);
    color: var(--color-text-muted);
  }

  /* The stretched link: its ::after covers the whole row, so the click target is
   * the row while the accessible name stays on the anchor. */
  .entity-row__link {
    color: var(--color-text);
    font-weight: 500;
    text-decoration: none;
  }

  .entity-row__link::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
  }

  .entity-row:hover .entity-row__link {
    color: var(--color-accent);
  }

  /* Keyboard focus belongs on the row, not on a zero-height anchor behind it:
   * the stretched ::after would otherwise draw the ring around the whole row
   * anyway, but clipped by the overlay's own stacking. */
  .entity-row__link:focus-visible {
    position: static;
    outline: none;
  }

  .entity-row:has(.entity-row__link:focus-visible) {
    outline: var(--focus-ring-width) solid var(--focus-ring);
    outline-offset: 2px;
  }

  /* Anything else interactive has to sit above the stretched overlay, or the
   * row link eats it. Links and buttons are the obvious ones — the pen, and the
   * contact icons that are real links. `[title]` is not padding: a phone or chat
   * contact icon is a <span title="phone: …"> and the grants chip carries its
   * full list on `title`, so without this the overlay silently swallowed the
   * tooltip and the number with it. */
  .entity-row a:not(.entity-row__link),
  .entity-row button,
  .entity-row [title] {
    position: relative;
    z-index: 1;
  }

  /* Always visible, never hover-only: each is a permission answer, and a
   * control that appears on hover cannot be found on a touch screen.
   *
   * The notes bubble shares every rule here. margin-left:auto on both is what
   * keeps the group at the row's edge when only one of them renders — a reader
   * with notes rights but no team-member gets the bubble alone, and without it
   * that row's control sat against the chips while its neighbours' sat at the
   * edge (METIS-pub#418). */
  .entity-row__edit,
  .entity-row__notes {
    flex-shrink: 0;
    margin-left: auto;
    color: var(--color-text-muted);
  }

  /* Once both render, only the first needs the auto margin; the pair then sits
   * together rather than splitting across the row. */
  .entity-row__notes + .entity-row__edit {
    margin-left: 0;
  }

  .entity-row:hover .entity-row__edit,
  .entity-row__edit:focus-visible,
  .entity-row:hover .entity-row__notes,
  .entity-row__notes:focus-visible {
    color: var(--color-text);
  }

  /* An inline <svg> with only a viewBox has no intrinsic size, and .btn svg is
   * deliberately not sized centrally (see button.css) — so this local rule is
   * the whole sizing for both controls. */
  .entity-row__edit svg,
  .entity-row__notes svg {
    width: 16px;
    height: 16px;
  }

  .entity-row__journey {
    flex-shrink: 0;
  }
}

@layer components {
  /* A row with its editor open. The row is still the row: its name, avatar and
   * status stay in the head, and the fields hang off an accent rail below —
   * the same "head stays, body folds out beneath it" shape as .disclosure, one
   * level down. Before this the pen swapped the whole row away and the name
   * came back under a "HOLON" label in a different layout, so nothing said
   * which row you were editing (METIS-pub#416).
   */
  .entity-row--open,
  .entity-row--open:hover {
    background: var(--color-accent-quiet);
  }

  /* The stretched .entity-row__link::after is positioned against the nearest
   * positioned ancestor. With the editor inside the row that is the whole row,
   * so the overlay covers every input in it and a click into a textarea
   * navigates to the holon. Making the head the containing block puts the
   * overlay back over the head alone. */
  .entity-row--open {
    position: static;
  }

  .entity-row--open > .entity-row__body {
    position: relative;
  }

  /* The editor's own rail, drawn from the avatar's centre: the row's padding
   * plus half the 36px avatar. */
  .entity-row__panel {
    border-left: 1.5px solid var(--color-accent);
    margin: 0 var(--space-2) var(--space-2) calc(var(--space-2) + 18px);
    padding: var(--space-3) 0 var(--space-2) var(--space-6);
  }

  /* The close control sits in the pen's slot and has to read as pressed, or
   * the only thing distinguishing "open" from "closed" is the panel itself. */
  .entity-row__edit[aria-expanded="true"] {
    color: var(--color-text);
    background: var(--color-surface);
    /* A border, not an inset shadow: the shadow scale is for elevation, and a
     * pressed control is not raised. The pen's own slot reserves the space, so
     * adding the border does not move it. */
    border: 1px solid var(--color-border);
  }
}
