/* ═══════════════════════════════════════════════════════════════
   Netfold UI kit · ноды на холсте
   Классы совместимы с текущими: .node .lv-0/1/2 .df-bg .df-color
   .selected .search-match .search-active .linking-source
   Новые: .shape-* .is-pinned .is-locked .is-collapsed .link-target .is-editing
   Пользовательские цвета (без .df-bg / .df-color) НЕ перекрываются.
   Тяжёлых эффектов нет: только box-shadow без размытия (кроме тем,
   где размытие нужно и оно стоит на 1–2 нодах: центр, выбранная).
   ═══════════════════════════════════════════════════════════════ */

.node {
  position: absolute;
  box-sizing: border-box;
  font-family: var(--nf-font-ui);
  font-size: var(--nf-n1-size);
  line-height: 1.35;
  padding: 12px 16px;
  border-radius: var(--nf-r1);
  transition: transform var(--nf-dur) var(--nf-ease), box-shadow var(--nf-dur) var(--nf-ease);
  -webkit-font-smoothing: antialiased;
  overflow-wrap: anywhere;
}

/* ── Уровни: значения по умолчанию ── */
.node.lv-0 { padding: 16px 22px; border-radius: var(--nf-r0); font-size: var(--nf-n0-size); box-shadow: var(--nf-n0-shadow); }
.node.lv-1 { box-shadow: var(--nf-n1-shadow); }
.node.lv-2 { padding: 9px 12px; border-radius: var(--nf-r2); font-size: var(--nf-n2-size); box-shadow: var(--nf-n2-shadow); }

.node.lv-0.df-bg { background: var(--nf-n0-bg); }
.node.lv-1.df-bg { background: var(--nf-n1-bg); }
.node.lv-2.df-bg { background: var(--nf-n2-bg); }
.node.lv-0.df-color { color: var(--nf-n0-fg); }
.node.lv-1.df-color { color: var(--nf-n1-fg); }
.node.lv-2.df-color { color: var(--nf-n2-fg); }

/* ── Содержимое ── */
.node .n-title { font-weight: var(--nf-n1-weight); letter-spacing: -.005em; }
.node.lv-0 .n-title { font-family: var(--nf-n0-font); font-weight: var(--nf-n0-weight); letter-spacing: -.01em; line-height: 1.2; }
.node .n-text { margin-top: 3px; opacity: .78; font-size: .9em; }
.node .n-meta { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 7px; }
.node .n-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font: 500 var(--nf-meta-size)/1 var(--nf-font-mono);
  padding: 4px 5px; border-radius: 6px;
  background: color-mix(in srgb, currentColor 9%, transparent);
  white-space: nowrap;
}
.node .n-chip::before { content: none; }
.node .n-chip.st-todo::before, .node .n-chip.st-doing::before, .node .n-chip.st-done::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; flex: none;
}
.node .n-chip.st-todo::before  { box-shadow: inset 0 0 0 1.5px currentColor; opacity: .7; }
.node .n-chip.st-doing::before { background: #E8A317; }
.node .n-chip.st-done::before  { background: #2E9E5B; }
.node .n-chip svg { width: 11px; height: 11px; }
.node mark { background: var(--nf-find-mark); color: inherit; border-radius: 3px; padding: 0 1px; }

/* ── Наведение ── */
@media (hover: hover) {
  .node:not(.is-locked):not(.selected):hover { transform: var(--nf-hover-shift); }
  .node.lv-1:not(.is-locked):not(.selected):hover { box-shadow: var(--nf-n1-shadow-hover); }
  .node.lv-2:not(.is-locked):not(.selected):hover { box-shadow: var(--nf-n2-shadow-hover); }
}

/* ── Рамка состояний: отдельный слой ::before вокруг ноды.
   Он лежит на холсте (зазор 5 px), поэтому виден на любой заливке ноды,
   в том числе на пользовательских цветах. Скругление повторяет форму. ── */
.node::before {
  content: ""; position: absolute; inset: -6px; pointer-events: none;
  border-radius: inherit; border: 0 solid transparent;
  opacity: 0; transition: opacity var(--nf-dur) var(--nf-ease);
}
.node.lv-0::before { border-radius: calc(var(--nf-r0) + 6px); }
.node.lv-1::before { border-radius: calc(var(--nf-r1) + 6px); }
.node.lv-2::before { border-radius: calc(var(--nf-r2) + 6px); }

/* выбрана: сплошная рамка 3 px + тонкий контур-разделитель */
.node.selected::before {
  opacity: 1; inset: -8px; border-width: 4px; border-color: var(--nf-sel);
  box-shadow: 0 0 0 1.5px var(--nf-sel-line), inset 0 0 0 1.5px var(--nf-sel-line), var(--nf-sel-glow);
}
/* поиск: совпадение — пунктир, текущее — сплошная + метка в тексте */
.node.search-match::before { opacity: 1; border-width: 2px; border-style: dashed; border-color: var(--nf-find); }
.node.search-active::before { opacity: 1; border-width: 3px; border-style: solid; border-color: var(--nf-find); box-shadow: 0 0 0 4px color-mix(in srgb, var(--nf-find) 22%, transparent); }
/* связь: источник — пунктир, цель под курсором — сплошная */
.node.linking-source::before { opacity: 1; border-width: 2px; border-style: dashed; border-color: var(--nf-link); }
.node.link-target::before { opacity: 1; border-width: 3px; border-color: var(--nf-link-target); }
body.is-linking .node:not(.linking-source) { cursor: crosshair; }
/* редактирование текста: та же рамка, что у выбранной, но тоньше */
.node.is-editing::before { opacity: 1; border-width: 2px; border-color: var(--nf-sel); box-shadow: 0 0 0 1.5px var(--nf-sel-line); }
.node.is-editing { cursor: text; }
.node.is-editing .n-sel { background: color-mix(in srgb, var(--nf-focus) 28%, transparent); border-radius: 2px; }
.node.is-editing .n-caret { display: inline-block; width: 1.5px; height: 1.05em; margin-left: 1px; vertical-align: -2px; background: currentColor; animation: nf-caret 1s steps(1) infinite; }
@keyframes nf-caret { 50% { opacity: 0; } }

/* ── Бейджи: закреплена / заблокирована ── */
.node .n-badge {
  position: absolute; top: -10px; right: -10px; z-index: 2;
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--nf-badge-bg); color: var(--nf-badge-fg);
  box-shadow: 0 0 0 1.5px var(--nf-badge-line);
}
.node .n-badge svg { width: 12px; height: 12px; stroke-width: 2.2; }
.node .n-badge + .n-badge { right: 16px; }
.node.is-locked { cursor: default; }
.node.is-locked .n-title, .node.is-locked .n-text { user-select: none; }

/* ── Свёрнутая ветка: кнопка «+N» на стороне, куда растёт ветка ── */
.node .n-fold {
  position: absolute; top: 50%; right: -15px; transform: translateY(-50%); z-index: 2;
  min-width: 30px; height: 24px; padding: 0 7px; border-radius: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  font: 600 11.5px/1 var(--nf-font-mono); cursor: pointer;
  background: var(--nf-badge-bg); color: var(--nf-badge-fg);
  border: 0; box-shadow: 0 0 0 1.5px var(--nf-badge-line);
}
.node.fold-left .n-fold { right: auto; left: -15px; }
.node.fold-down .n-fold { top: auto; bottom: -13px; right: 50%; transform: translateX(50%); }
.node .n-fold:focus-visible { outline: 2px solid var(--nf-focus); outline-offset: 2px; }
/* стопка за свёрнутой нодой — только линия, без заливки (не трогает пользовательский цвет) */
.node.is-collapsed::after {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  transform: translate(5px, 5px);
  box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--nf-ink) 35%, transparent);
  background: var(--nf-paper);
}
.node.fold-left.is-collapsed::after { transform: translate(-5px, 5px); }

