/* ── Typography, per brief §12 ────────────────────────────────
   Canela (Commercial Type) and Neue Haas Grotesk (Monotype) are both licensed
   commercial faces. The web-font files cannot be included here — they have to be
   bought and dropped into dist/fonts/ (see dist/fonts/README.md for the exact
   filenames). Until then every rule below resolves to the alternative the brief
   closest free matches: Newsreader for display, Inter for text. Newsreader replaced
   Fraunces (2026-08): Fraunces' lowercase f has a very narrow crossbar and a tightly
   curled terminal, which at title size read as a bare stroke rather than an f.

   Each src list starts with local(), so a licensed copy already installed on the
   machine is used for review. If neither a local install nor a file in dist/fonts/
   resolves, the face is unavailable and the stack falls through to the fallback —
   which is why the family stacks, not just these declarations, carry the fallback. */

@font-face{
  font-family: 'Canela';
  src: local('Canela Regular'), local('Canela-Regular') /* , url('dist/fonts/Canela-Regular.woff2') format('woff2') — uncomment once the file is in dist/fonts/ */;
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face{
  font-family: 'Canela';
  src: local('Canela Italic'), local('Canela-Italic') /* , url('dist/fonts/Canela-Italic.woff2') format('woff2') — uncomment once the file is in dist/fonts/ */;
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face{
  font-family: 'Canela';
  src: local('Canela Bold'), local('Canela-Bold') /* , url('dist/fonts/Canela-Bold.woff2') format('woff2') — uncomment once the file is in dist/fonts/ */;
  font-weight: 700; font-style: normal; font-display: swap;
}

@font-face{
  font-family: 'Neue Haas Grotesk';
  src: local('Neue Haas Grotesk Display Light'), local('NeueHaasDisplay-Light') /* , url('dist/fonts/NeueHaasGrotesk-Light.woff2') format('woff2') — uncomment once the file is in dist/fonts/ */;
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face{
  font-family: 'Neue Haas Grotesk';
  src: local('Neue Haas Grotesk Display Roman'), local('NeueHaasDisplay-Roman') /* , url('dist/fonts/NeueHaasGrotesk-Roman.woff2') format('woff2') — uncomment once the file is in dist/fonts/ */;
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face{
  font-family: 'Neue Haas Grotesk';
  src: local('Neue Haas Grotesk Display Mediu'), local('NeueHaasDisplay-Mediu') /* , url('dist/fonts/NeueHaasGrotesk-Medium.woff2') format('woff2') — uncomment once the file is in dist/fonts/ */;
  font-weight: 500; font-style: normal; font-display: swap;
}
/* ── Palette ─────────────────────────────────────────────── */
:root{
  --parchment: #fafaf8;
  --parchment-veil: #fcfcfa;
  --ink: #3a3a3a;       /* soft dark, not black */
  --ink-soft: #6f6f6f;
  --ink-faint: #a6a6a6;
  --rule: #dcdcdc;
  --white: #ffffff;
  --accent: #3a3a3a;
  --reveal-duration: 3000ms;
  --rhythm: 1;
  --ease: cubic-bezier(.16,.84,.20,1);
  /* Brief §12. --font-display carries the name, the chapter titles and the quotes;
     --font-text carries body copy, the discreet menu and the légendes. The fallback
     families sit inside each stack so the page still reads correctly before the
     licensed Canela / Neue Haas Grotesk files are dropped into dist/fonts/. */
  --font-display: 'Canela', 'Newsreader', Georgia, 'Times New Roman', serif;
  --font-text: 'Neue Haas Grotesk', 'Inter', "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* Compatibility aliases — existing rules resolve through these. */
  --font-body: var(--font-text);
  --font-title: var(--font-display);

  /* Unified type scale (single source of truth) — one token per role so that
     same-role elements can never drift apart again. */
  --type-title: clamp(2.4rem, 6.5vw, 5rem);
  /* A named série inside a chapter — one clear step below the chapter verb, so
     « Beirut e(s)t moi » reads as belonging to Habiter rather than rivalling it. */
  --type-title-series: clamp(1.75rem, 4.4vw, 3.2rem);
  --type-title-page: clamp(1.9rem, 3.6vw, 2.6rem);
  --type-lead: clamp(1.25rem, 2.4vw, 1.65rem);
  --type-desc: clamp(1.05rem, 1.8vw, 1.3rem);
  --type-section: clamp(1.2rem, 2.4vw, 1.6rem);
  --type-body: 1rem;
  --type-label: .82rem;
  --type-meta: .74rem;
  --track-section: .16em;
  --track-meta: .2em;
}

*,*::before,*::after{ box-sizing: border-box; }
html,body{ margin: 0; padding: 0; }
html{ background: var(--parchment); }
body{
  background: var(--parchment);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 16px;
  line-height: 1.8;
  letter-spacing: .06em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img{ max-width: 100%; display: block; -webkit-user-drag: none; user-drag: none; pointer-events: none; }
a{ color: inherit; }
::selection{ background: rgba(90,70,54,.14); color: var(--ink); }

/* ── Image protection ────────────────────────────────────── */
.frame, .gallery-item{ -webkit-user-select: none; user-select: none; }
/* Block image dragging / long-press save */
img, .img, .gallery-img{
  -webkit-user-drag: none;
  -khtml-user-drag: none;
  -moz-user-drag: none;
  -o-user-drag: none;
  user-drag: none;
  -webkit-touch-callout: none;
  pointer-events: none;
}
/* Restore pointer-events for interactive elements that contain images */
a img, button img, .frame, .gallery-overlay{ pointer-events: auto; }

/* ── Layout ──────────────────────────────────────────────── */
main{ display: block; }

/* Universe sections */
.universe{
  position: relative;
  padding: 8vh 6vw;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.universe + .universe{ padding-top: 6vh; }

/* Photos */
.photo{
  margin: 0;
  width: 100%;
  max-width: 540px;
  display: flex;
  justify-content: center;
}
.photo + .photo{ margin-top: 1.2cm; }
.universe > .photo:first-child{ margin-top: 0; }

.frame{
  position: relative;
  width: 100%;
  overflow: hidden;
  background: transparent;
}
.frame > .img{
  width: 100%;
  height: auto;
  display: block;
  transition:
    opacity var(--reveal-duration) var(--ease);
  opacity: 0;
}
.frame > .placeholder{
  position: absolute; inset: 0;
  background: linear-gradient(180deg, #f3ede0 0%, #ede5d4 100%);
  display: flex; align-items: center; justify-content: center;
  opacity: 0;
  transition:
    opacity var(--reveal-duration) var(--ease);
}
.frame > .placeholder .ph-meta{
  font-family: var(--font-body);
  font-size: 11px;
  color: var(--ink-soft);
  text-align: center;
  letter-spacing: .04em;
  line-height: 1.6;
}
.frame > .placeholder .ph-meta b{ display:block; color: var(--ink); font-weight:400; margin-bottom: 4px; }
.frame > .veil{
  position: absolute; inset: 0;
  background: var(--parchment-veil);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--reveal-duration) var(--ease);
}
.frame.is-revealed > .img,
.frame.is-revealed > .placeholder{ opacity: 1; }
.frame.is-revealed > .veil{ opacity: 0; }

/* Beyrouth — white border frame */
.universe.has-mat .photo .frame{
  border: 22px solid var(--white);
  box-shadow: 0 8px 32px rgba(90,70,54,.12), 0 1px 3px rgba(90,70,54,.07);
}
/* Placeholder stays full-frame */
.universe.has-mat .frame > .placeholder{ inset: 0; }

.universe-head{
  position: relative;
  z-index: 2;
  width: 100%;
  margin: 0 0 2.5vh;
  padding-bottom: 0;
  text-align: center;
  pointer-events: none;
}
.universe-head h2{
  font-family: var(--font-body);
  font-style: italic;
  font-weight: 200;
  font-size: clamp(1.8rem, 3.5vw, 2.6rem);
  color: var(--ink);
  margin: 0 0 .6rem;
  letter-spacing: .06em;
  opacity: .88;
}
.universe-head .subtitle{
  font-weight: 300;
  font-size: clamp(1.05rem, 1.7vw, 1.35rem);
  color: var(--ink);
  max-width: 640px;
  margin: 0 auto 2.6rem;
  letter-spacing: .04em;
  opacity: .88;
  line-height: 1.55;
}
.universe-head .series-title{
  font-family: var(--font-title);
  text-transform: uppercase;
  font-weight: 400;
  font-size: clamp(2.4rem, 5vw, 3.6rem);
  color: var(--ink);
  letter-spacing: .12em;
  margin: 0 0 1.2rem;
  line-height: 1.1;
}
/* Matière sub-sections sit under the MATIÈRE series title → smaller */
#matiere-objets .universe-head h2,
#matiere-glace .universe-head h2,
#matiere-corp .universe-head h2,
#matiere-paysage .universe-head h2{
  font-size: clamp(1.3rem, 2.4vw, 1.8rem);
}
.universe-head .epigraph{
  font-family: var(--font-body);
  font-style: normal;
  font-weight: 400;
  font-size: clamp(1rem, 1.5vw, 1.25rem);
  color: var(--ink-soft);
  margin: 0 auto;
  line-height: 1.5;
  max-width: 480px;
  opacity: .75;
}

.universe-description{
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(.9rem, 1.3vw, 1.1rem);
  color: var(--ink);
  line-height: 1.7;
  max-width: 600px;
  margin: 0 auto 2.5rem;
  text-align: center;
  align-self: center;
  opacity: .85;
}
.universe-description p{ margin: 0 0 1.1rem; }
.universe-description p:last-child{ margin-bottom: 0; }
.feature-img{ margin: 1.5rem auto 0; max-width: 300px; width: 100%; }
.feature-img img{ width: 100%; height: auto; display: block; }
.desc-title{
  font-family: var(--font-title);
  text-transform: uppercase;
  font-weight: 400;
  font-size: clamp(1.1rem, 2vw, 1.5rem);
  letter-spacing: .1em;
  color: var(--ink);
  margin: .4rem 0 0;
  line-height: 1.25;
}
.section-label{
  display: none;
}

/* Bio */
.site-intro{
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 6vh 6vw 0;
}
.site-intro + .universe{ padding-top: 0; }
.intro-name{
  font-family: var(--font-body);
  font-weight: 700;
  font-size: clamp(2.2rem, 4.5vw, 3.4rem);
  color: var(--ink);
  text-align: center;
  margin: 0 0 2rem;
  letter-spacing: .01em;
}
.site-intro .bio-portrait{
  max-width: 300px;
  margin: 0;
}
.bio{
  padding: 4vh 6vw 12vh;
  max-width: 720px;
  margin: 0 auto;
}
.bio-name{
  font-family: var(--font-body);
  font-weight: 600;
  font-size: clamp(1.6rem, 3.5vw, 2.4rem);
  color: var(--accent);
  text-align: center;
  margin: 0 0 2rem;
  letter-spacing: .01em;
}
.kicker{
  font-family: var(--font-body);
  font-style: italic;
  font-weight: 300;
  font-size: 1rem;
  color: var(--ink-faint);
  margin: 0 0 3rem;
  letter-spacing: .15em;
  text-transform: lowercase;
  text-align: center;
}
.narrow.text p{
  margin: 0 0 1.4rem;
  color: var(--ink);
  font-size: 17px;
  line-height: 1.8;
  text-align: center;
}
.narrow.text .lede{
  font-family: var(--font-body);
  font-style: normal;
  font-weight: 400;
  font-size: 1.4rem;
  line-height: 1.55;
  color: var(--ink);
  margin-bottom: 2rem;
}
.bio-portrait{
  margin: 3vh auto 5vh;
  max-width: 380px;
  width: 100%;
}
.bio-portrait .frame{ /* natural ratio — no crop */ }

/* Bio + TITUS */
.bio,
.bio p,
#titus .universe-head .epigraph{
  font-family: var(--font-body);
}

/* ── Menu discret (brief §4) ───────────────────────────────────
   Fixed top right, mirroring where the cover puts the name, so the eye already knows
   to look there. Absent over the cover — the six chapters are on that screen in full —
   then a slow fade in, and it stays for the rest of the parcours.

   No background of any kind, at any point. What makes it legible over a full-bleed
   photograph is a parchment halo on the letters: invisible against the parchment page,
   and a soft separation over an image. A panel would put a surface over the work, which
   is the one thing this site does not do. */
.site-menu{
  position: fixed;
  top: clamp(2.4vh, 4vh, 5vh);
  right: 6vw;
  /* Under the PDF overlay (9000) and the gallery overlay (1000) — a menu floating over
     an opened portfolio would be a mistake. */
  z-index: 800;
  text-align: right;
  opacity: 0;
  visibility: hidden;
  transition: opacity 1.4s var(--ease), visibility 0s linear 1.4s;
}
.site-menu.is-visible{
  opacity: 1;
  visibility: visible;
  transition: opacity 1.4s var(--ease), visibility 0s;
}
.site-menu-trigger,
.site-menu a{
  color: var(--ink);
  /* Layered so it reads as a glow rather than an outline. Invisible against the page,
     a soft separation over a pale photograph. */
  text-shadow:
    0 0 4px var(--parchment),
    0 0 10px var(--parchment),
    0 0 22px var(--parchment),
    0 0 34px var(--parchment);
  transition: color .8s var(--ease), text-shadow .8s var(--ease), opacity .6s var(--ease);
}
/* Over a photograph, the exact treatment the cover uses for the name and the chapter
   list — parchment on a soft dark halo — because the chapter openings are full-bleed and
   the darkest of them leaves dark ink unreadable. Applied per line: an open list can
   straddle the seam between an image and the page below it. */
.site-menu-trigger.is-over-image,
.site-menu a.is-over-image{
  color: var(--parchment);
  /* The cover's halo, tightened. The cover sits on one known photograph; the menu
     passes over all of them, including pale ones where a soft wide shadow alone leaves
     parchment text washed out. A denser inner shadow carries it without ever reading as
     a box. */
  text-shadow:
    0 0 2px rgba(58,58,58,.75),
    0 1px 14px rgba(58,58,58,.60),
    0 0 30px rgba(58,58,58,.35);
}
.site-menu-trigger{
  background: none;
  border: 0;
  cursor: pointer;
  /* Generous hit area on a phone; the visual size stays small. */
  padding: .55rem 0 .55rem 1.2rem;
  font-size: .72rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  opacity: .78;
  transition: opacity .6s var(--ease);
}
.site-menu-trigger:hover{ opacity: 1; }
.site-menu-list{
  list-style: none;
  margin: .7rem 0 0;
  padding: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity .9s var(--ease), visibility 0s linear .9s;
}
.site-menu.is-open .site-menu-list{
  opacity: 1;
  visibility: visible;
  transition: opacity .9s var(--ease), visibility 0s;
}
.site-menu-list li + li{ margin-top: .45rem; }
.site-menu-list a{
  display: inline-block;
  padding: .12rem 0;
  font-size: .86rem;
  letter-spacing: .06em;
  text-decoration: none;
  opacity: .68;
  transition: opacity .5s var(--ease);
}
.site-menu-list a:hover{ opacity: 1; }
/* The chapter being read, marked by presence rather than by a rule or a dot. */
.site-menu-list a[aria-current]{ opacity: 1; }
.site-menu-top{ margin-top: 1.3rem !important; }
.site-menu-top a{
  font-size: .68rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  opacity: .55;
}

@media (max-width: 700px){
  .site-menu{ right: 5vw; top: 2.2vh; }
  /* Touch targets: at least 44px tall on a phone, for the trigger and every entry.
     The padding does the work, so nothing grows visually — the tighter li spacing
     below gives the height back. */
  .site-menu-trigger{ padding: 1.05rem 0 1.05rem 1.6rem; }
  .site-menu-list{ margin-top: .2rem; }
  .site-menu-list li + li{ margin-top: 0; }
  .site-menu-list a{ font-size: .95rem; padding: .62rem 0; }
  .site-menu-top{ margin-top: .9rem !important; }
}

@media (prefers-reduced-motion: reduce){
  /* §4 asks that visitors who reduce animation be respected. The menu still appears
     and still opens — it simply stops fading. */
  .site-menu,
  .site-menu.is-visible,
  .site-menu-list,
  .site-menu.is-open .site-menu-list,
  .site-menu-trigger,
  .site-menu a{
    transition: none;
  }
}

/* ── Dernier écran (brief §10) ─────────────────────────────────
   « Le dernier écran doit être très vide. » A full screen of parchment holding one
   line of destinations and the coordonnées, centred, with nothing above them. The
   Expositions list and the portfolio blurb that used to sit here are gone: the list
   moved to expositions.html, which is what Expositions now links to, and §10 asks
   for no conclusion. */
.fin{
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(3vh, 5vh, 6vh);
  padding: clamp(3vh, 5vh, 7vh) 6vw clamp(8vh, 12vh, 14vh);
  text-align: center;
}
.fin-links ul{
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(1.2rem, 3vw, 2.8rem);
}
.fin-link{
  display: inline-block;
  font-size: var(--type-meta);
  letter-spacing: var(--track-meta);
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  transition: opacity .5s var(--ease);
  opacity: .82;
}
.fin-link:hover{ opacity: 1; }
/* The PDF entry is a button, since it opens the overlay rather than navigating.
   It has to be indistinguishable from the links beside it. */
button.fin-link{
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  line-height: inherit;
}
.fin-coordonnees{
  font-style: normal;
  font-size: .82rem;
  line-height: 2;
  letter-spacing: .04em;
  color: var(--ink-soft);
}
.fin-coordonnees a{
  color: inherit;
  text-decoration: none;
  transition: color .5s var(--ease);
}
.fin-coordonnees a:hover{ color: var(--ink); }

@media (max-width: 700px){
  /* Stacked rather than wrapped: uppercase labels reflowing mid-line read as a
     paragraph, not as navigation. The coordonnées stack for the same reason — wrapped
     inline, the « · » separator ends up dangling at the end of a line. */
  .fin-links ul{ flex-direction: column; gap: 1.5rem; }
  .fin-coordonnees{ display: flex; flex-direction: column; gap: .7rem; line-height: 1.5; }
  .fin-coordonnees span{ display: none; }
}

/* ── PDF Modal ───────────────────────────────────────────── */
.pdf-overlay{
  display: none;
  position: fixed;
  inset: 0;
  z-index: 9000;
  background: rgba(10,8,6,.80);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  align-items: center;
  justify-content: center;
  padding: 2vh 3vw;
}
.pdf-overlay.is-open{ display: flex; }
.pdf-shell{
  position: relative;
  width: min(820px, 96vw);
  height: min(92vh, 1120px);
  background: #faf8f3;
  border-radius: 2px;
  box-shadow: 0 32px 80px rgba(0,0,0,.45);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.pdf-close{
  position: absolute;
  top: 10px;
  right: 14px;
  z-index: 2;
  background: none;
  border: none;
  font-size: 1.8rem;
  line-height: 1;
  padding: 4px 8px;
  cursor: pointer;
  color: #7a6a56;
  opacity: .7;
  transition: opacity .25s;
}
.pdf-close:hover{ opacity: 1; }
.pdf-frame{
  flex: 1;
  width: 100%;
  border: none;
  display: block;
}
.colophon{
  margin-top: 8vh;
  font-family: var(--font-body);
  font-size: 11px;
  color: var(--ink-faint);
  letter-spacing: .08em;
}


/* Desktop masonry columns (>=900px) */
@media (min-width: 900px){
  .universe{ padding: 10vh 5vw; }

  /* ── Default: 2-column masonry flow ── */
  .photos-grid{
    width: 100%;
    margin: 0 auto;
    columns: 2;
    column-gap: 1.8rem;
  }
  .photos-grid .photo{
    break-inside: avoid;
    display: block;
    width: 100%;
    max-width: none;
    margin: 0 0 1.8rem;
    padding: 0;
  }
  .photos-grid .photo + .photo{ margin-top: 0; }

  /* ── 3-column override ── */
  .photos-grid.cols-3{ columns: 3; column-gap: 1.2rem; }
  .photos-grid.cols-3 .photo{ margin-bottom: 1.2rem; }

  /* ── Givrée: row-major grid so order = left-to-right reading order ── */
  #glace .photos-grid{
    columns: unset;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.2rem;
  }
  #glace .photos-grid .photo{ margin: 0; }

  /* ── Transformation: preserve explicit 12-col grid ── */
  .photos-grid.explicit{
    columns: unset;
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    column-gap: 1.2cm;
    row-gap: 1.2cm;
    align-items: start;
  }
  .photos-grid.explicit .photo{
    margin: 0;
    grid-column: span 12;
  }
  .photos-grid.explicit .photo.span-2{ grid-column: span 6; }
  .photos-grid.explicit .photo.fill{ align-self: start; }
  .photos-grid.explicit .photo.fill > .frame{ max-width: none; margin: 0; }

  /* ── Transformation + Matière paysage: 3-col bottom-aligned grid ── */
  #transformation .photos-grid.explicit,
  #matiere-paysage .photos-grid.explicit{
    grid-template-columns: repeat(3, 1fr);
    column-gap: 1.2rem;
    row-gap: 1.2rem;
    align-items: stretch;
  }
  #transformation .photos-grid.explicit .photo,
  #matiere-paysage .photos-grid.explicit .photo{
    grid-column: unset;
    min-height: 0;
  }
  #transformation .photos-grid.explicit .frame,
  #matiere-paysage .photos-grid.explicit .frame{ height: 100%; min-height: 0; }
  #transformation .photos-grid.explicit .frame > .img,
  #matiere-paysage .photos-grid.explicit .frame > .img{
    height: 100%;
    width: 100%;
    object-fit: cover;
    object-position: center;
  }

  /* ── Expo: 3 equal-height columns, bottoms aligned ── */
  #expo .photos-grid.explicit{
    columns: unset;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    column-gap: 1rem;
    row-gap: 1rem;
    align-items: stretch;
  }
  /* Exposition: poster beside the description */
  #expo .feature-row{
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 2.5rem;
    max-width: 900px;
    margin: 0 auto 3rem;
    text-align: left;
  }
  #expo .feature-row .universe-description{
    margin: 0;
    max-width: none;
    text-align: left;
    align-self: center;
  }
  #expo .feature-img{
    margin: 0;
    flex: 0 0 300px;
    max-width: 300px;
  }
  #expo .photos-grid.explicit .photo{
    margin: 0;
    grid-column: unset;
    min-height: 0;
  }
  #expo .photos-grid.explicit .frame{ height: 100%; min-height: 0; }
  #expo .photos-grid.explicit .frame > .img{
    height: 100%;
    width: 100%;
    object-fit: cover;
    object-position: center;
  }
}

