/* ==========================================================================
   Interaction Effects — macOS-style spring animations
   Version: 20260811-10 |  Deployed to haileichemicals.com + haileichemical.com
   Progressive enhancement: only active when <html class="hl-js"> is present.
   ========================================================================== */

:root {
  --hl-spring: cubic-bezier(0.22, 1, 0.36, 1);
  --hl-spring-pop: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Lock mobile scaling while preserving one-finger horizontal/vertical pan. */
html,
body {
  touch-action: pan-x pan-y;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* ---------------------------------------------------------------------------
   Domestic inline chat: keep the fixed wrapper transparent to page clicks.
   Only the collapsed tab and the genuinely open panel may receive a pointer.
   On phones the collapsed tab is deliberately narrow instead of covering the
   full viewport width, so article/product cards remain easy to tap.
   --------------------------------------------------------------------------- */
html body .chat-widget {
  pointer-events: none !important;
}
html body .chat-widget .chat-box,
html body .chat-widget .chat-tab,
html body .chat-widget .chat-call-button {
  pointer-events: auto !important;
}
html body .chat-widget .chat-actions {
  display: flex !important;
  flex-direction: column !important;
  align-items: flex-end !important;
  gap: 8px !important;
}
html body .chat-widget .chat-call-button {
  box-sizing: border-box;
  width: 132px;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 999px;
  background: #0a2744;
  color: #fff;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-decoration: none;
  font-size: 13px;
  font-weight: 800;
  line-height: 1;
  box-shadow: 0 8px 24px rgba(10, 39, 68, .22);
  white-space: nowrap;
  touch-action: manipulation;
}
html body .chat-widget .chat-call-button:hover {
  background: #163b60;
}
@media (max-width: 768px) {
  html body .chat-widget .chat-tab {
    width: 132px !important;
    min-width: 132px !important;
    max-width: 132px !important;
    padding-left: 10px !important;
    padding-right: 10px !important;
    justify-content: center !important;
    margin-left: auto !important;
  }
  html body .chat-widget .chat-tab > span:not(.chat-tab-dot) {
    display: none !important;
  }
  html body .chat-widget .chat-tab::after {
    content: "咨询";
    font-size: 13px;
    font-weight: 700;
    line-height: 1;
  }
  html[lang^="en"] body .chat-widget .chat-tab::after {
    content: "Chat";
  }
  html body .chat-widget .chat-call-button {
    width: 132px !important;
    min-width: 132px !important;
    max-width: 132px !important;
  }
}

/* ---------------------------------------------------------------------------
   1. Scroll reveal (light rise entrance, 16px). Elements below the fold only.
   JS adds .hl-reveal to non-first-screen blocks, .hl-in when in viewport.
   --------------------------------------------------------------------------- */
.hl-js .hl-reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .55s var(--hl-spring), transform .7s var(--hl-spring);
}
.hl-js .hl-reveal.hl-in {
  opacity: 1;
  transform: none;
}

/* ---------------------------------------------------------------------------
   2. Product / content cards — hover lift 3px, press to 0.97, spring back.
   No layout shift: transform/opacity only.
   --------------------------------------------------------------------------- */
.hl-js .product-card,
.hl-js .card,
.hl-js .link-card,
.hl-js .linkCard,
.hl-js .choice,
.hl-js .process-card,
.hl-js .process-grid li,
.hl-js .gallery-item,
.hl-js .capability-list article,
.hl-js .factory-item {
  transition: transform .4s var(--hl-spring), box-shadow .4s var(--hl-spring), border-color .3s var(--hl-spring);
}
@media (hover: hover) and (pointer: fine) {
  .hl-js .product-card:hover,
  .hl-js .card:hover,
  .hl-js .link-card:hover,
  .hl-js .linkCard:hover,
  .hl-js .choice:hover,
  .hl-js .gallery-item:hover {
    transform: translateY(-3px);
  }
  .hl-js .product-card:hover,
  .hl-js .card:hover,
  .hl-js .link-card:hover {
    box-shadow: 0 18px 38px rgba(8, 44, 70, .14);
  }
  .hl-js .process-card:hover,
  .hl-js .process-grid li:hover {
    transform: translateY(-3px);
  }
  .hl-js .product-card .product-image img {
    transition: transform .55s var(--hl-spring);
  }
  .hl-js .product-card:hover .product-image img {
    transform: scale(1.045);
  }
}

/* ---------------------------------------------------------------------------
   3. Buttons, submit, menu triggers — spring press + release.
   --------------------------------------------------------------------------- */
.hl-js .button,
.hl-js .btn,
.hl-js .form-submit,
.hl-js .nav-cta,
.hl-js .mobile-menu-cta,
.hl-js .btn-mobile,
.hl-js .nav-mobile-toggle,
.hl-js .menu-btn,
.hl-js .hamburger {
  transition: transform .35s var(--hl-spring-pop), box-shadow .35s var(--hl-spring), background .2s ease, border-color .2s ease;
}
.hl-js .button:active,
.hl-js .btn:active,
.hl-js .form-submit:active,
.hl-js .nav-cta:active,
.hl-js .mobile-menu-cta:active,
.hl-js .btn-mobile:active,
.hl-js .nav-mobile-toggle:active,
.hl-js .menu-btn:active,
.hl-js .hamburger:active,
.hl-js .solution-tab:active {
  transform: scale(.96);
}

/* Generic press feedback for touch (JS adds/removes .hl-press on pointerdown/up).
   Kept low so it never fights hover transforms for long. */
.hl-js .hl-press {
  transform: scale(.97) !important;
  transition: transform .28s var(--hl-spring-pop) !important;
}

/* ---------------------------------------------------------------------------
   4. Solution tabs (CN site) — switch with directional slide + reflow.
   The whole panel (image + text + labels) moves as one unit.
   --------------------------------------------------------------------------- */
.hl-js .solution-tab {
  transition: transform .35s var(--hl-spring), background .25s ease, border-color .25s ease, color .25s ease;
}
@media (hover: hover) and (pointer: fine) {
  .hl-js .solution-tab:hover {
    transform: translateY(-1px);
  }
}
.hl-js .solution-panel {
  will-change: transform, opacity;
}
.hl-solution-anim {
  animation: hl-solution-switch .52s var(--hl-spring);
}
@keyframes hl-solution-switch {
  0%   { opacity: 1; transform: translateX(0); }
  35%  { opacity: 0; transform: translateX(-18px); }
  55%  { opacity: 0; transform: translateX(18px); }
  100% { opacity: 1; transform: translateX(0); }
}

/* ---------------------------------------------------------------------------
   5. Quote / inquiry forms — spring-in on reveal, success bounce.
   --------------------------------------------------------------------------- */
.hl-js .quote-form,
.hl-js .inquiry-form {
  transition: transform .6s var(--hl-spring), box-shadow .6s var(--hl-spring);
}
.hl-js .quote-form.hl-bounce,
.hl-js .inquiry-form.hl-bounce {
  animation: hl-form-bounce .6s var(--hl-spring-pop);
}
@keyframes hl-form-bounce {
  0%   { transform: translateY(0) scale(1); }
  30%  { transform: translateY(-8px) scale(1.008); }
  60%  { transform: translateY(2px) scale(.997); }
  100% { transform: translateY(0) scale(1); }
}

/* ---------------------------------------------------------------------------
   6. Mobile menu drawers (both templates) + shared backdrop.
   Drawer stays display:block but off-screen when closed, so open AND close
   both animate. Existing open/close class logic is untouched.
   --------------------------------------------------------------------------- */
.hl-backdrop {
  position: fixed;
  inset: 0;
  z-index: 45; /* below all site headers, including area-page nav (50) */
  background: rgba(10, 39, 68, .36);
  opacity: 0;
  pointer-events: none;
  transition: opacity .35s var(--hl-spring);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.hl-backdrop.hl-backdrop-on {
  opacity: 1;
  pointer-events: auto;
}

/* International homepage template: .mobile-menu (#mobileMenu), nav 78px */
@media (max-width: 1100px) {
  .hl-js .mobile-menu {
    display: block;
    position: fixed;
    top: 78px;
    left: 0;
    right: auto;
    width: min(86%, 400px);
    height: calc(100dvh - 78px);
    padding: 14px 26px 20px;
    background: #fff;
    border-top: 1px solid #e6eef6;
    box-shadow: 0 30px 70px rgba(10, 39, 68, .3);
    z-index: 98;
    overflow-y: auto;
    transform: translateX(-106%);
    visibility: hidden;
    opacity: 0;
    transition: transform .55s var(--hl-spring-pop), opacity .32s var(--hl-spring), visibility .55s;
  }
  .hl-js .mobile-menu.open {
    transform: none;
    visibility: visible;
    opacity: 1;
  }
}
@media (max-width: 768px) {
  .hl-js .mobile-menu {
    top: 64px;
    height: calc(100dvh - 64px);
  }
}

/* International product-page template: .nav-mobile (#navMobile), header 78px */
@media (max-width: 1000px) {
  .hl-js .nav-mobile {
    display: flex;
    position: fixed;
    top: 78px;
    left: 0;
    right: auto;
    width: min(86%, 400px);
    bottom: 0;
    padding: 24px 26px;
    background: #fff;
    box-shadow: 0 30px 70px rgba(10, 39, 68, .3);
    z-index: 98;
    overflow-y: auto;
    transform: translateX(-106%);
    visibility: hidden;
    opacity: 0;
    transition: transform .55s var(--hl-spring-pop), opacity .32s var(--hl-spring), visibility .55s;
  }
  .hl-js .nav-mobile.show {
    transform: none;
    visibility: visible;
    opacity: 1;
  }
}

/* Domestic site: .nav-links (#navLinks) becomes drawer below 1050px, header 117px.
   IMPORTANT: the site's own inline CSS uses .nav-links.open { display: grid }.
   We override to a vertical flex so links stack (never overlap) in the drawer. */
@media (max-width: 1050px) {
  .hl-js .nav-links {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    position: fixed;
    top: 117px;
    left: 0;
    right: auto;
    width: min(86%, 400px);
    max-height: calc(100vh - 117px);
    padding: 12px 24px;
    background: #fff;
    box-shadow: 0 30px 60px rgba(9, 47, 79, .22);
    z-index: 98;
    overflow-y: auto;
    transform: translateX(-106%);
    visibility: hidden;
    opacity: 0;
    transition: transform .55s var(--hl-spring-pop), opacity .32s var(--hl-spring), visibility .55s;
  }
  .hl-js .nav-links a {
    display: block;
    width: 100%;
    text-align: left;
  }
  .hl-js .nav-links.open {
    transform: none;
    visibility: visible;
    opacity: 1;
  }
}
@media (max-width: 820px) {
  .hl-js .nav-links {
    top: 106px;
    max-height: calc(100vh - 106px);
  }
}
@media (max-width: 560px) {
  .hl-js .nav-links {
    top: 68px;
    max-height: calc(100vh - 68px);
  }
}

/* Domestic area pages: #menuBtn controls the adjacent .menu dropdown. Keep
   the existing layout, but leave it rendered off-state so close can animate. */
@media (max-width: 900px) {
  .hl-js #menuBtn + .menu {
    display: flex;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(-12px);
    z-index: 98;
    transition: transform .4s var(--hl-spring-pop), opacity .28s var(--hl-spring), visibility .4s;
  }
  .hl-js #menuBtn + .menu.open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
  }
}

