/* ═══ 19. IDENTITY PICKER (plan doc 12 §1) ═══════════════════════════════
   Netflix-style "who's working?" gate + the header identity badge. Layered
   above the sign-in gate (z 1000) so it appears once login has revealed the
   app, and covers everything while a daily pick is pending. Same warm paper &
   ink language as the rest of the app — no accent hue. */

.identity-gate {
  position: fixed; inset: 0; z-index: 1100;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg);
  padding: var(--ab-pad-y) var(--ab-pad-x);
  transition: opacity var(--dur-base) ease, visibility var(--dur-base) ease;
}
.identity-gate.hidden { opacity: 0; visibility: hidden; pointer-events: none; }

.idp-card {
  width: min(100%, 440px);
  display: flex; flex-direction: column; gap: 22px;
}

/* card.innerHTML rebuilds fresh on every showView() call, so .idp-head is a
   brand-new element each time — same mechanism that makes .idp-tile's own
   entrance replay correctly below. Gives the tiles/PIN/setpin view switch an
   entrance instead of an instant snap; needs no JS change. */
.idp-head {
  position: relative; text-align: center;
  animation: idp-view-in var(--dur-base) ease-out both;
}
@keyframes idp-view-in {
  from { opacity: 0; transform: translateY(4px); }
}
.idp-title {
  font-size: var(--text-xl); font-weight: 600; letter-spacing: .3px;
  color: var(--fg); line-height: var(--lh-title);
}
.idp-sub {
  margin-top: 8px; font-size: var(--text-base);
  color: var(--ink-faint); line-height: var(--lh-body);
}
.idp-back {
  position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  font-size: 22px; line-height: 1; color: var(--ink-soft);
  border: 1px solid var(--hairline); border-radius: 50%;
  transition: background var(--dur-fast), color var(--dur-fast);
}
.idp-back:hover { background: var(--hover-bg); color: var(--fg); }

/* ── tile grid ────────────────────────────────────────────────────────── */

.idp-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 14px; justify-items: center;
}
.idp-tile {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 10px; border-radius: var(--radius-md);
  border: 1px solid transparent;
  transition: transform var(--dur-fast), background var(--dur-fast), border-color var(--dur-fast);
  animation: idp-tile-in var(--dur-base) ease-out both;
}
.idp-tile:hover { background: var(--hover-bg); border-color: var(--hairline); }
.idp-tile:active { transform: scale(0.96); }
/* Netflix-style stagger for the "who's working?" grid — rare, once-per-
   session moment, so a little delight is in budget. Capped at the first six
   tiles: card.innerHTML rebuilds fresh every renderTiles() call, so this
   replays correctly each time the gate (or "Switch account") shows it. */
.idp-tile:nth-child(1) { animation-delay: 0ms; }
.idp-tile:nth-child(2) { animation-delay: 40ms; }
.idp-tile:nth-child(3) { animation-delay: 80ms; }
.idp-tile:nth-child(4) { animation-delay: 120ms; }
.idp-tile:nth-child(5) { animation-delay: 160ms; }
.idp-tile:nth-child(6) { animation-delay: 200ms; }
@keyframes idp-tile-in {
  from { opacity: 0; transform: translateY(6px); }
}
/* Per-character glow: each profile carries a --hue (set inline by identity.js)
   so its circle reads as its own "character" — a faint hue-tinted ring at
   rest, blooming into a full mouse-tracked glow on hover/press. --mouse-x/-y
   are px offsets identity.js writes on pointer move/down; they default to the
   circle's center (50%) so keyboard focus still glows evenly. Works on touch
   too: identity.js toggles .is-glow on pointerdown/up since touch has no
   sustained :hover. */