/* Mobile */
@media (max-width: 720px){
  .universe{ padding: 4vh 0; }
  .photo{ max-width: 100%; padding: 0 4vw; }
  .photo + .photo{ margin-top: 1.2cm; }
  .universe-head{ padding: 0 6vw; }
  .universe.has-mat .photo .frame{ border-width: 18px; }
  .bio{ padding: 10vh 6vw; }

}

/* Reduced motion */
@media (prefers-reduced-motion: reduce){
  .frame > .img, .frame > .placeholder, .frame > .veil{
    transition: opacity .4s ease;
    transform: none !important;
    filter: none !important;
  }
}

/* Gallery CTA + Modal */
.gallery-cta{
  display: block;
  margin: 2.5rem auto 0;
  background: none;
  border: none;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: clamp(.85rem, 1.2vw, .95rem);
  font-style: italic;
  font-weight: 300;
  color: var(--ink-soft);
  letter-spacing: .1em;
  text-decoration: underline;
  text-underline-offset: 4px;
  padding: 0;
  transition: color .2s;
}
.gallery-cta:hover{ color: var(--ink); }

.gallery-overlay{
  position: fixed;
  inset: 0;
  background: rgba(20,14,10,.8);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  backdrop-filter: blur(4px);
}
.gallery-modal{
  position: relative;
  background: var(--parchment);
  max-width: 960px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  padding: 3.5rem 2.5rem 2.5rem;
}
.gallery-close{
  position: absolute;
  top: 1rem;
  right: 1.4rem;
  background: none;
  border: none;
  cursor: pointer;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--ink-soft);
  font-weight: 300;
  transition: color .2s;
}
.gallery-close:hover{ color: var(--ink); }
.gallery-grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.2rem;
  align-items: end;
}
.gallery-grid .gallery-item{ margin: 0; }
.gallery-grid .gallery-img{
  width: 100%;
  height: auto;
  display: block;
}
@media(max-width: 600px){
  .gallery-grid{ grid-template-columns: 1fr; }
  .gallery-modal{ padding: 3rem 1.2rem 1.5rem; }
}

