/* cta-banner.css - the sitewide "30分鐘免費離婚諮詢" card fixed to the bottom of the screen.
   Owner 2026-09-28: sticky on mobile, a dynamic banner with decent motion that keeps the focus on the
   message, a big WhatsApp icon + our phone number; round 1: "more standout"; round 2 (issue #109: the
   break-out disc looked "cut off and weird"): EVERYTHING stays inside the card, the button is one
   即時查詢 pill, and the round floating pair rides up above the banner (contact-dock.css .dock-lift).
   Markup: src/components/shared/CtaBanner.astro. Layers, back to front: .cta-banner = 2px amber frame +
   drop shadow + soft amber glow; .cta-glint = a highlight that runs once round the frame (the card
   covers everything inside the frame, so it never crosses another element); .cta-card = the green card.
   site.js (dock observer) adds .is-up past 60% of a screen (.cta-mark sentinel) and drops it over .book /
   .foot-bar. Motion: keyframes only (transform / opacity / stroke-dashoffset), one 8s beat, offsets inside
   the keyframes: 0s the 30-minute dial (arc + half-face wedge) fills 12 -> 6 o'clock, 2.0-3.2s the frame
   highlight runs round once, 2.4s 免費 underline, 3.4s a light sweep across the 即時查詢 pill + glyph
   nudge (both clipped inside the pill), then still. Paused while hidden, rewound to beat 0 on show.
   Reduced motion: static, dial shown half full.
   --cta-h / --cta-b / --cta-max / --cta-pr are read by contact-dock.css to line the round pair up with
   the pill's right edge. */
:root { --cta-h: 72px; --cta-b: 10px; --cta-max: 600px; --cta-pr: 8px; }
.cta-mark { position: absolute; top: 60vh; left: 0; width: 1px; height: 1px; pointer-events: none; }

