@charset "UTF-8";
/* ==========================================================================
   cover / tools
   ========================================================================== */
/* ==========================================================================
   typo / tools
   ========================================================================== */
/* ==========================================================================
   gradient-border / tools
   Contour dégradé bleu → mauve dont les couleurs tournent en continu autour
   de l'élément (le bleu part du haut et descend, le mauve part du bas et monte).
   Le contour est un pseudo-élément ::before masqué : il fonctionne sur tous les
   fonds (même transparents) et garde les coins arrondis de l'élément.

   Utilisation :
     .element {
         @include gradient-border(3px);       // Prépare le contour (caché)
         &:hover { @include gradient-border-on; } // L'affiche et l'anime
     }
   $offset : déborde sur la bordure CSS existante (ex. bordure transparente de 2px).
   ========================================================================== */
/* ==========================================================================
   COLORS / SETTINGS
   Valeurs tirées des styles Figma (Primere, Secondaire, Linear, etc.)
   ========================================================================== */
:root {
  --color-white: #fff;
  --color-black: #000;
  --color-primary: #411ef8;
  --color-secondary: #f717f9;
  --color-primary-75: rgba(65, 30, 248, 0.75);
  --color-text: var(--color-black);
  --color-text-muted: rgba(0, 0, 0, 0.5);
  --color-text-inverse: var(--color-white);
  --color-text-label: rgba(0, 0, 0, 0.3);
  --color-bg: #efe6f9;
  --color-bg-dark: #473557;
  --color-border: #d5dae5;
  --color-line: var(--color-black);
  --color-line-muted: rgba(0, 0, 0, 0.55);
  --color-separator: rgba(0, 0, 0, 0.2);
  --gradient-brand: linear-gradient(180deg, var(--color-primary) 0%, var(--color-secondary) 100%);
  --surface-glass: linear-gradient(180deg, rgba(65, 30, 248, 0.06) 0%, rgba(22, 0, 137, 0.08) 100%),
      linear-gradient(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.9));
  --surface-glass-solid: linear-gradient(180deg, rgba(65, 30, 248, 0.053) 0%, rgba(22, 0, 137, 0.07) 100%),
      linear-gradient(var(--color-white), var(--color-white));
}

/* ==========================================================================
   easing / settings
   ========================================================================== */
/* ==========================================================================
   FONTS / SETTINGS
   Styles de texte Figma. Tailles fluides : maquette mobile (320px) → desktop (1440px).
   ========================================================================== */
:root {
  --font-primary: 'Nunito', 'Helvetica Neue', Arial, sans-serif;
  --font-secondary: 'Outfit', 'Helvetica Neue', Arial, sans-serif;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --font-weight-extrabold: 800;
  --font-weight-black: 900;
  --font-size-display: clamp(1.69rem, 2.95vw + 1.1rem, 3.75rem);
  --font-size-h1: clamp(1.5rem, 1.07vw + 1.29rem, 2.25rem);
  --font-size-h2: clamp(1.13rem, 1.07vw + 0.91rem, 1.88rem);
  --font-size-h3: clamp(0.88rem, 0.54vw + 0.77rem, 1.25rem);
  --font-size-subtitle: clamp(0.75rem, 0.36vw + 0.68rem, 1rem);
  --font-size-content: clamp(0.88rem, 0.18vw + 0.84rem, 1rem);
  --font-size-button: clamp(0.88rem, 0.36vw + 0.8rem, 1.13rem);
  --font-size-small: clamp(0.75rem, 0.18vw + 0.71rem, 0.88rem);
  --font-size-label: clamp(0.75rem, 0.18vw + 0.71rem, 0.88rem);
  --line-height-tight: 1;
  --line-height-content: 1.3125;
}

/* ==========================================================================
   DIMENSIONS / SETTINGS
   ========================================================================== */
:root {
  --spacing-2xs: 4px;
  --spacing-xs: 8px;
  --spacing-sm: 12px;
  --spacing-md: 16px;
  --spacing-lg: 24px;
  --spacing-xl: 32px;
  --spacing-2xl: 48px;
  --spacing-3xl: 64px;
  --gutter: clamp(1rem, 15.48vw + -6.43rem, 7.5rem);
  --radius-sm: 12px;
  --radius-md: 15px;
  --radius-lg: 20px;
  --radius-xl: 30px;
  --radius-full: 999px;
}

/* ==========================================================================
   EFFECTS / SETTINGS
   Effets Figma convertis en CSS.
   L'effet « GLASS » de Figma est approximé par backdrop-filter: blur().
   ========================================================================== */
:root {
  --shadow-ui: 0 4px 4px 0 rgba(0, 0, 0, 0.15), inset 0 8px 15px 10px rgba(255, 255, 255, 0.3);
  --blur-ui: blur(3px);
  --shadow-btn: 0 2px 2px 0 rgba(0, 0, 0, 0.15), inset 2px 1px 6px 0 rgba(255, 255, 255, 0.25),
      inset 1px 1px 1px 0 rgba(255, 255, 255, 0.5), inset 0 -2px 5px -2px rgba(0, 0, 0, 0.5),
      inset 0 -2px 2px -2px rgba(255, 255, 255, 0.5);
  --blur-btn: blur(1px);
  --shadow-icon: 0 2px 2px 0 rgba(0, 0, 0, 0.15), inset 2px 1px 6px 0 rgba(255, 255, 255, 0.25),
      inset 1px 1px 1px 0 rgba(255, 255, 255, 0.5), inset 0 -2px 2px -2px rgba(255, 255, 255, 0.5);
  --blur-icon: blur(1px);
  --shadow-app: 0 4px 4px 0 rgba(0, 0, 0, 0.2), inset 0 4px 5px 0 rgba(255, 255, 255, 0.25);
  --blur-app: blur(5px);
  --shadow-image: inset 0 -6px 6px 0 rgba(0, 0, 0, 0.25), inset 0 -3px 2px 0 rgba(255, 255, 255, 0.15),
      inset 0 2px 4px 0 rgba(255, 255, 255, 0.5), 0 1px 2px 0 rgba(0, 0, 0, 0.25);
  --shadow-glow: 0 42px 107px 0 rgba(255, 141, 245, 0.34), 0 24.721px 32.257px 0 rgba(255, 141, 245, 0.18),
      0 10.268px 13.398px 0 rgba(255, 141, 245, 0.22), 0 3.714px 4.846px 0 rgba(255, 141, 245, 0.44),
      inset 0 1px 18px 0 #d7e6ff, inset 0 1px 4px 0 #d7e6ff;
  --shadow-drop-sm: 0 4px 2px rgba(0, 0, 0, 0.15);
}

/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
   ========================================================================== */
/**
 * 1. Correct the line height in all browsers.
 * 2. Prevent adjustments of font size after orientation changes in iOS.
 */
html {
  line-height: 1.15; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
}

/* Sections
   ========================================================================== */
/**
 * Remove the margin in all browsers.
 */
body {
  margin: 0;
}

/**
 * Render the `main` element consistently in IE.
 */
main {
  display: block;
}

/**
 * Correct the font size and margin on `h1` elements within `section` and
 * `article` contexts in Chrome, Firefox, and Safari.
 */
h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

/* Grouping content
   ========================================================================== */
/**
 * 1. Add the correct box sizing in Firefox.
 * 2. Show the overflow in Edge and IE.
 */