/* Hero fade (kept for compatibility; not currently rendered) */
.hero{
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
}
.hero-frame{ width: 100%; max-width: 540px; aspect-ratio: 9/16; }
.hero-img{ width: 100%; height: 100%; object-fit: contain; }

/* ── Titles: Futura, all-caps, no bold, wide tracking ─────── */
.universe-head h2,
#titus .universe-head h2,
.chapter-title,
.intro-name,
.bio-name,
.kicker{
  font-family: var(--font-title);
  font-style: normal;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: .1em;
}

/* ── Page d'ouverture (brief §3) ──────────────────────────────
   Photograph full bleed. Name top right, six chapters bottom left, scroll hint
   bottom right. Text sits directly on the photograph, so it carries a very soft
   parchment glow rather than a scrim or a panel — enough to stay legible on a light
   image without putting a graphic element between the visitor and the work. */
.cover{
  position: relative;
  height: 100vh;   /* fallback: Safari < 15.4, Chrome < 108 have no svh */
  height: 100svh;
  /* No min-height. A floor taller than the viewport — which 32rem is on any landscape
     phone — pushes the chapter navigation below the fold, so the opening page arrives
     with no navigation on it at all. The viewport height is what "plein écran" means. */
  width: 100%;
  overflow: hidden;
  display: block;
  padding: 0;
}
.cover + .universe{ padding-top: 8vh; }