/* ═══ Формы ═══ */
.node.shape-capsule { border-radius: 999px !important; padding-inline: 22px; }
.node.shape-capsule::before { border-radius: 999px !important; }

.node.shape-circle, .node.shape-oval {
  display: grid; place-content: center; text-align: center;
  border-radius: 50% !important; padding: 18px;
}
.node.shape-circle { aspect-ratio: 1; }
.node.shape-oval { padding: 18px 30px; }
.node.shape-circle::before, .node.shape-oval::before { border-radius: 50% !important; }

.node.shape-cloud {
  border-radius: 48% 52% 45% 55% / 58% 50% 50% 42% !important;
  padding: 20px 26px; text-align: center;
}
.node.shape-cloud::before { border-radius: 48% 52% 45% 55% / 58% 50% 50% 42% !important; }

.node.shape-sticky {
  border-radius: 3px 3px 3px 3px !important;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 18px), calc(100% - 18px) 100%, 0 100%);
  box-shadow: none !important; padding-bottom: 20px;
}
.node.shape-sticky.df-bg { background: var(--nf-sticky-bg); }
/* загнутый уголок */
.node.shape-sticky > .n-curl {
  position: absolute; right: 0; bottom: 0; width: 18px; height: 18px;
  background: linear-gradient(135deg, color-mix(in srgb, currentColor 22%, transparent) 50%, transparent 50%);
}
/* у стикера рамка состояний рисуется обёрткой .node-wrap (clip-path обрезает ::before) —
   в прототипе это .shape-sticky-wrap; см. spec.md §3.4 */
.shape-sticky-wrap { position: absolute; }
.shape-sticky-wrap > .node { position: relative; left: 0 !important; top: 0 !important; }
.shape-sticky-wrap::before {
  content: ""; position: absolute; inset: -6px; border-radius: 9px; pointer-events: none; opacity: 0;
}
.shape-sticky-wrap.selected::before { opacity: 1; border: 3px solid var(--nf-sel); box-shadow: 0 0 0 1.5px var(--nf-sel-line), inset 0 0 0 1.5px var(--nf-sel-line); }
.shape-sticky-wrap { filter: drop-shadow(2px 3px 0 color-mix(in srgb, var(--nf-ink) 18%, transparent)); }

/* ═══ Линии связей (SVG) ═══ */
.nf-edge { fill: none; stroke-linecap: round; }
.nf-edge.e1 { stroke: var(--nf-edge-1); stroke-width: var(--nf-edge-w1); }
.nf-edge.e2 { stroke: var(--nf-edge-2); stroke-width: var(--nf-edge-w2); }
.nf-edge.e-link { stroke: var(--nf-link); stroke-width: 2px; stroke-dasharray: 6 6; }

/* ═══ Теме — свои мелочи ═══ */
body.theme-netfold .node.lv-2 .n-chip { background: rgba(22,24,29,.06); }
body.theme-midnight .node .n-chip { background: rgba(110,231,255,.08); }
body.theme-midnight .node.lv-0 .n-chip { background: rgba(4,32,42,.12); }
body.theme-lagoon .node.lv-0.df-bg { background-image: linear-gradient(135deg, #0F7489, #1B94AD); }
