/* components.css - buttons, lists, links, reveal animation */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 26px;
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-display);
  font-size: var(--fs-body);
  font-weight: var(--w-ui);
  letter-spacing: .05em;
  text-transform: uppercase;
  line-height: 1.1;
  cursor: pointer;
  transition: background .2s var(--ease), color .2s var(--ease),
              border-color .2s var(--ease), transform .2s var(--ease);
}

.btn:hover { text-decoration: none; transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--primary {
  background: var(--green);
  border-color: var(--green);
  color: var(--white);
}
.btn--primary:hover {
  background: var(--green-dark);
  border-color: var(--green-dark);
  color: var(--white);
}

.btn--outline {
  background: transparent;
  border-color: var(--blue);
  color: var(--blue);
}
.btn--outline:hover {
  background: var(--blue);
  color: var(--white);
}

.btn--ghost {
  background: rgba(255, 255, 255, .08);
  border-color: rgba(255, 255, 255, .6);
  color: var(--white);
}
.btn--ghost:hover {
  background: var(--white);
  border-color: var(--white);
  color: var(--blue-dark);
}

.btn--light {
  background: var(--white);
  border-color: var(--white);
  color: var(--blue-dark);
}
.btn--light:hover {
  background: #eef4fb;
  border-color: #eef4fb;
  color: var(--blue-dark);
}

.btn--lg { padding: 16px 32px; font-size: var(--fs-body); }
.btn--block { display: flex; width: 100%; }

.textlink {
  font-family: var(--font-display);
  font-size: var(--fs-body);
  font-weight: var(--w-ui);
  letter-spacing: .01em;
  color: var(--blue);
  border-bottom: 2px solid var(--green);
  padding-bottom: 2px;
}
.textlink:hover { color: var(--blue-dark); text-decoration: none; border-color: var(--blue-dark); }

.ticklist { margin: 22px 0 0; }

.ticklist li {
  position: relative;
  padding: 6px 0 6px 30px;
  font-size: var(--fs-body);
}

.ticklist li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 19px;
  width: 9px;
  height: 5px;
  border-left: 2.5px solid var(--green);
  border-bottom: 2.5px solid var(--green);
  transform: rotate(-45deg);
}

.ticklist--two {

  gap: 0 24px;
}

/* Scroll reveal. Content is visible by default and only hidden once
   JS confirms it can animate, so the page is never blank. */
.js-reveal.is-armed {
  opacity: 0;
  transform: translateY(18px);
}

.js-reveal.is-armed.is-in {
  opacity: 1;
  transform: none;
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}

/* Sticky action bar, mobile only. */
/* Anything fixed to the bottom hides the end of the page behind it. The
   footer gets padding to match, or the last links are unreachable. */
body { --callbar-h: 0px; }

.callbar {
  display: none;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 70;
  grid-template-columns: repeat(3, 1fr);
  background: var(--white);
  border-top: 1px solid var(--line);
  box-shadow: 0 -2px 14px rgba(22, 32, 46, .12);
  padding-bottom: env(safe-area-inset-bottom);
}

.callbar__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 9px 6px 10px;
  text-align: center;
  font-family: var(--font-display);
  font-size: var(--fs-micro);
  font-weight: var(--w-ui);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--blue-dark);
}

.callbar__item .icon { width: 21px; height: 21px; }
.callbar__item:hover { text-decoration: none; }
.callbar__item--wa { color: var(--green-dark); }
.callbar__item--book { background: var(--green); color: var(--white); }

/* ------------------------------------------------------------------
   Button consistency pass
   Buttons sat at different heights depending on whether they were an
   <a> or a <button>, and on whether the label wrapped to two lines.
------------------------------------------------------------------- */

.btn {
  min-height: 48px;
  text-align: center;
  text-wrap: balance;
}

.btn--lg { min-height: 54px; }

/* Buttons sitting next to each other in a row now match width behaviour
   instead of one stretching and the other not. */
.hero__actions .btn,
.cta__actions .btn,
.review__actions .btn { flex: 0 1 auto; }

/* Disabled buttons must not still look clickable. The sending state is
   already handled by .bookform.is-sending .btn in forms.css. */
.btn[disabled] {
  opacity: .6;
  pointer-events: none;
  transform: none;
}


/* ------------------------------------------------------------------
   Floating WhatsApp button
   Hidden on phones, where the sticky call bar already carries WhatsApp,
   so the two never overlap.
------------------------------------------------------------------- */