/* Two very soft veils, top and bottom, so the name and the chapters stay legible over
   any photograph — the cover image is meant to change, and dark ink on a mid-tone
   photograph disappears. Tinted from --ink rather than black, per the no-black rule.
   Nothing here reads as a panel or a graphic element. */
.cover::before,
.cover::after{
  content: '';
  position: absolute;
  left: 0; right: 0;
  pointer-events: none;
  z-index: 1;
}
.cover::before{
  top: 0;
  height: 34%;
  background: linear-gradient(to bottom, rgba(58,58,58,.30), rgba(58,58,58,0));
}
.cover::after{
  bottom: 0;
  height: 42%;
  background: linear-gradient(to top, rgba(58,58,58,.36), rgba(58,58,58,0));
}

.cover picture{ display: block; height: 100%; }
.cover-img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

.cover-name,
.cover-nav,
.cover-scroll{
  position: absolute;
  z-index: 2;
  color: var(--parchment);
  text-shadow: 0 1px 20px rgba(58,58,58,.55), 0 0 3px rgba(58,58,58,.35);
}

.cover-name{
  top: 6vh;
  right: 6vw;
  margin: 0;
  /* Doubled at Julian's request, from clamp(.82rem, 1.15vw, 1.05rem), then raised again
     (2026-08) along with the chapter list and the scroll hint — the whole cover
     furniture went up by about a third in one pass, so the three stay in proportion. */
  font-size: clamp(2.2rem, 3.1vw, 2.8rem);
  text-transform: uppercase;
  letter-spacing: .28em;
  line-height: 1.4;
  text-align: right;
}

.cover-nav{
  bottom: 8vh;
  left: 6vw;
}
.cover-nav ul{
  list-style: none;
  margin: 0;
  padding: 0;
}
.cover-nav li + li{ margin-top: .5rem; }
.cover-nav a{
  text-decoration: none;
  font-size: clamp(1.2rem, 1.45vw, 1.4rem);
  letter-spacing: .07em;
  line-height: 1.5;
  display: inline-block;
  transition: opacity .6s var(--ease);
  opacity: .88;
}
.cover-nav a:hover{ opacity: 1; }

.cover-scroll{
  bottom: 8vh;
  right: 6vw;
  text-decoration: none;
  font-size: .95rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  opacity: .62;
  transition: opacity .6s var(--ease);
}
.cover-scroll:hover{ opacity: .9; }

/* Movement: slow, almost imperceptible. The photograph never animates — it is simply
   there. The name arrives, then each chapter in turn. */
@keyframes coverArrive{
  from{ opacity: 0; }
  to{ opacity: 1; }
}
.cover-name{
  opacity: 0;
  animation: coverArrive 2400ms var(--ease) 400ms both;
}
.cover-nav li{
  opacity: 0;
  animation: coverArrive 1800ms var(--ease) both;
  animation-delay: calc(1600ms + var(--i) * 260ms);
}
.cover-scroll{
  animation: coverArrive 1600ms var(--ease) 3400ms both;
}

@media (max-width: 720px){
  /* Composition has to hold on a phone: the name stays readable, the chapters stay
     reachable, and nothing is cropped arbitrarily tighter than on desktop. */
  /* « Sherine Geagea » is 14 characters of tracked capitals: at 375px there is no room
     left to grow into, so the name is held to what fits on one line and the tracking
     tightened slightly to buy it. The chapters and the hint still take the increase. */
  .cover-name{ top: 4.5vh; right: 7vw; font-size: min(2.2rem, 7vw); letter-spacing: .18em; }
  .cover-nav{ bottom: 11vh; left: 7vw; }
  .cover-nav a{ font-size: 1.3rem; }
  .cover-nav li + li{ margin-top: .6rem; }
  .cover-scroll{ bottom: 5vh; right: 7vw; font-size: .86rem; }
}

/* Short viewports — landscape phones above all. Six chapters plus the name plus the
   scroll hint have to fit in as little as ~320px of height, so the list tightens. */
@media (max-height: 540px){
  /* Raised with the rest of the cover furniture, but by less: six chapters plus the name
     plus the hint still have to clear ~320px of height, so this stays the tightest set. */
  .cover-name{ top: 4vh; right: 5vw; font-size: 1.95rem; letter-spacing: .2em; }
  .cover-nav{ bottom: 5vh; left: 5vw; }
  .cover-nav a{ font-size: 1.04rem; line-height: 1.3; }
  .cover-nav li + li{ margin-top: .1rem; }
  .cover-scroll{ bottom: 5vh; right: 5vw; font-size: .8rem; }
}

@media (prefers-reduced-motion: reduce){
  .cover-name,
  .cover-nav li,
  .cover-scroll{
    animation: none;
    opacity: 1;
  }
  .cover-scroll{ opacity: .62; }
}

/* ── Chapters (brief §5) ──────────────────────────────────────
   Each chapter runs: full-bleed opening → respiration → verb + sous-titre →
   corps visuel → one sentence → full-bleed exit. */
.chapter{ position: relative; display: block; }

/* 1 & 6 — the plates that open and close a chapter. Full width, cinematic height. */
.bleed{ margin: 0; width: 100%; }
.bleed .frame{
  width: 100%;
  height: 82vh;   /* fallback for browsers without svh */
  height: 82svh;
  overflow: hidden;
}
.bleed .img{ width: 100%; height: 100%; object-fit: cover; }

/* 2 — respiration. A large white space before the title arrives. */
.respiration{ height: clamp(14vh, 26vh, 30vh); }

/* 3 — the verb, then one very short line. Sentence case, per the brief's own
   chapter names: Apparaître, not APPARAÎTRE. */
