/* =========================================================================
 * MY MAP · Design System
 * Patterns extracted from /apps/planning-studio/relationship-graph/index.html
 * Token, layer, blur, shadow и color decisions воспроизводят основное приложение,
 * чтобы новые сценарии можно было собирать копированием готовых паттернов.
 * ========================================================================= */

*, *::before, *::after {
  box-sizing: border-box;
}

:root {
  --bg-a: #f0ece4;
  --bg-b: #e8e4dc;
  --text: #292b2d;
  --muted: #6b7280;
  --glass-bg: rgba(255, 255, 255, 0.46);
  --glass-strong: rgba(255, 255, 255, 0.76);
  --glass-border: rgba(255, 255, 255, 0.68);
  --shadow: rgba(24, 31, 39, 0.09);
  --shadow-strong: rgba(24, 31, 39, 0.18);
  --line: rgba(79, 88, 99, 0.18);
  --shell: rgba(255, 255, 255, 0.44);
  --shell-strong: rgba(255, 255, 255, 0.78);
  --lens: rgba(255, 255, 255, 0.18);
  --panel: rgba(255, 255, 255, 0.72);
  --panel-strong: rgba(255, 255, 255, 0.90);
  --node-color: #3a6ab5;
  --halo-rgb: 120, 160, 220;
  /* 3D edge-линии на сфере (level1-app.js rebuildEdges) рисуются
     THREE.Points с AdditiveBlending — на светлом фоне аддитивное смешение
     почти не даёт контраста (белый + свет ≈ белый), поэтому светлая тема
     переключается на normal blending и требует более высокой opacity. */
  --edge-line-opacity: 0.85;
  --accent-day: #ff6b57;
  --accent-week: #f3a43b;
  --accent-month: #8d67f7;
  --accent-year: #4f7cff;
  --accent-three: #2aa7ff;
  --accent-long: #22b8a8;
  --accent-motive: #39c77f;

  font-family: "Space Grotesk", Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

body.dark {
  --bg-a: #171929;
  --bg-b: #111827;
  --text: #eceff1;
  --muted: #a2aab4;
  --glass-bg: rgba(26, 30, 48, 0.50);
  --glass-strong: rgba(32, 37, 58, 0.80);
  --glass-border: rgba(255, 255, 255, 0.15);
  --shadow: rgba(0, 0, 0, 0.34);
  --shadow-strong: rgba(0, 0, 0, 0.48);
  --line: rgba(231, 236, 242, 0.14);
  --shell: rgba(255, 255, 255, 0.12);
  --shell-strong: rgba(255, 255, 255, 0.24);
  --lens: rgba(255, 255, 255, 0.08);
  --panel: rgba(29, 35, 54, 0.72);
  --panel-strong: rgba(37, 45, 66, 0.92);
  --node-color: #8da4d6;
  --edge-line-opacity: 0.5;
}

html {
  scroll-behavior: smooth;
}

body {
  min-height: 100vh;
  margin: 0;
  color: var(--text);
  background: linear-gradient(135deg, var(--bg-a), var(--bg-b));
  letter-spacing: 0;
  transition: background 420ms ease, color 420ms ease;
}

button,
input {
  font: inherit;
}

button {
  color: inherit;
  cursor: pointer;
}

code {
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ------------------------------------------------------------------------ */
/* Shell & layout                                                            */
/* ------------------------------------------------------------------------ */

.ds-shell {
  width: min(1280px, calc(100vw - 32px));
  margin: 0 auto;
  padding: 16px 0 60px;
}

.surface {
  position: relative;
  isolation: isolate;
  border-radius: 20px;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  box-shadow: 0 14px 40px var(--shadow);
  backdrop-filter: blur(22px) saturate(1.18);
  -webkit-backdrop-filter: blur(22px) saturate(1.18);
}

.ds-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 14px;
  align-items: end;
  padding: 16px 18px;
  margin-bottom: 16px;
}

.hero-copy {
  display: grid;
  gap: 12px;
}

.hero-kicker {
  position: relative;
  width: fit-content;
  padding-left: 16px;
  margin: 0;
  color: color-mix(in srgb, var(--text) 64%, transparent);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.hero-kicker::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  transform: translateY(-50%);
  opacity: 0.84;
}

h1.hero-title {
  margin: 0;
  font-size: clamp(34px, 4.6vw, 56px);
  font-weight: 740;
  line-height: 0.94;
  letter-spacing: -0.045em;
}

.hero-lead {
  max-width: 540px;
  margin: 0;
  color: color-mix(in srgb, var(--text) 70%, transparent);
  font-size: clamp(13px, 1.1vw, 15px);
  line-height: 1.38;
  letter-spacing: -0.015em;
}

.theme-switcher {
  display: flex;
  align-self: start;
  gap: 4px;
  padding: 4px;
  border-radius: 14px;
}

.theme-radio {
  position: fixed;
  opacity: 0;
  pointer-events: none;
}

.theme-switcher label {
  min-width: 64px;
  padding: 8px 12px;
  border-radius: 10px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-align: center;
  text-transform: uppercase;
}

body:has(#theme-light:checked) label[for="theme-light"],
body:has(#theme-dark:checked) label[for="theme-dark"] {
  background: var(--panel);
  color: var(--text);
  box-shadow: 0 6px 18px var(--shadow);
}

.ds-nav {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px;
  border-radius: 14px;
}

.ds-nav a {
  padding: 8px 12px;
  border-radius: 10px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-decoration: none;
  text-transform: uppercase;
  transition: background 180ms ease, color 180ms ease;
}

.ds-nav a:hover {
  background: var(--shell);
  color: var(--text);
}

/* ------------------------------------------------------------------------ */
/* Sections + cards                                                          */
/* ------------------------------------------------------------------------ */

.section {
  margin-top: 16px;
  padding: 16px;
  border-radius: 22px;
}

.section-header {
  display: grid;
  grid-template-columns: minmax(0, 0.6fr) minmax(280px, 0.5fr);
  gap: 18px;
  align-items: end;
  padding: 14px 16px;
  margin-bottom: 10px;
  border-radius: 16px;
}

.section-kicker {
  grid-column: 1 / -1;
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.section-header h2 {
  margin: 0;
  font-size: clamp(28px, 3.6vw, 48px);
  font-weight: 740;
  line-height: 0.96;
  letter-spacing: -0.04em;
}

.section-header p {
  margin: 0;
  color: color-mix(in srgb, var(--text) 70%, transparent);
  font-size: clamp(13px, 1.1vw, 15px);
  line-height: 1.36;
}

.grid {
  display: grid;
  /* Дефолт — 2 колонки (по 2 карточки в строке). */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

/* Modifier'ы оставлены на случай явного переопределения секции,
   но дефолт теперь 2 колонки. */
.grid--two   { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--four  { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.card {
  display: grid;
  gap: 10px;
  align-content: start;
  padding: 14px;
  border-radius: 16px;
}

/* По умолчанию все карточки в строке по 2 (одной ширины); card--wide/card--full
   нейтрализованы (см. правило 2-per-row). */
.card--wide,
.card--full { grid-column: auto; }
/* Исключение: интерактивные flow-карточки с камерой и spatial detail
   (vertex-create) требуют горизонтального простора как в production viewport,
   иначе detail-панель не помещается рядом с вершиной. Помечаем .card--row. */
.card--row { grid-column: 1 / -1; }

/* Split layout — каждая карточка делится вертикально:
   сверху ДЕМО (.card__demo), снизу controls + facts (.card__info). */
.card--split {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "meta" "title" "demo" "info";
  gap: 12px;
  align-items: start;
}
.card--split > .card-meta  { grid-area: meta; }
.card--split > h3          { grid-area: title; }
.card--split > .card__demo { grid-area: demo; display: grid; gap: 10px; align-content: start; min-width: 0; }
.card--split > .card__info { grid-area: info; display: grid; gap: 12px; align-content: start; min-width: 0; }

.card-meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

.card-meta .tag {
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.card-meta code {
  color: color-mix(in srgb, var(--text) 80%, transparent);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: -0.01em;
}

.card h3 {
  margin: 0;
  font-size: 22px;
  font-weight: 740;
  line-height: 1.06;
  letter-spacing: -0.025em;
}

.facts {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
}

/* ------------------------------------------------------------------------ */
/* Live controls panel — drives CSS-vars on a target via [data-css-var]       */
/* ------------------------------------------------------------------------ */

.mol-controls {
  display: grid;
  gap: 6px;
  padding: 12px;
  margin: 0;
  border-radius: 12px;
  background: color-mix(in srgb, var(--shell), var(--text) 4%);
  border: 1px solid var(--line);
  font-size: 11px;
}

.mol-controls__title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: 0 0 4px;
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.mol-controls__title small {
  color: color-mix(in srgb, var(--text) 50%, transparent);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: -0.02em;
  text-transform: none;
}

.mol-controls__row {
  display: grid;
  grid-template-columns: minmax(0, 0.42fr) minmax(0, 1fr) 44px;
  align-items: center;
  gap: 10px;
}

.mol-controls__row code {
  color: color-mix(in srgb, var(--text) 78%, transparent);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 10px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mol-controls__row output {
  color: color-mix(in srgb, var(--text) 64%, transparent);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 10px;
  text-align: right;
}

.mol-controls input[type="range"] {
  width: 100%;
  accent-color: var(--accent-year, #4f7cff);
}

.mol-controls input[type="color"] {
  width: 32px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
}

.mol-controls input[type="text"],
.mol-controls select {
  width: 100%;
  height: 26px;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--shell);
  color: var(--text);
  font-family: inherit;
  font-size: 11px;
}

.mol-controls label.mol-controls__toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  grid-column: 1 / -1;
  color: color-mix(in srgb, var(--text) 78%, transparent);
}

.mol-controls input[type="checkbox"] {
  accent-color: var(--accent-year, #4f7cff);
}

.facts > div {
  display: grid;
  grid-template-columns: 60px minmax(0, 1fr);
  gap: 8px;
  padding: 0;
}

.facts dt {
  margin: 0;
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.facts dd {
  margin: 0;
  color: color-mix(in srgb, var(--text) 76%, transparent);
  font-size: 12px;
  line-height: 1.36;
}

.facts dd code {
  color: var(--text);
  font-size: 10px;
}

/* ------------------------------------------------------------------------ */
/* Demo stage — тёплый фон-сцена с radial-glow и grain                        */
/* ------------------------------------------------------------------------ */

.stage {
  position: relative;
  min-height: 168px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(135deg, var(--bg-a), var(--bg-b));
}

.stage::before {
  content: "";
  position: absolute;
  inset: -10%;
  background:
    radial-gradient(circle at 24% 30%, color-mix(in srgb, var(--node-color), transparent 78%), transparent 36%),
    radial-gradient(circle at 78% 64%, color-mix(in srgb, var(--accent-day), transparent 82%), transparent 42%),
    radial-gradient(circle at 50% 84%, color-mix(in srgb, var(--accent-motive), transparent 86%), transparent 40%);
  filter: blur(38px);
  opacity: 0.68;
  pointer-events: none;
}

.stage::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
    circle,
    color-mix(in srgb, var(--text) 30%, transparent) 0 1px,
    transparent 1.5px
  );
  background-size: 64px 64px;
  opacity: 0.18;
  mix-blend-mode: overlay;
  pointer-events: none;
}

.stage--tall {
  min-height: 240px;
}

.stage--center {
  display: grid;
  place-items: center;
  padding: 22px;
}

/* ------------------------------------------------------------------------ */
/* Foundations demos                                                         */
/* ------------------------------------------------------------------------ */

.tokens-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}

.token-chip {
  display: grid;
  gap: 6px;
  padding: 10px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--shell);
}

.token-swatch {
  height: 42px;
  border-radius: 8px;
  background: var(--swatch, #fff);
  border: 1px solid var(--line);
  box-shadow: inset 0 0 12px rgba(0, 0, 0, 0.08);
}

.token-chip strong {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0;
}

.token-chip span {
  color: var(--muted);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: -0.02em;
}

.type-stack {
  display: grid;
  gap: 10px;
}

.type-row {
  display: grid;
  gap: 4px;
  padding: 10px 0;
  border-bottom: 1px dashed var(--line);
}

.type-row:last-child {
  border-bottom: 0;
}

.type-row .meta {
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.type-row .display {
  font-size: 38px;
  font-weight: 740;
  line-height: 0.94;
  letter-spacing: -0.05em;
}

.type-row .heading {
  font-size: 22px;
  font-weight: 740;
  line-height: 1.06;
  letter-spacing: -0.025em;
}

.type-row .body {
  font-size: 16px;
  line-height: 1.42;
}

.type-row .small-meta {
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0.06em;
}

.layer-stack {
  display: grid;
  gap: 4px;
}

.layer-row {
  display: grid;
  grid-template-columns: 28px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 10px;
  background: var(--shell);
  border: 1px solid var(--line);
  font-size: 12px;
}

.layer-row strong {
  font-weight: 700;
  letter-spacing: -0.01em;
}

.layer-row code {
  color: var(--muted);
  font-size: 10px;
}

.layer-row .z {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  font-weight: 700;
  text-align: center;
  color: var(--muted);
}

.state-flags {
  display: grid;
  gap: 6px;
}

.state-row {
  display: grid;
  grid-template-columns: minmax(0, 0.4fr) minmax(0, 1fr);
  gap: 12px;
  padding: 10px;
  border-radius: 10px;
  background: var(--shell);
  border: 1px solid var(--line);
  font-size: 12px;
  line-height: 1.35;
}

.state-row code {
  color: var(--text);
  font-size: 11px;
}

.state-row span {
  color: var(--muted);
}

/* ========================================================================= */
/* ATOMS — abstract reusable primitives.                                      */
/* Each atom is parametrised through CSS variables; specific use-cases live   */
/* in molecules / organisms.                                                  */
/* ========================================================================= */

/* ------------------------------------------------------------------------ */
/* Atom: Dot — point/circle primitive (replaces particle / core / star)      */
/* ------------------------------------------------------------------------ */

.atom-dot {
  --dot-size: 7px;
  --dot-color: currentColor;
  --dot-alpha: 1;
  --dot-glow-radius: 0px;
  --dot-glow-alpha: 0.6;
  --dot-glow-radius-2: 0px;
  --dot-glow-alpha-2: 0;
  display: inline-block;
  width: var(--dot-size);
  height: var(--dot-size);
  border-radius: 999px;
  background: var(--dot-color);
  opacity: var(--dot-alpha);
  box-shadow:
    0 0 var(--dot-glow-radius)   color-mix(in srgb, var(--dot-color), transparent calc((1 - var(--dot-glow-alpha))   * 100%)),
    0 0 var(--dot-glow-radius-2) color-mix(in srgb, var(--dot-color), transparent calc((1 - var(--dot-glow-alpha-2)) * 100%));
  pointer-events: none;
}

/* Functional variants — configure CSS-vars only, not new shapes. */
.atom-dot--marker    { --dot-size: 7px;  --dot-glow-radius: 0;    --dot-glow-alpha: 0; }
.atom-dot--bullet    { --dot-size: 8px;  --dot-glow-radius: 14px; --dot-glow-alpha: 0.36; }

/* Node core variant — picks up node colour from --halo-rgb (sphere mesh DOM mirror). */
.atom-dot--node-core {
  --dot-size: var(--core-size, 12px);
  --dot-color: rgb(var(--halo-rgb, 120, 160, 220));
  --dot-glow-radius: 14px;
  --dot-glow-alpha: 0.7;
}

/* Particle variant — picks up legacy --particle-* tokens. */
.atom-dot--particle {
  --dot-size:  var(--particle-size,  2.4px);
  --dot-alpha: var(--particle-alpha, 0.42);
  --dot-color: color-mix(in srgb, var(--particle-accent, var(--accent-year)), transparent 10%);
  --dot-glow-radius:   7px;
  --dot-glow-alpha:    0.58;
  --dot-glow-radius-2: 16px;
  --dot-glow-alpha-2:  0.24;
  --dot-glow-color:   var(--particle-accent, var(--accent-year));
}

/* Star variant — picks up legacy --s/--c/--a/--g tokens. */
.atom-dot--star {
  --dot-size:  var(--s, 1.8px);
  --dot-alpha: var(--a, 0.7);
  --dot-color: rgb(var(--c, 255, 255, 255));
  --dot-glow-radius: var(--g, 4px);
  --dot-glow-alpha:  0.36;
}

.atom-dot--planet {
  --dot-size: 36px;
  --dot-glow-radius: 38px;
  --dot-glow-alpha:  0.42;
  --dot-glow-radius-2: 90px;
  --dot-glow-alpha-2:  0.18;
}

/* Convenience size attributes for inline use without per-element style. */
.atom-dot[data-size="sm"] { --dot-size: 1.6px; }
.atom-dot[data-size="md"] { --dot-size: 4px;   --dot-alpha: 0.62; --particle-size: 4px;   --particle-alpha: 0.62; }
.atom-dot[data-size="lg"] { --dot-size: 7px;   --dot-alpha: 0.86; --particle-size: 7px;   --particle-alpha: 0.86; }

/* ------------------------------------------------------------------------ */
/* Legacy aliases — старые class-имена ссылаются на новые atoms/molecules.   */
/* TODO: удалить после полного rewrite HTML showcase cards.                  */
/* ------------------------------------------------------------------------ */

.atom-kicker { /* alias for mol-label-with-meta--kicker primary style */
  position: relative;
  width: fit-content;
  padding-left: 16px;
  color: color-mix(in srgb, currentColor 64%, transparent);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.atom-kicker::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  transform: translateY(-50%);
  opacity: 0.84;
}

.atom-tag { /* alias for mol-tag-row__tag */
  --tag-color: var(--node-color, var(--accent-day));
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--tag-color);
  font-size: 10px;
  font-weight: 720;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.atom-tag::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 14px currentColor;
}

.atom-status { /* alias for mol-tag-row__status */
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: color-mix(in srgb, var(--text), var(--tag-color, var(--accent-day)) 42%);
  font-size: 10px;
  font-weight: 720;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.atom-status::before {
  content: "·";
  color: color-mix(in srgb, var(--tag-color, var(--accent-day)), transparent 20%);
  font-size: 18px;
  line-height: 0;
  margin-right: -2px;
}

.atom-title-display { /* alias for mol-text-with-glow--display */
  margin: 0;
  font-size: clamp(38px, 5vw, 58px);
  font-weight: 690;
  line-height: 0.92;
  letter-spacing: -0.045em;
  max-width: min(12ch, 100%);
  text-shadow:
    0 0 34px rgba(255, 255, 255, 0.46),
    0 0 14px rgba(255, 255, 255, 0.28),
    0 1px 0 rgba(255, 255, 255, 0.24);
}
body.dark .atom-title-display,
.org-detail-stage .atom-title-display {
  text-shadow:
    0 0 34px rgba(0, 0, 0, 0.55),
    0 0 14px rgba(0, 0, 0, 0.40),
    0 1px 0 rgba(255, 255, 255, 0.10);
}

.atom-intent { /* alias for mol-text-with-glow--body */
  margin: 0;
  color: color-mix(in srgb, var(--text), white 18%);
  font-size: 17px;
  line-height: 1.34;
  max-width: 28ch;
  text-shadow:
    0 0 22px rgba(255, 255, 255, 0.30),
    0 0 10px rgba(255, 255, 255, 0.18);
}
body.dark .atom-intent,
.org-detail-stage .atom-intent {
  color: color-mix(in srgb, var(--text), white 4%);
  text-shadow:
    0 0 22px rgba(0, 0, 0, 0.5),
    0 0 10px rgba(0, 0, 0, 0.3);
}

/* ------------------------------------------------------------------------ */
/* Atom: Icon — single unicode/SVG icon (incl. animated states)              */
/* ------------------------------------------------------------------------ */

.atom-icon {
  --icon-size: 22px;
  --icon-color: currentColor;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-size);
  height: var(--icon-size);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: var(--icon-size);
  line-height: 1;
  color: var(--icon-color);
  user-select: none;
}

.atom-icon--xs { --icon-size: 12px; }
.atom-icon--sm { --icon-size: 16px; }
.atom-icon--md { --icon-size: 22px; }
.atom-icon--lg { --icon-size: 28px; }

/* Animated bars variant — same atom-icon, different render via ::before children */
.atom-icon[data-animated="bars"] {
  width: 16px;
  height: 14px;
  position: relative;
  font-size: 0;
}
.atom-icon[data-animated="bars"]::before,
.atom-icon[data-animated="bars"]::after,
.atom-icon[data-animated="bars"] > span {
  content: "";
  position: absolute;
  bottom: 0;
  width: 2.5px;
  background: currentColor;
  border-radius: 1px;
  animation: animatedBars 0.9s ease-in-out infinite alternate;
}
.atom-icon[data-animated="bars"]::before { left: 0;   animation-delay: 0s; }
.atom-icon[data-animated="bars"] > span:nth-child(1) { left: 4px;  animation-delay: 0.15s; }
.atom-icon[data-animated="bars"] > span:nth-child(2) { left: 8px;  animation-delay: 0.3s;  }
.atom-icon[data-animated="bars"]::after  { right: 0;  animation-delay: 0.1s; }

.atom-icon[data-animated="bars"][data-state="paused"]::before,
.atom-icon[data-animated="bars"][data-state="paused"]::after,
.atom-icon[data-animated="bars"][data-state="paused"] > span {
  animation-play-state: paused;
  height: 5px !important;
}

@keyframes animatedBars {
  0%   { height: 3px;  }
  100% { height: 13px; }
}

/* ------------------------------------------------------------------------ */
/* Atom: Button — base interactive primitive (replaces glass-button / pill)  */
/* ------------------------------------------------------------------------ */

/* Spatial-default: plain text button — no border, no background, no glass.
   16px / 620 / 0.04em / uppercase, color slightly muted (0.82 of text).
   Modifiers (--halo, --pill) меняют форму/фон/размер. */
.atom-button {
  --btn-color: color-mix(in srgb, var(--text), transparent 18%);
  --btn-padding-x: 0;
  --btn-min-height: 32px;
  --btn-radius: 0;
  --btn-font-size: 16px;
  --btn-font-weight: 620;
  --btn-letter-spacing: 0.04em;
  --btn-text-transform: uppercase;
  --btn-bg: transparent;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: var(--btn-min-height);
  padding: 0 var(--btn-padding-x);
  border: 0;
  border-radius: var(--btn-radius);
  background: var(--btn-bg);
  color: var(--btn-color);
  font-family: inherit;
  font-size: var(--btn-font-size);
  font-weight: var(--btn-font-weight);
  letter-spacing: var(--btn-letter-spacing);
  text-transform: var(--btn-text-transform);
  white-space: nowrap;
  cursor: pointer;
  isolation: isolate;
  transition: transform 180ms ease, color 180ms ease, background 180ms ease, letter-spacing 180ms ease;
}

.atom-button:hover { color: var(--text); }

/* Shape variants — change padding/case, not the underlying button. */
.atom-button--pill {
  --btn-min-height: 30px;
  --btn-padding-x: 14px;
  --btn-radius: 16px;
  --btn-font-size: 14px;
  --btn-font-weight: 500;
  --btn-letter-spacing: 0.01em;
  --btn-text-transform: none;
  --btn-color: var(--muted);
}
.atom-button--text {
  --btn-bg: transparent;
}

/* Modifier: halo backdrop (added via ::before, no new class layout). */
.atom-button--halo::before {
  content: "";
  position: absolute;
  inset: -10px -16px;
  z-index: -1;
  border-radius: 999px;
  background: radial-gradient(
    ellipse 92% 78% at 34% 50%,
    rgba(255, 245, 232, 0.46) 0%,
    rgba(196, 220, 255, 0.18) 34%,
    transparent 82%
  );
  filter: blur(22px);
  opacity: 0.72;
  pointer-events: none;
  transition: opacity 180ms ease;
}
body.dark .atom-button--halo::before {
  background: radial-gradient(
    ellipse 92% 78% at 34% 50%,
    rgba(122, 150, 220, 0.20) 0%,
    rgba(62, 78, 124, 0.12) 34%,
    transparent 82%
  );
}
.atom-button--halo:hover { transform: translateX(2px); }
.atom-button--halo:hover::before,
.atom-button--halo.is-active::before { opacity: 1; }

.atom-button--pill:hover     { color: color-mix(in srgb, var(--btn-color) 72%, var(--text)); }
.atom-button--pill.is-active { color: var(--text); font-weight: 700; }

/* Leading marker (atom-dot--bullet) inside a button — animates with hover. */
.atom-button > .atom-dot--bullet {
  --dot-size: 6px;
  --dot-glow-radius: 12px;
  --dot-glow-alpha:  0.32;
  opacity: 0.82;
  transform: scale(0.82);
  transition: transform 180ms ease, opacity 180ms ease;
}
.atom-button:hover > .atom-dot--bullet,
.atom-button.is-active > .atom-dot--bullet { opacity: 1; transform: scale(1); }

/* Leading icon inside a button — same animation pattern. */
.atom-button > .atom-icon {
  --icon-size: 14px;
  opacity: 0.82;
  transition: opacity 180ms ease, transform 180ms ease;
}
.atom-button:hover > .atom-icon,
.atom-button.is-active > .atom-icon { opacity: 1; }

/* Layout helper for groups of buttons — no styling, just wrap+gap. */
.button-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

/* ------------------------------------------------------------------------ */
/* Atom: Input — single line text input primitive                            */
/* ------------------------------------------------------------------------ */

.atom-input {
  --input-color: var(--text);
  --input-line: color-mix(in srgb, var(--text) 24%, transparent);
  --input-line-focus: color-mix(in srgb, var(--text) 48%, transparent);
  width: 100%;
  min-height: 38px;
  padding: 0 28px 0 0;
  border: 0;
  border-bottom: 1px solid var(--input-line);
  outline: none;
  background: transparent;
  color: var(--input-color);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  transition: border-color 180ms ease;
}

.atom-input::placeholder {
  color: color-mix(in srgb, var(--text) 48%, transparent);
}

.atom-input:focus {
  border-bottom-color: var(--input-line-focus);
}

/* ------------------------------------------------------------------------ */
/* Atom: Separator — symbol or line                                          */
/* ------------------------------------------------------------------------ */

.atom-separator {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  line-height: 0;
  color: color-mix(in srgb, currentColor, transparent 20%);
}

.atom-separator--dot::before  { content: "·"; }
.atom-separator--bull::before { content: "•"; font-size: 12px; }
.atom-separator--line {
  display: block;
  width: 100%;
  height: 1px;
  background: color-mix(in srgb, currentColor, transparent 70%);
}

/* ------------------------------------------------------------------------ */
/* Glyph grid: layout helper for icon catalogues                              */
/* ------------------------------------------------------------------------ */

.glyph-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}

.glyph-card {
  display: grid;
  place-items: center;
  gap: 4px;
  padding: 12px 8px;
  border-radius: 10px;
  background: var(--shell);
  border: 1px solid var(--line);
  text-align: center;
}

.glyph-card span {
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 0.06em;
}

/* ------------------------------------------------------------------------ */
/* Atom: Noise canvas — WebGL fullscreen noise shader (#glBg)                */
/* ------------------------------------------------------------------------ */

.atom-noise-canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* ------------------------------------------------------------------------ */
/* Atom: Grain — KOTA-style film noise (rand uv·res + t)                     */
/* ------------------------------------------------------------------------ */

.atom-grain-stage {
  position: relative;
  min-height: 240px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(135deg, var(--bg-a), var(--bg-b));
}

.atom-grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: overlay;
  opacity: 0.55;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence baseFrequency='2.4' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.6 -0.8'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 240px 240px;
}

body.dark .atom-grain {
  opacity: 0.4;
  mix-blend-mode: screen;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence baseFrequency='2.4' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.95 0 0 0 0 0.96 0 0 0 0 1 0 0 0 1.4 -0.65'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

.atom-grain-meta {
  position: absolute;
  left: 14px;
  bottom: 12px;
  display: grid;
  gap: 4px;
  z-index: 1;
  pointer-events: none;
}

.atom-grain-meta .kicker {
  position: relative;
  padding-left: 14px;
  color: color-mix(in srgb, var(--text) 80%, transparent);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.atom-grain-meta .kicker::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  transform: translateY(-50%);
  opacity: 0.7;
}

.atom-grain-meta .hint {
  color: color-mix(in srgb, var(--text) 60%, transparent);
  font-size: 11px;
  letter-spacing: -0.01em;
}

/* ------------------------------------------------------------------------ */
/* Molecule: Floating background — composes atoms (HTML inclusion only)      */
/*   <atom-noise-canvas> + <atom-halo> × N + <atom-grain> + <atom-star> × N  */
/* ------------------------------------------------------------------------ */

.mol-floating-stage {
  position: relative;
  min-height: 520px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
}

/* Each layer is just a positioning wrapper — atoms style themselves. */
.mol-floating-stage > .atom-noise-canvas { position: absolute; inset: 0; z-index: 0; }
.mol-floating-stage > .atom-grain        { position: absolute; inset: 0; z-index: 1; }
.mol-floating-stage > .mol-floating-halos{ position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.mol-floating-stage > .mol-floating-stars{ position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.mol-floating-stage > .mol-floating-meta { position: absolute; left: 14px; bottom: 12px; z-index: 4; pointer-events: none; }

/* Halos slot: positions the .atom-halo children and applies the screen blend. */
.mol-floating-halos {
  mix-blend-mode: screen;
}
.mol-floating-halos .atom-halo {
  position: absolute;
  margin: 0;
  filter: blur(26px) saturate(1.05);
}

/* Stars slot: scatters .atom-star children as `position: absolute`. */
.mol-floating-stars .atom-dot {
  position: absolute;
}

.mol-floating-meta {
  position: absolute;
  left: 14px;
  bottom: 12px;
  display: grid;
  gap: 4px;
  z-index: 3;
  pointer-events: none;
}

.mol-floating-meta .kicker {
  position: relative;
  padding-left: 14px;
  color: color-mix(in srgb, var(--text) 80%, transparent);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-shadow: 0 0 12px rgba(255, 255, 255, 0.4);
}

.mol-floating-meta .kicker::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  transform: translateY(-50%);
  opacity: 0.7;
}

.mol-floating-meta .hint {
  color: color-mix(in srgb, var(--text) 70%, transparent);
  font-size: 11px;
  letter-spacing: -0.01em;
  text-shadow: 0 0 12px rgba(255, 255, 255, 0.4);
}

body.dark .mol-floating-meta .kicker,
body.dark .mol-floating-meta .hint {
  text-shadow: 0 0 12px rgba(0, 0, 0, 0.5);
}

.mol-floating-recipe {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}

.mol-floating-recipe-cell {
  display: grid;
  gap: 6px;
  padding: 12px;
  border-radius: 10px;
  background: var(--shell);
  border: 1px solid var(--line);
}

.mol-floating-recipe-cell .label {
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.mol-floating-recipe-cell .name {
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.mol-floating-recipe-cell code {
  color: color-mix(in srgb, var(--text) 70%, transparent);
  font-size: 10px;
}

.atom-floating-meta {
  position: absolute;
  left: 14px;
  bottom: 12px;
  display: grid;
  gap: 4px;
  z-index: 1;
  pointer-events: none;
}

.atom-floating-meta .kicker {
  position: relative;
  padding-left: 14px;
  color: color-mix(in srgb, var(--text) 80%, transparent);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-shadow: 0 0 12px rgba(255, 255, 255, 0.4);
}

.atom-floating-meta .kicker::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  transform: translateY(-50%);
  opacity: 0.7;
}

.atom-floating-meta .hint {
  color: color-mix(in srgb, var(--text) 70%, transparent);
  font-size: 11px;
  letter-spacing: -0.01em;
  text-shadow: 0 0 12px rgba(255, 255, 255, 0.4);
}

body.dark .atom-floating-meta .kicker,
body.dark .atom-floating-meta .hint {
  text-shadow: 0 0 12px rgba(0, 0, 0, 0.5);
}

.mol-particle-sphere-stage {
  position: relative;
  min-height: 280px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(135deg, var(--bg-a), var(--bg-b));
}

.mol-particle-sphere-stage::before {
  content: "";
  position: absolute;
  inset: -16%;
  background:
    radial-gradient(circle at 28% 36%, color-mix(in srgb, var(--accent-day), transparent 78%), transparent 38%),
    radial-gradient(circle at 78% 70%, color-mix(in srgb, var(--accent-year), transparent 80%), transparent 42%);
  filter: blur(48px);
  opacity: 0.45;
  pointer-events: none;
}

body.dark .mol-particle-sphere-stage::before {
  opacity: 0.22;
}

.mol-particle-sphere-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}

.mol-particle-sphere-stage-meta {
  position: absolute;
  left: 14px;
  bottom: 12px;
  display: grid;
  gap: 4px;
  z-index: 1;
  pointer-events: none;
}

.mol-particle-sphere-stage-meta .kicker {
  position: relative;
  padding-left: 14px;
  color: color-mix(in srgb, var(--text) 70%, transparent);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.mol-particle-sphere-stage-meta .kicker::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  transform: translateY(-50%);
  opacity: 0.7;
}

.mol-particle-sphere-stage-meta .hint {
  color: color-mix(in srgb, var(--text) 55%, transparent);
  font-size: 11px;
  letter-spacing: -0.01em;
}


/* ------------------------------------------------------------------------ */
/* Atom: Animations — keyframes catalog + transition tokens                  */
/* ------------------------------------------------------------------------ */

.atom-anim-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.atom-anim-card {
  position: relative;
  display: grid;
  gap: 8px;
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--shell);
  border: 1px solid var(--line);
  isolation: isolate;
}

.atom-anim-card .meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.atom-anim-card .meta code {
  color: color-mix(in srgb, var(--text) 84%, transparent);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-transform: none;
}

.atom-anim-card .preview {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 64px;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--bg-a), var(--bg-b));
  overflow: hidden;
}

.atom-anim-card .preview::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--accent-year), transparent 80%), transparent 70%);
  filter: blur(20px);
  opacity: 0.6;
  pointer-events: none;
}

