/* ==========================================================================
   INVESTORAMA GROUP — Components v2
   Reworked: generous spacing, softer geometry, duotone icon chips,
   redesigned info boxes, full-bleed hero with a straddling play button.

   Standalone — does NOT load components.css. v1 stays untouched for comparison.
   Depends on tokens.css + base.css only.
   ========================================================================== */

:root {
  /* --- v2 additive tokens (no v1 override) --- */
  --ivr-radius-card: 12px;
  --ivr-radius-chip: 10px;
  --ivr-radius-pill: 999px;
  /* buttons and eyebrows: tight radius, not pill */
  --ivr-radius-btn: 5px;
  --ivr-radius-eyebrow: 6px;

  /* card breathing room — the main complaint about v1 */
  --ivr-card-pad: clamp(1.75rem, 1.1rem + 2.4vw, 2.75rem);
  --ivr-box-pad: clamp(1.5rem, 1rem + 1.9vw, 2.25rem);
  --ivr-grid-gap-v2: clamp(1.5rem, 1rem + 2.2vw, 2.5rem);

  /* icon sizing */
  --ivr-icon-sm: 1.125rem;
  --ivr-icon-md: 1.375rem;
  --ivr-icon-lg: 1.75rem;
  --ivr-icon-xl: 2.25rem;

  /* duotone control — inherits into <use> shadow trees */
  --ivr-icon-dt-fill: currentColor;
  --ivr-icon-dt-opacity: 0.22;

  --ivr-shadow-card: 0 1px 2px rgb(19 24 32 / 0.04), 0 8px 24px -12px rgb(19 24 32 / 0.10);
  --ivr-shadow-card-hover: 0 2px 4px rgb(39 78 155 / 0.06), 0 20px 44px -16px rgb(39 78 155 / 0.28);
}

/* --------------------------------------------------------------------------
   ICONS
   -------------------------------------------------------------------------- */
.ivr-icon {
  inline-size: var(--ivr-icon-md);
  block-size: var(--ivr-icon-md);
  flex: none;
}

.ivr-icon--sm {
  inline-size: var(--ivr-icon-sm);
  block-size: var(--ivr-icon-sm);
}

.ivr-icon--lg {
  inline-size: var(--ivr-icon-lg);
  block-size: var(--ivr-icon-lg);
}

.ivr-icon--xl {
  inline-size: var(--ivr-icon-xl);
  block-size: var(--ivr-icon-xl);
}

/* a stronger duotone read for large feature icons */
.ivr-icon--duo-strong {
  --ivr-icon-dt-opacity: 0.32;
}

/* two genuinely different colours rather than one colour at two opacities */
.ivr-icon--duo-split {
  --ivr-icon-dt-fill: var(--ivr-blue-400);
  --ivr-icon-dt-opacity: 0.55;
}

/* mirror directional icons in RTL */
[dir="rtl"] .ivr-icon--flip {
  transform: scaleX(-1);
}

/* En RTL, les flèches (arrows) directionnelles pointent naturellement à
   droite dans le sprite → on les flip pour qu'elles suivent le sens de
   lecture arabe. On limite au sprite ARROW ; les CHEVRONS (drawer next/
   back notamment) sont gérés par leurs propres règles scoping
   (`.ivr-drawer__item .ivr-icon`, `.ivr-drawer__back .ivr-icon`, cf.
   sections.css) — cumuler `scale` là-bas + `transform` ici double-flip
   et annule l'effet. */
/* Spécificité zéro via `:where(...)` : cette règle s'applique aux flèches
   arrow-right/arrow-up-right en RTL, MAIS toute règle plus spécifique
   (drawer, carousel — cf. sections.css) la remplace sans effort. Sans
   ça, le carousel voyait ses deux flèches pointer dans le même sens. */
:where([dir="rtl"]) :where(svg:has(use[href="#i-arrow-right"]), svg:has(use[href="#i-arrow-up-right"])) {
  transform: scaleX(-1);
}

/* --------------------------------------------------------------------------
   ICON CHIP — tinted rounded square holding a duotone icon
   -------------------------------------------------------------------------- */
.ivr-chip {
  display: grid;
  place-items: center;
  inline-size: 3.5rem;
  block-size: 3.5rem;
  border-radius: var(--ivr-radius-chip);
  background-color: var(--ivr-blue-50);
  color: var(--ivr-blue-600);
  flex: none;
  transition:
    background-color var(--ivr-duration) var(--ivr-ease),
    color var(--ivr-duration) var(--ivr-ease),
    transform var(--ivr-duration) var(--ivr-ease-out);
}

.ivr-chip--sm {
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border-radius: 8px;
}

.ivr-chip--lg {
  inline-size: 4.25rem;
  block-size: 4.25rem;
  border-radius: 13px;
}

.ivr-chip--round {
  border-radius: var(--ivr-radius-pill);
}

.ivr-chip--solid {
  background-color: var(--ivr-blue-600);
  color: var(--ivr-gray-0);
  --ivr-icon-dt-opacity: 0.38;
}

.ivr-chip--inverse {
  background-color: rgb(255 255 255 / 0.10);
  color: var(--ivr-gray-0);
}

/* --------------------------------------------------------------------------
   CARD v2 — no top rule; the chip carries the brand instead
   -------------------------------------------------------------------------- */
.ivr-cardv2 {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--ivr-space-5);
  padding: var(--ivr-card-pad);
  background-color: var(--ivr-surface);
  border: var(--ivr-rule) solid var(--ivr-border-subtle);
  border-radius: var(--ivr-radius-card);
  box-shadow: var(--ivr-shadow-card);
  overflow: hidden;
  isolation: isolate;
  transition:
    border-color var(--ivr-duration) var(--ivr-ease),
    box-shadow var(--ivr-duration) var(--ivr-ease),
    transform var(--ivr-duration) var(--ivr-ease-out);
}

/* soft brand wash that fades up from the bottom on hover */
.ivr-cardv2::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, transparent 35%, var(--ivr-blue-50) 100%);
  opacity: 0;
  transition: opacity var(--ivr-duration-slow) var(--ivr-ease);
}

.ivr-cardv2:hover {
  border-color: var(--ivr-blue-150);
  box-shadow: var(--ivr-shadow-card-hover);
  transform: translateY(-4px);
}

.ivr-cardv2:hover::after {
  opacity: 1;
}

.ivr-cardv2:hover .ivr-chip {
  background-color: var(--ivr-blue-600);
  color: var(--ivr-gray-0);
  --ivr-icon-dt-opacity: 0.38;
  transform: scale(1.05);
}

.ivr-cardv2__title {
  font-size: var(--ivr-text-lg);
  font-weight: var(--ivr-weight-semibold);
  letter-spacing: var(--ivr-tracking-tight);
}

.ivr-cardv2__text {
  font-size: var(--ivr-text-sm);
  line-height: var(--ivr-leading-relaxed);
  color: var(--ivr-text-muted);
}

.ivr-cardv2__foot {
  margin-block-start: auto;
  padding-block-start: var(--ivr-space-6);
}

/* whole-card link */
.ivr-cardv2__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* subsidiary variant: adds a capital badge */
.ivr-cardv2__badge {
  display: inline-flex;
  align-items: center;
  gap: var(--ivr-space-2);
  padding: var(--ivr-space-1) var(--ivr-space-3);
  font-size: var(--ivr-text-2xs);
  font-weight: var(--ivr-weight-semibold);
  letter-spacing: var(--ivr-tracking-wide);
  text-transform: uppercase;
  color: var(--ivr-blue-700);
  background-color: var(--ivr-blue-50);
  border-radius: var(--ivr-radius-pill);
}

/* --------------------------------------------------------------------------
   INFO BOX v2 — soft tint, ring, icon chip, real padding
   -------------------------------------------------------------------------- */
.ivr-box {
  --ivr-box-tint: var(--ivr-blue-50);
  --ivr-box-ring: var(--ivr-blue-150);
  --ivr-box-accent: var(--ivr-blue-600);

  display: flex;
  gap: var(--ivr-space-5);
  padding: var(--ivr-box-pad);
  background-color: var(--ivr-box-tint);
  border: var(--ivr-rule) solid var(--ivr-box-ring);
  border-radius: var(--ivr-radius-card);
}

.ivr-box__icon {
  display: grid;
  place-items: center;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border-radius: 8px;
  background-color: var(--ivr-surface);
  color: var(--ivr-box-accent);
  flex: none;
  box-shadow: var(--ivr-shadow-xs);
}

.ivr-box__body {
  display: flex;
  flex-direction: column;
  gap: var(--ivr-space-2);
}

.ivr-box__title {
  font-size: var(--ivr-text-base);
  font-weight: var(--ivr-weight-semibold);
  letter-spacing: var(--ivr-tracking-tight);
  color: var(--ivr-text);
}

.ivr-box__text {
  font-size: var(--ivr-text-sm);
  line-height: var(--ivr-leading-relaxed);
  color: var(--ivr-text-muted);
}

.ivr-box__text>a {
  font-weight: var(--ivr-weight-medium);
}

.ivr-box--note {
  --ivr-box-tint: var(--ivr-gray-50);
  --ivr-box-ring: var(--ivr-border-subtle);
  --ivr-box-accent: var(--ivr-gray-600);
}

.ivr-box--warning {
  --ivr-box-tint: var(--ivr-warning-bg);
  --ivr-box-ring: #f0dcb4;
  --ivr-box-accent: var(--ivr-warning);
}

.ivr-box--success {
  --ivr-box-tint: var(--ivr-success-bg);
  --ivr-box-ring: #c3e2d2;
  --ivr-box-accent: var(--ivr-success);
}

.ivr-box--danger {
  --ivr-box-tint: var(--ivr-danger-bg);
  --ivr-box-ring: #eec9c9;
  --ivr-box-accent: var(--ivr-danger);
}

/* emphasis version — deep blue, used for the "Réclamation" CTA */
.ivr-box--brand {
  --ivr-box-tint: var(--ivr-blue-900);
  --ivr-box-ring: transparent;
  --ivr-box-accent: var(--ivr-blue-900);
  align-items: center;
  flex-wrap: wrap;
  padding: clamp(1.75rem, 1.1rem + 2.4vw, 3rem);
}

