/*
Theme Name: Ollie Child Theme
Theme URI: https://olliewp.com
Description: A child theme based on Ollie
Author: Clément Droff
Author URI: https://www.clementdroff.fr/
Template:     ollie
Version: 1.0.0
License:      GNU General Public License v2 or later
License URI:  http://www.gnu.org/licenses/gpl-2.0.html
Tags:         blog, portfolio, entertainment, grid-layout, one-column, two-columns, three-columns, four-columns, block-patterns, block-styles, custom-logo, custom-menu, editor-style, featured-images, full-site-editing, full-width-template, rtl-language-support, style-variations, template-editing, theme-options, translation-ready, wide-blocks
Text Domain: ollie-child
*/

html {
  scrollbar-color: var(--wp--preset--color--primary) var(--wp--preset--color--main);
  scrollbar-width: thin;
}

/* scroll-behavior:smooth sans condition rendait aussi le scroll animé
   pour les personnes ayant demandé moins de mouvement (sensibilité
   vestibulaire) : header-scroll.js/section-scrubber.js passent bien
   behavior:'auto' dans ce cas, mais 'auto' hérite du CSS — donc sans ce
   media query, le scroll restait quand même animé malgré leur préférence. */
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

::-webkit-scrollbar {
  width: 10px;
}

::-webkit-scrollbar-track {
  background: var(--wp--preset--color--main);
}

::-webkit-scrollbar-thumb {
  background: var(--wp--preset--color--primary);
  border-radius: 6px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--wp--preset--color--primary);
  opacity: 0.8;
}

/* Separator PAPAPLA */
.wp-block-separator:not(.is-style-dots), .wp-block-separator.has-background:not(.is-style-dots) {
    width: 80px;
    height: 2px;
    border: none;
}


/* Règle un débordement de bordure sur les boutons "contour" */
.wp-block-button.is-style-outline .wp-block-button__link {
  outline-offset: -1px;
}

/* Animations boutons : au survol, le fond glisse depuis la droite pour
   révéler la couleur inverse. Neutralisé si prefers-reduced-motion est
   actif (le changement de couleur reste, juste sans le glissement). */

/* Bouton brand (is-style-button-brand — tous les variants --N,
   comme pour is-style-outline). Le survol animait "background-position"
   (recalcul de peinture à chaque frame, animation "non composée") : un
   pseudo-élément qui grandit via "transform: scaleX()" donne le même
   effet de balayage, mais délégué au GPU. */
.wp-block-button.is-style-button-brand .wp-block-button__link {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background-color: var(--wp--preset--color--primary);
  background-image: none;
}

.wp-block-button.is-style-button-brand .wp-block-button__link::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: var(--wp--preset--color--main);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s ease-in-out;
}

.wp-block-button.is-style-button-brand .wp-block-button__link:hover::before {
  transform: scaleX(1);
}

.wp-block-button.is-style-button-brand .wp-block-button__link:hover {
  color: var(--wp--preset--color--primary);
}

/* Bouton contour (is-style-outline — s'applique à tous les variants
   --N puisqu'ils partagent tous la classe de base is-style-outline) */
.wp-block-button.is-style-outline .wp-block-button__link {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background-image: none;
}

.wp-block-button.is-style-outline .wp-block-button__link::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: var(--wp--preset--color--base);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s ease-in-out;
}

.wp-block-button.is-style-outline .wp-block-button__link:hover::before {
  transform: scaleX(1);
}

.wp-block-button.is-style-outline .wp-block-button__link:hover {
  color: var(--wp--preset--color--main);
  /* Le contour du bouton (outline, pas border) suit "currentColor" par
     défaut dans Ollie — sans ça il devient noir en même temps que le
     texte, ce qui tranche bizarrement sur le fond blanc qui glisse. On
     le garde blanc pour qu'il se fonde proprement dans le fond au survol. */
  outline-color: var(--wp--preset--color--base);
}

/* Bouton par défaut (sans style particulier) */
.wp-block-buttons .wp-block-button__link {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background-color: var(--wp--preset--color--main);
  background-image: none;
}

