Created
August 24, 2026 14:36
-
-
Save netlooker/a97493497df1f64baca44a5e1b34781e to your computer and use it in GitHub Desktop.
Prototyp 01
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="pl"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Radar Sytuacyjny Zespołu — Od Sygnału do Rozwiązania</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com"> | |
| <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> | |
| <script> | |
| tailwind.config = { | |
| theme: { | |
| extend: { | |
| fontFamily: { | |
| sans: ['Plus Jakarta Sans', 'sans-serif'], | |
| mono: ['JetBrains Mono', 'monospace'], | |
| }, | |
| colors: { | |
| primary: { | |
| 50: '#eef2ff', | |
| 100: '#e0e7ff', | |
| 500: '#6366f1', | |
| 600: '#4f46e5', | |
| 700: '#4338ca', | |
| 900: '#312e81', | |
| } | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| <style> | |
| .custom-slider { | |
| -webkit-appearance: none; | |
| width: 100%; | |
| height: 8px; | |
| border-radius: 5px; | |
| background: #e2e8f0; | |
| outline: none; | |
| } | |
| .custom-slider::-webkit-slider-thumb { | |
| -webkit-appearance: none; | |
| appearance: none; | |
| width: 24px; | |
| height: 24px; | |
| border-radius: 50%; | |
| background: #4f46e5; | |
| cursor: pointer; | |
| box-shadow: 0 4px 6px -1px rgba(79, 70, 229, 0.4); | |
| transition: all 0.2s; | |
| } | |
| .custom-slider::-webkit-slider-thumb:hover { | |
| transform: scale(1.15); | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-slate-50 text-slate-900 font-sans min-h-screen flex flex-col antialiased selection:bg-primary-500 selection:text-white"> | |
| <!-- TOP NAVIGATION BAR --> | |
| <header class="bg-white border-b border-slate-200/80 sticky top-0 z-40"> | |
| <div class="max-w-5xl mx-auto px-4 sm:px-6 h-16 flex items-center justify-between"> | |
| <div class="flex items-center space-x-3"> | |
| <div class="h-9 w-9 rounded-xl bg-gradient-to-tr from-primary-600 to-indigo-500 flex items-center justify-center text-white font-bold shadow-md shadow-primary-500/20"> | |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg> | |
| </div> | |
| <div> | |
| <span class="text-sm font-bold tracking-tight text-slate-900 block leading-tight">Radar Sytuacyjny Zespołu</span> | |
| <span class="text-[11px] font-medium text-slate-500">Bezpieczna nawigacja po trudnych sytuacjach w pracy</span> | |
| </div> | |
| </div> | |
| <!-- EXPERT TOGGLE --> | |
| <div class="flex items-center gap-3"> | |
| <label class="flex items-center gap-2 cursor-pointer bg-slate-100 hover:bg-slate-200/70 transition-colors px-3 py-1.5 rounded-full border border-slate-200"> | |
| <input type="checkbox" id="expertModeToggle" onchange="toggleExpertMode()" class="sr-only peer"> | |
| <div class="w-7 h-4 bg-slate-300 peer-checked:bg-primary-600 rounded-full peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-3 after:w-3 after:transition-all relative"></div> | |
| <span class="text-xs font-semibold text-slate-600 peer-checked:text-primary-900">Tryb Eksperta (3iM Backend)</span> | |
| </label> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- PROGRESS BAR --> | |
| <div class="bg-white border-b border-slate-200/60"> | |
| <div class="max-w-5xl mx-auto px-4 sm:px-6 py-3"> | |
| <div class="flex items-center justify-between text-xs font-semibold text-slate-500 mb-2"> | |
| <span id="stepIndicatorLabel">KROK 1 Z 4: Wybór sygnału</span> | |
| <span id="stepPercentLabel" class="font-mono text-primary-600">25%</span> | |
| </div> | |
| <div class="w-full bg-slate-100 h-2 rounded-full overflow-hidden"> | |
| <div id="progressBarFill" class="bg-primary-600 h-full w-1/4 transition-all duration-300 ease-out"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- MAIN CONTAINER --> | |
| <main class="flex-1 max-w-5xl w-full mx-auto px-4 sm:px-6 py-8 flex flex-col justify-center"> | |
| <!-- ========================================== --> | |
| <!-- KROK 1: WYBÓR SYGNAŁU POTOCZNEGO --> | |
| <!-- ========================================== --> | |
| <section id="step1" class="space-y-6"> | |
| <div class="text-center max-w-xl mx-auto space-y-2"> | |
| <span class="text-xs font-bold uppercase tracking-wider text-primary-600 bg-primary-50 px-3 py-1 rounded-full border border-primary-100">Punkt Wyjścia</span> | |
| <h1 class="text-2xl sm:text-3xl font-bold text-slate-900 tracking-tight">Coś w zespole nie gra? Nazwij to po swojemu.</h1> | |
| <p class="text-sm text-slate-600">Wybierz sformułowanie, które najlepiej oddaje Twoje codzienne odczucie z pracy. Bez oceniania ludzi — sprawdzamy zasady gry.</p> | |
| </div> | |
| <!-- SEARCH / FILTER --> | |
| <div class="max-w-xl mx-auto relative"> | |
| <input type="text" id="signalSearch" oninput="filterSignals()" placeholder="Szukaj (np. decyzje, szef, procedury, odpowiedzialność)..." class="w-full pl-10 pr-4 py-2.5 text-sm bg-white border border-slate-300 rounded-xl shadow-sm focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500"> | |
| <svg class="w-4 h-4 text-slate-400 absolute left-3.5 top-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg> | |
| </div> | |
| <!-- SIGNAL CARDS GRID --> | |
| <div id="signalsGrid" class="grid grid-cols-1 md:grid-cols-2 gap-3 max-w-3xl mx-auto max-h-[380px] overflow-y-auto p-1"> | |
| <!-- Injected by JS --> | |
| </div> | |
| <!-- INTENSITY & CONTEXT CARD (APPEARS ONCE SELECTED) --> | |
| <div id="selectedSignalConfig" class="max-w-3xl mx-auto bg-white p-6 rounded-2xl border border-primary-200 shadow-lg shadow-primary-500/5 space-y-5 hidden"> | |
| <div class="flex items-start justify-between border-b border-slate-100 pb-3"> | |
| <div> | |
| <span class="text-xs font-semibold text-primary-600 uppercase tracking-wider">Wybrana obserwacja</span> | |
| <h3 id="cfgSignalTitle" class="text-lg font-bold text-slate-900 mt-0.5"></h3> | |
| </div> | |
| <span class="text-xs font-mono bg-slate-100 text-slate-600 px-2.5 py-1 rounded-md" id="cfgSignalId">SIG-052</span> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div> | |
| <div class="flex justify-between items-center mb-2"> | |
| <label class="text-xs font-semibold text-slate-700">Jak mocno to odczuwasz? (1-10)</label> | |
| <span id="cfgIntensityVal" class="text-base font-bold font-mono text-primary-600 bg-primary-50 px-2.5 py-0.5 rounded-lg">8 / 10</span> | |
| </div> | |
| <input type="range" id="cfgIntensitySlider" min="1" max="10" value="8" oninput="updateIntensity(this.value)" class="custom-slider"> | |
| <div class="flex justify-between text-[10px] text-slate-400 mt-1 font-medium"> | |
| <span>Sporadycznie</span> | |
| <span>Często</span> | |
| <span>Notorycznie (paraliż)</span> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="text-xs font-semibold text-slate-700 block mb-2">Od jak dawna to trwa?</label> | |
| <select id="cfgTimeframe" class="w-full text-xs font-medium bg-slate-50 border border-slate-200 rounded-xl px-3 py-2.5 focus:bg-white focus:ring-2 focus:ring-primary-500"> | |
| <option>Pojedynczy incydent na ostatnim spotkaniu</option> | |
| <option selected>Powtarza się od kilku tygodni / miesięcy</option> | |
| <option>To stały, utrwalony zwyczaj w tej firmie</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="pt-2 flex justify-end"> | |
| <button onclick="goToStep(2)" class="w-full sm:w-auto px-6 py-3 bg-primary-600 hover:bg-primary-700 text-white text-sm font-semibold rounded-xl shadow-md shadow-primary-500/20 transition-all flex items-center justify-center gap-2"> | |
| Doprecyzujmy sytuację → | |
| </button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- ========================================== --> | |
| <!-- KROK 2: DOPRECYZOWANIE ZNACZENIA --> | |
| <!-- ========================================== --> | |
| <section id="step2" class="max-w-2xl mx-auto space-y-6 hidden"> | |
| <div class="text-center space-y-2"> | |
| <span class="text-xs font-bold uppercase tracking-wider text-primary-600 bg-primary-50 px-3 py-1 rounded-full border border-primary-100">Sprawdzenie Zrozumienia</span> | |
| <h2 class="text-2xl font-bold text-slate-900 tracking-tight">Czy dobrze rozumiemy, co masz na myśli?</h2> | |
| <p class="text-sm text-slate-600">Aplikacja odrzuca emocje i skupia się na faktach organizacyjnych.</p> | |
| </div> | |
| <div class="bg-white p-6 rounded-2xl border border-slate-200 shadow-sm space-y-5"> | |
| <div class="p-4 bg-slate-50 border border-slate-200 rounded-xl space-y-1.5"> | |
| <span class="text-xs font-semibold text-slate-500 uppercase tracking-wider">Neutralny opis zarządczy:</span> | |
| <p id="step2ClarificationText" class="text-sm font-semibold text-slate-800 leading-relaxed"></p> | |
| </div> | |
| <div class="space-y-3"> | |
| <label class="text-xs font-bold text-slate-700 block">Czy ten opis pasuje do Twojej sytuacji?</label> | |
| <div class="space-y-2"> | |
| <label class="flex items-center gap-3 p-3 border border-slate-200 rounded-xl cursor-pointer hover:bg-slate-50 transition-colors"> | |
| <input type="radio" name="confirmMeaning" value="exact" checked class="accent-primary-600"> | |
| <span class="text-xs font-medium text-slate-800">Tak, dokładnie o to chodzi w praktyce.</span> | |
| </label> | |
| <label class="flex items-center gap-3 p-3 border border-slate-200 rounded-xl cursor-pointer hover:bg-slate-50 transition-colors"> | |
| <input type="radio" name="confirmMeaning" value="partial" class="accent-primary-600"> | |
| <span class="text-xs font-medium text-slate-800">Częściowo — sytuacja jest bardziej złożona.</span> | |
| </label> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="text-xs font-semibold text-slate-700 block mb-1.5">Krótki przykład z życia (opcjonalnie, bez nazwisk):</label> | |
| <input type="text" id="step2UserExample" placeholder="np. Na zebraniu odrzucono wyliczenia kosztów, bo dyrektor miał inną wizję" class="w-full text-xs bg-slate-50 border border-slate-200 rounded-xl p-3 focus:bg-white focus:ring-2 focus:ring-primary-500"> | |
| </div> | |
| <div class="pt-3 flex justify-between items-center border-t border-slate-100"> | |
| <button onclick="goToStep(1)" class="px-4 py-2 text-xs font-semibold text-slate-600 hover:text-slate-900"> | |
| ← Wróć do wyboru | |
| </button> | |
| <button onclick="goToStep(3)" class="px-6 py-2.5 bg-primary-600 hover:bg-primary-700 text-white text-xs font-semibold rounded-xl shadow-md transition-all"> | |
| Przejdź do 3 kluczowych pytań → | |
| </button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- ========================================== --> | |
| <!-- KROK 3: 3 KLUCZOWE PYTANIA (PRYZMAT) --> | |
| <!-- ========================================== --> | |
| <section id="step3" class="max-w-2xl mx-auto space-y-6 hidden"> | |
| <div class="text-center space-y-2"> | |
| <span class="text-xs font-bold uppercase tracking-wider text-primary-600 bg-primary-50 px-3 py-1 rounded-full border border-primary-100">3 Wymiary Sytuacji</span> | |
| <h2 class="text-2xl font-bold text-slate-900 tracking-tight">Jak wygląda tło tej sytuacji?</h2> | |
| <p class="text-sm text-slate-600">Odpowiedz na 3 krótkie pytania, aby sprawdzić mechanizm decyzyjny.</p> | |
| </div> | |
| <div class="bg-white p-6 rounded-2xl border border-slate-200 shadow-sm space-y-6"> | |
| <!-- PYTANIE 1: WIEDZA --> | |
| <div class="space-y-2"> | |
| <div class="flex items-center gap-2 text-xs font-bold text-slate-800"> | |
| <span class="h-5 w-5 rounded-full bg-emerald-100 text-emerald-700 flex items-center justify-center text-[10px]">1</span> | |
| <span>FAKTY I WIEDZA: Czy zespół dysponował twardymi danymi lub raportami?</span> | |
| </div> | |
| <select id="qKnowledge" class="w-full text-xs bg-slate-50 border border-slate-200 rounded-xl p-3 font-medium focus:bg-white focus:ring-2 focus:ring-primary-500"> | |
| <option value="yes_ignored">Dane i analizy były na stole, ale zostały zignorowane</option> | |
| <option value="no_data">Nikt nie przygotował twardych danych — opierano się na intuicji</option> | |
| <option value="data_accepted">Dane zostały uwzględnione, ale przeważył inny czynnik</option> | |
| </select> | |
| </div> | |
| <!-- PYTANIE 2: WARTOŚCI / ZASADY --> | |
| <div class="space-y-2"> | |
| <div class="flex items-center gap-2 text-xs font-bold text-slate-800"> | |
| <span class="h-5 w-5 rounded-full bg-amber-100 text-amber-700 flex items-center justify-center text-[10px]">2</span> | |
| <span>KRYTERIUM: Co w praktyce okazało się najważniejsze przy rozstrzygnięciu?</span> | |
| </div> | |
| <select id="qValues" class="w-full text-xs bg-slate-50 border border-slate-200 rounded-xl p-3 font-medium focus:bg-white focus:ring-2 focus:ring-primary-500"> | |
| <option value="hierarchy">Autorytet formalny i racja osoby wyżej postawionej</option> | |
| <option value="belonging">Lojalność i przynależność do grupy zaufanej („swój-obcy”)</option> | |
| <option value="speed">Tempo i pozorna aktywność (byle odhaczyć zadanie)</option> | |
| <option value="merit">Rzeczywisty zysk merytoryczny i optymalizacja projektu</option> | |
| </select> | |
| </div> | |
| <!-- PYTANIE 3: WPŁYW / WŁADZA --> | |
| <div class="space-y-2"> | |
| <div class="flex items-center gap-2 text-xs font-bold text-slate-800"> | |
| <span class="h-5 w-5 rounded-full bg-purple-100 text-purple-700 flex items-center justify-center text-[10px]">3</span> | |
| <span>PRAWO SPRZECIWU: Kto mógł bezpiecznie zgłosić wątpliwość lub zatrzymać decyzję?</span> | |
| </div> | |
| <select id="qInfluence" class="w-full text-xs bg-slate-50 border border-slate-200 rounded-xl p-3 font-medium focus:bg-white focus:ring-2 focus:ring-primary-500"> | |
| <option value="monopoly">Tylko jedna osoba / ścisłe kierownictwo (monopol)</option> | |
| <option value="nobody">Nikt — procedury wymusiły bieg sprawy mimo wątpliwości</option> | |
| <option value="everyone">Każdy miał głos, ale nikt nie chciał wziąć odpowiedzialności</option> | |
| </select> | |
| </div> | |
| <div class="pt-3 flex justify-between items-center border-t border-slate-100"> | |
| <button onclick="goToStep(2)" class="px-4 py-2 text-xs font-semibold text-slate-600 hover:text-slate-900"> | |
| ← Wstecz | |
| </button> | |
| <button onclick="goToStep(4)" class="px-6 py-2.5 bg-primary-600 hover:bg-primary-700 text-white text-xs font-semibold rounded-xl shadow-md transition-all"> | |
| Wygeneruj Raport Sytuacyjny → | |
| </button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- ========================================== --> | |
| <!-- KROK 4: WYNIK („KARTY NA STÓŁ”) --> | |
| <!-- ========================================== --> | |
| <section id="step4" class="max-w-3xl mx-auto space-y-6 hidden"> | |
| <div class="text-center space-y-2"> | |
| <span class="text-xs font-bold uppercase tracking-wider text-emerald-700 bg-emerald-50 px-3 py-1 rounded-full border border-emerald-200">Karty na Stół</span> | |
| <h2 class="text-2xl sm:text-3xl font-bold text-slate-900 tracking-tight">Rozpoznany Wzorzec Zespołowy</h2> | |
| <p class="text-sm text-slate-600">To nie jest ocena charakteru ludzi. To opis mechanizmu, który utrudnia Wam współpracę.</p> | |
| </div> | |
| <!-- RESULT CARD --> | |
| <div class="bg-white p-6 sm:p-8 rounded-3xl border border-slate-200 shadow-xl shadow-slate-200/50 space-y-6"> | |
| <!-- HEADER WITH MECHANISM NAME --> | |
| <div class="flex flex-col sm:flex-row sm:items-center justify-between gap-3 border-b border-slate-100 pb-5"> | |
| <div> | |
| <span class="text-xs font-bold text-primary-600 uppercase tracking-wider block">Główny Mechanizm</span> | |
| <h3 id="resMechanismTitle" class="text-xl sm:text-2xl font-bold text-slate-900 mt-1"></h3> | |
| </div> | |
| <div class="text-left sm:text-right"> | |
| <span class="text-[11px] font-semibold text-slate-400 block uppercase">Nasilenie wzorca</span> | |
| <span id="resIntensityBadge" class="inline-block mt-0.5 text-xs font-bold font-mono px-3 py-1 bg-amber-100 text-amber-900 rounded-full border border-amber-200">WYSOKIE (8/10)</span> | |
| </div> | |
| </div> | |
| <!-- CRUMPLE ZONE HIGHLIGHT (STREFA ZGNIOTU) --> | |
| <div class="p-4 rounded-2xl bg-amber-50/80 border border-amber-200/80 space-y-1.5"> | |
| <div class="flex items-center gap-2 text-xs font-bold text-amber-950"> | |
| <svg class="w-4 h-4 text-amber-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg> | |
| Niewidzialne Pęknięcie (Rozbieżność Deklaracji z Praktyką) | |
| </div> | |
| <p id="resCrumpleDescription" class="text-xs text-amber-900 leading-relaxed"></p> | |
| </div> | |
| <!-- 2 COLS: WHAT TO CHECK & COUNTER-HYPOTHESIS --> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| <div class="p-4 rounded-2xl bg-slate-50 border border-slate-200 space-y-2"> | |
| <span class="text-xs font-bold text-slate-900 flex items-center gap-1.5"> | |
| <span class="h-2 w-2 rounded-full bg-primary-600"></span> | |
| Co warto sprawdzić w zespole? | |
| </span> | |
| <p id="resDeepeningQuestion" class="text-xs text-slate-600 leading-relaxed font-medium"></p> | |
| </div> | |
| <div class="p-4 rounded-2xl bg-slate-50 border border-slate-200 space-y-2"> | |
| <span class="text-xs font-bold text-slate-900 flex items-center gap-1.5"> | |
| <span class="h-2 w-2 rounded-full bg-slate-400"></span> | |
| Druga strona medalu (Alternatywne wyjaśnienie) | |
| </span> | |
| <p id="resCounterHypothesis" class="text-xs text-slate-600 leading-relaxed"></p> | |
| </div> | |
| </div> | |
| <!-- CONSTRUCTIVE NEXT STEPS --> | |
| <div class="p-4 rounded-2xl bg-emerald-50/70 border border-emerald-200 space-y-2"> | |
| <span class="text-xs font-bold text-emerald-950 flex items-center gap-1.5"> | |
| <svg class="w-4 h-4 text-emerald-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg> | |
| Rekomendowany krok naprawczy | |
| </span> | |
| <p id="resIntervention" class="text-xs text-emerald-900 leading-relaxed font-medium"></p> | |
| </div> | |
| <!-- FOOTER ACTIONS --> | |
| <div class="pt-4 flex flex-col sm:flex-row items-center justify-between gap-3 border-t border-slate-100"> | |
| <button onclick="goToStep(1)" class="w-full sm:w-auto px-4 py-2.5 text-xs font-semibold text-slate-600 hover:text-slate-900"> | |
| ← Rozpocznij nową analizę | |
| </button> | |
| <button onclick="printReport()" class="w-full sm:w-auto px-6 py-2.5 bg-slate-900 hover:bg-slate-800 text-white text-xs font-semibold rounded-xl shadow transition-all flex items-center justify-center gap-2"> | |
| <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z"/></svg> | |
| Drukuj / Zapisz Kartę Sytuacji | |
| </button> | |
| </div> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- ========================================== --> | |
| <!-- DRAWER TRYBU EKSPERTA (ONTOLOGIA W TLE) --> | |
| <!-- ========================================== --> | |
| <aside id="expertDrawer" class="fixed bottom-0 right-0 w-full lg:w-[480px] max-h-[85vh] bg-slate-950 text-slate-200 border-l border-t border-slate-800 rounded-tl-3xl shadow-2xl z-50 p-6 space-y-4 overflow-y-auto transform translate-y-full transition-transform duration-300"> | |
| <div class="flex items-center justify-between border-b border-slate-800 pb-3"> | |
| <div class="flex items-center gap-2"> | |
| <span class="h-2 w-2 rounded-full bg-emerald-400 animate-pulse"></span> | |
| <span class="text-xs font-mono font-bold text-slate-100 uppercase tracking-wider">3iM Backend Architecture</span> | |
| </div> | |
| <button onclick="document.getElementById('expertModeToggle').click()" class="text-slate-400 hover:text-white text-xs font-mono">Zamknij [x]</button> | |
| </div> | |
| <div class="space-y-3 text-xs font-mono"> | |
| <div class="bg-slate-900 p-3 rounded-xl border border-slate-800 space-y-1"> | |
| <span class="text-[10px] text-slate-500 uppercase">Mapowanie Ontologiczne (DDD Context):</span> | |
| <div class="text-emerald-400">Node: <span id="expCardId">im:Card_052</span></div> | |
| <div class="text-indigo-400">Syndrome ID: <span id="expSyndromeId">im:A1 (Czyje na Wierzchu)</span></div> | |
| </div> | |
| <div class="grid grid-cols-2 gap-2 text-[11px]"> | |
| <div class="p-2.5 bg-orange-950/40 border border-orange-800/60 rounded-lg text-orange-200"> | |
| <span class="text-[9px] text-orange-400 block font-bold">im:wwRelation</span> | |
| <span id="expWW">Maskarada (Ocena → Fakt)</span> | |
| </div> | |
| <div class="p-2.5 bg-purple-950/40 border border-purple-800/60 rounded-lg text-purple-200"> | |
| <span class="text-[9px] text-purple-400 block font-bold">im:influenceRelation</span> | |
| <span id="expInf">Monopol na decyzję</span> | |
| </div> | |
| </div> | |
| <div class="bg-slate-900 p-3 rounded-xl border border-slate-800 space-y-1"> | |
| <span class="text-[10px] text-slate-500 uppercase">Serializacja Semantyczna (Turtle RDF):</span> | |
| <pre id="expTTLCode" class="text-[10px] text-slate-300 overflow-x-auto p-2 bg-slate-950 rounded border border-slate-850 h-32 leading-relaxed select-all"></pre> | |
| </div> | |
| </div> | |
| </aside> | |
| <!-- JS ENGINE --> | |
| <script> | |
| const SIGNALS_DB = [ | |
| { | |
| id: 'SIG-052', | |
| phrase: 'Szef zawsze ma rację', | |
| tags: 'decyzje władza hierarchia', | |
| clarification: 'Argumenty merytoryczne i wyliczenia są wycofywane lub ignorowane, jeśli przełożony zajął już inne stanowisko.', | |
| mechanism: 'Przewaga pozycji nad argumentami (Syndrom „Czyje na Wierzchu”)[cite: 4, 5, 9, 10]', | |
| syndromeCode: 'A1', | |
| crumple: 'W firmie oficjalnie deklaruje się „podejmowanie decyzji na podstawie danych”, ale w praktyce decyduje wyłącznie hierarchia i autorytet stanowiska[cite: 4, 5, 12].', | |
| deepening: 'W którym momencie merytoryczna rozmowa o opłacalności zamieniła się w walkę o autorytet i rację[cite: 9, 10]?', | |
| counter: 'Czy sytuacja nie wymagała jednoosobowej, natychmiastowej decyzji ze względu na nagły kryzys lub odpowiedzialność prawną[cite: 2, 5, 6, 10]?', | |
| intervention: 'Wprowadzenie zasady „Karty na Stół”: przed podjęciem decyzji spisuje się rekomendacje merytoryczne bez znajomości zdania szefa[cite: 1, 5, 10, 15].' | |
| }, | |
| { | |
| id: 'SIG-051', | |
| phrase: 'Swój to swój (Podział na grupy)', | |
| tags: 'plemienność zaufanie kolesiostwo', | |
| clarification: 'Ocena pracy, pomysłów lub ludzi zależy od przynależności do określonego kręgu zaufania, a nie od rzeczywistych kompetencji[cite: 4, 5, 9, 10].', | |
| mechanism: 'Filtr przynależności grupowej (Syndrom Plemienności)[cite: 4, 5, 9, 10]', | |
| syndromeCode: 'A2', | |
| crumple: 'Oficjalnie obowiązują równe szanse i transparentność, ale w rzeczywistości dostęp do kluczowych projektów mają tylko „swoi”[cite: 4, 5, 10].', | |
| deepening: 'W którym miejscu kryterium „czy to nasz człowiek” zastąpiło kryterium „czy to rzetelna praca”[cite: 4, 5, 9, 10]?', | |
| counter: 'Czy preferowanie sprawdzonych osób nie wynika z wcześniejszych bolesnych doświadczeń z nieterminowymi podwykonawcami[cite: 2, 5, 6, 10]?', | |
| intervention: 'Wprowadzenie obiektywnych, jawnych wskaźników oceny efektów dostępnych dla każdego członka zespołu[cite: 5, 10].' | |
| }, | |
| { | |
| id: 'SIG-021', | |
| phrase: 'Ktoś musi być winny (Szukanie kozła ofiarnego)', | |
| tags: 'błędy wina porażka bezpieczeństwo', | |
| clarification: 'Po wystąpieniu błędu uwaga skupia się na wskazaniu i ukaraniu konkretnej osoby zamiast na naprawie procedury[cite: 4, 5, 9, 10].', | |
| mechanism: 'Personalizacja błędu systemowego (Syndrom Czarownicy)[cite: 4, 5, 9, 10]', | |
| syndromeCode: 'A3', | |
| crumple: 'Deklaruje się „kulturę ciągłego uczenia się i zaufania”, ale w momencie błędu natychmiast szuka się winnego[cite: 4, 5, 10, 16].', | |
| deepening: 'Jaki brak w procedurze lub narzędziu umożliwił powstanie tego błędu i dlaczego nie został wcześniej wykryty[cite: 9, 10]?', | |
| counter: 'Czy nie doszło do celowego, rażącego zaniedbania podstawowych obowiązków przez pracownika[cite: 2, 5, 6, 10]?', | |
| intervention: 'Format spotkań Post-Mortem bez nazwisk: analiza ścieżki procesu od zdarzenia do luki w infrastrukturze[cite: 3, 5, 10].' | |
| }, | |
| { | |
| id: 'SIG-050', | |
| phrase: 'Spotkanie za spotkaniem, mało konkretów', | |
| tags: 'czas bezproduktywność spotkania raporty', | |
| clarification: 'Widoczna aktywność, wielogodzinne spotkania i raporty zastępują realne dostarczanie wartości i rezultatów[cite: 4, 5, 9, 10].', | |
| mechanism: 'Pozorowanie ruchu (Syndrom Pustych Taczek)[cite: 4, 5, 9, 10]', | |
| syndromeCode: 'A7', | |
| crumple: 'Firma stawia na „efektywność i wyniki”, ale w praktyce premiuje obecność na zebraniach i grube raporty[cite: 4, 5, 9, 10].', | |
| deepening: 'Jaki konkretny, sprawdzalny rezultat został dostarczony po ostatniej serii zebrań[cite: 9, 10]?', | |
| counter: 'Czy wielość spotkań nie wynika z konieczności nagłej synchronizacji wielu działów w trakcie fuzji lub audytu[cite: 2, 5, 6, 10]?', | |
| intervention: 'Reguła: brak agendy z oczekiwaną decyzją = brak spotkania. Limit czasu spotkań do 25 minut[cite: 5, 10].' | |
| }, | |
| { | |
| id: 'SIG-035', | |
| phrase: 'Nie wiadomo, kto za to odpowiada', | |
| tags: 'odpowiedzialność silosy spychologia', | |
| clarification: 'Odpowiedzialność rozmywa się między działami; każdy pilnuje swojego wąskiego wycinka i unika całości[cite: 4, 5, 9, 10].', | |
| mechanism: 'Ochrona własnego podwórka (Syndrom Własnych Zabawek)[cite: 4, 5, 9, 10]', | |
| syndromeCode: 'A4', | |
| crumple: 'Deklaruje się współpracę międzyzespołową, ale cele roczne rozliczają wyłącznie z lokalnych wskaźników działu[cite: 4, 5, 9, 10].', | |
| deepening: 'Co tracą pracownicy poszczególnych działów, gdy dzielą się informacjami lub narzędziami z innymi[cite: 9, 10]?', | |
| counter: 'Czy brak właściciela procesu nie wynika z niedawnej reorientacji struktury firmy[cite: 2, 5, 6, 10]?', | |
| intervention: 'Powołanie jednoosobowego właściciela całego procesu end-to-end z uprawnieniem do rozstrzygania sporów[cite: 5, 10].' | |
| }, | |
| { | |
| id: 'SIG-069', | |
| phrase: 'Wszyscy wiedzą, ale nikt nic nie robi', | |
| tags: 'bierność bezradność tabu', | |
| clarification: 'Wszyscy mają świadomość nieskuteczności obecnego rozwiązania, lecz brak kanału wpływu paraliżuje reakcję[cite: 4, 5, 9, 10].', | |
| mechanism: 'Utrwalona bezradność (Syndrom Wkręcanego Gwoździa)[cite: 4, 5, 9, 10]', | |
| syndromeCode: 'A8', | |
| crumple: 'Mówi się o innowacyjności, ale próby zgłaszania usprawnień kończą się uwagą, że „tak było zawsze”.', | |
| deepening: 'Kto w zespole ma realne prawo do zatrzymania nieskutecznej procedury bez ryzyka sankcji[cite: 1, 9, 10, 13, 14, 16]?', | |
| counter: 'Czy brak zmian nie wynika z ograniczeń licencyjnych lub prawnych, których zespół nie zna[cite: 2, 5, 6, 10]?', | |
| intervention: 'Uruchomienie bezpiecznego kanału zgłaszania wątpliwości z obowiązkiem publicznej odpowiedzi zarządu[cite: 10, 13, 14].' | |
| } | |
| ]; | |
| let state = { | |
| selectedSignal: null, | |
| intensity: 8, | |
| timeframe: '', | |
| step: 1 | |
| }; | |
| function init() { | |
| renderSignals(SIGNALS_DB); | |
| selectSignal('SIG-052'); // Domyślny wybór na start | |
| } | |
| function renderSignals(list) { | |
| const grid = document.getElementById('signalsGrid'); | |
| grid.innerHTML = ''; | |
| list.forEach(sig => { | |
| const isSel = state.selectedSignal && state.selectedSignal.id === sig.id; | |
| const card = document.createElement('div'); | |
| card.className = `p-4 rounded-xl border transition-all cursor-pointer flex items-center justify-between ${ | |
| isSel ? 'bg-primary-50 border-primary-500 ring-2 ring-primary-500/20 shadow-sm' : 'bg-white border-slate-200 hover:border-slate-300 hover:bg-slate-50/70' | |
| }`; | |
| card.onclick = () => selectSignal(sig.id); | |
| card.innerHTML = ` | |
| <div> | |
| <span class="text-xs font-bold text-slate-900 block">${sig.phrase}</span> | |
| <span class="text-[11px] text-slate-500">${sig.tags}</span> | |
| </div> | |
| <span class="text-[10px] font-mono font-bold ${isSel ? 'text-primary-600 bg-primary-100' : 'text-slate-400 bg-slate-100'} px-2 py-0.5 rounded"> | |
| ${sig.id} | |
| </span> | |
| `; | |
| grid.appendChild(card); | |
| }); | |
| } | |
| function filterSignals() { | |
| const query = document.getElementById('signalSearch').value.toLowerCase(); | |
| const filtered = SIGNALS_DB.filter(s => | |
| s.phrase.toLowerCase().includes(query) || | |
| s.tags.toLowerCase().includes(query) || | |
| s.id.toLowerCase().includes(query) | |
| ); | |
| renderSignals(filtered); | |
| } | |
| function selectSignal(id) { | |
| state.selectedSignal = SIGNALS_DB.find(s => s.id === id); | |
| renderSignals(SIGNALS_DB); | |
| const cfg = document.getElementById('selectedSignalConfig'); | |
| cfg.classList.remove('hidden'); | |
| document.getElementById('cfgSignalTitle').innerText = `"${state.selectedSignal.phrase}"`; | |
| document.getElementById('cfgSignalId').innerText = state.selectedSignal.id; | |
| updateExpertBackend(); | |
| } | |
| function updateIntensity(val) { | |
| state.intensity = val; | |
| document.getElementById('cfgIntensityVal').innerText = `${val} / 10`; | |
| updateExpertBackend(); | |
| } | |
| function goToStep(stepNum) { | |
| state.step = stepNum; | |
| // Hide all steps | |
| for (let i = 1; i <= 4; i++) { | |
| document.getElementById(`step${i}`).classList.add('hidden'); | |
| } | |
| // Show target step | |
| document.getElementById(`step${stepNum}`).classList.remove('hidden'); | |
| // Update Progress Bar | |
| const bar = document.getElementById('progressBarFill'); | |
| const percentLabel = document.getElementById('stepPercentLabel'); | |
| const stepLabel = document.getElementById('stepIndicatorLabel'); | |
| const perc = (stepNum / 4) * 100; | |
| bar.style.width = `${perc}%`; | |
| percentLabel.innerText = `${perc}%`; | |
| if (stepNum === 1) stepLabel.innerText = 'KROK 1 Z 4: Wybór sygnału'; | |
| if (stepNum === 2) { | |
| stepLabel.innerText = 'KROK 2 Z 4: Doprecyzowanie sytuacji'; | |
| document.getElementById('step2ClarificationText').innerText = state.selectedSignal.clarification; | |
| } | |
| if (stepNum === 3) stepLabel.innerText = 'KROK 3 Z 4: 3 kluczowe pytania'; | |
| if (stepNum === 4) { | |
| stepLabel.innerText = 'KROK 4 Z 4: Gotowa diagnoza'; | |
| renderFinalReport(); | |
| } | |
| updateExpertBackend(); | |
| window.scrollTo({ top: 0, behavior: 'smooth' }); | |
| } | |
| function renderFinalReport() { | |
| const sig = state.selectedSignal; | |
| document.getElementById('resMechanismTitle').innerText = sig.mechanism; | |
| document.getElementById('resIntensityBadge').innerText = `NASILENIE: ${state.intensity} / 10`; | |
| document.getElementById('resCrumpleDescription').innerText = sig.crumple; | |
| document.getElementById('resDeepeningQuestion').innerText = sig.deepening; | |
| document.getElementById('resCounterHypothesis').innerText = sig.counter; | |
| document.getElementById('resIntervention').innerText = sig.intervention; | |
| } | |
| function toggleExpertMode() { | |
| const isChecked = document.getElementById('expertModeToggle').checked; | |
| const drawer = document.getElementById('expertDrawer'); | |
| if (isChecked) { | |
| drawer.classList.remove('translate-y-full'); | |
| } else { | |
| drawer.classList.add('translate-y-full'); | |
| } | |
| } | |
| function updateExpertBackend() { | |
| if (!state.selectedSignal) return; | |
| const sig = state.selectedSignal; | |
| document.getElementById('expCardId').innerText = `im:Card_${sig.id.replace('-', '_')}`; | |
| document.getElementById('expSyndromeId').innerText = `im:${sig.syndromeCode} (${sig.mechanism.split('(')[0].trim()})`; | |
| const ttl = `@prefix im: <http://3im.org/ontology/core#> . | |
| # Rekord wejściowy | |
| im:${sig.id} a im:Signal ; | |
| im:rawText "${sig.phrase}" ; | |
| im:intensity ${state.intensity} . | |
| # Karta Rozpoznania | |
| im:Card_${sig.id.replace('-', '_')} a im:Card ; | |
| im:hasSignal im:${sig.id} ; | |
| im:wwRelation [ a im:wwRelation ; rdfs:label "Maskarada/Filtr" ] ; | |
| im:influenceRelation [ a im:influenceRelation ; rdfs:label "Asymetria Wpływu" ] ; | |
| im:detectsSyndrome im:${sig.syndromeCode} .`; | |
| document.getElementById('expTTLCode').innerText = ttl; | |
| } | |
| function printReport() { | |
| window.print(); | |
| } | |
| window.onload = init; | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment