/* ==========================================================
FITZUNIVERSE — DIAGNOSTIC FITZ AI (results.html)
Repose sur les variables et le reset définis dans css/base.css
(même palette, même typographie, même système que index.html,
eligibility-test.html et eligibility-questions.html)
========================================================== */

body{

padding:60px 20px 100px;

}

.container{

width:100%;

max-width:820px;

margin:0 auto;

}

/* ==========================================================
RÉVÉLATION AU DÉFILEMENT
========================================================== */

.reveal{

opacity:1;

transform:none;

}

html.js-ready .reveal{

opacity:0;

transform:translateY(22px);

transition:opacity .7s var(--ease-premium), transform .7s var(--ease-premium);

}

html.js-ready .reveal.is-visible{

opacity:1;

transform:translateY(0);

}

@media (prefers-reduced-motion: reduce){

.reveal{

opacity:1 !important;

transform:none !important;

transition:none !important;

}

}

/* ==========================================================
EN-TÊTE
========================================================== */

/* Badge Fitz : apparence définie une seule fois dans css/base.css
(section "BADGE FITZ — signature unique"). Ne reste ici que
l'espacement propre à cette page. Vaut pour les DEUX badges de
results.html — celui de l'écran de chargement et celui de l'en-tête
du diagnostic — qui doivent rester identiques entre eux : c'est le
même Fitz avant et après le calcul. */
.ai-badge{

margin:0 auto 20px;

}

/* ==========================================================
ÉTAT DE CHARGEMENT — le temps que results.js charge le catalogue
Firestore et calcule de vraies opportunités (voir results.js). Seule
animation en boucle de cette page : transitoire, jamais montrée plus
de quelques secondes, retirée du DOM visuel dès que le rendu réel est
prêt.
========================================================== */

.results-loading{

display:flex;

flex-direction:column;

align-items:center;

gap:18px;

padding:120px 20px;

text-align:center;

}

/* Sans cette règle, l'attribut hidden posé par results.js:setLoading()
n'a AUCUN effet ici : la règle navigateur [hidden]{display:none} est
une feuille de style UA, que le display:flex ci-dessus — style
auteur — bat systématiquement. Le spinner « Fitz croise votre profil
avec le catalogue… » restait donc affiché en permanence AU-DESSUS du
diagnostic terminé, sur toutes les pages de résultats.

#resultsContent n'avait pas le problème (un div sans display déclaré
suit bien [hidden]), ce qui rendait le bug d'autant plus discret :
le contenu apparaissait normalement, il était juste précédé d'un
chargement qui ne se terminait jamais. */
.results-loading[hidden]{

display:none;

}

.results-loading p{

color:var(--text-light);

font-weight:600;

font-size:.95rem;

}

.results-loading-spinner{

width:36px;

height:36px;

border-radius:50%;

border:3px solid var(--background-alt);

border-top-color:var(--fitz-color);

animation:resultsSpin .8s linear infinite;

}

@keyframes resultsSpin{
to{ transform:rotate(360deg); }
}

@media (prefers-reduced-motion: reduce){

.results-loading-spinner{

animation:none;

border-top-color:var(--background-alt);

}

}

h1{

text-align:center;

font-size:clamp(1.8rem,4vw,2.4rem);

font-weight:800;

color:var(--text-color);

margin-bottom:32px;

}

/* ==========================================================
RÉCIT D'OUVERTURE
========================================================== */

.narrative-card{

display:flex;

align-items:flex-start;

gap:16px;

background:var(--background);

border:1px solid var(--border-color);

border-radius:var(--radius-lg);

padding:26px;

margin-bottom:32px;

box-shadow:var(--shadow-sm);

}

/* Icône nue, plus de pastille carrée en dégradé derrière elle
(retour utilisateur du 2026-08-22 : "je ne veux plus voir des icônes
comme celui en bleu, ils ne sont pas modernes"). Même décision que
sur les cartes flottantes de la page d'accueil — l'icône est colorée
par la couleur qui lui correspond au lieu d'être posée dans un
conteneur.

Couleur : --accent-600 plutôt que --fitz-color (#8B7CF6). Le violet
Fitz ne fait que 3,33:1 sur blanc — assez pour un décor, trop juste
pour un glyphe qui identifie qui parle. --accent-600 est le même
violet en plus dense (5,73:1) et reste dans la famille Fitz.

Le léger margin-top compense l'écart entre le haut du glyphe et la
première ligne de texte, que le flex align-items:flex-start ne
rattrape pas une fois le conteneur supprimé. */
/* Ciblé par la structure (enfant direct), pas seulement par la classe :
Lucide remplace le <i data-lucide> par un <svg> à l'exécution et ne
garantit pas de reporter les classes de l'élément d'origine. C'est la
convention suivie partout ailleurs dans ce dépôt ("parent i, parent
svg") — la classe reste dans le HTML comme point d'accroche lisible,
la mise en forme ne dépend pas d'elle. */
.narrative-card > i,
.narrative-card > svg,
.narrative-card > .assistant-avatar{

flex-shrink:0;

width:24px;

height:24px;

margin-top:3px;

color:var(--accent-600);

}

.narrative-text p{

color:var(--text-color);

line-height:1.75;

font-weight:500;

margin-bottom:10px;

}

.narrative-text p:last-child{

margin-bottom:0;

}

/* ==========================================================
TONS D'ÉTAT — vert / ambre / rouge (2026-08-22)
==========================================================
Le score et chaque ligne de sa décomposition étaient rendus en bleu
de marque, quelle que soit leur valeur : un 31/100 et un 92/100
avaient rigoureusement le même aspect, et la couleur ne portait donc
aucune information. Ces trois classes portent le ton — et rien
d'autre : elles ne décrivent aucun composant, elles ne font que poser
les 4 variables que l'anneau, les barres, le nombre et la pastille
consomment ensuite.

C'est le seul endroit du fichier où une valeur vert/ambre/rouge est
écrite. Un composant qui doit réagir au ton lit --tone-* ; il ne
redéclare jamais ses propres verts.

  --tone-1 / --tone-2   les deux arrêts du dégradé (surfaces)
  --tone-text           la seule valeur admise pour du texte ou une
                        icône porteuse de sens (les *-700 de
                        css/base.css tiennent AA sur fond clair,
                        contrairement à --success/--warning/--danger
                        bruts — voir la note de l'échelle d'état)
  --tone-glow           halo, purement décoratif

Le ton n'est jamais décidé ici : results.js pose is-positive/is-moyen/
is-faible d'après scoreTier() et toneForValue() (js/fitz-voice.js),
qui portent aussi le libellé du palier. Couleur et libellé viennent
donc de la même déclaration et ne peuvent pas se contredire.
========================================================== */

/* Repli neutre, pour tout composant qui lit --tone-* avant que
results.js ait posé sa classe de ton (script en erreur, rendu
interrompu) : gris, jamais un vert ou un rouge par défaut, qui
annoncerait un résultat non calculé.

:where() est indispensable ici, pas cosmétique — il annule la
spécificité du sélecteur. Écrit normalement, `.score-breakdown-row`
pèse autant que `.is-positive` (0,1,0) et, comme il vient plus bas
dans le fichier, il l'emporterait : toutes les barres restaient
grises malgré la bonne classe de ton. Avec :where(), le repli pèse 0
et n'importe quelle classe de ton le bat. */
:where(.score-section, .score-breakdown-row, .improvement-free){

--tone-1:var(--text-decorative);

--tone-2:var(--text-muted);

--tone-text:var(--text-light);

--tone-glow:rgba(26,23,20,.12);

}

.is-positive{

--tone-1:var(--success-500);

--tone-2:var(--success-600);

--tone-text:var(--success-700);

--tone-glow:rgba(22,163,74,.28);

}

.is-moyen{

--tone-1:var(--warning-500);

--tone-2:var(--warning-600);

--tone-text:var(--warning-700);

--tone-glow:rgba(217,119,6,.28);

}

.is-faible{

--tone-1:var(--danger-500);

--tone-2:var(--danger-600);

--tone-text:var(--danger-700);

--tone-glow:rgba(220,38,38,.26);

}

/* ==========================================================
SCORE
========================================================== */

.score-section{

display:flex;

align-items:center;

gap:36px;

background:var(--background);

border:1px solid var(--border-color);

border-radius:var(--radius-lg);

padding:36px;

margin-bottom:32px;

box-shadow:var(--shadow-md);

}

.score-ring{

--score-percent:0;

flex-shrink:0;

position:relative;

width:168px;

height:168px;

display:flex;

align-items:center;

justify-content:center;

}