.wp-block-buttons .wp-block-button__link::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: var(--wp--preset--color--base);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.5s ease-in-out;
}

.wp-block-buttons .wp-block-button__link:hover::before {
  transform: scaleX(1);
}

.wp-block-buttons .wp-block-button__link:hover {
  color: var(--wp--preset--color--main);
}

@media (prefers-reduced-motion: reduce) {
  .wp-block-button.is-style-button-brand .wp-block-button__link::before,
  .wp-block-button.is-style-outline .wp-block-button__link::before,
  .wp-block-buttons .wp-block-button__link::before {
    transition: none;
  }
}

/* Lecteurs Bandcamp intégrés en HTML brut (section Albums) : le code
   fourni par Bandcamp fixe une largeur/hauteur en dur (700x472px), qui
   déborde de l'écran sur mobile. On le rend fluide en gardant les mêmes
   proportions, sans dépasser sa taille d'origine sur grand écran. */
iframe[src*="bandcamp.com/EmbeddedPlayer"] {
  width: 100% !important;
  max-width: 700px;
  height: auto !important;
  aspect-ratio: 700 / 472;
}

@media screen and (max-width: 600px) {
  /* En suivant strictement le ratio desktop (700x472), la liste des
     pistes rétrécit avec la largeur et devient difficile à toucher.
     On donne plus de hauteur sur mobile, quitte à s'écarter du ratio —
     le lecteur Bandcamp gère son propre défilement interne si la liste
     ne tient pas entièrement. */
  iframe[src*="bandcamp.com/EmbeddedPlayer"] {
    aspect-ratio: auto;
    height: 300px !important;
  }
}

/* ---------- Façade Bandcamp (clic pour charger) ----------
   Générée par ollie_child_bandcamp_facade() (functions.php) : le lecteur
   ne se charge qu'au clic sur le bouton (bandcamp-facade.js ajoute alors
   "is-loaded"). La façade réserve exactement les mêmes dimensions que le
   lecteur — mêmes valeurs que les règles iframe ci-dessus — pour ne
   provoquer aucun décalage de mise en page au chargement. */
.bc-facade {
  position: relative;
  width: 100%;
  /* Le lecteur Bandcamp plafonne lui-même à 700px en interne (#player) :
     au-delà, l'iframe est plus large que ce que Bandcamp y affiche
     réellement, laissant une bande vide sur le côté (visible notamment
     au niveau de la scrollbar interne de la liste des pistes). */
  max-width: 700px;
  /* Aligné à gauche plutôt que centré dans sa colonne. !important
     nécessaire : la règle native de Gutenberg pour les layouts
     "contraints" (.is-layout-constrained > :where(...)) pose déjà
     margin-left/right: auto !important sur ce bloc — nos marges doivent
     faire au moins jeu égal pour l'emporter. */
  margin-left: 0 !important;
  margin-right: auto !important;
  aspect-ratio: 700 / 472;
  /* Plus sombre que le lecteur une fois chargé (bgcol=333333 dans son
     code d'intégration) : léger saut de couleur au clic, accepté pour
     mieux se fondre dans les fonds noirs du reste du site. Bordure fine
     claire en écho à .site-scrubber/.scrubber-dot, qui encadrent déjà
     leurs surfaces sombres de la même façon. */
  background: #111111;
  border: 1px solid rgba(255, 255, 255, 0.14);
}

.bc-facade iframe {
  display: none;
  width: 100% !important;
  height: 100% !important;
  /* Annule le max-width:700px de la règle iframe générique plus haut :
     ici c'est la façade qui dicte la taille, sinon le lecteur chargé
     resterait plus étroit que sa façade. */
  max-width: none;
  border: 0;
}

.bc-facade.is-loaded iframe {
  display: block;
}

.bc-facade.is-loaded .bc-facade__button {
  display: none;
}

