/*  Secret Paradise Experiences — les blocs propres a la page club.

    Cette page n est pas une page de texte illustree : c est une page
    d images commentees. Le lieu se montre plus qu il ne se raconte, et
    aucune phrase ne remplacera la photographie du salon transparent.

    Charge uniquement par club.html : les onze autres pages n en ont pas
    l usage et n ont pas a en payer le telechargement.

    Rien n est reinvente ici. Les jetons, l arrondi, la police et l or
    viennent de socle.css ; les formes reprennent celles de l accueil.     */

/* ══════════════════════════════════════════════ La tete de page ════════

   Ailleurs sur le site, l image d en-tete est floutee : elle situe, elle ne
   se regarde pas. Ici elle est nette et haute, parce qu elle EST le sujet.
   Le prix a payer est la lisibilite du titre, d ou le voile renforce plus
   bas et le halo local sous le bloc de texte.                             */

.club-tete {
    display: flex;
    align-items: flex-end;
    min-height: min(76svh, 700px);
}

.club-tete .page { width: 100%; }

/*  Variante nette du fond de section. On garde l assombrissement -- sans
    lui le texte blanc tombe sur l eau turquoise et devient illisible --
    mais on retire le flou et l agrandissement qui n avaient de raison
    d etre que pour masquer les bords delites d une image floutee.          */
.section-fond--net img {
    transform: scale(1.02);
    /*  Beaucoup plus clair que la variante floutee. Celle-ci assombrit a
        0.55 parce que son image n est qu une texture ; ici la photographie
        est le sujet, et une prise de vue de nuit assombrie encore de moitie
        ne montre plus rien du tout. La lisibilite du titre est reprise par
        le halo local, pas par l ecrasement de l image.                     */
    filter: saturate(1.04) brightness(0.86);
}

.section-fond--net::after {
    background: linear-gradient(180deg,
        rgba(8, 8, 8, 0.74) 0%,
        rgba(8, 8, 8, 0.22) 36%,
        rgba(8, 8, 8, 0.44) 76%,
        var(--noir) 100%);
}

/*  Un halo derriere le texte seul. Le voile general est volontairement
    leger au milieu pour laisser voir l eau ; sans ce halo, le titre
    s ecrase sur les reflets.                                              */
.club-tete .club-tete-texte {
    position: relative;
    isolation: isolate;
    max-width: 760px;
}

.club-tete .club-tete-texte::before {
    content: '';
    position: absolute;
    inset: -14% -10% -18% -12%;
    z-index: -1;
    background: radial-gradient(64% 60% at 34% 50%,
        rgba(8, 8, 8, 0.82) 0%, rgba(8, 8, 8, 0.44) 58%, transparent 100%);
    pointer-events: none;
}

.club-tete .titre-1 { max-width: 17ch; }

/* ══════════════════════════════════════════════════════ Le duo ═════════

   Une photographie et un texte, cote a cote, alternes d un bloc a l autre.
   La forme la plus simple qui laisse l image respirer a sa vraie taille au
   lieu de la reduire a une vignette d illustration.                       */

.duo {
    display: grid;
    grid-template-columns: 1.04fr 0.96fr;
    align-items: center;
    gap: clamp(30px, 4.4vw, 72px);
}

/*  L alternance. Sans elle, trois duos d affilee donnent une colonne
    d images a gauche et une colonne de texte a droite : un tableau.        */
.duo--inverse .duo-image { order: 2; }

.duo-image {
    position: relative;
    overflow: hidden;
    border-radius: var(--r-grand);
    border: 1px solid var(--trait);
    background: var(--noir-2);
}

.duo-image img {
    display: block;
    width: 100%;
    height: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    transition: transform 1.3s var(--courbe);
}

.duo-image--portrait img { aspect-ratio: 4 / 5; }

.duo:hover .duo-image img { transform: scale(1.045); }

/*  Le meme filet d or qui court sur les cartes de la flotte, pour que les
    deux familles de blocs se reconnaissent.                                */
.duo-image::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    border: 1px solid transparent;
    pointer-events: none;
    transition: border-color 0.6s var(--courbe);
}

.duo:hover .duo-image::after { border-color: var(--trait-or); }

.duo-texte { display: flex; flex-direction: column; align-items: flex-start; gap: 20px; }

.duo-texte .etiquette { margin-bottom: 2px; }