.score-ring-svg{

position:absolute;

inset:0;

width:100%;

height:100%;

/* Le tracé d'un <circle> SVG démarre à 3 h : sans cette rotation
l'anneau se remplirait depuis la droite au lieu du sommet. */
transform:rotate(-90deg);

overflow:visible;

}

/* Les deux arrêts du dégradé de l'anneau. En propriété CSS (et non en
attribut stop-color dans le HTML, où var() n'est pas résolu) : les
variables de ton, héritées depuis .score-section, s'appliquent alors
normalement. */
.score-ring-stop-1{ stop-color:var(--tone-1); }

.score-ring-stop-2{ stop-color:var(--tone-2); }

.score-ring-track{

fill:none;

stroke:var(--background-alt);

stroke-width:9;

}

.score-ring-progress{

fill:none;

stroke:url(#scoreRingGradient);

stroke-width:10;

/* L'extrémité arrondie est la vraie différence visuelle avec
l'ancien conic-gradient, qui coupait l'arc net. */
stroke-linecap:round;

/* 2π×52 ≈ 326.73 — voir le commentaire sur r=52 dans results.html.
L'arc visible vaut la circonférence moins l'offset : offset plein
(326.73) = anneau vide, offset nul = anneau complet. */
stroke-dasharray:326.73;

stroke-dashoffset:calc(326.73 - 326.73 * var(--score-percent) / 100);

filter:drop-shadow(0 3px 8px var(--tone-glow));

/* Part de 0 et se remplit une fois le score connu (results.js pose
--score-percent après le rendu, sur un frame séparé). */
transition:stroke-dashoffset 1.2s var(--ease-premium);

}

@media (prefers-reduced-motion: reduce){

.score-ring-progress{transition:none;}

}

.score-ring-inner{

position:relative;

z-index:1;

display:flex;

align-items:baseline;

justify-content:center;

width:132px;

height:132px;

border-radius:50%;

background:var(--background);

}

#score{

font-family:var(--font-display);

font-size:2.7rem;

font-weight:800;

/* Le chiffre porte lui aussi le ton : c'est l'élément que l'œil lit
en premier, il serait incohérent qu'il reste bleu dans un anneau
rouge. --tone-text (et non --tone-1/2) parce que c'est du texte. */
color:var(--tone-text);

font-variant-numeric:tabular-nums;

transition:color .6s var(--ease-premium);

}

.score-suffix{

font-size:1rem;

font-weight:700;

color:var(--text-muted);

margin-left:2px;

}

.score-copy{

flex:1;

min-width:0;

}

/* Pastille du palier ("Profil compétitif"...). Fond teinté + texte
--tone-text : le libellé et l'anneau disent alors la même chose au
même moment. La bordure fine évite que la pastille disparaisse pour
un daltonien — la couleur n'est jamais le seul porteur du sens ici,
le libellé l'énonce en toutes lettres. */
.score-label{

display:inline-block;

margin-bottom:10px;

padding:6px 14px;

border-radius:var(--radius-full);

background:color-mix(in srgb, var(--tone-text) 10%, transparent);

border:1px solid color-mix(in srgb, var(--tone-text) 22%, transparent);

color:var(--tone-text);

font-weight:700;

font-size:.82rem;

letter-spacing:.01em;

}

.score-copy p{

color:var(--text-color);

line-height:1.7;

margin-bottom:12px;

}

.score-note{

display:flex;

align-items:flex-start;

gap:8px;

font-size:.85rem;

color:var(--text-light);

line-height:1.6;

}

.score-note i,
.score-note svg{

flex-shrink:0;

width:16px;

height:16px;

margin-top:2px;

color:var(--primary-color);

}

/* ==========================================================
DÉCOMPOSITION DU SCORE
========================================================== */

.score-breakdown{

background:var(--background);

border:1px solid var(--border-color);

border-radius:var(--radius-lg);

padding:24px 26px;

box-shadow:var(--shadow-sm);

display:flex;

flex-direction:column;

gap:16px;

}

.score-breakdown-row{

display:grid;

grid-template-columns:170px 1fr 44px;

align-items:center;

gap:14px;

}

.score-breakdown-label{

display:flex;

align-items:center;

gap:8px;

font-size:.92rem;

color:var(--text-color);

font-weight:500;

}

.score-breakdown-icon{

display:inline-flex;

align-items:center;

justify-content:center;

}

