/* ---------- Fonts ---------- */
@font-face {
  font-family: "Alcyone";
  src: url("../assets/fonts/Alcyone-Thin.woff2?v=2") format("woff2");
  font-weight: 100; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Alcyone";
  src: url("../assets/fonts/Alcyone-ExtraLight.woff2?v=2") format("woff2");
  font-weight: 200; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Alcyone";
  src: url("../assets/fonts/Alcyone-Light.woff2?v=2") format("woff2");
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Alcyone";
  src: url("../assets/fonts/Alcyone-Regular.woff2?v=2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Alcyone";
  src: url("../assets/fonts/Alcyone-Medium.woff2?v=2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Alcyone";
  src: url("../assets/fonts/Alcyone-SemiBold.woff2?v=2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Alcyone";
  src: url("../assets/fonts/Alcyone-Bold.woff2?v=2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Alcyone";
  src: url("../assets/fonts/Alcyone-Black.woff2?v=2") format("woff2");
  font-weight: 900; font-style: normal; font-display: swap;
}

/* ---------- Tokens ---------- */
:root{
  --noir: #000000;
  --blanc: #fdfdfd;
  --rose: #fe08a3;
  --creme: #f3f1ec;

  --font: "Alcyone", "Helvetica Neue", Arial, sans-serif;

  /* One type scale for every page: running text, and the small grey
     uppercase labels ("Le projet", "Projet suivant", "Email"…). */
  --fs-text: clamp(14px, 1.1vw, 17px);
  --lh-text: 1.55;
  --fs-label: 12px;
  --fw-label: 600;
  --ls-label: .12em;
  --fs-small: 13px;

  /* Space above and below every section of the home page, so the gap
     between two sections is the same everywhere. */
  --section-pad: clamp(40px, 5.5vw, 80px);

  --nav-h: 64px;
  --pad-x: clamp(20px, 4vw, 56px);

  --ease: cubic-bezier(.16,1,.3,1);
  --ease-soft: cubic-bezier(.22,.61,.36,1);
}

/* ---------- Reset ---------- */
*, *::before, *::after{ box-sizing: border-box; }
html, body{ height: 100%; }
body{
  margin: 0;
  background: var(--blanc);
  color: var(--noir);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img{ display:block; max-width:100%; }
a{ color: inherit; text-decoration: none; }
button{ font-family: inherit; cursor: pointer; background:none; border:0; color: inherit; }
h1,h2,h3,p{ margin:0; }

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

/* =====================================================
   SITE / HEADER
===================================================== */
.site{ opacity: .01; }
.site.is-ready{ opacity: 1; transition: opacity .6s var(--ease); }

.header{
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  height: var(--nav-h);
  display:flex;
  align-items:center;
  justify-content: space-between;
  padding: 0 var(--pad-x);
  background: var(--noir);
}
.header__logo{
  display:flex;
  align-items:center;
  gap: 10px;
  position: relative;
  z-index: 1;
}
.header__mark{
  display: block;
  width: 58px;
  height: auto;
  filter: brightness(0) invert(1);
}
.header__word{
  font-weight: 600;
  font-size: 14px;
  letter-spacing: .01em;
  color: var(--blanc);
}
.header__nav{
  display:flex;
  gap: clamp(20px, 3vw, 40px);
}
.header__nav a{
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .04em;
  color: var(--blanc);
  position: relative;
  padding-bottom: 2px;
  transition: color .3s var(--ease);
}
.header__nav a::after{
  content:"";
  position:absolute;
  left:0; right:100%;
  bottom:-2px;
  height:1px;
  background: currentColor;
  transition: right .35s var(--ease);
}
.header__nav a:hover{ color: var(--rose); }
.header__nav a:hover::after{ right: 0; }

/* Two-line menu toggle, only shown where the links no longer fit (see the
   HEADER — MENU block in the responsive section). */
.header__toggle{ display: none; }

/* =====================================================
   HERO
===================================================== */
.hero{
  position: relative;
  /* At least one screen; taller when the text needs it (a phone held
     sideways), so nothing ends up under the fixed header. */
  min-height: 100vh;
  /* svh, not dvh: on a phone the address bar slides away while scrolling,
     and a dvh height would resize (and visibly re-zoom) the photo with it.
     --screen-h (js/main.js) is the screen height measured once, which even
     in-app browsers such as Instagram's cannot change mid-scroll. */
  min-height: 100svh;
  min-height: var(--screen-h, 100svh);
  padding-top: calc(var(--nav-h) + 24px);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

.hero__media{
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--noir);
}
.hero__media img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 56%;
}

.hero__scrim{
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(to top, rgba(0,0,0,.72) 0%, rgba(0,0,0,.28) 32%, transparent 58%),
    linear-gradient(to bottom, rgba(0,0,0,.5) 0%, transparent 22%);
}

.hero__text{
  position: relative;
  z-index: 2;
  display:flex;
  flex-direction: column;
  gap: clamp(8px, calc(var(--screen-h, 100vh) * .014), 16px);
  /* Set high enough that the sentences stay clear of the legs in the photo. */
  padding: 0 var(--pad-x) clamp(96px, calc(var(--screen-h, 100vh) * .3), 320px);
  max-width: 1040px;
}

.hero__eyebrow{
  font-size: clamp(14px, 1.25vw, 18px);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--rose);
}

.hero__title{
  font-weight: 900;
  /* Capped by the screen height too, so the name, the sentences and the
     button always fit above the fold. */
  font-size: clamp(44px, min(9vw, calc(var(--screen-h, 100vh) * .15)), 150px);
  line-height: .92;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--noir);
  display:flex;
  flex-direction: column;
  width: fit-content;
  cursor: default;
  transition: color .35s var(--ease);
}
.hero__title:hover{ color: var(--rose); }

/* "17 ans dans les Médias et la Communication." always on one line. */
.hero__sub-lead{ white-space: nowrap; }
.hero__sub{
  /* js/main.js sets its margin and width so the justified lines run from the
     V to the L of "VOGEL"; the max-width is the standing value until then. */
  max-width: 46ch;
  font-size: clamp(14px, min(1.2vw, calc(var(--screen-h, 100vh) * .021)), 19px);
  line-height: var(--lh-text);
  /* The same dark grey as on a phone. */
  color: rgba(0,0,0,.75);
  font-weight: 700;
  text-align: justify;
}

.hero__cta{
  margin-top: clamp(6px, calc(var(--screen-h, 100vh) * .014), 14px);
  display: inline-flex;
  width: fit-content;
  align-items: center;
  padding: 14px 28px;
  /* The same dark grey as the paragraph above it. */
  border: 1.5px solid rgba(0,0,0,.75);
  color: rgba(0,0,0,.75);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.hero__cta span{ position: relative; z-index: 1; transition: color .35s var(--ease); }
.hero__cta::before{
  content:"";
  position:absolute;
  inset: 0;
  background: var(--rose);
  transform: translateY(101%);
  transition: transform .4s var(--ease);
  z-index: 0;
}
.hero__cta:hover::before{ transform: translateY(0); }
.hero__cta:hover span{ color: var(--noir); }

/* =====================================================
   PROJECTS
===================================================== */
/* The sections simply follow one another as the page scrolls: no pinning,
   no section sliding over the previous one. */
.projects{
  position: relative;
  background: var(--blanc);
  padding: var(--section-pad) var(--pad-x);
  display: grid;
  grid-template-columns: minmax(220px, 0.85fr) 2fr;
  gap: clamp(32px, 6vw, 96px);
  align-items: start;
}

.projects__intro{
  position: sticky;
  top: calc(var(--nav-h) + clamp(24px, 6vh, 64px));
  display: flex;
  flex-direction: column;
  gap: clamp(14px, 2vh, 24px);
}

.projects__title{
  font-weight: 900;
  /* Capitals run wider: sized so the longest (SERVICES) fits its column,
     and capped at the size of the project page titles. */
  font-size: clamp(44px, 4.8vw, 80px);
  line-height: .92;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--noir);
  width: fit-content;
  cursor: default;
  transition: color .35s var(--ease);
}
.projects__title:hover{ color: var(--rose); }

.projects__sub{
  max-width: 32ch;
  font-size: var(--fs-text);
  line-height: var(--lh-text);
  font-weight: 700;
  color: rgba(0,0,0,.62);
}
.projects__sub a{
  color: var(--rose);
  transition: opacity .3s var(--ease);
}
.projects__sub a:hover{ opacity: .7; }

.projects__grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(10px, 1.4vw, 20px);
}

/* Each card is the project's logo, nothing else. On hover (or keyboard
   focus) the card lifts and gets a pink frame, which says "click me". */
.project-card{
  position: relative;
  display: block;
  aspect-ratio: 1;
  overflow: hidden;
  transition: transform .3s var(--ease);
}

.project-card__media{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Drawn over the image: a hairline at rest, so the light logos still read
   as a card on the white page; the pink frame on hover. */
.project-card::after{
  content: "";
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.08);
  pointer-events: none;
  transition: box-shadow .3s var(--ease);
}

.project-card:hover,
.project-card:focus-visible{
  outline: none;
  transform: translateY(-4px);
}
.project-card:hover::after,
.project-card:focus-visible::after{
  box-shadow: inset 0 0 0 3px var(--rose);
}

/* =====================================================
   EXPLORATIONS & CAMPAGNES
   No thumbnails here: the word itself is the link, set as large as the
   screen allows, like a type specimen. The detail lives on the section's
   own page.
===================================================== */
.bigsec{
  position: relative;
  background: var(--blanc);
  color: var(--noir);
  display: flex;
}

.bigsec__link{
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--section-pad) var(--pad-x);
  overflow: hidden;
}

