
:root {
  --bg:          #f2eee2;
  --panel:       #ffffff;
  --line:        #d8d2c2;
  --text:        #2f2a22;
  --muted:       #857f70;
  --male:        #b9e0f2;
  --male-edge:   #7fbcd8;
  --female:      #f7c9dd;
  --female-edge: #e094b8;
  --neutral:     #e4dfd2;
  --accent:      #1f6bb0;
  --danger:      #b3372c;
  --radius:      10px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

.loading { padding: 40px; color: var(--muted); }

/* --- Каркас ------------------------------------------------------------- */

.topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 20px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 10;
}
.topbar h1 { font-size: 17px; margin: 0; font-weight: 600; }
.topbar .spacer { flex: 1; }
.topbar .who { color: var(--muted); font-size: 13px; }

.wrap { max-width: 1180px; margin: 0 auto; padding: 20px; }
/* Екран дерева ширший: полотну простір потрібніший, ніж рівні поля */
.wrap.wide { max-width: 1720px; }
.columns { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 20px; align-items: start; }
@media (max-width: 900px) { .columns { grid-template-columns: minmax(0, 1fr); } }

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 16px;
}
.card h2 { margin: 0 0 12px; font-size: 15px; font-weight: 600; }
.card h3 { margin: 16px 0 8px; font-size: 13px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }

.side { position: sticky; top: 70px; }

/* --- Елементи керування -------------------------------------------------- */