hr {
  box-sizing: content-box; /* 1 */
  height: 0; /* 1 */
  overflow: visible; /* 2 */
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */
pre {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/* Text-level semantics
   ========================================================================== */
/**
 * Remove the gray background on active links in IE 10.
 */
a {
  background-color: transparent;
}

/**
 * 1. Remove the bottom border in Chrome 57-
 * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
 */
abbr[title] {
  border-bottom: none; /* 1 */
  text-decoration: underline; /* 2 */
  -webkit-text-decoration: underline dotted;
          text-decoration: underline dotted; /* 2 */
}

/**
 * Add the correct font weight in Chrome, Edge, and Safari.
 */
b,
strong {
  font-weight: bolder;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */
code,
kbd,
samp {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/**
 * Add the correct font size in all browsers.
 */
small {
  font-size: 80%;
}

/**
 * Prevent `sub` and `sup` elements from affecting the line height in
 * all browsers.
 */
sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

/* Embedded content
   ========================================================================== */
/**
 * Remove the border on images inside links in IE 10.
 */
img {
  border-style: none;
}

/* Forms
   ========================================================================== */
/**
 * 1. Change the font styles in all browsers.
 * 2. Remove the margin in Firefox and Safari.
 */
button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-size: 100%; /* 1 */
  line-height: 1.15; /* 1 */
  margin: 0; /* 2 */
}

/**
 * Show the overflow in IE.
 * 1. Show the overflow in Edge.
 */
button,
input { /* 1 */
  overflow: visible;
}

/**
 * Remove the inheritance of text transform in Edge, Firefox, and IE.
 * 1. Remove the inheritance of text transform in Firefox.
 */
button,
select { /* 1 */
  text-transform: none;
}

/**
 * Correct the inability to style clickable types in iOS and Safari.
 */
button,
[type=button],
[type=reset],
[type=submit] {
  -webkit-appearance: button;
}

/**
 * Remove the inner border and padding in Firefox.
 */
button::-moz-focus-inner,
[type=button]::-moz-focus-inner,
[type=reset]::-moz-focus-inner,
[type=submit]::-moz-focus-inner {
  border-style: none;
  padding: 0;
}

/**
 * Restore the focus styles unset by the previous rule.
 */
button:-moz-focusring,
[type=button]:-moz-focusring,
[type=reset]:-moz-focusring,
[type=submit]:-moz-focusring {
  outline: 1px dotted ButtonText;
}

/**
 * Correct the padding in Firefox.
 */
fieldset {
  padding: 0.35em 0.75em 0.625em;
}

/**
 * 1. Correct the text wrapping in Edge and IE.
 * 2. Correct the color inheritance from `fieldset` elements in IE.
 * 3. Remove the padding so developers are not caught out when they zero out
 *    `fieldset` elements in all browsers.
 */
legend {
  box-sizing: border-box; /* 1 */
  color: inherit; /* 2 */
  display: table; /* 1 */
  max-width: 100%; /* 1 */
  padding: 0; /* 3 */
  white-space: normal; /* 1 */
}

/**
 * Add the correct vertical alignment in Chrome, Firefox, and Opera.
 */
progress {
  vertical-align: baseline;
}

/**
 * Remove the default vertical scrollbar in IE 10+.
 */
textarea {
  overflow: auto;
}

/**
 * 1. Add the correct box sizing in IE 10.
 * 2. Remove the padding in IE 10.
 */
[type=checkbox],
[type=radio] {
  box-sizing: border-box; /* 1 */
  padding: 0; /* 2 */
}

/**
 * Correct the cursor style of increment and decrement buttons in Chrome.
 */
[type=number]::-webkit-inner-spin-button,
[type=number]::-webkit-outer-spin-button {
  height: auto;
}

/**
 * 1. Correct the odd appearance in Chrome and Safari.
 * 2. Correct the outline style in Safari.
 */
[type=search] {
  -webkit-appearance: textfield; /* 1 */
  outline-offset: -2px; /* 2 */
}

/**
 * Remove the inner padding in Chrome and Safari on macOS.
 */
[type=search]::-webkit-search-decoration {
  -webkit-appearance: none;
}

/**
 * 1. Correct the inability to style clickable types in iOS and Safari.
 * 2. Change font properties to `inherit` in Safari.
 */
::-webkit-file-upload-button {
  -webkit-appearance: button; /* 1 */
  font: inherit; /* 2 */
}

/* Interactive
   ========================================================================== */
/*
 * Add the correct display in Edge, IE 10+, and Firefox.
 */
details {
  display: block;
}

/*
 * Add the correct display in all browsers.
 */
summary {
  display: list-item;
}

/* Misc
   ========================================================================== */
/**
 * Add the correct display in IE 10+.
 */
template {
  display: none;
}

/**
 * Add the correct display in IE 10.
 */
[hidden] {
  display: none;
}

/* ==========================================================================
   RESET / GENERIC
   ========================================================================== */
html {
  box-sizing: border-box;
}

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

img {
  display: block;
  max-width: 100%;
  height: auto;
}

p,
figure {
  margin: 0;
}

ul,
ol {
  list-style: none;
  margin: 0;
  padding: 0;
}

button {
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  padding: 0;
}

/* ==========================================================================
   SCALE / GENERIC
   La maquette Figma est faite pour un écran de 1440px.
   Sur les grands écrans, toute la page est agrandie (zoom) pour garder
   les proportions de Figma : à 1920px, c'est la maquette ×1,33.
   --zoom sert aussi à corriger les hauteurs en vh (voir body et page Projets).
   ========================================================================== */
:root {
  --zoom: 1;
}

@media (min-width: 1600px) {
  :root {
    --zoom: 1.111;
  }
}
@media (min-width: 1760px) {
  :root {
    --zoom: 1.222;
  }
}
@media (min-width: 1920px) {
  :root {
    --zoom: 1.333;
  }
}
@media (min-width: 2240px) {
  :root {
    --zoom: 1.556;
  }
}
@media (min-width: 2560px) {
  :root {
    --zoom: 1.778;
  }
}
html {
  zoom: var(--zoom);
}

/* ==========================================================================
   ANIMATIONS / GENERIC
   Animations partagées par plusieurs composants.
   ========================================================================== */
@property --border-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
@keyframes border-rotate {
  from {
    --border-angle: 0deg;
  }
  to {
    --border-angle: 360deg;
  }
}
/* ==========================================================================
   BODY / ELEMENT
   Le body permet d'initialiser les propriétés générales de la page.
   Les éléments de la page vont hérités des propriétés inscrite dans body
   ========================================================================== */
html {
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  background-color: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-primary);
  font-size: var(--font-size-content);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-content);
  min-height: calc(100vh / var(--zoom));
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: url("../assets/images/img-fond-clair-mobile.webp") center top/cover no-repeat;
  pointer-events: none;
}
@media (orientation: landscape) {
  body::before {
    background-image: url("../assets/images/img-fond-clair.webp");
  }
}

main {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.body--dark {
  background-color: var(--color-bg-dark);
  color: var(--color-text-inverse);
}
.body--dark::before {
  background-image: url("../assets/images/img-fond-sombre-mobile.webp");
}
@media (orientation: landscape) {
  .body--dark::before {
    background-image: url("../assets/images/img-fond-sombre.webp");
  }
}

/* ==========================================================================
   TYPOGRAPHY / ELEMENT
   Hiérarchie Figma : Titre (display), H1, H2, H3, Sous titre, P.
   ========================================================================== */
h1,
h2,
h3,
.h1,
.h2,
.h3 {
  font-family: var(--font-secondary);
  line-height: var(--line-height-tight);
  margin: 0;
}

h1,
.h1 {
  font-size: var(--font-size-h1);
  font-weight: var(--font-weight-bold);
}

h2,
.h2 {
  font-size: var(--font-size-h2);
  font-weight: var(--font-weight-medium);
}

h3,
.h3 {
  font-size: var(--font-size-h3);
  font-weight: var(--font-weight-extrabold);
}

.display {
  font-family: var(--font-secondary);
  font-size: var(--font-size-display);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
}

.subtitle {
  font-family: var(--font-primary);
  font-size: var(--font-size-subtitle);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
}

strong,
b {
  font-weight: var(--font-weight-black);
}

.text-highlight {
  color: var(--color-primary);
}

em {
  font-style: italic;
}

/* ==========================================================================
   LINKS / ELEMENTS
   Style de base de tous les liens et bouton du site
   ========================================================================== */
a {
  color: inherit;
  text-decoration: none;
}
a:hover {
  color: var(--color-primary);
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
}

.text-link {
  color: var(--color-secondary);
  text-decoration: underline;
}
.text-link:hover {
  color: var(--color-primary);
}

/* ==========================================================================
   WRAPPER / ELEMENT
   ========================================================================== */
.wrapper {
  max-width: 1440px;
  width: calc(100% - var(--gutter) * 2);
  margin: 0 auto;
}

/* ==========================================================================
   HELPERS / ELEMENTS
   ========================================================================== */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
   GRID / OBJECT
   Grille de base du projet. Aucune grille externe n'est utilisée.
   ========================================================================== */
.grid {
  display: grid;
  gap: var(--spacing-lg);
}

.grid--2 {
  grid-template-columns: repeat(2, 1fr);
  gap: var(--spacing-md);
}
@media (min-width: 768px) {
  .grid--2 {
    gap: var(--spacing-lg);
  }
}

.grid--3 {
  grid-template-columns: 1fr;
}
@media (min-width: 480px) {
  .grid--3 {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 768px) {
  .grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* ==========================================================================
   icons / component
   ========================================================================== */
.icon {
  fill: currentColor;
  display: inline-block;
  flex: 0 0 auto;
  height: 1em;
  vertical-align: middle;
  width: 1em;
  stroke: transparent;
}

.icon--stroke {
  fill: transparent;
  stroke: currentColor;
}

.icon--xs {
  height: 0.75em;
  width: 0.75em;
}

.icon--sm {
  height: 0.8em;
  width: 0.8em;
}

.icon--md {
  height: 1.25em;
  width: 1.25em;
}

.icon--lg {
  height: 1.75em;
  width: 1.75em;
}

.icon--xl {
  height: 6em;
  width: 6em;
}

/* Tailles du projet (fluides : maquette mobile 320px → desktop 1440px)
   ========================================================================== */
.icon--status {
  height: 24px;
  width: 24px;
}

.icon--clock {
  height: clamp(1.5rem, 0.54vw + 1.39rem, 1.88rem);
  width: clamp(1.5rem, 0.54vw + 1.39rem, 1.88rem);
  margin: -2px -6px -6px -2px;
}

.icon--btn {
  height: clamp(1rem, 0.36vw + 0.93rem, 1.25rem);
  width: clamp(1rem, 0.36vw + 0.93rem, 1.25rem);
}

.icon--social {
  height: clamp(1.5rem, 0.89vw + 1.32rem, 2.13rem);
  width: clamp(1.5rem, 0.89vw + 1.32rem, 2.13rem);
}

.icon--social-sm {
  height: clamp(1.25rem, 0.8vw + 1.09rem, 1.81rem);
  width: clamp(1.25rem, 0.8vw + 1.09rem, 1.81rem);
}

.icon--tile {
  height: clamp(1.81rem, 3.13vw + 1.19rem, 4rem);
  width: clamp(1.81rem, 3.13vw + 1.19rem, 4rem);
}

.icon--nav {
  height: 100%;
  width: 100%;
}

.icon--tool {
  height: clamp(2.25rem, 1.07vw + 2.04rem, 3rem);
  width: clamp(2.25rem, 1.07vw + 2.04rem, 3rem);
}

.icon--cat-3d {
  height: clamp(2.5rem, 1.07vw + 2.29rem, 3.25rem);
  width: clamp(4.75rem, 2.05vw + 4.34rem, 6.19rem);
}

.icon--cat-2d {
  height: clamp(3.06rem, 1.34vw + 2.79rem, 4rem);
  width: clamp(3.56rem, 1.52vw + 3.26rem, 4.63rem);
}

.icon--cat-photo {
  height: clamp(3.19rem, 1.43vw + 2.9rem, 4.19rem);
  width: clamp(4.25rem, 1.88vw + 3.88rem, 5.56rem);
}

.icon--label {
  height: clamp(1rem, 0.36vw + 0.93rem, 1.25rem);
  width: clamp(1rem, 0.36vw + 0.93rem, 1.25rem);
}

.icon--contact {
  height: clamp(2.5rem, 1.25vw + 2.25rem, 3.38rem);
  width: clamp(2.5rem, 1.25vw + 2.25rem, 3.38rem);
}

.icon--software {
  height: clamp(2.75rem, 1.7vw + 2.41rem, 3.94rem);
  width: clamp(2.75rem, 1.7vw + 2.41rem, 3.94rem);
}

.icon--feature {
  height: clamp(3.5rem, 3.93vw + 2.71rem, 6.25rem);
  width: clamp(3.5rem, 3.93vw + 2.71rem, 6.25rem);
}

.icon--play {
  height: clamp(3.5rem, 3.93vw + 2.71rem, 6.25rem);
  width: clamp(3.5rem, 3.93vw + 2.71rem, 6.25rem);
}

/* ==========================================================================
   BOUTONS / COMPONENTS
   Bouton principal violet et mention (badge).
   ========================================================================== */
/* ==========================================================================
   BTN / COMPONENT
   Bouton principal violet. Figma : btn (effet « Btn »)
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-2xs);
  padding: var(--spacing-sm) var(--spacing-lg);
  border-radius: var(--radius-md);
  background-color: var(--color-primary-75);
  box-shadow: var(--shadow-btn);
  backdrop-filter: var(--blur-btn);
  color: var(--color-text-inverse);
  font-family: var(--font-primary);
  font-size: var(--font-size-button);
  font-weight: var(--font-weight-extrabold);
  line-height: 1;
  text-align: center;
  transition: background-color 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.btn:hover {
  background-color: var(--color-primary);
  color: var(--color-text-inverse);
}
@media (min-width: 1024px) {
  .btn {
    padding: 20px var(--spacing-xl);
  }
}

/* ==========================================================================
   BADGE / COMPONENT
   Mention (ex. « Music non libre de droit utiliser »).
   ========================================================================== */
.badge {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-2xs);
  padding: clamp(1rem, 0.71vw + 0.86rem, 1.5rem) clamp(1.25rem, 1.07vw + 1.04rem, 2rem);
  border-radius: var(--radius-xl);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(224, 0, 0, 0.1) 97.768%), linear-gradient(rgba(255, 255, 255, 0.75), rgba(255, 255, 255, 0.75));
  box-shadow: var(--shadow-ui);
  color: rgba(0, 0, 0, 0.6);
  font-size: var(--font-size-button);
  font-weight: var(--font-weight-extrabold);
  line-height: 1;
  text-align: center;
}

/* ==========================================================================
   ICON BTN / COMPONENT
   Petit bouton carré vitré avec une icône (ex. retour d'une fiche projet).
   Figma : Frame 165 (humbleicons:arrow-go-back)
   ========================================================================== */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--spacing-xs);
  border-radius: var(--radius-sm);
  background-color: rgba(255, 255, 255, 0.25);
  box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.15), inset 0 8px 15px 10px rgba(255, 255, 255, 0.3);
  backdrop-filter: var(--blur-ui);
  color: var(--color-text);
  transition: background-color 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.icon-btn .icon {
  width: 24px;
  height: 24px;
}
.icon-btn:hover {
  background-color: rgba(255, 255, 255, 0.7);
  color: var(--color-text);
}

/* ==========================================================================
   APP BTN / COMPONENT
   Icône d'application cliquable (réseaux dans la carte Contact des fiches projet).
   ========================================================================== */
.app-btn {
  display: flex;
  width: clamp(3rem, 1.43vw + 2.71rem, 4rem);
  height: clamp(3rem, 1.43vw + 2.71rem, 4rem);
  padding: clamp(0.5rem, 0.36vw + 0.43rem, 0.75rem);
  border-radius: var(--radius-sm);
  background-color: var(--color-white);
  box-shadow: var(--shadow-icon);
  transition: transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.app-btn .icon {
  width: 100%;
  height: 100%;
}
.app-btn:hover {
  transform: translateY(-2px);
}

/* ==========================================================================
   NAVIGATION / COMPONENTS
   Boutons ronds de la navigation principale (Accueil, Projets, À propos, Contact).
   ========================================================================== */
/* ==========================================================================
   MAIN NAV / COMPONENT
   Boutons ronds Accueil / Projets / À Propos / Contact. Figma : Barre home
   ========================================================================== */
.main-nav__list {
  display: flex;
  gap: clamp(0.75rem, 2.05vw + 0.34rem, 2.19rem);
}

.nav-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.31rem, -0.27vw + 0.37rem, 0.13rem);
  font-size: clamp(0.75rem, 0.54vw + 0.64rem, 1.13rem);
  font-weight: var(--font-weight-extrabold);
  line-height: 1;
  white-space: nowrap;
  transition: transform 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.nav-btn:hover {
  color: inherit;
}
.nav-btn:hover .nav-btn__circle {
  transform: scale(1.1);
}

.nav-btn__circle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: clamp(2.69rem, 1.34vw + 2.42rem, 3.63rem);
  height: clamp(2.69rem, 1.34vw + 2.42rem, 3.63rem);
  padding: clamp(0.44rem, 0.45vw + 0.35rem, 0.75rem) clamp(0.5rem, 0.18vw + 0.46rem, 0.63rem);
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  background-color: var(--color-white);
  box-shadow: var(--shadow-drop-sm), inset 0 8px 15px 0 rgba(255, 255, 255, 0.3);
  transition: transform 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  position: relative;
}
.nav-btn__circle::before {
  content: "";
  position: absolute;
  inset: -1px;
  padding: 3px;
  border-radius: inherit;
  background: conic-gradient(from var(--border-angle), var(--color-primary), var(--color-secondary), var(--color-primary));
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease-out;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}