.atom-anim-card .preview > * {
  position: relative;
  z-index: 1;
}

.atom-anim-music .bars {
  display: inline-flex;
  align-items: flex-end;
  gap: 3px;
  height: 16px;
}

.atom-anim-music .bars > span {
  width: 3px;
  background: var(--text);
  border-radius: 1px;
  animation: animatedBars 0.9s ease-in-out infinite alternate;
}

.atom-anim-music .bars > span:nth-child(2) { animation-delay: 0.15s; }
.atom-anim-music .bars > span:nth-child(3) { animation-delay: 0.30s; }
.atom-anim-music .bars > span:nth-child(4) { animation-delay: 0.10s; }

.atom-anim-arc-item .item {
  display: inline-grid;
  grid-template-columns: 18px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: -0.01em;
  --dot-shift: -4px;
  --arc-motion-distance: 18px;
  animation: relationshipArcItemIn 1.6s cubic-bezier(0.22, 1, 0.36, 1) infinite alternate;
}

.atom-anim-arc-item .dot {
  width: 12px;
  height: 12px;
  border-radius: 999px;
  background: var(--accent-year);
  box-shadow: 0 0 18px color-mix(in srgb, var(--accent-year), transparent 50%);
}

.atom-anim-arc-particle .swarm {
  position: relative;
  width: 60px;
  height: 32px;
}

.atom-anim-arc-particle .swarm > span {
  --arc-accent: var(--accent-day);
  --arc-motion-distance: 14px;
  position: absolute;
  width: 3px;
  height: 3px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--arc-accent), transparent 10%);
  box-shadow:
    0 0 7px color-mix(in srgb, var(--arc-accent), transparent 42%),
    0 0 16px color-mix(in srgb, var(--arc-accent), transparent 76%);
  animation: relationshipArcParticleIn 1.4s cubic-bezier(0.22, 1, 0.36, 1) infinite alternate;
}

.atom-anim-arc-particle .swarm > span:nth-child(1) { left:  10%; top: 30%; --arc-accent: var(--accent-day);   animation-delay: 0s;   }
.atom-anim-arc-particle .swarm > span:nth-child(2) { left:  34%; top: 60%; --arc-accent: var(--accent-week);  animation-delay: -0.2s; }
.atom-anim-arc-particle .swarm > span:nth-child(3) { left:  58%; top: 35%; --arc-accent: var(--accent-month); animation-delay: -0.4s; }
.atom-anim-arc-particle .swarm > span:nth-child(4) { left:  82%; top: 70%; --arc-accent: var(--accent-year);  animation-delay: -0.6s; }

.atom-anim-fade .ui {
  display: inline-block;
  padding: 6px 12px;
  border-radius: 8px;
  background: var(--panel);
  border: 1px solid var(--glass-border);
  font-size: 11px;
  font-weight: 600;
  color: var(--text);
  animation: atomUiFade 2.4s ease infinite alternate;
}

.atom-anim-flight {
  grid-column: 1 / -1;
}

.atom-anim-flight .preview {
  min-height: 132px;
  padding: 0;
}

.atom-anim-flight .preview::after {
  background: radial-gradient(circle at 50% 50%, rgba(140, 180, 255, 0.18), transparent 70%);
  opacity: 0.7;
}

.atom-anim-flight-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 1;
}

.atom-anim-table {
  display: grid;
  gap: 4px;
}

.atom-anim-row {
  display: grid;
  grid-template-columns: 110px 90px 1fr;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--shell);
  border: 1px solid var(--line);
  font-size: 11px;
}

.atom-anim-row code {
  color: var(--text);
  font-size: 10px;
  font-weight: 600;
}

.atom-anim-row .timing {
  color: var(--muted);
  font-family: "JetBrains Mono", monospace;
  font-size: 10px;
}

