diff --git a/network-poc/hub/nodes.db b/network-poc/hub/nodes.db index 7cf2122..e6efe86 100644 Binary files a/network-poc/hub/nodes.db and b/network-poc/hub/nodes.db differ diff --git a/network-poc/static/avatars/README.md b/network-poc/static/avatars/README.md new file mode 100644 index 0000000..b5f7c11 --- /dev/null +++ b/network-poc/static/avatars/README.md @@ -0,0 +1,34 @@ +# Kipinä Agentic Playground - Animaatioiden käyttöönotto + +Koska Kipinä-verkon agenttien avatarit tällä erää ovat staattisia PNG-kuvatiedostoja, käyttöliittymä hyödyntää CSS-pohjaista pomppimisilmiötä (sekä pulppuavaa 💬 puhekuplaa) "puhumisen" merkkinä. Olemme kuitenkin koodanneet taustalle piilotetun tuen aivioiduille videoloopeille myöhempää käyttöä varten! + +Näin saat UI:n tukemaan oikeasti animoituja kasvoja/videoita. + +## 1. Luo Animoidut GIF-tiedostot +Valitse mikä tahansa ulkoinen AI-työkalu (kuten HeyGen, Pika v1.0, tai Midjourney+Runway yhdistelmä) ja muunna avatar-kuvat (esim. `kettu_notext.png`) 3-5 sekunnin kestäviksi GIF-loopeiksi. Hahmon leuka tulisi pyöriä tai naama vääntyillä puhuessaan. + +## 2. Nimeä Tiedostot Oikein ja Lisää Ne Kansioon +Siirrä uudet GIF-animaatiot samaan kansioon alkuperäisten kuvien kanssa. Muuta niiden nimi siten, että se päättyy tunnisteeseen `_puhuva.gif`. + +Esimerkkejä: +- Koodari `kipina_notext.png` → `kipina_notext_puhuva.gif` +- Manageri `karhunpentu.png` → `karhunpentu_puhuva.gif` +- Asiakas `kettu_notext.png` → `kettu_notext_puhuva.gif` + +## 3. Aktivoi Koodi +Käännä Kipinä Playground -ohjaimen JavaScript-koodista piilotettu ominaisuus päälle. + +Etsi tiedostosta `../index.html` (noin riviltä 1084, `updatePromptEditor`-funktiosta): +```javascript +// Piilotettu ominaisuus: Puhuvien videoiden / gif-animaatioiden kytkentä +window.USE_ANIMATED_GIFS = false; +``` +Muuta tuo `false` arvoon `true`: +```javascript +window.USE_ANIMATED_GIFS = true; +``` + +**Mitä logiikka tekee?** +Aina kun valitset agentin kaaviosta, koodi korvaa aktiivisen kuvakkeen lopussa olevan `.png` -päätteen sanalla `_puhuva.gif` – lennosta! Jos poistut agentin valinnasta tai valitset jonkun toisen, koodi vaihtaa kuvan välittömästi takaisin staattiseen `.png`-versioon ja sulkee ilmentymän suun. + +Näin saat kaikkien asiantuntijoiden face-track looppeja hallittua yhdellä kädenkäänteellä. diff --git a/network-poc/static/avatars/forge_hero.svg b/network-poc/static/avatars/forge_hero.svg deleted file mode 100644 index 6bba7a3..0000000 --- a/network-poc/static/avatars/forge_hero.svg +++ /dev/null @@ -1,44 +0,0 @@ - diff --git a/network-poc/static/avatars/lizard_ai.svg b/network-poc/static/avatars/lizard_ai.svg deleted file mode 100644 index 43d1cba..0000000 --- a/network-poc/static/avatars/lizard_ai.svg +++ /dev/null @@ -1,54 +0,0 @@ - diff --git a/network-poc/static/avatars/raccoon_ai.svg b/network-poc/static/avatars/raccoon_ai.svg deleted file mode 100644 index 5e9d292..0000000 --- a/network-poc/static/avatars/raccoon_ai.svg +++ /dev/null @@ -1,66 +0,0 @@ - diff --git a/network-poc/static/avatars/sloth_ai.svg b/network-poc/static/avatars/sloth_ai.svg deleted file mode 100644 index 1194b47..0000000 --- a/network-poc/static/avatars/sloth_ai.svg +++ /dev/null @@ -1,49 +0,0 @@ - diff --git a/network-poc/static/index.html b/network-poc/static/index.html index 3747a83..ffd3030 100644 --- a/network-poc/static/index.html +++ b/network-poc/static/index.html @@ -393,6 +393,7 @@ align-items: center; margin-bottom: 40px; perspective: 1000px; + padding: 25px 50px; } .org-level { display: flex; @@ -439,6 +440,18 @@ border-color: rgba(240, 246, 252, 0.3); box-shadow: 0 12px 20px rgba(0,0,0,0.4); } + @keyframes idle-breathe { + 0%, 100% { transform: translateY(0) scale(1); } + 50% { transform: translateY(-2px) scale(1.01); } + } + @keyframes talking-head { + 0% { transform: scale(1.05) scaleY(1) translateY(0); } + 25% { transform: scale(1.05) scaleY(0.96) scaleX(1.02) translateY(2px); } + 50% { transform: scale(1.05) scaleY(1.02) scaleX(0.98) translateY(-2px); } + 75% { transform: scale(1.05) scaleY(0.97) scaleX(1.01) translateY(1px); } + 100% { transform: scale(1.05) scaleY(1) translateY(0); } + } + .avatar-card img { width: 80px; height: 80px; @@ -448,7 +461,10 @@ transition: all 0.4s ease; object-fit: cover; background: #010409; + animation: idle-breathe 4s infinite ease-in-out; + transform-origin: bottom center; } + .avatar-card.active, .avatar-card.selected { opacity: 1; transform: translateY(-8px) scale(1.05); @@ -457,10 +473,134 @@ box-shadow: 0 16px 24px rgba(0,0,0,0.5), 0 0 20px rgba(88, 166, 255, 0.3); z-index: 2; } - .avatar-card.active img, .avatar-card.selected img { + + .avatar-card.selected img { border-color: var(--accent-color); box-shadow: 0 0 25px rgba(88, 166, 255, 0.5); transform: scale(1.05); + animation: none; + } + + .avatar-card.active img { + border-color: var(--accent-color); + box-shadow: 0 0 25px rgba(88, 166, 255, 0.8); + animation: talking-head 0.4s infinite ease-in-out; + transform-origin: bottom center; + } + @keyframes talking-head-gallery { + 0% { transform: scaleY(1) translateY(0); } + 25% { transform: scaleY(0.94) scaleX(1.04) translateY(3px); } + 50% { transform: scaleY(1.04) scaleX(0.96) translateY(-3px); } + 75% { transform: scaleY(0.96) scaleX(1.02) translateY(1px); } + 100% { transform: scaleY(1) translateY(0); } + } + .gallery-head { + width: 55px; + height: 55px; + border-radius: 12px; + border: 2px solid rgba(240, 246, 252, 0.1); + object-fit: cover; + background: #010409; + transition: all 0.3s ease; + opacity: 0.4; + filter: grayscale(80%); + } + .gallery-head.active { + opacity: 1; + filter: grayscale(0%); + border-color: var(--accent-color); + box-shadow: 0 0 15px rgba(88, 166, 255, 0.5); + animation: talking-head-gallery 0.4s infinite ease-in-out; + transform-origin: bottom center; + } + + @keyframes confused-shake { + 0% { transform: translateX(0); } + 25% { transform: translateX(-2px) rotate(-3deg); } + 50% { transform: translateX(0); } + 75% { transform: translateX(2px) rotate(3deg); } + 100% { transform: translateX(0); } + } + + .gallery-head-wrap[data-tooltip]::before { + content: attr(data-tooltip); + position: absolute; + bottom: 110%; + left: 50%; + transform: translateX(-50%); + background: rgba(13, 17, 23, 0.95); + color: #f0f6fc; + padding: 8px 12px; + border-radius: 6px; + font-size: 11px; + white-space: pre-wrap; + width: 140px; + text-align: left; + border: 1px solid var(--border-color); + z-index: 100; + opacity: 0; + pointer-events: none; + transition: opacity 0.2s; + box-shadow: 0 4px 12px rgba(0,0,0,0.5); + } + .gallery-head-wrap:hover[data-tooltip]:not([data-tooltip=""])::before { opacity: 1; } + + /* Yhteiset kuplasäännöt */ + .gallery-head-wrap.state-question::after, + .gallery-head-wrap.state-alert::after, + .gallery-head-wrap.active:not(.state-question):not(.state-alert)::after { + position: absolute; + top: -10px; + right: -10px; + font-size: 14px; + width: 24px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + z-index: 10; + } + + /* State: Kysymys (Sininen ?) */ + .gallery-head-wrap.state-question::after { + content: '?'; + color: #ffffff; + font-weight: 900; + font-family: system-ui, -apple-system, sans-serif; + animation: speech-pulse 1s infinite alternate; + background: #1f6feb; border: 1px solid #58a6ff; + } + .gallery-head.state-question { + border-color: #58a6ff; box-shadow: 0 0 15px rgba(88, 166, 255, 0.4); + animation: confused-shake 2s infinite ease-in-out; filter: grayscale(10%); opacity: 0.9; + } + + /* State: Alert (Punainen !) */ + .gallery-head-wrap.state-alert::after { + content: '!'; + color: #ffffff; + font-weight: 900; + font-family: system-ui, -apple-system, sans-serif; + animation: speech-pulse 0.5s infinite alternate; + background: #da3633; border: 1px solid #ff7b72; + } + .gallery-head.state-alert { + border-color: #ff4444; box-shadow: 0 0 15px rgba(255, 68, 68, 0.5); + animation: confused-shake 0.5s infinite; filter: grayscale(30%); opacity: 0.9; + } + + .gallery-head-wrap { position: relative; display: inline-block; cursor: help; } + @keyframes speech-pulse { + 0% { transform: scale(0.8) translateY(0); opacity: 0.6; } + 50% { transform: scale(1.1) translateY(-2px); opacity: 1; } + 100% { transform: scale(0.8) translateY(0); opacity: 0.6; } + } + .gallery-head-wrap.active:not(.state-question):not(.state-alert)::after { + content: '💬'; + animation: speech-pulse 0.8s infinite ease-in-out; + background: #0d1117; + border: 1px solid var(--accent-color); } .avatar-name { font-weight: 700; font-size: 13px; color: #f0f6fc; letter-spacing: 0.5px; margin-bottom: 2px; } .avatar-role { font-size: 10px; color: #8b949e; text-transform: uppercase; letter-spacing: 0.5px; font-weight: 600; line-height: 1.2; word-wrap: break-word; } @@ -523,7 +663,7 @@ #metrics-grid { grid-template-columns: 1fr 1fr !important; } /* Org chart mobile tweaks */ - .org-chart { padding-left: 0; padding-right: 0; } + .org-chart { padding: 20px 10px; } .org-branch { display: none; } .org-connector { margin-bottom: 10px; height: 20px; } .org-level { flex-wrap: wrap; justify-content: center; gap: 15px !important; } @@ -859,75 +999,96 @@ Monitoring Active -