Operatørbeslutning 14.08, gitt etter publisering: «Kom i gang: tre kommandoer» fjernes fra docs/kort-presentasjon.html. Slidens innhold sto allerede i README-ens install-blokk, som er den ene kopien. To følgeendringer var obligatoriske, ellers ville flaten sagt noe usant om seg selv (A5-klassen): 1. Slide 1s foot-note lovet «tre kommandoer (side 11)» — en henvisning til en side som ikke lenger finnes. Skrevet om, ikke utvidet: setningen sier fortsatt at kjøringen kan gjentas uten kostnad, men peker ikke lenger på et sted i decket. En README-peker et annet sted i decket er en beslutning som ikke er tatt her. 2. «Tolv sider» → «Elleve sider» i samme foot-note, og README-linja «12 slides» → «11» (fortsatt innenfor planens 10–12). Målt i nettleser over lokal HTTP (file:// avvises av utvidelsen): 11 slides, teller 1/11, UTF-8 uten mojibake, null gjenværende treff på «Tolv sider» / «side 11» / «Kom i gang». Høyeste slide 808 px (< 900-taket), identisk i lyst og mørkt tema — sveipet måler .inner + padding, ikke seksjonen: første forsøk ga 1003 px for alle elleve, altså viewport-høyden, og et instrument som gir samme tall for hver slide kan ikke skille en høy fra en lav. Sidefunn, uttalt og ikke handlet på: `.cmd`-reglene i CSS-en har ingen bruker igjen. Inert, og å rydde dem er en egen beslutning. uv run pytest: 846 passed / 4 skipped (uendret). repo-standard: OK, 20 sjekker, null ERROR/WARN — men gaten var grønn før endringen også, så den er ikke verifikasjon for denne.
529 lines
38 KiB
HTML
529 lines
38 KiB
HTML
<!doctype html>
|
|
<meta charset="utf-8">
|
|
<title>Pengene inne i porteføljen</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<style>
|
|
:root {
|
|
--ground: #F6F5F1; --surface: #FFFFFF; --surface-2: #EFEDE6;
|
|
--ink: #22272B; --muted: #5C6570; --line: #D9D6CC;
|
|
--accent: #C89B00; --accent-ink: #7A5F00; --steel: #35566F;
|
|
--ok-bg: #E3F0E7; --ok-fg: #1F5C38;
|
|
--warn-bg: #F6ECD4; --warn-fg: #7A5410;
|
|
--bad-bg: #F5E0DD; --bad-fg: #8C3128;
|
|
}
|
|
@media (prefers-color-scheme: dark) {
|
|
:root:not([data-theme="light"]) {
|
|
--ground: #15181B; --surface: #1D2126; --surface-2: #23282E;
|
|
--ink: #E9E7E1; --muted: #9AA3AC; --line: #343A41;
|
|
--accent: #E3B93F; --accent-ink: #E3B93F; --steel: #8FB4D2;
|
|
--ok-bg: #1E3327; --ok-fg: #8FCCA6;
|
|
--warn-bg: #38301A; --warn-fg: #E0BE6A;
|
|
--bad-bg: #3A2523; --bad-fg: #E09A92;
|
|
}
|
|
}
|
|
:root[data-theme="dark"] {
|
|
--ground: #15181B; --surface: #1D2126; --surface-2: #23282E;
|
|
--ink: #E9E7E1; --muted: #9AA3AC; --line: #343A41;
|
|
--accent: #E3B93F; --accent-ink: #E3B93F; --steel: #8FB4D2;
|
|
--ok-bg: #1E3327; --ok-fg: #8FCCA6;
|
|
--warn-bg: #38301A; --warn-fg: #E0BE6A;
|
|
--bad-bg: #3A2523; --bad-fg: #E09A92;
|
|
}
|
|
|
|
* { box-sizing: border-box; }
|
|
html, body { height: 100%; }
|
|
body {
|
|
background: var(--ground); color: var(--ink);
|
|
font-family: Charter, "Bitstream Charter", Cambria, Georgia, serif;
|
|
margin: 0; overflow: hidden;
|
|
}
|
|
h1, h2, .kicker, .btn, .counter, .pill, .cmd, ul.plist {
|
|
font-family: -apple-system, "Segoe UI", system-ui, "Helvetica Neue", Arial, sans-serif;
|
|
}
|
|
|
|
.slide {
|
|
display: none; position: absolute; inset: 0;
|
|
padding: clamp(30px, 4.4vw, 72px) clamp(28px, 7vw, 116px) clamp(56px, 7vh, 88px);
|
|
flex-direction: column; justify-content: center;
|
|
}
|
|
.slide.active { display: flex; }
|
|
.inner { width: 100%; max-width: 1060px; margin: 0 auto; }
|
|
|
|
.kicker {
|
|
font-size: clamp(0.68rem, 1vw, 0.8rem); font-weight: 650;
|
|
text-transform: uppercase; letter-spacing: 0.12em;
|
|
color: var(--accent-ink); margin-bottom: 16px;
|
|
}
|
|
h1 { font-size: clamp(2rem, 4.8vw, 3.5rem); font-weight: 650; letter-spacing: -0.02em; line-height: 1.09; margin: 0 0 22px; text-wrap: balance; }
|
|
h2 { font-size: clamp(1.4rem, 3vw, 2.25rem); font-weight: 650; letter-spacing: -0.015em; line-height: 1.18; margin: 0 0 18px; text-wrap: balance; max-width: 26ch; }
|
|
|
|
/* selvbaerende brodtekst - hver slide skal kunne leses alene */
|
|
.say {
|
|
font-size: clamp(1rem, 1.55vw, 1.24rem);
|
|
line-height: 1.6; max-width: 62ch; margin: 0 0 1rem;
|
|
}
|
|
.say.dim { color: var(--muted); }
|
|
.say strong { font-weight: 650; }
|
|
.say:last-child { margin-bottom: 0; }
|
|
.lead-sub { font-size: clamp(1.05rem, 1.8vw, 1.4rem); color: var(--muted); max-width: 46ch; line-height: 1.5; }
|
|
|
|
code { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 0.88em;
|
|
background: var(--surface-2); border-radius: 3px; padding: 1px 5px; }
|
|
|
|
.cmd {
|
|
background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--accent);
|
|
padding: 20px 26px; margin: 6px 0 20px;
|
|
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
font-size: clamp(0.82rem, 1.35vw, 1.02rem); line-height: 2.0; overflow-x: auto; white-space: pre;
|
|
}
|
|
|
|
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; margin-top: 6px; }
|
|
.card { background: var(--surface); border: 1px solid var(--line); border-top: 3px solid var(--accent); padding: 20px 22px; }
|
|
.card .t { font-family: -apple-system, system-ui, sans-serif; font-weight: 650; font-size: clamp(0.98rem, 1.4vw, 1.1rem); display: block; margin-bottom: 12px; }
|
|
.card.good { border-top-color: var(--ok-fg); }
|
|
.card.good .t { color: var(--ok-fg); }
|
|
.card.risk { border-top-color: var(--bad-fg); }
|
|
.card.risk .t { color: var(--bad-fg); }
|
|
ul.plist { list-style: none; padding: 0; margin: 0; display: grid; gap: 11px; }
|
|
ul.plist li { font-size: clamp(0.86rem, 1.22vw, 1rem); line-height: 1.5; padding-left: 16px; position: relative; }
|
|
ul.plist li::before { content: "—"; position: absolute; left: 0; color: var(--muted); }
|
|
ul.plist .dim { color: var(--muted); }
|
|
|
|
.foot-note { color: var(--muted); font-size: clamp(0.82rem, 1.12vw, 0.96rem); margin-top: 20px; max-width: 64ch; line-height: 1.55; }
|
|
|
|
svg { display: block; max-width: 100%; height: auto; }
|
|
.fig { margin: 2px 0 16px; }
|
|
.svg-ink { fill: var(--ink); } .svg-muted { fill: var(--muted); } .svg-accent { fill: var(--accent-ink); }
|
|
.svg-box { fill: var(--surface); stroke: var(--line); stroke-width: 1.5; }
|
|
.svg-box-hi { fill: var(--surface-2); stroke: var(--accent); stroke-width: 2.5; }
|
|
.svg-line { stroke: var(--muted); stroke-width: 1.8; fill: none; }
|
|
.svg-line-hi { stroke: var(--accent); stroke-width: 2.5; fill: none; }
|
|
text { font-family: -apple-system, "Segoe UI", system-ui, sans-serif; }
|
|
|
|
.bar-ui {
|
|
position: fixed; left: 0; right: 0; bottom: 0;
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
padding: 9px clamp(16px, 3vw, 32px); gap: 16px;
|
|
border-top: 1px solid var(--line); background: var(--ground);
|
|
font-family: -apple-system, system-ui, sans-serif; font-size: 0.78rem; color: var(--muted);
|
|
}
|
|
.btn { background: var(--surface); border: 1px solid var(--line); color: var(--ink);
|
|
padding: 5px 13px; font-size: 0.8rem; cursor: pointer; border-radius: 4px; }
|
|
.btn:hover { border-color: var(--accent); }
|
|
.counter { font-variant-numeric: tabular-nums; letter-spacing: 0.03em; }
|
|
.where { font-weight: 600; color: var(--accent-ink); }
|
|
.nav { display: flex; gap: 10px; align-items: center; }
|
|
.progress { position: fixed; top: 0; left: 0; height: 3px; background: var(--accent); transition: width 0.18s ease; z-index: 5; }
|
|
@media print { .bar-ui, .progress { display: none; } }
|
|
</style>
|
|
|
|
<div class="progress" id="prog"></div>
|
|
|
|
<!-- ============ 1 · TITTEL ============ -->
|
|
<section class="slide" data-part="">
|
|
<div class="inner">
|
|
<div class="kicker">portfolio-optimiser · åpen kildekode</div>
|
|
<h1>Pengene inne i porteføljen</h1>
|
|
<p class="lead-sub">Et åpent rammeverk som leter etter kostnadsbesparelser i hvert enkelt prosjekt — og som ikke får lov til å godkjenne sine egne funn.</p>
|
|
<p class="foot-note">Elleve sider. Kjøringstallene underveis er hentet fra en eksempelkjøring som følger med i repoet — du kan gjenta den selv, uten kostnad.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ============ 2 · PROBLEMET ============ -->
|
|
<section class="slide" data-part="Problemet">
|
|
<div class="inner">
|
|
<div class="kicker">Problemet</div>
|
|
<h2>Besparelsene ligger inne i prosjekter som allerede er vedtatt</h2>
|
|
<div class="fig">
|
|
<svg viewBox="0 0 900 150" role="img" aria-label="En rekke vedtatte prosjekter, der noen bærer tiltak ingen har regnet på">
|
|
<rect class="svg-box" x="6" y="14" width="104" height="76" rx="3"/>
|
|
<rect class="svg-box" x="118" y="14" width="104" height="76" rx="3"/>
|
|
<rect class="svg-box" x="230" y="14" width="104" height="76" rx="3"/>
|
|
<rect class="svg-box" x="342" y="14" width="104" height="76" rx="3"/>
|
|
<rect class="svg-box" x="454" y="14" width="104" height="76" rx="3"/>
|
|
<rect class="svg-box" x="566" y="14" width="104" height="76" rx="3"/>
|
|
<rect class="svg-box" x="678" y="14" width="104" height="76" rx="3"/>
|
|
<rect class="svg-box" x="790" y="14" width="104" height="76" rx="3"/>
|
|
<rect x="130" y="58" width="80" height="22" rx="2" fill="var(--warn-bg)" stroke="var(--accent)" stroke-width="1.5"/>
|
|
<text x="170" y="74" font-size="11.5" font-weight="650" text-anchor="middle" fill="var(--warn-fg)">kr</text>
|
|
<rect x="466" y="58" width="80" height="22" rx="2" fill="var(--warn-bg)" stroke="var(--accent)" stroke-width="1.5"/>
|
|
<text x="506" y="74" font-size="11.5" font-weight="650" text-anchor="middle" fill="var(--warn-fg)">kr</text>
|
|
<rect x="690" y="58" width="80" height="22" rx="2" fill="var(--warn-bg)" stroke="var(--accent)" stroke-width="1.5"/>
|
|
<text x="730" y="74" font-size="11.5" font-weight="650" text-anchor="middle" fill="var(--warn-fg)">kr</text>
|
|
<text class="svg-muted" x="6" y="124" font-size="13">vedtatte prosjekter — hvert med sitt budsjett og sine kostlinjer</text>
|
|
<text class="svg-accent" x="894" y="124" font-size="13" font-weight="650" text-anchor="end">tiltak ingen har regnet på</text>
|
|
<path class="svg-line-hi" d="M 806 114 C 776 104 748 96 736 86" marker-end="url(#m2)"/>
|
|
<defs><marker id="m2" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0 0 L8 4 L0 8 z" class="svg-accent"/></marker></defs>
|
|
</svg>
|
|
</div>
|
|
<p class="say">En portefølje er mange uavhengige prosjekter, hvert med sitt budsjett og sine kostlinjer. Erfaringen er at flere av dem rommer tiltak — en utskifting, en smartere styring, en annen metode — som ville spart penger uten å true det prosjektet skal levere.</p>
|
|
<p class="say dim">Besparelsene står ikke i noen rapport. De må letes fram, kostlinje for kostlinje — og det er letingen som er dyr, ikke tiltakene.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ============ 3 · HVORFOR DE IKKE HENTES ============ -->
|
|
<section class="slide" data-part="Problemet">
|
|
<div class="inner">
|
|
<div class="kicker">Problemet</div>
|
|
<h2>Å lete koster tid, folk og fagkompetanse — per prosjekt</h2>
|
|
<div class="fig">
|
|
<svg viewBox="0 0 900 156" role="img" aria-label="Én fagperson mot en lang rekke prosjekter som blekner bortover">
|
|
<circle cx="60" cy="34" r="13" fill="none" stroke="var(--ink)" stroke-width="2"/>
|
|
<path d="M60 47 V84 M60 58 L40 72 M60 58 L80 72 M60 84 L46 112 M60 84 L74 112" fill="none" stroke="var(--ink)" stroke-width="2" stroke-linecap="round"/>
|
|
<text class="svg-muted" x="60" y="140" font-size="12.5" text-anchor="middle">én fagperson</text>
|
|
<g opacity="1"><rect class="svg-box" x="150" y="22" width="72" height="64" rx="3"/></g>
|
|
<g opacity="0.92"><rect class="svg-box" x="232" y="22" width="72" height="64" rx="3"/></g>
|
|
<g opacity="0.84"><rect class="svg-box" x="314" y="22" width="72" height="64" rx="3"/></g>
|
|
<g opacity="0.76"><rect class="svg-box" x="396" y="22" width="72" height="64" rx="3"/></g>
|
|
<g opacity="0.68"><rect class="svg-box" x="478" y="22" width="72" height="64" rx="3"/></g>
|
|
<g opacity="0.6"><rect class="svg-box" x="560" y="22" width="72" height="64" rx="3"/></g>
|
|
<g opacity="0.52"><rect class="svg-box" x="642" y="22" width="72" height="64" rx="3"/></g>
|
|
<g opacity="0.44"><rect class="svg-box" x="724" y="22" width="72" height="64" rx="3"/></g>
|
|
<g opacity="0.36"><rect class="svg-box" x="806" y="22" width="72" height="64" rx="3"/></g>
|
|
<path class="svg-line" d="M150 98 v6 H878 v-6"/>
|
|
<text class="svg-muted" x="514" y="126" font-size="13" text-anchor="middle">dager med lesing og regning — per prosjekt</text>
|
|
</svg>
|
|
</div>
|
|
<p class="say">Den som skal finne et slikt tiltak, må lese prosjektgrunnlaget, kjenne tiltakstypene og regne på tallene. Det er dager med arbeid for hvert eneste prosjekt — og det krever folk som allerede er opptatt med å levere.</p>
|
|
<p class="say dim">De fleste leter allerede. Det som mangler er ikke vilje, men en leting som skalerer — over hele porteføljen, igjen og igjen.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ============ 4 · HVORFOR KI ALENE IKKE LØSER DET ============ -->
|
|
<section class="slide" data-part="Problemet">
|
|
<div class="inner">
|
|
<div class="kicker">Problemet</div>
|
|
<h2>En språkmodell gir deg gjerne et pent tall ingen har regnet på</h2>
|
|
<div class="fig">
|
|
<svg viewBox="0 0 900 184" role="img" aria-label="Et pent notat med et stort beløp, og to ubesvarte spørsmål som peker på det">
|
|
<rect class="svg-box" x="330" y="10" width="240" height="150" rx="4"/>
|
|
<rect x="352" y="30" width="180" height="8" rx="2" fill="var(--line)"/>
|
|
<rect x="352" y="46" width="196" height="8" rx="2" fill="var(--line)"/>
|
|
<rect x="352" y="62" width="150" height="8" rx="2" fill="var(--line)"/>
|
|
<text class="svg-ink" x="450" y="112" font-size="24" font-weight="700" text-anchor="middle">«Spar 2,1 mill.»</text>
|
|
<text class="svg-muted" x="450" y="138" font-size="11.5" text-anchor="middle">grunnlag: ikke vedlagt</text>
|
|
<text class="svg-muted" x="6" y="66" font-size="13">Hvilke kostlinjer hviler det på?</text>
|
|
<path class="svg-line" d="M 214 62 H 320" marker-end="url(#m4)"/>
|
|
<text class="svg-muted" x="894" y="118" font-size="13" text-anchor="end">Er beløpet i det hele tatt oppnåelig?</text>
|
|
<path class="svg-line" d="M 646 114 H 580" marker-end="url(#m4)"/>
|
|
<text class="svg-accent" x="450" y="180" font-size="13" font-weight="650" text-anchor="middle">et overbevisende notat er en påstand — ikke en besparelse</text>
|
|
<defs><marker id="m4" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0 0 L8 4 L0 8 z" class="svg-muted"/></marker></defs>
|
|
</svg>
|
|
</div>
|
|
<p class="say">KI-modeller leser fort og skriver overbevisende — det er nettopp problemet. Et velskrevet notat som lover «spar 2,1 millioner», er ikke en besparelse; det er en påstand. Skal funn brukes i beslutninger, må hvert tall kunne etterprøves.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ============ 5 · GREPET ============ -->
|
|
<section class="slide" data-part="Grepet">
|
|
<div class="inner">
|
|
<div class="kicker">Grepet</div>
|
|
<h2>Maskinen får foreslå — aldri godkjenne seg selv</h2>
|
|
<div class="fig">
|
|
<svg viewBox="0 0 900 230" role="img" aria-label="Forslaget går til to uavhengige kontroller før det når fagpersonen">
|
|
<rect class="svg-box" x="6" y="86" width="170" height="64" rx="3"/>
|
|
<text class="svg-ink" x="91" y="112" font-size="15" font-weight="700" text-anchor="middle">Forslaget</text>
|
|
<text class="svg-muted" x="91" y="132" font-size="12" text-anchor="middle">fra KI-debatten</text>
|
|
<path class="svg-line" d="M176 104 C 220 96 230 70 274 64" marker-end="url(#m5)"/>
|
|
<path class="svg-line" d="M176 132 C 220 140 230 172 274 178" marker-end="url(#m5)"/>
|
|
<rect x="280" y="20" width="330" height="88" rx="3" fill="var(--warn-bg)" stroke="var(--accent)" stroke-width="2.5"/>
|
|
<text x="445" y="46" font-size="15" font-weight="700" text-anchor="middle" fill="var(--warn-fg)">Regnekoden — blokkerer</text>
|
|
<text x="445" y="68" font-size="12" text-anchor="middle" fill="var(--warn-fg)">avstemmer kostlinjene mot prosjektets faktiske tall</text>
|
|
<text x="445" y="88" font-size="12" text-anchor="middle" fill="var(--warn-fg)">beregner taket for hva som er oppnåelig</text>
|
|
<rect class="svg-box" x="280" y="140" width="330" height="76" rx="3"/>
|
|
<text class="svg-ink" x="445" y="168" font-size="15" font-weight="700" text-anchor="middle">Utfordreren</text>
|
|
<text class="svg-muted" x="445" y="190" font-size="12" text-anchor="middle">en KI-rolle med motsatt oppdrag: angripe begrunnelsen</text>
|
|
<path class="svg-line" d="M612 64 C 660 64 672 100 700 112" marker-end="url(#m5)"/>
|
|
<path class="svg-line" d="M612 178 C 660 178 672 142 700 136" marker-end="url(#m5)"/>
|
|
<rect x="706" y="92" width="188" height="64" rx="3" fill="var(--ok-bg)" stroke="var(--ok-fg)" stroke-width="2.5"/>
|
|
<text x="800" y="114" font-size="15" font-weight="700" text-anchor="middle" fill="var(--ok-fg)">Fagpersonen</text>
|
|
<text x="800" y="132" font-size="11.5" text-anchor="middle" fill="var(--ok-fg)">ser bare det som</text>
|
|
<text x="800" y="147" font-size="11.5" text-anchor="middle" fill="var(--ok-fg)">overlevde begge</text>
|
|
<defs><marker id="m5" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0 0 L8 4 L0 8 z" class="svg-muted"/></marker></defs>
|
|
</svg>
|
|
</div>
|
|
<p class="say">Hvert forslag må overleve to uavhengige kontroller: en <strong>deterministisk regnekode</strong> som ikke kan overtales, og en <strong>utfordrer</strong> som angriper resonnementet.</p>
|
|
<p class="say dim">I eksempelkjøringen virker det slik: påstanden på 2 100 000 kr ble avvist fordi taket var 1 769 915 kr. Det korrigerte forslaget — 445 500 kr — slapp gjennom. Avvisningen er ikke en feil; den er systemet som virker.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ============ 6 · KUNNSKAPSBASEN ============ -->
|
|
<section class="slide" data-part="Slik virker det">
|
|
<div class="inner">
|
|
<div class="kicker">Slik virker det</div>
|
|
<h2>Grunnlaget er en kunnskapsbase fagfolk kan lese og rette</h2>
|
|
<div class="fig">
|
|
<svg viewBox="0 0 900 236" role="img" aria-label="En innholdsfortegnelse peker til fem dokumenter som også lenker til hverandre">
|
|
<rect class="svg-box-hi" x="6" y="80" width="150" height="70" rx="3"/>
|
|
<text class="svg-ink" x="81" y="108" font-size="14" font-weight="650" text-anchor="middle">Inngangen</text>
|
|
<text class="svg-muted" x="81" y="126" font-size="11" text-anchor="middle">innholdsfortegnelsen</text>
|
|
<rect class="svg-box" x="220" y="14" width="190" height="62" rx="3"/>
|
|
<text class="svg-ink" x="315" y="40" font-size="13.5" font-weight="650" text-anchor="middle">Prosjektet</text>
|
|
<text class="svg-muted" x="315" y="58" font-size="11.5" text-anchor="middle">kostlinjer og rammer</text>
|
|
<rect class="svg-box" x="440" y="14" width="190" height="62" rx="3"/>
|
|
<text class="svg-ink" x="535" y="40" font-size="13.5" font-weight="650" text-anchor="middle">Tiltakstypene</text>
|
|
<text class="svg-muted" x="535" y="58" font-size="11.5" text-anchor="middle">hva som pleier å virke</text>
|
|
<rect class="svg-box" x="660" y="14" width="190" height="62" rx="3"/>
|
|
<text class="svg-ink" x="755" y="40" font-size="13.5" font-weight="650" text-anchor="middle">Erfaringstall</text>
|
|
<text class="svg-muted" x="755" y="58" font-size="11.5" text-anchor="middle">tidligere dommer</text>
|
|
<rect class="svg-box" x="330" y="150" width="190" height="62" rx="3"/>
|
|
<text class="svg-ink" x="425" y="176" font-size="13.5" font-weight="650" text-anchor="middle">Fagkilder</text>
|
|
<text class="svg-muted" x="425" y="194" font-size="11.5" text-anchor="middle">håndbøker og normtall</text>
|
|
<rect class="svg-box" x="550" y="150" width="190" height="62" rx="3"/>
|
|
<text class="svg-ink" x="645" y="176" font-size="13.5" font-weight="650" text-anchor="middle">Metoden</text>
|
|
<text class="svg-muted" x="645" y="194" font-size="11.5" text-anchor="middle">hvordan det regnes</text>
|
|
<path class="svg-line" d="M156 96 C 180 88 195 55 216 45" marker-end="url(#m6)"/>
|
|
<path class="svg-line" d="M156 104 C 280 92 380 58 436 46" marker-end="url(#m6)"/>
|
|
<path class="svg-line" d="M156 110 C 340 108 550 66 656 50" marker-end="url(#m6)"/>
|
|
<path class="svg-line" d="M156 122 C 220 140 270 168 326 178" marker-end="url(#m6)"/>
|
|
<path class="svg-line" d="M156 128 C 300 168 440 190 546 188" marker-end="url(#m6)"/>
|
|
<path class="svg-line" d="M412 45 H 436" stroke-dasharray="5 4"/>
|
|
<path class="svg-line" d="M632 45 H 656" stroke-dasharray="5 4"/>
|
|
<path class="svg-line" d="M535 78 C 510 110 470 122 445 148" stroke-dasharray="5 4"/>
|
|
<path class="svg-line" d="M755 78 C 730 112 690 124 662 148" stroke-dasharray="5 4"/>
|
|
<text class="svg-muted" x="450" y="232" font-size="12.5" text-anchor="middle">fem dokumenter i eksempelet — alle i klartekst, alle mulige å rette</text>
|
|
<defs><marker id="m6" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0 0 L8 4 L0 8 z" class="svg-muted"/></marker></defs>
|
|
</svg>
|
|
</div>
|
|
<p class="say">Maskinen graver ikke i løse dokumenthauger. Den navigerer en <strong>kunnskapsbase</strong> — en wiki av korte tekstdokumenter som lenker til hverandre. I eksempelet er det fem; i et virkelig prosjekt kan det være hundrevis.</p>
|
|
<p class="say dim">Alt maskinen bygger på, står i klartekst. En fagperson kan åpne basen, se nøyaktig hva systemet «vet» — og rette det som er feil. Grunnlaget er ditt, ikke modellens.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ============ 7 · ARKITEKTUREN ============ -->
|
|
<section class="slide" data-part="Slik virker det">
|
|
<div class="inner">
|
|
<div class="kicker">Slik virker det</div>
|
|
<h2>Fire lag — og bare det godkjente går tilbake</h2>
|
|
<div class="fig">
|
|
<svg viewBox="0 0 900 252" role="img" aria-label="Fire lag fra grunnlag til dom, med en returpil for godkjent kunnskap">
|
|
<rect x="40" y="10" width="700" height="48" rx="3" fill="var(--surface-2)" stroke="var(--line)" stroke-width="1.5"/>
|
|
<text class="svg-ink" x="58" y="40" font-size="14.5" font-weight="650">1 · Grunnlaget</text>
|
|
<text class="svg-muted" x="724" y="40" font-size="12" text-anchor="end">kunnskapsbasen — dokumentene fagfolk eier</text>
|
|
<rect class="svg-box" x="40" y="72" width="700" height="48" rx="3"/>
|
|
<text class="svg-ink" x="58" y="102" font-size="14.5" font-weight="650">2 · Forslaget</text>
|
|
<text class="svg-muted" x="724" y="102" font-size="12" text-anchor="end">KI-modeller foreslår og utfordrer hverandre</text>
|
|
<rect x="40" y="134" width="700" height="48" rx="3" fill="var(--warn-bg)" stroke="var(--accent)" stroke-width="2"/>
|
|
<text x="58" y="164" font-size="14.5" font-weight="650" fill="var(--warn-fg)">3 · Kontrollen</text>
|
|
<text x="724" y="164" font-size="12" text-anchor="end" fill="var(--warn-fg)">regnekoden blokkerer alt den ikke kan bekrefte</text>
|
|
<rect x="40" y="196" width="700" height="48" rx="3" fill="var(--ok-bg)" stroke="var(--ok-fg)" stroke-width="2"/>
|
|
<text x="58" y="226" font-size="14.5" font-weight="650" fill="var(--ok-fg)">4 · Dommen</text>
|
|
<text x="724" y="226" font-size="12" text-anchor="end" fill="var(--ok-fg)">fagpersonen dømmer det som står igjen</text>
|
|
<path class="svg-line" d="M390 58 V 66" marker-end="url(#m7)"/>
|
|
<path class="svg-line" d="M390 120 V 128" marker-end="url(#m7)"/>
|
|
<path class="svg-line" d="M390 182 V 190" marker-end="url(#m7)"/>
|
|
<path class="svg-line-hi" d="M 744 220 H 806 Q 826 220 826 200 V 54 Q 826 34 806 34 H 750" marker-end="url(#m7a)"/>
|
|
<text class="svg-accent" x="838" y="118" font-size="12" font-weight="650">godkjent</text>
|
|
<text class="svg-accent" x="838" y="134" font-size="12" font-weight="650">kunnskap</text>
|
|
<text class="svg-accent" x="838" y="150" font-size="12" font-weight="650">tilbake</text>
|
|
<defs>
|
|
<marker id="m7" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0 0 L8 4 L0 8 z" class="svg-muted"/></marker>
|
|
<marker id="m7a" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0 0 L8 4 L0 8 z" class="svg-accent"/></marker>
|
|
</defs>
|
|
</svg>
|
|
</div>
|
|
<p class="say">Grunnlaget mater forslagsarbeidet. Kontrollaget feller alt som ikke tåler etterregning. Fagpersonen dømmer det som står igjen. Og returpilen er poenget: en godkjent dom skrives tilbake i kunnskapsbasen, så neste kjøring starter klokere enn den forrige.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ============ 8 · DE ÅTTE STEGENE ============ -->
|
|
<section class="slide" data-part="Slik virker det">
|
|
<div class="inner">
|
|
<div class="kicker">Slik virker det</div>
|
|
<h2>Arbeidsprosessen: åtte steg, med menneskene i begge ender</h2>
|
|
<div class="fig">
|
|
<svg viewBox="0 0 900 268" role="img" aria-label="Åtte steg på rad, med bånd som viser hvem som utfører hvert steg">
|
|
<rect x="6" y="14" width="328" height="34" rx="3" fill="var(--surface-2)" stroke="var(--line)" stroke-width="1.5"/>
|
|
<text class="svg-muted" x="170" y="36" font-size="14" font-weight="650" text-anchor="middle">KI-modellene arbeider</text>
|
|
<rect x="342" y="14" width="104" height="34" rx="3" fill="var(--warn-bg)" stroke="var(--accent)" stroke-width="2"/>
|
|
<text x="394" y="36" font-size="14" font-weight="650" text-anchor="middle" fill="var(--warn-fg)">Regnekoden</text>
|
|
<rect x="454" y="14" width="216" height="34" rx="3" fill="var(--surface-2)" stroke="var(--line)" stroke-width="1.5"/>
|
|
<text class="svg-muted" x="562" y="36" font-size="14" font-weight="650" text-anchor="middle">KI + regnekode</text>
|
|
<rect x="678" y="14" width="216" height="34" rx="3" fill="var(--ok-bg)" stroke="var(--ok-fg)" stroke-width="2"/>
|
|
<text x="786" y="36" font-size="14" font-weight="650" text-anchor="middle" fill="var(--ok-fg)">Fagpersonen</text>
|
|
<g font-size="13">
|
|
<rect class="svg-box" x="6" y="70" width="104" height="76" rx="3"/>
|
|
<text class="svg-accent" x="58" y="96" font-size="19" font-weight="700" text-anchor="middle">1</text>
|
|
<text class="svg-muted" x="58" y="122" text-anchor="middle">Les</text>
|
|
<text class="svg-muted" x="58" y="138" text-anchor="middle">grunnlaget</text>
|
|
<rect class="svg-box" x="118" y="70" width="104" height="76" rx="3"/>
|
|
<text class="svg-accent" x="170" y="96" font-size="19" font-weight="700" text-anchor="middle">2</text>
|
|
<text class="svg-muted" x="170" y="122" text-anchor="middle">Foreslå</text>
|
|
<text class="svg-muted" x="170" y="138" text-anchor="middle">tiltak</text>
|
|
<rect class="svg-box" x="230" y="70" width="104" height="76" rx="3"/>
|
|
<text class="svg-accent" x="282" y="96" font-size="19" font-weight="700" text-anchor="middle">3</text>
|
|
<text class="svg-muted" x="282" y="122" text-anchor="middle">Utfordre</text>
|
|
<text class="svg-muted" x="282" y="138" text-anchor="middle">begrunnelsen</text>
|
|
<rect x="342" y="70" width="104" height="76" rx="3" fill="var(--warn-bg)" stroke="var(--accent)" stroke-width="2.5"/>
|
|
<text x="394" y="96" font-size="19" font-weight="700" text-anchor="middle" fill="var(--warn-fg)">4</text>
|
|
<text x="394" y="122" text-anchor="middle" fill="var(--warn-fg)">Regn etter</text>
|
|
<text x="394" y="138" text-anchor="middle" fill="var(--warn-fg)">— blokkerer</text>
|
|
<rect class="svg-box" x="454" y="70" width="104" height="76" rx="3"/>
|
|
<text class="svg-accent" x="506" y="96" font-size="19" font-weight="700" text-anchor="middle">5</text>
|
|
<text class="svg-muted" x="506" y="122" text-anchor="middle">Forbedre</text>
|
|
<text class="svg-muted" x="506" y="138" text-anchor="middle">og prøv igjen</text>
|
|
<rect class="svg-box" x="566" y="70" width="104" height="76" rx="3"/>
|
|
<text class="svg-accent" x="618" y="96" font-size="19" font-weight="700" text-anchor="middle">6</text>
|
|
<text class="svg-muted" x="618" y="122" text-anchor="middle">Lever</text>
|
|
<text class="svg-muted" x="618" y="138" text-anchor="middle">utfallet</text>
|
|
<rect x="678" y="70" width="104" height="76" rx="3" fill="var(--ok-bg)" stroke="var(--ok-fg)" stroke-width="2.5"/>
|
|
<text x="730" y="96" font-size="19" font-weight="700" text-anchor="middle" fill="var(--ok-fg)">7</text>
|
|
<text x="730" y="122" text-anchor="middle" fill="var(--ok-fg)">Døm</text>
|
|
<text x="730" y="138" text-anchor="middle" fill="var(--ok-fg)">resultatet</text>
|
|
<rect x="790" y="70" width="104" height="76" rx="3" fill="var(--ok-bg)" stroke="var(--ok-fg)" stroke-width="2.5"/>
|
|
<text x="842" y="96" font-size="19" font-weight="700" text-anchor="middle" fill="var(--ok-fg)">8</text>
|
|
<text x="842" y="122" text-anchor="middle" fill="var(--ok-fg)">Lagre det</text>
|
|
<text x="842" y="138" text-anchor="middle" fill="var(--ok-fg)">godkjente</text>
|
|
</g>
|
|
<path class="svg-line-hi" d="M506 152 V 176 Q 506 192 486 192 H 190 Q 170 192 170 176 V 152" marker-end="url(#m8)"/>
|
|
<text class="svg-accent" x="338" y="212" font-size="13" font-weight="650" text-anchor="middle">avvisningen sendes tilbake — begrenset antall forsøk</text>
|
|
<path class="svg-line-hi" d="M842 152 V 232 Q 842 250 820 250 H 80 Q 58 250 58 232 V 152" marker-end="url(#m8)"/>
|
|
<text class="svg-accent" x="450" y="266" font-size="13" font-weight="650" text-anchor="middle">det fagpersonen godkjente blir grunnlag for neste kjøring</text>
|
|
<defs><marker id="m8" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0 0 L8 4 L0 8 z" class="svg-accent"/></marker></defs>
|
|
</svg>
|
|
</div>
|
|
<p class="say">Grønt er der fagfolkene står. Gult er regnekoden som eier tallene. KI-modellene gjør lese- og skrivearbeidet imellom — og de to pilene tilbake er de eneste veiene noe går i retur.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ============ 9 · MENNESKENE ============ -->
|
|
<section class="slide" data-part="Menneskene">
|
|
<div class="inner">
|
|
<div class="kicker">Menneskene</div>
|
|
<h2>Dommen din blir systemets hukommelse</h2>
|
|
<div class="fig">
|
|
<svg viewBox="0 0 900 212" role="img" aria-label="En port slipper godkjente dommer inn i kunnskapsbasen og stopper rå maskinoutput">
|
|
<rect x="6" y="28" width="250" height="56" rx="3" fill="var(--ok-bg)" stroke="var(--ok-fg)" stroke-width="2"/>
|
|
<text x="131" y="52" font-size="14" font-weight="650" text-anchor="middle" fill="var(--ok-fg)">Dommen din — godkjent</text>
|
|
<text x="131" y="70" font-size="11.5" text-anchor="middle" fill="var(--ok-fg)">med begrunnelse, sporbar</text>
|
|
<rect x="6" y="124" width="250" height="56" rx="3" fill="var(--bad-bg)" stroke="var(--bad-fg)" stroke-width="2"/>
|
|
<text x="131" y="148" font-size="14" font-weight="650" text-anchor="middle" fill="var(--bad-fg)">Rå maskinoutput</text>
|
|
<text x="131" y="166" font-size="11.5" text-anchor="middle" fill="var(--bad-fg)">forslag ingen har dømt</text>
|
|
<rect x="452" y="16" width="8" height="58" fill="var(--surface-2)" stroke="var(--accent)" stroke-width="1.5"/>
|
|
<rect x="452" y="104" width="8" height="88" fill="var(--surface-2)" stroke="var(--accent)" stroke-width="1.5"/>
|
|
<path class="svg-line-hi" d="M258 56 C 360 58 400 86 468 88 H 634" marker-end="url(#m9)"/>
|
|
<path class="svg-line" d="M258 152 H 434" marker-end="url(#m9m)"/>
|
|
<path d="M441 144 l14 16 M455 144 l-14 16" stroke="var(--bad-fg)" stroke-width="2.5" fill="none"/>
|
|
<rect class="svg-box-hi" x="644" y="60" width="250" height="58" rx="3"/>
|
|
<text class="svg-ink" x="769" y="84" font-size="14.5" font-weight="650" text-anchor="middle">Kunnskapsbasen</text>
|
|
<text class="svg-muted" x="769" y="102" font-size="12" text-anchor="middle">neste kjøring starter her</text>
|
|
<text class="svg-muted" x="450" y="208" font-size="12.5" text-anchor="middle">porten er lukket som utgangspunkt — det som ikke er dømt, kommer ikke inn</text>
|
|
<defs>
|
|
<marker id="m9" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0 0 L8 4 L0 8 z" class="svg-accent"/></marker>
|
|
<marker id="m9m" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0 0 L8 4 L0 8 z" class="svg-muted"/></marker>
|
|
</defs>
|
|
</svg>
|
|
</div>
|
|
<p class="say">Når du godkjenner eller avviser et utfall, forsvinner ikke vurderingen i et referat. En port skriver den inn i kunnskapsbasen — og porten er lukket for alt annet: rå maskinoutput slipper aldri inn.</p>
|
|
<p class="say dim">I eksempelkjøringen: første kjøring hentet 0 tidligere dommer for kandidaten. Etter én godkjenning og ett driftsnotat i innboksen hentet neste kjøring 3 — og begge de målte realiseringsgradene (0,79 og 0,66) var på plass i dens hypotesegrunnlag.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ============ 10 · VERDIEN ============ -->
|
|
<section class="slide" data-part="Verdien">
|
|
<div class="inner">
|
|
<div class="kicker">Verdien</div>
|
|
<h2>Hva det gir, i størrelsesorden</h2>
|
|
<div class="fig">
|
|
<svg viewBox="0 0 900 212" role="img" aria-label="Fire søyler: kostlinja, den avviste påstanden, det beregnede taket og den validerte besparelsen">
|
|
<text class="svg-muted" x="250" y="30" font-size="13" text-anchor="end">kostlinja tiltaket rører</text>
|
|
<rect x="260" y="8" width="560" height="34" fill="var(--surface-2)" stroke="var(--line)" stroke-width="1.5"/>
|
|
<text class="svg-ink" x="812" y="30" font-size="13" font-weight="650" text-anchor="end">4 386 150 kr</text>
|
|
<text class="svg-muted" x="250" y="80" font-size="13" text-anchor="end">først påstått — avvist</text>
|
|
<rect x="260" y="58" width="268" height="34" fill="var(--bad-bg)" stroke="var(--bad-fg)" stroke-width="1.5"/>
|
|
<text x="536" y="80" font-size="13" font-weight="650" fill="var(--bad-fg)">2 100 000 kr</text>
|
|
<text class="svg-muted" x="250" y="130" font-size="13" text-anchor="end">taket regnekoden fant</text>
|
|
<rect x="260" y="108" width="226" height="34" fill="var(--warn-bg)" stroke="var(--accent)" stroke-width="1.5"/>
|
|
<text x="494" y="130" font-size="13" font-weight="650" fill="var(--warn-fg)">1 769 915 kr</text>
|
|
<text class="svg-muted" x="250" y="180" font-size="13" text-anchor="end">validert besparelse</text>
|
|
<rect x="260" y="158" width="57" height="34" fill="var(--ok-bg)" stroke="var(--ok-fg)" stroke-width="1.5"/>
|
|
<text x="325" y="180" font-size="13" font-weight="650" fill="var(--ok-fg)">445 500 kr — 10,2 % av linja</text>
|
|
<text class="svg-muted" x="450" y="208" font-size="12.5" text-anchor="middle">tallene er fra eksempelkjøringen — utskriften er byte-låst fasit i repoet</text>
|
|
</svg>
|
|
</div>
|
|
<p class="say">Dette er <strong>ett</strong> prosjekt og <strong>én</strong> kostlinje. Verdien av rammeverket er ikke ett enkelt tall, men tre egenskaper: letingen blir nesten gratis per prosjekt, bare etterprøvbare tall når fram til beslutning, og hver dom gjør neste leting bedre.</p>
|
|
<p class="say dim">Størrelsesorden, ikke løfte: hva din portefølje rommer, vet ingen før letingen er gjort. Det nye er at selve letingen er blitt billig.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ============ 11 · ÆRLIG STATUS ============ -->
|
|
<section class="slide" data-part="Ærlig status">
|
|
<div class="inner">
|
|
<div class="kicker">Ærlig status</div>
|
|
<h2>Hva som er bevist — og hva som ikke er</h2>
|
|
<div class="cards">
|
|
<div class="card good">
|
|
<span class="t">Bevist — målt, ikke ment</span>
|
|
<ul class="plist">
|
|
<li>Hele sløyfa kjører ende til ende offline, og læringen når fram på begge tidsskalaer. Utskriften er byte-låst som fasit i repoet.</li>
|
|
<li>Regneporten feller reelt: 2 100 000-påstanden avvises og 445 500 valideres — i hver kjøring, hver gang.</li>
|
|
<li>846 automatiske tester grønne (4 hoppes over), målt 14. august 2026.</li>
|
|
<li>Installasjonen er målt, ikke antatt: dokumentert kommando, 65 pakker, exit 0.</li>
|
|
</ul>
|
|
</div>
|
|
<div class="card risk">
|
|
<span class="t">Ikke bevist</span>
|
|
<ul class="plist">
|
|
<li>Rammeverket har <strong>aldri kjørt mot en levende språkmodell</strong>. Hvert forslag og hver dom til nå er skriptede stand-ins — demoen sier det selv, øverst i hver kjøring.</li>
|
|
<li>Om en ekte modell foreslår godt og dømmer klokt, er et åpent spørsmål. Ingen målt gevinst fra en virkelig portefølje ennå.</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<p class="say dim" style="margin-top:18px">Det som mangler, er nøyaktig det en første pilot finnes for å måle. Grunnmuren er bygget for at den målingen skal kunne stoles på.</p>
|
|
<p class="foot-note">Kjøringstallene i denne presentasjonen er byte-låst fasit: <code>tests/golden/demo-transcript.stdout</code>.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<div class="bar-ui">
|
|
<span>← → for å bla · F for fullskjerm</span>
|
|
<span class="where" id="where"></span>
|
|
<span class="nav"><button class="btn" id="prev">◀</button><span class="counter" id="count"></span><button class="btn" id="next">▶</button></span>
|
|
</div>
|
|
|
|
<script>
|
|
(function () {
|
|
var slides = Array.prototype.slice.call(document.querySelectorAll('.slide'));
|
|
var i = 0;
|
|
var count = document.getElementById('count');
|
|
var where = document.getElementById('where');
|
|
var prog = document.getElementById('prog');
|
|
|
|
function show(n) {
|
|
i = Math.max(0, Math.min(slides.length - 1, n));
|
|
slides.forEach(function (s, k) { s.classList.toggle('active', k === i); });
|
|
count.textContent = (i + 1) + ' / ' + slides.length;
|
|
where.textContent = slides[i].getAttribute('data-part') || '';
|
|
prog.style.width = ((i + 1) / slides.length * 100) + '%';
|
|
try { location.hash = String(i + 1); } catch (e) {}
|
|
}
|
|
function go(d) { show(i + d); }
|
|
|
|
document.addEventListener('keydown', function (e) {
|
|
var k = e.key;
|
|
if (k === 'ArrowRight' || k === 'ArrowDown' || k === 'PageDown' || k === ' ' || k === 'Enter') { go(1); e.preventDefault(); }
|
|
else if (k === 'ArrowLeft' || k === 'ArrowUp' || k === 'PageUp' || k === 'Backspace') { go(-1); e.preventDefault(); }
|
|
else if (k === 'Home') { show(0); e.preventDefault(); }
|
|
else if (k === 'End') { show(slides.length - 1); e.preventDefault(); }
|
|
else if (k === 'f' || k === 'F') {
|
|
if (document.fullscreenElement) { document.exitFullscreen(); }
|
|
else if (document.documentElement.requestFullscreen) { document.documentElement.requestFullscreen(); }
|
|
e.preventDefault();
|
|
}
|
|
});
|
|
|
|
document.getElementById('next').addEventListener('click', function () { go(1); });
|
|
document.getElementById('prev').addEventListener('click', function () { go(-1); });
|
|
|
|
var start = null;
|
|
document.addEventListener('touchstart', function (e) { start = e.changedTouches[0].clientX; }, {passive: true});
|
|
document.addEventListener('touchend', function (e) {
|
|
if (start === null) return;
|
|
var dx = e.changedTouches[0].clientX - start;
|
|
if (Math.abs(dx) > 55) { go(dx < 0 ? 1 : -1); }
|
|
start = null;
|
|
}, {passive: true});
|
|
|
|
var h = parseInt((location.hash || '').replace('#', ''), 10);
|
|
show(isNaN(h) ? 0 : h - 1);
|
|
})();
|
|
</script>
|