.atom-anim-row .target {
  color: color-mix(in srgb, var(--text) 72%, transparent);
}

@keyframes relationshipArcItemIn {
  from { transform: translate(var(--dot-shift), calc(-50% + var(--arc-motion-distance))) scale(0.98); opacity: 0; }
  to   { transform: translate(var(--dot-shift), -50%) scale(1); opacity: 1; }
}

@keyframes relationshipArcParticleIn {
  from { transform: translate(-50%, calc(-50% + var(--arc-motion-distance))) scale(0.96); opacity: 0; }
  to   { transform: translate(-50%, -50%) scale(1); opacity: var(--particle-alpha, 0.7); }
}

@keyframes atomUiFade {
  0%   { opacity: 0; transform: translate3d(0, 14px, 0); }
  60%  { opacity: 1; transform: translate3d(0, 0, 0); }
  100% { opacity: 1; transform: translate3d(0, 0, 0); }
}

/* ------------------------------------------------------------------------ */
/* Atom: Background — body environment (gradient + ambient halos + theme)    */
/* ------------------------------------------------------------------------ */

.atom-background-stage {
  position: relative;
  min-height: 240px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(135deg, var(--bg-a), var(--bg-b));
  transition: background 420ms ease, color 420ms ease;
}

.atom-background-stage::before {
  content: "";
  position: absolute;
  inset: -10%;
  background:
    radial-gradient(circle at 20% 30%, color-mix(in srgb, var(--accent-year),  transparent 76%), transparent 38%),
    radial-gradient(circle at 78% 22%, color-mix(in srgb, var(--accent-day),   transparent 80%), transparent 42%),
    radial-gradient(circle at 64% 80%, color-mix(in srgb, var(--accent-month), transparent 84%), transparent 40%);
  filter: blur(46px);
  opacity: 0.74;
  mix-blend-mode: screen;
  pointer-events: none;
}

.atom-background-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
    circle,
    color-mix(in srgb, var(--text) 30%, transparent) 0 1px,
    transparent 1.5px
  );
  background-size: 64px 64px;
  opacity: 0.16;
  mix-blend-mode: overlay;
  pointer-events: none;
}

.atom-background-axes {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: 1fr;
  align-items: end;
  padding: 14px 18px;
}

.atom-background-axes .row {
  display: grid;
  grid-template-columns: 90px 1fr;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  border-top: 1px dashed var(--line);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--muted);
}

.atom-background-axes .row code {
  color: var(--text);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

/* ------------------------------------------------------------------------ */
/* Atom: Halo — ambient glow (.node-halo / sphere outer-shell)               */
/* ------------------------------------------------------------------------ */

.atom-halo {
  --halo-rgb: 120, 160, 220;
  --halo-size: 184px;
  position: relative;
  width: var(--halo-size);
  height: var(--halo-size);
  border-radius: 999px;
  filter: blur(11px) saturate(1.04);
  mix-blend-mode: screen;
  pointer-events: none;
  background:
    radial-gradient(
      circle at center,
      rgba(255, 244, 232, 0.13) 0%,
      rgba(255, 232, 214, 0.07) 18%,
      rgba(255, 216, 192, 0.028) 34%,
      transparent 54%
    ),
    radial-gradient(
      circle at center,
      rgba(var(--halo-rgb), 0.24) 0%,
      rgba(var(--halo-rgb), 0.15) 24%,
      rgba(var(--halo-rgb), 0.08) 42%,
      rgba(var(--halo-rgb), 0.032) 60%,
      rgba(var(--halo-rgb), 0.010) 76%,
      transparent 90%
    ),
    radial-gradient(
      circle at center,
      rgba(var(--halo-rgb), 0.10) 0%,
      rgba(var(--halo-rgb), 0.028) 38%,
      transparent 72%
    );
}

body.dark .atom-halo {
  filter: blur(13px) saturate(1.05);
  background:
    radial-gradient(
      circle at center,
      rgba(224, 232, 255, 0.12) 0%,
      rgba(194, 210, 255, 0.058) 18%,
      rgba(164, 184, 248, 0.022) 34%,
      transparent 56%
    ),
    radial-gradient(
      circle at center,
      rgba(var(--halo-rgb), 0.30) 0%,
      rgba(var(--halo-rgb), 0.18) 26%,
      rgba(var(--halo-rgb), 0.095) 44%,
      rgba(var(--halo-rgb), 0.038) 62%,
      rgba(var(--halo-rgb), 0.012) 78%,
      transparent 92%
    ),
    radial-gradient(
      circle at center,
      rgba(var(--halo-rgb), 0.12) 0%,
      rgba(var(--halo-rgb), 0.032) 40%,
      transparent 74%
    );
}

.atom-halo--sm {
  --halo-size: 96px;
}

.atom-halo-stage {
  position: relative;
  min-height: 240px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(135deg, var(--bg-a), var(--bg-b));
}

.atom-halo-stage .core {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: rgb(var(--halo-rgb));
  box-shadow: 0 0 28px color-mix(in srgb, rgb(var(--halo-rgb)), transparent 30%);
}

.atom-halo-stage > .atom-halo {
  position: absolute;
  left: 50%;
  top: 50%;
  margin-left: calc(var(--halo-size) / -2);
  margin-top: calc(var(--halo-size) / -2);
}

.atom-halo-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}

.atom-halo-cell {
  position: relative;
  height: 96px;
  border-radius: 12px;
  overflow: hidden;
  background: linear-gradient(135deg, var(--bg-a), var(--bg-b));
  display: grid;
  place-items: end center;
  padding: 10px;
}

.atom-halo-cell .atom-halo {
  --halo-size: 110px;
  position: absolute;
  left: 50%;
  top: 42%;
  transform: translate(-50%, -50%);
}

.atom-halo-cell .core {
  position: absolute;
  left: 50%;
  top: 42%;
  transform: translate(-50%, -50%);
  width: 14px;
  height: 14px;
  border-radius: 999px;
  background: rgb(var(--halo-rgb));
  box-shadow: 0 0 14px color-mix(in srgb, rgb(var(--halo-rgb)), transparent 30%);
}

.atom-halo-cell .label {
  position: relative;
  z-index: 1;
  color: color-mix(in srgb, var(--text) 70%, transparent);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* ------------------------------------------------------------------------ */
/* Molecule: Brand                                                           */
/* ------------------------------------------------------------------------ */

.mol-brand {
  position: relative;
  display: grid;
  gap: 2px;
  padding: 4px 0 4px 18px;
  isolation: isolate;
}

.mol-brand::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.7em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--text) 88%, transparent);
  box-shadow: 0 0 14px color-mix(in srgb, var(--text) 36%, transparent);
}

.mol-brand::after {
  content: "";
  position: absolute;
  inset: -16px -22px;
  z-index: -1;
  border-radius: 999px;
  background: radial-gradient(
    ellipse 88% 70% at 28% 50%,
    rgba(255, 245, 232, 0.42) 0%,
    rgba(196, 220, 255, 0.16) 36%,
    transparent 82%
  );
  filter: blur(22px);
  opacity: 0.74;
  pointer-events: none;
}

body.dark .mol-brand::after {
  background: radial-gradient(
    ellipse 88% 70% at 28% 50%,
    rgba(122, 150, 220, 0.20) 0%,
    rgba(62, 78, 124, 0.12) 36%,
    transparent 82%
  );
}

.mol-brand strong {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.mol-brand span {
  color: var(--muted);
  font-size: 11px;
}

/* ------------------------------------------------------------------------ */
/* Molecule: Search field with menu                                          */
/* ------------------------------------------------------------------------ */

.mol-search {
  position: relative;
  width: 100%;
  max-width: 360px;
}

.mol-search-menu {
  position: relative;
  margin-top: 14px;
  display: grid;
  gap: 4px;
  isolation: isolate;
}

.mol-search-menu::before {
  content: "";
  position: absolute;
  inset: -16px -24px;
  z-index: -1;
  border-radius: 22px;
  background: radial-gradient(
    ellipse 90% 96% at 32% 30%,
    rgba(255, 245, 232, 0.38) 0%,
    rgba(196, 220, 255, 0.16) 38%,
    transparent 82%
  );
  filter: blur(22px);
  opacity: 0.78;
  pointer-events: none;
}

body.dark .mol-search-menu::before {
  background: radial-gradient(
    ellipse 90% 96% at 32% 30%,
    rgba(122, 150, 220, 0.20) 0%,
    rgba(62, 78, 124, 0.12) 38%,
    transparent 82%
  );
}

.mol-search-result {
  width: 100%;
  min-height: 36px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 6px 0 18px;
  border: 0;
  background: transparent;
  text-align: left;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  position: relative;
  letter-spacing: -0.01em;
}

.mol-search-result::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 8px;
  height: 1px;
  background: color-mix(in srgb, var(--text) 32%, transparent);
  transform: translateY(-50%);
  transition: width 180ms ease, background 180ms ease;
}

.mol-search-result:hover::before {
  width: 12px;
  background: color-mix(in srgb, var(--text) 64%, transparent);
}

.mol-search-result small {
  color: var(--muted);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ------------------------------------------------------------------------ */
/* Molecule: Depth pills bar                                                 */
/* ------------------------------------------------------------------------ */

.mol-depth-pills {
  position: relative;
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 5px;
  isolation: isolate;
}

.mol-depth-pills::before {
  content: "";
  position: absolute;
  inset: -10px -22px;
  z-index: -1;
  border-radius: 999px;
  background: radial-gradient(
    ellipse 92% 78% at 50% 50%,
    rgba(255, 245, 232, 0.44) 0%,
    rgba(196, 220, 255, 0.16) 34%,
    transparent 82%
  );
  filter: blur(22px);
  opacity: 0.72;
  pointer-events: none;
}

body.dark .mol-depth-pills::before {
  background: radial-gradient(
    ellipse 92% 78% at 50% 50%,
    rgba(122, 150, 220, 0.20) 0%,
    rgba(62, 78, 124, 0.12) 34%,
    transparent 82%
  );
}

/* ------------------------------------------------------------------------ */
/* Molecule: Music toggle                                                    */
/* ------------------------------------------------------------------------ */

.mol-music-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 36px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text);
  font-size: 12px;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  isolation: isolate;
  cursor: pointer;
  transition: transform 180ms ease, color 180ms ease;
}

.mol-music-toggle::after {
  content: "";
  position: absolute;
  inset: -10px -18px;
  z-index: -1;
  border-radius: 999px;
  background: radial-gradient(
    ellipse 92% 78% at 28% 50%,
    rgba(255, 245, 232, 0.44) 0%,
    rgba(196, 220, 255, 0.16) 34%,
    transparent 82%
  );
  filter: blur(22px);
  opacity: 0.7;
  pointer-events: none;
  transition: opacity 180ms ease;
}

body.dark .mol-music-toggle::after {
  background: radial-gradient(
    ellipse 92% 78% at 28% 50%,
    rgba(122, 150, 220, 0.20) 0%,
    rgba(62, 78, 124, 0.12) 34%,
    transparent 82%
  );
}

.mol-music-toggle:hover::after,
.mol-music-toggle.playing::after {
  opacity: 1;
}

.mol-music-toggle .label {
  display: inline-block;
}

.mol-music-toggle:hover {
  transform: translateX(2px);
}

.mol-music-toggle .bars {
  display: inline-flex;
  align-items: flex-end;
  gap: 2px;
  height: 14px;
}

.mol-music-toggle .bar {
  width: 2.5px;
  border-radius: 1px;
  background: currentColor;
}

.mol-music-toggle.playing .bar {
  animation: animatedBars 0.9s ease-in-out infinite alternate;
}

.mol-music-toggle.playing .bar:nth-child(1) { animation-delay: 0s; }
.mol-music-toggle.playing .bar:nth-child(2) { animation-delay: 0.15s; }
.mol-music-toggle.playing .bar:nth-child(3) { animation-delay: 0.3s; }
.mol-music-toggle.playing .bar:nth-child(4) { animation-delay: 0.1s; }

.mol-music-toggle:not(.playing) .bar {
  height: 3px !important;
}

/* ------------------------------------------------------------------------ */
/* Molecule: Cursor lens — единственная декларация см. ниже (≈строка 5068). */
/* Старая 200x200 fixed-size версия удалена — она конфликтовала с             */
/* full-stage overlay implementation (inset:0 + --lens-x/-y vars), потому    */
/* что width/height из старой декларации перетекали через cascade и lens     */
/* рисовался в углу stage'а 200x200 boксом.                                  */
/* ------------------------------------------------------------------------ */

/* ------------------------------------------------------------------------ */
/* Molecule: Node halo                                                       */
/* ------------------------------------------------------------------------ */

.mol-node-halo {
  --halo-rgb: 120, 160, 220;
  position: absolute;
  left: 70%;
  top: 50%;
  width: 160px;
  height: 160px;
  margin-left: -80px;
  margin-top: -80px;
  border-radius: 999px;
  filter: blur(11px) saturate(1.04);
  mix-blend-mode: screen;
  pointer-events: none;
  background:
    radial-gradient(
      circle at center,
      rgba(255, 244, 232, 0.20) 0%,
      rgba(255, 232, 214, 0.10) 18%,
      transparent 54%
    ),
    radial-gradient(
      circle at center,
      rgba(var(--halo-rgb), 0.42) 0%,
      rgba(var(--halo-rgb), 0.22) 24%,
      rgba(var(--halo-rgb), 0.08) 42%,
      transparent 90%
    );
}

body.dark .mol-node-halo {
  background:
    radial-gradient(
      circle at center,
      rgba(224, 232, 255, 0.18) 0%,
      rgba(194, 210, 255, 0.08) 18%,
      transparent 56%
    ),
    radial-gradient(
      circle at center,
      rgba(var(--halo-rgb), 0.46) 0%,
      rgba(var(--halo-rgb), 0.24) 26%,
      rgba(var(--halo-rgb), 0.10) 44%,
      transparent 92%
    );
}

/* ------------------------------------------------------------------------ */
/* Molecule: Node label                                                      */
/* ------------------------------------------------------------------------ */

.mol-node-label {
  --node-color: #ff6b57;
  position: relative;
  display: inline-block;
  padding: 0 0 0 16px;
  color: var(--text);
}

.mol-node-label::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.76em;
  width: 10px;
  height: 1px;
  background: color-mix(in srgb, var(--node-color), transparent 34%);
}

.mol-node-label::after {
  content: "";
  position: absolute;
  inset: -24px -34px -24px -22px;
  z-index: -1;
  border-radius: 999px;
  background: radial-gradient(
    ellipse 124% 112% at 40% 50%,
    color-mix(in srgb, white 82%, var(--node-color) 18%) 0%,
    color-mix(in srgb, var(--node-color), rgba(255, 255, 255, 0.54) 78%) 26%,
    color-mix(in srgb, var(--node-color), transparent 68%) 56%,
    transparent 86%
  );
  filter: blur(20px);
  opacity: 0.56;
  pointer-events: none;
}

.mol-node-label__row {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr;
  row-gap: 3px;
  justify-items: start;
}

.mol-node-label span {
  font-size: 13px;
  font-weight: 690;
  letter-spacing: -0.025em;
  text-shadow: 0 0 18px rgba(255, 255, 255, 0.16), 0 0 8px rgba(255, 255, 255, 0.08);
}

.mol-node-label small {
  color: var(--node-color);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-shadow: 0 0 14px color-mix(in srgb, var(--node-color), transparent 72%);
}

body.dark .mol-node-label::after {
  background: radial-gradient(
    ellipse 128% 116% at 40% 50%,
    color-mix(in srgb, var(--node-color), rgba(220, 232, 255, 0.28) 72%) 0%,
    color-mix(in srgb, var(--node-color), rgba(132, 160, 226, 0.18) 82%) 28%,
    transparent 88%
  );
  opacity: 0.62;
}

/* ------------------------------------------------------------------------ */
/* Molecule: Node-mark — UNIFIED vertex glyph for the whole map.             */
/*   Single composition (atom-halo + atom-core) reused everywhere a node     */
/*   shows up: on the sphere, in arc-items, as detail anchor.                */
/*   Variants only via parameters, not different shapes.                     */
/* ------------------------------------------------------------------------ */

.mol-node-mark {
  --mark-scale: 1;        /* multiplies both halo and core */
  --halo-size: calc(184px * var(--mark-scale));
  --core-size: calc(12px  * var(--mark-scale));
  --halo-rgb: 79, 124, 255;
  position: relative;
  display: inline-block;
  width: var(--core-size);
  height: var(--core-size);
  pointer-events: none;
}

.mol-node-mark > .atom-halo {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
}