.ivr-box--brand .ivr-box__title {
  color: var(--ivr-gray-0);
  font-size: var(--ivr-text-lg);
}

.ivr-box--brand .ivr-box__text {
  color: var(--ivr-text-inverse-muted);
}

.ivr-box--brand .ivr-box__icon {
  background-color: rgb(255 255 255 / 0.12);
  color: var(--ivr-gray-0);
  box-shadow: none;
}

.ivr-box--brand .ivr-box__body {
  flex: 1 1 22rem;
}

/* --------------------------------------------------------------------------
   STAT v2 — icon + oversized figure, no hard divider
   -------------------------------------------------------------------------- */
.ivr-statv2 {
  display: flex;
  flex-direction: column;
  gap: var(--ivr-space-4);
  padding: var(--ivr-space-8) var(--ivr-space-6) var(--ivr-space-8) 0;
}

.ivr-statv2__icon {
  color: var(--ivr-blue-500);
}

.ivr-statv2__value {
  font-size: var(--ivr-text-counter);
  font-weight: var(--ivr-weight-semibold);
  line-height: var(--ivr-leading-none);
  letter-spacing: var(--ivr-tracking-tighter);
  font-variant-numeric: tabular-nums;
  color: var(--ivr-text);
}

.ivr-statv2__value em {
  font-style: normal;
  color: var(--ivr-blue-600);
}

.ivr-statv2__label {
  font-size: var(--ivr-text-sm);
  line-height: var(--ivr-leading-snug);
  color: var(--ivr-text-muted);
  max-inline-size: 24ch;
}

.ivr-statv2__rule {
  inline-size: 2.5rem;
  block-size: var(--ivr-rule-accent);
  background-color: var(--ivr-blue-600);
  border-radius: var(--ivr-radius-pill);
}

.ivr-section--inverse .ivr-statv2__value {
  color: var(--ivr-gray-0);
}

.ivr-section--inverse .ivr-statv2__value em {
  color: var(--ivr-blue-300);
}

.ivr-section--inverse .ivr-statv2__label {
  color: var(--ivr-text-inverse-muted);
}

.ivr-section--inverse .ivr-statv2__icon {
  color: var(--ivr-blue-300);
}

.ivr-section--inverse .ivr-statv2__rule {
  background-color: var(--ivr-blue-300);
}

/* --------------------------------------------------------------------------
   BUTTONS v2 — taller, pill-adjacent, icon-aware
   -------------------------------------------------------------------------- */
.ivr-btnv2 {
  /* fixed height keeps every button in a row aligned regardless of icon or size */
  --ivr-btn-h: 3.5rem;
  --ivr-btn-inset: 0.3125rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ivr-space-3);
  --ivr-btn-pad-i: var(--ivr-space-7, 1.75rem);
  min-block-size: var(--ivr-btn-h);
  padding: var(--ivr-space-2) var(--ivr-btn-pad-i);
  font-size: 0.9375rem;
  font-weight: var(--ivr-weight-semibold);
  letter-spacing: var(--ivr-tracking-normal);
  line-height: var(--ivr-leading-snug);
  text-decoration: none;
  border: var(--ivr-rule) solid transparent;
  border-radius: var(--ivr-radius-btn);
  cursor: pointer;
  transition:
    background-color var(--ivr-duration-fast) var(--ivr-ease),
    border-color var(--ivr-duration-fast) var(--ivr-ease),
    color var(--ivr-duration-fast) var(--ivr-ease),
    box-shadow var(--ivr-duration) var(--ivr-ease),
    transform var(--ivr-duration-fast) var(--ivr-ease);
}

.ivr-btnv2:active {
  transform: translateY(1px);
}

/* Trailing icon in its own block, pinned to the trailing edge.
   The block is absolutely positioned and the button reserves room for it with
   padding — so the block never drifts when the label length changes, and the
   two radii stay concentric (inner = outer - inset). */
.ivr-btnv2--block {
  /* absolutely-positioned children resolve against the PADDING box, so the
     border has to come out of the slot size too — otherwise the inset reads
     4px on the sides and 3px top/bottom. */
  --ivr-btn-slot: calc(var(--ivr-btn-h) - (var(--ivr-btn-inset) * 2) - (var(--ivr-rule) * 2));
  /* Concentrique avec la courbe INTERIEURE du bouton : exterieur - bordure -
     retrait. Le plancher a 2px est indispensable depuis que le rayon du bouton
     est descendu a 5px : le calcul tombe alors en negatif, et un rayon negatif
     est ramene a 0 — le bloc fleche redeviendrait un carre net. */
  --ivr-btn-slot-radius: max(2px,
      calc(var(--ivr-radius-btn) - var(--ivr-rule) - var(--ivr-btn-inset)));
  position: relative;
  justify-content: flex-start;
  padding-inline: var(--ivr-btn-pad-i) calc(var(--ivr-btn-slot) + var(--ivr-btn-inset) + var(--ivr-space-4));
}

.ivr-btnv2__slot {
  position: absolute;
  inset-inline-end: var(--ivr-btn-inset);
  inset-block-start: 50%;
  translate: 0 -50%;
  display: grid;
  place-items: center;
  inline-size: var(--ivr-btn-slot);
  block-size: var(--ivr-btn-slot);
  border-radius: var(--ivr-btn-slot-radius);
  background-color: var(--ivr-blue-300);
  color: var(--ivr-blue-900);
  transition: background-color var(--ivr-duration-fast) var(--ivr-ease);
}

.ivr-btnv2--block:hover .ivr-btnv2__slot {
  background-color: var(--ivr-blue-200);
}

/* on a dark surface the block inverts to white */
.ivr-btnv2--inverse .ivr-btnv2__slot {
  background-color: var(--ivr-gray-0);
  color: var(--ivr-blue-800);
}

/* blue-50 was almost invisible on a white button */
.ivr-btnv2--outline .ivr-btnv2__slot {
  background-color: var(--ivr-blue-100);
  color: var(--ivr-blue-700);
}

.ivr-btnv2--outline:hover .ivr-btnv2__slot {
  background-color: var(--ivr-blue-150);
}

/* ---- alternate slot treatments ------------------------------------------ */

/* deep: the block goes darker than the button instead of lighter */
.ivr-btnv2--slot-deep .ivr-btnv2__slot {
  background-color: var(--ivr-blue-800);
  color: var(--ivr-gray-0);
}

.ivr-btnv2--slot-deep:hover .ivr-btnv2__slot {
  background-color: var(--ivr-blue-900);
}

/* ghost: a translucent wash of the button's own colour, no hard edge */
.ivr-btnv2--slot-ghost .ivr-btnv2__slot {
  background-color: rgb(255 255 255 / 0.16);
  color: var(--ivr-gray-0);
}

.ivr-btnv2--slot-ghost:hover .ivr-btnv2__slot {
  background-color: rgb(255 255 255 / 0.26);
}

/* bare: no block at all, just the arrow held at the trailing edge */
.ivr-btnv2--slot-bare .ivr-btnv2__slot {
  background-color: transparent;
  color: currentColor;
}

/* ---- variant A : arrow loop -------------------------------------------
   The arrow exits through the trailing edge while an identical one enters
   from the leading edge. Both icons share one grid cell; only the second is
   pre-offset. --ivr-loop-dir flips the travel direction for RTL.
   ---------------------------------------------------------------------- */
.ivr-btnv2--loop {
  --ivr-loop-dir: 1;
}

[dir="rtl"] .ivr-btnv2--loop {
  --ivr-loop-dir: -1;
}

.ivr-btnv2--loop .ivr-btnv2__slot {
  overflow: hidden;
}

/* Qualified with .ivr-icon on purpose: `.ivr-btnv2 .ivr-icon` further down
   declares `transition: transform` at equal specificity and would otherwise
   win, killing the transition and making the two arrows swap instantly —
   which, since they are identical, looks like nothing happening at all. */
.ivr-btnv2--loop .ivr-btnv2__slot>.ivr-icon {
  grid-area: 1 / 1;
  transition: translate var(--ivr-duration-slow) var(--ivr-ease-out);
}

/* the incoming clone waits outside the leading edge */
.ivr-btnv2--loop .ivr-btnv2__slot>.ivr-icon:nth-child(2) {
  translate: calc(-180% * var(--ivr-loop-dir)) 0;
}

.ivr-btnv2--loop:hover .ivr-btnv2__slot>.ivr-icon:nth-child(1) {
  translate: calc(180% * var(--ivr-loop-dir)) 0;
}

.ivr-btnv2--loop:hover .ivr-btnv2__slot>.ivr-icon:nth-child(2) {
  translate: 0 0;
}

/* ---- variant B : morphing fill ----------------------------------------
   The icon does not move. Its block grows out of its own corner until it
   becomes the whole button. Animating the four inset longhands (rather than
   width) keeps the interpolation on plain lengths, so it stays smooth.
   ---------------------------------------------------------------------- */
.ivr-btnv2--morph {
  isolation: isolate;
}

/* the visible block is the pseudo-element, so the slot itself goes clear */
.ivr-btnv2--morph .ivr-btnv2__slot,
.ivr-btnv2--morph:hover .ivr-btnv2__slot {
  background-color: transparent;
}

.ivr-btnv2--morph::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset-block: var(--ivr-btn-inset);
  inset-inline-end: var(--ivr-btn-inset);
  inset-inline-start: calc(100% - var(--ivr-btn-slot) - var(--ivr-btn-inset));
  background-color: var(--ivr-blue-300);
  border-radius: var(--ivr-btn-slot-radius);
  transition:
    inset-block-start var(--ivr-duration-slow) var(--ivr-ease-out),
    inset-block-end var(--ivr-duration-slow) var(--ivr-ease-out),
    inset-inline-start var(--ivr-duration-slow) var(--ivr-ease-out),
    inset-inline-end var(--ivr-duration-slow) var(--ivr-ease-out),
    border-radius var(--ivr-duration-slow) var(--ivr-ease-out);
}

/* Grow OUT to the border box, not just the padding box: a negative inset of
   one border-width lets the fill sit exactly on the button's outer edge, so
   its radius can be the button's own radius and the two curves coincide. */