/* L'icône de l'axe prend le ton de SA ligne : sur la ligne "Langue"
à 100% elle est verte, sur "Formation" à 60% elle est ambre. C'est
ce qui rend la colonne de gauche lisible d'un seul coup d'œil. */
.score-breakdown-icon i,
.score-breakdown-icon svg{

width:16px;

height:16px;

color:var(--tone-text);

}

/* Le "trait progressif" (retour utilisateur du 2026-08-22). Chaque
ligne porte is-positive/is-moyen/is-faible d'après SA propre valeur
(toneForValue, js/fitz-voice.js) — auparavant les 5 barres
partageaient --gradient-primary, donc un axe à 31% et un axe à 100%
s'affichaient dans le même bleu (voir le bloc TONS D'ÉTAT). */

.score-breakdown-bar{

position:relative;

height:9px;

border-radius:999px;

background:var(--background-alt);

/* Creuse légèrement le rail pour que la barre pleine se lise comme
posée dedans plutôt que dessinée dessus. */
box-shadow:inset 0 1px 2px rgba(23,19,16,.07);

overflow:hidden;

display:block;

}

.score-breakdown-bar span{

display:block;

height:100%;

border-radius:999px;

background:linear-gradient(90deg,var(--tone-1) 0%,var(--tone-2) 100%);

box-shadow:0 1px 4px var(--tone-glow);

transition:width .9s var(--ease-premium,ease);

}

/* Reflet en haut de la barre — le seul détail purement décoratif de
la décomposition, et la raison pour laquelle la barre a gagné 2px de
haut : en dessous de 9px le reflet devient une bouillie. */
.score-breakdown-bar span::after{

content:"";

position:absolute;

inset:0 0 auto 0;

height:50%;

border-radius:999px 999px 0 0;

background:linear-gradient(180deg,rgba(255,255,255,.28),transparent);

pointer-events:none;

}

@media (prefers-reduced-motion: reduce){

.score-breakdown-bar span{transition:none;}

}

.score-breakdown-pct{

text-align:right;

font-size:.88rem;

font-weight:700;

color:var(--tone-text);

font-variant-numeric:tabular-nums;

}

@media(max-width:600px){

.score-breakdown-row{grid-template-columns:120px 1fr 38px;gap:10px;}

}

/* ==========================================================
AMÉLIORATION — APERÇU VERROUILLÉ
========================================================== */

.improvement-free{

margin-top:18px;

display:flex;

align-items:flex-start;

gap:14px;

background:var(--background);

border:1px solid var(--border-color);

/* Le liseré gauche prend le ton de l'axe concerné, comme l'icône. */
border-left:3px solid var(--tone-text);

border-radius:var(--radius-lg);

padding:18px 20px;

box-shadow:var(--shadow-sm);

}

/* Icône nue (même retour du 2026-08-22 que .assistant-avatar), et
colorée par le ton de l'axe qu'elle désigne : c'est le point le plus
faible du profil, il s'affiche donc en ambre ou en rouge selon sa
gravité réelle plutôt qu'en bleu neutre. results.js pose la classe de
ton sur .improvement-free. */
.improvement-free > i,
.improvement-free > svg,
.improvement-free > .improvement-free-icon{

flex:0 0 auto;

width:22px;

height:22px;

margin-top:2px;

color:var(--tone-text);

}

.improvement-free-copy strong{

display:block;

font-size:.94rem;

color:var(--text-color);

margin-bottom:4px;

}

.improvement-free-copy p{

margin:0;

font-size:.86rem;

color:var(--text-muted);

line-height:1.55;

}

.reco-locked{

margin-top:18px;

display:flex;

align-items:center;

gap:18px;

background:var(--background-light);

border:1px dashed var(--border-color);

border-radius:var(--radius-lg);

padding:20px 22px;

flex-wrap:wrap;

}

/* Icône nue (même retour du 2026-08-22) — plus de pastille ronde
blanche. Gris sourd : le cadenas signale un contenu non débloqué,
pas un état bon ou mauvais du profil, il ne prend donc aucun ton. */
.reco-locked > i,
.reco-locked > svg,
.reco-locked > .reco-locked-icon{

flex:0 0 auto;

width:20px;

height:20px;

color:var(--text-muted);

}

.reco-locked-copy{flex:1 1 220px;}

.reco-locked-copy strong{

display:block;

font-size:.92rem;

color:var(--text-color);

margin-bottom:2px;

}

.reco-locked-copy p{

margin:0;

font-size:.85rem;

color:var(--text-muted);

}

