/* ============================================================
   AURI — styles de page.
   Les tokens et les composants de base sont dans tokens.css.
   Ici : uniquement ce qui est propre à la mise en page du site.
   ============================================================ */

/* ---------- Navigation ---------- */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
}

.nav__inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-block: 18px;
}

.nav__links { display: flex; gap: 28px; flex-wrap: wrap; }

.nav__links a { position: relative; padding-bottom: 2px; }

.nav__links a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-hover) var(--ease);
}

.nav__links a:hover::after,
.nav__links a:focus-visible::after { transform: scaleX(1); }

/* ---------- Sections ---------- */

/* La barre de navigation est collante : sans cette marge, une ancre place le
   haut de la section juste dessous, à moitié cachée. */
section[id], footer[id] { scroll-margin-top: 72px; }
[tabindex="-1"]:focus { outline: none; }

.section { padding-block: var(--space-section); }

.section--tight { padding-block: calc(var(--space-section) * 0.6); }

/* ---------- Hero ---------- */

.hero { padding-top: 40px; }

/* Ratio 1.75 exact (7/4), celui de la photo d'origine : aucune coupe.
   Ne pas la resserrer, elle y perdrait ses deux visages. */
.hero__banniere { aspect-ratio: 7 / 4; margin-bottom: 24px; }

/* Le texte de présentation suit immédiatement le titre, sans en-tête de bloc. */
.hero__presentation { margin-top: 40px; }

.hero .display { margin-top: 32px; }

/* ---------- Lien dans le texte ---------- */

/* Un filet, jamais une couleur : l'accent terre cuite reste réservé à une
   seule chose par page. */
.lien {
  border-bottom: 1px solid var(--rule);
  padding-bottom: 2px;
  transition: border-color var(--dur-hover) var(--ease);
}

.lien:hover { border-color: var(--ink); }

.invert .lien { border-color: var(--rule-on-dark); }
.invert .lien:hover { border-color: var(--paper); }

/* ---------- Page Inspirations ---------- */

/* En-tête sans bannière : le titre porte seul, comme le veut le contraste
   d'échelle de la charte. */
.hero--titre { padding-top: var(--space-section); }
.hero--titre .display { margin-top: 0; }

/* Chaque lieu s'ouvre sur un filet pleine largeur — la séparation se fait au
   trait, jamais au fond gris. L'alternance gauche/droite et les largeurs
   inégales des photos se règlent dans le HTML, par les classes de colonnes. */
.lieu {
  border-top: 1px solid var(--rule);
  padding-block: clamp(48px, 6vw, 96px);
}

/* Le dernier bloc est refermé par la section verte : pas de filet en trop. */

/* En une seule colonne, la photo passe toujours avant le texte : les trois
   blocs gardent le même rythme, quel que soit leur sens sur grand écran. */
@media (max-width: 768px) {
  .lieu__media { order: -1; }
}

/* ---------- Grille d'œuvres ---------- */

.works {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gutter) var(--gutter);
  row-gap: 56px;
}