.ivr-btnv2--morph:hover::before {
  inset: calc(var(--ivr-rule) * -1);
  border-radius: var(--ivr-radius-btn);
}

/* The border must recolour with the fill, or it outlines it in the old colour.
   Qualified with --block (always present on a morph button) to outrank
   `.ivr-btnv2--primary:hover`, which is declared later at equal specificity and
   would otherwise force the label back to white on the pale fill — 1.7:1. */
.ivr-btnv2--block.ivr-btnv2--morph:hover {
  color: var(--ivr-blue-900);
  background-color: var(--ivr-blue-600);
  border-color: var(--ivr-blue-300);
  box-shadow: none;
}

.ivr-btnv2--morph .ivr-btnv2__slot {
  color: var(--ivr-blue-900);
}

.ivr-btnv2--inverse.ivr-btnv2--morph::before {
  background-color: var(--ivr-gray-0);
}

.ivr-btnv2--inverse.ivr-btnv2--morph:hover {
  color: var(--ivr-blue-800);
  background-color: transparent;
  border-color: var(--ivr-gray-0);
}

.ivr-btnv2--inverse.ivr-btnv2--morph .ivr-btnv2__slot {
  color: var(--ivr-blue-800);
}

/* On an outline button the morph fills with a pale tint rather than solid
   brand blue, so a secondary CTA keeps its weight. The slot goes transparent
   because the growing pseudo-element already paints that block. */
.ivr-btnv2--outline.ivr-btnv2--morph::before {
  background-color: var(--ivr-blue-100);
}

.ivr-btnv2--outline.ivr-btnv2--morph .ivr-btnv2__slot {
  background-color: transparent;
}

.ivr-btnv2--outline.ivr-btnv2--morph:hover {
  border-color: var(--ivr-blue-100);
  background-color: transparent;
  color: var(--ivr-blue-800);
}

@media (prefers-reduced-motion: reduce) {

  .ivr-btnv2--loop .ivr-btnv2__slot>*,
  .ivr-btnv2--morph::before {
    transition-duration: 1ms;
  }
}

.ivr-btnv2--primary {
  background-color: var(--ivr-blue-600);
  color: var(--ivr-gray-0);
  box-shadow: 0 1px 2px rgb(1 51 116 / 0.24), 0 6px 16px -8px rgb(4 74 179 / 0.45);
}

.ivr-btnv2--primary:hover {
  background-color: var(--ivr-blue-700);
  color: var(--ivr-gray-0);
  box-shadow: 0 2px 4px rgb(1 51 116 / 0.24), 0 12px 26px -10px rgb(4 74 179 / 0.6);
}

/* transparent, not white — a filled secondary button reads as a chip on any
   tinted section and fights the primary next to it */
.ivr-btnv2--outline {
  border-color: var(--ivr-border);
  color: var(--ivr-text);
  background-color: transparent;
}

.ivr-btnv2--outline:hover {
  border-color: var(--ivr-blue-300);
  color: var(--ivr-blue-700);
  background-color: var(--ivr-blue-50);
}

.ivr-btnv2--ghost {
  padding-inline: var(--ivr-space-3);
  color: var(--ivr-blue-600);
}

.ivr-btnv2--ghost:hover {
  color: var(--ivr-blue-800);
}

.ivr-btnv2--inverse {
  border-color: rgb(255 255 255 / 0.28);
  color: var(--ivr-gray-0);
  backdrop-filter: blur(8px);
}

.ivr-btnv2--inverse:hover {
  background-color: var(--ivr-gray-0);
  color: var(--ivr-blue-800);
  border-color: var(--ivr-gray-0);
}

.ivr-btnv2--lg {
  --ivr-btn-h: 3.75rem;
  --ivr-btn-pad-i: var(--ivr-space-8);
  font-size: var(--ivr-text-base);
}

.ivr-btnv2--sm {
  --ivr-btn-h: 2.75rem;
  --ivr-btn-pad-i: var(--ivr-space-5);
}

.ivr-btnv2 .ivr-icon {
  transition: transform var(--ivr-duration-fast) var(--ivr-ease);
}

.ivr-btnv2:hover .ivr-icon--nudge {
  transform: translateX(3px);
}

[dir="rtl"] .ivr-btnv2 .ivr-icon--nudge {
  transform: scaleX(-1);
}

[dir="rtl"] .ivr-btnv2:hover .ivr-icon--nudge {
  transform: scaleX(-1) translateX(3px);
}

/* --------------------------------------------------------------------------
   HERO v2 — full-bleed, play button straddling the section boundary
   -------------------------------------------------------------------------- */
.ivr-hero {
  position: relative;
  /* The play button overhangs into the next section. Both the hero and that
     section are positioned with z-index auto, so they paint in DOM order and
     the later one covers the overhang. Lifting the hero keeps the button on
     top whatever follows it — the previous spacer only worked by accident,
     because it happened to have no background. */
  z-index: 1;
  display: grid;
  align-items: end;
  min-block-size: min(92svh, 56rem);
  /* the halo ring must match whatever section follows the hero */
  --ivr-hero-next-bg: var(--ivr-surface);
  --ivr-hero-play-size: 5.25rem;
  --ivr-hero-play-ring: 0.875rem;
  /* Fond sombre sous les slides : évite un flash blanc avant le chargement
     de la première image, et donne un point d'ancrage neutre pendant le
     crossfade si une slide met plus longtemps à décoder. */
  background-color: var(--ivr-blue-800);
  isolation: isolate;
}

/* Toutes les images du hero se superposent en absolu et se fondent l'une dans
   l'autre. Seule celle qui porte .is-active reste visible ; le script cycle la
   classe pour créer un loop infini avec crossfade lent. */
.ivr-hero__slides {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
}

.ivr-hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* Diaporama cinématique.
   Deux classes indépendantes, orchestrées par JS pour éviter tout saut :
   - .is-zooming pilote l'animation Ken Burns (transform)
   - .is-shown pilote l'opacité (crossfade)
   La slide sortante garde .is-zooming pendant tout le fondu → le zoom
   continue pendant que l'opacité descend, jamais de gel visuel. La slide
   entrante démarre son propre Ken Burns dès qu'elle apparaît, légèrement
   agrandie (scale 1.02) pour que le fondu enchaîne un mouvement en cours. */
.ivr-hero__slides .ivr-hero__media {
  z-index: 0;
  opacity: 0;
  transform: scale(1.02) translate3d(0, 0, 0);
  transform-origin: 50% 50%;
  transition: opacity 1800ms cubic-bezier(0.4, 0, 0.2, 1);
  will-change: opacity, transform;
}

.ivr-hero__slides .ivr-hero__media.is-shown {
  opacity: 1;
}

@keyframes ivr-hero-kenburns {
  from {
    transform: scale(1.02) translate3d(0, 0, 0);
  }

  to {
    transform: scale(1.10) translate3d(-1.5%, -0.8%, 0);
  }
}

@keyframes ivr-hero-kenburns-alt {
  from {
    transform: scale(1.02) translate3d(0, 0, 0);
  }

  to {
    transform: scale(1.10) translate3d(1.5%, 0.8%, 0);
  }
}

.ivr-hero__slides .ivr-hero__media.is-zooming {
  animation: ivr-hero-kenburns 10s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

/* Alterne la direction du pan pour ne pas donner l'impression d'un même
   mouvement répété entre deux slides consécutives. */
.ivr-hero__slides .ivr-hero__media.is-zooming:nth-child(even) {
  animation-name: ivr-hero-kenburns-alt;
}

@media (prefers-reduced-motion: reduce) {
  .ivr-hero__slides .ivr-hero__media {
    transition: opacity 400ms linear;
    transform: none;
    animation: none !important;
  }
}

.ivr-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--ivr-overlay-scrim);
}

/* lighter images need dark text instead of a heavy scrim */
.ivr-hero--light .ivr-hero__scrim {
  background: linear-gradient(100deg,
      rgb(249 250 251 / 0.94) 0%,
      rgb(249 250 251 / 0.78) 34%,
      rgb(249 250 251 / 0.10) 62%,
      rgb(2 26 59 / 0.10) 100%);
}

.ivr-hero__inner {
  inline-size: 100%;
  max-inline-size: var(--ivr-container);
  margin-inline: auto;
  padding-inline: var(--ivr-gutter);
  /* clear the half-overlapping play button */
  padding-block: clamp(10rem, 14vh, 11rem) calc(var(--ivr-hero-play-size) / 2 + var(--ivr-space-10));
}

.ivr-hero__content {
  display: flex;
  flex-direction: column;
  gap: var(--ivr-space-5);
  max-inline-size: 44rem;
}

/* text only, subtle tint, tight radius — no icon, no outline */
.ivr-hero__eyebrow {
  display: inline-block;
  align-self: flex-start;
  padding: var(--ivr-space-2) var(--ivr-space-4);
  font-size: var(--ivr-text-xs);
  font-weight: var(--ivr-weight-medium);
  letter-spacing: var(--ivr-tracking-wide);
  color: var(--ivr-gray-0);
  background-color: rgb(255 255 255 / 0.14);
  border-radius: var(--ivr-radius-eyebrow);
  backdrop-filter: blur(8px);
}

.ivr-hero__title {
  /* Valeurs cibles : ~80px / 500 / 0.9em / -0.05em (clamp pour fluidifier
     mobile → desktop tout en s'ancrant sur 5rem = 80px au grand écran). */
  font-size: clamp(2.75rem, 2rem + 3.5vw, 5rem);
  font-weight: 500;
  line-height: 0.9em;
  letter-spacing: -0.05em;
  color: var(--ivr-gray-0);
  text-wrap: balance;
}

/* Rotateur de mots derrière l'ancre "Bâtir". Les mots se superposent en
   inline-grid pour ne prendre que la largeur du plus long. Chaque mot joue
   la même keyframe avec un delay staggered → boucle CSS pure, aucun JS.
   4 mots × 3s = cycle 12s ; visible ~2.4s, 0.6s de fondu haut/bas. */
.ivr-hero__anchor {
  display: block;
}

