/*
 * Kit commun des fonds Otoko : silicone en filigrane, photos en duotone, motifs de Louise, mouvement doux.
 * Source : vault, 🌸 Com-Crea/site/themes/otoko-child/assets/commun/ (mode d'emploi : LISEZ-MOI.md).
 * Posé le 04/11 par la session « Design de /start », pour toutes les pages du thème.
 *
 * Trois règles tenues par le kit lui-même :
 *  - ce qui bouge ne passe que par transform et opacity ;
 *  - rien ne bouge si la personne a demandé moins d'animations (prefers-reduced-motion) ;
 *  - tout se lit sans JavaScript (le miroir d'annotation retire les scripts) : otoko-fonds.js
 *    ne fait qu'endormir ce qui sort de l'écran, faire glisser les photos et changer la teinte du bain.
 *
 * Chaque couche est décorative : aria-hidden="true" sur le conteneur, alt="" sur les images.
 */

/* ---- le conteneur : posé dans une section en position relative avec isolation: isolate */
.ok-fond { position: absolute; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }

/* ---- un champ de silicone : une photo floue de silicone coulé, fondue dans le noir par un masque.
   Réglages (style="") : --ok-haut, --ok-h (place et hauteur du champ), --ok-force (opacité),
   --ok-masque (la forme du fondu, voir les .ok-fondu-*). */
