/* contact-dock.css - the floating WhatsApp + call pair, bottom right, every page, every width.
   v2 (owner 2026-09-27: v1 "very crappy-looking ... expecting a much better design"; keep it a
   floating WhatsApp button + call button, with "reasonable and decent effects" that draw the eye).
   Markup (src/layouts/Base.astro): .contact-dock > a.dock-btn.dock-tel, a.dock-btn.dock-wa - call on
   top, WhatsApp at the bottom (the thumb spot). Owner 2026-09-28 "ensure both icon same size": both
   discs are one size and both glyphs are DRAWN the same size - the WhatsApp path fills its whole 24-unit
   box, the phone path only 18 of 24 units (3..21), so the phone <i> box is 4/3 of the WhatsApp one. Each button =
   .dock-face (the coloured disc + its shine) + <i> icon + .dock-tx label chip.
   WhatsApp keeps data-wa + .wa-pulse so the GTM link-click trigger (issue #65) and the offscreen
   pause observer in site.js still see it; this file overrides wa-pulse's own ring + wiggle.
   Motion, all on one 8s beat so the two buttons take turns and never shout at once:
     - WhatsApp: at 0s of the beat - two thin rings spread out, the icon nudges, a faint light sweep;
       label chip "WhatsApp 查詢" peeks out every 16s (touch screens too - words, not just icons).
     - Call: phone-ring shake + one amber ring at 4s of the beat. Between bursts both sit still
       (v2 review: an always-on ripple read as a stock WordPress chat plugin).
     - Entrance: both pop in with a small overshoot. Hover/focus: lift + label.
   site.js adds .dock-away while the page's own booking block (.book) is on screen.
   prefers-reduced-motion: everything static; labels still show on hover/focus. */
.contact-dock {
  --wa: 58px; --tel: 58px; --ring: 2px; --ring-grow: 1.35;
  position: fixed; z-index: 90;
  right: calc(14px + env(safe-area-inset-right, 0px));
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  width: var(--wa);
  display: flex; flex-direction: column; align-items: center; gap: 20px;
  transition: translate .5s cubic-bezier(.4, 0, .2, 1), opacity .35s, visibility 0s;
}
.contact-dock.dock-away { translate: 0 calc(100% + 48px); opacity: 0; visibility: hidden; pointer-events: none;
  transition: translate .5s cubic-bezier(.4, 0, .2, 1), opacity .35s, visibility 0s .5s; }
/* While away the pair is hidden from focus / screen readers (visibility flips only after the slide) and
   its 8s beat is paused, so nothing animates off screen (idle budget, issue #45). !important because the
   per-button animation shorthands below (e.g. .dock-wa.wa-pulse .wa) out-rank this selector. */
.contact-dock.dock-away *, .contact-dock.dock-away::before, .contact-dock.dock-away::after,
.contact-dock.dock-away *::before, .contact-dock.dock-away *::after { animation-play-state: paused !important; }
/* CTA banner (cta-banner.css) states, set by site.js while the banner is up:
   .dock-lift (default data-cta-dock="lift"; owner 2026-09-28 round 2, issue #109: "have those floating
     button go up a bit so that it won't overlap with the banner") - BOTH round discs stay and ride up with
     the banner (its entrance easing / duration): the lower disc's bottom sits 14px above the card's amber
     frame, and on phones / tablets the column's right edge lines up with the 即時查詢 pill's right edge
     (banner right inset + 2px frame + card padding --cta-pr). Desktop: the pair stays in its corner (the
     centred card never reaches it).
   .dock-call ("call") - the round call disc stays, the round WhatsApp disc tucks away (hidden from focus/AT,
     its beat paused); the call disc already clears the card by 14px (18 + wa + 20 = cta-b + cta-h + 14).
   .dock-away ("handoff") - the whole pair tucks away (rule above).
   Both bottoms carry the same safe-area inset, so it cancels out of the vertical distances. */
/* The dock box itself never takes taps (its hidden WhatsApp slot in call mode sat over the banner once and
   swallowed its taps - measured hit area 1x1 px) - only its visible buttons do. */
.contact-dock { pointer-events: none; }
.contact-dock .dock-btn { pointer-events: auto; }
.contact-dock.dock-away .dock-btn, .contact-dock.dock-call .dock-wa { pointer-events: none; }
.contact-dock .dock-wa { transition: transform .35s cubic-bezier(.34, 1.56, .64, 1), box-shadow .35s, opacity .3s, scale .35s, visibility 0s; }
.contact-dock.dock-call .dock-wa { opacity: 0; scale: .6; visibility: hidden; pointer-events: none;
  transition: transform .35s cubic-bezier(.34, 1.56, .64, 1), box-shadow .35s, opacity .3s, scale .35s, visibility 0s .35s; }