/* --- Variante V2 -------------------------------------------------------
   Structure : eyebrow (badge uppercase) → h1 → rotateur uppercase.
   Le contenu est plus long que la V1, donc l'échelle du h1 est réduite
   et le titre respire dans un container plus large. Sélecteur qualifié
   avec .ivr-hero__content pour surpasser la spécificité de base au cas
   où un ordre CSS viendrait à changer. */
.ivr-hero__content .ivr-hero__title--v2 {
  font-size: var(--ivr-text-4xl);
  line-height: var(--ivr-leading-tight);
  font-weight: var(--ivr-weight-medium);
  letter-spacing: -0.02em;
  max-inline-size: 22ch;
  text-wrap: balance;
}

/* Eyebrow V2 : reprend le style .ivr-hero__eyebrow (petite capsule
   translucide) mais posé en tête de bloc, au-dessus du titre. */
.ivr-hero__eyebrow--v2 {
  /* uppercase explicite + graisse renforcée pour la V2 */
  text-transform: uppercase;
  font-weight: var(--ivr-weight-bold, 700);
}

/* .ivr-hero__content utilise flex + gap = var(--ivr-space-5). Sur la V2 on
   remplace ce gap par un compactage vertical resserré : eyebrow collé au
   titre, rotateur juste sous le titre. La marge négative annule le gap
   flex hérité entre l'eyebrow et le h1. */
.ivr-hero__content:has(.ivr-hero__title--v2) .ivr-hero__eyebrow--v2 {
  margin-block-end: calc(var(--ivr-space-2) - var(--ivr-space-5));
}

/* Rotateur V2 — 3 items, uppercase et espacé, cycle 12 s. */
.ivr-hero__rot--v2 {
  display: grid;
  position: relative;
  overflow: hidden;
  padding-block: 0.15em;
  margin-block: -0.15em;
  margin-block-start: var(--ivr-space-5);
  font-size: clamp(0.95rem, 0.7rem + 0.6vw, 1.25rem);
  font-weight: var(--ivr-weight-medium, 500);
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--ivr-blue-200);
}

.ivr-hero__rot--v2 .ivr-hero__rot-i {
  animation-name: ivr-hero-rot-3;
  animation-duration: 12s;
}

.ivr-hero__rot--v2 .ivr-hero__rot-i[data-i="0"] {
  animation-delay: 0s;
}

.ivr-hero__rot--v2 .ivr-hero__rot-i[data-i="1"] {
  animation-delay: 4s;
}

.ivr-hero__rot--v2 .ivr-hero__rot-i[data-i="2"] {
  animation-delay: 8s;
}

/* Keyframe pour 3 mots dans un cycle 12 s : chaque mot occupe ~33 % du
   cycle (visible de 5 % à 30 %, transitions à 5 % et 34 %). */
@keyframes ivr-hero-rot-3 {
  0% {
    opacity: 0;
    transform: translateY(0.4em);
  }

  5% {
    opacity: 1;
    transform: translateY(0);
  }

  30% {
    opacity: 1;
    transform: translateY(0);
  }

  34% {
    opacity: 0;
    transform: translateY(-0.4em);
  }

  100% {
    opacity: 0;
    transform: translateY(-0.4em);
  }
}

.ivr-hero__rot {
  display: grid;
  position: relative;
  overflow: hidden;
  /* padding vertical léger pour que le translate ne clippe pas les jambages */
  padding-block: 0.15em;
  margin-block: -0.15em;
  /* on colle la ligne animée juste sous "Bâtir" */
  margin-block-start: 0.05em;
}

.ivr-hero__rot-i {
  grid-area: 1 / 1;
  opacity: 0;
  transform: translateY(0.4em);
  will-change: opacity, transform;
  animation: ivr-hero-rot 12s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  color: var(--ivr-gray-0);
}

.ivr-hero__rot-i[data-i="0"] {
  animation-delay: 0s;
}

.ivr-hero__rot-i[data-i="1"] {
  animation-delay: 3s;
}

.ivr-hero__rot-i[data-i="2"] {
  animation-delay: 6s;
}

.ivr-hero__rot-i[data-i="3"] {
  animation-delay: 9s;
}

@keyframes ivr-hero-rot {
  0% {
    opacity: 0;
    transform: translateY(0.4em);
  }

  5% {
    opacity: 1;
    transform: translateY(0);
  }

  22% {
    opacity: 1;
    transform: translateY(0);
  }

  27% {
    opacity: 0;
    transform: translateY(-0.4em);
  }

  100% {
    opacity: 0;
    transform: translateY(-0.4em);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ivr-hero__rot-i {
    animation: none;
  }

  /* n'afficher que le premier mot au repos */
  .ivr-hero__rot-i[data-i="0"] {
    opacity: 1;
    transform: none;
  }
}

.ivr-hero__lead {
  font-size: var(--ivr-text-base);
  line-height: 1.65;
  letter-spacing: var(--ivr-tracking-snug);
  color: rgb(255 255 255 / 0.78);
  max-inline-size: 52ch;
}

.ivr-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ivr-space-4);
  margin-block-start: var(--ivr-space-8);
}

/* dark-text variant for pale photography */
.ivr-hero--light .ivr-hero__title {
  color: var(--ivr-gray-900);
}

.ivr-hero--light .ivr-hero__lead {
  color: var(--ivr-text-muted);
}

.ivr-hero--light .ivr-hero__eyebrow {
  color: var(--ivr-gray-700);
  background-color: rgb(31 37 46 / 0.07);
  backdrop-filter: none;
}

/* ---- the straddling play button ----------------------------------------
   Centred on the hero's bottom edge, translated down by half its own height
   so exactly 50% sits in the hero and 50% in the next section. The ring is
   painted in the next section's colour so the disc reads as punched through.
   inset-inline + margin-inline:auto keeps it centred in RTL too.
   ------------------------------------------------------------------------ */
/* The wrapper paints the gap in the next section's colour. Keeping the ring on
   the wrapper — rather than as a spread shadow on the disc — means the disc
   owns its own shadow and pulse, so it reads as cut into the hero rather than
   as a white pill floating on top of it. */
.ivr-hero__play {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  margin-inline: auto;
  inline-size: fit-content;
  padding: var(--ivr-hero-play-ring);
  background-color: var(--ivr-hero-next-bg);
  border-radius: var(--ivr-radius-pill);
  line-height: 0;
  transform: translateY(50%);
  z-index: var(--ivr-z-base);
}

.ivr-playv2 {
  position: relative;
  display: grid;
  place-items: center;
  inline-size: var(--ivr-hero-play-size);
  block-size: var(--ivr-hero-play-size);
  border-radius: var(--ivr-radius-pill);
  background-color: var(--ivr-blue-600);
  color: var(--ivr-gray-0);
  cursor: pointer;
  /* sits on the ring, so the disc looks recessed into it */
  box-shadow:
    0 10px 24px -6px rgb(39 78 155 / 0.55),
    0 3px 8px rgb(2 26 59 / 0.20);
  transition:
    background-color var(--ivr-duration) var(--ivr-ease),
    box-shadow var(--ivr-duration) var(--ivr-ease),
    transform var(--ivr-duration) var(--ivr-ease-out);
}

.ivr-playv2:hover {
  background-color: var(--ivr-blue-700);
  transform: scale(1.06);
  box-shadow:
    0 14px 30px -6px rgb(39 78 155 / 0.65),
    0 4px 10px rgb(2 26 59 / 0.24);
}

.ivr-playv2__icon {
  inline-size: 1.5rem;
  block-size: 1.5rem;
  /* a triangle reads off-centre when mathematically centred */
  /* margin-inline-start: 0.2rem; */
}

[dir="rtl"] .ivr-playv2__icon {
  margin-inline-start: 0;
  /* margin-inline-end: 0.2rem; */
}

/* Pulse emanates from the disc and stops at the ring's outer edge.
   Max scale is (disc + 2 x ring) / disc = 1.33, so it never spills into the hero.
   A negative z-index would fall behind the wrapper's background, hence 0. */
.ivr-playv2::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 2px solid var(--ivr-blue-500);
  pointer-events: none;
  z-index: 0;
  animation: ivr-play-pulse 2.6s var(--ivr-ease-out) infinite;
}

@keyframes ivr-play-pulse {
  0% {
    transform: scale(1);
    opacity: 0.65;
  }

  75% {
    transform: scale(1.32);
    opacity: 0;
  }

  100% {
    transform: scale(1.32);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ivr-playv2::before {
    animation: none;
  }
}

.ivr-hero__play-label {
  display: block;
  margin-block-start: var(--ivr-space-3);
  font-size: var(--ivr-text-2xs);
  font-weight: var(--ivr-weight-medium);
  letter-spacing: var(--ivr-tracking-widest);
  text-transform: uppercase;
  text-align: center;
  color: var(--ivr-text-muted);
  white-space: nowrap;
}

/* the section directly after the hero must clear the overlapping half */
.ivr-section--after-hero {
  padding-block-start: calc(var(--ivr-hero-play-size, 5.25rem) / 2 + var(--ivr-space-16));
}

@media (max-width: 40rem) {
  .ivr-hero {
    --ivr-hero-play-size: 4.25rem;
    --ivr-hero-play-ring: 0.75rem;
  }
}

/* ==========================================================================
   CARDS — REDESIGN. Two directions, both with real micro-interaction.
   A · editorial   : corner block, drawn rule, ghost numeral, media footer
   B · immersive   : full-bleed image, veil, reveal-on-hover body
   ========================================================================== */

/* --------------------------------------------------------------------------
   A — EDITORIAL CARD
   -------------------------------------------------------------------------- */
.ivr-cardA {
  position: relative;
  display: flex;
  flex-direction: column;
  background-color: var(--ivr-surface);
  border: var(--ivr-rule) solid var(--ivr-border-subtle);
  border-radius: var(--ivr-radius-card);
  overflow: hidden;
  isolation: isolate;
  transition:
    border-color var(--ivr-duration) var(--ivr-ease),
    box-shadow var(--ivr-duration) var(--ivr-ease),
    transform var(--ivr-duration) var(--ivr-ease-out);
}

.ivr-cardA:hover {
  border-color: var(--ivr-blue-200);
  box-shadow: var(--ivr-shadow-card-hover);
  transform: translateY(-6px);
}

/* --- head : flush corner block + rule + numeral --- */
.ivr-cardA__head {
  display: flex;
  align-items: center;
  gap: var(--ivr-space-5);
  padding-inline-end: var(--ivr-card-pad);
}

/* bleeds into the corner, so the card's own radius shapes its outer edge */
.ivr-cardA__badge {
  display: grid;
  place-items: center;
  inline-size: 4.5rem;
  block-size: 4.5rem;
  flex: none;
  /* the deep blue rather than the saturated primary — it stays clearly blue
     without competing with the buttons and links on the same card */
  background-color: var(--ivr-blue-800);
  color: var(--ivr-gray-0);
  --ivr-icon-dt-opacity: 0.4;
  /* logical corner: bottom-right in LTR, bottom-left in RTL — the two edges
     that sit inside the card rather than on its rounded outer corner */
  border-end-end-radius: var(--ivr-radius-chip);
  transition: background-color var(--ivr-duration) var(--ivr-ease);
}

.ivr-cardA:hover .ivr-cardA__badge {
  background-color: var(--ivr-blue-600);
}

.ivr-cardA__badge svg {
  transition: transform var(--ivr-duration-slow) var(--ivr-ease-out);
}

.ivr-cardA:hover .ivr-cardA__badge svg {
  transform: scale(1.14);
}

/* dotted at rest; a solid brand line draws across it on hover */
.ivr-cardA__rule {
  position: relative;
  flex: 1 1 auto;
  block-size: 2px;
  background-image: radial-gradient(circle, var(--ivr-gray-300) 1px, transparent 1px);
  background-size: 7px 2px;
  background-repeat: repeat-x;
}

.ivr-cardA__rule::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--ivr-blue-500);
  transform: scaleX(0);
  /* transform-origin takes no logical keywords — `inline-start` is invalid and
     the whole declaration gets dropped, leaving the default centre origin. */
  transform-origin: left;
  transition: transform var(--ivr-duration-reveal) var(--ivr-ease-out);
}

