/* ==========================================================================
   Wazo — button interactions (public site)
   One place for hover / focus / pressed / loading behaviour, by button type.
   Loaded last on every public page (see templates/layouts/head.php).

   Rules this file follows, so effects never fight the rest of the site:
   - Buttons move with the individual `translate` and `scale` properties,
     never `transform`. Arrows keep their own transform for centring, and
     the scroll reveal (reveal.css) owns translate/scale only while an
     element is armed, where it wins with !important. GSAP (button-effects.js)
     never touches either: it only tweens --mx/--my, which [data-magnetic]
     below turns into a transform. (Tweening transform directly would make
     GSAP fold translate/scale into it and blank the effects here.)
   - Hover motion is limited to real hover devices (fine pointer); touch
     gets the pressed state and the focus ring only, so nothing sticks
     after a tap. prefers-reduced-motion removes movement, sheen and spin.
   - No effect changes a button's box (and .btn has no overflow:hidden), so
     nothing shifts, shrinks or clips.
   ========================================================================== */

:root {
    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

/* Shared focus ring: a white gap plus a navy ring reads on the cream page,
   on turquoise and on dark photography alike (the site-wide turquoise ring
   disappears on a turquoise button). Buttons mirror their hover fill on
   :focus-visible, so keyboard and mouse states look like the same thing. */
.btn:focus-visible,
.carousel-arrow:focus-visible,
.site-nav__toggle:focus-visible {
    outline: 2px solid var(--color-navy);
    outline-offset: 2px;
}

.btn:focus-visible {
    box-shadow: 0 0 0 4px var(--color-white), var(--btn-shadow, 0 0 0 0 transparent);
}

/* ---------------------------------------------------------------------------
   Base .btn: everything a variant below can animate, on one transition.
   Deliberately no overflow:hidden: it would let a button shrink below its
   label inside a flex row/column (mobile menu, room-card actions) and clip
   the text. The sheen and the wipe are backgrounds, which the pill's own
   rounded box already clips; isolation keeps the sheen behind the label.
   --------------------------------------------------------------------------- */
.btn {
    position: relative;
    isolation: isolate;
    transition: background-color 0.2s ease,
                color 0.2s ease,
                border-color 0.2s ease,
                background-size 0.3s var(--ease-out),
                box-shadow 0.22s var(--ease-out),
                translate 0.18s var(--ease-out),
                scale 0.12s var(--ease-out);
}

/* ---------------------------------------------------------------------------
   1. Main reservation buttons: .btn--primary, .btn--pill, .btn--dark.
   A confident, unhurried response: the fill deepens, the button lifts a
   hair and its glow follows, and a soft highlight glides across once.
   --------------------------------------------------------------------------- */
.btn--primary,
.btn--pill {
    --btn-shadow: 0 12px 28px -12px rgba(37, 170, 225, 0.8);
    box-shadow: var(--btn-shadow);
}

.btn--dark {
    --btn-shadow: 0 0 0 0 transparent;
    box-shadow: var(--btn-shadow);
}

/* The highlight is a gradient three times the button's width, parked off its
   left edge at rest and slid across by changing background-position. */
.btn--primary::before,
.btn--pill::before,
.btn--dark::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: linear-gradient(105deg, transparent 42%, rgba(255, 255, 255, 0.26) 50%, transparent 58%) no-repeat;
    background-size: 300% 100%;
    background-position: 100% 0;
    pointer-events: none;
}

.btn--dark::before {
    background-image: linear-gradient(105deg, transparent 42%, rgba(255, 255, 255, 0.14) 50%, transparent 58%);
}

@media (hover: hover) and (pointer: fine) {
    .btn--primary:hover:not(:disabled, [aria-disabled="true"], [aria-busy="true"]) {
        translate: 0 -2px;
        box-shadow: 0 18px 32px -12px rgba(37, 170, 225, 0.85);
    }

    .btn--pill:hover:not(:disabled, [aria-disabled="true"], [aria-busy="true"]) {
        translate: 0 -1px;
        box-shadow: 0 16px 30px -12px rgba(37, 170, 225, 0.85);
    }

    .btn--dark:hover:not(:disabled, [aria-disabled="true"], [aria-busy="true"]) {
        translate: 0 -1px;
        box-shadow: 0 14px 26px -12px rgba(0, 41, 74, 0.55);
    }
}

