/* ============================================================
   Promo bar "Jeu concours Céline Dion".

   One markup block, reshaped by media query — the mobile bar and the desktop
   card share the same inner structure, so there is no reason to ship both.

   The numbers below are taken from this site, not from the export mock-up:
   - .mobile-nav is 56px tall and disappears at 1200px, so that is where the
     mobile/desktop switch happens (the export assumed 901px, which would have
     left the bar floating over the tab-bar between 901 and 1200);
   - z-index 1090 keeps the bar under .common-up (1100), .fixed-phones (1101),
     .mobile-nav (1102) and .rgpd (1103) — the promo must never cover
     navigation or the cookie banner;
   - the desktop card sits in the bottom LEFT corner, which also keeps it clear
     of .common-up on the right;
   - on voyant phones .fixed-phones already occupies bottom:56px, so the bar
     stacks above it.
   ============================================================ */

.avt-promo,
.avt-promo *,
.avt-promo-cube,
.avt-promo-cube * { box-sizing: border-box; }

/* [hidden] has to beat display:flex */
.avt-promo[hidden],
.avt-promo-cube[hidden] { display: none !important; }

/* ---------- Bar, mobile layout (default) ---------- */
.avt-promo {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 56px;                 /* .mobile-nav height */
  width: 100%;
  max-width: 430px;
  z-index: 1090;
  padding: 0 8px 8px;
  animation: avtPromoUp .24s ease-out forwards;
}
.avt-promo-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 40px 11px 11px;
  border-radius: 12px;
  background: linear-gradient(96deg, #6B32DC 0%, #5F27CD 52%, #4B2C87 100%);
  box-shadow: 0 2px 4px rgba(23, 12, 42, .1), 0 10px 26px rgba(95, 39, 205, .34);
  overflow: hidden;
  text-decoration: none;
}
.avt-promo-line {               /* gold hairline, top edge on mobile */
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 2px;
  background: linear-gradient(90deg, #E9C77B, rgba(233, 199, 123, 0));
}
/* Bare emoji, no medallion behind it. Deliberately no width/height: emoji metrics
   differ between platforms, and a fixed box sized to macOS would clip the glyph on
   systems that draw it taller — the bar carries overflow:hidden on phones. Letting
   the glyph size itself cannot clip, and it does not move the bar either: the row
   height is set by the two-line title next to it, which is taller. Scale is
   controlled by font-size alone. */
.avt-promo-face {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 30px;
  line-height: 1;
}
.avt-promo-text {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.avt-promo-title {
  text-wrap: balance;
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -.2px;
  color: #fff;
}
.avt-promo-timer {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 10px;
  font-weight: 700;
  color: #F0D9A8;
  white-space: nowrap;
}
.avt-promo-dot {
  width: 4px; height: 4px; min-width: 4px;
  border-radius: 50%;
  background: #E9C77B;
  animation: avtPulseDot 1.8s infinite;
}
.avt-promo-cta {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 30px;
  padding: 0 11px;
  border-radius: 8px;
  background: #fff;
  color: #5F27CD;
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
}
.avt-promo-close {
  position: absolute;
  top: -6px;
  right: 2px;
  width: 30px; height: 30px;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #DCD8F5;
  border-radius: 50%;
  background: #fff;
  color: #706DB0;
  font-family: inherit;
  box-shadow: 0 2px 6px rgba(115, 115, 167, .2);
}

/* ---------- Swipe to dismiss ----------
   The offsets ride on custom properties so the drag composes with whatever
   transform the layout already uses: on phones the wrapper is centred with
   translateX(-50%), on desktop it is not, and the entrance keyframes hold their
   own transform with animation-fill-mode:forwards. Moving the inner elements
   instead of the wrapper sidesteps all three.

   touch-action:none on the wrapper: without it the browser scrolls the page on a
   downward drag and the gesture never reaches the script. Only the bar carries it,
   the cube keeps normal behaviour. Taps are unaffected — the CTA still opens. */
.avt-promo { touch-action: none; }

.avt-promo-bar,
.avt-promo-close {
  transform: translate(var(--avt-dx, 0px), var(--avt-dy, 0px));
  transition: transform .22s ease, opacity .22s ease;
}
.avt-promo-bar { opacity: var(--avt-op, 1); }

/* Пока палец на экране — никаких переходов, иначе элемент тянется за пальцем с запозданием */
.avt-promo--dragging .avt-promo-bar,
.avt-promo--dragging .avt-promo-close { transition: none; }

/* ---------- Collapsed state: 54x54 cube ---------- */
/* Куб держится за левый край экрана.

   Здесь была привязка к левой границе 430-пиксельной колонки, по которой
   выравнивается сама полоса: left: max(10px, calc(50% - 215px + 10px)).
   На узком телефоне это те же 10px, но как только экран шире 430px, выражение
   растёт вместе с ним — и куб уезжает к центру: на 568px он оказывался в 79px
   от края, на 667px в 137px, то есть на пятой части экрана. Ловится это только
   в альбомной ориентации телефона, поэтому и всплыло не у всех: у аппаратов с
   альбомной шириной от 768px работает десктопное правило с left: 24px, и там
   всё выглядело правильно. */
.avt-promo-cube {
  position: fixed;
  bottom: 74px;                                  /* clears the tab-bar */
  left: 10px;                                    /* к краю экрана, а не к колонке */
  z-index: 1090;
  width: 54px; height: 54px;
  padding: 0;
  cursor: pointer;
  border: none;
  border-radius: 12px;
  background: linear-gradient(160deg, #6B32DC, #4B2C87);
  box-shadow: 0 8px 20px rgba(95, 39, 205, .36);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  font-family: inherit;
  animation: avtCubeIn .2s ease-out forwards;
}
.avt-promo-cube span {
  font-size: 26px;
  line-height: 1;
}

/* ---------- Voyant profile: out of the way on phones ----------
   The profile already carries .fixed-phones, a 100px panel at bottom:56px with
   the call buttons. Together with the tab bar and the promo that was three fixed
   layers stacked on a phone screen, so the bar steps aside there entirely.

   Keyed off the presence of .fixed-phones rather than off the URL: the panel is
   what creates the conflict, it lives only in voyant.tpl and
   voyant/voyant-phone-fixed.tpl, and it is in the DOM on every voyant profile
   whether the voyant is online or not (offline it only gets .fixed-phones--hidden).
   Phones only: from 768px style.css hides the panel with visibility:hidden, and
   the promo is a small corner card by then, so the two no longer collide. */
@media (max-width: 767px) {
  body:has(.fixed-phones) .avt-promo,
  body:has(.fixed-phones) .avt-promo-cube { display: none !important; }
}

/* ---------- Recrutement ----------
   That page has its own sticky CTA, .recrute-button at bottom:68px with z-index 1,
   which the bar would cover. But .recrute-button is itself switched off from 1200px
   (display:none !important in style.css), so the conflict exists on phones and
   tablets only and the desktop card can stay.
   body.recrutement is set by the PHP layer, so this holds whatever the URI is. */
@media (max-width: 1199px) {
  body.recrutement .avt-promo,
  body.recrutement .avt-promo-cube { display: none !important; }
}

/* ═══ Портрет в верхнем баннере главной ══════════════════════════════════════
   ВРЕМЕННАЯ ПОДМЕНА, а не штатное место для этого.

   Сам баннер (.bannerMain) не в репозитории: его HTML вместе с инлайновыми
   стилями лежит в базе и приходит через $banner->bannerCode в index-banners.tpl.
   Картинка отдаётся с img.gestion.ph — это отдельный vhost на том же сервере,
   принадлежащий другой подписке, записи туда у нас нет.

   Поэтому фото подменяется здесь: content: url() заменяет содержимое <img>,
   не трогая ни базу, ни CDN. Высоты подняты так, чтобы отрисованная ширина
   совпала с прежним портретом (у нового кадра отношение 0.75 против 0.91,
   при той же высоте он был бы на 18% уже и место под текст поехало бы).
   Низ уходит под overflow:hidden баннера — тем же приёмом баннер уже кропит
   портрет на телефонах штатно.

   КАК УБРАТЬ ПРАВИЛЬНО: загрузить celine-hero.webp на CDN и поменять src в
   разметке баннера в админке, после чего весь этот блок удалить.
   ═══════════════════════════════════════════════════════════════════════════ */
.bannerMain .bPortrait {
  content: url("/avenirtel.fr/img/promo/celine-hero.webp");
  object-position: 50% 0%;
}
/* Десктоп: крупнее и левее по просьбе. Правая привязка сдвинута с 6% (значение
   из базы) до 9%, высота с 365 до 500px — левый край уезжает с 946 на 810px при
   баннере 1140px. До текста остаётся 42px: заголовок занимает коробку 660px, но
   сами буквы кончаются на 768px, отсюда и запас. Видно верхние 60% кадра — голова
   и жест с рукой у груди попадают целиком, ниже режет контейнер. */
/* top с !important: в разметке из базы у .bPortrait стоит top: 0 !important, и без
   этого объявление проигрывает независимо от специфичности селектора.
   -24px из измерения: в исходнике 61 прозрачная строка над волосами (6.8% от 900),
   при высоте отрисовки 500px это 34px пустоты сверху. Поднимаем на 24, оставляя
   10px воздуха над головой. */
@media (min-width: 1201px) { .bannerMain .bPortrait { height: 500px; right: 9%; top: -24px !important; } }
@media (max-width: 1200px) { .bannerMain .bPortrait { height: 292px; } }
@media (max-width: 768px)  { .bannerMain .bPortrait { height: 216px; } }
@media (max-width: 380px)  { .bannerMain .bPortrait { height: 204px; } }
@media (max-width: 340px)  { .bannerMain .bPortrait { height: 183px; } }

/* ---------- Phones: hold the bar back on the home page ----------
   On phones the bar is a full width strip. On the home page it would land right
   under the hero slider that carries the SAME campaign — two Céline Dion offers
   on one screen at once. So there it stays out of the way until the hero slider
   has scrolled off. Every other page has nothing to clash with and shows the bar
   straight away. promo-celine.js decides when and only adds the body class.

   The gate is CSS, not JS, deliberately: the script is deferred, so hiding from
   JS would let the bar paint first and then vanish. Above 767px the rule does not
   exist at all — the corner card shows immediately, as before. */
@media (max-width: 767px) {
  body:not(.avt-promo-ready) .avt-promo,
  body:not(.avt-promo-ready) .avt-promo-cube { display: none !important; }
}

/* ---------- Narrow phones ---------- */
@media (max-width: 400px) {
  .avt-promo-title { font-size: 11.5px; line-height: 1.2; letter-spacing: -.25px; }
  .avt-promo-cta { padding: 0 8px; font-size: 10.5px; height: 28px; }
  .avt-promo-face { font-size: 24px; }
  .avt-promo-bar { padding-right: 24px; padding-left: 8px; gap: 8px; }
}
@media (max-width: 380px) {
  .avt-promo-title { font-size: 11px; line-height: 1.18; }
}
@media (max-width: 345px) {
  .avt-promo-title { font-size: 10px; line-height: 1.16; letter-spacing: -.35px; text-wrap: pretty; }
  .avt-promo-cta { padding: 0 6px; font-size: 10.5px; height: 26px; }
  .avt-promo-bar { padding-right: 20px; padding-left: 6px; gap: 6px; }
  .avt-promo-face { font-size: 22px; }
  .avt-promo-timer { font-size: 9.5px; }
}

/* ---------- Tablet and desktop: floating card, bottom left ----------
   From 768px the full width bar turns into a compact card pinned to the bottom
   left corner. The offset differs by range, because the tab bar does not:
   .mobile-nav is still on screen up to 1200px, so between 768 and 1199 the card
   sits at 80px (56px tab bar + the same 24px visual gap the desktop card has),
   and only from 1200px does it drop to 24px off the bottom edge. */
@media (min-width: 768px) {
  .avt-promo {
    left: 24px;
    right: auto;
    bottom: 80px;
    transform: none;
    width: auto;
    max-width: none;
    padding: 0;
    animation: avtCubeIn .2s ease-out forwards;
  }
  .avt-promo-bar {
    display: inline-flex;
    gap: 10px;
    padding: 9px 22px 9px 14px;
    background: linear-gradient(150deg, #6B32DC 0%, #5F27CD 58%, #4B2C87 100%);
    box-shadow: 0 10px 28px rgba(75, 44, 135, .38);
    overflow: visible;
    border-radius: 12px;
  }
  .avt-promo-line {             /* gold hairline moves to the left edge */
    left: 0;
    right: auto;
    top: 10px;
    bottom: 10px;
    width: 3px;
    height: auto;
    border-radius: 0 3px 3px 0;
    background: #F0D9A8;
  }
  .avt-promo-face { font-size: 28px; }
  .avt-promo-text { max-width: 210px; flex: 0 1 auto; }
  .avt-promo-title { font-size: 13px; letter-spacing: -.25px; color: #FBF9FF; }
  .avt-promo-timer { font-size: 11px; }
  .avt-promo-dot { background: #F0D9A8; }
  .avt-promo-cta { height: 32px; padding: 0 12px; margin-left: -2px; font-size: 12px; }
  .avt-promo-close { top: -8px; right: -8px; width: 28px; height: 28px; }

  .avt-promo-cube {
    left: 24px;
    right: auto;
    bottom: 80px;
  }
}

/* Tab bar is gone from here, so the card drops to the bottom edge. */
@media (min-width: 1200px) {
  .avt-promo,
  .avt-promo-cube { bottom: 24px; }
}

/* ---------- Scroll-to-top button vs the promo ----------
   On phones the bar spans the full width and the button sits on top of it, so the
   button steps aside entirely while the bar is out. It comes back as soon as the
   bar is collapsed to the cube: the cube is 54px in the left corner and the button
   is on the right, so there is nothing left to collide with.
   From 768px the card sits in the bottom LEFT corner while .common-up stays on the
   right, so above that the button is never touched.
   body:not(.recrutement) matters: below 1200px the bar there is display:none, but
   :has(.avt-promo:not([hidden])) still matches — the element is in the DOM and the
   hidden ATTRIBUTE is not what hides it — so without this the button would be
   lifted on /recrutement to clear a bar that is not on screen.
   body.avt-promo-ready is part of the condition for the same reason it is on
   /recrutement: while the bar is still held back it is display:none, but
   :has(.avt-promo:not([hidden])) keeps matching, and the arrow would be pushed up
   to clear something that is not on screen yet.
   Offsets leave a 24px gap above the bar — at 136px the arrow sat 4px from it.
   :not(:has(.fixed-phones)) is the same guard for the voyant profile, where the
   bar is now hidden outright. */
@media (max-width: 767px) {
  body.avt-promo-ready:not(.recrutement):not(:has(.fixed-phones)):has(.avt-promo:not([hidden])) .common-up { display: none !important; }
}

@keyframes avtPromoUp {
  from { transform: translateX(-50%) translateY(14px); opacity: 0; }
  to   { transform: translateX(-50%) translateY(0); opacity: 1; }
}
@keyframes avtCubeIn {
  from { transform: scale(.7); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}
@keyframes avtPulseDot {
  0%, 100% { opacity: 1; }
  50%      { opacity: .25; }
}

@media (prefers-reduced-motion: reduce) {
  .avt-promo,
  .avt-promo-cube { animation: none; }
  .avt-promo-dot { animation: none; }
  .avt-promo-bar,
  .avt-promo-close { transition: none; }
}