[dir="rtl"] .ivr-cardA__rule::after {
  transform-origin: right;
}

.ivr-cardA:hover .ivr-cardA__rule::after {
  transform: scaleX(1);
}

.ivr-cardA__num {
  font-size: var(--ivr-text-xl);
  font-weight: var(--ivr-weight-bold);
  letter-spacing: var(--ivr-tracking-tighter);
  font-variant-numeric: tabular-nums;
  color: var(--ivr-gray-200);
  transition:
    color var(--ivr-duration) var(--ivr-ease),
    transform var(--ivr-duration-slow) var(--ivr-ease-out);
}

.ivr-cardA:hover .ivr-cardA__num {
  color: var(--ivr-blue-200);
  transform: translateY(-2px);
}

/* --- body --- */
.ivr-cardA__body {
  display: flex;
  flex-direction: column;
  gap: var(--ivr-space-3);
  padding: var(--ivr-space-8) var(--ivr-card-pad) var(--ivr-space-8);
}

.ivr-cardA__title {
  font-size: var(--ivr-text-lg);
  font-weight: var(--ivr-weight-semibold);
  letter-spacing: var(--ivr-tracking-tight);
  transition: color var(--ivr-duration) var(--ivr-ease);
}

.ivr-cardA:hover .ivr-cardA__title {
  color: var(--ivr-blue-700);
}

.ivr-cardA__text {
  font-size: var(--ivr-text-sm);
  line-height: var(--ivr-leading-relaxed);
  color: var(--ivr-text-muted);
}

/* The card CTA is a real .ivr-btnv2 now, so this class only supplies what the
   button system does not: the whole-card click target and the arrow nudge.
   Its old text-link declarations are gone — they sat later in the file than
   .ivr-btnv2 at equal specificity and would have overridden the button. */
.ivr-cardA__link {
  margin-block-start: var(--ivr-space-5);
  align-self: flex-start;
}

/* Stretched-link : la carte entière (image comprise) devient cliquable via
   un pseudo qui recouvre toute la surface de .ivr-cardA. Un seul <a> reste
   dans l'accessibility tree (le bouton visible), donc le tab-order et le
   lecteur d'écran ne voient qu'un lien par carte. */
.ivr-cardA__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* Neutralise le `transform: translateY(1px)` de .ivr-btnv2:active sur le
   lien-carte : ce transform crée un nouveau containing-block, ce qui fait
   collapser ::after sur la taille du bouton au mousedown → le mouseup tombe
   hors de l'ancre, aucun click n'est émis, et seule la zone du bouton finit
   par naviguer. Le bouton conserve son feedback :hover via .ivr-cardA:hover. */
.ivr-cardA__link:active {
  transform: none;
}

.ivr-cardA__link svg {
  transition: transform var(--ivr-duration) var(--ivr-ease);
}

.ivr-cardA:hover .ivr-cardA__link svg {
  transform: translateX(4px);
}

[dir="rtl"] .ivr-cardA__link svg {
  transform: scaleX(-1);
}

[dir="rtl"] .ivr-cardA:hover .ivr-cardA__link svg {
  transform: scaleX(-1) translateX(4px);
}

/* Sur mobile la carte est étroite : à la taille --sm le libellé passe sur
   deux lignes et le bouton mange la moitié de la carte. On réduit texte,
   hauteur et padding — la cible reste >= 40px de haut (tap target). */
@media (max-width: 40rem) {

  .ivr-cardA__link {
    --ivr-btn-h: 2.5rem;
    --ivr-btn-pad-i: var(--ivr-space-4);
    gap: var(--ivr-space-2);
    font-size: var(--ivr-text-sm);
  }
}

/* --- media footer --- */
.ivr-cardA__media {
  margin-block-start: auto;
  overflow: hidden;
  aspect-ratio: 5 / 4;
}

.ivr-cardA__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transform: scale(1.01);
  transition:
    transform var(--ivr-duration-reveal) var(--ivr-ease-out),
    filter var(--ivr-duration-slow) var(--ivr-ease);
  filter: saturate(0.85);
}

.ivr-cardA:hover .ivr-cardA__media img {
  transform: scale(1.08);
  filter: saturate(1);
}

/* --------------------------------------------------------------------------
   B — IMMERSIVE CARD
   -------------------------------------------------------------------------- */
.ivr-cardB {
  /* one inset value shared by the badge and the body, so the title sits on the
     same vertical axis as the badge above it */
  --ivr-cardB-pad: var(--ivr-space-6);
  position: relative;
  display: block;
  min-block-size: 27rem;
  border-radius: var(--ivr-radius-card);
  overflow: hidden;
  isolation: isolate;
  text-decoration: none;
  transition:
    box-shadow var(--ivr-duration) var(--ivr-ease),
    transform var(--ivr-duration) var(--ivr-ease-out);
}

.ivr-cardB:hover {
  box-shadow: var(--ivr-shadow-card-hover);
  transform: translateY(-6px);
}

.ivr-cardB__img {
  position: absolute;
  inset: 0;
  z-index: -2;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transform: scale(1.02);
  filter: saturate(0.7);
  transition:
    transform var(--ivr-duration-reveal) var(--ivr-ease-out),
    filter var(--ivr-duration-slow) var(--ivr-ease);
}

.ivr-cardB:hover .ivr-cardB__img {
  transform: scale(1.1);
  filter: saturate(1);
}

/* two stacked veils: a permanent legibility scrim, plus a brand wash on hover */
.ivr-cardB__veil {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top,
      rgb(2 26 59 / 0.92) 0%,
      rgb(2 26 59 / 0.55) 38%,
      rgb(2 26 59 / 0.12) 72%);
}

.ivr-cardB__veil::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--ivr-blue-700) 0%, transparent 68%);
  opacity: 0;
  transition: opacity var(--ivr-duration-slow) var(--ivr-ease);
}

.ivr-cardB:hover .ivr-cardB__veil::after {
  opacity: 0.85;
}

.ivr-cardB__badge {
  position: absolute;
  inset-block-start: var(--ivr-cardB-pad);
  inset-inline-start: var(--ivr-cardB-pad);
  padding: var(--ivr-space-2) var(--ivr-space-4);
  font-size: var(--ivr-text-2xs);
  font-weight: var(--ivr-weight-semibold);
  letter-spacing: var(--ivr-tracking-widest);
  text-transform: uppercase;
  color: var(--ivr-gray-0);
  /* visible at rest so a grid of these still reads as content, then it
     firms up to solid brand blue on hover */
  background-color: rgb(2 26 59 / 0.55);
  backdrop-filter: blur(6px);
  border-radius: var(--ivr-radius-eyebrow);
  transition:
    background-color var(--ivr-duration-slow) var(--ivr-ease),
    translate var(--ivr-duration-slow) var(--ivr-ease-out);
}

.ivr-cardB:hover .ivr-cardB__badge {
  background-color: var(--ivr-blue-600);
  translate: 0 -2px;
}

.ivr-cardB__body {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  display: flex;
  flex-direction: column;
  gap: var(--ivr-space-3);
  padding: var(--ivr-cardB-pad);
}

/* title and CTA share a row, so the description can run the full width
   underneath instead of sliding under the button */
.ivr-cardB__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ivr-space-4);
}

.ivr-cardB__title {
  font-size: var(--ivr-text-lg);
  font-weight: var(--ivr-weight-semibold);
  letter-spacing: var(--ivr-tracking-tight);
  color: var(--ivr-gray-0);
  /* base.css sets break-word on headings; in a narrow card that split
     "Construction" across two lines mid-word */
  overflow-wrap: normal;
}

/* 0fr → 1fr gives a height animation without hardcoding a max-height */
.ivr-cardB__reveal {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--ivr-duration-slow) var(--ivr-ease-out);
}

.ivr-cardB:hover .ivr-cardB__reveal {
  grid-template-rows: 1fr;
}

.ivr-cardB__reveal>* {
  overflow: hidden;
  font-size: var(--ivr-text-sm);
  line-height: var(--ivr-leading-relaxed);
  color: rgb(255 255 255 / 0.86);
  opacity: 0;
  transition: opacity var(--ivr-duration) var(--ivr-ease);
}

