/* Le site vitrine d'Oléo : la feuille commune à toutes ses pages.

   Elle réunit les styles des cadres de la maquette « Oléo — Site vitrine »
   (canevas Design du 16/10/2026). La mise en page elle-même vit en ligne dans
   les gabarits de views/vitrine/, comme dans la maquette : on peut ainsi
   comparer une section à son cadre, attribut par attribut. Ne viennent ici que
   ce qu'un attribut style ne sait pas dire — survols, focus, animations,
   requêtes média — et les familles de blocs répétées (questions, textes
   légaux, champs de formulaire).

   Aucun lien avec css/oleo.css : l'application et le site ne partagent ni
   gabarit ni feuille, seulement les couleurs. */

/* Les polices sont servies par nous, et non par Google Fonts. La page
   Confidentialité promet « aucun service tiers » : une police chargée chez
   Google lui transmettrait l'adresse IP de chaque visiteur. Ce sont des polices
   variables, un seul fichier couvre donc toutes les graisses. Sous-ensembles
   latin et latin étendu seulement (le vietnamien est écarté). */
@font-face {
    font-family: 'DM Sans';
    font-style: normal;
    font-weight: 100 1000;
    font-display: swap;
    src: url(polices/dm-sans-latin-ext.woff2) format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'DM Sans';
    font-style: normal;
    font-weight: 100 1000;
    font-display: swap;
    src: url(polices/dm-sans-latin.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Darker Grotesque';
    font-style: normal;
    font-weight: 300 900;
    font-display: swap;
    src: url(polices/darker-grotesque-latin-ext.woff2) format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Darker Grotesque';
    font-style: normal;
    font-weight: 300 900;
    font-display: swap;
    src: url(polices/darker-grotesque-latin.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

body { margin: 0; background: #FEF7EC; }
a { color: #2e4254; }
a:hover { color: #222c36; }

.o-page *, .o-page *::before, .o-page *::after { box-sizing: border-box; }
.o-page :focus-visible { outline: 3px solid #2e4254; outline-offset: 3px; }
.o-foot :focus-visible, .o-dark :focus-visible { outline-color: #FEF7EC; }

.o-skip { position: absolute; left: 16px; top: -80px; z-index: 20; background: #2e4254; color: #FEF7EC; padding: 12px 16px; border-radius: 8px; }
.o-skip:focus { top: 12px; color: #FEF7EC; }

/* Boutons. Le !important n'est pas une paresse : les couleurs de repos sont
   posées en ligne dans les gabarits, et seule une règle !important passe
   au-dessus d'un attribut style. */
.o-btn { transition: background-color .2s ease, color .2s ease, transform .25s cubic-bezier(.2,.7,.2,1), box-shadow .25s ease; }
.o-btn-c { box-shadow: 0 8px 24px -8px rgba(255,142,97,.75); }
.o-btn-c:hover { background: #f57a4a !important; color: #FFFFFF !important; transform: translateY(-2px); box-shadow: 0 14px 30px -10px rgba(251,110,150,.75); }
.o-btn-a:hover { background: #222c36 !important; color: #FEF7EC !important; transform: translateY(-2px); }
.o-btn-l:hover { background: rgba(255,255,255,.7) !important; }

/* Liens. Le soulignement de survol était écrit sans !important, et ne
   passait donc jamais au-dessus du « text-decoration:none » que chaque lien
   porte en ligne : aucun ne se soulignait. Couleur et épaisseur vont dans le
   même raccourci : écrites à part, elles perdraient contre ce style en ligne,
   qui les fixe lui aussi. */
.o-nav a:hover, .o-lnk:hover { text-decoration: underline 2px #FB6E96 !important; text-underline-offset: 5px; }
.o-foot a:hover, .o-dark a:not(.o-btn):hover { color: #FFFFFF !important; text-decoration: underline !important; text-underline-offset: 5px; }

/* Les liens de texte (.o-lnk) s'annoncent par une flèche : vers la droite
   pour une autre page, vers le bas pour une ancre de la même page. C'est un
   masque teint de la couleur du lien, pour qu'il suive son survol. Bloc en
   ligne : le soulignement passe sous le texte, pas sous la flèche. Le fil
   d'Ariane n'en a pas — ce n'est pas une invitation, c'est un repère. */
.o-lnk::after {
    content: ""; display: inline-block; width: .95em; height: .95em; margin-left: .4em; vertical-align: -.14em;
    background-color: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E") center / contain no-repeat;
    transition: transform .2s ease;
}
.o-lnk[href^="#"]::after {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 5v14M5 12l7 7 7-7'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 5v14M5 12l7 7 7-7'/%3E%3C/svg%3E");
}
.o-lnk:hover::after { transform: translateX(3px); }
.o-lnk[href^="#"]:hover::after { transform: translateY(3px); }
nav[aria-label="Fil d'Ariane"] .o-lnk::after { content: none; }
/* Les liens des sections sombres portent déjà leur flèche, en SVG : elle
   avance de même au survol. */
.o-dark a > svg:last-child { transition: transform .2s ease; }
.o-dark a:hover > svg:last-child { transform: translateX(3px); }

/* Le menu de téléphone : un <details>, qui s'ouvre et se ferme sans script. */
.o-mnav { display: none; }
@media (max-width: 980px) {
    .o-dnav { display: none !important; }
    .o-mnav { display: block !important; }
    .o-float { display: none !important; }
}
.o-page summary { list-style: none; cursor: pointer; }
.o-page summary::-webkit-details-marker { display: none; }

/* Verre dépoli, ombres teintées de rose. */
.o-glass { background: rgba(255,255,255,.58); -webkit-backdrop-filter: blur(18px) saturate(1.4); backdrop-filter: blur(18px) saturate(1.4); border: 1px solid rgba(255,255,255,.8); }
.o-glass-d { background: rgba(254,247,236,.06); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); border: 1px solid rgba(254,247,236,.14); }
/* Les photos légendées sur verre (une par page). Sous 720 px, le bandeau
   16/7,4 devient plus bas que sa légende, posée dessus en absolu : le titre
   débordait du cadre et y était rogné, ou la légende masquait toute la photo.
   La légende passe donc sous la photo, qu'elle ne chevauche plus que de son
   bord de verre, et la photo reprend de la hauteur. */
@media (max-width: 720px) {
    figure:has(> .o-zoom + figcaption.o-glass) { background: #FFFFFF; }
    figure > img.o-zoom { aspect-ratio: 4 / 3 !important; }
    figure > .o-zoom + figcaption.o-glass { position: relative !important; left: auto !important; bottom: auto !important; max-width: none !important; margin-top: -28px; border-width: 1px 0 0; border-radius: 24px 24px 0 0 !important; }
}
.o-sh { box-shadow: 0 1px 2px rgba(46,66,84,.06), 0 10px 28px -8px rgba(46,66,84,.16), 0 36px 72px -28px rgba(251,110,150,.32); }
.o-sh-s { box-shadow: 0 1px 2px rgba(46,66,84,.06), 0 8px 22px -10px rgba(46,66,84,.18); }
.o-lift { transition: transform .45s cubic-bezier(.2,.7,.2,1), box-shadow .45s ease; }
.o-lift:hover { transform: translateY(-6px); box-shadow: 0 1px 2px rgba(46,66,84,.06), 0 18px 40px -12px rgba(46,66,84,.2), 0 44px 80px -28px rgba(251,110,150,.4); }

/* Les halos qui dérivent derrière les sections. */
.o-halo { position: absolute; border-radius: 50%; filter: blur(72px); pointer-events: none; will-change: transform; }
/* Les halos s'estompent vers les bords de leur section au lieu d'y être
   tranchés net : sur un fond crème continu, la coupure dessinait une ligne en
   travers de la page — sous les annotations de l'accueil, juste au-dessus des
   questions fréquentes. Le haut de page ne s'estompe que vers le bas, et pas
   quand il touche une section à fond plein (.o-dark, .o-fond, comme sur
   Tarifs) : une bande pâle les séparerait. Les sections sombres gardent leurs
   halos entiers, leur fond s'arrêtant de toute façon net. Une section crème
   qui ne fait que porter une carte sombre n'est donc pas .o-dark : la classe
   va sur la carte, sinon ses halos tranchent la page au ras de la carte. */
main > section:not(:first-child):not(.o-dark) > .o-halos {
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 100px, #000 calc(100% - 100px), transparent);
    mask-image: linear-gradient(180deg, transparent, #000 100px, #000 calc(100% - 100px), transparent);
}
main > section:first-child > .o-halos {
    -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 120px), transparent);
    mask-image: linear-gradient(180deg, #000 calc(100% - 120px), transparent);
}
main > section:first-child:has(+ section.o-dark, + section.o-fond) > .o-halos { -webkit-mask-image: none; mask-image: none; }
@keyframes o-drift-a { 0%, 100% { transform: translate3d(0,0,0) scale(1); } 50% { transform: translate3d(70px,-40px,0) scale(1.15); } }
@keyframes o-drift-b { 0%, 100% { transform: translate3d(0,0,0) scale(1.1); } 50% { transform: translate3d(-60px,50px,0) scale(.92); } }
@keyframes o-drift-c { 0%, 100% { transform: translate3d(0,0,0) scale(.95); } 50% { transform: translate3d(40px,40px,0) scale(1.12); } }
.o-da { animation: o-drift-a 18s ease-in-out infinite; }
.o-db { animation: o-drift-b 22s ease-in-out infinite; }
.o-dc { animation: o-drift-c 26s ease-in-out infinite; }
@keyframes o-pulse { 0% { box-shadow: 0 0 0 0 rgba(251,110,150,.55); } 70% { box-shadow: 0 0 0 10px rgba(251,110,150,0); } 100% { box-shadow: 0 0 0 0 rgba(251,110,150,0); } }
.o-pulse { animation: o-pulse 2.2s ease-out infinite; }
@keyframes o-marq { to { transform: translate3d(-50%,0,0); } }
.o-marq { animation: o-marq 42s linear infinite; }
.o-marq-w:hover .o-marq { animation-play-state: paused; }
.o-grain { background-image: radial-gradient(rgba(46,66,84,.07) 1px, transparent 1px); background-size: 22px 22px; }
@media (min-width: 981px) { .o-stick { position: sticky; top: 110px; } }

/* Questions repliables : en cartes de verre sur l'accueil (.o-qa), en liste
   filetée sur les autres pages (.o-q). */
.o-qa { background: rgba(255,255,255,.62); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px); border: 1px solid rgba(255,255,255,.85); border-radius: 20px; padding: 0 22px; box-shadow: 0 1px 2px rgba(46,66,84,.06), 0 8px 22px -10px rgba(46,66,84,.18); transition: box-shadow .3s ease; }
.o-qa[open] { box-shadow: 0 1px 2px rgba(46,66,84,.06), 0 18px 40px -14px rgba(251,110,150,.35); }
.o-qa > summary { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 20px 0; font-weight: 700; font-size: 18px; line-height: 1.35; color: #2e4254; }
.o-qa > p { margin: 0 0 20px; font-size: 16px; line-height: 1.6; }
.o-q { border-top: 2px solid rgba(46,66,84,.16); }
.o-q > summary { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 20px 0; font-weight: 700; font-size: 18px; line-height: 1.35; color: #2e4254; }
.o-q > p { margin: 0 0 20px; font-size: 16px; line-height: 1.6; max-width: 44em; }
.o-chev { transition: transform .25s ease; }
.o-page details[open] > summary .o-chev { transform: rotate(180deg); }

/* Pages légales. */
.o-legal h2 { margin: 0 0 16px; font-family: 'Darker Grotesque', system-ui, sans-serif; font-weight: 800; font-size: clamp(28px,3vw,36px); line-height: 1; color: #2e4254; }
.o-legal h3 { margin: 24px 0 8px; font-size: 18px; color: #2e4254; }
.o-legal p, .o-legal li { font-size: 17px; line-height: 1.65; max-width: 44em; }
.o-legal p { margin: 0 0 14px; }
.o-legal ul { margin: 0 0 14px; padding-left: 22px; }
.o-legal section { padding: 32px 0; border-top: 2px solid rgba(46,66,84,.16); }

/* Ce qui reste à écrire avant la mise en ligne. Volontairement voyant : un
   « [À COMPLÉTER] » doit sauter aux yeux de quiconque relit la page, et
   l'outil de recette le compte (voir controllers/vitrine.js). */
.o-todo { display: inline; background: #FCEEDB; border: 1px dashed #2e4254; border-radius: 6px; padding: 1px 6px; font-weight: 700; color: #2e4254; }

/* Formulaire de contact. */
.o-field { display: flex; flex-direction: column; gap: 8px; }
.o-field label { font-weight: 700; font-size: 16px; color: #2e4254; }
.o-field input, .o-field textarea { font: inherit; font-size: 17px; color: #222c36; background: #FCFAF6; border: 1.5px solid rgba(46,66,84,.22); border-radius: 14px; transition: border-color .2s, box-shadow .2s; padding: 12px 14px; min-height: 48px; width: 100%; }
.o-field textarea { min-height: 200px; resize: vertical; }
.o-field input:focus, .o-field textarea:focus { outline: none; border-color: #FB6E96; box-shadow: 0 0 0 4px rgba(251,110,150,.18); }
.o-field small { font-size: 14px; color: #4e565e; }

/* Le piège à robots du formulaire : un champ qu'un humain ne voit pas et ne
   remplit donc jamais. Hors de l'écran plutôt qu'en display:none, que
   certains robots savent reconnaître. */
.o-pot { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

/* Retour du formulaire : envoyé, ou refusé avec la raison. */
.o-retour { display: flex; gap: 14px; align-items: flex-start; padding: 18px 20px; border-radius: 18px; font-size: 16px; line-height: 1.55; }
.o-retour-ok { background: #FFFFFF; border: 1.5px solid rgba(46,66,84,.12); }
.o-retour-ko { background: #FCEEDB; border: 1.5px solid #2e4254; }
.o-retour strong { display: block; margin-bottom: 2px; color: #2e4254; }

html { scroll-behavior: smooth; }

/* Le temps que GSAP pose l'état de départ des animations d'ouverture, l'en-tête
   et le haut de page restent invisibles : sans cela, ils s'afficheraient une
   fraction de seconde, disparaîtraient, puis entreraient en scène. La classe est
   posée par un script en ligne dans <head>, et retirée par vitrine.js — ou au
   bout de deux secondes et demie quoi qu'il arrive, si le script ne vient
   jamais. Sans JavaScript, elle n'est jamais posée. */
.o-anim .o-hdr, .o-anim main > section:first-child { visibility: hidden; }
/* Les halos, eux, n'entrent pas en scène : ils sont là dès l'affichage. */
.o-anim main > section:first-child > .o-halos { visibility: visible; }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    .o-page *, .o-page *::after { transition: none !important; animation: none !important; }
}
