Files
ThothII/presentations/thothii-congresso.html
T

785 lines
40 KiB
HTML

<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ThothII · Dal quesito clinico al dato tracciabile</title>
<meta name="description" content="Presentazione congressuale: come ThothII trasforma una domanda clinica in linguaggio naturale in SQL verificato, con evidenza citabile e un revisore umano a ogni decisione.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400..700;1,9..144,400..700&family=Manrope:wght@400..800&display=swap" rel="stylesheet">
<style>
/* ============================================================
ThothII · "The Clinical Workbench"
Palette derivata dai token OKLCH di DESIGN.md (porcellana calda,
grafite calda, rosso strumento scarso: mai più del ~10% della slide).
Tre registri tipografici: serif = autorità, sans = lettura,
mono = identità macchina (artefatti, metadati, SQL).
============================================================ */
:root{
--bg:#fcfafa; /* porcelain background */
--card:#fefefe; /* porcelain card */
--surface:#f7f5f5; /* warm surface */
--sunken:#f0edec; /* sunken surface */
--ink:#3e3538; /* warm graphite */
--muted:#7e7176; /* muted graphite */
--line:#e5e0e1; /* quiet border */
--red:#cb333b; /* instrument red */
--red-deep:#b52b33; /* instrument red pressed */
--mint:#3fae85; /* success (scuro abbastanza per il testo) */
--amber:#a97b1f; /* warning (versione leggibile) */
--info:#3f7fae; /* information */
--shadow-sm:0 1px 2px rgba(62,53,56,.05),0 2px 10px rgba(62,53,56,.05);
--shadow-md:0 2px 6px rgba(62,53,56,.07),0 14px 36px rgba(62,53,56,.09);
--ease:cubic-bezier(.22,1,.36,1);
--serif:"Fraunces","Source Serif Pro",Georgia,"Times New Roman",serif;
--sans:"Manrope",-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,Arial,sans-serif;
--mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,monospace;
color-scheme:light;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
background:var(--bg);color:var(--ink);
font-family:var(--sans);font-size:16px;line-height:1.6;
overflow:hidden;-webkit-font-smoothing:antialiased;font-kerning:normal;
}
::selection{background:rgba(203,51,59,.16)}
/* ---------- deck meccanica ---------- */
.deck{position:fixed;inset:0}
.slide{
position:absolute;inset:0;background:var(--bg);
opacity:0;visibility:hidden;pointer-events:none;
transition:opacity .24s var(--ease),visibility 0s linear .24s;
overflow:hidden;
}
.slide.on{opacity:1;visibility:visible;pointer-events:auto;transition:opacity .24s var(--ease)}
.frame{
height:100%;max-width:1300px;margin-inline:auto;
display:flex;flex-direction:column;
padding:clamp(34px,6.2vh,64px) clamp(28px,5vw,88px) clamp(56px,9vh,84px);
}
/* reveal scaglionato: entra con translate+fade, esce coperto dal fade della slide */
.rv{opacity:0;transform:translateY(14px);
transition:opacity .5s var(--ease),transform .5s var(--ease);
transition-delay:calc(var(--d,0)*70ms)}
.slide.on .rv{opacity:1;transform:none}
/* ---------- tipografia ---------- */
.kicker{
display:flex;align-items:center;gap:14px;
font-family:var(--mono);font-size:11.5px;font-weight:600;
letter-spacing:.09em;text-transform:uppercase;color:var(--muted);
margin-bottom:clamp(20px,3.6vh,40px);
}
.kicker .n{color:var(--red);font-variant-numeric:tabular-nums}
.ledger{position:relative;flex:1;height:1px;background:var(--line)}
.ledger::before{content:"";position:absolute;left:0;top:-2.5px;width:6px;height:6px;
border-radius:50%;background:var(--red)}
h1,h2{text-wrap:balance;font-optical-sizing:auto}
.title{
font-family:var(--serif);font-weight:600;
font-size:clamp(30px,4.1vw,56px);line-height:1.08;letter-spacing:-.015em;
max-width:22ch;
}
.title em{font-style:italic;font-weight:600}
.title .acc{color:var(--red)}
.lede{
font-size:clamp(16px,1.4vw,21px);line-height:1.55;color:var(--ink);
max-width:58ch;margin-top:clamp(14px,2.4vh,26px);
}
.lede .dim{color:var(--muted)}
p{max-width:62ch}
.small{font-size:13.5px;color:var(--muted)}
.mono{font-family:var(--mono)}
.chip{
display:inline-block;font-family:var(--mono);font-size:12.5px;font-weight:600;
color:var(--ink);background:var(--sunken);border:1px solid var(--line);
border-radius:6px;padding:3px 9px;white-space:nowrap;
}
.chip.red{color:var(--red-deep);background:rgba(203,51,59,.07);border-color:rgba(203,51,59,.22)}
/* ---------- componenti ricorrenti ---------- */
.rule-list{display:flex;flex-direction:column}
.rule-row{
display:grid;grid-template-columns:86px 1fr;gap:clamp(14px,2vw,28px);
padding:clamp(14px,2.4vh,24px) 0;border-top:1px solid var(--line);
}
.rule-row:last-child{border-bottom:1px solid var(--line)}
.num{
font-family:var(--serif);font-weight:600;font-style:italic;
font-size:clamp(26px,2.6vw,38px);line-height:1;color:var(--muted);
font-variant-numeric:tabular-nums;
}
.rule-row h3{font-size:clamp(15.5px,1.25vw,19px);font-weight:700;line-height:1.35}
.rule-row p{font-size:clamp(13.5px,1.05vw,15.5px);color:var(--muted);margin-top:5px}
.chain{display:flex;align-items:center;flex-wrap:wrap;gap:10px;
font-family:var(--mono);font-size:12.5px;font-weight:600}
.chain .node{background:var(--card);border:1px solid var(--line);border-radius:8px;
padding:7px 13px;box-shadow:var(--shadow-sm)}
.chain .node.last{border-color:rgba(203,51,59,.35);color:var(--red-deep)}
.chain .arr{color:var(--muted)}
/* centratura verticale del blocco contenuto nelle slide che non la ereditano */
.s-workflow .phases{margin-top:auto}
.s-workflow .callout{margin-bottom:auto}
.s-dialog .gates{margin-top:auto}
.s-dialog .truth{margin-bottom:auto}
/* barra HUD */
.hud{
position:fixed;left:0;right:0;bottom:0;z-index:10;
display:flex;align-items:center;gap:18px;
padding:14px clamp(28px,5vw,88px) 16px;pointer-events:none;
}
.hud .brand{font-family:var(--mono);font-size:10.5px;font-weight:600;
letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.hud .brand b{color:var(--red);font-weight:600}
.hud .count{font-family:var(--mono);font-size:11px;color:var(--muted);
font-variant-numeric:tabular-nums;letter-spacing:.08em}
.hud .track{flex:1;height:2px;background:var(--line);border-radius:2px;overflow:hidden}
.hud .fill{height:100%;width:0;background:var(--red);border-radius:2px;
transition:width .28s var(--ease)}
.hud button{
pointer-events:auto;cursor:pointer;width:34px;height:34px;border-radius:8px;
border:1px solid var(--line);background:var(--card);color:var(--muted);
display:grid;place-items:center;box-shadow:var(--shadow-sm);
transition:background .14s var(--ease),color .14s var(--ease),transform .14s var(--ease);
}
.hud button:hover{background:var(--surface);color:var(--ink)}
.hud button:active{transform:scale(.96)}
.hud button:focus-visible{outline:3px solid rgba(203,51,59,.35);outline-offset:1px}
.hud button:disabled{opacity:.4;cursor:default}
/* ============================================================
SLIDE 1 · copertina
============================================================ */
.s-cover .frame{justify-content:center}
.cover-mark{font-family:var(--serif);font-weight:600;letter-spacing:-.025em;
line-height:.95;font-size:clamp(64px,11vw,148px)}
.cover-mark .ii{color:var(--red)}
.cover-sub{
font-family:var(--serif);font-style:italic;font-weight:400;
font-size:clamp(19px,2.1vw,29px);line-height:1.3;max-width:34ch;
margin-top:clamp(18px,3vh,30px);color:var(--ink);
}
.cover-meta{display:flex;align-items:center;gap:16px;flex-wrap:wrap;
margin-top:clamp(26px,5vh,48px);
font-family:var(--mono);font-size:11.5px;font-weight:600;
letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}
.cover-meta .dot{width:4px;height:4px;border-radius:50%;background:var(--line)}
.hint{margin-top:clamp(22px,4.4vh,44px);font-family:var(--mono);font-size:11px;
color:var(--muted);letter-spacing:.06em}
/* ============================================================
SLIDE 2 · contesto: griglia asimmetrica 5/7
============================================================ */
.cols{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);
gap:clamp(30px,5vw,84px);align-items:start;flex:1;min-height:0;
align-content:center}
.s-context .lede{margin-top:18px}
.psychip{display:inline-flex;align-items:center;gap:8px;margin-top:clamp(20px,4vh,36px);
border:1px solid var(--line);background:var(--card);border-radius:8px;
padding:9px 14px;box-shadow:var(--shadow-sm);
font-family:var(--mono);font-size:12px;font-weight:600;color:var(--muted)}
.psychip i{width:7px;height:7px;border-radius:50%;background:var(--red);flex:none}
/* ============================================================
SLIDE 3 · principio
============================================================ */
.s-principle .frame{justify-content:center}
.s-principle .title{font-size:clamp(36px,5vw,68px);max-width:16ch}
.archi{margin-top:clamp(28px,5vh,52px)}
.archi-cap{font-family:var(--mono);font-size:11px;font-weight:600;
letter-spacing:.09em;text-transform:uppercase;color:var(--muted);margin-bottom:14px}
.archi-note{margin-top:16px;font-size:14px;color:var(--muted);max-width:66ch}
/* ============================================================
SLIDE 4 · workflow 8 fasi
============================================================ */
.phases{display:grid;grid-template-columns:repeat(4,1fr);
gap:0 clamp(20px,3vw,44px);margin-top:clamp(8px,2vh,18px)}
.phase{padding:clamp(12px,2vh,20px) 0;border-top:1px solid var(--line);
display:flex;flex-direction:column;gap:6px;min-width:0}
.phase .pn{font-family:var(--serif);font-style:italic;font-weight:600;
font-size:clamp(24px,2.4vw,34px);line-height:1;color:var(--muted);
font-variant-numeric:tabular-nums}
.phase.hot .pn{color:var(--red)}
.phase h3{font-size:clamp(14px,1.15vw,17px);font-weight:700;line-height:1.25}
.phase p{font-size:12.5px;line-height:1.45;color:var(--muted)}
.callout{
margin-top:clamp(20px,4vh,40px);border-radius:12px;
background:var(--surface);border:1px solid var(--line);
padding:clamp(16px,2.6vh,24px) clamp(18px,2.4vw,28px);
display:flex;gap:clamp(16px,2vw,28px);align-items:flex-start;
}
.callout .mark{font-family:var(--serif);font-style:italic;font-weight:600;
font-size:clamp(28px,3vw,44px);line-height:1;color:var(--red);flex:none}
.callout h3{font-size:clamp(15px,1.25vw,18px);font-weight:700;line-height:1.4}
.callout p{font-size:13.5px;color:var(--muted);margin-top:4px}
/* ============================================================
SLIDE 5 · disambiguazione: widget reale
============================================================ */
.widget{
background:var(--card);border:1px solid var(--line);border-radius:12px;
box-shadow:var(--shadow-md);padding:clamp(16px,2.2vh,22px) clamp(16px,1.8vw,22px);
font-size:13px;
}
.widget-head{display:flex;align-items:center;justify-content:space-between;gap:10px;
margin-bottom:12px}
.widget-head .tag{font-family:var(--mono);font-size:10.5px;font-weight:600;
letter-spacing:.1em;color:var(--muted)}
.wait{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);
font-size:10.5px;font-weight:600;letter-spacing:.05em;color:var(--amber)}
.wait i{width:6px;height:6px;border-radius:50%;background:#e9bd66;flex:none}
.widget .q{font-family:var(--serif);font-weight:600;font-size:15.5px;line-height:1.3;
margin-bottom:12px}
.opt{display:flex;gap:11px;padding:11px 12px;border:1px solid var(--line);
border-radius:8px;background:var(--bg)}
.opt + .opt{margin-top:8px}
.opt .radio{width:15px;height:15px;border-radius:50%;border:1.5px solid var(--line);
flex:none;margin-top:2px;position:relative}
.opt.rec .radio::after{content:"";position:absolute;inset:3px;border-radius:50%;
background:var(--red)}
.opt .radio.red{border-color:rgba(203,51,59,.5)}
.opt b{display:block;font-size:13px;line-height:1.35}
.opt code{display:block;margin-top:4px;font-family:var(--mono);font-size:11px;
color:var(--muted)}
.opt .badge{float:right;margin-left:10px;background:var(--red);color:var(--bg);
font-family:var(--mono);font-size:9.5px;font-weight:600;letter-spacing:.06em;
text-transform:uppercase;border-radius:6px;padding:2px 7px}
.wfoot{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}
.wfoot span{font-family:var(--mono);font-size:11px;color:var(--muted);
border:1px solid var(--line);border-radius:6px;padding:3px 9px;background:var(--bg)}
/* ============================================================
SLIDE 6 · evidence
============================================================ */
.flow{display:flex;align-items:stretch;gap:0;flex-wrap:wrap;
margin:clamp(14px,2.6vh,26px) 0 0}
.flow .step{flex:1 1 0;min-width:118px;border-top:1px solid var(--line);
padding:12px 14px 0 0;position:relative}
.flow .step + .step{padding-left:14px}
.flow .step::before{content:"";position:absolute;left:0;top:-3.5px;width:6px;height:6px;
border-radius:50%;background:var(--muted)}
.flow .step:first-child::before{background:var(--red)}
.flow b{display:block;font-size:13px;font-weight:700;line-height:1.3}
.flow span{display:block;font-size:11.5px;color:var(--muted);line-height:1.4;margin-top:3px}
.quote{
border-left:none;background:var(--surface);border:1px solid var(--line);
border-radius:12px;padding:clamp(14px,2.2vh,20px) clamp(16px,1.8vw,22px);
}
.quote .qt{font-family:var(--serif);font-style:italic;font-weight:400;
font-size:clamp(15px,1.35vw,18.5px);line-height:1.45}
.quote .src{font-family:var(--mono);font-size:11px;color:var(--muted);margin-top:10px;
letter-spacing:.04em}
.statrow{display:flex;gap:clamp(22px,3.5vw,54px);flex-wrap:wrap;
margin-top:clamp(16px,3vh,30px);align-items:baseline}
.stat .v{font-family:var(--serif);font-weight:600;line-height:1;
font-size:clamp(26px,2.8vw,40px);font-variant-numeric:tabular-nums}
.stat .v small{font-size:.55em;color:var(--muted);font-weight:600}
.stat .l{font-family:var(--mono);font-size:10.5px;font-weight:600;
letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin-top:6px}
/* ============================================================
SLIDE 7 · metadati DWH: pila stratificata
============================================================ */
.stack{display:flex;flex-direction:column;gap:10px}
.layer{border:1px solid var(--line);border-radius:10px;background:var(--card);
padding:13px 16px;display:grid;grid-template-columns:24px 1fr;gap:12px;
align-items:baseline;box-shadow:var(--shadow-sm)}
.layer .ld{width:7px;height:7px;border-radius:50%;background:var(--muted);
position:relative;top:-1px}
.layer.src .ld{background:var(--red)}
.layer b{font-size:14px;font-weight:700;display:block}
.layer b .mono{font-size:12px;color:var(--muted);font-weight:600}
.layer span{display:block;font-size:12.5px;color:var(--muted);line-height:1.45;margin-top:2px}
.stack .link{align-self:center;color:var(--muted);font-family:var(--mono);
font-size:11px;line-height:1;padding-left:8px}
/* ============================================================
SLIDE 8 · dialogo umano-AI
============================================================ */
.gates{display:flex;flex-direction:column;border-top:1px solid var(--line)}
.gate{display:grid;grid-template-columns:200px 1fr;gap:clamp(14px,2.4vw,32px);
padding:clamp(12px,2vh,19px) 0;border-bottom:1px solid var(--line);align-items:baseline}
.gate .gname{font-family:var(--mono);font-size:13px;font-weight:600;color:var(--red-deep)}
.gate .gname span{display:block;color:var(--muted);font-weight:400;font-size:11px;
margin-top:3px;letter-spacing:.04em}
.gate p{font-size:clamp(13.5px,1.1vw,15.5px);color:var(--ink);max-width:66ch}
.truth{
margin-top:clamp(18px,3.4vh,34px);display:grid;
grid-template-columns:auto 1fr;gap:clamp(16px,2.4vw,30px);align-items:start;
}
.truth .tmark{font-family:var(--serif);font-style:italic;font-weight:600;
font-size:clamp(28px,3vw,44px);line-height:1;color:var(--red)}
.truth h3{font-family:var(--serif);font-style:italic;font-weight:600;
font-size:clamp(19px,1.9vw,27px);line-height:1.25;letter-spacing:-.01em}
.truth p{font-size:13.5px;color:var(--muted);margin-top:8px;max-width:74ch}
/* ============================================================
SLIDE 9 · caso reale
============================================================ */
.trail{display:flex;flex-direction:column;position:relative;padding-left:19px}
.trail::before{content:"";position:absolute;left:5px;top:8px;bottom:8px;width:1px;
background:var(--line)}
.trail .tstep{position:relative;padding:7px 0 7px 6px;
font-family:var(--mono);font-size:12.5px;font-weight:600}
.trail .tstep::before{content:"";position:absolute;left:-18px;top:13px;width:7px;height:7px;
border-radius:50%;background:var(--card);border:1.5px solid var(--muted)}
.trail .tstep:first-child::before{border-color:var(--red);background:var(--red)}
.trail .tstep span{color:var(--muted);font-weight:400}
.outcome{display:flex;align-items:baseline;gap:12px;margin-top:clamp(16px,3vh,28px)}
.outcome .big{font-family:var(--serif);font-weight:600;font-size:clamp(44px,5vw,72px);
line-height:1;color:var(--red);font-variant-numeric:tabular-nums}
.outcome .lbl{font-size:14px;color:var(--muted);max-width:26ch;line-height:1.45}
.guar{display:flex;flex-direction:column}
.guar .g{display:grid;grid-template-columns:20px 1fr;gap:12px;
padding:clamp(11px,1.9vh,17px) 0;border-top:1px solid var(--line);align-items:baseline}
.guar .g:last-child{border-bottom:1px solid var(--line)}
.guar i{width:7px;height:7px;border-radius:50%;background:var(--mint);
position:relative;top:-1px;left:6px}
.guar b{font-size:14px;font-weight:700;display:block}
.guar span{font-size:12.5px;color:var(--muted);display:block;margin-top:2px;line-height:1.45}
/* ============================================================
SLIDE 10 · chiusura
============================================================ */
.s-end .frame{justify-content:center}
.s-end .title{font-size:clamp(40px,5.6vw,76px);max-width:14ch}
.principles{margin-top:clamp(24px,4.5vh,44px);max-width:860px}
.principles .rule-row{grid-template-columns:64px 1fr}
.principles h3{font-family:var(--serif);font-weight:600;font-style:italic;
font-size:clamp(16.5px,1.5vw,21px)}
.endmeta{margin-top:clamp(24px,4.5vh,42px);display:flex;align-items:center;gap:16px;
flex-wrap:wrap;font-family:var(--mono);font-size:11px;font-weight:600;
letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}
/* ---------- ridotto movimento: crossfade, zero spostamenti ---------- */
@media (prefers-reduced-motion:reduce){
.rv{transform:none;transition:opacity .2s linear;transition-delay:0ms}
.slide{transition:opacity .2s linear}
.hud .fill{transition:none}
}
/* ---------- stampato: una slide per pagina ---------- */
@media print{
body{overflow:visible}
.deck{position:static}
.slide{position:relative;opacity:1;visibility:visible;page-break-after:always;
height:100vh}
.hud{display:none}
}
</style>
</head>
<body>
<main class="deck" id="deck">
<!-- ══════════════ 1 · COPERTINA ══════════════ -->
<section class="slide s-cover" aria-label="Copertina">
<div class="frame">
<div class="kicker rv" style="--d:0"><span>Congresso · Informatica clinica</span><span class="ledger"></span></div>
<div class="cover-mark rv" style="--d:1">Thoth<span class="ii">II</span></div>
<p class="cover-sub rv" style="--d:2">L'intelligenza artificiale propone. Il medico decide.
Ogni risposta è tracciata fino all'evidenza.</p>
<div class="cover-meta rv" style="--d:3">
<span>Dal linguaggio naturale all'SQL</span><span class="dot"></span>
<span>Evidence curata</span><span class="dot"></span>
<span>Umano nel ciclo</span>
</div>
<p class="hint rv" style="--d:4">Usa le frecce ← → per navigare</p>
</div>
</section>
<!-- ══════════════ 2 · IL CONTESTO ══════════════ -->
<section class="slide s-context" aria-label="Il contesto">
<div class="frame">
<div class="kicker rv" style="--d:0"><span class="n">02</span><span>Il contesto</span><span class="ledger"></span></div>
<div class="cols">
<div>
<h1 class="title rv" style="--d:1">Il dato c'è. La domanda è fatta di parole.</h1>
<p class="lede rv" style="--d:2">I dati clinici vivono in un data warehouse, ma li
interroga solo chi scrive SQL. Ogni risposta ad hoc consuma il tempo di competenze
rare e non lascia traccia di come è stata costruita.</p>
<div class="psychip rv" style="--d:3"><i></i>DWH clinico · Policlinico San Donato · aritmologia</div>
</div>
<div class="rule-list rv" style="--d:2">
<div class="rule-row">
<span class="num">01</span>
<div><h3>Il linguaggio è ambiguo</h3>
<p>"Ricoveri nel 2023": anno solare o fiscale? Pazienti attivi o tutti?
Ogni parola nasconde una scelta clinica prima che tecnica.</p></div>
</div>
<div class="rule-row">
<span class="num">02</span>
<div><h3>Il significato è locale</h3>
<p>Le definizioni appartengono all'ospedale, non al dizionario:
cosa intende esattamente "fascia pediatrica" in questo dato?</p></div>
</div>
<div class="rule-row">
<span class="num">03</span>
<div><h3>Un numero senza percorso non è evidenza</h3>
<p>Una risposta che non si può verificare, ripetere e citare
non entra in una decisione clinica né in una ricerca.</p></div>
</div>
</div>
</div>
</div>
</section>
<!-- ══════════════ 3 · IL PRINCIPIO ══════════════ -->
<section class="slide s-principle" aria-label="Il principio">
<div class="frame">
<div class="kicker rv" style="--d:0"><span class="n">03</span><span>Il principio</span><span class="ledger"></span></div>
<h1 class="title rv" style="--d:1">Il modello propone.<br>Il medico <em class="acc">decide</em>.</h1>
<p class="lede rv" style="--d:2">ThothII è un banco di lavoro clinico: trasforma una domanda
in linguaggio naturale in SQL verificato, fase dopo fase, con un revisore umano a ogni
passaggio decisivo. Il modello non ha mai l'ultima parola, e non può prendersela:
persino l'avanzamento di fase è un atto umano registrato.</p>
<div class="archi rv" style="--d:3">
<div class="archi-cap">La catena, in un rigo</div>
<div class="chain">
<span class="node">Browser</span><span class="arr">→</span>
<span class="node">Backend</span><span class="arr">→</span>
<span class="node">Pi · agente</span><span class="arr">→</span>
<span class="node">tht · workflow</span><span class="arr">→</span>
<span class="node last">DWH in sola lettura</span>
</div>
<p class="archi-note">Nessuna scrittura sul magazzino dati: ThothII legge, propone e
documenta. Il risultato approvato può diventare un datamart, ma la fonte resta intoccata.</p>
</div>
</div>
</section>
<!-- ══════════════ 4 · IL WORKFLOW ══════════════ -->
<section class="slide s-workflow" aria-label="Il workflow in otto fasi">
<div class="frame">
<div class="kicker rv" style="--d:0"><span class="n">04</span><span>Il workflow</span><span class="ledger"></span></div>
<h1 class="title rv" style="--d:1">Otto fasi, uno stato che si calcola.</h1>
<div class="phases rv" style="--d:2">
<div class="phase hot"><span class="pn">1</span><h3>Chiarimento</h3>
<p>il significato della domanda, un'ambiguità alla volta</p></div>
<div class="phase"><span class="pn">2</span><h3>Memoria</h3>
<p>riuso della conoscenza già approvata in passato</p></div>
<div class="phase"><span class="pn">3</span><h3>Riscrittura</h3>
<p>la domanda diventa esplicita e non ambigua</p></div>
<div class="phase"><span class="pn">4</span><h3>Schema linking</h3>
<p>tabelle, colonne e join scelti sul catalogo</p></div>
<div class="phase"><span class="pn">5</span><h3>Sintesi</h3>
<p>il piano di calcolo, definito prima del codice</p></div>
<div class="phase"><span class="pn">6</span><h3>CTE</h3>
<p>ogni blocco viene testato sul dato reale</p></div>
<div class="phase"><span class="pn">7</span><h3>SQL finale</h3>
<p>approvato dal revisore, poi eseguito</p></div>
<div class="phase"><span class="pn">8</span><h3>Datamart</h3>
<p>export opzionale e promozione in memoria</p></div>
</div>
<div class="callout rv" style="--d:3">
<span class="mark">§</span>
<div>
<h3>La fase corrente non è mai memorizzata: è calcolata.</h3>
<p>Ripiegando il registro delle decisioni (<span class="chip">review_decisions.jsonl</span>)
il sistema ricava sempre lo stato vero. Riaprire una fase ricalcola tutto ciò che
viene dopo: le approvazioni diventate obsolete non contano più.</p>
</div>
</div>
</div>
</section>
<!-- ══════════════ 5 · DISAMBIGUAZIONE ══════════════ -->
<section class="slide s-disamb" aria-label="Disambiguazione">
<div class="frame">
<div class="kicker rv" style="--d:0"><span class="n">05</span><span>Disambiguazione</span><span class="ledger"></span></div>
<h1 class="title rv" style="--d:1">Una ambiguità alla volta,<br>con le conseguenze in vista.</h1>
<div class="cols" style="margin-top:clamp(18px,3.4vh,34px)">
<div>
<p class="lede rv" style="--d:2;margin-top:0">Ogni proposta di interpretazione
porta con sé tutto il necessario per decidere: il significato attribuito alle parole,
le tabelle coinvolte, il filtro che ne deriva sul dato, l'evidenza che la sostiene
e il rischio residuo.</p>
<p class="lede rv" style="--d:3;margin-top:14px"><span class="dim">La scelta
consigliata non è mai pre-confermata. E esistono sempre le vie di uscita:
</span>Altro, Torna indietro, Esci.</p>
<p class="lede rv" style="--d:4;margin-top:14px">Ogni risposta diventa una
<span class="chip">concept_clarified</span> nel registro: la disambiguazione
non è una chiacchierata, è un atto documentato.</p>
</div>
<div class="widget rv" style="--d:3" role="img" aria-label="Esempio di widget di selezione per la disambiguazione di una domanda clinica">
<div class="widget-head">
<span class="tag">REVIEWER_SELECT · F1 CHIARIMENTO</span>
<span class="wait"><i></i>In attesa di revisione</span>
</div>
<div class="q">"Pazienti con ricoveri nell'anno 2023": come va inteso "anno"?</div>
<div class="opt rec">
<span class="radio"></span>
<div style="flex:1;min-width:0">
<b><span class="badge">Consigliata</span>Anno solare</b>
<code>data_ricovero BETWEEN '2023-01-01' AND '2023-12-31'</code>
<code>ricoveri: REPARTI ⋈ RICOVERI · evidenza: calendario PSD</code>
</div>
</div>
<div class="opt">
<span class="radio"></span>
<div style="flex:1;min-width:0">
<b>Anno fiscale</b>
<code>periodo amministrativo definito dalla direzione sanitaria</code>
<code>richiede conferma del periodo esatto prima di procedere</code>
</div>
</div>
<div class="wfoot"><span>Altro</span><span>Torna indietro</span><span>Esci</span></div>
</div>
</div>
</div>
</section>
<!-- ══════════════ 6 · EVIDENCE ══════════════ -->
<section class="slide s-evidence" aria-label="Gestione delle evidence">
<div class="frame">
<div class="kicker rv" style="--d:0"><span class="n">06</span><span>Evidence</span><span class="ledger"></span></div>
<h1 class="title rv" style="--d:1">La conoscenza clinica, curata e citabile.</h1>
<div class="flow rv" style="--d:2">
<div class="step"><b>Fonte</b><span>documento originale, immutato</span></div>
<div class="step"><b>Unità atomiche</b><span>una regola o definizione per unità</span></div>
<div class="step"><b>Manifest</b><span>unità, fonte e impronta sha256</span></div>
<div class="step"><b>Validazione</b><span>controlli che falliscono in chiuso</span></div>
<div class="step"><b>Indicizzazione</b><span>BM25 + vettori densi</span></div>
<div class="step"><b>Generazioni</b><span>immutabili, con puntatore ACTIVE</span></div>
</div>
<div class="cols" style="grid-template-columns:minmax(0,7fr) minmax(0,5fr);margin-top:clamp(16px,3vh,30px)">
<div class="rv" style="--d:3">
<div class="quote">
<p class="qt">"La fascia pediatrica comprende i pazienti con età inferiore a 18 anni."</p>
<p class="src">unità di evidence · fonte tracciata · sha256 verificato</p>
</div>
<p class="lede" style="margin-top:18px;font-size:15px"><span class="dim">Ciò che il modello
recupera sono </span>candidati, non fatti<span class="dim">: i valori vanno verificati
sul dato reale, e ogni uso di un'evidence va citato con la sua provenienza. Niente
entra nella base di conoscenza senza un curatore umano.</span></p>
</div>
<div class="rv" style="--d:4">
<div class="statrow" style="margin-top:0;flex-direction:column;gap:18px">
<div class="stat"><div class="v">35</div><div class="l">Unità approvate · PSD</div></div>
<div class="stat"><div class="v">60</div><div class="l">In revisione del curatore</div></div>
<div class="stat"><div class="v">20<small>/20</small></div><div class="l">Accettazione retrieval · Hit@10</div></div>
</div>
</div>
</div>
</div>
</section>
<!-- ══════════════ 7 · METADATI DWH ══════════════ -->
<section class="slide s-metadata" aria-label="Metadati sul data warehouse">
<div class="frame">
<div class="kicker rv" style="--d:0"><span class="n">07</span><span>Metadati del DWH</span><span class="ledger"></span></div>
<h1 class="title rv" style="--d:1">Una fotografia versionata,<br>mai un bersaglio mobile.</h1>
<div class="cols" style="margin-top:clamp(18px,3.4vh,34px)">
<div class="stack rv" style="--d:2">
<div class="layer src"><span class="ld"></span><div>
<b>DWH clinico <span class="mono">· Policlinico San Donato</span></b>
<span>lo schema fiscale reale, letto una sola volta</span></div></div>
<span class="link">↓ snapshot</span>
<div class="layer"><span class="ld"></span><div>
<b>Snapshot <span class="mono">.tht-dwh · physical.yaml</span></b>
<span>catalogo preparato + firme LSH dei valori per la ricerca fuzzy</span></div></div>
<span class="link">↓ indici</span>
<div class="layer"><span class="ld"></span><div>
<b>Indici ibridi <span class="mono">Qdrant 1024 dim · BM25</span></b>
<span>schema e memoria condividono il denso, l'evidence aggiunge il lessicale</span></div></div>
<span class="link">↓ uso</span>
<div class="layer"><span class="ld"></span><div>
<b>Sessioni <span class="mono">· workspace_revision bloccata</span></b>
<span>ogni domanda interroga una versione precisa dei metadati</span></div></div>
</div>
<div class="rule-list rv" style="--d:3">
<div class="rule-row" style="grid-template-columns:1fr">
<div><h3>Introspezione una volta sola</h3>
<p>Il catalogo non viene interrogato a ogni domanda: si lavora su uno snapshot
preparato, veloce e stabile.</p></div>
</div>
<div class="rule-row" style="grid-template-columns:1fr">
<div><h3>Generazioni immutabili</h3>
<p>Ogni aggiornamento crea una nuova generazione con puntatore ACTIVE; le vecchie
restano leggibili.</p></div>
</div>
<div class="rule-row" style="grid-template-columns:1fr">
<div><h3>Se l'impronta non torna, ci si ferma</h3>
<p>La firma dell'owner viene verificata all'avvio: un ambiente che non corrisponde
fa fallire il sistema in chiuso, senza tentativi alla cieca.</p></div>
</div>
</div>
</div>
</div>
</section>
<!-- ══════════════ 8 · DIALOGO UMANO-AI ══════════════ -->
<section class="slide s-dialog" aria-label="Interazione umano-AI">
<div class="frame">
<div class="kicker rv" style="--d:0"><span class="n">08</span><span>Il dialogo umano-AI</span><span class="ledger"></span></div>
<h1 class="title rv" style="--d:1">Tre gesti per decidere.</h1>
<div class="gates rv" style="--d:2">
<div class="gate">
<div class="gname">reviewer_select<span>una scelta</span></div>
<p>Il modello propone interpretazioni mutuamente esclusive, ognuna con significato,
filtro ed evidenza. La scelta è essa stessa la conferma: niente passaggi inutili.</p>
</div>
<div class="gate">
<div class="gname">reviewer_decide<span>più scelte</span></div>
<p>Quando più letture sono legittime insieme, ogni voce selezionata è una decisione
distinta e registrata nel ledger.</p>
</div>
<div class="gate">
<div class="gname">reviewer_confirm<span>un artefatto</span></div>
<p>Domanda riscritta, schema collegato, SQL finale: i prodotti del lavoro passano
da un gate esplicito prima di valere come verità della sessione.</p>
</div>
</div>
<div class="truth rv" style="--d:3">
<span class="tmark">§</span>
<div>
<h3>"Ciò che non è registrato non è accaduto."</h3>
<p>Non esiste una trascrizione della conversazione: la verità di una sessione sono gli
artefatti su disco e il registro delle decisioni. Riprendere una sessione significa
rientrare nell'ultima fase incompleta, con tutto il filo ricostruibile. E un hook
anti-bypass impedisce al modello di avanzare da solo: la mano sul volante resta umana.</p>
</div>
</div>
</div>
</section>
<!-- ══════════════ 9 · CASO REALE ══════════════ -->
<section class="slide s-case" aria-label="Una sessione reale">
<div class="frame">
<div class="kicker rv" style="--d:0"><span class="n">09</span><span>Una sessione reale</span><span class="ledger"></span></div>
<h1 class="title rv" style="--d:1">Da una domanda a 78 pazienti,<br>senza mai perdere il filo.</h1>
<div class="cols" style="margin-top:clamp(16px,3vh,30px)">
<div class="rv" style="--d:2">
<div class="trail">
<div class="tstep">question.md <span>· la domanda, riscritta e non ambigua</span></div>
<div class="tstep">schema_linking.json <span>· tabelle e join scelti</span></div>
<div class="tstep">cte_plan.json <span>· il piano, a blocchi verificabili</span></div>
<div class="tstep">3 CTE testate <span>· ognuna contro il dato reale</span></div>
<div class="tstep">sql_final.sql <span>· approvata al gate dal revisore</span></div>
<div class="tstep">export <span>· il risultato, con il suo percorso</span></div>
</div>
<div class="outcome">
<span class="big">78</span>
<span class="lbl">pazienti restituiti da una sessione reale,
completata su tutti gli 8 passaggi</span>
</div>
</div>
<div class="rv" style="--d:3">
<div class="guar">
<div class="g"><i></i><div><b>Sola lettura sul magazzino</b>
<span>le credenziali di consultazione non scrivono mai sul DWH</span></div></div>
<div class="g"><i></i><div><b>Esecuzioni solo dall'elenco consentito</b>
<span>test CTE, explain, anteprima: massimo 10 righe, timeout a 30 secondi</span></div></div>
<div class="g"><i></i><div><b>Segreti fuori dal percorso</b>
<span>credenziali e configurazioni sensibili non vivono nel workspace</span></div></div>
<div class="g"><i></i><div><b>Cinque gate superati in questa sessione</b>
<span>ogni approvazione è una ricevuta nel registro delle decisioni</span></div></div>
</div>
</div>
</div>
</div>
</section>
<!-- ══════════════ 10 · CHIUSURA ══════════════ -->
<section class="slide s-end" aria-label="In sintesi">
<div class="frame">
<div class="kicker rv" style="--d:0"><span class="n">10</span><span>In sintesi</span><span class="ledger"></span></div>
<h1 class="title rv" style="--d:1">Proporre,<br>non decidere.</h1>
<div class="principles rv" style="--d:2">
<div class="rule-row"><span class="num">1</span>
<h3>Il modello propone, il clinico decide.</h3></div>
<div class="rule-row"><span class="num">2</span>
<h3>Ciò che non è registrato non è accaduto.</h3></div>
<div class="rule-row"><span class="num">3</span>
<h3>Ogni numero cita la propria provenienza.</h3></div>
<div class="rule-row"><span class="num">4</span>
<h3>In caso di dubbio, il sistema si ferma.</h3></div>
</div>
<div class="endmeta rv" style="--d:3">
<span>Thoth<b style="color:var(--red)">II</b></span><span class="dot" style="width:4px;height:4px;border-radius:50%;background:var(--line)"></span>
<span>Dal quesito clinico al dato tracciabile</span><span class="dot" style="width:4px;height:4px;border-radius:50%;background:var(--line)"></span>
<span>Grazie</span>
</div>
</div>
</section>
</main>
<!-- HUD: brand · progresso · contatore · navigazione -->
<footer class="hud" aria-hidden="false">
<span class="brand">Thoth<b>II</b></span>
<span class="track"><span class="fill" id="fill"></span></span>
<span class="count" id="count">01 / 10</span>
<button id="prev" aria-label="Slide precedente">
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<button id="next" aria-label="Slide successiva">
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M6 3l5 5-5 5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
</footer>
<script>
(function(){
const slides=[...document.querySelectorAll('.slide')];
const N=slides.length;
const fill=document.getElementById('fill');
const count=document.getElementById('count');
const prev=document.getElementById('prev');
const next=document.getElementById('next');
let cur=-1;
function pad(n){return String(n).padStart(2,'0')}
function go(i,push){
i=Math.max(0,Math.min(N-1,i));
if(i===cur)return;
if(cur>=0)slides[cur].classList.remove('on');
cur=i;
const s=slides[cur];
s.classList.add('on');
s.setAttribute('aria-hidden','false');
slides.forEach((el,k)=>{if(k!==cur)el.setAttribute('aria-hidden','true')});
fill.style.width=((cur+1)/N*100)+'%';
count.textContent=pad(cur+1)+' / '+pad(N);
prev.disabled=cur===0;next.disabled=cur===N-1;
if(push!==false)history.replaceState(null,'','#'+(cur+1));
}
function fromHash(){
const m=location.hash.match(/^#(\d+)$/);
go(m?parseInt(m[1],10)-1:0,false);
}
window.addEventListener('keydown',e=>{
if(e.target.closest('button')&&(e.key===' '||e.key==='Enter'))return;
if(e.key==='ArrowRight'||e.key==='PageDown'||e.key===' '){e.preventDefault();go(cur+1)}
else if(e.key==='ArrowLeft'||e.key==='PageUp'){e.preventDefault();go(cur-1)}
else if(e.key==='Home'){e.preventDefault();go(0)}
else if(e.key==='End'){e.preventDefault();go(N-1)}
});
prev.addEventListener('click',()=>{go(cur-1);prev.blur()});
next.addEventListener('click',()=>{go(cur+1);next.blur()});
/* swipe per touch */
let x0=null;
window.addEventListener('pointerdown',e=>{if(e.isPrimary)x0=e.clientX});
window.addEventListener('pointerup',e=>{
if(x0===null||!e.isPrimary)return;
const dx=e.clientX-x0;x0=null;
if(Math.abs(dx)>60)go(cur+(dx<0?1:-1));
});
window.addEventListener('hashchange',fromHash);
fromHash();
})();
</script>
</body>
</html>