.ivr-cardB:hover .ivr-cardB__reveal>* {
  opacity: 1;
  transition-delay: 120ms;
}

/* in flow, not absolute — it reserves its own space so nothing runs under it */
.ivr-cardB__cta {
  display: grid;
  place-items: center;
  flex: none;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border-radius: var(--ivr-radius-pill);
  background-color: var(--ivr-gray-0);
  color: var(--ivr-blue-800);
  scale: 0.7;
  opacity: 0;
  transition:
    scale var(--ivr-duration-slow) var(--ivr-ease-out),
    opacity var(--ivr-duration) var(--ivr-ease);
}

.ivr-cardB:hover .ivr-cardB__cta {
  scale: 1;
  opacity: 1;
}

/* --------------------------------------------------------------------------
   FILIALE CARD — conservee pour styleguide-v2.html, qui la référence encore.
   Plus utilisée par aucune page réelle : Groupe et Métiers affichent les
   logos EN COULEUR et sans plaque, décision qui a remplacé la désaturation
   codée ici.
   -------------------------------------------------------------------------- */
.ivr-filiale {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--ivr-space-5);
  padding: var(--ivr-card-pad);
  background-color: var(--ivr-surface);
  border: var(--ivr-rule) solid var(--ivr-border-subtle);
  border-radius: var(--ivr-radius-card);
  transition:
    border-color var(--ivr-duration) var(--ivr-ease),
    box-shadow var(--ivr-duration) var(--ivr-ease),
    transform var(--ivr-duration) var(--ivr-ease-out);
}

.ivr-filiale:hover {
  border-color: var(--ivr-blue-200);
  box-shadow: var(--ivr-shadow-card-hover);
  transform: translateY(-4px);
}

.ivr-filiale__plate {
  display: flex;
  align-items: center;
  block-size: 3rem;
}

/* Hauteur FIXE, jamais un pourcentage : la piste flex est auto-dimensionnee,
   donc block-size:100% est une dependance circulaire qui retombe a `auto` en
   silence — le logo Teka (1400px) s'affichait trois fois trop haut. */
.ivr-filiale__plate img {
  inline-size: 100%;
  block-size: 3rem;
  object-fit: contain;
  object-position: left center;
  filter: grayscale(1);
  opacity: 0.72;
  transition:
    filter var(--ivr-duration-slow) var(--ivr-ease),
    opacity var(--ivr-duration-slow) var(--ivr-ease);
}

[dir="rtl"] .ivr-filiale__plate img {
  object-position: right center;
}

.ivr-filiale:hover .ivr-filiale__plate img {
  filter: grayscale(0);
  opacity: 1;
}

.ivr-filiale__sector {
  font-size: var(--ivr-text-2xs);
  font-weight: var(--ivr-weight-semibold);
  letter-spacing: var(--ivr-tracking-widest);
  text-transform: uppercase;
  color: var(--ivr-blue-600);
}

.ivr-filiale__title {
  font-size: var(--ivr-text-lg);
  font-weight: var(--ivr-weight-semibold);
  letter-spacing: var(--ivr-tracking-tight);
}

.ivr-filiale__text {
  font-size: var(--ivr-text-sm);
  line-height: var(--ivr-leading-relaxed);
  color: var(--ivr-text-muted);
}

.ivr-filiale__foot {
  margin-block-start: auto;
  padding-block-start: var(--ivr-space-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ivr-space-4);
  border-block-start: var(--ivr-rule) solid var(--ivr-border-subtle);
}

.ivr-filiale__link {
  display: inline-flex;
  align-items: center;
  gap: var(--ivr-space-2);
  font-size: var(--ivr-text-sm);
  font-weight: var(--ivr-weight-medium);
  color: var(--ivr-blue-600);
  text-decoration: none;
}

.ivr-filiale__link::after {
  content: "";
  position: absolute;
  inset: 0;
}

.ivr-filiale__link svg {
  transition: transform var(--ivr-duration) var(--ivr-ease);
}

.ivr-filiale:hover .ivr-filiale__link svg {
  transform: translate(2px, -2px);
}

/* ==========================================================================
   COQUILLE DE PAGE INTERIEURE — partagee par Groupe, Metiers, RSE, Media,
   Carrieres, Contact. Ecrite une fois ici : ces deux blocs sont la seule
   difference structurelle entre l'accueil et toutes les autres pages.
   ========================================================================== */

/* --------------------------------------------------------------------------
   HERO DE PAGE — pendant de .ivr-hero pour les pages interieures.
   Meme construction que le hero d'accueil (photo + voile + texte blanc) mais
   plus court et sans affordance video. L'en-tete passe par-dessus en
   .ivr-header--over-hero (fixed, transparent, logo blanc), exactement comme
   sur l'accueil — d'ou le degagement de la hauteur d'en-tete en haut.
   -------------------------------------------------------------------------- */
.ivr-phero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  /* le contenu se cale en BAS du cadre */
  align-items: flex-end;
  min-block-size: clamp(30rem, 22rem + 26vw, 44rem);
  padding-block: calc(var(--ivr-header-h) + var(--ivr-space-12)) clamp(3rem, 2rem + 5vw, 5rem);
  background-color: var(--ivr-blue-950);
}

.ivr-phero__media {
  position: absolute;
  z-index: -2;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* Pondere vers le bas et le bord de debut, la ou se pose le texte : la photo
   est generee avec ce coin volontairement sombre, le voile ne fait que
   garantir le contraste. */
.ivr-phero__scrim {
  position: absolute;
  z-index: -1;
  inset: 0;
  background:
    linear-gradient(to top,
      rgb(2 18 42 / 0.90) 0%,
      rgb(2 18 42 / 0.62) 34%,
      rgb(2 18 42 / 0.20) 68%,
      rgb(2 18 42 / 0.34) 100%),
    linear-gradient(to right,
      rgb(2 18 42 / 0.55) 0%,
      rgb(2 18 42 / 0.10) 55%,
      rgb(2 18 42 / 0) 100%);
}

/* un degrade `to right` est PHYSIQUE : il faut le redeclarer en RTL, sinon le
   cote sombre passe du mauvais bord et le texte perd son contraste */
[dir="rtl"] .ivr-phero__scrim {
  background:
    linear-gradient(to top,
      rgb(2 18 42 / 0.90) 0%,
      rgb(2 18 42 / 0.62) 34%,
      rgb(2 18 42 / 0.20) 68%,
      rgb(2 18 42 / 0.34) 100%),
    linear-gradient(to left,
      rgb(2 18 42 / 0.55) 0%,
      rgb(2 18 42 / 0.10) 55%,
      rgb(2 18 42 / 0) 100%);
}

.ivr-phero__inner {
  inline-size: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--ivr-space-6);
}

.ivr-phero__head {
  display: flex;
  flex-direction: column;
  gap: var(--ivr-space-4);
}

.ivr-phero__title {
  max-inline-size: 18ch;
  font-size: var(--ivr-text-3xl);
  font-weight: var(--ivr-weight-semibold);
  line-height: var(--ivr-leading-tight);
  letter-spacing: var(--ivr-tracking-tighter);
  text-wrap: balance;
  color: var(--ivr-gray-0);
}

.ivr-phero__lead {
  max-inline-size: 54ch;
  font-size: var(--ivr-text-md);
  line-height: var(--ivr-leading-relaxed);
  color: rgb(255 255 255 / 0.82);
}

/* la pastille de surtitre est claire par defaut : illisible sur le voile */
.ivr-phero .ivr-overline {
  --ivr-overline-bg: rgb(255 255 255 / 0.14);
  --ivr-overline-dot: var(--ivr-blue-300);
  --ivr-overline-fg: var(--ivr-gray-0);
}

/* --------------------------------------------------------------------------
   SOUS-NAVIGATION — navigation interne a la page.
   Le menu deroulant de l'en-tete et le pied de page pointent tous deux vers
   les ancres d'une page interieure ; sans elle, le lecteur atterrit au milieu
   de la page sans moyen d'en parcourir le reste. Colle SOUS l'en-tete, d'ou
   la hauteur d'en-tete reduite comme decalage.
   -------------------------------------------------------------------------- */
.ivr-subnav {
  /* --ivr-subnav-h vient de tokens.css : les pages calent leurs ancres
     dessus, il ne doit exister qu'a un seul endroit */
  position: sticky;
  inset-block-start: var(--ivr-header-h-scrolled);
  z-index: var(--ivr-z-sticky);
  background-color: var(--ivr-blue-950);
  border-block-end: var(--ivr-rule) solid rgb(255 255 255 / 0.10);
}

.ivr-subnav__inner {
  position: relative;
  display: flex;
  align-items: center;
}

.ivr-subnav__list {
  display: flex;
  align-items: center;
  gap: var(--ivr-space-1);
  block-size: var(--ivr-subnav-h);
  inline-size: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: auto;
  scrollbar-width: none;
  scroll-behavior: smooth;
  /* un conteneur en overflow laisse voir le contenu a travers son padding de
     fin : la piste d'elan vient de la gouttiere, pas d'un padding sur la liste */
  scroll-padding-inline: var(--ivr-gutter);

  --fade-start: 0px;
  --fade-end: 0px;
  mask-image: linear-gradient(to right,
      transparent 0,
      #000 var(--fade-start),
      #000 calc(100% - var(--fade-end)),
      transparent 100%);
  transition: mask-image var(--ivr-duration) var(--ivr-ease);
}

.ivr-subnav__list::-webkit-scrollbar {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .ivr-subnav__list {
    scroll-behavior: auto;
  }
}

[dir="rtl"] .ivr-subnav__list {
  mask-image: linear-gradient(to left,
      transparent 0,
      #000 var(--fade-start),
      #000 calc(100% - var(--fade-end)),
      transparent 100%);
}

/* Un masque, pas un degrade superpose : la barre est translucide au-dessus de
   ce qui defile dessous, donc un degrade peint devrait connaitre ce fond. Le
   masque dissout les pastilles elles-memes. Chaque cote a sa variable : un
   cote qui n'a plus rien a reveler n'affiche aucun fondu. */
.ivr-subnav.can-scroll-start .ivr-subnav__list {
  --fade-start: 3rem;
}

