Set-OPS-Public/promo/valeur.html
Daniel Allaire 131a30075d Aurore : opacites reduites ; etat de forge-01 elucide
Palette (promo/, les 4 pages) — les teintes rose, verte et violette etaient
trop presentes une fois etalees au tour precedent. Reduction d'environ 40 % :
rose .075 -> .044, vert .058 -> .034, violet .062 -> .036, arrets
intermediaires abaisses dans la meme proportion, opacite de la nappe .aurora
.44 -> .32. Geometrie inchangee : meme largeur, meme position, seule
l'intensite baisse. 0 conflit CSS entre les quatre pages.

forge-01 — la note precedente presentait comme une contradiction a trancher
le fait que le plan dise `etat: planifie` et que le CHANGELOG du 2026-07-03
dise le branding « prouve sur forge-01 ». Ce n'en etait pas une : l'hote a ete
cree, puis supprime. Le plan decrit l'etat COURANT, le CHANGELOG un etat PASSE
— les deux disent vrai. La preuve reste valable, simplement non rejouable tant
que l'hote n'est pas recree. roles/serveur_forgejo/README.md corrige.

Valide : equilibre accolades/parentheses du CSS, 0 conflit CSS,
prouver.py --verifier -> CONFORME 16/16.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 11:57:50 -04:00

748 lines
37 KiB
HTML