.chapter-head{ text-align: center; padding: 0 6vw; }
.chapter-title{
  margin: 0;
  font-size: var(--type-title);
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: .01em;
  text-transform: none;
}
.chapter-subtitle{
  margin: 1.6rem auto 0;
  max-width: 42ch;
  font-size: var(--type-desc);
  line-height: 1.5;
  color: var(--ink-soft);
}
.chapter-intro{
  max-width: calc(44ch + 12vw);
  margin: clamp(3rem, 7vh, 6rem) auto 0;
  padding: 0 6vw;
  text-align: center;
  font-size: var(--type-body);
}
/* Habiter sends its sous-titre and texte court below the TITUS récit (introAfterTitus in
   content/fr.json), so the chapter opens on the verb alone. They keep .chapter-head for
   its centring and padding; only the space above them is new — .titus already carries
   its own bottom padding, so this is a nudge rather than a full respiration. */
.chapter-head--after-titus{ margin-top: clamp(2vh, 4vh, 6vh); }

/* A thin rule opening a chapter that has no title to announce it, so the transition
   reads as deliberate rather than as a gap. Short and centred: a full-width rule would
   cut the page in two, which the parcours never does. */
.chapter-rule{
  width: min(38%, 22rem);
  margin: 0 auto clamp(6vh, 11vh, 14vh);
  border: 0;
  border-top: 1px solid var(--rule);
}

/* The head of a named série opening the corps visuel: sous-titre, then the série name,
   then its texte court. Same centring and measure as a chapter head — only the title
   size differs, so the two never read as the same level. */
.series-head{ text-align: center; padding: 0 6vw; margin-top: clamp(4vh, 8vh, 11vh); }
.series-title{
  margin: 1.4rem 0 0;
  font-family: var(--font-display);
  font-size: var(--type-title-series);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: .01em;
}

/* 4 — corps visuel. Two independent columns, each filled top to bottom, every
   image at its natural height. The two sides carry different heights, so they drift
   out of phase as you scroll: the sequence reads as a rhythm rather than a grid.
   Nothing is cropped to fit a cell. */
.plates{
  display: flex;
  align-items: flex-start;
  gap: clamp(1.1rem, 4.5vw, 4.5rem);
  max-width: 1440px;
  margin: clamp(6vh, 11vh, 14vh) auto clamp(3vh, 6vh, 8vh);
  padding: 0 6vw;
}
.plates-col{
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(1.1rem, 4.5vw, 4.5rem);
}
/* The second column starts lower — the staircase. On the reference site the drift
   comes for free, because its images mix portrait and landscape so the two columns
   accumulate different heights. Most of Sherine's series are uniformly 2:3, which
   would make the columns align row for row and read as a plain grid. This offset puts
   them out of phase deliberately, and keeps them that way whatever she swaps in.

   A percentage, not a vh clamp. `margin-top` resolves against the *width* of the
   containing block, which is also what sets the column width and therefore the image
   height — so the step stays the same share of an image at every window size. A
   viewport-height clamp drifted: the same page read as a staircase on one screen and
   as a plain grid on another. 21% of the container ≈ 30% of an image's height at 2:3. */
.plates-col:nth-child(2){ margin-top: 21%; }

/* bodyLayout: "grid" — Beirut e(s)t moi in Habiter. A plain grid instead of the two
   drifting columns: four across, no staircase. The tighter gap is deliberate, since the
   column gap above was sized for two wide columns and reads as a chasm between four
   narrow ones. Images still keep their natural ratio: rows begin together at the top and
   are free to end at unequal heights, rather than being cropped into equal cells. */
.plates--grid{
  display: grid;
  /* --grid-cols is set per grid from the content (a gallery's `columns`); three across
     unless a série asks for something else. */
  grid-template-columns: repeat(var(--grid-cols, 3), 1fr);
  align-items: start;
  gap: clamp(.9rem, 2.6vw, 2.8rem);
}
/* Every plate in a grid shares one ratio, so tops and bottoms line up on every row
   (annotated 2026-08). 5:7 is the native ratio of the portraits in these séries, so most
   images give up nothing; a landscape file in the same grid is cropped to portrait,
   which is the price of a level row. Override --grid-ratio per grid to change it. */
.plates--grid .plate .frame{ aspect-ratio: var(--grid-ratio, 5 / 7); }
.plates--grid .plate .img{ height: 100%; object-fit: cover; }
/* At a third of the width the 22px passe-partout outweighs the image it frames. */
.plates--grid .plate--mat .frame{ border-width: clamp(8px, 1vw, 14px); }
/* One image on its own: centred at a column's width, rather than left in one half of a
   two-column row with the other half empty. */
.plates--single{ justify-content: center; }
.plates--single .plates-col{ flex: 0 1 50%; }
.plate{ margin: 0; width: 100%; }
.plate .frame{ width: 100%; }
.plate .img{ width: 100%; height: auto; }

/* The white passe-partout of the Beirut e(s)t moi series. Two scopes: `mat` on a
   chapter, which mats every plate in it, and `mat` on a single photo, which is how
   beirut_01 and beirut_02 keep their border now that they sit in Habiter among
   images that are not matted. */
.chapter.has-mat .plate .frame,
.plate--mat .frame{
  border: 22px solid var(--white);
  box-shadow: 0 8px 32px rgba(90,70,54,.12), 0 1px 3px rgba(90,70,54,.07);
}