.mol-node-mark > .atom-dot {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

/* Size presets — sm = arc-item dim, md = ambient node, lg = focus / source. */
.mol-node-mark--sm    { --mark-scale: 0.18; --core-size: 22px; }
.mol-node-mark--md    { --mark-scale: 0.42; --core-size: 12px; }
.mol-node-mark--lg    { --mark-scale: 0.76; --core-size: 14px; }
.mol-node-mark--xl    { --mark-scale: 1.10; --core-size: 18px; }

/* Showcase grid — token-based stage adapting to theme. */
.mol-node-mark-showcase {
  position: relative;
  min-height: 240px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(135deg, var(--bg-a), var(--bg-b));
  display: flex;
  align-items: center;
  justify-content: space-around;
  gap: 24px;
  padding: 28px;
}

.mol-node-mark-showcase::before {
  content: "";
  position: absolute;
  inset: -16%;
  background:
    radial-gradient(circle at 22% 50%, color-mix(in srgb, var(--accent-day),   transparent 76%), transparent 40%),
    radial-gradient(circle at 78% 50%, color-mix(in srgb, var(--accent-month), transparent 80%), transparent 42%);
  filter: blur(60px);
  opacity: 0.5;
  mix-blend-mode: screen;
  pointer-events: none;
}

.mol-node-mark-showcase .cell {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  gap: 14px;
}

.mol-node-mark-showcase .caption {
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* ========================================================================= */
/* MOLECULES — abstract reusable compositions of atoms.                       */
/* Specific use-cases (music-toggle, brand, depth-pills) live in HTML as      */
/* configurations (params on these base molecules), not as separate classes.  */
/* ========================================================================= */

/* ------------------------------------------------------------------------ */
/* Molecule: Icon-button — atom-button + atom-icon (+ optional label text)   */
/* ------------------------------------------------------------------------ */

.mol-icon-button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  isolation: isolate;
}

.mol-icon-button > .atom-icon {
  --icon-size: 14px;
  opacity: 0.82;
  transition: opacity 180ms ease, transform 180ms ease;
}

.mol-icon-button:hover > .atom-icon,
.mol-icon-button.is-active > .atom-icon { opacity: 1; }

/* ------------------------------------------------------------------------ */
/* Molecule: Pill-bar — atom-button[pill] × N + optional halo backdrop       */
/* ------------------------------------------------------------------------ */

.mol-pill-bar {
  position: relative;
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 5px;
  isolation: isolate;
}

.mol-pill-bar--with-halo::before {
  content: "";
  position: absolute;
  inset: -10px -22px;
  z-index: -1;
  border-radius: 999px;
  background: radial-gradient(
    ellipse 92% 78% at 50% 50%,
    rgba(255, 245, 232, 0.44) 0%,
    rgba(196, 220, 255, 0.16) 34%,
    transparent 82%
  );
  filter: blur(22px);
  opacity: 0.72;
  pointer-events: none;
}

body.dark .mol-pill-bar--with-halo::before {
  background: radial-gradient(
    ellipse 92% 78% at 50% 50%,
    rgba(122, 150, 220, 0.20) 0%,
    rgba(62, 78, 124, 0.12) 34%,
    transparent 82%
  );
}

/* ------------------------------------------------------------------------ */
/* Molecule: Search-field — atom-input + atom-icon trigger + halo backdrop   */
/* ------------------------------------------------------------------------ */

.mol-search-field {
  position: relative;
  width: 100%;
  isolation: isolate;
}

.mol-search-field--with-halo::before {
  content: "";
  position: absolute;
  inset: -14px -22px;
  z-index: -1;
  border-radius: 999px;
  background: radial-gradient(
    ellipse 86% 72% at 34% 50%,
    rgba(255, 245, 232, 0.42) 0%,
    rgba(196, 220, 255, 0.16) 34%,
    transparent 82%
  );
  filter: blur(22px);
  opacity: 0.78;
  pointer-events: none;
}

body.dark .mol-search-field--with-halo::before {
  background: radial-gradient(
    ellipse 86% 72% at 34% 50%,
    rgba(122, 150, 220, 0.20) 0%,
    rgba(62, 78, 124, 0.12) 34%,
    transparent 82%
  );
}

.mol-search-field > .atom-input {
  padding-right: 44px;
}

.mol-search-field > .mol-search-field__trigger {
  position: absolute;
  right: 0;
  top: 4px;
  width: 30px;
  height: 30px;
  border: 0;
  border-radius: 50%;
  background: none;
  color: color-mix(in srgb, var(--text) 64%, transparent);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.mol-search-field > .mol-search-field__trigger:hover { color: var(--text); }

/* ------------------------------------------------------------------------ */
/* Molecule: Label-with-meta — text-style + (dot + meta-text)                */
/*   Замена для kicker, brand, node-label.                                   */
/* ------------------------------------------------------------------------ */

.mol-label-with-meta {
  --label-color: currentColor;
  --label-meta-color: currentColor;
  display: inline-grid;
  row-gap: 3px;
  justify-items: start;
  color: var(--label-color);
}

.mol-label-with-meta__primary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 690;
  letter-spacing: -0.025em;
  line-height: 1.12;
}

.mol-label-with-meta__meta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--label-meta-color);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* Variant: kicker — small caps marker + dot leading. */
.mol-label-with-meta--kicker .mol-label-with-meta__primary {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: color-mix(in srgb, currentColor 64%, transparent);
}

/* Variant: brand — bigger title + smaller subtitle. */
.mol-label-with-meta--brand .mol-label-with-meta__primary {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.mol-label-with-meta--brand .mol-label-with-meta__meta {
  color: var(--muted);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
}

/* ------------------------------------------------------------------------ */
/* Molecule: Tag-row — atom-typography + atom-dot + atom-separator + meta    */
/*   Production .detail-top: tag (accent + glow-dot) + status (separator)    */
/* ------------------------------------------------------------------------ */

.mol-tag-row {
  display: inline-flex;
  align-items: center;
  gap: 16px;
}

.mol-tag-row__tag {
  --tag-color: var(--accent-day);
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--tag-color);
  font-size: 10px;
  font-weight: 720;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.mol-tag-row__status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: color-mix(in srgb, var(--text), var(--tag-color, var(--accent-day)) 42%);
  font-size: 10px;
  font-weight: 720;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* ------------------------------------------------------------------------ */
/* Molecule: Text-with-glow — atom-typography + halo-treatment text-shadow   */
/*   Replaces atom-title-display, atom-intent.                               */
/* ------------------------------------------------------------------------ */

.mol-text-with-glow {
  --glow-strength: 0.46;
  --glow-strength-secondary: 0.28;
  margin: 0;
  text-shadow:
    0 0 34px rgba(255, 255, 255, var(--glow-strength)),
    0 0 14px rgba(255, 255, 255, var(--glow-strength-secondary)),
    0 1px 0 rgba(255, 255, 255, 0.24);
}

body.dark .mol-text-with-glow,
[data-on-dark] .mol-text-with-glow {
  text-shadow:
    0 0 34px rgba(0, 0, 0, 0.55),
    0 0 14px rgba(0, 0, 0, 0.40),
    0 1px 0 rgba(255, 255, 255, 0.10);
}

/* Sizing variants — call into typography scale. */
.mol-text-with-glow--display {
  font-size: clamp(38px, 5vw, 58px);
  font-weight: 690;
  line-height: 0.92;
  letter-spacing: -0.045em;
  max-width: min(12ch, 100%);
}

.mol-text-with-glow--body {
  --glow-strength: 0.30;
  --glow-strength-secondary: 0.18;
  color: color-mix(in srgb, var(--text), white 18%);
  font-size: 17px;
  line-height: 1.34;
  max-width: 28ch;
}

body.dark .mol-text-with-glow--body,
[data-on-dark] .mol-text-with-glow--body {
  color: color-mix(in srgb, var(--text), white 4%);
  text-shadow:
    0 0 22px rgba(0, 0, 0, 0.5),
    0 0 10px rgba(0, 0, 0, 0.3);
}

.mol-text-with-glow--comment {
  --glow-strength: 0.18;
  --glow-strength-secondary: 0.08;
  color: color-mix(in srgb, var(--text), white 2%);
  font-size: 14px;
  line-height: 1.36;
}

body.dark .mol-text-with-glow--comment,
[data-on-dark] .mol-text-with-glow--comment {
  text-shadow:
    0 0 16px rgba(0, 0, 0, 0.4),
    0 0 8px rgba(0, 0, 0, 0.24);
}

/* ------------------------------------------------------------------------ */
/* Molecule: Text-block — title-display + body + comment(s) stack            */
/* ------------------------------------------------------------------------ */

.mol-text-block {
  display: grid;
  gap: 12px;
}

.mol-text-block .mol-text-with-glow + .mol-text-with-glow { margin: 0; }

.mol-text-block__comments {
  display: grid;
  gap: 8px;
  max-width: 30ch;
}

/* ------------------------------------------------------------------------ */
/* Molecule: Particle-cluster — N × atom-dot in a layout (drift / scatter)   */
/* ------------------------------------------------------------------------ */

.mol-particle-cluster {
  position: relative;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.mol-particle-cluster .atom-dot {
  position: absolute;
  animation: dotDrift 5.4s ease-in-out infinite alternate;
}

@keyframes dotDrift {
  0%   { transform: translate(0, 0) scale(1); }
  50%  { transform: translate(8px, -10px) scale(1.06); }
  100% { transform: translate(-6px, 6px) scale(0.94); }
}

/* ------------------------------------------------------------------------ */
/* Molecule: Node (vertex) — node-mark + label (production .node-label)      */
/* ------------------------------------------------------------------------ */

.mol-node-stage {
  position: relative;
  min-height: 360px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(135deg, var(--bg-a), var(--bg-b));
  color: var(--text);
}

.mol-node-stage::before {
  content: "";
  position: absolute;
  inset: -16%;
  background:
    radial-gradient(circle at 20% 26%, color-mix(in srgb, var(--accent-year), transparent 70%), transparent 40%),
    radial-gradient(circle at 76% 64%, color-mix(in srgb, var(--accent-day),  transparent 75%), transparent 40%);
  filter: blur(60px);
  opacity: 0.55;
  mix-blend-mode: screen;
  pointer-events: none;
}

/* Stars dust adapts to theme: dark stage → bright dots, light stage → muted shadow dots. */
.mol-node-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(circle at 14% 38%, color-mix(in srgb, var(--text) 50%, transparent) 0 0.6px, transparent 1px),
    radial-gradient(circle at 38% 76%, color-mix(in srgb, var(--text) 40%, transparent) 0 0.6px, transparent 1px),
    radial-gradient(circle at 64% 18%, color-mix(in srgb, var(--text) 40%, transparent) 0 0.6px, transparent 1px),
    radial-gradient(circle at 88% 60%, color-mix(in srgb, var(--text) 60%, transparent) 0 0.6px, transparent 1px);
  background-size: 22px 22px, 26px 26px, 32px 32px, 38px 38px;
  opacity: 0.45;
  pointer-events: none;
}

.mol-node-stage::after        { mix-blend-mode: multiply; }
body.dark .mol-node-stage::after { mix-blend-mode: screen; }

/* Composes <mol-node-mark> + label.
   Molecule provides only positioning; mark + atoms render themselves. */
.mol-node {
  --halo-rgb: 79, 124, 255;
  --node-color: #4f7cff;
  position: absolute;
  pointer-events: none;
}

.mol-node > .mol-node-mark {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.mol-node .label {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  row-gap: 3px;
  justify-items: start;
  padding: 0 0 0 16px;
  color: var(--text);
  font-size: 13px;
  font-weight: 690;
  letter-spacing: -0.025em;
  line-height: 1.12;
  text-shadow: 0 0 18px rgba(255, 255, 255, 0.16), 0 0 8px rgba(255, 255, 255, 0.08);
  isolation: isolate;
}

.mol-node .label .title {
  white-space: nowrap;
}

.mol-node .label small {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--node-color);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-shadow: 0 0 14px color-mix(in srgb, var(--node-color), transparent 72%);
}

.mol-node .label small::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 10px currentColor;
}

.mol-node .label::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.76em;
  width: 10px;
  height: 1px;
  background: color-mix(in srgb, var(--node-color), transparent 34%);
}

.mol-node .label::after {
  content: "";
  position: absolute;
  inset: -16px -22px -16px -10px;
  z-index: -1;
  border-radius: 999px;
  background: radial-gradient(
    ellipse 124% 112% at 40% 50%,
    color-mix(in srgb, white 82%, var(--node-color) 18%) 0%,
    color-mix(in srgb, var(--node-color), rgba(255, 255, 255, 0.54) 78%) 26%,
    color-mix(in srgb, var(--node-color), transparent 68%) 56%,
    transparent 86%
  );
  filter: blur(20px);
  opacity: 0.46;
  pointer-events: none;
}

body.dark .mol-node .label {
  color: color-mix(in srgb, var(--text), white 8%);
  text-shadow: 0 0 18px rgba(42, 56, 88, 0.26), 0 0 8px rgba(0, 0, 0, 0.18);
}

body.dark .mol-node .label::after {
  background: radial-gradient(
    ellipse 128% 116% at 40% 50%,
    color-mix(in srgb, var(--node-color), rgba(220, 232, 255, 0.28) 72%) 0%,
    color-mix(in srgb, var(--node-color), rgba(132, 160, 226, 0.18) 82%) 28%,
    transparent 88%
  );
  filter: blur(24px);
  opacity: 0.54;
}

.mol-node--selected > .mol-node-mark {
  --mark-scale: 1.10;
  --core-size: 18px;
}

.mol-node--selected > .mol-node-mark > .atom-dot {
  box-shadow: 0 0 22px color-mix(in srgb, rgb(var(--halo-rgb)), transparent 16%);
}

/* ------------------------------------------------------------------------ */
/* Organism: Relationship arc — .relationship-arc-switcher + arc particles   */
/* ------------------------------------------------------------------------ */