.ok-champ { position: absolute; left: 0; right: 0; top: var(--ok-haut, 0); height: var(--ok-h, 100%); opacity: var(--ok-force, 0.6);
    -webkit-mask-image: var(--ok-masque, linear-gradient(180deg, transparent 0, #000 22%, #000 78%, transparent 100%));
    mask-image: var(--ok-masque, linear-gradient(180deg, transparent 0, #000 22%, #000 78%, transparent 100%)); }
/* L'image déborde le champ de 9 % de chaque côté, pour que la dérive ne découvre jamais un bord.
   max-width: none !important : les thèmes plafonnent les images à 100 % (.otoko-start img…), ce qui couperait le champ net. */
.ok-champ img, .ok-champ .ok-couche { position: absolute; inset: -9%; width: 118%; height: 118%; max-width: none !important; object-fit: cover; }
/* Les fondus : le champ retombe dans le noir du côté où le texte se pose. */
.ok-fondu-droite { --ok-masque: radial-gradient(ellipse 78% 52% at 88% 50%, #000 0, rgba(0, 0, 0, 0.6) 48%, transparent 78%); }
.ok-fondu-gauche { --ok-masque: radial-gradient(ellipse 78% 52% at 12% 50%, #000 0, rgba(0, 0, 0, 0.6) 48%, transparent 78%); }
.ok-fondu-haut { --ok-masque: linear-gradient(180deg, #000 0, #000 30%, transparent 100%); }
.ok-fondu-bas { --ok-masque: linear-gradient(0deg, #000 0, #000 30%, transparent 100%); }
.ok-fondu-bords { --ok-masque: linear-gradient(180deg, transparent 0, #000 22%, #000 78%, transparent 100%); }

/* ---- une photo en filigrane, en duotone : les ombres restent noires, les clairs prennent --ok-teinte.
   Les photos -gris.webp sont faites pour ça (niveaux de gris, contraste étiré). */
.ok-photo { position: absolute; left: 0; right: 0; top: var(--ok-haut, 0); height: var(--ok-h, 100%); opacity: var(--ok-force, 0.3);
    background: var(--ok-teinte, #e049fb);
    -webkit-mask-image: var(--ok-masque, linear-gradient(180deg, transparent 0, #000 25%, #000 75%, transparent 100%));
    mask-image: var(--ok-masque, linear-gradient(180deg, transparent 0, #000 25%, #000 75%, transparent 100%)); }
.ok-photo img { display: block; width: 100%; height: 118%; max-width: none !important; object-fit: cover; mix-blend-mode: multiply; }
.ok-photo--couleur { background: none; }
.ok-photo--couleur img { mix-blend-mode: normal; }

/* ---- un motif de Louise : la forme est un masque SVG, la matière est ce qu'on met dessous
   (une encre par défaut, ou un silicone : c'est le dégradé « en aplat dans la forme » de la charte).
   Réglages : --ok-taille (côté), --ok-x, --ok-y (coin haut gauche), --ok-opacite, --ok-encre. */
.ok-motif { position: absolute; left: var(--ok-x, auto); top: var(--ok-y, 0); width: var(--ok-taille, 110vw); max-width: 1500px; aspect-ratio: 1;
    background: var(--ok-encre, #fff); opacity: var(--ok-opacite, 0.08);
    -webkit-mask: var(--ok-forme) center / contain no-repeat; mask: var(--ok-forme) center / contain no-repeat; }
.ok-motif--rosace { --ok-forme: url(motifs/rosace.svg); }
.ok-motif--rosace-gras { --ok-forme: url(motifs/rosace-gras.svg); }
.ok-motif--louise-1 { --ok-forme: url(motifs/louise-1.svg); }
.ok-motif--louise-1-gras { --ok-forme: url(motifs/louise-1-gras.svg); }
.ok-motif--louise-3 { --ok-forme: url(motifs/louise-3.svg); }
.ok-motif--louise-4 { --ok-forme: url(motifs/louise-4.svg); }
.ok-motif--frise-carree { --ok-forme: url(motifs/frise-carree.svg); }
/* La matière dans la forme : un silicone, cadré sur le motif. */
.ok-dans-lavande { background: #2a1240 url(silicone/lavande.webp) center / cover; }
.ok-dans-rose { background: #3a0d2c url(silicone/rose.webp) center / cover; }
.ok-dans-chaud { background: #4a1a20 url(silicone/chaud.webp) center / cover; }
.ok-dans-orchidee { background: #3a1440 url(silicone/orchidee.webp) center / cover; }
/* La frise de Louise en bandeau (séparateur, bordure), répétée en largeur, en dégradé Thermal dans la forme. */
.ok-frise { display: block; height: var(--ok-h, 28px); background: linear-gradient(135deg, #e049fb, #ff7100);
    -webkit-mask: url(motifs/frise-carree.svg) left center / auto 100% repeat-x; mask: url(motifs/frise-carree.svg) left center / auto 100% repeat-x;
    opacity: var(--ok-opacite, 0.9); }
.ok-frise--froide { background: linear-gradient(135deg, #c2b8fe, #fa3ca4); }

/* ---- une carte (lien, bouton de choix, carte à ouvrir) : contour et dégradé dans sa couleur, visibles au repos,
   pleins au survol, au toucher, au focus et quand elle est choisie ou ouverte. Sam, 04/11, sur les cartes de /start :
   « un petit dégradé lors du hovering peut être ? Ou entouré en couleur ? ». Les deux, posés par /start v8.
   Réglages : --c (le contour et le début du dégradé), --c2 (la suite du dégradé), --ok-carte-repos (0.6),
   --ok-carte-fond (rgba(0, 0, 0, 0.5) ; sur un fond clair, un blanc cassé translucide).
   Seul le dégradé fond (opacity) ; le contour change net au survol, et la carte s'enfonce un peu au toucher. */
.ok-carte { position: relative; isolation: isolate; overflow: hidden; border-radius: 14px; background: var(--ok-carte-fond, rgba(0, 0, 0, 0.5));
    box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--c, #c2b8fe) 68%, transparent); transition: transform 120ms cubic-bezier(0.25, 1, 0.5, 1); }
.ok-carte::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    background: linear-gradient(110deg, color-mix(in oklab, var(--c, #c2b8fe) 30%, transparent) 0, color-mix(in oklab, var(--c2, #e049fb) 16%, transparent) 55%, transparent 100%);
    opacity: var(--ok-carte-repos, 0.6); transition: opacity 320ms cubic-bezier(0.25, 1, 0.5, 1); }
.ok-carte:active { transform: scale(0.98); }
.ok-carte:active::before, .ok-carte:focus-visible::before, .ok-carte[aria-pressed="true"]::before, .ok-carte[aria-expanded="true"]::before, .ok-carte[open]::before { opacity: 1; }
.ok-carte[aria-pressed="true"], .ok-carte[aria-expanded="true"], .ok-carte[open] { box-shadow: inset 0 0 0 2px var(--c, #c2b8fe); }
@media (hover: hover) { .ok-carte:hover { box-shadow: inset 0 0 0 1.5px var(--c, #c2b8fe); } .ok-carte:hover::before { opacity: 1; } }

/* ---- le bain : un silicone fixe derrière toute la page, dont la teinte change d'une section à l'autre.
   <div class="ok-bain" aria-hidden="true"> + une .ok-bain-couche[data-ok-teinte] par teinte ;
   les sections portent data-ok-teinte ; sans JavaScript, chaque section porte sa teinte elle-même (plus bas).
   Le body doit avoir un fond transparent (le html garde le noir), sinon il couvre le bain.
   Réglages : --ok-bain-force (opacité d'une teinte, à poser sur [data-ok-teinte="…"] : il vaut pour la couche
   et pour la section), --ok-voile, --ok-voile-bords. */
.ok-bain { position: fixed; top: 0; left: 0; width: 100%; height: 100lvh; z-index: -2; overflow: hidden; pointer-events: none; background: #000; }
.ok-bain-couche { position: absolute; inset: 0; opacity: 0; transition: opacity 1600ms cubic-bezier(0.25, 1, 0.5, 1); }
.ok-bain-couche:first-child, .ok-bain-couche.ok-actif { opacity: var(--ok-bain-force, 0.7); }
.ok-bain.ok-pilote .ok-bain-couche:not(.ok-actif) { opacity: 0; }
.ok-bain-couche img { position: absolute; inset: -9%; width: 118%; height: 118%; max-width: none !important; object-fit: cover; }
/* Le voile qui garde le texte lisible : plus sombre au centre, où vit la colonne de texte (--ok-voile),
   plus clair sur les bords (--ok-voile-bords). Sur téléphone la colonne prend toute la largeur : voile uniforme. */
.ok-bain::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(0, 0, 0, var(--ok-voile-bords, 0.25)) 0, rgba(0, 0, 0, var(--ok-voile, 0.5)) 30%, rgba(0, 0, 0, var(--ok-voile, 0.5)) 70%, rgba(0, 0, 0, var(--ok-voile-bords, 0.25)) 100%); }
@media (max-width: 899px) { .ok-bain { --ok-voile-bords: var(--ok-voile, 0.5); } }
/* Sans script, le bain ne peut pas suivre le défilement : c'est l'état que voit le cadre de /annoter, qui retire
   tous les scripts, et celui d'un navigateur qui les coupe. Chaque section [data-ok-teinte] porte alors sa teinte
   elle-même, au même dosage (sa force sous le même voile, sur noir), en pleine largeur. --ok-bain-debord étend la
   teinte vers le haut, sur la marge qui sépare la section de la précédente.
   La page pose <script>document.documentElement.classList.add('ok-js')</script> juste avant le .ok-bain, pour que
   ce repli ne s'affiche pas un instant au chargement ; otoko-fonds.js le pose aussi. */
html:not(.ok-js) .ok-bain { display: none; }
html:not(.ok-js) body:has(.ok-bain) [data-ok-teinte]:not(.ok-bain-couche) { position: relative; isolation: isolate; }
html:not(.ok-js) body:has(.ok-bain) [data-ok-teinte]:not(.ok-bain-couche)::before { content: ""; position: absolute; z-index: -3; pointer-events: none;
    top: calc(-1 * var(--ok-bain-debord, 0px)); bottom: 0; left: calc(50% - 50vw); width: 100vw;
    --ok-v: rgba(0, 0, 0, var(--ok-voile, 0.5)); --ok-vb: rgba(0, 0, 0, var(--ok-voile-bords, 0.25));
    background: #000 center / cover no-repeat; opacity: var(--ok-bain-force, 0.7);
    -webkit-mask-image: linear-gradient(transparent 0, #000 var(--ok-bain-debord, 0px)); mask-image: linear-gradient(transparent 0, #000 var(--ok-bain-debord, 0px)); }
@media (max-width: 899px) { html:not(.ok-js) body:has(.ok-bain) [data-ok-teinte]:not(.ok-bain-couche)::before { --ok-vb: var(--ok-v); } }
html:not(.ok-js) body:has(.ok-bain) [data-ok-teinte="lavande"]:not(.ok-bain-couche)::before { background-image: linear-gradient(90deg, var(--ok-vb) 0, var(--ok-v) 30%, var(--ok-v) 70%, var(--ok-vb) 100%), url(silicone/lavande.webp); }
html:not(.ok-js) body:has(.ok-bain) [data-ok-teinte="rose"]:not(.ok-bain-couche)::before { background-image: linear-gradient(90deg, var(--ok-vb) 0, var(--ok-v) 30%, var(--ok-v) 70%, var(--ok-vb) 100%), url(silicone/rose.webp); }
html:not(.ok-js) body:has(.ok-bain) [data-ok-teinte="chaud"]:not(.ok-bain-couche)::before { background-image: linear-gradient(90deg, var(--ok-vb) 0, var(--ok-v) 30%, var(--ok-v) 70%, var(--ok-vb) 100%), url(silicone/chaud.webp); }
html:not(.ok-js) body:has(.ok-bain) [data-ok-teinte="orchidee"]:not(.ok-bain-couche)::before { background-image: linear-gradient(90deg, var(--ok-vb) 0, var(--ok-v) 30%, var(--ok-v) 70%, var(--ok-vb) 100%), url(silicone/orchidee.webp); }

/* ---- le mouvement doux (récit, pas produit : lent, en aller-retour, jamais un rebond) */
@keyframes ok-derive { from { transform: translate3d(-3%, -2.5%, 0) scale(1.04); } to { transform: translate3d(3%, 2.5%, 0) scale(1.12); } }
@keyframes ok-coule { 0%, 25% { opacity: 0; } 75%, 100% { opacity: 1; } }
@keyframes ok-respire { from { opacity: var(--ok-o1, 0.05); } to { opacity: var(--ok-o2, 0.11); } }
@keyframes ok-tourne { to { transform: rotate(360deg); } }
@keyframes ok-flotte { from { transform: translate3d(0, -1.5%, 0) rotate(-2deg); } to { transform: translate3d(0, 1.5%, 0) rotate(2deg); } }
/* La graisse qui respire : la version grasse d'un motif se pose sur la fine et s'efface, en fondu.
   Elle monte jusqu'à la dose du motif (--ok-opacite), pas jusqu'à l'encre pleine : vu le 04/11 par la session des
   articles, une dose posée sur la couche grasse était écrasée par l'animation et le trait montait à 100 %. */
@keyframes ok-graisse { 0%, 20% { opacity: 0; } 80%, 100% { opacity: var(--ok-opacite, 0.08); } }
@keyframes ok-entre { from { opacity: 0; transform: translate3d(0, 18px, 0); } to { opacity: 1; transform: none; } }

.ok-derive { animation: ok-derive var(--ok-duree, 46s) ease-in-out infinite alternate; }
.ok-coule { animation: ok-coule var(--ok-duree, 24s) ease-in-out infinite alternate; }
.ok-respire { animation: ok-respire var(--ok-duree, 9s) ease-in-out infinite alternate; }
.ok-tourne { animation: ok-tourne var(--ok-duree, 420s) linear infinite; }
.ok-flotte { animation: ok-flotte var(--ok-duree, 14s) ease-in-out infinite alternate; }
.ok-graisse { animation: ok-graisse var(--ok-duree, 7s) ease-in-out infinite alternate; }
/* Décalage de phase, pour que deux couches voisines ne respirent pas ensemble. */
.ok-dephase { animation-delay: calc(var(--ok-duree, 20s) / -2); }
/* Une section endormie (hors de l'écran, posé par otoko-fonds.js) ne fait rien tourner. */
.ok-dort, .ok-dort * { animation-play-state: paused !important; }

/* Ce qui entre dans l'écran monte doucement, seulement si otoko-fonds.js a posé .ok-anime sur <html>. */
.ok-anime .ok-v { opacity: 0; transform: translate3d(0, 18px, 0); transition: opacity 800ms cubic-bezier(0.16, 1, 0.3, 1), transform 800ms cubic-bezier(0.16, 1, 0.3, 1); transition-delay: calc(var(--i, 0) * 80ms); }
.ok-anime .ok-v.ok-vu { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
    .ok-derive, .ok-coule, .ok-respire, .ok-tourne, .ok-flotte, .ok-graisse { animation: none !important; }
    .ok-coule { opacity: 0.5; }
    .ok-graisse { opacity: calc(var(--ok-opacite, 0.08) * 0.5); }
    .ok-bain-couche, .ok-carte, .ok-carte::before { transition: none; }
    .ok-carte:active { transform: none; }
    [data-ok-vitesse] { transform: none !important; }
}