/* The description sits to the left of the first line, in the gap the indent
   leaves for it. */
.bigsec__row{
  display: flex;
  align-items: flex-start;
  gap: clamp(20px, 3vw, 48px);
}

.bigsec__note{
  flex: 0 0 auto;
  width: clamp(170px, 19vw, 300px);
  /* Its own settings, not the display ones it sits next to. */
  white-space: normal;
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0;
  /* The top is aligned on the letters, not on the boxes, at every screen
     width: the display sizes follow vw, the text size clamps, so the offset
     subtracts the text's own cap height (E cap: 0.027em of the 24vw line). */
  --note-fs: clamp(14px, 1.1vw, 17px);
  /* The page margin, as for every other section; js/main.js refines it. */
  padding-left: var(--pad-x);
  margin-top: calc(0.648vw - var(--note-fs) * 0.387);
  font-size: var(--note-fs);
  line-height: var(--lh-text);
  color: rgba(0,0,0,.62);
  transition: color .35s var(--ease);
}

/* The word runs the full width of the screen; anything that does not fit is
   cropped by the section, as on a printed specimen. */
.bigsec__word{
  display: block;
  margin: 0 0 0 calc(-1 * var(--pad-x));
  font-weight: 900;
  /* Sized so the word spans the screen exactly: measured 7.45em wide. */
  font-size: 13.4vw;
  line-height: .8;
  letter-spacing: -0.035em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: color .35s var(--ease);
}
/* Campagnes mirrors it: the gap is on the right, and the text sits in it. */
.bigsec--campagnes .bigsec__note{
  /* Pushed against the right edge, where the A above ends. The exact inset is
     measured by js/main.js; 1% of the page is the standing approximation. */
  margin-left: auto;
  /* Slid left to meet the end of the line above. js/main.js measures the
     exact distance; 17% of the page stands in until it runs. */
  transform: translateX(calc(-17 * var(--vwpx, 1vw)));
  text-align: right;
  padding-left: 0;
}
/* The row reaches the right edge of the screen, where the S below ends. */
.bigsec--campagnes .bigsec__row{ margin-right: calc(-1 * var(--pad-x)); }
/* Campagnes keeps one size for both lines: the longer one sets it and runs
   edge to edge, the shorter one leaves the gap the text sits in. */