.org-arc-stage {
  /* Light theme: warm paper-like surface; цветные ambient-зоны от accent'ов
     дают шанс planet-glow эффекту читаться через мягкие тени. */
  position: relative;
  min-height: 540px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(circle at 28% 32%, color-mix(in srgb, var(--arc-accent, #ff6b57), white 78%), transparent 58%),
    radial-gradient(circle at 78% 72%, color-mix(in srgb, var(--arc-accent, #ff6b57), white 86%), transparent 64%),
    linear-gradient(135deg, #faf6ee 0%, #f0ebe1 48%, #e6dfd2 100%);
  color: var(--text);
}

/* Dark theme: production spatial scene — глубокий navy с двумя accent-glow'ами. */
body.dark .org-arc-stage {
  background:
    radial-gradient(circle at 28% 32%, rgba(53, 70, 130, 0.42), transparent 58%),
    radial-gradient(circle at 78% 72%, rgba(94, 60, 158, 0.34), transparent 64%),
    linear-gradient(135deg, #0c1027 0%, #0a0d1f 48%, #06070f 100%);
  color: rgba(245, 247, 255, 0.9);
}

.org-arc-stage::before {
  content: "";
  position: absolute;
  inset: -10%;
  background:
    radial-gradient(circle at 22% 46%, color-mix(in srgb, var(--arc-accent, #ff6b57), transparent 72%), transparent 42%),
    radial-gradient(circle at 76% 64%, color-mix(in srgb, var(--arc-accent, #ff6b57), transparent 86%), transparent 50%);
  filter: blur(64px);
  opacity: 0.52;
  pointer-events: none;
  z-index: 0;
}

/* Source node anchor — reuse <div class="mol-node mol-node--selected"> directly. */

/* Switcher panel attached to a side. */
.org-arc-switcher {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 56%;
  padding: 0;
  pointer-events: auto;
}

.org-arc-switcher[data-side="right"] { right: 0; }
.org-arc-switcher[data-side="left"]  { left:  0; }

/* Items column scrolls, faded at the top/bottom via mask. */
.org-arc-items {
  position: relative;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 12%, #000 88%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 12%, #000 88%, transparent 100%);
}
.org-arc-items::-webkit-scrollbar { display: none; }

/* Items are absolutely positioned for the arc curve, so we need a spacer
   to give the scroll container something to scroll. Tallest item top is
   ~116%, so 130% gives a comfortable trailing gap. */
.org-arc-items::after {
  content: "";
  display: block;
  height: 130%;
  pointer-events: none;
}

/* Molecule: Arc item — composes <mol-node-mark> + <strong> + <small>.
   Same vertex glyph as elsewhere on the map, just larger / brighter for focus. */
.mol-arc-item {
  --item-color: var(--arc-accent);
  --item-emphasis: 0.7;
  --dot-size: 28px;
  --dot-shift: -14px;
  position: absolute;
  display: grid;
  grid-template-columns: var(--dot-size) minmax(0, 320px);
  align-items: center;
  column-gap: 18px;
  min-width: 382px;
  padding: 0;
  border: 0;
  background: none;
  color: color-mix(in srgb, var(--text), var(--item-color) 12%);
  cursor: pointer;
  font: inherit;
  opacity: calc(0.38 + var(--item-emphasis) * 0.62);
  text-align: left;
  transform: translate(var(--dot-shift), -50%);
  transition: color 180ms ease, opacity 180ms ease, transform 180ms ease;
}

.mol-arc-item > .mol-node-mark {
  --halo-rgb: var(--arc-accent-rgb, 79, 124, 255);
  justify-self: center;
  align-self: center;
}

/* Emphasis presets — only mark scale + opacity differ. Same shape. */
.mol-arc-item[data-role="focus"] {
  --item-emphasis: 1;
  --dot-size: 52px;
  --dot-shift: -26px;
  min-width: 440px;
  opacity: 1;
}
.mol-arc-item[data-role="focus"] > .mol-node-mark {
  --mark-scale: 1.1;
  --core-size: 18px;
}
.mol-arc-item:not([data-role="focus"]) > .mol-node-mark {
  --mark-scale: 0.42;
  --core-size: 12px;
}

.mol-arc-item .copy {
  display: grid;
  gap: 3px;
  justify-items: start;
  min-width: 0;
}

.mol-arc-item strong {
  display: -webkit-box;
  max-width: 320px;
  overflow: hidden;
  font-size: 13px;
  font-weight: 760;
  letter-spacing: 0.03em;
  line-height: 1.12;
  white-space: normal;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  text-shadow: 0 0 18px rgba(255, 255, 255, 0.22);
}

.mol-arc-item small {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: color-mix(in srgb, var(--item-color), var(--text) 30%);
  font-size: 9px;
  font-weight: 760;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.mol-arc-item small .status::before {
  content: "·";
  margin-right: 8px;
  color: color-mix(in srgb, var(--item-color), transparent 28%);
}

body.dark .mol-arc-item strong,
.org-arc-stage .mol-arc-item strong {
  text-shadow: 0 0 18px rgba(0, 0, 0, 0.42);
}

/* Organism slot: scattered <atom-particle> inside the switcher. */
.org-arc-particles {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.org-arc-particles .atom-dot {
  position: absolute;
  transform: translate(-50%, -50%);
}

/* ------------------------------------------------------------------------ */
/* Organism: Onboarding gate                                                 */
/* ------------------------------------------------------------------------ */

.org-onboarding-gate {
  position: relative;
  display: grid;
  gap: 14px;
  width: min(420px, 100%);
}

/* Modifier — горизонтально центрирует title/copy/button. По-умолчанию
   organism left-align (production showcase). Level1 включает через
   data-align="center" — нейтрально для других потребителей. */
.org-onboarding-gate[data-align="center"] {
  justify-items: center;
  text-align: center;
}
.org-onboarding-gate[data-align="center"] .gate-copy {
  justify-items: center;
}
.org-onboarding-gate[data-align="center"] .gate-start {
  justify-self: center;
}

/* Optional icon slot — иконка перед заголовком gate. Параметризовано:
   любой inline-флекс контейнер (SVG, emoji в span, atom-dot). Не имеет
   фиксированного размера — родитель задаёт. */
.org-onboarding-gate .gate-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: inherit;
  opacity: 0.92;
}

.org-onboarding-gate::before {
  content: "";
  position: absolute;
  inset: -40px -60px;
  background:
    radial-gradient(circle at 34% 46%, rgba(255, 255, 255, 0.38), transparent 22%),
    radial-gradient(circle at 54% 54%, rgba(182, 215, 255, 0.18), transparent 34%);
  filter: blur(34px);
  opacity: 0.88;
  pointer-events: none;
}

body.dark .org-onboarding-gate::before {
  background:
    radial-gradient(circle at 34% 46%, rgba(158, 202, 255, 0.18), transparent 22%),
    radial-gradient(circle at 54% 54%, rgba(94, 120, 196, 0.16), transparent 34%);
}

.org-onboarding-gate .gate-title {
  position: relative;
  margin: 0;
  font-size: clamp(38px, 4.6vw, 56px);
  line-height: 0.92;
  letter-spacing: -0.06em;
}

.org-onboarding-gate .gate-copy {
  position: relative;
  display: grid;
  gap: 6px;
  max-width: 360px;
  color: color-mix(in srgb, var(--text) 72%, transparent);
  font-size: 17px;
  line-height: 1.18;
  letter-spacing: -0.03em;
}

.org-onboarding-gate .gate-start {
  position: relative;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  transition: transform 180ms ease;
}

.org-onboarding-gate .gate-start::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.82;
}

.org-onboarding-gate .gate-start::after {
  content: "";
  position: absolute;
  left: 18px;
  right: 0;
  bottom: -4px;
  height: 1px;
  background: currentColor;
  opacity: 0.34;
  transform-origin: left center;
  transition: transform 180ms ease, opacity 180ms ease;
}

.org-onboarding-gate .gate-start:hover {
  transform: translate3d(0, -1px, 0);
}

.org-onboarding-gate .gate-start:hover::after {
  opacity: 0.68;
  transform: scaleX(1.06);
}

/* ── Template wrapper: full-viewport overlay, центрирует organism gate.
   Используется когда gate работает как первый экран перед чем-то
   (flight, режим, settings). Тема через те же flight-vars. */
.org-onboarding-overlay {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: grid;
  place-items: center;
  padding: 24px;
  background:
    radial-gradient(circle at 50% 36%, var(--flight-bg-glow), transparent 60%),
    var(--flight-bg-base);
  color: var(--flight-text);
  opacity: 1;
  transition: opacity 480ms ease;
}
.org-onboarding-overlay[hidden] {
  display: none;
}
.org-onboarding-overlay.fading {
  opacity: 0;
  pointer-events: none;
}

/* ------------------------------------------------------------------------ */
/* Organism: Onboarding flight                                               */
/* ------------------------------------------------------------------------ */

.org-flight {
  position: relative;
  width: 100%;
  display: grid;
  place-items: center;
  gap: 16px;
  text-align: center;
  padding: 24px 0;
}

.org-flight .flight-hint {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  color: color-mix(in srgb, var(--text) 64%, transparent);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.org-flight .flight-step {
  display: grid;
  gap: 8px;
}

.org-flight .flight-step p {
  margin: 0;
}

.org-flight .flight-step p:first-child {
  font-size: clamp(28px, 3.4vw, 44px);
  line-height: 0.92;
  letter-spacing: -0.06em;
  text-shadow: 0 0 24px rgba(255, 255, 255, 0.18), 0 0 58px rgba(132, 194, 255, 0.16);
}

.org-flight .flight-step p + p {
  font-size: 16px;
  line-height: 1.14;
  letter-spacing: -0.03em;
  color: color-mix(in srgb, var(--text) 74%, transparent);
}

.org-flight .flight-progress {
  width: 220px;
  height: 1px;
  background: color-mix(in srgb, var(--text) 18%, transparent);
  overflow: hidden;
}

.org-flight .flight-progress-bar {
  width: 64%;
  height: 100%;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0), color-mix(in srgb, var(--text) 76%, transparent));
}

.org-flight .flight-status {
  color: color-mix(in srgb, var(--text) 64%, transparent);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* ── Live mode: organism активируется JS'ом через [data-onboarding-flight] ─
   Полноэкранный overlay, который проигрывает sequential 3-phase flight intro
   (approach → dwell → depart per step). Шаги наслаиваются на одну точку,
   движутся СТРОГО по оси Z (без scale/rotate) — чистая перпендикулярность
   плоскости камеры. Тема следует за prefers-color-scheme + body.dark/.light. */

/* Theme tokens — defaults для светлой темы (OS-light). Нейтральная
   cool-grey палитра без тёплых оттенков. */
:root {
  --flight-bg-base: #f5f6f8;
  --flight-bg-glow: rgba(140, 150, 170, 0.10);
  --flight-text: rgba(20, 22, 38, 0.92);
  --flight-text-subtle: rgba(20, 22, 38, 0.58);
  --flight-progress-track: rgba(20, 22, 38, 0.14);
  --flight-progress-fill: rgba(20, 22, 38, 0.62);
  --flight-shadow: 0 0 24px rgba(20, 22, 38, 0.08), 0 0 58px rgba(132, 194, 255, 0.10);
}
@media (prefers-color-scheme: dark) {
  :root {
    --flight-bg-base: linear-gradient(135deg, #0c1027 0%, #0a0d1f 48%, #06070f 100%);
    --flight-bg-glow: rgba(94, 60, 158, 0.32);
    --flight-text: rgba(245, 247, 255, 0.92);
    --flight-text-subtle: rgba(245, 247, 255, 0.58);
    --flight-progress-track: rgba(245, 247, 255, 0.14);
    --flight-progress-fill: rgba(245, 247, 255, 0.62);
    --flight-shadow: 0 0 24px rgba(255, 255, 255, 0.18), 0 0 58px rgba(132, 194, 255, 0.16);
  }
}
/* Manual override через body class — пользователь может форсировать. */
body.light {
  --flight-bg-base: #f5f6f8;
  --flight-bg-glow: rgba(140, 150, 170, 0.10);
  --flight-text: rgba(20, 22, 38, 0.92);
  --flight-text-subtle: rgba(20, 22, 38, 0.58);
  --flight-progress-track: rgba(20, 22, 38, 0.14);
  --flight-progress-fill: rgba(20, 22, 38, 0.62);
  --flight-shadow: 0 0 24px rgba(20, 22, 38, 0.08), 0 0 58px rgba(132, 194, 255, 0.10);
}
body.dark {
  --flight-bg-base: linear-gradient(135deg, #0c1027 0%, #0a0d1f 48%, #06070f 100%);
  --flight-bg-glow: rgba(94, 60, 158, 0.32);
  --flight-text: rgba(245, 247, 255, 0.92);
  --flight-text-subtle: rgba(245, 247, 255, 0.58);
  --flight-progress-track: rgba(245, 247, 255, 0.14);
  --flight-progress-fill: rgba(245, 247, 255, 0.62);
  --flight-shadow: 0 0 24px rgba(255, 255, 255, 0.18), 0 0 58px rgba(132, 194, 255, 0.16);
}

.org-flight[data-onboarding-flight] {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  display: block;
  padding: 0;
  perspective: 1400px;
  perspective-origin: 50% 50%;
  overflow: hidden;
  isolation: isolate;
  z-index: 60;
  color: var(--flight-text);
  background:
    radial-gradient(circle at 50% 36%, var(--flight-bg-glow), transparent 60%),
    var(--flight-bg-base);
}
.org-flight[data-onboarding-flight] > .atom-anim-flight-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}
.org-flight[data-onboarding-flight] .flight-steps {
  position: absolute;
  inset: 0;
  display: block;
  transform-style: preserve-3d;
  z-index: 2;
  pointer-events: none;
}
.org-flight[data-onboarding-flight] .flight-step {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(720px, 80vw);
  text-align: center;
  opacity: 0;
  color: var(--flight-text);
  will-change: opacity, transform;
}
.org-flight[data-onboarding-flight] .flight-step p {
  margin: 0;
}
.org-flight[data-onboarding-flight] .flight-step p:first-child {
  font-size: clamp(28px, 3.4vw, 44px);
  line-height: 1.05;
  letter-spacing: -0.04em;
  text-shadow: var(--flight-shadow);
}
.org-flight[data-onboarding-flight] .flight-step p + p {
  font-size: clamp(16px, 1.6vw, 22px);
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--flight-text-subtle);
  margin-top: 12px;
}
/* Inline link-style кнопка внутри .flight-step — для интерактивных
   призывов в gate-шаге (например fullscreen). Наследует font/color от
   <p>-обёртки, добавляет underline + cursor pointer. pointer-events:auto
   нужен потому что родитель .flight-steps имеет pointer-events:none. */
.org-flight[data-onboarding-flight] .flight-step .gate-fullscreen {
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  color: inherit;
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  cursor: pointer;
  pointer-events: auto;
  transition: color 160ms ease, text-decoration-color 160ms ease;
}
.org-flight[data-onboarding-flight] .flight-step .gate-fullscreen:hover,
.org-flight[data-onboarding-flight] .flight-step .gate-fullscreen:focus-visible {
  color: var(--flight-text);
  text-decoration-color: currentColor;
  outline: none;
}
.org-flight[data-onboarding-flight] .flight-progress {
  position: absolute;
  bottom: 60px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  width: min(280px, 60vw);
  height: 1px;
  background: var(--flight-progress-track);
  overflow: hidden;
}
.org-flight[data-onboarding-flight] .flight-progress-bar {
  width: 100%;
  height: 100%;
  transform-origin: 0% 50%;
  background: var(--flight-progress-fill);
  transition: transform 120ms linear;
}
.org-flight[data-onboarding-flight] .flight-status {
  position: absolute;
  bottom: 36px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  color: var(--flight-text-subtle);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
/* Hint — текстовая подсказка над progress-баром. Подсказывает пользователю,
   что нужно скроллить для продвижения. */
.org-flight[data-onboarding-flight] .flight-hint {
  position: absolute;
  top: auto;
  bottom: 84px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  color: var(--flight-text-subtle);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  opacity: 0.82;
  /* Hint мягко пульсирует, привлекая внимание к scroll-affordance. */
  animation: flightHintBreath 2.8s ease-in-out infinite;
}
@keyframes flightHintBreath {
  0%, 100% { opacity: 0.42; }
  50%      { opacity: 0.86; }
}
/* Hidden state — overlay полностью убран из layout, чтобы pointer
   events проваливались на stage снизу. Базовое display:block перебивает
   HTML hidden attribute, поэтому фиксируем правилом для [hidden]. */
.org-flight[data-onboarding-flight][hidden] {
  display: none;
}
/* .fading — safety для timer-driver demo и forced complete(). */
.org-flight[data-onboarding-flight].fading {
  opacity: 0;
  transition: opacity 520ms ease;
  pointer-events: none;
}

/* ------------------------------------------------------------------------ */
/* Organism: Guide flow                                                      */
/* ------------------------------------------------------------------------ */

.org-guide-flow {
  position: relative;
  width: min(320px, 100%);
  display: grid;
  gap: 10px;
  padding: 4px 0;
}

.org-guide-flow::before {
  content: "";
  position: absolute;
  inset: -36px -48px;
  background:
    radial-gradient(circle at 42% 28%, rgba(255, 255, 255, 0.24), transparent 24%),
    radial-gradient(circle at 50% 48%, rgba(118, 176, 255, 0.12), transparent 42%);
  filter: blur(26px);
  opacity: 0.72;
  pointer-events: none;
}

body.dark .org-guide-flow::before {
  background:
    radial-gradient(circle at 42% 28%, rgba(158, 202, 255, 0.18), transparent 24%),
    radial-gradient(circle at 50% 48%, rgba(94, 120, 196, 0.16), transparent 42%);
}

.org-guide-flow .gf-kicker,
.org-guide-flow .gf-step {
  position: relative;
  z-index: 1;
  margin: 0;
  color: color-mix(in srgb, var(--text) 62%, transparent);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.org-guide-flow .gf-title {
  position: relative;
  z-index: 1;
  margin: 0;
  font-size: 28px;
  font-weight: 740;
  line-height: 0.94;
  letter-spacing: -0.05em;
}

.org-guide-flow .gf-copy {
  position: relative;
  z-index: 1;
  max-width: 300px;
  margin: 0;
  font-size: 15px;
  line-height: 1.2;
  letter-spacing: -0.03em;
  color: color-mix(in srgb, var(--text) 78%, transparent);
}

.org-guide-flow .gf-meta {
  position: relative;
  z-index: 1;
  max-width: 280px;
  margin: 0;
  font-size: 12px;
  line-height: 1.26;
  color: color-mix(in srgb, var(--text) 52%, transparent);
}

/* ------------------------------------------------------------------------ */
/* Organism: Detail panel — glass + spotlight + backdrop (production .detail)*/
/* ------------------------------------------------------------------------ */

.org-detail-stage {
  /* Light theme: warm paper-like surface с двумя accent ambient-glow'ами.
     Backdrop в этом режиме рисуется через светлый radial-gradient (см.
     стейдж-override .detail-backdrop ниже). */
  position: relative;
  min-height: 540px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(circle at 30% 36%, color-mix(in srgb, var(--detail-accent, #ff6b57), white 78%), transparent 56%),
    radial-gradient(circle at 76% 70%, color-mix(in srgb, var(--detail-accent, #ff6b57), white 88%), transparent 62%),
    linear-gradient(135deg, #faf6ee 0%, #f0ebe1 48%, #e6dfd2 100%);
  color: var(--text);
}

/* Dark theme: production spatial scene. */
body.dark .org-detail-stage {
  background:
    radial-gradient(circle at 30% 36%, rgba(74, 92, 168, 0.38), transparent 56%),
    radial-gradient(circle at 76% 70%, rgba(108, 70, 178, 0.34), transparent 62%),
    linear-gradient(135deg, #0c1027 0%, #0a0d1f 48%, #06070f 100%);
  color: rgba(245, 247, 255, 0.92);
}

.org-detail-stage::before {
  content: "";
  position: absolute;
  inset: -16%;
  background:
    radial-gradient(circle at 26% 50%, color-mix(in srgb, var(--accent-day),   transparent 70%), transparent 40%),
    radial-gradient(circle at 70% 30%, color-mix(in srgb, var(--accent-year),  transparent 76%), transparent 44%),
    radial-gradient(circle at 80% 80%, color-mix(in srgb, var(--accent-month), transparent 82%), transparent 40%);
  filter: blur(70px);
  opacity: 0.65;
  mix-blend-mode: screen;
  pointer-events: none;
}

/* Star-dust — adapts to theme. Light: subtle dark specks on paper.
   Dark: bright white pinpoints on deep space. */
.org-detail-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(circle at 12% 22%, color-mix(in srgb, var(--text), transparent 65%) 0 0.6px, transparent 1px),
    radial-gradient(circle at 32% 70%, color-mix(in srgb, var(--text), transparent 75%) 0 0.6px, transparent 1px),
    radial-gradient(circle at 48% 12%, color-mix(in srgb, var(--text), transparent 75%) 0 0.6px, transparent 1px),
    radial-gradient(circle at 62% 88%, color-mix(in srgb, var(--text), transparent 65%) 0 0.6px, transparent 1px),
    radial-gradient(circle at 84% 30%, color-mix(in srgb, var(--text), transparent 75%) 0 0.6px, transparent 1px),
    radial-gradient(circle at 92% 64%, color-mix(in srgb, var(--text), transparent 65%) 0 0.6px, transparent 1px);
  background-size: 18px 18px, 22px 22px, 28px 28px, 34px 34px, 40px 40px, 26px 26px;
  opacity: 0.35;
  pointer-events: none;
}
body.dark .org-detail-stage::after {
  background-image:
    radial-gradient(circle at 12% 22%, rgba(255, 255, 255, 0.55) 0 0.6px, transparent 1px),
    radial-gradient(circle at 32% 70%, rgba(255, 255, 255, 0.40) 0 0.6px, transparent 1px),
    radial-gradient(circle at 48% 12%, rgba(255, 255, 255, 0.40) 0 0.6px, transparent 1px),
    radial-gradient(circle at 62% 88%, rgba(255, 255, 255, 0.55) 0 0.6px, transparent 1px),
    radial-gradient(circle at 84% 30%, rgba(255, 255, 255, 0.40) 0 0.6px, transparent 1px),
    radial-gradient(circle at 92% 64%, rgba(255, 255, 255, 0.55) 0 0.6px, transparent 1px);
  opacity: 0.6;
}

/* Stage is always dark — stars use screen blend regardless of page theme. */
.org-detail-stage::after { mix-blend-mode: screen; }

/* Cursor-following spotlight — JS updates --cursor-x / --cursor-y as %. */
.org-detail-stage {
  --cursor-x: 50%;
  --cursor-y: 50%;
}

.org-detail-stage > .org-detail-cursor-lens {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(
    circle 240px at var(--cursor-x) var(--cursor-y),
    color-mix(in srgb, var(--detail-accent, var(--accent-day)), transparent 62%) 0%,
    color-mix(in srgb, var(--detail-accent, var(--accent-day)), transparent 86%) 30%,
    transparent 60%
  );
  mix-blend-mode: screen;
  opacity: 0;
  transition: opacity 240ms ease;
}

.org-detail-stage:hover > .org-detail-cursor-lens { opacity: 1; }

/* Sphere canvas behind detail-stage content. */
.org-detail-stage > .org-detail-sphere {
  position: absolute;
  inset: 0;
  z-index: 0;
}

/* Clickable node-marks on top of the sphere. */
.org-detail-stage > .org-detail-nodes {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}

.org-detail-stage .org-detail-node {
  position: absolute;
  display: grid;
  place-items: center;
  pointer-events: auto;
  cursor: pointer;
  background: none;
  border: 0;
  padding: 0;
  transform: translate(-50%, -50%);
  transition: transform 220ms ease;
}

.org-detail-stage .org-detail-node:hover { transform: translate(-50%, -50%) scale(1.06); }

.org-detail-stage .org-detail-node[aria-selected="true"] > .mol-node-mark {
  --mark-scale: 1.10;
  --core-size: 18px;
}

/* Detail panel sits on top of sphere + nodes; positioned near the selected node via JS. */
.org-detail-stage .org-detail {
  position: absolute;
  z-index: 4;
  transition: top 320ms cubic-bezier(.22,1,.36,1), left 320ms cubic-bezier(.22,1,.36,1), right 320ms cubic-bezier(.22,1,.36,1);
}

/* Backdrop follows the selected node — JS sets --detail-x/--detail-y. */
.org-detail-stage .org-detail-backdrop {
  --detail-x: 50%;
  --detail-y: 50%;
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(
    ellipse 320px 220px at var(--detail-x) var(--detail-y),
    color-mix(in srgb, var(--detail-accent, var(--accent-day)), transparent 30%) 0%,
    color-mix(in srgb, var(--detail-accent, var(--accent-day)), transparent 70%) 32%,
    transparent 68%
  );
  filter: blur(28px);
  opacity: 0.95;
  mix-blend-mode: screen;
  transition: opacity 320ms ease;
}

/* Detail anchor: reuse <div class="mol-node"> directly inside the stage. */

.org-detail-backdrop {
  --detail-accent: #ff6b57;
  --spot-x: 50%;
  --spot-y: 38%;
  position: absolute;
  left: 28%;
  top: 52%;
  width: 460px;
  height: 320px;
  border-radius: 132px;
  pointer-events: none;
  transform: translate3d(-50%, -50%, 0);
  background:
    radial-gradient(
      ellipse 116% 98% at var(--spot-x) var(--spot-y),
      rgba(255, 255, 255, 0.78) 0%,
      rgba(255, 255, 255, 0.62) 22%,
      rgba(255, 255, 255, 0.42) 46%,
      rgba(255, 255, 255, 0.24) 68%,
      rgba(255, 255, 255, 0.10) 84%,
      transparent 100%
    ),
    linear-gradient(
      135deg,
      rgba(255, 255, 255, 0.18) 0%,
      rgba(255, 255, 255, 0.12) 36%,
      rgba(255, 255, 255, 0.04) 100%
    );
  filter: blur(34px);
  opacity: 0.92;
}

body.dark .org-detail-backdrop {
  background:
    radial-gradient(
      ellipse 116% 98% at var(--spot-x) var(--spot-y),
      rgba(168, 188, 232, 0.40) 0%,
      rgba(120, 144, 200, 0.30) 22%,
      rgba(76, 96, 160, 0.18) 46%,
      rgba(52, 64, 112, 0.10) 68%,
      rgba(36, 44, 80, 0.04) 84%,
      transparent 100%
    );
  opacity: 0.85;
}

/* Spatial variant — text in space, no glass card, no border, no background.
   Title is huge with multi-layer text-shadow; links live in arc-switcher. */
.org-detail {
  --detail-accent: #ff6b57;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translateY(-50%);
  width: min(430px, calc(100% - 96px));
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: var(--text);
  isolation: isolate;
  z-index: 1;
  overflow: visible;
}

.org-detail[data-side="left"] {
  left: auto;
  right: 50%;
  transform: translateY(-50%);
  text-align: right;
}

/* Spatial: no decorative ::before / ::after / spotlight. */
.org-detail-spotlight { display: none; }

.org-detail-motion {
  position: relative;
  z-index: 1;
}

.org-detail-top {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 16px;
  margin-bottom: 18px;
}

.org-detail[data-side="left"] .org-detail-top {
  flex-direction: row-reverse;
  justify-content: flex-end;
}

/* Detail panel composes <atom-tag>, <atom-status>, <atom-title-display>,
   <atom-intent> directly. No org-* type/text rules — atoms own appearance. */

/* Detail spacing — composition uses molecules (tag-row + text-with-glow). */
.org-detail-motion .mol-tag-row { margin-bottom: 18px; }
.org-detail-motion .mol-text-with-glow--display { margin: 0 0 12px; }
.org-detail-motion .mol-text-with-glow--body    { margin: 0 0 12px; }
.org-detail-motion .org-detail-comments {
  display: grid;
  gap: 8px;
  max-width: 30ch;
  margin: 0;
}

.org-detail-motion .org-detail-comments p {
  margin: 0;
  color: color-mix(in srgb, var(--text), white 2%);
  font-size: 14px;
  line-height: 1.36;
  text-shadow:
    0 0 16px rgba(255, 255, 255, 0.18),
    0 0 8px rgba(255, 255, 255, 0.08);
}

.org-detail-stage .org-detail-comments p {
  text-shadow:
    0 0 16px rgba(0, 0, 0, 0.4),
    0 0 8px rgba(0, 0, 0, 0.24);
}

/* Spatial detail hides connections — they live in <org-arc-switcher>. */
.org-detail-motion .org-detail-links-label,
.org-detail-motion .org-detail-links {
  display: none;
}

/* ------------------------------------------------------------------------ */
/* Organism: Settings panel                                                  */
/* ------------------------------------------------------------------------ */

.org-settings {
  position: relative;
  width: min(380px, 100%);
  display: grid;
  gap: 12px;
  padding: 14px 18px;
  isolation: isolate;
}

.org-settings::before {
  content: "";
  position: absolute;
  inset: -8px -18px;
  z-index: -1;
  border-radius: 28px;
  background: radial-gradient(
    ellipse 90% 84% at 38% 30%,
    rgba(255, 245, 232, 0.34) 0%,
    rgba(196, 220, 255, 0.14) 38%,
    transparent 82%
  );
  filter: blur(24px);
  opacity: 0.72;
  pointer-events: none;
}

body.dark .org-settings::before {
  background: radial-gradient(
    ellipse 90% 84% at 38% 30%,
    rgba(122, 150, 220, 0.20) 0%,
    rgba(62, 78, 124, 0.12) 38%,
    transparent 82%
  );
}

.org-settings .nav-label {
  margin: 4px 4px 0;
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.org-settings .nav-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.org-settings .nav-row .atom-button {
  flex: 1 1 96px;
}

.org-settings .nav-hint {
  max-width: 320px;
  padding: 0 4px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
}

/* ------------------------------------------------------------------------ */
/* Organism: Top action bar (brand + search + actions)                       */
/* ------------------------------------------------------------------------ */

.org-topbar {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
  padding: 16px;
}

.org-topbar .center {
  display: grid;
  justify-items: center;
}

.org-topbar .right {
  display: flex;
  gap: 8px;
}

/* ------------------------------------------------------------------------ */
/* Flow list                                                                 */
/* ------------------------------------------------------------------------ */

.flow-list {
  display: grid;
  gap: 8px;
}

.flow-row {
  display: grid;
  grid-template-columns: 56px minmax(180px, 0.32fr) 1fr;
  gap: 18px;
  align-items: baseline;
  padding: 16px 18px;
  border-radius: 14px;
  background: var(--shell);
  border: 1px solid var(--line);
}

.flow-row .num {
  color: var(--muted);
  font-family: "JetBrains Mono", monospace;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.16em;
}

.flow-row strong {
  font-size: 18px;
  font-weight: 740;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.flow-row p {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.4;
}

.flow-row code {
  color: var(--text);
  font-size: 11px;
}

/* ------------------------------------------------------------------------ */
/* Variant matrix                                                            */
/* ------------------------------------------------------------------------ */

.matrix {
  display: grid;
  gap: 10px;
}

.matrix-row {
  display: grid;
  grid-template-columns: 160px minmax(0, 1fr);
  gap: 18px;
  align-items: center;
  padding: 14px 16px;
  border-radius: 14px;
  background: var(--shell);
  border: 1px solid var(--line);
}

.matrix-row strong {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
}

.matrix-row code {
  display: block;
  margin-top: 4px;
  color: var(--muted);
  font-size: 10px;
}

.matrix-row .values {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.matrix-row .pill {
  display: inline-flex;
  align-items: center;
  padding: 5px 10px;
  border-radius: 999px;
  background: var(--panel);
  color: var(--text);
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: -0.01em;
  border: 1px solid var(--line);
}

/* ------------------------------------------------------------------------ */
/* Code snippet block                                                        */
/* ------------------------------------------------------------------------ */

.snippet {
  margin: 0;
  padding: 12px 14px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--text) 6%, transparent);
  border: 1px solid var(--line);
  color: var(--text);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 11px;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-x: auto;
}

body.dark .snippet {
  background: rgba(255, 255, 255, 0.04);
}

/* ------------------------------------------------------------------------ */
/* Responsive                                                                */
/* ------------------------------------------------------------------------ */

@media (max-width: 1024px) {
  .grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .grid--three {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .card--wide {
    grid-column: span 2;
  }
}

@media (max-width: 720px) {
  .ds-shell {
    width: min(100vw - 24px, 1240px);
    padding-top: 16px;
  }

  .ds-hero,
  .section,
  .card {
    padding: 16px;
  }

  .grid,
  .grid--two,
  .grid--three {
    grid-template-columns: 1fr;
  }

  .card--wide {
    grid-column: auto;
  }

  .section-header {
    grid-template-columns: 1fr;
  }

  .flow-row {
    grid-template-columns: 1fr;
  }

  .matrix-row {
    grid-template-columns: 1fr;
  }

  .org-topbar {
    grid-template-columns: 1fr;
    text-align: left;
  }
}

/* ========================================================================= */
/* Production-parity organism layer.                                          */
/* Точная копия CSS из production relationship-graph для                      */
/* `.detail`, `.detail-*`, `.relationship-arc-switcher`, `.relationship-arc-*`*/
/* — чтобы organisms можно было переиспользовать копи-пастом в прототип.      */
/* Override `position: fixed` → absolute, `height: 100vh` → 100% для дизайн-  */
/* системы (organisms живут внутри stage, а не fullscreen).                   */
/* ========================================================================= */

/* ── Detail panel ────────────────────────────────────────────────────── */

.detail {
  --detail-accent: #3a6ab5;
  --spot-x: 50%;
  --spot-y: 38%;
  position: absolute;
  z-index: 8;
  display: block;
  width: min(348px, calc(100vw - 48px));
  padding: 14px 14px 16px;
  border: 1px solid rgba(255, 255, 255, 0.58);
  border-radius: 28px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.60), rgba(255, 255, 255, 0.22)),
    radial-gradient(circle at 18% 10%, color-mix(in srgb, var(--detail-accent), transparent 94%) 0%, transparent 44%);
  box-shadow:
    0 18px 42px rgba(24, 31, 39, 0.10),
    0 8px 22px rgba(255, 255, 255, 0.22) inset;
  opacity: 0;
  pointer-events: none;
  transform: translate3d(-50%, calc(-50% + 18px), 0) scale(0.98);
  backdrop-filter: blur(18px) saturate(1.08);
  -webkit-backdrop-filter: blur(18px) saturate(1.08);
  overflow: hidden;
  isolation: isolate;
  transition:
    opacity 220ms ease,
    transform 340ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: opacity, transform;
}

.detail::before,
.detail::after,
.detail-spotlight {
  content: "";
  position: absolute;
  pointer-events: none;
}

.detail::before {
  top: -34px;
  left: -12px;
  width: 72%;
  height: 46%;
  border-radius: 999px;
  background: linear-gradient(140deg, rgba(255, 255, 255, 0.58) 0%, rgba(255, 255, 255, 0.12) 34%, transparent 60%);
  transform: rotate(-7deg);
  opacity: 0.86;
}

.detail::after {
  inset: auto 18px 12px 18px;
  height: 1px;
  border: 0;
  border-radius: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.62), transparent);
  opacity: 0.78;
}

.detail-spotlight {
  inset: -34px;
  z-index: 0;
  border-radius: 44px;
  background: radial-gradient(
    ellipse 48% 34% at var(--spot-x) var(--spot-y),
    rgba(255, 255, 255, 0.82) 0%,
    rgba(255, 255, 255, 0.42) 22%,
    rgba(255, 255, 255, 0.14) 42%,
    transparent 72%
  );
  filter: blur(10px);
  opacity: 0.48;
}

.detail-backdrop {
  --detail-accent: #3a6ab5;
  --spot-x: 50%;
  --spot-y: 38%;
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  border-radius: 132px;
  pointer-events: none;
  background:
    radial-gradient(
      ellipse 116% 98% at var(--spot-x) var(--spot-y),
      rgba(255, 255, 255, 0.78) 0%,
      rgba(255, 255, 255, 0.62) 22%,
      rgba(255, 255, 255, 0.42) 46%,
      rgba(255, 255, 255, 0.24) 68%,
      rgba(255, 255, 255, 0.10) 84%,
      transparent 100%
    ),
    linear-gradient(135deg, rgba(255, 255, 255, 0.18) 0%, rgba(255, 255, 255, 0.12) 36%, rgba(255, 255, 255, 0.04) 100%);
  filter: blur(34px);
  opacity: 0;
  transform: translate3d(-50%, -50%, 0) scale(0.96);
  transition: opacity 220ms ease, transform 320ms cubic-bezier(0.22, 1, 0.36, 1);
}

.detail-backdrop.visible { opacity: 1; transform: translate3d(-50%, -50%, 0) scale(1); }
.detail.visible          { opacity: 1; pointer-events: auto; }
.detail[data-phase="opening"],
.detail[data-phase="visible"]  { transform: translate3d(-50%, -50%, 0) scale(1); }
.detail[data-phase="closing"]  { transform: translate3d(-50%, calc(-50% + 14px), 0) scale(0.985); }

.detail-motion {
  position: relative;
  z-index: 1;
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: opacity 160ms ease, transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}
.detail.content-hidden .detail-motion { opacity: 0; transform: translate3d(0, 10px, 0) scale(0.99); }

.detail-top {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.detail-tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  padding: 0 11px;
  border: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--detail-accent), rgba(255, 255, 255, 0.82) 84%);
  color: var(--detail-accent);
  font-size: 10px;
  font-weight: 760;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.detail-tag::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 16px currentColor;
}

.detail-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  color: color-mix(in srgb, var(--text), var(--detail-accent) 32%);
  font-size: 10px;
  font-weight: 720;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}
.detail-status::before {
  content: "·";
  color: color-mix(in srgb, var(--detail-accent), transparent 20%);
  font-size: 18px;
  line-height: 0;
}

.detail-close { display: none; }

/* Спрятать пустые элементы detail panel ТОЛЬКО для spatial-варианта
   (view-only) — production renderDetail не рендерит empty values в DOM.
   В authoring mode title/intent могут быть пустыми, но placeholder
   (mol-editable-text:empty::before) должен показываться — поэтому
   .detail-title:empty не должен скрываться. Скопил селекторы под
   [data-spatial-detail], чтобы не цеплять authoring detail. */
/* tag/status — буллет через ::before, без текста показывать его незачем.
   Глобальное правило (не только spatial), иначе в authoring detail остаются
   "висячие" точки над заголовком. title/intent НЕ глобально — у них есть
   placeholder в authoring mode через mol-editable-text. */
.detail-tag:empty,
.detail-status:empty { display: none; }
/* В authoring mode (CTA draft) title/intent пустые — это норма, нужно
   показывать placeholder через :empty::before. Поэтому :not([data-mode=
   "authoring"]). Comments/links/label всегда скрываются empty, они не
   имеют placeholder. */
[data-spatial-detail]:not([data-mode="authoring"]) .detail-title:empty,
[data-spatial-detail]:not([data-mode="authoring"]) .detail-intent:empty {
  display: none;
}
[data-spatial-detail] .detail-comments:empty,
[data-spatial-detail] .detail-links:empty,
[data-spatial-detail] .detail-links-label:empty { display: none; }

.detail-title {
  position: relative;
  z-index: 1;
  margin: 0 0 10px;
  font-size: 30px;
  font-weight: 740;
  line-height: 0.98;
  letter-spacing: -0.03em;
}
.detail-intent {
  position: relative;
  z-index: 1;
  margin: 0 0 14px;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.45;
  max-width: 24ch;
}
.detail-comments {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 8px;
  max-width: 30ch;
  margin: 0 0 14px;
}
.detail-comments p {
  margin: 0;
  color: color-mix(in srgb, var(--muted), var(--text) 28%);
  font-size: 13px;
  line-height: 1.36;
}
.detail-links-label {
  position: relative;
  z-index: 1;
  margin-bottom: 9px;
  color: var(--muted);
  font-size: 10px;
  font-weight: 760;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.detail-links {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Spatial variant — text in space, no glass card. */
.detail[data-variant="spatial"] {
  width: min(430px, calc(100vw - 96px));
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  overflow: visible;
}
.detail[data-variant="spatial"]::before,
.detail[data-variant="spatial"]::after { display: none; opacity: 0; }
.detail[data-variant="spatial"] .detail-spotlight { display: none; }
.detail[data-variant="spatial"][data-side="left"] { text-align: right; }

.detail[data-variant="spatial"] .detail-top {
  margin-bottom: 18px;
  align-items: center;
  justify-content: flex-start;
  gap: 16px;
}
.detail[data-variant="spatial"][data-side="left"] .detail-top { flex-direction: row-reverse; }
.detail[data-variant="spatial"] .detail-tag {
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  font-size: 10px;
  font-weight: 720;
  letter-spacing: 0.18em;
  gap: 9px;
}
.detail[data-variant="spatial"] .detail-status {
  min-height: 0;
  color: color-mix(in srgb, var(--text), var(--detail-accent) 42%);
  font-size: 10px;
  font-weight: 720;
  letter-spacing: 0.18em;
}
.detail[data-variant="spatial"] .detail-tag::before {
  position: static;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  box-shadow: 0 0 14px currentColor;
}
/* Light theme defaults: text-shadow гладко переходит в тёплый paper-фон через
   warm-tinted glow с примесью accent. Текст dark, тени subtle и тоже dark. */
.detail[data-variant="spatial"] .detail-title {
  margin-bottom: 12px;
  font-size: clamp(38px, 5vw, 58px);
  font-weight: 690;
  line-height: 0.92;
  letter-spacing: -0.045em;
  max-width: min(12ch, 100%);
  text-shadow:
    0 0 32px color-mix(in srgb, var(--detail-accent), transparent 78%),
    0 1px 0 rgba(255, 255, 255, 0.6);
}
.detail[data-variant="spatial"][data-side="left"] .detail-title,
.detail[data-variant="spatial"][data-side="left"] .detail-intent,
.detail[data-variant="spatial"][data-side="left"] .detail-comments,
.detail[data-variant="spatial"][data-side="left"] .detail-links { margin-left: auto; }
.detail[data-variant="spatial"] .detail-intent {
  margin-bottom: 12px;
  font-size: 17px;
  line-height: 1.34;
  max-width: 28ch;
  color: color-mix(in srgb, var(--text), white 6%);
  text-shadow: 0 0 18px color-mix(in srgb, var(--detail-accent), transparent 84%);
}
.detail[data-variant="spatial"] .detail-comments { max-width: 30ch; }
.detail[data-variant="spatial"] .detail-comments p {
  color: color-mix(in srgb, var(--text), var(--muted) 28%);
  text-shadow: 0 0 14px rgba(255, 255, 255, 0.4);
}
.detail[data-variant="spatial"] .detail-links-label,
.detail[data-variant="spatial"] .detail-links { display: none; }

body.dark .detail[data-variant="spatial"] {
  border: 0;
  background: none;
  box-shadow: none;
  backdrop-filter: none;
}
/* Dark theme: production WHITE-glow text-shadow поверх deep-space bg. */
body.dark .detail[data-variant="spatial"] .detail-title {
  text-shadow:
    0 0 34px rgba(255, 255, 255, 0.46),
    0 0 14px rgba(255, 255, 255, 0.28),
    0 1px 0 rgba(255, 255, 255, 0.24);
}
body.dark .detail[data-variant="spatial"] .detail-intent {
  color: color-mix(in srgb, var(--text), white 18%);
  text-shadow: 0 0 22px rgba(255, 255, 255, 0.30), 0 0 10px rgba(255, 255, 255, 0.18);
}
body.dark .detail[data-variant="spatial"] .detail-comments p {
  color: color-mix(in srgb, var(--text), white 2%);
  text-shadow: 0 0 16px rgba(255, 255, 255, 0.18), 0 0 8px rgba(255, 255, 255, 0.08);
}

/* Scope override only inside the showcase stage so design-system can render
   detail in both themes without messing with global .detail-backdrop rules. */
body.dark .org-detail-stage .detail-backdrop {
  border-radius: 156px;
  background:
    radial-gradient(
      ellipse 122% 104% at var(--spot-x) var(--spot-y),
      rgba(148, 176, 236, 0.22) 0%,
      rgba(118, 144, 212, 0.18) 22%,
      rgba(88, 108, 170, 0.14) 46%,
      rgba(56, 68, 108, 0.10) 68%,
      rgba(20, 24, 38, 0.04) 86%,
      transparent 100%
    ),
    linear-gradient(135deg, rgba(88, 110, 176, 0.12) 0%, rgba(50, 64, 106, 0.08) 42%, rgba(16, 20, 34, 0.02) 100%);
  filter: blur(42px);
  opacity: 0.98;
}
body.dark .org-detail-stage .detail-backdrop:not(.visible) { opacity: 0; }

/* ── Relationship arc switcher ──────────────────────────────────────── */

.relationship-arc-switcher {
  --arc-accent: var(--detail-accent);
  --arc-motion-distance: 84px;
  position: absolute;        /* production: fixed; design-system: scoped to stage */
  top: 0;
  z-index: 7;
  width: min(680px, 52%);    /* production uses 52vw; we use % of stage */
  height: 100%;              /* production: 100vh */
  opacity: 1;
  overflow: visible;
  pointer-events: none;
  transform: translate3d(0, 0, 0) scale(1);
  transform-origin: center;
  transition: opacity 220ms ease, transform 220ms ease;
  touch-action: none;
}
.relationship-arc-switcher.visible {
  opacity: 1;
  pointer-events: auto;
  transform: translate3d(0, 0, 0) scale(1);
}
.relationship-arc-switcher[data-side="left"]  { left: 0; }
.relationship-arc-switcher[data-side="right"] { right: 0; }

.relationship-arc-switcher__particles,
.relationship-arc-switcher__items {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.relationship-arc-switcher__items {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 9%, #000 91%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 9%, #000 91%, transparent 100%);
}
.relationship-arc-switcher__particles {
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 7%, #000 93%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 7%, #000 93%, transparent 100%);
}

.relationship-arc-particle {
  --particle-alpha: 0.42;
  --particle-size: 2.4px;
  /* Drift params — bridge задаёт per-particle для рассинхронизированного
     движения (как «дыхание» частиц на сфере). Fallback'и для статичного. */
  --drift-x: 0px;
  --drift-y: 0px;
  --drift-dur: 6s;
  --drift-delay: 0s;
  /* Cursor pull — bridge обновляет per-particle через RAF loop (как
     uCursor pull у частиц на сфере). Складывается с drift в transform. */
  --pull-x: 0px;
  --pull-y: 0px;
  position: absolute;
  width: var(--particle-size);
  height: var(--particle-size);
  border-radius: 999px;
  background: color-mix(in srgb, var(--arc-accent), transparent 10%);
  box-shadow:
    0 0 7px  color-mix(in srgb, var(--arc-accent), transparent 42%),
    0 0 16px color-mix(in srgb, var(--arc-accent), transparent 76%);
  opacity: var(--particle-alpha);
  transform: translate(-50%, -50%);
  /* Подвижность — плавный drift + лёгкое пульсирование opacity, как
     частицы на сфере. Каждая частица со своими amplitude/duration/delay
     (CSS-vars), поэтому движение не синхронное. */
  animation: arcParticleDrift var(--drift-dur) ease-in-out infinite;
  animation-delay: var(--drift-delay);
  will-change: transform, opacity;
}
@keyframes arcParticleDrift {
  0% {
    transform: translate(-50%, -50%) translate(var(--pull-x), var(--pull-y));
    opacity: var(--particle-alpha);
  }
  50% {
    transform: translate(-50%, -50%)
      translate(calc(var(--drift-x) + var(--pull-x)), calc(var(--drift-y) + var(--pull-y)));
    opacity: min(1, calc(var(--particle-alpha) * 1.55));
  }
  100% {
    transform: translate(-50%, -50%) translate(var(--pull-x), var(--pull-y));
    opacity: var(--particle-alpha);
  }
}
@media (prefers-reduced-motion: reduce) {
  /* Без drift, но cursor pull остаётся (применяется через transform var). */
  .relationship-arc-particle {
    animation: none;
    transform: translate(-50%, -50%) translate(var(--pull-x), var(--pull-y));
  }
}

.relationship-arc-item {
  --item-color: var(--arc-accent);
  --item-emphasis: 0.7;
  --dot-size: calc(18px + var(--item-emphasis) * 18px);
  --dot-shift: -18px;
  position: absolute;
  display: grid;
  grid-template-columns: var(--dot-size) minmax(0, 320px);
  align-items: center;
  column-gap: 18px;
  min-width: 382px;
  padding: 0;
  border: 0;
  background: none;
  color: color-mix(in srgb, var(--text), var(--item-color) 12%);
  cursor: pointer;
  font: inherit;
  opacity: calc(0.38 + var(--item-emphasis) * 0.62);
  text-align: left;
  transform: translate(var(--dot-shift), -50%);
  transition: color 180ms ease, opacity 180ms ease, transform 180ms ease, letter-spacing 180ms ease;
}
.relationship-arc-item[disabled] { cursor: default; opacity: 0.34; pointer-events: none; }
.relationship-arc-item.exiting   { pointer-events: none; z-index: 6; }

.relationship-arc-item__dot {
  position: relative;
  width: var(--dot-size);
  height: var(--dot-size);
  border-radius: 50%;
  isolation: isolate;
  background:
    radial-gradient(circle at center,
      color-mix(in srgb, var(--item-color), white 3%) 0 11%,
      var(--item-color) 23%,
      color-mix(in srgb, var(--item-color), transparent 26%) 38%,
      color-mix(in srgb, var(--item-color), transparent 78%) 62%,
      transparent 82%),
    radial-gradient(circle at center,
      color-mix(in srgb, var(--item-color), transparent 20%) 0 32%,
      color-mix(in srgb, var(--item-color), transparent 76%) 58%,
      transparent 74%);
  box-shadow:
    0 0 calc(24px + var(--item-emphasis) * 42px) color-mix(in srgb, var(--item-color), transparent 42%),
    0 0 calc(62px + var(--item-emphasis) * 68px) color-mix(in srgb, var(--item-color), transparent 82%);
  filter: blur(0.15px) saturate(1.14);
}
.relationship-arc-item__dot::before,
.relationship-arc-item__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
}
.relationship-arc-item__dot::before {
  inset: 20%;
  background: radial-gradient(circle at center,
    color-mix(in srgb, var(--item-color), white 4%) 0 24%,
    var(--item-color) 54%,
    color-mix(in srgb, var(--item-color), black 10%) 100%);
  box-shadow: 0 0 10px color-mix(in srgb, var(--item-color), transparent 16%),
              0 0 2px  color-mix(in srgb, var(--item-color), white 10%) inset;
}
.relationship-arc-item__dot::after {
  inset: 6%;
  background:
    radial-gradient(circle at 46% 32%, color-mix(in srgb, var(--item-color), transparent 18%) 0 1.3px, transparent 2.2px),
    radial-gradient(circle at 62% 58%, color-mix(in srgb, var(--item-color), transparent 28%) 0 1px,   transparent 2px),
    radial-gradient(circle at 34% 64%, color-mix(in srgb, var(--item-color), transparent 38%) 0 0.9px, transparent 1.8px);
  opacity: calc(0.36 + var(--item-emphasis) * 0.32);
}

.relationship-arc-item__copy {
  display: grid;
  gap: 3px;
  justify-items: start;
  min-width: 0;
}
.relationship-arc-item strong {
  display: -webkit-box;
  max-width: 320px;
  overflow: hidden;
  font-size: 13px;
  font-weight: 760;
  letter-spacing: 0.03em;
  line-height: 1.12;
  white-space: normal;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}
.relationship-arc-item small {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: color-mix(in srgb, var(--item-color), var(--text) 30%);
  font-size: 9px;
  font-weight: 760;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.relationship-arc-item small .relationship-arc-item__status::before {
  content: "·";
  margin-right: 8px;
  color: color-mix(in srgb, var(--item-color), transparent 28%);
}

.relationship-arc-item[data-role="focus"] {
  --dot-size: 52px;
  --dot-shift: -26px;
  min-width: 440px;
  opacity: 1;
}
.relationship-arc-item[data-role="focus"] .relationship-arc-item__dot {
  box-shadow: 0 0 72px  color-mix(in srgb, var(--item-color), transparent 34%),
              0 0 132px color-mix(in srgb, var(--item-color), transparent 78%);
}
.relationship-arc-item[data-role="focus"] strong {
  max-width: 360px;
  font-size: 16px;
  font-weight: 800;
}
.relationship-arc-item:hover {
  color: var(--text);
  letter-spacing: 0.01em;
  transform: translate(var(--dot-shift), calc(-50% - 3px));
}

/* ── Add-item CTA (role="add-parent" / role="add-child") ──
   Пустой dashed circle с "+" вместо filled vertex dot. Использует
   --halo-rgb (production accent) для tint, чтобы CTA не выглядело как
   real node, но визуально часть arc'а. */
.relationship-arc-item--add {
  --item-color: rgb(var(--halo-rgb, 255, 107, 87));
}
.relationship-arc-item__dot--add {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--dot-size);
  height: var(--dot-size);
  border: 1.8px dashed color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), transparent 30%);
  border-radius: 50%;
  background: transparent !important;
  box-shadow: 0 0 calc(16px + var(--item-emphasis) * 26px)
              color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), transparent 78%);
  color: color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), var(--text) 40%);
  font-size: 22px;
  font-weight: 600;
  line-height: 1;
  filter: none;
  transition: border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease;
}
.relationship-arc-item__dot--add::before,
.relationship-arc-item__dot--add::after {
  display: none;  /* CTA не нуждается в декоративных layer'ах obычного dot'a. */
}
.relationship-arc-item--add:hover .relationship-arc-item__dot--add {
  border-color: color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), transparent 8%);
  box-shadow: 0 0 calc(28px + var(--item-emphasis) * 40px)
              color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), transparent 60%);
  transform: scale(1.08);
}

/* ========================================================================= */
/* Flow · Vertex Create — long-press 3s pattern                              */
/* ========================================================================= */

.org-vertex-create-stage {
  /* Light theme: warm paper background с мягкими accent-glow'ами от --halo-rgb. */
  position: relative;
  min-height: 540px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(circle at 30% 36%, color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), white 78%), transparent 56%),
    radial-gradient(circle at 76% 70%, color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), white 88%), transparent 62%),
    linear-gradient(135deg, #faf6ee 0%, #f0ebe1 48%, #e6dfd2 100%);
  color: var(--text);
  touch-action: none;
  user-select: none;
  cursor: crosshair;
}
body.dark .org-vertex-create-stage {
  background:
    radial-gradient(circle at 28% 32%, rgba(53, 70, 130, 0.42), transparent 58%),
    radial-gradient(circle at 78% 72%, rgba(94, 60, 158, 0.34), transparent 64%),
    linear-gradient(135deg, #0c1027 0%, #0a0d1f 48%, #06070f 100%);
  color: rgba(245, 247, 255, 0.92);
}

.org-vertex-create-stage > .org-detail-sphere {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

/* Hint в idle-state — гаснет во время удержания. */
.org-vertex-create-hint {
  position: absolute;
  left: 50%;
  bottom: 18px;
  z-index: 6;
  transform: translateX(-50%);
  color: color-mix(in srgb, var(--text), transparent 50%);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  pointer-events: none;
  transition: opacity 220ms ease;
}
body.dark .org-vertex-create-hint {
  color: color-mix(in srgb, rgba(245, 247, 255, 0.6), transparent 30%);
}
.org-vertex-create-stage[data-state="converging"] .org-vertex-create-hint,
.org-vertex-create-stage[data-state="materialized"] .org-vertex-create-hint,
.org-vertex-create-stage[data-state="authoring"] .org-vertex-create-hint,
.org-vertex-create-stage[data-state="persisted"] .org-vertex-create-hint {
  opacity: 0;
}

/* Halo в точке давления — растёт во время удержания.
   --create-progress (0..1) обновляется из JS каждый кадр.
   Base size 280px (compact), scale 0.15 → 1.0. После материализации
   этот халo полностью скрывается — финальный nimbus даёт встроенный
   .atom-halo внутри .mol-node-mark (точно как у вершин в графе). */
.org-vertex-create-halo {
  position: absolute;
  z-index: 2;
  width: 280px;
  height: 280px;
  margin: -140px 0 0 -140px;  /* центрирование от left/top */
  border-radius: 50%;
  /* Light theme — два слоя: насыщенный ядерный glow без blend mode (виден
     на бумаге) + ambient ореол с soft alpha. Цвет через --halo-rgb. */
  background:
    radial-gradient(circle at center,
      rgba(var(--halo-rgb, 255, 107, 87), 0.58) 0%,
      rgba(var(--halo-rgb, 255, 107, 87), 0.38) 14%,
      rgba(var(--halo-rgb, 255, 107, 87), 0.18) 32%,
      rgba(var(--halo-rgb, 255, 107, 87), 0.07) 54%,
      rgba(var(--halo-rgb, 255, 107, 87), 0.02) 74%,
      transparent 88%);
  filter: blur(calc(2px + var(--create-progress, 0) * 14px)) saturate(1.06);
  opacity: calc(var(--create-progress, 0) * (2 - var(--create-progress, 0)));
  transform: scale(calc(0.15 + var(--create-progress, 0) * 0.85));
  pointer-events: none;
  /* Транзишен только для смены состояний (materialized/cancel),
     во время converging --create-progress обновляется каждый кадр. */
}
/* Dark theme — добавляем mix-blend-mode: screen для bright glow поверх
   deep-space, цвета чуть ярче. */
body.dark .org-vertex-create-stage .org-vertex-create-halo {
  background:
    radial-gradient(circle at center,
      rgba(var(--halo-rgb, 255, 107, 87), 0.95) 0%,
      rgba(var(--halo-rgb, 255, 107, 87), 0.62) 12%,
      rgba(var(--halo-rgb, 255, 107, 87), 0.32) 28%,
      rgba(var(--halo-rgb, 255, 107, 87), 0.12) 52%,
      rgba(var(--halo-rgb, 255, 107, 87), 0.03) 74%,
      transparent 88%);
  mix-blend-mode: screen;
}

/* Halo opacity управляется ТОЛЬКО через --create-progress (0..1).
   - converging: JS ramp'ит progress 0→1 → halo проявляется
   - materialize/cancel: JS ramp'ит progress 1→0 → halo плавно гаснет
   - reset/idle: progress = 0 → opacity = 0
   Никаких state-based instant'ов opacity (это вызывало «блик»). */

/* Materialized vertex — node-mark в точке давления, появляется на 100% удержания. */
.org-vertex-create-mark {
  position: absolute;
  z-index: 3;
  width: 1px;     /* anchor; mol-node-mark внутри сам задаёт размер */
  height: 1px;
  pointer-events: none;
  opacity: 0;
  transform: scale(0);
  transition:
    opacity 280ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 280ms cubic-bezier(0.22, 1, 0.36, 1);
}
.org-vertex-create-mark > .mol-node-mark {
  position: absolute;
  transform: translate(-50%, -50%);
}
.org-vertex-create-stage[data-state="materialized"] .org-vertex-create-mark,
.org-vertex-create-stage[data-state="authoring"] .org-vertex-create-mark,
.org-vertex-create-stage[data-state="persisted"] .org-vertex-create-mark {
  opacity: 1;
  transform: scale(1);
}

/* ── Molecule: Editable text — reusable contenteditable + placeholder ──
   Используется везде, где нужен inline-ввод без рамок и подчёркиваний:
   detail-title authoring, detail-intent authoring, любое spatial-поле.
   Атомы: .atom-typography (size/weight задаёт родитель), placeholder через
   ::before с attr(data-placeholder) — тот же шрифт, более муьеный цвет. */
.mol-editable-text {
  outline: none;
  cursor: text;
  caret-color: var(--editable-caret, rgb(var(--halo-rgb, 255, 107, 87)));
  /* Сохраняем typography родителя (detail-title, detail-intent и т.д.). */
}
/* Без contenteditable элемент только показывает placeholder (read-only) —
   I-beam cursor сбивает с толку. Делаем default. */
.mol-editable-text:not([contenteditable]) {
  cursor: default;
  caret-color: transparent;
}
.mol-editable-text:empty::before {
  content: attr(data-placeholder);
  color: var(--editable-placeholder,
    color-mix(in srgb, currentColor, transparent 56%));
  pointer-events: none;
}
/* Spatial-контекст: placeholder примешивает accent для деликатной подсветки. */
.detail[data-variant="spatial"] .mol-editable-text:empty::before {
  color: color-mix(in srgb,
    color-mix(in srgb, currentColor, transparent 56%),
    var(--detail-accent, #ff6b57) 14%);
}

/* Spatial detail в authoring-режиме — title/intent редактируются inline.
   Все правила placeholder/caret теперь идут от .mol-editable-text. */
.org-vertex-create-stage > .detail[data-mode="authoring"] {
  z-index: 8;
}
.detail[data-mode="authoring"] .detail-tag {
  /* Authoring: tag тоже placeholder, либо пустой. По умолчанию — пустой. */
  opacity: 0.6;
}

/* ── Molecule: Action key — кнопка действия с keyboard-hint ПОД ней.
   Reusable паттерн: glyph + label сверху, hint ниже мелким муьеным шрифтом.
   Никаких рамок/фонов; на hover чуть приподнимается. Tone задаётся через
   --action-tone (default = currentColor; --detail-accent для confirm). */
.mol-action-key {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  color: var(--action-tone, currentColor);
  transition: color 180ms ease, transform 180ms ease;
}
.mol-action-key:hover {
  transform: translateY(-1px);
  color: var(--action-tone-hover, var(--action-tone, currentColor));
}
.mol-action-key__label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 720;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.mol-action-key__glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  font-size: 14px;
}
.mol-action-key__hint {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.45;
}
.mol-action-key-showcase {
  display: inline-flex;
  gap: 28px;
}

/* ── Authoring actions group — confirm / discard. Использует .mol-action-key. */
.detail-authoring-actions {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 22px;
  margin-top: 18px;
}
.detail[data-variant="spatial"][data-side="left"] .detail-authoring-actions {
  justify-content: flex-end;
}
[data-vertex-confirm],
[data-spatial-confirm] {
  --action-tone: var(--detail-accent, #ff6b57);
  --action-tone-hover: color-mix(in srgb, var(--detail-accent, #ff6b57), white 18%);
}
[data-vertex-discard],
[data-spatial-discard] {
  --action-tone: color-mix(in srgb, currentColor, transparent 50%);
  --action-tone-hover: currentColor;
}

/* Spatial detail authoring mode — CTA flow для создания родителя.
   Default (view mode): actions/chips/close видны/скрыты соответственно.
   Authoring mode (draft-vertex): actions visible, chips/close скрыты,
   title/intent редактируемые (contenteditable + mol-editable-text class
   добавляются bridge'ом). */
[data-spatial-detail]:not([data-mode="authoring"]) [data-spatial-authoring-actions] {
  display: none;
}
[data-spatial-detail][data-mode="authoring"] .detail-chips,
[data-spatial-detail][data-mode="authoring"] [data-spatial-close],
[data-spatial-detail][data-mode="authoring"] [data-spatial-comments],
[data-spatial-detail][data-mode="authoring"] [data-spatial-links],
[data-spatial-detail][data-mode="authoring"] .detail-links-label {
  display: none;
}

/* В persisted-режиме actions скрыты (вершина сохранена, делать нечего). */
.detail[data-mode="persisted"] .detail-authoring-actions { display: none; }
.detail[data-mode="persisted"] .mol-editable-text {
  caret-color: transparent;
}
/* Пустые поля (например, intent без описания) исчезают, не показывают
   placeholder в персистнутом состоянии. */
.detail[data-mode="persisted"] .mol-editable-text:empty {
  display: none;
}

/* В spatial-режиме detail = view of existing vertex (open via tap).
   Read-only поведение идентично persisted: no caret, no actions, empty
   intent не показывает placeholder. Но persist observer не триггерится
   (он слушает только 'persisted' = save после создания через long-press).
   Plus spatial показывает close + comments + links (production parity). */
.detail[data-mode="spatial"] .detail-authoring-actions { display: none; }
.detail[data-mode="spatial"] .mol-editable-text {
  caret-color: transparent;
}
.detail[data-mode="spatial"] .mol-editable-text:empty {
  display: none;
}

/* close / comments / links / spotlight видны только в spatial.
   В authoring (creation of new vertex) они скрыты — поле фокусировано
   на вводе title/intent + actions Save/Cancel. */
.detail[data-mode="authoring"] .detail-close,
.detail[data-mode="authoring"] .detail-comments,
.detail[data-mode="authoring"] .detail-links-label,
.detail[data-mode="authoring"] .detail-links,
.detail[data-mode="authoring"] .detail-spotlight {
  display: none;
}
.detail[data-mode="persisted"] .detail-close,
.detail[data-mode="persisted"] .detail-comments,
.detail[data-mode="persisted"] .detail-links-label,
.detail[data-mode="persisted"] .detail-links,
.detail[data-mode="persisted"] .detail-spotlight {
  display: none;
}
/* Spatial — show close button (overrides default .detail-close{display:none}).
   detail-links / detail-links-label для spatial variant DS уже скрыты
   (см. .detail[data-variant="spatial"] .detail-links{display:none} выше),
   связи показываются через отдельный relationship-arc-switcher слева. */
.detail[data-mode="spatial"] .detail-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: auto;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  background: none;
  color: color-mix(in srgb, var(--text), transparent 40%);
  font-size: 22px;
  font-weight: 400;
  line-height: 1;
  border-radius: 50%;
  cursor: pointer;
  transition: color 180ms ease, background-color 180ms ease;
}
.detail[data-mode="spatial"] .detail-close:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--text), transparent 92%);
}

/* Reset button в controls. */
.mol-controls [data-vertex-reset] {
  padding: 6px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--text);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 160ms ease, border-color 160ms ease;
}
.mol-controls [data-vertex-reset]:hover {
  background: color-mix(in srgb, var(--shell), var(--text) 8%);
}

/* ========================================================================= */
/* Wizard pattern — ghost cursor + contextual hints для онбординга           */
/* ========================================================================= */

/* ── Molecule: wizard fog — canvas + backdrop-filter blur. Изначально
   весь stage под fog'ом (опаковый canvas + blur backdrop'a сзади),
   как «туман войны» / «замёрзшее стекло». Cursor движется → erase
   destination-out → fog рассеивается ПОД курсором, оставляя clear-след.
   След накапливается: куда уже двигали ghost / user cursor — там fog'a нет.
   Работает в обеих темах (canvas рисует semi-opaque base, blur — на фоне). */
/* Wizard backdrop — чистый blur без цветной подложки. Mask управляется
   JS'ом из wireWizard: накапливается trail вокруг wizard cursor (всегда
   растёт) + trail вокруг user cursor (растёт пока user рядом с wizard'ом,
   decay'ит когда уходит за PROXIMITY_PX). mask-composite: intersect →
   pixel transparent если transparent хотя бы в одном слое (внутри любой
   trail точки). Initial mask приходит из JS при wire. */
.mol-wizard-fog {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  mask-composite: intersect;
  -webkit-mask-composite: source-in;
  transition: opacity 360ms ease, backdrop-filter 360ms ease;
}
/* fogClear — для step'ов где пользователь должен ясно видеть нижний слой
   (drag-to-rotate sphere, click на конкретный element). Blur полностью
   отключается; ghost cursor + hint остаются. */
.mol-wizard-fog.cleared {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* ── Molecule: ghost cursor — full-stage cursor lens overlay + центральный
   marker. Визуально идентичен реальному cursor lens (radial gradient
   с centred-at-cursor), но с двумя distinguishing features:
   1) Пульсирующая opacity (1.6s ease-in-out) — реальный lens статичен
   2) Центральный marker-dot — у реального cursor lens'а его нет
   Position через --ghost-x / --ghost-y (px relative to stage); JS
   плавно лерпит координаты через rAF для эффекта «движения курсора». */
.mol-ghost-cursor {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;  /* внутри .org-wizard — выше backdrop, ниже marker/hint */
  /* Halo вокруг cursor — accent цвет (production coral).
     ВАЖНО: НЕ использовать mix-blend-mode — оно создаёт isolation stacking
     context на .org-wizard, и backdrop-filter в .mol-wizard-fog перестаёт
     видеть sphere/floating-bg под overlay'ем (blur пропадает).
     Pulse animation даёт жизни. Visible UI element, не fog backdrop. */
  background: radial-gradient(
    circle 240px at var(--ghost-x, 50%) var(--ghost-y, 50%),
    color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), transparent 56%) 0%,
    color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), transparent 82%) 30%,
    transparent 60%
  );
  animation: ghostLensBreath 1.6s ease-in-out infinite;
}
@keyframes ghostLensBreath {
  0%, 100% { opacity: 0.65; }
  50%      { opacity: 1.00; }
}
/* User cursor halo — accent glow вокруг реального курсора пользователя в
   wizard режиме. Использует --halo-rgb (production accent, по умолчанию
   coral) — цветной как floating background halos. Чуть мягче ghost lens'a
   чтобы wizard cursor оставался primary visual anchor. */
.mol-user-cursor {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;  /* тот же слой что ghost lens */
  background: radial-gradient(
    circle 180px at var(--user-x, -200px) var(--user-y, -200px),
    color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), transparent 60%) 0%,
    color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), transparent 84%) 35%,
    transparent 65%
  );
}