.btn--primary:hover:not(:disabled, [aria-disabled="true"], [aria-busy="true"])::before,
.btn--pill:hover:not(:disabled, [aria-disabled="true"], [aria-busy="true"])::before,
.btn--dark:hover:not(:disabled, [aria-disabled="true"], [aria-busy="true"])::before,
.btn--primary:focus-visible::before,
.btn--pill:focus-visible::before,
.btn--dark:focus-visible::before {
    background-position: 0 0;
    transition: background-position 0.65s var(--ease-out);
}

/* Pressed: settles down and the glow tightens; deeper fill than hover. */
.btn--primary:active:not(:disabled, [aria-disabled="true"], [aria-busy="true"]),
.btn--pill:active:not(:disabled, [aria-disabled="true"], [aria-busy="true"]) {
    background-color: #2fa5d6;
    box-shadow: 0 6px 14px -8px rgba(37, 170, 225, 0.8);
}

.btn--dark:active:not(:disabled, [aria-disabled="true"], [aria-busy="true"]) {
    background-color: #001b32;
}

.btn:active:not(:disabled, [aria-disabled="true"], [aria-busy="true"]) {
    translate: 0 0;
    scale: 0.975;
}

/* Magnetic pull (fine pointers only): button-effects.js marks the button and
   tweens --mx / --my; the offset is a few pixels at most. */
[data-magnetic] {
    transform: translate(var(--mx, 0px), var(--my, 0px));
}

/* ---------------------------------------------------------------------------
   2. Secondary / outline buttons: .btn--outline-light, .btn--secondary.
   Quieter than the reservation buttons: no lift, no glow. A soft fill
   rises from the bottom edge while the border brightens.
   --------------------------------------------------------------------------- */
.btn--outline-light,
.btn--secondary {
    background-repeat: no-repeat;
    background-position: 0 100%;
    background-size: 100% 0;
}

.btn--outline-light {
    background-image: linear-gradient(rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.16));
}

.btn--secondary {
    background-image: linear-gradient(var(--color-navy), var(--color-navy));
    transition-delay: 0s, 0.06s, 0s, 0s, 0s, 0s, 0s;
}

.btn--outline-light:focus-visible,
.btn--secondary:focus-visible {
    background-color: transparent;
    background-size: 100% 100%;
}

.btn--outline-light:focus-visible {
    border-color: var(--color-white);
}

@media (hover: hover) and (pointer: fine) {
    .btn--outline-light:hover,
    .btn--secondary:hover {
        background-color: transparent;
        background-size: 100% 100%;
    }

    .btn--outline-light:hover {
        border-color: var(--color-white);
    }
}

.btn--outline-light:active {
    background-color: rgba(255, 255, 255, 0.1);
}

/* ---------------------------------------------------------------------------
   3. Text links with an arrow: .link-arrow ("Découvrir", unit links).
   The underline turns turquoise and lifts away from the text while a small
   chevron slides forward. Underline and chevron are the only things that
   move, and the link keeps its colour, so it stays legible.
   --------------------------------------------------------------------------- */
.link-arrow {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    text-decoration-line: underline;
    text-decoration-thickness: 1px;
    text-decoration-color: rgba(0, 41, 74, 0.45);
    text-underline-offset: 2px;
    transition: text-decoration-color 0.2s ease,
                text-underline-offset 0.2s var(--ease-out),
                opacity 0.12s ease;
}

.link-arrow::after {
    content: "";
    flex-shrink: 0;
    width: 0.42em;
    height: 0.42em;
    border-top: 1.5px solid currentColor;
    border-right: 1.5px solid currentColor;
    rotate: 45deg;
    transition: translate 0.2s var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
    .link-arrow:hover {
        text-decoration-color: var(--color-turquoise);
        text-underline-offset: 5px;
    }

    .link-arrow:hover::after {
        translate: 3px 0;
    }
}

.link-arrow:focus-visible {
    text-decoration-color: var(--color-turquoise);
    text-underline-offset: 5px;
    outline-offset: 4px;
}

.link-arrow:focus-visible::after {
    translate: 3px 0;
}

.link-arrow:active {
    opacity: 0.7;
}

/* ---------------------------------------------------------------------------
   4. Gallery and carousel arrows: .carousel-arrow (+ --prev / --next).
   Crisp and directional: the disc fills navy in 140ms and the chevron
   nudges toward the direction it will take you. A press shrinks it.
   The arrows keep their own transform (vertical centring), so these use
   `translate`/`scale` only.
   --------------------------------------------------------------------------- */
.carousel-arrow {
    transition: background-color 0.14s ease,
                border-color 0.14s ease,
                color 0.14s ease,
                box-shadow 0.14s ease,
                scale 0.1s ease;
}

