/* ==========================================================================
   Grapheva — page Réalisations
   Grille, filtres et visionneuse repris de l’ancienne feuille du site : ils
   fonctionnent, les retoucher n'apportait rien. Seuls les jetons de couleur
   sont retraduits ci-dessous vers ceux du redesign, pour que la page tienne
   sans l'ancienne feuille.
   ========================================================================== */

.works-page,
.works-lightbox {
  --bg: var(--ink-deep);
  --bg-elevated: var(--ink-panel);
  --bg-elevated-hover: #393a44;
  --ink: #ffffff;
  --ink-muted: var(--muted);
  --border: var(--hairline);
  --grid-line: rgba(255, 255, 255, 0.035);
  --radius-sm: var(--r-sm);
  --ease: var(--ease-out-soft);
}

.works-page{
  display: flex;
  align-items: flex-start;
  gap: 6.25vw;
  /* Bottom padding keeps the sticky sidebar (and the hover readout at its
     foot) from settling flush against the footer once you scroll to the
     end of the mosaic. */
  padding: 150px 6.25vw 72px 6.25vw;
  background: var(--bg);
  transition: background-color .35s var(--ease);
}

/* ---- Sidebar: title + categories ----
   Sticky rather than fixed, so it rides alongside the mosaic but stops
   at the end of the section instead of floating over the footer. */
.works-sidebar{
  position: sticky;
  top: 110px;
  width: 12.5vw;
  flex-shrink: 0;
  z-index: 5;
}
.works-title{
  font-size: 1.9rem;
  font-weight: 300;
  letter-spacing: .04em;
  line-height: 1.1;
  margin: 0 0 6.25vw;
}
.works-cats ul{ display:block; }
.works-cat{
  display:block;
  position:relative;
  border-bottom: 1px solid var(--border);
  margin: 0 0 20px;
  transition: border-color .3s var(--ease);
}
.works-cat button{
  display:flex; align-items:baseline; justify-content:space-between; gap:10px;
  width:100%;
  padding: 5px 0;
  background:none; border:none;
  text-align:left;
  font-family: inherit;
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .06em;
  line-height: 1.45;
  color: var(--ink-muted);
  transition: color .3s var(--ease), padding-left .3s var(--ease);
}
.works-cat button:hover{ color: var(--ink); }
.works-cat.is-active{ border-color: var(--ink); }
.works-cat.is-active button{ color: var(--ink); }
/* Zero-padded tally (024, 006) — recomputed from the markup by js/galerie.js */
.works-count{
  flex-shrink:0;
  font-size: .7rem; font-weight: 700; letter-spacing: .1em;
  font-variant-numeric: tabular-nums;
  opacity: .55;
}
/* Compact control that replaces the list once the sidebar unpins */
.works-select{ display:none; }
.works-select select{
  font: inherit; font-size:.85rem;
  color: var(--ink);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 11px 14px;
  width: 100%;
}

/* ---- Mosaic ----
   6 columns over the track the sidebar leaves free — 100vw less the page
   padding (2 × 6.25vw), the sidebar (12.5vw) and the flex gap (6.25vw),
   i.e. 68.75vw — separated by --mosaic-gap. grid-auto-rows subtracts the
   gaps so a row is exactly as tall as a column is wide: every module is a
   square (1×1 or 2×2). */
.works-mosaic{
  --mosaic-gap: 10px;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-auto-rows: calc((68.75vw - 5 * var(--mosaic-gap)) / 6);
  grid-auto-flow: dense;
  gap: var(--mosaic-gap);
  flex: 1;
  min-width: 0;
}
.tile{
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: 5px;
  grid-column: span 1;
  grid-row: span 1;
}
.tile--w2{ grid-column: span 2; }
.tile--h2{ grid-row: span 2; }
.tile[hidden]{ display:none; }

/* Placeholder surface: theme-aware gradient + fine trame + logomark
   watermark. Set --img on .tile-media to drop a real photograph in;
   it covers the placeholder completely. */