.ivr-subnav.can-scroll-end .ivr-subnav__list {
  --fade-end: 3rem;
}

.ivr-subnav__arrow {
  position: absolute;
  z-index: 2;
  inset-block: 0;
  display: grid;
  place-items: center;
  inline-size: 2.25rem;
  color: var(--ivr-gray-0);
  background-color: var(--ivr-blue-950);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--ivr-duration) var(--ivr-ease),
    visibility 0s linear var(--ivr-duration);
}

.ivr-subnav__arrow--prev {
  inset-inline-start: 0;
}

.ivr-subnav__arrow--next {
  inset-inline-end: 0;
}

.ivr-subnav__arrow .ivr-icon {
  transition: transform var(--ivr-duration-fast) var(--ivr-ease);
}

.ivr-subnav__arrow--prev .ivr-icon {
  scale: -1 1;
}

[dir="rtl"] .ivr-subnav__arrow--prev .ivr-icon {
  scale: 1 1;
}

[dir="rtl"] .ivr-subnav__arrow--next .ivr-icon {
  scale: -1 1;
}

.ivr-subnav.can-scroll-start .ivr-subnav__arrow--prev,
.ivr-subnav.can-scroll-end .ivr-subnav__arrow--next {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

.ivr-subnav__arrow:hover {
  color: var(--ivr-blue-300);
}

.ivr-subnav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--ivr-space-2);
  flex: none;
  padding: var(--ivr-space-2) var(--ivr-space-4);
  font-size: var(--ivr-text-sm);
  font-weight: var(--ivr-weight-medium);
  letter-spacing: var(--ivr-tracking-snug);
  white-space: nowrap;
  color: rgb(255 255 255 / 0.62);
  text-decoration: none;
  border-radius: var(--ivr-radius-eyebrow);
  transition:
    color var(--ivr-duration-fast) var(--ivr-ease),
    background-color var(--ivr-duration-fast) var(--ivr-ease);
}

.ivr-subnav__link:hover {
  color: var(--ivr-gray-0);
  background-color: rgb(255 255 255 / 0.08);
}

.ivr-subnav__link.is-active {
  color: var(--ivr-gray-0);
  background-color: rgb(255 255 255 / 0.12);
}

.ivr-subnav__num {
  font-size: var(--ivr-text-2xs);
  font-weight: var(--ivr-weight-semibold);
  letter-spacing: var(--ivr-tracking-normal);
  color: rgb(255 255 255 / 0.38);
  font-variant-numeric: tabular-nums;
}

.ivr-subnav__link.is-active .ivr-subnav__num {
  color: var(--ivr-blue-300);
}

/* ==========================================================================
   FORMULAIRES — partages par Carrieres et Contact.
   ========================================================================== */
.ivr-form {
  display: grid;
  gap: var(--ivr-space-6);
}

.ivr-form__grid {
  display: grid;
  gap: var(--ivr-space-5);
  grid-template-columns: 1fr;
  /* Chaque cellule prend sa hauteur naturelle. Sans ça, un champ voisin
     avec un tip de validation ("Ce champ est obligatoire.") tirait toute
     la rangée, donc l'input du frère paraissait plus grand. */
  align-items: start;
}

@media (min-width: 46rem) {
  .ivr-form__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .ivr-form__grid>.ivr-field--full {
    grid-column: 1 / -1;
  }
}

.ivr-field {
  display: grid;
  gap: var(--ivr-space-2);
}

.ivr-field__label {
  font-size: var(--ivr-text-xs);
  font-weight: var(--ivr-weight-semibold);
  letter-spacing: var(--ivr-tracking-wide);
  text-transform: uppercase;
  color: var(--ivr-text-muted);
}

/* la mention est portee par le label, pas seulement par l'attribut required :
   un lecteur d'ecran l'annonce, et l'oeil la voit */
.ivr-field__label span {
  color: var(--ivr-blue-600);
}

.ivr-input,
.ivr-select,
.ivr-textarea {
  inline-size: 100%;
  padding: var(--ivr-space-4) var(--ivr-space-5);
  font-family: inherit;
  font-size: var(--ivr-text-base);
  color: var(--ivr-text);
  background-color: var(--ivr-surface);
  border: var(--ivr-rule) solid var(--ivr-border);
  border-radius: var(--ivr-radius-btn);
  transition:
    border-color var(--ivr-duration-fast) var(--ivr-ease),
    box-shadow var(--ivr-duration-fast) var(--ivr-ease);
}

.ivr-textarea {
  min-block-size: 6rem;
  resize: vertical;
  line-height: var(--ivr-leading-relaxed);
}

.ivr-input::placeholder,
.ivr-textarea::placeholder {
  color: var(--ivr-gray-400);
}

.ivr-input:hover,
.ivr-select:hover,
.ivr-textarea:hover {
  border-color: var(--ivr-border-strong);
}

.ivr-input:focus-visible,
.ivr-select:focus-visible,
.ivr-textarea:focus-visible {
  outline: none;
  border-color: var(--ivr-blue-600);
  box-shadow: 0 0 0 3px var(--ivr-blue-100);
}

/* La fleche native du <select> disparait avec appearance: none — il faut la
   redessiner. Chevron en data-uri plutot qu'un <svg> frere : un select ne peut
   pas contenir d'enfant, et un pseudo-element ne s'y applique pas. */
.ivr-select {
  appearance: none;
  padding-inline-end: var(--ivr-space-12);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2362696f' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 1.125rem;
  background-position: right var(--ivr-space-5) center;
}

[dir="rtl"] .ivr-select {
  background-position: left var(--ivr-space-5) center;
}

/* ---- champ fichier ----
   L'input natif est masque mais reste dans le flux et focusable : c'est le
   <label> qui sert de bouton. `display: none` le retirerait du parcours
   clavier et de la validation. */
.ivr-file {
  display: flex;
  flex-direction: column;
  gap: var(--ivr-space-2);
}

/* Le "drop" est la seule zone cliquable qui ouvre le sélecteur natif.
   `position: relative` ici (et pas sur .ivr-file) → l'input absolu ne
   déborde plus sur les chips de la liste dessous, qui redeviennent
   cliquables (bouton × en particulier). */
.ivr-file__drop {
  position: relative;
}

.ivr-file__input {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  inline-size: 100%;
  block-size: 100%;
  opacity: 0;
  cursor: pointer;
}

.ivr-file__face {
  display: flex;
  align-items: center;
  gap: var(--ivr-space-3);
  padding: var(--ivr-space-4) var(--ivr-space-5);
  font-size: var(--ivr-text-sm);
  color: var(--ivr-text-muted);
  background-color: var(--ivr-surface);
  border: var(--ivr-rule) dashed var(--ivr-border-strong);
  border-radius: var(--ivr-radius-btn);
  transition:
    border-color var(--ivr-duration-fast) var(--ivr-ease),
    color var(--ivr-duration-fast) var(--ivr-ease);
}

.ivr-file__input:hover+.ivr-file__face,
.ivr-file__input:focus-visible+.ivr-file__face {
  border-color: var(--ivr-blue-600);
  color: var(--ivr-blue-700);
}

.ivr-file__face .ivr-icon {
  flex: none;
  color: var(--ivr-blue-600);
}

/* -- Liste des fichiers sélectionnés (multi-upload) -----------------
   Un chip par fichier avec nom, taille et bouton de retrait. Rendu
   vide (display: none) tant que rien n'est sélectionné pour ne pas
   ajouter d'espace parasite. */
.ivr-file__list {
  display: none;
  flex-direction: column;
  gap: var(--ivr-space-2);
  margin: var(--ivr-space-3) 0 0;
  padding: 0;
  list-style: none;
}

.ivr-file__list:not(:empty) {
  display: flex;
}

.ivr-file__chip {
  display: flex;
  align-items: center;
  gap: var(--ivr-space-3);
  padding: var(--ivr-space-2) var(--ivr-space-3) var(--ivr-space-2) var(--ivr-space-4);
  font-size: var(--ivr-text-sm);
  color: var(--ivr-text);
  background-color: var(--ivr-surface-alt, #f7f8fa);
  border: var(--ivr-rule) solid var(--ivr-border);
  border-radius: var(--ivr-radius-btn);
}

.ivr-file__chip-icon {
  flex: none;
  inline-size: 1.125rem;
  block-size: 1.125rem;
  color: #16a34a;
}

/* Chip d'erreur (fichier rejeté : trop volumineux, mauvais format).
   Le fichier reste visible pour que l'utilisateur voie CE qui a été
   refusé, avec le motif à droite ; mais il n'est pas recopié dans
   input.files donc pas envoyé au serveur. */
.ivr-file__chip--error {
  color: #7f1d1d;
  background-color: #fef2f2;
  border-color: #fecaca;
}

.ivr-file__chip--error .ivr-file__chip-icon,
.ivr-file__chip--error .ivr-file__chip-size {
  color: #b91c1c;
}

.ivr-file__chip-name {
  flex: 1 1 auto;
  min-inline-size: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ivr-file__chip-size {
  flex: none;
  font-size: var(--ivr-text-xs);
  color: var(--ivr-text-subtle);
}

.ivr-file__chip-remove {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 1.75rem;
  block-size: 1.75rem;
  padding: 0;
  color: var(--ivr-text-muted);
  background-color: transparent;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  transition:
    color var(--ivr-duration-fast) var(--ivr-ease),
    background-color var(--ivr-duration-fast) var(--ivr-ease);
}

.ivr-file__chip-remove:hover,
.ivr-file__chip-remove:focus-visible {
  color: #dc2626;
  background-color: rgb(220 38 38 / 0.08);
  outline: none;
}

.ivr-file__chip-remove svg {
  inline-size: 0.875rem;
  block-size: 0.875rem;
}

.ivr-field__hint {
  font-size: var(--ivr-text-xs);
  color: var(--ivr-text-subtle);
}

.ivr-form__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ivr-space-5);
}

/* ============================================================
   Contact Form 7 — pontage avec notre design system.

   CF7 enveloppe systématiquement chaque champ dans
   `<span class="wpcf7-form-control-wrap">` et injecte des divs
   d'état (validation, spinner, output response) qui cassent notre
   grille et l'adjacence .ivr-file__input + .ivr-file__face.
   `display: contents` neutralise ces wrappers sans les retirer
   (nécessaires au JS AJAX de CF7).
   ============================================================ */