@media (max-width: 900px) { .works { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .works { grid-template-columns: 1fr; } }

.work { display: flex; flex-direction: column; gap: 12px; }

/* Le cadre prend le format réel de la toile (posé en style inline au rendu).
   Les hauteurs varient donc d'elles-mêmes, sans jamais rogner une œuvre. */
.work .media { aspect-ratio: 1 / 1; }

.work__title {
  color: var(--ink);
  font-size: var(--fs-label);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin: 0;
}

/* Métadonnées puis statut, chacun sur sa ligne : le libellé technique est trop
   long pour tenir à côté du statut sans se couper n'importe où. */
.work__foot { display: flex; flex-direction: column; gap: 6px; }

.work__foot .label { margin: 0; }

.work__btn {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-align: left;
  display: block;
  width: 100%;
}

/* Image absente : bloc de remplacement dans le ton de la charte,
   pour que la page reste juste avant que les photos soient posées. */
.media--vide {
  background: var(--paper-pure);
  border: 1px solid var(--rule);
  display: grid;
  place-items: center;
}

.media--vide span {
  font-size: var(--fs-label);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  padding: 16px;
  text-align: center;
}

/* ---------- Colonnes de texte ---------- */

.col-6 { grid-column: span 6; }
.col-5 { grid-column: span 5; }
.col-7 { grid-column: span 7; }
.col-4 { grid-column: span 4; }

/* Colonnes décalées vers la droite. En classes et non en style inline : un
   style inline écrase les media queries et fait déborder la grille sur mobile. */
.col-droite-6 { grid-column: 7 / span 6; }
.col-droite-5 { grid-column: 8 / span 5; }
.col-droite-4 { grid-column: 9 / span 4; }

@media (max-width: 768px) {
  .col-6, .col-5, .col-7, .col-4,
  .col-droite-6, .col-droite-5, .col-droite-4 { grid-column: 1 / -1; }
}

.stack > * + * { margin-top: 20px; }

/* ---------- Contact ---------- */

/* Image à gauche, formulaire au milieu, vide à droite : la composition reste
   asymétrique, comme le veut la charte, sans coller le formulaire au bord. */
.contact__media { grid-column: 1 / span 4; }
.contact__form  { grid-column: 6 / span 5; }

@media (max-width: 768px) {
  .contact__media, .contact__form { grid-column: 1 / -1; }
  .contact__media { margin-bottom: 8px; }
}

/* ---------- Formulaire ---------- */

.form { display: flex; flex-direction: column; gap: 24px; max-width: 560px; }

.champ { display: flex; flex-direction: column; gap: 8px; }

/* Champ piège contre les robots (functions/api/commande.js). Poussé hors de
   l'écran plutôt que masqué : certains robots sautent les champs en
   display:none, et c'est justement ceux-là qu'on veut attraper. */
.champ-piege {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.champ label {
  font-size: var(--fs-label);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted-on-dark);
}

.champ input,
.champ textarea,
.champ select {
  font: inherit;
  color: var(--paper);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule-on-dark);
  border-radius: 0;
  padding: 10px 0;
  transition: border-color var(--dur-hover) var(--ease);
}

.champ textarea { resize: vertical; min-height: 110px; }

.champ input:focus,
.champ textarea:focus,
.champ select:focus { outline: none; border-bottom-color: var(--paper); }

.champ select option { color: var(--ink); }

/* 12-error-state-shake — le seul mouvement nerveux que la charte tolère.
   Les paliers en % sont les durées cumulées : 80/60/80/60 = 280 ms, soit
   28.57 / 57.14 / 78.57 / 100. À recalculer si les durées changent. */
.champ.secoue input,
.champ.secoue textarea,
.champ.secoue select {
  animation: secousse calc(var(--dur-secousse-a) * 2 + var(--dur-secousse-b) * 2) linear;
}

.champ.est-invalide input,
.champ.est-invalide textarea,
.champ.est-invalide select { border-bottom-color: var(--accent-on-dark); }

@keyframes secousse {
  0%     { transform: translateX(0);                               animation-timing-function: var(--ease); }
  28.57% { transform: translateX(var(--dist-secousse));            animation-timing-function: var(--ease); }
  57.14% { transform: translateX(calc(var(--dist-secousse) * -1)); animation-timing-function: var(--ease); }
  78.57% { transform: translateX(var(--dist-rattrapage));          animation-timing-function: var(--ease); }
  100%   { transform: translateX(0); }
}

.champ__erreur {
  font-size: var(--fs-label);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent-on-dark);
  min-height: 1em;
}

/* 10-success-check — 500 ms. Le seul moment où le site se permet une
   célébration, et elle tient en un trait qui se dessine. */
.form__envoi { display: flex; align-items: center; gap: 16px; }

.coche { display: inline-flex; color: var(--paper); opacity: 0; }
.coche svg { display: block; overflow: visible; }
.coche svg path { stroke-dasharray: 18; stroke-dashoffset: 18; }

.coche.est-tracee { animation: coche-parait var(--dur-toast-in) var(--ease) forwards; }
.coche.est-tracee svg path { animation: coche-trace var(--dur-toast-in) var(--ease) forwards; }