/* Légende — discreet, but present, to identify the work (brief §12). */
.legende{
  margin: 0 auto clamp(6vh, 10vh, 13vh);
  padding: 0 6vw;
  text-align: center;
  font-size: .7rem;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* 5 — one sentence. Never a paragraph. */
.chapter-sentence{
  max-width: calc(42ch + 12vw);
  margin: 0 auto clamp(10vh, 16vh, 20vh);
  padding: 0 6vw;
  text-align: center;
  font-size: var(--type-lead);
  line-height: 1.65;
  color: var(--ink);
}

/* Coda of Transmettre — portrait, name, biography. No « Bio » heading (§9). */
.coda{
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 6vw clamp(3vh, 6vh, 8vh);
}
.coda-portrait{ margin: 0 0 clamp(4vh, 8vh, 10vh); width: 100%; max-width: 420px; }
.coda-portrait .img{ width: 100%; height: auto; }
.coda-name{
  margin: 0 0 clamp(3vh, 5vh, 6vh);
  font-size: clamp(1.5rem, 3vw, 2.3rem);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .16em;
  text-align: center;
}
.coda-text{ max-width: 62ch; }
.coda-text p{ margin: 0 0 1.4rem; text-align: left; }
.coda-text p:last-child{ margin-bottom: 0; }

@media (max-width: 720px){
  /* One column on a phone. The images keep their own height, so the sequence
     survives — it simply becomes a single river. */
  .plates{ flex-direction: column; gap: 1.2cm; padding: 0 4vw; }
  .plates-col{ gap: 1.2cm; }
  /* The grid stays a grid on a phone — two across, not one river. */
  .plates--grid{ grid-template-columns: repeat(2, 1fr); gap: clamp(.7rem, 3vw, 1.2rem); }
  .plates--grid .plate--mat .frame{ border-width: 8px; }
  /* No staircase in a single column — the offset would just open a gap in the middle
     of the river, wider than every other gap around it. */
  .plates-col:nth-child(2){ margin-top: 0; }
  .bleed .frame{ height: 68svh; }
  .respiration{ height: 12vh; }
  .chapter.has-mat .plate .frame,
  .plate--mat .frame{ border-width: 14px; }
  .coda-text p{ text-align: left; }
}

/* ── Brief §12 — per-element assignments ──────────────────────
   Nom → Canela Bold · Titres → Canela Regular · Citations → Canela Italic
   Textes → Neue Haas Grotesk · Menu → NHG Medium · Légendes → NHG Light
   The title/name selectors above already route through --font-title, which now
   resolves to --font-display; what follows sets the weights and styles the brief
   asks for, and moves légendes and the menu onto the text face. */

/* Nom « Sherine Geagea » — Canela Bold */
.intro-name,
.bio-name,
.cover-name,
.coda-name{
  font-family: var(--font-display);
  font-weight: 700;
}

/* Citations — Canela Italic */
.universe-head .epigraph,
.universe-head .subtitle,
#titus .universe-head .epigraph,
.cover-subtitle,
.chapter-subtitle,
.chapter-sentence,
.citation{
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
}

/* Légendes des œuvres — Neue Haas Grotesk Light */
.universe-head .series-title,
.legende{
  font-family: var(--font-text);
  font-style: normal;
  font-weight: 300;
}

/* Menu discret — Neue Haas Grotesk Medium */
.gallery-cta,
.cover-nav a,
.site-menu a,
.site-menu-trigger,
.cover-scroll,
.fin-link{
  font-family: var(--font-text);
  font-style: normal;
  font-weight: 500;
}

/* ── TITUS, inside Habiter (brief §7) ─────────────────────────
   The récit, then Titus en mouvement, then privatisation kept visibly apart from
   the artistic narrative and leading to its own page (§12). */
.titus{
  max-width: calc(62ch + 12vw);   /* +12vw so the padding does not eat the measure */
  /* Breathing room: without it the récit's opening line lands directly under the
     chapter's sous-titre and the two italic serif lines read as one block. */
  margin: clamp(6vh, 10vh, 12vh) auto 0;
  padding: 0 6vw clamp(4vh, 8vh, 10vh);
}
/* On a wide screen the block was leaving very large empty margins either side, and the
   three views read as stamps in the middle of the page rather than as a row.
   The block itself widens and the prose is held to its own measure inside it, rather
   than the images breaking out of a narrow block: a negative-margin breakout has to be
   re-derived from the padding every time either changes, and centres wrongly the moment
   it is off. This way the three views simply fill the block they are already in. */
@media (min-width: 1000px){
  .titus{ max-width: calc(94ch + 12vw); }
  /* A line of prose past roughly 75 characters gets hard to track, so the récit and the
     quote keep their measure and stay centred while the block around them grows. */
  .titus-recit,
  .titus-quote{ max-width: 72ch; margin-inline: auto; }
}
/* The TITUS wordmark, opening the Titus block — space above and below so it reads as
   a threshold into the maison. It links to titus.html; the click target is the mark
   itself, centred, with a quiet hover. */
.titus-logo-link{
  display: block;
  width: clamp(84px, 12vw, 128px);
  margin: clamp(3vh, 6vh, 8vh) auto clamp(4vh, 7vh, 9vh);
  opacity: .92;
  transition: opacity .45s var(--ease);
}
.titus-logo-link:hover{ opacity: 1; }
.titus-logo{
  display: block;
  width: 100%;
  height: auto;
}
.titus-quote{
  margin: 0 0 clamp(3vh, 6vh, 7vh);
  text-align: center;
  font-size: var(--type-lead);
  line-height: 1.55;
}
.titus-recit p{ margin: 0 0 1.4rem; }
.titus-recit p:last-child{ margin-bottom: 0; }

.titus-kicker{
  margin: clamp(6vh, 10vh, 12vh) 0 clamp(2vh, 4vh, 5vh);
  font-family: var(--font-text);
  font-size: var(--type-section);
  font-weight: 500;
  letter-spacing: var(--track-section);
  text-transform: uppercase;
  color: var(--ink-soft);
}
.titus-mouvement{
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* Tightened (2026-08): at the old clamp(1.8rem, 3vw, 2.6rem) the four entries read as
     four separate blocks rather than one list. */
  gap: clamp(1.1rem, 1.8vw, 1.5rem);
}
.titus-mouvement h4{
  margin: 0 0 .3rem;
  font-family: var(--font-text);
  /* Was --type-label (.82rem), which sat visibly below the prose it labels. Matched to
     the body size so the list reads at the same scale as the section above it. */
  font-size: var(--type-body);
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.titus-mouvement p{ margin: 0; }
.titus-mouvement a{ border-bottom: 1px solid var(--rule); text-decoration: none; }

/* « Workshops » in Titus en mouvement jumps to the série lower down the page. The
   heading is the link, so it keeps the hairline rule the other links use and inherits
   its own colour rather than looking like a second kind of type. */
.titus-mouvement h4 a{ color: inherit; }
.titus-mouvement h4 a:hover{ color: var(--ink); border-color: var(--ink); }
/* A jump that lands hard is at odds with a site built on slow reveals — but only for
   people who have not asked for less movement. */
@media (prefers-reduced-motion: no-preference){
  html{ scroll-behavior: smooth; }
}
/* The fixed header sits over the top of the page, so an anchor target has to clear it
   or its heading lands underneath. */
#workshops,
#collaborations,
#evenements{ scroll-margin-top: clamp(5rem, 12vh, 7rem); }

/* TITUSMOOD — the player « Écouter » opens in place. Held to the measure of the text it
   belongs to rather than the full width: it is a footnote to the line above, not a
   feature of the page. Spotify renders its own dark widget inside the iframe and none of
   it can be styled from here, so the restraint has to come from the frame around it. */
.titusmood-player{
  margin-top: clamp(1rem, 2vh, 1.4rem);
  max-width: 42rem;
  animation: coverArrive .6s var(--ease) both;
}
.titusmood-player[hidden]{ display: none; }
.titusmood-player iframe{
  display: block;
  width: 100%;
  border: 0;
  border-radius: 12px;
}
@media (prefers-reduced-motion: reduce){
  .titusmood-player{ animation: none; }
}

/* ── Les workshops : les cercles ──────────────────────────────────────────────
   Thirteen circles, every one the same diameter, wrapping on their own. Each shows a
   different detail of a flower photograph the site already carries: --crop names the
   file and --x/--y place the detail inside the circle, so a new circle costs one line
   and no new asset. background-size: cover keeps the crop resolution-independent. */
.atelier-cercles{
  list-style: none;
  margin: clamp(4vh, 7vh, 9vh) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(1.1rem, 2.6vw, 2.2rem);
}
.atelier-cercle{
  /* One size for all of them — a circle is never sized by its label. */
  width: var(--cercle, 148px);
  height: var(--cercle, 148px);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background-image: var(--crop);
  background-size: cover;
  background-position: var(--x, 50%) var(--y, 50%);
  cursor: pointer;
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  /* The veil the rest of the site uses on its plates, so a circle sits in the parchment
     rather than punching a hole in it. It lifts on hover and on focus. */
  box-shadow: 0 6px 26px rgba(90,70,54,.10), 0 1px 3px rgba(90,70,54,.06);
  transition: transform .9s var(--ease), box-shadow .9s var(--ease);
}
.atelier-cercle::before{
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  /* Lighter than it was: the crops are photographs of the people who gave the
     workshops, and at .52 they read as ghosts. The name keeps its legibility from
     the halo below rather than from drowning the picture. */
  background: rgba(250,250,248,.40);
  transition: background-color .9s var(--ease);
}
.atelier-cercle:hover,
.atelier-cercle:focus-visible{
  transform: translateY(-4px);
  box-shadow: 0 12px 34px rgba(90,70,54,.16), 0 1px 3px rgba(90,70,54,.07);
}
.atelier-cercle:hover::before,
.atelier-cercle:focus-visible::before{ background: rgba(250,250,248,.14); }
.atelier-cercle:focus-visible{ outline: 1px solid var(--ink); outline-offset: 4px; }
/* The name sits on the crop, not under it: the circle is the whole target. */
.atelier-nom{
  position: relative;
  z-index: 1;
  padding: 0 .6em;
  font-family: var(--font-text);
  font-size: .74rem;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-align: center;
  line-height: 1.35;
  color: var(--ink);
  text-shadow: 0 1px 3px rgba(250,250,248,1), 0 0 14px rgba(250,250,248,.95), 0 0 26px rgba(250,250,248,.75);
}

/* ── Les workshops : le film ──────────────────────────────────────────────────
   Opened over the page. `hidden` until asked for, and the <video> carries no src at
   rest, so none of the ~126 MB is fetched until a circle is activated. */
.atelier-vue[hidden]{ display: none; }
.atelier-vue{
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(.4rem, 2vw, 1.6rem);
  /* The top padding reserves the strip .atelier-fermer occupies: it is absolutely
     positioned, so without this the vertically-centred film slides under it on a short
     viewport (a landscape phone) and the Fermer button sits on top of the picture. */
  padding: clamp(4.5rem, 9vh, 6rem) clamp(1rem, 4vw, 3rem) clamp(1rem, 4vw, 3rem);
  background: rgba(250,250,248,.97);
  animation: coverArrive .5s var(--ease) both;
}
.atelier-scene{
  flex: 1 1 auto;
  min-width: 0;
  max-width: 1100px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(.8rem, 2vh, 1.4rem);
}
.atelier-video{
  width: 100%;
  max-height: 74vh;
  background: var(--ink);
  border-radius: 2px;
  box-shadow: 0 12px 40px rgba(90,70,54,.16);
}
.atelier-legende{
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--type-desc);
  color: var(--ink-soft);
  text-align: center;
}
.atelier-fermer,
.atelier-fleche{
  flex: 0 0 auto;
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--ink-soft);
  border-radius: 999px;
  cursor: pointer;
  font-family: var(--font-text);
  transition: color .45s var(--ease), border-color .45s var(--ease);
}
.atelier-fermer:hover,
.atelier-fleche:hover{ color: var(--ink); border-color: var(--ink); }
.atelier-fermer:focus-visible,
.atelier-fleche:focus-visible{ outline: 1px solid var(--ink); outline-offset: 3px; }
.atelier-fleche{
  /* 44px minimum: these are tapped on a phone as much as clicked. */
  width: 48px; height: 48px;
  display: grid; place-items: center;
  font-size: 1.1rem;
  line-height: 1;
}
.atelier-fermer{
  position: absolute;
  top: clamp(1rem, 3vw, 2rem);
  right: clamp(1rem, 4vw, 3rem);
  padding: .7em 1.4em;
  font-size: .7rem;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
}