/* Marker — точка-прицел в центре ghost lens'a. Анимация пульсации
   синхронна с lens'ом, размер 8px с soft glow. */
.mol-ghost-cursor__marker {
  position: absolute;
  z-index: 3;  /* выше ghost lens'a */
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  /* Marker — accent цвет для контраста с halo. Глаз сразу видит куда
     указывает wizard. */
  background: rgb(var(--halo-rgb, 255, 107, 87));
  box-shadow: 0 0 14px rgb(var(--halo-rgb, 255, 107, 87));
  left: var(--ghost-x, 50%);
  top: var(--ghost-y, 50%);
  animation: ghostMarkerPulse 1.6s ease-in-out infinite;
  pointer-events: none;
}
@keyframes ghostMarkerPulse {
  0%, 100% { transform: scale(0.78); opacity: 0.78; }
  50%      { transform: scale(1.18); opacity: 1.00; }
}

/* Clickable variant — для wizard intro click-target step'ов. Marker
   принимает pointer events, расширяет hit area через ::after (48px),
   показывает курсор pointer. JS toggle'ит через .clickable class. */
.mol-ghost-cursor__marker.clickable {
  pointer-events: auto;
  cursor: pointer;
}
.mol-ghost-cursor__marker.clickable::after {
  content: '';
  position: absolute;
  inset: -22px;        /* расширяет hit area до 48px вокруг 8px marker'a */
  border-radius: 50%;
  pointer-events: auto;
}