/* ==========================================================
ANALYSE — POINTS FORTS / AXES DE PROGRESSION
========================================================== */

.analysis-card{

margin-top:4px;

background:var(--background);

border:1px solid var(--border-color);

border-radius:var(--radius-lg);

padding:26px;

box-shadow:var(--shadow-sm);

}

.analysis-heading{

display:flex;

align-items:center;

gap:10px;

margin-bottom:16px;

}

.analysis-heading i,
.analysis-heading svg{

width:20px;

height:20px;

}

.strengths-card .analysis-heading i,
.strengths-card .analysis-heading svg{

color:var(--success);

}

.weaknesses-card .analysis-heading i,
.weaknesses-card .analysis-heading svg{

color:var(--accent-color);

}

.analysis-heading h2{

font-size:1.02rem;

font-weight:700;

color:var(--text-color);

}

.analysis-card ul{

display:flex;

flex-direction:column;

gap:10px;

}

.analysis-card li{

display:flex;

align-items:flex-start;

gap:10px;

font-size:.92rem;

line-height:1.6;

color:var(--text-color);

}

.analysis-card li i,
.analysis-card li svg{

flex-shrink:0;

width:16px;

height:16px;

margin-top:2px;

}

.strengths-card li i,
.strengths-card li svg{

color:var(--success);

}

.weaknesses-card li i,
.weaknesses-card li svg{

color:var(--accent-color);

}

.analysis-card li.empty{

color:var(--text-light);

font-style:italic;

}

/* ==========================================================
SECTIONS GÉNÉRIQUES
========================================================== */

/* Alternance de fond entre sections (audit du 2026-08-15) : la page
enchaînait 6 <section class="section"> sans aucune rupture visuelle
(toutes sur --background, blanc uni), malgré le nombre de sujets
traités (score, points forts, destinations, opportunités, axes à
renforcer, recommandations). Aucun pattern d'alternance de section
équivalent n'existait déjà ailleurs sur le site (vérifié :
universities.html/scholarships.html/index.html n'alternent pas leurs
sections par couleur) — celui-ci reste dans les 3 tons déjà définis
dans css/base.css (--background/--background-soft/--background-alt),
aucune nouvelle couleur. .section-tint marque une section sur deux
(voir results.html) en --background-soft ; les autres restent
transparentes (le --gradient-hero du body, déjà très clair, transparaît). */
.section{

margin-bottom:32px;

padding:36px 32px;

border-radius:var(--radius-lg);

}

.section.section-tint{

background:var(--background-soft);

}

.section-heading{

display:flex;

align-items:center;

gap:10px;

margin-bottom:14px;

}

.section-heading i,
.section-heading svg{

width:22px;

height:22px;

color:var(--primary-color);

}

.section-heading h2{

font-size:1.2rem;

font-weight:700;

color:var(--text-color);

}

.section-subtext{

color:var(--text-light);

font-size:.92rem;

margin-bottom:16px;

}

.section > ul li{

display:flex;

align-items:flex-start;

gap:10px;

padding:14px 16px;

margin-bottom:10px;

background:var(--background);

border:1px solid var(--border-color);

border-radius:var(--radius-md);

font-size:.94rem;

color:var(--text-color);

line-height:1.6;

}

.section > ul li i,
.section > ul li svg{

flex-shrink:0;

width:18px;

height:18px;

margin-top:1px;

color:var(--primary-color);

}

.section > ul li.empty{

color:var(--text-light);

font-style:italic;

background:transparent;

border-style:dashed;

}

/* ==========================================================
DESTINATIONS (pills)
========================================================== */

.pill-list{

display:flex;

flex-wrap:wrap;

gap:12px;

}

.country-pill{

display:flex;

align-items:center;

gap:8px;

padding:10px 18px;

border-radius:var(--radius-full);

background:var(--background-light);

color:var(--primary-color);

font-weight:700;

font-size:.92rem;

}

.country-pill i,
.country-pill svg{

width:16px;

height:16px;

}

/* ==========================================================
OPPORTUNITÉS
========================================================== */

.opportunity-list{

display:flex;

flex-direction:column;

gap:16px;

}

.opportunity-card{

background:var(--background);

border:1px solid var(--border-color);

border-radius:var(--radius-lg);

padding:24px;

transition:var(--transition);

}