.tile-media{
  position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center;
  background-image:
    repeating-linear-gradient(90deg, var(--grid-line) 0 1px, transparent 1px 38px),
    repeating-linear-gradient(0deg, var(--grid-line) 0 1px, transparent 1px 38px),
    linear-gradient(150deg, var(--bg-elevated), var(--bg-elevated-hover));
  background-size: auto, auto, cover;
  transition: opacity .3s var(--ease), transform .6s var(--ease);
}
.tile:nth-child(3n+2) .tile-media{
  background-image:
    repeating-linear-gradient(90deg, var(--grid-line) 0 1px, transparent 1px 38px),
    repeating-linear-gradient(0deg, var(--grid-line) 0 1px, transparent 1px 38px),
    linear-gradient(28deg, var(--bg-elevated-hover), var(--bg-elevated));
}
.tile:nth-child(3n+3) .tile-media{
  background-image:
    repeating-linear-gradient(90deg, var(--grid-line) 0 1px, transparent 1px 38px),
    repeating-linear-gradient(0deg, var(--grid-line) 0 1px, transparent 1px 38px),
    linear-gradient(205deg, var(--bg-elevated), var(--bg-elevated-hover));
}
/* Photograph layer — paints over the watermark once --img is set */
.tile-media::after{
  content:""; position:absolute; inset:0;
  background-image: var(--img, none);
  background-size: cover;
  background-position: center;
}
.tile-mark{
  width: 30%; max-width: 72px; height:auto;
  color: var(--ink);
  opacity: .07;
}
/* Hairline separating adjacent modules. The reference has none — its
   tiles are photographs — but flat placeholders need the edge to read. */
.tile::before{
  content:""; position:absolute; inset:0; z-index:2;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--border);
  pointer-events:none;
}

/* Hover: the pointed-at tile lifts, everything else recedes */
.works-mosaic.is-hovered .tile-media{ opacity: .2; }
.tile:hover .tile-media,
.tile:focus-visible .tile-media{ opacity: 1; transform: scale(1.03); }

/* Wipe-in "open" badge at the centre of the hovered tile */
.tile::after{
  content:"";
  position:absolute; inset:0; margin:auto;
  width:50px; height:50px; z-index:3;
  background-color: var(--accent-fill);
  background-image: linear-gradient(var(--accent-on-fill), var(--accent-on-fill)),
                    linear-gradient(var(--accent-on-fill), var(--accent-on-fill));
  background-size: 14px 1px, 1px 14px;
  background-position: center, center;
  background-repeat: no-repeat;
  clip-path: polygon(0 0, 0 0, 0 100%, 0 100%);
  transition: clip-path .35s var(--ease);
}
.tile:hover::after,
.tile:focus-visible::after{ clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }

/* ---- Readout: year + name of the hovered project ----
   Lives at the foot of the sidebar column rather than pinned to the
   viewport, so it stays inside its column and can never ride over the
   footer. Nothing sits below it, so fading it in shifts no other
   content — only opacity animates. */
.works-readout{
  margin-top: 40px;
  padding-top: 22px;
  border-top: 1px solid var(--border);
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s var(--ease);
}
.works-readout.is-visible{ opacity: 1; }
.works-readout-year{
  display:flex; align-items:center; gap:15px;
  font-size: .62rem; font-weight: 600; letter-spacing: .06em;
  color: var(--ink-muted);
  margin-bottom: 10px;
}
.works-readout-year::before{
  content:""; display:block;
  width:0; height:0;
  border-left: 6px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
}
.works-readout-title{
  font-size: .78rem; font-weight: 300; letter-spacing: .03em;
  color: var(--ink);
}

