Zamknij

Twój koszyk

Razem: 0.00 zł
Razem z VAT: 0,00 zł
Przejdź do kasy

Heading

<!DOCTYPE html> <html lang="pl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Real Estate Management — Mapa Stanowisk</title> <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@300;400;500;600&family=DM+Mono:wght@400;500&family=Fraunces:ital,wght@0,300;0,600;1,300&display=swap" rel="stylesheet"> <style>   *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }    :root {     --bg: #F4F2EE;     --surface: #FAFAF8;     --core-dark: #1A3A2A;     --core-mid: #2D6A4F;     --core-light: #E8F5EE;     --core-accent: #52B788;     --nc-dark: #2C1810;     --nc-mid: #8B4513;     --nc-light: #FDF0E8;     --nc-accent: #E07B39;     --client-dark: #1A1A3A;     --client-mid: #3A3A8B;     --client-light: #EEEEFF;     --client-accent: #6B6BD4;     --supplier-dark: #0D2626;     --supplier-mid: #1A5C5C;     --supplier-light: #E6F5F5;     --supplier-accent: #3AABAB;     --ink: #1C1C1C;     --ink-soft: #6B6B6B;     --ink-ghost: #ADADAD;     --line: #E0DDD8;     --white: #FFFFFF;   }    body {     font-family: 'DM Sans', sans-serif;     background: var(--bg);     color: var(--ink);     min-height: 100vh;     overflow-x: hidden;   }    /* ── TOP HEADER ──────────────────────────────────────────────────── */   .page-header {     padding: 48px 60px 32px;     border-bottom: 1px solid var(--line);     display: flex;     justify-content: space-between;     align-items: flex-end;     background: var(--surface);   }   .page-header h1 {     font-family: 'Fraunces', serif;     font-size: 36px;     font-weight: 300;     letter-spacing: -0.5px;     line-height: 1.1;     color: var(--ink);   }   .page-header h1 em {     font-style: italic;     color: var(--core-mid);   }   .page-header .meta {     text-align: right;     font-size: 12px;     color: var(--ink-ghost);     font-family: 'DM Mono', monospace;     letter-spacing: 0.05em;     line-height: 1.8;   }    /* ── LEGEND ──────────────────────────────────────────────────────── */   .legend-bar {     display: flex;     gap: 32px;     padding: 16px 60px;     background: var(--surface);     border-bottom: 1px solid var(--line);     align-items: center;     flex-wrap: wrap;   }   .legend-item {     display: flex;     align-items: center;     gap: 8px;     font-size: 12px;     color: var(--ink-soft);     font-family: 'DM Mono', monospace;     letter-spacing: 0.04em;   }   .legend-dot {     width: 10px; height: 10px;     border-radius: 2px;     flex-shrink: 0;   }   .legend-label { font-size: 11px; }    /* ── MAIN LAYOUT ─────────────────────────────────────────────────── */   .canvas {     padding: 48px 60px 60px;     display: flex;     flex-direction: column;     gap: 12px;   }    /* ── AXIS LABEL ──────────────────────────────────────────────────── */   .axis-row {     display: grid;     grid-template-columns: 120px 1fr;     gap: 12px;     align-items: start;   }   .axis-label {     font-family: 'DM Mono', monospace;     font-size: 10px;     letter-spacing: 0.12em;     text-transform: uppercase;     color: var(--ink-ghost);     padding-top: 18px;     text-align: right;     padding-right: 16px;     line-height: 1.4;   }    /* ── SECTION BLOCKS ──────────────────────────────────────────────── */   .section-block {     border-radius: 12px;     overflow: hidden;     border: 1px solid transparent;     transition: all 0.25s ease;   }    .section-header {     display: flex;     align-items: center;     gap: 14px;     padding: 14px 20px;     cursor: pointer;     position: relative;   }   .section-num {     font-family: 'DM Mono', monospace;     font-size: 11px;     font-weight: 500;     opacity: 0.6;     letter-spacing: 0.06em;     min-width: 32px;   }   .section-title {     font-size: 14px;     font-weight: 600;     letter-spacing: -0.2px;     flex: 1;   }   .section-subtitle {     font-size: 11px;     font-weight: 400;     opacity: 0.65;     margin-top: 1px;   }   .section-tag {     font-family: 'DM Mono', monospace;     font-size: 10px;     padding: 3px 8px;     border-radius: 4px;     letter-spacing: 0.06em;     white-space: nowrap;   }   .chevron {     font-size: 12px;     opacity: 0.4;     transition: transform 0.25s ease;     margin-left: 8px;   }   .section-block.open .chevron { transform: rotate(180deg); }    /* ── ROLES GRID ──────────────────────────────────────────────────── */   .roles-panel {     display: none;     padding: 0 20px 20px;     gap: 8px;   }   .section-block.open .roles-panel { display: flex; flex-direction: column; }    /* Sub-perspective header */   .perspective-label {     font-family: 'DM Mono', monospace;     font-size: 10px;     letter-spacing: 0.1em;     text-transform: uppercase;     padding: 10px 0 6px;     border-bottom: 1px solid rgba(0,0,0,0.06);     margin-bottom: 6px;     opacity: 0.7;     display: flex;     align-items: center;     gap: 8px;   }   .perspective-label::before {     content: '';     width: 6px; height: 6px;     border-radius: 50%;     flex-shrink: 0;   }    .roles-grid {     display: grid;     grid-template-columns: repeat(5, 1fr);     gap: 6px;   }    .role-card {     background: rgba(255,255,255,0.7);     border-radius: 8px;     padding: 10px 12px;     border: 1px solid rgba(0,0,0,0.06);     transition: all 0.2s ease;     cursor: default;     position: relative;   }   .role-card:hover {     transform: translateY(-2px);     box-shadow: 0 6px 20px rgba(0,0,0,0.08);   }   .role-level {     font-family: 'DM Mono', monospace;     font-size: 9px;     letter-spacing: 0.08em;     text-transform: uppercase;     margin-bottom: 5px;     opacity: 0.5;   }   .role-title-pl {     font-size: 12px;     font-weight: 600;     line-height: 1.3;     margin-bottom: 3px;   }   .role-title-en {     font-size: 10px;     font-style: italic;     opacity: 0.55;     line-height: 1.3;     margin-bottom: 6px;   }   .role-scope {     font-size: 10px;     line-height: 1.4;     opacity: 0.6;   }    /* ── CORE STYLING ────────────────────────────────────────────────── */   .core-block {     background: var(--core-light);     border-color: rgba(45, 106, 79, 0.15);   }   .core-block .section-header { background: rgba(45,106,79,0.08); }   .core-block .section-num { color: var(--core-mid); }   .core-block .section-title { color: var(--core-dark); }   .core-block .section-tag { background: var(--core-mid); color: white; }   .core-block .role-card { border-color: rgba(45,106,79,0.1); }   .core-block .role-level { color: var(--core-mid); }   .core-block .role-title-pl { color: var(--core-dark); }    /* ── NON-CORE STYLING ────────────────────────────────────────────── */   .nc-block {     background: var(--nc-light);     border-color: rgba(139, 69, 19, 0.15);   }   .nc-block .section-header { background: rgba(139,69,19,0.07); }   .nc-block .section-num { color: var(--nc-mid); }   .nc-block .section-title { color: var(--nc-dark); }   .nc-block .section-tag { background: var(--nc-mid); color: white; }   .nc-block .role-card { border-color: rgba(139,69,19,0.1); }   .nc-block .role-level { color: var(--nc-mid); }   .nc-block .role-title-pl { color: var(--nc-dark); }    /* ── CLIENT / SUPPLIER SPLIT ─────────────────────────────────────── */   .split-panel {     display: grid;     grid-template-columns: 1fr 1fr;     gap: 12px;     margin-top: 6px;   }   .split-side {     border-radius: 8px;     padding: 12px;   }   .client-side {     background: rgba(107, 107, 212, 0.07);     border: 1px solid rgba(107,107,212,0.15);   }   .supplier-side {     background: rgba(58, 171, 171, 0.07);     border: 1px solid rgba(58,171,171,0.15);   }   .client-side .perspective-label::before { background: var(--client-accent); }   .supplier-side .perspective-label::before { background: var(--supplier-accent); }   .client-side .perspective-label { color: var(--client-mid); }   .supplier-side .perspective-label { color: var(--supplier-mid); }   .client-side .role-level { color: var(--client-mid); }   .supplier-side .role-level { color: var(--supplier-mid); }   .client-side .role-card { border-color: rgba(107,107,212,0.12); }   .supplier-side .role-card { border-color: rgba(58,171,171,0.12); }    .split-roles-grid {     display: grid;     grid-template-columns: repeat(5, 1fr);     gap: 5px;   }    /* ── DIVIDER BETWEEN CORE / NON-CORE ─────────────────────────────── */   .section-divider {     display: flex;     align-items: center;     gap: 16px;     padding: 8px 0;     margin: 8px 0 4px;   }   .divider-label {     font-family: 'DM Mono', monospace;     font-size: 11px;     letter-spacing: 0.12em;     text-transform: uppercase;     white-space: nowrap;     padding: 5px 14px;     border-radius: 20px;     font-weight: 500;   }   .divider-line {     flex: 1;     height: 1px;     background: var(--line);   }   .core-divider .divider-label { background: var(--core-dark); color: white; }   .nc-divider .divider-label { background: var(--nc-dark); color: white; }    /* ── SENIORITY SCALE ─────────────────────────────────────────────── */   .seniority-bar {     display: flex;     gap: 6px;     align-items: center;     padding: 20px 60px 0;     margin-bottom: -8px;   }   .seniority-bar-label {     font-family: 'DM Mono', monospace;     font-size: 10px;     color: var(--ink-ghost);     letter-spacing: 0.08em;     margin-right: 8px;     text-transform: uppercase;   }   .sen-pill {     font-family: 'DM Mono', monospace;     font-size: 10px;     padding: 4px 12px;     border-radius: 20px;     background: var(--white);     border: 1px solid var(--line);     color: var(--ink-soft);     letter-spacing: 0.06em;     display: flex;     align-items: center;     gap: 6px;   }   .sen-pill::after {     content: '→';     color: var(--ink-ghost);   }   .sen-pill:last-child::after { display: none; }    /* ── EXPAND ALL BUTTON ───────────────────────────────────────────── */   .controls {     padding: 0 60px;     display: flex;     gap: 12px;     align-items: center;     margin-bottom: 4px;   }   .btn {     font-family: 'DM Mono', monospace;     font-size: 11px;     letter-spacing: 0.06em;     padding: 7px 16px;     border-radius: 6px;     border: 1px solid var(--line);     background: var(--white);     color: var(--ink-soft);     cursor: pointer;     transition: all 0.15s ease;   }   .btn:hover { background: var(--ink); color: var(--white); border-color: var(--ink); }    .stats-row {     display: flex;     gap: 24px;     padding: 0 60px 12px;   }   .stat {     display: flex;     flex-direction: column;     gap: 2px;   }   .stat-num {     font-family: 'Fraunces', serif;     font-size: 28px;     font-weight: 600;     color: var(--ink);     line-height: 1;   }   .stat-label {     font-size: 11px;     color: var(--ink-ghost);     letter-spacing: 0.04em;   }   .stat-divider {     width: 1px;     background: var(--line);     align-self: stretch;     margin: 4px 0;   }    /* ── TOOLTIP ─────────────────────────────────────────────────────── */   .tooltip {     position: fixed;     background: var(--ink);     color: white;     padding: 10px 14px;     border-radius: 8px;     font-size: 11px;     line-height: 1.5;     max-width: 260px;     pointer-events: none;     opacity: 0;     transition: opacity 0.15s ease;     z-index: 1000;     box-shadow: 0 8px 24px rgba(0,0,0,0.2);   }   .tooltip.visible { opacity: 1; }    /* ── FADE IN ─────────────────────────────────────────────────────── */   @keyframes fadeUp {     from { opacity: 0; transform: translateY(10px); }     to { opacity: 1; transform: translateY(0); }   }   .section-block {     animation: fadeUp 0.4s ease forwards;     opacity: 0;   }   .section-block:nth-child(1) { animation-delay: 0.05s; }   .section-block:nth-child(2) { animation-delay: 0.10s; }   .section-block:nth-child(3) { animation-delay: 0.15s; }   .section-block:nth-child(4) { animation-delay: 0.20s; }   .section-block:nth-child(5) { animation-delay: 0.25s; }   .section-block:nth-child(6) { animation-delay: 0.30s; }   .section-block:nth-child(7) { animation-delay: 0.35s; }   .section-block:nth-child(8) { animation-delay: 0.40s; }   .section-block:nth-child(9) { animation-delay: 0.45s; }   .section-block:nth-child(10) { animation-delay: 0.50s; }   .section-block:nth-child(11) { animation-delay: 0.55s; }   .section-block:nth-child(12) { animation-delay: 0.60s; }   .section-block:nth-child(13) { animation-delay: 0.65s; }   .section-block:nth-child(14) { animation-delay: 0.70s; }    /* ── LEVEL PANEL ─────────────────────────────────────────────────── */   .level-panel {     background: var(--surface);     border-bottom: 1px solid var(--line);     padding: 24px 60px 20px;   }   .level-panel-header {     display: flex;     justify-content: space-between;     align-items: center;     margin-bottom: 18px;   }   .level-panel-title {     font-size: 13px;     font-weight: 600;     color: var(--ink);     display: flex;     align-items: center;     gap: 8px;     letter-spacing: -0.1px;   }   .level-panel-icon {     font-size: 16px;     color: var(--ink-soft);   }   .level-panel-sub {     font-size: 11px;     font-weight: 400;     color: var(--ink-ghost);     font-family: 'DM Mono', monospace;     letter-spacing: 0.02em;   }   .level-panel-toggle {     font-family: 'DM Mono', monospace;     font-size: 10px;     padding: 5px 12px;     border-radius: 6px;     border: 1px solid var(--line);     background: transparent;     color: var(--ink-soft);     cursor: pointer;     letter-spacing: 0.06em;     transition: all 0.15s;   }   .level-panel-toggle:hover { background: var(--ink); color: white; border-color: var(--ink); }    /* Level cards */   .level-cards-row {     display: grid;     grid-template-columns: repeat(4, 1fr);     gap: 14px;     margin-bottom: 18px;   }   .level-card {     border-radius: 10px;     padding: 18px;     cursor: pointer;     border: 2px solid transparent;     transition: all 0.2s ease;     position: relative;     user-select: none;   }   .level-card:not(.active) { opacity: 0.35; filter: grayscale(0.4); }   .level-card:hover { transform: translateY(-2px); }    .level-card.strategic { background: linear-gradient(135deg, #EEF2FF 0%, #E8EEFF 100%); border-color: rgba(79,70,229,0.2); }   .level-card.strategic.active { border-color: #4F46E5; box-shadow: 0 4px 20px rgba(79,70,229,0.15); }   .level-card.tactical { background: linear-gradient(135deg, #FFFBEB 0%, #FEF3C7 100%); border-color: rgba(217,119,6,0.2); }   .level-card.tactical.active { border-color: #D97706; box-shadow: 0 4px 20px rgba(217,119,6,0.15); }   .level-card.operational { background: linear-gradient(135deg, #F0FDF4 0%, #DCFCE7 100%); border-color: rgba(22,163,74,0.2); }   .level-card.operational.active { border-color: #16A34A; box-shadow: 0 4px 20px rgba(22,163,74,0.15); }    .level-card-badge {     width: 32px; height: 32px;     border-radius: 8px;     display: flex; align-items: center; justify-content: center;     font-family: 'Fraunces', serif;     font-size: 18px;     font-weight: 600;     margin-bottom: 10px;   }   .strategic .level-card-badge { background: #4F46E5; color: white; }   .tactical .level-card-badge { background: #D97706; color: white; }   .operational .level-card-badge { background: #16A34A; color: white; }    .level-card-name {     font-size: 13px;     font-weight: 700;     letter-spacing: 0.05em;     margin-bottom: 2px;   }   .strategic .level-card-name { color: #3730A3; }   .tactical .level-card-name { color: #92400E; }   .operational .level-card-name { color: #14532D; }    .level-card-en {     font-family: 'DM Mono', monospace;     font-size: 10px;     opacity: 0.55;     letter-spacing: 0.06em;     margin-bottom: 4px;   }   .level-card-seniority {     font-family: 'DM Mono', monospace;     font-size: 10px;     font-weight: 500;     padding: 3px 8px;     border-radius: 4px;     display: inline-block;     margin-bottom: 12px;   }   .strategic .level-card-seniority { background: rgba(79,70,229,0.1); color: #4F46E5; }   .tactical .level-card-seniority { background: rgba(217,119,6,0.1); color: #D97706; }   .operational .level-card-seniority { background: rgba(22,163,74,0.1); color: #16A34A; }    .level-card-divider {     height: 1px;     background: rgba(0,0,0,0.07);     margin-bottom: 12px;   }   .level-card-def {     font-size: 12px;     line-height: 1.55;     color: var(--ink);     margin-bottom: 12px;   }   .level-card-def strong { font-weight: 600; }    .level-card-decisions-label {     font-family: 'DM Mono', monospace;     font-size: 10px;     letter-spacing: 0.08em;     opacity: 0.5;     text-transform: uppercase;     margin-bottom: 6px;   }   .level-card-decision-item {     font-size: 11px;     line-height: 1.5;     color: var(--ink-soft);     padding: 2px 0;   }   .level-card-examples {     display: flex;     flex-wrap: wrap;     gap: 4px;     margin-top: 10px;   }   .level-ex-pill {     font-family: 'DM Mono', monospace;     font-size: 9px;     padding: 2px 7px;     border-radius: 4px;     letter-spacing: 0.04em;   }   .strategic .level-ex-pill { background: rgba(79,70,229,0.08); color: #4F46E5; border: 1px solid rgba(79,70,229,0.15); }   .tactical .level-ex-pill { background: rgba(217,119,6,0.08); color: #D97706; border: 1px solid rgba(217,119,6,0.15); }   .operational .level-ex-pill { background: rgba(22,163,74,0.08); color: #16A34A; border: 1px solid rgba(22,163,74,0.15); }    /* Mapping strip */   .mapping-strip {     background: var(--bg);     border-radius: 8px;     padding: 12px 16px;     display: flex;     align-items: center;     gap: 16px;     flex-wrap: wrap;     margin-bottom: 12px;   }   .mapping-strip-label {     font-family: 'DM Mono', monospace;     font-size: 10px;     color: var(--ink-ghost);     letter-spacing: 0.06em;     text-transform: uppercase;     white-space: nowrap;   }   .mapping-items {     display: flex;     align-items: center;     gap: 10px;     flex-wrap: wrap;     flex: 1;   }   .mapping-item {     display: flex;     align-items: center;     gap: 8px;     padding: 6px 12px;     border-radius: 6px;   }   .mapping-item.strat { background: rgba(79,70,229,0.06); }   .mapping-item.tact { background: rgba(217,119,6,0.06); }   .mapping-item.oper { background: rgba(22,163,74,0.06); }   .mapping-badge {     width: 22px; height: 22px;     border-radius: 5px;     display: flex; align-items: center; justify-content: center;     font-family: 'Fraunces', serif;     font-size: 13px;     font-weight: 600;     color: white;     flex-shrink: 0;   }   .mapping-badge.S { background: #4F46E5; }   .mapping-badge.T { background: #D97706; }   .mapping-badge.O { background: #16A34A; }   .mapping-title { font-size: 12px; font-weight: 600; }   .mapping-roles { font-family: 'DM Mono', monospace; font-size: 10px; color: var(--ink-soft); }   .mapping-arrow { color: var(--ink-ghost); font-size: 14px; }   .mapping-note {     font-size: 10px;     color: var(--ink-ghost);     font-style: italic;     margin-left: 8px;     flex: 1;     min-width: 200px;   }    /* Filter indicator */   .filter-indicator {     display: flex;     align-items: center;     gap: 12px;     padding: 8px 14px;     background: var(--ink);     border-radius: 8px;     color: white;     font-size: 12px;     font-family: 'DM Mono', monospace;     letter-spacing: 0.04em;     margin-top: 4px;   }   .filter-clear {     background: rgba(255,255,255,0.15);     border: none;     color: white;     padding: 3px 10px;     border-radius: 5px;     cursor: pointer;     font-size: 11px;     font-family: 'DM Mono', monospace;     transition: background 0.15s;   }   .filter-clear:hover { background: rgba(255,255,255,0.3); }    /* Role card level badge overlay */   .role-level-badge {     position: absolute;     top: 7px;     right: 8px;     width: 18px; height: 18px;     border-radius: 4px;     display: flex; align-items: center; justify-content: center;     font-size: 10px;     font-weight: 700;     font-family: 'Fraunces', serif;     color: white;     opacity: 0.85;   }   .role-level-badge.S { background: #4F46E5; }   .role-level-badge.T { background: #D97706; }   .role-level-badge.O { background: #16A34A; }    /* Dimmed card when filtered */   .role-card.dimmed {     opacity: 0.12;     pointer-events: none;     transform: none !important;   }    .level-card.wykonawczy { background: linear-gradient(135deg, #FFF7ED 0%, #FFEDD5 100%); border-color: rgba(180,83,9,0.2); }   .level-card.wykonawczy.active { border-color: #B45309; box-shadow: 0 4px 20px rgba(180,83,9,0.15); }   .wykonawczy .level-card-badge { background: #B45309; color: white; }   .wykonawczy .level-card-name { color: #7C2D12; }   .wykonawczy .level-card-seniority { background: rgba(180,83,9,0.1); color: #B45309; }   .wykonawczy .level-ex-pill { background: rgba(180,83,9,0.08); color: #B45309; border: 1px solid rgba(180,83,9,0.15); }   .mapping-item.exec { background: rgba(180,83,9,0.06); }   .mapping-badge.W { background: #B45309; }    /* Wykonawczy role card style */   .role-card.wykonawczy-card {     background: linear-gradient(135deg, #FFFBF5 0%, #FFF7ED 100%);     border-color: rgba(180,83,9,0.15);     border-left: 3px solid #B45309;   }   .role-card.wykonawczy-card .role-level { color: #B45309; }   .role-card.wykonawczy-card .role-title-pl { color: #7C2D12; }   .role-level-badge.W { background: #B45309; }    /* Wykonawczy section within split panels */   .wykonawczy-section {     margin-top: 10px;     border-radius: 8px;     padding: 12px;     background: rgba(180,83,9,0.05);     border: 1px solid rgba(180,83,9,0.15);   }   .wykonawczy-section .perspective-label { color: #B45309; }   .wykonawczy-section .perspective-label::before { background: #B45309; }    /* ── ENERGY SECTION ──────────────────────────────────────────────── */   .energy-block {     background: #F0F4FF;     border-color: rgba(60, 90, 180, 0.2);   }   .energy-block .section-header { background: rgba(60, 90, 180, 0.07); }   .energy-block .section-num { color: #3C5AB4; }   .energy-block .section-title { color: #1A2A5A; }   .energy-block .section-tag { background: #3C5AB4; color: white; }   .energy-block .role-card { border-color: rgba(60,90,180,0.12); }   .energy-block .role-level { color: #3C5AB4; }   .energy-block .role-title-pl { color: #1A2A5A; }    .crosslinks-bar {     display: flex;     flex-wrap: wrap;     gap: 6px;     padding: 8px 0 14px;     align-items: center;   }   .crosslinks-label {     font-family: 'DM Mono', monospace;     font-size: 10px;     color: #888;     letter-spacing: 0.08em;     text-transform: uppercase;     margin-right: 4px;   }   .crosslink-pill {     font-family: 'DM Mono', monospace;     font-size: 10px;     padding: 3px 10px;     border-radius: 20px;     background: rgba(60,90,180,0.08);     border: 1px solid rgba(60,90,180,0.2);     color: #3C5AB4;     letter-spacing: 0.04em;   }   .context-badge {     display: inline-block;     font-family: 'DM Mono', monospace;     font-size: 9px;     padding: 2px 6px;     border-radius: 4px;     background: rgba(60,90,180,0.1);     color: #3C5AB4;     margin-top: 5px;     letter-spacing: 0.04em;   }   .energy-roles-grid {     display: grid;     grid-template-columns: repeat(3, 1fr);     gap: 6px;   }    /* ── BUILDING TYPE FILTER ────────────────────────────────────────── */   .btype-panel {     background: var(--surface);     border-bottom: 2px solid var(--line);     padding: 20px 60px 18px;   }   .btype-header {     display: flex;     justify-content: space-between;     align-items: center;     margin-bottom: 14px;   }   .btype-title {     font-size: 13px;     font-weight: 600;     color: var(--ink);     display: flex;     align-items: center;     gap: 8px;   }   .btype-icon { font-size: 16px; }   .btype-sub {     font-size: 11px;     font-weight: 400;     color: var(--ink-ghost);     font-family: 'DM Mono', monospace;     letter-spacing: 0.02em;   }   .btype-cards-row {     display: flex;     gap: 8px;     flex-wrap: wrap;     margin-bottom: 12px;   }   .btype-card {     display: flex;     flex-direction: column;     align-items: center;     gap: 4px;     padding: 10px 14px;     border-radius: 10px;     border: 2px solid var(--line);     background: var(--white);     cursor: pointer;     transition: all 0.18s ease;     min-width: 100px;     flex: 1;     max-width: 160px;   }   .btype-card:hover { border-color: #555; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.08); }   .btype-card.active { border-color: var(--ink); background: var(--ink); }   .btype-card.active .btype-name { color: white; }   .btype-card.active .btype-en { color: rgba(255,255,255,0.6); }   .btype-card.active .btype-emoji { filter: brightness(1.3); }   .btype-emoji { font-size: 22px; line-height: 1; }   .btype-name { font-size: 11px; font-weight: 600; color: var(--ink); text-align: center; line-height: 1.3; }   .btype-en { font-family: 'DM Mono', monospace; font-size: 9px; color: var(--ink-ghost); text-align: center; letter-spacing: 0.04em; line-height: 1.3; }    /* Unique roles panel */   .btype-unique-panel {     background: var(--bg);     border-radius: 10px;     padding: 14px 16px;     margin-bottom: 10px;     border: 1px solid var(--line);   }   .btype-unique-header {     display: flex;     align-items: baseline;     gap: 10px;     margin-bottom: 12px;   }   #btypeUniqueTitle {     font-size: 13px;     font-weight: 700;     color: var(--ink);   }   .btype-unique-sub {     font-family: 'DM Mono', monospace;     font-size: 10px;     color: var(--ink-ghost);     letter-spacing: 0.04em;   }   .btype-unique-grid {     display: grid;     grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));     gap: 6px;   }   .btype-unique-card {     background: white;     border-radius: 8px;     padding: 10px 12px;     border: 1px solid var(--line);     border-left: 3px solid #555;   }   .btype-unique-card .u-cat {     font-family: 'DM Mono', monospace;     font-size: 9px;     color: var(--ink-ghost);     letter-spacing: 0.06em;     text-transform: uppercase;     margin-bottom: 4px;   }   .btype-unique-card .u-pl { font-size: 12px; font-weight: 600; color: var(--ink); margin-bottom: 2px; }   .btype-unique-card .u-en { font-size: 10px; font-style: italic; color: var(--ink-soft); margin-bottom: 4px; }   .btype-unique-card .u-scope { font-size: 10px; color: var(--ink-soft); line-height: 1.4; }   .btype-unique-card .u-level {     font-family: 'DM Mono', monospace;     font-size: 9px;     padding: 2px 6px;     border-radius: 3px;     background: rgba(0,0,0,0.06);     color: var(--ink-soft);     display: inline-block;     margin-top: 5px;   }    .btype-active-bar {     display: flex;     align-items: center;     gap: 12px;     padding: 7px 12px;     background: var(--ink);     border-radius: 7px;     color: white;     font-size: 11px;     font-family: 'DM Mono', monospace;   }    /* role-card building type visibility */   .role-card.btype-hidden { display: none; }   .section-block.btype-all-hidden { opacity: 0.2; pointer-events: none; }    /* ── FINDER MODULE ───────────────────────────────────────────────── */   .finder-module {     margin: 0 60px 40px;     border-radius: 16px;     border: 1px solid var(--line);     background: var(--surface);     overflow: hidden;     box-shadow: 0 4px 32px rgba(0,0,0,0.05);   }   .finder-inner { padding: 36px 40px 32px; }   .finder-header { margin-bottom: 24px; }   .finder-eyebrow {     font-family: 'DM Mono', monospace;     font-size: 10px;     letter-spacing: 0.14em;     color: var(--ink-ghost);     text-transform: uppercase;     margin-bottom: 8px;   }   .finder-title {     font-family: 'Fraunces', serif;     font-size: 26px;     font-weight: 300;     letter-spacing: -0.3px;     color: var(--ink);     margin-bottom: 6px;     line-height: 1.2;   }   .finder-subtitle {     font-size: 13px;     color: var(--ink-soft);     line-height: 1.5;   }    /* Input */   .finder-form { margin-bottom: 0; }   .finder-input-row {     display: flex;     gap: 10px;     align-items: flex-start;     margin-bottom: 8px;   }   .finder-input-wrap {     flex: 1;     position: relative;   }   .finder-input {     width: 100%;     padding: 14px 18px;     font-family: 'DM Sans', sans-serif;     font-size: 15px;     border: 2px solid var(--line);     border-radius: 10px;     background: white;     color: var(--ink);     outline: none;     transition: border-color 0.15s;   }   .finder-input:focus { border-color: var(--ink); }   .finder-hint {     font-family: 'DM Mono', monospace;     font-size: 10px;     color: var(--ink-ghost);     letter-spacing: 0.04em;   }    /* Autocomplete suggestions */   .finder-suggestions {     position: absolute;     top: calc(100% + 4px);     left: 0; right: 0;     background: white;     border: 1px solid var(--line);     border-radius: 8px;     box-shadow: 0 8px 24px rgba(0,0,0,0.1);     z-index: 100;     display: none;     max-height: 220px;     overflow-y: auto;   }   .finder-suggestions.open { display: block; }   .finder-suggestion-item {     padding: 9px 14px;     font-size: 13px;     cursor: pointer;     display: flex;     align-items: center;     gap: 10px;     border-bottom: 1px solid var(--line);     transition: background 0.1s;   }   .finder-suggestion-item:last-child { border-bottom: none; }   .finder-suggestion-item:hover { background: var(--bg); }   .suggestion-pl { font-weight: 500; color: var(--ink); flex: 1; }   .suggestion-meta {     font-family: 'DM Mono', monospace;     font-size: 10px;     color: var(--ink-ghost);     white-space: nowrap;   }   .suggestion-highlight { background: #FEF08A; border-radius: 2px; }    /* Button */   .finder-btn {     padding: 14px 28px;     border-radius: 10px;     background: var(--ink);     color: white;     border: none;     font-family: 'DM Sans', sans-serif;     font-size: 14px;     font-weight: 600;     cursor: pointer;     transition: all 0.15s;     white-space: nowrap;     min-width: 130px;   }   .finder-btn:hover { background: #333; transform: translateY(-1px); }   .finder-btn:disabled { background: var(--ink-ghost); cursor: not-allowed; transform: none; }   .finder-btn.loading { background: #555; }    /* Spinner */   @keyframes spin { to { transform: rotate(360deg); } }   .spinner {     display: inline-block;     width: 14px; height: 14px;     border: 2px solid rgba(255,255,255,0.3);     border-top-color: white;     border-radius: 50%;     animation: spin 0.6s linear infinite;     vertical-align: middle;     margin-right: 6px;   }    /* Result panel */   .finder-result {     margin-top: 20px;     border-radius: 12px;     overflow: hidden;     animation: fadeUp 0.3s ease;   }    /* FOUND result */   .result-found {     background: linear-gradient(135deg, #F0FDF4, #DCFCE7);     border: 1px solid #86EFAC;     padding: 20px 24px;   }   .result-found-header {     display: flex;     align-items: center;     gap: 10px;     margin-bottom: 14px;   }   .result-found-icon { font-size: 22px; }   .result-found-title { font-size: 15px; font-weight: 700; color: #14532D; }   .result-found-sub { font-size: 12px; color: #166534; margin-top: 1px; }   .result-location-cards {     display: flex;     flex-wrap: wrap;     gap: 8px;   }   .result-location-card {     background: white;     border: 1px solid #BBF7D0;     border-radius: 8px;     padding: 10px 14px;     cursor: pointer;     transition: all 0.15s;     flex: 1;     min-width: 200px;     max-width: 320px;   }   .result-location-card:hover { border-color: #16A34A; box-shadow: 0 4px 12px rgba(22,163,74,0.15); transform: translateY(-1px); }   .rlc-category { font-family: 'DM Mono', monospace; font-size: 9px; color: #16A34A; letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 4px; }   .rlc-name { font-size: 13px; font-weight: 600; color: var(--ink); margin-bottom: 2px; }   .rlc-en { font-size: 11px; color: var(--ink-soft); font-style: italic; margin-bottom: 6px; }   .rlc-badges { display: flex; gap: 4px; flex-wrap: wrap; }   .rlc-badge {     font-family: 'DM Mono', monospace;     font-size: 9px;     padding: 2px 6px;     border-radius: 4px;     border: 1px solid;   }   .rlc-badge.stl-S { background: rgba(79,70,229,0.08); color: #4F46E5; border-color: rgba(79,70,229,0.2); }   .rlc-badge.stl-T { background: rgba(217,119,6,0.08); color: #D97706; border-color: rgba(217,119,6,0.2); }   .rlc-badge.stl-O { background: rgba(22,163,74,0.08); color: #16A34A; border-color: rgba(22,163,74,0.2); }   .rlc-badge.stl-W { background: rgba(180,83,9,0.08); color: #B45309; border-color: rgba(180,83,9,0.2); }   .rlc-badge.level { background: var(--bg); color: var(--ink-soft); border-color: var(--line); }    /* NOT FOUND result — add form */   .result-notfound {     background: linear-gradient(135deg, #FFF7ED, #FFEDD5);     border: 1px solid #FCD34D;     padding: 20px 24px;   }   .result-nf-header {     display: flex; align-items: center; gap: 10px; margin-bottom: 6px;   }   .result-nf-icon { font-size: 22px; }   .result-nf-title { font-size: 15px; font-weight: 700; color: #92400E; }   .result-nf-sub { font-size: 12px; color: #B45309; margin-bottom: 16px; }   .result-nf-sub strong { color: #92400E; }   .add-form-grid {     display: grid;     grid-template-columns: 1fr 1fr;     gap: 10px;     margin-bottom: 12px;   }   .add-form-full { grid-column: 1 / -1; }   .add-label {     font-family: 'DM Mono', monospace;     font-size: 10px;     letter-spacing: 0.06em;     color: var(--ink-soft);     text-transform: uppercase;     margin-bottom: 5px;   }   .add-input, .add-select, .add-textarea {     width: 100%;     padding: 9px 12px;     font-family: 'DM Sans', sans-serif;     font-size: 13px;     border: 1px solid #FCD34D;     border-radius: 8px;     background: white;     color: var(--ink);     outline: none;     transition: border-color 0.15s;   }   .add-input:focus, .add-select:focus, .add-textarea:focus { border-color: #D97706; }   .add-textarea { resize: vertical; min-height: 60px; }   .add-submit-row { display: flex; gap: 10px; align-items: center; }   .add-submit-btn {     padding: 10px 22px;     border-radius: 8px;     background: #D97706;     color: white;     border: none;     font-family: 'DM Sans', sans-serif;     font-size: 13px;     font-weight: 600;     cursor: pointer;     transition: all 0.15s;   }   .add-submit-btn:hover { background: #B45309; }   .add-skip-btn {     font-size: 12px;     color: var(--ink-ghost);     background: none;     border: none;     cursor: pointer;     text-decoration: underline;     font-family: 'DM Sans', sans-serif;   }    /* ADDED SUCCESS */   .result-added {     background: linear-gradient(135deg, #EFF6FF, #DBEAFE);     border: 1px solid #93C5FD;     padding: 20px 24px;   }   .result-added-header { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }   .result-added-icon { font-size: 22px; }   .result-added-title { font-size: 15px; font-weight: 700; color: #1E3A8A; }   .result-added-card {     background: white;     border: 1px solid #93C5FD;     border-left: 4px solid #2563EB;     border-radius: 8px;     padding: 12px 16px;     margin-top: 10px;   }   .added-in-schema { font-size: 12px; color: #1D4ED8; margin-top: 8px; font-style: italic; }    /* Added roles list at bottom */   .finder-added-list {     margin-top: 20px;     padding: 14px 18px;     background: var(--bg);     border-radius: 10px;     border: 1px solid var(--line);   }   .finder-added-title {     font-family: 'DM Mono', monospace;     font-size: 10px;     letter-spacing: 0.08em;     text-transform: uppercase;     color: var(--ink-soft);     margin-bottom: 10px;   }   .added-pill {     display: inline-flex;     align-items: center;     gap: 6px;     padding: 4px 10px;     background: white;     border: 1px solid var(--line);     border-radius: 20px;     font-size: 11px;     color: var(--ink);     margin: 3px;     cursor: pointer;     transition: all 0.15s;   }   .added-pill:hover { border-color: #2563EB; color: #2563EB; }   .added-pill-cat { font-family: 'DM Mono', monospace; font-size: 9px; color: var(--ink-ghost); }    /* AI Classification card */   .ai-classification-card {     background: white;     border: 1px solid #E0E7FF;     border-radius: 10px;     padding: 18px 20px;     margin: 14px 0;     border-left: 4px solid #4F46E5;   }   .ai-class-row {     display: grid;     grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));     gap: 10px;     margin-bottom: 10px;   }   .ai-class-field { display: flex; flex-direction: column; gap: 4px; }   .ai-class-label {     font-family: 'DM Mono', monospace;     font-size: 10px;     letter-spacing: 0.08em;     text-transform: uppercase;     color: var(--ink-ghost);   }   .ai-reasoning {     display: flex;     align-items: flex-start;     gap: 8px;     background: #F5F3FF;     border: 1px solid #DDD6FE;     border-radius: 7px;     padding: 10px 12px;     margin: 12px 0 10px;     font-size: 12px;     color: #4C1D95;     line-height: 1.5;   }   .ai-reasoning-icon { font-size: 14px; flex-shrink: 0; margin-top: 1px; }   .ai-summary-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }   .result-nf-analyzing {     display: flex;     align-items: center;     gap: 8px;     font-size: 12px;     color: var(--ink-soft);     margin-top: 6px;     font-style: italic;   }    /* ── PRINT ───────────────────────────────────────────────────────── */   @media print {     .controls { display: none; }     .section-block.open .roles-panel { display: flex; }   } </style> </head> <body>  <!-- HEADER --> <div class="page-header">   <div>     <h1>Real Estate Management<br><em>Mapa stanowisk i taksonomia zawodów</em></h1>   </div>   <div class="meta">     PODZIAŁ CORE / NON-CORE<br>     ZAMAWIAJĄCY / DOSTAWCA<br>     JUNIOR → C-LEVEL<br>     16 KATEGORII · 80+ STANOWISK   </div> </div>  <!-- LEGEND --> <div class="legend-bar">   <span class="legend-item"><span class="legend-dot" style="background:#2D6A4F"></span><span class="legend-label">CORE — funkcje kluczowe</span></span>   <span class="legend-item"><span class="legend-dot" style="background:#8B4513"></span><span class="legend-label">NON-CORE — funkcje wspierające</span></span>   <span class="legend-item"><span class="legend-dot" style="background:#6B6BD4"></span><span class="legend-label">Perspektywa Zamawiającego</span></span>   <span class="legend-item"><span class="legend-dot" style="background:#3AABAB"></span><span class="legend-label">Perspektywa Dostawcy</span></span>   <span class="legend-item"><span class="legend-dot" style="background:#3C5AB4"></span><span class="legend-label">⚡ Funkcja crossfunkcyjna (Energy)</span></span>   <span class="legend-item" style="margin-left:auto"><span class="legend-label" style="font-size:10px;font-family:'DM Mono',monospace">↓ kliknij sekcję aby rozwinąć stanowiska</span></span> </div>  <!-- STATS --> <div class="stats-row" style="padding-top:24px">   <div class="stat"><span class="stat-num">6</span><span class="stat-label">kategorii CORE</span></div>   <div class="stat-divider"></div>   <div class="stat"><span class="stat-num">10</span><span class="stat-label">kategorii NON-CORE</span></div>   <div class="stat-divider"></div>   <div class="stat"><span class="stat-num">80+</span><span class="stat-label">stanowisk</span></div>   <div class="stat-divider"></div>   <div class="stat"><span class="stat-num">5</span><span class="stat-label">poziomów seniority</span></div>   <div class="stat-divider"></div>   <div class="stat"><span class="stat-num">3</span><span class="stat-label">poziomy zarządzania</span></div>   <div class="stat-divider"></div>   <div class="stat"><span class="stat-num">2</span><span class="stat-label">perspektywy (FM)</span></div> </div>  <!-- SENIORITY SCALE --> <div class="seniority-bar">   <span class="seniority-bar-label">Seniority:</span>   <span class="sen-pill">Junior</span>   <span class="sen-pill">Mid</span>   <span class="sen-pill">Senior</span>   <span class="sen-pill">Director</span>   <span class="sen-pill">C-level</span>   <span style="font-family:'DM Mono',monospace;font-size:11px;color:#888;margin:0 4px">+</span>   <span class="sen-pill" style="border-color:#B45309;color:#B45309;background:#FFFBEB">Wykonawczy ★</span> </div>  <!-- STRATEGIC LEVEL FILTER PANEL --> <div class="level-panel" id="levelPanel">   <div class="level-panel-header">     <div class="level-panel-title">       <span class="level-panel-icon">◈</span>       Poziomy zarządzania w Real Estate       <span class="level-panel-sub">— kliknij poziom aby przefiltrować stanowiska na schemacie</span>     </div>     <button class="level-panel-toggle" onclick="toggleLevelPanel()">Zwiń ▲</button>   </div>    <div class="level-cards-row" id="levelCards">      <div class="level-card strategic active" data-level="S" onclick="filterLevel('S')">       <div class="level-card-badge">S</div>       <div class="level-card-name">STRATEGICZNY</div>       <div class="level-card-en">Strategic Level</div>       <div class="level-card-seniority">C-level · Director</div>       <div class="level-card-divider"></div>       <div class="level-card-def">         Odpowiada na pytanie <strong>„Dlaczego?"</strong> i <strong>„Co?"</strong>. Ustala kierunek, alokuje kapitał, decyduje o portfelu i modelu biznesowym. Horyzont: 3–10 lat.       </div>       <div class="level-card-decisions">         <div class="level-card-decisions-label">Typowe decyzje w RE:</div>         <div class="level-card-decision-item">→ Kupić czy wynająć nieruchomość?</div>         <div class="level-card-decision-item">→ Outsourcować FM czy budować in-house?</div>         <div class="level-card-decision-item">→ Jaką strategię ESG przyjąć dla portfela?</div>         <div class="level-card-decision-item">→ W jakich rynkach geograficznych być?</div>         <div class="level-card-decision-item">→ Jaki model workplace dla organizacji?</div>       </div>       <div class="level-card-examples">         <span class="level-ex-pill">CIO / CREO</span>         <span class="level-ex-pill">Head of FM</span>         <span class="level-ex-pill">Portfolio Director</span>         <span class="level-ex-pill">MD Agency</span>       </div>     </div>      <div class="level-card tactical active" data-level="T" onclick="filterLevel('T')">       <div class="level-card-badge">T</div>       <div class="level-card-name">TAKTYCZNY</div>       <div class="level-card-en">Tactical Level</div>       <div class="level-card-seniority">Senior · Mid (wyższy)</div>       <div class="level-card-divider"></div>       <div class="level-card-def">         Odpowiada na pytanie <strong>„Jak?"</strong> i <strong>„Kiedy?"</strong>. Tłumaczy strategię na plany, projekty i procesy. Zarządza zasobami i dostawcami. Horyzont: 6 mies. – 3 lata.       </div>       <div class="level-card-decisions">         <div class="level-card-decisions-label">Typowe decyzje w RE:</div>         <div class="level-card-decision-item">→ Jak skonstruować przetarg na IFM?</div>         <div class="level-card-decision-item">→ Jak rozłożyć budżet FM na obiekty?</div>         <div class="level-card-decision-item">→ Jak wdrożyć hot-desking w biurze?</div>         <div class="level-card-decision-item">→ Jak renegocjować umowę najmu?</div>         <div class="level-card-decision-item">→ Jak osiągnąć certyfikat BREEAM Excellent?</div>       </div>       <div class="level-card-examples">         <span class="level-ex-pill">Asset Manager</span>         <span class="level-ex-pill">Contract Manager</span>         <span class="level-ex-pill">Senior PM</span>         <span class="level-ex-pill">ESG Manager</span>       </div>     </div>      <div class="level-card operational active" data-level="O" onclick="filterLevel('O')">       <div class="level-card-badge">O</div>       <div class="level-card-name">OPERACYJNY</div>       <div class="level-card-en">Operational Level</div>       <div class="level-card-seniority">Mid · Junior · Technik</div>       <div class="level-card-divider"></div>       <div class="level-card-def">         Odpowiada na pytanie <strong>„Co dokładnie?"</strong> i <strong>„Teraz?"</strong>. Realizuje zadania, obsługuje obiekty, przetwarza dane. Horyzont: dzienny – miesięczny.       </div>       <div class="level-card-decisions">         <div class="level-card-decisions-label">Typowe decyzje w RE:</div>         <div class="level-card-decision-item">→ Kiedy zlecić przegląd instalacji HVAC?</div>         <div class="level-card-decision-item">→ Jak obsłużyć zgłoszenie awarii od najemcy?</div>         <div class="level-card-decision-item">→ Jak wypełnić raport occupancy za tydzień?</div>         <div class="level-card-decision-item">→ Kiedy wygasa opcja przedłużenia najmu?</div>         <div class="level-card-decision-item">→ Jak zebrać dane do raportu mediów?</div>       </div>       <div class="level-card-examples">         <span class="level-ex-pill">FM Coordinator</span>         <span class="level-ex-pill">Technik utrzymania</span>         <span class="level-ex-pill">Lease Admin</span>         <span class="level-ex-pill">Space Planner</span>       </div>     </div>      <div class="level-card wykonawczy active" data-level="W" onclick="filterLevel('W')">       <div class="level-card-badge">W</div>       <div class="level-card-name">WYKONAWCZY</div>       <div class="level-card-en">Field / Frontline Level</div>       <div class="level-card-seniority">Pracownik · Brygadzista · Technik</div>       <div class="level-card-divider"></div>       <div class="level-card-def">         Odpowiada na pytanie <strong>„Robię to teraz."</strong> Bezpośrednia realizacja usługi na obiekcie — fizyczna obecność, praca zmianowa, kontakt z przestrzenią i użytkownikami. Horyzont: zmiana – dzień.       </div>       <div class="level-card-decisions">         <div class="level-card-decisions-label">Typowe działania w RE:</div>         <div class="level-card-decision-item">→ Wykonać przegląd instalacji elektrycznej na piętrze</div>         <div class="level-card-decision-item">→ Odpowiedzieć na zgłoszenie awarii w ciągu 15 min</div>         <div class="level-card-decision-item">→ Przeprowadzić obchód ochroniarski o godz. 22:00</div>         <div class="level-card-decision-item">→ Uprzątnąć powierzchnię biurową według harmonogramu</div>         <div class="level-card-decision-item">→ Zgłosić brygadziście usterkę wymagającą eskalacji</div>       </div>       <div class="level-card-examples">         <span class="level-ex-pill">Technik HVAC</span>         <span class="level-ex-pill">Sprzątaczka</span>         <span class="level-ex-pill">Ochroniarz</span>         <span class="level-ex-pill">Brygadzista</span>       </div>     </div>    </div>    <!-- MAPPING STRIP -->   <div class="mapping-strip">     <div class="mapping-strip-label">Mapowanie poziomów ↔ seniority w RE:</div>     <div class="mapping-items">       <div class="mapping-item strat">         <div class="mapping-badge S">S</div>         <div class="mapping-text">           <div class="mapping-title">Strategiczny</div>           <div class="mapping-roles">C-level · Director</div>         </div>       </div>       <div class="mapping-arrow">→</div>       <div class="mapping-item tact">         <div class="mapping-badge T">T</div>         <div class="mapping-text">           <div class="mapping-title">Taktyczny</div>           <div class="mapping-roles">Senior · Mid+</div>         </div>       </div>       <div class="mapping-arrow">→</div>       <div class="mapping-item oper">         <div class="mapping-badge O">O</div>         <div class="mapping-text">           <div class="mapping-title">Operacyjny</div>           <div class="mapping-roles">Mid · Junior</div>         </div>       </div>       <div class="mapping-arrow">→</div>       <div class="mapping-item exec">         <div class="mapping-badge W">W</div>         <div class="mapping-text">           <div class="mapping-title">Wykonawczy</div>           <div class="mapping-roles">Pracownik · Brygadzista</div>         </div>       </div>       <div class="mapping-note">         ⚠ Poziom Wykonawczy (W) dotyczy wyłącznie ścieżki niebiurowej — dostawcy usług FM, soft services i technicznych. Brygadzista = najwyższy szczebel tej ścieżki.       </div>     </div>   </div>    <!-- ACTIVE FILTER INDICATOR -->   <div class="filter-indicator" id="filterIndicator" style="display:none">     <span id="filterText"></span>     <button class="filter-clear" onclick="clearFilter()">✕ Pokaż wszystkie</button>   </div> </div>  <!-- CONTROLS --> <div class="controls" style="padding-top:16px">   <button class="btn" onclick="expandAll()">Rozwiń wszystkie</button>   <button class="btn" onclick="collapseAll()">Zwiń wszystkie</button> </div>  <!-- BUILDING TYPE FILTER PANEL --> <div class="btype-panel" id="btypePanel">   <div class="btype-header">     <div class="btype-title">       <span class="btype-icon">🏢</span>       Filtr według typu obiektu       <span class="btype-sub">— wybierz typ aby zobaczyć tylko relevantne stanowiska i role unikalne dla tego obiektu</span>     </div>     <button class="level-panel-toggle" onclick="toggleBtypePanel()">Zwiń ▲</button>   </div>   <div class="btype-cards-row" id="btypeCards">     <div class="btype-card active" data-btype="ALL" onclick="filterBuilding('ALL')">       <div class="btype-emoji">◎</div>       <div class="btype-name">Wszystkie typy</div>       <div class="btype-en">All Building Types</div>     </div>     <div class="btype-card" data-btype="OFF" onclick="filterBuilding('OFF')">       <div class="btype-emoji">🏢</div>       <div class="btype-name">Biurowy</div>       <div class="btype-en">Office</div>     </div>     <div class="btype-card" data-btype="RET" onclick="filterBuilding('RET')">       <div class="btype-emoji">🛍️</div>       <div class="btype-name">Handlowy</div>       <div class="btype-en">Retail / Shopping Centre</div>     </div>     <div class="btype-card" data-btype="LOG" onclick="filterBuilding('LOG')">       <div class="btype-emoji">📦</div>       <div class="btype-name">Magazynowy / Logistyczny</div>       <div class="btype-en">Warehouse / Logistics</div>     </div>     <div class="btype-card" data-btype="IND" onclick="filterBuilding('IND')">       <div class="btype-emoji">🏭</div>       <div class="btype-name">Przemysłowy / Fabryka</div>       <div class="btype-en">Industrial / Manufacturing</div>     </div>     <div class="btype-card" data-btype="HOT" onclick="filterBuilding('HOT')">       <div class="btype-emoji">🏨</div>       <div class="btype-name">Hotelowy / Hospitality</div>       <div class="btype-en">Hotel / Hospitality</div>     </div>     <div class="btype-card" data-btype="MIX" onclick="filterBuilding('MIX')">       <div class="btype-emoji">🏙️</div>       <div class="btype-name">Mieszany</div>       <div class="btype-en">Mixed-use</div>     </div>     <div class="btype-card" data-btype="PUB" onclick="filterBuilding('PUB')">       <div class="btype-emoji">🎭</div>       <div class="btype-name">Użyteczności Publicznej</div>       <div class="btype-en">Public / Cultural / Transport</div>     </div>   </div>   <!-- Unique roles panel — shown when a building type is selected -->   <div class="btype-unique-panel" id="btypeUniquePanel" style="display:none">     <div class="btype-unique-header">       <span id="btypeUniqueTitle"></span>       <span class="btype-unique-sub">Stanowiska unikalne lub charakterystyczne dla tego typu obiektu</span>     </div>     <div class="btype-unique-grid" id="btypeUniqueGrid"></div>   </div>   <div class="btype-active-bar" id="btypeActiveBar" style="display:none">     <span id="btypeActiveText"></span>     <button class="filter-clear" onclick="filterBuilding('ALL')">✕ Pokaż wszystkie typy</button>   </div> </div>  <!-- MAIN CANVAS --> <div class="canvas" id="canvas"></div>  <!-- FIND YOUR POSITION MODULE --> <div class="finder-module" id="finderModule">   <div class="finder-inner">     <div class="finder-header">       <div class="finder-title-block">         <div class="finder-eyebrow">MODUŁ INTERAKTYWNY</div>         <h2 class="finder-title">Czy Twoje stanowisko jest na tej mapie?</h2>         <p class="finder-subtitle">Wpisz swoją nazwę stanowiska — sprawdzimy gdzie się znajduje lub pomożemy je umieścić.</p>       </div>     </div>      <!-- SEARCH FORM -->     <div class="finder-form" id="finderForm">       <div class="finder-input-row">         <div class="finder-input-wrap">           <input             type="text"             id="finderInput"             class="finder-input"             placeholder="np. Facility Manager, Asset Manager, Brygadzista ochrony..."             autocomplete="off"             onkeydown="if(event.key==='Enter') runFinder()"           />           <div class="finder-suggestions" id="finderSuggestions"></div>         </div>         <button class="finder-btn" onclick="runFinder()" id="finderBtn">           <span id="finderBtnText">Sprawdź →</span>         </button>       </div>       <div class="finder-hint">Możesz wpisać nazwę po polsku lub angielsku</div>     </div>      <!-- RESULT PANEL -->     <div class="finder-result" id="finderResult" style="display:none"></div>      <!-- ADDED ROLES LIST -->     <div class="finder-added-list" id="finderAddedList" style="display:none">       <div class="finder-added-title">📌 Stanowiska dodane przez użytkowników tej sesji:</div>       <div id="finderAddedItems"></div>     </div>   </div> </div>  <!-- TOOLTIP --> <div class="tooltip" id="tooltip"></div>  <script> const DATA = {   core: [     {       id: 'C1', label: 'CORE 1',       title: 'Asset & Portfolio Management',       subtitle: 'Zarządzanie Aktywem i Portfelem Inwestycyjnym',       desc: 'Nieruchomość jako produkt finansowy. Optymalizacja wartości, NOI, decyzje hold/sell, relacje z inwestorami.',       roles: [         { level:'C-level', stl:'S', pl:'Dyrektor ds. Inwestycji RE', en:'Chief Investment Officer (RE)', scope:'Strategia inwestycyjna portfela, alokacja kapitału, raport do zarządu' },         { level:'Director', stl:'S', pl:'Dyrektor Portfela', en:'Portfolio Director', scope:'Nadzór nad Asset Managerami, relacje z inwestorami, hold/sell decisions' },         { level:'Senior', stl:'T', pl:'Starszy Zarządca Aktywów', en:'Senior Asset Manager', scope:'Samodzielne zarządzanie portfelem klasy A/B, capex, NOI' },         { level:'Mid', stl:'T', pl:'Zarządca Aktywów', en:'Asset Manager', scope:'Bieżące zarządzanie 2–5 nieruchomościami, budżety, najemcy' },         { level:'Junior', stl:'O', pl:'Analityk Inwestycyjny RE', en:'Real Estate Investment Analyst', scope:'Modele DCF, due diligence, raporty rynkowe' },       ]     },     {       id: 'C2', label: 'CORE 2',       title: 'Property & Lease Management',       subtitle: 'Zarządzanie Nieruchomością i Administracja Najmu',       desc: 'Operacyjne zarządzanie budynkiem. Relacje właściciel–najemca, service charge, compliance z umowami.',       roles: [         { level:'C-level', stl:'S', pl:'Dyrektor Zarządzania Nieruchomościami', en:'Head of Property Management', scope:'Strategia zarządzania całym portfelem, polityki i standardy' },         { level:'Director', stl:'S', pl:'Regionalny Dyrektor Zarządzania', en:'Regional Property Director', scope:'Nadzór nad PM w regionie, relacje z kluczowymi najemcami' },         { level:'Senior', stl:'T', pl:'Starszy Zarządca Nieruchomości', en:'Senior Property Manager', scope:'Budynek klasy A, serwis opłat, negocjacje, compliance' },         { level:'Mid', stl:'O', pl:'Zarządca Nieruchomości', en:'Property Manager', scope:'Codzienna operacja budynku, relacje z najemcami, budżet serwisowy' },         { level:'Junior', stl:'O', pl:'Specjalista ds. Administracji Najmu', en:'Lease Administrator', scope:'Śledzenie terminów, indeksacje, opcje, bazy danych najmu' },       ]     },     {       id: 'C3', label: 'CORE 3',       title: 'Corporate Real Estate (CRE) Strategy',       subtitle: 'Strategia Nieruchomości Korporacyjnych',       desc: 'Wewnętrzna funkcja korporacyjna. Portfel jako zasób strategiczny — decyzje lokalizacyjne, optymalizacja kosztów.',       roles: [         { level:'C-level', stl:'S', pl:'Dyrektor ds. Nieruchomości Korporacyjnych', en:'Head of CRE / CREO', scope:'Strategia portfela korporacji, alignment z CFO/COO' },         { level:'Director', stl:'S', pl:'Dyrektor CRE', en:'CRE Director / VP Real Estate', scope:'Globalny portfel, occupancy, workplace strategy' },         { level:'Senior', stl:'T', pl:'Starszy Menedżer CRE', en:'Senior CRE Manager', scope:'Transakcje najmu, negocjacje z landlordami, due diligence' },         { level:'Mid', stl:'T', pl:'Menedżer ds. Nieruchomości', en:'Real Estate / Transaction Manager', scope:'Umowy najmu, relacje z właścicielami, raporty kosztowe' },         { level:'Junior', stl:'O', pl:'Analityk Portfela RE', en:'Real Estate Portfolio Analyst', scope:'Analizy kosztów, benchmarking, wsparcie negocjacji' },       ]     },     {       id: 'C4', label: 'CORE 4',       title: 'Facility & Technical Operations Management',       subtitle: 'Zarządzanie Operacyjno-Techniczne FM',       desc: 'Utrzymanie nieruchomości w sprawności. Podzielone na perspektywę Zamawiającego (Client) i Dostawcy (Supplier).',       split: true,       client: {         label: 'ZAMAWIAJĄCY — Client Side / In-house FM',         roles: [           { level:'C-level', stl:'S', pl:'Dyrektor FM (Zamawiający)', en:'Head of FM (Client)', scope:'Strategia FM, budżet, governance kontraktów IFM' },           { level:'Director', stl:'S', pl:'Regionalny Dyrektor FM', en:'Regional FM Director (Client)', scope:'Nadzór nad kontraktami FM w regionie, KPI dostawcy' },           { level:'Senior', stl:'T', pl:'Starszy Menedżer Kontraktu FM', en:'Senior FM Contract Manager', scope:'Rozliczanie SLA/KPI, audyty dostawcy' },           { level:'Mid', stl:'T', pl:'Menedżer FM (Zamawiający)', en:'FM Manager (Client Side)', scope:'Współpraca z dostawcą, budżet FM, helpdesk' },           { level:'Junior', stl:'O', pl:'Koordynator FM', en:'FM Coordinator (Client)', scope:'Obsługa zgłoszeń, weryfikacja faktur, CAFM' },         ]       },       supplier: {         label: 'DOSTAWCA — Supplier Side / IFM Operator',         roles: [           { level:'C-level', stl:'S', pl:'Dyrektor Operacyjny (Dostawca FM)', en:'COO / FM Division Director', scope:'P&L działu FM, strategia kontraktów, oferta usługowa' },           { level:'Director', stl:'S', pl:'Dyrektor Klienta Kluczowego', en:'Account Director / Key Account Director', scope:'Relacja strategiczna z klientem, odnowienia kontraktów' },           { level:'Senior', stl:'T', pl:'Menedżer Kontraktu (Dostawca)', en:'Contract Manager / Senior Ops Manager', scope:'Zarządzanie kontraktem IFM, SLA, nadzór nad zespołem' },           { level:'Mid', stl:'O', pl:'Menedżer Obiektu', en:'Site Manager / Building Manager', scope:'Operacja obiektów klienta, hard/soft services' },           { level:'Junior', stl:'O', pl:'Koordynator / Technik FM', en:'FM Coordinator / Maintenance Technician', scope:'Realizacja zleceń, helpdesk, przeglądy techniczne' },         ],         frontline: [           { level:'Brygadzista', stl:'W', pl:'Brygadzista Techniczny', en:'Technical Team Leader / Shift Supervisor', scope:'Nadzór nad technikami na zmianie, przydział zadań, pierwsza eskalacja awarii, odbiór prac' },           { level:'Pracownik', stl:'W', pl:'Technik Utrzymania Ruchu (wielobranżowy)', en:'Multi-skilled Maintenance Technician', scope:'Przeglądy prewencyjne, naprawy bieżące: elektryka, hydraulika, HVAC, drobne prace ogólnobudowlane' },           { level:'Pracownik', stl:'W', pl:'Technik HVAC / Chłodnictwa', en:'HVAC / Refrigeration Technician', scope:'Serwis central wentylacyjnych, klimatyzatorów, chillerów, urządzeń chłodniczych' },           { level:'Pracownik', stl:'W', pl:'Elektryk Utrzymania', en:'Electrical Maintenance Technician', scope:'Obsługa rozdzielni, instalacji elektrycznych, UPS, oświetlenia awaryjnego, BMS' },           { level:'Pracownik', stl:'W', pl:'Technik BMS / Automatyki', en:'BMS / Building Automation Technician', scope:'Monitoring i programowanie systemu zarządzania budynkiem, reakcja na alarmy systemowe' },         ]       }     },     {       id: 'C5', label: 'CORE 5',       title: 'Development & Project Management',       subtitle: 'Deweloperstwo i Zarządzanie Projektami RE',       desc: 'Tworzenie i adaptacja przestrzeni. Fit-out, relokacje, przebudowy, projekty deweloperskie.',       roles: [         { level:'C-level', stl:'S', pl:'Dyrektor Rozwoju / Techniczny', en:'Development Director / Technical Director', scope:'Pipeline projektów deweloperskich, capex, nabycie gruntów' },         { level:'Director', stl:'S', pl:'Dyrektor Projektów RE', en:'Head of Project Management (RE)', scope:'Portfel projektów fit-out i budowlanych, standardy, budżety' },         { level:'Senior', stl:'T', pl:'Starszy Kierownik Projektu RE', en:'Senior Project Manager (RE/Fit-out)', scope:'Kompleksowe zarządzanie projektem aranżacji od A do Z' },         { level:'Mid', stl:'T', pl:'Kierownik Projektu Budowlanego', en:'Project Manager (Construction/Fit-out)', scope:'Koordynacja wykonawców, harmonogram, budżet, odbiory' },         { level:'Junior', stl:'O', pl:'Asystent Projektu / Kosztorysant', en:'Project Coordinator / Junior QS', scope:'Wsparcie PM, kosztorysy, zamówienia, dokumentacja' },       ]     },     {       id: 'C6', label: 'CORE 6',       title: 'Transaction & Agency Services',       subtitle: 'Usługi Transakcyjne i Agencyjne',       desc: 'Rynek zewnętrzny — kupno, sprzedaż, najem, reprezentacja stron. Agencje: JLL, CBRE, Savills, Cushman, Knight Frank.',       roles: [         { level:'C-level', stl:'S', pl:'Dyrektor ds. Rynków Kapitałowych', en:'Head of Capital Markets / MD', scope:'Strategia transakcyjna, relacje z inwestorami instytucjonalnymi' },         { level:'Director', stl:'S', pl:'Dyrektor Działu Transakcyjnego', en:'Director – Investment / Leasing', scope:'Zarządzanie zespołem brokerskim, kluczowe transakcje' },         { level:'Senior', stl:'T', pl:'Starszy Doradca Transakcyjny', en:'Senior Investment / Leasing Advisor', scope:'Samodzielne transakcje klasy A, reprezentacja klienta' },         { level:'Mid', stl:'T', pl:'Doradca ds. Wynajmu / Inwestycji', en:'Leasing / Investment Consultant', scope:'Komercjalizacja powierzchni, reprezentacja najemców' },         { level:'Junior', stl:'O', pl:'Analityk Rynkowy / Asystent', en:'Research Analyst / Junior Advisor', scope:'Raporty rynkowe, bazy transakcji, wsparcie due diligence' },       ]     },   ],   noncore: [     {       id: 'N1', label: 'NON-CORE 1',       title: 'Workplace Experience & Environment',       subtitle: 'Doświadczenie i Środowisko Pracy',       desc: 'Miękka warstwa FM — hospitality w biurze, community management, kultura miejsca pracy.',       roles: [         { level:'Director', stl:'S', pl:'Dyrektor ds. Środowiska Pracy', en:'Head of Workplace Experience', scope:'Strategia employee experience, hospitality, kultura miejsca pracy' },         { level:'Senior', stl:'T', pl:'Menedżer Doświadczeń Workplace', en:'Workplace Experience Manager', scope:'Programy amenity, onboarding do przestrzeni, events biurowe' },         { level:'Mid', stl:'O', pl:'Menedżer Front of House', en:'Front of House / Office Hospitality Mgr', scope:'Recepcja, concierge, standardy obsługi, dostawcy hospitality' },         { level:'Junior', stl:'O', pl:'Host / Koordynator Biura', en:'Workplace Host / Community Coordinator', scope:'Codzienna obsługa użytkowników, feedback, wsparcie eventów' },       ]     },     {       id: 'N2', label: 'NON-CORE 2',       title: 'Workplace Strategy & Space Planning',       subtitle: 'Strategia Miejsca Pracy i Planowanie Przestrzeni',       desc: 'Projektowanie modelu użytkowania — hybrydowość, ABW, desk ratio, occupancy analytics.',       roles: [         { level:'Director', stl:'S', pl:'Dyrektor ds. Strategii Workplace', en:'Head of Workplace Strategy', scope:'Globalna strategia: hybrydowość, desk ratio, ABW' },         { level:'Senior', stl:'T', pl:'Starszy Strateg Workplace', en:'Senior Workplace Strategist', scope:'Projektowanie modeli pracy, occupancy badania, wdrożenie ABW' },         { level:'Mid', stl:'T', pl:'Planista Przestrzeni', en:'Space Planner / Space Manager', scope:'Plany CAD/CAFM, alokacje działów, raporty space utilization' },         { level:'Junior', stl:'O', pl:'Analityk Occupancy', en:'Occupancy / Workplace Data Analyst', scope:'Dane z sensorów IoT, dashboardy, benchmarking zajętości' },       ]     },     {       id: 'N3', label: 'NON-CORE 3 ★',       title: 'Sustainability, ESG & Energy Management',       subtitle: 'Zrównoważony Rozwój i Zarządzanie Energią',       desc: 'Certyfikacje BREEAM/LEED/WELL, CSRD, EU Taxonomy, dekarbonizacja aktywów. Migruje do CORE.',       roles: [         { level:'C-level', stl:'S', pl:'Dyrektor ds. Zrównoważonego Rozwoju RE', en:'Head of ESG / Sustainability Director', scope:'Strategia ESG portfela, CSRD, EU Taxonomy, net zero roadmap' },         { level:'Senior', stl:'T', pl:'Menedżer ESG (RE)', en:'ESG Manager (Real Estate)', scope:'BREEAM/LEED/WELL, audyty CO₂, green lease, GHG reporting' },         { level:'Mid', stl:'T', pl:'Menedżer Energii', en:'Energy Manager', scope:'Zarządzanie zużyciem energii, umowy z dostawcami, M&V' },         { level:'Junior', stl:'O', pl:'Specjalista ds. Zrównoważonego Budownictwa', en:'Sustainability Analyst / Green Building Spec.', scope:'Dane ESG, wsparcie certyfikacji, raporty środowiskowe' },       ]     },     {       id: 'N4', label: 'NON-CORE 4',       title: 'Soft Services Management',       subtitle: 'Zarządzanie Usługami Miękkimi',       desc: 'Ochrona, czystość, catering, recepcja, parking, waste. Typowo outsourcowane. Podział na Client/Supplier.',       split: true,       client: {         label: 'ZAMAWIAJĄCY — Client Side',         roles: [           { level:'Senior', stl:'T', pl:'Menedżer Usług Miękkich (Zamawiający)', en:'Soft Services Manager (Client)', scope:'Nadzór nad dostawcami ochrony, czystości, cateringu, SLA' },           { level:'Mid', stl:'O', pl:'Koordynator Usług Dodatkowych', en:'Soft Services Coordinator (Client)', scope:'Rozliczanie dostawców, inspekcje jakości, budżet' },         ]       },       supplier: {         label: 'DOSTAWCA — Supplier Side',         roles: [           { level:'Director', stl:'S', pl:'Dyrektor Operacyjny – Usługi Miękkie', en:'Operations Director – Soft Services', scope:'Dywizja soft services (cleaning, security, catering) – P&L' },           { level:'Senior', stl:'T', pl:'Menedżer Kontraktu – Usługi Miękkie', en:'Contract Manager – Soft Services', scope:'Realizacja usług, SLA, nadzór nad zespołami' },           { level:'Mid', stl:'O', pl:'Kierownik Obiektu – Usługi Miękkie', en:'Site Supervisor – Cleaning / Security', scope:'Nadzór operacyjny, grafiki, kontrola jakości' },           { level:'Junior', stl:'O', pl:'Pracownik Serwisu', en:'Service Operative', scope:'Realizacja usługi na obiekcie wg harmonogramu' },         ],         frontline: [           { level:'Brygadzista', stl:'W', pl:'Brygadzista Czystości / Shift Leader', en:'Cleaning Team Leader / Shift Leader', scope:'Nadzór nad pracownikami sprzątającymi na zmianie, kontrola jakości, przydział stref, raport do supervisora' },           { level:'Brygadzista', stl:'W', pl:'Dowódca Zmiany Ochrony', en:'Security Shift Commander / Head Guard', scope:'Zarządzanie posterunkami i patrolami podczas zmiany, eskalacja incydentów, raport pozmianowy' },           { level:'Pracownik', stl:'W', pl:'Pracownik Sprzątający / Serwis Czystości', en:'Cleaning Operative / Housekeeper', scope:'Sprzątanie stref biurowych, sanitariatów, przestrzeni wspólnych wg harmonogramu i standardu' },           { level:'Pracownik', stl:'W', pl:'Pracownik Ochrony Fizycznej', en:'Security Guard / Officer', scope:'Ochrona obiektu, kontrola dostępu, monitoring CCTV, obchody, reakcja na incydenty' },           { level:'Pracownik', stl:'W', pl:'Recepcjonista / Host Recepcji', en:'Receptionist / Front Desk Officer', scope:'Obsługa wejścia głównego, rejestracja gości, obsługa centrali, koordynacja kurierów' },           { level:'Pracownik', stl:'W', pl:'Pracownik Cateringu / Kelner Biurowy', en:'Catering Assistant / Corporate Hospitality Staff', scope:'Obsługa kuchni pracowniczej, serwis kawowy, cateringi na spotkania, obsługa sali jadalnej' },         ]       }     },     {       id: 'N5', label: 'NON-CORE 5',       title: 'Health, Safety & Compliance (HSE)',       subtitle: 'BHP i Zgodność Regulacyjna',       desc: 'Fire safety, Legionella, CDM, statutory inspections. Krytyczna prawnie, wspierająca operacyjnie.',       roles: [         { level:'Director', stl:'S', pl:'Dyrektor ds. BHP i Compliance RE', en:'Head of HSE & Compliance (RE)', scope:'Polityka BHP portfela, zarządzanie ryzykiem, regulatory compliance' },         { level:'Senior', stl:'T', pl:'Starszy Specjalista BHP', en:'Senior HSE Manager / Fire Safety Manager', scope:'Audyty bezpieczeństwa, ryzyko pożarowe, Legionella, CDM' },         { level:'Mid', stl:'O', pl:'Inspektor BHP / Compliance Manager', en:'HSE Officer / Statutory Compliance Mgr', scope:'Przeglądy, dokumentacja BHP, szkolenia, wymogi prawne' },         { level:'Junior', stl:'O', pl:'Asystent ds. Bezpieczeństwa', en:'HSE Coordinator / Safety Administrator', scope:'Rejestracja zdarzeń, wsparcie audytów, baza dokumentacji' },       ]     },     {       id: 'N6', label: 'NON-CORE 6 ★',       title: 'Technology, Data & PropTech',       subtitle: 'Technologie, Dane i PropTech',       desc: 'CAFM/IWMS, IoT, smart building, digital twin, AI w FM. Rosnące znaczenie strategiczne — migruje do CORE.',       roles: [         { level:'Director', stl:'S', pl:'Dyrektor ds. Technologii RE / PropTech', en:'Head of PropTech / Digital RE Director', scope:'Transformacja cyfrowa RE/FM, strategia IWMS, IoT, AI' },         { level:'Senior', stl:'T', pl:'Menedżer Systemów CAFM/IWMS', en:'CAFM / IWMS System Manager', scope:'Wdrożenie Planon, Archibus, Tririga, ServiceNow – integracje' },         { level:'Mid', stl:'O', pl:'Specjalista Smart Building / IoT', en:'Smart Building Specialist / IoT Engineer', scope:'BMS, sensory, dashboardy danych budynkowych' },         { level:'Junior', stl:'O', pl:'Analityk Danych RE', en:'RE Data Analyst / PropTech Analyst', scope:'Analizy CAFM, occupancy, media; BI, raporty' },       ]     },     {       id: 'N7', label: 'NON-CORE 7',       title: 'Finance, Reporting & Administration (RE)',       subtitle: 'Finanse i Administracja Back-office RE',       desc: 'Rachunkowość portfela, service charge, procurement FM/RE, administracja umów.',       roles: [         { level:'Director', stl:'S', pl:'Dyrektor Finansowy RE', en:'RE Finance Director / Controller', scope:'Raportowanie finansowe portfela, budżetowanie capex/opex' },         { level:'Senior', stl:'T', pl:'Starszy Księgowy / Kontroler RE', en:'Senior RE Accountant / Budget Controller', scope:'Service charge accounting, rozliczenia z najemcami' },         { level:'Mid', stl:'T', pl:'Specjalista ds. Zamówień FM/RE', en:'Procurement Manager (FM/RE)', scope:'Przetargi FM/RE, umowy ramowe, zarządzanie dostawcami' },         { level:'Junior', stl:'O', pl:'Administrator Kontraktów', en:'Contract / Lease Data Administrator', scope:'Bazy danych umów, faktury, dokumentacja RE' },       ]     },     {       id: 'N8', label: 'NON-CORE 8',       title: 'Consultancy, Research & Advisory',       subtitle: 'Doradztwo Zewnętrzne i Badania Rynku',       desc: 'Audyty FM, specyfikacje usług, raporty rynkowe, doradztwo transakcyjne. Ekspertyza sprzedawana na rynek.',       roles: [         { level:'Director', stl:'S', pl:'Dyrektor ds. Doradztwa RE', en:'Director – Real Estate Advisory', scope:'Strategiczne doradztwo dla korporacji i inwestorów' },         { level:'Senior', stl:'T', pl:'Starszy Konsultant FM/RE', en:'Senior Consultant (FM / Workplace / CRE)', scope:'Audyty FM, specyfikacje usług, przetargi po stronie klienta' },         { level:'Mid', stl:'O', pl:'Analityk Rynku Nieruchomości', en:'Market Research Analyst (RE)', scope:'Raporty rynkowe, vacancy rates, trendy, dane transakcyjne' },         { level:'Junior', stl:'O', pl:'Młodszy Konsultant / Analityk', en:'Junior Consultant / Research Associate', scope:'Dane, prezentacje, wsparcie projektów doradczych' },       ]     },     {       id: 'N9', label: 'NON-CORE 9',       title: 'Facility Management (jako funkcja wspierająca)',       subtitle: 'FM Outsourcowany / Niestrategiczny w modelu korporacyjnym',       desc: 'W organizacjach, które traktują FM jako funkcję wyłącznie wspierającą i w pełni outsourcowaną — FM nie jest kompetencją wewnętrzną, lecz zarządzaną usługą zewnętrzną. Obejmuje całość operacji budynkowych oddanych dostawcy IFM.',       split: true,       client: {         label: 'ZAMAWIAJĄCY — Minimalna funkcja nadzorcza (Client Lite)',         roles: [           { level:'Director', stl:'S', pl:'Dyrektor Administracyjny / COO', en:'Head of Administration / COO', scope:'FM jako jeden z obszarów pod COO lub CFO, brak dedykowanego Head of FM' },           { level:'Senior', stl:'T', pl:'Menedżer ds. Usług Ogólnych', en:'General Services Manager / Office Manager', scope:'Nadzór nad jednym dostawcą IFM, budżet biurowy, relacja z landlord' },           { level:'Mid', stl:'O', pl:'Koordynator Administracyjno-FM', en:'Facilities Coordinator / Admin Manager', scope:'Punkt kontaktowy z dostawcą, helpdesk, odbiór faktur, raportowanie' },           { level:'Junior', stl:'O', pl:'Asystent Administracyjny ds. Biura', en:'Office Administrator / FM Assistant', scope:'Obsługa zgłoszeń, zaopatrzenie biura, wsparcie koordynatora' },         ]       },       supplier: {         label: 'DOSTAWCA — Pełna obsługa IFM (Total FM / Managed Services)',         roles: [           { level:'C-level', stl:'S', pl:'Dyrektor Zarządzający (Dostawca IFM)', en:'Managing Director / CEO (FM Company)', scope:'Strategia i P&L całej firmy FM, pozyskiwanie portfela kontraktów' },           { level:'Director', stl:'S', pl:'Dyrektor Operacyjny / Account Director', en:'Operations Director / Senior Account Director', scope:'Zarządzanie kluczowymi kontraktami IFM, ekspansja klienta, eskalacje' },           { level:'Senior', stl:'T', pl:'Menedżer IFM / Menedżer Kontraktu', en:'IFM Manager / Contract Manager', scope:'Pełen zakres usług na kontrakcie: hard, soft, helpdesk, raportowanie' },           { level:'Mid', stl:'O', pl:'Menedżer Obiektu / Koordynator IFM', en:'Site Manager / IFM Coordinator', scope:'Codzienna operacja budynku, nadzór serwisów, kontakt z klientem' },           { level:'Junior', stl:'O', pl:'Technik / Specjalista Serwisu', en:'Multi-skilled Technician / Service Specialist', scope:'Realizacja przeglądów, napraw, interwencji technicznych i miękkich' },         ],         frontline: [           { level:'Brygadzista', stl:'W', pl:'Brygadzista Utrzymania (IFM)', en:'IFM Shift Supervisor / Team Leader', scope:'Nadzór nad całym zespołem wykonawczym na zmianie (technika + serwisy miękkie), przydzielanie zadań, eskalacje' },           { level:'Pracownik', stl:'W', pl:'Technik Wielobranżowy (IFM)', en:'Multi-skilled IFM Technician', scope:'Realizacja zleceń wszystkich branż technicznych w ramach kontraktu IFM — elektryka, HVAC, hydraulika, BMS' },           { level:'Pracownik', stl:'W', pl:'Pracownik Sprzątający (IFM)', en:'IFM Cleaning Operative', scope:'Sprzątanie obiektu w ramach zintegrowanego kontraktu FM — koordynacja z techniką' },           { level:'Pracownik', stl:'W', pl:'Pracownik Ochrony (IFM)', en:'IFM Security Officer', scope:'Ochrona obiektu jako element zintegrowanego kontraktu FM — monitoring, dostęp, obchody' },         ]       }     },     {       id: 'N10', label: 'NON-CORE 10 ⚡',       title: 'Energy & Utilities Management',       subtitle: 'Zarządzanie Energią i Mediami — funkcja crossfunkcyjna',       desc: 'Funkcja crossfunkcyjna przecinająca kilka kategorii. Zależnie od kontekstu organizacyjnego zakorzeniona w ESG (dekarbonizacja), FM (media/koszty operacyjne), Finance (zakup energii) lub Asset Management (wartość aktywa). Poniżej pełna taksonomia stanowisk z oznaczeniem przynależności.',       energy: true,       crosslinks: ['CORE 1 — wartość aktywa / Green Premium', 'CORE 4 — media jako koszt FM', 'NON-CORE 3 — dekarbonizacja / ESG', 'NON-CORE 7 — zakup energii / Finance'],       roles: [         { level:'C-level', stl:'S', pl:'Dyrektor ds. Energii i Dekarbonizacji', en:'Head of Energy & Decarbonisation', scope:'Strategia energetyczna portfela, net zero roadmap, raportowanie GHG Scope 1/2/3', context:'NON-CORE 3 / CORE 1' },         { level:'Director', stl:'S', pl:'Dyrektor ds. Zarządzania Energią', en:'Energy Director / Head of Energy Management', scope:'Zarządzanie programem energetycznym całej organizacji lub portfela nieruchomości', context:'NON-CORE 3' },         { level:'Senior', stl:'T', pl:'Starszy Menedżer Energii (Portfel)', en:'Senior Energy Manager (Portfolio)', scope:'Monitoring zużycia energii w portfelu, projekty efektywności, targety redukcji', context:'CORE 4 Client / NON-CORE 3' },         { level:'Senior', stl:'T', pl:'Menedżer Zakupów Energii', en:'Energy Procurement Manager', scope:'Przetargi na dostawy energii, hedging cen, umowy PPA, rozliczenia service charge', context:'NON-CORE 7' },         { level:'Senior', stl:'T', pl:'Menedżer EPC / Gwarantowanych Oszczędności', en:'Energy Performance Contract Manager', scope:'Energy Performance Contracting, M&V (Measurement & Verification), gwarantowane savings', context:'CORE 4 Supplier' },         { level:'Mid', stl:'T', pl:'Menedżer Energii (Obiekt)', en:'Energy / Utilities Manager (Site)', scope:'Zarządzanie mediami na obiekcie: energia, woda, gaz — monitoring, awarie, budżet', context:'CORE 4 Client lub Supplier' },         { level:'Mid', stl:'O', pl:'Analityk Zużycia Energii', en:'Energy Data Analyst / Metering Analyst', scope:'Submetering, dashboardy zużycia, anomalie, raporty ISO 50001, ESOS compliance', context:'CORE 4 / NON-CORE 6' },         { level:'Mid', stl:'T', pl:'Specjalista ds. Efektywności Energetycznej', en:'Energy Efficiency Specialist', scope:'Audyty energetyczne, modernizacje instalacji, LED, BMS, pompy ciepła, OZE', context:'NON-CORE 3' },         { level:'Junior', stl:'O', pl:'Koordynator ds. Energii i Mediów', en:'Energy Coordinator / Utilities Administrator', scope:'Zbieranie danych licznikowych, obsługa faktur za media, wsparcie raportowania', context:'CORE 4 / NON-CORE 7' },       ]     },   ] };  function makeRoleCard(role) {   const stlColors = { S:'#4F46E5', T:'#D97706', O:'#16A34A' };   const stlBadge = role.stl ? `<div class="role-level-badge ${role.stl}" style="background:${stlColors[role.stl]}">${role.stl}</div>` : '';   return `     <div class="role-card" data-stl="${role.stl||''}"          onmouseenter="showTooltip(event, '${role.scope.replace(/'/g,"&#39;")}')"          onmouseleave="hideTooltip()">       ${stlBadge}       <div class="role-level">${role.level}</div>       <div class="role-title-pl">${role.pl}</div>       <div class="role-title-en">${role.en}</div>     </div>`; }  function makeFrontlineCard(role) {   const stlColors = { W:'#B45309' };   return `     <div class="role-card wykonawczy-card" data-stl="W"          onmouseenter="showTooltip(event, '${role.scope.replace(/'/g,"&#39;")}')"          onmouseleave="hideTooltip()">       <div class="role-level-badge W" style="background:#B45309">W</div>       <div class="role-level" style="color:#B45309">${role.level}</div>       <div class="role-title-pl" style="color:#7C2D12">${role.pl}</div>       <div class="role-title-en">${role.en}</div>     </div>`; }  function makeSplitSection(sec, isCore) {   const cls = isCore ? 'core-block' : 'nc-block';   const tag = isCore ? 'CORE' : 'NON-CORE';   const tagStyle = isCore ? '' : '';    return `   <div class="section-block ${cls}" id="${sec.id}">     <div class="section-header" onclick="toggle('${sec.id}')">       <span class="section-num">${sec.label}</span>       <div style="flex:1">         <div class="section-title">${sec.title}</div>         <div class="section-subtitle">${sec.subtitle}</div>       </div>       <span class="section-tag">${tag}</span>       <span style="font-family:'DM Mono',monospace;font-size:10px;opacity:0.5;margin:0 8px">CLIENT + SUPPLIER</span>       <span class="chevron">▼</span>     </div>     <div class="roles-panel">       <div style="font-size:11px;color:#666;padding:4px 0 8px;font-style:italic">${sec.desc}</div>       <div class="split-panel">         <div class="split-side client-side">           <div class="perspective-label">${sec.client.label}</div>           <div class="split-roles-grid">             ${sec.client.roles.map(makeRoleCard).join('')}           </div>         </div>         <div class="split-side supplier-side">           <div class="perspective-label">${sec.supplier.label}</div>           <div class="split-roles-grid">             ${sec.supplier.roles.map(makeRoleCard).join('')}           </div>           ${sec.supplier.frontline ? `           <div class="wykonawczy-section">             <div class="perspective-label">↳ POZIOM WYKONAWCZY — Pracownicy i Brygadziści (Frontline)</div>             <div class="split-roles-grid">               ${sec.supplier.frontline.map(makeFrontlineCard).join('')}             </div>           </div>` : ''}         </div>       </div>     </div>   </div>`; }  function makeEnergySection(sec) {   return `   <div class="section-block energy-block" id="${sec.id}">     <div class="section-header" onclick="toggle('${sec.id}')">       <span class="section-num">${sec.label}</span>       <div style="flex:1">         <div class="section-title">${sec.title}</div>         <div class="section-subtitle">${sec.subtitle}</div>       </div>       <span class="section-tag">NON-CORE</span>       <span style="font-family:'DM Mono',monospace;font-size:10px;opacity:0.5;margin:0 8px">CROSSFUNKCYJNA</span>       <span class="chevron">▼</span>     </div>     <div class="roles-panel">       <div style="font-size:11px;color:#555;padding:4px 0 8px;font-style:italic">${sec.desc}</div>       <div class="crosslinks-bar">         <span class="crosslinks-label">⚡ Powiązania:</span>         ${sec.crosslinks.map(l => `<span class="crosslink-pill">${l}</span>`).join('')}       </div>       <div class="energy-roles-grid">       ${sec.roles.map(r => {         const stlColors = { S:'#4F46E5', T:'#D97706', O:'#16A34A' };         const stlBadge = r.stl ? `<div class="role-level-badge ${r.stl}" style="background:${stlColors[r.stl]}">${r.stl}</div>` : '';         return `           <div class="role-card" data-stl="${r.stl||''}"                onmouseenter="showTooltip(event, '${r.scope.replace(/'/g,"&#39;")}')"                onmouseleave="hideTooltip()">             ${stlBadge}             <div class="role-level">${r.level}</div>             <div class="role-title-pl">${r.pl}</div>             <div class="role-title-en">${r.en}</div>             <div class="context-badge">${r.context}</div>           </div>`;}).join('')}       </div>     </div>   </div>`; }  function makeSection(sec, isCore) {   if (sec.energy) return makeEnergySection(sec);   if (sec.split) return makeSplitSection(sec, isCore);   const cls = isCore ? 'core-block' : 'nc-block';   const tag = isCore ? 'CORE' : 'NON-CORE';    return `   <div class="section-block ${cls}" id="${sec.id}">     <div class="section-header" onclick="toggle('${sec.id}')">       <span class="section-num">${sec.label}</span>       <div style="flex:1">         <div class="section-title">${sec.title}</div>         <div class="section-subtitle">${sec.subtitle}</div>       </div>       <span class="section-tag">${tag}</span>       <span class="chevron">▼</span>     </div>     <div class="roles-panel">       <div style="font-size:11px;color:#666;padding:4px 0 8px;font-style:italic">${sec.desc}</div>       <div class="roles-grid">         ${sec.roles.map(makeRoleCard).join('')}       </div>     </div>   </div>`; }  function render() {   const canvas = document.getElementById('canvas');   let html = '';    // CORE divider   html += `<div class="section-divider core-divider">     <div class="divider-line"></div>     <div class="divider-label">CORE — Funkcje kluczowe</div>     <div class="divider-line"></div>   </div>`;    DATA.core.forEach(sec => { html += makeSection(sec, true); });    // NON-CORE divider   html += `<div class="section-divider nc-divider" style="margin-top:16px">     <div class="divider-line"></div>     <div class="divider-label">NON-CORE — Funkcje wspierające</div>     <div class="divider-line"></div>   </div>   <div style="padding:0 0 6px;font-size:11px;color:#999;font-style:italic;font-family:'DM Mono',monospace">     ★ = kategorie migrujące do CORE ze względu na regulacje ESG i cyfryzację &nbsp;·&nbsp; ⚡ = funkcja crossfunkcyjna (Energy)   </div>`;    DATA.noncore.forEach(sec => { html += makeSection(sec, false); });    canvas.innerHTML = html; }  // ── LEVEL FILTER ──────────────────────────────────────────────────── let activeFilters = new Set(['S','T','O','W']);  function filterLevel(lvl) {   const card = document.querySelector(`.level-card[data-level="${lvl}"]`);   if (activeFilters.has(lvl)) {     // If all 3 active and we click one → solo filter that level     if (activeFilters.size === 4) {       activeFilters.clear();       activeFilters.add(lvl);     } else if (activeFilters.size === 1) {       // Re-enable all       activeFilters = new Set(['S','T','O']);     } else {       activeFilters.delete(lvl);     }   } else {     activeFilters.add(lvl);   }   applyFilter(); }  function applyFilter() {   const allActive = activeFilters.size === 4;    // Update level cards visual state   document.querySelectorAll('.level-card').forEach(c => {     const lvl = c.dataset.level;     c.classList.toggle('active', activeFilters.has(lvl));   });    // Dim/show role cards   document.querySelectorAll('.role-card').forEach(card => {     const stl = card.dataset.stl;     if (allActive || !stl || activeFilters.has(stl)) {       card.classList.remove('dimmed');     } else {       card.classList.add('dimmed');     }   });    // Auto-expand all sections when filter active   if (!allActive) {     document.querySelectorAll('.section-block').forEach(el => el.classList.add('open'));   }    // Update filter indicator   const indicator = document.getElementById('filterIndicator');   const filterText = document.getElementById('filterText');   const labels = { S:'⬡ Strategiczny', T:'⬡ Taktyczny', O:'⬡ Operacyjny', W:'⬡ Wykonawczy' };   if (allActive) {     indicator.style.display = 'none';   } else {     indicator.style.display = 'flex';     const names = [...activeFilters].map(f => labels[f]).join(' + ');     filterText.textContent = `Filtr aktywny: ${names} — widoczne tylko stanowiska tego poziomu`;   } }  function clearFilter() {   activeFilters = new Set(['S','T','O','W']);   applyFilter(); }  function toggleLevelPanel() {   const cards = document.getElementById('levelCards');   const btn = document.querySelector('.level-panel-toggle');   const hidden = cards.style.display === 'none';   cards.style.display = hidden ? 'grid' : 'none';   btn.textContent = hidden ? 'Zwiń ▲' : 'Rozwiń ▼'; }  function toggle(id) {   const el = document.getElementById(id);   el.classList.toggle('open'); }  function expandAll() {   document.querySelectorAll('.section-block').forEach(el => el.classList.add('open')); }  function collapseAll() {   document.querySelectorAll('.section-block').forEach(el => el.classList.remove('open')); }  // Tooltip const tooltip = document.getElementById('tooltip'); function showTooltip(e, text) {   tooltip.textContent = text;   tooltip.classList.add('visible');   moveTooltip(e); } function hideTooltip() { tooltip.classList.remove('visible'); } document.addEventListener('mousemove', e => {   if (tooltip.classList.contains('visible')) moveTooltip(e); }); function moveTooltip(e) {   tooltip.style.left = (e.clientX + 16) + 'px';   tooltip.style.top = (e.clientY - 8) + 'px'; }  // ════════════════════════════════════════════════════════════════════ // BUILDING TYPE DATA // Dla każdej roli w DATA: dodajemy pole bt:[array of building codes] // Kody: OFF=biurowy, RET=handlowy, LOG=magazynowy, IND=przemysłowy, //       HOT=hotelowy, MIX=mieszany, PUB=użyteczności publicznej // Brak pola bt = ALL (wszystkie typy) // ════════════════════════════════════════════════════════════════════  // Mapowanie ról na typy obiektów — bt field added inline below // Funkcje zarządcze portfelowe (C1,C3,C6) są relevantne dla wszystkich typów // FM (C4,N9) różni się znacznie między typami // Unikalne stanowiska per typ obiektu:  const BUILDING_TYPES = {   ALL: { name:'Wszystkie typy', emoji:'◎', color:'#1C1C1C' },   OFF: { name:'Biurowy', emoji:'🏢', color:'#2563EB',     unique: [       { cat:'CORE 3', level:'Senior', stl:'T', pl:'Menedżer ds. Środowiska Pracy (CRE)', en:'Workplace Manager (Corporate Office)', scope:'Hybrydowy model pracy, desk booking, standardy biurowe, employee experience' },       { cat:'CORE 4', level:'Mid', stl:'O', pl:'Menedżer Recepcji Korporacyjnej', en:'Corporate Reception Manager', scope:'Zarządzanie recepcją, goście VIP, standardy obsługi w biurze klasy A' },       { cat:'CORE 4', level:'Pracownik', stl:'W', pl:'Technik AV / Sal Konferencyjnych', en:'AV / Conference Room Technician', scope:'Obsługa systemów audio-video, sal spotkań, wsparcie techniczne prezentacji' },       { cat:'NON-CORE 2', level:'Mid', stl:'T', pl:'Koordynator Hot-Desk / Desk Booking', en:'Desk Booking Coordinator / Workplace App Admin', scope:'Administracja systemem rezerwacji biurek, analiza occupancy, wsparcie pracowników' },       { cat:'NON-CORE 4', level:'Pracownik', stl:'W', pl:'Barista / Kawiarnia Biurowa', en:'Corporate Barista / Coffee Bar Operative', scope:'Obsługa kawiarni lub punktu kawowego w biurze, przygotowanie napojów, obsługa gości' },     ]   },   RET: { name:'Handlowy / Retail', emoji:'🛍️', color:'#DC2626',     unique: [       { cat:'CORE 2', level:'Senior', stl:'T', pl:'Zarządca Centrum Handlowego', en:'Shopping Centre Manager / Mall Manager', scope:'Zarządzanie operacją centrum, tenant mix, marketing, footfall, relacje z najemcami retail' },       { cat:'CORE 2', level:'Mid', stl:'T', pl:'Menedżer ds. Najemców Retail', en:'Retail Leasing / Tenant Relations Manager', scope:'Relacje z najemcami sklepowymi, renegocjacje, egzekwowanie standardów handlowych' },       { cat:'CORE 6', level:'Senior', stl:'T', pl:'Doradca ds. Najmu Retail', en:'Retail Leasing Advisor', scope:'Komercjalizacja powierzchni handlowych, reprezentacja właściciela centrum, tenant mix strategy' },       { cat:'CORE 4', level:'Mid', stl:'O', pl:'Menedżer Operacji Centrum', en:'Mall Operations Manager', scope:'Koordynacja techniki, ochrony, czystości i logistyki dostaw w centrum handlowym' },       { cat:'NON-CORE 1', level:'Mid', stl:'O', pl:'Menedżer Marketingu Centrum', en:'Shopping Centre Marketing Manager', scope:'Kampanie, eventy, loyalty programme, media społecznościowe, ruch klientów' },       { cat:'CORE 4', level:'Brygadzista', stl:'W', pl:'Brygadzista Dostaw / Koordynator Rampy', en:'Delivery Bay Supervisor / Loading Dock Coordinator', scope:'Nadzór nad dostawami towarów do sklepów, harmonogram ramp, kontrola ruchu w strefie dostaw' },       { cat:'NON-CORE 4', level:'Pracownik', stl:'W', pl:'Pracownik Ochrony Retail (detektyw)', en:'Retail Loss Prevention Officer', scope:'Ochrona przed kradzieżami sklepowymi, monitoring CCTV, współpraca z policją' },     ]   },   LOG: { name:'Magazynowy / Logistyczny', emoji:'📦', color:'#D97706',     unique: [       { cat:'CORE 2', level:'Senior', stl:'T', pl:'Zarządca Parku Logistycznego', en:'Logistics Park Manager / Warehouse Estate Manager', scope:'Zarządzanie wielobudynkowym parkiem magazynowym, najem, utrzymanie, relacje z operatorami' },       { cat:'CORE 4', level:'Senior', stl:'T', pl:'Menedżer Techniczny – Obiekty Magazynowe', en:'Technical Manager (Warehouse / Industrial)', scope:'Utrzymanie bram, doków, posadzek przemysłowych, dachów, sprinklerów, instalacji specjalnych' },       { cat:'CORE 4', level:'Mid', stl:'O', pl:'Inspektor Techniczny Hali', en:'Warehouse Facilities Inspector / Site Surveyor', scope:'Przeglądy stanu technicznego hal, dachu, elewacji, infrastruktury zewnętrznej' },       { cat:'CORE 4', level:'Pracownik', stl:'W', pl:'Technik Bram i Doków Załadunkowych', en:'Loading Dock / Dock Leveller Technician', scope:'Serwis bram przemysłowych, levelerów, uszczelnień dokowych, systemów sterowania' },       { cat:'NON-CORE 5', level:'Mid', stl:'T', pl:'Specjalista HSE – Obiekty Magazynowe', en:'HSE Specialist (Logistics / Warehouse)', scope:'BHP w obiektach wysokiego składowania, ATEX, praca wózków widłowych, ryzyko pożarowe' },       { cat:'CORE 4', level:'Pracownik', stl:'W', pl:'Technik Sprinklerów / Instalacji Ppoż.', en:'Sprinkler / Fire Suppression Technician', scope:'Przeglądy i serwis systemów tryskaczowych, instalacji ppoż. wymaganych w halach magazynowych' },     ]   },   IND: { name:'Przemysłowy / Fabryka', emoji:'🏭', color:'#6D28D9',     unique: [       { cat:'CORE 4', level:'Director', stl:'S', pl:'Dyrektor Utrzymania Ruchu (Fabryka)', en:'Head of Maintenance / Plant Engineering Director', scope:'Strategia utrzymania ruchu zakładu, UR, TPM, budżet capex/opex infrastruktury' },       { cat:'CORE 4', level:'Senior', stl:'T', pl:'Inżynier Utrzymania Ruchu', en:'Maintenance Engineer / Plant Engineer', scope:'Planowanie i realizacja przeglądów maszyn i infrastruktury, zarządzanie CMMS, MTTR/MTBF' },       { cat:'CORE 4', level:'Mid', stl:'T', pl:'Planista Utrzymania Ruchu (CMMS)', en:'Maintenance Planner (CMMS / SAP PM)', scope:'Planowanie zleceń pracy, zarządzanie częściami zamiennymi, harmonogramy przeglądów' },       { cat:'CORE 4', level:'Pracownik', stl:'W', pl:'Mechanik / Elektromechanik Maszyn', en:'Machine Mechanic / Electromechanical Technician', scope:'Naprawy i przeglądy maszyn produkcyjnych, instalacji przemysłowych, automatyki' },       { cat:'NON-CORE 5', level:'Senior', stl:'T', pl:'Inżynier BHP / Bezpieczeństwo Procesowe', en:'Process Safety Engineer / Industrial HSE Manager', scope:'Bezpieczeństwo procesów chemicznych lub produkcyjnych, ATEX, HAZOP, REACH' },       { cat:'NON-CORE 3', level:'Mid', stl:'T', pl:'Inżynier Środowiska / Emisji', en:'Environmental / Emissions Engineer', scope:'Monitoring emisji do atmosfery, ścieków, odpadów, pozwolenia środowiskowe, IPPC/IED' },       { cat:'CORE 4', level:'Brygadzista', stl:'W', pl:'Mistrz Utrzymania Ruchu / Shift UR', en:'Maintenance Shift Leader / UR Foreman', scope:'Nadzór nad zespołem mechaników i elektryków na zmianie, priorytety awaryjne' },     ]   },   HOT: { name:'Hotelowy / Hospitality', emoji:'🏨', color:'#DB2777',     unique: [       { cat:'CORE 2', level:'Senior', stl:'T', pl:'Menedżer Nieruchomości Hotelowej', en:'Hotel Property Manager / Asset Manager (Hospitality)', scope:'Zarządzanie aktywem hotelowym w imieniu właściciela, relacja z operatorem, KPI hotelowe' },       { cat:'CORE 4', level:'Senior', stl:'T', pl:'Chief Engineer / Dyrektor Techniczny Hotelu', en:'Chief Engineer (Hotel)', scope:'Zarządzanie całą infrastrukturą techniczną hotelu: HVAC, elektryka, hydraulika, windy, baseny' },       { cat:'NON-CORE 1', level:'Senior', stl:'T', pl:'Rooms Division Manager / Kierownik Pięter', en:'Rooms Division Manager / Housekeeping Manager', scope:'Zarządzanie piętrowymi, standardy czystości pokoi, zarządzanie bielizną, turnover' },       { cat:'NON-CORE 4', level:'Mid', stl:'O', pl:'Kierownik Służby Pięter', en:'Executive Housekeeper / Floor Supervisor', scope:'Nadzór nad pokojówkami, inspekcja pokoi, zarządzanie harmonogramem sprzątania' },       { cat:'NON-CORE 4', level:'Pracownik', stl:'W', pl:'Pokojówka / Housekeeper', en:'Room Attendant / Housekeeper', scope:'Sprzątanie i przygotowanie pokoi hotelowych według standardu marki' },       { cat:'NON-CORE 1', level:'Mid', stl:'O', pl:'Concierge / Guest Relations Manager', en:'Concierge / Guest Experience Manager', scope:'Obsługa gości VIP, rezerwacje, rekomendacje, wyjątkowe doświadczenia gości' },       { cat:'CORE 4', level:'Pracownik', stl:'W', pl:'Technik Hotelowy (nocny)', en:'Hotel Night Maintenance Technician', scope:'Utrzymanie techniczne hotelu w godzinach nocnych, reakcja na usterki zgłoszone przez gości' },     ]   },   MIX: { name:'Mieszany', emoji:'🏙️', color:'#0891B2',     unique: [       { cat:'CORE 2', level:'Senior', stl:'T', pl:'Zarządca Obiektu Mixed-Use', en:'Mixed-Use Asset Manager / Property Manager', scope:'Zarządzanie portfelem mixed-use: biuro+retail+PRS/resi — różne reżimy najmu i standardy' },       { cat:'CORE 3', level:'Senior', stl:'T', pl:'Menedżer RE – Projekty Wielofunkcyjne', en:'CRE Manager (Mixed-Use / TOD Projects)', scope:'Koordynacja CRE w projektach mixed-use, transport-oriented development, joint ventures' },       { cat:'CORE 4', level:'Senior', stl:'T', pl:'Menedżer FM Mixed-Use (Multi-tenant)', en:'Multi-tenant FM Manager', scope:'FM dla obiektu obsługującego jednocześnie najemców biurowych, handlowych i mieszkalnych' },       { cat:'NON-CORE 1', level:'Mid', stl:'O', pl:'Community Manager (Mixed-Use)', en:'Community & Place Manager', scope:'Zarządzanie społecznością i tożsamością miejsca — eventy, relacje między najemcami różnych sektorów' },       { cat:'CORE 6', level:'Senior', stl:'T', pl:'Doradca ds. Transakcji Mixed-Use', en:'Mixed-Use Transaction Advisor', scope:'Due diligence i transakcje dla obiektów mixed-use — wycena różnych komponentów, complex leasing' },     ]   },   PUB: { name:'Użyteczności Publicznej', emoji:'🎭', color:'#059669',     unique: [       { cat:'CORE 2', level:'Senior', stl:'T', pl:'Zarządca Obiektu Kultury / Lotniska', en:'Public Venue / Airport Facility Manager', scope:'Zarządzanie obiektem użyteczności publicznej: muzeum, teatr, kino, arena, lotnisko, dworzec' },       { cat:'CORE 4', level:'Senior', stl:'T', pl:'Menedżer Operacji – Lotnisko / Arena', en:'Operations Manager (Airport / Arena / Stadium)', scope:'Koordynacja operacji dużego obiektu publicznego: przepływ ludzi, logistyka eventów, bezpieczeństwo' },       { cat:'NON-CORE 5', level:'Senior', stl:'T', pl:'Menedżer Bezpieczeństwa Masowego', en:'Crowd Safety / Mass Event Safety Manager', scope:'Planowanie ewakuacji, zarządzanie tłumem, bezpieczeństwo eventów masowych (SGSA, UEFA, FIFA)' },       { cat:'NON-CORE 4', level:'Mid', stl:'O', pl:'Kierownik Ochrony Obiektu Publicznego', en:'Security Manager (Public Venue)', scope:'Ochrona obiektu otwartego dla publiczności, kontrola wejść, procedury sytuacji kryzysowych' },       { cat:'NON-CORE 1', level:'Mid', stl:'O', pl:'Menedżer Obsługi Widzów / Visitor Experience', en:'Visitor Experience Manager', scope:'Zarządzanie doświadczeniem odwiedzających: przepływ, informacja, obsługa, dostępność' },       { cat:'CORE 4', level:'Pracownik', stl:'W', pl:'Technik Sceny / Obiekt Kulturalny', en:'Stage / Venue Technical Operative', scope:'Obsługa techniczna sceny, oświetlenia, nagłośnienia, riggingu w teatrach, kinach, salach widowiskowych' },       { cat:'NON-CORE 3', level:'Mid', stl:'T', pl:'Menedżer Zrównoważonego Transportu', en:'Sustainable Transport / Mobility Manager', scope:'Zarządzanie infrastrukturą mobilności: parkingi, rowery, EV charging, komunikacja publiczna dla obiektów' },     ]   } };  // Mapa relevancji ról ogólnych do typów obiektów // Każda sekcja ma tablicę typów dla których jest relevantna // Role wspólne mają ALL, specyficzne mają subset const SECTION_BUILDING_MAP = {   C1: ['ALL'],   // Asset management — wszystkie typy   C2: ['ALL'],   // Property management — wszystkie typy   C3: ['OFF','MIX','RET'],  // CRE strategy — głównie biuro i mixed   C4: ['ALL'],   // FM — wszystkie typy   C5: ['ALL'],   // Development — wszystkie typy   C6: ['ALL'],   // Transaction — wszystkie typy   N1: ['OFF','HOT','RET','MIX','PUB'],  // Workplace experience — nie magazyn/fabryka   N2: ['OFF','MIX'],        // Workplace strategy — tylko biuro i mixed   N3: ['ALL'],              // ESG — wszystkie   N4: ['ALL'],              // Soft services — wszystkie   N5: ['ALL'],              // HSE — wszystkie   N6: ['ALL'],              // PropTech — wszystkie   N7: ['ALL'],              // Finance — wszystkie   N8: ['ALL'],              // Consultancy — wszystkie   N9: ['ALL'],              // FM non-core — wszystkie   N10: ['ALL'],             // Energy — wszystkie };  // Szczegółowe mapowanie ról w sekcjach do typów const ROLE_BUILDING_MAP = {   // CORE 2 — Property Management specjalizacje   'Zarządca Centrum Handlowego': ['RET'],   'Zarządca Parku Logistycznego': ['LOG','IND'],   'Zarządca Obiektu Mixed-Use': ['MIX'],   'Zarządca Obiektu Kultury / Lotniska': ['PUB'],   // CORE 4 — FM specjalizacje   'Menedżer Techniczny – Obiekty Magazynowe': ['LOG'],   'Chief Engineer / Dyrektor Techniczny Hotelu': ['HOT'],   'Dyrektor Utrzymania Ruchu (Fabryka)': ['IND'],   'Inżynier Utrzymania Ruchu': ['IND'],   // NON-CORE 1 — Workplace   'Community Manager (Mixed-Use)': ['MIX'],   'Menedżer Obsługi Widzów / Visitor Experience': ['PUB'], };  let activeBuilding = 'ALL';  function filterBuilding(btype) {   activeBuilding = btype;    // Update card states   document.querySelectorAll('.btype-card').forEach(c => {     c.classList.toggle('active', c.dataset.btype === btype);   });    if (btype === 'ALL') {     // Show everything     document.querySelectorAll('.role-card').forEach(c => c.classList.remove('btype-hidden'));     document.querySelectorAll('.wykonawczy-card').forEach(c => c.classList.remove('btype-hidden'));     document.querySelectorAll('.section-block').forEach(c => c.classList.remove('btype-all-hidden'));     document.getElementById('btypeUniquePanel').style.display = 'none';     document.getElementById('btypeActiveBar').style.display = 'none';     return;   }    const btData = BUILDING_TYPES[btype];    // Show unique roles panel   const uniquePanel = document.getElementById('btypeUniquePanel');   const uniqueGrid = document.getElementById('btypeUniqueGrid');   const uniqueTitle = document.getElementById('btypeUniqueTitle');   uniqueTitle.textContent = `${btData.emoji} ${btData.name} — stanowiska unikalne i charakterystyczne`;   uniqueGrid.innerHTML = btData.unique.map(u => `     <div class="btype-unique-card" style="border-left-color:${btData.color}">       <div class="u-cat">${u.cat}</div>       <div class="u-pl">${u.pl}</div>       <div class="u-en">${u.en}</div>       <div class="u-scope">${u.scope}</div>       <span class="u-level">${u.level} · ${u.stl}</span>     </div>`).join('');   uniquePanel.style.display = 'block';    // Active bar   document.getElementById('btypeActiveBar').style.display = 'flex';   document.getElementById('btypeActiveText').textContent =     `Filtr aktywny: ${btData.emoji} ${btData.name} — wyświetlane tylko stanowiska relevantne dla tego typu obiektu`;    // Expand all sections so hidden/visible is visible   document.querySelectorAll('.section-block').forEach(el => el.classList.add('open'));    // Filter sections and roles   document.querySelectorAll('.section-block').forEach(block => {     const secId = block.id;     const secMap = SECTION_BUILDING_MAP[secId];     const secRelevant = !secMap || secMap.includes('ALL') || secMap.includes(btype);     // Show all role cards in relevant sections, hide in irrelevant     block.querySelectorAll('.role-card, .wykonawczy-card').forEach(card => {       if (!secRelevant) {         card.classList.add('btype-hidden');       } else {         card.classList.remove('btype-hidden');       }     });     // Count visible roles     const visible = block.querySelectorAll('.role-card:not(.btype-hidden), .wykonawczy-card:not(.btype-hidden)').length;     block.classList.toggle('btype-all-hidden', visible === 0);   }); }  function toggleBtypePanel() {   const cards = document.getElementById('btypeCards');   const btn = document.querySelectorAll('.level-panel-toggle')[1];   if (!btn) return;   const hidden = cards.style.display === 'none';   cards.style.display = hidden ? 'flex' : 'none';   btn.textContent = hidden ? 'Zwiń ▲' : 'Rozwiń ▼'; }  // ════════════════════════════════════════════════════════════════════ // FINDER MODULE // ════════════════════════════════════════════════════════════════════  // Collect all roles from DATA into flat searchable list function getAllRoles() {   const all = [];   const addRoles = (roles, secId, secLabel, secTitle, side) => {     (roles || []).forEach(r => {       all.push({ ...r, secId, secLabel, secTitle, side: side || '' });     });   };   const processSec = (sec) => {     if (sec.split) {       addRoles(sec.client?.roles, sec.id, sec.label, sec.title, 'Zamawiający');       addRoles(sec.client?.frontline, sec.id, sec.label, sec.title, 'Zamawiający — Wykonawczy');       addRoles(sec.supplier?.roles, sec.id, sec.label, sec.title, 'Dostawca');       addRoles(sec.supplier?.frontline, sec.id, sec.label, sec.title, 'Dostawca — Wykonawczy');     } else if (sec.energy) {       addRoles(sec.roles, sec.id, sec.label, sec.title, '');     } else {       addRoles(sec.roles, sec.id, sec.label, sec.title, '');     }   };   DATA.core.forEach(processSec);   DATA.noncore.forEach(processSec);   return all; }  // Also include BUILDING_TYPES unique roles function getAllUniqueRoles() {   const all = [];   Object.entries(BUILDING_TYPES).forEach(([code, bt]) => {     if (code === 'ALL' || !bt.unique) return;     bt.unique.forEach(u => {       all.push({ pl: u.pl, en: u.en, level: u.level, stl: u.stl,         scope: u.scope, secId: u.cat.replace(' ',''), secLabel: u.cat,         secTitle: `Stanowisko unikalne — ${bt.name}`, side: bt.name,         isUnique: true, btCode: code });     });   });   return all; }  // Session-added roles let addedRoles = [];  // Normalize string for fuzzy matching function normalize(s) {   return s.toLowerCase()     .replace(/[ąą]/g,'a').replace(/[ćc]/g,'c').replace(/[ęe]/g,'e')     .replace(/[łl]/g,'l').replace(/[ńn]/g,'n').replace(/[óo]/g,'o')     .replace(/[śs]/g,'s').replace(/[źżz]/g,'z')     .replace(/[^a-z0-9\s]/g,' ').trim(); }  function score(query, role) {   const q = normalize(query);   const pl = normalize(role.pl);   const en = normalize(role.en || '');   if (pl === q || en === q) return 100;   if (pl.includes(q) || en.includes(q)) return 80;   const words = q.split(/\s+/);   const matched = words.filter(w => w.length > 2 && (pl.includes(w) || en.includes(w)));   if (matched.length === words.length) return 70;   if (matched.length > 0) return 40 + (matched.length / words.length) * 30;   return 0; }  function searchRoles(query) {   if (!query || query.length < 2) return [];   const all = [...getAllRoles(), ...getAllUniqueRoles(), ...addedRoles];   return all     .map(r => ({ ...r, _score: score(query, r) }))     .filter(r => r._score >= 40)     .sort((a, b) => b._score - a._score)     .slice(0, 8); }  // Autocomplete const input = document.getElementById('finderInput'); const sugBox = document.getElementById('finderSuggestions');  function highlight(text, query) {   const norm = normalize(query);   const re = new RegExp('(' + norm.split(/\s+/).filter(w=>w.length>1).join('|') + ')', 'gi');   return text.replace(re, '<span class="suggestion-highlight">$1</span>'); }  input.addEventListener('input', () => {   const q = input.value.trim();   if (q.length < 2) { sugBox.classList.remove('open'); return; }   const results = searchRoles(q);   if (!results.length) { sugBox.classList.remove('open'); return; }   sugBox.innerHTML = results.slice(0,6).map(r => `     <div class="finder-suggestion-item" onclick="selectSuggestion('${r.pl.replace(/'/g,"&#39;")}')">       <div class="suggestion-pl">${highlight(r.pl, q)}</div>       <div class="suggestion-meta">${r.secLabel} · ${r.level}</div>     </div>`).join('');   sugBox.classList.add('open'); });  document.addEventListener('click', e => {   if (!e.target.closest('.finder-input-wrap')) sugBox.classList.remove('open'); });  function selectSuggestion(pl) {   input.value = pl;   sugBox.classList.remove('open');   runFinder(); }  // ── MAIN FINDER LOGIC ───────────────────────────────────────────── async function runFinder() {   const query = input.value.trim();   if (!query) return;   sugBox.classList.remove('open');    const results = searchRoles(query);   const resultPanel = document.getElementById('finderResult');   resultPanel.style.display = 'block';    if (results.length > 0 && results[0]._score >= 60) {     // FOUND     showFound(results, query);   } else {     // NOT FOUND — use AI to classify     await showNotFound(query);   }   resultPanel.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); }  function showFound(results, query) {   const panel = document.getElementById('finderResult');   const top = results.filter(r => r._score >= 60);   panel.innerHTML = `     <div class="result-found">       <div class="result-found-header">         <span class="result-found-icon">✅</span>         <div>           <div class="result-found-title">Znaleziono ${top.length} dopasowanie${top.length>1?'nia':''}!</div>           <div class="result-found-sub">Kliknij kartę, aby podświetlić stanowisko na schemacie powyżej</div>         </div>       </div>       <div class="result-location-cards">         ${top.map(r => `           <div class="result-location-card" onclick="highlightRole('${r.secId}','${r.pl.replace(/'/g,"&#39;")}')">             <div class="rlc-category">${r.secLabel}${r.side ? ' · '+r.side : ''}</div>             <div class="rlc-name">${r.pl}</div>             <div class="rlc-en">${r.en || ''}</div>             <div class="rlc-badges">               <span class="rlc-badge level">${r.level}</span>               ${r.stl ? `<span class="rlc-badge stl-${r.stl}">${r.stl === 'S' ? 'Strategiczny' : r.stl === 'T' ? 'Taktyczny' : r.stl === 'O' ? 'Operacyjny' : 'Wykonawczy'}</span>` : ''}               ${r.isUnique ? `<span class="rlc-badge" style="background:#FEF9C3;color:#713F12;border-color:#FCD34D">Unikalne dla: ${r.side}</span>` : ''}             </div>           </div>`).join('')}       </div>     </div>`; }  async function showNotFound(query) {   const panel = document.getElementById('finderResult');    // Show loading state immediately   panel.innerHTML = `     <div class="result-notfound">       <div class="result-nf-header">         <span class="result-nf-icon">🔍</span>         <div>           <div class="result-nf-title">Nie znaleziono: <strong>"${query}"</strong></div>           <div class="result-nf-analyzing">             <span class="spinner"></span>             Analizuję stanowisko i szukam właściwego miejsca w taksonomii...           </div>         </div>       </div>     </div>`;    // Build taxonomy summary for AI context   const taxSummary = [     ...DATA.core.map(s => `${s.id} | ${s.label}: ${s.title} — ${s.desc}`),     ...DATA.noncore.map(s => `${s.id} | ${s.label}: ${s.title} — ${s.desc}`)   ].join('\n');    const prompt = `Jesteś ekspertem taksonomii stanowisk w branży Real Estate Management (RE, FM, CRE).  Użytkownik wpisał stanowisko: "${query}"  Oto dostępne kategorie taksonomii: ${taxSummary}  Poziomy seniority: C-level, Director, Senior, Mid, Junior, Brygadzista, Pracownik Poziomy zarządzania: S (Strategiczny: C-level/Director), T (Taktyczny: Senior/Mid+), O (Operacyjny: Mid/Junior), W (Wykonawczy: Pracownik/Brygadzista) Typy obiektów: ALL, OFF (biurowy), RET (handlowy), LOG (magazynowy), IND (przemysłowy), HOT (hotelowy), MIX (mieszany), PUB (użyteczności publicznej)  Odpowiedz TYLKO w formacie JSON (bez żadnego tekstu przed ani po): {   "secId": "np. C4 lub N5",   "secLabel": "pełna etykieta kategorii np. CORE 4",   "secTitle": "tytuł kategorii",   "level": "np. Senior",   "stl": "S|T|O|W",   "pl": "poprawiona/pełna polska nazwa stanowiska",   "en": "angielska nazwa stanowiska",   "scope": "1-2 zdania opisu zakresu obowiązków tego stanowiska w kontekście RE/FM",   "btype": "kod typu obiektu lub ALL",   "reasoning": "1 zdanie po polsku dlaczego ta kategoria" }`;    try {     const response = await fetch('https://api.anthropic.com/v1/messages', {       method: 'POST',       headers: { 'Content-Type': 'application/json' },       body: JSON.stringify({         model: 'claude-sonnet-4-20250514',         max_tokens: 1000,         messages: [{ role: 'user', content: prompt }]       })     });      const data = await response.json();     const raw = data.content?.map(b => b.text || '').join('') || '';     const clean = raw.replace(/```json|```/g, '').trim();     const ai = JSON.parse(clean);      showAIClassification(query, ai);    } catch (err) {     // Fallback to manual form if AI fails     showManualForm(query);   } }  function showAIClassification(query, ai) {   const panel = document.getElementById('finderResult');   const stlLabel = { S:'Strategiczny', T:'Taktyczny', O:'Operacyjny', W:'Wykonawczy' }[ai.stl] || ai.stl;   const stlColor = { S:'#4F46E5', T:'#D97706', O:'#16A34A', W:'#B45309' }[ai.stl] || '#666';   const btName = BUILDING_TYPES[ai.btype]?.name || 'Wszystkie typy';   const btEmoji = BUILDING_TYPES[ai.btype]?.emoji || '◎';    panel.innerHTML = `     <div class="result-notfound">       <div class="result-nf-header">         <span class="result-nf-icon">🤖</span>         <div>           <div class="result-nf-title">Stanowisko nieznalezione — AI zaproponowała klasyfikację</div>           <div class="result-nf-sub">Sprawdź propozycję i zatwierdź lub edytuj przed dodaniem do schematu</div>         </div>       </div>        <div class="ai-classification-card">         <div class="ai-class-row">           <div class="ai-class-field">             <div class="ai-class-label">Nazwa stanowiska (PL)</div>             <input class="add-input" id="addPl" value="${ai.pl}" />           </div>           <div class="ai-class-field">             <div class="ai-class-label">Nazwa (EN)</div>             <input class="add-input" id="addEn" value="${ai.en}" />           </div>         </div>          <div class="ai-class-row">           <div class="ai-class-field">             <div class="ai-class-label">Kategoria taksonomii</div>             <select class="add-select" id="addSec">               <option value="">— wybierz —</option>               ${[...DATA.core, ...DATA.noncore].map(s =>                 `<option value="${s.id}" ${s.id === ai.secId ? 'selected' : ''}>${s.label} — ${s.title}</option>`               ).join('')}             </select>           </div>           <div class="ai-class-field">             <div class="ai-class-label">Poziom seniority</div>             <select class="add-select" id="addLevel">               ${['C-level','Director','Senior','Mid','Junior','Brygadzista','Pracownik'].map(l =>                 `<option value="${l}" ${l === ai.level ? 'selected' : ''}>${l}</option>`               ).join('')}             </select>           </div>           <div class="ai-class-field">             <div class="ai-class-label">Poziom zarządzania</div>             <select class="add-select" id="addStl">               ${[['S','Strategiczny'],['T','Taktyczny'],['O','Operacyjny'],['W','Wykonawczy']].map(([v,n]) =>                 `<option value="${v}" ${v === ai.stl ? 'selected' : ''}>${v} — ${n}</option>`               ).join('')}             </select>           </div>           <div class="ai-class-field">             <div class="ai-class-label">Typ obiektu</div>             <select class="add-select" id="addBtype">               ${Object.entries(BUILDING_TYPES).map(([k,v]) =>                 `<option value="${k}" ${k === ai.btype ? 'selected' : ''}>${v.emoji || '◎'} ${v.name}</option>`               ).join('')}             </select>           </div>         </div>          <div class="ai-class-field" style="margin-top:8px">           <div class="ai-class-label">Zakres obowiązków</div>           <textarea class="add-textarea" id="addScope" rows="2">${ai.scope}</textarea>         </div>          <div class="ai-reasoning">           <span class="ai-reasoning-icon">💡</span>           <span>${ai.reasoning}</span>         </div>          <div class="ai-summary-pills">           <span class="rlc-badge level">${ai.level}</span>           <span class="rlc-badge stl-${ai.stl}" style="background:${stlColor}22;color:${stlColor};border-color:${stlColor}44">${stlLabel}</span>           <span class="rlc-badge" style="background:#F0F9FF;color:#0369A1;border-color:#BAE6FD">${btEmoji} ${btName}</span>           <span class="rlc-badge" style="background:#F5F3FF;color:#5B21B6;border-color:#DDD6FE">${ai.secLabel}</span>         </div>       </div>        <div class="add-submit-row">         <button class="add-submit-btn" onclick="submitAddRole()">📌 Zatwierdź i dodaj do schematu</button>         <button class="add-skip-btn" onclick="showManualForm('${query.replace(/'/g,"\\'")}')">✏️ Edytuj ręcznie</button>         <button class="add-skip-btn" onclick="document.getElementById('finderResult').style.display='none'">Pomiń</button>       </div>     </div>`; }  function showManualForm(query) {   const panel = document.getElementById('finderResult');   const sectionOptions = [     ...DATA.core.map(s => `<option value="${s.id}">${s.label} — ${s.title}</option>`),     ...DATA.noncore.map(s => `<option value="${s.id}">${s.label} — ${s.title}</option>`)   ].join('');    panel.innerHTML = `     <div class="result-notfound">       <div class="result-nf-header">         <span class="result-nf-icon">✏️</span>         <div class="result-nf-title">Uzupełnij ręcznie: <strong>"${query}"</strong></div>       </div>       <div class="result-nf-sub">Podaj szczegóły stanowiska aby dodać je do schematu.</div>       <div class="ai-class-row" style="margin-top:16px">         <div class="ai-class-field">           <div class="ai-class-label">Nazwa stanowiska (PL)</div>           <input class="add-input" id="addPl" value="${query}" />         </div>         <div class="ai-class-field">           <div class="ai-class-label">Nazwa (EN)</div>           <input class="add-input" id="addEn" placeholder="np. Facility Manager" />         </div>       </div>       <div class="ai-class-row">         <div class="ai-class-field">           <div class="ai-class-label">Kategoria</div>           <select class="add-select" id="addSec"><option value="">— wybierz —</option>${sectionOptions}</select>         </div>         <div class="ai-class-field">           <div class="ai-class-label">Seniority</div>           <select class="add-select" id="addLevel">             ${['C-level','Director','Senior','Mid','Junior','Brygadzista','Pracownik'].map(l => `<option value="${l}" ${l==='Mid'?'selected':''}>${l}</option>`).join('')}           </select>         </div>         <div class="ai-class-field">           <div class="ai-class-label">Poziom zarządzania</div>           <select class="add-select" id="addStl">             <option value="S">S — Strategiczny</option>             <option value="T" selected>T — Taktyczny</option>             <option value="O">O — Operacyjny</option>             <option value="W">W — Wykonawczy</option>           </select>         </div>         <div class="ai-class-field">           <div class="ai-class-label">Typ obiektu</div>           <select class="add-select" id="addBtype">             ${Object.entries(BUILDING_TYPES).map(([k,v]) => `<option value="${k}">${v.emoji||'◎'} ${v.name}</option>`).join('')}           </select>         </div>       </div>       <div class="ai-class-field" style="margin-top:8px">         <div class="ai-class-label">Zakres obowiązków</div>         <textarea class="add-textarea" id="addScope" rows="2" placeholder="Krótki opis roli..."></textarea>       </div>       <div class="add-submit-row" style="margin-top:12px">         <button class="add-submit-btn" onclick="submitAddRole()">📌 Dodaj do schematu</button>         <button class="add-skip-btn" onclick="document.getElementById('finderResult').style.display='none'">Pomiń</button>       </div>     </div>`; }  function submitAddRole() {   const pl = document.getElementById('addPl')?.value?.trim();   const en = document.getElementById('addEn')?.value?.trim() || pl;   const secId = document.getElementById('addSec')?.value;   const level = document.getElementById('addLevel')?.value || 'Mid';   const stl = document.getElementById('addStl')?.value || 'T';   const scope = document.getElementById('addScope')?.value?.trim() || 'Stanowisko dodane przez użytkownika';   const btype = document.getElementById('addBtype')?.value || 'ALL';    if (!pl) return;    // Find section info   const allSecs = [...DATA.core, ...DATA.noncore];   const sec = allSecs.find(s => s.id === secId);   const secLabel = sec ? sec.label : 'Nieprzypisane';   const secTitle = sec ? sec.title : '';    const newRole = { pl, en, level, stl, scope, secId, secLabel, secTitle, side: '', isAdded: true, btype };   addedRoles.push(newRole);    // Add card to schema if section exists   if (sec && !sec.split && !sec.energy) {     sec.roles.push({ pl, en, level, stl, scope, isAdded: true });     render(); // re-render     // Re-apply filters     applyFilter();     if (activeBuilding !== 'ALL') filterBuilding(activeBuilding);   }    // Show success   const panel = document.getElementById('finderResult');   const stlLabel = { S:'Strategiczny', T:'Taktyczny', O:'Operacyjny', W:'Wykonawczy' }[stl] || stl;   panel.innerHTML = `     <div class="result-added">       <div class="result-added-header">         <span class="result-added-icon">📌</span>         <div class="result-added-title">Stanowisko dodane do schematu!</div>       </div>       <div class="result-added-card">         <div class="rlc-category">${secLabel}${secTitle ? ' — '+secTitle : ''}</div>         <div class="rlc-name">${pl}</div>         <div class="rlc-en">${en}</div>         <div class="rlc-badges" style="margin-top:6px">           <span class="rlc-badge level">${level}</span>           <span class="rlc-badge stl-${stl}">${stlLabel}</span>         </div>         <div class="added-in-schema">${sec ? '✓ Widoczne w schemacie powyżej' : '✓ Dodane do listy stanowisk sesji'}</div>       </div>     </div>`;    updateAddedList();    // Highlight in schema if added   if (sec) setTimeout(() => highlightRole(secId, pl), 400); }  function highlightRole(secId, pl) {   // Open section   const block = document.getElementById(secId);   if (block) {     block.classList.add('open');     // Find and flash the role card     block.querySelectorAll('.role-card, .wykonawczy-card').forEach(card => {       const titleEl = card.querySelector('.role-title-pl');       if (titleEl && normalize(titleEl.textContent).includes(normalize(pl.substring(0,10)))) {         card.scrollIntoView({ behavior:'smooth', block:'center' });         card.style.transition = 'box-shadow 0.3s, transform 0.3s';         card.style.boxShadow = '0 0 0 3px #2563EB, 0 8px 24px rgba(37,99,235,0.3)';         card.style.transform = 'scale(1.04)';         setTimeout(() => {           card.style.boxShadow = '';           card.style.transform = '';         }, 2200);       }     });   } }  function updateAddedList() {   if (!addedRoles.length) return;   const list = document.getElementById('finderAddedList');   const items = document.getElementById('finderAddedItems');   list.style.display = 'block';   items.innerHTML = addedRoles.map(r => `     <span class="added-pill" onclick="highlightRole('${r.secId}','${r.pl.replace(/'/g,"&#39;")}')">       <span class="added-pill-cat">${r.secLabel}</span>       ${r.pl}     </span>`).join(''); }  render(); </script> </body> </html>