/* ORI by Juraweal — Main CSS */

/* ─── Typographie ────────────────────────────────────────────────────────────
   Le client impose Univers Condensed (Laurent, 13/08/2026), police sous licence
   payante Linotype/Monotype dont la licence webfont est facturee au volume de
   pages vues. En attendant un arbitrage budgetaire, on utilise Roboto Condensed,
   substitut libre le plus proche disponible sur Google Fonts.

   Pour basculer sur Univers Condensed le jour ou la licence est acquise :
   remplacer la valeur des deux variables ci-dessous et le <link> Google Fonts
   dans templates/base.html.twig. Aucun autre fichier a toucher.
   ------------------------------------------------------------------------- */
:root {
  --font-display: 'Roboto Condensed', 'Arial Narrow', 'Helvetica Neue Condensed', system-ui, sans-serif;
  --font-body: 'Roboto Condensed', 'Arial Narrow', 'Helvetica Neue Condensed', system-ui, sans-serif;

  /* Hauteur de la barre de navigation, qui est en position fixe. Tout contenu
     place en tete de page doit s'en degager, sinon il passe dessous. Les hero
     s'en sortent grace a leur grand padding, mais un bandeau colle en haut,
     non. */
  --topbar-h: 82px;
}

/* Animations */
@keyframes dpfloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-18px); }
}

@keyframes dpfloat2 {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-11px); }
}

@keyframes dppulse {
  0%, 100% { opacity: .45; transform: translate(-50%, -50%) scale(1); }
  50% { opacity: .8; transform: translate(-50%, -50%) scale(1.08); }
}

@keyframes dpspin {
  to { transform: rotate(360deg); }
}

@keyframes dpspinr {
  to { transform: rotate(-360deg); }
}

@keyframes dpshimmer {
  0% { transform: translateX(-130%) skewX(-18deg); }
  100% { transform: translateX(130%) skewX(-18deg); }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* Base reset */
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
}

/* Scroll reveal initial state (set by JS) */
[data-reveal] {
  /* Elements start visible; JS will hide them and animate in */
}


/* -------------------------------------------------------------------------
   Pyramide ORI-Locus, en volume
   Quatre faces triangulaires assemblees en 3D, aux proportions de Khephren :
   6 de haut pour 9,66 de large.

   La geometrie en decoule et n'est pas a ajuster a l'oeil. Pour une base de
   9,66 et une hauteur de 6, la demi-base vaut 4,83 et l'apotheme de chaque face
   sqrt(6² + 4,83²) = 7,7025, soit 0,79736 fois la base. Chaque face s'incline
   de asin(4,83 / 7,7025) = 38,834° depuis la verticale, ce qui ramene les
   quatre sommets exactement sur l'axe, a la hauteur voulue.

   Changer une de ces valeurs sans recalculer les autres ouvre la pyramide ou la
   referme : les faces ne se rejoignent plus au sommet.
   ------------------------------------------------------------------------- */
.ori-pyramide {
  --base: 240px;
  --apotheme: calc(var(--base) * 0.79736);
  --inclinaison: 38.834deg;
  /* Hauteur reellement occupee : apotheme x cos(38,834°). */
  --hauteur: calc(var(--base) * 0.62112);

  /* Prise de vue. Ces deux valeurs ne sont pas decoratives : elles decident si
     le carre de la base se lit comme un carre.

     La distance a d'abord valu 3,4 fois la base, soit un teleobjectif : la
     perspective existait mais ne convergeait presque pas. L'inclinaison valait
     14°, ce qui revient a regarder le plan de la base en rasant, ou un carre se
     comprime en un ruban. Mesure a l'appui, les cotes opposes de la base
     tombaient alors a 1,2° du parallelisme sur toute la plage du trois-quarts.
     L'oeil y voyait un parallelogramme, et il avait raison.

     A 2,2 fois la base et 20°, le pire cas de la meme plage remonte a 8,1°.

     Ne pas monter l'inclinaison plus haut en croyant mieux faire : au-dela de
     25° la base occupe plus de surface projetee que les faces, et la silhouette
     cesse de se lire comme une pyramide pour devenir une gemme trapue. */
  --distance: 2.2;
  --prise-de-vue: 20deg;

  width: var(--base);
  height: var(--hauteur);
  perspective: calc(var(--base) * var(--distance));
  perspective-origin: 50% 50%;
  filter: drop-shadow(0 26px 36px rgba(232, 200, 122, .20));
}

.ori-pyramide--flotte { animation: dpfloat 7s ease-in-out infinite; }

/* Miniatures de panier : meme volume, mais immobile et sans halo. A cette
   taille une rotation devient un scintillement, et le halo bave sur le texte. */
.ori-pyramide--fixe { filter: none; }
.ori-pyramide--fixe .ori-pyramide__corps { animation: none; transform: rotateX(var(--prise-de-vue)) rotateY(38deg); }
.ori-pyramide--fixe .ori-pyramide__halo,
.ori-pyramide--fixe .ori-pyramide__ombre { display: none; }

.ori-pyramide__corps {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transform: rotateX(var(--prise-de-vue)) rotateY(45deg);
  animation: oriTourne 22s ease-in-out infinite;
}

