/* Дизайн-токены из утверждённого UX-прототипа gen.zaday.ru */
:root{
  /* отступ плавающих островков от края полотна — один для всех и всех экранов:
     раньше виды стояли на 12px, зум на 14px, и разнобой был заметен глазом */
  --rail-gap:12px;
  --bg:#FBFBF8; --surface:#FFFFFF; --surface-2:#F4F3EC;
  --ink:#1C231F; --ink-soft:#59635C; --ink-faint:#98A099;
  --line:#E4E2D7;
  --accent:#17604A; --accent-soft:#E4EDE7; --accent-ink:#0E4534;
  --gold:#A9781E; --gold-soft:#F2E9D6; --living:#2E8B6B;
  --node-male:#eef4fc; --node-female:#fceef4;
  --shadow:rgba(30,40,34,.10); --radius:13px;
  --serif:"Iowan Old Style","Palatino Linotype","Georgia",serif;
  --sans:"Segoe UI",system-ui,-apple-system,"Helvetica Neue",sans-serif;
}
:root[data-theme="dark"]{
  --bg:#12150F; --surface:#1A1E17; --surface-2:#222720;
  --ink:#ECEFE7; --ink-soft:#A6AFA4; --ink-faint:#6C766B;
  --line:#2C3128;
  --accent:#5FBE97; --accent-soft:#1D2A22; --accent-ink:#8FD6B7;
  --gold:#D6A84A; --gold-soft:#2A2416; --living:#5FBE97;
    --node-male:#1a2430; --node-female:#2a1c25;
  --shadow:rgba(0,0,0,.45);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#12150F; --surface:#1A1E17; --surface-2:#222720;
    --ink:#ECEFE7; --ink-soft:#A6AFA4; --ink-faint:#6C766B; --line:#2C3128;
    --accent:#5FBE97; --accent-soft:#1D2A22; --accent-ink:#8FD6B7;
    --gold:#D6A84A; --gold-soft:#2A2416; --living:#5FBE97;
    --node-male:#1a2430; --node-female:#2a1c25; --shadow:rgba(0,0,0,.45);
  }
}

*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--sans);font-size:15px;line-height:1.5;-webkit-font-smoothing:antialiased}

.topbar{display:flex;align-items:center;gap:14px;padding:11px 16px;
  background:var(--surface);border-bottom:1px solid var(--line)}
.brand{display:flex;align-items:center;gap:9px;font-weight:600;letter-spacing:-.01em;
  color:var(--ink);text-decoration:none}
.brand .mark{width:26px;height:26px;flex:none;color:var(--accent)}
.brand b{color:var(--accent)}
.brand span{color:var(--ink-soft);font-weight:400}

.content{max-width:820px;margin:0 auto;padding:48px 20px}

/* Футер: реквизиты оператора + ссылка на политику (образец — vnpfoto.ru). */
.site-footer{max-width:820px;margin:8px auto 0;padding:20px;border-top:1px solid var(--line);
  display:flex;flex-wrap:wrap;gap:8px 18px;align-items:center;justify-content:space-between;
  color:var(--ink-faint);font-size:13px;line-height:1.5}
.site-footer a{color:var(--ink-soft);text-decoration:none;white-space:nowrap}
.site-footer a:hover{color:var(--accent-ink);text-decoration:underline}
@media (max-width:560px){.site-footer{justify-content:center;text-align:center;gap:6px 14px}}
.hero .eyebrow{font-size:12px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--gold);font-weight:600;margin:0 0 10px}
.hero h1{font-family:var(--serif);font-size:38px;line-height:1.12;margin:0 0 14px;text-wrap:balance}
.hero .lead{font-size:17px;color:var(--ink-soft);max-width:60ch}
.status{margin-top:22px;display:inline-block;padding:8px 14px;border-radius:20px;
  background:var(--surface-2);border:1px solid var(--line);font-size:13px;color:var(--ink-soft);
  font-variant-numeric:tabular-nums}

/* Навигация: правый блок */
.topbar .spacer{flex:1}
.nav-actions{display:flex;align-items:center;gap:14px;font-size:14px}
.nav-actions a{color:var(--accent-ink);text-decoration:none}
.nav-link{color:var(--ink-soft);padding:5px 2px;border-bottom:2px solid transparent}
.nav-link:hover{color:var(--ink)}
.nav-link.active{color:var(--accent-ink);border-bottom-color:var(--accent)}

/* Колокольчик уведомлений */
.bell-menu{position:relative}
.bell-btn{position:relative;display:flex;align-items:center;justify-content:center;width:38px;height:38px;
  border:1px solid var(--line);background:var(--surface);border-radius:50%;cursor:pointer;color:var(--ink-soft)}
.bell-btn:hover{border-color:var(--accent);color:var(--accent);background:var(--surface-2)}
.bell-btn svg{width:19px;height:19px}
.bell-dot{position:absolute;top:-3px;right:-3px;min-width:17px;height:17px;padding:0 4px;border-radius:9px;
  background:#c0392b;color:#fff;font-size:10.5px;font-weight:700;line-height:17px;text-align:center;
  border:2px solid var(--surface);font-variant-numeric:tabular-nums}
.bell-dot[hidden]{display:none}
.bell-dropdown{position:absolute;right:0;top:calc(100% + 8px);width:340px;max-width:92vw;background:var(--surface);
  border:1px solid var(--line);border-radius:12px;box-shadow:0 10px 30px var(--shadow);z-index:100;overflow:hidden}
.bell-dropdown[hidden]{display:none}
.bell-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 14px;
  border-bottom:1px solid var(--line)}
.bell-list{max-height:min(60vh,440px);overflow-y:auto}
.bell-items{list-style:none;margin:0;padding:0}
.bell-item{border-bottom:1px solid var(--line)}
.bell-item:last-child{border-bottom:none}
.bell-item a{display:flex;gap:10px;align-items:flex-start;padding:10px 14px;text-decoration:none;color:var(--ink)}
.bell-item a:hover{background:var(--surface-2)}
.bell-item.unread{background:var(--accent-soft)}
.bell-item.unread a:hover{background:var(--accent-soft)}
.bell-emoji{flex:0 0 auto;font-size:16px;line-height:1.3}
.bell-text{min-width:0;display:flex;flex-direction:column;gap:2px}
.bell-title{font-size:13.5px;line-height:1.35}
.bell-meta{font-size:11.5px;color:var(--ink-faint)}
.bell-empty{padding:22px 16px;text-align:center;font-size:13px}

/* Меню пользователя (аватар → выпадашка) */
.user-menu{position:relative}
.user-chip{display:flex;align-items:center;gap:8px;border:1px solid var(--line);background:var(--surface);
  border-radius:22px;padding:4px 10px 4px 4px;cursor:pointer;font:inherit;font-size:14px;color:var(--ink)}
