deck: slide 02 ported to Orbit composition + missing-piece popups

- scattered island map replaces the syscard grid: four systems with
  emblem icons, names and scopes, clickable (problem popups)
- central 'Missing Pieces' column: four dashed rects with '?' marks,
  clickable (popups explaining each gap with 'The gap' box)
- title 'four missing pieces' to match the four destinations
- deck.css: scatter/isle/todo/missing-title styles
This commit is contained in:
Codex
2026-09-07 12:36:39 +02:00
parent f796b14b70
commit 0ad8577621
2 changed files with 70 additions and 26 deletions
+21 -14
View File
@@ -213,20 +213,24 @@ button.brain-btn:hover, button.brain-btn:focus-visible { transform: scale(1.18);
.arit .chip.tbd { color: var(--bordeaux-deep); border: 1px solid var(--bordeaux); background: #fff;
border-radius: 9999px; padding: 6px 12px; font: 700 10.5px/1 var(--sans); letter-spacing: .06em; }
/* where we started */
.arit .sysmap { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; flex: 1; align-content: center; }
.arit .syscard { position: relative; display: block; width: 100%; border: 1.5px solid var(--line-strong);
border-radius: 8px; background: var(--surface-alt); padding: 20px 16px 14px; text-align: left;
cursor: pointer; font-family: var(--sans); transition: transform .15s ease, box-shadow .15s ease; }
.arit button.syscard:hover, .arit button.syscard:focus-visible { transform: translateY(-3px);
box-shadow: 0 6px 18px rgba(42,36,38,.14); outline: none; }
.arit .syscard b { display: block; font: 700 17px/1.3 var(--sans); color: var(--ink); margin-bottom: 6px; }
.arit .syscard .d { display: block; font: 400 12.5px/1.45 var(--sans); color: var(--ink-muted); }
.arit .syscard .tag20 { position: absolute; top: -10px; right: 12px; background: var(--bordeaux); color: #fff;
border-radius: 9999px; padding: 3px 10px; font: 700 9.5px/1 var(--sans); letter-spacing: .08em; }
.arit .syscard.ghost { border: 1.5px dashed var(--bordeaux); background: #fff; cursor: default; }
.arit .syscard.ghost b { color: var(--bordeaux-deep); }
.arit .syscard.ghost .tag20 { background: var(--bordeaux-deep); }
/* where we started — scattered orbit map */
.arit .scatter { position: relative; flex: 1; min-height: 0; }
.arit .todo-stack { position: absolute; z-index: 2; }
.arit .todo { display: flex; align-items: center; gap: 12px; border: 2px dashed var(--bordeaux);
border-radius: 8px; background: #fff; padding: 8px 12px; margin-bottom: 8px;
box-shadow: 0 2px 8px rgba(42,36,38,.06); cursor: pointer; }
.arit .todo .q { font: 800 22px/1 var(--sans); color: var(--bordeaux-deep); }
.arit .todo .tx { display: flex; flex-direction: column; }
.arit .todo b { font: 700 13.5px/1.3 var(--sans); color: var(--bordeaux-deep); }
.arit .todo .tx span { font: 400 12px/1.4 var(--sans); color: var(--ink-muted); margin-top: 2px; }
.arit .missing-title { position: absolute; font: 700 30px/1.2 var(--sans); color: var(--bordeaux-deep); }
.arit .isle { position: absolute; display: flex; flex-direction: column; align-items: center; gap: 2px;
cursor: pointer; transform: rotate(var(--rot, 0deg)); transition: transform .18s ease;
border: none; background: none; font-family: var(--sans); width: 230px; }
.arit .isle:hover, .arit .isle:focus-visible { transform: rotate(var(--rot, 0deg)) scale(1.05); outline: none; }
.arit .isle .ico { width: var(--size, 120px); height: var(--size, 120px); color: var(--bordeaux); display: block; }
.arit .isle .nm { font: 700 16px/1.3 var(--sans); color: var(--ink); margin-top: 4px; }
.arit .isle .sc { font: 400 13.5px/1.4 var(--sans); color: var(--ink-muted); max-width: 240px; }
.arit .hint { margin-top: 12px; font: italic 400 12px/1.4 var(--sans); color: var(--ink-muted); }
/* snapshot tours + chart placeholders */
@@ -264,3 +268,6 @@ button.brain-btn:hover, button.brain-btn:focus-visible { transform: scale(1.18);
.arit.flow-slide .lead { margin-top: 6px; font-size: 15px; }
.arit.flow-slide .flow { margin-top: 14px; }
.arit.flow-slide .pillars { padding-top: 8px; }
/* popup: lead + list (missing-pieces popups) */
.ai-pop-card p.lead { font-style: italic; color: var(--ink-muted); }
+49 -12
View File
@@ -5,7 +5,7 @@
<title>AritmoLab — Role of AI in the Analysis of Unstructured Clinical Databases</title>
<link rel="stylesheet" href="vendor/reveal/dist/reveal.css">
<link rel="stylesheet" href="fonts.css?v=8">
<link rel="stylesheet" href="deck.css?v=9">
<link rel="stylesheet" href="deck.css?v=21">
</head>
<body>
<div class="reveal"><div class="slides">
@@ -52,17 +52,29 @@
<span class="band-section">Where we started</span>
</nav>
<div class="sbody">
<div class="kicker">Twenty years ago</div>
<h2>Four islands and two missing pieces</h2>
<div class="sysmap">
<button class="syscard" data-start="cardioref"><span class="tag20">20 YEARS</span><b>Cardioref</b><span class="d">clinical records: patients, daily activity, planning of the Aritmology Unit</span></button>
<button class="syscard" data-start="genetic"><b>Genetic data</b><span class="d">a dedicated collector for genetic tests and variants</span></button>
<button class="syscard" data-start="omics"><b>Omics Portal</b><span class="d">360° patient management — still in its infancy</span></button>
<button class="syscard" data-start="ecg"><b>ECG subsystems</b><span class="d">ECG acquisition and storage, device by device</span></button>
<div class="syscard ghost"><span class="tag20">MISSING</span><b>No Health Intelligence</b><span class="d">nothing usable to analyse historical data</span></div>
<div class="syscard ghost"><span class="tag20">MISSING</span><b>No ML-ready datamarts</b><span class="d">nothing ready for predictive statistics or machine learning</span></div>
<h2>Four islands and four missing pieces</h2>
<div class="scatter">
<div class="todo-stack" style="left:30%; top:22%; width:40%">
<div class="todo" data-missing="ci" style="margin-left:0"><span class="q">?</span><span class="tx"><b>Clinical Intelligence</b><span>dashboards on the clinical history of the Unit and its patients</span></span></div>
<div class="todo" data-missing="dwh" style="margin-left:9%"><b>Datawarehouse</b><span>the single source of truth</span></div>
<div class="todo" data-missing="ml" style="margin-left:4%"><b>ML-ready data</b><span>cohort tables, ready for model training</span></div>
<div class="todo" data-missing="portal" style="margin-left:12%"><b>Professional Portal</b><span>AritmoLab — the grown-up Omics Portal</span></div>
</div>
<button class="isle" data-start="cardioref" style="--rot:-3deg; --size:104px; left:0%; top:10%; width:230px">
<svg class="ico" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M24 33 c-6-3.5-9-7-9-10.5 0-3 4-5.5 7-3 1 .8 1.6 1.8 2 3 .4-1.2 1-2.2 2-3 3-2.5 7 0 7 3 0 3.5-3 7-9 10.5z" fill="currentColor" stroke="none"/><path d="M22.5 21 h3 v3 h3 v3 h-3 v3 h-3 v-3 h-3 v-3 h3 z" fill="#fff" stroke="none"/></svg>
<span class="nm">Cardioref</span><span class="sc">visits · operations · reports — twenty years of management on structured forms</span></button>
<button class="isle" data-start="genetic" style="--rot:3deg; --size:104px; left:73%; top:8%; width:230px">
<svg class="ico" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8 C28 14 28 20 18 26 C12 30 12 35 18 40"/><path d="M30 8 C20 14 20 20 30 26 C36 30 36 35 30 40"/><path d="M17 12 H31"/><path d="M15.5 18 H32.5"/><path d="M17 24 H31"/><path d="M14.5 31 H22"/><rect x="25" y="29" width="12" height="12" rx="1.5" stroke-width="2"/><path d="M25 34 H37"/><path d="M30.5 29 V41"/></svg>
<span class="nm">Genetic data</span><span class="sc">DNA instruments — results typed into Excel by hand</span></button>
<button class="isle" data-start="omics" style="--rot:-2deg; --size:106px; left:0%; top:62%; width:230px">
<svg class="ico" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="24" cy="24" r="20" stroke-width="2.6"/><circle cx="24" cy="24" r="4" fill="currentColor" stroke="none"/><circle cx="24" cy="10" r="3.4"/><circle cx="11.5" cy="31" r="3.4"/><circle cx="36.5" cy="31" r="3.4"/><path d="M24 20.5 V13.5"/><path d="M21 26.5 L14 29.5"/><path d="M27 26.5 L34 29.5"/></svg>
<span class="nm">Omics Portal</span><span class="sc">meant to host Cardioref + genetics — still immature</span></button>
<button class="isle" data-start="ecg" style="--rot:2deg; --size:104px; left:73%; top:60%; width:230px">
<svg class="ico" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="24" cy="24" r="20" stroke-width="2.6"/><path d="M9 24 h6 l3-9 5 16 3-7 h14" stroke-width="2.4"/><circle cx="24" cy="24" r="1.8" fill="currentColor" stroke="none"/></svg>
<span class="nm">ECG</span><span class="sc">paper strip + a CSV on request</span></button>
<div class="missing-title" style="left:calc(30% + 14px); top:calc(22% - 46px); width:40%">Missing Pieces</div>
</div>
<p class="hint">▸ click a system: how it was used — and what held it back</p>
<p class="hint">▸ click a system: how it was used — and what held it back · click a missing piece: what it would have given</p>
</div>
<footer class="foot"><span class="g">Role of AI in the Analysis of Unstructured Clinical Databases</span><span class="g">Dr. Marco Pancotti - MultiPhysixLab</span><span class="g">Dr. Sara Paratico - Gruppo San Donato</span><span class="g">San Donato Milanese, Milan, Italy · 2–3 October 2026</span><span class="g num">02 / 15</span></footer>
<aside class="notes">
@@ -616,6 +628,29 @@
line.setAttribute('x2', ax); line.setAttribute('y2', ly);
dot.setAttribute('cx', bx); dot.setAttribute('cy', by);
};
const MISSING_CONTRIBS = {
ci: { kicker: 'The missing piece · 20 years ago', title: 'Clinical Intelligence — the history, made visible',
body: `<p class="lead">Twenty years of clinical history, with no way to show it.</p>
<ul class="ai-pop-list"><li><b>What it is</b> — dashboards on the Unit's activity and its patients: volumes, incidence, outcomes</li>
<li><b>Who needed it</b> — management, audit, clinical research</li>
<li><b>Why it never existed</b> — the data was in prose; building dashboards on text was impractical</li></ul>
<div class="roi"><b class="k">The gap</b>No fast answer to “how are we doing?” — every question meant a manual query.</div>` },
dwh: { kicker: 'The missing piece · 20 years ago', title: 'Datawarehouse — one analysis-ready home',
body: `<p class="lead">One home for every record the Unit produces: text, structured fields, genetics, ECG.</p>
<ul class="ai-pop-list"><li><b>What it is</b> — a single schema joining all the sources, designed for analysis</li>
<li><b>Why it never existed</b> — each system kept its own silo; joining them meant hand-stitching exports</li></ul>
<div class="roi"><b class="k">The gap</b>Every research question started with manual exports — and ended in fragile spreadsheets.</div>` },
ml: { kicker: 'The missing piece · 20 years ago', title: 'ML-ready data — cohorts for research',
body: `<p class="lead">Tables shaped for statistics and model training: clean, wide, reproducible.</p>
<ul class="ai-pop-list"><li><b>What it is</b> — one row per patient, features beside outcomes, rebuildable at will</li>
<li><b>Why it never existed</b> — building it by hand from free text and separate silos took weeks</li></ul>
<div class="roi"><b class="k">The gap</b>Predictive research on the Unit's data stayed out of reach.</div>` },
portal: { kicker: 'The missing piece · 20 years ago', title: 'Professional Portal — the 360° view',
body: `<p class="lead">The 360° view of the patient: Cardioref and genetics finally in one place.</p>
<ul class="ai-pop-list"><li><b>What it is</b> — the grown-up Omics Portal: management, care and research on the same platform</li>
<li><b>Why it never existed</b> — the idea was there; the integrated data to feed it was not</li></ul>
<div class="roi"><b class="k">The gap</b>A single door for patients and clinicians — promised, never delivered.</div>` },
};
const START_CONTRIBS = {
cardioref: {
kicker: 'The starting point · 20 years ago',
@@ -677,8 +712,10 @@
document.addEventListener('click', (e) => {
const b = e.target.closest('.brain-btn[data-ai]');
if (b) { openPop(b.dataset.ai, b, AI_CONTRIBS); return; }
const s = e.target.closest('.syscard[data-start]');
const s = e.target.closest('.isle[data-start]');
if (s) { openPop(s.dataset.start, s, START_CONTRIBS); return; }
const m = e.target.closest('.todo[data-missing]');
if (m) { openPop(m.dataset.missing, m, MISSING_CONTRIBS); return; }
if (e.target.closest('.ai-pop-x') || e.target === pop) closePop();
});
// Escape closes the popup first (capture), without toggling Reveal's overview