.bc-facade__button {
  position: absolute;
  inset: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--wp--preset--color--base);
  font-family: var(--wp--preset--font-family--primary);
  font-size: 14px;
  letter-spacing: 0.04em;
}

.bc-facade__button:focus-visible {
  outline: 2px solid var(--wp--preset--color--primary);
  outline-offset: -4px;
}

.bc-facade__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--wp--preset--color--primary);
  color: var(--wp--preset--color--main);
  transition: transform 0.15s ease;
}

/* Le triangle "play" est optiquement plus centré avec un léger décalage. */
.bc-facade__icon svg {
  margin-left: 3px;
}

.bc-facade__button:hover .bc-facade__icon,
.bc-facade__button:focus-visible .bc-facade__icon {
  transform: scale(1.1);
}

@media (prefers-reduced-motion: reduce) {
  .bc-facade__icon {
    transition: none;
  }

  .bc-facade__button:hover .bc-facade__icon,
  .bc-facade__button:focus-visible .bc-facade__icon {
    transform: none;
  }
}

@media screen and (max-width: 600px) {
  /* Mêmes dimensions mobiles que le lecteur (règle iframe ci-dessus). */
  .bc-facade {
    aspect-ratio: auto;
    height: 300px;
  }
}

/*** Mise en page spécifique ***/
#concerts .wp-block-group.is-nowrap > p.has-base-font-size {
  min-width: 100px;
  flex-shrink: 0;
}

@media screen and (max-width: 600px) {
  /* Le bouton "Réserver" passe systématiquement sous la date/lieu sur
     mobile. Un simple flex-wrap ne suffit pas : il ne se déclenche que
     si la ligne déborde, or un nom de lieu court (ex: "Chantepie") ne
     déborde pas et le bouton reste collé à côté. On force donc
     l'empilement plutôt que de compter sur un débordement naturel. */
  #concerts .is-content-justification-space-between {
    flex-direction: column;
    align-items: flex-start;
  }

  /* Date + lieu : sur desktop ils sont côte à côte (date à largeur fixe
     pour l'alignement des colonnes). Sur mobile cette largeur réservée
     laisse un vide entre la date et le lieu — on empile les deux à la
     place, sans largeur imposée. */
  #concerts .wp-block-group.is-nowrap {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }

  #concerts .wp-block-group.is-nowrap > p.has-base-font-size {
    min-width: 0;
  }

  /* Un peu plus de respiration entre deux concerts, pour bien les
     distinguer en scrollant vite. */
  #concerts .is-content-justification-space-between {
    margin-bottom: var(--wp--preset--spacing--small);
  }
}

.wp-block-navigation__responsive-container-close svg, .wp-block-navigation__responsive-container-open svg {
  height: 48px;
  width: 48px;
}

/* ---------- Player de navigation entre sections (home uniquement) ----------
   Généré par section-scrubber.js à partir des blocs marqués ".nav-section"
   (ancre HTML + classe "nav-label-XXX" pour le libellé). Les couleurs
   viennent des presets du thème (FSE) plutôt que d'être codées en dur. */

:root {
  --scrubber-height: 64px;
}

/* Le player est fixe par-dessus le bas de l'écran : sur des sections en
   100vh, son contenu (souvent aligné en bas) se retrouvait caché derrière.
   On réduit la hauteur utile de chaque section de la hauteur du player,
   sans toucher aux paddings/marges réglés dans le FSE. */
body.home .nav-section,
/* Cas de la section Intro : le "min-height:100vh" n'est pas sur le bloc
   qui porte l'ancre nav-section, mais sur le bloc vidéo à l'intérieur. */
body.home .nav-section .video-bg-section {
  /* 100vh correspond à la hauteur du viewport quand la barre d'adresse
     mobile est cachée — au chargement elle est visible, donc l'espace
     réel est plus petit et le bas du contenu (ex: la fin de la tagline)
     se retrouvait caché sous le player. 100dvh s'ajuste en temps réel à
     l'espace réellement visible ; on garde 100vh en repli pour les
     navigateurs qui ne connaissent pas encore dvh (règle ignorée sinon). */
  min-height: calc(100vh - var(--scrubber-height)) !important;
  min-height: calc(100dvh - var(--scrubber-height)) !important;
}