.duo-texte p { color: var(--blanc-2); font-size: 15.5px; line-height: 1.82; }

.duo-texte p + p { margin-top: -4px; }

.duo-texte strong { color: var(--blanc); font-weight: 400; }

/* ══════════════════════════════════ Les cartes d experience ════════════

   Meme grammaire que les cartes de la flotte : la photographie en haut,
   desaturee au repos, qui retrouve sa couleur au survol. Les huit voitures
   viennent de huit series de qualites tres inegales et ce filtre les fait
   tenir ensemble ; ici il sert surtout la continuite avec elles.          */

.experiences {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: clamp(14px, 1.7vw, 22px);
}

.exp { grid-column: span 2; }

/*  Les deux dernieres occupent la moitie chacune : cinq cartes dans une
    grille de trois laissent sinon un trou a droite de la seconde ligne.    */
.exp:nth-child(4),
.exp:nth-child(5) { grid-column: span 3; }

.exp {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--trait);
    border-radius: var(--r-grand);
    background: rgba(16, 16, 16, 0.58);
    backdrop-filter: blur(8px);
    transition: transform 0.55s var(--courbe), border-color 0.55s var(--courbe);
}

.exp:hover {
    transform: translateY(-6px);
    border-color: var(--trait-or);
}

.exp:active { transform: translateY(-2px); transition-duration: 0.1s; }

.exp-photo { position: relative; overflow: hidden; aspect-ratio: 3 / 2; }

.exp-photo img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: grayscale(0.28) contrast(1.04) brightness(0.9);
    transition: transform 1.2s var(--courbe), filter 0.7s var(--courbe);
}

.exp:hover .exp-photo img {
    transform: scale(1.06);
    filter: grayscale(0) contrast(1) brightness(1);
}

/*  Le degrade sous la photo : il rattache l image au corps de la carte au
    lieu de laisser une arete horizontale nette au milieu du bloc.          */
.exp-photo::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, transparent 52%, rgba(8, 8, 8, 0.72) 100%);
    pointer-events: none;
}

.exp-corps {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    flex: 1;
    padding: clamp(20px, 2.1vw, 28px);
}

.exp-corps h3 { transition: color 0.4s var(--courbe); }

.exp:hover .exp-corps h3 { color: var(--or); }

.exp-corps p { color: var(--gris); font-size: 14.5px; line-height: 1.75; }

/*  Le lien est colle en bas quel que soit le nombre de lignes du texte :
    sans cela, cinq cartes de longueurs differentes alignent cinq liens a
    cinq hauteurs differentes.                                              */
.exp-corps .lien { margin-top: auto; padding-top: 6px; }

/* ══════════════════════════════════════════════════ La mosaique ════════

   La galerie. Des formats differents -- panoramas, portraits, carres --
   ranges dans une grille dense : c est le desordre apparent qui fait lire
   « photographies d un lieu reel » plutot que « banque d images ».        */

.mosaique {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-auto-rows: clamp(126px, 14.5vw, 208px);
    grid-auto-flow: dense;
    gap: clamp(10px, 1.1vw, 14px);
}

.mosaique figure {
    position: relative;
    margin: 0;
    overflow: hidden;
    border-radius: var(--r);
    border: 1px solid var(--trait);
    background: var(--noir-2);
}

.m-2x2 { grid-column: span 2; grid-row: span 2; }
.m-2x1 { grid-column: span 2; }
.m-1x2 { grid-row: span 2; }

.mosaique img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: brightness(0.88) saturate(0.94);
    transition: transform 1.4s var(--courbe), filter 0.7s var(--courbe);
}

.mosaique figure:hover img {
    transform: scale(1.07);
    filter: brightness(1) saturate(1);
}

/*  La legende n apparait qu au survol. Elle nomme ce qu on regarde -- une
    photographie de lieu sans legende laisse deviner -- sans encombrer la
    mosaique au repos.                                                      */
.mosaique figcaption {
    position: absolute;
    inset: auto 0 0 0;
    padding: 26px 16px 13px;
    font-size: 12.5px;
    letter-spacing: 0.02em;
    color: var(--blanc);
    background: linear-gradient(180deg, transparent 0%, rgba(8, 8, 8, 0.86) 62%);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.45s var(--courbe), transform 0.45s var(--courbe);
}

.mosaique figure:hover figcaption { opacity: 1; transform: none; }