.nav-btn:not(.is-active):hover .nav-btn__circle::before,
.nav-btn:not(.is-active):focus-visible .nav-btn__circle::before {
  opacity: 1;
  animation: border-rotate 3s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .nav-btn:not(.is-active):hover .nav-btn__circle::before,
  .nav-btn:not(.is-active):focus-visible .nav-btn__circle::before {
    animation: none;
  }
}

.nav-btn.is-active .nav-btn__circle {
  background: url("../assets/images/img-texture-grain.webp") 0 0/116px 116px repeat, var(--gradient-brand);
  background-blend-mode: plus-lighter, normal;
  box-shadow: var(--shadow-glow);
}

/* ==========================================================================
   TABS / COMPONENT
   Onglets (Tabs.js). Figma : Contexte / Rôle d'une fiche projet.
   Mobile : côte à côte. Desktop : empilés à gauche de la carte.
   ========================================================================== */
.tabs {
  display: flex;
  gap: var(--spacing-sm);
}
@media (min-width: 1024px) {
  .tabs {
    flex-direction: column;
    gap: var(--spacing-xl);
  }
}

.tabs__btn {
  flex: 1;
  padding: 11px var(--spacing-md);
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  background-color: rgba(255, 255, 255, 0.35);
  box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.15), inset 0 8px 15px 0 rgba(255, 255, 255, 0.3);
  color: var(--color-text);
  font-family: var(--font-primary);
  font-size: var(--font-size-button);
  font-weight: var(--font-weight-extrabold);
  line-height: 1;
  text-align: left;
  transition: border-color 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  position: relative;
}
.tabs__btn::before {
  content: "";
  position: absolute;
  inset: -2px;
  padding: 2px;
  border-radius: inherit;
  background: conic-gradient(from var(--border-angle), var(--color-primary), var(--color-secondary), var(--color-primary));
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease-out;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}
.tabs__btn:hover {
  border-color: rgba(255, 255, 255, 0.6);
}
.tabs__btn[aria-selected=true]::before {
  opacity: 1;
  animation: border-rotate 3s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .tabs__btn[aria-selected=true]::before {
    animation: none;
  }
}

/* ==========================================================================
   CARTES / COMPONENTS
   Cartes réutilisées sur plusieurs pages : tuile (Hub, Contact), carte blanche
   (À propos, Contact, fiches projet), cadre d'image et vignette vitrée.
   ========================================================================== */
/* ==========================================================================
   TILE / COMPONENT
   Tuile d'accès rapide. Figma : Frame 115 (Default / Variant2)
   Default = verre dépoli, Variant2 (dégradé) = survol / focus.
   ========================================================================== */
.tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 100%;
  min-height: clamp(7.5rem, 2.68vw + 6.96rem, 9.38rem);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: var(--surface-glass);
  box-shadow: var(--shadow-ui);
  backdrop-filter: var(--blur-ui);
  color: var(--color-text);
  font-family: var(--font-secondary);
  font-size: var(--font-size-h3);
  font-weight: var(--font-weight-extrabold);
  line-height: 1;
  transition: box-shadow 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94), transform 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
@media (min-width: 1024px) {
  .tile {
    border-radius: var(--radius-xl);
  }
}

.tile:hover,
.tile:focus-visible {
  border-color: var(--color-white);
  background: var(--gradient-brand);
  box-shadow: var(--shadow-glow);
  color: var(--color-text-inverse);
}

.tile:hover,
.tile:focus-visible {
  transform: translateY(-2px);
}

/* ==========================================================================
   INFO CARD / COMPONENT
   Carte blanche de la page À propos (Info, Soft Skills, Recherche de stage...).
   Figma : Moi / Competance / Galerie passion
   ========================================================================== */
.info-card {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
  padding: clamp(1rem, 0.71vw + 0.86rem, 1.5rem) clamp(1.13rem, 1.25vw + 0.88rem, 2rem);
  border-radius: var(--radius-xl);
  background-color: rgba(255, 255, 255, 0.75);
  box-shadow: var(--shadow-ui);
  backdrop-filter: var(--blur-ui);
  color: var(--color-text);
}

.info-card--gallery {
  gap: var(--spacing-lg);
}

.info-card--light {
  background-color: rgba(255, 255, 255, 0.3);
}

.info-card--alert {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(224, 0, 0, 0.1) 97.768%), linear-gradient(rgba(255, 255, 255, 0.75), rgba(255, 255, 255, 0.75));
}
.info-card--alert .info-card__label {
  color: rgba(255, 0, 0, 0.3);
}
.info-card--alert .info-card__label .icon {
  color: #f00;
}

.info-card--orange {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(224, 113, 0, 0.1) 97.768%), linear-gradient(rgba(255, 255, 255, 0.75), rgba(255, 255, 255, 0.75));
}

.info-card--blue {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(0, 79, 236, 0.1) 97.768%), linear-gradient(rgba(255, 255, 255, 0.75), rgba(255, 255, 255, 0.75));
}

.info-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-sm);
}

.info-card__label {
  display: flex;
  align-items: center;
  gap: var(--spacing-2xs);
  margin: 0;
  color: rgba(0, 0, 0, 0.3);
  font-family: var(--font-primary);
  font-size: clamp(0.69rem, 0.63vw + 0.56rem, 1.13rem);
  font-weight: var(--font-weight-bold);
  line-height: 1;
}
.info-card__label .icon {
  color: var(--color-black);
}

.info-card__toggle {
  position: relative;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  opacity: 0.3;
  transition: opacity 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.info-card__toggle::before, .info-card__toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 3px;
  right: 3px;
  height: 2px;
  margin-top: -1px;
  border-radius: 2px;
  background-color: currentColor;
  transition: transform 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.info-card__toggle::after {
  transform: rotate(90deg) scaleX(0);
}
.info-card__toggle[aria-expanded=false]::after {
  transform: rotate(90deg) scaleX(1);
}
.info-card__toggle:hover {
  opacity: 0.6;
}

.info-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}

.info-card__identity {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xs);
  padding-bottom: var(--spacing-xs);
  border-bottom: 2px solid var(--color-line);
}
@media (max-width: 1023px) {
  .info-card__identity {
    display: none;
  }
}

.info-card__btn {
  width: 100%;
}

.info-card__list {
  font-size: clamp(0.75rem, 0.36vw + 0.68rem, 1rem);
  line-height: clamp(1rem, 0.45vw + 0.91rem, 1.31rem);
}

.info-card__bullets {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xs);
  padding-left: 1.2em;
  font-size: clamp(0.75rem, 0.36vw + 0.68rem, 1rem);
  list-style: disc;
}
.info-card__bullets strong {
  font-weight: var(--font-weight-black);
}

.info-card__body[hidden] {
  display: none;
}

/* ==========================================================================
   MEDIA FRAME / COMPONENT
   Image arrondie avec reflets (galerie À propos, images des fiches projet).
   Figma : Image_effect
   ========================================================================== */
.media-frame {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-xl);
  background-color: rgba(0, 0, 0, 0.08);
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.25);
}
.media-frame img {
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
}
.media-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 2px 4px 0 rgba(255, 255, 255, 0.5), inset 0 -3px 2px 0 rgba(255, 255, 255, 0.15), inset 0 -6px 6px 0 rgba(0, 0, 0, 0.25);
  pointer-events: none;
}

/* ==========================================================================
   THUMB / COMPONENT
   Vignette vitrée : image dans un cadre de verre.
   Figma : Catégrie_Vide (autres projets) et vignette de l'en-tête d'un projet
   ========================================================================== */
.thumb {
  display: flex;
  aspect-ratio: 160/149;
  padding: clamp(0.5rem, 0.63vw + 0.38rem, 0.94rem);
  border-radius: clamp(1.13rem, 1.07vw + 0.91rem, 1.88rem);
  background-color: rgba(255, 255, 255, 0.2);
  box-shadow: var(--shadow-app);
  backdrop-filter: var(--blur-app);
}
.thumb img {
  flex: 1;
  min-width: 0;
  border-radius: clamp(0.38rem, 0.36vw + 0.3rem, 0.63rem);
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.15), inset 0 1px 2px 0 rgba(255, 255, 255, 0.35);
  -o-object-fit: cover;
     object-fit: cover;
}

/* ==========================================================================
   TITRE DE PAGE / COMPONENTS
   Titre + sous-titre en haut des pages (Projets, À propos, Contact).
   ========================================================================== */
/* ==========================================================================
   PAGE TITLE / COMPONENT
   Titre de page + sous-titre (ex. « Projets / Découvrez les projets »).
   L'opacité garde le même rendu sur fond clair (texte noir) et sombre (texte blanc).
   ========================================================================== */
.page-title {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.page-title__title {
  opacity: 0.6;
}

.page-title__subtitle {
  font-size: var(--font-size-subtitle);
  font-weight: var(--font-weight-bold);
  line-height: 1;
  opacity: 0.35;
}

/* ==========================================================================
   SECTION TITLE / COMPONENT
   Titre de section centré entre deux traits (« Processus », « Produit final »).
   ========================================================================== */
.section-title {
  display: flex;
  align-items: center;
  gap: var(--spacing-lg);
  padding-inline: clamp(0rem, 18.3vw + -3.66rem, 12.81rem);
  text-align: center;
}
.section-title::before, .section-title::after {
  content: "";
  flex: 1;
  min-width: var(--spacing-lg);
  height: 2px;
  background-color: currentColor;
}

/* ==========================================================================
   CARROUSEL / COMPONENT
   Carrousel d'images (Carousel.js) avec points de navigation.
   Figma : Étape 5 d'une fiche projet (Frame 60 + Navigation)
   ========================================================================== */
.carousel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-lg);
}

.carousel__viewport {
  position: relative;
  flex: 1;
  width: 100%;
  min-height: 0;
  aspect-ratio: 665/382;
  overflow: hidden;
  border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.25);
}
.carousel__viewport::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 2px 4px 0 rgba(255, 255, 255, 0.5), inset 0 -3px 2px 0 rgba(255, 255, 255, 0.15), inset 0 -6px 6px 0 rgba(0, 0, 0, 0.25);
  pointer-events: none;
}

.carousel__viewport.is-draggable {
  cursor: grab;
  touch-action: pan-y;
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
.carousel__viewport.is-draggable img {
  -webkit-user-drag: none;
}

.carousel__viewport.is-dragging {
  cursor: grabbing;
}

.carousel__track {
  display: flex;
  height: 100%;
  transition: transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.is-dragging .carousel__track {
  transition: none;
}
@media (prefers-reduced-motion: reduce) {
  .carousel__track {
    transition: none;
  }
}

.carousel__slide {
  flex: 0 0 100%;
}
.carousel__slide img {
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
}

.carousel__dots {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
}

.carousel__dot {
  display: block;
  width: 16px;
  height: 13px;
  border-radius: 4px;
  background: linear-gradient(rgba(247, 23, 249, 0.1), rgba(247, 23, 249, 0.1)), linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15));
  box-shadow: 0 2px 4px -1px rgba(247, 23, 249, 0.05), inset 0 -4px 2px -2px rgba(0, 0, 0, 0.08), inset 2px 2px 1.5px -2px rgba(255, 255, 255, 0.75), inset 0 3px 1.5px -1px rgba(255, 255, 255, 0.35);
  transition: width 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94), height 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.carousel__dot.is-active {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  background: rgba(247, 23, 249, 0.5);
  box-shadow: 0 2px 2px -1px rgba(247, 23, 249, 0.2), inset 0 -4px 2px -2px rgba(0, 0, 0, 0.08), inset 2px 2px 1.5px -2px rgba(255, 255, 255, 0.75), inset 0 3px 1.5px -1px rgba(255, 255, 255, 0.35);
}

/* ==========================================================================
   FOND ANIMÉ / COMPONENT
   Fond clair construit en code à partir de Figma (« Fond claire D » 1440 × 720
   et « Fond claire mobile » 320 × 568) : dégradé rose → lavande, formes de verre
   qui flottent doucement, voile blanc vers le bas.
   Remplace l'image img-fond-clair.webp sur les pages qui ont {% set bgScene = true %}.

   Calques (même ordre que Figma) :
   1. dégradé (.bg-scene)
   2. bulles et carrés de verre
   3. voile blanc vers le bas (Figma : Rectangle 61)
   4. deux petites bulles par-dessus le voile

   Rendu : BgScene.js dessine tout en WebGL (verre liquide calculé par la carte graphique)
   en lisant les variables ci-dessous. Sans WebGL, les formes HTML s'affichent en verre dépoli.
   ========================================================================== */
.has-bg-scene::before {
  display: none;
}