/* Connecté, la barre d'admin WP prend aussi de la place en haut de
   l'écran (32px, 46px sous 782px de large comme WordPress lui-même) —
   sans ça, le calcul ci-dessus ne suffit plus et le bas du contenu
   repasse sous le player, comme avant le fix 100dvh. Même logique que
   le décalage du header transparent un peu plus haut dans ce fichier. */
body.admin-bar.home .nav-section,
body.admin-bar.home .nav-section .video-bg-section {
  min-height: calc(100vh - var(--scrubber-height) - 32px) !important;
  min-height: calc(100dvh - var(--scrubber-height) - 32px) !important;
}

@media screen and (max-width: 782px) {
  body.admin-bar.home .nav-section,
  body.admin-bar.home .nav-section .video-bg-section {
    min-height: calc(100vh - var(--scrubber-height) - 46px) !important;
    min-height: calc(100dvh - var(--scrubber-height) - 46px) !important;
  }
}

.site-scrubber {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 200;
  height: var(--scrubber-height);
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 0 24px;
  background: rgba(0, 0, 0, 0.86);
  backdrop-filter: blur(10px);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  color: var(--wp--preset--color--base);
  font-family: var(--wp--preset--font-family--primary);
  /* position:fixed + backdrop-filter sur un élément ajouté dynamiquement en
     JS ne se peint parfois pas sur mobile tant qu'aucun repaint n'a eu
     lieu (d'où le besoin de scroller pour le voir apparaître). Forcer son
     propre calque graphique dès la création règle ce souci. */
  transform: translateZ(0);
}

.scrubber-now {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 140px;
  font-family: var(--wp--preset--font-family--monospace, monospace);
}

.scrubber-idx {
  font-size: 15px;
  font-variant-numeric: tabular-nums;
  color: var(--wp--preset--color--primary);
}

.scrubber-total {
  font-size: 11px;
  /* 0.4 ne passait pas le contraste minimum (3,77:1, sous les 4,5:1
     requis pour du texte) — 0.5 remonte à ~5:1. */
  color: rgba(255, 255, 255, 0.5);
  font-variant-numeric: tabular-nums;
}

.scrubber-label {
  font-family: var(--wp--preset--font-family--primary);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.scrubber-track-wrap {
  position: relative;
  flex: 1;
  height: 32px;
  display: flex;
  align-items: center;
}

.scrubber-track {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: rgba(255, 255, 255, 0.14);
  border-radius: 2px;
}

.scrubber-fill {
  position: absolute;
  left: 0;
  height: 2px;
  /* Largeur pleine + "transform: scaleX()" plutôt qu'animer "width" :
     réévalué à chaque scroll, "width" force un recalcul de mise en page à
     chaque frame (animation "non composée"), scaleX() est délégué au GPU. */
  width: 100%;
  transform: scaleX(0);
  transform-origin: left;
  background: var(--wp--preset--color--primary);
  border-radius: 2px;
  transition: transform 0.08s linear;
}

.scrubber-ticks {
  position: relative;
  width: 100%;
  display: flex;
  justify-content: space-between;
}

.scrubber-tick {
  position: relative;
  appearance: none;
  border: none;
  background: none;
  padding: 16px;
  margin: -16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* appearance:none supprime aussi l'anneau de focus par défaut du bouton :
   sans ceci, un utilisateur au clavier ne voit pas quel point est
   sélectionné. */
.scrubber-tick:focus-visible {
  outline: 2px solid var(--wp--preset--color--primary);
  outline-offset: 2px;
  border-radius: 4px;
}

.scrubber-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--wp--preset--color--main);
  /* 0.28 ne passait pas le contraste minimum pour les contours d'éléments
     d'interface (2,40:1, sous les 3:1 requis) — 0.4 remonte à ~3,3:1. */
  border: 2px solid rgba(255, 255, 255, 0.4);
  /* Seul transform est animé (accéléré matériellement) : background et
     border-color ne le sont pas ("animation non composée" signalée par
     PageSpeed). Sur un point de 8px, le basculement instantané de
     couleur est imperceptible ; le grossissement reste fluide. */
  transition: transform 0.15s ease;
}