/* ══════════════════════════════════════════════════ Le a-venir ════════

   Le pavillon bien-etre n existe pas encore. Il ne peut donc ni prendre une
   carte -- il n a pas de photographie -- ni etre passe sous silence : c est
   une raison de revenir. Une bande, un filet d or, deux phrases.          */

.bientot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 26px;
    padding: clamp(26px, 3vw, 40px) clamp(24px, 3vw, 44px);
    border: 1px solid var(--trait-or);
    border-radius: var(--r-grand);
    background:
        linear-gradient(120deg, rgba(201, 162, 74, 0.07) 0%, transparent 58%),
        rgba(16, 16, 16, 0.62);
}

.bientot-texte { display: flex; flex-direction: column; gap: 12px; max-width: 62ch; }

.bientot-texte p { color: var(--gris); font-size: 14.5px; line-height: 1.72; }

.bientot .etiquette { margin-bottom: 2px; }

/* ══════════════════════════════════════════════════ Le rappel ═════════

   La derniere image de la page, pleine largeur, avec l invitation par
   dessus. On ne quitte pas une page de lieu sur un paragraphe.            */

.rappel {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    min-height: min(58svh, 520px);
    padding: clamp(70px, 9vw, 120px) var(--marge);
}

.rappel-texte {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24px;
    max-width: 720px;
}

/*  Meme halo que sous le titre de la tete de page, et pour la meme raison :
    le bar eclaire occupe la droite de la photographie, et la ligne de chapo
    y perdait son contraste.                                                */
.rappel-texte::before {
    content: "";
    position: absolute;
    inset: -22% -18%;
    z-index: -1;
    background: radial-gradient(58% 56% at 50% 50%,
        rgba(8, 8, 8, 0.78) 0%, rgba(8, 8, 8, 0.4) 58%, transparent 100%);
    pointer-events: none;
}

.rappel-actions { display: flex; flex-wrap: wrap; gap: 15px; justify-content: center; }

/* ══════════════════════════════════════════════════ Les reprises ══════

   Un seul point de bascule par bloc, choisi la ou la forme casse et non a
   une largeur ronde.                                                       */