/* ── Molecule: wizard hint — spatial text + pulsing accent marker. ──
   Distinguishing features (отличает от обычного текста):
   - Слева pulsing accent dot (синхронно с ghost cursor pulse)
   - Цвет: accent-tinted (color-mix с accent 18%)
   - Чуть меньше body (14px vs 17-18px), letter-spacing 0.005em */
.mol-wizard-hint {
  position: absolute;
  z-index: 4;  /* внутри .org-wizard — выше backdrop/ghost/marker */
  display: block;
  width: max-content;
  max-width: min(260px, calc(100vw - 48px));
  padding: 0 8px;
  text-align: center;
  /* Hint расположен ПОД ghost cursor'ом. Horizontal alignment управляется
     через --hint-tx (JS читает позицию ghost и выбирает: -50% для центра,
     0 для align-start у левого края, -100% для align-end у правого). */
  left: var(--ghost-x, 50%);
  top: var(--ghost-y, 50%);
  transform: translate(var(--hint-tx, -50%), 32px);
  pointer-events: none;
  transition: opacity 240ms ease;
  opacity: 0;
}
.mol-wizard-hint.visible {
  opacity: 1;
}
.mol-wizard-hint__marker {
  width: 6px;
  height: 6px;
  margin-top: 7px;
  border-radius: 50%;
  background: rgb(var(--halo-rgb, 255, 107, 87));
  box-shadow: 0 0 10px rgb(var(--halo-rgb, 255, 107, 87));
  animation: ghostBreath 1.6s ease-in-out infinite;
}
.mol-wizard-hint__text {
  font-size: 14px;
  font-weight: 540;
  line-height: 1.42;
  letter-spacing: 0.005em;
  /* Нейтральный текст hint'a — без accent tint. */
  color: var(--flight-text, var(--text));
}