.ori-pyramide__face {
  position: absolute;
  left: 0;
  bottom: 0;
  width: var(--base);
  height: var(--apotheme);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  transform-origin: 50% 100%;
  /* L'ordre compte. On oriente la face autour de l'axe, on l'ecarte d'une
     demi-base, puis on couche son sommet vers l'axe. L'inclinaison est
     positive : en CSS, rotateX positif bascule le haut vers l'arriere, donc
     vers l'interieur une fois la face poussee vers l'avant. Au signe oppose la
     pyramide s'ouvre en corolle au lieu de se refermer. */
  transform:
    rotateY(calc(var(--i) * 90deg))
    translateZ(calc(var(--base) / 2))
    rotateX(var(--inclinaison));
  /* Les faces arriere restent visibles : le quartz coule dans le PMMA est
     translucide, les masquer creuserait la pyramide. */
  backface-visibility: visible;
}

/* Quartz dans du PMMA : translucide, plus clair au sommet, dore vers la base.
   Chaque face porte sa propre intensite pour que le volume se lise a l'arret. */
.ori-pyramide__face { background: linear-gradient(180deg, rgba(196,238,255,.60), rgba(126,150,255,.22) 46%, rgba(232,200,122,.34)); }
.ori-pyramide__face[style*="--i:1"] { filter: brightness(.82); }
.ori-pyramide__face[style*="--i:2"] { filter: brightness(.68); }
.ori-pyramide__face[style*="--i:3"] { filter: brightness(.82); }

/* La base. Elle n'existait pas : le bas de la pyramide n'etait qu'un assemblage
   de quatre aretes, et l'oeil devait deviner un plan a partir de rien. Le
   materiau etant translucide, cette face se voit a travers les autres, comme
   sur la photo du produit.

   rotateX(90deg) couche le carre, puis translateY le recentre : apres la
   rotation, l'axe Y local pointe vers Z, une demi-base ramene donc le carre de
   -base..0 a -base/2..+base/2. */
.ori-pyramide__base {
  position: absolute;
  left: 0;
  bottom: 0;
  width: var(--base);
  height: var(--base);
  transform-origin: 50% 100%;
  transform: rotateX(90deg) translateY(calc(var(--base) / 2));
  /* Assourdie a dessein. On regarde la pyramide d'au-dessus : cette face est le
     sol vu au travers du quartz, pas une plaque posee devant. Rendue au meme
     eclat que les faces, elle prenait le dessus et la silhouette se lisait
     comme une gemme a huit faces. */
  background: linear-gradient(160deg, rgba(126, 150, 255, .13), rgba(232, 200, 122, .10));
  /* L'arete est ce qui fait lire un objet translucide : sans elle le carre se
     devine, avec elle il se voit. C'est aussi ce que montre la photo du
     produit, ou le PMMA accroche la lumiere sur chaque arete. */
  border: 1px solid rgba(255, 255, 255, .22);
}

.ori-pyramide__halo {
  position: absolute;
  top: 46%;
  left: 50%;
  width: calc(var(--base) * 1.35);
  height: calc(var(--base) * 1.35);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, var(--accent-soft, rgba(232,200,122,.18)) 0%, transparent 62%);
  filter: blur(20px);
  animation: dppulse 6s ease-in-out infinite;
  pointer-events: none;
}

.ori-pyramide__ombre {
  position: absolute;
  left: 50%;
  bottom: -6px;
  width: calc(var(--base) * 0.66);
  height: 18px;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(ellipse, var(--accent-soft, rgba(232,200,122,.30)), transparent 70%);
  filter: blur(7px);
  pointer-events: none;
}

/* Le tour complet est abandonne. Une pyramide vue de face est un triangle plat,
   et vue de trois quarts exactement a 45° ses deux faces visibles sont
   identiques : le tour traversait quatre fois chacun de ces angles morts, ou le
   volume cesse de se lire. On oscille donc dans la plage ou il se lit toujours,
   comme un presentoir qui se balance plutot qu'un plateau qui tourne. */
@keyframes oriTourne {
  0%, 100% { transform: rotateX(var(--prise-de-vue)) rotateY(28deg); }
  50%      { transform: rotateX(var(--prise-de-vue)) rotateY(62deg); }
}

/* Une rotation permanente gene une partie des visiteurs, et le systeme le dit :
   on s'arrete sur une vue de trois quarts, qui montre le volume sans bouger. */
@media (prefers-reduced-motion: reduce) {
  .ori-pyramide__corps { animation: none; transform: rotateX(var(--prise-de-vue)) rotateY(45deg); }
  .ori-pyramide--flotte,
  .ori-pyramide__halo { animation: none; }
}

/* -------------------------------------------------------------------------
   Barre de navigation
   Elle ne se replie pas : sur un ecran etroit le bouton de precommande sortait
   de l'ecran, coupe net. Il disparait donc en dessous de 620px — la page porte
   de toute facon son propre appel a l'action, et une barre qui deborde coute
   plus cher qu'un bouton en moins.
   ------------------------------------------------------------------------- */
.ori-topbar { max-width: 100vw; overflow-x: clip; }

/* Le sigle « ORI » n'occupe qu'un quart de la hauteur du logo : en dessous de
   50px il devient illisible. Mais a 52px sur un telephone, le diamant vient
   toucher le selecteur de langue. Compromis par palier. */
.ori-topbar__logo { height: 52px; }

@media (max-width: 520px) {
  .ori-topbar__logo { height: 42px; }
}

@media (max-width: 620px) {
  .ori-topbar__cta { display: none !important; }
}