.cta-banner {
  position: fixed; z-index: 89; box-sizing: border-box;
  left: calc(10px + env(safe-area-inset-left, 0px)); right: calc(10px + env(safe-area-inset-right, 0px));
  bottom: calc(var(--cta-b) + env(safe-area-inset-bottom, 0px));
  height: var(--cta-h); max-width: var(--cta-max); margin-inline: auto; padding: 2px; border-radius: 24px;
  background: linear-gradient(135deg, #F7C866 0%, #E9A93A 50%, #D08C21 100%);
  box-shadow: 0 20px 44px -14px rgba(6,36,28,.6), 0 0 22px rgba(233,169,58,.22);
  translate: 0 calc(100% + var(--cta-b) + 24px); opacity: 0; visibility: hidden;
  transition: translate .4s cubic-bezier(.4, 0, 1, 1), opacity .3s ease-in, visibility 0s .4s;
}
.cta-banner.is-up { translate: 0 0; opacity: 1; visibility: visible;
  transition: translate .55s cubic-bezier(.34, 1.4, .64, 1), opacity .25s, visibility 0s; }

/* The frame highlight: a conic wedge on a square wider than the card, rotated once per beat and squashed
   (scale 1 x .22, applied after the rotation) so it travels the long, flat frame at an even pace; the card
   covers the middle, so it only shows in the 2px frame. Transform + opacity only. */
.cta-glint { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; }
.cta-glint::before {
  content: ""; position: absolute; left: 50%; top: 50%; width: 150%; aspect-ratio: 1; translate: -50% -50%; scale: 1 .22;
  background: conic-gradient(transparent 0deg 250deg, rgba(255,250,235,.35) 305deg, #FFFCF2 345deg, rgba(255,250,235,.7) 353deg, transparent 360deg);
  opacity: 0; animation: ctaGlint 8s linear infinite;
}

.cta-card {
  position: relative; box-sizing: border-box; height: 100%;
  display: grid; grid-template-columns: 40px minmax(0, 1fr) auto; align-items: center; gap: 8px;
  padding: 0 var(--cta-pr) 0 10px; border-radius: 22px; color: var(--white);
  background: #0F3B2E linear-gradient(135deg, #12503F 0%, #0B2E24 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14);
}

/* The 30-minute dial, on its own lighter disc: face ring, ticks, an amber wedge + arc filling the right
   half, hand, centre dot. */
.cta-dial { position: relative; width: 40px; height: 40px; border-radius: 50%;
  background: linear-gradient(160deg, #1D6A55, #14533F);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 3px 8px -3px rgba(0,0,0,.4); }
.cta-dial::before { content: ""; position: absolute; inset: -8px; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(233,169,58,.17), transparent); }
.cta-dial svg { position: relative; display: block; width: 100%; height: 100%; fill: none; stroke-linecap: round; }
.cta-ring { stroke: rgba(242,243,238,.3); stroke-width: 1.5; }
.cta-tick { stroke: rgba(242,243,238,.6); stroke-width: 1.6; }
.cta-wedge { stroke: var(--amber); stroke-opacity: .22; stroke-width: 18; stroke-linecap: butt; stroke-dasharray: 50 100;
  transform-origin: 24px 24px; transform: rotate(-90deg); animation: ctaWedge 8s linear infinite; }
.cta-arc { stroke: var(--amber); stroke-width: 3.2; stroke-dasharray: 100 100; animation: ctaArc 8s linear infinite; }
.cta-hand { stroke: var(--amber); stroke-width: 2.2; transform-origin: 24px 24px; transform: rotate(180deg);
  animation: ctaHand 8s linear infinite; }
.cta-dot { fill: var(--paper); }

.cta-text { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.cta-head { margin: 0; font-size: clamp(16px, 4.62vw, 18px); font-weight: 700; line-height: 1.3; white-space: nowrap; }
.cta-free { position: relative; color: var(--amber); }
.cta-free::after {
  content: ""; position: absolute; left: .04em; right: .04em; bottom: -2px; height: 2px; border-radius: 2px;
  background: var(--amber); transform-origin: 0 50%; animation: ctaLine 8s linear infinite;
}
/* The phone line stays one text line tall; its ::before grows the tap area to >= 44px without moving
   the visible box (or its focus ring) onto the headline. */
.cta-tel { position: relative; align-self: flex-start; display: inline-flex; align-items: center; gap: 5px;
  font-size: 13.5px; line-height: 1.4; color: var(--mute-d); text-decoration: none; white-space: nowrap; }
.cta-tel::before { content: ""; position: absolute; inset: -14px -6px; }
.cta-tel .tel { width: 13px; height: 13px; color: var(--amber); }
.cta-tel b { color: var(--paper); font-weight: 600; letter-spacing: .02em; }
.cta-tel:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; border-radius: 4px; }

/* 即時查詢: one WhatsApp-green pill (deepened from the dock disc's #25D366 so white text passes 4.5:1),
   the official glyph + white bold text. Its beat effect is a light sweep clipped inside the pill. */
.cta-wa {
  position: relative; justify-self: end; display: inline-flex; align-items: center; gap: 6px; box-sizing: border-box;
  height: 44px; padding: 0 14px 0 12px; border-radius: 999px; overflow: hidden;
  color: var(--white); text-decoration: none; font-size: 15px; font-weight: 700; line-height: 1.2;
  background: #148045 linear-gradient(155deg, #1A9A52 0%, #117A40 55%, #0B6634 100%);
  box-shadow: inset 0 1.5px 0 rgba(255,255,255,.3), inset 0 -3px 8px rgba(0,40,20,.25), 0 6px 14px -8px rgba(0,0,0,.5);
  transition: transform .3s cubic-bezier(.34, 1.56, .64, 1);
}
.cta-wa .wa { width: 20px; height: 20px; animation: ctaNudge 8s ease-in-out infinite; }
.cta-wa-tx { white-space: nowrap; letter-spacing: .04em; }
.cta-wa::after {
  content: ""; position: absolute; inset: -20% auto -20% 0; width: 45%; pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.28), transparent);
  transform: translateX(-130%) skewX(-18deg); animation: ctaShine 8s ease-in-out infinite;
}
.cta-wa:hover, .cta-wa:focus-visible { transform: scale(1.03); }
.cta-wa:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

.cta-banner:not(.is-up) *, .cta-banner:not(.is-up) ::before, .cta-banner:not(.is-up) ::after { animation-play-state: paused; }

/* Narrow phones, measured: 360 fits dial + headline + 致電 line only without 致電; below 360 the dial goes. */
@media (max-width: 379px) {
  .cta-tel-w { display: none; }
  .cta-wa { gap: 5px; padding: 0 11px 0 9px; }
}
@media (max-width: 359px) {
  .cta-card { grid-template-columns: minmax(0, 1fr) auto; padding-left: 12px; }
  .cta-dial { display: none; }
}
/* Landscape phone: compact (<= 56px tall), dial hidden, headline and phone on one row. */
@media (max-height: 500px) and (max-width: 1023px) {
  :root { --cta-h: 52px; --cta-max: 640px; --cta-pr: 4px; }
  .cta-banner { border-radius: 20px; }
  .cta-card { grid-template-columns: minmax(0, 1fr) auto; padding-left: 18px; border-radius: 18px; }
  .cta-dial { display: none; }
  .cta-text { flex-direction: row; align-items: center; gap: 16px; }
  .cta-head { font-size: 15px; }
  .cta-tel { font-size: 12.5px; }
  .cta-wa { font-size: 14px; }
  .cta-wa .wa { width: 18px; height: 18px; }
}
@media (min-width: 1024px) {
  :root { --cta-h: 84px; --cta-b: 24px; --cta-max: 760px; --cta-pr: 16px; }
  .cta-banner { left: 32px; right: 32px; border-radius: 28px; }
  .cta-card { grid-template-columns: 56px minmax(0, 1fr) auto; gap: 18px; padding-left: 16px; border-radius: 26px; }
  .cta-dial { width: 56px; height: 56px; }
  .cta-text { gap: 6px; }
  .cta-head { font-size: 24px; }
  .cta-tel { font-size: 15px; }
  .cta-wa { height: 52px; gap: 8px; padding: 0 24px 0 18px; font-size: 17px; }
  .cta-wa .wa { width: 24px; height: 24px; }
}

@keyframes ctaArc {
  0% { stroke-dashoffset: 100; opacity: 0; }
  1% { stroke-dashoffset: 100; opacity: 1; animation-timing-function: cubic-bezier(.45, .05, .3, 1); }
  27.5%, 81% { stroke-dashoffset: 0; opacity: 1; }
  88%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes ctaWedge {
  0% { stroke-dashoffset: 50; opacity: 0; }
  1% { stroke-dashoffset: 50; opacity: 1; animation-timing-function: cubic-bezier(.45, .05, .3, 1); }
  27.5%, 81% { stroke-dashoffset: 0; opacity: 1; }
  88%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes ctaHand {
  0% { transform: rotate(0); animation-timing-function: cubic-bezier(.45, .05, .3, 1); }
  27.5%, 81% { transform: rotate(180deg); opacity: 1; }
  88% { transform: rotate(180deg); opacity: 0; }
  90% { transform: rotate(0); opacity: 0; }
  96%, 100% { transform: rotate(0); opacity: 1; }
}
@keyframes ctaLine {
  0%, 30% { transform: scaleX(0); opacity: 1; animation-timing-function: cubic-bezier(.3, .7, .3, 1); }
  36.5%, 81% { transform: scaleX(1); opacity: 1; }
  88%, 100% { transform: scaleX(1); opacity: 0; }
}
/* 2.0s -> 3.2s: one lap round the frame, fading in and out at the ends. */
@keyframes ctaGlint {
  0%, 25% { transform: rotate(0deg); opacity: 0; }
  27% { opacity: 1; }
  38% { opacity: 1; }
  40%, 100% { transform: rotate(360deg); opacity: 0; }
}
/* 3.4s -> 4.6s: one light sweep across the 即時查詢 pill. */
@keyframes ctaShine {
  0%, 42.5% { transform: translateX(-130%) skewX(-18deg); }
  57.5%, 100% { transform: translateX(330%) skewX(-18deg); }
}
@keyframes ctaNudge {
  0%, 42.5%, 56.5% { transform: none; }
  45% { transform: scale(1.14) rotate(-12deg); }
  47.5% { transform: scale(1.1) rotate(10deg); }
  50% { transform: scale(1.06) rotate(-6deg); }
  52.5% { transform: scale(1.03) rotate(3deg); }
}

@media (prefers-reduced-motion: reduce) {
  .cta-banner, .cta-banner *, .cta-banner ::before, .cta-banner ::after { animation: none !important; transition: none !important; }
}