.bg-scene--clair {
  --scene-top: #ffeaff;
  --scene-bottom: #d0c7ff;
  --scene-fill: #ffffff;
  --scene-fill-opacity: 0.16;
  --scene-border: #ffffff;
  --scene-border-opacity: 1;
  --scene-fade: #ffffff;
  --scene-fade-opacity: 0.85;
}

.bg-scene--sombre {
  --scene-top: #663e66;
  --scene-bottom: #0b0044;
  --scene-fill: #000000;
  --scene-fill-opacity: 0.2;
  --scene-border: #ffffff;
  --scene-border-opacity: 0.35;
  --scene-fade: #000000;
  --scene-fade-opacity: 0.6;
}

.bg-scene {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  container-type: size;
  background: linear-gradient(180deg, var(--scene-top) 0%, var(--scene-bottom) 100%);
  pointer-events: none;
}

.bg-scene__stage {
  position: absolute;
  top: 0;
  left: 50%;
  width: max(100cqw, 200cqh);
  aspect-ratio: 1440/720;
  container-type: inline-size;
  transform: translateX(-50%);
}
@media (orientation: portrait) {
  .bg-scene__stage {
    width: max(100cqw, 56.338cqh);
    aspect-ratio: 320/568;
  }
}

.bg-scene__fade {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 0%, var(--scene-fade) 100%);
  opacity: var(--scene-fade-opacity);
}

/* Formes de verre
   ========================================================================== */
.bg-shape {
  position: absolute;
  top: var(--y);
  left: var(--x);
  width: var(--size);
  aspect-ratio: 1;
  margin: calc(var(--size) / -2) 0 0 calc(var(--size) / -2);
  border: 0.278cqw solid color-mix(in srgb, var(--scene-border) calc(var(--scene-border-opacity) * 100%), transparent);
  border-radius: var(--radius);
  background-color: color-mix(in srgb, var(--scene-fill) calc(var(--scene-fill-opacity) * 100%), transparent);
  box-shadow: inset 0 8px 15px 10px rgba(255, 255, 255, 0.3);
  rotate: var(--rot);
  animation: bg-float var(--float-duration) ease-in-out var(--float-delay) infinite;
  will-change: translate, rotate;
}
@media (orientation: portrait) {
  .bg-shape {
    border-width: 0.78cqw;
  }
}
@media (prefers-reduced-motion: reduce) {
  .bg-shape {
    animation: none;
  }
}

@keyframes bg-float {
  0%, 100% {
    translate: 0 0;
    rotate: var(--rot);
  }
  33% {
    translate: var(--float-x1) var(--float-y1);
    rotate: calc(var(--rot) + var(--float-rot));
  }
  66% {
    translate: var(--float-x2) var(--float-y2);
    rotate: calc(var(--rot) - var(--float-rot) / 2);
  }
}
.bg-shape {
  backdrop-filter: blur(6px) saturate(1.3);
  -webkit-backdrop-filter: blur(6px) saturate(1.3);
}

.bg-scene__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.bg-scene.is-webgl .bg-scene__stage {
  display: none;
}

/* Position, taille et flottement de chaque forme (valeurs Figma)
   ========================================================================== */
.bg-shape--bulle-moyenne {
  --x: 13.333%;
  --y: 98.194%;
  --size: 28.014cqw;
  --rot: -15deg;
  --radius: 50%;
  --float-x1: 6%;
  --float-y1: -5%;
  --float-x2: -3%;
  --float-y2: 4%;
  --float-rot: 6deg;
  --float-duration: 26s;
  --float-delay: -4s;
}
@media (orientation: portrait) {
  .bg-shape--bulle-moyenne {
    --x: 11.812%;
    --y: 96.567%;
    --size: 57.156cqw;
    --radius: 50%;
  }
}

.bg-shape--bulle-geante {
  --x: -2.951%;
  --y: 66.319%;
  --size: 46.875cqw;
  --rot: -15deg;
  --radius: 50%;
  --float-x1: 4%;
  --float-y1: -3%;
  --float-x2: -2%;
  --float-y2: 3%;
  --float-rot: 4deg;
  --float-duration: 32s;
  --float-delay: -12s;
}
@media (orientation: portrait) {
  .bg-shape--bulle-geante {
    --x: -21.438%;
    --y: 78.239%;
    --size: 95.656cqw;
    --radius: 50%;
  }
}

.bg-shape--bulle-basse {
  --x: 29.424%;
  --y: 110.514%;
  --size: 22.868cqw;
  --rot: -15deg;
  --radius: 50%;
  --float-x1: -5%;
  --float-y1: -6%;
  --float-x2: 4%;
  --float-y2: -3%;
  --float-rot: 8deg;
  --float-duration: 24s;
  --float-delay: -7s;
}
@media (orientation: portrait) {
  .bg-shape--bulle-basse {
    --x: 44.625%;
    --y: 103.644%;
    --size: 46.656cqw;
    --radius: 50%;
  }
}

.bg-shape--carre-grand {
  --x: 79.542%;
  --y: -12.583%;
  --size: 28.958cqw;
  --rot: -15deg;
  --radius: 23.981%;
  --float-x1: -4%;
  --float-y1: 5%;
  --float-x2: 3%;
  --float-y2: 2%;
  --float-rot: -7deg;
  --float-duration: 30s;
  --float-delay: -3s;
}
@media (orientation: portrait) {
  .bg-shape--carre-grand {
    --x: 70.031%;
    --y: -2.095%;
    --size: 57.188cqw;
    --radius: 13.661%;
  }
}

.bg-shape--carre-moyen {
  --x: 98.417%;
  --y: 3.639%;
  --size: 24.972cqw;
  --rot: -15deg;
  --radius: 27.809%;
  --float-x1: -5%;
  --float-y1: 4%;
  --float-x2: -2%;
  --float-y2: -4%;
  --float-rot: 8deg;
  --float-duration: 27s;
  --float-delay: -15s;
}
@media (orientation: portrait) {
  .bg-shape--carre-moyen {
    --x: 107.312%;
    --y: 6.937%;
    --size: 49.312cqw;
    --radius: 15.843%;
  }
}

.bg-shape--losange {
  --x: 85.264%;
  --y: 9.833%;
  --size: 14.326cqw;
  --rot: -135deg;
  --radius: 14.542%;
  --float-x1: 7%;
  --float-y1: 6%;
  --float-x2: -4%;
  --float-y2: 9%;
  --float-rot: -12deg;
  --float-duration: 22s;
  --float-delay: -9s;
}
@media (orientation: portrait) {
  .bg-shape--losange {
    --x: 81.344%;
    --y: 10.37%;
    --size: 28.281cqw;
    --radius: 16.575%;
  }
}

.bg-shape--bulle-petite {
  --x: 31.882%;
  --y: 70.292%;
  --size: 9.993cqw;
  --rot: -15deg;
  --radius: 50%;
  --float-x1: 14%;
  --float-y1: -12%;
  --float-x2: -8%;
  --float-y2: 10%;
  --float-rot: 10deg;
  --float-duration: 18s;
  --float-delay: -5s;
}
@media (orientation: portrait) {
  .bg-shape--bulle-petite {
    --x: 49.656%;
    --y: 80.528%;
    --size: 20.375cqw;
    --radius: 50%;
  }
}

.bg-shape--bulle-mini {
  --x: 40.035%;
  --y: 98.125%;
  --size: 9.472cqw;
  --rot: -15deg;
  --radius: 50%;
  --float-x1: -12%;
  --float-y1: -14%;
  --float-x2: 10%;
  --float-y2: -8%;
  --float-rot: -10deg;
  --float-duration: 20s;
  --float-delay: -11s;
}
@media (orientation: portrait) {
  .bg-shape--bulle-mini {
    --x: 66.281%;
    --y: 96.532%;
    --size: 19.344cqw;
    --radius: 50%;
  }
}

/* ==========================================================================
   GLASS / COMPONENT
   Effet « liquid glass » de GlassSurface.js (adapté de React Bits) :
   ce qui est derrière l'élément est déformé sur les bords, avec des reflets irisés.
   À ajouter sur un élément : data-component="GlassSurface".
   La forme, la couleur et les ombres de l'élément restent dans son propre style.
   ========================================================================== */
.glass-surface--svg {
  backdrop-filter: var(--filter-id) saturate(var(--glass-saturation, 1.5));
}

.glass-surface--fallback {
  backdrop-filter: blur(10px) saturate(1.6) brightness(1.05);
  -webkit-backdrop-filter: blur(10px) saturate(1.6) brightness(1.05);
}

/* ==========================================================================
   CURSEUR / COMPONENT
   Main personnalisée (CustomCursor.js) : remplace le curseur de la souris.
   ========================================================================== */
body {
  --spark-color: #411ef8;
}

.body--dark {
  --spark-color: #fff;
}

.has-custom-cursor,
.has-custom-cursor * {
  cursor: none !important;
}

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10000;
  filter: drop-shadow(6px 3px 1px rgba(0, 0, 0, 0.15));
  pointer-events: none;
  transition: opacity 0.15s ease-out;
  will-change: transform;
}
.cursor.is-hidden {
  opacity: 0;
}

.cursor__hand {
  position: absolute;
  display: block;
  max-width: none;
  height: auto;
  visibility: hidden;
  will-change: transform;
}
.cursor__hand.is-active {
  visibility: visible;
}

.cursor-trail {
  position: fixed;
  inset: 0;
  z-index: 9999;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ==========================================================================
   HEADER / COMPONENTS
   En-tête de toutes les pages : nom, navigation et barre d'état (heure).
   ========================================================================== */
/* ==========================================================================
   HEADER / COMPONENT
   Hub : barre d'état seulement.
   Autres pages (.header--nav) : nom + navigation + barre d'état.
   ========================================================================== */
.header {
  display: flex;
  justify-content: flex-end;
  padding: clamp(2rem, 0.89vw + 1.82rem, 2.63rem) max(var(--gutter), (100% - 1440px) / 2) 0;
}

.header--nav {
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--spacing-sm);
  padding-top: clamp(1rem, 0.18vw + 0.96rem, 1.13rem);
}
@media (max-width: 479px) {
  .header--nav {
    justify-content: center;
  }
  .header--nav .status-bar {
    order: -1;
    width: 100%;
    justify-content: flex-end;
  }
}
@media (min-width: 1024px) {
  .header--nav {
    position: sticky;
    top: 0;
    z-index: 10;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
  }
  .header--nav::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: -1;
    height: calc(100% + 10px);
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%);
    backdrop-filter: blur(6px);
    -webkit-mask-image: linear-gradient(180deg, #000 40%, transparent 100%);
            mask-image: linear-gradient(180deg, #000 40%, transparent 100%);
    pointer-events: none;
  }
  .header--nav .status-bar {
    justify-self: end;
    margin-top: 17px;
  }
}

.header__brand {
  display: none;
}
@media (min-width: 1024px) {
  .header__brand {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
    margin-top: 10px;
    font-family: var(--font-secondary);
    font-size: var(--font-size-h3);
    font-weight: var(--font-weight-extrabold);
    line-height: 1;
    white-space: nowrap;
  }
}