<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Set-OPS — La valeur · Chezlepro</title>
<meta name="description" content="Ce que Set-OPS remplace, ce qu'il coûte, ce qu'il prouve. Calculateur de coût total, tableau des équivalences SaaS, registre d'affirmations vérifiables. Infrastructure numérique souveraine sur votre propre matériel.">
<meta name="color-scheme" content="dark">
</head>
<body>
<style>
:root{
--night:#05060f; --night-2:#0a0d24; --night-3:#0e1640;
--ink:#e9ecff; --dim:#99a1c9; --dim-2:#727aa6;
--line:rgba(255,255,255,.10); --line-2:rgba(255,255,255,.06);
--panel:rgba(255,255,255,.045); --panel-2:rgba(255,255,255,.03);
--teal:#4fe3c1; --cyan:#56c2ff; --violet:#a98bff; --amber:#ffc46b;
--rose:#ff6fc4; --vert:#5cff9d; /* frange magenta + vert fluo de l'aurore */
--aurora:linear-gradient(100deg,var(--teal) 0%,var(--cyan) 46%,var(--violet) 100%);
--sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Noto Sans","Helvetica Neue",Arial,sans-serif;
--mono:ui-monospace,"SF Mono","JetBrains Mono",Menlo,Consolas,"Liberation Mono",monospace;
--wrap:1140px;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
margin:0; font-family:var(--sans); color:var(--ink); line-height:1.6;
background:
radial-gradient(1200px 760px at 82% -8%,#141c4c 0%,transparent 58%),
radial-gradient(900px 620px at 8% -2%,#0e1640 0%,transparent 55%),
radial-gradient(1500px 1020px at 76% 28%,rgba(255,111,196,.044) 0%,rgba(255,111,196,.021) 44%,transparent 82%),
radial-gradient(1620px 1120px at 20% 64%,rgba(92,255,157,.034) 0%,rgba(92,255,157,.016) 46%,transparent 84%),
radial-gradient(1400px 960px at 52% 106%,rgba(169,139,255,.036) 0%,rgba(169,139,255,.017) 44%,transparent 80%),
linear-gradient(180deg,var(--night-2) 0%,var(--night) 62%) fixed;
-webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
overflow-x:hidden;
}
#sky{position:fixed;inset:0;z-index:-2;pointer-events:none}
#sky canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.aurora{
position:fixed;left:-10%;right:-10%;top:-22%;height:74vh;z-index:-1;pointer-events:none;
filter:blur(86px) saturate(140%);opacity:.32;
background:
radial-gradient(60% 80% at 22% 50%,var(--vert) 0%,transparent 78%),
radial-gradient(40% 60% at 20% 30%,var(--teal) 0%,transparent 70%),
radial-gradient(45% 70% at 55% 20%,var(--cyan) 0%,transparent 70%),
radial-gradient(40% 65% at 82% 35%,var(--violet) 0%,transparent 70%),
radial-gradient(58% 78% at 79% 57%,var(--rose) 0%,transparent 78%);
animation:drift 24s ease-in-out infinite alternate;
}
@keyframes drift{from{transform:translate(-3%,0) scale(1)}to{transform:translate(3%,2%) scale(1.08)}}
.wrap{max-width:var(--wrap);margin-inline:auto;padding-inline:24px}
header.nav{position:sticky;top:0;z-index:20;backdrop-filter:blur(12px);
background:linear-gradient(180deg,rgba(5,6,15,.72),rgba(5,6,15,.28));
border-bottom:1px solid var(--line-2)}
.nav .wrap{display:flex;align-items:center;gap:20px;height:64px}
.brand{display:flex;align-items:center;gap:11px;font-weight:650;letter-spacing:.2px;text-decoration:none;color:var(--ink)}
.brand svg{width:30px;height:30px;flex:none}
.brand b{font-weight:750}
.nav nav{margin-left:auto;display:flex;gap:24px;align-items:center}
.nav nav a{color:var(--dim);text-decoration:none;font-size:.94rem;font-weight:500}
.nav nav a:hover{color:var(--ink)}
.nav nav a[aria-current="page"]{color:var(--ink);font-weight:640}
.nav nav a[aria-current="page"]::after{content:"";display:block;height:2px;border-radius:2px;background:var(--aurora);margin-top:3px}
.nav .cta-mini{padding:8px 16px;border-radius:999px;background:var(--aurora);color:#04121a;font-weight:700;font-size:.9rem}
.nav .cta-mini:hover{color:#04121a;filter:brightness(1.08)}
@media(max-width:860px){.nav nav a:not(.cta-mini){display:none}}
.eyebrow{font-family:var(--mono);font-size:.76rem;letter-spacing:.28em;text-transform:uppercase;color:var(--cyan);font-weight:600}
h1,h2,h3{text-wrap:balance;line-height:1.08;margin:0}
.grad{background:var(--aurora);-webkit-background-clip:text;background-clip:text;color:transparent}
p{margin:0}
.lede{color:var(--dim);font-size:1.12rem;max-width:60ch}
.hero{position:relative;padding:82px 0 60px}
.hero .eyebrow{display:block;margin-bottom:22px}
.hero h1{font-size:clamp(2.3rem,6vw,4.6rem);font-weight:800;letter-spacing:-.02em;max-width:17ch}
.hero .lede{margin-top:26px;font-size:clamp(1.05rem,1.9vw,1.26rem);max-width:64ch}
.cta-row{display:flex;flex-wrap:wrap;gap:14px;margin-top:36px}
.btn{display:inline-flex;align-items:center;gap:9px;padding:14px 24px;border-radius:999px;font-weight:700;text-decoration:none;font-size:1rem;border:1px solid transparent;transition:transform .15s ease,filter .15s ease,border-color .15s ease}
.btn-primary{background:var(--aurora);color:#04121a}
.btn-primary:hover{transform:translateY(-2px);filter:brightness(1.08)}
.btn-ghost{color:var(--ink);border-color:var(--line);background:var(--panel)}
.btn-ghost:hover{border-color:var(--cyan);transform:translateY(-2px)}
section{padding:72px 0;position:relative}
.sec-head{max-width:68ch;margin-bottom:42px}
.sec-head h2{font-size:clamp(1.75rem,3.4vw,2.6rem);font-weight:750;letter-spacing:-.015em;margin-top:14px}
.sec-head p{margin-top:16px;color:var(--dim);font-size:1.07rem}
.rule{height:1px;border:0;margin:0;background:linear-gradient(90deg,rgba(92,255,157,.28),rgba(86,194,255,.22) 34%,rgba(255,111,196,.24) 68%,transparent)}
/* ---- calculateur ---- */
.calc{display:grid;grid-template-columns:minmax(0,340px) minmax(0,1fr);gap:26px;align-items:start}
@media(max-width:900px){.calc{grid-template-columns:1fr}}
.panel{background:var(--panel);border:1px solid var(--line);border-radius:18px;padding:24px}
.panel h3{font-size:1.02rem;font-weight:700;margin-bottom:6px}
.panel .hint{color:var(--dim-2);font-size:.85rem;margin-bottom:20px}
.field{margin-bottom:20px}
.field label{display:flex;justify-content:space-between;align-items:baseline;gap:10px;font-size:.9rem;color:var(--dim);margin-bottom:9px}
.field label b{color:var(--ink);font-family:var(--mono);font-size:.95rem;font-weight:600}
.field input[type=range]{width:100%;accent-color:#56c2ff;height:22px;cursor:pointer}
.field .sub{font-size:.78rem;color:var(--dim-2);margin-top:5px}
.results{display:grid;gap:18px}
.verdict{background:linear-gradient(135deg,rgba(79,227,193,.11),rgba(169,139,255,.09));border:1px solid rgba(86,194,255,.3);border-radius:18px;padding:26px}
.verdict .big{font-size:clamp(1.6rem,4.2vw,2.5rem);font-weight:800;letter-spacing:-.02em;line-height:1.15}
.verdict p{color:var(--dim);margin-top:12px;font-size:.99rem;max-width:56ch}
.vs{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media(max-width:560px){.vs{grid-template-columns:1fr}}
.col{background:var(--panel-2);border:1px solid var(--line-2);border-radius:15px;padding:20px}
.col .who{font-family:var(--mono);font-size:.75rem;letter-spacing:.14em;text-transform:uppercase;color:var(--dim-2)}
.col .amt{font-size:1.85rem;font-weight:780;letter-spacing:-.02em;margin:8px 0 3px;font-variant-numeric:tabular-nums}
.col.saas .amt{color:var(--amber)}
.col.setops .amt{color:var(--teal)}
.col .per{font-size:.84rem;color:var(--dim-2)}
.lines{list-style:none;padding:0;margin:16px 0 0;display:grid;gap:7px;font-size:.87rem}
.lines li{display:flex;justify-content:space-between;gap:12px;color:var(--dim)}
.lines li span:last-child{font-family:var(--mono);color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.lines li.zero span:last-child{color:var(--teal);font-weight:700}
.note{font-size:.87rem;color:var(--dim-2);margin-top:18px;max-width:76ch}
.note b{color:var(--dim)}
/* ---- tableau remplace ---- */
.tbl-scroll{overflow-x:auto;border:1px solid var(--line);border-radius:16px;background:var(--panel-2)}
table{border-collapse:collapse;width:100%;min-width:640px;font-size:.94rem}
thead th{text-align:left;padding:15px 18px;font-family:var(--mono);font-size:.74rem;letter-spacing:.13em;text-transform:uppercase;color:var(--dim-2);border-bottom:1px solid var(--line);font-weight:600;white-space:nowrap}
tbody td{padding:14px 18px;border-bottom:1px solid var(--line-2);vertical-align:top;color:var(--dim)}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover{background:rgba(255,255,255,.022)}
tbody td:first-child{color:var(--ink);font-weight:640;white-space:nowrap}
tbody td.libre{color:var(--dim);font-family:var(--mono);font-size:.86rem}
.st{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:.7rem;letter-spacing:.07em;text-transform:uppercase;padding:4px 10px;border-radius:999px;white-space:nowrap;margin-left:auto;flex:none}
.st.ok{color:#7ff0d0;background:rgba(79,227,193,.12);border:1px solid rgba(79,227,193,.32)}
.st.wip{color:#ffd79a;background:rgba(255,196,107,.1);border:1px solid rgba(255,196,107,.3)}
/* ---- preuve ---- */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:16px;margin-bottom:34px}
.stat{background:var(--panel-2);border:1px solid var(--line-2);border-radius:15px;padding:22px}
.stat .n{font-size:2rem;font-weight:800;letter-spacing:-.02em;background:var(--aurora);-webkit-background-clip:text;background-clip:text;color:transparent;font-variant-numeric:tabular-nums}
.stat .l{color:var(--dim);font-size:.9rem;margin-top:5px}
.term{background:#04050d;border:1px solid var(--line);border-radius:16px;overflow:hidden;font-family:var(--mono);font-size:.88rem}
.term .bar{display:flex;align-items:center;gap:7px;padding:11px 16px;background:rgba(255,255,255,.03);border-bottom:1px solid var(--line-2)}
.term .bar i{width:10px;height:10px;border-radius:50%;background:#2c3155;display:block}
.term .bar span{margin-left:8px;color:var(--dim-2);font-size:.78rem;letter-spacing:.05em}
.term pre{margin:0;padding:20px 18px;overflow-x:auto;line-height:1.75;color:var(--dim)}
.term .p{color:var(--violet)}
.term .c{color:var(--cyan)}
.term .g{color:var(--teal)}
.term .w{color:var(--ink)}
/* ---- colonnes génériques ---- */
.duo{display:grid;grid-template-columns:repeat(2,1fr);gap:20px}
@media(max-width:820px){.duo{grid-template-columns:1fr}}
.card{position:relative;background:var(--panel);border:1px solid var(--line);border-radius:18px;padding:26px;overflow:hidden;transition:transform .2s ease,border-color .2s ease,box-shadow .2s ease}
.card:hover{transform:translateY(-3px);border-color:rgba(86,194,255,.42);box-shadow:0 18px 50px -24px rgba(86,194,255,.45)}
.card::before{content:"";position:absolute;inset:0 0 auto 0;height:2px;background:var(--aurora);opacity:.75}
.card h3{font-size:1.2rem;font-weight:720;margin-bottom:10px}
.card p{color:var(--dim);font-size:.95rem}
ul.does{list-style:none;padding:0;margin:16px 0 0;display:grid;gap:9px}
ul.does li{position:relative;padding-left:22px;color:var(--dim);font-size:.94rem}
ul.does li::before{content:"";position:absolute;left:2px;top:.62em;width:7px;height:7px;border-radius:2px;background:var(--aurora);transform:rotate(45deg)}
ul.does b{color:var(--ink);font-weight:640}
.honest{background:var(--panel-2);border:1px solid var(--line);border-left:3px solid var(--amber);border-radius:14px;padding:24px 26px}
.honest h3{font-size:1.04rem;font-weight:700;margin-bottom:12px;color:var(--amber)}
.honest ul{margin:0;padding-left:20px;display:grid;gap:10px}
.honest li{color:var(--dim);font-size:.95rem}
.honest b{color:var(--ink);font-weight:640}
.close{text-align:center;padding:88px 0 96px}
.close h2{font-size:clamp(1.9rem,4.6vw,3.1rem);font-weight:800;letter-spacing:-.02em;max-width:20ch;margin-inline:auto}
.close p{margin:20px auto 0;color:var(--dim);max-width:56ch;font-size:1.06rem}
.close .cta-row{justify-content:center}
footer{border-top:1px solid var(--line-2);padding:40px 0;color:var(--dim-2);font-size:.9rem}
footer .wrap{display:flex;flex-wrap:wrap;gap:16px 28px;align-items:center;justify-content:space-between}
footer a{color:var(--dim);text-decoration:none}
footer a:hover{color:var(--cyan)}
.reveal{opacity:0;transform:translateY(16px);transition:opacity .6s ease,transform .6s ease}
.reveal.in{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){
.reveal{opacity:1;transform:none;transition:none}
.aurora{animation:none}
html{scroll-behavior:auto}
}
</style>
<div id="sky" aria-hidden="true"><canvas></canvas></div>
<div class="aurora" aria-hidden="true"></div>
<header class="nav">
<div class="wrap">
<a class="brand" href="#top" aria-label="Set-OPS — Chezlepro">
<svg viewBox="0 0 32 32" role="img" aria-hidden="true"><defs>
<radialGradient id="sky1" cx="50%" cy="36%" r="75%"><stop offset="0%" stop-color="#10184a"/><stop offset="100%" stop-color="#05060f"/></radialGradient>
<linearGradient id="au1" x1="0" y1="1" x2="1" y2="0"><stop offset="0%" stop-color="#2ec18f"/><stop offset="45%" stop-color="#56c2ff"/><stop offset="100%" stop-color="#a98bff"/></linearGradient>
<radialGradient id="gl1" cx="50%" cy="50%" r="50%"><stop offset="0%" stop-color="#bfe9ff"/><stop offset="100%" stop-color="#bfe9ff" stop-opacity="0"/></radialGradient>
<radialGradient id="st1" cx="50%" cy="45%" r="60%"><stop offset="0%" stop-color="#fff"/><stop offset="100%" stop-color="#d6ecff"/></radialGradient>
</defs>
<circle cx="16" cy="16" r="16" fill="url(#sky1)"/>
<path d="M3 21 C 9 16, 13 23, 18 18 C 22 14, 26 17, 30 13" fill="none" stroke="url(#au1)" stroke-width="2.6" stroke-linecap="round" opacity=".85"/>
<circle cx="7" cy="9" r=".9" fill="#cfe6ff"/><circle cx="24" cy="8" r="1.1" fill="#fff"/><circle cx="26" cy="22" r=".8" fill="#bfe9ff"/><circle cx="9" cy="25" r=".7" fill="#cfe6ff"/>
<circle cx="16" cy="15" r="9" fill="url(#gl1)" opacity=".55"/>
<path d="M16 5 C 16.9 12.4, 17.6 13.1, 25 14 C 17.6 14.9, 16.9 15.6, 16 23 C 15.1 15.6, 14.4 14.9, 7 14 C 14.4 13.1, 15.1 12.4, 16 5 Z" fill="url(#st1)"/>
</svg>
<span>Set&#8209;OPS <b>·</b> <span style="color:var(--dim);font-weight:500">Chezlepro</span></span>
</a>
<nav>
<a href="index.html">Capacités</a>
<a href="offres.html">Offres</a>
<a href="tarifs.html">Tarifs</a>
<a href="valeur.html" aria-current="page">Valeur</a>
<a class="cta-mini" href="https://chezlepro.ca/contact">Nous parler</a>
</nav>
</div>
</header>
<main id="top">
<!-- =================== HERO =================== -->
<div class="hero">
<div class="wrap">
<span class="eyebrow">Valeur · Coût total · Preuve</span>
<h1>Le nuage vous <span class="grad">loue</span> votre propre organisation.</h1>
<p class="lede">
Chaque mois, vous payez pour héberger vos courriels, vos documents, vos identités et
votre mémoire institutionnelle sur des serveurs qui ne vous appartiennent pas, sous des
lois qui ne sont pas les vôtres, à un prix que vous ne fixez pas.
Set&#8209;OPS installe la même chose chez vous — avec du logiciel libre, sur votre
matériel — et vérifie par lui&#8209;même qu'il tient parole.
</p>
<div class="cta-row">
<a class="btn btn-primary" href="#calcul">Faire le calcul &rarr;</a>
<a class="btn btn-ghost" href="#preuve">Voir la preuve</a>
</div>
</div>
</div>
<hr class="rule">
<!-- =================== CALCULATEUR =================== -->
<section id="calcul">
<div class="wrap">
<div class="sec-head reveal">
<span class="eyebrow">1 — L'arithmétique</span>
<h2>Vos chiffres, pas les nôtres.</h2>
<p>
Les hypothèses ci&#8209;dessous sont des valeurs de départ, pas des promesses.
Remplacez&#8209;les par votre réalité : l'addition se refait toute seule.
</p>
</div>
<div class="calc reveal">
<div class="panel">
<h3>Votre situation</h3>
<p class="hint">Glissez les curseurs.</p>
<div class="field">
<label for="p">Personnes à desservir <b id="p-v">60</b></label>
<input type="range" id="p" min="5" max="250" step="5" value="60">
<p class="sub">Employé·es, membres et bénévoles ayant un compte.</p>
</div>
<div class="field">
<label for="s">Abonnements $/personne/mois <b id="s-v">26 $</b></label>
<input type="range" id="s" min="6" max="80" step="2" value="26">
<p class="sub">Suite bureautique, courriel, stockage, visioconférence, forge, sauvegarde — additionnés.</p>
</div>
<div class="field">
<label for="h">Matériel, achat unique <b id="h-v">9 000 $</b></label>
<input type="range" id="h" min="3000" max="40000" step="1000" value="9000">
<p class="sub">Serveurs et réseau, amortis sur 5 ans.</p>
</div>
<div class="field">
<label for="m">Mise en place, une fois <b id="m-v">15 000 $</b></label>
<input type="range" id="m" min="0" max="60000" step="1000" value="15000">
<p class="sub">Installation, migration, formation. Zéro si vous la faites vous&#8209;même.</p>
</div>
<div class="field">
<label for="e">Exploitation $/mois <b id="e-v">600 $</b></label>
<input type="range" id="e" min="0" max="4000" step="50" value="600">
<p class="sub">Infogérance, ou le temps de votre propre équipe.</p>
</div>
</div>
<div class="results">
<div class="verdict">
<p class="big" id="verdict-big"></p>
<p id="verdict-txt"></p>
</div>
<div class="vs">
<div class="col saas">
<p class="who">Abonnements · 5 ans</p>
<p class="amt" id="saas-5"></p>
<p class="per" id="saas-1"></p>
<ul class="lines">
<li><span>Licences et sièges</span><span id="l-saas"></span></li>
<li><span>Matériel</span><span>0 $</span></li>
<li><span>Vos données</span><span>ailleurs</span></li>
<li><span>Si les prix montent</span><span>vous payez</span></li>
</ul>
</div>
<div class="col setops">
<p class="who">Set-OPS · 5 ans</p>
<p class="amt" id="so-5"></p>
<p class="per" id="so-1"></p>
<ul class="lines">
<li class="zero"><span>Licences logicielles</span><span>0 $</span></li>
<li><span>Matériel amorti</span><span id="l-hw"></span></li>
<li><span>Mise en place</span><span id="l-mep"></span></li>
<li><span>Exploitation</span><span id="l-ops"></span></li>
</ul>
</div>
</div>
<p class="note">
<b>Ce que ce calcul ne dit pas.</b> Il compare des dollars, et les dollars sont la
plus petite partie de la question. Une migration coûte du temps et de la patience.
Un serveur chez vous demande quelqu'un pour s'en occuper. En échange, vous cessez de
louer votre propre organisation, et vous pouvez partir quand vous voulez — tout est
libre, rien n'est captif.
</p>
</div>
</div>
</div>
</section>
<hr class="rule">
<!-- =================== CE QUE ÇA REMPLACE =================== -->
<section id="remplace">
<div class="wrap">
<div class="sec-head reveal">
<span class="eyebrow">2 — L'équivalence</span>
<h2>Ligne pour ligne, ce qui sort de votre budget.</h2>
<p>
Set&#8209;OPS n'est pas un logiciel de plus : c'est le moteur qui installe et tient à
jour une pile complète de logiciels libres, sur votre matériel. Voici ce que chaque
brique remplace — et son état réel, sans embellissement.
</p>
</div>
<div class="tbl-scroll reveal">
<table>
<thead>
<tr>
<th>Brique</th>
<th>Ce que vous louez aujourd'hui</th>
<th>Le libre qui le fait</th>
<th>État</th>
</tr>
</thead>
<tbody>
<tr>
<td>Identité unique</td>
<td>Entra ID, Google Workspace</td>
<td class="libre">OpenLDAP + Keycloak</td>
<td><span class="st ok">Éprouvé</span></td>
</tr>
<tr>
<td>Courriel</td>
<td>Microsoft 365, Google Workspace</td>
<td class="libre">Postfix + Dovecot + rspamd</td>
<td><span class="st ok">Éprouvé</span></td>
</tr>
<tr>
<td>Fichiers et bureautique</td>
<td>Dropbox, OneDrive, Google Docs</td>
<td class="libre">Nextcloud + Collabora</td>
<td><span class="st wip">En chantier</span></td>
</tr>
<tr>
<td>Forge et code</td>
<td>GitHub, GitLab payant</td>
<td class="libre">Forgejo</td>
<td><span class="st ok">Éprouvé</span></td>
</tr>
<tr>
<td>Site et applications web</td>
<td>Hébergeur, PaaS</td>
<td class="libre">nginx + systemd (natif)</td>
<td><span class="st ok">Éprouvé</span></td>
</tr>
<tr>
<td>Base de données</td>
<td>RDS, bases infogérées</td>
<td class="libre">PostgreSQL + Redis</td>
<td><span class="st ok">Éprouvé</span></td>
</tr>
<tr>
<td>Certificats et chiffrement</td>
<td>Certificats commerciaux</td>
<td class="libre">step-ca (autorité interne)</td>
<td><span class="st ok">Éprouvé</span></td>
</tr>
<tr>
<td>DNS</td>
<td>DNS infogéré</td>
<td class="libre">PowerDNS + Unbound</td>
<td><span class="st ok">Éprouvé</span></td>
</tr>
<tr>
<td>Supervision et journaux</td>
<td>Datadog, New Relic</td>
<td class="libre">Prometheus + Grafana + Loki + Icinga</td>
<td><span class="st ok">Éprouvé</span></td>
</tr>
<tr>
<td>Sauvegardes</td>
<td>Sauvegarde infonuagique</td>
<td class="libre">restic, hors&#8209;nœud, chiffré</td>
<td><span class="st ok">Éprouvé</span></td>
</tr>
<tr>
<td>Sécurité du parc</td>
<td>Options de sécurité facturées</td>
<td class="libre">nftables, fail2ban, AppArmor, auditd</td>
<td><span class="st ok">Éprouvé</span></td>
</tr>
</tbody>
</table>
</div>
<p class="note">
<b>« Éprouvé »</b> signifie déployé et vérifié sur des machines réelles, pas seulement
écrit. <b>« En chantier »</b> signifie exactement cela. Nous distinguons les deux parce
que la confusion entre les deux est le mensonge le plus courant de notre industrie.
</p>
</div>
</section>
<hr class="rule">
<!-- =================== LA PREUVE =================== -->
<section id="preuve">
<div class="wrap">
<div class="sec-head reveal">
<span class="eyebrow">3 — La différence</span>
<h2>Ne nous croyez pas. Lancez la commande.</h2>
<p>
N'importe quel fournisseur peut écrire une page comme celle&#8209;ci. Presque aucun ne
vous donne le moyen de la contredire. Set&#8209;OPS tient un <b>registre de ses propres
affirmations</b> — chaque phrase publique du projet y est reliée soit à une commande
qui la vérifie, soit à un aveu qu'elle n'est pas prouvée.
</p>
</div>
<div class="stats reveal">
<div class="stat"><p class="n">51</p><p class="l">rôles d'installation, testés et documentés</p></div>
<div class="stat"><p class="n">16 / 16</p><p class="l">preuves automatiques au vert</p></div>
<div class="stat"><p class="n">54</p><p class="l">affirmations publiques tracées au registre</p></div>
<div class="stat"><p class="n">8 600</p><p class="l">lignes de documentation en français</p></div>
</div>
<div class="term reveal">
<div class="bar"><i></i><i></i><i></i><span>make prouver</span></div>
<pre><span class="p">$</span> <span class="w">make prouver</span>
<span class="c">P01</span> Lint Ansible ................................ <span class="g">OK</span>
<span class="c">P03</span> L'inventaire est bien généré depuis le plan . <span class="g">OK</span>
<span class="c">P06</span> Les registres du plan sont valides .......... <span class="g">OK</span>
<span class="c">P09</span> Flux réseau : schéma et matrice cohérents ... <span class="g">OK</span>
<span class="c">P11</span> Syntaxe des 35 playbooks .................... <span class="g">OK</span>
<span class="c">P13</span> Invariants : SSH par clé, pare-feu, licence . <span class="g">OK</span>
<span class="c">P16</span> Inventaire complet déchiffré et lu .......... <span class="g">OK</span>
<span class="g">CONFORME : 16 OK, 0 échec, 0 sauté.</span>
<span class="w">→ docs/audit/preuve-2026-07-20.md</span>
</pre>
</div>
<div class="duo reveal" style="margin-top:26px">
<div class="card">
<h3>Un rapport daté, à archiver</h3>
<p>
Chaque exécution produit une pièce justificative horodatée, versionnée avec le code.
Utilisable en conseil d'administration, en audit, en demande de subvention, ou
simplement pour dormir tranquille.
</p>
</div>
<div class="card">
<h3>Le registre a le droit de perdre</h3>
<p>
Une affirmation qui échoue redescend au statut « non prouvée », publiquement, dans le
dépôt. C'est la seule façon qu'un tel registre ait la moindre valeur — et c'est
pourquoi le nôtre en a.
</p>
</div>
</div>
</div>
</section>
<hr class="rule">
<!-- =================== SOUVERAINETÉ =================== -->
<section id="souverainete">
<div class="wrap">
<div class="sec-head reveal">
<span class="eyebrow">4 — Ce qui ne se chiffre pas</span>
<h2>La valeur qui apparaît le jour où ça tourne mal.</h2>
</div>
<div class="duo reveal">
<div class="card">
<h3>Vos données restent où vous êtes</h3>
<ul class="does">
<li><b>Résidence réelle</b> — les disques sont dans votre local, pas dans une région infonuagique.</li>
<li><b>Aucune loi étrangère</b> ne s'applique à un serveur que personne d'autre ne détient.</li>
<li><b>Vos obligations en matière de vie privée</b> deviennent vérifiables : vous pouvez montrer la machine.</li>
</ul>
</div>
<div class="card">
<h3>Vous pouvez partir</h3>
<ul class="does">
<li><b>Zéro licence, zéro captivité</b> — chaque composant est libre, remplaçable, documenté.</li>
<li><b>Aucune hausse de prix unilatérale</b> : personne ne peut doubler votre facture par courriel.</li>
<li><b>Aucune fonction retirée</b> parce qu'un fournisseur a changé de stratégie.</li>
</ul>
</div>
<div class="card">
<h3>L'infrastructure est du texte</h3>
<ul class="does">
<li><b>Tout est décrit dans des fichiers</b> lisibles, versionnés, relus comme du code.</li>
<li><b>Reconstructible</b> : la même commande rebâtit la même chose sur du matériel neuf.</li>
<li><b>Auditable par un tiers</b> — un consultant externe lit tout en une journée.</li>
</ul>
</div>
<div class="card">
<h3>Pensé pour des organisations réelles</h3>
<ul class="does">
<li><b>En français</b>, documentation et interface comprises.</li>
<li><b>À l'échelle d'un OBNL ou d'une coop</b> — pas une machinerie d'entreprise du Fortune 500.</li>
<li><b>Exploitable par un humain seul</b>, sans intelligence artificielle, sans l'auteur.</li>
</ul>
</div>
</div>
</div>
</section>
<hr class="rule">
<!-- =================== RÉSERVES =================== -->
<section id="reserves">
<div class="wrap">
<div class="sec-head reveal">
<span class="eyebrow">5 — Honnêteté</span>
<h2>Ce que nous ne prétendons pas.</h2>
<p>
La règle du projet est écrite dans son dépôt : <i>ne jamais affirmer plus que ce qu'on
prouve.</i> Elle s'applique aussi à cette page.
</p>
</div>
<div class="honest reveal">
<h3>Nos réserves, en clair</h3>
<ul>
<li>
<b>Ce n'est pas rentable pour tout le monde.</b> En dessous d'une certaine taille, le
calcul ci&#8209;dessus ne bascule pas en votre faveur avant des années. À cette
échelle, on choisit Set&#8209;OPS pour la souveraineté, pas pour l'économie — et nous
vous le dirons.
</li>
<li>
<b>Il faut quelqu'un.</b> Un serveur chez soi demande une personne responsable, à
l'interne ou sous contrat. Set&#8209;OPS réduit énormément ce travail ; il ne le
supprime pas.
</li>
<li>
<b>Le projet repose encore sur un seul mainteneur.</b> C'est le risque principal, nous
le nommons. La documentation, les procédures et le registre de preuves existent
précisément pour que le savoir ne vive pas dans une seule tête.
</li>
<li>
<b>Une épreuve est en cours.</b> Un administrateur système indépendant, qui n'est pas
l'auteur, doit installer l'ensemble à partir de la seule documentation, sans aide et
sans IA. Le protocole est public, le résultat sera publié — <i>y compris s'il
échoue.</i>
</li>
</ul>
</div>
</div>
</section>
<!-- =================== CLOSE =================== -->
<div class="close">
<div class="wrap reveal">
<h2>Reprenez vos <span class="grad">clés</span>.</h2>
<p>
Parlons de votre organisation : ce que vous payez aujourd'hui, ce que vous hébergez,
et ce qu'il faudrait pour que tout cela vous appartienne à nouveau.
</p>
<div class="cta-row">
<a class="btn btn-primary" href="index.html">Voir toutes les capacités &rarr;</a>
<a class="btn btn-ghost" href="#calcul">Refaire le calcul</a>
</div>
</div>
</div>
</main>
<footer>
<div class="wrap">
<div style="display:flex;align-items:center;gap:10px">
<svg viewBox="0 0 32 32" width="26" height="26" aria-hidden="true">
<circle cx="16" cy="16" r="16" fill="#0a0d24"/>
<path d="M3 21 C 9 16, 13 23, 18 18 C 22 14, 26 17, 30 13" fill="none" stroke="#56c2ff" stroke-width="2.4" stroke-linecap="round" opacity=".8"/>
<path d="M16 6 C 16.8 12.6, 17.4 13.2, 24 14 C 17.4 14.8, 16.8 15.4, 16 22 C 15.2 15.4, 14.6 14.8, 8 14 C 14.6 13.2, 15.2 12.6, 16 6 Z" fill="#e9ecff"/></svg>
<span>Chezlepro inc. · Saint-Bruno-de-Montarville, Québec</span>
</div>
<div><a href="index.html">Capacités</a> · <a href="offres.html">Offres</a> · <a href="tarifs.html">Tarifs</a> · <a href="valeur.html">Valeur</a></div>
<div>Set&#8209;OPS — moteur libre, licence AGPLv3 · <a href="https://chezlepro.ca">chezlepro.ca</a></div>
</div>
</footer>
<script>
(function(){
var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
/* ---------- constellation ---------- */
var sky = document.querySelector('#sky canvas');
if(sky){
var ctx = sky.getContext('2d'), W, H, DPR, stars=[], raf;
function size(){
DPR = Math.min(window.devicePixelRatio||1, 2);
W = sky.clientWidth; H = sky.clientHeight;
sky.width = W*DPR; sky.height = H*DPR; ctx.setTransform(DPR,0,0,DPR,0,0);
var count = Math.min(120, Math.round(W*H/14000));
stars = [];
for(var i=0;i<count;i++){
stars.push({x:Math.random()*W, y:Math.random()*H,
r:Math.random()*1.3+0.3, vx:(Math.random()-.5)*0.12, vy:(Math.random()-.5)*0.12,
tw:Math.random()*Math.PI*2, ts:Math.random()*0.02+0.006});
}
}
function frame(){
ctx.clearRect(0,0,W,H);
for(var i=0;i<stars.length;i++){
var s=stars[i];
if(!reduce){ s.x+=s.vx; s.y+=s.vy; s.tw+=s.ts;
if(s.x<0)s.x+=W; if(s.x>W)s.x-=W; if(s.y<0)s.y+=H; if(s.y>H)s.y-=H; }
var a = 0.5 + Math.sin(s.tw)*0.4;
ctx.beginPath(); ctx.arc(s.x,s.y,s.r,0,6.2832);
ctx.fillStyle='rgba(207,230,255,'+a.toFixed(3)+')'; ctx.fill();
}
for(var i=0;i<stars.length;i++){
for(var j=i+1;j<stars.length;j++){
var dx=stars[i].x-stars[j].x, dy=stars[i].y-stars[j].y, d=dx*dx+dy*dy;
if(d<10000){
var o=(1-d/10000)*0.22;
ctx.strokeStyle='rgba(86,194,255,'+o.toFixed(3)+')'; ctx.lineWidth=0.6;
ctx.beginPath(); ctx.moveTo(stars[i].x,stars[i].y); ctx.lineTo(stars[j].x,stars[j].y); ctx.stroke();
}
}
}
if(!reduce) raf=requestAnimationFrame(frame);
}
size(); frame();
var to; window.addEventListener('resize',function(){ clearTimeout(to); to=setTimeout(function(){ cancelAnimationFrame(raf); size(); frame(); },180); });
document.addEventListener('visibilitychange',function(){
if(document.hidden){ cancelAnimationFrame(raf); } else if(!reduce){ raf=requestAnimationFrame(frame); }
});
}
/* ---------- calculateur de coût total ---------- */
var ANS = 5, AMORT = 5;
var f0 = new Intl.NumberFormat('fr-CA',{style:'currency',currency:'CAD',maximumFractionDigits:0});
function $(id){ return document.getElementById(id); }
function money(n){ return f0.format(Math.round(n)); }
var ids = ['p','s','h','m','e'];
function read(){
return {
p:+$('p').value, s:+$('s').value, h:+$('h').value,
m:+$('m').value, e:+$('e').value
};
}
function calc(){
var v = read();
$('p-v').textContent = v.p;
$('s-v').textContent = money(v.s);
$('h-v').textContent = money(v.h);
$('m-v').textContent = money(v.m);
$('e-v').textContent = money(v.e);
var saasAn = v.p * v.s * 12;
var saas5 = saasAn * ANS;
/* Matériel : achat initial + renouvellement au prorata des années au-delà de l'amortissement */
var hw5 = v.h * (ANS / AMORT);
var ops5 = v.e * 12 * ANS;
var so5 = v.m + hw5 + ops5;
var soAn1 = v.m + v.h + v.e * 12;
$('saas-5').textContent = money(saas5);
$('saas-1').textContent = 'soit ' + money(saasAn) + ' par année';
$('so-5').textContent = money(so5);
$('so-1').textContent = 'dont ' + money(soAn1) + ' la première année';
$('l-saas').textContent = money(saas5);
$('l-hw').textContent = money(hw5);
$('l-mep').textContent = money(v.m);
$('l-ops').textContent = money(ops5);
/* Point de bascule : première année où le cumul Set-OPS passe sous le cumul abonnements */
var bascule = 0;
for(var a=1; a<=25; a++){
var cSaas = saasAn * a;
var cSo = v.m + v.h * Math.ceil(a/AMORT) + v.e * 12 * a;
if(cSo <= cSaas){ bascule = a; break; }
}
var ecart = saas5 - so5;
var big = $('verdict-big'), txt = $('verdict-txt');
if(bascule && bascule <= ANS){
big.textContent = money(Math.abs(ecart)) + ' de moins sur 5 ans';
txt.innerHTML = 'Le point de bascule tombe dans la <b>' + bascule +
(bascule === 1 ? '<sup>re</sup>' : '<sup>e</sup>') + ' année</b> : ' +
'à partir de là, chaque mois joue en votre faveur. Et les ' + v.p +
' personnes desservies ne coûtent plus rien de plus à ajouter.';
} else if(bascule){
big.innerHTML = 'Rentable à la ' + bascule + '<sup>e</sup> année';
txt.innerHTML = 'Au&#8209;delà de l\'horizon de 5 ans retenu ici. À cette taille, ' +
'le gain n\'est pas d\'abord monétaire : <b>c\'est le contrôle de vos données et ' +
'la liberté de partir.</b> Nous préférons vous le dire que vous le cacher.';
} else {
big.textContent = 'Pas rentable, à cette échelle';
txt.innerHTML = 'Avec ces hypothèses, l\'autohébergement ne se rembourse pas. ' +
'<b>La bonne raison de le faire devient la souveraineté, pas le budget</b> — ' +
'et c\'est une raison parfaitement valable, tant qu\'elle est choisie en connaissance de cause.';
}
}
ids.forEach(function(id){
var el = $(id);
if(el){ el.addEventListener('input', calc); }
});
calc();
/* ---------- révélations au scroll ---------- */
var els = document.querySelectorAll('.reveal');
if(reduce || !('IntersectionObserver' in window)){
els.forEach(function(e){ e.classList.add('in'); });
} else {
var io = new IntersectionObserver(function(entries){
entries.forEach(function(en){ if(en.isIntersecting){ en.target.classList.add('in'); io.unobserve(en.target); } });
}, {rootMargin:'0px 0px -8% 0px', threshold:0.08});
els.forEach(function(e){ io.observe(e); });
}
})();
</script>
</body>
</html>