/* =====================================================================
   Beyond Journey - "talk to an expert" nudge
   ---------------------------------------------------------------------
   The brief was a reminder that keeps coming back every few minutes to
   pull the visitor towards an expert. Repeating an interruption is the
   one version of this that reliably backfires - it trains people to hunt
   for the close button, and on a page where the only conversion is a
   phone call that is the opposite of what we want.

   So the persistence is there, but it is carried by a launcher that is
   ALWAYS on screen and never interrupts, and the interruption itself
   happens once, at a moment the visitor has shown real interest:

     launcher      a quiet pill, bottom-left, present from the start
     auto-open     once per visit, at 30s dwell or 45% scroll
     exit intent   once, on desktop, if it has not opened yet
     dismissed     collapses back to the launcher, and stays quiet for
                   seven days (js/bj-expert.js holds the cap)

   Bottom-RIGHT: the corner a thumb reaches, and the corner people look
   in for help on every site they already use. The column sits 84px up so
   the template's own #back-to-top circle continues it rather than landing
   on the pill; below 991px it clears the detail page's fixed price bar.

   Colours come from css/bj-listing.css tokens when the page loads it,
   with the brand values restated as fallbacks so this can be dropped on
   any page in the site on its own.
   ===================================================================== */

.bjx {
  --bjx-navy: var(--bjl-navy, #17233e);
  --bjx-orange: var(--bjl-orange, #f5761a);
  --bjx-orange-600: var(--bjl-orange-600, #d9600d);
  --bjx-ink: var(--bjl-ink, #17233e);
  --bjx-muted: var(--bjl-muted, #5a6377);
  --bjx-faint: var(--bjl-faint, #8b93a5);
  --bjx-line: var(--bjl-line, #e6e3dc);
  --bjx-surface: #fff;
  --bjx-ease: cubic-bezier(.4, 0, .2, 1);

  position: fixed;
  right: 20px;
  bottom: 84px;                  /* above the template's #back-to-top circle */
  z-index: 1060;                 /* over the detail page's price bar (1040) */

  display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
  font-family: var(--bjl-ui, 'Poppins', 'Segoe UI', system-ui, sans-serif);
}

/* ---------------------------------------------------------------
   The launcher - always available, never in the way
   --------------------------------------------------------------- */
/* Two lines: the desk, and what it costs to use it. A one-line pill kept
   asking a question it did not answer - people hesitate over a "talk to
   us" button because they are working out what happens next, so the
   second line says it. Left rail in orange because the eye needs one
   thing to land on in a corner that now holds three controls. */
.bjx-pill {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 9px 12px 9px 10px;
  border: 0; border-left: 3px solid var(--bjx-orange);
  border-radius: 12px;
  background: var(--bjx-navy); color: #fff;
  font-family: inherit; text-align: left;
  box-shadow: 0 12px 30px -10px rgba(11, 17, 32, .6);
  cursor: pointer;
  transition: transform .2s var(--bjx-ease), background .2s var(--bjx-ease),
              box-shadow .2s var(--bjx-ease);
}
.bjx-pill:hover {
  background: #1f2e50; transform: translateY(-2px);
  box-shadow: 0 16px 34px -10px rgba(11, 17, 32, .68);
}
/* :not() guards the medallion - an unqualified `.bjx-pill span` rule would
   capture it and knock out its display:grid, dropping the glyph into the
   corner. That trap has caught us three times elsewhere in this codebase. */
.bjx-pill__ico {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--bjx-orange); color: #fff; font-size: 13px;
}
/* The pill breathes: it folds back to the medallion and opens again on
   a two second beat, so it keeps catching the eye without ever holding
   the corner of the screen. Only the text and chevron move - the
   medallion stays exactly where it was, so the tap target never
   travels under the reader's thumb. */
.bjx-pill__txt {
  display: block; white-space: nowrap; line-height: 1.25;
  max-width: 220px; overflow: hidden;
  transition: max-width .42s var(--bjx-ease), opacity .26s var(--bjx-ease),
              margin .42s var(--bjx-ease);
}
.bjx-pill.is-mini { padding-right: 10px; gap: 0; }
.bjx-pill.is-mini .bjx-pill__txt { max-width: 0; opacity: 0; margin-left: -2px; }
.bjx-pill.is-mini .bjx-pill__go { max-width: 0; width: 0; opacity: 0; overflow: hidden; }
.bjx-pill__txt b { display: block; font-size: 13px; font-weight: 700; }
.bjx-pill__txt small {
  display: block; margin-top: 1px;
  font-size: 10px; font-weight: 600; letter-spacing: .04em;
  color: rgba(255, 255, 255, .58);
}
.bjx-pill__go {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 18px; font-size: 10px; color: rgba(255, 255, 255, .45);
  transition: transform .22s var(--bjx-ease), color .22s var(--bjx-ease),
              width .42s var(--bjx-ease), opacity .26s var(--bjx-ease);
}
.bjx-pill:hover .bjx-pill__go { transform: translateX(3px); color: var(--bjx-orange); }
.bjx.is-open .bjx-pill { display: none; }

/* ---------------------------------------------------------------
   The card
   --------------------------------------------------------------- */
.bjx-card {
  display: none;
  width: 460px; max-width: calc(100vw - 40px);
  background: var(--bjx-surface);
  border: 1px solid var(--bjx-line); border-radius: 14px;
  box-shadow: 0 18px 46px -14px rgba(11, 17, 32, .45);
  overflow: hidden;
}
.bjx.is-open .bjx-card {
  display: block;
  animation: bjx-in .26s var(--bjx-ease) both;
}
@keyframes bjx-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.bjx-card__head {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 15px 15px 12px;
  background: var(--bjx-navy); color: #fff;
}
.bjx-card__ico {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 50%;
  background: rgba(255, 255, 255, .12); color: var(--bjx-orange); font-size: 14px;
}
/* Both lines used to inherit uppercase, which suited the old two-word
   label. They are whole sentences now, and a sentence in caps reads as
   shouting rather than as a greeting. */
.bjx-card__head > span { display: block; min-width: 0; }
.bjx-card__head strong {
  display: block; font-size: 15px; font-weight: 700; line-height: 1.3;
  text-transform: none; letter-spacing: 0;
}
.bjx-card__head > span > span {
  display: block; margin-top: 3px;
  font-size: 12px; line-height: 1.45; letter-spacing: 0; text-transform: none;
  color: rgba(255, 255, 255, .68);
}
.bjx-close {
  margin-left: auto; flex: 0 0 auto;
  width: 26px; height: 26px; border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .12); color: #fff;
  font-size: 11px; cursor: pointer; transition: background .18s var(--bjx-ease);
}
.bjx-close:hover { background: rgba(255, 255, 255, .24); }

.bjx-card__body { padding: 14px 15px 15px; }
.bjx-card__body p {
  margin: 0 0 12px; font-size: 13px; line-height: 1.6; color: var(--bjx-muted);
}

.bjx-act {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; padding: 11px 14px; margin: 0 0 8px;
  border: 0; border-radius: 9px;
  background: var(--bjx-orange); color: #fff;
  font-family: inherit; font-size: 13.5px; font-weight: 700;
  text-align: center; cursor: pointer;
  transition: background .2s var(--bjx-ease);
}
.bjx-act:hover { background: var(--bjx-orange-600); color: #fff; }
.bjx-act--quiet {
  background: transparent; color: var(--bjx-ink);
  border: 1px solid var(--bjx-line); margin-bottom: 0;
}
.bjx-act--quiet:hover { background: #faf8f5; color: var(--bjx-orange-600); border-color: var(--bjx-orange); }

/* the one line that keeps this honest: what we promise, not what we
   refuse to do */
.bjx-note {
  margin: 11px 0 0; padding-top: 10px;
  border-top: 1px dashed var(--bjx-line);
  font-size: 11px; line-height: 1.55; color: var(--bjx-faint);
}

/* the field the visitor lands on after choosing "request a callback",
   so the jump is visible rather than mysterious */
.bjx-flash {
  animation: bjx-flash 1.6s var(--bjx-ease) 1;
  border-radius: 8px;
}
@keyframes bjx-flash {
  0%, 100% { box-shadow: 0 0 0 0 rgba(245, 118, 26, 0); }
  25%      { box-shadow: 0 0 0 4px rgba(245, 118, 26, .3); }
}

/* The booking journey and the package detail page both park a bar along
   the bottom of a phone. Where one exists the dock steps above it
   rather than sitting on its shoulder. Browsers without :has() keep the
   84px default, which clears the bar on all but the tallest of them. */
@media (max-width: 767px) {
  body:has(.bjb-mobilebar) .bjx,
  body:has(.bjd-mobilebar) .bjx { bottom: 150px; }
}

@media (max-width: 991px) {
  /* clears the package detail page's fixed price bar */
  .bjx { right: 12px; bottom: 88px; }
  .bjx-card { width: 400px; max-width: calc(100vw - 24px); }
}

@media (max-width: 575px) {
  .bjx { bottom: 80px; }
}

@media (prefers-reduced-motion: reduce) {
  .bjx.is-open .bjx-card { animation: none; }
  .bjx-flash { animation: none; }
  .bjx-pill:hover { transform: none; }
}

/* =====================================================================
   The action dock
   ---------------------------------------------------------------------
   Three controls in one column at the bottom-right: call, WhatsApp, and
   the pill that opens the card. Right rather than left because that is
   the corner a thumb reaches and the corner people look in for help on
   every site they already use.

   It sits 84px up so the template's own #back-to-top circle (fixed,
   bottom:20px right:20px, 50px across) continues the same column instead
   of landing on top of the pill.

   On phones the pill drops its label and becomes a third circle: three
   round icons take a fraction of the width, and the label is restated
   inside the card the moment it opens.
   ===================================================================== */
.bjx-dock {
  display: flex; flex-direction: column; align-items: flex-end; gap: 9px;
}
.bjx.is-open .bjx-dock { display: none; }

.bjx-dock__btn {
  display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: 50%;
  color: #fff; font-size: 15px; text-decoration: none;
  box-shadow: 0 8px 22px -8px rgba(11, 17, 32, .5);
  transition: transform .2s var(--bjx-ease), filter .2s var(--bjx-ease);
}
.bjx-dock__btn:hover,
.bjx-dock__btn:focus-visible { color: #fff; transform: translateY(-2px); filter: brightness(1.08); }
.bjx-dock__btn--call { background: var(--bjx-navy); }
.bjx-dock__btn--wa { background: #25d366; }
.bjx-dock__btn svg { display: block; }

/* The icons breathe in once, on arrival, one after another.

   Scoped to .is-entering, which js/bj-expert.js strips a second later,
   and NOT to `.bjx-dock > *`: the reminder nod below sets `animation` on
   the same elements, so an always-on rule here meant every nod replaced
   the entrance and then handed it back - re-running the fade-from-zero
   each time a reminder appeared. The icons blinked out every twenty
   seconds and it read as a rendering fault. */
.bjx-dock.is-entering > * { animation: bjx-rise .45s var(--bjx-ease) both; }
.bjx-dock.is-entering > :nth-child(1) { animation-delay: .15s; }
.bjx-dock.is-entering > :nth-child(2) { animation-delay: .28s; }
.bjx-dock.is-entering > :nth-child(3) { animation-delay: .41s; }
@keyframes bjx-rise {
  from { opacity: 0; transform: translateY(12px) scale(.85); }
  to   { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------
   The reminder
   ---------------------------------------------------------------
   Sits above the dock, right-aligned with it, and clears itself after
   seven seconds. Twice a visit at most - js/bj-expert.js holds that cap
   and the reason for it.
   --------------------------------------------------------------- */
.bjx-tip {
  order: -1;                     /* appended last in the DOM, drawn on top */
  display: flex; align-items: flex-start; gap: 10px;
  width: 268px; max-width: calc(100vw - 32px);
  padding: 11px 12px;
  background: var(--bjx-surface);
  border: 1px solid var(--bjx-line); border-left: 3px solid var(--bjx-orange);
  border-radius: 12px;
  box-shadow: 0 14px 34px -12px rgba(11, 17, 32, .4);
  cursor: pointer; text-align: left;
  opacity: 0; transform: translateY(8px);
  transition: opacity .3s var(--bjx-ease), transform .3s var(--bjx-ease);
}
.bjx-tip.is-in { opacity: 1; transform: none; }
.bjx-tip:hover { border-color: var(--bjx-orange); }

/* :not() guards the medallion: an unqualified `.bjx-tip span` rule would
   capture it too and knock out its display:grid, dropping the glyph into
   the corner. This has caught us out three times elsewhere. */
.bjx-tip__ico {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 28px; height: 28px; border-radius: 50%;
  background: #fdf0e4; color: var(--bjx-orange); font-size: 12px;
}
.bjx-tip__txt {
  flex: 1 1 auto;
  font-size: 11.5px; line-height: 1.5; color: var(--bjx-muted);
}
.bjx-tip__txt b {
  display: block; margin-bottom: 1px;
  font-size: 12.5px; font-weight: 700; color: var(--bjx-ink);
}
.bjx-tip__x {
  flex: 0 0 auto; align-self: flex-start;
  width: 20px; height: 20px; padding: 0;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--bjx-faint);
  font-size: 10px; line-height: 1; cursor: pointer;
  transition: background .18s var(--bjx-ease), color .18s var(--bjx-ease);
}
.bjx-tip__x:hover { background: #f2efe9; color: var(--bjx-ink); }

/* The dock nods once each time a reminder comes up. It is the "hide and
   unhide" half of the brief: the words arrive, the icons acknowledge
   them, and a reader whose eye is elsewhere on the page still catches the
   movement in the corner. One beat, then still - a permanently animating
   control is just a distraction with a phone number on it. */
.bjx.is-nudging .bjx-dock__btn,
.bjx.is-nudging .bjx-pill { animation: bjx-nod .7s var(--bjx-ease) 2; }
.bjx.is-nudging .bjx-dock__btn--wa { animation-delay: .1s; }
.bjx.is-nudging .bjx-pill { animation-delay: .2s; }
@keyframes bjx-nod {
  0%, 100% { transform: none; }
  30% { transform: translateX(-5px); }
  60% { transform: translateX(2px); }
}

@media (max-width: 991px) {
  /* label off, so the dock is three circles hugging the edge and never
     covers the copy on a narrow page */
  .bjx-pill {
    padding: 0; width: 46px; height: 46px;
    justify-content: center; border-radius: 50%; border-left: 0;
  }
  .bjx-pill__txt, .bjx-pill__go { display: none; }
  .bjx-pill__ico { width: 30px; height: 30px; font-size: 13px; }
  .bjx-dock__btn { width: 42px; height: 42px; font-size: 14px; }
}

@media (prefers-reduced-motion: reduce) {
  .bjx-dock.is-entering > * { animation: none; }
  .bjx.is-nudging .bjx-dock__btn,
  .bjx.is-nudging .bjx-pill { animation: none; }
  .bjx-tip { transition: opacity .01s; transform: none; }
  .bjx-dock__btn:hover { transform: none; }
}