.header__avatar {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  padding: 2px;
  border-radius: var(--radius-full);
  background: var(--gradient-brand);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.header__avatar img {
  width: 100%;
  height: 100%;
  border-radius: var(--radius-full);
  -o-object-fit: cover;
     object-fit: cover;
}

.body--dark .header--nav::before {
  background: none;
}

/* ==========================================================================
   STATUS BAR / COMPONENT
   Barre d'état en haut à droite (son, batterie, date/heure, horloge).
   Figma : Nav (Hub desktop et mobile)
   ========================================================================== */
.status-bar {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
}
.status-bar::before {
  content: "";
  align-self: stretch;
  width: 2px;
  margin-right: var(--spacing-xs);
  background-color: currentColor;
}
@media (min-width: 1024px) {
  .status-bar {
    gap: var(--spacing-md);
  }
  .status-bar::before {
    margin-right: var(--spacing-xs);
  }
}

.status-bar__icon--desktop {
  display: none;
}
@media (min-width: 1024px) {
  .status-bar__icon--desktop {
    display: inline-block;
  }
}

.status-bar__time {
  font-family: var(--font-secondary);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.1em;
  line-height: 1;
  white-space: nowrap;
}

/* ==========================================================================
   ACCUEIL / COMPONENTS
   Page d'accueil (Hub) : photo, nom, réseaux, accès rapide.
   ========================================================================== */
/* ==========================================================================
   SOCIALS / COMPONENT
   CV / Linkedin / Mail / Instagram / ArtStation : une rangée de boutons-icônes
   en verre (comme une barre d'applications). Le nom apparaît dans la bulle d'info
   au survol (components/tooltip) et le contour dégradé animé du site s'allume.
   Compact : la rangée ne déborde jamais, même avec d'autres réseaux.
   ========================================================================== */
.socials {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(0.63rem, 0.54vw + 0.52rem, 1rem);
  margin-top: clamp(0.25rem, 0.36vw + 0.18rem, 0.5rem);
}
@media (min-width: 1024px) {
  .socials {
    justify-content: flex-start;
  }
}

.socials__link {
  position: relative;
}
.socials__link::before {
  content: "";
  position: absolute;
  inset: 0px;
  padding: 2px;
  border-radius: inherit;
  background: conic-gradient(from var(--border-angle), var(--color-primary), var(--color-secondary), var(--color-primary));
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease-out;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}
.socials__link {
  display: grid;
  place-items: center;
  width: clamp(3rem, 1.07vw + 2.79rem, 3.75rem);
  aspect-ratio: 1;
  border-radius: var(--radius-md);
  background: var(--surface-glass-solid);
  box-shadow: var(--shadow-drop-sm), inset 0 8px 15px 0 rgba(255, 255, 255, 0.3);
  transition: box-shadow 0.25s ease, background-color 0.25s ease;
}
.socials__link .icon {
  width: 52%;
  height: 52%;
}
.socials__link:hover::before, .socials__link:focus-visible::before {
  opacity: 1;
  animation: border-rotate 3s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .socials__link:hover::before, .socials__link:focus-visible::before {
    animation: none;
  }
}
.socials__link:hover, .socials__link:focus-visible {
  background-color: rgba(255, 255, 255, 0.55);
  box-shadow: 0 8px 16px rgba(65, 30, 248, 0.18), inset 0 8px 15px 0 rgba(255, 255, 255, 0.4);
}
.socials__link:focus-visible {
  outline: none;
}

/* ==========================================================================
   HUB / COMPONENT
   Page d'accueil. Figma : Hub (1440) et Hub mobile (320)
   Mobile / tablette : colonne centrée — Desktop (≥ 1024px) : photo + texte côte à côte.
   ========================================================================== */
.hub {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(1.5rem, 2.32vw + 1.04rem, 3.13rem);
  padding-block: var(--spacing-lg) var(--spacing-xl);
  max-width: 560px;
}
@media (min-width: 1024px) {
  .hub {
    max-width: 1200px;
    padding-block: clamp(1.5rem, 2.32vw + 1.04rem, 3.13rem);
  }
}

/* Intro (photo + nom + réseaux)
   ========================================================================== */
.hub__intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-md);
}
@media (min-width: 1024px) {
  .hub__intro {
    flex-direction: row;
    align-items: flex-start;
    gap: var(--spacing-lg);
  }
}

.hub__hint {
  display: none;
}
@media (min-width: 1024px) {
  .hub__hint {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    flex: 0 0 113px;
    margin-top: 105px;
    color: var(--color-text-muted);
    font-size: 16px;
    font-weight: var(--font-weight-bold);
    line-height: 18px;
    text-align: center;
  }
  .hub__hint::after {
    content: "";
    flex: 0 0 auto;
    border-top: 9px solid transparent;
    border-bottom: 9px solid transparent;
    border-left: 10px solid currentColor;
  }
}

.hub__photo {
  flex: 0 0 auto;
  width: clamp(6.81rem, 11.79vw + 4.46rem, 15.06rem);
  aspect-ratio: 1;
  padding: clamp(0.25rem, 0.18vw + 0.21rem, 0.38rem);
  border-radius: var(--radius-full);
  background: var(--gradient-brand);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
}
.hub__photo img {
  width: 100%;
  height: 100%;
  border-radius: var(--radius-full);
  -o-object-fit: cover;
     object-fit: cover;
}
@media (min-width: 1024px) {
  .hub__photo {
    margin-right: calc(58px - var(--spacing-lg));
  }
}

.hub__content {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
  width: 100%;
}
@media (min-width: 1024px) {
  .hub__content {
    flex: 0 1 661px;
    align-self: center;
    gap: var(--spacing-lg);
  }
}

.hub__heading {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding-bottom: var(--spacing-xs);
  border-bottom: 3px solid var(--color-line);
  text-align: center;
}
@media (min-width: 1024px) {
  .hub__heading {
    padding-bottom: var(--spacing-md);
    text-align: left;
  }
}

.hub__tagline {
  margin-top: calc(var(--spacing-xs) - var(--spacing-sm));
}
@media (min-width: 1024px) {
  .hub__tagline {
    margin-top: calc(var(--spacing-md) - var(--spacing-lg));
  }
}

.hub__video {
  width: 100%;
}
@media (min-width: 1024px) {
  .hub__video {
    width: 454px;
    max-width: 100%;
  }
}

/* Accès rapide
   ========================================================================== */
.quick-access {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
  width: 100%;
}
@media (min-width: 1024px) {
  .quick-access {
    gap: var(--spacing-lg);
    max-width: 996px;
    margin-inline: auto;
  }
}

.quick-access__title {
  display: flex;
  align-items: center;
  gap: var(--spacing-lg);
  white-space: nowrap;
}
.quick-access__title::after {
  content: "";
  flex: 1;
  height: 3px;
  background-color: var(--color-line-muted);
}

.quick-access__list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--spacing-sm);
}
@media (min-width: 768px) {
  .quick-access__list {
    gap: var(--spacing-md);
  }
}
@media (min-width: 1024px) {
  .quick-access__list {
    gap: var(--spacing-lg);
  }
}

/* ==========================================================================
   PROJETS / COMPONENTS
   Page Projets : cartes projets, points de navigation et mise en page.
   ========================================================================== */
/* ==========================================================================
   PROJECT CARD / COMPONENT
   Carte d'un projet. Figma : Frame 175 / 195 / 196
   Survol (Variant2) : contour dégradé, la photo laisse place à une couleur
   et l'image détourée « sort » du cadre.
   ========================================================================== */
.project-card {
  position: relative;
  padding: 5px;
  border-radius: var(--radius-xl);
  scroll-margin-top: var(--spacing-lg);
  position: relative;
}
.project-card::before {
  content: "";
  position: absolute;
  inset: 0px;
  padding: 5px;
  border-radius: inherit;
  background: conic-gradient(from var(--border-angle), var(--color-primary), var(--color-secondary), var(--color-primary));
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease-out;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}

.project-card__inner {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
  margin: 6px;
  padding: var(--spacing-md);
  border-radius: var(--radius-xl);
  background-color: rgba(255, 255, 255, 0.2);
  box-shadow: var(--shadow-app);
  backdrop-filter: var(--blur-app);
}
@media (min-width: 1024px) {
  .project-card__inner {
    flex-direction: row;
    gap: var(--spacing-lg);
  }
}

@media (min-width: 1024px) {
  .project-card--reverse .project-card__media {
    order: 2;
  }
}

/* Image
   ========================================================================== */
.project-card__media {
  position: relative;
  display: flex;
  align-items: flex-end;
  flex: 0 0 auto;
  width: 100%;
  aspect-ratio: 350/300;
  padding: var(--spacing-sm);
}
@media (min-width: 1024px) {
  .project-card__media {
    width: clamp(280px, 31.6%, 480px);
  }
}

.project-card__media::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: var(--radius-xl);
  background: var(--project-shade, linear-gradient(180deg, rgba(0, 0, 0, 0) 57.667%, rgba(0, 0, 0, 0.75) 87.386%));
  pointer-events: none;
}

.project-card__frame {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: var(--radius-xl);
  background: var(--project-color, var(--color-primary));
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.15);
}
.project-card__frame::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  box-shadow: inset 0 1px 2px 0 rgba(255, 255, 255, 0.35), inset 0 -1px 2px 0 rgba(0, 0, 0, 0.3);
}

.project-card__img {
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
  transition: opacity 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.project-card__cutout {
  position: absolute;
  bottom: 0;
  left: var(--cutout-x, 50%);
  z-index: 2;
  width: auto;
  max-width: none;
  height: var(--cutout-h, 124%);
  opacity: 0;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15));
  pointer-events: none;
  transform: translate(-50%, 16px);
  transition: opacity 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94), transform 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  display: none;
}
@media (min-width: 1024px) {
  .project-card__cutout {
    display: block;
  }
}

.project-card__category {
  position: relative;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  padding-inline: var(--spacing-xs);
  color: var(--color-text-inverse);
  font-size: var(--font-size-button);
  font-weight: var(--font-weight-extrabold);
  line-height: 1;
  text-align: center;
}

.project-card__category-label {
  max-width: 140px;
}

/* Contenu
   ========================================================================== */
.project-card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--spacing-md);
  min-width: 0;
}

.project-card__content {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
}

.project-card__heading {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
  padding-bottom: var(--spacing-sm);
  border-bottom: 2px solid var(--color-line);
}
@media (min-width: 768px) {
  .project-card__heading {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}
.project-card__heading h2 {
  max-width: 490px;
}

.project-card__meta {
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-sm);
}
@media (min-width: 768px) {
  .project-card__meta {
    flex: 0 0 auto;
    flex-direction: column;
    align-items: flex-end;
  }
}

.project-card__tools {
  display: flex;
  gap: var(--spacing-sm);
}

.project-card__actions {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}
@media (min-width: 768px) {
  .project-card__actions {
    flex-direction: row;
    gap: var(--spacing-lg);
  }
}

.project-card__btn {
  flex: 1;
}

/* Carte sélectionnée (ProjectSlider.js), survol et focus clavier
   ========================================================================== */
@media (hover: hover) {
  .project-card:hover .project-card__img {
    opacity: 0;
  }
  .project-card:hover .project-card__cutout {
    opacity: 1;
    transform: translate(-50%, 0);
  }
  .project-card.is-active:hover::before {
    opacity: 1;
    animation: border-rotate 3s linear infinite;
  }
}
@media (hover: hover) and (prefers-reduced-motion: reduce) {
  .project-card.is-active:hover::before {
    animation: none;
  }
}
.project-card.is-active .project-card__img,
.project-card:focus-within .project-card__img {
  opacity: 0;
}
.project-card.is-active .project-card__cutout,
.project-card:focus-within .project-card__cutout {
  opacity: 1;
  transform: translate(-50%, 0);
}

.project-card:has(:focus-visible)::before {
  opacity: 1;
  animation: border-rotate 3s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .project-card:has(:focus-visible)::before {
    animation: none;
  }
}

/* Variantes par catégorie
   ========================================================================== */
.project-card--3d {
  --project-color: linear-gradient(180deg, #7da3c8 0%, #d9c2a5 100%);
  --cutout-h: 120%;
  --cutout-x: 52%;
}

.project-card--2d {
  --project-color: #fcc03d;
  --cutout-h: 133%;
  --cutout-x: 55%;
  --project-shade: linear-gradient(
      180deg,
      rgba(255, 255, 255, 0) 57.667%,
      rgba(255, 255, 255, 0.75) 87.386%
  );
}
.project-card--2d .project-card__category {
  color: var(--color-text);
}

.project-card--photo {
  --project-color: linear-gradient(180deg, #8856e5 0%, #360a88 100%);
  --cutout-h: 124%;
  --cutout-x: 60%;
}

/* ==========================================================================
   PROJECT NAV / COMPONENT
   Points à droite de la carte sélectionnée : indiquent le projet affiché et y mènent.
   Figma : Navigation (desktop seulement)
   ========================================================================== */
.project-nav {
  display: none;
}
@media (min-width: 1024px) {
  .project-nav {
    display: flex;
    flex: 0 0 18px;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-sm);
    transition: height 0.6s cubic-bezier(0.215, 0.61, 0.355, 1);
  }
}

.project-nav__dot {
  display: block;
  width: 13px;
  height: 16px;
  border-radius: 4px;
  background: linear-gradient(rgba(247, 23, 249, 0.1), rgba(247, 23, 249, 0.1)), rgba(0, 0, 0, 0.15);
  box-shadow: 0 2px 4px -1px rgba(247, 23, 249, 0.05), inset 0 -4px 2px -2px rgba(0, 0, 0, 0.08), inset 2px 2px 1.5px -2px rgba(255, 255, 255, 0.75), inset 0 3px 1.5px -1px rgba(255, 255, 255, 0.35);
  transition: width 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94), height 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94), background 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.project-nav__dot:hover {
  background: rgba(247, 23, 249, 0.3);
}
.project-nav__dot.is-active {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  background: rgba(247, 23, 249, 0.5);
  box-shadow: 0 2px 2px -1px rgba(247, 23, 249, 0.2), inset 0 -4px 2px -2px rgba(0, 0, 0, 0.08), inset 2px 2px 1.5px -2px rgba(255, 255, 255, 0.75), inset 0 3px 1.5px -1px rgba(255, 255, 255, 0.35);
}