/* Split over two lines. Both sections share one size — the longest line
   (RATIONS) sets it by running edge to edge, the shorter ones fall back and
   leave the gap the text sits in.
   The sizes are a share of --vwpx (a hundredth of the page width, set by
   js/main.js) rather than of vw, which counts the scrollbar and would push
   the last letter past the edge. */
.bigsec__line{
  display: block;
  line-height: .78;
  font-size: calc(22.54 * var(--vwpx, 1vw));
}
.bigsec__line--a{ margin-left: auto; } /* pushed right, text in the gap */
/* The capitals sit slightly inside their line box (2.8% of the size at the
   top, 2.6% at the bottom): pulled out by that much, the visible letters
   start and end exactly on the section padding, like every other section. */
.bigsec__line--a,
.bigsec__line--c{ margin-top: -0.028em; }
.bigsec__line--b,
.bigsec__line--d{ margin-bottom: -0.026em; }

.bigsec__link:hover .bigsec__word,
.bigsec__link:focus-visible .bigsec__word{ color: var(--rose); }

/* =====================================================
   SERVICES
===================================================== */
.services{
  position: relative;
  background: var(--blanc);
  padding: var(--section-pad) var(--pad-x);
  display: grid;
  grid-template-columns: 2fr minmax(220px, 0.85fr);
  gap: clamp(32px, 6vw, 96px);
  align-items: start;
}

.services__intro{
  position: sticky;
  top: calc(var(--nav-h) + clamp(24px, 6vh, 64px));
  order: 2;
}

.services__title{
  /* Capitals start on the section padding, as for Contact. */
  margin-top: -0.09em;
  font-weight: 900;
  /* Capitals run wider: sized so the longest (SERVICES) fits its column,
     and capped at the size of the project page titles. */
  font-size: clamp(44px, 4.8vw, 80px);
  line-height: .92;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--noir);
  width: fit-content;
  cursor: default;
  transition: color .35s var(--ease);
}
.services__title:hover{ color: var(--rose); }

.services__list{
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 1000px;
  order: 1;
}

.services__item{
  display: grid;
  /* minmax(0, …) keeps every row on the same columns: a plain fr track
     widens to fit a long unbreakable word ("Communication"). */
  grid-template-columns: 3.5rem minmax(0, 1.2fr) minmax(0, 1fr);
  align-items: baseline;
  gap: clamp(16px, 3vw, 40px);
  /* Rows also scale with viewport height, so the whole list fits on one
     screen. */
  padding: clamp(10px, 2vh, 24px) 0;
  border-top: 1px solid rgba(0,0,0,.12);
}
.services__item:last-child{
  border-bottom: 1px solid rgba(0,0,0,.12);
}
/* On hover the content slides right. A transform, not padding: padding
   would narrow the columns and re-wrap the descriptions. */
.services__list .services__item > *{ transition: transform .35s var(--ease), color .35s var(--ease); }
.services__list .services__item:hover > *{ transform: translateX(14px); }

.services__index{
  font-size: 13px;
  letter-spacing: .1em;
  color: rgba(0,0,0,.4);
  font-variant-numeric: tabular-nums;
  transition: color .35s var(--ease);
}

.services__name{
  font-weight: 700;
  font-size: clamp(18px, min(2.2vw, 3.8vh), 30px);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--noir);
  transition: color .35s var(--ease);
}

.services__desc{
  font-size: var(--fs-text);
  font-weight: 700;
  line-height: var(--lh-text);
  color: rgba(0,0,0,.55);
  transition: color .35s var(--ease);
}

/* =====================================================
   ABOUT
===================================================== */
.about{
  position: relative;
  background: var(--blanc);
  padding: var(--section-pad) var(--pad-x);
  display: grid;
  grid-template-columns: 1.3fr minmax(260px, 0.9fr);
  gap: clamp(40px, 6vw, 96px);
  align-items: center;
}

.about__carousel{
  width: 100%;
  max-width: 420px;
  order: 2;
}

.about__track{
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--blanc);
}

.about__slide{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .6s var(--ease);
}
.about__slide.is-active{
  opacity: 1;
  z-index: 1;
}

.about__dots{
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 20px;
}

.about__dot{
  width: 8px;
  height: 8px;
  border-radius: 50%;
  padding: 0;
  border: 0;
  background: rgba(0,0,0,.2);
  cursor: pointer;
  transition: background .3s var(--ease), transform .3s var(--ease);
}
/* A larger, invisible tap area around each dot. */
.about__dot{ position: relative; }
.about__dot::after{
  content: "";
  position: absolute;
  inset: -5px;
}
.about__dot:hover{ background: rgba(0,0,0,.4); }
.about__dot.is-active{
  background: var(--rose);
  transform: scale(1.3);
}

.about__content{
  display: flex;
  flex-direction: column;
  gap: clamp(20px, 3vh, 32px);
  order: 1;
}