.ivr-form .wpcf7-form-control-wrap:not(.cf7apps-honeypot-wrap) {
  display: contents;
}

/* Honeypot (CF7 Honeypot plugin) : masqué mais toujours présent dans le
   DOM — les bots basiques postent tous les champs du formulaire et se
   font rejeter côté serveur. `display:none` plutôt qu'un off-screen :
   les lecteurs d'écran ignorent complètement le champ (l'off-screen fait
   annoncer « Please leave this field empty » aux non-voyants). */
.ivr-form .cf7apps-honeypot-wrap {
  display: none !important;
}

/* Le .ivr-file contient (via display:contents du wrap CF7) l'input, la
   face et un éventuel .wpcf7-not-valid-tip. On garde une hauteur figée
   pour que le label reste collé au bord du bloc. */
.ivr-form .ivr-file {
  min-block-size: 3.5rem;
}

/* -- Bandeau d'état (validation/succès/erreur) ---------------------- */
/* Invisible par défaut ; seul un état parent (sent / invalid / failed /
   spam) le rend visible avec un fond, une bordure fine et un padding
   généreux. Aligné plein-largeur dans la grille, aucun décalage. */
.ivr-form .wpcf7-response-output {
  grid-column: 1 / -1;
  margin: 0;
  padding: var(--ivr-space-5) var(--ivr-space-6);
  border: 1px solid transparent;
  border-radius: var(--ivr-radius-btn);
  font-size: var(--ivr-text-sm);
  line-height: var(--ivr-leading-relaxed);
  color: var(--ivr-text);
  background-color: transparent;
  letter-spacing: 0;
  text-align: start;
  /* CF7 laisse l'élément dans le DOM même à vide → on le cache tant
     qu'aucun état n'est posé, pour éviter le "yellow-ish neutral". */
  display: none;
}

.ivr-form form.sent .wpcf7-response-output,
.ivr-form form.invalid .wpcf7-response-output,
.ivr-form form.failed .wpcf7-response-output,
.ivr-form form.spam .wpcf7-response-output {
  display: block;
}

/* Padding, marges et bordure partagés par succès ET erreur — seule la
   couleur change. Aligné plein-largeur dans la grille du formulaire
   (grid-column: 1/-1 sur la règle de base), aucun décalage manuel. */
.ivr-form form.sent .wpcf7-response-output,
.ivr-form form.invalid .wpcf7-response-output,
.ivr-form form.failed .wpcf7-response-output,
.ivr-form form.spam .wpcf7-response-output {
  margin: 2em 0em 1em;
  padding: 1em 1.5em;
  border-width: 1px;
  border-style: solid;
}

.ivr-form form.sent .wpcf7-response-output {
  border-color: #16a34a;
  color: #14532d;
  background-color: #f0fdf4;
}

.ivr-form form.invalid .wpcf7-response-output,
.ivr-form form.failed .wpcf7-response-output,
.ivr-form form.spam .wpcf7-response-output {
  border-color: #dc2626;
  color: #b91c1c;
  background-color: #fef2f2;
}

/* -- Erreurs inline (par champ) ------------------------------------- */
.ivr-form .wpcf7-not-valid-tip {
  display: block;
  /* margin-block-start: var(--ivr-space-2); */
  font-size: var(--ivr-text-xs);
  line-height: var(--ivr-leading-snug);
  color: #b91c1c;
}

/* Bordure rouge + halo doux quand un champ est invalide. Le sélecteur
   couvre les inputs, selects, textareas ET la face du champ fichier. */
.ivr-form .wpcf7-not-valid,
.ivr-form .ivr-input.wpcf7-not-valid,
.ivr-form .ivr-select.wpcf7-not-valid,
.ivr-form .ivr-textarea.wpcf7-not-valid {
  border-color: #dc2626 !important;
  box-shadow: 0 0 0 3px rgb(220 38 38 / 0.10) !important;
}

/* Champ fichier invalide : l'input natif étant invisible (opacity 0),
   c'est la face qui doit indiquer l'erreur. Deux sélecteurs pour couvrir
   les navigateurs sans :has() : le premier via :has (Chrome/Safari
   modernes), le second via la classe `is-invalid` posée par le JS
   au submit CF7 (voir initCf7FileState dans site.js). */
.ivr-form .ivr-file:has(.wpcf7-not-valid) .ivr-file__face,
.ivr-form .ivr-file.is-invalid .ivr-file__face {
  border-color: #dc2626;
  border-style: solid;
  color: #b91c1c;
  background-color: #fef2f2;
}

/* Halo d'erreur autour du seul drop (pas de la liste des chips en
   dessous, qui restent lisibles avec leurs propres états). */
.ivr-form .ivr-file:has(.wpcf7-not-valid) .ivr-file__drop,
.ivr-form .ivr-file.is-invalid .ivr-file__drop {
  border-radius: var(--ivr-radius-btn);
}

/* Le tip serveur CF7 ("Ce champ est obligatoire.") est injecté DANS le
   .wpcf7-form-control-wrap, qui est display:contents → il apparaît
   entre l'input (invisible) et .ivr-file__face. Sans forçage d'ordre
   il s'affiche AU-DESSUS du drop et casse la lecture. On l'envoie en
   dernier via `order` sur le flex parent (voir .ivr-file plus haut). */
.ivr-form .ivr-file .wpcf7-not-valid-tip {
  order: 99;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
}

/* -- Spinner AJAX --------------------------------------------------- */
.ivr-form .wpcf7-spinner {
  display: inline-block;
  inline-size: 1.25rem;
  block-size: 1.25rem;
  margin-inline-start: var(--ivr-space-3);
  border-radius: 50%;
  background: transparent;
  border: 2px solid var(--ivr-border);
  border-block-start-color: var(--ivr-blue-600);
  animation: ivr-cf7-spin 720ms linear infinite;
  opacity: 0;
  transition: opacity 200ms;
}

.ivr-form form.submitting .wpcf7-spinner {
  opacity: 1;
}

@keyframes ivr-cf7-spin {
  to {
    transform: rotate(360deg);
  }
}

/* -- Foot du formulaire (item full-width) --------------------------- */
.ivr-form .ivr-form__foot {
  display: flex;
  gap: var(--ivr-space-5);
  align-items: center;
}

/* Aligner texte + slot pill dans le bouton CF7 (surplus d'espaces
   blancs dans le markup CF7 peut décaler le libellé) */
.ivr-form .ivr-btnv2 {
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   RTL — champs de formulaire
   PIÈGE : CF7 sort son wrapper `<div class="wpcf7" dir="ltr"
   lang="fr-FR">` en dur, basé sur la locale STOCKÉE du formulaire
   (fr_FR). Cet attribut `dir="ltr"` court-circuite l'héritage RTL du
   <html> et fait que toutes les descendantes calculent `text-align:
   start` = **gauche** (au lieu de droite). D'où : labels alignés à
   gauche, placeholders à gauche, chevron du select mal placé…
   → on force `direction: rtl` sur `.wpcf7` en pages arabes ; tout le
   reste des règles ci-dessous devient alors "juste" nécessaire pour
   les champs form (spec HTML des controls, `direction` ne cascade pas
   sur inputs sur tous moteurs).
   -------------------------------------------------------------------------- */
[dir="rtl"] .wpcf7,
[dir="rtl"] .wpcf7 form {
  direction: rtl;
}

[dir="rtl"] .ivr-form .ivr-input,
[dir="rtl"] .ivr-form .ivr-select,
[dir="rtl"] .ivr-form .ivr-textarea {
  direction: rtl;
  text-align: start;
}

[dir="rtl"] .ivr-form .ivr-input::placeholder,
[dir="rtl"] .ivr-form .ivr-textarea::placeholder {
  text-align: start;
  direction: rtl;
}

/* Champs tel / email / URL : le CONTENU (valeur + placeholder) doit rester
   en LTR même quand le formulaire est en arabe — un "+212" ou un
   "name@example.com" se lit de gauche à droite. Le placement dans le
   champ, lui, reste à droite pour coller à la mise en page RTL. Cette
   règle vient APRÈS la générale ci-dessus, donc elle gagne à spécificité
   égale — pas besoin de !important. */
[dir="rtl"] .ivr-form input[type="tel"],
[dir="rtl"] .ivr-form input[type="email"],
[dir="rtl"] .ivr-form input[type="url"] {
  direction: ltr;
  text-align: right;
  unicode-bidi: isolate;
}

[dir="rtl"] .ivr-form input[type="tel"]::placeholder,
[dir="rtl"] .ivr-form input[type="email"]::placeholder,
[dir="rtl"] .ivr-form input[type="url"]::placeholder {
  direction: ltr;
  text-align: right;
}

[dir="rtl"] .ivr-form .ivr-field__label,
[dir="rtl"] .ivr-form .ivr-field__hint,
[dir="rtl"] .ivr-form .wpcf7-not-valid-tip {
  text-align: start;
}

/* Select : la flèche est déjà repositionnée à gauche via `background-
   position: left …` dans le bloc [dir="rtl"] .ivr-select (voir plus haut).
   On rebalance juste le padding-inline-end pour laisser la place au
   chevron du côté gauche en RTL. */
[dir="rtl"] .ivr-form .ivr-select {
  padding-inline-end: var(--ivr-space-12);
  padding-inline-start: var(--ivr-space-5);
}

/* --------------------------------------------------------------------------
   Texte multilingue hors du contexte principal
   Ex. option arabe du switcher de langue affichée sur une page FR/EN :
   `--ivr-font-sans` = Plus Jakarta Sans (pas de glyphes arabes) → le
   navigateur tombe sur la police système par défaut (variable selon
   l'OS). On force Readex Pro sur tout élément dont `lang` commence par
   "ar" (couvre ar_MA, ar-EG…). Idem pour d'éventuels blocs isolés en
   arabe côté FR (citations, notes de bas de page).
   -------------------------------------------------------------------------- */
:lang(ar) {
  font-family: "Readex Pro", "Readex Fallback", "Plus Jakarta Sans", sans-serif;
}