/* ════════════════════════════════════════════════════════════════════
   Mobile Family Navigator — hierarchical click-up / click-down
   (S4, harnessing-iphone-flotilla; LOCKED mobile_p0_08_family_navigator)
   Anchor #4: NO graphical family tree. Faces + arrows + sibling row.
   Active at <= 767px (mobile breakpoint).
   ════════════════════════════════════════════════════════════════════ */

@media (max-width: 767px) {

  :root {
    --fnav-substrate:        #0a2e2e;
    --fnav-substrate-tint:   #0d3535;
    --fnav-trace-1:          #134040;
    --fnav-trace-2:          #1a5252;
    --fnav-surface-1:        #0f3636;
    --fnav-surface-2:        #133e3e;
    --fnav-teal:             #6DD4D4;
    --fnav-teal-soft:        rgba(109, 212, 212, 0.16);
    --fnav-pink:             #E8A0B8;
    --fnav-amber:            #e8a040;
    --fnav-amber-soft:       rgba(232, 160, 64, 0.14);
    --fnav-fg-1:             #e0e0e8;
    --fnav-fg-2:             #a8b0b8;
    --fnav-fg-3:             #6c7680;
    --fnav-fg-bright:        #ffffff;
    --fnav-border-subtle:    rgba(224, 224, 232, 0.08);
    --fnav-border-trace:     #134040;
    --fnav-shadow-soft:      0 2px 12px rgba(0, 0, 0, 0.35);
    --fnav-shadow-frame:     0 8px 32px rgba(0, 0, 0, 0.45);
    --fnav-shadow-deep:      0 12px 48px rgba(0, 0, 0, 0.55);
    --fnav-ease:             cubic-bezier(0.4, 0, 0.2, 1);
    --fnav-ease-out:         cubic-bezier(0, 0, 0.2, 1);
    --fnav-dur-fast:         260ms;
    --fnav-dur-base:         640ms;
    --fnav-font-display:     'Playfair Display', 'Iowan Old Style', Georgia, serif;
  }

  /* ── root + scroll container ─────────────────────────────────────── */

  /* meticulous-tailoring-canvas S4 D-D1 carry-forward (2026-05-10) — Iron-Law
     class fix mirroring S1 D-A1/D-A2 hide-all-desktop-siblings pattern. The
     desktop chrome (#familyNavigator side panel + #personPanel slide-in)
     remained reachable beneath MobileFamilyView's mount, leaking taps + tab
     focus into invisible buttons. CSS-layer hide is race-free vs JS-only
     `style.display = 'none'` in family-mobile.js init(). */
  #view-family-navigator > #familyNavigator,
  #view-family-navigator > #personPanel {
    display: none !important;
  }

  .fnav-root {
    position: relative;
    display: flex;
    flex-direction: column;
    min-height: 100%;
    background: var(--fnav-substrate);
    color: var(--fnav-fg-1);
    /* leave room for the State 1 TabBar at the bottom (D8) */
    padding-bottom: calc(56px + env(safe-area-inset-bottom) + 16px);
    isolation: isolate;
  }

  /* PCB-trace background — extremely faint, decorative only */
  .fnav-root::before {
    content: '';
    position: absolute;
    inset: 0;
    background:
      linear-gradient(90deg, transparent 0%, transparent calc(33% - 0.5px), var(--fnav-trace-1) calc(33% - 0.5px), var(--fnav-trace-1) calc(33% + 0.5px), transparent calc(33% + 0.5px)),
      linear-gradient(0deg,  transparent 0%, transparent calc(72% - 0.5px), var(--fnav-trace-2) calc(72% - 0.5px), var(--fnav-trace-2) calc(72% + 0.5px), transparent calc(72% + 0.5px));
    opacity: 0.18;
    pointer-events: none;
    z-index: 0;
  }

  .fnav-scroll {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    position: relative;
    z-index: 2;
    scroll-behavior: smooth;
    scrollbar-width: none;
    /* reflective-swimming-ripple S1 D1-C (2026-05-11) — Issue #6 root-cause
       fix. Without overscroll-behavior, an over-scroll past the top edge of
       .fnav-scroll propagated into the outer scroll chain (.main-content →
       body), revealing the page background above the Family modal's content
       as a "blank panel above". `contain` stops the chain at this container's
       boundary — bounce stays inside .fnav-scroll, the top-nav remains
       the modal's visual top edge, no reveal possible. Same pattern as the
       body-level rule at mobile.css :39 (fluffy-puzzling-dongarra S1 D2),
       applied here at the inner scroll-container boundary. */
    overscroll-behavior-y: contain;
    overscroll-behavior-x: none;
  }
  .fnav-scroll::-webkit-scrollbar { display: none; }

  .fnav-content {
    padding: 6px 0 32px;
    min-height: 100%;
  }

  /* ── header + breadcrumb + search ───────────────────────────────── */

  .fnav-nav {
    position: sticky;
    top: 0;
    z-index: 30;
    padding: calc(env(safe-area-inset-top) + 8px) 16px 6px;
    background: linear-gradient(180deg, rgba(10, 46, 46, 0.96) 0%, rgba(10, 46, 46, 0.78) 80%, rgba(10, 46, 46, 0) 100%);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
  }

  .fnav-nav-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    height: 44px;
  }

  .fnav-title {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    min-width: 0;
  }
  /* reflective-swimming-ripple S3 D3-B (2026-05-11) — the static "Family"
     label rule remains here as historical reference; the markup that used
     it (`.fnav-crumb-label` span) is gone from family-mobile.js init(). If
     no caller is reintroduced before the next visual refactor, drop these
     bytes. */
  .fnav-crumb-current {
    font-family: var(--fnav-font-display);
    font-size: 17px;
    font-weight: 600;
    color: var(--fnav-fg-bright);
    line-height: 1.1;
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .fnav-icon-btn {
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    color: var(--fnav-fg-1);
    background: transparent;
    border: 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    flex-shrink: 0;
  }
  .fnav-icon-btn svg {
    width: 22px;
    height: 22px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .fnav-icon-btn:active { background: rgba(255, 255, 255, 0.04); border-radius: 12px; }

  .fnav-breadcrumb {
    margin: 8px -16px 0;
    padding: 4px 16px 8px;
    display: flex;
    align-items: center;
    gap: 6px;
    overflow-x: auto;
    scroll-behavior: smooth;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .fnav-breadcrumb::-webkit-scrollbar { display: none; }
  .fnav-crumb {
    flex-shrink: 0;
    font-size: 12px;
    color: var(--fnav-fg-2);
    background: rgba(19, 64, 64, 0.6);
    border: 1px solid var(--fnav-border-trace);
    border-radius: 999px;
    padding: 5px 10px;
    cursor: pointer;
    white-space: nowrap;
    font-weight: 500;
    transition: color var(--fnav-dur-fast) var(--fnav-ease), background var(--fnav-dur-fast) var(--fnav-ease);
  }
  .fnav-crumb:active { background: var(--fnav-trace-2); }
  /* realizing-mobile-modals S1 D3 (2026-05-13) — retire the trailing
     gold-bordered focal-name pill. The focal's full formal name now
     occupies the chrome-band centered title slot (D2); the duplicate
     `.fnav-crumb.is-current` pill that previously floated in the modal
     body just below the band was Joe's handoff Issue #2 ("subject name
     pill floats as a gold-bordered chip"). The breadcrumb's ancestor
     pills (the climb path before the current focal) remain visible so the
     climb navigation affordance persists — only the trailing duplicate is
     suppressed. A 1-item trail collapses the breadcrumb to empty space
     (no orphan pill); the band title still surfaces the focal. */
  .fnav-crumb.is-current {
    display: none !important;
  }
  /* When the trailing is-current pill is the only thing the breadcrumb
     would carry, collapse the breadcrumb's vertical margin so the modal
     body doesn't leave a dead row under the band. The :has() guard keeps
     the breadcrumb visually present whenever the climb path has depth. */
  .fnav-breadcrumb:not(:has(.fnav-crumb:not(.is-current))) {
    margin: 0;
    padding: 0;
  }
  .fnav-crumb-sep {
    color: var(--fnav-fg-3);
    font-size: 10px;
    flex-shrink: 0;
    user-select: none;
  }

  /* ── Family Navigator roster overlay (realizing-mobile-chrome-contract
     S2 D4, 2026-05-14) — opened by the upper-right launcher button in the
     Family modal. Replaces the prior token-prefix search panel. Mounts to
     <body> so it stacks above the .fnav-root + .main-content cluster
     without ancestor-overflow clipping; z-index sits below .top-nav
     (z:11500, Header-always-visible invariant) so the chrome band remains
     reachable. Backdrop tap / × / hardware back dismiss. ── */
  .fnav-roster-overlay {
    position: fixed;
    inset: 0;
    z-index: 11200;
    display: flex;
    align-items: flex-end;
    justify-content: center;
  }
  .fnav-roster-overlay[hidden] { display: none; }
  .fnav-roster-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(5, 18, 18, 0.62);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
  }
  .fnav-roster-card {
    position: relative;
    width: 100%;
    max-width: 560px;
    max-height: calc(100vh - var(--mobile-top-bar-total-height, 56px) - 24px);
    margin: 0 auto;
    background: var(--fnav-surface-1, #0f2e2e);
    border-top-left-radius: 18px;
    border-top-right-radius: 18px;
    box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.45);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: fnav-roster-slide-up 220ms cubic-bezier(0.32, 0.72, 0, 1) both;
  }
  @keyframes fnav-roster-slide-up {
    from { transform: translateY(28px); opacity: 0.6; }
    to { transform: translateY(0); opacity: 1; }
  }
  .fnav-roster-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px 10px;
    border-bottom: 1px solid var(--fnav-border-subtle, rgba(255, 255, 255, 0.06));
  }
  .fnav-roster-title {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
    color: var(--fnav-fg-bright, #f5f5f7);
    letter-spacing: 0.01em;
  }
  .fnav-roster-close {
    width: 36px;
    height: 36px;
    display: grid;
    place-items: center;
    background: transparent;
    border: 0;
    color: var(--fnav-fg-1, #d6e2e2);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    border-radius: 10px;
  }
  .fnav-roster-close svg {
    width: 20px;
    height: 20px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
  }
  .fnav-roster-close:active { background: rgba(255, 255, 255, 0.06); }
  .fnav-roster-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 12px 16px 16px;
  }
  .fnav-roster-fallback {
    margin: 24px 0;
    text-align: center;
    color: var(--fnav-fg-3, #8a9a9a);
    font-size: 14px;
  }

  /* ── generation strips (parents above / children below focal) ────── */

  .fnav-gen-strip {
    position: relative;
    padding: 10px 16px 6px;
  }
  .fnav-gen-label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--fnav-fg-3);
    margin-bottom: 8px;
    padding-left: 4px;
  }
  .fnav-gen-label .count {
    color: var(--fnav-fg-2);
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: none;
    font-size: 11px;
  }
  .fnav-gen-row {
    display: flex;
    gap: 10px;
    align-items: center;
    overflow-x: auto;
    margin: 0 -16px;
    padding: 4px 16px;
    scrollbar-width: none;
  }
  .fnav-gen-row::-webkit-scrollbar { display: none; }
  .fnav-gen-pill {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-shrink: 0;
    background: var(--fnav-surface-1);
    border: 1px solid var(--fnav-border-trace);
    border-radius: 12px;
    padding: 6px 12px 6px 6px;
    cursor: pointer;
    transition: transform var(--fnav-dur-fast) var(--fnav-ease), border-color var(--fnav-dur-fast) var(--fnav-ease);
    min-height: 48px;
    user-select: none;
    -webkit-user-select: none;
    /* meticulous-tailoring-canvas S4 D-D1 (2026-05-10) — Iron-Law root-cause
       fix for "long-press doesn't open Person view" (Issue #8). iOS Safari
       intercepts long-press with the system text-callout / image magnifier
       menu unless `-webkit-touch-callout: none` is set; the interception
       fires before our 480ms pointerdown timer in family-mobile.js could
       resolve, so _openPersonModal() never executed on iPhone. Apply across
       every Family Navigator card surface. */
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
  }
  .fnav-gen-pill:active { transform: scale(0.97); }
  .fnav-pill-who {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
  }
  .fnav-pill-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--fnav-fg-bright);
    white-space: nowrap;
  }
  .fnav-pill-meta {
    font-size: 11px;
    color: var(--fnav-fg-2);
    font-variant-numeric: tabular-nums;
  }
  .fnav-gen-empty {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border: 1px dashed var(--fnav-border-trace);
    border-radius: 12px;
    font-size: 12px;
    color: var(--fnav-fg-3);
    font-style: italic;
  }

  /* Climb rail — connective tissue between generation strip + focal */
  .fnav-climb-rail {
    position: relative;
    height: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    margin-top: 2px;
  }
  .fnav-climb-rail::before {
    content: '';
    position: absolute;
    left: 50%;
    top: 0;
    bottom: 0;
    width: 1px;
    background: linear-gradient(180deg, rgba(232, 160, 64, 0.45) 0%, rgba(232, 160, 64, 0.05) 100%);
  }
  .fnav-climb-rail.down::before {
    background: linear-gradient(180deg, rgba(232, 160, 64, 0.05) 0%, rgba(232, 160, 64, 0.45) 100%);
  }
  .fnav-rail-arrow {
    position: relative;
    width: 22px;
    height: 22px;
    display: grid;
    place-items: center;
    color: var(--fnav-amber);
    background: var(--fnav-substrate);
    border-radius: 50%;
  }
  .fnav-rail-arrow svg {
    width: 14px;
    height: 14px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  /* ── focal hero card ────────────────────────────────────────────── */

  .fnav-focal {
    margin: 6px 16px 8px;
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--fnav-surface-1);
    border: 1px solid var(--fnav-border-trace);
    border-radius: 16px;
    padding: 18px 18px 20px;
    box-shadow: var(--fnav-shadow-frame);
    /* meticulous-tailoring-canvas S4 D-D1 (2026-05-10) — see .fnav-gen-pill
       for full Iron-Law rationale. Long-press on the focal portrait must
       reach our pointerdown timer, not iOS Safari's image callout. */
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
  }
  .fnav-focal::before {
    /* picture-frame inner stroke */
    content: '';
    position: absolute;
    inset: 8px;
    border: 1px solid rgba(232, 160, 64, 0.18);
    border-radius: 10px;
    pointer-events: none;
  }
  .fnav-focal.is-swapping {
    animation: fnav-focal-swap var(--fnav-dur-base) var(--fnav-ease);
  }
  @keyframes fnav-focal-swap {
    0%   { opacity: 1; transform: translateY(0); }
    35%  { opacity: 0; transform: translateY(8px); }
    36%  { transform: translateY(-8px); }
    100% { opacity: 1; transform: translateY(0); }
  }

  .fnav-focal-body {
    display: grid;
    grid-template-columns: 156px 1fr;
    gap: 14px;
    align-items: stretch;
  }
  .fnav-focal-portrait {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .fnav-focal-portrait .fnav-avatar {
    box-shadow: var(--fnav-shadow-deep), 0 0 0 1px var(--fnav-amber);
    animation: fnav-hero-breathe 2400ms var(--fnav-ease) infinite;
  }
  @keyframes fnav-hero-breathe {
    0%, 100% { box-shadow: var(--fnav-shadow-deep), 0 0 0 1px var(--fnav-amber), 0 0 24px rgba(232, 160, 64, 0.18); }
    50%      { box-shadow: var(--fnav-shadow-deep), 0 0 0 1px var(--fnav-amber), 0 0 40px rgba(232, 160, 64, 0.32); }
  }

  .fnav-focal-side {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    min-width: 0;
  }

  /* crisp-anchoring-cradle S2 D2-A (2026-05-11) — Family modal restructure:
     `.fnav-focal-side--bios` replaces the legacy TAP UP / TAP DOWN climb-
     arrow column (item 3). Holds the AI Biography + Authorized Biography
     two-button stack right-of-photo. The `.fnav-bio-row` grid (default 2-col)
     becomes a 1-col vertical stack inside the focal-side container so each
     bio button reads horizontally as a wide row at the side of the photo. */
  .fnav-focal-side--bios {
    justify-content: center;
    gap: 10px;
    /* realizing-mobile-modals S2 D1 (2026-05-13) — Issue #3: bio button stack
       was crowding the picture-frame inner stroke. Add right padding so the
       column has breathing room against the card's right edge. */
    padding-right: 4px;
  }
  .fnav-focal-side--bios .fnav-bio-row {
    margin-top: 0;
    grid-template-columns: 1fr;
    gap: 8px;
  }
  /* realizing-mobile-modals S2 D1 (2026-05-13) — Issue #3: narrow the bio
     buttons so they fit comfortably in the ~150px column right of the 156px
     headshot. Tighter padding + smaller icon + smaller label font + reduced
     min-height. Label remains readable; sub-line stays informative.
     Original: padding 10/12, gap 10, icon 20px, label 13px/700, min-h 60.
     Narrowed: padding 8/9, gap 7, icon 17px, label 12px/700, min-h 50. */
  .fnav-focal-side--bios .fnav-bio-btn {
    min-height: 50px;
    padding: 8px 9px;
    gap: 7px;
    border-radius: 11px;
  }
  .fnav-focal-side--bios .fnav-bio-btn-icon {
    font-size: 17px;
  }
  .fnav-focal-side--bios .fnav-bio-btn-label {
    font-size: 12px;
    letter-spacing: 0;
  }
  .fnav-focal-side--bios .fnav-bio-btn-sub {
    font-size: 10.5px;
  }

  /* crisp-anchoring-cradle S2 D2-A item 2 (2026-05-11) — eliminate triple-
     naming. The chrome-band centered slot carries the focal name; the in-body
     surfacings beneath (`.fnav-crumb-current`) and beneath the portrait
     (`.fnav-focal-name`) are retired. We hide rather than remove from markup
     so external callers reading `_shortName(focal)` from `#fnavCurrent` (e.g.
     legacy share targets) keep functioning if any exist. */
  .fnav-crumb-current,
  .fnav-focal-name {
    display: none !important;
  }
  /* Title slot is now empty; collapse its row to reclaim vertical space. */
  .fnav-title {
    height: 0;
    overflow: hidden;
  }
  .fnav-focal-arrow {
    appearance: none;
    background: transparent;
    border: 1px solid var(--fnav-border-trace);
    border-radius: 10px;
    color: var(--fnav-amber);
    font-family: inherit;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 12px;
    height: 44px;
    cursor: pointer;
    width: 100%;
    -webkit-tap-highlight-color: transparent;
    transition: background var(--fnav-dur-fast) var(--fnav-ease), border-color var(--fnav-dur-fast) var(--fnav-ease), transform var(--fnav-dur-fast) var(--fnav-ease);
  }
  .fnav-focal-arrow:active { transform: scale(0.97); background: var(--fnav-amber-soft); }
  .fnav-focal-arrow:disabled {
    color: var(--fnav-fg-3);
    border-style: dashed;
    border-color: var(--fnav-border-subtle);
    cursor: not-allowed;
    opacity: 0.7;
  }
  .fnav-focal-arrow-lbl {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    line-height: 1.1;
    gap: 1px;
    min-width: 0;
  }
  .fnav-focal-arrow-who {
    font-size: 9px;
    letter-spacing: 0.06em;
    color: var(--fnav-fg-3);
    font-weight: 500;
    text-transform: none;
    max-width: 90px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .fnav-focal-arrow-icon {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--fnav-amber-soft);
    flex-shrink: 0;
  }
  .fnav-focal-arrow-icon svg {
    width: 18px;
    height: 18px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .fnav-focal-meta {
    margin-top: 14px;
    position: relative;
    z-index: 1;
  }
  .fnav-focal-name {
    font-family: var(--fnav-font-display);
    font-weight: 600;
    font-size: 26px;
    line-height: 1.05;
    color: var(--fnav-fg-bright);
    letter-spacing: -0.01em;
    margin: 0;
    text-wrap: balance;
  }
  .fnav-focal-middle {
    display: block;
    font-size: 16px;
    color: var(--fnav-fg-2);
    font-style: italic;
    font-weight: 400;
    letter-spacing: 0;
    margin-top: 2px;
  }
  .fnav-focal-life {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 8px;
    font-size: 13px;
    color: var(--fnav-fg-2);
    font-variant-numeric: tabular-nums;
  }
  .fnav-focal-life .dot {
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--fnav-fg-3);
    flex-shrink: 0;
  }
  .fnav-focal-life .role {
    color: var(--fnav-amber);
    font-style: italic;
  }

  /* ── Presence chips (S4 D-D5, 2026-05-10) ──────────────────────────
     Depth-of-record signals on the focal hero card. Mirrors the Mac
     dashboard's presence ribbon, compressed to a flex-wrap row of pill
     chips. Surfaces photo/video/doc counts + story count + AI bio status
     so the family member sees how much the archive holds about this
     person without leaving the Family tab. */
  .fnav-focal-chips {
    margin-top: 10px;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }
  .fnav-focal-chip {
    /* crisp-anchoring-cradle S2 D2-A item 4 (2026-05-11) — chips are now
       buttons that launch downstream modals (Browse Media / Stories) with
       focal-person filters pre-applied. Reset native button chrome; keep
       the pill silhouette; raise contrast on `:active` to communicate
       tap-affordance. */
    appearance: none;
    -webkit-appearance: none;
    cursor: pointer;
    font-family: inherit;
    -webkit-tap-highlight-color: transparent;
    transition: background var(--fnav-dur-fast) var(--fnav-ease),
                transform var(--fnav-dur-fast) var(--fnav-ease),
                border-color var(--fnav-dur-fast) var(--fnav-ease);
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 9px;
    background: rgba(19, 64, 64, 0.6);
    border: 1px solid var(--fnav-border-trace);
    border-radius: 999px;
    font-size: 11px;
    font-weight: 500;
    color: var(--fnav-fg-2);
    line-height: 1.3;
  }
  /* A fingertip's target (Greg G-151, FergiPhone 2026-10-24): the four chips measured 76–108 × 22 px — buttons that
     open Browse Media / Stories, at half the 44 px floor. Each pill grows to 36 px; an invisible band takes the
     hit area to 44 px, reaching only 4 px into the 8 px gap so two rows never share a band. */
  .fnav-focal-chips { row-gap: 8px; column-gap: 8px; }
  .fnav-focal-chip { position: relative; min-height: 36px; padding: 6px 12px; font-size: 12px; }
  .fnav-focal-chip::after { content: ''; position: absolute; left: 0; right: 0; top: -4px; bottom: -4px; }
  .fnav-focal-chip:active {
    transform: scale(0.95);
    background: var(--fnav-amber-soft);
    color: var(--fnav-amber);
    border-color: rgba(232, 160, 64, 0.5);
  }
  .fnav-focal-chip .fnav-chip-icon {
    font-size: 11px;
    line-height: 1;
    filter: saturate(1.05);
  }
  .fnav-focal-chip .fnav-chip-label {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }

  /* ── Bio control row (reflective-swimming-ripple S3 D3-B, 2026-05-11) ─
     Two-button row beneath the focal hero meta: AI Biography · Authorized
     Biography. Replaces the single View-Profile button retired in D3-C;
     the View-Profile demographic content lives in `.fnav-demographic-
     section` below the relations block. Each button opens MobileBioPopup
     (D3-A) targeting the focal person.

     Empty states (no AI bio generated yet / no authorized bio) get a
     muted treatment but stay visible per Visibility-Over-Silent-Action —
     the family member sees the slot rather than wondering whether the
     surface exists. */

  .fnav-bio-row {
    margin-top: 12px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
  }
  .fnav-bio-btn {
    appearance: none;
    background: rgba(232, 160, 64, 0.14);
    border: 1px solid rgba(232, 160, 64, 0.36);
    border-radius: 12px;
    padding: 10px 12px;
    display: flex;
    align-items: center;
    gap: 10px;
    color: #f0d090;
    font-family: inherit;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    min-height: 52px;
    text-align: left;
    transition: background var(--fnav-dur-fast) var(--fnav-ease),
                transform var(--fnav-dur-fast) var(--fnav-ease);
  }
  .fnav-bio-btn:active {
    transform: scale(0.97);
    background: rgba(232, 160, 64, 0.22);
  }
  .fnav-bio-btn.is-empty {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.10);
    color: var(--fnav-fg-2);
  }
  .fnav-bio-btn.is-empty:active {
    background: rgba(255, 255, 255, 0.08);
  }
  .fnav-bio-btn-icon {
    font-size: 20px;
    line-height: 1;
    flex-shrink: 0;
  }
  .fnav-bio-btn-body {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
    gap: 1px;
    min-width: 0;
    flex: 1;
  }
  .fnav-bio-btn-label {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .fnav-bio-btn-sub {
    font-size: 11px;
    font-weight: 500;
    opacity: 0.85;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* ── Unified Family relations block (D3-B, 2026-05-11) ──────────────
     Replaces the prior top Parents gen-strip + bottom Children gen-strip
     + sibling row. Sits below the focal hero card and groups every known
     relation under Parents · Spouse · Siblings · Children sub-sections. */

  .fnav-relations-block {
    margin: 14px 0 4px;
    padding: 8px 16px 4px;
  }
  .fnav-relations-title {
    font-family: var(--fnav-font-display);
    font-size: 13px;
    font-weight: 600;
    color: var(--fnav-fg-2);
    text-transform: uppercase;
    letter-spacing: 0.14em;
    margin: 0 0 4px;
  }
  .fnav-rel-group {
    margin: 10px 0;
  }
  .fnav-rel-group-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 0 4px 6px;
  }
  .fnav-rel-group-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--fnav-fg-1);
  }
  .fnav-rel-group-count {
    font-size: 11px;
    color: var(--fnav-fg-3);
    font-weight: 500;
    letter-spacing: 0.04em;
    font-style: italic;
  }
  .fnav-rel-group--empty .fnav-rel-group-count {
    color: var(--fnav-fg-3);
  }
  .fnav-rel-group-row {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    margin: 0 -16px;
    padding: 2px 16px 10px;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
    scroll-padding-inline: 16px;   /* snap to the gutter, not the glass (Greg G-163) */
  }
  .fnav-rel-group-row::-webkit-scrollbar { display: none; }
  .fnav-rel-card {
    appearance: none;
    flex-shrink: 0;
    width: 100px;
    background: var(--fnav-surface-1);
    border: 1px solid var(--fnav-border-trace);
    border-radius: 12px;
    padding: 8px 8px 10px;
    color: var(--fnav-fg-1);
    cursor: pointer;
    font-family: inherit;
    text-align: left;
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
    scroll-snap-align: start;
    transition: transform var(--fnav-dur-fast) var(--fnav-ease);
  }
  .fnav-rel-card:active { transform: scale(0.97); }
  .fnav-rel-card .fnav-avatar {
    width: 84px;
    height: 100px;
    border-radius: 8px;
    margin: 0 auto 6px;
    display: block;
  }
  .fnav-rel-card-name {
    font-size: 12px;
    font-weight: 600;
    color: var(--fnav-fg-bright);
    line-height: 1.2;
    text-wrap: balance;
    text-align: center;
  }
  .fnav-rel-card-meta {
    font-size: 11px;
    color: var(--fnav-fg-2);
    margin-top: 2px;
    font-variant-numeric: tabular-nums;
    text-align: center;
  }

  /* crisp-anchoring-cradle S2 D2-A item 6 (2026-05-11) — single horizontally-
     scrollable family-relations panel. Ordering: Parents → Spouse + Children
     → Siblings. Each section is a visual group inside one continuous
     horizontal scroll row, separated by `.fnav-rel-divider`. Replaces the
     prior 4 vertically-stacked `.fnav-rel-group` rows. (Old `.fnav-rel-group-*`
     rules above are kept defensively but no longer matched by new markup.) */
  .fnav-rel-scroll {
    display: flex;
    align-items: stretch;
    gap: 14px;
    overflow-x: auto;
    margin: 0 -16px;
    padding: 6px 16px 12px;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
    /* Snap to the gutter, not the glass (Greg G-163, 2026-10-25): with no scroll-padding the snapport is the
       row's border box, so snapping scrolled the row 16 px and 'PARENTS' sat at x 2, flush against the screen. */
    scroll-padding-inline: 16px;
    -webkit-overflow-scrolling: touch;
  }
  .fnav-rel-scroll::-webkit-scrollbar { display: none; }
  .fnav-rel-section {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
  }
  .fnav-rel-section--empty {
    align-self: center;
    padding-right: 4px;
  }
  .fnav-rel-section-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 0 2px 2px;
    white-space: nowrap;
  }
  .fnav-rel-section-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--fnav-fg-1);
  }
  .fnav-rel-section-count {
    font-size: 11px;
    color: var(--fnav-fg-3);
    font-weight: 500;
    letter-spacing: 0.04em;
    font-style: italic;
  }
  .fnav-rel-section-empty {
    font-size: 11px;
    color: var(--fnav-fg-3);
    font-style: italic;
    letter-spacing: 0.02em;
  }
  .fnav-rel-section-cards {
    display: flex;
    gap: 10px;
    align-items: stretch;
  }
  .fnav-rel-divider {
    flex-shrink: 0;
    width: 1px;
    align-self: stretch;
    background: var(--fnav-border-subtle);
    margin: 6px 2px;
  }

  /* ── Demographic-detail section (D3-C, 2026-05-11) ──────────────────
     View Profile fold-in. Tabular label-value rows for birth/death/
     occupation/address etc., plus optional prose biography summary. */

  .fnav-demographic-section {
    margin: 8px 0 4px;
    padding: 16px 16px 8px;
    border-top: 1px solid var(--fnav-border-subtle);
  }
  .fnav-demo-title {
    font-family: var(--fnav-font-display);
    font-size: 13px;
    font-weight: 600;
    color: var(--fnav-fg-2);
    text-transform: uppercase;
    letter-spacing: 0.14em;
    margin: 0 0 10px;
  }
  .fnav-demo-table {
    display: flex;
    flex-direction: column;
    background: var(--fnav-surface-1);
    border: 1px solid var(--fnav-border-trace);
    border-radius: 12px;
    overflow: hidden;
  }
  .fnav-demo-row {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--fnav-border-subtle);
    font-size: 13px;
    line-height: 1.35;
  }
  .fnav-demo-row:last-child {
    border-bottom: 0;
  }
  .fnav-demo-label {
    width: 96px;
    flex-shrink: 0;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--fnav-fg-3);
  }
  .fnav-demo-value {
    flex: 1;
    color: var(--fnav-fg-bright);
    word-break: break-word;
  }
  .fnav-demo-prose {
    margin-top: 12px;
    padding: 12px 14px;
    background: var(--fnav-surface-1);
    border: 1px solid var(--fnav-border-trace);
    border-radius: 12px;
  }
  .fnav-demo-prose-label {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--fnav-fg-3);
    margin-bottom: 6px;
  }
  .fnav-demo-prose-text {
    margin: 0;
    font-size: 14px;
    line-height: 1.55;
    color: var(--fnav-fg-1);
    white-space: pre-line;
  }

  /* ── siblings row ─────────────────────────────────────────────── */

  .fnav-sib-section {
    margin-top: 12px;
  }
  .fnav-sib-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 6px 16px 8px;
  }
  .fnav-sib-head .h {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--fnav-fg-3);
  }
  .fnav-sib-head .h em {
    font-style: normal;
    color: var(--fnav-amber);
  }
  .fnav-sib-head .hint {
    font-size: 11px;
    color: var(--fnav-fg-3);
    font-style: italic;
  }
  .fnav-sib-row {
    display: flex;
    gap: 12px;
    padding: 4px 16px 16px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-left: 16px;
    scrollbar-width: none;
  }
  .fnav-sib-row::-webkit-scrollbar { display: none; }
  .fnav-sib-card {
    flex-shrink: 0;
    width: 112px;
    scroll-snap-align: start;
    background: var(--fnav-surface-1);
    border: 1px solid var(--fnav-border-trace);
    border-radius: 10px;
    padding: 8px;
    position: relative;
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
    /* S4 D-D1 (2026-05-10) — see .fnav-gen-pill for full rationale. */
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
    transition: transform var(--fnav-dur-fast) var(--fnav-ease);
  }
  .fnav-sib-card:active { transform: scale(0.97); }
  .fnav-sib-card.is-self {
    border-color: rgba(232, 160, 64, 0.4);
    background: rgba(232, 160, 64, 0.06);
  }
  .fnav-sib-card.is-self::before {
    content: 'You are here';
    position: absolute;
    top: -7px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--fnav-substrate);
    background: var(--fnav-amber);
    padding: 2px 6px;
    border-radius: 4px;
    white-space: nowrap;
  }
  .fnav-sib-card.is-spouse {
    width: 96px;
    background: rgba(196, 96, 136, 0.06);
    border-color: rgba(196, 96, 136, 0.22);
  }
  .fnav-sib-card.is-spouse::after {
    content: '';
    position: absolute;
    left: -7px;
    top: 50%;
    width: 5px;
    height: 1px;
    background: rgba(196, 96, 136, 0.5);
  }
  .fnav-sib-tag {
    font-size: 9px;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    font-weight: 600;
    color: var(--fnav-teal);
    margin-bottom: 6px;
    display: block;
  }
  .fnav-sib-tag.spouse { color: var(--fnav-pink); }
  .fnav-sib-card .fnav-avatar {
    width: 96px;
    height: 116px;
    border-radius: 6px;
    margin: 0 auto 8px;
  }
  .fnav-sib-card.is-spouse .fnav-avatar {
    width: 80px;
    height: 96px;
  }
  .fnav-sib-name {
    font-size: 12px;
    font-weight: 600;
    color: var(--fnav-fg-bright);
    line-height: 1.2;
    text-wrap: balance;
  }
  .fnav-sib-meta {
    font-size: 11px;
    color: var(--fnav-fg-2);
    margin-top: 2px;
    font-variant-numeric: tabular-nums;
  }

  /* ── gesture hint ──────────────────────────────────────────────── */

  .fnav-gesture-hint {
    margin: 4px 16px 12px;
    padding: 10px 12px;
    display: flex;
    align-items: center;
    gap: 10px;
    background: rgba(19, 64, 64, 0.5);
    border: 1px solid var(--fnav-border-subtle);
    border-radius: 10px;
    font-size: 12px;
    color: var(--fnav-fg-2);
    line-height: 1.4;
  }
  .fnav-gh-icon {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--fnav-teal-soft);
    color: var(--fnav-teal);
    display: grid;
    place-items: center;
    flex-shrink: 0;
  }
  .fnav-gh-icon svg {
    width: 14px;
    height: 14px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.6;
  }
  .fnav-gesture-hint kbd {
    font-family: inherit;
    background: var(--fnav-substrate);
    border: 1px solid var(--fnav-border-trace);
    border-radius: 4px;
    padding: 1px 5px;
    font-size: 11px;
    color: var(--fnav-fg-1);
  }

  /* ── avatar (face crop) ───────────────────────────────────────── */

  .fnav-avatar {
    position: relative;
    border-radius: 8px;
    overflow: hidden;
    flex-shrink: 0;
    isolation: isolate;
    background: var(--fnav-substrate-tint);
    display: grid;
    place-items: center;
  }
  .fnav-avatar::after {
    content: '';
    position: absolute;
    inset: 4px;
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 5px;
    pointer-events: none;
    z-index: 2;
  }
  .fnav-avatar-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 1;
    display: block;
    /* S4 D-D1 (2026-05-10) — iOS Safari image long-press magnifier callout
       suppressed at the <img> level (parent suppression does not propagate
       to <img>). Without this, long-press on a face crop opens "Save Image"
       / "Add to Photos" / "Look Up" instead of our Person modal. */
    -webkit-touch-callout: none;
    -webkit-user-drag: none;
    pointer-events: none;
  }
  .fnav-avatar-img.is-failed { display: none; }
  .fnav-avatar-initials {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-family: var(--fnav-font-display);
    font-weight: 600;
    color: rgba(255, 255, 255, 0.92);
    letter-spacing: -0.01em;
    z-index: 0;
    pointer-events: none;
  }
  .fnav-avatar:not(.no-photo) .fnav-avatar-initials { display: none; }

  .fnav-avatar.fnav-s-32  { width: 32px; height: 32px; border-radius: 6px; }
  .fnav-avatar.fnav-s-32::after { inset: 2px; border-radius: 4px; }
  .fnav-avatar.fnav-s-32 .fnav-avatar-initials { font-size: 13px; }

  .fnav-avatar.fnav-s-44  { width: 44px; height: 44px; }
  .fnav-avatar.fnav-s-44 .fnav-avatar-initials { font-size: 15px; }

  .fnav-avatar.fnav-s-72  { width: 72px; height: 88px; border-radius: 10px; }
  .fnav-avatar.fnav-s-72 .fnav-avatar-initials { font-size: 26px; }

  .fnav-avatar.fnav-s-80  { width: 80px; height: 96px; border-radius: 6px; }
  .fnav-avatar.fnav-s-80 .fnav-avatar-initials { font-size: 28px; }

  .fnav-avatar.fnav-s-96  { width: 96px; height: 116px; border-radius: 6px; }
  .fnav-avatar.fnav-s-96 .fnav-avatar-initials { font-size: 32px; }

  .fnav-avatar.fnav-s-156 { width: 156px; height: 192px; border-radius: 12px; }
  .fnav-avatar.fnav-s-156::after { inset: 8px; border-radius: 6px; border-color: rgba(255, 255, 255, 0.14); }
  .fnav-avatar.fnav-s-156 .fnav-avatar-initials { font-size: 56px; }

  /* Press / long-press feedback ring */
  .fnav-press-ring {
    position: absolute;
    border-radius: inherit;
    pointer-events: none;
    inset: -3px;
    border: 2px solid var(--fnav-teal);
    opacity: 0;
    z-index: 5;
  }
  .is-long-pressing .fnav-press-ring {
    animation: fnav-long-press 520ms var(--fnav-ease-out) forwards;
  }
  @keyframes fnav-long-press {
    0%   { opacity: 0; transform: scale(1.05); }
    20%  { opacity: 0.6; }
    100% { opacity: 1; transform: scale(1); border-color: var(--fnav-amber); }
  }
  .is-long-pressing .fnav-avatar { transform: scale(0.97); transition: transform 480ms var(--fnav-ease); }

  /* ── edge-swipe-from-left back zone (D6) ───────────────────────── */

  .fnav-edge-swipe {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: 24px;
    z-index: 25;
    /* Visible only via the back gesture; transparent + above content */
    background: transparent;
    pointer-events: auto;
  }

  /* ── loading + empty states ────────────────────────────────────── */

  .fnav-loading {
    padding: 60px 16px;
    display: grid;
    place-items: center;
  }
  .fnav-spinner {
    width: 28px;
    height: 28px;
    border: 3px solid rgba(255, 255, 255, 0.12);
    border-top-color: var(--fnav-amber);
    border-radius: 50%;
    animation: fnav-spin 800ms linear infinite;
  }
  @keyframes fnav-spin {
    to { transform: rotate(360deg); }
  }
  .fnav-empty {
    padding: 48px 24px;
    text-align: center;
    color: var(--fnav-fg-3);
    font-size: 14px;
    font-style: italic;
  }

  /* ── reduced motion ────────────────────────────────────────────── */
  @media (prefers-reduced-motion: reduce) {
    .fnav-focal-portrait .fnav-avatar { animation: none; }
    .fnav-focal.is-swapping { animation: none; }
    .is-long-pressing .fnav-press-ring { animation-duration: 1ms; }
    .fnav-spinner { animation-duration: 2s; }
  }

}