@media (max-width: 720px){
  .atelier-cercle{ --cercle: 124px; }
  /* On a phone the arrows move under the film rather than squeezing it from the sides. */
  .atelier-vue{ flex-wrap: wrap; align-content: center; }
  .atelier-scene{ order: -1; flex-basis: 100%; }
  .atelier-video{ max-height: 56vh; }
}

@media (prefers-reduced-motion: reduce){
  .atelier-cercle,
  .atelier-cercle::before{ transition: none; }
  .atelier-cercle:hover,
  .atelier-cercle:focus-visible{ transform: none; }
  .atelier-vue{ animation: none; }
}

/* Privatisation — a commercial offer sitting inside an artist's parcours, so it is
   set apart by a rule and quieter type rather than by a box or a button. */
/* Titus set as type rather than as the wordmark — same face and size as the série title
   of Beirut e(s)t moi, centred like the wordmark it replaces. */
.titus-title{
  margin: 0 0 clamp(2vh, 4vh, 5vh);
  text-align: center;
}

/* The maison in three views. Landscape frames, so they sit across the récit's own
   measure and stack on a phone rather than shrinking to stamps.
   auto-fit, not repeat(3, …): the row fills whatever is there. Two views sit as two
   equal halves and three as three thirds, so a missing file never leaves a hole in the
   row — it simply makes the others wider. */
.titus-gallery{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr));
  align-items: start;
  gap: clamp(.7rem, 1.8vw, 1.5rem);
  margin: clamp(4vh, 7vh, 9vh) 0 0;
}
/* The views share one ratio so their top and bottom edges line up (annotated 2026-08).
   This is the one place on the site where an image is cropped to fit — everywhere else
   a photograph keeps its own height. 3:2 is titus_01's native ratio, so only the others
   give anything up, and the columns are equal, so equal ratio means equal height. */
.titus-gallery .plate .frame{ aspect-ratio: 3 / 2; }
.titus-gallery .plate .img{ height: 100%; object-fit: cover; }
@media (max-width: 720px){
  .titus-gallery{ grid-template-columns: 1fr; gap: 1.2cm; }
}

/* No rule above the CTA (annotated 2026-08): with the privatisation copy gone, the line
   separated the button from the images for no reason. The space it framed is kept.
   The block is centred so the lone CTA sits under the middle of the measure; the copy
   below stays ranged left, so restoring it does not silently recentre it. */
.privatisation{
  margin-top: clamp(3vh, 5vh, 6vh);
  padding-top: clamp(2vh, 4vh, 5vh);
  text-align: center;
}
.privatisation .titus-kicker,
.privatisation-lede{ text-align: left; }
.privatisation-lede{
  margin: 0 0 clamp(2vh, 4vh, 5vh);
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--type-desc);
  line-height: 1.6;
}
.privatisation-links{
  margin: 0;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: .84rem;
  letter-spacing: .1em;
}
.privatisation-links a{
  text-decoration: none;
  border-bottom: 1px solid var(--ink-faint);
  padding-bottom: 2px;
  transition: border-color .5s var(--ease);
}
.privatisation-links a:hover{ border-color: var(--ink); }

/* « Découvrir l'espace » — an outlined CTA under the privatisation lede that leads to
   titus.html. Fills on hover; quiet enough to sit inside an artist's page. */
.privatisation-cta{
  display: inline-block;
  margin-top: clamp(2.5vh, 4vh, 5vh);
  padding: .9em 2.1em;
  border: 1px solid var(--ink);
  border-radius: 999px;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: .74rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  transition: background-color .45s var(--ease), color .45s var(--ease);
}
.privatisation-cta:hover{ background: var(--ink); color: var(--parchment); }

/* Chapter galleries — a titled set of images (the TITUS space, the Barbie series),
   set within a chapter's scroll. A masonry keeps every file's natural aspect while
   the two columns drift out of phase, echoing the corps visuel; a small caps title
   names the set. Namespaced away from the .gallery-* lightbox above. */
.chapter-gallery{
  max-width: 1440px;
  margin: clamp(6vh, 11vh, 14vh) auto clamp(3vh, 6vh, 8vh);
  padding: 0 6vw;
}
.chapter-gallery-title{
  margin: 0 0 clamp(3.5vh, 6vh, 7vh);
  text-align: center;
  font-family: var(--font-text);
  font-weight: 500;
  /* ~3× the original .74rem kicker, at Julian's request — a proper section title. */
  font-size: var(--type-section);
  letter-spacing: var(--track-section);
  text-transform: uppercase;
  color: var(--ink-soft);
}
/* A grid série nests .plates inside .chapter-gallery, and both carry `padding: 0 6vw`,
   so the gutters added up to 12vw and the série sat visibly narrower than the corps
   visuel above it. The inner one yields. */
.chapter-gallery .plates{ padding-left: 0; padding-right: 0; }

/* A grid série is titled like Beirut e(s)t moi and Titus rather than as the old
   uppercase kicker: same face, same size, one step below the chapter verb. Declared
   after the kicker so it wins on the properties the two share. */
.chapter-gallery-title.series-title{
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--type-title-series);
  letter-spacing: .01em;
  text-transform: none;
  color: var(--ink);
}

.chapter-gallery-grid{
  display: flex;
  align-items: flex-start;
  gap: clamp(1.1rem, 4.5vw, 4.5rem);
}
.chapter-gallery-col{
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(1.1rem, 4.5vw, 4.5rem);
}
/* The staircase: the second column starts lower, exactly like the corps visuel. */
.chapter-gallery-col:nth-child(2){ margin-top: 21%; }
@media (max-width: 720px){
  /* One river on a phone, like the corps visuel. */
  .chapter-gallery-grid{ flex-direction: column; gap: 1.2cm; }
  .chapter-gallery-col{ gap: 1.2cm; }
  .chapter-gallery-col:nth-child(2){ margin-top: 0; }
  .chapter-gallery{ padding: 0 4vw; }
}

