{"id":651,"date":"2026-01-27T14:51:38","date_gmt":"2026-01-27T14:51:38","guid":{"rendered":"https:\/\/www.opey.org\/opeyit\/?page_id=651"},"modified":"2026-02-27T16:28:48","modified_gmt":"2026-02-27T16:28:48","slug":"risk-dashboard","status":"publish","type":"page","link":"https:\/\/www.opey.org\/opeyit\/?page_id=651","title":{"rendered":"Risk Dashboard"},"content":{"rendered":"\n<div id=\"wcf-executive-dashboard\">\n\n<style>\n#wcf-executive-dashboard { font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, sans-serif; color: #2d3748; line-height: 1.6; background: #0f172a; min-height: 100vh; }\n#wcf-executive-dashboard * { box-sizing: border-box; }\n@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }\n\n\/* HERO *\/\n#wcf-executive-dashboard .wcf-hero { background: linear-gradient(145deg, #0f172a 0%, #1e3a5f 40%, #065f46 100%); padding: 50px 20px; text-align: center; }\n#wcf-executive-dashboard .wcf-hero-inner { max-width: 1000px; margin: 0 auto; }\n#wcf-executive-dashboard .wcf-dashboard-icon { margin-bottom: 16px; display: flex; justify-content: center; align-items: center; }\n#wcf-executive-dashboard .wcf-dashboard-icon svg { width: 48px; height: 48px; }\n#wcf-executive-dashboard .wcf-label { color: #22c55e; font-size: 11px; font-weight: 700; letter-spacing: 3px; text-transform: uppercase; margin-bottom: 12px; display: block; }\n#wcf-executive-dashboard .wcf-title { color: #fff; font-size: 40px; font-weight: 800; margin: 0 0 12px; line-height: 1.1; }\n#wcf-executive-dashboard .wcf-subtitle { color: rgba(255,255,255,0.9); font-size: 18px; margin: 0 0 16px; }\n#wcf-executive-dashboard .wcf-hero-desc { color: rgba(255,255,255,0.7); font-size: 14px; max-width: 600px; margin: 0 auto 20px; }\n#wcf-executive-dashboard .wcf-live-badge { display: inline-block; background: #22c55e; color: #fff; padding: 4px 12px; border-radius: 20px; font-size: 10px; font-weight: 700; text-transform: uppercase; animation: pulse 2s infinite; }\n#wcf-executive-dashboard .wcf-back-link { display: inline-flex; align-items: center; gap: 8px; color: rgba(255,255,255,0.6); font-size: 13px; text-decoration: none; margin-top: 20px; transition: color 0.2s; }\n#wcf-executive-dashboard .wcf-back-link:hover { color: #fff; }\n\n\/* DATA STATUS *\/\n#wcf-executive-dashboard .wcf-data-status { background: rgba(254, 243, 199, 0.1); border: 1px solid rgba(245, 158, 11, 0.3); padding: 12px 20px; border-radius: 8px; margin: 20px auto; max-width: 600px; color: #fbbf24; font-size: 13px; display: none; }\n#wcf-executive-dashboard .wcf-data-status.visible { display: block; }\n#wcf-executive-dashboard .wcf-data-status.error { background: rgba(254, 202, 202, 0.1); border-color: rgba(220, 38, 38, 0.3); color: #f87171; }\n\n\/* KPI BAR *\/\n#wcf-executive-dashboard .wcf-kpi-bar { background: #0f172a; padding: 24px 20px; border-bottom: 4px solid #dc2626; }\n#wcf-executive-dashboard .wcf-kpi-inner { max-width: 1200px; margin: 0 auto; display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px; }\n#wcf-executive-dashboard .wcf-kpi { background: rgba(255,255,255,0.05); border-radius: 12px; padding: 18px; border: 1px solid rgba(255,255,255,0.1); position: relative; overflow: hidden; }\n#wcf-executive-dashboard .wcf-kpi::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; }\n#wcf-executive-dashboard .wcf-kpi.red::before { background: #dc2626; }\n#wcf-executive-dashboard .wcf-kpi.orange::before { background: #ea580c; }\n#wcf-executive-dashboard .wcf-kpi.yellow::before { background: #f59e0b; }\n#wcf-executive-dashboard .wcf-kpi.green::before { background: #22c55e; }\n#wcf-executive-dashboard .wcf-kpi.blue::before { background: #3b82f6; }\n#wcf-executive-dashboard .wcf-kpi-label { font-size: 10px; color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 6px; }\n#wcf-executive-dashboard .wcf-kpi-value { font-size: 28px; font-weight: 800; line-height: 1; }\n#wcf-executive-dashboard .wcf-kpi.red .wcf-kpi-value { color: #f87171; }\n#wcf-executive-dashboard .wcf-kpi.orange .wcf-kpi-value { color: #fb923c; }\n#wcf-executive-dashboard .wcf-kpi.yellow .wcf-kpi-value { color: #fbbf24; }\n#wcf-executive-dashboard .wcf-kpi.green .wcf-kpi-value { color: #4ade80; }\n#wcf-executive-dashboard .wcf-kpi.blue .wcf-kpi-value { color: #60a5fa; }\n#wcf-executive-dashboard .wcf-kpi-delta { font-size: 11px; margin-top: 6px; color: rgba(255,255,255,0.4); }\n#wcf-executive-dashboard .wcf-kpi-delta.up { color: #f87171; }\n#wcf-executive-dashboard .wcf-kpi-delta.down { color: #4ade80; }\n\n\/* YEAR FILTER *\/\n#wcf-executive-dashboard .wcf-filter-section { background: #1e293b; padding: 20px; border-bottom: 1px solid rgba(255,255,255,0.1); }\n#wcf-executive-dashboard .wcf-filter-inner { max-width: 1200px; margin: 0 auto; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }\n#wcf-executive-dashboard .wcf-filter-label { font-size: 12px; font-weight: 600; color: rgba(255,255,255,0.6); text-transform: uppercase; letter-spacing: 1px; }\n#wcf-executive-dashboard .wcf-year-btn { padding: 8px 16px; font-size: 13px; font-weight: 600; border-radius: 6px; cursor: pointer; border: 1px solid rgba(255,255,255,0.2); background: transparent; color: rgba(255,255,255,0.6); transition: all 0.2s; }\n#wcf-executive-dashboard .wcf-year-btn:hover { border-color: #22c55e; color: #22c55e; }\n#wcf-executive-dashboard .wcf-year-btn.active { background: #22c55e; border-color: #22c55e; color: #0f172a; }\n\n\/* MAIN CONTENT *\/\n#wcf-executive-dashboard .wcf-main { padding: 30px 20px; }\n#wcf-executive-dashboard .wcf-main-inner { max-width: 1200px; margin: 0 auto; }\n\n\/* GRID LAYOUTS *\/\n#wcf-executive-dashboard .wcf-grid-2col { display: grid; grid-template-columns: 1fr 340px; gap: 24px; margin-bottom: 24px; }\n#wcf-executive-dashboard .wcf-grid-3col { display: grid; grid-template-columns: 1fr 1fr 1.2fr; gap: 24px; margin-bottom: 24px; }\n\n\/* CARDS *\/\n#wcf-executive-dashboard .wcf-card { background: #1e293b; border-radius: 16px; border: 1px solid rgba(255,255,255,0.1); overflow: hidden; }\n#wcf-executive-dashboard .wcf-card-header { padding: 18px 24px; border-bottom: 1px solid rgba(255,255,255,0.1); display: flex; justify-content: space-between; align-items: center; }\n#wcf-executive-dashboard .wcf-card-title { font-size: 16px; font-weight: 700; color: #fff; margin: 0; }\n#wcf-executive-dashboard .wcf-card-subtitle { font-size: 12px; color: rgba(255,255,255,0.5); margin-top: 2px; }\n#wcf-executive-dashboard .wcf-card-body { padding: 24px; }\n\n\/* ===== PROVIDER \u00d7 TIME MATRIX - ENHANCED WITH VERTICAL SCROLL ===== *\/\n#wcf-executive-dashboard .wcf-matrix-wrapper {\n    position: relative;\n    width: 100%;\n}\n#wcf-executive-dashboard .wcf-matrix-container {\n    overflow: auto;\n    max-height: 480px; \/* Show ~18 providers before scroll, adjust as needed *\/\n    padding-bottom: 10px;\n    scrollbar-width: thin;\n    scrollbar-color: rgba(34, 197, 94, 0.5) rgba(255,255,255,0.1);\n}\n#wcf-executive-dashboard .wcf-matrix-container::-webkit-scrollbar {\n    width: 8px;\n    height: 8px;\n}\n#wcf-executive-dashboard .wcf-matrix-container::-webkit-scrollbar-track {\n    background: rgba(255,255,255,0.1);\n    border-radius: 4px;\n}\n#wcf-executive-dashboard .wcf-matrix-container::-webkit-scrollbar-thumb {\n    background: rgba(34, 197, 94, 0.5);\n    border-radius: 4px;\n}\n#wcf-executive-dashboard .wcf-matrix-container::-webkit-scrollbar-thumb:hover {\n    background: rgba(34, 197, 94, 0.8);\n}\n#wcf-executive-dashboard .wcf-matrix-container::-webkit-scrollbar-corner {\n    background: rgba(255,255,255,0.05);\n}\n#wcf-executive-dashboard .wcf-matrix { display: flex; flex-direction: column; gap: 2px; }\n#wcf-executive-dashboard .wcf-matrix-row { display: flex; flex-direction: row; align-items: center; gap: 2px; }\n#wcf-executive-dashboard .wcf-matrix-row.header {\n    position: sticky;\n    top: 0;\n    z-index: 10;\n    background: #1e293b;\n    padding-bottom: 4px;\n    margin-bottom: 2px;\n}\n#wcf-executive-dashboard .wcf-provider-label {\n    font-size: 10px;\n    font-weight: 600;\n    color: rgba(255,255,255,0.8);\n    padding: 4px 6px;\n    background: rgba(255,255,255,0.05);\n    border-radius: 3px;\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    width: 90px;\n    min-width: 90px;\n    max-width: 90px;\n    flex-shrink: 0;\n    position: sticky;\n    left: 0;\n    z-index: 5;\n}\n#wcf-executive-dashboard .wcf-matrix-row.header .wcf-provider-label {\n    background: #1e293b;\n    z-index: 15;\n}\n#wcf-executive-dashboard .wcf-matrix-row:not(.header) .wcf-provider-label {\n    background: #1e293b;\n}\n#wcf-executive-dashboard .wcf-day-label { font-size: 8px; color: rgba(255,255,255,0.4); text-align: center; width: 20px; min-width: 20px; max-width: 20px; flex-shrink: 0; }\n#wcf-executive-dashboard .wcf-matrix-cell { height: 20px; width: 20px; min-width: 20px; max-width: 20px; flex-shrink: 0; border-radius: 3px; background: rgba(255,255,255,0.05); cursor: pointer; transition: all 0.15s; display: flex; align-items: center; justify-content: center; position: relative; }\n#wcf-executive-dashboard .wcf-matrix-cell:hover { transform: scale(1.15); z-index: 5; box-shadow: 0 0 0 2px #fff; }\n#wcf-executive-dashboard .wcf-matrix-cell.critical { background: #dc2626; }\n#wcf-executive-dashboard .wcf-matrix-cell.major { background: #ea580c; }\n#wcf-executive-dashboard .wcf-matrix-cell.moderate { background: #f59e0b; }\n#wcf-executive-dashboard .wcf-matrix-cell.minor { background: #22c55e; }\n#wcf-executive-dashboard .wcf-matrix-cell .count { font-size: 8px; font-weight: 700; color: rgba(0,0,0,0.6); line-height: 20px; }\n#wcf-executive-dashboard .wcf-matrix-cell.critical .count, #wcf-executive-dashboard .wcf-matrix-cell.major .count { color: #fff; }\n\n\/* SCROLL HINTS - HORIZONTAL AND VERTICAL *\/\n#wcf-executive-dashboard .wcf-scroll-hint-h {\n    display: none;\n    position: absolute;\n    right: 0;\n    top: 0;\n    bottom: 0;\n    width: 50px;\n    background: linear-gradient(90deg, transparent 0%, rgba(30, 41, 59, 0.95) 100%);\n    pointer-events: none;\n    z-index: 20;\n    align-items: center;\n    justify-content: flex-end;\n    padding-right: 8px;\n}\n#wcf-executive-dashboard .wcf-scroll-hint-v {\n    display: none;\n    position: absolute;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    height: 40px;\n    background: linear-gradient(180deg, transparent 0%, rgba(30, 41, 59, 0.95) 100%);\n    pointer-events: none;\n    z-index: 20;\n    align-items: flex-end;\n    justify-content: center;\n    padding-bottom: 6px;\n}\n#wcf-executive-dashboard .wcf-scroll-hint-h svg,\n#wcf-executive-dashboard .wcf-scroll-hint-v svg {\n    width: 20px;\n    height: 20px;\n    stroke: rgba(34, 197, 94, 0.8);\n}\n#wcf-executive-dashboard .wcf-scroll-hint-h svg { animation: scrollHintH 1.5s ease-in-out infinite; }\n#wcf-executive-dashboard .wcf-scroll-hint-v svg { animation: scrollHintV 1.5s ease-in-out infinite; }\n@keyframes scrollHintH {\n    0%, 100% { transform: translateX(0); opacity: 0.6; }\n    50% { transform: translateX(5px); opacity: 1; }\n}\n@keyframes scrollHintV {\n    0%, 100% { transform: translateY(0); opacity: 0.6; }\n    50% { transform: translateY(5px); opacity: 1; }\n}\n\n\/* MATRIX LEGEND *\/\n#wcf-executive-dashboard .wcf-matrix-legend { display: flex; gap: 20px; margin-top: 16px; padding-top: 16px; border-top: 1px solid rgba(255,255,255,0.1); justify-content: flex-end; flex-wrap: wrap; }\n#wcf-executive-dashboard .wcf-legend-item { display: flex; align-items: center; gap: 6px; font-size: 11px; color: rgba(255,255,255,0.6); }\n#wcf-executive-dashboard .wcf-legend-swatch { width: 14px; height: 14px; border-radius: 3px; }\n\n\/* MATRIX STATS *\/\n#wcf-executive-dashboard .wcf-matrix-stats {\n    display: flex;\n    gap: 16px;\n    margin-top: 12px;\n    padding-top: 12px;\n    border-top: 1px solid rgba(255,255,255,0.05);\n    font-size: 11px;\n    color: rgba(255,255,255,0.5);\n}\n#wcf-executive-dashboard .wcf-matrix-stats span {\n    display: flex;\n    align-items: center;\n    gap: 4px;\n}\n#wcf-executive-dashboard .wcf-matrix-stats .wcf-stat-value {\n    color: #22c55e;\n    font-weight: 600;\n}\n\n\/* RISK GAUGE *\/\n#wcf-executive-dashboard .wcf-risk-gauge-container { display: flex; flex-direction: column; align-items: center; padding: 20px 0; }\n#wcf-executive-dashboard .wcf-risk-gauge { position: relative; width: 160px; height: 80px; }\n#wcf-executive-dashboard .wcf-risk-gauge svg { width: 100%; height: 100%; }\n#wcf-executive-dashboard .wcf-gauge-bg { fill: none; stroke: rgba(255,255,255,0.1); stroke-width: 14; }\n#wcf-executive-dashboard .wcf-gauge-fill { fill: none; stroke-width: 14; stroke-linecap: round; }\n#wcf-executive-dashboard .wcf-risk-score { position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); font-size: 40px; font-weight: 800; color: #f87171; }\n#wcf-executive-dashboard .wcf-risk-label { font-size: 10px; color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 1px; margin-top: 12px; }\n#wcf-executive-dashboard .wcf-risk-status { margin-top: 12px; padding: 8px 20px; border-radius: 20px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; }\n#wcf-executive-dashboard .wcf-risk-status.high { background: rgba(220, 38, 38, 0.2); color: #f87171; border: 1px solid rgba(220, 38, 38, 0.3); }\n#wcf-executive-dashboard .wcf-risk-status.medium { background: rgba(245, 158, 11, 0.2); color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.3); }\n#wcf-executive-dashboard .wcf-risk-status.low { background: rgba(34, 197, 94, 0.2); color: #4ade80; border: 1px solid rgba(34, 197, 94, 0.3); }\n\n\/* SEVERITY GRID *\/\n#wcf-executive-dashboard .wcf-severity-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }\n#wcf-executive-dashboard .wcf-severity-item { background: rgba(255,255,255,0.05); border-radius: 10px; padding: 16px; text-align: center; }\n#wcf-executive-dashboard .wcf-severity-count { font-size: 28px; font-weight: 800; line-height: 1; }\n#wcf-executive-dashboard .wcf-severity-item.critical .wcf-severity-count { color: #f87171; }\n#wcf-executive-dashboard .wcf-severity-item.major .wcf-severity-count { color: #fb923c; }\n#wcf-executive-dashboard .wcf-severity-item.moderate .wcf-severity-count { color: #fbbf24; }\n#wcf-executive-dashboard .wcf-severity-item.minor .wcf-severity-count { color: #4ade80; }\n#wcf-executive-dashboard .wcf-severity-label { font-size: 10px; color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 1px; margin-top: 6px; }\n\n\/* PROVIDER LIST *\/\n#wcf-executive-dashboard .wcf-provider-list { display: flex; flex-direction: column; gap: 10px; }\n#wcf-executive-dashboard .wcf-provider-row { display: grid; grid-template-columns: 28px 110px 1fr 45px; align-items: center; gap: 12px; padding: 10px 12px; background: rgba(255,255,255,0.05); border-radius: 8px; transition: background 0.15s; }\n#wcf-executive-dashboard .wcf-provider-row:hover { background: rgba(255,255,255,0.08); }\n#wcf-executive-dashboard .wcf-rank { font-size: 12px; color: rgba(255,255,255,0.4); text-align: center; font-weight: 600; }\n#wcf-executive-dashboard .wcf-provider-name { font-size: 13px; font-weight: 600; color: #fff; }\n#wcf-executive-dashboard .wcf-provider-bar-container { height: 6px; background: rgba(255,255,255,0.1); border-radius: 3px; overflow: hidden; }\n#wcf-executive-dashboard .wcf-provider-bar { height: 100%; border-radius: 3px; }\n#wcf-executive-dashboard .wcf-provider-count { font-size: 13px; color: rgba(255,255,255,0.7); text-align: right; font-weight: 600; }\n\n\/* ROOT CAUSE *\/\n#wcf-executive-dashboard .wcf-cause-list { display: flex; flex-direction: column; gap: 10px; }\n#wcf-executive-dashboard .wcf-cause-row { display: flex; align-items: center; gap: 12px; padding: 12px; background: rgba(255,255,255,0.05); border-radius: 10px; }\n#wcf-executive-dashboard .wcf-cause-icon { width: 32px; height: 32px; border-radius: 6px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; position: relative; }\n#wcf-executive-dashboard .wcf-cause-icon.config { background: rgba(220, 38, 38, 0.2); }\n#wcf-executive-dashboard .wcf-cause-icon.power { background: rgba(234, 88, 12, 0.2); }\n#wcf-executive-dashboard .wcf-cause-icon.network { background: rgba(245, 158, 11, 0.2); }\n#wcf-executive-dashboard .wcf-cause-icon.software { background: rgba(59, 130, 246, 0.2); }\n#wcf-executive-dashboard .wcf-cause-icon svg { width: 16px; height: 16px; }\n#wcf-executive-dashboard .wcf-cause-icon.config svg { stroke: #f87171; }\n#wcf-executive-dashboard .wcf-cause-icon.power svg { stroke: #fb923c; }\n#wcf-executive-dashboard .wcf-cause-icon.network svg { stroke: #fbbf24; }\n#wcf-executive-dashboard .wcf-cause-icon.software svg { stroke: #60a5fa; }\n#wcf-executive-dashboard .wcf-cause-info { flex: 1; min-width: 0; }\n#wcf-executive-dashboard .wcf-cause-name { font-size: 12px; font-weight: 600; color: #fff; line-height: 1.3; }\n#wcf-executive-dashboard .wcf-cause-count { font-size: 10px; color: rgba(255,255,255,0.5); margin-top: 2px; }\n#wcf-executive-dashboard .wcf-cause-pct { font-size: 15px; font-weight: 700; color: rgba(255,255,255,0.8); flex-shrink: 0; min-width: 38px; text-align: right; }\n\n\/* IMPACT TIMELINE - FIXED LAYOUT *\/\n#wcf-executive-dashboard .wcf-timeline { display: flex; flex-direction: column; gap: 10px; }\n#wcf-executive-dashboard .wcf-timeline-item { display: flex; flex-direction: column; gap: 8px; padding: 14px; background: rgba(255,255,255,0.05); border-radius: 10px; border-left: 3px solid transparent; }\n#wcf-executive-dashboard .wcf-timeline-item.critical { border-left-color: #dc2626; }\n#wcf-executive-dashboard .wcf-timeline-item.major { border-left-color: #ea580c; }\n#wcf-executive-dashboard .wcf-timeline-item.moderate { border-left-color: #f59e0b; }\n#wcf-executive-dashboard .wcf-timeline-header { display: flex; justify-content: space-between; align-items: center; gap: 8px; }\n#wcf-executive-dashboard .wcf-timeline-date { font-size: 11px; color: rgba(255,255,255,0.5); flex-shrink: 0; }\n#wcf-executive-dashboard .wcf-timeline-cost { font-size: 13px; font-weight: 700; color: #f87171; text-align: right; white-space: nowrap; }\n#wcf-executive-dashboard .wcf-timeline-content { }\n#wcf-executive-dashboard .wcf-timeline-provider { font-size: 10px; color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; }\n#wcf-executive-dashboard .wcf-timeline-title { font-size: 12px; font-weight: 600; color: #fff; line-height: 1.4; }\n\n\/* ===== INCIDENT TABLE - MOBILE RESPONSIVE FIX ===== *\/\n#wcf-executive-dashboard .wcf-table-wrapper {\n    position: relative;\n    width: 100%;\n    overflow: hidden;\n}\n#wcf-executive-dashboard .wcf-table-scroll {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n    scrollbar-width: thin;\n    scrollbar-color: rgba(255,255,255,0.3) rgba(255,255,255,0.1);\n}\n#wcf-executive-dashboard .wcf-table-scroll::-webkit-scrollbar {\n    height: 8px;\n}\n#wcf-executive-dashboard .wcf-table-scroll::-webkit-scrollbar-track {\n    background: rgba(255,255,255,0.1);\n    border-radius: 4px;\n}\n#wcf-executive-dashboard .wcf-table-scroll::-webkit-scrollbar-thumb {\n    background: rgba(255,255,255,0.3);\n    border-radius: 4px;\n}\n#wcf-executive-dashboard .wcf-table-scroll::-webkit-scrollbar-thumb:hover {\n    background: rgba(255,255,255,0.5);\n}\n#wcf-executive-dashboard .wcf-scroll-hint {\n    display: none;\n    position: absolute;\n    right: 0;\n    top: 0;\n    bottom: 0;\n    width: 60px;\n    background: linear-gradient(90deg, transparent 0%, rgba(30, 41, 59, 0.95) 100%);\n    pointer-events: none;\n    z-index: 10;\n    align-items: center;\n    justify-content: flex-end;\n    padding-right: 12px;\n}\n#wcf-executive-dashboard .wcf-scroll-hint svg {\n    width: 24px;\n    height: 24px;\n    stroke: rgba(255,255,255,0.6);\n    animation: scrollHintH 1.5s ease-in-out infinite;\n}\n#wcf-executive-dashboard .wcf-incident-table { width: 100%; border-collapse: collapse; min-width: 700px; }\n#wcf-executive-dashboard .wcf-incident-table th { text-align: left; padding: 12px 16px; font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: rgba(255,255,255,0.5); border-bottom: 1px solid rgba(255,255,255,0.1); background: rgba(255,255,255,0.03); white-space: nowrap; }\n#wcf-executive-dashboard .wcf-incident-table td { padding: 14px 16px; font-size: 13px; color: rgba(255,255,255,0.8); border-bottom: 1px solid rgba(255,255,255,0.05); }\n#wcf-executive-dashboard .wcf-incident-table tr:hover td { background: rgba(255,255,255,0.03); }\n#wcf-executive-dashboard .wcf-incident-table .wcf-col-date { min-width: 100px; white-space: nowrap; }\n#wcf-executive-dashboard .wcf-incident-table .wcf-col-provider { min-width: 100px; }\n#wcf-executive-dashboard .wcf-incident-table .wcf-col-incident { min-width: 200px; }\n#wcf-executive-dashboard .wcf-incident-table .wcf-col-severity { min-width: 90px; }\n#wcf-executive-dashboard .wcf-incident-table .wcf-col-duration { min-width: 80px; white-space: nowrap; }\n#wcf-executive-dashboard .wcf-incident-table .wcf-col-impact { min-width: 120px; white-space: nowrap; }\n#wcf-executive-dashboard .wcf-severity-badge { display: inline-block; padding: 4px 10px; border-radius: 4px; font-size: 10px; font-weight: 700; text-transform: uppercase; }\n#wcf-executive-dashboard .wcf-severity-badge.critical { background: rgba(220, 38, 38, 0.2); color: #f87171; }\n#wcf-executive-dashboard .wcf-severity-badge.major { background: rgba(234, 88, 12, 0.2); color: #fb923c; }\n#wcf-executive-dashboard .wcf-severity-badge.moderate { background: rgba(245, 158, 11, 0.2); color: #fbbf24; }\n#wcf-executive-dashboard .wcf-severity-badge.minor { background: rgba(34, 197, 94, 0.2); color: #4ade80; }\n#wcf-executive-dashboard .wcf-cost-value { color: #f87171; font-weight: 600; }\n#wcf-executive-dashboard .wcf-date-value { color: rgba(255,255,255,0.5); }\n\n\/* CTA SECTION *\/\n#wcf-executive-dashboard .wcf-cta-section { background: linear-gradient(135deg, #7c2d12 0%, #991b1b 50%, #0f172a 100%); padding: 50px 20px; margin-top: 30px; }\n#wcf-executive-dashboard .wcf-cta-inner { max-width: 900px; margin: 0 auto; display: flex; align-items: center; gap: 40px; flex-wrap: wrap; }\n#wcf-executive-dashboard .wcf-cta-content { flex: 1; min-width: 300px; }\n#wcf-executive-dashboard .wcf-cta-label { display: inline-block; background: rgba(245, 158, 11, 0.2); color: #f59e0b; padding: 6px 14px; border-radius: 20px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 16px; }\n#wcf-executive-dashboard .wcf-cta-title { color: #fff; font-size: 32px; font-weight: 800; margin: 0 0 12px; line-height: 1.2; }\n#wcf-executive-dashboard .wcf-cta-text { color: rgba(255,255,255,0.8); font-size: 15px; line-height: 1.7; margin: 0 0 24px; }\n#wcf-executive-dashboard .wcf-cta-buttons { display: flex; gap: 16px; flex-wrap: wrap; }\n#wcf-executive-dashboard .wcf-btn { display: inline-block; padding: 14px 28px; font-size: 14px; font-weight: 700; border-radius: 8px; text-decoration: none; transition: all 0.3s; }\n#wcf-executive-dashboard .wcf-btn-primary { background: linear-gradient(135deg, #f59e0b, #d97706); color: #0f172a; }\n#wcf-executive-dashboard .wcf-btn-primary:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(245, 158, 11, 0.4); }\n#wcf-executive-dashboard .wcf-btn-outline { background: transparent; color: #fff; border: 2px solid rgba(255,255,255,0.3); }\n#wcf-executive-dashboard .wcf-btn-outline:hover { border-color: #fff; background: rgba(255,255,255,0.1); }\n\n\/* FOOTER *\/\n#wcf-executive-dashboard .wcf-footer { background: #0f172a; padding: 24px 20px; border-top: 1px solid rgba(255,255,255,0.1); }\n#wcf-executive-dashboard .wcf-footer-inner { max-width: 1200px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px; font-size: 12px; color: rgba(255,255,255,0.4); }\n#wcf-executive-dashboard .wcf-footer a { color: #f59e0b; text-decoration: none; }\n#wcf-executive-dashboard .wcf-footer a:hover { text-decoration: underline; }\n\n\/* ===== FIXED TOOLTIP - EXECUTIVE STYLE ===== *\/\n#wcf-executive-dashboard .wcf-tooltip {\n    position: fixed;\n    background: linear-gradient(145deg, #1e293b 0%, #0f172a 100%);\n    border: 1px solid rgba(34, 197, 94, 0.4);\n    border-radius: 12px;\n    padding: 0;\n    min-width: 280px;\n    max-width: 340px;\n    box-shadow: 0 20px 60px rgba(0,0,0,0.6), 0 0 40px rgba(34, 197, 94, 0.1);\n    z-index: 99999;\n    pointer-events: none;\n    opacity: 0;\n    visibility: hidden;\n    transition: opacity 0.2s ease, visibility 0.2s ease;\n    overflow: hidden;\n}\n#wcf-executive-dashboard .wcf-tooltip.visible {\n    opacity: 1;\n    visibility: visible;\n}\n#wcf-executive-dashboard .wcf-tooltip-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 14px 16px;\n    background: rgba(34, 197, 94, 0.1);\n    border-bottom: 1px solid rgba(255,255,255,0.1);\n}\n#wcf-executive-dashboard .wcf-tooltip-provider {\n    font-weight: 700;\n    font-size: 15px;\n    color: #22c55e;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n}\n#wcf-executive-dashboard .wcf-tooltip-date {\n    font-size: 11px;\n    color: rgba(255,255,255,0.5);\n    font-weight: 600;\n}\n#wcf-executive-dashboard .wcf-tooltip-body {\n    padding: 14px 16px;\n}\n#wcf-executive-dashboard .wcf-tooltip-severity {\n    display: inline-block;\n    padding: 3px 10px;\n    border-radius: 4px;\n    font-size: 9px;\n    font-weight: 700;\n    text-transform: uppercase;\n    letter-spacing: 1px;\n    margin-bottom: 10px;\n}\n#wcf-executive-dashboard .wcf-tooltip-severity.critical { background: rgba(220, 38, 38, 0.25); color: #f87171; }\n#wcf-executive-dashboard .wcf-tooltip-severity.major { background: rgba(234, 88, 12, 0.25); color: #fb923c; }\n#wcf-executive-dashboard .wcf-tooltip-severity.moderate { background: rgba(245, 158, 11, 0.25); color: #fbbf24; }\n#wcf-executive-dashboard .wcf-tooltip-severity.minor { background: rgba(34, 197, 94, 0.25); color: #4ade80; }\n#wcf-executive-dashboard .wcf-tooltip-title {\n    font-size: 13px;\n    font-weight: 600;\n    color: #fff;\n    line-height: 1.5;\n    margin-bottom: 12px;\n}\n#wcf-executive-dashboard .wcf-tooltip-metrics {\n    display: grid;\n    grid-template-columns: 1fr 1fr;\n    gap: 10px;\n    padding-top: 10px;\n    border-top: 1px solid rgba(255,255,255,0.1);\n}\n#wcf-executive-dashboard .wcf-tooltip-metric {\n    text-align: center;\n}\n#wcf-executive-dashboard .wcf-tooltip-metric-value {\n    font-size: 16px;\n    font-weight: 800;\n    color: #f87171;\n}\n#wcf-executive-dashboard .wcf-tooltip-metric-label {\n    font-size: 9px;\n    color: rgba(255,255,255,0.4);\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    margin-top: 2px;\n}\n#wcf-executive-dashboard .wcf-tooltip-footer {\n    padding: 10px 16px;\n    background: rgba(0,0,0,0.2);\n    font-size: 10px;\n    color: rgba(255,255,255,0.4);\n    text-align: center;\n}\n#wcf-executive-dashboard .wcf-tooltip-multi {\n    margin-top: 8px;\n    padding-top: 8px;\n    border-top: 1px dashed rgba(255,255,255,0.1);\n}\n#wcf-executive-dashboard .wcf-tooltip-multi-label {\n    font-size: 10px;\n    color: rgba(255,255,255,0.5);\n    margin-bottom: 6px;\n}\n#wcf-executive-dashboard .wcf-tooltip-multi-item {\n    font-size: 11px;\n    color: rgba(255,255,255,0.7);\n    padding: 4px 0;\n    border-bottom: 1px solid rgba(255,255,255,0.05);\n}\n#wcf-executive-dashboard .wcf-tooltip-multi-item:last-child {\n    border-bottom: none;\n}\n\n\/* NO DATA STATE *\/\n#wcf-executive-dashboard .wcf-no-data { text-align: center; padding: 40px 20px; color: rgba(255,255,255,0.5); }\n#wcf-executive-dashboard .wcf-no-data-icon { font-size: 48px; margin-bottom: 16px; opacity: 0.5; }\n#wcf-executive-dashboard .wcf-no-data-text { font-size: 14px; }\n\n\/* LOADING *\/\n#wcf-executive-dashboard .wcf-loading { text-align: center; padding: 60px 20px; color: rgba(255,255,255,0.6); }\n#wcf-executive-dashboard .wcf-loading-spinner { width: 40px; height: 40px; border: 3px solid rgba(255,255,255,0.1); border-top-color: #22c55e; border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto 16px; }\n@keyframes spin { to { transform: rotate(360deg); } }\n\n\/* ===== RESPONSIVE - ENHANCED FOR TABLE AND MATRIX ===== *\/\n@media (max-width: 1024px) {\n    #wcf-executive-dashboard .wcf-grid-2col { grid-template-columns: 1fr; }\n    #wcf-executive-dashboard .wcf-grid-3col { grid-template-columns: 1fr; }\n    #wcf-executive-dashboard .wcf-kpi-inner { grid-template-columns: repeat(3, 1fr); }\n    #wcf-executive-dashboard .wcf-scroll-hint { display: flex; }\n    #wcf-executive-dashboard .wcf-scroll-hint-h { display: flex; }\n    #wcf-executive-dashboard .wcf-matrix-container { max-height: 400px; }\n}\n@media (max-width: 768px) {\n    #wcf-executive-dashboard .wcf-title { font-size: 28px; }\n    #wcf-executive-dashboard .wcf-kpi-inner { grid-template-columns: repeat(2, 1fr); }\n    #wcf-executive-dashboard .wcf-filter-inner { justify-content: center; }\n    #wcf-executive-dashboard .wcf-cta-inner { flex-direction: column; text-align: center; }\n    #wcf-executive-dashboard .wcf-cta-buttons { justify-content: center; }\n    #wcf-executive-dashboard .wcf-scroll-hint { display: flex; }\n    #wcf-executive-dashboard .wcf-scroll-hint-h { display: flex; }\n    #wcf-executive-dashboard .wcf-scroll-hint-v { display: flex; }\n    #wcf-executive-dashboard .wcf-incident-table th,\n    #wcf-executive-dashboard .wcf-incident-table td { padding: 10px 12px; font-size: 12px; }\n    #wcf-executive-dashboard .wcf-matrix-container { max-height: 350px; }\n}\n@media (max-width: 480px) {\n    #wcf-executive-dashboard .wcf-card-header { padding: 14px 16px; }\n    #wcf-executive-dashboard .wcf-card-body { padding: 16px; }\n    #wcf-executive-dashboard .wcf-incident-table { min-width: 600px; }\n    #wcf-executive-dashboard .wcf-matrix-container { max-height: 300px; }\n}\n<\/style>\n\n<!-- HERO -->\n<div class=\"wcf-hero\">\n    <div class=\"wcf-hero-inner\">\n        <div class=\"wcf-dashboard-icon\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"12\" width=\"4\" height=\"9\" rx=\"1\" fill=\"#22c55e\" stroke=\"#22c55e\"\/><rect x=\"10\" y=\"7\" width=\"4\" height=\"14\" rx=\"1\" fill=\"#3b82f6\" stroke=\"#3b82f6\"\/><rect x=\"17\" y=\"3\" width=\"4\" height=\"18\" rx=\"1\" fill=\"#f87171\" stroke=\"#f87171\"\/><\/svg><\/div>\n        <span class=\"wcf-label\">Executive Intelligence<\/span>\n        <h1 class=\"wcf-title\">Cloud Sovereignty Risk Dashboard<\/h1>\n        <p class=\"wcf-subtitle\">7 Years of Infrastructure Failures Visualized<\/p>\n        <p class=\"wcf-hero-desc\">Transform raw outage data into board-ready intelligence. Interactive heatmaps, provider risk matrix, and cost analysis.<\/p>\n        <span class=\"wcf-live-badge\" id=\"live-badge\">Loading&#8230;<\/span>\n        <div class=\"wcf-data-status\" id=\"data-status\"><\/div>\n        <a href=\"https:\/\/www.opey.org\/opeyit\/?page_id=585\" class=\"wcf-back-link\">\u2190 Back to Full Database<\/a>\n    <\/div>\n<\/div>\n\n<!-- KPI BAR -->\n<div class=\"wcf-kpi-bar\">\n    <div class=\"wcf-kpi-inner\" id=\"kpi-bar\">\n        <div class=\"wcf-loading\"><div class=\"wcf-loading-spinner\"><\/div>Loading data&#8230;<\/div>\n    <\/div>\n<\/div>\n\n<!-- YEAR FILTER -->\n<div class=\"wcf-filter-section\">\n    <div class=\"wcf-filter-inner\" id=\"filter-container\">\n        <span class=\"wcf-filter-label\">Loading&#8230;<\/span>\n    <\/div>\n<\/div>\n\n<!-- MAIN CONTENT -->\n<div class=\"wcf-main\">\n    <div class=\"wcf-main-inner\">\n        \n        <!-- ROW 1: Matrix + Risk Score -->\n        <div class=\"wcf-grid-2col\">\n            <div class=\"wcf-card\">\n                <div class=\"wcf-card-header\">\n                    <div>\n                        <div class=\"wcf-card-title\">Provider \u00d7 Day Incident Matrix<\/div>\n                        <div class=\"wcf-card-subtitle\" id=\"matrix-subtitle\">Loading&#8230;<\/div>\n                    <\/div>\n                <\/div>\n                <div class=\"wcf-card-body\">\n                    <div class=\"wcf-matrix-wrapper\">\n                        <div class=\"wcf-matrix-container\" id=\"matrix-container\">\n                            <div class=\"wcf-matrix\" id=\"incident-matrix\">\n                                <div class=\"wcf-loading\"><div class=\"wcf-loading-spinner\"><\/div><\/div>\n                            <\/div>\n                        <\/div>\n                        <!-- Scroll hints for both directions -->\n                        <div class=\"wcf-scroll-hint-h\" id=\"matrix-scroll-hint-h\">\n                            <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                                <polyline points=\"9 18 15 12 9 6\"><\/polyline>\n                            <\/svg>\n                        <\/div>\n                        <div class=\"wcf-scroll-hint-v\" id=\"matrix-scroll-hint-v\">\n                            <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                                <polyline points=\"6 9 12 15 18 9\"><\/polyline>\n                            <\/svg>\n                        <\/div>\n                    <\/div>\n                    <div class=\"wcf-matrix-legend\">\n                        <div class=\"wcf-legend-item\"><div class=\"wcf-legend-swatch\" style=\"background: rgba(255,255,255,0.05);\"><\/div><span>None<\/span><\/div>\n                        <div class=\"wcf-legend-item\"><div class=\"wcf-legend-swatch\" style=\"background: #22c55e;\"><\/div><span>Minor<\/span><\/div>\n                        <div class=\"wcf-legend-item\"><div class=\"wcf-legend-swatch\" style=\"background: #f59e0b;\"><\/div><span>Moderate<\/span><\/div>\n                        <div class=\"wcf-legend-item\"><div class=\"wcf-legend-swatch\" style=\"background: #ea580c;\"><\/div><span>Major<\/span><\/div>\n                        <div class=\"wcf-legend-item\"><div class=\"wcf-legend-swatch\" style=\"background: #dc2626;\"><\/div><span>Critical<\/span><\/div>\n                    <\/div>\n                    <div class=\"wcf-matrix-stats\" id=\"matrix-stats\">\n                        <!-- Populated by JS -->\n                    <\/div>\n                <\/div>\n            <\/div>\n            \n            <div style=\"display: flex; flex-direction: column; gap: 24px;\">\n                <div class=\"wcf-card\">\n                    <div class=\"wcf-card-header\">\n                        <div>\n                            <div class=\"wcf-card-title\">Sovereignty Risk Score<\/div>\n                            <div class=\"wcf-card-subtitle\">Industry concentration risk<\/div>\n                        <\/div>\n                    <\/div>\n                    <div class=\"wcf-card-body\">\n                        <div class=\"wcf-risk-gauge-container\" id=\"risk-gauge-container\">\n                            <div class=\"wcf-loading\"><div class=\"wcf-loading-spinner\"><\/div><\/div>\n                        <\/div>\n                    <\/div>\n                <\/div>\n                \n                <div class=\"wcf-card\" style=\"flex: 1;\">\n                    <div class=\"wcf-card-header\">\n                        <div>\n                            <div class=\"wcf-card-title\">Severity Distribution<\/div>\n                            <div class=\"wcf-card-subtitle\" id=\"severity-subtitle\">Loading&#8230;<\/div>\n                        <\/div>\n                    <\/div>\n                    <div class=\"wcf-card-body\">\n                        <div class=\"wcf-severity-grid\" id=\"severity-grid\">\n                            <div class=\"wcf-loading\"><div class=\"wcf-loading-spinner\"><\/div><\/div>\n                        <\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n        \n        <!-- ROW 2: Top Providers + Root Causes + High Impact -->\n        <div class=\"wcf-grid-3col\">\n            <div class=\"wcf-card\">\n                <div class=\"wcf-card-header\">\n                    <div>\n                        <div class=\"wcf-card-title\">Top Providers by Incidents<\/div>\n                        <div class=\"wcf-card-subtitle\" id=\"providers-subtitle\">Loading&#8230;<\/div>\n                    <\/div>\n                <\/div>\n                <div class=\"wcf-card-body\">\n                    <div class=\"wcf-provider-list\" id=\"provider-list\"><\/div>\n                <\/div>\n            <\/div>\n            \n            <div class=\"wcf-card\">\n                <div class=\"wcf-card-header\">\n                    <div>\n                        <div class=\"wcf-card-title\">Root Cause Categories<\/div>\n                        <div class=\"wcf-card-subtitle\">Primary failure attribution<\/div>\n                    <\/div>\n                <\/div>\n                <div class=\"wcf-card-body\">\n                    <div class=\"wcf-cause-list\" id=\"cause-list\"><\/div>\n                <\/div>\n            <\/div>\n            \n            <div class=\"wcf-card\">\n                <div class=\"wcf-card-header\">\n                    <div>\n                        <div class=\"wcf-card-title\">Highest Impact Events<\/div>\n                        <div class=\"wcf-card-subtitle\">By estimated cost<\/div>\n                    <\/div>\n                <\/div>\n                <div class=\"wcf-card-body\">\n                    <div class=\"wcf-timeline\" id=\"impact-timeline\"><\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n        \n        <!-- ROW 3: Recent Incidents Table - FIXED FOR MOBILE -->\n        <div class=\"wcf-card\">\n            <div class=\"wcf-card-header\">\n                <div>\n                    <div class=\"wcf-card-title\">Recent High-Impact Incidents<\/div>\n                    <div class=\"wcf-card-subtitle\" id=\"table-subtitle\">Critical and major incidents \u2022 Swipe to see all columns<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"wcf-card-body\" style=\"padding: 0;\">\n                <div class=\"wcf-table-wrapper\">\n                    <div class=\"wcf-table-scroll\" id=\"incident-table-scroll\">\n                        <table class=\"wcf-incident-table\">\n                            <thead>\n                                <tr>\n                                    <th class=\"wcf-col-date\">Date<\/th>\n                                    <th class=\"wcf-col-provider\">Provider<\/th>\n                                    <th class=\"wcf-col-incident\">Incident<\/th>\n                                    <th class=\"wcf-col-severity\">Severity<\/th>\n                                    <th class=\"wcf-col-duration\">Duration<\/th>\n                                    <th class=\"wcf-col-impact\">Est. Impact<\/th>\n                                <\/tr>\n                            <\/thead>\n                            <tbody id=\"incident-table\"><\/tbody>\n                        <\/table>\n                    <\/div>\n                    <div class=\"wcf-scroll-hint\" id=\"scroll-hint\">\n                        <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                            <polyline points=\"9 18 15 12 9 6\"><\/polyline>\n                        <\/svg>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n        \n    <\/div>\n<\/div>\n\n<!-- CTA SECTION -->\n<div class=\"wcf-cta-section\">\n    <div class=\"wcf-cta-inner\">\n        <div class=\"wcf-cta-content\">\n            <span class=\"wcf-cta-label\">Take Action<\/span>\n            <h2 class=\"wcf-cta-title\">Calculate Your Organization&#8217;s Risk<\/h2>\n            <p class=\"wcf-cta-text\">These industry-wide failures have already happened. Use our Sovereign Risk Assessment to calculate your specific cloud dependency score and generate a board-ready report.<\/p>\n            <div class=\"wcf-cta-buttons\">\n                <a href=\"https:\/\/www.opey.org\/opeyit\/?page_id=643\" class=\"wcf-btn wcf-btn-primary\">Calculate Your Score<\/a>\n                <a href=\"https:\/\/www.amazon.com\/dp\/B0GHP5RV68\" class=\"wcf-btn wcf-btn-outline\">Get the Book<\/a>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- FOOTER -->\n<div class=\"wcf-footer\">\n    <div class=\"wcf-footer-inner\">\n        <div>Data: <a href=\"https:\/\/www.opey.org\/opeyit\/?page_id=585\">OPEY Cloud Outage Database<\/a> \u2022 Source: <a href=\"https:\/\/www.amazon.com\/dp\/B0GHP5RV68\">&#8220;When Clouds Fail&#8221;<\/a> by Steve Oppenheim \u2022 License: <a href=\"https:\/\/creativecommons.org\/licenses\/by\/4.0\/\">CC BY 4.0<\/a><\/div>\n        <div>Updated: <span id=\"timestamp\"><\/span><\/div>\n    <\/div>\n<\/div>\n\n<!-- EXECUTIVE TOOLTIP - MOVED OUTSIDE SCROLL CONTAINERS -->\n<div class=\"wcf-tooltip\" id=\"wcf-exec-tooltip\"><\/div>\n\n<\/div>\n\n<script>\n(function() {\n    \/\/ =====================================================\n    \/\/ CONFIGURATION\n    \/\/ =====================================================\n    var CONFIG = {\n        SHEET_ID: '11SvFM_W9LB661CrcOVMrOiY0coSV1xIQrKCrOZJnqKE',\n        MAX_MATRIX_PROVIDERS: 100, \/\/ Increased from 12 to support 44+ vendors\n        MATRIX_MAX_HEIGHT: 480    \/\/ Default max-height in pixels (adjustable)\n    };\n\n    var incidentData = [];\n    var currentYear = 'latest';\n    var allYears = [];\n    var tooltipEl = null;\n\n    \/\/ Fallback data\n    var FALLBACK = [\n        { date: \"Jan 27, 2026\", year: \"2026\", providers: [\"AWS\"], title: \"AWS US-EAST-1 DynamoDB DNS Outage\", severity: \"critical\", scope: \"Global\", duration: \"~4h\", rootcause: \"DynamoDB DNS record deletion from software update bug\", costestimate: \"$500M - $1B\" },\n        { date: \"Jan 27, 2026\", year: \"2026\", providers: [\"Salesforce\"], title: \"Salesforce USA26 Instance Performance Degradation\", severity: \"moderate\", scope: \"Instance-Specific\", duration: \"~2h\", rootcause: \"Core Service performance degradation\", costestimate: \"$15M - $30M\" },\n        { date: \"Jan 25, 2026\", year: \"2026\", providers: [\"TikTok\", \"Oracle\"], title: \"TikTok US Data Center Power Outage\", severity: \"major\", scope: \"United States\", duration: \"72h+\", rootcause: \"Weather-related power outage at Oracle data center\", costestimate: \"$150M - $250M\" },\n        { date: \"Jan 25, 2026\", year: \"2026\", providers: [\"US Power Grid\"], title: \"Winter Storm Fern Infrastructure Collapse\", severity: \"critical\", scope: \"US Eastern Two-Thirds\", duration: \"96h+\", rootcause: \"Polar vortex winter storm\", costestimate: \"$5B - $8B\" },\n        { date: \"Jan 22, 2026\", year: \"2026\", providers: [\"Microsoft\", \"Azure\"], title: \"Microsoft 365 and Azure Infrastructure Failure\", severity: \"critical\", scope: \"Global\", duration: \"~18h\", rootcause: \"Control plane processing failure\", costestimate: \"$1.1B - $1.6B\" },\n        { date: \"Jan 22, 2026\", year: \"2026\", providers: [\"Cloudflare\"], title: \"Cloudflare IPv6 BGP Route Leak\", severity: \"major\", scope: \"Americas\", duration: \"25m\", rootcause: \"Routing policy configuration error\", costestimate: \"$80M - $120M\" },\n        { date: \"Jan 14, 2026\", year: \"2026\", providers: [\"Verizon\"], title: \"Verizon Nationwide Wireless Collapse\", severity: \"critical\", scope: \"United States\", duration: \"~10h\", rootcause: \"Core network software issue\", costestimate: \"$650M - $1.5B\" }\n    ];\n\n    \/\/ =====================================================\n    \/\/ UTILITY FUNCTIONS\n    \/\/ =====================================================\n    function getField(obj, fieldName) {\n        if (obj[fieldName] && String(obj[fieldName]).trim()) return String(obj[fieldName]);\n        var lower = fieldName.toLowerCase();\n        for (var key in obj) {\n            if (key.toLowerCase() === lower && obj[key] && String(obj[key]).trim()) {\n                return String(obj[key]);\n            }\n        }\n        return '';\n    }\n\n    function formatDate(value) {\n        if (!value) return value;\n        var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n        if (typeof value === 'string' && value.indexOf('Date(') === 0) {\n            var match = value.match(\/Date\\((\\d+),(\\d+),(\\d+)\\)\/);\n            if (match) return months[parseInt(match[2])] + ' ' + match[3] + ', ' + match[1];\n        }\n        if (typeof value === 'string' && \/^[A-Z][a-z]{2}\\s+\\d\/.test(value)) return value;\n        if (typeof value === 'string' && \/^\\d{4}-\\d{2}-\\d{2}\/.test(value)) {\n            var d = new Date(value);\n            return months[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear();\n        }\n        return value;\n    }\n\n    function parseCost(costStr) {\n        if (!costStr) return 0;\n        var matches = costStr.match(\/([\\d.]+)\\s*([BMK])?\/gi);\n        if (!matches || matches.length === 0) return 0;\n        var last = matches[matches.length - 1];\n        var m = last.match(\/([\\d.]+)\\s*([BMK])?\/i);\n        if (!m) return 0;\n        var n = parseFloat(m[1]);\n        var suffix = (m[2] || '').toUpperCase();\n        if (suffix === 'B') return n * 1000;\n        if (suffix === 'K') return n \/ 1000;\n        return n;\n    }\n\n    function extractDay(dateStr) {\n        if (!dateStr) return null;\n        var match = dateStr.match(\/(\\d{1,2})\/);\n        return match ? parseInt(match[1]) : null;\n    }\n\n    function extractMonth(dateStr) {\n        if (!dateStr) return null;\n        var months = { jan: 1, feb: 2, mar: 3, apr: 4, may: 5, jun: 6, jul: 7, aug: 8, sep: 9, oct: 10, nov: 11, dec: 12 };\n        var match = dateStr.toLowerCase().match(\/^([a-z]{3})\/);\n        return match ? months[match[1]] : null;\n    }\n\n    function formatCostShort(costStr) {\n        if (!costStr) return 'N\/A';\n        var match = costStr.match(\/^\\$[\\d.]+[BMK]?\\s*-?\\s*\\$?[\\d.]*[BMK]?\/i);\n        return match ? match[0].trim() : costStr.substring(0, 15);\n    }\n\n    \/\/ =====================================================\n    \/\/ DATA LOADING\n    \/\/ =====================================================\n    function loadData() {\n        var url = 'https:\/\/docs.google.com\/spreadsheets\/d\/' + CONFIG.SHEET_ID + '\/gviz\/tq?tqx=out:json&gid=0&headers=1';\n\n        fetch(url)\n            .then(function(response) {\n                if (!response.ok) throw new Error('HTTP ' + response.status);\n                return response.text();\n            })\n            .then(function(text) {\n                var start = text.indexOf('{');\n                var end = text.lastIndexOf('}');\n                if (start === -1) throw new Error('No JSON in response');\n\n                var json = JSON.parse(text.substring(start, end + 1));\n                var headers = json.table.cols.map(function(c) {\n                    return (c.label || c.id || '').trim();\n                });\n\n                if (headers.every(function(h) { return \/^[A-Za-z]$\/.test(h); })) {\n                    headers = json.table.rows[0].c.map(function(c) {\n                        return c ? String(c.v || '').trim() : '';\n                    });\n                    json.table.rows.shift();\n                }\n\n                incidentData = json.table.rows.map(function(row) {\n                    if (!row || !row.c) return null;\n                    var obj = {};\n                    row.c.forEach(function(cell, i) {\n                        if (headers[i]) {\n                            var val = cell ? (cell.f || (cell.v != null ? String(cell.v) : '')) : '';\n                            if (headers[i].toLowerCase() === 'date') val = formatDate(val);\n                            obj[headers[i].toLowerCase()] = val.trim();\n                        }\n                    });\n                    var provStr = getField(obj, 'providers');\n                    obj.providers = provStr ? provStr.split(',').map(function(p) { return p.trim(); }).filter(Boolean) : [];\n                    return obj;\n                }).filter(function(o) {\n                    return o && getField(o, 'date') && getField(o, 'title') && getField(o, 'severity');\n                });\n\n                if (incidentData.length === 0) throw new Error('No valid incidents');\n\n                document.getElementById('live-badge').textContent = 'Live Data';\n                showDataStatus('Loaded ' + incidentData.length + ' incidents from database', false);\n                renderAll();\n            })\n            .catch(function(err) {\n                console.error('Load failed:', err.message);\n                incidentData = FALLBACK;\n                document.getElementById('live-badge').textContent = 'Sample Data';\n                showDataStatus('Live data unavailable. Showing sample data.', true);\n                renderAll();\n            });\n    }\n\n    function showDataStatus(message, isError) {\n        var el = document.getElementById('data-status');\n        el.textContent = message;\n        el.className = 'wcf-data-status visible' + (isError ? ' error' : '');\n        if (!isError) {\n            setTimeout(function() { el.classList.remove('visible'); }, 3000);\n        }\n    }\n\n    \/\/ =====================================================\n    \/\/ RENDER ALL\n    \/\/ =====================================================\n    function renderAll() {\n        incidentData.sort(function(a, b) {\n            return new Date(getField(b, 'date')) - new Date(getField(a, 'date'));\n        });\n\n        allYears = [];\n        incidentData.forEach(function(inc) {\n            var y = getField(inc, 'year');\n            if (y && allYears.indexOf(y) === -1) allYears.push(y);\n        });\n        allYears.sort(function(a, b) { return b - a; });\n        currentYear = allYears[0] || '2026';\n\n        renderFilters();\n        renderDashboard(currentYear);\n        document.getElementById('timestamp').textContent = new Date().toLocaleString();\n        \n        \/\/ Initialize tooltip element\n        tooltipEl = document.getElementById('wcf-exec-tooltip');\n        \n        \/\/ Initialize scroll hints\n        initMatrixScrollHints();\n        initTableScrollHint();\n    }\n\n    function renderFilters() {\n        var container = document.getElementById('filter-container');\n        var html = '<span class=\"wcf-filter-label\">Select Year:<\/span>';\n        allYears.forEach(function(year, i) {\n            var active = (i === 0) ? ' active' : '';\n            html += '<button class=\"wcf-year-btn' + active + '\" onclick=\"wcfDashFilter(\\'' + year + '\\')\">' + year + '<\/button>';\n        });\n        container.innerHTML = html;\n    }\n\n    function getFilteredData(year) {\n        return incidentData.filter(function(inc) {\n            return getField(inc, 'year') === year;\n        });\n    }\n\n    function renderDashboard(year) {\n        currentYear = year;\n        var data = getFilteredData(year);\n\n        renderKPIs(data, year);\n        renderRiskGauge(data);\n        renderSeverityGrid(data, year);\n        renderMatrix(data, year);\n        renderProviderList(data, year);\n        renderRootCauses(data);\n        renderImpactTimeline(data);\n        renderIncidentTable(data, year);\n        \n        \/\/ Re-check scroll hints after rendering\n        setTimeout(function() {\n            initMatrixScrollHints();\n            initTableScrollHint();\n        }, 100);\n    }\n\n    \/\/ =====================================================\n    \/\/ SCROLL HINTS - MATRIX (HORIZONTAL + VERTICAL)\n    \/\/ =====================================================\n    function initMatrixScrollHints() {\n        var container = document.getElementById('matrix-container');\n        var hintH = document.getElementById('matrix-scroll-hint-h');\n        var hintV = document.getElementById('matrix-scroll-hint-v');\n        \n        if (!container || !hintH || !hintV) return;\n        \n        function checkScroll() {\n            \/\/ Horizontal scroll check\n            var isScrollableH = container.scrollWidth > container.clientWidth;\n            var isScrolledToEndH = container.scrollLeft + container.clientWidth >= container.scrollWidth - 10;\n            \n            if (isScrollableH && !isScrolledToEndH) {\n                hintH.style.display = 'flex';\n            } else {\n                hintH.style.display = 'none';\n            }\n            \n            \/\/ Vertical scroll check\n            var isScrollableV = container.scrollHeight > container.clientHeight;\n            var isScrolledToEndV = container.scrollTop + container.clientHeight >= container.scrollHeight - 10;\n            \n            if (isScrollableV && !isScrolledToEndV) {\n                hintV.style.display = 'flex';\n            } else {\n                hintV.style.display = 'none';\n            }\n        }\n        \n        \/\/ Check on scroll\n        container.removeEventListener('scroll', checkScroll);\n        container.addEventListener('scroll', checkScroll);\n        \n        \/\/ Initial check\n        checkScroll();\n        \n        \/\/ Re-check on resize\n        window.removeEventListener('resize', checkScroll);\n        window.addEventListener('resize', checkScroll);\n    }\n\n    \/\/ =====================================================\n    \/\/ SCROLL HINT FOR TABLE\n    \/\/ =====================================================\n    function initTableScrollHint() {\n        var scrollContainer = document.getElementById('incident-table-scroll');\n        var scrollHint = document.getElementById('scroll-hint');\n        \n        if (!scrollContainer || !scrollHint) return;\n        \n        function checkScroll() {\n            var isScrollable = scrollContainer.scrollWidth > scrollContainer.clientWidth;\n            var isScrolledToEnd = scrollContainer.scrollLeft + scrollContainer.clientWidth >= scrollContainer.scrollWidth - 10;\n            \n            if (isScrollable && !isScrolledToEnd) {\n                scrollHint.style.display = 'flex';\n            } else {\n                scrollHint.style.display = 'none';\n            }\n        }\n        \n        scrollContainer.removeEventListener('scroll', checkScroll);\n        scrollContainer.addEventListener('scroll', checkScroll);\n        checkScroll();\n        window.removeEventListener('resize', checkScroll);\n        window.addEventListener('resize', checkScroll);\n    }\n\n    \/\/ =====================================================\n    \/\/ KPIs\n    \/\/ =====================================================\n    function renderKPIs(data, year) {\n        var totalIncidents = data.length;\n        var totalImpact = 0;\n        var totalDuration = 0;\n        var durationCount = 0;\n        var providers = [];\n\n        data.forEach(function(inc) {\n            totalImpact += parseCost(getField(inc, 'costestimate'));\n            var dur = getField(inc, 'duration');\n            if (dur) {\n                var hours = dur.match(\/(\\d+)\\s*h\/i);\n                var mins = dur.match(\/(\\d+)\\s*m\/i);\n                if (hours || mins) {\n                    var h = hours ? parseInt(hours[1]) : 0;\n                    var m = mins ? parseInt(mins[1]) : 0;\n                    totalDuration += h + (m \/ 60);\n                    durationCount++;\n                }\n            }\n            (inc.providers || []).forEach(function(p) {\n                var pLower = p.toLowerCase();\n                if (providers.indexOf(pLower) === -1) providers.push(pLower);\n            });\n        });\n\n        var avgDuration = durationCount > 0 ? (totalDuration \/ durationCount).toFixed(1) : '--';\n        var criticalCount = data.filter(function(i) { return getField(i, 'severity').toLowerCase() === 'critical'; }).length;\n\n        var container = document.getElementById('kpi-bar');\n        container.innerHTML =\n            '<div class=\"wcf-kpi red\"><div class=\"wcf-kpi-label\">' + year + ' Incidents<\/div><div class=\"wcf-kpi-value\">' + totalIncidents + '<\/div><div class=\"wcf-kpi-delta\">' + criticalCount + ' Critical<\/div><\/div>' +\n            '<div class=\"wcf-kpi orange\"><div class=\"wcf-kpi-label\">Est. Economic Impact<\/div><div class=\"wcf-kpi-value\">$' + (totalImpact >= 1000 ? (totalImpact \/ 1000).toFixed(1) + 'B' : totalImpact.toFixed(0) + 'M') + '<\/div><div class=\"wcf-kpi-delta\">' + year + ' Total<\/div><\/div>' +\n            '<div class=\"wcf-kpi yellow\"><div class=\"wcf-kpi-label\">Avg Duration<\/div><div class=\"wcf-kpi-value\">' + avgDuration + 'h<\/div><div class=\"wcf-kpi-delta\">Per incident<\/div><\/div>' +\n            '<div class=\"wcf-kpi blue\"><div class=\"wcf-kpi-label\">Providers Affected<\/div><div class=\"wcf-kpi-value\">' + providers.length + '<\/div><div class=\"wcf-kpi-delta\">Unique providers<\/div><\/div>' +\n            '<div class=\"wcf-kpi green\"><div class=\"wcf-kpi-label\">Data Points<\/div><div class=\"wcf-kpi-value\">' + incidentData.length + '<\/div><div class=\"wcf-kpi-delta\">Total in database<\/div><\/div>';\n    }\n\n    \/\/ =====================================================\n    \/\/ RISK GAUGE\n    \/\/ =====================================================\n    function renderRiskGauge(data) {\n        var critical = data.filter(function(i) { return getField(i, 'severity').toLowerCase() === 'critical'; }).length;\n        var major = data.filter(function(i) { return getField(i, 'severity').toLowerCase() === 'major'; }).length;\n        var score = Math.min(99, Math.round(40 + (critical * 8) + (major * 4)));\n        var status = score >= 70 ? 'high' : score >= 50 ? 'medium' : 'low';\n        var statusLabel = status === 'high' ? 'High Concentration' : status === 'medium' ? 'Medium Risk' : 'Low Risk';\n        var strokeColor = status === 'high' ? '#dc2626' : status === 'medium' ? '#f59e0b' : '#22c55e';\n        var scoreColor = status === 'high' ? '#f87171' : status === 'medium' ? '#fbbf24' : '#4ade80';\n        var dashOffset = 188 - (score \/ 100 * 188);\n\n        var container = document.getElementById('risk-gauge-container');\n        container.innerHTML =\n            '<div class=\"wcf-risk-gauge\"><svg viewBox=\"0 0 160 80\"><path class=\"wcf-gauge-bg\" d=\"M 12 72 A 60 60 0 0 1 148 72\"><\/path><path class=\"wcf-gauge-fill\" d=\"M 12 72 A 60 60 0 0 1 148 72\" style=\"stroke: ' + strokeColor + '; stroke-dasharray: 188; stroke-dashoffset: ' + dashOffset + ';\"><\/path><\/svg><div class=\"wcf-risk-score\" style=\"color: ' + scoreColor + ';\">' + score + '<\/div><\/div>' +\n            '<div class=\"wcf-risk-label\">Industry Risk Index<\/div>' +\n            '<div class=\"wcf-risk-status ' + status + '\">' + statusLabel + '<\/div>';\n    }\n\n    \/\/ =====================================================\n    \/\/ SEVERITY GRID\n    \/\/ =====================================================\n    function renderSeverityGrid(data, year) {\n        var severities = { critical: 0, major: 0, moderate: 0, minor: 0 };\n        data.forEach(function(inc) {\n            var sev = getField(inc, 'severity').toLowerCase();\n            if (severities.hasOwnProperty(sev)) severities[sev]++;\n        });\n\n        var container = document.getElementById('severity-grid');\n        container.innerHTML =\n            '<div class=\"wcf-severity-item critical\"><div class=\"wcf-severity-count\">' + severities.critical + '<\/div><div class=\"wcf-severity-label\">Critical<\/div><\/div>' +\n            '<div class=\"wcf-severity-item major\"><div class=\"wcf-severity-count\">' + severities.major + '<\/div><div class=\"wcf-severity-label\">Major<\/div><\/div>' +\n            '<div class=\"wcf-severity-item moderate\"><div class=\"wcf-severity-count\">' + severities.moderate + '<\/div><div class=\"wcf-severity-label\">Moderate<\/div><\/div>' +\n            '<div class=\"wcf-severity-item minor\"><div class=\"wcf-severity-count\">' + severities.minor + '<\/div><div class=\"wcf-severity-label\">Minor<\/div><\/div>';\n\n        document.getElementById('severity-subtitle').textContent = year;\n    }\n\n    \/\/ =====================================================\n    \/\/ MATRIX WITH VERTICAL SCROLL SUPPORT\n    \/\/ =====================================================\n    function renderMatrix(data, year) {\n        var container = document.getElementById('incident-matrix');\n        var providerMap = {};\n        var severityOrder = ['critical', 'major', 'moderate', 'minor'];\n\n        \/\/ Build complete incident data for each provider\/day\n        data.forEach(function(inc) {\n            var day = extractDay(getField(inc, 'date'));\n            if (!day) return;\n            (inc.providers || []).forEach(function(p) {\n                var pName = p.trim();\n                if (!pName) return;\n                if (!providerMap[pName]) providerMap[pName] = { incidents: {}, totalCount: 0 };\n                if (!providerMap[pName].incidents[day]) providerMap[pName].incidents[day] = [];\n                providerMap[pName].incidents[day].push({\n                    severity: getField(inc, 'severity').toLowerCase(),\n                    title: getField(inc, 'title'),\n                    duration: getField(inc, 'duration') || 'N\/A',\n                    cost: formatCostShort(getField(inc, 'costestimate')),\n                    scope: getField(inc, 'scope') || 'Unknown',\n                    rootcause: getField(inc, 'rootcause') || 'Under investigation',\n                    date: getField(inc, 'date')\n                });\n                providerMap[pName].totalCount++;\n            });\n        });\n\n        \/\/ Sort providers by incident count (descending), NO artificial limit\n        var providers = Object.keys(providerMap).sort(function(a, b) {\n            return providerMap[b].totalCount - providerMap[a].totalCount;\n        }).slice(0, CONFIG.MAX_MATRIX_PROVIDERS); \/\/ Now supports 100 providers\n\n        var totalProviders = Object.keys(providerMap).length;\n\n        if (providers.length === 0) {\n            container.innerHTML = '<div class=\"wcf-no-data\"><div class=\"wcf-no-data-text\">No data for selected period<\/div><\/div>';\n            document.getElementById('matrix-stats').innerHTML = '';\n            return;\n        }\n\n        \/\/ Build header row with sticky positioning\n        var html = '<div class=\"wcf-matrix-row header\"><div class=\"wcf-provider-label\" style=\"background:#1e293b;\"><\/div>';\n        for (var d = 1; d <= 31; d++) {\n            html += '<div class=\"wcf-day-label\">' + d + '<\/div>';\n        }\n        html += '<\/div>';\n\n        \/\/ Build provider rows\n        providers.forEach(function(provider) {\n            var pData = providerMap[provider];\n            html += '<div class=\"wcf-matrix-row\"><div class=\"wcf-provider-label\">' + provider + '<\/div>';\n\n            for (var d = 1; d <= 31; d++) {\n                var dayIncs = pData.incidents[d] || [];\n                if (dayIncs.length > 0) {\n                    var highestSev = severityOrder.find(function(s) { return dayIncs.some(function(i) { return i.severity === s; }); }) || 'moderate';\n                    \n                    \/\/ Store full incident data as JSON for rich tooltip\n                    var incDataStr = encodeURIComponent(JSON.stringify(dayIncs));\n                    \n                    html += '<div class=\"wcf-matrix-cell ' + highestSev + '\" ' +\n                            'data-provider=\"' + provider + '\" ' +\n                            'data-day=\"' + d + '\" ' +\n                            'data-year=\"' + year + '\" ' +\n                            'data-incidents=\"' + incDataStr + '\">';\n                    if (dayIncs.length > 1) html += '<span class=\"count\">' + dayIncs.length + '<\/span>';\n                    html += '<\/div>';\n                } else {\n                    html += '<div class=\"wcf-matrix-cell\"><\/div>';\n                }\n            }\n            html += '<\/div>';\n        });\n\n        container.innerHTML = html;\n        \n        \/\/ Update subtitle with provider count\n        document.getElementById('matrix-subtitle').textContent = year + ' \u2022 ' + providers.length + ' providers \u2022 Hover cells for executive briefing';\n        \n        \/\/ Update matrix stats\n        var statsHtml = '<span>Providers tracked: <span class=\"wcf-stat-value\">' + totalProviders + '<\/span><\/span>';\n        if (providers.length < totalProviders) {\n            statsHtml += '<span>Showing top <span class=\"wcf-stat-value\">' + providers.length + '<\/span> by incidents<\/span>';\n        }\n        document.getElementById('matrix-stats').innerHTML = statsHtml;\n\n        \/\/ Attach event listeners using event delegation\n        attachMatrixTooltips();\n    }\n\n    \/\/ =====================================================\n    \/\/ EXECUTIVE TOOLTIP SYSTEM\n    \/\/ =====================================================\n    function attachMatrixTooltips() {\n        var matrix = document.getElementById('incident-matrix');\n        \n        \/\/ Remove old listeners (use cloneNode trick or named functions)\n        var newMatrix = matrix.cloneNode(true);\n        matrix.parentNode.replaceChild(newMatrix, matrix);\n        matrix = newMatrix;\n        \n        \/\/ Use event delegation on the matrix container\n        matrix.addEventListener('mouseover', function(e) {\n            var cell = e.target.closest('.wcf-matrix-cell[data-provider]');\n            if (cell) {\n                showExecutiveTooltip(cell, e);\n            }\n        });\n        \n        matrix.addEventListener('mouseout', function(e) {\n            var cell = e.target.closest('.wcf-matrix-cell[data-provider]');\n            if (cell) {\n                hideExecutiveTooltip();\n            }\n        });\n        \n        matrix.addEventListener('mousemove', function(e) {\n            var cell = e.target.closest('.wcf-matrix-cell[data-provider]');\n            if (cell && tooltipEl && tooltipEl.classList.contains('visible')) {\n                positionTooltip(e);\n            }\n        });\n    }\n\n    function showExecutiveTooltip(cell, e) {\n        if (!tooltipEl) tooltipEl = document.getElementById('wcf-exec-tooltip');\n        \n        var provider = cell.dataset.provider;\n        var day = cell.dataset.day;\n        var year = cell.dataset.year;\n        var incidentsData = [];\n        \n        try {\n            incidentsData = JSON.parse(decodeURIComponent(cell.dataset.incidents));\n        } catch(err) {\n            console.error('Tooltip data parse error:', err);\n            return;\n        }\n        \n        if (incidentsData.length === 0) return;\n        \n        var primary = incidentsData[0];\n        var monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n        var displayDate = primary.date || (monthNames[0] + ' ' + day + ', ' + year);\n        \n        \/\/ Build executive-focused tooltip content\n        var html = '<div class=\"wcf-tooltip-header\">' +\n                   '<span class=\"wcf-tooltip-provider\">' + provider + '<\/span>' +\n                   '<span class=\"wcf-tooltip-date\">' + displayDate + '<\/span>' +\n                   '<\/div>' +\n                   '<div class=\"wcf-tooltip-body\">' +\n                   '<span class=\"wcf-tooltip-severity ' + primary.severity + '\">' + primary.severity + '<\/span>' +\n                   '<div class=\"wcf-tooltip-title\">' + primary.title + '<\/div>' +\n                   '<div class=\"wcf-tooltip-metrics\">' +\n                   '<div class=\"wcf-tooltip-metric\"><div class=\"wcf-tooltip-metric-value\">' + primary.duration + '<\/div><div class=\"wcf-tooltip-metric-label\">Duration<\/div><\/div>' +\n                   '<div class=\"wcf-tooltip-metric\"><div class=\"wcf-tooltip-metric-value\">' + primary.cost + '<\/div><div class=\"wcf-tooltip-metric-label\">Est. Impact<\/div><\/div>' +\n                   '<\/div>';\n        \n        \/\/ Add additional incidents if multiple on same day\n        if (incidentsData.length > 1) {\n            html += '<div class=\"wcf-tooltip-multi\">' +\n                    '<div class=\"wcf-tooltip-multi-label\">+ ' + (incidentsData.length - 1) + ' more incident(s):<\/div>';\n            for (var i = 1; i < Math.min(incidentsData.length, 4); i++) {\n                html += '<div class=\"wcf-tooltip-multi-item\">' + incidentsData[i].title + '<\/div>';\n            }\n            html += '<\/div>';\n        }\n        \n        html += '<\/div>' +\n                '<div class=\"wcf-tooltip-footer\">Scope: ' + primary.scope + '<\/div>';\n        \n        tooltipEl.innerHTML = html;\n        positionTooltip(e);\n        tooltipEl.classList.add('visible');\n    }\n\n    function positionTooltip(e) {\n        if (!tooltipEl) return;\n        \n        var x = e.clientX + 20;\n        var y = e.clientY + 15;\n        var tooltipWidth = 320;\n        var tooltipHeight = tooltipEl.offsetHeight || 200;\n        \n        \/\/ Keep tooltip in viewport\n        if (x + tooltipWidth > window.innerWidth - 20) {\n            x = e.clientX - tooltipWidth - 20;\n        }\n        if (y + tooltipHeight > window.innerHeight - 20) {\n            y = e.clientY - tooltipHeight - 15;\n        }\n        if (x < 10) x = 10;\n        if (y < 10) y = 10;\n        \n        tooltipEl.style.left = x + 'px';\n        tooltipEl.style.top = y + 'px';\n    }\n\n    function hideExecutiveTooltip() {\n        if (tooltipEl) {\n            tooltipEl.classList.remove('visible');\n        }\n    }\n\n    \/\/ =====================================================\n    \/\/ PROVIDER LIST\n    \/\/ =====================================================\n    function renderProviderList(data, year) {\n        var providerCounts = {};\n        var providerColors = {\n            'aws': '#ff9900', 'microsoft': '#00bcf2', 'azure': '#0078d4', 'google': '#4285f4',\n            'cloudflare': '#f38020', 'meta': '#1877f2', 'facebook': '#1877f2', 'verizon': '#cd040b',\n            'salesforce': '#00a1e0', 'github': '#333', 'slack': '#4a154b', 'x': '#000', 'twitter': '#1da1f2',\n            'oracle': '#f80000', 'tiktok': '#000', 'grok': '#1a1a2e', 'xai': '#1a1a2e',\n            'anthropic': '#d4a574', 'openai': '#412991'\n        };\n\n        data.forEach(function(inc) {\n            (inc.providers || []).forEach(function(p) {\n                var pName = p.trim();\n                if (!pName) return;\n                providerCounts[pName] = (providerCounts[pName] || 0) + 1;\n            });\n        });\n\n        var sorted = Object.keys(providerCounts).map(function(name) {\n            return { name: name, count: providerCounts[name] };\n        }).sort(function(a, b) { return b.count - a.count; }).slice(0, 8);\n\n        if (sorted.length === 0) {\n            document.getElementById('provider-list').innerHTML = '<div class=\"wcf-no-data\"><div class=\"wcf-no-data-text\">No provider data<\/div><\/div>';\n            return;\n        }\n\n        var maxCount = sorted[0].count;\n        var html = sorted.map(function(p, i) {\n            var width = (p.count \/ maxCount) * 100;\n            var color = providerColors[p.name.toLowerCase()] || '#6366f1';\n            return '<div class=\"wcf-provider-row\"><span class=\"wcf-rank\">' + (i + 1) + '<\/span><span class=\"wcf-provider-name\">' + p.name + '<\/span><div class=\"wcf-provider-bar-container\"><div class=\"wcf-provider-bar\" style=\"width: ' + width + '%; background: ' + color + ';\"><\/div><\/div><span class=\"wcf-provider-count\">' + p.count + '<\/span><\/div>';\n        }).join('');\n\n        document.getElementById('provider-list').innerHTML = html;\n        document.getElementById('providers-subtitle').textContent = year;\n    }\n\n    \/\/ =====================================================\n    \/\/ ROOT CAUSES\n    \/\/ =====================================================\n    function renderRootCauses(data) {\n        var categories = {\n            config: { name: 'Configuration \/ Deploy', count: 0, keywords: ['config', 'deploy', 'update', 'change', 'migration', 'rollout'] },\n            power: { name: 'Power \/ Infrastructure', count: 0, keywords: ['power', 'cooling', 'heat', 'fire', 'weather', 'storm', 'electrical'] },\n            network: { name: 'Network \/ BGP', count: 0, keywords: ['bgp', 'dns', 'network', 'routing', 'peering', 'connectivity'] },\n            software: { name: 'Software \/ API', count: 0, keywords: ['software', 'bug', 'api', 'code', 'thread', 'memory', 'capacity'] }\n        };\n\n        data.forEach(function(inc) {\n            var rootCause = (getField(inc, 'rootcause') + ' ' + getField(inc, 'title')).toLowerCase();\n            var matched = false;\n            for (var cat in categories) {\n                if (categories[cat].keywords.some(function(kw) { return rootCause.indexOf(kw) !== -1; })) {\n                    categories[cat].count++;\n                    matched = true;\n                    break;\n                }\n            }\n            if (!matched) categories.software.count++;\n        });\n\n        var total = data.length || 1;\n        var icons = {\n            config: '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"><\/circle><path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z\"><\/path><\/svg>',\n            power: '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polygon points=\"13 2 3 14 12 14 11 22 21 10 12 10 13 2\"><\/polygon><\/svg>',\n            network: '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"><\/circle><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"><\/line><path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"><\/path><\/svg>',\n            software: '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"16 18 22 12 16 6\"><\/polyline><polyline points=\"8 6 2 12 8 18\"><\/polyline><\/svg>'\n        };\n\n        var sorted = Object.keys(categories).map(function(key) {\n            return { key: key, name: categories[key].name, count: categories[key].count, pct: Math.round((categories[key].count \/ total) * 100) };\n        }).sort(function(a, b) { return b.count - a.count; });\n\n        var html = sorted.map(function(cat) {\n            return '<div class=\"wcf-cause-row\"><div class=\"wcf-cause-icon ' + cat.key + '\">' + icons[cat.key] + '<\/div><div class=\"wcf-cause-info\"><div class=\"wcf-cause-name\">' + cat.name + '<\/div><div class=\"wcf-cause-count\">' + cat.count + ' incidents<\/div><\/div><div class=\"wcf-cause-pct\">' + cat.pct + '%<\/div><\/div>';\n        }).join('');\n\n        document.getElementById('cause-list').innerHTML = html;\n    }\n\n    \/\/ =====================================================\n    \/\/ IMPACT TIMELINE\n    \/\/ =====================================================\n    function renderImpactTimeline(data) {\n        var sorted = data.slice().sort(function(a, b) {\n            return parseCost(getField(b, 'costestimate')) - parseCost(getField(a, 'costestimate'));\n        }).slice(0, 5);\n\n        var html = sorted.map(function(inc) {\n            var sev = getField(inc, 'severity').toLowerCase();\n            var cost = formatCostShort(getField(inc, 'costestimate'));\n            var provider = (inc.providers || [])[0] || 'Unknown';\n            var dateMatch = getField(inc, 'date').match(\/^([A-Za-z]+\\s+\\d+)\/);\n            var shortDate = dateMatch ? dateMatch[1] : getField(inc, 'date');\n            var title = getField(inc, 'title');\n            if (title.length > 40) title = title.substring(0, 37) + '...';\n            return '<div class=\"wcf-timeline-item ' + sev + '\">' +\n                '<div class=\"wcf-timeline-header\">' +\n                '<div class=\"wcf-timeline-date\">' + shortDate + '<\/div>' +\n                '<div class=\"wcf-timeline-cost\">' + cost + '<\/div>' +\n                '<\/div>' +\n                '<div class=\"wcf-timeline-content\">' +\n                '<div class=\"wcf-timeline-provider\">' + provider + '<\/div>' +\n                '<div class=\"wcf-timeline-title\">' + title + '<\/div>' +\n                '<\/div>' +\n                '<\/div>';\n        }).join('');\n\n        document.getElementById('impact-timeline').innerHTML = html || '<div class=\"wcf-no-data\"><div class=\"wcf-no-data-text\">No cost data available<\/div><\/div>';\n    }\n\n    \/\/ =====================================================\n    \/\/ INCIDENT TABLE\n    \/\/ =====================================================\n    function renderIncidentTable(data, year) {\n        var filtered = data.filter(function(inc) {\n            var sev = getField(inc, 'severity').toLowerCase();\n            return sev === 'critical' || sev === 'major';\n        }).slice(0, 10);\n\n        var html = filtered.map(function(inc) {\n            var sev = getField(inc, 'severity').toLowerCase();\n            var provider = (inc.providers || []).join(', ') || 'Unknown';\n            return '<tr>' +\n                '<td class=\"wcf-col-date wcf-date-value\">' + getField(inc, 'date') + '<\/td>' +\n                '<td class=\"wcf-col-provider\">' + provider + '<\/td>' +\n                '<td class=\"wcf-col-incident\">' + getField(inc, 'title') + '<\/td>' +\n                '<td class=\"wcf-col-severity\"><span class=\"wcf-severity-badge ' + sev + '\">' + sev + '<\/span><\/td>' +\n                '<td class=\"wcf-col-duration\">' + (getField(inc, 'duration') || '-') + '<\/td>' +\n                '<td class=\"wcf-col-impact wcf-cost-value\">' + (getField(inc, 'costestimate') || '-') + '<\/td>' +\n                '<\/tr>';\n        }).join('');\n\n        document.getElementById('incident-table').innerHTML = html || '<tr><td colspan=\"6\" style=\"text-align:center;color:rgba(255,255,255,0.5);padding:40px;\">No critical\/major incidents<\/td><\/tr>';\n        document.getElementById('table-subtitle').textContent = 'Critical and major incidents \u2022 ' + year + ' \u2022 Swipe to see all columns';\n    }\n\n    \/\/ =====================================================\n    \/\/ YEAR FILTER GLOBAL\n    \/\/ =====================================================\n    window.wcfDashFilter = function(year) {\n        currentYear = year;\n        document.querySelectorAll('#wcf-executive-dashboard .wcf-year-btn').forEach(function(btn) {\n            btn.classList.remove('active');\n            if (btn.textContent === year) btn.classList.add('active');\n        });\n        renderDashboard(year);\n    };\n\n    \/\/ =====================================================\n    \/\/ INITIALIZE\n    \/\/ =====================================================\n    if (document.readyState === 'loading') {\n        document.addEventListener('DOMContentLoaded', loadData);\n    } else {\n        loadData();\n    }\n})();\n<\/script>\n\n\n\n\n<div id=\"elemID031021\" style=\"line-height:16px;text-align:center;z-index:100000;\"><a title=\"wix guests ip\" href=\"https:\/\/www.tracemyip.org\/pv1-3-36447-2\"><img decoding=\"async\" src=\"\/\/s3.tracemyip.org\/vLg\/1217\/4684NR-IPIB\/57003\/9\/njsUrl\/\" alt=\"Wix guests ip\" referrerpolicy=\"no-referrer-when-downgrade\" style=\"border:0px;\"><\/a><div><a href=\"https:\/\/www.tracemyip.org\/pv1-3-36447-2\">ip traffic<\/a><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Executive Intelligence Cloud Sovereignty Risk Dashboard 7 Years of Infrastructure Failures Visualized Transform raw outage data into board-ready intelligence. Interactive heatmaps, provider risk matrix, and cost analysis. Loading&#8230; \u2190 Back to Full Database Loading data&#8230; Loading&#8230; Provider \u00d7 Day Incident Matrix Loading&#8230; None Minor Moderate Major Critical Sovereignty Risk Score Industry concentration risk Severity Distribution [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-651","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.opey.org\/opeyit\/index.php?rest_route=\/wp\/v2\/pages\/651","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.opey.org\/opeyit\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.opey.org\/opeyit\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.opey.org\/opeyit\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.opey.org\/opeyit\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=651"}],"version-history":[{"count":18,"href":"https:\/\/www.opey.org\/opeyit\/index.php?rest_route=\/wp\/v2\/pages\/651\/revisions"}],"predecessor-version":[{"id":744,"href":"https:\/\/www.opey.org\/opeyit\/index.php?rest_route=\/wp\/v2\/pages\/651\/revisions\/744"}],"wp:attachment":[{"href":"https:\/\/www.opey.org\/opeyit\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=651"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}