/* ============================================================
   DUGA UI KIT · 2/3 · КОМПОНЕНТЫ
   Каждый блок независим: можно скопировать только нужную секцию
   (между линиями ═══). Требует duga-tokens.css.
   Все классы с префиксом dm- : не конфликтуют с вашим style.css.
   ============================================================ */

/* ═══════════════ К01 · АВРОРА-ФОН (чистый CSS) ═══════════════
   <div class="dm-aurora"></div>  — первым элементом в body */
.dm-aurora{
  position:fixed;inset:-20%;z-index:0;pointer-events:none;filter:blur(90px);opacity:.5;
  background:
    conic-gradient(from var(--dm-aurora) at 30% 25%, transparent 60%, oklch(65% 0.17 35 / .35) 75%, transparent 90%),
    conic-gradient(from calc(var(--dm-aurora)*-1.4) at 75% 70%, transparent 55%, oklch(60% 0.12 250 / .28) 72%, transparent 88%);
  animation:dm-aurora 26s linear infinite;
}
@keyframes dm-aurora{to{--dm-aurora:360deg}}

/* ═══════════════ К02 · MESH-ФОН (canvas, нужен JS: DugaMotion.mesh) ═══════════════
   <canvas class="dm-mesh" data-dm="mesh"></canvas> */
.dm-mesh{position:fixed;inset:0;z-index:0;opacity:.5;pointer-events:none}

/* ═══════════════ К03 · КОЛЬЦО ИСТОРИИ ═══════════════
   <button class="dm-story [seen]">
     <span class="dm-story-ring"><span class="dm-story-in" style="background:...">М</span></span>
     <span class="dm-story-name">Мама</span></button> */
.dm-story{display:inline-flex;flex-direction:column;align-items:center;gap:6px;font-size:11px;
  color:var(--dm-dim);border:none;background:none;cursor:pointer;font-family:var(--dm-font);
  transition:.3s var(--dm-spring-soft)}
.dm-story:hover{transform:translateY(-3px)}
.dm-story-ring{width:58px;height:58px;border-radius:50%;padding:3px;position:relative;display:block}
.dm-story-ring::before{content:"";position:absolute;inset:0;border-radius:50%;
  background:conic-gradient(from var(--dm-ring), var(--dm-coral), oklch(70% 0.2 350), oklch(75% 0.16 80), var(--dm-coral));
  animation:dm-spin 4s linear infinite}