/* ==========================================================================
   PROJECTS / COMPONENT
   Mise en page de la page Projets. Figma : Page Projets (Frame 214)
   Desktop (≥ 1024px) : la page tient dans l'écran et ne défile pas,
   ce sont les cartes qui montent (voir ProjectSlider.js).
   Mobile : la page défile normalement.
   ========================================================================== */
@media (min-width: 1024px) {
  body.page--projets {
    height: calc(100vh / var(--zoom));
    height: calc(100dvh / var(--zoom));
    overflow: hidden;
  }
  body.page--projets main {
    min-height: 0;
  }
}
.projects {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding-block: clamp(1.5rem, 0.54vw + 1.39rem, 1.88rem) var(--spacing-3xl);
}
@media (min-width: 1024px) {
  .projects {
    flex: 1;
    min-height: 0;
    padding-bottom: 0;
  }
}

.projects__layout {
  display: flex;
  align-items: flex-start;
  gap: 49px;
}
@media (min-width: 1024px) {
  .projects__layout {
    flex: 1;
    min-height: 0;
  }
}

.projects__viewport {
  flex: 1;
  min-width: 0;
}

.projects__list {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

@media (min-width: 1024px) {
  .projects .page-title,
  .projects__list {
    transform: translateY(calc(var(--slide-offset, 0px) + var(--drag-offset, 0px)));
    transition: transform 0.6s cubic-bezier(0.215, 0.61, 0.355, 1);
  }
}
@media (min-width: 1024px) and (prefers-reduced-motion: reduce) {
  .projects .page-title,
  .projects__list {
    transition: none;
  }
}
@media (min-width: 1024px) {
  .projects__viewport {
    cursor: grab;
  }
  .projects.is-dragging {
    cursor: grabbing;
    -webkit-user-select: none;
       -moz-user-select: none;
            user-select: none;
  }
  .projects.is-dragging .page-title,
  .projects.is-dragging .projects__list {
    transition: none;
  }
  .projects.is-dragging a,
  .projects.is-dragging .projects__viewport {
    cursor: grabbing;
  }
  .project-card:not(.is-active):not(.is-past) {
    cursor: pointer;
  }
  .projects__list .project-card {
    transform: scale(0.94);
    transition: transform 0.6s cubic-bezier(0.215, 0.61, 0.355, 1);
  }
  .projects__list .project-card.is-active {
    transform: none;
  }
}
@media (min-width: 1024px) and (prefers-reduced-motion: reduce) {
  .projects__list .project-card {
    transition: none;
  }
}
.project-card.is-past {
  pointer-events: none;
}

/* ==========================================================================
   À PROPOS / COMPONENTS
   Page À propos : photos, compétences, galerie de passions et mise en page.
   ========================================================================== */
/* ==========================================================================
   POP PHOTO / COMPONENT
   Photo arrondie + personnage détouré qui dépasse du cadre par le haut.
   Figma : D3E51607 (À propos) et 4F47F197 (Photographie)
   --pop-ratio : proportion de l'ensemble / --pop-bg : hauteur du cadre
   ========================================================================== */
.pop-photo {
  position: relative;
  display: block;
  flex: 0 0 auto;
  aspect-ratio: var(--pop-ratio, 282/273);
}

.pop-photo__frame {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: var(--pop-bg, 80.6%);
  overflow: hidden;
  border-radius: var(--radius-xl);
  background-color: rgba(255, 255, 255, 0.2);
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.25);
}
.pop-photo__frame::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 2px 4px 0 rgba(255, 255, 255, 0.5), inset 0 -3px 2px 0 rgba(255, 255, 255, 0.15), inset 0 -6px 6px 0 rgba(0, 0, 0, 0.25);
}

.pop-photo__bg {
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
}

.pop-photo__cutout {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: 0 0 var(--radius-xl) var(--radius-xl);
  -o-object-fit: cover;
     object-fit: cover;
  -o-object-position: bottom;
     object-position: bottom;
}

/* ==========================================================================
   SKILLS / COMPONENT
   Barres de compétences (Hard Skill). Couleur et pourcentage par élément :
   style="--skill: 95%; --skill-color: #3718f6"
   ========================================================================== */
.skills {
  gap: var(--spacing-sm);
}

.skill {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  row-gap: clamp(0.75rem, 0.71vw + 0.61rem, 1.25rem);
  -moz-column-gap: var(--spacing-xs);
       column-gap: var(--spacing-xs);
}

.skill__name {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  font-family: var(--font-secondary);
  font-size: clamp(0.88rem, 0.54vw + 0.77rem, 1.25rem);
  font-weight: var(--font-weight-extrabold);
  line-height: 1;
}
.skill__name::before {
  content: "";
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  border-radius: var(--radius-full);
  background-color: var(--skill-color);
}

.skill__value {
  color: rgba(0, 0, 0, 0.75);
  font-size: clamp(0.81rem, 0.63vw + 0.69rem, 1.25rem);
  font-weight: var(--font-weight-bold);
  line-height: 1;
}

.skill__bar {
  grid-column: 1/-1;
  height: clamp(0.31rem, 0.45vw + 0.22rem, 0.63rem);
  border-radius: 10px;
  background: linear-gradient(var(--skill-color), var(--skill-color)) 0 0/var(--skill) 100% no-repeat, rgba(0, 0, 0, 0.35);
}

/* ==========================================================================
   PASSIONS / COMPONENT
   Galerie de passions en collage (images qui se chevauchent).
   Tailles et chevauchements en « cqw » (% de la largeur du bloc .passion,
   524px dans Figma) : le collage garde ses proportions sur tous les écrans.
   Le texte réserve en dessous la place du chevauchement (padding-bottom),
   pour qu'une image ne passe jamais par-dessus le texte.
   ========================================================================== */
.passions {
  gap: var(--spacing-lg);
}

.passion {
  display: flex;
  flex-direction: column;
  container-type: inline-size;
}

.passion__row {
  display: grid;
  align-items: start;
  -moz-column-gap: var(--spacing-md);
       column-gap: var(--spacing-md);
}

.passion__text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--spacing-sm);
  min-width: 0;
}
.passion__text p {
  font-size: clamp(0.75rem, 0.36vw + 0.68rem, 1rem);
  line-height: clamp(1rem, 0.45vw + 0.91rem, 1.31rem);
}
.passion__text .h2 {
  font-size: clamp(1.63rem, 0.36vw + 1.55rem, 1.88rem);
}

.passion__text--right .h2 {
  text-align: right;
}

.passion__img {
  position: relative;
  flex: 0 0 auto;
}

/* Photographie
   ========================================================================== */
.passion--photo .passion__row {
  grid-template-columns: 48.3cqw minmax(0, 1fr);
}

.passion__pop {
  --pop-ratio: 253 / 170;
  --pop-bg: 84.7%;
  width: 100%;
  margin-bottom: 7.4cqw;
}

.passion--photo .passion__text {
  padding-bottom: calc(14.3cqw + var(--spacing-xs));
}

.passion__img--photo-2 {
  align-self: flex-end;
  width: 62.2cqw;
  aspect-ratio: 326/209;
  margin-top: -14.3cqw;
}

.passion__img--photo-3 {
  width: 42.9cqw;
  aspect-ratio: 225/209;
  margin-top: -20cqw;
}

/* Construire des PC
   ========================================================================== */
.passion--pc .passion__row {
  grid-template-columns: minmax(0, 1fr) 48.3cqw;
  align-items: center;
}

.passion--pc .passion__text {
  padding-bottom: calc(4.2cqw + var(--spacing-xs));
}

.passion__img--pc-1 {
  width: 100%;
  aspect-ratio: 253/209;
}

.passion__img--pc-2 {
  width: 74.2cqw;
  aspect-ratio: 389/247;
  margin-top: -4.2cqw;
}

.passion__img--pc-3 {
  align-self: flex-end;
  width: 53.6cqw;
  aspect-ratio: 281/204;
  margin-top: -27.1cqw;
}

/* Le dessin
   ========================================================================== */
.passion--dessin {
  gap: var(--spacing-md);
}

.passion__img--dessin {
  width: 100%;
  aspect-ratio: 524/328;
}

/* ==========================================================================
   ABOUT / COMPONENT
   Mise en page de la page À propos. Figma : Page apropos (desktop) / Apropos mobile
   Desktop : colonne gauche fixe (sticky), colonne droite qui défile sous la navigation.
   ========================================================================== */
.about {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
  padding-block: var(--spacing-md) var(--spacing-3xl);
}
@media (min-width: 1024px) {
  .about {
    display: grid;
    grid-template-columns: minmax(282px, var(--about-aside, 27.5%)) minmax(0, 49%) minmax(0, 1fr);
    container-type: inline-size;
    align-items: start;
    gap: var(--spacing-lg);
    padding-top: 12px;
  }
}

/* Colonne de gauche
   ========================================================================== */
.about__aside {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}
@media (min-width: 1024px) and (min-height: 720px) {
  .about__aside {
    position: sticky;
    top: 108px;
  }
}

@media (min-width: 1024px) {
  .about__title {
    padding-left: 20px;
  }
}

.about__intro {
  display: flex;
  align-items: flex-end;
  gap: var(--spacing-md);
}
.about__intro > .info-card {
  flex: 1;
}
@media (min-width: 1024px) {
  .about__intro {
    flex-direction: column;
    align-items: stretch;
  }
  .about__intro > .info-card {
    flex: none;
  }
}

.about__photo {
  --pop-ratio: 800 / 821;
  --pop-bg: 80.4%;
  width: 150px;
}
@media (min-width: 1024px) {
  .about__photo {
    width: 100%;
  }
}

/* Colonne de droite
   ========================================================================== */
.about__main {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}
@media (min-width: 1024px) {
  .about__main {
    margin-top: 74px;
  }
}

.about__identity {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xs);
  padding-bottom: var(--spacing-xs);
  border-bottom: 2px solid currentColor;
  text-shadow: 0 0 20px #000;
}
@media (min-width: 1024px) {
  .about__identity {
    display: none;
  }
}

.about__identity-role {
  font-family: var(--font-secondary);
  font-size: 14px;
  font-weight: var(--font-weight-extrabold);
  line-height: 1;
}

.about__copyright {
  margin-top: var(--spacing-md);
  font-family: var(--font-secondary);
  font-size: var(--font-size-h3);
  font-weight: var(--font-weight-medium);
  text-align: center;
}

/* Animation 3D du vaisseau (ShipAnimation.js)
   Position reprise de la maquette Figma (Page apropos, 1440 × 720) : le rendu
   2560 × 1440 y fait 1603px de large (0.6262) pour un contenu de 1200px.
   Toutes les mesures sont en cqw (largeur de .about) pour garder les proportions :
   1px du rendu = 0.052181cqw. L'aile gauche passe derrière les cartes et le
   vaisseau est coupé par le bord droit de l'écran.
   ========================================================================== */
.page--a-propos main {
  overflow-x: clip;
}

.about__ship {
  display: none;
}
@media (min-width: 1024px) {
  .about__ship {
    grid-column: 3;
    grid-row: 1;
    position: sticky;
    top: 31%;
    z-index: -1;
    display: block;
    pointer-events: none;
  }
}
.about__ship canvas {
  position: absolute;
  top: -35.5cqw;
  left: -71.5cqw;
  width: 133.58cqw;
  height: auto;
  transition: opacity 0.4s ease;
}

.about__ship-img {
  display: block;
  width: 81.14cqw;
  max-width: none;
  height: auto;
  margin-left: -19.06cqw;
  transition: opacity 0.4s ease;
}
.about__ship.is-loading .about__ship-img, .about__ship.is-playing .about__ship-img {
  opacity: 0;
}

.about__ship.is-done canvas {
  opacity: 0;
}

.ship-intro {
  position: fixed;
  top: 50%;
  left: 50%;
  z-index: -1;
  width: calc(min(1440px, 100vw / var(--zoom) - var(--gutter) * 2) * 1.3358);
  height: auto;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

/* ==========================================================================
   CONTACT / COMPONENTS
   Page Contact : champs du formulaire, formulaire et tuiles de contact.
   ========================================================================== */
/* ==========================================================================
   FIELD / COMPONENT
   Champ de formulaire (libellé + saisie). Figma : Frame 160 / 161 / 201
   ========================================================================== */
.field {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2xs);
  min-width: 0;
}

.field--grow {
  flex: 1;
}

.field__label {
  font-size: var(--font-size-button);
  font-weight: var(--font-weight-extrabold);
  line-height: 1;
}