.scrubber-tick.is-active .scrubber-dot {
  background: var(--wp--preset--color--primary);
  border-color: var(--wp--preset--color--primary);
  transform: scale(1.25);
}

.scrubber-tick.is-passed .scrubber-dot {
  border: 1px solid var(--wp--preset--color--primary);
}

.scrubber-tip {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translate(-50%, 4px);
  margin-bottom: 8px;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--wp--preset--color--main);
  background: var(--wp--preset--color--primary);
  padding: 4px 8px;
  border-radius: 4px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.scrubber-tick:hover .scrubber-tip,
.scrubber-tick:focus-visible .scrubber-tip {
  opacity: 1;
  transform: translate(-50%, 0);
}

.scrubber-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  justify-content: flex-end;
}

.scrubber-counter {
  font-family: var(--wp--preset--font-family--monospace, monospace);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.55);
  width: 4ch;
  text-align: right;
}

.scrubber-eq {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 16px;
}

.scrubber-eq span {
  width: 3px;
  border-radius: 1px;
  background: var(--wp--preset--color--primary);
  /* Hauteur fixe + "transform: scaleY()" plutôt qu'animer "height" : la
     hauteur déclenche un recalcul de mise en page à chaque frame (animation
     "non composée", coûteux), scaleY() est délégué au GPU. */
  height: 100%;
  transform: scaleY(0.3);
  transform-origin: bottom;
  animation: scrubber-eq-idle 1.6s ease-in-out infinite;
}

.scrubber-eq span:nth-child(1) { animation-delay: -1.1s; }
.scrubber-eq span:nth-child(2) { animation-delay: -0.4s; }
.scrubber-eq span:nth-child(3) { animation-delay: -0.9s; }
.scrubber-eq span:nth-child(4) { animation-delay: -0.2s; }

.scrubber-eq.is-boost span {
  animation-name: scrubber-eq-boost;
  animation-duration: 0.5s;
}

@keyframes scrubber-eq-idle {
  0%, 100% { transform: scaleY(0.2); }
  50% { transform: scaleY(0.55); }
}

@keyframes scrubber-eq-boost {
  0%, 100% { transform: scaleY(0.25); }
  50% { transform: scaleY(1); }
}

@media (prefers-reduced-motion: reduce) {
  .scrubber-eq span { animation: none; transform: scaleY(0.4); }
}

@media screen and (max-width: 640px) {
  .scrubber-label { display: none; }
  .site-scrubber { padding: 0 16px; gap: 14px; }
  /* Le libellé disparaît déjà : plus besoin de réserver 140px, ça libère
     de la place pour la piste de progression sur petit écran. */
  .scrubber-now { min-width: auto; gap: 4px; }
}

@media screen and (max-width: 380px) {
  .scrubber-idx { font-size: 13px; }
  .scrubber-total { font-size: 10px; }
  .site-scrubber { gap: 10px; padding: 0 12px; }
}

/* ---------- Reveal au scroll ----------
   Généré par reveal.js : ajoute "is-visible" quand un bloc marqué
   ".reveal-section" entre dans l'écran (une fois, pas de va-et-vient).
   Fondu + léger glissement vers le haut, désactivé si l'utilisateur a
   demandé moins d'animations. */
.reveal-section,
.reveal-item {
  opacity: 0;
  transform: translateY(28px);
}

.reveal-section.is-visible,
.reveal-item.is-visible {
  opacity: 1;
  transform: none;
  /* La transition est ici, pas sur l'état caché ci-dessus : ".reveal-item"
     est ajouté en JS après le premier affichage (contrairement à
     ".reveal-section", déjà présent dans le HTML). Si la transition était
     sur l'état caché, ce simple ajout de classe animerait un passage
     "visible -> caché" parasite (fade out) juste avant le vrai fade in. */
  transition: opacity 0.6s ease, transform 0.6s ease;
}