.wa-float {
  position: fixed;
  left: 22px;
  bottom: 22px;
  z-index: 65;
  display: inline-flex;
  align-items: center;
  gap: 0;
  height: 58px;
  padding: 0 18px;
  border-radius: 999px;
  background: #25d366;
  color: var(--white);
  box-shadow: 0 8px 24px rgba(12, 60, 30, .3);
  transition: gap .28s var(--ease), padding .28s var(--ease),
              transform .2s var(--ease), box-shadow .2s var(--ease);
}

.wa-float .icon {
  width: 30px;
  height: 30px;
  color: var(--white);
}

/* The label is folded away until hover, so the button stays a small bubble
   and does not sit over the content. */
.wa-float__label {
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  font-family: var(--font-display);
  font-size: var(--fs-body);
  font-weight: var(--w-ui);
  letter-spacing: .04em;
  text-transform: uppercase;
  transition: max-width .28s var(--ease);
}

.wa-float:hover,
.wa-float:focus-visible {
  gap: 10px;
  text-decoration: none;
  transform: translateY(-2px);
  box-shadow: 0 12px 30px rgba(12, 60, 30, .38);
}

.wa-float:hover .wa-float__label,
.wa-float:focus-visible .wa-float__label { max-width: 190px; }

@media (prefers-reduced-motion: reduce) {
  .wa-float,
  .wa-float__label { transition: none; }
  .wa-float:hover { transform: none; }
}

/* ------------------------------------------------------------------
   Assistant launcher
   Lives here rather than in chat.css because the button is on the page
   from the start, while chat.css is only fetched when someone opens it.
------------------------------------------------------------------- */

.chat-launch {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 66;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 58px;
  padding: 0 22px 0 18px;
  border: 0;
  border-radius: 999px;
  background: var(--blue);
  color: var(--white);
  font-family: var(--font-display);
  font-size: var(--fs-body);
  font-weight: var(--w-h1);
  letter-spacing: .04em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(12, 40, 80, .32);
  transition: transform .2s var(--ease), box-shadow .2s var(--ease), opacity .2s var(--ease);
}

.chat-launch:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 30px rgba(12, 40, 80, .4);
}

.chat-launch.is-hidden {
  opacity: 0;
  pointer-events: none;
  transform: scale(.9);
}

.chat-launch__icon { display: grid; place-items: center; }
.chat-launch__icon .icon { width: 26px; height: 26px; }

/* The ring is a pseudo element animating transform and opacity, so it runs
   on the compositor and never repaints the button. It also stops after a
   few passes rather than running for the life of the page. */
.chat-launch__dot {
  position: relative;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--green);
}

.chat-launch__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--green);
  opacity: 0;
  animation: chat-ping 2.4s var(--ease) 5;
}

@keyframes chat-ping {
  0%   { transform: scale(1);   opacity: .7; }
  70%  { transform: scale(3.4); opacity: 0; }
  100% { transform: scale(3.4); opacity: 0; }
}


/* ------------------------------------------------------------------
   Card form placeholder
   Between the click on pay and Stripe's iframe appearing there are three
   round trips: our server, Stripe's session API, then Stripe's own form.
   None of that can be removed, because the amount is not known until the
   customer types it. What can be removed is the blank box they stare at
   while it happens, which is what makes the wait read as broken.
------------------------------------------------------------------- */

.pay-skeleton {
  display: grid;
  gap: 14px;
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--white);
}

.pay-skeleton__label {
  margin: 0 0 4px;
  font-size: var(--fs-small);
  color: var(--muted);
}

.pay-skeleton__bar {
  height: 44px;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--band) 25%, #e8eef6 37%, var(--band) 63%);
  background-size: 400% 100%;
  animation: pay-shimmer 1.4s var(--ease) infinite;
}

.pay-skeleton__bar--short { width: 55%; }

@keyframes pay-shimmer {
  0%   { background-position: 100% 0; }
  100% { background-position: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  .pay-skeleton__bar { animation: none; }
}
/* Mobile view fix for Assistant Launcher */
@media (max-width: 680px) {
  .chat-launch {
    right: 16px;
    /* Sticky call bar-க்கு மேல float ஆக */
    bottom: calc(78px + env(safe-area-inset-bottom)); 
    width: 52px;
    height: 52px;
    padding: 0;
    border-radius: 50%;
    z-index: 99; /* Callbar (z-index: 70) mela theria z-index 99 */
    justify-content: center;
    gap: 0;
  }

  /* Text and Green dot-a mobile-la hide panna */
  .chat-launch__text,
  .chat-launch__dot {
    display: none !important;
  }

  /* Icon-a center-la position panna */
  .chat-launch__icon {
    margin: 0;
  }
}