.field__input {
  width: 100%;
  padding: clamp(0.75rem, 0.36vw + 0.68rem, 1rem) clamp(1rem, 0.71vw + 0.86rem, 1.5rem);
  border: 2px solid var(--color-white);
  border-radius: var(--radius-md);
  background-color: rgba(251, 115, 250, 0.05);
  box-shadow: var(--shadow-btn);
  color: var(--color-text);
  font-size: var(--font-size-content);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-content);
  transition: border-color 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94), background-color 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.field__input::-moz-placeholder {
  color: rgba(0, 0, 0, 0.3);
}
.field__input::placeholder {
  color: rgba(0, 0, 0, 0.3);
}
.field__input:focus {
  border-color: var(--color-primary);
  background-color: rgba(255, 255, 255, 0.5);
  outline: none;
}

.field__input--area {
  flex: 1;
  min-height: 120px;
  resize: vertical;
}

/* ==========================================================================
   CONTACT / COMPONENT
   Page Contact. Figma : Page contact (desktop) — formulaire + 6 tuiles.
   Proportions Figma sur 1200px : formulaire 793px, tuiles 382px, espace 24px.
   ========================================================================== */
.contact {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
  padding-block: var(--spacing-md) var(--spacing-3xl);
}
@media (min-width: 1024px) {
  .contact {
    padding-block: 12px var(--spacing-2xl);
  }
}

@media (min-width: 1024px) {
  .contact__title {
    padding-left: 20px;
  }
}

.contact__layout {
  display: grid;
  gap: var(--spacing-lg);
}
@media (min-width: 1024px) {
  .contact__layout {
    grid-template-columns: minmax(0, 793fr) minmax(0, 382fr);
    align-items: stretch;
  }
}

/* Formulaire
   ========================================================================== */
.contact-form {
  gap: var(--spacing-sm);
}

.contact-form__label {
  font-weight: var(--font-weight-semibold);
  font-size: clamp(0.75rem, 0.36vw + 0.68rem, 1rem);
}

.contact-form__intro {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.contact-form__lead {
  color: rgba(0, 0, 0, 0.6);
  font-size: var(--font-size-subtitle);
  font-weight: var(--font-weight-bold);
  line-height: 1.2;
}

.contact-form__row {
  display: grid;
  gap: var(--spacing-sm);
}
@media (min-width: 768px) {
  .contact-form__row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.contact-form__submit {
  width: 100%;
  margin-top: var(--spacing-2xs);
}

/* Tuiles de contact
   ========================================================================== */
.contact-links {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: 1fr;
  gap: var(--spacing-md) var(--spacing-lg);
}
@media (min-width: 768px) and (max-width: 1023px) {
  .contact-links {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.contact-links > li:last-child:nth-child(odd) {
  grid-column: 1/-1;
}

.tile--contact {
  min-height: clamp(7.5rem, 2.5vw + 7rem, 9.25rem);
  padding: var(--spacing-sm);
  font-family: var(--font-primary);
  font-size: clamp(0.81rem, 0.27vw + 0.76rem, 1rem);
  font-weight: var(--font-weight-bold);
  text-align: center;
  border-radius: var(--radius-xl);
}
.tile--contact .icon {
  transition: filter 0.25s ease;
}
.tile--contact:hover .icon, .tile--contact:focus-visible .icon {
  filter: brightness(0) invert(1);
}

/* ==========================================================================
   Desktop : toute la page tient dans l'écran, sans défiler.
   Le formulaire et les tuiles prennent la hauteur restante sous le titre :
   la zone « message » et les tuiles s'ajustent à la hauteur de l'écran.
   (Écran très bas, moins de 600px : la page peut défiler, pour rester lisible.)
   ========================================================================== */
@media (min-width: 1024px) and (min-height: 600px) {
  body.page--contact {
    height: calc(100vh / var(--zoom));
    height: calc(100dvh / var(--zoom));
    overflow: hidden;
  }
  body.page--contact main {
    min-height: 0;
  }
  .page--contact .contact {
    flex: 1;
    min-height: 0;
    padding-block: 12px clamp(1.5rem, 1.43vw + 1.21rem, 2.5rem);
  }
  .page--contact .contact__layout {
    flex: 1;
    min-height: 0;
    grid-template-rows: minmax(0, 1fr);
  }
  .page--contact .contact-form {
    min-height: 0;
  }
  .page--contact .field--grow {
    min-height: 0;
  }
  .page--contact .field__input--area {
    min-height: 60px;
    resize: none;
  }
  .page--contact .contact-links {
    min-height: 0;
    grid-auto-rows: minmax(0, 1fr);
    gap: clamp(0.75rem, 0.36vw + 0.68rem, 1rem) clamp(1rem, 0.71vw + 0.86rem, 1.5rem);
  }
  .page--contact .tile--contact {
    min-height: 0;
    gap: clamp(0.38rem, 0.36vw + 0.3rem, 0.63rem);
  }
  .page--contact .icon--contact {
    width: auto;
    height: clamp(28px, 6vh, 54px);
    aspect-ratio: 1;
  }
}
/* ==========================================================================
   FICHE PROJET / PAGE
   Page d'un projet (ex. projet-vaisseau.html).
   Figma : M2 / Page Projet / Desktop 1446
   ========================================================================== */
.body--projet::before {
  background-image: linear-gradient(180deg, rgba(255, 234, 255, 0.25) 0%, rgba(208, 199, 255, 0.25) 100%), linear-gradient(var(--color-white), var(--color-white));
}

.body--projet::after {
  content: "";
  position: fixed;
  inset: -60px 0 0 -60px;
  z-index: -1;
  background: url("../assets/images/img-motif-cubes.webp") 0 0/30px 60px repeat;
  animation: cubes-defilement 10s linear infinite;
  pointer-events: none;
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .body--projet::after {
    animation: none;
  }
}

@keyframes cubes-defilement {
  to {
    transform: translate(60px, 60px);
  }
}
.projet {
  position: relative;
  z-index: 0;
}

.body--projet .header {
  position: relative;
  z-index: 1;
}
@media (min-width: 1024px) {
  .body--projet .header {
    position: sticky;
    z-index: 10;
  }
}

.body--projet .header--nav {
  color: var(--color-text-inverse);
}
@media (min-width: 1024px) {
  .body--projet .header--nav::before {
    height: calc(100% + 60px);
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 100%);
    backdrop-filter: none;
  }
  .body--projet .header--nav::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: -1;
    height: calc(100% + 10px);
    backdrop-filter: blur(6px);
    -webkit-mask-image: linear-gradient(180deg, #000 40%, transparent 100%);
            mask-image: linear-gradient(180deg, #000 40%, transparent 100%);
    opacity: 0;
    transition: opacity 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
    pointer-events: none;
  }
  .body--projet .header--nav.is-scrolled::after {
    opacity: 1;
  }
}

.projet {
  display: flex;
  flex-direction: column;
  gap: clamp(1.5rem, 0.71vw + 1.36rem, 2rem);
}

.projet .media-frame {
  border-radius: var(--radius-lg);
}
.projet .media-frame img {
  position: absolute;
  inset: 0;
}

/* En-tête : image en fond, titre, date, catégorie
   ========================================================================== */
.projet-hero {
  position: relative;
  color: var(--color-text-inverse);
}

.projet-hero__bg {
  position: absolute;
  top: -300px;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: -1;
  overflow: hidden;
  background-color: var(--color-black);
}
.projet-hero__bg img {
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
  opacity: 0.8;
}
.projet-hero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(127.68deg, rgba(61, 61, 61, 0.5) 18.111%, rgba(255, 255, 255, 0.05) 70.01%, rgba(28, 2, 164, 0.25) 100%);
}

.projet-hero__inner {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--spacing-lg);
  min-height: clamp(10.63rem, 7.14vw + 9.2rem, 15.63rem);
}
@media (min-width: 1024px) {
  .projet-hero__inner {
    gap: 0;
  }
}
.projet-hero__inner {
  padding-block: clamp(0.5rem, 0.63vw + 0.38rem, 0.94rem) clamp(1rem, 0.71vw + 0.86rem, 1.5rem);
}

.projet-hero__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--spacing-md);
}
@media (min-width: 1024px) {
  .projet-hero__top {
    padding-left: var(--spacing-md);
  }
}

.projet-hero__category {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  max-width: clamp(4.75rem, 2.05vw + 4.34rem, 6.19rem);
  font-size: clamp(0.63rem, 0.36vw + 0.55rem, 0.88rem);
  font-weight: var(--font-weight-extrabold);
  line-height: 0.85;
  text-align: center;
}

@media (min-width: 1024px) {
  .projet-hero__bottom {
    display: grid;
    grid-template-columns: 180px minmax(0, 1fr);
    align-items: end;
    -moz-column-gap: 25px;
         column-gap: 25px;
  }
}

.projet-hero__thumb {
  display: none;
}
@media (min-width: 1024px) {
  .projet-hero__thumb {
    display: flex;
    margin-bottom: -54px;
  }
}

.projet-hero__heading {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--spacing-xs) var(--spacing-lg);
}

.projet-hero__title {
  max-width: 13.3em;
  text-shadow: 0 0 20px rgba(0, 0, 0, 0.35);
}

.projet-hero__date {
  color: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
}

/* Présentation : Contexte / Rôle, logiciels, crédits, IA
   ========================================================================== */