/* reveal.js ajoute cette classe quand une ".reveal-section" contient
   plusieurs blocs : chaque enfant devient sa propre cible ("reveal-item")
   et le conteneur lui-même n'a plus besoin d'être caché/révélé. */
.reveal-group {
  opacity: 1;
  transform: none;
  transition: none;
}

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

/* Ollie charge style.css comme feuille de style de l'éditeur (add_editor_style).
   reveal.js ne tourne que côté site public, donc sans cette règle un bloc
   ".reveal-section" reste invisible en permanence dans l'admin (jamais de
   scroll réel pour déclencher l'IntersectionObserver). */
.editor-styles-wrapper .reveal-section,
.editor-styles-wrapper .reveal-item {
  opacity: 1;
  transform: none;
  transition: none;
}

/* ---------- Titres qui se lèvent depuis un masque ----------
   Généré par text-reveal.js : ".reveal-heading" découpe le texte en mots
   (ou en lettres avec le modificateur "reveal-heading--letters") et
   révèle chaque unité au passage à l'écran, une fois. */
.reveal-heading__mask {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
}

.reveal-heading__unit {
  display: inline-block;
  transform: translateY(115%);
  transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(var(--i) * 45ms);
}

.reveal-heading--letters .reveal-heading__unit {
  transition-delay: calc(var(--i) * 40ms);
}

.reveal-heading.is-visible .reveal-heading__unit {
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .reveal-heading__unit {
    transform: none;
    transition: none;
  }
}

/* Même raison que pour .reveal-section : text-reveal.js ne tourne pas
   dans l'éditeur, donc sans ça le texte resterait caché en permanence
   dans le back-office. */
.editor-styles-wrapper .reveal-heading__unit {
  transform: none;
  transition: none;
}

/* ---------- Logo/SVG qui apparaît lettre par lettre ----------
   Généré par svg-reveal.js : ".reveal-svg" sur la balise <svg> (collée en
   HTML personnalisé) fait apparaître chaque <path> l'un après l'autre au
   passage à l'écran, une fois. Pour le logo papapla, un <path> = une
   lettre. */
.reveal-svg path {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.5s ease, transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(var(--i) * 60ms);
}

.reveal-svg.is-visible path {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .reveal-svg path {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

.editor-styles-wrapper .reveal-svg path {
  opacity: 1;
  transform: none;
  transition: none;
}

/* Taille du logo papapla collé en SVG inline. Le SVG n'a pas de
   width/height propre une fois inliné (il prend une taille par défaut du
   navigateur), donc on la fixe ici. Change juste la valeur de "width" pour
   ajuster la taille — "height: auto" garde les proportions. */
.papapla-logo-svg {
  width: 600px;
  max-width: 100%;
  height: auto;
}

@media (max-width: 782px) {
  .papapla-logo-svg {
    width: 400px;
  }
}

@media (max-width: 600px) {
  .papapla-logo-svg {
    width: 200px;
  }
}

/* La grille garde ses colonnes définies même quand l'une d'elles est
   masquée via "ollie-hide-on-mobile" (masquer un enfant ne change pas la
   structure de la grille) : on force donc une seule colonne pleine
   largeur au même seuil que ce masquage, pour que la colonne restante
   (logo + texte) récupère toute la largeur. */
@media (max-width: 781px) {
  .hero-grid {
    grid-template-columns: 1fr;
  }
}

/* Réduit le tagline sur mobile pour que chaque mot ("SLOW-", "DREAM-"...)
   tienne sur sa propre ligne sans être coupé en plein milieu.
   !important nécessaire : la classe "has-base-font-size" posée par les
   Global Styles WordPress arrive après ce fichier dans la cascade et
   l'emporte sinon, à spécificité égale. */
@media (max-width: 600px) {
  .hero-tagline {
    font-size: 13px !important;
  }
}