Palette (promo/, les 4 pages) — ajoute --rose:#ff6fc4 (frange magenta) et
--vert:#5cff9d (vert fluo), uniquement dans les DÉGRADÉS FONCÉS : fond fixe du
corps, nappe .aurora dérivante, filets .rule. Opacités de 5,5 % à 8,5 %, une
teinte et non un motif. Le vert entre par la gauche et le rose sort par la
droite, comme une vraie aurore. --aurora (texte et boutons) est inchangé :
l'identité de marque ne bouge pas. Appliqué identiquement aux quatre fichiers,
0 conflit CSS après coup.
Thème Forgejo (alliance.css, 29 → 118 lignes) — la feuille étant injectée par
templates/custom/header.tmpl sur toutes les pages, le wiki est couvert sans
feuille distincte. Réorganisée en deux sections de risque explicite :
§1 Variables — couleurs officielles + ciel nocturne. Sûr, résiste aux
mises à jour. ÉPROUVÉ sur forge-01 (CHANGELOG 2026-07-03).
§2 Décor — fond aurore, filet sous les titres, citations, tableaux et code
en ligne de .markup. Fragile (classes internes). JAMAIS RENDU.
Supprimer §2 ramène au thème sobre. Le ciel nocturne ne s'applique qu'aux
thèmes sombres, pour ne pas casser le thème clair.
docs/theme-forgejo-hors-flotte.md — pose manuelle sur une instance Forgejo non
gérée par Set-OPS (la forge historique qui héberge ce dépôt et son wiki).
Forgejo n'ayant aucun réglage web pour le CSS, il faut déposer la feuille sur
le serveur. La procédure ne duplique aucun fichier : elle pointe vers ceux du
rôle. Inclut la détection du répertoire custom, un garde-fou pour ne pas
écraser un header.tmpl existant (ajout de ligne), la vérification curl et la
marche arrière.
Corrige deux affirmations fausses de ma part :
- « thème jamais rendu par un Forgejo réel » était faux pour §1, éprouvée.
Le statut est désormais donné section par section.
- Contradiction consignée sur forge-01 : le plan la dit `etat: planifie`, le
CHANGELOG 2026-07-03 dit le branding « prouvé sur forge-01 ». Les deux ne
peuvent pas être vrais ; l'écart est écrit dans le README du rôle, à trancher.
Validé : équilibre accolades/parenthèses du CSS, 0 conflit CSS entre les quatre
pages, lien de doc résolu, ansible-lint 0 échec sur 485 fichiers,
prouver.py --verifier → CONFORME 16/16.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
748 lines
36 KiB
HTML
748 lines
36 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(780px 540px at 97% 38%,rgba(255,111,196,.085) 0%,transparent 62%),
|
|
radial-gradient(840px 580px at 3% 72%,rgba(92,255,157,.065) 0%,transparent 62%),
|
|
radial-gradient(700px 500px at 50% 112%,rgba(169,139,255,.07) 0%,transparent 60%),
|
|
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(64px) saturate(140%);opacity:.42;
|
|
background:
|
|
radial-gradient(34% 52% at 6% 52%,var(--vert) 0%,transparent 66%),
|
|
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(32% 48% at 95% 62%,var(--rose) 0%,transparent 66%);
|
|
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‑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‑OPS installe la même chose chez vous — avec du logiciel libre, sur votre
|
|
matériel — et vérifie par lui‑même qu'il tient parole.
|
|
</p>
|
|
<div class="cta-row">
|
|
<a class="btn btn-primary" href="#calcul">Faire le calcul →</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‑dessous sont des valeurs de départ, pas des promesses.
|
|
Remplacez‑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‑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‑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‑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‑ci. Presque aucun ne
|
|
vous donne le moyen de la contredire. Set‑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‑dessus ne bascule pas en votre faveur avant des années. À cette
|
|
échelle, on choisit Set‑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‑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 →</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‑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‑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>
|