﻿    @layer base {
      :root {
        /* Easings personnalisés disponibles sur tout le site.
           Utilisables via transition-timing-function: var(--ease-out) ou
           en arbitrary value Tailwind : ease-[var(--ease-out)]. */
        --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
        --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
        --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
      }
      /* overflow-x: clip placé sur html plutôt que body.
         Sur body, la spec CSS transforme automatiquement overflow-y: visible
         en auto dès qu'un axe est non-visible, ce qui fait de body un second
         scroll container (en plus de html) et crée un conflit avec Lenis,
         qui est attaché au window/html. Sur html, le clip reste isolé. */
      html {
        overflow-x: clip;
      }
      body {
        font-family: Supreme, sans-serif;
        color: #eef2f3;
        background-color: #0a0d12;
        -webkit-font-smoothing: antialiased;
        font-feature-settings: "salt";
      }
      .site-nav-inner {
        display: flex;
        align-items: center;
        justify-content: space-between;
        flex-wrap: wrap;
        gap: 0.75rem 1.5rem;
        padding-top: 1rem;
        padding-bottom: 1rem;
      }
      .site-nav-links {
        display: flex;
        align-items: center;
        gap: clamp(0.75rem, 2vw, 2.5rem);
      }
      .page-intro {
        padding-top: 11rem;
        padding-bottom: 4rem;
      }
      .faq-item {
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
      }
      .faq-question {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 1rem;
        padding: 1.75rem 0;
        cursor: pointer;
        list-style: none;
      }
      .faq-question::-webkit-details-marker {
        display: none;
      }
      .faq-icon {
        position: relative;
        display: block;
        flex: 0 0 1.5rem;
        width: 1.5rem;
        height: 1.5rem;
      }
      .faq-icon::before,
      .faq-icon::after {
        position: absolute;
        top: 50%;
        left: 50%;
        width: 1rem;
        height: 1px;
        background: currentColor;
        content: "";
        transform: translate(-50%, -50%);
      }
      .faq-icon::after {
        width: 1px;
        height: 1rem;
        transition: transform 200ms ease;
      }
      .faq-item[open] .faq-icon::after {
        transform: translate(-50%, -50%) scaleY(0);
      }
      .faq-answer {
        color: #c4cbcd;
      }
      @media (max-width: 767px) {
        .site-nav-links {
          order: 3;
          width: 100%;
          justify-content: space-between;
          gap: 0.5rem;
        }
        .site-nav-links a {
          font-size: 0.8rem;
        }
        .site-nav-cta {
          margin-left: auto;
        }
        .page-intro {
          padding-top: 9rem;
        }
      }
      /* Neutralise le style user-agent du <mark> (fond jaune).
         Les effets [data-highlight] mark et [data-underline-draw] mark
         ajoutent ensuite leur propre traitement quand le parent a l'attribut. */
      mark {
        background: none;
        color: inherit;
      }
      /* Masque le watermark de la lib @firecms/neat (mesh-gradient).
         La lib injecte un <a data-n="1" href="https://neat.firecms.co">NEAT</a>
         en absolute z-10000 en bas à droite. Le sélecteur reste très ciblé
         pour ne pas masquer d'autres liens. */
      a[data-n][href*="neat.firecms.co"] {
        display: none !important;
      }
      /* FOUC protection sur les reveals clip-path :
         l'élément se rend hidden dès le parsing HTML, avant même que GSAP ne
         soit initialisé. JS prend ensuite le relais pour animer vers inset 0.
         Sans ça, l'image apparaît visible une fraction de seconde puis se cache
         quand gsap.set() s'exécute, ce qui ressemble à un flash désagréable. */
      [data-curtain],
      [data-reveal]:not([data-reveal="center"]),
      [data-mask-reveal] {
        clip-path: inset(0 0 100% 0);
      }
      [data-curtain="top"] { clip-path: inset(100% 0 0 0); }
      [data-curtain="left"] { clip-path: inset(0 100% 0 0); }
      [data-curtain="right"] { clip-path: inset(0 0 0 100%); }
      [data-curtain="center"],
      [data-reveal="center"] { clip-path: inset(50% 50% 50% 50%); }
      [data-curtain="diagonal"] { clip-path: inset(0 100% 100% 0); }
      [data-reveal="top"] { clip-path: inset(100% 0 0 0); }
      /* Les fonts display Google à glyphes épais (Bagel Fat One, Rubik Wet
         Paint, Caprasimo, Dela Gothic One, Shrikhand...) ne tolèrent pas un
         leading serré en casse mixte : les descendantes (g, y, p, q) se
         chevauchent avec les ascendantes de la ligne suivante. On force un
         minimum de 1.12 sauf quand le texte est explicitement en uppercase
         (class "uppercase" ou text-transform: uppercase), cas où les
         ascendantes/descendantes sont minimes et où un leading serré reste
         propre. */
      [style*="Bagel Fat One"]:not(.uppercase):not([class*=":uppercase"]),
      [style*="Rubik Wet Paint"]:not(.uppercase):not([class*=":uppercase"]),
      [style*="Rubik Puddles"]:not(.uppercase):not([class*=":uppercase"]),
      [style*="Rubik Glitch"]:not(.uppercase):not([class*=":uppercase"]),
      [style*="Rubik Mono One"]:not(.uppercase):not([class*=":uppercase"]),
      [style*="Dela Gothic One"]:not(.uppercase):not([class*=":uppercase"]),
      [style*="Caprasimo"]:not(.uppercase):not([class*=":uppercase"]),
      [style*="Shrikhand"]:not(.uppercase):not([class*=":uppercase"]),
      [style*="Playwrite"]:not(.uppercase):not([class*=":uppercase"]),
      [style*="Monoton"]:not(.uppercase):not([class*=":uppercase"]) {
        line-height: 1.12 !important;
      }
    }

