/* audreyguttman.com — noir sur blanc, une seule police, deux styles.
   Typographie d'après karmakarma.org, mise en page d'après sebastienbertrand.com. */

/* --- Police ------------------------------------------------------------- */
/* Deux sous-ensembles par style : le navigateur ne charge « latin-ext » que si
   la page contient des caractères qui l'exigent (Jiří Kolář, Pelù…). */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-normal-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: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-normal-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: 'Inter';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-italic-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: 'Inter';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-italic-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;
}

/* --- Repères ------------------------------------------------------------ */

:root {
  color-scheme: light; /* site de galerie : blanc assumé, pas de thème sombre */

  --ink: #000;
  --paper: #fff;
  --muted: #767676; /* contraste 4.6:1 sur blanc */
  --rule: #e2e2e2;

  --text: clamp(1.0625rem, 0.72vw + 0.92rem, 1.3125rem); /* 17 → 21 px */
  --small: clamp(0.875rem, 0.3vw + 0.81rem, 1rem); /* 14 → 16 px */
  --leading: 1.36;
  --tracking: 0.02em;

  --gutter: clamp(1.125rem, 3vw, 2.25rem);
  --header-h: 4.25rem;

  /* Largeur d'une image pleine page, et la hauteur qui en découle pour une
     horizontale en 3/2 : elle sert de plafond à toutes les autres. */
  --figure-w: 68rem;
  --figure-h: calc(var(--figure-w) / 1.5);

  /* Les deux colonnes de l'index des expositions, reprises par chaque groupe. */
  --index-columns: minmax(7rem, 12rem) minmax(0, 1fr);
  --index-gap: clamp(1.5rem, 5vw, 4rem);
  /* Longueur de ligne. Karma s'en tient à 34em ; Audrey trouvait la colonne
     étroite face aux images, qui courent sur 68rem. 44em reste en deçà. */
  --measure: 44em;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;
  font-size: var(--text);
  line-height: var(--leading);
  letter-spacing: var(--tracking);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
  /* Dissuasion : pas de glisser-déposer vers le bureau, pas de menu « Enregistrer
     l'image » au appui long sur iOS. Rien n'empêche une capture d'écran ou un
     détour par le code source — l'idée est seulement de rendre le geste moins
     évident. Le clic droit est neutralisé sur les images dans src/js/site.js. */
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

a {
  color: inherit;
  text-decoration: none;
}

/* Le soulignement suit la ligne de base plutôt que de traverser les jambages.
   L'index des expositions s'en passe : il ne souligne qu'au survol. */
a.underline,
main p a,
main .links a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: var(--gutter);
  top: 0.5rem;
  z-index: 100;
  background: var(--paper);
  padding: 0.5rem 0.75rem;
}

/* --- En-tête ------------------------------------------------------------ */
/* Logotype bas-de-casse à gauche, menu serré à droite : repère pris sur
   sebastienbertrand.com. */

.header {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.15rem var(--gutter);
  background: var(--paper);
}

.header__logo {
  font-size: var(--text);
  letter-spacing: 0.005em;
  white-space: nowrap;
}

.nav {
  display: flex;
  align-items: baseline;
  gap: clamp(0.75rem, 1.4vw, 1.35rem);
  font-size: var(--small);
}

.nav a[aria-current='page'],
.nav__group-toggle.is-current {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}

/* --- Menu déroulant ----------------------------------------------------- */
/* Le panneau s'ouvre au survol, au focus (donc au clavier et à l'appui sur
   mobile) et sur clic via .is-open posé par src/js/site.js. Les trois voies
   sont indépendantes : les pages filles restent atteignables sans JavaScript. */

.nav__group {
  position: relative;
}

.nav__group-toggle {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
  cursor: pointer;
}

.nav__menu {
  display: none;
  position: absolute;
  top: calc(100% + 0.85rem);
  left: -0.9rem;
  z-index: 60;
  flex-direction: column;
  gap: 0.55rem;
  padding: 0.8rem 1.6rem 0.9rem 0.9rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  white-space: nowrap;
}

