/* Platform-wide avatar atom. `.global-avatar` is the single circular person
   image with an initials fallback — the one face treatment for a worker, a
   member, a payee, a rater, or the signed-in user in the sidebar.

   It replaced six hand-rolled copies of the same circle:
     • main.css            .avatar + .avatar-xs/-sm/-md/-lg/-xl
     • star-rating.css     .rating-avatar
     • sidebar.css         .global-sidebar-profile-avatar / img.sidebar-profile-photo
     • payment-dashboard   .payments-bill-row__avatar(--img), .bill-sidebar__avatar
     • payment-dashboard   .payments-pay-confirm__avatar(--img)
       workers.css         .worker-hero-avatar
       profile.css         .profile-avatar          (dead 132px hero)

       <span class="global-avatar global-avatar--sm global-avatar--ink">RH</span>
       <img class="global-avatar global-avatar--sm" src="..." alt="">
       <span class="global-avatar global-avatar--xs global-avatar--empty"
             aria-hidden="true"><i class="bi bi-person-dash"></i></span>

   SIZE LADDER — five steps, and only five. A face is xs/sm/md/lg/xl; there is no
   in-between. The hero step is ONE value: the three former hero sizes (96px dead
   .avatar-xl, 104px worker hero, 132px dead .profile-avatar) collapse into --xl.

   FILL is a modifier, never a default. The base is geometry only, exactly like
   the `.avatar` it replaces, so a caller that supplies its own fill (a feature
   skin like `.global-sidebar-profile-avatar`) keeps winning and nothing re-tints. Pick one of
   --ink / --soft / --muted / --empty when you want the primitive to own it.

   Every color, radius, and shadow resolves to a token (ADR-125). --radius-pill
   on a square box renders the same circle 50% did. */

/* ── Canonical component ── geometry only: a circle that clips its image and
   centers its initials. Never sets a fill; see the fill modifiers below. */
.global-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    overflow: hidden;
    border-radius: var(--radius-pill);
    font-weight: var(--font-weight-medium);
}

/* A photo inside the circle, and the same circle used AS the photo — both fill
   the box and crop to center, so `<img class="global-avatar">` needs no wrapper
   (this is what retired .bill-row__avatar--img, .pay-confirm__avatar--img, and
   img.sidebar-profile-photo). */
.global-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

img.global-avatar {
    display: block;
    object-fit: cover;
}

/* ── Size ladder ── each step carries its own type size so initials always fit. */

/* xs — 24px. Dense rows and table cells (bill rows, meeting pickers). */
.global-avatar--xs {
    width: 24px;
    height: 24px;
    font-size: var(--font-size-2xs);
}

/* sm — 32px. The default face: lists, pickers, the sidebar profile row. */
.global-avatar--sm {
    width: 32px;
    height: 32px;
    font-size: var(--font-size-xs);
}

/* md — 40px. Card and roster rows where the face leads the line. */
.global-avatar--md {
    width: 40px;
    height: 40px;
    font-size: var(--font-size-md);
}

/* lg — 48px. Detail headers, modal payee identity. */
.global-avatar--lg {
    width: 48px;
    height: 48px;
    font-size: var(--font-size-base);
}

/* xl — 104px. The ONE hero step (worker detail header). No type token exists
   above 20px, so the hero glyph keeps the size the hero already rendered. */
.global-avatar--xl {
    width: 104px;
    height: 104px;
    font-size: 2.2rem;
}

/* ── Fill modifiers ── each collapses a fill recipe that was hand-rolled per
   feature. Mutually exclusive: they all set background + color at equal
   specificity, so stacking two just lets the later one win — pick one. */

/* --ink: solid ink circle with white initials. Avatars are neutral on every
   tenant — a person is not the org's marketing surface. Was .rating-avatar,
   .bill-sidebar__avatar, and .payments-pay-confirm__avatar (which hard-coded `white`). */
.global-avatar--ink {
    background: var(--color-action);
    color: var(--color-neutral-ink-fg);
}

/* --soft: tinted disc behind dark initials — a quieter face for a dense row
   that shouldn't carry a solid disc. Was .payments-bill-row__avatar. */
.global-avatar--soft {
    background: var(--color-action-tint-pressed);
    color: var(--color-text);
}

/* --muted: neutral card fill with a hairline, for a face on a busy neutral
   surface that must not read as branded. Was .worker-avatar-initials. */
.global-avatar--muted {
    background: var(--color-card-bg);
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
}

/* --gradient: the hero's ink gradient behind large initials. Was
   .worker-hero-avatar--initials / .profile-avatar--initials.
   The far stop only lifts 15% toward white so the white initials hold the
   4.5:1 floor where the gradient lightens; a bigger lift (the old 55%)
   dropped them to ~3.5:1. Keep the sheen small — a highlight, not a fade. */
.global-avatar--gradient {
    background: linear-gradient(135deg, var(--color-action), color-mix(in srgb, var(--color-action) 85%, white));
    color: var(--color-neutral-ink-fg);
}

/* --empty: the UNASSIGNED seat — nobody holds this slot yet. Previously
   undefined platform-wide, so each surface improvised (the bill row drew a
   person-dash glyph inside a full brand-tinted disc, reading like a real
   person). The explicit treatment: no fill, a dashed hairline, a quiet glyph — an
   open outline that reads as "empty" at a glance and never as a person. It is a
   STATE, not a fill; combine it with a size, never with --ink/--soft/--muted.

   The glyph is --color-text-secondary (#64748b, 4.76:1 on the white card), NOT
   --color-text-muted (#9ca3af, 2.57:1). The seat this replaces drew brand ink on
   a brand tint at roughly 14:1, and a consolidation must never hand back less
   contrast than the thing it absorbed — muted would have failed both the 4.5:1
   text floor and the 3:1 non-text floor for a glyph that carries meaning. */
.global-avatar--empty {
    background: transparent;
    color: var(--color-text-secondary);
    /* 1.5px dashed --color-text-secondary (#64748b, ~4.8:1 on the white card)
       clears the 3:1 non-text floor. The old 1px --color-border (#d0d4db) was
       1.49:1 — a shape carrying "empty" meaning that barely showed on a bright
       screen. Nick picked the stronger outline in the visual review. */
    border: 1.5px dashed var(--color-text-secondary);
}

/* ── Ring ── the hero's halo: an ink-tinted spread ring plus the standard small
   elevation. Both layers are real tokens from tokens.css — the ring literal is
   NOT re-declared here under a component-local property name, because renaming a
   raw elevation into a --custom-prop the ratchet's regex misses would dodge the
   gate without removing the literal (ADR-125 keeps elevation off raw values, and
   the point is the value, not the property name). */
.global-avatar--ring {
    box-shadow: var(--shadow-avatar-ring), var(--shadow-sm);
}