@media (max-width: 767px) {
  #hero {
    height: auto;
    min-height: 100vh;
    min-height: 100svh;
  }
  #hero .home-hero-copy {
    justify-content: flex-start;
    padding-top: 11rem;
    padding-bottom: 4rem;
  }
}

    /* Shared design system */
    /* Layout system */
/* Layout system */
.op-container {
	width: 100%;
	max-width: 1920px;
	margin-left: auto;
	margin-right: auto;
	padding-left: 1rem;
	padding-right: 1rem;
}
@media (min-width: 768px) {
	.op-container {
		padding-left: 2.25em;
		padding-right: 2.25em;
	}
}

#secteurs [data-stagger] {
	align-items: stretch;
}
#secteurs [data-stagger] > div {
	display: flex;
	flex-direction: column;
	height: 100%;
}
#secteurs [data-stagger] > div h3 {
	display: flex;
	align-items: flex-end;
	min-height: 2.9em;
	margin-bottom: 1rem;
}

/* Fluid typography */
.op-display {
	font-size: clamp(3.5rem, 8vw, 10rem);
	line-height: 0.95;
	letter-spacing: -0.03em;
	text-wrap: balance;
}
.op-heading-1 {
	font-size: clamp(2.5rem, 6vw, 7rem);
	line-height: 1.05;
	letter-spacing: -0.02em;
	text-wrap: balance;
}
.op-heading-2 {
	font-size: clamp(2rem, 4.5vw, 5rem);
	line-height: 1.1;
	letter-spacing: -0.02em;
	text-wrap: balance;
}
.op-heading-3 {
	font-size: clamp(1.75rem, 3.5vw, 3.5rem);
	line-height: 1.15;
	letter-spacing: -0.01em;
	text-wrap: balance;
}
.op-heading-4 {
	font-size: clamp(1.5rem, 2.2vw, 2.25rem);
	line-height: 1.2;
	text-wrap: balance;
}
.op-body-lg {
	font-size: clamp(1.125rem, 1.4vw, 1.375rem);
	line-height: 1.6;
	text-wrap: balance;
}
.op-body {
	font-size: clamp(1rem, 1.15vw, 1.125rem);
	line-height: 1.6;
	text-wrap: balance;
}
.op-body-sm {
	font-size: clamp(0.875rem, 1vw, 1rem);
	line-height: 1.6;
}
.op-label {
	font-size: clamp(0.625rem, 0.7vw, 0.75rem);
	line-height: 1.4;
	letter-spacing: 0.15em;
	text-transform: uppercase;
}


    /* Safety reset : certains documents générés par le LLM (ou le design
       system) posent body { overflow-x: hidden }, ce qui - par la spec CSS -
       transforme automatiquement overflow-y: visible en auto et fait de body
       un second scroll container (conflit avec Lenis attaché au window).
       On réimpose le clip horizontal sur html et on laisse body scroll-transparent. */
    html { overflow-x: clip !important; }
    body { overflow: visible !important; }

    /* Safety overflow : un titre en font-size 18vw + white-space:nowrap
       déborde la viewport et provoque un scroll horizontal global qui
       décale toute la page. On contraint chaque section à la viewport et
       on clip ce qui dépasse. Le rendu visuel intentionnel des éléments
       qui "bleed" volontairement (stickers, scotch, polaroids) reste OK
       tant qu'ils ne dépassent pas 100vw. */
    section { max-width: 100vw; }
    body > section, body > nav, body > footer, body > header {
      overflow-x: clip;
      overflow-clip-margin: 1rem;
    }

    /* Hero sticky: z-index handled by JS */

    /* Global border-radius override */
    .rounded-2xl, .rounded-xl { border-radius: 8px !important; }
    .rounded-lg { border-radius: 6px !important; }
    .rounded-full:not(button):not([data-wave-btn]) { border-radius: 8px !important; }

    /* Tilt: preserve border-radius, no transition on radius */
    [data-tilt] {
      overflow: hidden !important;
      border-radius: 8px !important;
    }
    [data-tilt] * { border-radius: inherit; }
    [data-tilt] .js-tilt-glare, [data-tilt] .js-tilt-glare-inner {
      border-radius: inherit !important;
      overflow: hidden !important;
    }

    /* Hide content until GSAP is ready - prevents FOUC.
       Désactivé en mode preview (tailwindMode=cdn) : le HTML arrive en
       streaming, les sections seraient masquées jusqu'à ce qu'elles soient
       toutes là et que GSAP init. On veut au contraire voir les sections
       apparaître progressivement. */
    body:not(.animations-ready) section,
    body:not(.animations-ready) header { opacity: 0; }


    /* Image reveal clip-path */
    [data-reveal] { overflow: hidden; }
    [data-reveal] img, [data-reveal] video { transform: scale(1.2); }

    /* Image hover - zoom on clickable cards and data-hover-img */
    [data-hover-img] { overflow: hidden; }
    [data-hover-img] img,
    a [data-reveal] img,
    a[data-reveal] img { transition: transform 0.7s cubic-bezier(0.16, 1, 0.3, 1); }
    [data-hover-img]:hover img,
    a:hover [data-reveal] img,
    a[data-reveal]:hover img { transform: scale(1.06) !important; }

    /* Custom cursor variants - visible only on links.
       Pas de transform: scale(0/1) ici : GSAP.quickTo pilote déjà transform pour
       suivre la souris (translate), s'il trouve scale(0) dans le CSS initial il
       l'intègre à sa matrice et fige le cursor à scale 0. On utilise opacity
       seule pour le show/hide ; les variants peuvent ajouter leur propre
       scale au hover via transform multiples (ce que GSAP respecte). */
    .custom-cursor {
      position: fixed;
      top: 0;
      left: 0;
      pointer-events: none;
      z-index: 99999;
      opacity: 0;
      transition: opacity 0.3s;
    }
    .custom-cursor.hovering { opacity: 1; }
    /* Le label "Voir" n'est visible que pour le variant text. Les autres
       variantes (filled, ring, dot-ring, blur) gardent le texte dans le DOM
       mais le masquent pour ne pas polluer le visuel. */
    .custom-cursor-label { display: none; }
    [data-cursor="text"] .custom-cursor-label { display: block; }

    /* Variant: filled (default) - solid circle with blend mode */
    [data-cursor="filled"] .custom-cursor,
    body:not([data-cursor]) .custom-cursor {
      width: 60px; height: 60px; border-radius: 50%;
      background: #eef2f3; mix-blend-mode: difference;
    }

    /* Variant: ring - hollow circle outline */
    [data-cursor="ring"] .custom-cursor {
      width: 50px; height: 50px; border-radius: 50%;
      border: 1.5px solid #eef2f3; background: none;
    }
    [data-cursor="ring"] .custom-cursor.hovering { transform: scale(1.4); }

    /* Variant: dot-ring - small dot + ring outline, reste discret au hover
       pour ne pas masquer le contenu du lien survolé. */
    [data-cursor="dot-ring"] .custom-cursor {
      width: 36px; height: 36px; border-radius: 50%;
      border: 1px solid #eef2f3; background: none;
    }
    [data-cursor="dot-ring"] .custom-cursor::after {
      content: ''; position: absolute; top: 50%; left: 50%;
      width: 4px; height: 4px; border-radius: 50%;
      background: #eef2f3; transform: translate(-50%, -50%);
    }

    /* Variant: text - circle with "Voir" label */
    [data-cursor="text"] .custom-cursor {
      width: 80px; height: 80px; border-radius: 50%;
      background: #eef2f3;
      display: flex; align-items: center; justify-content: center;
      font-size: 11px; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase;
      color: #0a0d12; font-family: Supreme, sans-serif;
    }

    /* Variant: blur - frosted glass circle */
    [data-cursor="blur"] .custom-cursor {
      width: 60px; height: 60px; border-radius: 50%;
      background: rgba(255,255,255,0.1);
      backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
      border: 1px solid rgba(255,255,255,0.15);
    }
    [data-cursor="blur"] .custom-cursor.hovering { transform: scale(1.3); }

    /* Magnetic button effect placeholder - JS enhanced */
    [data-magnetic] { transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1); }

    /* Nav top-bar: ne promouvoir en fixed que la nav principale, enfant direct du body.
       Les <nav> secondaires imbriquées dans un footer/section gardent leur flow normal. */
    body > nav {
      position: fixed !important;
      top: 0 !important;
      left: 0 !important;
      width: 100% !important;
      z-index: 1000 !important;
      transition: none !important;
    }

    /* Sidebar nav - backdrop sombre */
    [data-nav-backdrop] {
      position: fixed;
      inset: 0;
      z-index: 9997;
      background: rgba(0,0,0,0.5);
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.5s cubic-bezier(0.76, 0, 0.24, 1);
    }
    [data-nav-backdrop].open {
      opacity: 1;
      pointer-events: auto;
    }
    /* Sidebar nav - panneau droit par défaut, gauche si data-side="left", plein écran si data-side="full" */
    [data-nav-overlay] {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      width: min(500px, 85vw);
      z-index: 9998;
      background: var(--nav-bg, #ffffff);
      color: var(--nav-text, #1a1a1a);
      display: flex;
      flex-direction: column;
      justify-content: center;
      padding: clamp(5rem, 8vw, 7rem) clamp(3rem, 6vw, 5rem) clamp(2.5rem, 5vw, 4rem) clamp(3.5rem, 8vw, 6rem) !important;
      transform: translateX(100%);
      transition: transform 0.6s cubic-bezier(0.76, 0, 0.24, 1);
      pointer-events: none;
    }
    [data-nav-overlay][data-side="left"] {
      right: auto;
      left: 0;
      transform: translateX(-100%);
      padding: clamp(5rem, 8vw, 7rem) clamp(3.5rem, 8vw, 6rem) clamp(2.5rem, 5vw, 4rem) clamp(3rem, 6vw, 5rem) !important;
    }
    [data-nav-overlay][data-side="full"] {
      right: 0;
      left: 0;
      width: 100vw;
      padding: clamp(5rem, 10vh, 8rem) clamp(3rem, 8vw, 8rem) !important;
      transform: translateY(-100%);
    }
    [data-nav-overlay].open {
      transform: translateX(0);
      pointer-events: auto;
    }
    [data-nav-overlay][data-side="full"].open {
      transform: translateY(0);
    }
    [data-nav-overlay] a {
      font-size: clamp(1.25rem, 2vw, 1.75rem) !important;
      line-height: 1.4 !important;
    }
    /* Les spans internes des liens hébergent les animations data-text-slide
       qui règlent elles-mêmes height/line-height/overflow sur les wrappers
       de chaque lettre. On ne force rien sur ces spans pour ne pas casser
       le clip lettre par lettre. */
    [data-nav-overlay] a > span > span {
      font-size: inherit;
    }
    [data-nav-overlay] > nav,
    [data-nav-overlay] > div { padding: 0 !important; margin-left: 0 !important; margin-right: 0 !important; }
    [data-nav-overlay] a {
      display: block;
      transform: translateX(30px);
      opacity: 0;
      transition: opacity 0.3s, transform 0.3s;
      margin-bottom: 0.75rem;
    }
    [data-nav-overlay].open a {
      transform: translateX(0);
      opacity: 1;
    }
    [data-nav-overlay] a:hover {
      opacity: 0.5;
    }
    /* Burger button - top-right par défaut, gauche si data-pos="left", au centre si data-pos="center" */
    [data-nav-burger] {
      position: fixed;
      top: 24px;
      right: 24px;
      z-index: 9999;
      width: 48px;
      height: 48px;
      cursor: pointer;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      gap: 7px;
      background: #0a0d12cc;
      backdrop-filter: blur(12px);
      -webkit-backdrop-filter: blur(12px);
      color: #eef2f3;
      border: none;
      border-radius: 50%;
      padding: 0;
    }
    [data-nav-burger] span {
      display: block;
      width: 28px;
      height: 1.5px;
      background: currentColor;
      transition: transform 0.4s cubic-bezier(0.76, 0, 0.24, 1), opacity 0.3s;
      transform-origin: center;
    }
    [data-nav-burger].open span:nth-child(1) { transform: translateY(8.5px) rotate(45deg); }
    [data-nav-burger].open span:nth-child(2) { opacity: 0; }
    [data-nav-burger].open span:nth-child(3) { transform: translateY(-8.5px) rotate(-45deg); }
    [data-nav-burger][data-pos="left"] { right: auto; left: 24px; }
    [data-nav-burger][data-pos="center"] { right: auto; left: 50%; transform: translateX(-50%); }
    /* Nav logo (fixed top left par défaut, droite si data-pos="right", centre si data-pos="center") */
    [data-nav-logo] {
      position: fixed;
      top: 24px;
      left: 24px;
      z-index: 9999;
    }
    [data-nav-logo][data-pos="right"] { left: auto; right: 24px; }
    [data-nav-logo][data-pos="center"] { left: 50%; transform: translateX(-50%); }
    /* Un logo DANS une barre de nav horizontale (nav/header avec liens inline)
       doit rester dans le flux flex de la barre. Le positionnement fixe ci-dessus
       n'est destiné qu'à un logo autonome flottant sur le hero ; appliqué à un logo
       de barre, il le sort du flux et le superpose aux liens du menu. */
    nav [data-nav-logo],
    header [data-nav-logo] {
      position: static;
      top: auto;
      left: auto;
      right: auto;
    }

    /* Event slider (Swiper) - bleeding edge both sides, starts at container padding */
    [data-event-slider] { overflow: hidden; margin-left: calc(-1 * clamp(24px, 5vw, 64px)); margin-right: calc(-1 * clamp(24px, 5vw, 64px)); }
    [data-event-slider] .swiper { padding-left: clamp(24px, 5vw, 64px); }
    [data-event-slider] .swiper-slide { width: auto; height: auto; }
    [data-event-slider] .swiper-button-disabled { opacity: 0.25; cursor: default; }

    /* Nav link letter hover */
    [data-scramble] { cursor: pointer; overflow: hidden; }

    /* SplitType lines reveal */
    [data-split] .line { display: block; overflow: hidden; width: 100%; padding-bottom: 0.08em; }
    [data-split] .line-inner { display: block; will-change: transform; width: 100%; }

    /* Horizontal rule animation */
    [data-animate-line] { transform-origin: left; transform: scaleX(0); }

    /* Marquee infinite scroll */
    [data-marquee] { overflow: hidden; white-space: nowrap; }
    [data-marquee] .marquee-track {
      display: inline-flex;
      flex-wrap: nowrap;
      animation: marquee-scroll var(--marquee-duration, 20s) linear infinite;
      white-space: nowrap;
    }
    /* Garantit qu'un item avec du texte long reste sur une ligne : pas de
       retrait, pas de wrap interne. S'applique aux enfants directs du track
       ainsi qu'à leurs descendants textuels. */
    [data-marquee] .marquee-track > * {
      flex-shrink: 0;
      white-space: nowrap;
      max-width: none;
    }
    [data-marquee][data-direction="right"] .marquee-track {
      animation-direction: reverse;
    }
    [data-marquee]:hover .marquee-track {
      animation-play-state: paused;
    }
    @keyframes marquee-scroll {
      0% { transform: translateX(0); }
      100% { transform: translateX(-50%); }
    }

    /* Blurry text reveal */
    [data-blur-reveal] { filter: blur(6px); opacity: 0.5; }

    /* Text highlight on scroll */
    [data-highlight] mark {
      background: linear-gradient(to right, var(--highlight-color, #00e5c740) 50%, transparent 50%);
      background-size: 200% 100%;
      background-position: 100% 0;
      color: inherit;
      padding: 0.1em 0;
      white-space: nowrap;
    }

    /* Hand-drawn underline */
    [data-underline-draw] mark {
      position: relative;
      background: none;
      color: inherit;
      white-space: nowrap;
    }
    [data-underline-draw] mark svg {
      position: absolute;
      bottom: -4px;
      left: -2%;
      width: 104%;
      height: 10px;
      overflow: visible;
    }
    [data-underline-draw] mark svg path {
      fill: none;
      stroke: var(--underline-color, #00e5c7);
      stroke-width: 2;
      stroke-linecap: round;
    }

    /* Telescope hero */
    [data-telescope-hero] {
      position: sticky;
      top: 0;
      height: 100vh;
      overflow: hidden;
      perspective: 100vh;
    }
    [data-telescope-hero] [data-telescope-img] {
      position: absolute;
      overflow: hidden;
      border-radius: 6px;
    }
    [data-telescope-hero] [data-telescope-img] img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
    [data-telescope-hero] [data-telescope-center] {
      position: absolute;
      top: 50%;
      left: 50%;
      overflow: hidden;
      z-index: 10;
    }
    [data-telescope-hero] [data-telescope-center] img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      filter: blur(8px);
    }
    [data-telescope-hero] [data-telescope-text] {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      z-index: 5;
      white-space: nowrap;
    }
    [data-telescope-hero] [data-telescope-text="left"] { left: 50%; transform: translateY(-50%) translateX(calc(-100% - 1vw)); }
    [data-telescope-hero] [data-telescope-text="right"] { right: 50%; transform: translateY(-50%) translateX(calc(100% + 1vw)); }

    /* 3D grid */
    [data-grid-3d] { perspective: 1200px; }

    /* 3D scroll text (cylinder / tube) */
    [data-text3d] {
      position: relative;
      width: 100%;
      height: 100svh;
      perspective: 1200px;
      overflow: hidden;
    }
    [data-text3d="cylinder"] {
      display: flex;
      align-items: center;
      justify-content: center;
    }
    [data-text3d] [data-text3d-wrapper] {
      transform-style: preserve-3d;
      -webkit-transform-style: preserve-3d;
      transform-origin: center center;
      text-align: center;
      list-style: none;
      margin: 0;
      padding: 0;
      will-change: transform;
    }
    [data-text3d="cylinder"] [data-text3d-wrapper] {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }
    [data-text3d="tube"] [data-text3d-wrapper] {
      position: relative;
      width: 100%;
      height: 100%;
    }
    [data-text3d] [data-text3d-item] {
      position: absolute;
      top: 50%;
      width: 100%;
      backface-visibility: hidden;
      -webkit-backface-visibility: hidden;
      list-style: none;
      margin: 0;
      will-change: transform;
    }
    [data-text3d="cylinder"] [data-text3d-item] { left: 50%; }
    [data-text3d="tube"] [data-text3d-item] { left: 0; }

    /* Terminal hover */
    [data-terminal-hover] { cursor: pointer; font-variant-numeric: tabular-nums; }

    /* Assemble layout */
    [data-assemble] { position: relative; }

    /* Scroll traveller */
    [data-traveller] { position: fixed; z-index: 100; pointer-events: none; }

    /* Scroll zoom */
    [data-zoom-scroll] { overflow: hidden; }
    [data-zoom-scroll] img, [data-zoom-scroll] video { will-change: transform; }

    /* Stacked cards */
    [data-stack-card] { will-change: transform, filter; transform-origin: center top; }