/* Le panneau flotte sous le bouton, et cet intervalle n'appartient à aucun des
   deux : la souris qui descendait vers « bio » sortait du groupe et refermait le
   menu avant de l'atteindre. Ce pont invisible rattache le vide au panneau. */
.nav__menu::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: 0.95rem;
}

.nav__group:focus-within > .nav__menu,
.nav__group.is-open > .nav__menu {
  display: flex;
}

@media (hover: hover) {
  .nav__group:hover > .nav__menu {
    display: flex;
  }
}

/* Après les règles d'ouverture : referme malgré le focus resté à l'intérieur. */
.nav__group.is-closed > .nav__menu {
  display: none;
}

.nav__toggle {
  display: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: var(--small);
  letter-spacing: inherit;
  color: inherit;
  cursor: pointer;
}

/* Seuil du menu replié. Le logotype et les cinq entrées tiennent sur une ligne
   jusqu'à ~520 px : 36rem (576 px) laisse la marge et garde la barre dépliée sur
   les tablettes et les fenêtres étroites. À garder en phase avec src/js/site.js. */
@media (max-width: 36rem) {
  .nav__toggle {
    display: block;
  }
  .nav {
    position: fixed;
    inset: var(--header-h) 0 auto;
    flex-direction: column;
    gap: 0.65rem;
    padding: 1.25rem var(--gutter) 2rem;
    background: var(--paper);
    font-size: var(--text);
    border-bottom: 1px solid var(--rule);
  }
  .nav[hidden] {
    display: none;
  }
  /* Menu mobile : le panneau se déplie dans le flux, en retrait, au lieu de
     flotter au-dessus d'une colonne déjà étroite. Plus de vide à franchir, donc
     plus de pont — il recouvrirait l'entrée juste au-dessus. */
  .nav__menu {
    position: static;
    padding: 0.55rem 0 0 1.1rem;
    border: 0;
  }
  .nav__menu::before {
    content: none;
  }
}

/* --- Structure ---------------------------------------------------------- */

.wrap {
  padding-inline: var(--gutter);
}

.measure {
  max-width: var(--measure);
}

.stack > * + * {
  margin-top: 1.15em;
}

main {
  padding-bottom: clamp(4rem, 12vh, 8rem);
}

.muted {
  color: var(--muted);
}

/* --- Accueil ------------------------------------------------------------ */
/* Image pleine largeur sans marge sous l'en-tête, légende en surimpression. */

.hero {
  position: relative;
  margin: 0;
}

.hero__slide {
  margin: 0;
}

.hero__slide[hidden] {
  display: none;
}

/* Les flèches tiennent la ligne de la légende, à l'autre bout. */
.hero__nav {
  position: absolute;
  right: var(--gutter);
  bottom: 0;
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  color: var(--muted);
  font-size: var(--small);
}

.hero__nav[hidden] {
  display: none;
}

.hero__arrow {
  border: 0;
  background: none;
  padding: 0 0.25em;
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
  cursor: pointer;
}

/* L'image entière, dans ses proportions. Elle était jusqu'ici rognée pour tenir
   dans la hauteur de l'écran, ce qui la réduisait à un bandeau — et amputait la
   vue d'exposition d'un tiers de sa hauteur. Sur une grande fenêtre, elle peut
   déborder du premier écran : c'est le prix de l'image complète. */
.hero img {
  width: 100%;
}

/* La légende se lit sous l'image, en noir sur blanc comme le reste du site. En
   surimpression, elle demandait un dégradé pour rester lisible sur les vues de
   murs blancs — et ce dégradé assombrissait le bas de chaque œuvre. */
.hero__caption {
  padding: clamp(0.85rem, 2.2vw, 1.25rem) var(--gutter) 0;
}

.hero__caption em {
  font-style: italic;
}