.opportunity-card:hover{

transform:translateY(-8px);

box-shadow:var(--shadow-lg);

border-color:rgba(26,23,20,.16);

}

.opportunity-head{

display:flex;

align-items:center;

gap:14px;

margin-bottom:16px;

}

/* Vignette de ville réelle (results.js, scholarship.image — même champ
"universities".image déjà utilisé par universities-page.js/details.js),
remplace l'ancienne icône générique --gradient-primary. object-fit:cover
+ dimensions fixes : les photos sources ont des ratios variés (voir
scripts/generate-city-srcset.mjs), jamais de déformation. */
.opportunity-thumb{

flex-shrink:0;

width:46px;

height:46px;

border-radius:14px;

object-fit:cover;

background:var(--background-alt);

}

.opportunity-head h3{

font-size:1.05rem;

font-weight:700;

color:var(--text-color);

margin-bottom:2px;

}

.opportunity-country{

display:inline-flex;

align-items:center;

gap:6px;

font-size:.85rem;

color:var(--text-light);

font-weight:600;

}

.opportunity-flag{

flex-shrink:0;

width:16px;

height:16px;

border-radius:3px;

object-fit:cover;

}

/* Deadline réelle du programme (recommendPrograms(), results.js) —
absente tant que les opportunités venaient des 4 pays codés en dur. */
.opportunity-deadline{

display:flex;

align-items:center;

gap:6px;

margin:10px 0 14px;

padding:8px 12px;

border-radius:var(--radius-sm);

background:var(--background-soft);

color:var(--text-light);

font-size:.82rem;

font-weight:600;

}

.opportunity-deadline i,
.opportunity-deadline svg{

flex-shrink:0;

width:14px;

height:14px;

color:var(--primary-color);

}

.opportunity-reasons-label{

font-size:.82rem;

font-weight:700;

color:var(--text-muted);

text-transform:uppercase;

letter-spacing:.03em;

margin-bottom:10px;

}

.opportunity-reasons{

display:flex;

flex-direction:column;

gap:8px;

}

.opportunity-reasons li{

display:flex;

align-items:flex-start;

gap:8px;

font-size:.92rem;

line-height:1.6;

color:var(--text-color);

}

.opportunity-reasons i,
.opportunity-reasons svg{

flex-shrink:0;

width:16px;

height:16px;

margin-top:2px;

color:var(--success);

}

p.empty{

color:var(--text-light);

font-style:italic;

}

/* ==========================================================
TRANSITION VERS L'ACCOMPAGNEMENT
========================================================== */

/* Fond passé de --gradient-primary à --gradient-deep le 2026-08-23.
La règle est déjà écrite dans css/base.css : --gradient-primary est
fait pour les PETITES surfaces (bouton, pastille, jauge), où l'on ne
voit guère que son premier arrêt lumineux #4A5BC4. Sur une carte de
56px de rembourrage occupant toute la largeur de la section, ce même
arrêt occupe un coin entier et donne le bleu électrique qui détonnait
avec le reste de la page. --gradient-deep garde la construction et la
profondeur diagonale, resserrées vers le bas de l'échelle. */

.closing-card{

text-align:center;

background:var(--gradient-deep);

border-radius:var(--radius-lg);

padding:56px 40px;

color:#fff;

}

/* Icône nue (même retour du 2026-08-22) — plus de pastille ronde
translucide. Sur le fond en dégradé de .closing-card le blanc plein
suffit largement à la détacher ; le léger halo remplace le disque
sans réintroduire de conteneur. */
.closing-card > i,
.closing-card > svg,
.closing-card > .closing-icon{

display:block;

width:34px;

height:34px;

margin:0 auto 20px;

color:#fff;

filter:drop-shadow(0 2px 6px rgba(0,0,0,.22));

}

.closing-card h2{

font-size:clamp(1.5rem,3vw,1.9rem);

font-weight:800;

margin-bottom:18px;

max-width:520px;

margin-left:auto;

margin-right:auto;

/* Sans ce color explicite, la règle globale h1-h6 (css/base.css) bat
le color:#fff hérité de .closing-card — même bug que .cta-box. */
color:#fff;

}

.closing-card p{

max-width:560px;

margin:0 auto 16px;

line-height:1.75;

opacity:.92;

color:#fff;

}

.closing-checklist{

display:grid;

grid-template-columns:1fr 1fr;

gap:10px 20px;

max-width:560px;

margin:22px auto 6px;

text-align:left;

}