/* ── Organism: wizard overlay — контейнер для ghost cursor + hint.
   Накладывается поверх stage'a, не блокирует pointer events. */
.org-wizard {
  position: absolute;
  inset: 0;
  z-index: 11;
  pointer-events: none;
  opacity: 0;
  transition: opacity 220ms ease;
}
.org-wizard.visible { opacity: 1; }

/* Туман (mol-wizard-fog) виден ТОЛЬКО когда ghost cursor двигается.
   Когда стоит — wizard "молча подсказывает", без фокус-эффекта.
   `.moving` class toggle'ится JS в animateGhostTo (organisms.js).
   Default — fog скрыт; во время движения — поднимается. */
.org-wizard .mol-wizard-fog {
  opacity: 0;
  transition: opacity 280ms ease;
}
.org-wizard.moving .mol-wizard-fog {
  opacity: 1;
}

/* Minimized state — wizard в левом верхнем углу, blur выключен, hint скрыт.
   Marker остаётся видим (с halo) как индикатор «помощник доступен».
   На .hover (proximity к marker'у) wizard раскрывается обратно. */
.org-wizard.minimized .mol-wizard-fog {
  opacity: 0;
  transition: opacity 320ms ease;
}
.org-wizard.minimized .mol-ghost-cursor {
  opacity: 0.55;
  transition: opacity 320ms ease;
}
/* Hint остаётся видимым в minimized — wizard в углу постоянно показывает
   «что делать дальше». Текст слегка деэмфазирован (opacity 0.78), на hover
   полная яркость. */
.org-wizard.minimized .mol-wizard-hint {
  opacity: 0.85 !important;
  pointer-events: none;
}
.org-wizard.minimized .mol-user-cursor {
  opacity: 0;
}
.org-wizard.minimized.hover .mol-wizard-fog {
  opacity: 1;
}
.org-wizard.minimized.hover .mol-ghost-cursor {
  opacity: 1;
}
.org-wizard.minimized.hover .mol-wizard-hint {
  opacity: 1 !important;
}
.org-wizard.minimized.hover .mol-user-cursor {
  opacity: 1;
}

/* ── Реальный cursor lens — следует за курсором пользователя.
   Используется в любом stage'е (wireCursorLens). Визуально идентичен
   ghost cursor'у: radial gradient halo + центральная dot для точного
   targeting'а (см. ghostMarkerPulse). */
.mol-cursor-lens {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 11;
  /* Halo вокруг курсора, размером сопоставим с vertex halo (atom-halo,
     --halo-size: 184px diameter + 11px blur ≈ 220px effective glow).
     Radius 110px = diameter 220px — визуально matches размеру halo
     вокруг созданной вершины. Плавный многоступенчатый gradient. */
  background: radial-gradient(
    circle 110px at var(--lens-x, 50%) var(--lens-y, 50%),
    color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), transparent 40%) 0%,
    color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), transparent 62%) 18%,
    color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), transparent 82%) 42%,
    color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), transparent 95%) 65%,
    transparent 85%
  );
  /* mix-blend-mode: screen убран — создаёт isolation stacking context,
     который мог конфликтовать с backdrop-filter сверху и был слабо
     различим на light theme. Plain source-over даёт стабильный glow. */
  opacity: 0;
  transition: opacity 220ms ease;
}
/* visible class задаётся wireCursorLens на pointermove. Breathing
   animation идентична .mol-ghost-cursor — pulse 1.6s ease-in-out,
   opacity 0.65 ↔ 1.0. Визуально lens теперь like wizard ghost cursor. */
.mol-cursor-lens.visible {
  opacity: 1;
  animation: ghostLensBreath 1.6s ease-in-out infinite;
}
/* Центральная dot — точечный target для precise targeting'а. Reuse
   ghostMarkerPulse keyframes от wizard marker. Position через
   --lens-x/-y CSS vars (set'ятся wireCursorLens на pointermove).
   Размер 8px + soft glow — идентичен wizard ghost marker'у. */
.mol-cursor-lens.visible::after {
  content: '';
  position: absolute;
  left: var(--lens-x, 50%);
  top: var(--lens-y, 50%);
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: rgb(var(--halo-rgb, 255, 107, 87));
  box-shadow: 0 0 14px rgb(var(--halo-rgb, 255, 107, 87));
  pointer-events: none;
  animation: ghostMarkerPulse 1.6s ease-in-out infinite;
}

/* ── Showcase stage для wizard demo ── */
.org-wizard-demo-stage {
  position: relative;
  min-height: 420px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(circle at 30% 36%, color-mix(in srgb, var(--accent-day), white 78%), transparent 56%),
    radial-gradient(circle at 76% 70%, color-mix(in srgb, var(--accent-year), white 88%), transparent 62%),
    linear-gradient(135deg, #faf6ee 0%, #f0ebe1 48%, #e6dfd2 100%);
  color: var(--text);
}
body.dark .org-wizard-demo-stage {
  background:
    radial-gradient(circle at 30% 36%, rgba(74, 92, 168, 0.38), transparent 56%),
    radial-gradient(circle at 76% 70%, rgba(108, 70, 178, 0.34), transparent 62%),
    linear-gradient(135deg, #0c1027 0%, #0a0d1f 48%, #06070f 100%);
  color: rgba(245, 247, 255, 0.92);
}
.org-wizard-demo-canvas {
  position: absolute;
  inset: 0;
}
.org-wizard-demo-canvas [data-wizard-target] {
  position: absolute;
  transform: translate(-50%, -50%);
}

/* ========================================================================= */
/* Organism · Edge Create — long-drag создание связи между двумя вершинами  */
/* ========================================================================= */

.org-edge-create-stage {
  /* Spatial scene — те же тёмные/светлые backdrop'ы что и vertex-create. */
  position: relative;
  min-height: 540px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(circle at 30% 36%, color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), white 78%), transparent 56%),
    radial-gradient(circle at 76% 70%, color-mix(in srgb, rgb(var(--halo-rgb, 255, 107, 87)), white 88%), transparent 62%),
    linear-gradient(135deg, #faf6ee 0%, #f0ebe1 48%, #e6dfd2 100%);
  color: var(--text);
  touch-action: none;
  user-select: none;
}
body.dark .org-edge-create-stage {
  background:
    radial-gradient(circle at 28% 32%, rgba(53, 70, 130, 0.42), transparent 58%),
    radial-gradient(circle at 78% 72%, rgba(94, 60, 158, 0.34), transparent 64%),
    linear-gradient(135deg, #0c1027 0%, #0a0d1f 48%, #06070f 100%);
  color: rgba(245, 247, 255, 0.92);
}

.org-edge-create-stage > .org-detail-sphere {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}
.org-edge-create-edges {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 2;
}
.org-edge-create-nodes {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}
.org-edge-create-node {
  position: absolute;
  display: grid;
  place-items: center;
  pointer-events: auto;
  cursor: grab;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  /* Position через CSS variables — bridge'и (level1) обновляют --node-x/-y
     каждый rAF через _sphereControl.onFrame projection. translate(-50%, -50%)
     центрирует marker на projected screen point.
     --node-scale (default 1) обновляется per-frame на основе cameraDistance:
     при zoom-out все ноды уменьшаются (production-faithful distance fade).
     Hover/armed/target-hover умножают scale через CSS calc внутри transform. */
  left: 0; top: 0;
  transform: translate3d(calc(var(--node-x, 0px) - 50%), calc(var(--node-y, 0px) - 50%), 0)
             scale(var(--node-scale, 1));
  transition: opacity 220ms ease;
  will-change: transform, opacity;
}
.org-edge-create-node:hover {
  transform: translate3d(calc(var(--node-x, 0px) - 50%), calc(var(--node-y, 0px) - 50%), 0)
             scale(calc(var(--node-scale, 1) * 1.06));
}
.org-edge-create-node[data-armed="true"] {
  cursor: grabbing;
  transform: translate(-50%, -50%) scale(1.18);
}
.org-edge-create-node[data-armed="true"] > .mol-node-mark {
  filter: brightness(1.15) saturate(1.2);
}
.org-edge-create-node[data-target-hover="true"] {
  transform: translate(-50%, -50%) scale(1.24);
}
.org-edge-create-node[data-target-hover="true"] > .mol-node-mark {
  filter: brightness(1.25) saturate(1.3);
}

/* Edge line (in-progress drag) — pulsing accent stroke, soft glow. */
.org-edge-create-edges path[data-edge-drag] {
  fill: none;
  stroke: rgb(var(--edge-rgb, 255, 107, 87));
  stroke-width: 2;
  stroke-linecap: round;
  filter: drop-shadow(0 0 6px rgb(var(--edge-rgb, 255, 107, 87)));
  opacity: 0.9;
  pointer-events: none;
}
/* Persisted edge — постоянная линия после commit'a, чуть тоньше. */
.org-edge-create-edges path[data-edge-persisted] {
  fill: none;
  stroke: rgb(var(--edge-rgb, 255, 107, 87));
  stroke-width: 1.4;
  stroke-linecap: round;
  filter: drop-shadow(0 0 4px rgb(var(--edge-rgb, 255, 107, 87)));
  opacity: 0.65;
  pointer-events: none;
}

/* Hint в idle, гаснет в priming/armed. */
.org-edge-create-hint {
  position: absolute;
  left: 50%;
  bottom: 18px;
  z-index: 6;
  transform: translateX(-50%);
  color: color-mix(in srgb, var(--text), transparent 50%);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  pointer-events: none;
  transition: opacity 220ms ease;
}
body.dark .org-edge-create-hint {
  color: color-mix(in srgb, rgba(245, 247, 255, 0.6), transparent 30%);
}
.org-edge-create-stage[data-state="armed"] .org-edge-create-hint,
.org-edge-create-stage[data-state="priming"] .org-edge-create-hint {
  opacity: 0.3;
}