.hero__caption a:hover em {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

.intro {
  margin-top: clamp(2.5rem, 7vh, 5rem);
}

/* --- Index des expositions ---------------------------------------------- */
/* Deux colonnes : filtres à gauche, liste typographique à droite. */

.index {
  display: grid;
  grid-template-columns: var(--index-columns);
  gap: 0 var(--index-gap);
  margin-top: clamp(1.5rem, 4vh, 3rem);
}

/* Chaque groupe reprend les deux colonnes de la grille parente : l'intitulé reste
   aligné à gauche, en face de sa liste.
   La première déclaration est un repli : `subgrid` est ignoré par Safari 15 et
   par les Chrome antérieurs à 117, et le groupe retombait alors sur une colonne
   unique — l'intitulé passait au-dessus de sa liste. Reprendre les mêmes pistes
   donne le même résultat, la largeur des colonnes ne dépendant pas du contenu. */
.index__group {
  display: grid;
  grid-template-columns: var(--index-columns);
  grid-template-columns: subgrid;
  column-gap: var(--index-gap);
  grid-column: 1 / -1;
}

.index__group + .index__group {
  margin-top: clamp(2.5rem, 7vh, 4.5rem);
}

.index__label {
  font-size: inherit;
  font-weight: 400;
  margin: 0;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}

.index__list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 40em;
}

.index__list li + li {
  margin-top: 1.36em; /* une ligne vide, comme sur Karma */
}

/* Vignette à gauche, notice à droite — d'après l'index de sebastienbertrand.com,
   ramené à la taille d'une icône pour que la liste reste lisible d'un coup d'œil. */
.index__list a {
  display: flex;
  align-items: flex-start;
  gap: clamp(0.85rem, 2vw, 1.35rem);
}

.index__thumb {
  flex: 0 0 clamp(5rem, 18vw, 7.5rem);
}

.index__thumb img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