@keyframes coche-parait { from { opacity: 0; } to { opacity: 1; } }
@keyframes coche-trace  { to { stroke-dashoffset: 0; } }

/* Lien de navigation de la section en cours : le même filet que le survol. */
.nav__links a.est-active::after { transform: scaleX(1); }

.form__reponse {
  font-size: var(--fs-label);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  min-height: 1em;
  /* 22-toast — montée 500 ms, sortie 350 ms. La confirmation monte à sa
     place : pas de bandeau flottant, ce serait un badge. */
  opacity: 0;
  transform: translateY(var(--dist-toast));
  filter: blur(var(--flou-image));
  transition: opacity   var(--dur-toast-out) var(--ease),
              transform var(--dur-toast-out) var(--ease),
              filter    var(--dur-toast-out) var(--ease);
}

.form__reponse.est-visible {
  opacity: 1;
  transform: none;
  filter: blur(0);
  transition: opacity   var(--dur-toast-in) var(--ease),
              transform var(--dur-toast-in) var(--ease),
              filter    var(--dur-toast-in) var(--ease);
}

/* ---------- Fiche d'œuvre (lightbox) ---------- */

.fiche {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--paper);
  overflow-y: auto;
  padding-block: 32px var(--space-section);
}

.fiche[hidden] { display: none !important; }

/* 06-modal — ouverture 250 ms, fermeture 150 ms, aucun rebond.
   L'attribut hidden reste la vraie sécurité : sans JavaScript la fiche ne
   s'ouvre jamais, donc son opacité nulle n'a aucune conséquence. */
.fiche {
  opacity: 0;
  transform: scale(var(--scale-fiche));
  transition: opacity   var(--dur-hover) var(--ease),
              transform var(--dur-hover) var(--ease);
}

.fiche.est-ouverte { opacity: 1; transform: none; }

.fiche.se-ferme {
  opacity: 0;
  transform: scale(var(--scale-fiche));
  transition: opacity   var(--dur-close) var(--ease),
              transform var(--dur-close) var(--ease);
}

/* Barre de la fiche : pagination à gauche, fermeture à droite. */
.fiche__barre {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--paper);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.fiche__pager { display: flex; gap: 24px; }

.fiche__lien {
  appearance: none;
  background: none;
  border: 0;
  padding: 8px 0;
  font: inherit;
  font-size: var(--fs-label);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  cursor: pointer;
  transition: color var(--dur-hover) var(--ease);
}

.fiche__lien:hover { color: var(--ink); }
.fiche__lien[disabled] { opacity: 0.35; cursor: default; }

/* 08-page-side-by-side — d'une œuvre à la suivante : 250 ms, 8 px, flou 3 px.
   C'est le cas d'usage exact de la recette : liste ↔ détail. */
.fiche__contenu {
  transition: opacity   var(--dur-glisse) var(--ease),
              transform var(--dur-glisse) var(--ease),
              filter    var(--dur-glisse) var(--ease);
}

.fiche__contenu.sort-gauche {
  opacity: 0;
  transform: translateX(calc(var(--dist-glisse) * -1));
  filter: blur(var(--flou-image));
}

.fiche__contenu.sort-droite {
  opacity: 0;
  transform: translateX(var(--dist-glisse));
  filter: blur(var(--flou-image));
}

/* Repositionnement instantané entre la sortie et l'entrée. */
.fiche__contenu.sans-transition { transition: none !important; }

.fiche__fermer {
  position: sticky;
  top: 0;
  margin-left: auto;
  display: block;
  appearance: none;
  background: var(--paper);
  border: 0;
  padding: 8px 0 8px 16px;
  font: inherit;
  font-size: var(--fs-label);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  cursor: pointer;
}

.fiche__fermer:hover { color: var(--ink); }

.fiche__media { grid-column: span 7; }

@media (max-width: 768px) { .fiche__media { grid-column: 1 / -1; } }

.fiche__media img { width: 100%; height: auto; }