.closing-checklist li{

display:flex;

align-items:flex-start;

gap:10px;

font-size:.92rem;

line-height:1.5;

font-weight:600;

}

.closing-checklist i,
.closing-checklist svg{

flex-shrink:0;

width:17px;

height:17px;

margin-top:2px;

padding:2px;

border-radius:50%;

background:rgba(255,255,255,.18);

color:#fff;

}

.closing-card .btn{

margin:18px auto 0;

}

.btn-lg{

padding:16px 30px;

font-size:1.02rem;

}

.closing-note{

display:flex;

align-items:center;

justify-content:center;

gap:8px;

margin-top:18px !important;

font-size:.85rem;

opacity:.85;

}

.closing-note i,
.closing-note svg{

width:16px;

height:16px;

}

/* ==========================================================
RESPONSIVE — TABLETTE (768–1023px)
========================================================== */

@media(max-width:1023px){

.score-section{

flex-direction:column;

text-align:center;

}

.score-copy{

text-align:center;

}

.score-note{

text-align:left;

}

}

/* ==========================================================
RESPONSIVE — MOBILE (< 768px)
========================================================== */

@media(max-width:767px){

body{

padding:36px 16px 70px;

}

.narrative-card{

padding:20px;

gap:12px;

}

.score-section{

padding:26px;

}

.section{

padding:24px 20px;

}

.score-ring{

width:128px;

height:128px;

}

.score-ring-inner{

width:102px;

height:102px;

}

#score{

font-size:2.1rem;

}

.closing-card{

padding:40px 24px;

}

.closing-checklist{

grid-template-columns:1fr;

}

}

@media(max-width:380px){

.container{

max-width:100%;

}

}


/* ============================================================
   Analyse de Fitz sur la page de résultats
   ------------------------------------------------------------
   À coller à la fin de results.css.

   Quatre états, un seul bloc : verrouillé (visiteur sans compte),
   en cours, prêt, échec. Le bloc garde la même largeur et la même
   place dans tous les cas — un cadre qui saute quand la réponse
   arrive donnerait l'impression que la page se casse.
   ============================================================ */

.fitz-analysis {
  border: 1px solid var(--border, rgba(0, 0, 0, 0.08));
  border-radius: 16px;
  padding: 24px;
  margin-bottom: 24px;
  background: var(--surface, #fff);
}

.fitz-analysis:empty {
  display: none;
}

.fitz-analysis-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.fitz-analysis-head h3 {
  margin: 0;
  font-size: 1.05rem;
  line-height: 1.3;
}

.fitz-analysis-head i,
.fitz-analysis-head svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  color: #e9a319;
}

.fitz-analysis-body h3 {
  font-size: 0.95rem;
  margin: 18px 0 6px;
}

.fitz-analysis-body h3:first-child {
  margin-top: 0;
}

.fitz-analysis-body p {
  margin: 0 0 10px;
  line-height: 1.6;
}

.fitz-analysis-body ul {
  margin: 0 0 10px;
  padding-left: 20px;
}

.fitz-analysis-note {
  font-size: 0.9rem;
  opacity: 0.75;
}

/* --- Verrouillé : le visiteur n'a pas encore de compte --- */
.fitz-analysis.is-locked {
  border-style: dashed;
}

.fitz-analysis.is-locked .btn {
  margin-top: 8px;
}

/* --- En cours : l'icône tourne, le texte s'écrit au fil de l'eau ---
   L'animation est coupée pour qui a demandé moins de mouvement ;
   l'icône reste, seule la rotation disparaît. */
.fitz-analysis.is-loading .fitz-analysis-head i,
.fitz-analysis.is-loading .fitz-analysis-head svg {
  animation: fitz-analysis-spin 1.1s linear infinite;
}

@keyframes fitz-analysis-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .fitz-analysis.is-loading .fitz-analysis-head i,
  .fitz-analysis.is-loading .fitz-analysis-head svg {
    animation: none;
  }
}

/* --- Échec : visible sans être alarmant. L'analyse est un
       supplément, son échec ne remet pas en cause le diagnostic. --- */
.fitz-analysis.is-error {
  border-color: rgba(200, 90, 40, 0.35);
}

.fitz-analysis.is-error .fitz-analysis-head i,
.fitz-analysis.is-error .fitz-analysis-head svg {
  color: #c85a28;
}

