|
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Mockup — Plan d'action (ticket #22)</title>
|
|
<style>
|
|
:root {
|
|
--primary:#78c738; --primary-hover:#609f2d; --primary-100:#e4f4d7; --primary-700:#487722;
|
|
--secondary:#50a7af; --accent:#de8c21; --accent-100:#f8e8d3; --accent-700:#855414;
|
|
--danger:#ef4444; --slate-200:#e2e8f0; --slate-500:#64748b; --slate-700:#334155; --slate-900:#0f172a;
|
|
}
|
|
* { box-sizing:border-box; }
|
|
body { font-family:'Geist Sans',system-ui,Arial,sans-serif; background:#f8fafc; color:var(--slate-900); margin:0; padding:32px; }
|
|
h1 { font-size:20px; margin:0 0 4px; }
|
|
.sub { color:var(--slate-500); font-size:13px; margin:0 0 24px; }
|
|
.grid { display:flex; gap:24px; flex-wrap:wrap; align-items:flex-start; }
|
|
.card { background:#fff; border:1px solid var(--slate-200); border-radius:12px; padding:20px; width:360px; box-shadow:0 1px 2px rgba(0,0,0,.04); }
|
|
.role { font-size:16px; font-weight:600; }
|
|
.meta { font-size:13px; color:var(--slate-500); margin-top:2px; }
|
|
.stack { display:flex; gap:6px; flex-wrap:wrap; margin:12px 0; }
|
|
.chip { background:#dcedef; color:#306469; border:1px solid #b9dcdf; border-radius:999px; padding:2px 10px; font-size:12px; font-weight:500; }
|
|
.divider { border-top:1px solid #f1f5f9; margin:14px 0; }
|
|
.label { font-size:11px; text-transform:uppercase; letter-spacing:.04em; color:var(--slate-500); font-weight:600; margin-bottom:8px; }
|
|
|
|
/* Bouton CTA — états */
|
|
.btn { width:100%; border:none; border-radius:10px; padding:11px 16px; font-size:14px; font-weight:600; cursor:pointer; display:flex; align-items:center; justify-content:center; gap:8px; }
|
|
.btn-default { background:var(--primary); color:#fff; }
|
|
.btn-default:hover { background:var(--primary-hover); }
|
|
.btn-loading { background:var(--primary); color:#fff; opacity:.85; cursor:progress; }
|
|
.spinner { width:15px; height:15px; border:2px solid rgba(255,255,255,.4); border-top-color:#fff; border-radius:50%; animation:spin .7s linear infinite; }
|
|
@keyframes spin { to { transform:rotate(360deg); } }
|
|
|
|
/* Checklist inline */
|
|
.checklist { list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:12px; }
|
|
.item { display:flex; gap:10px; }
|
|
.bullet { width:18px; height:18px; flex:0 0 18px; margin-top:1px; border-radius:5px; border:1.5px solid var(--primary); color:var(--primary); display:flex; align-items:center; justify-content:center; font-size:11px; }
|
|
.action { font-size:14px; font-weight:500; color:var(--slate-900); line-height:1.35; }
|
|
.why { font-size:12.5px; font-style:italic; color:var(--slate-500); line-height:1.35; margin-top:2px; }
|
|
|
|
/* Badges de confiance */
|
|
.badges { display:flex; gap:10px; flex-wrap:wrap; margin-top:14px; }
|
|
.badge { border-radius:999px; padding:4px 12px; font-size:12px; font-weight:600; display:inline-flex; align-items:center; gap:6px; border:1px solid; }
|
|
.badge .dot { width:7px; height:7px; border-radius:50%; }
|
|
.b-high { background:var(--primary-100); color:var(--primary-700); border-color:#c9e9af; }
|
|
.b-high .dot { background:var(--primary); }
|
|
.b-mid { background:var(--accent-100); color:var(--accent-700); border-color:#f2d1a6; }
|
|
.b-mid .dot { background:var(--accent); }
|
|
.b-low { background:#fee2e2; color:#b91c1c; border-color:#fecaca; }
|
|
.b-low .dot { background:var(--danger); }
|
|
|
|
.conf-row { display:flex; justify-content:space-between; align-items:center; margin-top:6px; }
|
|
.regen { font-size:11.5px; color:var(--secondary); cursor:pointer; text-decoration:underline; }
|
|
|
|
/* États annexes */
|
|
.state-box { font-size:13px; border-radius:10px; padding:12px 14px; }
|
|
.state-loading { background:#f1f5f9; color:var(--slate-700); display:flex; align-items:center; gap:10px; }
|
|
.skel { height:12px; border-radius:6px; background:linear-gradient(90deg,#e2e8f0 25%,#f1f5f9 50%,#e2e8f0 75%); background-size:200% 100%; animation:sh 1.2s infinite; }
|
|
@keyframes sh { to { background-position:-200% 0; } }
|
|
.state-error { background:#fef2f2; color:#b91c1c; border:1px solid #fecaca; }
|
|
.retry { color:#b91c1c; font-weight:600; text-decoration:underline; cursor:pointer; }
|
|
.state-empty { background:#f8fafc; color:var(--slate-500); border:1px dashed var(--slate-200); }
|
|
.persist-flag { font-size:11px; color:var(--secondary); margin-top:10px; display:flex; align-items:center; gap:6px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Plan d'action — bouton + checklist inline (ticket #22)</h1>
|
|
<p class="sub">Charte GetYourJob v2.3 — Primary = Willow Green #78c738 (le #1A73E8 du ticket est réconcilié sur la primaire de marque). Tout est inline : aucune modale, aucun panneau latéral.</p>
|
|
|
|
<div class="grid">
|
|
|
|
<!-- 1. Bouton — état par défaut -->
|
|
<div class="card">
|
|
<div class="role">Senior Frontend Engineer</div>
|
|
<div class="meta">Doctolib · ESN · Paris · Remote</div>
|
|
<div class="stack"><span class="chip">React</span><span class="chip">TypeScript</span><span class="chip">Next.js</span></div>
|
|
<div class="divider"></div>
|
|
<div class="label">Bouton — défaut</div>
|
|
<button class="btn btn-default"><span>✨</span> Générer un plan d'action</button>
|
|
<div class="label" style="margin-top:18px">Bouton — génération en cours</div>
|
|
<button class="btn btn-loading"><span class="spinner"></span> Génération du plan…</button>
|
|
</div>
|
|
|
|
<!-- 2. Checklist générée (état populé + persisté) -->
|
|
<div class="card">
|
|
<div class="role">Senior Frontend Engineer</div>
|
|
<div class="meta">Doctolib · ESN · Paris · Remote</div>
|
|
<div class="stack"><span class="chip">React</span><span class="chip">TypeScript</span><span class="chip">Next.js</span></div>
|
|
<div class="divider"></div>
|
|
<div class="label">Plan d'action (le bouton est remplacé en place)</div>
|
|
<ul class="checklist">
|
|
<li class="item">
|
|
<span class="bullet">✓</span>
|
|
<div>
|
|
<div class="action">Trouver le responsable recrutement sur LinkedIn</div>
|
|
<div class="why">Cette entreprise est une ESN, le manager a plus de poids que les RH.</div>
|
|
</div>
|
|
</li>
|
|
<li class="item">
|
|
<span class="bullet">✓</span>
|
|
<div>
|
|
<div class="action">Personnaliser votre message d'approche sur le stack React</div>
|
|
<div class="why">Leur offre insiste sur la performance front : citez une optimisation concrète.</div>
|
|
</div>
|
|
</li>
|
|
<li class="item">
|
|
<span class="bullet">✓</span>
|
|
<div>
|
|
<div class="action">Préparer 2 questions sur leur passage à Next.js</div>
|
|
<div class="why">Montre une veille active et ouvre un échange technique dès le premier contact.</div>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
<div class="conf-row">
|
|
<div class="badges">
|
|
<span class="badge b-high"><span class="dot"></span>Confiance : Élevée</span>
|
|
</div>
|
|
<span class="regen">Régénérer</span>
|
|
</div>
|
|
<div class="persist-flag">🔖 Persisté — restitué tel quel depuis le dashboard (aucune régénération)</div>
|
|
</div>
|
|
|
|
<!-- 3. Variantes de badge + états annexes -->
|
|
<div class="card">
|
|
<div class="label">Badge de confiance — 3 variantes</div>
|
|
<div class="badges">
|
|
<span class="badge b-high"><span class="dot"></span>Confiance : Élevée</span>
|
|
<span class="badge b-mid"><span class="dot"></span>Confiance : Moyenne</span>
|
|
<span class="badge b-low"><span class="dot"></span>Confiance : Faible</span>
|
|
</div>
|
|
<div class="divider"></div>
|
|
|
|
<div class="label">État — chargement (skeleton)</div>
|
|
<div class="state-box state-loading">
|
|
<span class="spinner" style="border-color:#cbd5e1;border-top-color:#64748b"></span>
|
|
<div style="flex:1; display:flex; flex-direction:column; gap:7px">
|
|
<div class="skel" style="width:85%"></div>
|
|
<div class="skel" style="width:60%"></div>
|
|
<div class="skel" style="width:72%"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="label" style="margin-top:16px">État — erreur</div>
|
|
<div class="state-box state-error">
|
|
Impossible de générer le plan d'action. <span class="retry">Réessayer</span>
|
|
</div>
|
|
|
|
<div class="label" style="margin-top:16px">État — vide (aucune recommandation)</div>
|
|
<div class="state-box state-empty">
|
|
Pas assez d'informations sur cette entreprise pour générer un plan. Réessayez plus tard.
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|