.fiche__col { grid-column: 9 / span 4; }

@media (max-width: 768px) { .fiche__col { grid-column: 1 / -1; } }

.fiche__prix {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  letter-spacing: -0.02em;
}

/* ---------- Pied de page ---------- */

.pied { padding-block: var(--space-section) 48px; }

.pied__signature {
  font-family: var(--font-display);
  font-size: clamp(3rem, 12vw, 9rem);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  line-height: 0.85;
  margin: 0 0 48px;
}

.pied__cols {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gutter);
  padding-top: 20px;
  border-top: 1px solid var(--rule-on-dark);
}

@media (max-width: 768px) { .pied__cols { grid-template-columns: repeat(2, 1fr); row-gap: 32px; } }

.pied__cols a:hover { text-decoration: underline; text-underline-offset: 4px; }

.pied__bas {
  margin-top: 56px;
  padding-top: 16px;
  border-top: 1px solid var(--rule-on-dark);
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

/* ---------- Apparition au scroll : décalage de grille ---------- */

.reveal--1 { transition-delay: calc(var(--dur-stagger) * 1); }
.reveal--2 { transition-delay: calc(var(--dur-stagger) * 2); }
.reveal--3 { transition-delay: calc(var(--dur-stagger) * 3); }
.reveal--4 { transition-delay: calc(var(--dur-stagger) * 4); }
.reveal--5 { transition-delay: calc(var(--dur-stagger) * 5); }

@media (prefers-reduced-motion: reduce) {
  .reveal--1, .reveal--2, .reveal--3, .reveal--4, .reveal--5 { transition-delay: 0s; }
}

/* ---------- Saut au contenu ---------- */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: var(--paper);
  padding: 12px 20px;
  font-size: var(--fs-label);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  z-index: 100;
}

.skip:focus { left: 0; }


/* ---------- Repli mobile ----------
   Toutes les rangées en « flex + space-between » doivent pouvoir se replier :
   sinon les micro-labels, tracking compris, dépassent la largeur de l'écran. */

@media (max-width: 560px) {
  .nav__inner { gap: 12px; }
  .nav__links { gap: 16px; }

  .blockhead { flex-wrap: wrap; gap: 4px 16px; }


  /* Le titre display ne doit jamais forcer la page à s'élargir. */
  .display, .pied__signature { overflow-wrap: anywhere; }
}


/* ============================================================
   Téléphone
   Vérifié à 375 px : rien ne dépasse, et tout ce qui se touche fait au
   moins 44 px de haut, la taille d'un pouce.
   ============================================================ */

/* iOS grossit le texte en paysage si on ne l'en empêche pas. */
html { -webkit-text-size-adjust: 100%; }

/* Métadonnées d'œuvre repliées sur deux lignes : l'interligne 1 du label
   les faisait se toucher. */
.work__foot .label { line-height: 1.5; }

/* Sur écran tactile, le survol reste « collé » après un toucher : la toile
   resterait zoomée. Le zoom lent ne vaut qu'avec une souris. */
@media (hover: none) {
  .media:hover img { transform: none; }
}

/* Champs du formulaire : 44 px minimum. */
.champ input,
.champ select { min-height: 44px; }

/* ---------- Menu ----------
   Le bouton n'existe qu'avec JavaScript et sur petit écran. Sans script, les
   liens restent affichés en ligne, comme avant : rien n'est jamais caché. */

.nav__menu { display: none; }

/* Sans script, et sur la page 404 qui n'en charge pas : pas de bouton Menu,
   les liens restent en ligne mais gagnent une zone tactile de 44 px. */
@media (max-width: 768px) {
  html:not(.js) .nav__inner { padding-block: 0; }
  html:not(.js) .nav__inner > a.label,
  html:not(.js) .nav__links a { padding-block: 17px; }
}