@media (max-width: 640px) {
  .fitz-analysis {
    padding: 18px;
    border-radius: 14px;
  }
}


/* --- Création de compte en place (js/creer-compte.js) ---
   Affichée dans le bloc d'analyse quand le visiteur n'a pas de
   compte. Volontairement sobre : c'est un formulaire de trois champs
   au milieu d'une page de résultats, pas une page d'inscription. */

.compte-inline {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border, rgba(0, 0, 0, 0.08));
}

.compte-inline-titre {
  margin: 0;
  font-size: 0.98rem;
}

.compte-inline-intro {
  margin: 0;
  font-size: 0.92rem;
  opacity: 0.8;
}

.compte-inline-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.compte-inline-field > span {
  font-size: 0.86rem;
  font-weight: 600;
}

.compte-inline-field input {
  width: 100%;
  min-width: 0;
  padding: 11px 13px;
  font: inherit;
  font-size: 0.95rem;
  color: inherit;
  background: #fff;
  border: 1px solid var(--border, rgba(0, 0, 0, 0.14));
  border-radius: 10px;
}

.compte-inline-field input:focus-visible {
  outline: 2px solid #e9a319;
  outline-offset: 1px;
  border-color: #e9a319;
}

/* Autofill de Chrome : sans cette règle, le champ rempli
   automatiquement repasse en bleu clair. Même recette que auth.css. */
.compte-inline-field input:-webkit-autofill,
.compte-inline-field input:-webkit-autofill:focus {
  -webkit-text-fill-color: inherit;
  box-shadow: 0 0 0 1000px #fff inset;
}

.compte-inline-field small {
  font-size: 0.8rem;
  opacity: 0.65;
}

.compte-inline-error {
  margin: 0;
  padding: 9px 12px;
  font-size: 0.88rem;
  color: #8a2f10;
  background: rgba(200, 90, 40, 0.09);
  border-radius: 9px;
}

.compte-inline button[type="submit"] {
  align-self: flex-start;
}

.compte-inline button[type="submit"][disabled] {
  opacity: 0.65;
  cursor: default;
}

.compte-inline-note {
  margin: 0;
  font-size: 0.82rem;
  opacity: 0.65;
}

@media (max-width: 640px) {
  .compte-inline button[type="submit"] {
    align-self: stretch;
    justify-content: center;
  }
}

/* ============================================================
   LA RÉFLEXION DE FITZ — 2026-09-05

   Six étapes affichées pendant que le diagnostic se calcule. Ce n'est
   pas un sablier déguisé : chaque ligne porte une grandeur réelle
   (nombre de bourses parcourues, d'opportunités retenues, d'échéances
   encore ouvertes) et n'apparaît que lorsque son étape commence.

   L'étape en cours tourne, les précédentes se cochent. Rien ne
   disparaît : l'étudiant doit pouvoir relire ce qui a été fait pour
   lui, c'est tout l'objet de ces quinze secondes.
   ============================================================ */

.reflexion {
  list-style: none;
  margin: 20px auto 0;
  padding: 0;
  max-width: 460px;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.reflexion-step {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 0.95rem;
  line-height: 1.45;
  opacity: 0;
  transform: translateY(6px);
  animation: reflexion-entree 0.35s ease forwards;
}

@keyframes reflexion-entree {
  to { opacity: 1; transform: none; }
}

.reflexion-step i,
.reflexion-step svg {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  margin-top: 2px;
  color: #e9a319;
}

/* L'étape en cours : l'icône tourne. Coupée pour qui a demandé moins
   de mouvement — l'icône reste, seule la rotation disparaît. */
.reflexion-step.is-current i,
.reflexion-step.is-current svg {
  animation: reflexion-rotation 1.1s linear infinite;
}

@keyframes reflexion-rotation {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .reflexion-step { animation: none; opacity: 1; transform: none; }
  .reflexion-step.is-current i,
  .reflexion-step.is-current svg { animation: none; }
}

/* Étape terminée : la coche remplace le sablier, le texte s'efface
   légèrement pour que l'attention reste sur la ligne en cours. */
.reflexion-step.is-done {
  opacity: 0.62;
}

.reflexion-step.is-done i,
.reflexion-step.is-done svg {
  animation: none;
}

.reflexion-step.is-done::marker { content: none; }

@media (max-width: 640px) {
  .reflexion {
    max-width: none;
    gap: 12px;
  }
  .reflexion-step { font-size: 0.92rem; }
}