.about__title{
  font-weight: 900;
  /* Capitals run wider: sized so the longest (SERVICES) fits its column,
     and capped at the size of the project page titles. */
  font-size: clamp(44px, 4.8vw, 80px);
  line-height: .92;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--noir);
  width: fit-content;
  cursor: default;
  transition: color .35s var(--ease);
}
.about__title:hover{ color: var(--rose); }

.about__text{
  max-width: 58ch;
  font-size: var(--fs-text);
  line-height: var(--lh-text);
  font-weight: 700;
  color: rgba(0,0,0,.62);
}

.about__meta{
  margin: 0;
  display: flex;
  flex-direction: column;
  max-width: 560px;
}
.about__meta-row{
  display: grid;
  /* The label column narrows on phones, so the values (the Instagram
     handle) stay on one line. */
  /* Wide enough for INSTAGRAM and EXPERTISE on the narrowest phones. */
  grid-template-columns: clamp(90px, 25vw, 140px) minmax(0, 1fr);
  gap: clamp(10px, 3vw, 16px);
  padding: 14px 0;
  border-top: 1px solid rgba(0,0,0,.12);
}
.about__meta-row:last-child{
  border-bottom: 1px solid rgba(0,0,0,.12);
}
.about__meta-row dt{
  margin: 0;
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: rgba(0,0,0,.45);
  font-weight: var(--fw-label);
}
.about__meta-row dd{
  margin: 0;
  overflow-wrap: anywhere;
  font-size: var(--fs-text);
  font-weight: 500;
  color: var(--noir);
}
.about__meta-row a{
  color: var(--rose);
  transition: opacity .3s var(--ease);
}
.about__meta-row a:hover{ opacity: .7; }

.services__item:hover .services__index{ color: var(--rose); }
.services__item:hover .services__name,
.services__item:hover .services__desc{ color: var(--rose); }

/* =====================================================
   CONTACT
===================================================== */
.contact{
  position: relative;
  background: var(--blanc);
  /* Same padding and columns as Services: title top-right, details on the left.
     Section + footer fill exactly one screen, so at the bottom of the page the
     title stays clear of the fixed header. --footer-h is set by js/main.js. */
  padding: var(--section-pad) var(--pad-x);
  min-height: calc(100vh - var(--footer-h, 64px));
  min-height: calc(100svh - var(--footer-h, 64px));
  display: grid;
  grid-template-columns: 2fr minmax(220px, 0.85fr);
  gap: clamp(32px, 6vw, 96px);
}

.contact__title{
  order: 2;
  align-self: start;
  /* The capitals sit 9% of the size inside the line box: pulled up by that
     much, the title starts on the section padding like the other sections. */
  margin-top: -0.09em;
  font-weight: 900;
  /* Capitals run wider: sized so the longest (SERVICES) fits its column,
     and capped at the size of the project page titles. */
  font-size: clamp(44px, 4.8vw, 80px);
  line-height: .92;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--noir);
  width: fit-content;
  cursor: default;
  transition: color .35s var(--ease);
}
.contact__title:hover{ color: var(--rose); }

.contact__list{
  order: 1;
  /* Centred in the visible area: the top margin offsets the fixed header
     that covers the top of the section. */
  align-self: center;
  margin: var(--nav-h) 0 0;
  border-top: 1px solid rgba(0,0,0,.14);
}

.contact__row{
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px clamp(20px, 4vw, 48px);
  padding: clamp(10px, 2vh, 22px) 0;
  border-bottom: 1px solid rgba(0,0,0,.14);
}