.idp-avatar {
  position: relative; z-index: 1;
  --sat: 55%; --lit: 55%;
  width: 72px; height: 72px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--text-xl); font-weight: 600; letter-spacing: .5px;
  /* Fill matches the page canvas so the circle reads as an outline, not a
     filled disc — only the hue ring (and its glow) sit on top. Initials use
     --fg, which IS the near-white the dark theme wants; a literal white would
     be ~1.3:1 on light mode's greige --bg, failing the contrast law in §2. */
  color: var(--fg); background: var(--bg);
  border: 2px solid hsla(var(--hue, 0), var(--sat), var(--lit), 0.35);
  transition: border-color var(--dur-fast) ease;
}
.idp-tile:hover .idp-avatar,
.idp-tile:focus-visible .idp-avatar,
.idp-avatar.is-glow { border-color: transparent; }
.idp-tile:active .idp-avatar { transform: scale(0.94); }

.idp-avatar::before,
.idp-avatar::after {
  content: ""; position: absolute; inset: -4px; border-radius: inherit;
  z-index: -1; opacity: 0;
  background: radial-gradient(
    100px circle at var(--mouse-x, 50%) var(--mouse-y, 50%),
    hsla(var(--hue, 0), 70%, 80%, 1) 0%,
    hsla(var(--hue, 0), 70%, 60%, 0.9) 20%,
    transparent 50%
  );
  transition: opacity .5s ease;
}
.idp-avatar::after { filter: blur(8px); z-index: -2; }

.idp-tile:hover .idp-avatar::before,
.idp-tile:hover .idp-avatar::after,
.idp-tile:focus-visible .idp-avatar::before,
.idp-tile:focus-visible .idp-avatar::after,
.idp-avatar.is-glow::before,
.idp-avatar.is-glow::after { opacity: 1; }

/* Opaque mask, same fill as the circle's own background — sits above the
   glow pseudo-elements (z:-1, later in source) so the glow only shows as a
   thin bleed in the 4px ring outside inset:0, not washed across the initials. */
.idp-avatar-mask {
  position: absolute; inset: 0; border-radius: inherit;
  background: var(--bg); z-index: -1;
}
.idp-name { font-size: var(--text-base); color: var(--ink-soft); }

.idp-empty {
  font-size: var(--text-base); color: var(--ink-faint);
  line-height: var(--lh-body); text-align: center;
}
.idp-empty code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--chip-bg); padding: 1px 5px; border-radius: var(--radius-sm);
}

/* ── PIN entry ────────────────────────────────────────────────────────── */

.idp-pinwrap {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
}
.idp-pinlabel { font-size: var(--text-base); color: var(--ink-soft); }
.idp-dots { display: flex; gap: 14px; }
.idp-dot {
  width: 12px; height: 12px; border-radius: 50%;
  border: 1px solid var(--line-strong); background: transparent;
  transition: background var(--dur-fast), border-color var(--dur-fast), transform var(--dur-fast);
}
.idp-dot.on { background: var(--fg); border-color: var(--fg); transform: scale(1.08); }
/* The real input captures keystrokes but is visually invisible, overlaid on
   the dots so a tap there focuses it (mobile) yet the dots read as the field. */
.idp-pininput {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; border: none; background: transparent; cursor: pointer;
  font-size: 16px; /* ≥16px stops iOS zoom-on-focus */
}
.idp-err { font-size: var(--text-sm); color: var(--bad-text); min-height: 1em; }

.idp-pinwrap.shake { animation: idp-shake .32s ease; }
@keyframes idp-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); } 40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); } 80% { transform: translateX(4px); }
}

/* ── footer ───────────────────────────────────────────────────────────── */

.idp-foot { display: flex; justify-content: center; }
.idp-foot-split { justify-content: center; }
.idp-link {
  border-color: transparent; color: var(--ink-faint);
  text-decoration: underline; text-underline-offset: 3px;
}
.idp-link:hover { color: var(--fg); }

/* ── header user icon: doubles as the identity indicator ────────────────
   Netflix-style — the person icon IS the account button. Once a profile is
   picked, its initials replace the generic silhouette inside the same
   circular hdr-icon-btn (identity.js swaps which child is visible). */

.hdr-user-initials {
  font-size: var(--text-lg); font-weight: 700; letter-spacing: .3px;
  color: inherit;
}