.contact-dock.dock-call .dock-wa, .contact-dock.dock-call .dock-wa *, .contact-dock.dock-call .dock-wa::before,
.contact-dock.dock-call .dock-wa::after, .contact-dock.dock-call .dock-wa *::before,
.contact-dock.dock-call .dock-wa *::after { animation-play-state: paused !important; }
.contact-dock.dock-lift {
  translate: calc(14px + env(safe-area-inset-right, 0px) - max(10px + env(safe-area-inset-right, 0px), (100vw - var(--cta-max, 600px)) / 2) - 2px - var(--cta-pr, 8px))
    calc(18px - var(--cta-b, 10px) - var(--cta-h, 72px) - 14px);
  transition: translate .55s cubic-bezier(.34, 1.4, .64, 1), opacity .35s, visibility 0s;
}

.dock-btn {
  position: relative; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  -webkit-tap-highlight-color: transparent;
  transition: transform .35s cubic-bezier(.34, 1.56, .64, 1), box-shadow .35s;
  animation: dockPop .75s cubic-bezier(.34, 1.56, .64, 1) .7s backwards;
}
.dock-wa { width: var(--wa); height: var(--wa); color: var(--white);
  box-shadow: 0 14px 28px -10px rgba(18,140,78,.72), 0 4px 10px -2px rgba(8,57,52,.22); }
.dock-tel { width: var(--tel); height: var(--tel); color: var(--green); animation-delay: .85s;
  box-shadow: 0 0 0 1px rgba(150,95,15,.35), 0 12px 24px -10px rgba(176,112,18,.72), 0 4px 10px -2px rgba(8,57,52,.2); }

/* The disc: a lit-from-above gradient + a hairline top highlight, so it reads as a solid object
   instead of a flat sticker. overflow:clip keeps the light sweep inside the circle. */