@media (max-width: 980px) {
    .duo { grid-template-columns: 1fr; gap: 30px; }

    /*  L alternance n a plus de sens sur une colonne : l image passe
        toujours au-dessus du texte qu elle illustre.                       */
    .duo--inverse .duo-image { order: 0; }

    .duo-image img,
    .duo-image--portrait img { aspect-ratio: 16 / 10; }

    .experiences { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .exp,
    .exp:nth-child(4),
    .exp:nth-child(5) { grid-column: span 1; }

    /*  Cinq cartes sur deux colonnes laissent la derniere seule : on lui
        donne la largeur entiere plutot qu une demi-carte orpheline.        */
    .exp:nth-child(5) { grid-column: span 2; }
}

@media (max-width: 760px) {
    .club-tete { min-height: min(66svh, 560px); }

    .mosaique {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-auto-rows: clamp(122px, 30vw, 190px);
    }
}

@media (max-width: 620px) {
    .experiences { grid-template-columns: 1fr; }
    .exp,
    .exp:nth-child(4),
    .exp:nth-child(5) { grid-column: span 1; }

    .bientot { flex-direction: column; align-items: flex-start; }
    .bientot .bouton { width: 100%; justify-content: center; }
}

/*  Le mouvement est un agrement, jamais un support d information : tout ce
    qui bouge ici peut etre coupe sans qu une phrase disparaisse.           */
@media (prefers-reduced-motion: reduce) {
    .duo-image img,
    .exp-photo img,
    .mosaique img { transition: none; }

    .duo:hover .duo-image img,
    .exp:hover .exp-photo img,
    .mosaique figure:hover img { transform: none; }

    .exp:hover { transform: none; }
}


/* ══════════════════════════════════════════════ La remontee d eau ══════

   L apparition des images de cette page.

   Ailleurs sur le site, un bloc arrive en fondu et remonte de dix-huit
   pixels. C est correct, et c est partout. Ici le sujet est un salon place
   SOUS le niveau de l eau : les photographies emergent donc comme le ferait
   un bassin qui se vide -- une ligne d eau descend, l image apparait
   derriere elle.

   Le mecanisme tient dans une propriete personnalisee animable. Une
   variable CSS ordinaire ne se transitionne pas : le navigateur ignore
   qu il manipule un pourcentage et saute d une valeur a l autre.
   @property le lui dit, et la ligne devient continue.

   « inherits: true » n est pas un detail : c est ce qui permet au trait
   lumineux, dessine en ::after, de suivre la ligne de decoupe. Sans lui le
   pseudo-element resterait a la valeur initiale, et le trait ne bougerait
   pas d un pixel.                                                          */

@property --niveau {
    syntax: "<percentage>";
    inherits: true;
    initial-value: 100%;
}

.js .emerge { --niveau: 100%; }

/*  Le masque porte sur l IMAGE, pas sur la figure.

    Masquer la figure revenait a masquer aussi son ::before -- c est-a-dire
    la ligne d eau elle-meme, posee pile sur le bord du masque : elle etait
    coupee en deux et sa lueur disparaissait. En descendant le masque d un
    cran, la ligne reste libre et l arrondi continue d etre assure par le
    overflow: hidden de la figure.                                         */
.js .emerge img { clip-path: inset(var(--niveau) 0 0 0); }

/*  On neutralise le fondu du systeme commun sur ces elements-la : les deux
    animations ensemble donnent une image qui emerge en transparence,
    c est-a-dire un effet mou et deux fois plus long.                       */
.js .emerge.apparait,
.js .emerge.apparait.vue {
    opacity: 1;
    transform: none;
}

.js .emerge.vue {
    --niveau: 0%;
    transition: --niveau 1.5s var(--courbe);
}

/*  Le trait lumineux, cale sur la ligne de decoupe. C est lui qui fait lire
    « surface de l eau » plutot que « volet qui s ouvre » : une decoupe nue
    reste un effet de transition, une ligne qui brille est une surface.     */
/*  ::before et non ::after : sur les grandes images, l ::after porte deja
    le filet dore du survol. Les deux effets sur le meme pseudo-element se
    marchent dessus, et l opacite nulle de la ligne d eau eteignait le
    filet pour de bon.                                                     */
.js .emerge::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: var(--niveau);
    height: 2px;
    z-index: 2;
    opacity: 0;
    pointer-events: none;
    background: linear-gradient(90deg,
        transparent 0%,
        rgba(240, 220, 164, 0.8) 18%,
        rgba(255, 252, 244, 1) 50%,
        rgba(240, 220, 164, 0.8) 82%,
        transparent 100%);
    /*  Deux ombres, pas une. Celle du haut est la lueur, et elle suffit
        tant que le trait descend sur du noir. Celle du bas est sombre :
        sans elle, le trait disparait des qu il passe sur une zone claire
        de la photographie -- l eau turquoise, ici, mange l or.           */
    box-shadow:
        0 -7px 24px 2px rgba(240, 220, 164, 0.38),
        0 7px 20px -4px rgba(8, 8, 8, 0.65);
}

.js .emerge.vue::before { animation: ligne-deau 1.5s var(--courbe); }

@keyframes ligne-deau {
    0%   { opacity: 0; }
    14%  { opacity: 1; }
    76%  { opacity: 0.8; }
    100% { opacity: 0; }
}

/* ══════════════════════════════════════════════════ Les caustiques ═════

   Les taches de lumiere que l eau projette sur les parois d un bassin.

   Trois nappes tres floues, tres pales, qui derivent a des vitesses
   differentes et ne se retrouvent jamais au meme endroit en meme temps :
   29, 37 et 43 secondes, des durees premieres entre elles dont le cycle
   commun depasse de loin la duree d une visite. On ne voit donc jamais
   l animation se repeter -- on sent seulement que la photographie n est
   pas un aplat.

   « screen » plutot qu une simple opacite : la lumiere s ajoute a l image
   au lieu de la voiler, ce qui est exactement ce que fait un reflet.       */

.caustique {
    position: absolute;
    inset: -25%;
    z-index: 1;
    pointer-events: none;
    mix-blend-mode: screen;
    filter: blur(28px);
    will-change: transform;
}

.caustique-a {
    background:
        radial-gradient(34% 24% at 24% 32%, rgba(152, 208, 255, 0.17), transparent 64%),
        radial-gradient(22% 30% at 68% 62%, rgba(198, 232, 255, 0.11), transparent 62%);
    animation: derive-eau-a 29s ease-in-out infinite alternate;
}