@media (max-width: 768px) {
  .js .nav__inner { min-height: 56px; padding-block: 0; }

  /* Le logo et le bouton gagnent une zone tactile pleine hauteur. */
  .js .nav__inner > a.label { padding-block: 22px; }

  .js .nav__menu {
    display: block;
    appearance: none;
    background: none;
    border: 0;
    margin-right: calc(var(--margin) * -1);
    padding: 22px var(--margin) 22px 24px;
    font: inherit;
    font-size: var(--fs-label);
    color: var(--ink);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }

  /* 05-menu-dropdown — le panneau descend de la barre, depuis le bouton :
     250 ms à l'ouverture, 150 ms à la fermeture, aucun rebond. visibility
     retire les liens de la tabulation quand le menu est fermé. */
  .js .nav__links {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 0;
    padding: 0 var(--margin) 16px;
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
    transform-origin: top right;
    transform: scale(var(--dropdown-pre-scale));
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    will-change: transform, opacity;
  }

  .js .nav__links.is-open {
    transform: scale(1);
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition:
      transform var(--dropdown-open-dur) var(--dropdown-ease),
      opacity   var(--dropdown-open-dur) var(--dropdown-ease);
  }

  .js .nav__links.is-closing {
    transform: scale(var(--dropdown-closing-scale));
    opacity: 0;
    visibility: visible;
    pointer-events: none;
    transition:
      transform var(--dropdown-close-dur) var(--dropdown-ease),
      opacity   var(--dropdown-close-dur) var(--dropdown-ease);
  }

  /* Les liens reprennent le sommaire de la charte : grandes capitales,
     filet entre chaque ligne. */
  .js .nav__links a {
    display: block;
    padding-block: 18px;
    border-top: 1px solid var(--rule);
    font-family: var(--font-display);
    font-size: var(--fs-section);
    font-weight: 500;
    letter-spacing: -0.02em;
    line-height: 1;
    color: var(--ink);
  }

  .js .nav__links a:first-child { border-top: 0; }
  .js .nav__links a::after { display: none; }
  .js .nav__links a[aria-current="page"] { color: var(--muted); }
}

@media (prefers-reduced-motion: reduce) {
  .js .nav__links { transition: none !important; }
}

/* ---------- Fiche d'œuvre ---------- */

@media (max-width: 768px) {
  /* La barre colle tout en haut : avec la marge haute de la fiche, la toile
     défilait visible au-dessus d'elle. Un filet la sépare du contenu, comme
     le bandeau d'en-tête de la charte. */
  .fiche { padding-top: 0; }

  .fiche__barre {
    border-bottom: 1px solid var(--rule);
    margin-bottom: 16px;
  }

  /* Précédente, Suivante, Fermer : 44 px de haut pour le pouce. */
  .fiche__lien,
  .fiche__fermer { padding-block: 17px; }

  /* La barre touche le haut de l'écran : un cadre de focus décalé vers
     l'extérieur y serait coupé. Il passe à l'intérieur du bouton. */
  .fiche__lien:focus-visible,
  .fiche__fermer:focus-visible { outline-offset: -4px; }
}

/* ---------- Accueil, pied de page ---------- */

@media (max-width: 560px) {
  /* AURI en très grand : le contraste d'échelle de la charte. L'accueil
     seulement — ATELIER ou INSPIRATIONS ne tiendraient pas à cette taille. */
  .hero:not(.hero--titre) .display {
    font-size: clamp(3rem, 27vw, 8.5rem);
    margin-top: 20px;
  }

  .hero__presentation { margin-top: 24px; }

  /* Une colonne : l'adresse e-mail touchait le bord à deux colonnes. */
  .pied__cols { grid-template-columns: 1fr; row-gap: 12px; }
  .pied__cols p { margin: 0; }
  .pied__cols a { display: inline-block; padding-block: 12px; }
}


/* ---------- L'alcôve ----------
   La seule forme non rectangulaire du site, reprise de la maquette Canva :
   arc plein cintre en haut, côtés droits, base plate. C'est une forme
   SIGNATURE, pas un coin arrondi générique — la règle « rayon 0 » vaut
   toujours partout ailleurs. Une alcôve par page, deux au maximum. */

.alcove { border-radius: 50% 50% 0 0 / 33% 33% 0 0; }