button {
  font: inherit;
  padding: 7px 13px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #fff;
  color: var(--text);
  cursor: pointer;
}
button:hover { background: #f6f3ea; }
button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
button.primary:hover { filter: brightness(1.08); }
button.danger { color: var(--danger); border-color: #e0bdb8; }
button.danger:hover { background: #fbf0ee; }
button.small { padding: 4px 9px; font-size: 13px; }
button:disabled { opacity: .5; cursor: default; }

input, select, textarea {
  font: inherit;
  width: 100%;
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #fff;
  color: var(--text);
}
textarea { min-height: 70px; resize: vertical; }
input:focus, select:focus, textarea:focus { outline: 2px solid #bcd8ef; border-color: var(--accent); }

label { display: block; margin-bottom: 10px; }
label > span { display: block; font-size: 13px; color: var(--muted); margin-bottom: 3px; }
.hint { font-size: 12px; color: var(--muted); margin-top: 3px; }
.row { display: flex; gap: 8px; flex-wrap: wrap; }
.row > * { flex: 1; min-width: 0; }
.row.tight > * { flex: 0 0 auto; }

/* --- Повідомлення -------------------------------------------------------- */

.msg { padding: 9px 12px; border-radius: 7px; margin-bottom: 12px; font-size: 14px; }
.msg.error { background: #fbeae8; color: var(--danger); border: 1px solid #eccbc6; }
.msg.ok    { background: #e9f4e9; color: #2c6b30; border: 1px solid #c6e0c8; }

/* --- Вхід ---------------------------------------------------------------- */

.auth { max-width: 380px; margin: 60px auto; }
.auth .tabs { display: flex; gap: 6px; margin-bottom: 16px; }
.auth .tabs button { flex: 1; }
.auth .tabs button.on { background: var(--accent); border-color: var(--accent); color: #fff; }

/* --- Список дерев -------------------------------------------------------- */

.tree-item {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 0; border-bottom: 1px solid var(--line);
}
.tree-item:last-child { border-bottom: none; }
.tree-item .name { flex: 1; font-weight: 500; }
.tree-item .meta { color: var(--muted); font-size: 13px; }

/* --- Структура родини ---------------------------------------------------- */

.family { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px; margin-bottom: 12px; background: #fdfcf8; }
.family .couple { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.family .kids { margin: 10px 0 0 20px; padding-left: 12px; border-left: 2px solid var(--line); }
.family .kids > * { margin-top: 6px; }
.family .label { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.family .plus { color: var(--muted); }

.person {
  display: inline-flex; align-items: baseline; gap: 7px;
  padding: 6px 11px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--neutral); background: var(--neutral);
  text-align: left;
}
.person.m { background: var(--male);   border-color: var(--male-edge); }
.person.f { background: var(--female); border-color: var(--female-edge); }
.person.on { outline: 2px solid var(--accent); outline-offset: 1px; }
.person .nm { font-weight: 600; color: #17456f; }
.person .dt { font-size: 12px; color: #5b6c7d; }
.person.dead .nm::after { content: " †"; color: var(--muted); font-weight: 400; }

.empty { color: var(--muted); padding: 8px 0; }

/* --- Панель особи -------------------------------------------------------- */

.altname { display: flex; gap: 6px; margin-bottom: 6px; align-items: center; }
.altname input { flex: 1; }
.altname select { flex: 0 0 130px; }
.altname button { flex: 0 0 auto; }

.rel-buttons { display: flex; flex-wrap: wrap; gap: 6px; }

.union-item {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px;
  margin-bottom: 10px;
  background: #fdfcf8;
}
.union-item:last-child { margin-bottom: 0; }
.union-with { font-weight: 600; margin-bottom: 8px; }
.union-item .row { margin-bottom: 6px; }

/* Коротке підсвічування картки, коли на неї навели з полотна кнопкою «+» */
.card.flash { animation: flash 900ms ease-out; }
@keyframes flash {
  0%   { box-shadow: 0 0 0 3px rgba(31,107,176,.55); }
  100% { box-shadow: 0 0 0 3px rgba(31,107,176,0); }
}


/* --- Полотно дерева ------------------------------------------------------ */

.canvas {
  position: relative;
  overflow: hidden;
  height: calc(100vh - 132px);
  min-height: 420px;
  background: var(--bg);
  background-image:
    linear-gradient(rgba(0,0,0,.028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0,0,0,.028) 1px, transparent 1px);
  background-size: 28px 28px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: grab;
  touch-action: none;          /* панораму ведемо самі, браузер хай не заважає */
  user-select: none;
}
.canvas.dragging { cursor: grabbing; }

.viewport {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 0 0;
}

.edges { position: absolute; top: 0; left: 0; overflow: visible; }
.edge { fill: none; stroke: #c9c0ab; stroke-width: 2; stroke-linecap: square; }
.edge-dot { fill: #c9c0ab; }

.cards { position: absolute; top: 0; left: 0; }

.node {
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  padding: 8px 12px;
  border: 1px solid var(--neutral);
  background: var(--neutral);
  border-radius: 9px;
  box-shadow: 0 1px 2px rgba(0,0,0,.10);
  cursor: pointer;
}
.node.m { background: var(--male);   border-color: var(--male-edge); }
.node.f { background: var(--female); border-color: var(--female-edge); }
.node:hover { filter: brightness(1.04); }
.node.on { outline: 2px solid var(--accent); outline-offset: 2px; }

.node-name {
  font-weight: 600;
  font-size: 13px;
  line-height: 1.25;
  color: #17456f;
  /* Довге прізвище обрізаємо, а не розсовуємо картку: розкладка порахована
     під сталу ширину, і «поповзла» б уся картинка */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.node-dates {
  font-size: 11px;
  color: #5b6c7d;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.node.dead .node-name::after { content: " †"; font-weight: 400; color: #6b7885; }

.node-add {
  position: absolute;
  left: 50%;
  bottom: -11px;
  margin-left: -11px;
  width: 22px;
  height: 22px;
  padding: 0;
  line-height: 1;
  font-size: 15px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--muted);
  opacity: 0;
  transition: opacity .12s;
}
.node:hover .node-add, .node.on .node-add { opacity: 1; }
.node-add:hover { color: var(--accent); border-color: var(--accent); }

.zoombar {
  position: absolute;
  top: 12px;
  right: 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.zoombar button {
  width: 32px;
  height: 32px;
  padding: 0;
  font-size: 16px;
  line-height: 1;
  background: #fff;
  box-shadow: 0 1px 2px rgba(0,0,0,.12);
}

.canvas-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.canvas-empty > div {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px 20px;
  max-width: 420px;
}

/* --- Дрібні утиліти ------------------------------------------------------
   Окремі класи замість атрибутів style: політика безпеки (style-src 'self')
   вбудовані стилі не пропускає, і атрибут style мовчки не спрацював би.
   Програмна зміна властивостей (element.style.left = ...) під заборону
   не підпадає — саме так позиціонуються картки на полотні. */

.mt-8  { margin-top: 8px; }
.mt-14 { margin-top: 14px; }
.w-190 { width: 190px; flex: 0 0 auto; }
.no-grow { flex: 0 0 auto; }

.check { display: flex; align-items: center; gap: 8px; }
.check > input { width: auto; flex: 0 0 auto; }
.check > span { display: inline; margin: 0; font-size: 15px; color: var(--text); }