.caustique-b {
    background:
        radial-gradient(28% 20% at 78% 26%, rgba(120, 186, 240, 0.14), transparent 60%),
        radial-gradient(20% 26% at 40% 78%, rgba(170, 220, 255, 0.10), transparent 64%);
    animation: derive-eau-b 37s ease-in-out infinite alternate;
}

.caustique-c {
    background: radial-gradient(46% 30% at 52% 50%, rgba(232, 246, 255, 0.07), transparent 68%);
    animation: derive-eau-c 43s ease-in-out infinite alternate;
}

@keyframes derive-eau-a {
    from { transform: translate3d(-3%, -2%, 0) scale(1.00); }
    to   { transform: translate3d( 4%,  3%, 0) scale(1.12); }
}

@keyframes derive-eau-b {
    from { transform: translate3d( 3%,  2%, 0) scale(1.10); }
    to   { transform: translate3d(-4%, -3%, 0) scale(1.00); }
}

@keyframes derive-eau-c {
    from { transform: translate3d(0,  2%, 0) scale(1.06); }
    to   { transform: translate3d(0, -2%, 0) scale(1.00); }
}

/*  Sur telephone, une seule nappe.

    Six couches pleine page, floutees a vingt-huit pixels, fusionnees en
    « screen » et animees sans fin : sur un ordinateur cela ne se sent pas,
    sur un telephone d entree de gamme cela se paye en images perdues et en
    batterie. On garde la premiere -- celle qui porte l essentiel de
    l effet -- et on allege son flou.                                      */
@media (max-width: 760px) {
    .caustique-b,
    .caustique-c { display: none; }

    .caustique-a { filter: blur(20px); }
}

/* ══════════════════════════════════════════════════════ La derive ═════

   Les tuiles de la mosaique ne defilent pas toutes a la meme vitesse : le
   script leur donne un decalage vertical de quelques pixels, fonction de
   leur position dans l ecran. Neuf photographies figees dans une grille
   font un tableau ; les memes avec dix pixels d ecart font un mur de
   cadres.

   Aucune transition ici : le decalage est reecrit a chaque image par le
   script, et une transition par-dessus le rendrait pateux.                */

.mosaique figure { will-change: transform; }

.mosaique figure:hover { border-color: var(--trait-or); }

/* ══════════════════════════════════════════════════ Les temperatures ══

   Les deux chiffres qui disent « ouvert toute l annee » mieux que la
   phrase. Ils comptent une fois, quand le paragraphe entre dans l ecran.

   La largeur est bloquee sur deux chiffres : sans cela le texte qui suit
   avance et recule pendant le comptage.                                   */

.nombre {
    display: inline-block;
    min-width: 2ch;
    font-weight: 400;
    font-variant-numeric: tabular-nums;
    color: var(--blanc);
}

/* ══════════════════════════════════════════════ Le reflet du a-venir ══

   La bande « Bientot » annonce ce qui n existe pas encore. Un reflet la
   traverse toutes les sept secondes : assez pour qu on la remarque en
   descendant, trop lent pour qu on la surveille.                          */

.bientot { position: relative; overflow: hidden; isolation: isolate; }

.bientot::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: linear-gradient(105deg,
        transparent 34%,
        rgba(240, 220, 164, 0.10) 48%,
        rgba(255, 250, 235, 0.14) 52%,
        transparent 66%);
    transform: translateX(-100%);
    animation: reflet 7s var(--courbe) infinite;
}

@keyframes reflet {
    0%, 62% { transform: translateX(-100%); }
    100%    { transform: translateX(100%); }
}

/* ══════════════════════════════════════════ L invite a descendre ══════

   Le meme filet que sur l accueil, remonte : cette tete de page fait trois
   quarts d ecran et non un ecran entier.                                  */

.club-tete .ouverture-suite { bottom: clamp(22px, 3vh, 34px); }

@media (max-width: 760px) { .club-tete .ouverture-suite { display: none; } }

/* ══════════════════════════════════════════════════════════════════════

   Rien de tout cela ne porte d information : tout se coupe.               */

@media (prefers-reduced-motion: reduce) {
    .js .emerge { --niveau: 0%; }
    .js .emerge img { clip-path: none; }
    .js .emerge::before { display: none; }
    .caustique { display: none; }
    .bientot::before { display: none; }
    .mosaique figure { transform: none !important; }
}