body.hl-menu-open {
  overflow: hidden;
}

/* ---------------------------------------------------------------------------
   7. Hero visual — gentle settle-in on load. Transform only (no opacity change),
   so the LCP element paints at full opacity immediately.
   --------------------------------------------------------------------------- */
.hl-js .hero-visual {
  animation: hl-hero-settle .8s var(--hl-spring);
}
@keyframes hl-hero-settle {
  0%   { transform: translateY(14px); }
  100% { transform: none; }
}

/* ---------------------------------------------------------------------------
   8. Reduced motion: kill all movement, keep opacity states at visible.
   Sound remains independent (JS side, not gated here).
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .hl-js .hl-reveal,
  .hl-js .hl-reveal.hl-in {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .hl-js .hero-visual,
  .hl-js .quote-form.hl-bounce,
  .hl-js .inquiry-form.hl-bounce,
  .hl-solution-anim {
    animation: none !important;
  }
  .hl-js .product-card,
  .hl-js .card,
  .hl-js .link-card,
  .hl-js .linkCard,
  .hl-js .choice,
  .hl-js .process-card,
  .hl-js .process-grid li,
  .hl-js .gallery-item,
  .hl-js .button,
  .hl-js .btn,
  .hl-js .form-submit,
  .hl-js .nav-mobile-toggle,
  .hl-js .menu-btn,
  .hl-js .hamburger,
  .hl-js .solution-tab {
    transition: none !important;
  }
  .hl-js .product-card:hover,
  .hl-js .card:hover,
  .hl-js .link-card:hover,
  .hl-js .linkCard:hover,
  .hl-js .choice:hover,
  .hl-js .gallery-item:hover,
  .hl-js .process-card:hover,
  .hl-js .process-grid li:hover,
  .hl-js .button:hover,
  .hl-js .btn:hover {
    transform: none !important;
  }
}