/* ── Secondary page (titus.html) ──────────────────────────────
   Not part of the scroll — a quiet document you arrive at from Habiter. */
.page{
  max-width: calc(68ch + 12vw);
  margin: 0 auto;
  padding: clamp(8vh, 14vh, 16vh) 6vw clamp(10vh, 16vh, 18vh);
}
.page-back{
  display: inline-block;
  margin-bottom: clamp(5vh, 9vh, 11vh);
  font-family: var(--font-text);
  font-weight: 500;
  font-size: var(--type-meta);
  letter-spacing: var(--track-meta);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-soft);
}
.page-back:hover{ color: var(--ink); }

/* The fixed return link a secondary page carries top-left, opposite the « Chapitres »
   menu top-right — the header titus.html established, now shared with expositions.html
   so the two cannot drift. Same discreet uppercase register as the menu. */
.page-home{
  position: fixed; top: clamp(2.4vh, 4vh, 5vh); left: 6vw; z-index: 800;
  font-family: var(--font-text); font-weight: 500; font-size: var(--type-meta);
  letter-spacing: var(--track-meta); text-transform: uppercase; text-decoration: none;
  color: var(--ink-soft); opacity: .82;
  transition: color .5s var(--ease), opacity .5s var(--ease);
}
.page-home:hover{ color: var(--ink); opacity: 1; }
@media (max-width: 700px){ .page-home{ left: 5vw; top: 2.2vh; } }
/* Both header items are fixed and neither reserves room for the other, so on a narrow
   phone « Retour à Sherine Geagea » ran under the Chapitres trigger and its last words
   were caught by the menu instead of the link. Dropping « Retour à » is better than
   ellipsising a person's name, and leaves exactly the label titus.html already uses. */
.page-home{ white-space: nowrap; }
/* The menu's own box is wider than the word « Chapitres » it shows, and it is fixed on
   top of the return link, so it was swallowing clicks over empty space. Only the parts
   that are actually visible should take a pointer. */
.site-menu{ pointer-events: none; }
.site-menu-trigger,
.site-menu-list{ pointer-events: auto; }
@media (max-width: 520px){
  .page-home-long{
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
}

/* A page whose title is its masthead: centred, and at the scale of a chapter title
   rather than the smaller secondary-page size. Clears the fixed header above it.
   `.page.page--titled` rather than `.page--titled`: `.page h1` below carries the same
   specificity and is declared later, so it would otherwise win on font-size. */
.page.page--titled{ padding-top: clamp(14vh, 22vh, 26vh); }
.page.page--titled > h1{
  margin-bottom: clamp(6vh, 10vh, 12vh);
  text-align: center;
  font-size: var(--type-title);
}
/* TITUS wordmark as the masthead of titus.html — centred above the description. */
.page-logo{
  display: block;
  width: clamp(96px, 15vw, 148px);
  height: auto;
  margin: clamp(1vh, 3vh, 4vh) auto clamp(4vh, 7vh, 9vh);
  opacity: .92;
}
.page h1{
  margin: 0 0 clamp(3vh, 5vh, 6vh);
  font-family: var(--font-display);
  font-size: var(--type-title-page);
  font-weight: 400;
  line-height: 1.15;
}
.page-lede{
  margin: 0 0 clamp(3vh, 6vh, 7vh);
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--type-desc);
  line-height: 1.6;
}
/* Centred under the wordmark on maisontitus.com, where the lede is a single line
   standing on its own. A modifier rather than a change to .page-lede, because the lede
   on expositions.html is a paragraph and stays ranged left with the prose. */
.page-lede--centre{ text-align: center; }
/* The opening line of titus.html — a touch larger than the other lede, as the page's
   first statement. */
.page-lede.page-lede--hero{  /* both classes -> wins over .page-lede regardless of source order */
  font-size: var(--type-lead);
  line-height: 1.4;
}
.page p{ margin: 0 0 1.4rem; }
.page h2{
  margin: clamp(7vh, 11vh, 13vh) 0 clamp(2vh, 4vh, 5vh);
  font-family: var(--font-text);
  font-size: var(--type-section);
  font-weight: 500;
  letter-spacing: var(--track-section);
  text-transform: uppercase;
  color: var(--ink-soft);
}
/* « Elle naît à Beyrouth. / Elle traverse la Méditerranée. / … » — four lines that are
   the passage's rhythm, so they keep their breaks and sit a little apart from the prose
   above them, in the display italic the site uses for the artist's own voice. */
.page-voyage{
  margin-top: clamp(3vh, 5vh, 6vh);
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--type-desc);
  line-height: 1.75;
  color: var(--ink-soft);
}

.page-contact{ list-style: none; margin: 0; padding: 0; }
.page-contact li{ margin-bottom: .6rem; }
.page-contact a{ text-decoration: none; border-bottom: 1px solid var(--rule); }

/* The TITUS space gallery on titus.html — the photography moved here from Habiter's
   « Découvrir l'espace ». A two-column masonry that keeps each file's natural aspect.
   Static: this page loads no app.js, so it must NOT use the .frame/.veil reveal (which
   stays at opacity 0 without the IntersectionObserver). Plain <img>/<video> instead. */
.espace-gallery{
  columns: 2;
  column-gap: clamp(.9rem, 2.5vw, 1.4rem);
  margin: clamp(3vh, 5vh, 6vh) 0 0;
}
.espace-plate{
  margin: 0 0 clamp(.9rem, 2.5vw, 1.4rem);
  break-inside: avoid;
}
.espace-plate img,
.espace-plate video{
  width: 100%;
  height: auto;
  display: block;
}
@media (max-width: 560px){
  .espace-gallery{ columns: 1; }
}

/* The exhibition list on expositions.html — a year against its entry, one rule
   between them, nothing more. */
.page-list{ list-style: none; margin: 0 0 clamp(4vh, 7vh, 8vh); padding: 0; }
.page-list li{
  display: grid;
  grid-template-columns: 5rem 1fr;
  gap: 1.5rem;
  align-items: baseline;
  padding-bottom: 1.4rem;
  margin-bottom: 1.4rem;
  border-bottom: 1px solid var(--rule);
}
.page-list li:last-child{ border-bottom: none; }
.page-list-year{
  font-family: var(--font-text);
  font-weight: 300;
  font-size: .78rem;
  letter-spacing: .12em;
  color: var(--ink-soft);
}
.page-list-meta{ display: block; }
.page-list-title{
  display: block;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--type-desc);
  line-height: 1.4;
}
.page-list-where{
  display: block;
  font-size: .92rem;
  color: var(--ink-soft);
}

/* Images on a secondary page: a single column at natural ratio, nothing cropped. */
/* Exposition gallery — breaks out of the narrow reading column into a wide two-column
   staircase, echoing the parcours corps visuel: the second column drifts down. */
.page-figures{
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  width: min(94vw, 1180px);
  margin-top: clamp(6vh, 11vh, 14vh);
  display: flex;
  align-items: flex-start;
  gap: clamp(1rem, 3.2vw, 3.2rem);
}
.page-figures-col{
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(1rem, 3.2vw, 3.2rem);
}
.page-figures-col:nth-child(2){ margin-top: 12%; }
.page-figures figure{ margin: 0; }
.page-figures img{ display: block; width: 100%; height: auto; }
@media (max-width: 700px){
  /* One river on a phone: no breakout, no staircase. */
  .page-figures{ left: auto; transform: none; width: 100%; flex-direction: column; gap: 1.2cm; }
  .page-figures-col{ gap: 1.2cm; }
  .page-figures-col:nth-child(2){ margin-top: 0; }
}

@media (max-width: 700px){
  .page-list li{ grid-template-columns: 1fr; gap: .3rem; }
}

/* A line attached to the images directly above it, not to the whole chapter. */
.body-note{
  max-width: calc(40ch + 12vw);
  margin: clamp(-2vh, -1vh, 0px) auto clamp(5vh, 9vh, 11vh);
  padding: 0 6vw;
  text-align: center;
  font-size: var(--type-desc);
  line-height: 1.6;
  color: var(--ink-soft);
}