.user-chip:hover{border-color:var(--accent);background:var(--surface-2)}
.user-av{width:28px;height:28px;border-radius:50%;background:var(--accent);color:#fff;flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700}
.user-av-img{object-fit:cover;padding:0}
.user-caret{width:15px;height:15px;color:var(--ink-faint)}
.user-dropdown{position:absolute;right:0;top:calc(100% + 6px);min-width:190px;background:var(--surface);
  border:1px solid var(--line);border-radius:11px;box-shadow:0 8px 24px var(--shadow);padding:6px;z-index:100}
.user-dropdown[hidden]{display:none}
.user-dropdown a,.user-dropdown button{display:block;width:100%;text-align:left;padding:9px 11px;
  border:none;background:none;font:inherit;font-size:14px;color:var(--ink);border-radius:8px;cursor:pointer}
.user-dropdown a:hover,.user-dropdown button:hover{background:var(--surface-2)}
.user-dropdown form{margin:0}

/* Кнопки */
.btn{display:inline-flex;align-items:center;gap:7px;padding:8px 15px;border-radius:9px;
  border:1px solid var(--line);background:var(--surface);color:var(--ink);font:inherit;
  font-size:14px;cursor:pointer;text-decoration:none;transition:.12s}
.btn:hover{border-color:var(--accent)}
.btn-primary{background:var(--accent);border-color:var(--accent);color:#fff}
.btn-primary:hover{background:var(--accent-ink)}
.btn-danger{color:#B23A3A;border-color:transparent;background:transparent;padding:6px 8px}
.btn-danger:hover{background:var(--gold-soft);border-color:transparent}
.btn-sm{padding:5px 10px;font-size:13px}

/* Заголовок раздела */
.page-head{display:flex;align-items:baseline;gap:12px;margin:0 0 22px}
.page-head h1{font-family:var(--serif);font-size:28px;margin:0}
.page-head .sub{color:var(--ink-soft);font-size:14px}
.crumbs{font-size:13px;color:var(--ink-faint);margin:0 0 16px}
.crumbs a{color:var(--ink-soft);text-decoration:none}

/* Карточки/списки */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  padding:18px 20px;box-shadow:0 1px 2px var(--shadow);margin:0 0 14px}
.tree-list,.person-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.tree-list a{color:var(--ink);text-decoration:none}
.row{display:flex;align-items:center;gap:12px;background:var(--surface);
  border:1px solid var(--line);border-radius:11px;padding:9px 13px}
.row[hidden]{display:none}  /* иначе display:flex перебивает атрибут hidden (фильтр поиска) */
.row .grow{flex:1;min-width:0}
.row .name{font-weight:600;color:var(--ink);text-decoration:none}
.row .name:hover{color:var(--accent-ink);text-decoration:underline}
.row .meta{font-size:13px;color:var(--ink-soft)}

/* Аватар в строке списка */
.prow-av{width:38px;height:38px;border-radius:10px;flex:0 0 auto;display:flex;align-items:center;
  justify-content:center;color:#fff;font-weight:700;font-size:14px;text-decoration:none;
  background-size:cover;background-position:center;border:1px solid var(--line)}
.av-0{background-color:#17604A}.av-1{background-color:#2f6ae0}
.av-2{background-color:#12a89a}.av-3{background-color:#e07d1a}
.av-4{background-color:#8a3ff0}.av-5{background-color:#c0508a}
.av-6{background-color:#0e93c7}.av-7{background-color:#b8781e}

/* Поиск по списку людей */
.list-search{display:flex;align-items:center;gap:9px;background:var(--surface);border:1px solid var(--line);
  border-radius:10px;padding:8px 12px;margin-bottom:12px;max-width:460px}
.list-search svg{width:18px;height:18px;color:var(--ink-faint);flex:0 0 auto}
.list-search input{flex:1;min-width:0;border:none;background:none;font:inherit;font-size:15px;color:var(--ink);outline:none}
.list-search #person-count{font-size:12px;white-space:nowrap}

/* Карта мест (Leaflet) */
#places-map{height:420px;border-radius:11px;border:1px solid var(--line);z-index:0}
@media(max-width:640px){#places-map{height:320px}}
.map-search{display:flex;align-items:center;gap:9px;background:var(--surface-2);border:1px solid var(--line);
  border-radius:10px;padding:7px 12px;max-width:520px}
.map-search svg{width:18px;height:18px;color:var(--ink-faint);flex:0 0 auto}
.map-search input{flex:1;min-width:0;border:none;background:none;font:inherit;font-size:15px;color:var(--ink);outline:none}
.pick-panel{margin-top:10px;padding:9px 12px;background:var(--accent-soft);color:var(--accent-ink);
  border-radius:9px;font-size:14px}
.pick-panel[hidden]{display:none}
.leaflet-container{font:inherit}

/* Живая совместка: тосты, presence, «правит» */
/* --sheet-h подставляет tree.js по высоте нижнего листа: без этого тосты ложились
   поверх карточки и закрывали её кнопки. На десктопе переменная пустая → 0. */
.rt-toasts{position:fixed;right:16px;bottom:calc(16px + var(--sheet-h, 0px));z-index:10001;
  display:flex;flex-direction:column;gap:8px;max-width:calc(100vw - 32px)}
.rt-toast{display:flex;align-items:center;gap:12px;background:var(--ink);color:#fff;border-radius:11px;
  padding:11px 14px;box-shadow:0 8px 24px rgba(0,0,0,.28);font-size:14px;max-width:340px;
  animation:rt-in .2s ease}
/* крестик у вечных тостов — тише кнопки-действия, но с зоной под палец */
.rt-toast .rt-toast-x{flex:none;background:none;border:none;color:#fff;opacity:.65;
  font-size:20px;line-height:1;padding:0;width:32px;height:32px;border-radius:8px;cursor:pointer}
.rt-toast .rt-toast-x:hover{opacity:1;background:rgba(255,255,255,.12)}
.rt-toast button{border:none;background:var(--accent);color:#fff;border-radius:8px;padding:6px 12px;
  font:inherit;font-size:13px;font-weight:600;cursor:pointer;white-space:nowrap}
.rt-toast button:hover{background:var(--accent-ink)}
@keyframes rt-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.rt-presence{position:absolute;top:66px;left:50%;transform:translateX(-50%);z-index:6;
  background:var(--surface);border:1px solid var(--line);border-radius:20px;padding:5px 14px;
  font-size:13px;color:var(--ink-soft);box-shadow:0 2px 8px var(--shadow);white-space:nowrap;
  max-width:80vw;overflow:hidden;text-overflow:ellipsis}
.rt-presence[hidden]{display:none}
.rt-editing{background:var(--gold-soft);color:var(--gold);border-radius:9px;padding:8px 12px;
  font-size:13px;font-weight:600;margin-bottom:12px}
.rt-editing[hidden]{display:none}
.badge{font-size:11px;padding:2px 8px;border-radius:12px;font-weight:600;letter-spacing:.02em}
.badge.living{background:var(--accent-soft);color:var(--accent-ink)}
.badge.gone{background:var(--surface-2);color:var(--ink-soft)}
.badge.unknown{background:var(--gold-soft);color:var(--gold)}
.badge.private{background:var(--gold-soft);color:var(--gold)}

/* Галерея фото человека */
.gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:12px}
/* Массовое удаление: галочка поверх снимка, выбранное подсвечено рамкой */
.gal-bar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:0 0 12px;
  padding:8px 12px;background:var(--surface-2);border:1px solid var(--line);border-radius:10px}
.gal-bar .gal-all{display:flex;align-items:center;gap:7px;font-size:14px;cursor:pointer}
.gal-bar #gal-del{margin-left:auto}
.gal-pick{position:absolute;top:6px;left:6px;z-index:2;display:flex;padding:5px;border-radius:7px;
  background:rgba(255,255,255,.86);box-shadow:0 1px 4px rgba(0,0,0,.2);cursor:pointer}
.gal-pick input{width:18px;height:18px;margin:0;cursor:pointer}
.gal-item{position:relative;margin:0;border:1px solid var(--line);border-radius:11px;
  overflow:hidden;background:var(--surface-2)}
.gal-item.picked{border-color:var(--danger,#b5462f);box-shadow:0 0 0 2px var(--danger,#b5462f)}
.gal-item.picked img{opacity:.72}
.gal-item.is-main{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}
.gal-item img{display:block;width:100%;height:130px;object-fit:cover}
.gal-item figcaption{display:flex;flex-wrap:wrap;gap:6px;align-items:center;padding:8px}
/* «Кто на фото» — отметки людей */
.gal-tags{display:flex;flex-wrap:wrap;gap:5px;align-items:center;padding:0 8px 8px}
.gal-tag-label{font-size:12px;color:var(--ink-soft);width:100%;font-weight:600}
.tag-chip{display:inline-flex;align-items:center;gap:3px;font-size:12px;background:var(--accent-soft);
  color:var(--accent-ink);padding:2px 4px 2px 8px;border-radius:11px}
.tag-chip button{border:none;background:none;color:var(--accent-ink);cursor:pointer;font-size:15px;
  line-height:1;padding:0 3px}
.tag-chip button:hover{color:#B23A3A}
.gal-tag-add{display:flex;gap:4px;width:100%;margin-top:4px}
.gal-tag-add select{flex:1;min-width:0;padding:5px 8px;border:1px solid var(--line);border-radius:8px;
  background:var(--surface);font:inherit;font-size:13px}

/* ── Карточка человека: шапка ── */
.pc-head{display:flex;align-items:flex-start;gap:16px;margin-bottom:16px}
/* Аватар сам себе кнопка: пусто → клик по заглушке, есть фото → карандаш в углу */
.pc-av-col{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:2px}
.pc-avatar-form{margin:0}
.pc-avatar{position:relative;width:88px;height:88px;border-radius:16px;overflow:hidden;
  background:var(--accent);color:#fff;display:flex;align-items:center;justify-content:center;
  font:600 34px var(--serif);border:1px solid var(--line)}
.pc-avatar img{width:100%;height:100%;object-fit:cover}
.pc-avatar.editable{cursor:pointer}
.pc-av-btn{position:absolute;right:5px;bottom:5px;width:26px;height:26px;border-radius:50%;
  background:var(--surface);color:var(--accent-ink);border:1px solid var(--line);
  display:flex;align-items:center;justify-content:center;box-shadow:0 1px 4px var(--shadow);
  transition:.12s}
.pc-av-btn svg{width:14px;height:14px}
.pc-avatar.editable:hover .pc-av-btn{background:var(--accent);color:#fff;border-color:var(--accent)}
/* Пустой аватар: подсказка «добавить» крупнее и по центру — цель промаха меньше */
.pc-avatar.editable:not(.has-photo) .pc-av-btn{inset:auto;right:5px;bottom:5px}
.pc-avatar.editable:not(.has-photo):hover .pc-av-init{opacity:.35}
.pc-av-init{transition:.12s}
.pc-av-clear{margin:0}
.pc-av-clear .btn{font-size:12px;padding:2px 6px}
.pc-head-main{flex:1;min-width:0;padding-top:4px}
.pc-title-row{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.pc-title-row h1{margin:0}
.pc-self{margin-top:8px;display:flex;align-items:center;gap:9px;flex-wrap:wrap}
/* Заявка «Это я»: ждёт подтверждения владельца / решение владельца */
.claim-note{margin-top:8px;font-size:13px;color:var(--ink-soft);border-left:3px solid var(--accent);
  background:var(--surface-2,var(--surface));padding:8px 12px;border-radius:0 8px 8px 0}
.claim-req{margin-top:8px;display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:13px;
  border-left:3px solid #c99a2e;background:var(--surface-2,var(--surface));padding:8px 12px;
  border-radius:0 8px 8px 0}
.claim-req form{display:inline}
/* «✓ Это вы» со снятием отметки крестиком на самой плашке — вместо отдельной кнопки */
.self-badge{display:inline-flex;align-items:center;gap:6px}
.self-badge form{display:inline-flex}
.self-badge .self-x{border:none;background:none;cursor:pointer;padding:0 0 0 2px;
  font-size:15px;line-height:1;color:currentColor;opacity:.55}
.self-badge .self-x:hover{opacity:1}
.badge.age{background:var(--surface-2);color:var(--ink-soft);border:1px solid var(--line)}
.badge.dead{background:var(--gold-soft);color:var(--gold)}
.invite-card{background:var(--accent-soft);margin-bottom:16px}
.invite-head{display:flex;align-items:center;gap:9px;font-weight:600;font-size:15px;
  color:var(--accent-ink);margin-bottom:14px}
.invite-head svg{flex:none;color:var(--accent)}
.invite-fields{display:flex;flex-direction:column;gap:15px}
.invite-fld{display:flex;flex-direction:column;gap:6px}
.invite-lbl{font-size:12.5px;font-weight:600;color:var(--ink-soft)}
.invite-fld select,.invite-input{padding:9px 12px;border:1px solid var(--line);border-radius:9px;
  font:inherit;font-size:13.5px;background:var(--surface);color:var(--ink);
  width:100%;max-width:420px;box-sizing:border-box}
.invite-fld select{max-width:240px;padding-right:30px}
.invite-input:focus,.invite-fld select:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
.invite-input:disabled{opacity:.5;cursor:not-allowed}
.invite-alias{gap:7px}
.invite-check{display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  font-size:13.5px;color:var(--ink);width:fit-content}
.invite-check input{margin:0;cursor:pointer;width:16px;height:16px;accent-color:var(--accent)}
.invite-hint{font-size:12px;color:var(--ink-soft);line-height:1.4}
.invite-cta{display:flex;align-items:center;gap:12px;margin-top:18px;flex-wrap:wrap}
.invite-note{font-size:12.5px}
.invite-foot{font-size:12px;color:var(--ink-soft);margin:14px 0 0;line-height:1.45}
.invite-link{display:flex;gap:8px;align-items:center;margin-top:14px}
.invite-link input{flex:1;min-width:0;padding:9px 12px;border:1px solid var(--line);border-radius:9px;
  font:inherit;font-size:13px;background:var(--surface);color:var(--ink)}
.pc-progress{margin-top:12px;max-width:360px}
.pc-progress-lbl{display:flex;justify-content:space-between;font-size:12px;color:var(--ink-soft);margin-bottom:4px}
.pc-bar{height:7px;background:var(--surface-2);border-radius:6px;overflow:hidden}
.pc-bar>i{display:block;height:100%;background:linear-gradient(90deg,var(--gold),#d8b45a);transition:width .3s}
.pc-progress-hint{font-size:11px;color:var(--ink-faint);margin-top:5px}

/* Связи с аватарами (группы Родители/Супруги/Дети/Братья-сёстры) */
.rel-groups{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px}
@media(max-width:640px){.rel-groups{grid-template-columns:1fr}}
.rel-group h3{font:600 13px var(--sans);color:var(--ink-soft);margin:0 0 8px;text-transform:uppercase;letter-spacing:.03em}
.rel-card{display:flex;align-items:center;gap:10px;border:1px solid var(--line);border-radius:11px;
  padding:8px 10px;margin-bottom:8px;background:var(--surface)}
.rel-card .rel-person{display:flex;align-items:center;gap:10px;flex:1;min-width:0}
.rel-av{width:40px;height:40px;border-radius:10px;flex:0 0 auto;display:flex;align-items:center;
  justify-content:center;color:#fff;font-weight:700;font-size:14px;text-decoration:none;
  background-size:cover;background-position:center;border:1px solid var(--line)}
.rel-info{min-width:0;display:flex;flex-direction:column}
.rel-role{font-size:11px;color:var(--ink-faint)}
.rel-name{font-size:14px;font-weight:600;color:var(--ink);text-decoration:none;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rel-name:hover{color:var(--accent-ink);text-decoration:underline}
.rel-remove{flex:0 0 auto}
.rel-empty{margin:0;font-size:13px}
.rel-add{border-top:1px solid var(--line);padding-top:12px;margin-top:6px}

/* ── Карточка человека: вкладки ── */
.pc-tabs{display:flex;gap:4px;border-bottom:2px solid var(--line);margin:22px 0 0;flex-wrap:wrap}
.pc-tab{appearance:none;border:none;background:none;font:inherit;font-size:14px;font-weight:600;
  color:var(--ink-soft);padding:10px 14px;cursor:pointer;position:relative;border-radius:8px 8px 0 0;
  display:flex;align-items:center;gap:7px}
.pc-tab .cnt{font-size:11px;background:var(--surface-2);color:var(--ink-soft);border-radius:10px;padding:1px 7px}
.pc-tab:hover{color:var(--ink);background:var(--surface-2)}
.pc-tab.active{color:var(--accent-ink)}
.pc-tab.active::after{content:"";position:absolute;left:8px;right:8px;bottom:-2px;height:2px;background:var(--accent)}
.pc-tab.active .cnt{background:var(--accent-soft);color:var(--accent-ink)}
.pc-tab svg{width:16px;height:16px}
.pc-panel{display:none;margin-top:14px}
.pc-panel.active{display:block}

/* ── Таблица событий ── */
.evt-table{width:100%;border-collapse:collapse;font-size:13px}
.evt-table th{text-align:left;color:var(--ink-faint);font-weight:600;font-size:12px;
  padding:0 10px 8px;border-bottom:1px solid var(--line)}
.evt-table td{padding:11px 10px;border-bottom:1px solid var(--line);vertical-align:middle}
.evt-table .nowrap{white-space:nowrap}
.etype{font-weight:600}
.auto{font-size:10px;background:var(--accent-soft);color:var(--accent-ink);border-radius:10px;padding:1px 6px;font-weight:600}
.evt-parts{display:flex;flex-wrap:wrap;gap:4px;align-items:center}
.chip-a{width:26px;height:26px;border-radius:50%;background:var(--accent);color:#fff;
  display:inline-flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;flex:0 0 auto}
.evt-tags{display:flex;flex-wrap:wrap;gap:4px;align-items:center}
.evt-tags .tag{display:inline-block;background:var(--gold-soft);color:var(--gold);border-radius:10px;
  padding:1px 8px;font-size:11px}
.evt-tag-edit{display:flex;gap:3px;align-items:center;width:100%;margin-top:2px}
.evt-tag-edit input{flex:1;min-width:70px;padding:4px 7px;border:1px solid var(--line);border-radius:7px;
  font:inherit;font-size:12px;background:var(--surface-2)}

/* ── История изменений (журнал) ── */
.hist-list{list-style:none;margin:0;padding:0}
.hist-item{display:flex;gap:12px;padding:0 0 16px;position:relative}
.hist-item::before{content:"";position:absolute;left:5px;top:14px;bottom:-2px;width:2px;background:var(--line)}
.hist-item:last-child::before{display:none}
.hist-dot{width:12px;height:12px;border-radius:50%;flex:0 0 auto;margin-top:3px;
  background:var(--accent);border:2px solid var(--surface);box-shadow:0 0 0 1px var(--line);z-index:1}
.hist-family .hist-dot{background:var(--gold)}
.hist-a-delete .hist-dot{background:#B23A3A}
.hist-body{flex:1;min-width:0}
.hist-head{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
.hist-title{font-weight:600;font-size:14px}
.hist-meta{font-size:12px;color:var(--ink-faint)}
.hist-changes{list-style:none;margin:5px 0 0;padding:0;font-size:13px}
.hist-changes li{padding:1px 0;color:var(--ink-soft)}
.hist-field{color:var(--ink-faint)}
.hist-old{text-decoration:line-through;color:var(--ink-faint)}
.hist-arrow{color:var(--ink-faint)}
.hist-new{color:var(--ink);font-weight:500}

/* Формы */
.form{display:flex;flex-direction:column;gap:13px;max-width:460px}
.form.wide{max-width:none}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:13px}
.field{display:flex;flex-direction:column;gap:5px}
.field label{font-size:13px;color:var(--ink-soft);font-weight:600}
.field input,.field select,.field textarea{padding:9px 11px;border:1px solid var(--line);
  border-radius:9px;background:var(--surface);color:var(--ink);font:inherit;font-size:14px}
.field input:focus,.field select:focus,.field textarea:focus{outline:2px solid var(--accent-soft);
  border-color:var(--accent)}

/* Единый вид выпадающих списков. Системная стрелка в каждом браузере своя и с нашими
   скруглениями не дружит — убираем её и рисуем свою. Цвет фиксированный: currentColor
   в data-URI не работает, поэтому для тёмной темы правило переопределено ниже. */
.field select,.invite-row select,.member-link select,.row form select,.rf-row select,.evt-add select{
  -webkit-appearance:none;-moz-appearance:none;appearance:none;
  padding-right:30px;cursor:pointer;
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2359635C' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 9px center;background-size:14px}
.field select:hover,.invite-row select:hover,.member-link select:hover,
.row form select:hover,.rf-row select,.evt-add select:hover{border-color:var(--accent)}
:root[data-theme="dark"] .field select,:root[data-theme="dark"] .invite-row select,
:root[data-theme="dark"] .member-link select,:root[data-theme="dark"] .row form select,
:root[data-theme="dark"] .rf-row select,:root[data-theme="dark"] .evt-add select{
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A6AFA4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .field select,:root:not([data-theme="light"]) .invite-row select,
  :root:not([data-theme="light"]) .member-link select,:root:not([data-theme="light"]) .row form select,
  :root:not([data-theme="light"]) .rf-row select,:root:not([data-theme="light"]) .evt-add select{
    background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A6AFA4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")}
}
.check{flex-direction:row;align-items:center;gap:8px}
.check input{width:16px;height:16px}
.form-actions{display:flex;gap:10px;align-items:center;margin-top:4px}
.alert{padding:10px 14px;border-radius:9px;font-size:14px;margin:0 0 16px}
.alert.err{background:#FBE9E7;color:#9B2C2C;border:1px solid #F1C9C4}
:root[data-theme="dark"] .alert.err{background:#3A211F;color:#F0B7B0;border-color:#5A302C}
.muted{color:var(--ink-faint);font-size:14px}
.auth-wrap{max-width:420px;margin:6vh auto 0}

/* Визуализация древа */
.tree-canvas{position:relative;overflow:hidden;height:70vh;min-height:420px;
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--radius);
  touch-action:none;cursor:grab}
.tree-canvas:active{cursor:grabbing}
.tree-svg{display:block;user-select:none}
/* stroke задаётся атрибутом на каждом пути (свой цвет семьи); в CSS его НЕ ставим,
   иначе CSS перебьёт атрибут. Фолбэк-цвет — через :not([stroke]). */
.tree-svg .edges path{fill:none;stroke-width:2.2;stroke-linecap:round}
.tree-svg .edges path:not([stroke]){stroke:var(--ink-faint)}
.tree-svg .marriages line,.tree-svg .marriages path{stroke:var(--gold);stroke-width:2;fill:none}
/* Веер: спицы предков — прямые тонкие линии от корня к кольцам */
.tree-svg .edges path.radial-spoke{stroke-width:2.4;opacity:.85}
.tree-svg .edges path.radial-spoke.dim{opacity:.2}
.tree-svg .edges path.radial-spoke.hi{stroke-width:3.4;opacity:1}
/* Подсветка «ветки участника»: всё вне конуса приглушено, конус ярок */
.tree-svg .node.faded{opacity:.22}
.tree-svg .edges path.faded,.tree-svg .marriages line.faded,.tree-svg .marriages path.faded{opacity:.15}
.tree-svg .node rect{fill:var(--surface);stroke:var(--line);stroke-width:1.5}
/* прозрачная зона нажатия булавки — не карточка, заливать/обводить не надо */
.tree-svg .node rect.pin-hit{fill:transparent!important;stroke:none!important}
/* перетаскивание плиток со снапом к сетке + рокировка (как иконки Android) */
.tree-svg .node{cursor:grab}
.tree-svg .node.dragging{cursor:grabbing;opacity:.92}
.tree-svg .node.dragging rect{stroke:var(--accent);stroke-width:2.5}
/* тач-long-press: узел «поднят» — сигнал, что схвачен и готов к переносу */
.tree-svg .node.node-grabbed{filter:drop-shadow(0 6px 14px rgba(0,0,0,.32))}
.tree-svg .node.node-grabbed rect{stroke:var(--accent);stroke-width:2.5}
/* сосед, «отъезжающий» на освобождённую ячейку — плавно */
.tree-svg .node.reflow{transition:transform .18s ease}
/* пунктирный слот-приземление в целевой ячейке сетки */
.tree-svg .drop-slot{fill:none;stroke:var(--accent);stroke-width:2;
  stroke-dasharray:7 5;opacity:.75;pointer-events:none}
/* «сбросить раскладку» — плавающая кнопка снизу слева */
/* Панель правок живёт в верхнем тулбаре: в левом нижнем углу 30-пиксельные
   полупрозрачные иконки просто не находили. */
/* Панель правок — отдельным рядом ПОД переключателем видов: в общем ряду она
   растягивала его на пол-экрана и наезжала на название дерева. */
/* Блок правок без подложки: у самих кнопок уже есть фон и тень, общая рамка
   вокруг них была лишней. */
.layout-tools{position:absolute;top:12px;left:12px;z-index:6;display:flex;gap:6px;
  align-items:center;background:none;border:none;padding:0;box-shadow:none}
.layout-tools .btn{box-shadow:0 2px 10px var(--shadow)}
.layout-tools .btn[hidden]{display:none}
.layout-tools .btn:disabled{opacity:.45;cursor:default}
.icon-btn{padding:6px;line-height:0}
.icon-btn svg{width:16px;height:16px}
.icon-btn:disabled{opacity:.35;cursor:default;border-color:var(--line)}
/* Пол: мягкий тинт фона узла (муж — голубой, жен — розовый) */
.tree-svg .node-member{stroke:#fff;stroke-width:1.5}
/* свёртыш коллатералей в Личном виде: «+N» раскрыть / «−» свернуть */
.tree-svg .expand-chip{cursor:pointer}
.tree-svg .expand-chip rect{fill:var(--accent);stroke:#fff;stroke-width:1.5}
.tree-svg .expand-chip text{fill:#fff;font:700 11px var(--sans)}
.tree-svg .expand-chip:hover rect{fill:var(--accent-strong,var(--accent))}
.tree-svg .node.male rect{fill:var(--node-male,#eef4fc)}
.tree-svg .node.female rect{fill:var(--node-female,#fceef4)}
.tree-svg .node.living rect{stroke:var(--living)}
.tree-svg .node.unknown rect{stroke:var(--gold)}  /* неизвестно (есть дата рождения) */
.tree-svg .node.redacted rect{stroke-dasharray:4 3}
.tree-svg .node .nm{fill:var(--ink);font:600 13px var(--sans);text-anchor:middle}
.tree-svg .node .avinit{fill:#fff;font:600 15px var(--sans);text-anchor:middle;pointer-events:none}
.tree-svg .node .avph{opacity:.92}
.tree-svg .node .yr{fill:var(--ink-soft);font:11px var(--sans);text-anchor:middle;
  font-variant-numeric:tabular-nums}
.toolbar{display:flex;gap:10px;align-items:center;margin:0 0 14px;flex-wrap:wrap}

.invite-row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.invite-row select{padding:8px 30px 8px 11px;border:1px solid var(--line);border-radius:9px;
  background-color:var(--surface);color:var(--ink);font:inherit;font-size:14px}
.invite-row select:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
.invite-row #inv-note{font-size:12px}
#inv-link{margin-top:10px}

/* Кого из дерева представляет аккаунт */
.member-link{display:flex;align-items:center;gap:6px;margin-top:4px;font-size:12.5px;flex-wrap:wrap}
.member-link select{font:inherit;font-size:12.5px;padding:2px 6px;border-radius:7px;
  border:1px solid var(--line);background:var(--surface);color:var(--ink);max-width:230px}

/* Галочка «видит ветку супруга» у участника */
.ssb-form{margin:0}
.ssb{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--ink-soft);
  white-space:nowrap;cursor:pointer}
.ssb input{margin:0;cursor:pointer}

/* Плитки деревьев: превью с мини-эскизом + название + размер */
.tiles{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));margin:0 0 22px}
.tile{display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius);overflow:hidden;text-decoration:none;color:inherit;
  box-shadow:0 1px 2px var(--shadow);transition:.14s}
.tile:hover{border-color:var(--accent);box-shadow:0 6px 18px var(--shadow);transform:translateY(-1px)}
.tile-prev{background:var(--surface-2);border-bottom:1px solid var(--line);padding:14px;
  display:flex;align-items:center;justify-content:center}
.tile-sketch{width:100%;max-width:190px;height:auto;display:block}
.tile-sketch .s-node{fill:var(--surface);stroke:var(--accent);stroke-width:1.6;opacity:.75}
.tile-sketch .s-me{fill:var(--accent-soft);stroke:var(--accent);opacity:1}
.tile-sketch .s-line{fill:none;stroke:var(--accent);stroke-width:1.4;opacity:.45;stroke-linecap:round}
.tile-sketch .s-empty{stroke:var(--ink-faint);stroke-dasharray:3 3;opacity:.6;fill:none}
.tile-body{padding:12px 14px 13px;display:flex;flex-direction:column;gap:5px;flex:1}
.tile-name{font-weight:600;font-size:15px;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.tile-desc{font-size:13px;color:var(--ink-soft);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tile-meta{margin-top:auto;padding-top:6px;display:flex;justify-content:space-between;
  align-items:center;font-size:12.5px;color:var(--ink-faint)}
.tile-link{color:var(--accent-ink);cursor:pointer}
.tile-link:hover{text-decoration:underline}
#trash-btn.active{border-color:var(--accent);background:var(--accent-soft);color:var(--accent-ink)}
.empty-state{text-align:center;display:flex;flex-direction:column;align-items:center;gap:10px;padding:26px}
.empty-state .tile-prev{background:none;border:none;padding:0}

/* Модалка (нативный <dialog>): Создать / Отмена */
.modal{border:1px solid var(--line);border-radius:var(--radius);padding:20px;max-width:440px;width:calc(100% - 32px);
  background:var(--surface);color:var(--ink);box-shadow:0 18px 50px var(--shadow)}
.modal::backdrop{background:rgba(20,26,22,.45)}
.modal-head h2{font-family:var(--serif);font-size:21px;margin:0 0 14px}
.modal-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:18px}

/* Вкладки страницы дерева: люди / семьи / участники / места */
.tabs{display:flex;gap:2px;align-items:flex-end;margin:0 0 18px;border-bottom:1px solid var(--line);
  overflow-x:auto;-webkit-overflow-scrolling:touch}
.tabs .tab{flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;padding:9px 14px;
  border:none;background:none;font:inherit;font-size:14px;color:var(--ink-soft);cursor:pointer;
  border-bottom:2px solid transparent;margin-bottom:-1px;text-decoration:none;white-space:nowrap}
.tabs .tab:hover{color:var(--ink)}
.tabs .tab.active{color:var(--accent-ink);border-bottom-color:var(--accent);font-weight:600}
.tabs .tab-n{font-size:12px;color:var(--ink-faint);background:var(--surface-2);
  border-radius:9px;padding:1px 7px;font-variant-numeric:tabular-nums}
.tabs .tab.active .tab-n{background:var(--accent-soft);color:var(--accent-ink)}
[data-pane][hidden]{display:none}
.hint{font-size:13px;color:var(--ink-faint)}

/* ── Мобильная адаптация ── */
@media (max-width:560px){
  .topbar{padding:10px 12px;gap:8px}
  .brand span{display:none}
  .brand .mark{width:22px;height:22px}
  .nav-actions{gap:10px;font-size:13px}
  .user-name{display:none}                 /* имя прячем, аватар остаётся */
  .user-chip{padding:4px}
  .content{padding:24px 14px}
  .hero h1{font-size:29px}
  .page-head{flex-wrap:wrap;gap:2px 10px}
  .page-head h1{font-size:23px}
  /* строки списков переносятся: имя на всю ширину, действия — ниже */
  .row{flex-wrap:wrap}
  .row .grow{flex-basis:100%;margin-bottom:4px}
  .row form{flex-wrap:wrap;width:100%}
  .row form select{flex:1 1 140px;min-width:0}
  /* формы в один столбец, поля не распирают */
  .grid2{grid-template-columns:1fr}
  .field input,.field select,.field textarea{width:100%;min-width:0}
  .form,.auth-wrap{max-width:none}
  /* публичная ссылка не выходит за экран */
  #public-panel .row input{min-width:0;width:100%}
  .tree-canvas{height:66vh}
}

.tree-svg .node{cursor:pointer}
.tree-svg .node.selected rect{stroke:var(--gold);stroke-width:3}

/* Ручки связи (диаграммный UX): точки по сторонам выбранного узла */
/* Ручки-«плюсы» вокруг выбранного: клик — добавить родню, протяжка — связать */
.tree-svg .link-handle{fill:var(--accent);stroke:#fff;stroke-width:2;pointer-events:none}
.tree-svg .link-handle-plus{stroke:#fff;stroke-width:2;stroke-linecap:round;pointer-events:none}
.tree-svg .link-handle-hit{fill:transparent;cursor:pointer}
.tree-svg .kin-handle:hover .link-handle{fill:var(--accent-ink)}
/* Заготовки родни вокруг выбранного (раскрываются «плюсом»): пол зашит в кнопку */
.tree-svg .kin-backdrop{fill:var(--paper,#f2efe7);opacity:.72;cursor:pointer}
.tree-svg .kin-ghost{cursor:pointer}
.tree-svg .kin-ghost rect{fill:var(--surface);stroke:var(--accent);stroke-width:1.5;
  stroke-dasharray:5 4;opacity:.97}
.tree-svg .kin-ghost:hover rect{stroke-dasharray:none;stroke-width:2;fill:var(--surface-2,var(--surface))}
.tree-svg .kin-ghost .gav{fill:var(--accent);opacity:.14;stroke:none}
.tree-svg .kin-ghost .gplus{stroke:var(--accent-ink,var(--accent));stroke-width:2.2;stroke-linecap:round}
.tree-svg .kin-ghost text{fill:var(--ink);font-size:13px;font-weight:600;dominant-baseline:auto}
.tree-svg .kin-ghost-x{cursor:pointer}
.tree-svg .kin-ghost-x circle{fill:var(--surface);stroke:var(--line);stroke-width:1}
.tree-svg .kin-ghost-x path{stroke:var(--ink-soft);stroke-width:2;stroke-linecap:round}
.tree-svg .kin-ghost-x:hover circle{stroke:var(--ink-soft)}
/* подпись «Добавить родню» у плюса — по наведению (ручки только для мыши) */
.tree-svg .kin-lab{opacity:0;transition:opacity .12s;pointer-events:none}
.tree-svg .kin-handle:hover .kin-lab{opacity:1}
.tree-svg .kin-lab rect{fill:var(--surface);stroke:var(--line);stroke-width:1}
.tree-svg .kin-lab text{fill:var(--ink);font-size:11px;font-weight:600}
.tree-svg .node.link-target rect{stroke:var(--accent);stroke-width:3.5}
.link-drag-overlay{position:fixed;inset:0;width:100vw;height:100vh;pointer-events:none;z-index:9999}
.link-drag-line{stroke:var(--accent);stroke-width:2.5;stroke-dasharray:6 5;fill:none;stroke-linecap:round}

/* Поповер «создать и связать» (тянешь ручку в пустоту) */
.drag-create{position:fixed;z-index:10000;width:260px;background:var(--surface);
  border:1px solid var(--line);border-radius:12px;box-shadow:0 8px 28px var(--shadow);padding:14px}
.drag-create[hidden]{display:none}
.drag-create .dc-title{font-size:12px;color:var(--ink-faint);margin-bottom:8px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.drag-create .dc-name{width:100%;padding:9px 11px;border:1px solid var(--line);border-radius:9px;
  font:inherit;font-size:14px;background:var(--surface-2)}
.drag-create .dc-name:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
.drag-create .dc-hint{font-size:12px;color:var(--ink-soft);margin:10px 0 6px}
.drag-create .dc-rels{display:grid;grid-template-columns:1fr 1fr;gap:6px}
/* свой display перебивает UA-правило [hidden] — возвращаем скрытие явно, иначе с
   готовой заготовкой («Жена») ниже всё равно виден выбор родства */
.drag-create [hidden]{display:none}
.drag-create .dc-rels button{padding:8px 6px;border:1px solid var(--line);border-radius:9px;
  background:var(--surface);font:inherit;font-size:13px;cursor:pointer;color:var(--accent-ink);font-weight:600}
.drag-create .dc-rels button:hover{background:var(--accent);border-color:var(--accent);color:#fff}
/* выбранное родство (проставлено заготовкой или кликом) */
.drag-create .dc-rels button.on{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:600}
.drag-create .dc-sexrow{display:flex;align-items:center;gap:8px;margin:10px 0 10px;
  font-size:12px;color:var(--ink-soft)}
.drag-create .dc-sexrow select{flex:1;padding:7px 9px;border:1px solid var(--line);border-radius:9px;
  background:var(--surface);color:var(--ink);font:inherit;font-size:13px}
.drag-create .dc-go{width:100%}
.drag-create .dc-go[disabled]{opacity:.45;cursor:default}
.drag-create .dc-cancel{margin-top:8px;width:100%;padding:6px;border:none;background:none;
  color:var(--ink-faint);font:inherit;font-size:12px;cursor:pointer}
.drag-create .dc-err{color:#B23A3A;font-size:12px;margin:6px 0 0}

/* Педигри-медиана: полутон половин + пунктир по центру */
.tree-svg .half-l{fill:#3f6ad0;opacity:.05}
.tree-svg .half-r{fill:#c0508a;opacity:.05}
.tree-svg .median-line{stroke:#c0508a;stroke-width:1.5;stroke-dasharray:6 5;opacity:.5}

/* «Часы»: холст на территории не делим (веера предков перекрываются по природе —
   у каждого двое родителей), поэтому чья это линия метим самой карточкой */

/* Чип «+N» лежит ВНУТРИ карточки, поэтому `.node.male rect` перекрашивал и его —
   получался белый текст на почти белом фоне. Селектор должен быть не слабее. */
.tree-svg .node .expand-chip rect{fill:var(--accent);stroke:#fff;stroke-width:1.5}
.tree-svg .node .expand-chip text{fill:#fff;font:700 13px var(--sans)}
.tree-svg .node .expand-chip:hover rect{fill:var(--accent-strong,#0f4a39)}

/* Сват: стоп-знак на верхней грани — предков этой родни добавляет админ */
.tree-svg .node .node-stop .stopbg{fill:var(--surface);stroke:var(--line);stroke-width:1}
.tree-svg .node .node-stop .stopring{fill:none;stroke:#c0392b;stroke-width:1.4;opacity:.85}
.tree-svg .node .node-stop .stopline{stroke:#c0392b;stroke-width:1.4;stroke-linecap:round;opacity:.85}

/* Ушёл из жизни: свеча бейджем на кромке аватара — тихая пометка, не акцент.
   Стоит ПОСЛЕ `.node.male/.female rect`: специфичность равная, побеждает нижний —
   иначе тело свечи красится в цвет карточки по полу. */
.tree-svg .node .node-passed{opacity:.75}
.tree-svg .node .node-passed .pbg{fill:var(--surface);stroke:var(--line);stroke-width:1}
.tree-svg .node .node-passed rect{fill:#8c959e;stroke:none}
.tree-svg .node .node-passed ellipse{fill:#d8a93c;stroke:none}

/* Ветка выбранной персоны: карточки и ЕЁ линии связи выделены жирным.
   Не гасим остальных — это поверх обычного выделения, а не вместо. */
.tree-svg .node.branch > rect{stroke:var(--gold);stroke-width:2.5}
.tree-svg .edges path.hi{stroke-width:4;stroke-linecap:round}
.tree-svg .marriages line.hi,.tree-svg .marriages path.hi{stroke-width:4}
/* всё, что не в ветке, тухнет — она и заменяет прежние «Ветки участника» */
.tree-svg .edges path.dim,.tree-svg .marriages line.dim,.tree-svg .marriages path.dim{opacity:.22}
.tree-svg .node.dim{opacity:.3;transition:opacity .2s ease}
.tree-svg .node.dim:hover{opacity:.75}   /* навёл — видно, по кому кликать дальше */

/* Переключатель представлений: три иконки — Дерево · Пара · Часы */
.view-switch{display:inline-flex;border:1px solid var(--line);border-radius:9px;overflow:hidden}
.vbtn{display:inline-flex;align-items:center;justify-content:center;width:40px;height:34px;
  background:var(--surface);color:var(--ink-soft);cursor:pointer;text-decoration:none;border:none}
.vbtn+.vbtn{border-left:1px solid var(--line)}
.vbtn:hover{color:var(--accent);background:var(--surface-2)}
.vbtn.active{background:var(--accent);color:#fff}
.vbtn svg{width:21px;height:21px}
.vlbl{display:none}  /* подписи к иконкам — только на мобилке (нет hover-подсказок) */

/* «+ добавить ▾» с выпадашкой (родителя/супруга/ребёнка) */
.add-group{position:relative;display:inline-block}
.add-menu{position:absolute;left:0;bottom:calc(100% + 5px);z-index:20;display:flex;flex-direction:column;
  gap:3px;background:var(--surface);border:1px solid var(--line);border-radius:10px;padding:5px;
  box-shadow:0 8px 22px var(--shadow);min-width:140px}
.add-menu[hidden]{display:none}
.add-menu .btn{border:none;justify-content:flex-start;width:100%}
.add-menu .btn:hover{background:var(--surface-2);border-color:transparent}
.sheet-grab{display:none}

/* Онбординг-плашка «С чего начать» (первый заход) */
.strip-help{width:30px;padding:5px 0;justify-content:center;font-weight:700}
.onboard{position:absolute;top:60px;left:50%;transform:translateX(-50%);z-index:9;width:min(360px,92vw);
  background:var(--surface);border:1px solid var(--line);border-radius:13px;padding:16px 18px;
  box-shadow:0 8px 26px var(--shadow)}
.onboard[hidden]{display:none}
.onboard-title{font-family:var(--serif);font-size:19px;margin:0 0 8px}
.onboard-steps{margin:0 0 12px;padding-left:20px;font-size:14px;color:var(--ink-soft);line-height:1.6}
.onboard-steps b{color:var(--ink)}
.onboard-x{position:absolute;top:8px;right:10px;border:none;background:none;font-size:22px;
  line-height:1;color:var(--ink-faint);cursor:pointer;padding:2px 6px}
.onboard-x:hover{color:var(--ink)}

/* Пошаговый мастер онбординга (Вы → Мама → Папа → Готово).
   Фон полупрозрачный — под ним виден растущий настоящий граф (живой предпросмотр). */
.wiz-overlay{position:absolute;inset:0;z-index:12;display:flex;align-items:center;
  justify-content:center;padding:16px;background:rgba(20,26,22,.28);backdrop-filter:blur(1.5px)}
.wiz-overlay[hidden]{display:none}
.wiz-card{position:relative;width:min(420px,94vw);background:var(--surface);
  border:1px solid var(--line);border-radius:16px;box-shadow:0 18px 50px rgba(20,30,25,.28);
  padding:22px 22px 20px}
.wiz-x{position:absolute;top:10px;right:12px;border:none;background:none;font-size:22px;line-height:1;
  color:var(--ink-faint);cursor:pointer;padding:2px 6px}
.wiz-x:hover{color:var(--ink)}
.wiz-dots{display:flex;align-items:center;gap:6px;margin-bottom:16px;flex-wrap:wrap}
.wiz-dot{font-size:11.5px;color:var(--ink-faint);white-space:nowrap}
.wiz-dot.on{color:var(--accent-ink);font-weight:700}
.wiz-dot.done{color:var(--accent)}
.wiz-sep{flex:1;min-width:8px;height:1px;background:var(--line)}
.wiz-title{font-family:var(--serif);font-size:23px;line-height:1.2;margin:0 0 6px;text-wrap:balance}
.wiz-sub{font-size:14px;color:var(--ink-soft);margin:0 0 16px;line-height:1.5}
.wiz-lbl{display:block;font-size:12.5px;font-weight:600;color:var(--ink-soft);margin:0 0 5px}
.wiz-opt{font-weight:400;color:var(--ink-faint)}
.wiz-inp{width:100%;box-sizing:border-box;border:1px solid var(--line);border-radius:9px;
  padding:10px 12px;font:inherit;font-size:15px;color:var(--ink);background:var(--surface);
  margin:0 0 13px;outline:none}
.wiz-inp:focus{border-color:var(--accent)}
.wiz-sex{display:flex;gap:8px;margin:0 0 13px}
.wiz-seg{flex:1;border:1px solid var(--line);background:var(--surface);border-radius:9px;
  padding:9px 0;font:inherit;font-size:14px;color:var(--ink);cursor:pointer}
.wiz-seg:hover{border-color:var(--accent)}
.wiz-seg.on{background:var(--accent);border-color:var(--accent);color:#fff}
.wiz-err{background:var(--gold-soft);color:#8a5a12;border-radius:8px;padding:7px 10px;
  font-size:13px;margin:0 0 12px}
.wiz-err[hidden]{display:none}
.wiz-actions{display:flex;align-items:center;gap:10px;margin-top:4px}
.wiz-actions .btn-primary{padding:10px 20px;font-size:15px}
.wiz-later{color:var(--ink-soft)}
.wiz-skip{display:block;width:100%;margin-top:14px;border:none;background:none;
  color:var(--ink-faint);font:inherit;font-size:13px;cursor:pointer;text-align:center}
.wiz-skip:hover{color:var(--accent-ink);text-decoration:underline}
.wiz-check{width:52px;height:52px;border-radius:50%;background:var(--accent-soft);color:var(--accent);
  display:flex;align-items:center;justify-content:center;margin:4px 0 14px}
.wiz-check svg{width:28px;height:28px}
@media (max-width:1024px), (pointer:coarse), (hover:none){
  .wiz-overlay{align-items:flex-end;padding:0}
  .wiz-card{width:100%;border-radius:18px 18px 0 0;padding:20px 18px calc(18px + env(safe-area-inset-bottom))}
}

/* FAB «+» — добавить человека, когда никто не выбран */
.fab{position:fixed;right:18px;bottom:18px;z-index:8;width:56px;height:56px;border-radius:50%;
  border:none;background:var(--accent);color:#fff;font-size:30px;line-height:1;cursor:pointer;
  display:flex;align-items:center;justify-content:center;box-shadow:0 4px 14px var(--shadow);
  transition:.12s}
.fab:hover{background:var(--accent-ink)}
.fab[hidden]{display:none}
/* Название дерева в полосе */

/* ── Полотно-на-весь-экран + плавающие островки (как Miro/Фэмири) ──
   Применяется на ВСЕХ размерах: граф — ядро продукта, ему максимум места. */
.content-full{max-width:none;padding:0}
.graph-page{position:relative}
.graph-page .crumbs,.graph-page .page-head{display:none}
/* карта во всю площадь под шапкой */
.tree-canvas{height:calc(100vh - 52px);height:calc(100dvh - 52px);min-height:0;
  border-radius:0;border-left:none;border-right:none;margin:0}
/* островок контролов — сверху-справа; на десктопе виден всегда (как в Google Maps) */
#tree-strip{position:absolute;top:12px;right:var(--rail-gap);left:auto;z-index:6;margin:0;width:auto;
  display:flex;gap:8px;align-items:center;padding:7px 9px;border-radius:12px;
  background:var(--surface);border:1px solid var(--line);box-shadow:0 2px 10px var(--shadow);
  transition:transform .2s ease,opacity .2s ease}
/* Поиск человека на полотне — островок слева сверху: лупа + поле + список найденных */
.graph-search{position:absolute;top:12px;left:12px;z-index:6;display:flex;align-items:center;gap:6px;
  flex-wrap:wrap;padding:5px 8px;border-radius:12px;background:var(--surface);border:1px solid var(--line);
  box-shadow:0 2px 10px var(--shadow);max-width:min(46vw,300px);transition:transform .2s ease,opacity .2s ease}
.gs-icon{display:flex;align-items:center;justify-content:center;width:28px;height:28px;flex:0 0 auto;
  border:none;background:none;color:var(--ink-faint);cursor:pointer;padding:0}
.gs-icon svg{width:17px;height:17px}
.gs-field{display:flex;align-items:center;gap:4px;flex:1;min-width:0}
.graph-search input{border:none;background:none;font:inherit;font-size:14px;color:var(--ink);
  outline:none;min-width:0;width:100%}
.graph-search input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
.gs-clear{display:flex;align-items:center;justify-content:center;width:22px;height:22px;flex:0 0 auto;
  border:none;background:none;color:var(--ink-faint);cursor:pointer;padding:0;border-radius:50%}
.gs-clear:hover{background:var(--surface-2);color:var(--ink)}
.gs-clear svg{width:14px;height:14px}
.gs-clear[hidden]{display:none}
/* список результатов — выпадает под полем на всю ширину островка */
.gs-results{list-style:none;margin:6px 0 0;padding:0;width:100%;flex-basis:100%;
  max-height:min(50vh,320px);overflow-y:auto;border-top:1px solid var(--line)}
.gs-results[hidden]{display:none}
.gs-item{display:flex;align-items:baseline;gap:8px;padding:8px 6px;border-radius:8px;cursor:pointer}
.gs-item:hover{background:var(--surface-2)}
.gs-name{font-size:13.5px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gs-yr{font-size:11.5px;color:var(--ink-faint);flex:0 0 auto;font-variant-numeric:tabular-nums}
.gs-empty{padding:10px 6px;font-size:13px;color:var(--ink-faint);text-align:center}
/* найденные — золотой контур, остальные приглушены; выбранный из списка — ярче */
.tree-svg .node.search-hit > rect{stroke:var(--gold);stroke-width:3}
.tree-svg .node.search-dim{opacity:.22}
.tree-svg .node.search-pick > rect{stroke:var(--gold);stroke-width:3.5;filter:drop-shadow(0 0 4px var(--gold))}
/* Фантомы: призрачный предпросмотр родни соседа вокруг узла (кросс-мостик) */
.tree-svg .phantom-link{stroke:#2f6ae0;stroke-width:2;stroke-dasharray:4 4;opacity:.5}
.tree-svg .phantom-rect{fill:var(--surface);stroke:#2f6ae0;stroke-width:1.6;stroke-dasharray:5 4;opacity:.6}
.tree-svg .phantom-av{fill:#2f6ae0;opacity:.5}
.tree-svg .phantom-init{fill:#fff;font-size:15px;font-weight:700;text-anchor:middle;opacity:.9}
.tree-svg .phantom-nm{fill:var(--ink-soft);font-size:12.5px;opacity:.85}
.tree-svg .phantom{opacity:.9}
/* точечный импорт: призрак кликабелен */
.tree-svg .phantom-add{cursor:pointer}
.tree-svg .phantom-add:hover .phantom-rect{opacity:.95;stroke-dasharray:none}
.tree-svg .phantom-add:hover .phantom-av{opacity:.85}
.tree-svg .phantom-plus-bg{fill:#2f6ae0;opacity:.85}
.tree-svg .phantom-plus-tx{fill:#fff;font-size:16px;font-weight:700;text-anchor:middle}
.tree-svg .phantom-add:hover .phantom-plus-bg{opacity:1}
.tree-svg .phantom-busy{opacity:.4;pointer-events:none}
/* 2-й уровень (родня родни) — «двойное осветление»: бледнее и без бейджа */
.tree-svg .phantom2{opacity:.55}
.tree-svg .phantom2 .phantom-nm{font-size:11px}
.tree-svg .phantom2 .phantom-init{font-size:12px}
.tree-svg .phantom-link2{opacity:.28;stroke-width:1.4;stroke-dasharray:3 4}
/* тост-уведомление поверх графа */
.tree-toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(12px);
  background:#1f2937;color:#fff;padding:10px 16px;border-radius:10px;font-size:14px;
  box-shadow:0 6px 24px rgba(0,0,0,.28);opacity:0;pointer-events:none;z-index:9999;
  transition:opacity .18s,transform .18s;max-width:80vw}
.tree-toast--show{opacity:1;transform:translateX(-50%) translateY(0)}
.tree-toast--err{background:#b3261e}
/* островок с названием дерева — отдельно, по центру сверху */
/* Имя дерева живёт в полосе МЕЖДУ поиском слева и панелью справа. Раньше оно
   центрировалось по окну и после переноса кнопок в панель обрезалось. */
.tree-name-island{position:absolute;top:12px;left:270px;right:300px;z-index:6;
  margin:0 auto;width:max-content;
  padding:8px 16px;border-radius:12px;background:var(--surface);border:1px solid var(--line);
  box-shadow:0 2px 10px var(--shadow);font-weight:600;color:var(--ink);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;max-width:100%;transition:transform .2s ease,opacity .2s ease}
/* плашка «ветки участника» — под названием дерева, по центру сверху */
.focus-banner{position:absolute;top:56px;left:50%;transform:translateX(-50%);z-index:6;
  display:flex;align-items:center;gap:12px;padding:6px 8px 6px 16px;border-radius:12px;
  background:var(--accent-soft);border:1px solid var(--accent);box-shadow:0 2px 10px var(--shadow);
  color:var(--ink);white-space:nowrap;max-width:70vw}
.focus-banner b{overflow:hidden;text-overflow:ellipsis;max-width:36vw}
.focus-banner[hidden]{display:none}  /* иначе display:flex перебивает атрибут hidden */
/* островок зума справа */
.zoom-island{position:absolute;right:var(--rail-gap);top:50%;transform:translateY(-50%);z-index:6;
  display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line);
  border-radius:12px;box-shadow:0 2px 10px var(--shadow);overflow:hidden;transition:opacity .2s ease}
.zoom-island button{width:38px;height:36px;border:none;background:none;color:var(--ink-soft);
  cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0}
.zoom-island button+button{border-top:1px solid var(--line)}
.zoom-island button:hover{background:var(--surface-2);color:var(--accent)}
.zoom-island svg{width:18px;height:18px}
/* островок действий по выбранному — плавающая карточка снизу по центру.
   .graph-page-скоуп — чтобы перебить базовый .node-toolbar ниже по файлу. */
.graph-page .node-toolbar{position:fixed;left:50%;transform:translateX(-50%);bottom:16px;z-index:7;
  margin:0;min-width:320px;max-width:min(880px,94vw);border-radius:14px;overflow:visible;
  box-shadow:0 6px 24px var(--shadow)}

/* ── Мобилка и планшет: полоса на всю ширину, действия — нижним листом ── */
/* Мобильный вид = узкий экран ИЛИ нет мыши. Планшет бывает шире 1024, но пальцем
   боковая панель на 384px неудобна — там нужен тот же нижний лист, что на телефоне.
   Парный блок для десктопа ниже требует и ширины, и мыши — иначе они пересекались бы
   на планшете и правила спорили порядком. */
@media (max-width:1024px), (pointer:coarse), (hover:none){
  .strip-full{display:none}
  /* держим полосу в правой части и разрешаем перенос (ось уходит на 2-й ряд),
     чтобы в педигри-виде она не наезжала на имя дерева слева */
  /* Стопка островков справа: вид · настройки · ?. Общий фон убираем — каждый
     элемент сам себе плашка (см. артефакт 1cfebe25). */
  #tree-strip{top:12px;right:var(--rail-gap);left:auto;padding:0;background:none;border:none;box-shadow:none;
    flex-direction:column;align-items:flex-end;gap:8px;width:auto;max-width:none}
  #tree-strip > .view-dd .view-dd-trigger,
  #tree-strip > .strip-settings,
  #tree-strip > #help-btn{background:var(--surface);border:1px solid var(--line);
    box-shadow:0 2px 8px var(--shadow);border-radius:11px;min-height:40px}
  /* настройки на мобилке — только шестерёнка */
  #tree-strip > .strip-settings{width:40px;height:40px;padding:0;justify-content:center}
  #tree-strip > .strip-settings .ss-txt{display:none}
  #tree-strip > .strip-settings .ss-ic{display:block}
  #tree-strip > #help-btn{width:40px;height:40px;padding:0}
  /* зум — по центру правого края (подняли из низа) */
  .zoom-island{top:50%;bottom:auto;right:var(--rail-gap);transform:translateY(-50%);
    flex-direction:column;border-radius:12px}
  .zoom-island button{width:40px;height:40px}
  /* на тач-экране место дорого: островки уезжают при работе с картой */
  .graph-page.map-active #tree-strip,
  .graph-page.map-active .fab{transform:translateY(-160%);opacity:0;pointer-events:none}
  .graph-page.map-active .fab{transform:translateY(120%)}
  .tree-name-island{left:8px;transform:none;top:8px;max-width:30vw;padding:7px 12px}
  /* второй ряд под именем дерева — не налезает на имя (top:8px) и на виды (right:8px) */
  /* Мобилка: второй ряд под именем дерева. Свёрнуто — только лупа (40px), тап (.open)
     → строка + список во всю ширину. Не налезает на имя (top:8px) и виды (right:8px). */
  .graph-search{top:54px;left:8px;right:auto;padding:5px;max-width:calc(100vw - 16px)}
  .graph-search:not(.open){width:40px;height:40px;padding:0}
  .graph-search:not(.open) .gs-icon{width:40px;height:40px}
  .graph-search:not(.open) .gs-field,
  .graph-search:not(.open) .gs-results{display:none}
  .graph-search.open{left:8px;right:8px;max-width:none;width:auto}
  .graph-page.map-active .graph-search{transform:translateY(-260%);opacity:0;pointer-events:none}
  .graph-page.map-active .tree-name-island{transform:translateY(-160%);opacity:0;pointer-events:none}
  /* иконки видов с подписью (нет hover на телефоне) — компактно по высоте,
     чтобы островок видов не наезжал на второй ряд с поиском */
  #tree-strip{padding:5px 6px}
  .vbtn{flex-direction:column;gap:1px;width:auto;min-width:44px;height:auto;padding:3px 7px}
  .vbtn svg{width:16px;height:16px}
  .vlbl{display:block;font-size:9px;line-height:1;font-weight:600}
  /* +/- показываем и на телефоне: «вписать всё» пальцами не заменишь.
     Позиция задана выше (по центру правого края) — здесь только показываем. */
  .zoom-island{display:flex}
  /* панели-листы = нижний лист во всю ширину */
  .graph-page .node-toolbar{left:0;right:0;bottom:0;transform:none;min-width:0;max-width:none;
    border-radius:16px 16px 0 0;box-shadow:0 -4px 18px var(--shadow);transition:transform .2s ease}
  /* Полоска рисуется псевдоэлементом, а нажимается вся кнопка: сама полоска
     40×5 — в неё пальцем не попасть, лист «не поднимался». Вид тот же, зона 88×26. */
  .sheet-grab{display:block;width:88px;height:26px;margin:0 auto 2px;padding:0;
    border:none;background:none;position:relative;cursor:pointer}
  .sheet-grab::before{content:"";position:absolute;left:50%;top:10px;transform:translateX(-50%);
    width:40px;height:5px;border-radius:3px;background:var(--line)}
  /* зона протяжки листа: жест наш, а не браузера (иначе страница поедет сама) */
  .node-toolbar .sheet-grab,
  .node-toolbar .pcard-hd{touch-action:none}
  /* свёрнутый лист: видны только «ручка» + имя */
  /* .pcard-secs — тоже: иначе «свёрнутый» лист с раскрытыми разделами оставался
     во весь экран, и ручка переставала что-либо сворачивать */
  .node-toolbar.collapsed .node-actions,
  .node-toolbar.collapsed .pcard-secs,
  .node-toolbar.collapsed .relative-form{display:none}
  .node-toolbar.collapsed{padding-bottom:10px}
  .node-actions{gap:6px}
  /* Мини-лист: имя и действия сразу, разделы — по тапу. На узком экране полный
     список разделов закрывал бы дерево целиком, ради которого сюда и пришли. */
  /* .node-toolbar перед классом — чтобы перебить глобальное .pcard-more{display:none}
     ниже по файлу (одинаковая точность там решалась бы порядком, не в нашу пользу) */
  .node-toolbar .pcard-more{display:flex;align-items:center;gap:6px;width:100%;background:none;border:0;
    border-top:1px solid var(--line-soft,var(--line));margin-top:2px;padding:9px 2px 2px;
    font:inherit;font-size:12px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;
    color:var(--ink-soft);cursor:pointer}
  .pcard-more-ch{width:7px;height:7px;margin-left:auto;border-left:2px solid currentColor;
    border-bottom:2px solid currentColor;transform:rotate(-45deg);transition:transform .18s ease}
  .node-toolbar[data-expanded="1"] .pcard-more-ch{transform:rotate(135deg)}
  .node-toolbar:not([data-expanded="1"]) .pcard-secs{display:none}
  .node-toolbar.collapsed .pcard-more{display:none}
  /* Раскрытый лист не должен перерастать экран: иначе шапка с крестиком и сама
     строка «Подробнее» уезжают за верхний край — ни свернуть, ни закрыть.
     Держим потолок, а разделы внутри листа прокручиваем. */
  .graph-page .node-toolbar[data-expanded="1"]{max-height:78vh}
  .graph-page .node-toolbar[data-expanded="1"] .pcard-secs{
    flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
    -webkit-overflow-scrolling:touch}
}

/* «Подробнее о человеке» — только на узком экране (правила показа — в медиазапросе
   выше). На десктопе разделы видны сразу, прятать их за тапом незачем. */
.pcard-more{display:none}

/* Кнопка «＋ Родня» нужна только там, где нет мыши: с мышью родню добавляют
   «плюсом» на ручке узла, и вторая точка входа лишь мусорит панель. */
.kin-add-btn{display:none}
.coarse-pointer .kin-add-btn{display:inline-flex;align-items:center}

/* Лист «Кого добавить?» — тач-замена заготовкам вокруг узла: восемь призраков
   в 320px не помещаются и мелковаты для пальца. */
.kin-pick{position:fixed;left:0;right:0;bottom:0;z-index:22;background:var(--surface);
  border-top:1px solid var(--line);border-radius:16px 16px 0 0;
  padding:8px 14px calc(16px + env(safe-area-inset-bottom));
  box-shadow:0 -6px 22px var(--shadow)}
.kin-pick[hidden]{display:none}
.kin-pick-hd{display:flex;align-items:flex-start;gap:8px;margin-bottom:10px}
.kin-pick-hd b{font-size:15px}
.kin-pick-hd .muted{display:block;font-size:12px}
.kin-pick-x{margin-left:auto;width:30px;height:30px;flex:none;border:1px solid var(--line);
  border-radius:9px;background:var(--surface);color:var(--ink-soft);font-size:18px;line-height:1;cursor:pointer}
.kin-pick-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.kin-pick-grid button{display:flex;align-items:center;gap:9px;padding:11px 10px;font:inherit;
  font-size:14px;font-weight:600;color:var(--ink);background:var(--surface);
  border:1px solid var(--line);border-radius:11px;cursor:pointer;text-align:left}
.kin-pick-grid button:active{background:var(--surface-2,var(--bg))}
.kin-pick-grid i{width:26px;height:26px;flex:none;display:grid;place-items:center;font-style:normal;
  font-size:15px;font-weight:700;border-radius:50%;background:var(--accent-soft,var(--bg));color:var(--accent)}
.kin-pick-back{position:fixed;inset:0;z-index:21;background:rgba(0,0,0,.28)}
.kin-pick-back[hidden]{display:none}

/* Тулбар выделенного узла */
.node-toolbar{display:flex;flex-direction:column;gap:10px;margin:0 0 14px;padding:12px 14px;
  background:var(--surface);border:1px solid var(--line);border-radius:11px;box-shadow:0 1px 2px var(--shadow)}
/* класс .node-toolbar{display:flex} перебивал бы UA [hidden] — возвращаем скрытие */
.node-toolbar[hidden]{display:none}
.node-toolbar .sel-name{font-weight:600}
.node-actions{display:flex;gap:8px;flex-wrap:wrap}

/* Кнопки ряда действий не сжимаются и не переносят подпись: при нехватке места
   ряд уходит на вторую строку целыми кнопками, а не плющит их по буквам. */
.node-actions > *{flex:none}
.node-actions .btn{white-space:nowrap}
/* Кнопка-иконка в ряду действий (⋯ и корзина) — без подписи. Высоту не задаём
   числом: padding:0 схлопывал бы её, поэтому тянемся по высоте ряда (её задают
   соседние текстовые кнопки), и иконки всегда вровень с ними. */
.node-actions .act-icon{width:34px;padding:0;display:inline-grid;place-items:center;
  align-self:stretch;min-height:32px}   /* min-height — если ряд перенесётся и кнопка
    останется на строке одна: тогда stretch тянет по своей строке, а не по всему ряду */
.node-actions .act-icon svg{width:16px;height:16px}
/* .add-group — обёртка выпадашки: тоже тянем, иначе ⋯ внутри неё не растянется */
.node-actions .add-group{align-self:stretch;display:inline-flex}

/* ── Карточка персоны: шапка (аватар · имя · даты/место · закрыть) ── */
.pcard-hd{display:flex;gap:12px;align-items:flex-start}
.pcard-ava{width:52px;height:52px;border-radius:50%;flex:none;overflow:hidden;background:var(--sunk,#eae4d6);
  display:grid;place-items:center;font-family:var(--serif,Georgia,serif);font-weight:600;font-size:20px;
  color:var(--ink-soft);border:2px solid var(--surface)}
.pcard-ava img{width:100%;height:100%;object-fit:cover}
.pcard-ava.male{background:#dbe7f4;color:#3a5a7a}
.pcard-ava.female{background:#f5dde7;color:#8a4a63}
.pcard-idn{min-width:0;flex:1}
.pcard-idn .sel-name{font-family:var(--serif,Georgia,serif);font-size:17px;line-height:1.15;display:block}
.pcard-sub{font-size:12.5px;color:var(--ink-soft);margin-top:3px;line-height:1.35}
/* Прогресс заполнения в боковой панели — тот же язык, что полоска в шапке карточки */
.pcard-fill{margin:10px 0 2px}
.pcard-fill .pcf-row{display:flex;justify-content:space-between;font-size:11.5px;
  color:var(--ink-soft);margin-bottom:4px}
.pcard-fill .pcf-pct{font-variant-numeric:tabular-nums;font-weight:600}
.pcard-fill .pcf-bar{height:6px;background:var(--surface-2);border-radius:6px;overflow:hidden}
.pcard-fill .pcf-bar>i{display:block;height:100%;width:0;
  background:linear-gradient(90deg,var(--gold),#d8b45a);transition:width .3s}
.pcard-fill.done .pcf-bar>i{background:linear-gradient(90deg,var(--accent),#4c9e6d)}
.pcard-fill .pcf-hint{font-size:11px;color:var(--ink-faint);margin-top:5px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pcard-fill.done .pcf-hint{color:var(--accent)}
/* на свёрнутом мини-листе телефона подсказку прячем — дерево важнее, % остаётся */
@media (max-width:1024px), (pointer:coarse), (hover:none){
  .node-toolbar:not([data-expanded="1"]) .pcard-fill .pcf-hint{display:none}
}
.pcard-x{margin-left:auto;width:26px;height:26px;flex:none;border-radius:8px;border:1px solid var(--line);
  background:var(--surface);color:var(--ink-soft);font-size:18px;line-height:1;cursor:pointer;display:grid;place-items:center}
.pcard-x:hover{background:var(--sunk,#eae4d6)}

/* ── Секции-простыня (аккордеон) ── */
.pcard-secs{display:flex;flex-direction:column;border-top:1px solid var(--line);margin-top:2px}
.pcard-sec{border-bottom:1px solid var(--line)}
.pcard-sec:last-child{border-bottom:0}
.pcard-shrow{display:flex;align-items:center;gap:4px}
.pcard-sh{display:flex;align-items:center;gap:8px;padding:9px 2px;cursor:pointer;user-select:none;flex:1;min-width:0;
  background:none;border:0;text-align:left;color:inherit;font:inherit}
/* стрелка идёт ПОСЛЕ названия (как на карточке MyHeritage): раскрыто — «^»,
   свёрнуто — «v». Слева она сдвигала заголовок и ломала общий левый край. */
.pcard-sh .chev{width:7px;height:7px;flex:none;color:var(--ink-faint);transition:transform .15s;
  border-left:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(135deg);margin:0 0 3px}
.pcard-sec.closed .pcard-sh .chev{transform:rotate(-45deg);margin-bottom:0}
.pcard-sh .t{font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-soft);font-weight:700}
.pcard-sh .cnt{min-width:17px;padding:0 5px;font-size:10.5px;line-height:16px;text-align:center;
  background:var(--sunk,#eae4d6);color:var(--ink-soft);border-radius:9px;font-weight:700}
.pcard-shrow .sadd{flex:none;margin-left:auto;color:var(--green,#2f7d4f);font-weight:700;font-size:14px;
  line-height:1;width:26px;height:26px;display:grid;place-items:center;cursor:pointer;
  background:none;border:1px solid transparent;border-radius:8px;font-family:inherit}
.pcard-shrow .sadd:hover{background:var(--sunk,#eae4d6);border-color:var(--line)}
.pcard-bd{padding:0 2px 12px}
.pcard-sec.closed .pcard-bd{display:none}
.pcard-kv{display:grid;grid-template-columns:96px 1fr;gap:4px 10px;font-size:13px;margin:0}
.pcard-kv dt{color:var(--ink-soft)} .pcard-kv dd{margin:0;font-weight:500}
/* Места — построчная правка: наведение показывает ✎/✕, клик разворачивает поле */
.pl-row{display:flex;gap:8px;align-items:flex-start;font-size:13px;padding:5px 6px;border-radius:8px}
.pl-row:hover{background:var(--sunk,#eae4d6)}
.pl-pin{flex:none;margin-top:2px;line-height:0}
.pl-pin svg{width:15px;height:15px;color:#b5462f}
.pl-txt{flex:1;min-width:0} .pl-txt b{font-weight:600}
.pl-none{color:var(--ink-faint);font-style:italic}
.pl-ic{flex:none;border:none;background:none;cursor:pointer;color:var(--ink-soft);opacity:0;
  font-size:12px;padding:0 3px;border-radius:6px}
.pl-row:hover .pl-ic{opacity:.7}
.pl-ic:hover{opacity:1;color:var(--accent)}
.pl-row.editing{background:var(--sunk,#eae4d6);align-items:flex-start}
.pl-edit{flex:1;min-width:0}
.pl-edit .pl-lbl{font-size:11.5px;color:var(--ink-soft);margin-bottom:4px;font-weight:600}
.pl-inp{width:100%;padding:6px 9px;border:1px solid var(--line);border-radius:8px;
  background:var(--surface);color:var(--ink);font:inherit;font-size:13px}
.pl-inp:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
.pl-drop{margin-top:4px;border:1px solid var(--line);border-radius:8px;background:var(--surface);
  overflow:hidden;box-shadow:0 3px 10px var(--shadow)}
.pl-drop[hidden]{display:none}
.pl-opt{display:block;width:100%;text-align:left;padding:6px 9px;border:none;background:none;
  font:inherit;font-size:12.5px;color:var(--ink);cursor:pointer;border-bottom:1px solid var(--line2)}
.pl-opt:last-child{border-bottom:0}
.pl-opt:hover{background:var(--accent-soft)}
.pl-opt.pl-new{color:var(--accent);font-weight:600}
.pcard-bio{font-size:13px;color:var(--ink-soft);line-height:1.5;margin:0;white-space:pre-wrap}
.pcard-fam{display:flex;flex-direction:column;gap:1px}
.pcard-fam .grp{font-size:11px;color:var(--ink-soft);margin:7px 0 2px;font-weight:600}
/* НЕ .row: глобальный .row даёт рамку и фон (строки списков) — своё имя, чтобы
   строка родни в карточке не подхватывала чужой стиль */
.pcard-fam .prow{display:flex;align-items:center;gap:8px;padding:4px 6px;cursor:pointer;border-radius:8px}
.pcard-fam .prow:hover{background:var(--sunk,#eae4d6)}
.pcard-fam .fa{width:26px;height:26px;border-radius:50%;background:var(--sunk,#eae4d6);flex:none;overflow:hidden;
  display:grid;place-items:center;font-size:11px;font-weight:600;color:var(--ink-soft)}
.pcard-fam .fa img{width:100%;height:100%;object-fit:cover}
.pcard-fam .fn{font-size:13px;font-weight:600} .pcard-fam .fr{font-size:11px;color:var(--ink-soft)}
.pcard-empty{font-size:12.5px;color:var(--ink-soft);padding:2px 0}
/* Формы правки прямо в секции карточки */
.pcard-form{display:flex;flex-direction:column;gap:7px}
.pcard-form .pf{display:grid;grid-template-columns:96px 1fr;align-items:center;gap:8px}
.pcard-form .pf-l{font-size:12.5px;color:var(--ink-soft)}
.pcard-form input,.pcard-form select,.pcard-form textarea{width:100%;padding:6px 9px;
  border:1px solid var(--line);border-radius:8px;background:var(--surface);color:var(--ink);
  font:inherit;font-size:13px}
.pcard-form textarea{resize:vertical;line-height:1.45}
.pcard-form input:focus,.pcard-form select:focus,.pcard-form textarea:focus{
  outline:2px solid var(--accent-soft);border-color:var(--accent)}
.pcard-form .pf-acts{display:flex;align-items:center;gap:7px;margin-top:4px;flex-wrap:wrap}
.pcard-form .pf-err{color:#B23A3A;font-size:12px;flex-basis:100%}
/* События — таймлайн */
.pcard-tl .ev{display:flex;align-items:flex-start;gap:9px;padding:6px;border-radius:8px;
  border-bottom:1px dashed var(--line)}
.pcard-tl .ev:hover{background:var(--sunk,#eae4d6)}
.pcard-tl .evy{flex:none;width:38px}
.pcard-tl .evg{flex:1;min-width:0}
.pcard-tl .ev .pl-ic{opacity:0}
.pcard-tl .ev:hover .pl-ic{opacity:.7}
.pcard-tl .ev:last-child{border-bottom:0}
.pcard-tl .evy{font-weight:700;font-size:12.5px;color:var(--accent-ink,#215c39)}
.pcard-tl .evt{font-size:12.5px;font-weight:600}
.pcard-tl .evs{font-size:11.5px;color:var(--ink-soft)}
/* Галерея — плитка миниатюр */
.pcard-gal{display:grid;grid-template-columns:repeat(auto-fill,minmax(64px,1fr));gap:6px}
.pcard-gal .ph{display:block;aspect-ratio:1;border-radius:8px;overflow:hidden;background:var(--sunk,#eae4d6)}
.pcard-gal .ph img{width:100%;height:100%;object-fit:cover;display:block}
/* История — журнал правок */
.pcard-hist .hr{display:grid;grid-template-columns:72px 1fr;gap:8px;padding:5px 0;
  border-bottom:1px dashed var(--line)}
.pcard-hist .hr:last-child{border-bottom:0}
.pcard-hist .hw{font-size:11.5px;color:var(--ink-soft);font-variant-numeric:tabular-nums}
.pcard-hist .ht{font-size:12.5px}
.pcard-hist .hu{font-size:11px;color:var(--ink-soft)}

/* ── Десктоп: нижний островок → левая боковая панель ── */
@media (min-width:1025px) and (hover:hover) and (pointer:fine){
  .graph-page .node-toolbar{left:0;top:64px;bottom:14px;transform:none;
    width:384px;min-width:0;max-width:88vw;border-radius:0 14px 14px 0;
    /* место под полосу прокрутки держим всегда: иначе её появление сужает панель
       и кнопки в ряду действий плющит */
    overflow:auto;scrollbar-gutter:stable;box-shadow:6px 0 24px var(--shadow)}
  /* пять кнопок в 384px влезают впритык — поджимаем зазор и боковые поля,
     иначе корзина срывается на вторую строку одна */
  .graph-page .node-toolbar .node-actions{gap:4px;align-items:center}
  .graph-page .node-toolbar .node-actions .btn-sm{padding-left:8px;padding-right:8px}
  .graph-page .node-toolbar .node-actions .act-icon{padding:0}
  .graph-page .node-toolbar .node-actions #del-btn{margin-left:auto}
  /* в боковой панели выпадашки раскрываются ВНИЗ (внизу листа было вверх),
     а у правых кнопок — влево, иначе их срезает край панели (overflow:auto) */
  .graph-page .node-toolbar .add-menu{top:calc(100% + 5px);bottom:auto}
  .graph-page .node-toolbar #more-menu{left:auto;right:0}
}
.relative-form{border-top:1px solid var(--line);padding-top:10px}
/* Вспышка: панель «связи»/«кем приходится» открывается внизу карточки — после
   мягкой прокрутки коротко подсвечиваем её, иначе появление легко пропустить. */
@keyframes panel-flash{
  0%{background:var(--accent-soft);box-shadow:0 0 0 3px var(--accent-soft)}
  55%{background:var(--accent-soft);box-shadow:0 0 0 3px var(--accent-soft)}
  100%{background:transparent;box-shadow:0 0 0 3px transparent}
}
.relative-form.flash{border-radius:10px;animation:panel-flash 1.4s ease-out}
@media (prefers-reduced-motion:reduce){
  .relative-form.flash{animation:none;background:var(--accent-soft);border-radius:10px}
}
.rf-title{font-size:13px;color:var(--ink-soft);margin-bottom:8px}
/* Калькулятор родства — плашка результата */
.kin-panel .kin-title{font-size:13px;color:var(--ink-soft);margin-bottom:6px}
.kin-panel .kin-line{font-size:14px;margin-bottom:4px}
.kin-panel .kin-term{font-family:var(--serif);font-size:23px;line-height:1.15;
  color:var(--accent-ink);margin:3px 0 8px;text-transform:lowercase}
.kin-panel .kin-rev{font-size:12.5px;color:var(--ink-soft);margin-bottom:9px}
.rf-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.rf-row input[type=text],.rf-row input:not([type]),.rf-row input[name=first_name],
.rf-row input[name=last_name],.rf-row input[type=date],.rf-row select{
  padding:7px 10px;border:1px solid var(--line);border-radius:8px;background:var(--surface);
  color:var(--ink);font:inherit;font-size:14px}
.rf-alive{display:flex;align-items:center;gap:6px;font-size:14px;color:var(--ink-soft)}
.rf-err{color:#B23A3A;font-size:13px;margin-top:8px}

/* Мостики в другие деревья (карточка человека) */
.bridges{border-top:1px solid var(--line);margin-top:18px;padding-top:16px}
.bridges-h{font-family:var(--serif);font-size:17px;margin:0 0 4px}
.bridge-list{list-style:none;margin:0 0 12px;padding:0;display:flex;flex-direction:column;gap:7px}
.bridge-row{display:flex;align-items:center;gap:10px;background:var(--surface-2);
  border:1px solid var(--line);border-radius:10px;padding:8px 12px}
.bridge-kind{font-size:11.5px;font-weight:600;color:var(--accent-ink);background:var(--accent-soft);
  border-radius:20px;padding:2px 9px;white-space:nowrap}
.bridge-link{color:var(--ink);text-decoration:none;font-weight:600;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.bridge-broken{color:var(--muted-ink,#8a8f98);font-weight:500;font-style:italic}
.bridge-link:hover{color:var(--accent-ink);text-decoration:underline}
.bridge-add{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.bridge-add select{border:1px solid var(--line);border-radius:9px;padding:8px 10px;font:inherit;
  font-size:14px;color:var(--ink);background:var(--surface)}
.bridge-add select:disabled{opacity:.55}
.bridge-cross{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:12px;
  padding-top:12px;border-top:1px dashed var(--line)}
.bridge-cross select{border:1px solid var(--line);border-radius:9px;padding:8px 10px;font:inherit;
  font-size:14px;color:var(--ink);background:var(--surface)}
.bridge-propose-card{background:var(--surface-2);border:1px solid var(--line);border-radius:10px;
  padding:12px 14px}
.bp-person{font-weight:600;font-size:15px;color:var(--ink)}

/* Автосведение: список совпадений и предложений */
.match-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.match-row{display:flex;align-items:center;gap:14px;flex-wrap:wrap;background:var(--surface-2);
  border:1px solid var(--line);border-radius:11px;padding:11px 14px}
.match-body{flex:1;min-width:200px}
.match-main{font-size:14.5px;color:var(--ink)}
.match-arrow{color:var(--accent);font-weight:700;margin:0 4px}
.match-sub{font-size:12.5px;color:var(--ink-soft);margin-top:3px}
.match-score{background:var(--accent-soft);color:var(--accent-ink);border-radius:20px;
  padding:1px 8px;font-size:11px;font-weight:700;margin-left:6px}
.match-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.match-actions form{margin:0}
.match-rel{font-size:12.5px;color:var(--ink-soft);margin-top:4px}
.match-rel-note{color:var(--ink-faint);font-size:11px}
/* Совпадение прямо на карточке человека */
.match-hint{border:1px solid var(--accent);background:var(--accent-soft);border-radius:11px;
  padding:12px 14px;margin:0 0 14px}
/* Этап 3-B: сверка полей с общей записью соседа */
.pull-sync{border:1px dashed var(--border);border-radius:11px;padding:10px 12px;margin:10px 0}
.pull-sync-title{font-weight:600;margin-bottom:6px}
.pull-sync-src{font-size:12.5px;margin:6px 0 2px}
.pull-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:4px 0}
.pull-label{min-width:120px;font-size:13px;color:var(--ink-soft)}
.pull-vals{display:flex;align-items:center;gap:8px;font-size:13px}
.pull-mine{opacity:.65;text-decoration:line-through}
.pull-arrow{opacity:.5}
.pull-theirs{font-weight:600}
.pull-take{margin-left:auto}
.match-hint-title{font-weight:600;color:var(--accent-ink);margin-bottom:8px}
.match-hint-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.match-hint-body{flex:1;min-width:200px;font-size:14px;color:var(--ink)}

/* Peek-панель ветки соседа на графе (кросс-мостик) */
.bridge-peek{position:absolute;top:64px;right:14px;z-index:8;width:min(320px,92vw);
  background:var(--surface);border:1px solid var(--line);border-radius:14px;
  box-shadow:0 10px 30px var(--shadow);overflow:hidden}
.bridge-peek[hidden]{display:none}
.bridge-peek .bp-head{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:11px 14px;border-bottom:1px solid var(--line);background:var(--surface-2)}
.bridge-peek .bp-title{font-weight:600;font-size:14px;color:var(--ink)}
.bridge-peek .bp-x{border:none;background:none;font-size:20px;line-height:1;color:var(--ink-faint);
  cursor:pointer;padding:0 4px}
.bridge-peek .bp-x:hover{color:var(--ink)}
.bridge-peek .bp-sub{padding:9px 14px 4px;font-size:12.5px;color:var(--ink-soft)}
.bridge-peek .bp-body{padding:2px 14px 8px;max-height:min(52vh,420px);overflow-y:auto}
.bp-group{margin:8px 0}
.bp-gtitle{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-faint);
  font-weight:700;margin-bottom:3px}
.bp-group ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:3px}
.bp-group li{font-size:13.5px;color:var(--ink)}
.bridge-peek .bp-import-row{padding:10px 14px;border-top:1px solid var(--line);
  display:flex;flex-direction:column;gap:6px;align-items:flex-start}
.bp-import-note{font-size:12px;color:var(--ink-soft)}
/* уже добавленные — приглушены: список показывает всю ветку соседа, но глаз
   должен цепляться за тех, кого ещё можно взять */
.bp-group li.bp-has{color:var(--ink-faint)}
.bp-hastag{margin-left:6px;font-size:11px;color:var(--ink-faint);
  border:1px solid var(--line);border-radius:20px;padding:0 6px;white-space:nowrap}
/* «Убрать мостик» — действие редкое и необратимое, поэтому не кнопка,
   а ссылка: не спорит за внимание с «Добавить ветку к себе» */
.bp-unlink{align-self:flex-start;border:none;background:none;padding:0;
  font:inherit;font-size:12.5px;color:var(--ink-soft);cursor:pointer;
  text-decoration:underline;text-underline-offset:2px}
.bp-unlink:hover{color:var(--danger)}
.bp-unlink[hidden]{display:none}
.bridge-peek .bp-foot{padding:9px 14px;border-top:1px solid var(--line);font-size:11.5px;
  color:var(--ink-faint);background:var(--surface-2)}
@media (max-width:1024px), (pointer:coarse), (hover:none){
  .bridge-peek{top:auto;bottom:0;right:0;left:0;width:auto;border-radius:16px 16px 0 0}
}
/* личный ярлык дерева (алиас участника) */
.name-edit{margin-left:8px;font-size:12.5px}
/* тело правки раскрывается ниже во всю ширину, а сам «✎ Изменить» стоит в строке названия */
.name-edit[open]{width:100%;flex-basis:100%}
.name-edit summary{cursor:pointer;color:var(--muted-ink,#8a8f98);list-style:none;user-select:none}
.name-edit summary::-webkit-details-marker{display:none}
.name-edit-body{display:flex;flex-direction:column;gap:12px;margin-top:10px;max-width:520px}
.name-edit .field label{display:block;font-size:12.5px;color:var(--soft,#6f6656);margin-bottom:5px}
.name-edit .ne-row{display:flex;gap:8px;align-items:center}
.name-edit .ne-row input{flex:1;min-width:0;padding:9px 11px;border:1px solid var(--line);
  border-radius:9px;font:inherit;font-size:14px;background:var(--bg,#fff);color:var(--ink)}
.name-edit .ne-row input:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}

/* ── Статистика дерева ── */
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:12px;margin:0 0 18px}
.stat-card{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:16px;text-align:center}
.stat-num{font-size:30px;font-weight:700;color:var(--accent-ink);line-height:1}
.stat-lbl{font-size:12.5px;color:var(--ink-soft);margin-top:6px}
.stat-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:16px;margin-bottom:16px}
.stat-block-h{font-weight:600;font-size:13.5px;color:var(--ink-soft);margin-bottom:10px}
.stat-big{font-size:34px;font-weight:700;color:var(--accent-ink);line-height:1}
.stat-bar{display:flex;height:16px;border-radius:8px;overflow:hidden;background:var(--accent-soft)}
.stat-bar-m{background:var(--node-male,#5b8def)}
.stat-bar-f{background:var(--node-female,#e879b0)}
.stat-legend{display:flex;gap:16px;flex-wrap:wrap;margin-top:10px;font-size:12.5px}
.stat-legend .dot{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:5px}
.dot-m{background:var(--node-male,#5b8def)}
.dot-f{background:var(--node-female,#e879b0)}
.stat-oldest{font-weight:600;color:var(--ink);text-decoration:none}
.stat-oldest:hover{color:var(--accent)}
.stat-top{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.stat-top li{display:flex;align-items:center;gap:10px;font-size:13.5px}
.stat-top-nm{min-width:96px;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.stat-top-bar{flex:1;height:8px;background:var(--accent-soft);border-radius:5px;overflow:hidden}
.stat-top-bar i{display:block;height:100%;background:var(--accent);border-radius:5px}
.stat-top-cnt{min-width:24px;text-align:right;color:var(--ink-soft);font-variant-numeric:tabular-nums}

/* ── Печатная карточка человека ── */
.pcard-toolbar{display:flex;gap:10px;margin-bottom:16px}
.pcard{max-width:720px;margin:0 auto;background:var(--surface);border:1px solid var(--line);
  border-radius:14px;padding:28px 30px}
.pcard-head{display:flex;gap:20px;align-items:center;border-bottom:1px solid var(--line);padding-bottom:20px}
.pcard-av{flex:none;width:96px;height:96px;border-radius:16px;overflow:hidden;display:flex;
  align-items:center;justify-content:center;font-size:38px;font-weight:700;color:#fff;background:var(--accent)}
.pcard-av.male{background:var(--node-male,#5b8def)}
.pcard-av.female{background:var(--node-female,#e879b0)}
.pcard-av img{width:100%;height:100%;object-fit:cover}
.pcard-name{font-size:26px;margin:0 0 4px}
.pcard-maiden{font-size:13px;color:var(--ink-soft)}
.pcard-life{font-size:14px;color:var(--ink-soft);margin-top:6px}
.pcard-sect{margin-top:20px}
.pcard-sect-h{font-size:12.5px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;
  color:var(--accent-ink);margin-bottom:10px}
.pcard-line{font-size:14px;margin:3px 0}
.pcard-bio{font-size:14px;line-height:1.55;white-space:pre-wrap}
.pcard-fam{display:flex;gap:12px;align-items:baseline;margin:8px 0}
.pcard-fam-lbl{flex:none;width:120px;font-size:12.5px;color:var(--ink-soft);padding-top:6px}
.pcard-fam-list{display:flex;flex-wrap:wrap;gap:8px}
.pcard-rel{display:inline-flex;align-items:center;gap:7px;text-decoration:none;color:var(--ink);
  border:1px solid var(--line);border-radius:20px;padding:4px 12px 4px 4px;font-size:13px}
.pcard-rel:hover{border-color:var(--accent)}
.pcard-rel-av{flex:none;width:26px;height:26px;border-radius:50%;overflow:hidden;display:flex;
  align-items:center;justify-content:center;font-size:12px;font-weight:700;color:#fff;background:var(--accent)}
.pcard-rel-av.male{background:var(--node-male,#5b8def)}
.pcard-rel-av.female{background:var(--node-female,#e879b0)}
.pcard-rel-av img{width:100%;height:100%;object-fit:cover}
.pcard-foot{margin-top:24px;padding-top:14px;border-top:1px solid var(--line);
  font-size:11.5px;color:var(--ink-soft);text-align:center}
@media print{
  header,.bell-menu,.user-menu,nav,.nav-link,#rt-toasts,.pcard-toolbar,.no-print{display:none !important}
  body,main,.content,.content-full{background:#fff !important;margin:0;padding:0}
  .pcard{border:none;box-shadow:none;max-width:100%;padding:0}
  .pcard-rel{border-color:#ccc}
  a{color:inherit !important;text-decoration:none}
}
.crumbs-action{display:inline-flex;align-items:center;gap:5px;margin-left:10px;color:var(--accent-ink);
  text-decoration:none;font-size:13px;vertical-align:middle}
.crumbs-action:hover{color:var(--accent)}
.pcard-route{margin-left:8px;font-size:12.5px;color:var(--accent-ink);text-decoration:none}
.pcard-route:hover{color:var(--accent)}

/* ── Лендинг (index.html) ──────────────────────────────────────────────── */
.lp-hero{max-width:720px;margin-top:26px}
.lp-cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:22px}
.lp-cta .btn{padding:11px 22px;font-size:15px}
.lp-note{margin-top:14px;font-size:13px;color:var(--ink-faint)}
.lp-section{margin:52px 0}
.lp-head{margin-bottom:20px}
.lp-head h2{font-family:var(--serif);font-size:26px;margin:0 0 6px}
.lp-head .muted{max-width:64ch}

.demo-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(250px,1fr))}
.demo-card{display:flex;flex-direction:column;gap:9px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--radius);padding:16px 17px;
  text-decoration:none;color:inherit;transition:border-color .15s,box-shadow .15s,transform .15s}
.demo-card:hover{border-color:var(--accent);box-shadow:0 6px 18px var(--shadow);transform:translateY(-1px)}
.demo-top{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.demo-name{font-family:var(--serif);font-size:18px;font-weight:600;line-height:1.15}
.demo-years{font-size:12.5px;color:var(--ink-faint);white-space:nowrap;font-variant-numeric:tabular-nums}
.demo-role{font-size:13.5px;color:var(--ink-soft)}
.demo-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;
  margin-top:2px;padding-top:10px;border-top:1px solid var(--line);font-size:12.5px}
.demo-tie{display:inline-flex;align-items:center;gap:5px;color:var(--accent-ink)}
.demo-tie svg{width:14px;height:14px;flex:none}
.demo-count{color:var(--ink-faint);white-space:nowrap}

.feat-grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
.feat{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:18px}
.feat svg{width:24px;height:24px;color:var(--accent);margin-bottom:10px}
.feat h3{font-size:15.5px;margin:0 0 6px}
.feat p{font-size:13.5px;color:var(--ink-soft);margin:0;line-height:1.5}

.lp-final{text-align:center;background:var(--accent-soft);border:1px solid var(--line);
  border-radius:var(--radius);padding:38px 24px;margin:52px 0 20px}
.lp-final h2{font-family:var(--serif);font-size:24px;margin:0 0 8px}
.lp-final .muted{max-width:52ch;margin:0 auto}
.lp-final .lp-cta{justify-content:center}
@media (max-width:560px){.lp-hero h1{font-size:30px}.lp-section{margin:40px 0}}

/* ── Публичная карточка человека (клик по узлу на публичном дереве) ──────── */
.pubcard-ov{position:fixed;inset:0;z-index:1000;background:rgba(20,26,22,.42);
  display:flex;align-items:center;justify-content:center;padding:18px}
.pubcard{position:relative;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius);box-shadow:0 18px 50px var(--shadow);
  width:min(420px,94vw);max-height:86vh;overflow:auto;padding:22px 22px 20px}
.pubcard .pc-x{position:absolute;top:8px;right:10px;border:none;background:none;
  font-size:26px;line-height:1;color:var(--ink-faint);cursor:pointer;padding:2px 6px}
.pubcard .pc-x:hover{color:var(--ink)}
.pubcard .pc-name{font-family:var(--serif);font-size:21px;margin:0 26px 14px 0;line-height:1.2}
.pubcard .pc-row{display:flex;gap:10px;padding:7px 0;border-top:1px solid var(--line);font-size:14px}
.pubcard .pc-row:first-of-type{border-top:none}
.pubcard .pc-k{flex:0 0 130px;color:var(--ink-faint)}
.pubcard .pc-bio{margin-top:12px;padding-top:12px;border-top:1px solid var(--line);
  font-size:13.5px;color:var(--ink-soft);line-height:1.55}
.pubcard .pc-note{color:var(--ink-soft);font-size:14px;margin:4px 0 0}

/* Описание публичного дерева (под заголовком) */
.tree-desc-public{max-width:70ch;margin:2px 0 14px;color:var(--ink-soft);font-size:14.5px;line-height:1.55}

/* Плашка «войти как» (импersonation) */
.impersonate-bar{background:var(--gold-soft);border-bottom:1px solid var(--line);
  padding:9px 18px;font-size:13.5px;color:var(--ink);text-align:center}
.impersonate-bar form{display:inline}
.impersonate-bar button{margin-left:8px;background:var(--gold);color:#fff;border:none;
  border-radius:8px;padding:4px 12px;font-size:13px;cursor:pointer}
.impersonate-bar button:hover{filter:brightness(1.05)}

/* ── Мемориал-страница персоны (public_person.html) ─────────────────────── */
.mem-page{display:flex;gap:32px;flex-wrap:wrap;align-items:flex-start;margin-top:18px}
.mem-main{flex:1 1 380px;min-width:0}
.mem-back{font-size:13.5px;color:var(--accent-ink);text-decoration:none}
.mem-back:hover{color:var(--accent)}
.mem-name{font-family:var(--serif);font-size:30px;margin:10px 0 2px;line-height:1.15}
.mem-years{font-size:17px;color:var(--ink-soft);margin:0 0 16px;font-variant-numeric:tabular-nums}
.mem-facts{margin:0 0 4px}
.mem-row{display:flex;gap:12px;padding:8px 0;border-top:1px solid var(--line);font-size:14.5px}
.mem-row:first-child{border-top:none}
.mem-k{flex:0 0 140px;color:var(--ink-faint)}
.mem-route{margin-left:8px;color:var(--accent-ink);text-decoration:none;font-size:13px}
.mem-bio{margin:16px 0;font-size:15px;line-height:1.6;color:var(--ink)}
.mem-family{margin-top:16px;padding-top:14px;border-top:1px solid var(--line)}
.mem-fam-group{display:flex;gap:12px;padding:6px 0;font-size:14px}
.mem-fam-group a{color:var(--accent-ink);text-decoration:none}
.mem-fam-group a:hover{color:var(--accent)}
.mem-qr{flex:0 0 200px;text-align:center;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius);padding:18px}
.mem-qr-box{width:170px;height:170px;margin:0 auto}
.mem-qr-box svg{width:100%;height:100%;display:block}
.mem-qr-cap{font-size:12.5px;color:var(--ink-faint);margin:10px 0 12px}
@media (max-width:560px){.mem-name{font-size:25px}.mem-qr{flex-basis:100%}}
.pubcard .pc-mem{display:inline-block;margin-top:14px;padding-top:12px;border-top:1px solid var(--line);
  width:100%;color:var(--accent-ink);text-decoration:none;font-size:14px}
.pubcard .pc-mem:hover{color:var(--accent)}

/* Секция «Публичная страница памяти» на карточке */
.mem-settings{margin:18px 0}
.mem-settings h3{font-size:16px;margin:0 0 8px}
.mem-slug-row{display:flex;align-items:stretch;border:1px solid var(--line);border-radius:9px;overflow:hidden}
.mem-slug-pre{background:var(--surface-2);color:var(--ink-faint);padding:8px 8px;font-size:13.5px;white-space:nowrap;border-right:1px solid var(--line)}
.mem-slug-row input{border:none;flex:1;min-width:0;padding:8px 10px;background:var(--surface)}
.mem-live{margin-top:10px;font-size:13.5px}
.mem-live a{color:var(--accent-ink);text-decoration:none}

/* Фото на публичной карточке-модалке */
.pubcard .pc-photo{display:block;width:104px;height:104px;object-fit:cover;border-radius:12px;
  border:1px solid var(--line);margin:0 auto 12px;background:var(--surface-2)}
/* Фото на мемориал/публичной странице персоны */
.mem-head{display:flex;align-items:center;gap:16px;margin-bottom:4px}
.mem-photo{width:120px;height:120px;object-fit:cover;border-radius:14px;flex:none;
  border:1px solid var(--line);box-shadow:0 4px 14px var(--shadow);background:var(--surface-2)}
@media (max-width:560px){.mem-photo{width:92px;height:92px}}

/* ── Публичная витрина дерева: полноэкранное полотно + плавающая интро-карточка (десктоп)
   / полоса-имя + ⓘ → нижняя панель (мобилка). Тема наследуется от переменных выше. ── */
.graph-public .gp-card{position:absolute;top:14px;left:14px;z-index:6;width:302px;
  max-width:calc(100vw - 28px);background:var(--surface);border:1px solid var(--line);
  border-radius:14px;padding:14px 16px 12px;box-shadow:0 3px 16px var(--shadow)}
.graph-public .gp-head{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.graph-public .gp-name{font-family:var(--serif);font-size:20px;font-weight:600;margin:0;
  color:var(--ink);line-height:1.14}
.graph-public .gp-meta{color:var(--ink-faint);font-size:12.5px;font-variant-numeric:tabular-nums}
.graph-public .gp-desc{color:var(--ink-soft);font-size:13px;line-height:1.5;margin:9px 0 0}
.graph-public .gp-hint{color:var(--ink-faint);font-size:11.5px;line-height:1.45;margin:9px 0 0}
.graph-public .gp-card.collapsed .gp-desc,.graph-public .gp-card.collapsed .gp-hint{display:none}
.graph-public .gp-collapse,.graph-public .gp-close{margin-top:11px;font:inherit;font-size:12px;
  font-weight:600;color:var(--accent);background:none;border:1px solid var(--line);border-radius:8px;
  padding:4px 12px;cursor:pointer}
.graph-public .gp-collapse:hover,.graph-public .gp-close:hover{background:var(--surface-2)}
.graph-public .gp-collapse:focus-visible,.graph-public .gp-info:focus-visible,
.graph-public .gp-close:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.graph-public .gp-brand{position:absolute;right:14px;bottom:12px;z-index:6;font-size:12px;
  color:var(--ink-faint);text-decoration:none;padding:4px 9px;border-radius:8px;
  background:color-mix(in srgb,var(--surface) 78%,transparent)}
.graph-public .gp-brand:hover{color:var(--accent)}
/* мобильные элементы прячем на десктопе */
.graph-public .gp-bar,.graph-public .gp-scrim,.graph-public .gp-sheet{display:none}

@media (max-width:1024px), (pointer:coarse), (hover:none){
  .graph-public .gp-card{display:none}
  .graph-public .gp-bar{display:flex;position:absolute;top:0;left:0;right:0;z-index:6;
    align-items:center;justify-content:space-between;gap:10px;padding:10px 12px}
  .graph-public .gp-bar-txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
    font-size:15px;color:var(--ink);min-width:0;background:var(--surface);border:1px solid var(--line);
    border-radius:12px;padding:7px 13px;box-shadow:0 2px 10px var(--shadow)}
  .graph-public .gp-bar-txt b{font-family:var(--serif);font-weight:600}
  .graph-public .gp-bar .gp-meta{font-size:11.5px}
  .graph-public .gp-info{flex:none;width:30px;height:30px;border-radius:50%;font-size:16px;
    cursor:pointer;display:grid;place-items:center;color:var(--accent);background:var(--surface);
    border:1px solid var(--line);box-shadow:0 2px 10px var(--shadow)}
  .graph-public .gp-scrim{display:block;position:absolute;inset:0;z-index:7;background:rgba(18,21,15,.32);
    opacity:0;visibility:hidden;transition:opacity .26s ease,visibility .26s}
  .graph-public.sheet-open .gp-scrim{opacity:1;visibility:visible}
  .graph-public .gp-sheet{display:block;position:absolute;left:8px;right:8px;bottom:8px;z-index:8;
    background:var(--surface);border:1px solid var(--line);border-radius:16px;
    padding:12px 16px calc(14px + env(safe-area-inset-bottom));box-shadow:0 -6px 26px var(--shadow);
    transform:translateY(calc(100% + 18px));transition:transform .28s cubic-bezier(.22,1,.36,1)}
  .graph-public.sheet-open .gp-sheet{transform:translateY(0)}
  .graph-public .gp-grab{width:36px;height:4px;border-radius:3px;background:var(--line);margin:0 auto 10px}
  .graph-public .gp-sheet .gp-name{font-size:18px}
  .graph-public .gp-sheet .gp-desc{font-size:13.5px}
  .graph-public .gp-brand{right:10px;bottom:10px;font-size:11px}
}
@media (prefers-reduced-motion:reduce){
  .graph-public .gp-sheet,.graph-public .gp-scrim{transition:none}
}

/* ── «Пригласить»: свёрнуто в кнопку, форма — оверлеем.
   Десктоп — модалка по центру, мобилка/планшет — нижняя шторка.
   Раньше блок был раскрыт всегда и занимал пол-экрана карточки. ── */
.invite-trigger{margin-bottom:16px}
.invite-trigger .btn{display:inline-flex;align-items:center;gap:8px}
.invite-overlay{position:fixed;inset:0;z-index:60;visibility:hidden;pointer-events:none}
.invite-overlay.open{visibility:visible;pointer-events:auto}
.invite-scrim{position:absolute;inset:0;background:rgba(18,21,15,.42);opacity:0;transition:opacity .25s ease}
.invite-overlay.open .invite-scrim{opacity:1}
body.inv-locked{overflow:hidden}
.invite-grab{display:none}
.invite-close{margin-left:auto;flex:none;width:30px;height:30px;border-radius:9px;cursor:pointer;
  border:1px solid var(--line);background:var(--surface);color:var(--ink-soft);font-size:19px;line-height:1}
.invite-close:hover{background:var(--surface-2);color:var(--ink)}
.invite-close:focus-visible,.invite-trigger .btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* десктоп — модалка по центру */
.invite-card{position:absolute;top:50%;left:50%;transform:translate(-50%,-46%);
  width:460px;max-width:calc(100vw - 32px);max-height:86vh;overflow-y:auto;
  background:var(--surface);margin:0;opacity:0;box-shadow:0 20px 50px var(--shadow);
  transition:opacity .22s ease,transform .22s ease}
.invite-overlay.open .invite-card{opacity:1;transform:translate(-50%,-50%)}
/* мобилка/планшет — нижняя шторка */
@media (max-width:1024px), (pointer:coarse), (hover:none){
  .invite-card{top:auto;bottom:0;left:0;right:0;width:auto;max-width:none;transform:translateY(100%);
    border-radius:18px 18px 0 0;max-height:88vh;padding-bottom:calc(16px + env(safe-area-inset-bottom))}
  .invite-overlay.open .invite-card{transform:translateY(0)}
  .invite-grab{display:block;width:36px;height:4px;border-radius:3px;background:var(--line);margin:0 auto 10px}
}
@media (prefers-reduced-motion:reduce){.invite-card,.invite-scrim{transition:none}}

/* иначе display:flex перебивает атрибут hidden — пустое поле «Копировать» торчало до создания ссылки */
.invite-link[hidden]{display:none}

/* Родня в публичной карточке персоны — кликабельные чипы (открывают карточку родственника) */
.pc-rel-row{align-items:flex-start}
.pc-rels{display:flex;flex-direction:column;gap:4px;align-items:flex-end;text-align:right}
.pc-rel{font:inherit;font-size:13.5px;color:var(--ink);background:none;border:none;padding:0;
  cursor:pointer;text-align:right;line-height:1.35;border-bottom:1px dashed transparent}
.pc-rel:hover{color:var(--accent);border-bottom-color:var(--accent)}
.pc-rel:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.pc-rel-yr{color:var(--ink-faint);font-size:12px;margin-left:6px;font-variant-numeric:tabular-nums}

/* Подсказка под иконкой «i»: длинное пояснение не занимает место, пока не спросят */
.check-row{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.check-row .field.check{margin:0}
.hint-i{flex:none;width:21px;height:21px;border-radius:50%;cursor:pointer;
  border:1px solid var(--line);background:var(--surface);color:var(--ink-faint);
  font-family:var(--serif);font-size:13px;font-weight:600;line-height:1;
  display:grid;place-items:center;padding:0}
.hint-i:hover,.hint-i[aria-expanded="true"]{color:var(--accent);border-color:var(--accent)}
.hint-i:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.field-hint{margin:9px 0 0;padding:11px 13px;max-width:64ch;font-size:13px;line-height:1.5;
  color:var(--ink-soft);background:var(--surface-2);border:1px solid var(--line);border-radius:10px}
.field-hint[hidden]{display:none}
.field-hint p{margin:0 0 8px}
.field-hint p:last-child{margin-bottom:0}
.field-hint .hint-note{color:var(--ink-faint);border-top:1px solid var(--line);padding-top:8px}

/* Подсказки геопоиска: раньше брался один результат и молча подставлялся в форму */
.geo-results{list-style:none;margin:8px 0 0;padding:6px;max-height:320px;overflow-y:auto;
  background:var(--surface);border:1px solid var(--line);border-radius:11px;
  box-shadow:0 6px 20px var(--shadow)}
.geo-results[hidden]{display:none}
.geo-item{padding:8px 10px;border-radius:8px;cursor:pointer;font-size:14px;line-height:1.35}
.geo-item:hover{background:var(--surface-2)}
.geo-item b{color:var(--ink)}
.geo-kind{font-size:11px;color:var(--accent);background:var(--accent-soft);
  border-radius:5px;padding:1px 6px;margin-left:6px;vertical-align:middle}
.geo-addr{display:block;font-size:12px;color:var(--ink-faint);margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.geo-empty{padding:10px;font-size:13px;color:var(--ink-faint)}

/* ── Выбор места прямо из карточки персоны ──────────────────────────────────
   Раньше был select готовых мест + отдельная страница с картой «несколькими
   экранами ниже». Теперь поле-подсказчик (свои места первыми) + «На карте». */
.place-combo{position:relative}
.plc-row{display:flex;gap:7px;align-items:stretch}
.plc-input{flex:1;min-width:0;font:inherit;font-size:15px;padding:9px 12px;
  border:1px solid var(--line);border-radius:9px;background:var(--surface);color:var(--ink)}
.plc-input:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
.plc-map{flex:none;width:40px;display:grid;place-items:center;cursor:pointer;
  border:1px solid var(--line);border-radius:9px;background:var(--surface);color:var(--accent)}
.plc-map:hover{background:var(--accent-soft)}
.plc-map:focus-visible,.plc-input:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.plc-dd{position:absolute;z-index:30;left:0;right:0;top:calc(100% + 5px);margin:0;padding:5px;
  list-style:none;max-height:320px;overflow-y:auto;background:var(--surface);
  border:1px solid var(--line);border-radius:11px;box-shadow:0 10px 28px var(--shadow)}
.plc-dd[hidden]{display:none}
.plc-group{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;font-weight:700;
  color:var(--ink-faint);padding:8px 9px 4px}
.plc-opt{display:flex;align-items:baseline;gap:7px;padding:8px 9px;border-radius:8px;
  cursor:pointer;font-size:14px}
.plc-opt:hover{background:var(--surface-2)}
.plc-nm{color:var(--ink)}
.plc-addr{color:var(--ink-faint);font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.plc-badge{font-size:10px;font-weight:700;border-radius:5px;padding:1px 6px;flex:none}
.plc-badge.own{color:var(--accent);background:var(--accent-soft)}
.plc-badge.kind{color:var(--gold);background:var(--gold-soft)}
.plc-empty{padding:10px 9px;font-size:13px;color:var(--ink-faint)}
.plc-keep{margin-top:4px;padding:9px 10px;border-top:1px solid var(--line);
  background:var(--gold-soft);border-radius:8px;cursor:pointer;font-size:13.5px;color:var(--ink)}
.plc-keep small{display:block;color:var(--ink-soft);font-size:12px;margin-top:2px}
/* карта-шторка */
.plc-sheet-ov{position:fixed;inset:0;z-index:70;visibility:hidden;pointer-events:none}
.plc-sheet-ov.open{visibility:visible;pointer-events:auto}
.plc-scrim{position:absolute;inset:0;background:rgba(18,21,15,.42);opacity:0;transition:opacity .25s}
.plc-sheet-ov.open .plc-scrim{opacity:1}
body.plc-locked{overflow:hidden}
.plc-sheet{position:absolute;top:50%;left:50%;transform:translate(-50%,-46%);width:min(720px,calc(100vw - 32px));
  background:var(--surface);border:1px solid var(--line);border-radius:16px;overflow:hidden;
  box-shadow:0 20px 50px var(--shadow);opacity:0;transition:opacity .22s,transform .22s}
.plc-sheet-ov.open .plc-sheet{opacity:1;transform:translate(-50%,-50%)}
.plc-sheet-head,.plc-sheet-foot{display:flex;align-items:center;justify-content:space-between;
  gap:10px;padding:11px 15px}
.plc-sheet-head{border-bottom:1px solid var(--line)}
.plc-sheet-foot{border-top:1px solid var(--line);font-size:13.5px;color:var(--ink-soft)}
.plc-close{width:30px;height:30px;border-radius:9px;border:1px solid var(--line);cursor:pointer;
  background:var(--surface);color:var(--ink-soft);font-size:19px;line-height:1}
.plc-map-canvas{height:min(58vh,420px)}
@media (max-width:1024px), (pointer:coarse), (hover:none){
  .plc-sheet{top:auto;bottom:0;left:0;transform:translateY(100%);width:100%;
    border-radius:18px 18px 0 0;max-height:92vh}
  .plc-sheet-ov.open .plc-sheet{transform:translateY(0)}
}
@media (prefers-reduced-motion:reduce){.plc-sheet,.plc-scrim{transition:none}}
/* «Создать новое место» — когда тёзка уже есть, но это другой населённый пункт */
.plc-keep.plc-force{background:var(--surface-2);border-top:0;margin-top:2px}
.plc-keep.plc-force b{color:var(--accent)}

/* Подтверждение выбранного места: видно регион и тип выбора — «Красных Горок»
   восемь в разных областях, и без этого проверить было нечем */
.plc-chosen{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:7px;
  padding:7px 10px;border-radius:9px;background:var(--accent-soft);font-size:13px}
.plc-chosen[hidden]{display:none}
.plc-ok{color:var(--accent);font-weight:700}
.plc-ch-nm{color:var(--ink);font-weight:600}
.plc-ch-where{color:var(--ink-soft)}
.plc-ch-kind{color:var(--ink-faint);font-size:11.5px;background:var(--surface);
  border:1px solid var(--line);border-radius:5px;padding:1px 7px}
.plc-ch-x{margin-left:auto;width:24px;height:24px;border-radius:6px;cursor:pointer;
  border:1px solid var(--line);background:var(--surface);color:var(--ink-soft);font-size:15px;line-height:1}
.plc-ch-x:hover{background:var(--surface-2);color:var(--ink)}
/* Список подсказок вверх, если снизу нет места (на телефоне поле часто внизу экрана) */
.plc-dd.up{top:auto;bottom:calc(100% + 5px)}
/* Подсказки геопоиска на странице мест — вверх, если снизу нет места */
.map-search{position:relative}
.geo-results.up{position:absolute;left:0;right:0;bottom:calc(100% + 6px);z-index:30;
  background:var(--surface);box-shadow:0 -8px 24px var(--shadow)}
/* Подтверждение после сохранения места: список лежит ниже формы, и без этого
   казалось, что кнопка не сработала */
.flash-ok{margin:0 0 14px;padding:11px 14px;border-radius:11px;font-size:14px;
  background:var(--accent-soft);color:var(--ink);border:1px solid var(--accent)}
/* Точка на кнопке «Поделиться» — ссылка включена */
#share-open{display:inline-flex;align-items:center;gap:7px}
.pub-dot{width:8px;height:8px;border-radius:50%;background:var(--living);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--living) 25%,transparent)}
/* Сколько людей реально видно по публичной ссылке (ловушка «включил — а там пусто») */
.pub-count{margin:0 0 10px;padding:9px 12px;border-radius:9px;font-size:13.5px;line-height:1.45}
.pub-count.ok{background:var(--accent-soft);color:var(--ink)}
.pub-count.warn{background:var(--gold-soft);color:var(--ink);border:1px solid var(--gold)}
/* Публичная ссылка включена, но никто не отмечен — объясняем вместо пустого полотна */
.gp-empty{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:5;
  max-width:min(420px,90vw);text-align:center;padding:20px 22px;border-radius:14px;
  background:var(--surface);border:1px solid var(--line);box-shadow:0 6px 22px var(--shadow)}
.gp-empty b{font-family:var(--serif);font-size:17px}
.gp-empty p{margin:8px 0 0;font-size:13.5px;color:var(--ink-soft);line-height:1.5}

/* ── «Кого показывать»: список галочек. Живёт и в шторке «Поделиться», и на
   отдельной странице /publish, поэтому высота ограничена и список прокручивается. */
.pub-block { margin-top: 12px; }
.pub-filter {
  width: 100%; margin-bottom: 8px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 8px; font: inherit; background: var(--bg);
}
.pub-people {
  list-style: none; margin: 0; padding: 0;
  max-height: 44vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--line); border-radius: 10px;
}
.pub-people .pub-row { border-bottom: 1px solid var(--line); }
.pub-people .pub-row:last-child { border-bottom: none; }
.pub-people label {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 9px 11px; cursor: pointer; min-height: 44px;  /* палец, не курсор */
}
.pub-people input[disabled] + span { opacity: .55; }
.pub-people label:has(input[disabled]) { cursor: not-allowed; }
.pub-people input[type="checkbox"] { margin-top: 3px; width: 18px; height: 18px; flex: none; }
.pub-people .name { display: block; font-weight: 600; font-size: 14px; }
.pub-people .meta { display: block; font-size: 12px; color: var(--muted); }

/* Настройки «что показывать»: общие (в шапке списка) и персональные (в строке) */
.pub-fields { border: 1px solid var(--line); border-radius: 10px; margin-bottom: 8px; }
.pub-fields > summary { padding: 10px 12px; cursor: pointer; font-size: 14px; }
.pub-fields > form { padding: 0 12px 12px; }
.pub-f { display: flex; gap: 8px; align-items: center; padding: 6px 0; font-size: 14px; }
.pub-f input { width: 18px; height: 18px; flex: none; }
.pub-f-in { padding-left: 26px; }
.pub-warn { font-size: 12px; color: var(--muted); margin: 6px 0 0; }
.pub-person-fields { margin: 0 11px 9px 39px; }
.pub-person-fields > summary { font-size: 12px; color: var(--muted); cursor: pointer; }
.pub-person-fields > form { padding-top: 6px; }
.pub-saved { color: var(--ok, #2e7d32); font-size: 12px; }

/* Публичная страница: переключатель вида и предупреждение о неполном показе */
.gp-views { position: absolute; top: 12px; right: 12px; z-index: 5; }
/* [hidden] должен побеждать display:flex — иначе плашка висит всегда */
.gp-partial[hidden] { display: none; }
.gp-partial {
  position: absolute; left: 50%; transform: translateX(-50%); bottom: 16px; z-index: 5;
  background: var(--surface, #fff); border: 1px solid var(--line); border-radius: 10px;
  padding: 8px 12px; font-size: 13px; box-shadow: 0 6px 20px rgba(0,0,0,.12);
  display: flex; gap: 10px; align-items: center; max-width: calc(100vw - 24px);
}
.gp-partial-fix {
  border: 1px solid var(--line); background: transparent; color: inherit;
  border-radius: 8px; padding: 5px 10px; font: inherit; cursor: pointer; white-space: nowrap;
}
@media (max-width: 700px) {
  .gp-views { top: 56px; right: 8px; }
  .gp-views .vlbl { display: none; }   /* на узком экране — только значки */
  .gp-partial { bottom: 10px; font-size: 12px; }
}
.node-place { cursor: help; opacity: .85; }
.node-place:hover { opacity: 1; }

/* Центр вида: рамка, ярлык «в центре», подпись над полотном */
.node.center > rect:first-of-type { stroke: #c99a2e; stroke-width: 2.4px; }
/* центр вида — мишень: золотой кружок с кольцом и точкой */
.node-center-cap circle { fill: #c99a2e; stroke: #fff; stroke-width: 1.6; }
.node-center-cap .cc-ring { fill: none; stroke: #fff; stroke-width: 1.6; }
.node-center-cap .cc-dot { fill: #fff; stroke: none; }
.view-center { position: absolute; left: 14px; top: 60px; z-index: 6; font-size: 13px;
  color: var(--muted); background: var(--surface, #fff); border: 1px solid var(--line);
  border-radius: 999px; padding: 5px 12px; box-shadow: 0 2px 10px var(--shadow);
  display: flex; gap: 8px; align-items: center; max-width: 60vw; }
.view-center.auto { border-color: #c99a2e; color: var(--ink); }
.vc-pick { border: 1px solid #c99a2e; background: transparent; color: inherit;
  border-radius: 999px; padding: 3px 10px; font: inherit; font-size: 12px; cursor: pointer; }

/* Плашка «задайте центр» и режим выбора */
.root-prompt { position: absolute; left: 50%; transform: translateX(-50%); top: 96px; z-index: 8;
  background: var(--surface,#fff); border: 1px solid #c99a2e; border-radius: 14px; padding: 14px 16px;
  box-shadow: 0 8px 28px rgba(0,0,0,.14); max-width: min(520px, 92vw); }
.rp-head { margin: 0 0 4px; font-size: 14px; }
.rp-sub { margin: 0 0 10px; font-size: 12px; color: var(--muted); }
.rp-cands { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
.rp-cand { display: flex; justify-content: space-between; gap: 10px; align-items: baseline;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: transparent;
  color: inherit; font: inherit; cursor: pointer; text-align: left; }
.rp-cand:hover { border-color: #c99a2e; }
.rp-meta { font-size: 12px; color: var(--muted); white-space: nowrap; }
.rp-actions { display: flex; gap: 8px; }
.pick-hint { position: absolute; left: 50%; transform: translateX(-50%); top: 96px; z-index: 8;
  background: #c99a2e; color: #fff; border-radius: 999px; padding: 7px 14px; font-size: 13px; }
.tree-canvas.pick-center .node { cursor: pointer; }
.tree-canvas.pick-center .node > rect:first-of-type { stroke-dasharray: 4 3; }
.vc-clear { border: none; background: transparent; color: var(--muted); font-size: 16px;
  line-height: 1; cursor: pointer; padding: 0 2px; }
.vc-clear:hover { color: var(--ink); }

/* Поиск и название рода в шапке. Название бывает очень длинным, поэтому ужимается
   многоточием и никогда не выталкивает поиск и меню аккаунта. */
.topbar-slot{display:flex;align-items:center;gap:12px;min-width:0;flex:1 1 auto;margin-left:18px}
/* Десктоп: название рода по центру шапки, поиск прижат к правому краю (к меню). */
/* Центрируем название только там, где для него есть место. Ниже 900px правый блок
   съедает почти всю ширину, и центрированное имя ужималось до «…», всё равно
   налезая на лупу — там оно просто течёт в строке, как на телефоне. */
@media (min-width:900px){
  .topbar-slot{justify-content:flex-end}
  .topbar-slot .spacer,.topbar>.spacer{display:none}
  /* Название центрировано абсолютно и о правом блоке (поиск+колокольчик+аватар,
     ~339px) ничего не знает — на узком десктопе доезжало под лупу. Второе
     ограничение оставляет ему только реально свободную половину. */
  .tree-name-hd{position:absolute;left:50%;transform:translateX(-50%);
    max-width:min(42vw, calc(100vw - 720px));
    pointer-events:none;flex:none}
  .tree-name-hd .tn-edit,.tree-name-hd .tn-text{pointer-events:auto}
}
.topbar-slot .graph-search{position:static;flex:0 1 260px;min-width:44px}
.tree-name-hd{font-weight:600;color:var(--ink);min-width:0;flex:0 1 auto;
  display:inline-flex;align-items:center;gap:6px}
/* текст ужимается многоточием, карандаш — вне зоны обрезки, всегда виден */
.tree-name-hd .tn-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.tree-name-hd .tn-edit{flex:none;display:inline-flex;color:var(--faint,#9a917f);
  padding:2px;border-radius:6px;line-height:0}
.tree-name-hd .tn-edit:hover{color:var(--accent,#2f7d4f);background:var(--surface-2,#efe9dc)}
.tree-name-hd .tn-edit svg{width:15px;height:15px}
.strip-settings{white-space:nowrap}
@media (max-width:900px){
  .topbar-slot{gap:8px;margin-left:10px}
  .topbar-slot .graph-search{flex:0 1 160px}
  .tree-name-hd{font-size:14px}
}
@media (max-width:560px){
  /* Мобильная шапка, вариант A: значок логотипа + название рода + поиск-иконка.
     Текст «Семейное древо» прячем — место отдаём названию дерева. */
  .brand > div{display:none}
  .spacer{display:none}
  .topbar-slot{margin-left:8px;gap:6px;min-width:0}
  /* display:flex (не block!), иначе карандаш-ссылка уезжала за край экрана.
     Обрезка — на .tn-text, карандаш остаётся виден. */
  .tree-name-hd{display:inline-flex;align-items:center;gap:6px;flex:1 1 auto;min-width:0;
    font-size:15px;padding-right:2px}
  /* Правки (отменить/вернуть/сбросить) — внизу слева, не мешают шапке */
  .layout-tools{position:fixed;left:8px;bottom:8px;top:auto;right:auto}
  /* «сбросить раскладку» — только значок ↺, подпись на телефоне прячем */
  #layout-reset .lt-lbl{display:none}
  #layout-reset{width:38px;height:38px;padding:0;border-radius:11px;font-size:18px;
    display:inline-flex;align-items:center;justify-content:center}
}

/* Подсказка мест по тапу (на тач-экране наведения нет) */
.place-tip{position:fixed;z-index:60;max-width:min(320px,86vw);background:var(--ink,#23303a);
  color:#fff;border-radius:10px;padding:9px 12px;font-size:13px;line-height:1.35;
  white-space:pre-line;box-shadow:0 8px 24px rgba(0,0,0,.28);cursor:pointer}
.place-tip[hidden]{display:none}

/* Поиск в шапке свёрнут до иконки; по нажатию разъезжается вправо поверх названия
   рода — в момент поиска имя дерева не нужно. */
/* Иконка поиска идёт СЛЕДОМ за названием в общем потоке. Абсолютное
   позиционирование клало её поверх текста («Ро(о)маниновых»): слот шире имени,
   и right:0 попадал в середину строки. */
.topbar-slot .graph-search{position:static;flex:0 0 auto;align-self:center;
  width:40px;height:40px;overflow:hidden;transition:width .18s ease;background:var(--surface);
  border:1px solid var(--line);border-radius:999px;padding:4px}
/* раскрытый поиск в шапке — высоту держим 40, чтобы не превращаться в овал */
.topbar-slot .graph-search.open{height:40px}
/* Раскрытый поиск не должен доезжать до меню аккаунта: на узком экране он
   ограничен шириной слота, а слот ужат остальными элементами шапки. */
.topbar-slot{overflow:hidden}
.topbar-slot .graph-search.open{width:min(300px,100%)}
.topbar-slot .graph-search input{width:100%;min-width:0}
/* Свёрнутый поиск в шапке: иконку — строго по центру круга. Старое правило
   форсило .gs-icon width:40 в контейнере с padding — иконка вылезала за край,
   overflow:hidden обрезал её, и лупа «съезжала» в левый верхний угол. */
.topbar-slot .graph-search:not(.open){display:flex;align-items:center;justify-content:center;box-sizing:border-box}
.topbar-slot .graph-search:not(.open) .gs-icon{width:100%;height:100%}
.topbar-slot .graph-search:not(.open) input,
.topbar-slot .graph-search:not(.open) #gs-clear{opacity:0;pointer-events:none}
.topbar-slot .tree-name-hd{padding-right:8px}

/* Разъезд поиска требует overflow:hidden, но он же резал выпадающий список
   («утакова» с обрезанным краем). Пока поле открыто — обрезку снимаем,
   а ширину держим max-width, чтобы поле по-прежнему не лезло на меню. */
.topbar-slot:has(.graph-search.open){overflow:visible}
.topbar-slot .graph-search.open{overflow:visible;max-width:min(300px,100%)}
/* position:relative нужен для привязки списка, но вместе с ним оживают top/left
   из старого «плавающего» правила — поиск съезжал на 12px вниз и вылезал из шапки. */
.topbar-slot .graph-search{position:relative;top:auto;left:auto;right:auto;bottom:auto;
  align-self:center;margin:0}
/* Список результатов привязан к полю: слева под ним, своей шириной, поверх полотна */
.topbar-slot .graph-search #gs-results{position:absolute;top:calc(100% + 6px);left:0;right:auto;
  min-width:280px;max-width:min(360px,92vw);z-index:40;background:var(--surface);
  border:1px solid var(--line);border-radius:12px;box-shadow:0 8px 24px var(--shadow);
  max-height:60vh;overflow:auto}
@media (max-width:560px){
  /* На телефоне список привязываем к ЭКРАНУ, а не к полю: поле узкое и стоит
     у правого края, поэтому список уезжал за левую границу (x = -18). */
  .topbar-slot .graph-search #gs-results{position:fixed;left:8px;right:8px;
    top:58px;min-width:0;max-width:none;width:auto}
}


/* Строка результата: лицо — имя — годы (как в поиске vnpfoto) */
.gs-item{display:flex;align-items:center;gap:10px;padding:8px 10px}
.gs-ava{flex:0 0 34px;width:34px;height:34px;border-radius:50%;overflow:hidden;
  display:flex;align-items:center;justify-content:center;color:#fff;font-size:12px;
  font-weight:600;background:var(--line)}
.gs-ava img{width:100%;height:100%;object-fit:cover;display:block}
.gs-txt{display:flex;flex-direction:column;min-width:0}
.gs-item .gs-name{font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gs-item .gs-yr{font-size:12px;color:var(--muted)}

/* Встроенная поисковая лупа/крестик браузера накладывались на нашу иконку
   («косая лупа» на телефоне) — гасим, оставляем только svg. */
#gsearch::-webkit-search-decoration,
#gsearch::-webkit-search-cancel-button,
#gsearch::-webkit-search-results-button,
#gsearch::-webkit-search-results-decoration{-webkit-appearance:none;appearance:none;display:none}
#gsearch{-webkit-appearance:none;appearance:none}

/* Зона удаления дерева — внизу страницы, отделена от обычных действий */
.danger-zone{margin:40px 0 8px;padding-top:18px;border-top:1px solid var(--line);
  display:flex;justify-content:flex-end}

/* Второстепенные действия дерева — одним рядом. На узком экране «Экспорт GEDCOM»
   сокращаем до «Экспорт», иначе три кнопки не помещаются. */
.tree-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin:0 0 22px}
.tree-actions .ta-short{display:none}
@media (max-width:420px){
  .tree-actions{gap:6px;flex-wrap:nowrap}
  .tree-actions .btn{padding-left:10px;padding-right:10px;font-size:13px;white-space:nowrap}
  .tree-actions .ta-full{display:none}
  .tree-actions .ta-short{display:inline}
}

/* ── Вид как выпадашка (триггер + меню) ── */
.view-dd{position:relative;display:inline-flex}
.view-dd-trigger{display:inline-flex;align-items:center;gap:7px}
.view-dd-trigger .vdd-icon{display:inline-flex;line-height:0;color:var(--accent)}
.view-dd-trigger .vdd-icon svg{width:16px;height:16px}
.view-dd-trigger .vdd-car{width:13px;height:13px;color:var(--faint);transition:transform .18s ease}
.view-dd.open .vdd-trigger .vdd-car,.view-dd.open .vdd-car{transform:rotate(180deg)}
/* меню поверх полотна */
.view-dd-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:30;
  flex-direction:column;background:var(--surface,#fff);border:1px solid var(--line);
  border-radius:12px;box-shadow:0 8px 24px var(--shadow);padding:5px;min-width:150px;gap:2px}
.view-dd-menu[hidden]{display:none}
/* кнопки видов в меню — строкой: иконка + подпись слева */
/* триггер — только иконка вида, без подписи */
.view-dd-trigger .vdd-label{display:none}
.view-dd-trigger{gap:5px;padding:6px 9px}
/* пункты меню — иконка+текст в СТРОКУ (перебиваем мобильный column у .vbtn) */
.view-dd-menu .vbtn{display:flex;flex-direction:row;align-items:center;gap:10px;width:100%;justify-content:flex-start;
  padding:8px 10px;border:none;background:none;border-radius:8px;cursor:pointer;color:var(--ink)}
.view-dd-menu .vbtn .vlbl{display:inline;font-size:14px}
.view-dd-menu .vbtn svg{width:17px;height:17px;color:var(--soft)}
.view-dd-menu .vbtn:hover{background:var(--surface-2,#efe9dc)}
.view-dd-menu .vbtn.active{background:var(--green-soft,#e2ede6);font-weight:600}
.view-dd-menu .vbtn.active svg{color:var(--accent)}

/* Настройки: на десктопе текст, на мобилке — иконка-шестерёнка (в стопке островков) */
/* Настройки дерева — только шестерёнка, как «?» рядом: подпись занимала место
   на полотне, а заходят туда редко. Смысл держит title и aria-label. */
.strip-settings .ss-ic{display:block;width:17px;height:17px}
.strip-settings .ss-txt{display:none}
.strip-settings{display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:30px;padding:0}

/* ── Поиск как островок в мобильной стопке (перенесён из шапки JS-ом) ── */
@media (max-width:560px){
  #tree-strip .graph-search{position:relative;top:auto;left:auto;right:auto;
    width:40px;height:40px;padding:0;background:var(--surface);border:1px solid var(--line);
    border-radius:11px;box-shadow:0 2px 8px var(--shadow);overflow:visible;
    display:flex;align-items:center;justify-content:center}
  #tree-strip .graph-search .gs-icon{width:40px;height:40px}
  /* раскрытие: иконка остаётся справа (row-reverse), поле выезжает ВЛЕВО поверх полотна.
     left:auto + right:0 перебивают старое островное left:12, из-за которого поле уходило вправо. */
  #tree-strip .graph-search.open{position:absolute;right:0;left:auto;top:0;
    flex-direction:row-reverse;width:min(240px,74vw);
    justify-content:flex-start;padding:0 4px 0 12px;border-color:var(--accent)}
  #tree-strip .graph-search:not(.open) .gs-field{display:none}
  #tree-strip .graph-search.open .gs-field{display:flex;flex:1;min-width:0}
  /* список результатов — под полем поиска, во всю ширину экрана, с прокруткой.
     top:auto вычислялся в -72px (список улетал за верх, перекрывая шапку) — задаём явно. */
  #tree-strip .graph-search #gs-results{position:fixed;left:8px;right:8px;top:116px;bottom:auto;
    min-width:0;max-width:none;width:auto;max-height:60vh;overflow-y:auto;
    -webkit-overflow-scrolling:touch;background:var(--surface);border:1px solid var(--line);
    border-radius:14px;box-shadow:0 10px 30px var(--shadow);padding:4px}
}

/* Попап правки названия дерева (по карандашу в шапке графа) */
.tname-pop{position:fixed;z-index:40;display:flex;gap:8px;align-items:center;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  padding:8px;box-shadow:0 10px 30px var(--shadow);width:260px}
.tname-pop[hidden]{display:none}
.tname-pop input{flex:1;min-width:0;padding:8px 10px;border:1px solid var(--line);
  border-radius:9px;font:inherit;font-size:14px;background:var(--bg);color:var(--ink)}
.tname-pop input:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
.tn-edit{border:none;background:none;cursor:pointer;padding:2px;pointer-events:auto}

/* Плашка «кто-то не влез в текущий вид» (одиночки/острова в Часах и др.) */
/* Подсказка «не в этом виде» переехала в тост (см. showViewHidden в tree.js):
   плашкой она стояла над полотном и закрывала кнопки карточки. */

/* ── Просмотр фото во весь экран (lightbox.js) ──────────────────────────────
   Общий для страницы персоны и панели графа: крупный снимок, стрелки и
   отметки «кто на фото» — отмечать людей на миниатюре 130px невозможно. */
.lbx{position:fixed;inset:0;z-index:10050;display:none;background:rgba(20,17,12,.92);
  align-items:center;justify-content:center;gap:0;padding:24px}
.lbx.open{display:flex}
html.lbx-lock{overflow:hidden}
.lbx-stage{flex:1 1 auto;height:100%;display:grid;place-items:center;min-width:0}
.lbx-stage img{max-width:100%;max-height:100%;object-fit:contain;border-radius:6px;
  box-shadow:0 18px 50px rgba(0,0,0,.55)}
.lbx-side{flex:0 0 260px;align-self:stretch;background:var(--surface);border-radius:12px;
  margin-left:20px;padding:16px;display:flex;flex-direction:column;gap:12px;overflow-y:auto}
.lbx-count{font-size:12px;color:var(--ink-soft);font-variant-numeric:tabular-nums}
.lbx-tags-t{font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-soft)}
.lbx-tags{display:flex;flex-wrap:wrap;gap:6px}
.lbx-none{font-size:12.5px;color:var(--ink-faint,var(--ink-soft))}
.lbx-chip{display:inline-flex;align-items:center;gap:6px;background:var(--bg);
  border:1px solid var(--line);border-radius:20px;padding:3px 6px 3px 11px;font-size:12.5px}
.lbx-chip button{border:none;background:none;color:var(--ink-soft);font-size:15px;line-height:1;
  cursor:pointer;padding:0 2px;border-radius:4px}
.lbx-chip button:hover{color:var(--danger)}
.lbx-add select{width:100%;font:inherit;font-size:13px;padding:6px 8px;border:1px solid var(--line);
  border-radius:8px;background:var(--surface);color:var(--ink)}
.lbx-acts{margin-top:auto;display:flex;flex-direction:column;gap:7px}
.lbx-btn{display:block;font:inherit;font-size:13px;font-weight:600;text-align:left;
  padding:8px 11px;border:1px solid var(--line);border-radius:9px;background:var(--surface);
  color:var(--ink);cursor:pointer;text-decoration:none}
.lbx-btn:hover{background:var(--bg)}
.lbx-btn.lbx-dg{color:var(--danger);border-color:var(--danger)}
.lbx-x{position:absolute;top:14px;right:16px;width:40px;height:40px;border:none;border-radius:10px;
  background:rgba(255,255,255,.12);color:#fff;font-size:24px;line-height:1;cursor:pointer}
.lbx-x:hover{background:rgba(255,255,255,.22)}
.lbx-arw{flex:none;width:44px;height:44px;border:none;border-radius:50%;cursor:pointer;
  background:rgba(255,255,255,.14);color:#fff;font-size:26px;line-height:1;align-self:center}
.lbx-arw:hover{background:rgba(255,255,255,.26)}
.lbx-arw[hidden]{display:none}
.lbx :focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* узкий экран: подпись и отметки уезжают вниз, снимок занимает верх */
@media (max-width:760px), (pointer:coarse){
  .lbx{flex-direction:column;padding:12px;gap:10px}
  .lbx-stage{width:100%;flex:1 1 auto;min-height:0}
  .lbx-side{flex:0 0 auto;width:100%;margin:0;max-height:42vh;
    padding:12px calc(12px + env(safe-area-inset-bottom))}
  .lbx-acts{flex-direction:row;flex-wrap:wrap}
  .lbx-acts .lbx-btn{flex:1 1 auto;text-align:center}
  .lbx-arw{position:absolute;top:44%;z-index:2}
  .lbx-prev{left:10px} .lbx-next{right:10px}
}

/* ── Галерея на странице персоны (gallery.js) ───────────────────────────────
   Раньше под каждым снимком стояли две формы и выпадашка отметок — управления
   было больше, чем фотографий. Теперь в сетке только снимки, действия
   появляются на наведении, а отметки живут в лайтбоксе. */
.gal-drop{display:flex;flex-direction:column;align-items:center;gap:3px;text-align:center;
  border:2px dashed var(--line);border-radius:12px;padding:20px 16px;background:var(--surface-2);
  cursor:pointer;transition:border-color .15s,background .15s}
.gal-drop:hover,.gal-drop:focus-visible{border-color:var(--accent)}
.gal-drop.hot{border-color:var(--accent);background:var(--accent-soft,var(--surface-2))}
.gal-drop b{font-size:14.5px}
.gal-drop-ic{width:32px;height:32px;border-radius:50%;background:var(--accent-soft,var(--bg));
  color:var(--accent);display:grid;place-items:center;font-size:17px;font-weight:700;margin-bottom:4px}
.gal-drop-sub{font-size:12.5px;color:var(--ink-soft)}

.gal-queue{display:grid;grid-template-columns:repeat(auto-fill,minmax(84px,1fr));gap:8px;margin-top:12px}
.gal-queue:empty{display:none}
.gal-q{position:relative;aspect-ratio:1;border-radius:9px;overflow:hidden;background:var(--surface-2)}
.gal-q img{width:100%;height:100%;object-fit:cover;display:block}
.gal-q.done{outline:2px solid var(--accent);outline-offset:-2px}
.gal-q.done img,.gal-q.failed img{opacity:.55}
.gal-q.failed{outline:2px solid var(--danger);outline-offset:-2px}
.gal-qx{position:absolute;top:4px;right:4px;width:20px;height:20px;border:none;border-radius:50%;
  background:rgba(0,0,0,.62);color:#fff;font-size:13px;line-height:20px;cursor:pointer;padding:0}
.gal-qbar{position:absolute;left:0;right:0;bottom:0;height:4px;background:rgba(255,255,255,.4)}
.gal-qbar i{display:block;height:100%;width:0;background:var(--accent);transition:width .15s}
.gal-qerr{position:absolute;left:0;right:0;bottom:0;padding:3px 5px;font-size:10px;line-height:1.25;
  background:var(--danger);color:#fff}
.gal-qerr:empty{display:none}
.gal-qfoot{display:flex;align-items:center;gap:10px;margin-top:10px;font-size:13px;color:var(--ink-soft)}
/* display:flex перебивает UA-правило для [hidden] — возвращаем скрытие явно,
   иначе «Загрузить» и панель выбора висят на пустом месте (поймано на телефоне) */
.gal-qfoot[hidden],.gal-selbar[hidden]{display:none}
.gal-qfoot button{margin-left:auto}

.gal-selbar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:14px 0 0;
  padding:8px 12px;background:var(--surface-2);border:1px solid var(--line);border-radius:10px}
.gal-selall{display:flex;align-items:center;gap:7px;font-size:14px;cursor:pointer}
.gal-selbar button{margin-left:auto}

.gal-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:10px;margin-top:14px}
.gal-empty{grid-column:1/-1;margin:0;padding:18px 0}
.gal-cell{position:relative;margin:0;aspect-ratio:1;border-radius:10px;overflow:hidden;
  background:var(--surface-2);border:1px solid var(--line)}
.gal-cell img{width:100%;height:100%;object-fit:cover;display:block;cursor:zoom-in}
.gal-cell.picked{border-color:var(--danger);box-shadow:0 0 0 2px var(--danger)}
.gal-cell.picked img{opacity:.7}
/* число отмеченных на снимке — чтобы не открывать каждый ради проверки */
.gal-tagged{position:absolute;bottom:6px;left:6px;background:rgba(0,0,0,.6);color:#fff;
  font-size:11px;font-weight:700;border-radius:20px;padding:1px 7px;pointer-events:none}
.gal-tagged::before{content:"👤 "}
/* действия — только под мышью; на таче их заменяет лайтбокс */
.gal-ov{position:absolute;top:0;right:0;display:flex;gap:4px;padding:5px;opacity:0;
  transition:opacity .12s}
.gal-cell:hover .gal-ov,.gal-cell:focus-within .gal-ov{opacity:1}
.gal-ov button{width:26px;height:26px;border:none;border-radius:7px;background:rgba(255,255,255,.92);
  color:var(--ink);font-size:13px;line-height:1;cursor:pointer;padding:0;box-shadow:0 1px 4px rgba(0,0,0,.25)}
.gal-ov button[data-act="del"]{color:var(--danger)}
.gal-pick{position:absolute;top:6px;left:6px;display:none;padding:5px;border-radius:7px;
  background:rgba(255,255,255,.9);box-shadow:0 1px 4px rgba(0,0,0,.2);cursor:pointer}
.gal-pick input{width:18px;height:18px;margin:0;cursor:pointer}
.gal-grid.picking .gal-pick{display:flex}
.gal-grid.picking .gal-ov{display:none}
.gal-grid.picking .gal-cell img{cursor:pointer}
@media (pointer:coarse){ .gal-ov{opacity:1} }

/* ── Галерея и лайтбокс на телефоне ─────────────────────────────────────────
   Две колонки вместо трёх: на 390px три дают 118px — лица не разобрать, а ради
   лиц галерея и нужна (отметки «кто на фото»). */
@media (max-width:560px){
  .gal-grid{grid-template-columns:1fr 1fr}
  .gal-queue{grid-template-columns:repeat(3,1fr)}
}
/* Тащить файлы на телефоне нечем — зона становится крупной кнопкой. Подписи
   меняем местами, а не прячем: «перетащите» без мыши звучит издевательством. */
.gal-drop .for-touch{display:none}
@media (pointer:coarse),(hover:none){
  .gal-drop .for-mouse{display:none}
  .gal-drop .for-touch{display:block}
  .gal-drop{padding:16px 12px}
}
/* пустой раздел галереи в панели графа зовёт добавить, а не молчит */
.pcard-gal-empty{display:flex;flex-direction:column;align-items:center;gap:7px;
  border:1.5px dashed var(--line);border-radius:10px;padding:12px;background:var(--surface-2);
  font-size:12.5px;color:var(--ink-soft);text-align:center}

/* ── Всплывашка загрузки (photo-upload.js) ──────────────────────────────────
   Зона и очередь нужны только в момент загрузки; постоянно они занимали место
   над сеткой и отодвигали вниз сами фотографии. */
.pu-back{position:fixed;inset:0;z-index:10060;background:rgba(20,17,12,.42)}
.pu{position:fixed;z-index:10061;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(420px,calc(100vw - 32px));background:var(--surface);border:1px solid var(--line);
  border-radius:14px;box-shadow:var(--shadow);padding:14px}
.pu-hd{display:flex;align-items:center;gap:8px;margin-bottom:10px}
.pu-hd b{font-size:16px}
.pu-x{margin-left:auto;width:30px;height:30px;border:1px solid var(--line);border-radius:8px;
  background:var(--surface);color:var(--ink-soft);font-size:18px;line-height:1;cursor:pointer}
.pu-grab{display:none}
/* на телефоне — лист снизу: там ждут действий именно оттуда */
@media (max-width:560px),(pointer:coarse){
  .pu{left:0;right:0;top:auto;bottom:0;transform:none;width:auto;border-radius:16px 16px 0 0;
    border-left:0;border-right:0;border-bottom:0;
    padding:8px 14px calc(16px + env(safe-area-inset-bottom))}
  .pu-grab{display:block;width:38px;height:4px;border-radius:2px;background:var(--line);margin:0 auto 8px}
}

/* Страница персоны: перетаскивание принимает сама сетка — рамка появляется
   только когда файлы занесли над ней. */
.gal-head-acts{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.gal-grid.hot{outline:2px dashed var(--accent);outline-offset:6px;border-radius:12px}
.gal-dnd-hint{margin:10px 0 0;font-size:12px;color:var(--ink-faint,var(--ink-soft));text-align:center}
@media (pointer:coarse),(hover:none){ .gal-dnd-hint{display:none} }

/* Панель графа: ссылка на полную галерею — править и удалять удобнее там */
.pcard-gal-all{display:block;margin-top:8px;font-size:12px;color:var(--accent);text-decoration:none}
.pcard-gal-all:hover{text-decoration:underline}

/* ── «Не в этом виде»: бейдж на переключателе видов ─────────────────────────
   Было тостом — но это состояние, а не событие: пока выбран такой вид, оно
   верно всегда. Держим у причины — у выбора вида. */
.view-dd-trigger{position:relative}
.vdd-miss{position:absolute;top:-6px;right:-6px;min-width:18px;height:18px;padding:0 5px;
  border-radius:20px;background:var(--gold,#C99A2E);color:#fff;font-size:11px;font-weight:700;
  line-height:18px;text-align:center;box-shadow:0 1px 3px rgba(0,0,0,.3);
  font-variant-numeric:tabular-nums;pointer-events:none}
/* пояснение — внутри выпадашки видов: там же, где выбирают вид */
.vdd-note{margin:5px 3px 1px;padding:8px 9px 2px;border-top:1px solid var(--line);
  font-size:12px;line-height:1.45;color:var(--ink-soft);white-space:normal;max-width:220px}
.vdd-note b{color:var(--ink)}
.vdd-note a{color:var(--accent);font-weight:700;text-decoration:none;white-space:nowrap}
.vdd-note a:hover{text-decoration:underline}
/* цифра у выбранного вида в списке — та же, что на кнопке-триггере */
.vbtn-miss{margin-left:auto;min-width:18px;height:18px;padding:0 5px;border-radius:20px;
  background:var(--gold,#C99A2E);color:#fff;font-size:11px;font-weight:700;line-height:18px;
  text-align:center;font-variant-numeric:tabular-nums;flex:none}
.view-dd-menu .vbtn{display:flex;align-items:center}

/* ── Маршрут жизни на карточке ──────────────────────────────────────────────
   События с координатами — точками по датам: таблица дат не отвечает на вопрос
   «откуда и куда двигался человек», карта отвечает. */
.life-route{margin:0 0 16px;border:1px solid var(--line);border-radius:12px;overflow:hidden;
  background:var(--surface-2)}
.life-route[hidden]{display:none}
.lr-head{display:flex;align-items:center;gap:10px;padding:9px 12px;font-size:14px}
.lr-head b{font-size:15px}
.lr-head .muted{font-size:12.5px}
.lr-head button{margin-left:auto}
.lr-map{height:280px;background:var(--surface)}
@media (max-width:560px){ .lr-map{height:220px} }
/* номер точки: без порядка на карте не понять, что было раньше */
.lr-pin span{display:grid;place-items:center;width:24px;height:24px;border-radius:50%;
  background:var(--accent);color:#fff;font:700 12px/1 var(--font-sans,system-ui);
  box-shadow:0 1px 4px rgba(0,0,0,.35);border:2px solid #fff}
.leaflet-container{font:inherit}

/* крестик на участнике события: снять человека с события можно было только
   запросом — эндпоинт был, кнопки не было */
/* Крестик УГЛОМ, а не внутри кружка: 26px заняты инициалами, и вставленный
   внутрь крестик их вытеснял — плашка переставала читаться. */
.chip-a.removable{position:relative;overflow:visible}
/* Крестик виден всегда: под наведением его приходилось угадывать — человек не
   знал, что плашку вообще можно убрать. Приглушён, чтобы не спорить с инициалами,
   и наливается цветом под курсором. */
.chip-a .chip-x{position:absolute;top:-6px;right:-6px;width:18px;height:18px;padding:0;
  border:2px solid var(--surface);border-radius:50%;background:var(--ink-soft);color:#fff;
  font-size:12px;line-height:14px;cursor:pointer;opacity:.9;transition:background .12s,opacity .12s}
.chip-a.removable:hover .chip-x{background:var(--danger);opacity:1}
.chip-a .chip-x:hover{background:var(--danger);opacity:1}

/* Много участников: четыре плашки + «+N». Строка таблицы перестаёт зависеть от
   числа отмеченных — на свадьбе их десяток, и раньше она распухала на четыре
   ряда, выталкивая соседние события за экран. */
.parts-more{width:26px;height:26px;border-radius:50%;border:1px dashed var(--line);
  background:var(--surface-2);color:var(--ink-soft);font:700 11px/1 inherit;cursor:pointer;
  flex:none;padding:0;font-variant-numeric:tabular-nums}
.parts-more:hover{border-color:var(--accent);color:var(--accent)}
.parts-all{flex-basis:100%;display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}
.parts-all[hidden]{display:none}
.part-pill{display:inline-flex;align-items:center;gap:6px;background:var(--surface-2);
  border:1px solid var(--line);border-radius:20px;padding:2px 4px 2px 3px;font-size:12.5px}
.part-pill .chip-a{width:20px;height:20px;font-size:9px}
.part-pill .pill-x{border:none;background:none;color:var(--ink-faint,var(--ink-soft));
  font-size:14px;line-height:1;cursor:pointer;padding:0 4px;border-radius:50%}
.part-pill .pill-x:hover{color:var(--danger);background:rgba(0,0,0,.06)}
/* Список «кого отметить» живёт в таблице, а не в .field — рамку и скругления
   ему приходится выдавать отдельно, иначе он выпадает браузерным серым. */
/* Подписи мест на картах. Рисуем поверх пёстрого рельефа, поэтому не рамка с
   фоном (пятнами закрывала бы карту), а белая обводка вокруг букв. */
.lr-lbl{background:none;border:none;box-shadow:none;padding:0;
  font:600 12px/1.2 inherit;color:var(--ink);white-space:nowrap;
  text-shadow:0 0 3px #fff,0 0 3px #fff,0 0 2px #fff,1px 1px 2px #fff}
.lr-lbl::before{display:none}
.map-nolabels .lr-lbl{display:none}
:root[data-theme="dark"] .lr-lbl{color:#1b1f1c}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .lr-lbl{color:#1b1f1c}}

.evt-add{display:flex;align-items:center;gap:6px;margin-top:6px;min-width:190px}
.evt-add select{flex:1 1 auto;min-width:0;padding:7px 30px 7px 10px;border:1px solid var(--line);border-radius:9px;
  background-color:var(--surface);color:var(--ink);font:inherit;font-size:13px;max-width:158px}
.evt-add select:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