.dock-face { position: absolute; inset: 0; border-radius: 50%; overflow: clip; }
.dock-wa .dock-face { background: linear-gradient(155deg, #4BE68B 0%, #25D366 42%, #16A151 100%);
  box-shadow: inset 0 1.5px 0 rgba(255,255,255,.45), inset 0 -4px 10px rgba(6,70,40,.24); }
.dock-tel .dock-face { background: linear-gradient(155deg, #F7C866 0%, #E9A93A 50%, #D08C21 100%);
  box-shadow: inset 0 1.5px 0 rgba(255,255,255,.5), inset 0 -4px 9px rgba(120,70,0,.2); }
.dock-face::after {
  content: ""; position: absolute; inset: -10% auto -10% 0; width: 80%;
  background: linear-gradient(100deg, transparent 0%, rgba(255,255,255,.24) 50%, transparent 100%);
  transform: translateX(-140%) skewX(-18deg);
}
.dock-wa .dock-face::after { animation: dockShine 8s ease-in-out 2.8s infinite; }

.dock-btn i { position: relative; }
.dock-wa i { width: 30px; height: 30px; }
.dock-tel i { width: 40px; height: 40px; animation: dockPhone 8s ease-in-out 6.8s infinite; }
/* wa-pulse.css's 6s wiggle is replaced by a nudge on the shared 8s beat. */
.dock-wa.wa-pulse .wa { animation: dockNudge 8s ease-in-out 2.8s infinite; }

/* Rings sit BEHIND the disc (z-index -1). Phone: 2px ring grown 1.35x = (29+2)*1.35-29 = 13px past the
   disc, inside the 14px gutter, so the screen edge never cuts it; desktop has a 28px gutter, so 3px
   and 1.5x. The 20px gap keeps the WhatsApp ring off the call disc. */
.dock-btn::before, .dock-btn::after {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: 50%;
  opacity: 0; pointer-events: none; box-shadow: none;
}
.dock-wa::before, .dock-wa.wa-pulse::after { box-shadow: 0 0 0 var(--ring) rgba(37,211,102,.55); animation: dockRipple 8s cubic-bezier(.2, .6, .35, 1) 2.8s infinite; }
.dock-wa.wa-pulse::after { animation-delay: 3.3s; }
.dock-tel::after { box-shadow: 0 0 0 var(--ring) rgba(233,169,58,.65); animation: dockRipple 8s cubic-bezier(.2, .6, .35, 1) 6.8s infinite; }

/* Label chip: white pill with a small tail, to the left of its button. */
.dock-tx {
  position: absolute; right: calc(100% + 14px); top: 50%;
  padding: 8px 14px; border-radius: 999px; white-space: nowrap;
  background: var(--white); color: var(--ink); font-size: 14px; font-weight: 600; line-height: 1.4;
  box-shadow: 0 12px 26px -10px rgba(8,57,52,.4), 0 0 0 1px rgba(8,57,52,.06);
  transform: translateY(-50%); translate: 10px 0; opacity: 0; pointer-events: none;
  transition: opacity .25s, translate .35s cubic-bezier(.34, 1.56, .64, 1);
}
.dock-tx::after {
  content: ""; position: absolute; right: -4px; top: 50%; width: 10px; height: 10px;
  background: inherit; border-radius: 2px; transform: translateY(-50%) rotate(45deg);
}
.dock-tx b { color: var(--green-mid); font-weight: 700; }
.dock-wa .dock-tx b { color: #0F7A43; }
/* Both chips end on one vertical line (the call disc is narrower than the WhatsApp one). */
.dock-tel .dock-tx { right: calc(100% + 14px + (var(--wa) - var(--tel)) / 2); }
.dock-wa .dock-tx { animation: dockPeek 16s ease 2.2s infinite; }

.dock-btn:hover, .dock-btn:focus-visible { transform: translateY(-3px) scale(1.06); }
.dock-wa:hover, .dock-wa:focus-visible { box-shadow: 0 20px 34px -10px rgba(18,140,78,.8), 0 6px 14px -2px rgba(8,57,52,.24); }
.dock-tel:hover, .dock-tel:focus-visible { box-shadow: 0 18px 30px -10px rgba(176,112,18,.8), 0 6px 14px -2px rgba(8,57,52,.22); }
.dock-btn:hover .dock-tx, .dock-btn:focus-visible .dock-tx { animation: none; opacity: 1; translate: 0 0; }
.dock-btn:focus-visible { outline: 3px solid var(--amber); outline-offset: 4px; }
.dock-tel:focus-visible { outline-color: var(--green); }
.dock-btn:active { transform: scale(.94); transition-duration: .12s; }
/* Touch screens: the WhatsApp chip still peeks on its timer; the call chip only exists for mice. */
@media (hover: none) { .dock-tel .dock-tx { display: none; } }

@media (min-width: 1024px) {
  .contact-dock { --wa: 64px; --tel: 64px; --ring: 3px; --ring-grow: 1.5; right: 28px; bottom: 28px; gap: 22px; }
  .contact-dock.dock-lift { translate: none; }
  .dock-wa i { width: 32px; height: 32px; }
  .dock-tel i { width: 43px; height: 43px; }
  .dock-tx { font-size: 15px; }
}
@media (min-width: 1440px) {
  .contact-dock { --wa: 70px; --tel: 70px; }
  .dock-wa i { width: 34px; height: 34px; }
  .dock-tel i { width: 45px; height: 45px; }
}

@keyframes dockPop { from { scale: .35; opacity: 0; } to { scale: 1; opacity: 1; } }
@keyframes dockRipple {
  0% { transform: scale(1); opacity: 1; }
  24%, 100% { transform: scale(var(--ring-grow)); opacity: 0; }
}
@keyframes dockNudge {
  0%, 14%, 100% { transform: scale(1) rotate(0); }
  2.5% { transform: scale(1.16) rotate(-12deg); }
  5% { transform: scale(1.12) rotate(10deg); }
  7.5% { transform: scale(1.08) rotate(-6deg); }
  10% { transform: scale(1.04) rotate(3deg); }
}
@keyframes dockShine {
  0% { transform: translateX(-140%) skewX(-18deg); }
  16%, 100% { transform: translateX(260%) skewX(-18deg); }
}
@keyframes dockPhone {
  0%, 12%, 100% { transform: rotate(0); }
  1.5%, 4.5%, 7.5% { transform: rotate(-14deg); }
  3%, 6%, 9% { transform: rotate(14deg); }
}
@keyframes dockPeek {
  0% { opacity: 0; translate: 10px 0; }
  3%, 28% { opacity: 1; translate: 0 0; }
  31%, 100% { opacity: 0; translate: 10px 0; }
}

@media (prefers-reduced-motion: reduce) {
  .contact-dock, .contact-dock .dock-btn, .contact-dock .dock-tx { transition: none; }
  .contact-dock .dock-btn, .contact-dock .dock-btn i, .contact-dock .dock-wa.wa-pulse .wa,
  .contact-dock .dock-face::after, .contact-dock .dock-tx { animation: none; }
  .contact-dock .dock-btn::before, .contact-dock .dock-btn::after,
  .contact-dock .dock-wa.wa-pulse::after { animation: none; opacity: 0; }
}