.index__list a:hover .index__title {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

.index__title {
  font-style: italic;
}

/* Sur écran étroit, la colonne des intitulés et la vignette ne peuvent plus se
   partager la largeur : l'intitulé repasse au-dessus de sa liste. */
@media (max-width: 36rem) {
  .index {
    grid-template-columns: minmax(0, 1fr);
  }
  .index__group {
    display: block;
  }
  .index__label {
    margin-bottom: 1.1rem;
  }
}

/* --- Page d'exposition -------------------------------------------------- */

.exhibition__header {
  margin: clamp(1.5rem, 5vh, 3.5rem) auto clamp(2rem, 6vh, 4rem);
  text-align: center;
  /* Assez large pour que « Four-Artist Show with… » tienne sur une ligne : une
     ligne de distribution coupée en deux se lit comme deux mentions distinctes. */
  max-width: var(--measure);
}

.exhibition__title {
  font-size: inherit;
  font-weight: 400;
  font-style: italic;
  margin: 0;
}

/* L'italique dit « titre d'œuvre » : une exposition, un livre, un texte. Le nom
   d'une rubrique — Books, Editions, Contact — n'en est pas un et reste droit. */
.exhibition__title--plain {
  font-style: normal;
}

.exhibition__text {
  margin: 0 auto clamp(2.5rem, 7vh, 5rem);
  max-width: var(--measure);
  white-space: pre-line; /* les retours à la ligne saisis dans Airtable sont conservés */
}

.figures {
  display: flex;
  flex-direction: column;
  gap: clamp(2rem, 6vh, 4.5rem);
  align-items: center;
}

.figure {
  margin: 0;
  width: 100%;
  max-width: var(--figure-w);
}

/* Une image en hauteur affichée sur toute la largeur devenait un mur : deux fois
   plus haute qu'une vue d'exposition, elle sortait de l'écran. Toutes les lignes
   ont donc la hauteur d'une horizontale pleine largeur, et c'est la largeur qui
   cède : une verticale seule tient la moitié de la page, deux verticales voisines
   se partagent la ligne. La largeur de chaque ligne est calculée au rendu, où les
   proportions des images sont connues. */
.figures__row {
  display: flex;
  align-items: flex-start;
  gap: clamp(0.5rem, 1.4vw, 0.9rem);
  width: 100%;
  margin-inline: auto;
}

/* flex-basis nulle : la largeur ne vient que du flex-grow posé sur chaque figure,
   égal à ses proportions. Les images d'une ligne ont donc la même hauteur. */
.figures__row .figure {
  flex: 1 1 0;
  min-width: 0;
  max-width: none;
}

/* Sur téléphone, deux verticales côte à côte feraient des timbres-poste : la
   ligne se défait et chaque image reprend toute la largeur. */
@media (max-width: 40rem) {
  .figures__row {
    flex-direction: column;
    gap: clamp(2rem, 6vh, 4.5rem);
    max-width: none !important; /* la largeur posée en ligne sur chaque rangée */
  }
}

/* C'est l'image qui donne sa taille à la boîte ; le bouton n'est qu'une surface
   cliquable posée dessus. Tant que l'image vivait dans le bouton, Firefox en
   rognait le bas — un <button> clippe son contenu et calcule sa hauteur
   autrement que Chrome quand l'image est dimensionnée en pourcentage. */
.figure__media {
  position: relative;
  display: block;
}

.figure__media img {
  width: 100%;
}

.figure__media > button {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  cursor: zoom-in;
  /* iOS dessine ses propres bordures sur un bouton et fait clignoter un voile gris
     à l'appui : sur une surface posée sur l'œuvre, les deux se voient. */
  -webkit-appearance: none;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
}

.figure figcaption {
  margin-top: 0.7rem;
  font-size: var(--small);
  color: var(--muted);
}

/* --- Vidéo --------------------------------------------------------------- */
/* La vignette et son triangle de lecture, jusqu'au clic. */

.figure__media > button.video {
  cursor: pointer;
}

.video__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 4.5rem;
  height: 4.5rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 1px 14px rgba(0, 0, 0, 0.25);
  transition: transform 0.18s ease;
}

/* Le triangle, en bordures : pas d'image à charger pour trois traits. */
.video__play::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0;
  height: 0;
  border: 0.75rem solid transparent;
  border-left: 1.2rem solid var(--ink);
  transform: translateX(0.2rem);
}

.video:hover .video__play {
  transform: scale(1.06);
}

.video__frame {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  max-height: var(--figure-h);
  margin-inline: auto;
  border: 0;
}

/* Le portrait de la page bio n'a pas à occuper toute la largeur : c'est une photo
   d'appoint, pas une œuvre. */
.figures--compact .figure {
  max-width: 26rem;
}

/* Le CV, à la suite de la bio, sous son propre intitulé. */
.appendix {
  margin-top: clamp(2.5rem, 7vh, 5rem);
}

.appendix__title {
  font-size: inherit;
  font-weight: 700;
  margin: 0 auto clamp(1.25rem, 4vh, 2rem);
  max-width: var(--measure);
  text-transform: uppercase;
}

.cv__heading {
  font-weight: 700;
}

/* --- Index des textes --------------------------------------------------- */
/* D'après karmakarma.org : un bloc par texte, et au survol un filet sous l'année
   et le titre seulement. Le filet est toujours là, transparent au repos : sans
   ça, son apparition décalerait la ligne d'un pixel. */

.texts {
  list-style: none;
  margin: clamp(1.5rem, 4vh, 3rem) auto 0;
  padding: 0;
  max-width: 40em;
}

.texts li + li {
  margin-top: 1.36em; /* une ligne vide, comme sur Karma */
}

.texts__mark {
  border-bottom: 1px solid transparent;
}

.texts__title {
  font-style: italic;
}

.texts__author {
  color: var(--muted);
}

@media (hover: hover) {
  .texts a:hover .texts__mark {
    border-bottom-color: var(--ink);
  }
}