/* ---- Detail overlay (stands in for per-project pages) ---- */
.works-lightbox{
  position:fixed; inset:0; z-index:200;
  display:none;
  align-items:center; justify-content:center;
  padding: 48px;
  background: rgba(9,9,11,.9);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.works-lightbox.is-open{ display:flex; }
/* Full-screen dialog: media stage on the left 60%, description + CTA on
   the right 40%. Fills the viewport inside the overlay's 12px inset. */
.lightbox-dialog{
  position:relative;
  display:grid; grid-template-columns: 60% 40%;
  width: 100%;
  height: 100%;
  max-height: none;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 5px;
  overflow:hidden;
}
.lightbox-frame{
  position:relative;
  min-height: 0;
  overflow:hidden;
  background: var(--bg-elevated);
}

/* ---- Carousel (the "images" work type) ---------------------------------
   A horizontal track of full-bleed slides translated by whole widths.
   Arrows sit over the media as translucent chips; a pill counter and a
   morphing dot row anchor to the corners. Controls collapse when a
   project has a single slide (.is-single). */
.carousel{ position:absolute; inset:0; }
.carousel-track{
  display:flex; height:100%;
  transition: transform .5s var(--ease);
  will-change: transform;
  touch-action: pan-y;
}
.carousel.is-dragging .carousel-track,
.carousel.no-anim .carousel-track{ transition:none; }

.cslide{ position:relative; flex:0 0 100%; height:100%; overflow:hidden; }
/* Per-slide surface: brand placeholder (trame + gradient + logomark and a
   faint slide number), overpainted by the real photo when --img is set. */
.cslide-media{
  position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center;
  background-image:
    repeating-linear-gradient(90deg, var(--grid-line) 0 1px, transparent 1px 38px),
    repeating-linear-gradient(0deg, var(--grid-line) 0 1px, transparent 1px 38px),
    linear-gradient(150deg, var(--bg-elevated), var(--bg-elevated-hover));
}
.cslide:nth-child(3n+2) .cslide-media{
  background-image:
    repeating-linear-gradient(90deg, var(--grid-line) 0 1px, transparent 1px 38px),
    repeating-linear-gradient(0deg, var(--grid-line) 0 1px, transparent 1px 38px),
    linear-gradient(28deg, var(--bg-elevated-hover), var(--bg-elevated));
}
.cslide:nth-child(3n+3) .cslide-media{
  background-image:
    repeating-linear-gradient(90deg, var(--grid-line) 0 1px, transparent 1px 38px),
    repeating-linear-gradient(0deg, var(--grid-line) 0 1px, transparent 1px 38px),
    linear-gradient(205deg, var(--bg-elevated), var(--bg-elevated-hover));
}
.cslide-media::after{
  content:""; position:absolute; inset:0; z-index:2;
  background-image: var(--img, none);
  background-size: cover; background-position:center;
}
.cslide-num{
  position:absolute; left:18px; top:14px;
  font-size:2.4rem; font-weight:700; letter-spacing:.04em;
  color: var(--ink); opacity:.10;
  font-variant-numeric: tabular-nums;
}
.cslide .tile-mark{ width:24%; max-width:92px; opacity:.09; }

/* Arrows — dark translucent chips, image-agnostic in either theme */
.carousel-arrow{
  position:absolute; top:50%; transform: translateY(-50%);
  z-index:4;
  display:inline-flex; align-items:center; justify-content:center;
  width:44px; height:44px; border-radius:50%;
  border:1px solid rgba(255,255,255,.14);
  background: rgba(9,9,11,.5);
  color:#fff;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  opacity:0;
  transition: opacity .3s var(--ease), background-color .2s var(--ease), transform .2s var(--ease);
}
.carousel-prev{ left:16px; }
.carousel-next{ right:16px; }
.carousel:hover .carousel-arrow,
.carousel:focus-within .carousel-arrow{ opacity:1; }
.carousel-arrow:hover{ background: rgba(9,9,11,.72); }
.carousel-prev:hover{ transform: translateY(-50%) scale(1.08) translateX(-2px); }
.carousel-next:hover{ transform: translateY(-50%) scale(1.08) translateX(2px); }

/* Position counter — pill, top-right of the media column (the close chip
   sits over the info column, so they never meet) */
.carousel-count{
  position:absolute; top:16px; right:16px; z-index:4;
  font-size:.7rem; font-weight:600; letter-spacing:.12em;
  font-variant-numeric: tabular-nums;
  color:#fff; background: rgba(9,9,11,.5);
  padding:5px 11px; border-radius:999px;
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
}

/* Dot row — active dot stretches into a bar */
.carousel-dots{
  position:absolute; left:0; right:0; bottom:16px; z-index:4;
  display:flex; gap:7px; justify-content:center; align-items:center;
}
.carousel-dot{
  width:7px; height:7px; border-radius:999px; padding:0;
  border:none; background: rgba(255,255,255,.45);
  transition: width .3s var(--ease), background-color .3s var(--ease);
}
.carousel-dot:hover{ background: rgba(255,255,255,.7); }
.carousel-dot.is-active{ width:22px; background:#fff; }

/* Single-slide projects (maquette / before-after fallback): no controls */
.carousel.is-single .carousel-arrow,
.carousel.is-single .carousel-count,
.carousel.is-single .carousel-dots{ display:none; }

@media (prefers-reduced-motion: reduce){
  .carousel-track{ transition:none; }
}
.lightbox-info{
  padding: clamp(32px, 4vw, 64px);
  display:flex; flex-direction:column; gap:14px;
  overflow-y:auto;
}
.lightbox-cat{
  font-size:.68rem; font-weight:600; letter-spacing:.06em;
  color: var(--ink-muted);
}
.lightbox-title{
  font-size:1.35rem; font-weight:300; letter-spacing:.01em;
  line-height:1.3;
  /* keeps a long title from running under the close button */
  padding-right: 42px;
}
.lightbox-desc{ font-size:.95rem; line-height:1.7; color: var(--ink-muted); margin-top:6px; }
.lightbox-actions{ display:flex; align-items:center; gap:10px; margin-top:auto; padding-top: 24px; }
/* Floats over the media, so it keeps one look in both themes:
   white glyph on a dark chip, inset from the dialog corner. */
.lightbox-close{
  position:absolute; top:12px; right:12px; z-index:4;
  display:inline-flex; align-items:center; justify-content:center;
  width:38px; height:38px;
  border:none;
  border-radius: 5px;
  background: rgba(9,9,11,.72);
  color: #fff;
  transition: background-color .2s var(--ease);
}
.lightbox-close:hover{ background: rgba(9,9,11,.92); }

@media (prefers-reduced-motion: reduce){
  .tile-media{ transition: opacity .3s; }
  .tile:hover .tile-media{ transform:none; }
  .tile::after{ transition:none; }
}

/* ---- Mosaic responsive ----
   The sidebar unpins and the module count drops; wide/tall spans are
   progressively flattened so a tile never dominates a narrow screen. */
@media (max-width: 1400px){
  .works-page{ gap: 5vw; padding-left: 5vw; padding-right: 5vw; }
  .works-sidebar{ width: 16vw; }
  .works-mosaic{
    /* 100vw − 2×5vw padding − 16vw sidebar − 5vw flex gap = 69vw */
    grid-template-columns: repeat(5, 1fr);
    grid-auto-rows: calc((69vw - 4 * var(--mosaic-gap)) / 5);
  }
}

@media (max-width: 1080px){
  .works-page{
    display: block;
    padding: 120px 24px 56px;
  }
  .works-sidebar{
    position: static;
    width: 100%;
    max-width: var(--container-w);
    margin-inline: auto;
  }
  .works-title{ font-size:1.6rem; margin-bottom: 26px; }
  .works-cats{ display:none; }
  .works-select{ display:block; max-width: 320px; }
  /* Sidebar is no longer a column here, and hover has no meaning on touch */
  .works-readout{ display:none; }
  .works-mosaic{
    width: 100%;
    margin-left: 0;
    margin-top: 40px;
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: calc((100vw - 48px - 3 * var(--mosaic-gap)) / 4);
  }
}

@media (max-width: 760px){
  .works-page{ padding-top: 100px; }
  .works-mosaic{
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: calc((100vw - 48px - var(--mosaic-gap)) / 2);
  }
  /* Two columns only — every tile flattens to the same square module */
  .tile--w2{ grid-column: span 1; }
  .tile--h2{ grid-row: span 1; }
  .tile::after{ width:40px; height:40px; }
  /* 48px a side would eat a phone screen */
  .works-lightbox{ padding: 16px; }
  /* Too narrow for two columns — the media stage moves back on top and
     the info panel takes the rest of the screen height */
  .lightbox-dialog{
    grid-template-columns: 1fr;
    grid-template-rows: auto minmax(0, 1fr);
  }
  .lightbox-frame{ aspect-ratio: 4 / 3; min-height:0; }
  .lightbox-info{ padding: 28px 24px 30px; }
  /* Stacked again, so the close chip lands on the media — shift the
     image counter clear of it */
  .carousel-count{ right: 60px; }
  .carousel-arrow{ width:38px; height:38px; }
  .carousel-prev{ left:10px; }
  .carousel-next{ right:10px; }
}

/* No hover to reveal the arrows on touch devices — keep them visible */
@media (hover: none){
  .carousel-arrow{ opacity:1; }
}