.carousel-arrow > span {
    display: block;
    transition: translate 0.16s var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
    .carousel-arrow:hover {
        background-color: var(--color-navy);
        border-color: var(--color-navy);
        color: var(--color-white);
        box-shadow: 0 12px 24px -10px rgba(0, 41, 74, 0.6);
    }

    .carousel-arrow--prev:hover > span {
        translate: -2px 0;
    }

    .carousel-arrow--next:hover > span {
        translate: 2px 0;
    }
}

.carousel-arrow:focus-visible {
    background-color: var(--color-navy);
    border-color: var(--color-navy);
    color: var(--color-white);
}

.carousel-arrow--prev:focus-visible > span {
    translate: -2px 0;
}

.carousel-arrow--next:focus-visible > span {
    translate: 2px 0;
}

.carousel-arrow:active {
    scale: 0.92;
}

/* ---------------------------------------------------------------------------
   6. Toggles: the mobile-menu button and the language pill.
   The three bars fold into a cross while the menu is open (driven by the
   aria-expanded state main.js already maintains), so open and closed are
   unmistakable. Both toggles share the pressed behaviour below.
   --------------------------------------------------------------------------- */
.site-nav__toggle {
    border-radius: var(--radius-full);
    transition: background-color 0.2s ease, scale 0.1s ease;
}

.site-nav__toggle-bar {
    transition: transform 0.25s var(--ease-out), opacity 0.15s ease;
}

.site-nav__toggle[aria-expanded="true"] {
    background-color: rgba(0, 41, 74, 0.07);
}

.site-nav__toggle[aria-expanded="true"] .site-nav__toggle-bar:nth-child(1) {
    transform: translateY(6px) rotate(45deg);
}

.site-nav__toggle[aria-expanded="true"] .site-nav__toggle-bar:nth-child(2) {
    opacity: 0;
    transform: scaleX(0.4);
}

.site-nav__toggle[aria-expanded="true"] .site-nav__toggle-bar:nth-child(3) {
    transform: translateY(-6px) rotate(-45deg);
}

@media (hover: hover) and (pointer: fine) {
    .site-nav__toggle:hover {
        background-color: rgba(0, 41, 74, 0.06);
    }
}

.site-nav__toggle:active,
.lang-switch__button:active,
.mobile-menu__lang-link:active {
    scale: 0.95;
}

.lang-switch__button,
.mobile-menu__lang-link {
    transition: background-color 0.2s ease,
                border-color 0.2s ease,
                color 0.2s ease,
                scale 0.1s ease;
}

/* ---------------------------------------------------------------------------
   7. Form submit buttons (.form__submit).
   They inherit the reservation hover and press above. Loading is set by
   button-effects.js on a real submission (aria-busy): the label stays in
   place (so the button never changes size) and a small ring turns over it.
   Disabled and busy buttons show no hover, lift or sheen.
   --------------------------------------------------------------------------- */
.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.5;
    box-shadow: none;
    cursor: not-allowed;
}

.btn[aria-busy="true"] {
    color: transparent;
    cursor: progress;
}

.btn[aria-busy="true"]::after {
    content: "";
    position: absolute;
    inset: 0;
    width: 1.15em;
    height: 1.15em;
    margin: auto;
    border: 2px solid rgba(0, 41, 74, 0.25);
    border-top-color: var(--wz-navy);
    border-radius: 50%;
    animation: btn-spin 0.7s linear infinite;
}

/* Turquoise buttons carry navy text, so their spinner is navy; the dark and
   ghost buttons carry white text and get a white spinner. */
.btn--dark[aria-busy="true"]::after,
.btn--outline-light[aria-busy="true"]::after {
    border-color: rgba(255, 255, 255, 0.35);
    border-top-color: var(--color-white);
}

@keyframes btn-spin {
    to {
        rotate: 360deg;
    }
}

/* ---------------------------------------------------------------------------
   Reduced motion: keep every colour and state change (they carry meaning),
   drop the movement. Busy buttons dim instead of spinning.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .btn,
    .btn:hover,
    .btn:active,
    .carousel-arrow,
    .carousel-arrow > span,
    .site-nav__toggle,
    .site-nav__toggle-bar,
    .lang-switch__button,
    .link-arrow::after {
        translate: none !important;
        scale: none !important;
    }

    .btn--primary::before,
    .btn--pill::before,
    .btn--dark::before {
        display: none;
    }

    .btn[aria-busy="true"] {
        color: inherit;
        opacity: 0.6;
    }

    .btn[aria-busy="true"]::after {
        display: none;
    }
}