.contact__label{
  flex: 0 0 auto;
  font-size: var(--fs-label);
  font-weight: var(--fw-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: rgba(0,0,0,.45);
}

.contact__field{
  margin: 0;
  text-align: right;
}

.contact__value{
  font-weight: 700;
  font-size: clamp(20px, 3.2vw, 40px);
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: var(--noir);
  transition: color .3s var(--ease);
}
/* Applies to the plain-text values too (localisation), so every row
   reacts the same way on hover. */
.contact__value:hover{ color: var(--rose); }

@media (max-width: 560px){
  .contact__row{
    flex-direction: column;
    align-items: flex-start;
  }
  .contact__field{ text-align: left; }
}

/* =====================================================
   FOOTER
===================================================== */
.footer{
  position: relative;
  background: var(--noir);
  padding: clamp(20px, 3.2vh, 32px) var(--pad-x);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}

.footer__copy{
  font-size: var(--fs-small);
  color: rgba(253,253,253,.6);
}

/* Site credit — quieter than the copyright line so it stays discreet. */
.footer__credit{
  font-size: var(--fs-small);
  color: rgba(253,253,253,.45);
}

.footer__legal{
  display: flex;
  align-items: center;
  gap: 14px;
}
.footer__legal a{
  font-size: 13px;
  color: rgba(253,253,253,.6);
  position: relative;
  padding-bottom: 2px;
  transition: color .3s var(--ease);
}
.footer__legal a::after{
  content:"";
  position:absolute;
  left:0; right:100%;
  bottom:-2px;
  height:1px;
  background: currentColor;
  transition: right .35s var(--ease);
}
.footer__legal a:hover{ color: var(--rose); }
.footer__legal a:hover::after{ right: 0; }

.footer__sep{
  color: rgba(253,253,253,.3);
  font-size: 13px;
}

/* Reveal-in elements (driven by JS on page load) */
[data-reveal]{
  opacity: 0;
  transform: translateY(22px);
}
.site.is-ready [data-reveal]{
  animation: reveal-up .8s var(--ease-soft) forwards;
}
.site.is-ready .hero__title span:nth-child(1){ animation-delay: .05s; }
.site.is-ready .hero__title span:nth-child(2){ animation-delay: .12s; }
.site.is-ready .hero__eyebrow{ animation-delay: 0s; }
.site.is-ready .hero__sub{ animation-delay: .22s; }
.site.is-ready .hero__cta{ animation-delay: .3s; }

@keyframes reveal-up{
  to{ opacity: 1; transform: translateY(0); }
}

/* =====================================================
   RESPONSIVE
===================================================== */
/* HEADER — MENU
   Below 821px the six links no longer fit beside the logo: they move into a
   full-screen panel opened by the two-line toggle (js/nav.js). */
@media (max-width: 820px){
  .header__toggle{
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 6px;
    width: 40px;
    height: 40px;
    margin-right: -8px;
    padding: 8px;
    position: relative;
    z-index: 2;
  }
  .header__toggle span{
    display: block;
    width: 24px;
    height: 1.5px;
    background: var(--blanc);
    transition: transform .35s var(--ease), background-color .3s var(--ease);
  }
  .header__toggle:hover span{ background: var(--rose); }
  /* The two lines meet in a cross: each moves half of (gap + line height). */
  .header.is-open .header__toggle span:first-child{ transform: translateY(3.75px) rotate(45deg); }
  .header.is-open .header__toggle span:last-child{ transform: translateY(-3.75px) rotate(-45deg); }

  .header__nav{
    position: fixed;
    inset: var(--nav-h) 0 0 0;
    flex-direction: column;
    justify-content: center;
    gap: clamp(10px, 2.4vh, 22px);
    padding: 0 var(--pad-x) var(--nav-h);
    background: var(--noir);
    opacity: 0;
    visibility: hidden;
    transition: opacity .35s var(--ease), visibility 0s linear .35s;
  }
  .header.is-open .header__nav{
    opacity: 1;
    visibility: visible;
    transition: opacity .35s var(--ease);
  }
  .header__nav a{
    width: fit-content;
    font-size: clamp(30px, 8.5vw, 48px);
    font-weight: 900;
    line-height: 1.05;
    letter-spacing: -0.01em;
  }
  .header__nav a::after{ display: none; }
  html.nav-open{ overflow: hidden; }
}

@media (max-width: 900px){
  /* Capped by the height too, for phones held sideways. */
  .hero__title{ font-size: clamp(36px, min(15vw, calc(var(--screen-h, 100vh) * .16)), 84px); }
  /* The longest names (DMC.LUXURY, VÉTÉRINAIRE) must fit the narrowest
     phones (280px). */
  .pnext .pnext__title{ font-size: clamp(22px, 8vw, 40px); }
  .hero__sub{ text-align: left; }
  .hero__text{ max-width: none; }
  .projects{
    position: relative;
    grid-template-columns: 1fr;
    gap: clamp(28px, 6vh, 48px);
  }
  .projects__intro{
    position: static;
  }
  /* Too narrow to sit beside the word: the text goes back above it, and the
     first line runs the full width again. */
  .bigsec__row{
    flex-direction: column;
    gap: clamp(20px, 4vh, 40px);
  }
  .bigsec__note{
    width: auto;
    max-width: 34ch;
    /* The word bleeds past the page gutter; its text must not. */
    padding-left: var(--pad-x);
    /* Pulled up by the space above its capitals, so the section starts on
       its padding like the others. */
    margin-top: -0.34em;
  }
  /* Stacked, both words start at the left edge. */
  .bigsec__line--a{ margin-left: 0; }
  /* The text belongs above the whole word here, not between its two lines:
     the row dissolves so all three can be ordered freely. */
  .bigsec--campagnes .bigsec__word{
    display: flex;
    flex-direction: column;
  }
  .bigsec--campagnes .bigsec__row{ display: contents; }
  .bigsec--campagnes .bigsec__note{
    order: -1;
    margin: -0.34em 0 clamp(20px, 4vh, 40px);
    text-align: left;
    padding-left: var(--pad-x);
    /* Nothing to slide towards here: it sits above the word. */
    transform: none;
  }
  .services{
    grid-template-columns: 1fr;
    gap: clamp(28px, 6vh, 48px);
  }
  .services__intro{
    position: static;
    order: initial;
  }
  .services__list{
    order: initial;
  }
  .services__item{
    grid-template-columns: 1fr;
    gap: 6px;
  }
  .services__index{ order: -1; }
  .about{
    /* minmax(0, …): a plain 1fr would grow to the carousel's 320px minimum
       and push the page sideways on the narrowest phones. */
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(32px, 6vh, 48px);
  }
  .about__carousel{
    max-width: 320px;
    margin: 0 auto;
    order: initial;
  }
  .about__content{
    order: initial;
  }
  /* On a phone the section is as tall as its content: the details sit
     right under the title, and the footer follows after the usual section
     space. */
  .contact{
    display: flex;
    flex-direction: column;
    gap: clamp(20px, 4vh, 32px);
    min-height: 0;
    padding-bottom: var(--section-pad);
  }
  .contact__title,
  .contact__list{
    order: initial;
  }
  /* Full width, on the page margin like the title and the other sections. */
  .contact__list{ margin: 0; align-self: stretch; }
}

/* On a phone or tablet held upright, the photo cropped to the screen hides
   the person behind the text. The photo is scaled down instead and set on
   the floor of the screen, so the whole pose shows; its studio wall carries
   on above it (same grey, the photo's top edge fades into it) and the text
   sits on that wall, top left, in black. Up to 1100px wide whichever way
   the screen is held: on a tablet or a phone on its side, too, the cropped
   photo leaves no room for the text beside the legs. So on any screen not
   much wider than it is tall (4:3 or narrower), where the photo, scaled to
   the height, is blown up behind the text. */
@media (max-width: 1100px), (max-aspect-ratio: 4/3){
  .hero{ justify-content: flex-start; }
  .hero__media{
    background: linear-gradient(to right, #dedede 0%, #ececec 45%, #e8e8e8 70%, #dadada 100%);
  }
  .hero__media img{
    position: absolute;
    left: 50%;
    bottom: 0;
    width: auto;
    height: min(58vh, 120vw); /* Browsers without svh (iOS before 15.4). */
    height: min(58svh, 120vw);
    height: min(calc(var(--screen-h, 100svh) * .58), 120vw);
    max-width: none;
    /* Centred on the person (who sits a little left of the photo's middle). */
    transform: translateX(-48%);
    /* The top edge fades into the wall; so do the sides, which show on a
       screen wider than the scaled-down photo (a tablet on its side). */
    -webkit-mask-image:
      linear-gradient(to bottom, transparent 0, #000 22%),
      linear-gradient(to right, transparent 0, #000 12%, #000 88%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(to bottom, transparent 0, #000 22%),
      linear-gradient(to right, transparent 0, #000 12%, #000 88%, transparent 100%);
    mask-composite: intersect;
  }
  .hero__scrim{ display: none; }
  .hero__text{ padding-top: clamp(8px, calc(var(--screen-h, 100vh) * .03), 32px); padding-bottom: 0; }
  .hero__sub{ color: rgba(0,0,0,.75); text-align: left; }
}

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

@media (max-width: 520px){
  .header__word{ display:none; }
  .footer{
    flex-direction: column;
    align-items: flex-start;
  }
}

/* =====================================================
   REDUCED MOTION
===================================================== */
@media (prefers-reduced-motion: reduce){
  .services__list .services__item > *{ transition: color .35s var(--ease); }
  .services__list .services__item:hover > *{ transform: none; }
  [data-reveal]{ opacity: 1; transform: none; animation: none !important; }
  .hero__cta::before{ transition: none; }
  .header__nav a::after{ transition: none; }
  .project-card, .project-card::after{ transition: none; }
  .project-card:hover, .project-card:focus-visible{ transform: none; }
  .about__slide{ transition: none; }
  .about__dot{ transition: none; }
}

/* =====================================================
   LEGAL PAGES
===================================================== */
.legal{
  max-width: 760px;
  margin: 0 auto;
  /* Clear of the fixed header. */
  padding: calc(var(--nav-h) + clamp(48px, 8vh, 96px)) var(--pad-x) clamp(80px, 12vh, 140px);
}

.legal__back{
  display: inline-flex;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .04em;
  color: rgba(0,0,0,.5);
  margin-bottom: clamp(24px, 4vh, 40px);
  transition: color .3s var(--ease);
}
.legal__back:hover{ color: var(--rose); }

.legal__title{
  font-weight: 900;
  /* Same size and capitals as the section titles; the lower floor keeps
     CONFIDENTIALITÉ on a phone screen. */
  font-size: clamp(28px, 4.8vw, 80px);
  line-height: .92;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--noir);
  margin-bottom: clamp(32px, 5vh, 56px);
}

.legal__updated{
  font-size: 13px;
  color: rgba(0,0,0,.45);
  margin-top: -1.5rem;
  margin-bottom: clamp(32px, 5vh, 56px);
}

.legal__section{
  padding: clamp(20px, 3vh, 28px) 0;
  border-top: 1px solid rgba(0,0,0,.12);
}
.legal__section:last-child{
  border-bottom: 1px solid rgba(0,0,0,.12);
}

.legal__section h2{
  font-weight: 700;
  font-size: clamp(17px, 1.6vw, 20px);
  color: var(--noir);
  margin-bottom: 12px;
}

.legal__section p{
  font-size: var(--fs-text);
  line-height: var(--lh-text);
  color: rgba(0,0,0,.65);
  margin-bottom: 10px;
}
.legal__section p:last-child{ margin-bottom: 0; }

.legal__section a{
  color: var(--rose);
}
.legal__section a:hover{ opacity: .7; }

.legal__placeholder{
  background: rgba(254,8,163,.08);
  padding: 1px 6px;
  border-radius: 3px;
}

/* =====================================================
   PROJECT PAGE
   Structure ported from the "Le petit oiseau" reference:
   one flat cream canvas, hairline dividers between
   sections, sticky nav, reveal-on-scroll behaviour (js/project.js).
===================================================== */
.project-page{
  background: #ffffff;
  color: var(--noir);
}

/* Same side margin as the home page and the header logo. */
.project-container{
  padding: 0 var(--pad-x);
}

.skip-link{
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--rose);
  color: var(--noir);
  padding: 12px 20px;
  z-index: 100;
  font-weight: 700;
}
.skip-link:focus{ left: 16px; top: 16px; }
/* Text for screen readers only. */
.sr-only{
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------- Reveal --------------------------------- */
/* Scroll reveal for text, per element (js/project.js adds .is-visible as each
   one enters the screen; elements arriving together get a staggered
   --anim-delay). */
.anim-up{
  opacity: 0;
  transform: translateY(32px);
  transition: opacity .9s var(--ease), transform .9s var(--ease);
  transition-delay: var(--anim-delay, 0s);
}
.anim-up.is-visible{ opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce){
  .anim-up{ opacity: 1; transform: none; transition: none; }
}

.reveal{
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.reveal.is-visible{ opacity: 1; transform: translateY(0); }

.reveal-stagger > *{
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}
.reveal-stagger.is-visible > *{ opacity: 1; transform: translateY(0); }
.reveal-stagger.is-visible > *:nth-child(1){ transition-delay: .02s; }
.reveal-stagger.is-visible > *:nth-child(2){ transition-delay: .09s; }
.reveal-stagger.is-visible > *:nth-child(3){ transition-delay: .16s; }
.reveal-stagger.is-visible > *:nth-child(4){ transition-delay: .23s; }

@media (prefers-reduced-motion: reduce){
  .reveal, .reveal-stagger > *{ opacity: 1; transform: none; transition: none; }
}

/* --------------------------------- Title hero --------------------------------- */
/* --------------------------------- Cover --------------------------------- */
/* Optional full-screen visual shown before the title: the work first, no text.
   It stays pinned while the rest of the page slides over it. */
.pcover{
  position: sticky;
  top: 0;
  z-index: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  background: var(--noir);
}
.pcover__img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  animation: pcover-in 1.4s var(--ease) both;
}
@keyframes pcover-in{
  from{ opacity: 0; transform: scale(1.08); }
  to{ opacity: 1; transform: none; }
}
/* Scroll cue: a label over a frosted-glass disc holding a pink arrow that
   bobs downward, so it reads on light and dark images alike. */
.pcover__cue{
  position: absolute;
  left: 50%;
  bottom: clamp(24px, 5vh, 48px);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  color: var(--blanc);
}
.pcover__cue-text{
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  white-space: nowrap;
  text-shadow: 0 1px 12px rgba(0,0,0,.45);
}
.pcover__cue-arrow{
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.35);
  background: rgba(255,255,255,.16);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: var(--rose);
  transition: background .3s var(--ease);
}
.pcover__cue-arrow svg{
  width: 22px;
  height: 22px;
  animation: pcover-cue 1.6s var(--ease-soft) infinite;
}
.pcover__cue:hover .pcover__cue-arrow{ background: rgba(255,255,255,.3); }
@keyframes pcover-cue{
  0%, 100% { transform: translateY(-3px); opacity: .7; }
  50%      { transform: translateY(4px);  opacity: 1; }
}
/* Everything after the cover is opaque and above it, so it slides over. */
.pcover ~ section{
  position: relative;
  z-index: 1;
  background: #ffffff;
}
.pcover + .phero{ box-shadow: 0 -32px 60px rgba(0,0,0,.28); }
@media (prefers-reduced-motion: reduce){
  .pcover__img, .pcover__cue-arrow svg{ animation: none; }
}

.phero{
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding: clamp(32px, 6vw, 64px) 0;
}
/* The fade hits the content, not the section: with a cover pinned behind,
   a translucent section would let the image show through. */
.phero > .project-container{ transition: opacity .5s var(--ease); }
.phero.is-faded > .project-container{ opacity: .25; }

.phero__cat{
  display: block;
  font-size: clamp(13px, 1.05vw, 16px);
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--rose);
  margin-bottom: 22px;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}
.phero__cat.is-in{ opacity: 1; transform: translateY(0); }

.phero__title{
  font-weight: 900;
  /* The low floor lets the longest word ("INSTITUTIONNELLE", ~9.5em) keep
     fitting on narrow phones instead of pushing the page sideways. */
  font-size: clamp(28px, 9vw, 120px);
  line-height: .94;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

.phero__line{ display: block; overflow: hidden; }
.phero__line-text{ display: block; transform: translateY(108%); transition: transform .9s var(--ease); }
.phero__line.is-in .phero__line-text{ transform: translateY(0); }
.phero__line-text.accent{ color: var(--rose); }

.phero__meta{
  margin-top: 35px;
  font-size: var(--fs-small);
  color: rgba(0,0,0,.45);
  letter-spacing: .02em;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
  transition-delay: .5s;
}
.phero__meta.is-in{ opacity: 1; transform: translateY(0); }

@media (prefers-reduced-motion: reduce){
  .phero{ transition: none; }
  .phero.is-faded{ opacity: 1; }
  .phero__cat, .phero__meta{ transition: none; opacity: 1; transform: none; }
  .phero__line-text{ transition: none; transform: none; }
}

/* Project pages put the text beside the title (.phero--split), so the
   title runs a little smaller to leave it room. */
.phero--split .phero__grid{
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, .8fr);
  gap: clamp(28px, 5vw, 72px);
  /* Both columns end on the same line: the last line of the text sits level
     with the last line of the title, and the date runs underneath. */
  align-items: end;
}
.phero--split .phero__meta{ grid-column: 1 / -1; }
/* The hero is a flex row: without this its content would only be as wide as
   it needs, and on very wide screens stop short of the gallery's width. */
.phero--split > .project-container{ flex: 1; min-width: 0; }
/* The title no longer fills the screen on its own, so the visuals start
   sooner. */
.phero--split{
  /* As tall as its content: the visuals start right under the text. */
  min-height: 0;
  /* Start the block lower so the category line doesn't sit right under the
     header; top-aligned (not centred). The gap, the title and the text all
     follow the screen height as well as its width, so the whole block —
     date and place included — is on screen the moment the page opens. */
  align-items: flex-start;
  padding-top: calc(var(--nav-h) + clamp(40px, 11vh, 140px));
  padding-bottom: 0;
}
.phero--split .phero__meta{ margin-top: clamp(16px, 3.5vh, 35px); }
.phero--split + .pcontent{ padding-top: clamp(24px, 3vw, 40px); }
/* One title size for every project page, so the longest names (Cabinet
   vétérinaire) still fit with the date and place on screen. */
.phero--split .phero__title{ font-size: clamp(28px, min(5.6vw, 10vh), 80px); }
.phero--split .phero__aside{
  display: flex;
  flex-direction: column;
  gap: 12px;
}
/* Side by side: the category line and "Le projet" share the first row; below,
   the title is centred on the text, so the block reads the same on every
   project page whatever the length of the text. */
@media (min-width: 901px){
  .phero--split .phero__grid{ align-items: start; row-gap: 0; }
  .phero--split .phero__main,
  .phero--split .phero__aside{ display: contents; }
  .phero--split .phero__cat,
  .phero--split .pintro__label{ grid-row: 1; margin-bottom: 22px; }
  .phero--split .phero__cat{ grid-column: 1; }
  .phero--split .pintro__label{ grid-column: 2; align-self: center; }
  /* Title and text sit on the same row, each centred against the other. */
  .phero--split .phero__title{ grid-row: 2; grid-column: 1; align-self: center; }
  .phero--split .pintro__body{ grid-row: 2; grid-column: 2; align-self: center; }
  .phero--split .phero__meta{ grid-row: 3; }
}
/* The text column lines up exactly with the right-hand photo of the
   gallery below (three columns, 20px apart); the title takes the width of
   the other two. */
@media (min-width: 901px){
  .phero--split .phero__grid{
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: 20px;
  }
  .phero--split .phero__cat,
  .phero--split .phero__title{ grid-column: 1 / span 2; }
  .phero--split .pintro__label,
  .phero--split .pintro__body{ grid-column: 3; max-width: none; }
}
@media (max-width: 900px){
  .phero--split .phero__grid{ grid-template-columns: 1fr; align-items: start; }
  /* Stacked, the date reads better right under the title than after the text. */
  .phero--split .phero__meta{ order: 1; }
  .phero--split .phero__aside{ order: 2; }
}

/* -------------------------------- Content -------------------------------- */
.pcontent{
  padding: clamp(48px, 7vw, 80px) 0 clamp(64px, 8vw, 96px);
}

.pintro{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(32px, 6vw, 80px);
  margin-bottom: clamp(48px, 7vw, 80px);
}
.pintro__label{
  font-size: var(--fs-label);
  font-weight: var(--fw-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: rgba(0,0,0,.45);
}
.pintro__body{
  font-size: var(--fs-text);
  line-height: var(--lh-text);
  max-width: 46ch;
}

.pgallery{
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 20px;
}
.pgallery__item{
  grid-column: span 6;
  aspect-ratio: 16 / 10;
  background: var(--card-bg, #d8d5cd);
  display: flex;
  align-items: flex-end;
  padding: 24px;
  position: relative;
  overflow: hidden;
}
.pgallery__item--half{ grid-column: span 3; }
/* Portrait visuals (4:5, e.g. social posts): three per row. */
.pgallery__item--third{ grid-column: span 2; aspect-ratio: 4 / 5; }
/* Square research visuals (Explorations): three per row. */
.pgallery__item--square{ grid-column: span 2; aspect-ratio: 1; }
/* A wide strip (Samuel Martial's ARtiste), full width at its own ratio. */
.pgallery__item--banner{ grid-column: span 6; aspect-ratio: 2000 / 626; }
/* Posters (Campagnes), same 2:3 as the cards on the home page. */
.pgallery__item--poster{ grid-column: span 2; aspect-ratio: 2 / 3; }
/* A real visual fills its slot; the frame's ratio decides the crop. */
.pgallery__img{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.pgallery__note{
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 11px;
  letter-spacing: .03em;
  color: rgba(245,243,239,.75);
  background: rgba(0,0,0,.42);
  padding: 8px 12px;
}
/* The export size is the point of the placeholder, so it leads. */
.pgallery__size{
  font-size: 14px;
  font-weight: 700;
  letter-spacing: .01em;
  color: rgba(245,243,239,.98);
}

@media (max-width: 760px){
  .pintro{ grid-template-columns: 1fr; }
  .pgallery__item, .pgallery__item--half, .pgallery__item--third,
  .pgallery__item--square, .pgallery__item--poster{ grid-column: span 6; }
}

/* ----------------------------- Next project ----------------------------- */
.pnext__link{
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: clamp(56px, 8vw, 96px) var(--pad-x);
  transition: gap .35s var(--ease);
}
.pnext__link:hover{ gap: 18px; }
.pnext__label{
  font-size: var(--fs-label);
  font-weight: var(--fw-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: rgba(0,0,0,.45);
}
.pnext__title{
  display: flex;
  align-items: center;
  gap: 16px;
  font-weight: 900;
  /* Same size as the section titles of the home page; the lower floor keeps
     the longest name (VÉTÉRINAIRE) on a phone screen. */
  font-size: clamp(35px, 4.8vw, 80px);
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
.pnext__title svg{
  width: .6em;
  height: .6em;
  color: var(--rose);
  flex-shrink: 0;
  transition: transform .35s var(--ease);
}
.pnext__link:hover .pnext__title svg{ transform: translateX(10px); }

/* -------------------------- Touch targets -------------------------- */
/* Small links and the carousel dots get an invisible hit area around them,
   so they are easy to tap on a phone (24px minimum) without changing how
   they look or moving anything. */
.about__dot,
.about__meta-row a,
.footer__legal a,
.legal__back{ position: relative; }
.about__dot::before,
.about__meta-row a::before,
.footer__legal a::before,
.legal__back::before{
  content: "";
  position: absolute;
  inset: -10px -6px;
}
.about__dot::before{ inset: -10px -4px; }

/* =====================================================
   CUSTOM CURSOR
===================================================== */
body.has-custom-cursor,
body.has-custom-cursor a,
body.has-custom-cursor button{
  cursor: none;
}

.cursor{
  position: fixed;
  top: 0;
  left: 0;
  width: 64px;
  height: 64px;
  pointer-events: none;
  z-index: 9999;
  opacity: 0;
  transition: opacity .3s var(--ease);
  will-change: transform;
}
.cursor.is-active{ opacity: 1; }
.cursor img{
  width: 100%;
  height: auto;
  display: block;
}