.projet-intro {
  display: grid;
  gap: clamp(1rem, 0.71vw + 0.86rem, 1.5rem);
  padding-top: clamp(0rem, 1.96vw + -0.39rem, 1.38rem);
}
@media (min-width: 768px) {
  .projet-intro {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.projet-intro__top {
  display: grid;
  gap: clamp(1rem, 0.71vw + 0.86rem, 1.5rem);
}
@media (min-width: 768px) {
  .projet-intro__top {
    grid-column: 1/-1;
    grid-template-columns: minmax(0, 1fr) minmax(200px, 272px);
  }
}

.projet-intro__main {
  display: grid;
  grid-template-areas: "tabs" "panel";
  gap: clamp(0.75rem, 1.07vw + 0.54rem, 1.5rem);
}
@media (min-width: 1024px) {
  .projet-intro__main {
    grid-template-areas: "tabs panel";
    grid-template-columns: 180px minmax(0, 1fr);
    align-items: center;
  }
}
.projet-intro__main .tabs {
  grid-area: tabs;
}

.projet-intro__panel {
  grid-area: panel;
  align-self: stretch;
  min-height: clamp(8.75rem, 4.29vw + 7.89rem, 11.75rem);
}

.projet-intro__panel[hidden] {
  display: flex;
  visibility: hidden;
}

.projet-intro__tools-list {
  display: flex;
  flex: 1;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.projet-intro__credits .info-card__bullets {
  gap: 2px;
}

/* Processus
   ========================================================================== */
.projet-process {
  display: flex;
  flex-direction: column;
  gap: clamp(1.5rem, 0.71vw + 1.36rem, 2rem);
  padding-top: clamp(0rem, 1.96vw + -0.39rem, 1.38rem);
}

.step > .h2 + p,
.step__text > .h2 + p {
  margin-top: calc(6px - var(--spacing-sm));
}

.step__text {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.projet-process__duo {
  display: grid;
  gap: clamp(1rem, 2.86vw + 0.43rem, 3rem);
}
@media (min-width: 1024px) {
  .projet-process__duo {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.projet-process__steps {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}

.projet-process__duo-img {
  aspect-ratio: 576/437;
}
.projet-process__duo-img img {
  -o-object-position: 50% 6%;
     object-position: 50% 6%;
}
@media (min-width: 1024px) {
  .projet-process__duo-img {
    aspect-ratio: auto;
  }
}

.step__row {
  display: grid;
  gap: clamp(1rem, 1.43vw + 0.71rem, 2rem);
}
@media (min-width: 768px) {
  .step__row {
    grid-template-columns: minmax(0, 453fr) minmax(0, 651fr);
    align-items: start;
  }
}

.step--wide .step__img {
  aspect-ratio: 651/250;
}
@media (min-width: 768px) {
  .step--wide .step__img {
    aspect-ratio: auto;
    height: clamp(11.25rem, 10.42vw + 6.25rem, 15.63rem);
  }
}

.projet-band {
  position: relative;
  padding-block: clamp(2rem, 2.86vw + 1.43rem, 4rem);
  box-shadow: 0 4px 2px rgba(0, 0, 0, 0.15);
  color: var(--color-text-inverse);
}

.projet-band__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background-color: var(--color-black);
}
.projet-band__bg img {
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
  opacity: 0.5;
}
.projet-band__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(117.79deg, rgba(61, 61, 61, 0.9) 18.111%, rgba(255, 255, 255, 0.09) 70.01%, rgba(28, 2, 164, 0.45) 100%);
  box-shadow: inset 0 8px 15px 0 rgba(255, 255, 255, 0.3);
}

.projet-band__inner {
  display: grid;
  gap: clamp(1rem, 1.43vw + 0.71rem, 2rem);
}
@media (min-width: 1024px) {
  .projet-band__inner {
    grid-template-columns: minmax(0, 466fr) minmax(0, 702fr);
    align-items: start;
  }
}

.projet-band__img {
  aspect-ratio: 702/379;
}

.step--dark {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
  padding: clamp(0rem, 2.14vw + -0.43rem, 1.5rem) clamp(0rem, 2.86vw + -0.57rem, 2rem);
}
.step--dark .info-card__label {
  color: rgba(255, 255, 255, 0.5);
}
.step--dark .info-card__label .icon {
  color: var(--color-white);
}

.projet-process__render {
  display: grid;
  gap: clamp(1rem, 2.86vw + 0.43rem, 3rem);
}
@media (min-width: 1024px) {
  .projet-process__render {
    grid-template-columns: minmax(0, 487fr) minmax(0, 665fr);
  }
}

.step--media .step__img {
  flex: 1;
  min-height: clamp(10rem, 6.79vw + 8.64rem, 14.75rem);
}

@media (min-width: 1024px) {
  .projet-process__render .carousel {
    padding-bottom: var(--spacing-lg);
  }
}

/* Défis et apprentissages : bande violette pleine largeur
   ========================================================================== */
.projet-learn {
  padding-block: clamp(2rem, 2.86vw + 1.43rem, 4rem);
  background-color: rgba(65, 30, 248, 0.6);
  box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.15), inset 0 8px 15px 10px rgba(255, 255, 255, 0.3);
  color: var(--color-text-inverse);
  text-align: center;
}

.projet-learn__inner {
  display: grid;
  gap: var(--spacing-xl);
}
@media (min-width: 768px) {
  .projet-learn__inner {
    grid-template-columns: auto auto;
    justify-content: space-between;
    padding-inline: clamp(0rem, 9.11vw + -1.82rem, 6.38rem);
  }
}

.projet-learn__col,
.projet-learn__list {
  display: flex;
  flex-direction: column;
  gap: clamp(0.5rem, 0.8vw + 0.34rem, 1.06rem);
}

/* Produit final
   ========================================================================== */
.projet-final {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}

.projet-final__video {
  aspect-ratio: 1200/500;
}
.projet-final__video::before {
  content: "";
  position: absolute;
  inset: 0;
  background-color: rgba(65, 30, 248, 0.1);
}

.projet-final__video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.projet-final__video.is-playing {
  aspect-ratio: 16/9;
  background-color: var(--color-black);
}
.projet-final__video.is-playing::before {
  display: none;
}
.projet-final__video.is-playing img,
.projet-final__video.is-playing .projet-final__play {
  display: none;
}

.projet-final__glass {
  position: absolute;
  inset: 6.25%;
  z-index: -1;
  border-radius: 50%;
  box-shadow: inset 0 1px 2px rgba(255, 255, 255, 0.6), inset 0 -2px 6px rgba(0, 0, 0, 0.15);
}

.projet-final__play {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 1;
  display: flex;
  color: var(--color-white);
  transform: translate(-50%, -50%);
  transition: transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.projet-final__play:hover {
  transform: translate(-50%, -50%) scale(1.08);
}

/* Pied de page : autres projets + contact (_partials/_projet-footer.html)
   ========================================================================== */
.projet-more {
  display: flex;
  flex-direction: column;
  gap: clamp(1.5rem, 2.14vw + 1.07rem, 3rem);
  padding-block: clamp(1.5rem, 2.14vw + 1.07rem, 3rem) var(--spacing-lg);
}

.projet-more__head {
  display: flex;
  flex: 1;
  align-items: center;
  gap: clamp(0.75rem, 1.07vw + 0.54rem, 1.5rem);
}
.projet-more__head p {
  margin-top: 2px;
  font-weight: 400;
}

.projet-more__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 1.43vw + 0.71rem, 2rem);
}
@media (min-width: 480px) {
  .projet-more__list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .projet-more__list {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

.projet-more__link {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: clamp(0.75rem, 0.18vw + 0.71rem, 0.88rem);
  font-weight: var(--font-weight-extrabold);
  line-height: 1;
  text-align: center;
}
.projet-more__link .thumb {
  transition: transform 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.projet-more__link:hover .thumb {
  transform: translateY(-4px);
}

.projet-contact__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(1rem, 0.71vw + 0.86rem, 1.5rem);
}

.projet-contact__socials {
  display: flex;
  gap: clamp(0.75rem, 1.07vw + 0.54rem, 1.5rem);
}

.copyright {
  font-family: var(--font-secondary);
  font-size: var(--font-size-h3);
  font-weight: var(--font-weight-medium);
  line-height: 1;
  text-align: center;
}

/* ==========================================================================
   Modèle 3D interactif (ModelViewer)
   L'image (poster) reste visible jusqu'à ce que le modèle soit prêt,
   puis le canevas 3D apparaît en fondu par-dessus.
   ========================================================================== */
.model-viewer {
  background: radial-gradient(circle at 50% 45%, #3a2a8a, #110d24 75%);
}

.model-viewer__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 0.6s ease;
}
.is-ready .model-viewer__canvas {
  opacity: 1;
}

.model-viewer__poster {
  transition: opacity 0.6s ease;
}
.is-ready .model-viewer__poster {
  opacity: 0;
}

.model-viewer__progress {
  position: absolute;
  inset: auto 0 0;
  height: 3px;
  background-color: var(--color-white);
  transform: scaleX(var(--progress, 0));
  transform-origin: left;
  opacity: 0;
  transition: opacity 0.3s ease, transform 0.2s linear;
}
.is-loading .model-viewer__progress {
  opacity: 0.8;
}

.model-viewer__hint {
  position: absolute;
  inset: auto 0 clamp(0.5rem, 0.71vw + 0.36rem, 1rem);
  margin-inline: auto;
  width: -moz-fit-content;
  width: fit-content;
  padding: 6px 14px;
  border-radius: 999px;
  background-color: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(8px);
  color: var(--color-white);
  font-size: clamp(0.75rem, 0.18vw + 0.71rem, 0.88rem);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s ease;
}
.is-ready .model-viewer__hint {
  opacity: 1;
}
.is-ready.has-interacted .model-viewer__hint {
  opacity: 0;
}

/* ==========================================================================
   Lightbox : image en grand dans une superposition
   ========================================================================== */
.is-zoomable {
  cursor: zoom-in;
  transition: filter 0.3s ease;
}
.is-zoomable:hover {
  filter: brightness(1.06);
}
.is-zoomable:focus-visible {
  outline: 3px solid var(--color-primary);
  outline-offset: 3px;
}

.has-lightbox {
  overflow: hidden;
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: grid;
  grid-template-rows: minmax(0, 1fr);
  place-items: center;
  padding: clamp(3.5rem, 1.43vw + 3.21rem, 4.5rem) clamp(1rem, 7.14vw + -0.43rem, 6rem);
  background-color: rgba(10, 6, 30, 0.82);
  backdrop-filter: blur(12px);
  opacity: 0;
  transition: opacity 0.35s ease;
  touch-action: pan-y;
}
.lightbox.is-open {
  opacity: 1;
}
.lightbox[hidden] {
  display: none;
}

.lightbox__figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-sm);
  width: 100%;
  height: 100%;
  min-height: 0;
  justify-content: center;
}

.lightbox__img {
  max-width: 100%;
  min-height: 0;
  max-height: calc(100% - 40px);
  width: auto;
  height: auto;
  -o-object-fit: contain;
     object-fit: contain;
  border-radius: var(--radius-md);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}

.lightbox__caption {
  max-width: 60ch;
  color: var(--color-white);
  font-size: clamp(0.81rem, 0.27vw + 0.76rem, 1rem);
  text-align: center;
  opacity: 0.85;
}

.lightbox__count {
  position: absolute;
  top: clamp(1rem, 0.71vw + 0.86rem, 1.5rem);
  left: 50%;
  transform: translateX(-50%);
  color: var(--color-white);
  font-size: clamp(0.81rem, 0.18vw + 0.78rem, 0.94rem);
  opacity: 0.75;
}

.lightbox__btn {
  position: absolute;
  display: grid;
  place-items: center;
  width: clamp(2.5rem, 1.07vw + 2.29rem, 3.25rem);
  height: clamp(2.5rem, 1.07vw + 2.29rem, 3.25rem);
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: var(--radius-full);
  background-color: rgba(255, 255, 255, 0.12);
  backdrop-filter: blur(8px);
  color: var(--color-white);
  transition: background-color 0.2s ease, transform 0.2s ease;
}
.lightbox__btn:hover {
  background-color: rgba(255, 255, 255, 0.24);
}
.lightbox__btn:active {
  transform: scale(0.94);
}
.lightbox__btn:focus-visible {
  outline: 3px solid var(--color-white);
  outline-offset: 3px;
}
.lightbox__btn .icon--lightbox {
  width: 45%;
  height: 45%;
}

.lightbox__close {
  top: clamp(0.75rem, 1.07vw + 0.54rem, 1.5rem);
  right: clamp(0.75rem, 1.07vw + 0.54rem, 1.5rem);
}

.lightbox__prev,
.lightbox__next {
  top: 50%;
  margin-top: calc(clamp(2.5rem, 1.07vw + 2.29rem, 3.25rem) / -2);
}
.lightbox__prev:active,
.lightbox__next:active {
  transform: scale(0.94);
}

.lightbox__prev,
.lightbox__next {
  border: 0;
  background-color: transparent;
  backdrop-filter: none;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.5));
  opacity: 0.8;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.lightbox__prev:hover,
.lightbox__next:hover {
  background-color: transparent;
  opacity: 1;
}

.lightbox__prev {
  left: clamp(0.5rem, 1.43vw + 0.21rem, 1.5rem);
}
.lightbox__prev .icon--lightbox {
  transform: translateX(-8%);
}

.lightbox__next {
  right: clamp(0.5rem, 1.43vw + 0.21rem, 1.5rem);
}
.lightbox__next .icon--lightbox {
  transform: translateX(8%);
}

.lightbox__close .icon--lightbox {
  width: 60%;
  height: 60%;
}

/* ==========================================================================
   Bulle d'info au survol (Figma : « Text hover »)
   <li class="has-tooltip" data-tooltip="Blender">…</li>
   La bulle et sa pointe sont dessinées en CSS (::after et ::before).
   ========================================================================== */
.has-tooltip {
  position: relative;
  transition: opacity 0.18s ease, transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.has-tooltip .icon {
  filter: drop-shadow(0 0 0 rgba(0, 0, 0, 0));
  transition: filter 0.25s ease;
}
.has-tooltip::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 14px);
  left: 50%;
  z-index: 20;
  padding: clamp(0.38rem, 0.18vw + 0.34rem, 0.5rem) clamp(0.75rem, 0.36vw + 0.68rem, 1rem);
  border-radius: var(--radius-full);
  background: linear-gradient(180deg, #f5f4fc 0%, #ebe9f6 100%);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
  color: var(--color-black);
  font-family: var(--font-primary);
  font-size: clamp(0.75rem, 0.27vw + 0.7rem, 0.94rem);
  font-weight: var(--font-weight-bold);
  line-height: 1.2;
  white-space: nowrap;
  pointer-events: none;
}
.has-tooltip::before {
  content: "";
  position: absolute;
  bottom: calc(100% + 7px);
  left: 50%;
  z-index: 21;
  width: 18px;
  height: 18px;
  border-bottom-right-radius: 5px;
  background-color: #ebe9f6;
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
  pointer-events: none;
}
.has-tooltip::after, .has-tooltip::before {
  opacity: 0;
  transform: translate(-50%, 6px) scale(0.85);
  transform-origin: 50% 100%;
  transition: opacity 0.18s ease, transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.has-tooltip::before {
  transform: translate(-50%, 6px) scale(0.85) rotate(45deg);
  transform-origin: 50% 50%;
}
.has-tooltip:hover, .has-tooltip:focus-within {
  z-index: 30;
  transform: scale(1.1);
}
.has-tooltip:hover .icon, .has-tooltip:focus-within .icon {
  filter: drop-shadow(0 6px 2px rgba(0, 0, 0, 0.2));
}
.has-tooltip:hover::after, .has-tooltip:hover::before, .has-tooltip:focus-within::after, .has-tooltip:focus-within::before {
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
}
.has-tooltip:hover::before, .has-tooltip:focus-within::before {
  transform: translate(-50%, 0) scale(1) rotate(45deg);
}