/* ============================================================================
   Hiệu ứng giao diện — dùng chung cho static/index.html và static/landing.html.

   Ý tưởng lấy từ bộ sưu tập https://wiweb.vn/hieu-ung-website/ rồi viết lại
   theo bảng màu xanh nước biển của web: mọi màu ở đây đều đọc từ biến khai báo
   trong <style> của từng trang (--brand, --grad, --surface...), nên đổi màu ở
   trang là hiệu ứng đổi theo.

   File này nạp SAU <style> của trang để đè được các luật cùng độ ưu tiên.
   Người dùng bật "giảm chuyển động" trong hệ điều hành: khối cuối file tắt
   hết chuyển động, giao diện vẫn đầy đủ.
   ========================================================================== */

/* ------------------------------------------- 1. Công tắc Ngày/Đêm ----------
   (Day-Night Switch) Mặt trời trượt sang phải và bị "nhật thực" thành trăng
   khuyết, nền trời chuyển xanh nhạt → xanh đêm, sao hiện ra. Trạng thái lấy từ
   aria-checked do effects.js đặt.                                             */
.theme-sw {
  position: relative; flex: none; width: 58px; height: 30px; padding: 0;
  border: 0; border-radius: 999px; background: none; cursor: pointer;
}
.theme-sw:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
.theme-sw-track {
  position: absolute; inset: 0; border-radius: inherit; overflow: hidden;
  background: linear-gradient(135deg, #BAE6FD 0%, #7DD3FC 45%, #38BDF8 100%);
  box-shadow: inset 0 1px 3px rgba(10, 25, 47, 0.22), 0 0 0 1px var(--line-2);
  transition: background 0.5s var(--ease), box-shadow 0.5s;
}
.theme-sw[aria-checked="true"] .theme-sw-track {
  background: linear-gradient(135deg, #0A192F 0%, #10223D 55%, #1E3A5F 100%);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(186, 230, 253, 0.25);
}
.theme-sw-orb {
  position: absolute; top: 4px; left: 4px; width: 22px; height: 22px; border-radius: 50%;
  background: #FDE68A; box-shadow: 0 0 10px 2px rgba(253, 230, 138, 0.75);
  overflow: hidden;
  transition: transform 0.55s var(--ease), background 0.5s, box-shadow 0.5s;
}
/* Mảng "bóng" che dần mặt trời thành trăng khuyết — cùng màu trời đêm. */
.theme-sw-orb::after {
  content: ""; position: absolute; top: -4px; right: -5px; width: 19px; height: 19px;
  border-radius: 50%; background: #12294A;
  transform: scale(0); transform-origin: 80% 20%;
  transition: transform 0.55s var(--ease);
}
.theme-sw[aria-checked="true"] .theme-sw-orb {
  transform: translateX(28px) rotate(-20deg);
  background: #E0F2FE; box-shadow: 0 0 10px 1px rgba(224, 242, 254, 0.55);
}
.theme-sw[aria-checked="true"] .theme-sw-orb::after { transform: scale(1); }
.theme-sw-cloud {
  position: absolute; right: 7px; top: 12px; width: 18px; height: 7px; border-radius: 999px;
  background: #FFF; opacity: 0.9; transition: opacity 0.4s, transform 0.5s var(--ease);
}
.theme-sw-cloud::before {
  content: ""; position: absolute; left: 4px; top: -4px; width: 9px; height: 9px;
  border-radius: 50%; background: inherit;
}
.theme-sw[aria-checked="true"] .theme-sw-cloud { opacity: 0; transform: translateX(10px); }
.theme-sw-star {
  position: absolute; width: 3px; height: 3px; border-radius: 50%; background: #FFF;
  opacity: 0; transform: scale(0.3); transition: opacity 0.4s, transform 0.4s;
}
.theme-sw-star:nth-of-type(1) { left: 9px;  top: 8px; }
.theme-sw-star:nth-of-type(2) { left: 18px; top: 17px; width: 2px; height: 2px; }
.theme-sw-star:nth-of-type(3) { left: 24px; top: 7px;  width: 2px; height: 2px; }
.theme-sw[aria-checked="true"] .theme-sw-star {
  opacity: 1; transform: none; animation: fx-twinkle 2.4s ease-in-out infinite;
}
.theme-sw[aria-checked="true"] .theme-sw-star:nth-of-type(2) { animation-delay: 0.8s; }
.theme-sw[aria-checked="true"] .theme-sw-star:nth-of-type(3) { animation-delay: 1.6s; }
@keyframes fx-twinkle { 50% { opacity: 0.25; } }

/* ------------------------------------------- 2. Về đầu trang ---------------
   (Back To Top) Hình tròn mũi tên; rê chuột thì giãn thành viên thuốc, mũi
   tên trượt lên biến mất, chữ trượt từ dưới lên. --to-top-w do effects.js đo
   theo độ dài chữ của ngôn ngữ đang chọn.                                    */
.to-top {
  position: fixed; right: 20px; bottom: 20px; z-index: 45;
  width: 50px; height: 50px; padding: 0; border: 0; border-radius: 999px;
  display: grid; place-items: center; justify-content: center; overflow: hidden;
  background: var(--grad); color: #FFF; box-shadow: var(--glow-brand);
  font: 700 14px/1 var(--font-sans); cursor: pointer;
  opacity: 0; visibility: hidden; transform: translateY(18px) scale(0.9);
  transition: opacity 0.3s, transform 0.35s var(--ease), visibility 0s linear 0.35s,
              width 0.4s var(--ease);
}
.to-top.show { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.to-top > * { grid-area: 1 / 1; transition: transform 0.35s var(--ease), opacity 0.3s; }
.to-top svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.to-top span { white-space: nowrap; padding: 0 22px; opacity: 0; transform: translateY(160%); }
.to-top:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
@media (hover: hover) {
  .to-top:hover, .to-top:focus-visible { width: var(--to-top-w, 170px); }
  .to-top:hover svg, .to-top:focus-visible svg { transform: translateY(-160%); opacity: 0; }
  .to-top:hover span, .to-top:focus-visible span { transform: none; opacity: 1; }
}

/* ------------------------------------------- 3. Nút chính "ma thuật" -------
   (Magic Button) Gradient trôi liên tục + vầng hào quang mờ phía sau khi rê
   chuột. Gradient lặp lại (đầu = cuối) nên trôi không bị giật.               */
.btn {
  position: relative; isolation: isolate;
  background-image: linear-gradient(110deg, var(--brand) 0%, var(--brand-2) 25%,
                    var(--brand-3) 50%, var(--brand-2) 75%, var(--brand) 100%);
  background-size: 200% 100%;
}
.btn::before {
  content: ""; position: absolute; inset: 2px; z-index: -1; border-radius: inherit;
  background: inherit; filter: blur(16px); opacity: 0; transition: opacity 0.35s;
}
.btn:hover:not(:disabled), .btn:hover:not(:disabled)::before { animation: fx-flow 2.6s linear infinite; }
.btn:hover:not(:disabled)::before { opacity: 0.8; }
@keyframes fx-flow { to { background-position: 200% 0; } }

/* ------------------------------------------- 4. Viền sáng chạy quanh -------
   (Border Effect) Ô dán link: một vệt sáng xanh chạy vòng theo viền. Vệt sáng
   là ::before (gradient nón xoay), ::after phủ lên chừa đúng 1.5px làm viền.
   Bấm vào ô thì vệt sáng chạy nhanh hơn.                                      */
.console-wrapper {
  overflow: hidden; isolation: isolate;
  border-width: 0; padding: 9px;
}
.console-wrapper::before {
  content: ""; position: absolute; z-index: -2; left: 50%; top: 50%;
  width: max(200%, 400px); aspect-ratio: 1; translate: -50% -50%;
  background: conic-gradient(var(--line-2) 0 58%, var(--brand-3) 72%, var(--brand-2) 82%,
                             var(--brand) 90%, var(--line-2) 100%);
  animation: fx-spin 5s linear infinite;
}
.console-wrapper::after {
  content: ""; position: absolute; z-index: -1; inset: 1.5px;
  border-radius: calc(var(--r-xl) - 1.5px); background: var(--surface);
}
.console-wrapper:focus-within::before { animation-duration: 2s; }
@keyframes fx-spin { to { transform: rotate(360deg); } }

/* ------------------------------------------- 5. Chữ tự gõ -----------------
   (Typewriter) Dòng chữ mờ có sẵn, lớp chữ gradient được "gõ" đè lên từ trái
   sang phải kèm con trỏ nhấp nháy. effects.js dựng lớp phủ; xong thì gỡ đi.  */
.tw-on { position: relative; background: none !important; color: var(--line-2) !important; }
.tw-ink { position: absolute; inset: 0; pointer-events: none; }
.tw-typed {
  background: var(--grad); -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
/* Con trỏ rộng 0 (lề âm bù lại) để không đẩy lệch chữ phía sau. */
.tw-typed::after {
  content: ""; display: inline-block; width: 3px; height: 0.9em; margin-right: -3px;
  vertical-align: -0.08em; background: var(--brand-2); border-radius: 2px;
  animation: fx-caret 0.75s steps(1) infinite;
}
.tw-rest { visibility: hidden; }
@keyframes fx-caret { 50% { opacity: 0; } }

/* ------------------------------------------- 6. Chữ trượt kiểu máy quay số -
   (Sliding Text) Tên nền tảng lần lượt trượt lên, mép trên/dưới mờ dần.
   Có 7 dòng: 6 nền tảng + lặp lại dòng đầu để vòng lặp liền mạch.            */
/* :is(p, div, span) để thắng luật ".sec-head p" (cỡ chữ đoạn mô tả) của trang. */
:is(p, div, span).slot {
  display: inline-flex; height: 1.3em; overflow: hidden; vertical-align: bottom; margin: 10px 0 0;
  font-size: clamp(28px, 4.4vw, 46px); font-weight: 800; letter-spacing: -0.03em; line-height: 1.3;
  -webkit-mask-image: linear-gradient(transparent, #000 22%, #000 78%, transparent);
  mask-image: linear-gradient(transparent, #000 22%, #000 78%, transparent);
}
.slot-track { display: flex; flex-direction: column; animation: fx-slot 13s infinite; }
.slot-track span {
  height: 1.3em; text-align: center;
  background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
@keyframes fx-slot {
  0%, 12.5%       { transform: translateY(0); animation-timing-function: cubic-bezier(.6, -.35, .3, 1.35); }
  16.67%, 29.17%  { transform: translateY(-1.3em); animation-timing-function: cubic-bezier(.6, -.35, .3, 1.35); }
  33.33%, 45.83%  { transform: translateY(-2.6em); animation-timing-function: cubic-bezier(.6, -.35, .3, 1.35); }
  50%, 62.5%      { transform: translateY(-3.9em); animation-timing-function: cubic-bezier(.6, -.35, .3, 1.35); }
  66.67%, 79.17%  { transform: translateY(-5.2em); animation-timing-function: cubic-bezier(.6, -.35, .3, 1.35); }
  83.33%, 95.83%  { transform: translateY(-6.5em); animation-timing-function: cubic-bezier(.6, -.35, .3, 1.35); }
  100%            { transform: translateY(-7.8em); }
}

/* ------------------------------------------- 7. Tiêu điểm khi rê chuột -----
   (Focus Hover) Thẻ đang rê nổi lên, các thẻ cùng hàng thu nhỏ và mờ đi như
   ống kính lấy nét. Chỉ bật với chuột thật (màn cảm ứng không có "rê").     */
@media (hover: hover) {
  .feat, .step, .price-card {
    transition: transform 0.4s var(--ease), filter 0.4s, opacity 0.4s,
                box-shadow 0.4s, border-color 0.4s;
  }
  .feats:has(> .feat:hover) > .feat:not(:hover),
  .steps:has(> .step:hover) > .step:not(:hover),
  .pricing:has(> .price-card:hover) > .price-card:not(:hover) {
    transform: scale(0.96); filter: blur(2px) saturate(0.7); opacity: 0.55;
  }
}

/* ------------------------------------------- 8. Biểu tượng chờ -------------
   (Three-dot Loader) Ba chấm xoay quanh tâm, vừa xoay vừa co vào giãn ra.
   Thay cho vòng xoay cũ ở mọi chỗ có <span class="spin">. Màu theo chữ nút. */
.spin {
  display: inline-block; flex: none; width: 18px; height: 18px;
  border: 0; border-radius: 0;
  background:
    radial-gradient(circle, currentColor 0 2.6px, transparent 3.1px) 50% 0 / 7px 7px no-repeat,
    radial-gradient(circle, currentColor 0 2.6px, transparent 3.1px) 0 100% / 7px 7px no-repeat,
    radial-gradient(circle, currentColor 0 2.6px, transparent 3.1px) 100% 100% / 7px 7px no-repeat;
  animation: fx-spin 1.5s linear infinite, fx-breathe 0.75s ease-in-out infinite alternate;
}
@keyframes fx-breathe {
  to { background-position: 50% 28%, 24% 76%, 76% 76%; }
}

/* (Ripple Loader) Khung chờ khi đang quét link: logo nhịp đập giữa các vòng
   sóng lan toả.                                                              */
.fx-ripple {
  position: relative; flex: none; width: 140px; height: 80px; overflow: hidden;
  display: grid; place-items: center; border-radius: var(--r); background: var(--surface-hover);
}
.fx-ripple i {
  position: absolute; width: 34px; height: 34px; border-radius: 50%;
  border: 2px solid var(--brand); opacity: 0;
  animation: fx-ripple 2.1s cubic-bezier(.2, .6, .3, 1) infinite;
}
.fx-ripple i:nth-child(2) { animation-delay: 0.7s; }
.fx-ripple i:nth-child(3) { animation-delay: 1.4s; }
.fx-ripple span {
  position: relative; width: 34px; height: 34px; border-radius: 10px;
  display: grid; place-items: center; background: var(--grad); color: #FFF;
  box-shadow: var(--glow-brand); animation: fx-beat 2.1s ease-in-out infinite;
}
.fx-ripple svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.2; }
@keyframes fx-ripple { 0% { transform: scale(0.6); opacity: 0.9; } 100% { transform: scale(3.4); opacity: 0; } }
@keyframes fx-beat { 50% { transform: scale(0.88); filter: brightness(1.2) hue-rotate(-12deg); } }

/* ------------------------------------------- 9. Nút tải nhiều trạng thái ---
   (Download Button) Đang tải: viền nhịp sáng, "nước" dâng từ đáy đúng theo %
   tải thật (--p, 0→1, effects do index.html đặt). Chưa biết % (máy chủ đang
   chuẩn bị file) thì một vệt sáng quét ngang. Xong: nút bật nảy và chuyển
   xanh lá.                                                                   */
.btn-dl { position: relative; overflow: hidden; isolation: isolate; }
.btn-dl::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; z-index: -1;
  height: 0; background: linear-gradient(0deg, rgba(2, 132, 199, 0.30), rgba(6, 182, 212, 0.22));
  transition: height 0.25s linear;
}
.btn-dl[aria-busy="true"] {
  opacity: 1; cursor: progress; color: var(--brand); border-color: var(--brand);
  animation: fx-pulse 1.4s ease-out infinite;
}
.btn-dl[aria-busy="true"].has-p::before { height: calc(var(--p, 0) * 100%); }
.btn-dl[aria-busy="true"]:not(.has-p)::before {
  height: 100%; background: linear-gradient(90deg, transparent, rgba(2, 132, 199, 0.20), transparent)
    no-repeat; background-size: 50% 100%; animation: fx-sweep 1.3s linear infinite;
}
.btn-dl.done { animation: fx-pop 0.5s var(--ease); }
@keyframes fx-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(2, 132, 199, 0.45); }
  70%  { box-shadow: 0 0 0 10px rgba(2, 132, 199, 0); }
  100% { box-shadow: 0 0 0 0 rgba(2, 132, 199, 0); }
}
@keyframes fx-sweep { from { background-position: -100% 0; } to { background-position: 200% 0; } }
@keyframes fx-pop { 0% { transform: scale(0.9); } 60% { transform: scale(1.07); } 100% { transform: scale(1); } }

/* ------------------------------------------- 10. Nút bắn sao ---------------
   (Star Button) Rê chuột vào nút nâng cấp: nút chuyển sang viền phát sáng và
   6 ngôi sao bắn ra các hướng. Sao là <i class="fx-star"> trong nút; chữ của
   nút nằm trong <span data-i18n> riêng để i18n.js không xoá mất sao.        */
.fx-stars { position: relative; }
.fx-star {
  position: absolute; left: 50%; top: 50%; z-index: -1; width: 14px; height: 14px;
  background: var(--fx-star, var(--brand-3));
  clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
  opacity: 0; transform: translate(-50%, -50%) scale(0.2);
  transition: transform 0.8s cubic-bezier(.05, .83, .43, .96), opacity 0.4s;
  pointer-events: none;
}
.fx-star:nth-of-type(2) { width: 9px;  height: 9px;  background: var(--fx-star, var(--brand-2)); }
.fx-star:nth-of-type(3) { width: 6px;  height: 6px; }
.fx-star:nth-of-type(4) { width: 10px; height: 10px; background: var(--fx-star, var(--brand)); }
.fx-star:nth-of-type(5) { width: 12px; height: 12px; background: var(--fx-star, var(--brand-2)); }
.fx-star:nth-of-type(6) { width: 7px;  height: 7px; }
.fx-stars:hover .fx-star, .fx-stars:focus-visible .fx-star { opacity: 1; z-index: 2; }
.fx-stars:hover .fx-star:nth-of-type(1), .fx-stars:focus-visible .fx-star:nth-of-type(1) { transform: translate(-50%, -50%) translate(-110px, -34px) rotate(40deg); }
.fx-stars:hover .fx-star:nth-of-type(2), .fx-stars:focus-visible .fx-star:nth-of-type(2) { transform: translate(-50%, -50%) translate(-60px, 30px) rotate(-30deg); transition-delay: 0.05s; }
.fx-stars:hover .fx-star:nth-of-type(3), .fx-stars:focus-visible .fx-star:nth-of-type(3) { transform: translate(-50%, -50%) translate(-14px, -36px); transition-delay: 0.1s; }
.fx-stars:hover .fx-star:nth-of-type(4), .fx-stars:focus-visible .fx-star:nth-of-type(4) { transform: translate(-50%, -50%) translate(40px, 32px) rotate(25deg); transition-delay: 0.08s; }
.fx-stars:hover .fx-star:nth-of-type(5), .fx-stars:focus-visible .fx-star:nth-of-type(5) { transform: translate(-50%, -50%) translate(104px, -30px) rotate(-45deg); transition-delay: 0.03s; }
.fx-stars:hover .fx-star:nth-of-type(6), .fx-stars:focus-visible .fx-star:nth-of-type(6) { transform: translate(-50%, -50%) translate(80px, 34px); transition-delay: 0.12s; }
/* Nút nâng cấp trong thẻ giá: rê chuột thì thành nút viền phát sáng. */
.price-cta.primary.fx-stars:hover {
  background: transparent; color: var(--brand); border-color: var(--brand);
  box-shadow: 0 0 0 1px var(--brand), 0 0 22px rgba(2, 132, 199, 0.45);
}
.cta { --fx-star: #FFF; }

/* ------------------------------------------- 11. Sóng nước -----------------
   (Wave Effect) Hai lớp sóng trắng mờ chạy ngược chiều dưới đáy khung kêu
   gọi cuối trang. Mỗi lớp trôi đúng một chu kỳ ảnh nên lặp không giật.       */
.cta > * { position: relative; z-index: 1; }
.cta::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 110px;
  pointer-events: none;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 110' preserveAspectRatio='none'%3E%3Cpath d='M0 60 C150 20 150 100 300 60 S450 20 600 60 V110 H0Z' fill='%23fff' fill-opacity='.16'/%3E%3C/svg%3E") 0 100% / 600px 100% repeat-x,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 900 110' preserveAspectRatio='none'%3E%3Cpath d='M0 75 C225 40 225 110 450 75 S675 40 900 75 V110 H0Z' fill='%23fff' fill-opacity='.12'/%3E%3C/svg%3E") 0 100% / 900px 100% repeat-x;
  animation: fx-wave 14s linear infinite;
}
@keyframes fx-wave { to { background-position: 600px 100%, -900px 100%; } }

/* ------------------------------------------- 12. Nút viền tràn màu ---------
   (Button Hover Effect) Lớp gradient lướt vào từ cạnh phải lấp đầy nút, chữ
   đổi trắng và nảy nhẹ.                                                       */
.btn-ghost { position: relative; isolation: isolate; overflow: hidden; }
.btn-ghost::before {
  content: ""; position: absolute; inset: 0; z-index: -1; background: var(--grad);
  transform: scaleX(0); transform-origin: right; transition: transform 0.45s var(--ease);
}
.btn-ghost:hover { color: #FFF; border-color: transparent; animation: fx-bounce 0.5s var(--ease) forwards; }
.btn-ghost:hover::before { transform: scaleX(1); }
@keyframes fx-bounce {
  0% { transform: translateY(0); } 40% { transform: translateY(-5px); }
  70% { transform: translateY(1px); } 100% { transform: translateY(-2px); }
}

/* ------------------------------------------- Giảm chuyển động --------------
   Giữ nguyên giao diện, chỉ bỏ chuyển động.                                  */
@media (prefers-reduced-motion: reduce) {
  .theme-sw *, .theme-sw *::after, .to-top, .to-top > * { transition: none !important; animation: none !important; }
  .btn:hover:not(:disabled), .btn:hover:not(:disabled)::before { animation: none; }
  .console-wrapper::before { animation: none; background: var(--line-2); }
  .console-wrapper:focus-within::before { background: var(--brand); }
  .slot-track { animation: none; }
  .feats:has(> .feat:hover) > .feat:not(:hover),
  .steps:has(> .step:hover) > .step:not(:hover),
  .pricing:has(> .price-card:hover) > .price-card:not(:hover) { transform: none; filter: none; opacity: 1; }
  .spin { animation: none; }
  .fx-ripple i, .fx-ripple span { animation: none; }
  .fx-ripple i:first-child { opacity: 0.5; transform: scale(1.8); }
  .btn-dl[aria-busy="true"], .btn-dl.done { animation: none; }
  .btn-dl[aria-busy="true"]:not(.has-p)::before { animation: none; background: rgba(2, 132, 199, 0.12); }
  .fx-star { display: none; }
  .cta::after { animation: none; }
  .btn-ghost:hover { animation: none; }
  .btn-ghost::before { transition: none; }
}