.dm-story.seen .dm-story-ring::before{background:var(--dm-line2);animation:none}
.dm-story-in{position:relative;width:100%;height:100%;border-radius:50%;border:3px solid var(--dm-bg);
  display:grid;place-items:center;font-weight:800;color:#fff;font-size:17px}
@keyframes dm-spin{to{--dm-ring:360deg}}

/* ═══════════════ К04 · ПУЗЫРИ СООБЩЕНИЙ ═══════════════
   <div class="dm-msg in|out">
     <div class="dm-bubble">Текст</div>
     <div class="dm-meta">18:05 <span class="dm-tick read">✓✓</span> 🔒</div>
   </div>
   Контейнер ленты: display:flex;flex-direction:column. */
.dm-msg{max-width:min(70%,600px);display:flex;flex-direction:column;position:relative;
  font-family:var(--dm-font);animation:dm-msg-in .55s var(--dm-spring-pop) backwards}
.dm-msg.in{align-self:flex-start}.dm-msg.out{align-self:flex-end}
@keyframes dm-msg-in{from{opacity:0;transform:translateY(16px) scale(.94)}}
.dm-bubble{padding:10px 14px;border-radius:20px;position:relative;overflow-wrap:anywhere;
  color:var(--dm-text);transition:transform .2s var(--dm-spring-soft)}
.dm-msg.in .dm-bubble{background:var(--dm-bubble-in);border:1px solid var(--dm-line);
  border-bottom-left-radius:7px;backdrop-filter:blur(10px)}
.dm-msg.out .dm-bubble{color:var(--dm-ink);border-bottom-right-radius:7px;
  background:linear-gradient(135deg,var(--dm-coral-hot),var(--dm-coral) 60%, oklch(66% 0.19 25));
  background-attachment:fixed; /* градиент «течёт» сквозь все пузыри как одно полотно */
  box-shadow:0 6px 20px oklch(70% 0.19 35 / .25)}
.dm-bubble:active{transform:scale(.98)}
.dm-meta{display:flex;gap:5px;font-size:10.5px;color:var(--dm-dim2);justify-content:flex-end;
  margin-top:3px;align-items:center}
.dm-tick{display:inline-block}
.dm-msg.out .dm-tick{color:var(--dm-coral)}
.dm-tick.read{animation:dm-tickpop .4s var(--dm-spring-pop)}
@keyframes dm-tickpop{50%{transform:scale(1.4)}}

/* ═══════════════ К05 · РЕАКЦИИ-ЧИПЫ ═══════════════
   <div class="dm-reacts"><span class="dm-rc my">❤️ 1</span></div>  (после .dm-bubble) */
.dm-reacts{display:flex;gap:5px;margin-top:6px}
.dm-rc{background:var(--dm-glass-hard);border:1px solid var(--dm-line2);border-radius:99px;
  padding:2px 9px;font-size:12.5px;display:flex;gap:4px;align-items:center;cursor:pointer;
  color:var(--dm-text);transition:.25s var(--dm-spring-pop)}
.dm-rc:hover{transform:scale(1.15) rotate(-4deg)}
.dm-rc.my{border-color:var(--dm-coral);background:oklch(70% 0.19 35 / .15)}

/* ═══════════════ К06 · «ПЕЧАТАЕТ…» (жидкие точки) ═══════════════
   <div class="dm-typing"><i></i><i></i><i></i></div> */
.dm-typing{align-self:flex-start;display:inline-flex;gap:5px;padding:13px 16px;
  background:var(--dm-bubble-in);border:1px solid var(--dm-line);border-radius:20px;
  border-bottom-left-radius:7px}
.dm-typing i{width:8px;height:8px;border-radius:50%;background:var(--dm-dim);
  animation:dm-liquid 1.3s ease-in-out infinite}
.dm-typing i:nth-child(2){animation-delay:.16s}.dm-typing i:nth-child(3){animation-delay:.32s}
@keyframes dm-liquid{0%,60%,100%{transform:translateY(0) scale(1);opacity:.4}
  30%{transform:translateY(-7px) scale(1.25);opacity:1}}

/* ═══════════════ К07 · ГОЛОСОВОЕ С ЖИВОЙ ВОЛНОЙ ═══════════════
   <div class="dm-voice" data-dm="voice"> — JS сам построит палочки
     <button class="dm-vplay">▶</button><div class="dm-wave"></div><span class="dm-vtime">0:19</span>
   </div>   клик по .dm-voice — волна оживает (класс playing) */
.dm-voice{display:flex;align-items:center;gap:10px;min-width:240px;cursor:pointer}
.dm-vplay{width:36px;height:36px;border-radius:50%;background:oklch(0% 0 0/.16);border:none;
  color:inherit;cursor:pointer;display:grid;place-items:center;flex:none;transition:.3s var(--dm-spring-pop)}
.dm-vplay:hover{transform:scale(1.12)}
.dm-wave{display:flex;align-items:center;gap:2.5px;height:30px;flex:1}
.dm-wave i{width:3px;border-radius:3px;background:currentColor;opacity:.6;height:6px}
.dm-voice.playing .dm-wave i{animation:dm-wave 1s ease-in-out infinite}
.dm-vtime{font-size:11px;opacity:.7}
@keyframes dm-wave{50%{transform:scaleY(2.6);opacity:1}}

/* ═══════════════ К08 · БЕЙДЖИ E2E / МАРШРУТ ═══════════════
   <span class="dm-badge e2e">🔒 E2E · сверено</span>
   <span class="dm-badge rt">📶 локальная сеть · 12 мс</span> */
.dm-badge{font-size:11px;font-weight:700;padding:3px 10px;border-radius:99px;
  display:inline-flex;gap:5px;align-items:center;cursor:pointer;font-family:var(--dm-font);
  transition:.25s var(--dm-spring-soft);border:1px solid transparent}
.dm-badge:hover{transform:translateY(-1px)}
.dm-badge.e2e{background:oklch(65% 0.12 175 / .16);color:oklch(78% 0.12 175)}
.dm-badge.rt{background:oklch(65% 0.12 250 / .14);color:oklch(78% 0.1 250)}
[data-theme=light] .dm-badge.e2e{color:oklch(45% 0.12 175)}
[data-theme=light] .dm-badge.rt{color:oklch(45% 0.1 250)}

/* ═══════════════ К09 · ВИДЖЕТ «ПУТЬ СООБЩЕНИЯ» ═══════════════
   Разметку смотри в snippets/08 — svg-кривая + узлы + .dm-pulse-dot.
   Импульс летит по кривой через offset-path. */
.dm-routecard{width:min(430px,92%);background:var(--dm-glass-hard);border:1px solid var(--dm-line2);
  border-radius:var(--dm-r-l);padding:16px;backdrop-filter:blur(18px);box-shadow:var(--dm-shadow);
  font-family:var(--dm-font);color:var(--dm-text);animation:dm-msg-in .5s var(--dm-spring-pop)}
.dm-routecard h5{font-size:13px;margin:0 0 12px;display:flex;gap:8px;align-items:center}
.dm-route-line{position:relative;height:64px}
.dm-route-line svg{width:100%;height:100%;overflow:visible}
.dm-rnode{position:absolute;top:8px;width:40px;height:40px;border-radius:50%;
  background:var(--dm-glass-hard);border:1px solid var(--dm-line2);display:grid;place-items:center;
  font-size:16px;translate:-50% 0}
.dm-rnode.on{border-color:var(--dm-coral);box-shadow:0 0 14px oklch(70% 0.19 35/.4)}
.dm-rlabel{position:absolute;top:52px;font-size:10.5px;color:var(--dm-dim);translate:-50% 0;white-space:nowrap}
.dm-pulse-dot{position:absolute;width:10px;height:10px;border-radius:50%;background:var(--dm-coral);
  box-shadow:0 0 12px var(--dm-coral);
  offset-path:path("M 20 28 C 120 -8, 240 64, 380 28");offset-rotate:0deg;
  animation:dm-ride 2.4s cubic-bezier(.45,0,.55,1) infinite}
@keyframes dm-ride{0%{offset-distance:0%;opacity:0}12%{opacity:1}88%{opacity:1}100%{offset-distance:100%;opacity:0}}
.dm-routenote{font-size:11.5px;color:var(--dm-dim);margin-top:8px}

/* ═══════════════ К10 · ДИНАМИЧЕСКИЙ ОСТРОВОК ═══════════════
   Вызывается из JS: DugaMotion.island('текст')  — сам появится и уйдёт */
.dm-island{position:absolute;top:14px;left:50%;translate:-50% 0;z-index:30;display:flex;
  align-items:center;gap:10px;background:var(--dm-glass-hard);backdrop-filter:blur(20px);
  border:1px solid var(--dm-line2);border-radius:99px;padding:9px 18px;font-size:13px;
  font-weight:650;font-family:var(--dm-font);color:var(--dm-text);box-shadow:var(--dm-shadow);
  animation:dm-island .6s var(--dm-spring-pop);white-space:nowrap}
.dm-island.hide{animation:dm-islandOut .4s ease forwards}
@keyframes dm-island{from{transform:translateY(-56px) scale(.6);opacity:0}}
@keyframes dm-islandOut{to{transform:translateY(-56px) scale(.6);opacity:0}}

/* ═══════════════ К11 · КОМПОЗЕР + КНОПКА-ПРУЖИНА ═══════════════
   <div class="dm-cbox"><input ...><button class="dm-emo">😊</button></div>
   <button class="dm-send">↑</button>  (JS flipSend анимирует отправку) */
.dm-cbox{display:flex;align-items:center;gap:8px;background:var(--dm-glass-hard);
  border:1px solid var(--dm-line2);border-radius:24px;padding:6px 8px 6px 16px;
  transition:.3s var(--dm-spring-soft);font-family:var(--dm-font)}
.dm-cbox:focus-within{border-color:var(--dm-coral);box-shadow:0 0 0 4px oklch(70% 0.19 35/.14);
  transform:translateY(-1px)}
.dm-cbox input{flex:1;background:none;border:none;outline:none;color:var(--dm-text);
  font:inherit;padding:8px 0;min-width:0}
.dm-emo{border:none;background:none;cursor:pointer;font-size:17px}
.dm-send{width:46px;height:46px;border-radius:50%;display:grid;place-items:center;border:none;
  cursor:pointer;color:var(--dm-ink);flex:none;
  background:linear-gradient(135deg,var(--dm-coral-hot),var(--dm-coral));
  transition:.35s var(--dm-spring-pop);box-shadow:0 6px 18px oklch(70% 0.19 35/.35)}
.dm-send:hover{transform:scale(1.1) rotate(-8deg)}
.dm-send:active{transform:scale(.88)}
.dm-send.sent{animation:dm-sendpop .5s var(--dm-spring-pop)}
@keyframes dm-sendpop{40%{transform:scale(1.28) rotate(8deg)}}

/* ═══════════════ К12 · РАДИАЛЬНЫЙ ПОПОВЕР РЕАКЦИЙ ═══════════════
   Создаётся из JS: DugaMotion.attachReactions(контейнер) */
.dm-rpop{position:fixed;z-index:70;display:flex;gap:4px;background:var(--dm-glass-hard);
  border:1px solid var(--dm-line2);border-radius:99px;padding:6px;backdrop-filter:blur(20px);
  box-shadow:var(--dm-shadow);animation:dm-rpop .45s var(--dm-spring-pop)}
@keyframes dm-rpop{from{transform:scale(.4);opacity:0}}
.dm-rpop button{width:38px;height:38px;border-radius:50%;font-size:19px;border:none;
  background:none;cursor:pointer;display:grid;place-items:center;transition:.25s var(--dm-spring-pop)}
.dm-rpop button:hover{transform:scale(1.35) translateY(-4px);background:var(--dm-glass)}

/* частица для burst (создаёт JS) */
.dm-pt{position:fixed;z-index:60;pointer-events:none;font-size:18px;will-change:transform,opacity}

/* ═══════════════ К13 · СМЕНА ТЕМЫ ВОЛНОЙ ═══════════════
   <div class="dm-wipe" id="dmWipe"></div> + JS DugaMotion.themeSwipe(event) */
.dm-wipe{position:fixed;inset:0;z-index:100;pointer-events:none;
  clip-path:circle(0 at var(--dm-wx,90%) var(--dm-wy,10%))}
.dm-wipe.go{transition:clip-path .7s cubic-bezier(.4,0,.2,1);
  clip-path:circle(150% at var(--dm-wx,90%) var(--dm-wy,10%))}

/* ═══════════════ К14 · ЭЛЕМЕНТ СПИСКА ЧАТОВ ═══════════════
   <button class="dm-chat [act]"> <span class="dm-ava" style="background:...">М<i class="dm-on"></i></span>
     <span class="dm-chat-col"><span class="dm-chat-1">Имя<b class="dm-chat-tm">21:40</b></span>
     <span class="dm-chat-2">превью<b class="dm-un">2</b></span></span></button> */
.dm-chat{display:flex;gap:12px;align-items:center;padding:11px 12px;border-radius:var(--dm-r-m);
  text-align:left;border:none;background:none;cursor:pointer;width:100%;position:relative;
  font-family:var(--dm-font);color:var(--dm-text);transition:.28s var(--dm-spring-soft);
  animation:dm-rise .5s var(--dm-spring-pop) backwards}
@keyframes dm-rise{from{opacity:0;transform:translateY(14px) scale(.97)}}
.dm-chat:hover{background:var(--dm-glass-hard);transform:translateX(3px)}
.dm-chat.act{background:var(--dm-glass-hard)}
.dm-chat.act::before{content:"";position:absolute;left:-2px;top:18px;bottom:18px;width:3px;
  border-radius:99px;background:var(--dm-coral);box-shadow:0 0 12px var(--dm-coral)}
.dm-ava{width:48px;height:48px;border-radius:50%;display:grid;place-items:center;font-weight:800;
  color:#fff;flex:none;position:relative}
.dm-on{position:absolute;right:0;bottom:0;width:12px;height:12px;border-radius:50%;
  background:#3fbf7f;border:2.5px solid var(--dm-bg);animation:dm-pulse 2.4s infinite}
@keyframes dm-pulse{50%{box-shadow:0 0 0 5px oklch(70% 0.18 155 / .25)}}
.dm-chat-col{flex:1;min-width:0;display:block}
.dm-chat-1{display:flex;align-items:center;gap:6px;font-weight:750;font-size:14.5px}
.dm-chat-tm{margin-left:auto;font-size:11px;color:var(--dm-dim2);font-weight:600}
.dm-chat-2{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--dm-dim);margin-top:2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dm-un{margin-left:auto;min-width:20px;height:20px;border-radius:99px;background:var(--dm-coral);
  color:var(--dm-ink);display:grid;place-items:center;font-size:11px;font-weight:800;padding:0 6px;
  flex:none;font-style:normal;animation:dm-unpop .5s var(--dm-spring-pop)}
@keyframes dm-unpop{from{transform:scale(0)}}

/* ═══════════════ К15 · СКЕЛЕТОН-ШИММЕР ═══════════════
   <div class="dm-skel" style="width:200px;height:16px"></div> */
.dm-skel{border-radius:14px;background:linear-gradient(100deg,var(--dm-bubble-in) 40%,
  var(--dm-glass-hard) 50%,var(--dm-bubble-in) 60%);background-size:220% 100%;
  animation:dm-shimmer 1.4s linear infinite}
@keyframes dm-shimmer{to{background-position:-120% 0}}

/* ═══════════════ К16 · СТЕКЛЯННАЯ ПАНЕЛЬ (универсальная) ═══════════════
   <div class="dm-glass-panel">…</div> */
.dm-glass-panel{background:var(--dm-glass-hard);border:1px solid var(--dm-line2);
  border-radius:var(--dm-r-l);backdrop-filter:blur(24px) saturate(1.4);box-shadow:var(--dm-shadow);
  color:var(--dm-text);font-family:var(--dm-font)}