.texts a:focus-visible .texts__mark {
  border-bottom-color: var(--ink);
}

/* --- Editions ----------------------------------------------------------- */

.editions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr));
  gap: clamp(1.5rem, 4vw, 3rem);
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: 68rem;
}

.editions img {
  margin-bottom: 0.7rem;
}

.editions__title {
  font-style: normal;
}

.editions a:hover .editions__title {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

.buy {
  margin: 0;
}

.buy__button {
  display: inline-block;
  border: 1px solid var(--ink);
  padding: 0.55em 1.15em;
}

.buy__button:hover {
  background: var(--ink);
  color: var(--paper);
}

.buy--out {
  color: var(--muted);
}

.buy__note {
  margin-top: 0.6rem;
  font-size: var(--small);
}

/* --- Listes : textes, livres, commandes --------------------------------- */

.entry + .entry {
  margin-top: clamp(3.5rem, 11vh, 7rem);
}

/* Les notices reprennent la mise en page de l'ancien site : titre et année sur la
   même ligne, texte puis planche de vignettes. Le bloc entier est centré et large
   comme la planche, sinon le texte s'arrêtait au milieu de l'écran et le reste de
   la page restait vide à droite. */
.entry {
  max-width: 68rem;
  margin-inline: auto;
}

.entry__title {
  font-size: inherit;
  font-weight: 400;
  font-style: normal;
  margin: 0;
  max-width: var(--measure);
}

.entry__year {
  font-style: normal;
}

.entry__text {
  margin: 1.15em 0 0;
  max-width: var(--measure);
  white-space: pre-line;
}

.gallery {
  display: flex;
  flex-direction: column;
  gap: clamp(0.5rem, 1.4vw, 0.9rem);
  margin-top: clamp(1.75rem, 5vh, 3rem);
}

.gallery__row {
  display: flex;
  align-items: flex-start;
  gap: clamp(0.5rem, 1.4vw, 0.9rem);
}

/* flex-basis nulle : la largeur ne vient que du flex-grow posé sur chaque figure,
   égal à ses proportions. Toutes les images d'une rangée ont donc la même hauteur,
   chacune dans son format d'origine. */
.gallery__row .figure {
  flex: 1 1 0;
  min-width: 0;
}

/* Sur téléphone, six vignettes par ligne feraient des timbres-poste : on repasse
   à trois, quitte à perdre l'alignement des hauteurs. */
@media (max-width: 36rem) {
  .gallery__row {
    flex-wrap: wrap;
    max-width: none !important; /* la largeur en ligne des lignes incomplètes */
  }
  .gallery__row .figure {
    flex: 1 1 28%;
    min-width: 28%;
  }
}

.links {
  margin: clamp(2.5rem, 7vh, 5rem) auto 0;
  max-width: var(--measure);
  list-style: none;
  padding: 0;
}

.links li + li {
  margin-top: 0.35em;
}

/* --- Visionneuse -------------------------------------------------------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  grid-template-rows: 1fr auto;
  background: var(--paper);
  padding: var(--gutter);
  gap: 1rem;
  /* Le geste de balayage ne doit pas entraîner la page restée derrière. */
  overscroll-behavior: contain;
}

.lightbox[hidden] {
  display: none;
}

.lightbox__stage {
  display: grid;
  place-items: center;
  min-height: 0;
}

.lightbox__stage img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.lightbox__bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  font-size: var(--small);
  color: var(--muted);
}

.lightbox__bar button {
  border: 0;
  background: none;
  padding: 0 0.4em;
  font: inherit;
  letter-spacing: inherit;
  color: var(--ink);
  cursor: pointer;
}

.lightbox__close {
  position: absolute;
  top: var(--gutter);
  right: var(--gutter);
}

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

.footer {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  justify-content: space-between;
  padding: 2rem var(--gutter);
  border-top: 1px solid var(--rule);
  font-size: var(--small);
  color: var(--muted);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
