Ajouter presentation publique au login

This commit is contained in:
Daniel Allaire 2026-05-31 14:26:28 -04:00
parent ab8b4ea487
commit 25470f4642
2 changed files with 468 additions and 0 deletions

View file

@ -0,0 +1,461 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Présentation aux membres</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,400;12..96,600;12..96,800&family=Spectral:ital,wght@0,400;0,500;1,400&display=swap" rel="stylesheet">
<style>
:root{
--bg:#0e1116;
--bg2:#161b24;
--panel:#1b212c;
--ink:#f3eee3;
--ink-soft:#aeb4bf;
--amber:#f0a830;
--amber-deep:#d98a14;
--green:#7fb285;
--teal:#5fb6b0;
--line:rgba(243,238,227,.12);
}
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
html,body{height:100%;overflow:hidden;}
body{
font-family:'Spectral',Georgia,serif;
background:var(--bg);
color:var(--ink);
position:fixed;inset:0;
overscroll-behavior:none;
}
/* viewport that holds the horizontal track */
.stage{position:absolute;inset:0;overflow:hidden;}
.track{
display:flex;height:100%;width:100%;
transition:transform .5s cubic-bezier(.65,.05,.18,1);
will-change:transform;
}
.slide{
flex:0 0 100%;width:100%;height:100%;
display:flex;flex-direction:column;justify-content:center;
padding:clamp(30px,8vw,60px) clamp(26px,7.5vw,48px);
padding-top:max(clamp(30px,8vw,60px),calc(env(safe-area-inset-top) + 24px));
padding-bottom:calc(110px + env(safe-area-inset-bottom));
overflow-y:auto;-webkit-overflow-scrolling:touch;
position:relative;
}
.slide::-webkit-scrollbar{width:0;}
/* animated content only on the active slide */
.slide .rise{opacity:0;transform:translateY(26px);}
.slide.active .rise{animation:rise .65s cubic-bezier(.2,.7,.3,1) forwards;}
.slide.active .rise:nth-child(1){animation-delay:.10s;}
.slide.active .rise:nth-child(2){animation-delay:.18s;}
.slide.active .rise:nth-child(3){animation-delay:.26s;}
.slide.active .rise:nth-child(4){animation-delay:.34s;}
.slide.active .rise:nth-child(5){animation-delay:.42s;}
.slide.active .rise:nth-child(6){animation-delay:.50s;}
@keyframes rise{to{opacity:1;transform:none;}}
.kicker{
font-family:'Bricolage Grotesque',sans-serif;
font-weight:600;
font-size:clamp(13px,3.8vw,16px);
letter-spacing:.16em;text-transform:uppercase;
color:var(--amber);
margin-bottom:clamp(20px,5vw,30px);
display:flex;align-items:baseline;gap:12px;
}
.kicker .num{
font-size:clamp(40px,12vw,64px);
font-weight:800;line-height:.8;
color:var(--panel);
-webkit-text-stroke:1.5px var(--amber-deep);
letter-spacing:0;
}
h1{
font-family:'Bricolage Grotesque',sans-serif;
font-weight:800;
font-size:clamp(48px,15vw,84px);
line-height:.96;letter-spacing:-.03em;
margin-bottom:14px;
}
h2{
font-family:'Bricolage Grotesque',sans-serif;
font-weight:800;
font-size:clamp(38px,11vw,62px);
line-height:1.0;letter-spacing:-.025em;
margin-bottom:clamp(22px,5vw,30px);
}
h2 em,h1 em{font-style:normal;color:var(--amber);}
p{
font-size:clamp(19px,5.4vw,24px);
line-height:1.5;
color:var(--ink-soft);
margin-bottom:clamp(16px,4vw,20px);
}
p.lead{
color:var(--ink);
font-size:clamp(21px,6vw,28px);
line-height:1.4;
}
p strong{color:var(--ink);font-weight:500;}
p.neg{color:var(--ink);font-style:italic;}
.bar{height:5px;width:64px;background:var(--amber);border-radius:5px;margin-bottom:clamp(22px,5vw,30px);}
ul{list-style:none;margin:clamp(6px,2vw,12px) 0;}
ul li{
font-size:clamp(18px,5vw,23px);
line-height:1.4;color:var(--ink);
padding:clamp(11px,3vw,15px) 0 clamp(11px,3vw,15px) 30px;
position:relative;border-bottom:1px solid var(--line);
}
ul li:last-child{border-bottom:none;}
ul li::before{
content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);
width:11px;height:11px;border-radius:3px;background:var(--amber);
}
ul li strong{font-weight:600;}
/* compact two-column for long lists, bigger text than before */
ul.cols{columns:2;column-gap:clamp(20px,5vw,30px);}
ul.cols li{
border-bottom:none;padding:clamp(7px,2vw,10px) 0 clamp(7px,2vw,10px) 24px;
break-inside:avoid;font-size:clamp(17px,4.6vw,21px);color:var(--ink-soft);
}
ul.cols li::before{width:8px;height:8px;border-radius:2px;background:var(--teal);}
ol{counter-reset:s;list-style:none;}
ol li{
font-size:clamp(18px,5vw,23px);line-height:1.4;color:var(--ink);
padding:clamp(14px,3.5vw,18px) 0 clamp(14px,3.5vw,18px) 56px;
position:relative;border-bottom:1px solid var(--line);
}
ol li:last-child{border-bottom:none;}
ol li::before{
counter-increment:s;content:counter(s);
position:absolute;left:0;top:50%;transform:translateY(-50%);
width:38px;height:38px;border-radius:11px;
background:var(--amber);color:var(--bg);
font-family:'Bricolage Grotesque',sans-serif;font-weight:800;
font-size:18px;display:flex;align-items:center;justify-content:center;
}
/* COVER */
.cover{
justify-content:center;
background:
radial-gradient(130% 90% at 90% 5%,rgba(240,168,48,.20),transparent 50%),
radial-gradient(110% 80% at 0% 100%,rgba(95,182,176,.16),transparent 55%),
var(--bg);
}
.cover h1{font-size:clamp(56px,18vw,104px);}
.cover .sub{
font-family:'Spectral',serif;font-style:italic;
font-size:clamp(22px,6.4vw,30px);
color:var(--ink-soft);max-width:18ch;line-height:1.3;margin-top:6px;
}
.cover .tag{
font-family:'Bricolage Grotesque',sans-serif;font-weight:600;
font-size:clamp(13px,3.6vw,15px);letter-spacing:.2em;text-transform:uppercase;
color:var(--amber);margin-top:clamp(28px,7vw,40px);
display:inline-flex;align-items:center;gap:10px;
}
.cover .tag::before{content:"";width:34px;height:2px;background:var(--amber);}
/* CLOSING */
.close{
justify-content:center;text-align:left;
background:radial-gradient(120% 80% at 50% 0%,rgba(240,168,48,.16),transparent 55%),var(--bg);
}
.pillars{display:flex;flex-direction:column;gap:clamp(4px,1.5vw,8px);margin:clamp(8px,2vw,14px) 0 clamp(22px,5vw,28px);}
.pillars span{
font-family:'Bricolage Grotesque',sans-serif;font-weight:800;
font-size:clamp(26px,7.4vw,38px);line-height:1.05;color:var(--ink);
letter-spacing:-.02em;
}
.pillars span em{font-style:normal;color:var(--amber);}
/* NAV */
.nav{
position:fixed;left:0;right:0;bottom:0;z-index:30;
display:flex;align-items:center;justify-content:space-between;
padding:16px clamp(22px,6vw,34px);
padding-bottom:calc(16px + env(safe-area-inset-bottom));
background:linear-gradient(to top,var(--bg) 60%,transparent);
}
.nav button{
font-family:'Bricolage Grotesque',sans-serif;font-weight:800;
background:var(--panel);border:1px solid var(--line);color:var(--ink);
width:54px;height:54px;border-radius:16px;font-size:24px;cursor:pointer;
display:flex;align-items:center;justify-content:center;line-height:1;
transition:transform .15s ease,background .2s ease,opacity .2s ease;
}
.nav button:active{transform:scale(.88);background:var(--amber);color:var(--bg);}
.nav button:disabled{opacity:.3;}
.counter{
font-family:'Bricolage Grotesque',sans-serif;font-weight:600;
font-size:15px;letter-spacing:.14em;color:var(--ink-soft);
font-variant-numeric:tabular-nums;
}
.counter b{color:var(--amber);font-weight:800;}
.progress{position:fixed;top:0;left:0;height:4px;z-index:40;
background:linear-gradient(90deg,var(--amber),var(--teal));transition:width .5s cubic-bezier(.65,.05,.18,1);}
.hint{
position:fixed;bottom:calc(98px + env(safe-area-inset-bottom));left:50%;
transform:translateX(-50%);z-index:25;font-family:'Bricolage Grotesque',sans-serif;
font-size:13px;letter-spacing:.1em;color:var(--ink-soft);text-transform:uppercase;
opacity:.65;animation:fade 3s ease forwards 3s;pointer-events:none;
}
@keyframes fade{to{opacity:0;}}
</style>
</head>
<body>
<div class="progress" id="prog"></div>
<div class="stage">
<div class="track" id="track">
<!-- 0 -->
<section class="slide cover active">
<h1 class="rise">Présentation<br>aux <em>membres</em></h1>
<div class="sub rise">L'attrait plutôt que la réclame.</div>
<div class="tag rise">Un outil au service du groupe</div>
</section>
<!-- 1 -->
<section class="slide">
<div class="kicker rise"><span class="num">01</span> Ouverture</div>
<h2 class="rise">Au service<br>du groupe</h2>
<p class="lead rise">Cette présentation ne vend pas un outil. Dans AA, ce qui dure repose rarement sur la pression.</p>
<p class="rise">L'application aide le groupe à mieux garder sa mémoire, ses décisions et sa trésorerie — sans jamais remplacer la conscience de groupe.</p>
<p class="neg rise">Elle ne décide pas à notre place. Elle ne dirige pas le groupe.</p>
</section>
<!-- 2 -->
<section class="slide">
<div class="kicker rise"><span class="num">02</span> Pourquoi</div>
<h2 class="rise">Réduire la <em>fragilité</em></h2>
<p class="rise">Plusieurs choses se suivent régulièrement :</p>
<ul class="cols rise">
<li>Rencontres</li><li>Assemblées</li><li>Présences</li>
<li>Procès-verbaux</li><li>Propositions</li><li>Décisions</li>
<li>Collectes</li><li>Dépenses</li><li>Contributions</li>
<li>Postes de service</li><li>Littérature</li><li>Événements</li>
</ul>
<p class="rise" style="margin-top:18px;">Quand tout repose sur des souvenirs dispersés, on perd le fil. L'info reste transmissible <strong>même quand les serviteurs changent</strong>.</p>
</section>
<!-- 3 -->
<section class="slide">
<div class="kicker rise"><span class="num">03</span> Ce qu'elle apporte</div>
<h2 class="rise">Surtout de <em>l'ordre</em></h2>
<div class="bar rise"></div>
<ul class="rise">
<li>Un <strong>membre</strong> consulte sans demander à trois personnes.</li>
<li>Un <strong>serviteur</strong> saisit son service au bon endroit.</li>
<li>Un <strong>trésorier</strong> suit entrées, sorties et réserves.</li>
<li>Un <strong>secrétaire</strong> prépare assemblées et PV.</li>
<li>Le <strong>groupe</strong> retrouve ses décisions passées.</li>
</ul>
</section>
<!-- 4 -->
<section class="slide">
<div class="kicker rise"><span class="num">04</span> Ses limites</div>
<h2 class="rise">Ce qu'elle <em>ne remplace pas</em></h2>
<ul class="rise">
<li>L'assemblée d'affaires</li>
<li>La discussion</li>
<li>Le vote ou le consensus</li>
<li>La responsabilité des serviteurs</li>
<li>La rotation</li>
<li>La confiance</li>
</ul>
<p class="rise" style="margin-top:18px;">Seulement un endroit commun pour noter ce qui a été décidé ensemble.</p>
</section>
<!-- 5 -->
<section class="slide">
<div class="kicker rise"><span class="num">05</span> Les membres</div>
<h2 class="rise">Commencer <em>simplement</em></h2>
<p class="rise">On peut s'en servir pour :</p>
<ul class="cols rise">
<li>Voir les événements</li><li>Consulter la littérature</li>
<li>Voir les postes</li><li>Proposer sa candidature</li>
<li>Soumettre une proposition</li><li>Seconder</li>
<li>Soumettre une dépense</li><li>Consulter les décisions</li>
</ul>
<p class="rise" style="margin-top:18px;"><strong>Personne n'a besoin de tout utiliser.</strong></p>
</section>
<!-- 6 -->
<section class="slide">
<div class="kicker rise"><span class="num">06</span> Les serviteurs</div>
<h2 class="rise">Alléger<br>la tâche</h2>
<p class="rise">Tout au même endroit :</p>
<ul class="cols rise">
<li>Rencontre</li><li>Collecte</li><li>Ventes</li>
<li>Jetons &amp; gâteaux</li><li>Assemblée</li><li>Présences</li>
<li>Procès-verbal</li><li>Rapport du trésorier</li><li>Décisions</li>
<li>Postes à pourvoir</li>
</ul>
<p class="rise" style="margin-top:18px;">Pas plus de travail — du travail <strong>plus clair et transmissible</strong>.</p>
</section>
<!-- 7 -->
<section class="slide">
<div class="kicker rise"><span class="num">07</span> La trésorerie</div>
<h2 class="rise">L'argent<br>demande de la <em>clarté</em></h2>
<ul class="cols rise">
<li>Encaisse</li><li>Solde bancaire</li><li>Collectes</li>
<li>Dépenses</li><li>Contributions</li><li>Réserves</li>
<li>Montants engagés</li><li>Registre</li><li>État des résultats</li>
<li>Rapport mensuel</li>
</ul>
<p class="rise" style="margin-top:18px;">Comprendre où en est le groupe, <strong>sans dépendre d'une seule mémoire</strong>.</p>
</section>
<!-- 8 -->
<section class="slide">
<div class="kicker rise"><span class="num">08</span> Les assemblées</div>
<h2 class="rise">Mieux<br><em>préparées</em></h2>
<ul class="cols rise">
<li>Ordre du jour</li><li>PV précédent</li><li>Présences</li>
<li>Rapport du trésorier</li><li>Propositions</li><li>Décisions</li>
<li>Contributions</li><li>Postes à pourvoir</li>
</ul>
<p class="rise" style="margin-top:18px;">Le rapport PDF s'imprime. <strong>Si la technologie fait défaut, le groupe continue avec le papier.</strong></p>
</section>
<!-- 9 -->
<section class="slide">
<div class="kicker rise"><span class="num">09</span> L'esprit AA</div>
<h2 class="rise">Au service,<br>pas dans un <em>moule</em></h2>
<ul class="cols rise">
<li>Mémoire collective</li><li>Transparence</li>
<li>Rotation</li><li>Responsabilité</li>
<li>Simplicité</li><li>Autonomie du groupe</li>
</ul>
<p class="rise" style="margin-top:18px;">Elle s'adapte aux pratiques du groupe, tant qu'elles restent cohérentes.</p>
</section>
<!-- 10 -->
<section class="slide">
<div class="kicker rise"><span class="num">10</span> Prudence</div>
<h2 class="rise">Assez,<br><em>pas plus</em></h2>
<ul class="rise">
<li>Utiliser son propre compte</li>
<li>Ne pas partager son PIN</li>
<li>Se déconnecter sur un appareil partagé</li>
<li>Respecter l'anonymat</li>
<li>Limiter les accès aux responsabilités réelles</li>
</ul>
<p class="rise" style="margin-top:16px;"><strong>Assez pour bien servir, pas plus que nécessaire.</strong></p>
</section>
<!-- 11 -->
<section class="slide">
<div class="kicker rise"><span class="num">11</span> Commencer</div>
<h2 class="rise"><em>Tranquillement</em></h2>
<ol class="rise">
<li>Les membres consultent l'accueil.</li>
<li>Les serviteurs utilisent leurs modules.</li>
<li>Le trésorier utilise la trésorerie.</li>
<li>Le secrétaire utilise les assemblées.</li>
<li>Le groupe ajuste au fil de l'usage.</li>
</ol>
<p class="rise" style="margin-top:16px;">L'outil grandit par l'utilité qu'il démontre.</p>
</section>
<!-- 12 -->
<section class="slide">
<div class="kicker rise"><span class="num">12</span> Notre demande</div>
<h2 class="rise">L'essayer avec <em>ouverture</em></h2>
<div class="bar rise"></div>
<p class="lead rise">Pas d'adopter une nouveauté par enthousiasme. Seulement de l'essayer avec ouverture.</p>
<p class="rise">Si elle aide, elle trouvera sa place. Si elle complique, il faudra la corriger.</p>
<p class="neg rise">L'application doit rester un outil de service.</p>
</section>
<!-- 13 -->
<section class="slide close">
<div class="kicker rise" style="color:var(--teal);"><span class="num" style="-webkit-text-stroke-color:var(--teal);">∎</span> Conclusion</div>
<h2 class="rise">Les plus utiles<br>sont les plus <em>simples</em></h2>
<div class="pillars rise">
<span>Le <em>groupe</em> est important.</span>
<span>Les <em>membres</em> sont importants.</span>
<span>Le <em>message</em> est important.</span>
<span>Le <em>service</em> est important.</span>
</div>
<p class="rise">Nous laisserons ensuite l'expérience parler d'elle-même.</p>
</section>
</div>
</div>
<div class="hint" id="hint">glissez pour avancer</div>
<div class="nav">
<button id="prev" aria-label="Précédent">‹</button>
<div class="counter"><b id="cur">01</b> / <span id="tot">14</span></div>
<button id="next" aria-label="Suivant">›</button>
</div>
<script>
const track=document.getElementById('track');
const slides=[...track.children];
const prog=document.getElementById('prog');
const prevB=document.getElementById('prev');
const nextB=document.getElementById('next');
const cur=document.getElementById('cur');
document.getElementById('tot').textContent=String(slides.length).padStart(2,'0');
let i=0;
function go(n){
n=Math.max(0,Math.min(slides.length-1,n));
if(n===i){return;}
slides[i].classList.remove('active');
i=n;
track.style.transform='translateX(-'+(i*100)+'%)';
const s=slides[i];
s.scrollTop=0;
// restart entrance animations
s.classList.remove('active');void s.offsetWidth;s.classList.add('active');
cur.textContent=String(i+1).padStart(2,'0');
prog.style.width=(i/(slides.length-1)*100)+'%';
prevB.disabled=i===0;
nextB.disabled=i===slides.length-1;
}
prog.style.width='0%';
prevB.disabled=true;
nextB.onclick=()=>go(i+1);
prevB.onclick=()=>go(i-1);
document.addEventListener('keydown',e=>{
if(e.key==='ArrowRight'){go(i+1);}
if(e.key==='ArrowLeft'){go(i-1);}
});
let x0=null,y0=null;
track.addEventListener('touchstart',e=>{x0=e.touches[0].clientX;y0=e.touches[0].clientY;},{passive:true});
track.addEventListener('touchend',e=>{
if(x0===null){return;}
const dx=e.changedTouches[0].clientX-x0;
const dy=e.changedTouches[0].clientY-y0;
if(Math.abs(dx)>48 && Math.abs(dx)>Math.abs(dy)*1.3){
if(dx<0){go(i+1);}else{go(i-1);}
}
x0=y0=null;
},{passive:true});
</script>
</body>
</html>

View file

@ -124,6 +124,13 @@ export default function Login() {
{loading ? '...' : 'Connexion'}
</button>
<a
href="/presentation.html"
className="block w-full p-3 bg-blue-50 text-aa-blue rounded-xl text-center text-sm font-bold"
>
Découvrir l'application
</a>
<button
type="button"
onClick={() => setPage('inscription')}