/* seo_check 樣式。先載 tw/master.css，本檔只負責 .seoCheck 裡面的頁面區塊。
   header／footer／滑出選單走 master.css，不要在這裡再寫一份。 */
@charset "UTF-8";
/* ==========================================================
   index.scss — 首頁主檔
   編譯：sass scss/index.scss css/index.css --style=expanded
   ========================================================== */
/* ==========================================================
   _setting.scss — 全域變數（顏色 / 字體 / 字級）
   斷點（max-width 由大而小覆寫）：1680 / 1536 / 1440 / 1280 / 1180 / 991 / 768 / 480 / 375
   ========================================================== */
:root{
  /* 顏色 */
  --mainColor: #ff5001;
  --mainColorLight: #ff8a3d;
  --secondColor: #000000; /* 原 #252525，全站黑色統一 #000000（使用者 2026-09-11） */
  --thirdColor: #f9f9fb;
  --grayColor: #f5f5f5;
  --titleColor: #000000; /* 原 #111111，同上 */
  --textColor: #666666; /* 原 #7d7d7f，內文統一 #666（使用者 2026-09-11） */
  --linkColor: var(--secondColor);
  --linkHoverColor: var(--mainColor);
  --btnColor: #fff;
  --btnBgColor: var(--mainColor);
  --lineColor: rgba(0, 0, 0, 0.1);
  --maskColor: rgba(0, 0, 0, 0.7);
  --dangerColor: #e8241f;
  --cardShadow: 0 20px 50px rgba(0, 0, 0, 0.06);
  --mainGradient: linear-gradient(160deg, #ff7a1a 0%, #ff5001 60%, #fe4d01 100%);
  /* 字體 */
  /* 字體
     Poppins 只含拉丁字母與數字，中文會自動 fallback 到 Noto Sans TC，
     因此「數字與英文用 Poppins、中文用 Noto Sans TC」只需這一組 font-family。
     順序與主站 ixpert.com.tw 的 master.css 一致。 */
  --mainFont: 'Poppins', 'Noto Sans TC', 'Microsoft JhengHei', sans-serif;
  --secondFont: 'Poppins', 'Noto Sans TC', 'Microsoft JhengHei', sans-serif;
  /* 字級 */
  --heroTitleSize: 60px;
  --heroTitleSizeMedium: 48px;
  --heroTitleSizeSmall: 38px; /* 原 32，2026-09-11 使用者要求手機版主標再大一點；40 在 360 寬手機會折行 */
  /* titleBox 三段文字照主站 master.css .titleBox（2026-09-11）：title 40/36/30（≤480 再降 24） */
  --titleSize: 40px;
  --titleSizeMedium: 36px;
  --titleSizeSmall: 30px;
  --titleSizeXs: 24px;
  --subtitleSize: 28px;
  --subtitleSizeMedium: 24px;
  --subtitleSizeSmall: 20px;
  --decoTitleSize: 17px;
  --decoTitleSizeMedium: 16px;
  --decoTitleSizeSmall: 15px;
  --textTitleSize: 22px;
  --textTitleSizeMedium: 20px;
  --textTitleSizeSmall: 18px;
  --textSize: 18px;
  --textSizeMedium: 16px;
  --textSizeSmall: 15px;
  --dataTitleSize: 22px;
  --dataTitleSizeMedium: 20px;
  --dataTitleSizeSmall: 18px;
  --dataTextSize: 16px;
  --dataTextSizeMedium: 15px;
  --dataTextSizeSmall: 14px;
  /* 比較表價格數字（參考 2608-ai-robot 方案價格 44px，本站表格較密，取 40） */
  --priceSize: 40px;
  --priceSizeMedium: 36px;
  --priceSizeSmall: 32px;
  /* 版面 */
  --wrapWidth: 1430px;
  --headerHeight: 120px; /* 共用 header：top 30px + 選單列約 80px */
  --headerHeightSmall: 90px; /* ≤1180：header top 20px，選單收起 */
  --radiusLg: 40px;
  --radiusMd: 30px;
  --radiusSm: 20px;
}

/* ---------- Reset ---------- */
.seoCheck,
.seoCheck *,
.seoCheck *::before,
.seoCheck *::after{
  box-sizing: border-box;
}

html{
  scroll-behavior: smooth;
}

body.seo_checkPage{
  margin: 0;
  font-family: var(--mainFont);
  font-size: var(--textSize);
  line-height: 1.7;
  color: var(--secondColor);
  background: #fff;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.seoCheck h1,
.seoCheck h2,
.seoCheck h3,
.seoCheck h4,
.seoCheck p,
.seoCheck figure,
.seoCheck ul{
  margin: 0;
}

.seoCheck ul{
  padding: 0;
  list-style: none;
}

.seoCheck a{
  color: var(--linkColor);
  text-decoration: none;
  transition: all 0.5s ease-in-out;
}

.seoCheck img{
  max-width: 100%;
  height: auto;
  display: block;
}

.seoCheck button{
  font-family: inherit;
  cursor: pointer;
}

/* ---------- 共用 ---------- */
.seoCheck .wrap{
  width: 100%;
  max-width: var(--wrapWidth);
  margin: 0 auto;
  padding: 0 20px;
  position: relative;
}

.seoCheck .Img img{
  width: 100%;
}

/* 動畫插圖：figure.Img 內放 inline SVG（見 problemArea / contactArea） */
.seoCheck .Img > svg{
  display: block;
  width: 100%;
  height: auto;
}

/* 暫用裁圖（自設計稿 JPG 裁出、含淺色底）：用 multiply 隱藏底色；換成去背 PNG 後可移除 */
.seoCheck .blendImg img{
  mix-blend-mode: multiply;
}

/* 標題只在空格／標點處斷行 */
.seoCheck .titleBox .title,
.seoCheck .bannerArea .bannerTxt .title,
.seoCheck .priceTitle{
  word-break: keep-all;
  overflow-wrap: anywhere;
}

.seoCheck .textMain{
  color: var(--mainColor);
}

/* 全站文字選取：預設藍底白字 → 主色橘底白字。
   ::selection 與 ::-moz-selection 必須分開寫，不能併成一條選擇器清單——
   清單中只要有一個選擇器瀏覽器不認得，整條規則就會被整個丟棄。 */
.seoCheck ::selection{
  background: var(--mainColor);
  color: #fff;
  text-shadow: none;
}

.seoCheck ::-moz-selection{
  background: var(--mainColor);
  color: #fff;
  text-shadow: none;
}

/* titleBox：三段文字的字級／行高／字距／顏色／間距全部照主站 master.css
   `.titleBox .decoTitle / .title / .exp`（本站 .text ＝ 主站 .exp），
   含 ib_imageText_030.css 的 decoTitle padding-bottom 5px。
   主站 .exp 沒有 RWD 字級，所以 .text 固定 20px、不吃斷點。 */
.seoCheck .titleBox .decoTitle{
  display: block;
  color: #fe5000;
  font-size: var(--decoTitleSize);
  line-height: 1.4;
  letter-spacing: 0.2px;
  padding-bottom: 5px;
}
.seoCheck .titleBox .title{
  font-size: var(--titleSize);
  font-weight: 700;
  line-height: 1.2;
  color: #000;
  letter-spacing: 0.4px;
}
.seoCheck .titleBox .text{
  color: #666; /* 原 #555，內文統一 #666（使用者 2026-09-11） */
  font-size: 20px;
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: 0.3px;
  padding-top: 18px;
}
.seoCheck .titleBox.center{
  text-align: center;
}

/* 標題逐字裁切進場（參考 2608-ai-robot，2026-09-11）
   js/main.js 的 initTitleReveal() 把 .titleBox > .title 與 banner 主標的每個字拆成
   .ch（overflow: hidden 遮罩）＋ 內層 <i>（實際位移的字），拆完加 .isSplit；
   進入視窗加 .isIn，字從遮罩下緣往上推出（110% → 0），delay 由 JS 逐字寫在 inline style。
   離開視窗拿掉 .isIn 時不套 transition，字瞬間回到起始位，捲回來會重播。
   動效偏好關閉、或 JS 沒跑，就不會有 .isSplit，標題照常顯示。 */
.seoCheck .title.isSplit .ch{
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
}
.seoCheck .title.isSplit{
  /* 拆字後每個字都是獨立的 inline-block，英文單字會被逐字斷行；
     連續英數字由 JS 包進 .word，整組不換行 */
}
.seoCheck .title.isSplit .word{
  display: inline-block;
  vertical-align: bottom;
  white-space: nowrap;
}
.seoCheck .title.isSplit .ch > i{
  display: inline-block;
  font-style: normal;
  white-space: pre; /* 保留半形空白的寬度 */
  transform: translateY(110%);
  will-change: transform;
}
.seoCheck .title.isSplit{
  /* 0.9s power3.out ≒ cubic-bezier(.215, .61, .355, 1) */
}
.seoCheck .title.isSplit.isIn .ch > i{
  transform: translateY(0);
  transition: transform 0.9s cubic-bezier(0.215, 0.61, 0.355, 1);
  transition-delay: var(--chDelay, 0s);
}

@media (max-width: 1180px) {
  .seoCheck .titleBox .decoTitle{
    font-size: var(--decoTitleSizeMedium);
  }
  .seoCheck .titleBox .title{
    font-size: var(--titleSizeMedium);
  }
}
@media (max-width: 768px) {
  .seoCheck .titleBox .decoTitle{
    font-size: var(--decoTitleSizeSmall);
  }
  .seoCheck .titleBox .title{
    font-size: var(--titleSizeSmall);
  }
}
@media (max-width: 480px) {
  .seoCheck .titleBox .title{
    font-size: var(--titleSizeXs);
  }
}
/* 只在手機版生效的換行：桌機一行、≤768 在指定位置斷（使用者 2026-09-11 指定標題斷行位置）。
   js/main.js 拆字動效會忽略隱藏中的 .brSm，不會在桌機的單行標題中間多出行間停頓。 */
.seoCheck .brSm{
  display: none;
}

/* 只在桌機顯示的內容（例：手機版已斷行、逗號多餘時把逗號藏掉），與 .brSm 成對使用 */
@media (max-width: 768px) {
  .seoCheck .brSm{
    display: inline;
  }
  .seoCheck .hideSm{
    display: none;
  }
}
/* 按鈕 */
.seoCheck .btnBox{
  display: flex;
  gap: 16px;
}

/* 按鈕 hover 為主站 https://www.ixpert.com.tw/ 原版機制（master.css 行 826–1035）：
   .animation 的 ::after 白色遮罩寬度 0 → 100%，錨點由 right:0 換成 left:0。
   right:auto 無法內插，所以錨點會瞬間跳到左側再展開 → hover 時白色由左往右刷過、
   移出時往右收回，這個來回方向差就是主站的特徵。
   ::after 的 z-index:-1 搭配 .btn 的 z-index:1：按鈕自成堆疊脈絡後，
   遮罩會疊在背景之上、文字之下，所以刷白時文字不會被蓋掉。 */
.seoCheck .btn{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 1;
  min-height: 56px;
  padding: 0 40px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: var(--textSize);
  font-weight: 500;
  line-height: 1;
  transition: all 0.5s;
}
.seoCheck .btn.animation{
  overflow: hidden;
}
.seoCheck .btn.animation::after{
  content: "";
  position: absolute;
  right: 0;
  top: 0;
  z-index: -1;
  width: 0;
  height: 100%;
  background-color: #fff;
  transition: all 0.5s;
}
.seoCheck .btn.bgMain{
  color: var(--btnColor);
  background-color: var(--btnBgColor);
  border-color: var(--btnBgColor);
}
.seoCheck .btn.colorMain{
  color: var(--mainColor);
  background-color: #fff;
  border-color: var(--mainColor);
  /* 反色按鈕的遮罩是橘的，刷過後變橘底白字 */
}
.seoCheck .btn.colorMain.animation::after{
  background-color: var(--mainColor);
}

/* 主站是用 @media (min-width: 1201px) 判定 hover，
   這裡沿用專案規範的 (hover: hover) and (pointer: fine)，避免觸控裝置誤觸發；
   動態本身與主站完全一致。 */
@media (hover: hover) and (pointer: fine) {
  .seoCheck .btn.animation:hover::after{
    width: 100%;
    left: 0;
    right: auto;
  }
  .seoCheck .btn.bgMain:hover{
    color: var(--mainColor);
  }
  /* 沒有 .animation 的按鈕沒有遮罩可刷，直接換底色 */
  .seoCheck .btn.bgMain:hover:not(.animation){
    background-color: #fff;
  }
  .seoCheck .btn.colorMain:hover{
    color: #fff;
  }
  .seoCheck .btn.colorMain:hover:not(.animation){
    background-color: var(--mainColor);
  }
}
/* 區塊背景大字（SOLUTIONS / BLOG） */
.seoCheck .bgWord{
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  font-size: 400px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.02em;
  color: rgba(0, 0, 0, 0.035);
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}

@media (max-width: 1180px) {
  .seoCheck .bgWord{
    font-size: 240px;
  }
}
@media (max-width: 768px) {
  .seoCheck .bgWord{
    font-size: 120px;
  }
}
/* 檢查 / 警示 icon（inline svg 共用尺寸） */
.seoCheck .iconCheck{
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  color: var(--mainColor);
}

/* 卡片警示三角（#iconAlertGlass）：外光暈沿用插畫 problemIllu 的 psAlertShadow 濾鏡數值
   —— dx -4、dy 4、feGaussianBlur stdDeviation 10（≈ CSS blur 20px）、色 rgba(254,30,0,0.5)。
   改用 CSS drop-shadow 是為了讓光暈能畫到 svg viewBox 之外不被切掉。 */
.seoCheck .badgeAlert{
  position: absolute;
  width: 56px;
  height: 56px;
  filter: drop-shadow(-4px 4px 20px rgba(254, 30, 0, 0.5));
}

/* ---------- 無障礙：使用者若在系統關閉動態效果，停用裝飾性循環動畫 ---------- */
@media (prefers-reduced-motion: reduce) {
  .seoCheck .problemIllu *,
.seoCheck .bannerArea .bannerImg .Img,
.seoCheck .bannerArea .badgeItem,
.seoCheck .bannerArea .bannerImg .bannerLens,
.seoCheck .conceptArea .conceptImg .Img,
.seoCheck .contactArea .priceBox .target,
.seoCheck .contactArea .glowBox .glow,
.seoCheck .problemArea .problemItem,
.seoCheck .problemArea .problemItem .badgeAlert,
.seoCheck .problemArea .problemItem .item .icon::before,
.seoCheck .problemArea .problemItem .item .icon::after,
.seoCheck .conceptArea .conceptItem.myth .label svg,
.seoCheck .conceptArea .conceptItem.myth .crossLine,
.seoCheck .conceptArea .conceptItem.myth .textMain::after,
.seoCheck .solutionArea .recommendTag .tagShine,
.seoCheck .solutionArea .compareHint .chev{
    animation: none !important;
  }
  /* 動畫關掉後，叉叉與底線要停在「已經畫完」的狀態，不能停在畫到一半 */
  .seoCheck .conceptArea .conceptItem.myth .crossLine{
    stroke-dashoffset: 0 !important;
  }
  .seoCheck .conceptArea .conceptItem.myth .textMain::after{
    transform: scaleX(1) !important;
  }
  /* 箭是 transition 不是 animation，上面那條 animation: none 抓不到；
     關掉飛行、直接顯示在射中的定點。 */
  .seoCheck .contactArea .priceBox .target .targetArrow{
    transition: none !important;
    transform: none !important;
    opacity: 1 !important;
  }
}
/* ==========================================================
   共用動畫
   ========================================================== */
@keyframes slideUpAnimation {
  0% {
    opacity: 0;
    transform: translateY(10px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes floatY {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    /* 幅度可由 --floatY 覆寫（預設 12px）。banner 螢幕圖設 6px 減半，
       其餘用到 floatY 的區塊不指定就維持原本的 12px。 */
    transform: translateY(calc(var(--floatY, 12px) * -1));
  }
}
/* 卡片微弱懸浮（problemArea .problemItem），幅度比 floatY 小 */
@keyframes floatCard {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-5px);
  }
}
/* 「推薦方案」膠囊反光：光帶 rect 起點 x=-40（寬 70），外層 skewX(-20) 會讓
   下緣再往左偏約 30，膠囊右緣 x=256，所以往右移 360 就完全掃出膠囊外。
   前 40% 掃過，之後停住等下一輪，避免光帶一直閃太搶眼。 */
@keyframes tagShine {
  0% {
    transform: translateX(0);
  }
  40%, 100% {
    transform: translateX(360px);
  }
}
/* SCROLL DOWN 同心圓：整顆（外環＋內圓）一起上下浮動，
   動畫必須掛在外層 .dot，若掛在內圓 ::after 上內圓會滑出外環變成錯位 */
/* 線段與同心圓必須同相位、同位移量（60px × 0.1 = 6px = dot 的 translateY），
   否則圓往下走時會離開線段末端 */
@keyframes scrollLine {
  0%, 100% {
    transform: scaleY(1);
  }
  50% {
    transform: scaleY(1.1);
  }
}
@keyframes scrollDot {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(6px);
  }
}
/* ----------------------------------------------------------
   插圖動畫（problemArea / contactArea 的 inline SVG）
   位移單位為 SVG user unit，因 viewBox 與原始尺寸 1:1，等同 px。
   ---------------------------------------------------------- */
/* 循環動作一律寫成「單向」（from = 靜止、to = 峰值），播放端用
   `animation-direction: alternate` 正播一次＋反播一次無限循環：
   路徑天生對稱、兩端的速度都是 0，循環最順，也不會有「重來一次」的機械感。
   時長是單程時間，來回一趟＝2 倍（改數值時記得換算）。
   例外：boltFlash（閃電快閃）、markBounce（!! 彈跳）、alertPulse（三角脈動）是刻意的
   重音節拍，本來就從靜止出發、回到靜止，維持原本的來回寫法、不加 alternate；
   alertPulse 另外還被 .problemItem .badgeAlert 共用，改它會連帶影響卡片上的警示圖示。 */
/* 閃電：每輪開頭快閃兩下，其餘時間靜止 */
@keyframes boltFlash {
  0% {
    opacity: 1;
    transform: scale(1);
  }
  5% {
    opacity: 0.2;
    transform: scale(0.94);
  }
  11% {
    opacity: 1;
    transform: scale(1.1);
  }
  17% {
    opacity: 0.45;
    transform: scale(1);
  }
  23% {
    opacity: 1;
    transform: scale(1.04);
  }
  32%, 100% {
    opacity: 1;
    transform: scale(1);
  }
}
/* 「!!」雙驚嘆號：彈跳兩下後靜止 */
@keyframes markBounce {
  0% {
    transform: translateY(0);
  }
  12% {
    transform: translateY(-5px);
  }
  26% {
    transform: translateY(0);
  }
  36% {
    transform: translateY(-2.5px);
  }
  46%, 100% {
    transform: translateY(0);
  }
}
/* 卡片左上警示圖示：鬧鐘式左右晃動，1.5s 一輪（前 60% 小幅度擺 6 下、其餘 40% 靜止），
   每下約 ±6°、0.15s，transform-origin 設在底部中央，搭配 .problemItem .badgeAlert 使用 */
@keyframes alertShake {
  0% {
    transform: rotate(0deg);
  }
  5% {
    transform: rotate(-6deg);
  }
  15% {
    transform: rotate(6deg);
  }
  25% {
    transform: rotate(-6deg);
  }
  35% {
    transform: rotate(6deg);
  }
  45% {
    transform: rotate(-6deg);
  }
  55% {
    transform: rotate(6deg);
  }
  60%, 100% {
    transform: rotate(0deg);
  }
}
/* 警示三角：緩慢脈動（本來就是對稱來回、端點速度為 0，維持原寫法；
   注意 .problemItem .badgeAlert 也共用這組 keyframes，改動會連帶影響卡片上的警示圖示） */
@keyframes alertPulse {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.07);
  }
}
/* ---------- problemArea 新插圖（.problemIllu）：人物與物件的循環動作 ----------
   位移／角度單位皆為 SVG user unit（viewBox 425×264 與顯示尺寸 1:1，等同 px）。
   幅度一律壓在「看得出來在動、但不會覺得圖歪掉」的範圍：旋轉 ≤2.6°、縮放 ≤0.8%。 */
/* 人物呼吸：以桌面線為軸做極小幅 scaleY，只有上半身微微起伏 */
@keyframes psBreath {
  from {
    transform: scaleY(1);
  }
  to {
    transform: scaleY(1.02);
  }
}
/* 男生點頭：兩段式，像在看螢幕時邊聽邊點頭 */
@keyframes psNod {
  from {
    transform: rotate(0deg) translateY(0);
  }
  to {
    transform: rotate(-4.5deg) translateY(1px);
  }
}
/* 女生：頭髮與臉同 pivot、同節奏的側傾（幅度比男生大，因為她是站著看螢幕、動作比較外顯） */
@keyframes psTilt {
  from {
    transform: rotate(-2.5deg);
  }
  to {
    transform: rotate(5deg);
  }
}
/* 女生身體：呼吸之外再加一點以腳下為軸的重心擺動。
   整個人（頭髮＋身體＋臉）包在同一個 <g> 裡一起轉，脖子才不會脫節；
   週期刻意跟頭部側傾錯開（3.8s vs 4.6s），兩個動作疊起來就不會看起來像機械式來回。 */
@keyframes psWomanSway {
  from {
    transform: rotate(-0.5deg) scaleY(1);
  }
  to {
    transform: rotate(0.5deg) scaleY(1.025);
  }
}
/* 指著螢幕的手：每輪點兩下（與警示三角的 2.6s 節奏同步） */
@keyframes psPoint {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(-5deg);
  }
}
/* 盆栽葉子：以盆口為軸左右搖擺 */
@keyframes psSway {
  from {
    transform: rotate(-1.8deg);
  }
  to {
    transform: rotate(1.8deg);
  }
}
/* 螢幕長條圖：由底部長高／縮回（搭配 nth-child 延遲做出依序律動） */
@keyframes psBarGrow {
  from {
    transform: scaleY(1);
  }
  to {
    transform: scaleY(0.5);
  }
}
/* 螢幕折線圖資料點：依序閃爍 */
@keyframes psDotBlink {
  from {
    opacity: 1;
    transform: scale(1);
  }
  to {
    opacity: 0.2;
    transform: scale(0.6);
  }
}
/* ---------- problemArea 插圖的「進場」動畫（由 js/main.js 的 IntersectionObserver 加 .isShow 觸發）----------
   .isReady 先把要進場的元素壓成起始態，沒有 JS 時不加 class＝完全不套用，插圖照常靜態顯示。 */
/* 螢幕：以底座為軸由小而大展開，尾段小回彈 */
@keyframes psScreenOpen {
  0% {
    opacity: 0;
    transform: scale(0.55);
  }
  55% {
    opacity: 1;
    transform: scale(1.05);
  }
  75% {
    transform: scale(0.985);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}
/* 螢幕內的卡片：淡入＋輕微上浮（搭配 nth 延遲依序出現） */
@keyframes psFadeUp {
  0% {
    opacity: 0;
    transform: translateY(6px) scale(0.94);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
/* 警示三角：彈入後才接上 alertPulse 的循環 */
@keyframes psPop {
  0% {
    opacity: 0;
    transform: scale(0.2);
  }
  65% {
    opacity: 1;
    transform: scale(1.15);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}
/* banner 放大鏡閒置動畫：在儀表板右下角走一圈有明確方向的掃描環，
   右上 → 右 → 右下 → 左下 → 左上收回，一圈約 402 px，並在兩個位置明顯放慢做「檢視」。

   控制點（封閉 Catmull-Rom，座標＝鏡片圓心，設計靜止點是 (1378,534)）：
   (1406,512) → (1430,470) → (1472,534) → (1464,612) → (1394,624)
   兩個停頓點：(1430,470) 壓在那排灰色圓點上、(1464,612) 壓在右邊那組橘色膠囊上。

   ── 為什麼形狀是歪的、不能整條平移 ──
   安全區是「上窄下寬」的錐形，左邊界越往上越靠右：
   y 470 只有 x 1420–1440、y 500 是 1400–1450、y 530 是 1400–1480、y 560 之後才開到 1380–1490。
   （上界是「92%」數字＋放大鏡握把，右界是「結構化資料完整度」膠囊。）
   所以要把路徑往上移，必須同時把左半邊往右收，不能整條平移。

   ── 速度 ──
   時間軸用 linear，緩進緩出與停頓都寫在關鍵影格的疏密裡。
   速度 v(t) = 1 − 0.92 ×（兩個高斯凹陷，中心在上述兩點的弧長位置、寬 0.055），下限 0.03
   —— 接近靜止但沒有真的停死，進出都是平滑的。
   凹陷有做週期外的鏡像疊加，所以循環接點的速度連續，繞回起點不會頓。
   位置沿曲線**弧長**取樣 57 格，速度才是真的均勻。

   ── 旋轉 ──
   只有 0 ~ −12deg，與高度連動（越高越側），維持「稍微側著往前推」的前進感，不會變得太垂直。
   **不要再加大**：握把從圓心往左下延伸，角度一大就會掃到「92%」或「SEO SCORE」；
   而且外層 .lensFly 有 drop-shadow 濾鏡，旋轉幅度越大越容易觸發閃爍。

   ── 避讓（沿曲線 400 點、用旋轉後的完整輪廓實測）──
   「92%」數字、SEO SCORE、五顆膠囊、左欄文案，全程重疊皆為 0。
   活動範圍 x 1394–1472 / y 470–632，完全在儀表板內。

   --lensWobble（js/main.js 依捲動進度寫入 1 − 進度，且值有變才寫）：整組動態的幅度，
   捲動後平滑收掉，接著由 JS 把 .lensFly 往下帶到 problemArea；
   到站後改由橘卡裡的 .hiLens 跑 lensInspect。 */
@keyframes lensSearch {
  0% {
    transform: translate3d(calc(var(--lensWobble, 1) * 28px), calc(var(--lensWobble, 1) * -22px), 0) rotate(calc(var(--lensWobble, 1) * -8.86deg));
  }
  1.79% {
    transform: translate3d(calc(var(--lensWobble, 1) * 30.1px), calc(var(--lensWobble, 1) * -30.4px), 0) rotate(calc(var(--lensWobble, 1) * -9.48deg));
  }
  3.57% {
    transform: translate3d(calc(var(--lensWobble, 1) * 32.3px), calc(var(--lensWobble, 1) * -38.6px), 0) rotate(calc(var(--lensWobble, 1) * -10.09deg));
  }
  5.36% {
    transform: translate3d(calc(var(--lensWobble, 1) * 34.8px), calc(var(--lensWobble, 1) * -46.2px), 0) rotate(calc(var(--lensWobble, 1) * -10.65deg));
  }
  7.14% {
    transform: translate3d(calc(var(--lensWobble, 1) * 37.5px), calc(var(--lensWobble, 1) * -52.7px), 0) rotate(calc(var(--lensWobble, 1) * -11.13deg));
  }
  8.93% {
    transform: translate3d(calc(var(--lensWobble, 1) * 39.9px), calc(var(--lensWobble, 1) * -57.3px), 0) rotate(calc(var(--lensWobble, 1) * -11.47deg));
  }
  10.71% {
    transform: translate3d(calc(var(--lensWobble, 1) * 41.7px), calc(var(--lensWobble, 1) * -59.8px), 0) rotate(calc(var(--lensWobble, 1) * -11.65deg));
  }
  12.5% {
    transform: translate3d(calc(var(--lensWobble, 1) * 42.5px), calc(var(--lensWobble, 1) * -60.8px), 0) rotate(calc(var(--lensWobble, 1) * -11.73deg));
  }
  14.29% {
    transform: translate3d(calc(var(--lensWobble, 1) * 43px), calc(var(--lensWobble, 1) * -61.3px), 0) rotate(calc(var(--lensWobble, 1) * -11.77deg));
  }
  16.07% {
    transform: translate3d(calc(var(--lensWobble, 1) * 44.4px), calc(var(--lensWobble, 1) * -62.6px), 0) rotate(calc(var(--lensWobble, 1) * -11.86deg));
  }
  17.86% {
    transform: translate3d(calc(var(--lensWobble, 1) * 47.9px), calc(var(--lensWobble, 1) * -64.3px), 0) rotate(calc(var(--lensWobble, 1) * -11.99deg));
  }
  19.64% {
    transform: translate3d(calc(var(--lensWobble, 1) * 53.7px), calc(var(--lensWobble, 1) * -63.2px), 0) rotate(calc(var(--lensWobble, 1) * -11.91deg));
  }
  21.43% {
    transform: translate3d(calc(var(--lensWobble, 1) * 59.6px), calc(var(--lensWobble, 1) * -58.7px), 0) rotate(calc(var(--lensWobble, 1) * -11.57deg));
  }
  23.21% {
    transform: translate3d(calc(var(--lensWobble, 1) * 65.2px), calc(var(--lensWobble, 1) * -52.6px), 0) rotate(calc(var(--lensWobble, 1) * -11.13deg));
  }
  25% {
    transform: translate3d(calc(var(--lensWobble, 1) * 70.5px), calc(var(--lensWobble, 1) * -45.9px), 0) rotate(calc(var(--lensWobble, 1) * -10.63deg));
  }
  26.79% {
    transform: translate3d(calc(var(--lensWobble, 1) * 75.5px), calc(var(--lensWobble, 1) * -38.7px), 0) rotate(calc(var(--lensWobble, 1) * -10.1deg));
  }
  28.57% {
    transform: translate3d(calc(var(--lensWobble, 1) * 80.2px), calc(var(--lensWobble, 1) * -31.3px), 0) rotate(calc(var(--lensWobble, 1) * -9.55deg));
  }
  30.36% {
    transform: translate3d(calc(var(--lensWobble, 1) * 84.4px), calc(var(--lensWobble, 1) * -23.7px), 0) rotate(calc(var(--lensWobble, 1) * -8.98deg));
  }
  32.14% {
    transform: translate3d(calc(var(--lensWobble, 1) * 88.3px), calc(var(--lensWobble, 1) * -15.9px), 0) rotate(calc(var(--lensWobble, 1) * -8.4deg));
  }
  33.93% {
    transform: translate3d(calc(var(--lensWobble, 1) * 91.6px), calc(var(--lensWobble, 1) * -7.8px), 0) rotate(calc(var(--lensWobble, 1) * -7.8deg));
  }
  35.71% {
    transform: translate3d(calc(var(--lensWobble, 1) * 94.1px), calc(var(--lensWobble, 1) * 0.6px), 0) rotate(calc(var(--lensWobble, 1) * -7.19deg));
  }
  37.5% {
    transform: translate3d(calc(var(--lensWobble, 1) * 95.8px), calc(var(--lensWobble, 1) * 9.2px), 0) rotate(calc(var(--lensWobble, 1) * -6.55deg));
  }
  39.29% {
    transform: translate3d(calc(var(--lensWobble, 1) * 96.8px), calc(var(--lensWobble, 1) * 17.9px), 0) rotate(calc(var(--lensWobble, 1) * -5.91deg));
  }
  41.07% {
    transform: translate3d(calc(var(--lensWobble, 1) * 97.3px), calc(var(--lensWobble, 1) * 26.5px), 0) rotate(calc(var(--lensWobble, 1) * -5.26deg));
  }
  42.86% {
    transform: translate3d(calc(var(--lensWobble, 1) * 97.3px), calc(var(--lensWobble, 1) * 35.1px), 0) rotate(calc(var(--lensWobble, 1) * -4.63deg));
  }
  44.64% {
    transform: translate3d(calc(var(--lensWobble, 1) * 96.9px), calc(var(--lensWobble, 1) * 43.1px), 0) rotate(calc(var(--lensWobble, 1) * -4.04deg));
  }
  46.43% {
    transform: translate3d(calc(var(--lensWobble, 1) * 96.2px), calc(var(--lensWobble, 1) * 50.1px), 0) rotate(calc(var(--lensWobble, 1) * -3.52deg));
  }
  48.21% {
    transform: translate3d(calc(var(--lensWobble, 1) * 95.3px), calc(var(--lensWobble, 1) * 55.4px), 0) rotate(calc(var(--lensWobble, 1) * -3.12deg));
  }
  50% {
    transform: translate3d(calc(var(--lensWobble, 1) * 94.6px), calc(var(--lensWobble, 1) * 58.6px), 0) rotate(calc(var(--lensWobble, 1) * -2.89deg));
  }
  51.79% {
    transform: translate3d(calc(var(--lensWobble, 1) * 94.3px), calc(var(--lensWobble, 1) * 59.9px), 0) rotate(calc(var(--lensWobble, 1) * -2.79deg));
  }
  53.57% {
    transform: translate3d(calc(var(--lensWobble, 1) * 94.1px), calc(var(--lensWobble, 1) * 60.7px), 0) rotate(calc(var(--lensWobble, 1) * -2.74deg));
  }
  55.36% {
    transform: translate3d(calc(var(--lensWobble, 1) * 93.7px), calc(var(--lensWobble, 1) * 62.4px), 0) rotate(calc(var(--lensWobble, 1) * -2.61deg));
  }
  57.14% {
    transform: translate3d(calc(var(--lensWobble, 1) * 92.5px), calc(var(--lensWobble, 1) * 65.9px), 0) rotate(calc(var(--lensWobble, 1) * -2.35deg));
  }
  58.93% {
    transform: translate3d(calc(var(--lensWobble, 1) * 90.3px), calc(var(--lensWobble, 1) * 71.3px), 0) rotate(calc(var(--lensWobble, 1) * -1.95deg));
  }
  60.71% {
    transform: translate3d(calc(var(--lensWobble, 1) * 86.4px), calc(var(--lensWobble, 1) * 77.5px), 0) rotate(calc(var(--lensWobble, 1) * -1.49deg));
  }
  62.5% {
    transform: translate3d(calc(var(--lensWobble, 1) * 80.3px), calc(var(--lensWobble, 1) * 83px), 0) rotate(calc(var(--lensWobble, 1) * -1.08deg));
  }
  64.29% {
    transform: translate3d(calc(var(--lensWobble, 1) * 73px), calc(var(--lensWobble, 1) * 87.5px), 0) rotate(calc(var(--lensWobble, 1) * -0.75deg));
  }
  66.07% {
    transform: translate3d(calc(var(--lensWobble, 1) * 65.1px), calc(var(--lensWobble, 1) * 91.1px), 0) rotate(calc(var(--lensWobble, 1) * -0.48deg));
  }
  67.86% {
    transform: translate3d(calc(var(--lensWobble, 1) * 56.8px), calc(var(--lensWobble, 1) * 94px), 0) rotate(calc(var(--lensWobble, 1) * -0.27deg));
  }
  69.64% {
    transform: translate3d(calc(var(--lensWobble, 1) * 48.4px), calc(var(--lensWobble, 1) * 96.2px), 0) rotate(calc(var(--lensWobble, 1) * -0.11deg));
  }
  71.43% {
    transform: translate3d(calc(var(--lensWobble, 1) * 39.7px), calc(var(--lensWobble, 1) * 97.4px), 0) rotate(calc(var(--lensWobble, 1) * -0.02deg));
  }
  73.21% {
    transform: translate3d(calc(var(--lensWobble, 1) * 31px), calc(var(--lensWobble, 1) * 97.5px), 0) rotate(calc(var(--lensWobble, 1) * -0.01deg));
  }
  75% {
    transform: translate3d(calc(var(--lensWobble, 1) * 22.5px), calc(var(--lensWobble, 1) * 95.5px), 0) rotate(calc(var(--lensWobble, 1) * -0.16deg));
  }
  76.79% {
    transform: translate3d(calc(var(--lensWobble, 1) * 15.9px), calc(var(--lensWobble, 1) * 89.9px), 0) rotate(calc(var(--lensWobble, 1) * -0.57deg));
  }
  78.57% {
    transform: translate3d(calc(var(--lensWobble, 1) * 13.5px), calc(var(--lensWobble, 1) * 81.6px), 0) rotate(calc(var(--lensWobble, 1) * -1.19deg));
  }
  80.36% {
    transform: translate3d(calc(var(--lensWobble, 1) * 12.9px), calc(var(--lensWobble, 1) * 72.8px), 0) rotate(calc(var(--lensWobble, 1) * -1.84deg));
  }
  82.14% {
    transform: translate3d(calc(var(--lensWobble, 1) * 13.2px), calc(var(--lensWobble, 1) * 64.1px), 0) rotate(calc(var(--lensWobble, 1) * -2.48deg));
  }
  83.93% {
    transform: translate3d(calc(var(--lensWobble, 1) * 13.8px), calc(var(--lensWobble, 1) * 55.4px), 0) rotate(calc(var(--lensWobble, 1) * -3.13deg));
  }
  85.71% {
    transform: translate3d(calc(var(--lensWobble, 1) * 14.8px), calc(var(--lensWobble, 1) * 46.7px), 0) rotate(calc(var(--lensWobble, 1) * -3.77deg));
  }
  87.5% {
    transform: translate3d(calc(var(--lensWobble, 1) * 16px), calc(var(--lensWobble, 1) * 38px), 0) rotate(calc(var(--lensWobble, 1) * -4.41deg));
  }
  89.29% {
    transform: translate3d(calc(var(--lensWobble, 1) * 17.4px), calc(var(--lensWobble, 1) * 29.4px), 0) rotate(calc(var(--lensWobble, 1) * -5.05deg));
  }
  91.07% {
    transform: translate3d(calc(var(--lensWobble, 1) * 18.9px), calc(var(--lensWobble, 1) * 20.8px), 0) rotate(calc(var(--lensWobble, 1) * -5.69deg));
  }
  92.86% {
    transform: translate3d(calc(var(--lensWobble, 1) * 20.6px), calc(var(--lensWobble, 1) * 12.2px), 0) rotate(calc(var(--lensWobble, 1) * -6.33deg));
  }
  94.64% {
    transform: translate3d(calc(var(--lensWobble, 1) * 22.3px), calc(var(--lensWobble, 1) * 3.6px), 0) rotate(calc(var(--lensWobble, 1) * -6.96deg));
  }
  96.43% {
    transform: translate3d(calc(var(--lensWobble, 1) * 24.1px), calc(var(--lensWobble, 1) * -5px), 0) rotate(calc(var(--lensWobble, 1) * -7.6deg));
  }
  98.21% {
    transform: translate3d(calc(var(--lensWobble, 1) * 26px), calc(var(--lensWobble, 1) * -13.5px), 0) rotate(calc(var(--lensWobble, 1) * -8.23deg));
  }
  100% {
    transform: translate3d(calc(var(--lensWobble, 1) * 28px), calc(var(--lensWobble, 1) * -22px), 0) rotate(calc(var(--lensWobble, 1) * -8.86deg));
  }
}
/* problemArea 標題橘卡到站後的「檢視」動畫。
   跑在文件流裡的 .hiLens（不是 fixed 的 .lensFly），所以完全不受捲動影響、不會抖。
   幅度刻意做得比 banner 的巡視明顯：位移 + 旋轉 + 縮放脈動（像真的在對焦放大）。
   偏左設計：x 只在 -30 ~ +10 之間，橘卡文字最左緣在 x 676、鏡片右緣最遠 598，
   最靠近時仍留 78px，不會碰到文案。
   transform-origin 設在鏡片圓心 (145,76)（236px 寬時），縮放才不會把整支歪掉。 */
@keyframes lensInspect {
  0% {
    transform: translate3d(0, 0, 0) rotate(0deg) scale(1);
  }
  14% {
    transform: translate3d(-14px, -10px, 0) rotate(-2.4deg) scale(1.035);
  }
  30% {
    transform: translate3d(-30px, 2px, 0) rotate(-4deg) scale(1.075);
  }
  46% {
    transform: translate3d(-22px, 14px, 0) rotate(-1.6deg) scale(1.05);
  }
  62% {
    transform: translate3d(-4px, 16px, 0) rotate(1.8deg) scale(1.02);
  }
  78% {
    transform: translate3d(10px, 6px, 0) rotate(3.4deg) scale(1.045);
  }
  90% {
    transform: translate3d(6px, -6px, 0) rotate(1.6deg) scale(1.02);
  }
  100% {
    transform: translate3d(0, 0, 0) rotate(0deg) scale(1);
  }
}
/* solutionArea 方案 icon：圓形漣漪（兩圈錯開半週期，形成連續往外擴散） */
@keyframes iconRipple {
  0% {
    transform: translate(-50%, -50%) scale(0.9);
    opacity: 0.5;
  }
  100% {
    transform: translate(-50%, -50%) scale(1.5);
    opacity: 0;
  }
}
/* solutionArea 方案 icon：本體輕微呼吸縮放 */
@keyframes iconBreath {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.06);
  }
}
/* 「推薦方案」標籤上的皇冠：上下懸浮。
   badge 桌機為 1:1 顯示（svg 286×117 對 CSS 286px），這裡的 px 就是畫面 px。
   皇冠 bbox 上緣 y≈44、膠囊上緣 y=25，所以上移量最多 19px 才會頂到膠囊邊。 */
@keyframes crownFloat {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-5px);
  }
}
/* contactArea 背景光暈。

   漫遊那顆（.glowRoam）拆成三條互質週期的動畫：X 17s／Y 23s／淡入淡出 13s，
   LCM = 17×23×13 = 5,083 秒（約 85 分鐘），在那之前路徑與亮度的組合都不會重複。
   X 要拆到外層、Y 放內層，是因為同一元素跑兩條 transform 動畫時後者會整條覆蓋前者。 */
/* 水平：元素靠右（right: -10%），向左 82vw 大約就碰到左緣；
   停點取 0 / -30 / -82 / -46 / 0 vw，間距不均匀才不會像等速來回。 */
@keyframes glowRoamX {
  0%, 100% {
    transform: translateX(0);
  }
  26% {
    transform: translateX(-30vw);
  }
  52% {
    transform: translateX(-82vw);
  }
  79% {
    transform: translateX(-46vw);
  }
}
/* 垂直＋縮放：幅度刻意比水平小，不要跑出區塊上下緣太多 */
@keyframes glowRoamY {
  0%, 100% {
    transform: translateY(0) scale(1);
  }
  21% {
    transform: translateY(14vh) scale(1.12);
  }
  47% {
    transform: translateY(-6vh) scale(0.9);
  }
  68% {
    transform: translateY(19vh) scale(1.05);
  }
  86% {
    transform: translateY(5vh) scale(0.96);
  }
}
/* 淡入淡出：最暗降到 0.12（幾乎消失），不歸零是避免不見後又突然冒出來 */
@keyframes glowFade {
  0%, 100% {
    opacity: 0.85;
  }
  17% {
    opacity: 0.35;
  }
  38% {
    opacity: 1;
  }
  59% {
    opacity: 0.12;
  }
  81% {
    opacity: 0.7;
  }
}
/* contactArea 射箭：箭從右上方（部落格區方向）沿箭軸飛進來釘到靶心。
   位移用 % 而不用 px：translate 的 % 參照元素自己的尺寸，手機版箭變小時飛行距離會自動等比縮，不用分斷點調。
   279% / -274% 是沿箭軸（水平上方 36.3°）退約 420px（以桌機版箭寬 121px 換算）。 */
@keyframes arrowShot {
  0% {
    opacity: 0;
    transform: translate(279%, -274%) scale(1.35);
  }
  25% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: translate(0, 0) scale(1);
  }
}
/* 中靶漣漪：靶盤是斜的（量測：長軸 52.2°、短/長軸比 0.827），
   每一幀都要先 rotate ＋ scaleY 把圓壓成同角度的椭圓，再做均匀縮放，
   不然會變成一個正圓套在斜靶盤上，一看就趿。 */
@keyframes hitRipple {
  /* 兩波寫在同一條動畫裡，是因為 CSS 的 iteration-count 沒辦法讓第二刷跑不同的值。
     50% 這個接點靠 step-end 瞬間把縮放跳回起點，不然會看到環從外面縮回來。 */
  0% {
    opacity: 0.85;
    transform: rotate(52.2deg) scaleY(0.827) scale(0.28);
    animation-timing-function: ease-out;
  }
  49.99% {
    opacity: 0;
    transform: rotate(52.2deg) scaleY(0.827) scale(1.6);
    animation-timing-function: step-end;
  }
  /* 第二波：透明度取第一波的一半 */
  50% {
    opacity: 0.42;
    transform: rotate(52.2deg) scaleY(0.827) scale(0.28);
    animation-timing-function: ease-out;
  }
  100% {
    opacity: 0;
    transform: rotate(52.2deg) scaleY(0.827) scale(1.6);
  }
}
/* 中靶震動：震幅逐次衰減的小幅位移＋微旋轉，最後歸位。
   位移用 % （參照元素自身尺寸），手機版靶變小時震幅會自動等比縮。 */
@keyframes targetHit {
  0% {
    transform: translate(0, 0) rotate(0deg);
  }
  14% {
    transform: translate(-2.4%, 1.1%) rotate(-1.3deg);
  }
  32% {
    transform: translate(1.8%, -0.8%) rotate(0.9deg);
  }
  52% {
    transform: translate(-1.1%, 0.5%) rotate(-0.55deg);
  }
  72% {
    transform: translate(0.6%, -0.3%) rotate(0.3deg);
  }
  100% {
    transform: translate(0, 0) rotate(0deg);
  }
}
/* ==========================================================
   conceptArea 錯誤迷思卡：畫叉叉 → 畫底線 → 停 1.4s → 收回，3s 一輪
   三組共用同一條時間軸，改節奏請三組一起改百分比。
   17 = 每一劃的路徑長（M6 6l12 12 → √(12²+12²) ≈ 16.97），dasharray 取 18 保險。
   ========================================================== */
@keyframes mythCrossL1 {
  0% {
    stroke-dashoffset: 18;
  }
  12% {
    stroke-dashoffset: 0;
  }
  88% {
    stroke-dashoffset: 0;
  }
  96%, 100% {
    stroke-dashoffset: 18;
  }
}
@keyframes mythCrossL2 {
  0%, 12% {
    stroke-dashoffset: 18;
  }
  24% {
    stroke-dashoffset: 0;
  }
  88% {
    stroke-dashoffset: 0;
  }
  96%, 100% {
    stroke-dashoffset: 18;
  }
}
@keyframes mythUnderline {
  0%, 24% {
    transform: scaleX(0);
  }
  40% {
    transform: scaleX(1);
  }
  88% {
    transform: scaleX(1);
  }
  96%, 100% {
    transform: scaleX(0);
  }
}
/* conceptArea 錯誤迷思卡的警示三角：放大後左右各晃兩下再收回。
   注意：problemArea 另有 alertShake／alertPulse 在用，兩邊不要互相沿用。 */
@keyframes mythAlertShake {
  0%, 48%, 100% {
    transform: scale(1) rotate(0deg);
  }
  6% {
    transform: scale(1.3) rotate(0deg);
  }
  11% {
    transform: scale(1.3) rotate(-15deg);
  }
  16% {
    transform: scale(1.3) rotate(15deg);
  }
  21% {
    transform: scale(1.3) rotate(-15deg);
  }
  26% {
    transform: scale(1.3) rotate(15deg);
  }
  31% {
    transform: scale(1.3) rotate(-15deg);
  }
  36% {
    transform: scale(1.3) rotate(15deg);
  }
  42% {
    transform: scale(1.3) rotate(0deg);
  }
}
/* Pyramid layers fall with their labels, sway sideways, then settle on impact. */
@keyframes pyramidHeavyDrop {
  0% {
    opacity: 0;
    transform: translateY(-380px) scale(1, 1);
  }
  10% {
    opacity: 1;
  }
  60% {
    transform: translateY(0) scale(1, 1);
    animation-timing-function: ease-out;
  }
  72% {
    transform: translateY(0) scale(1.022, 0.972);
    animation-timing-function: ease-in-out;
  }
  88% {
    transform: translateY(0) scale(0.998, 1.003);
    animation-timing-function: ease-in-out;
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1, 1);
  }
}
/* Independent horizontal easing keeps the vertical fall uninterrupted. */
@keyframes pyramidSway {
  0% {
    translate: -4px 0;
  }
  30% {
    translate: 3px 0;
  }
  60% {
    translate: -2px 0;
  }
  73% {
    translate: 2px 0;
  }
  86% {
    translate: -0.8px 0;
  }
  100% {
    translate: 0 0;
  }
}
/* conceptArea 金字塔進場的交接：掉落切片淡出，露出底下同樣位置的 .s1。
   用 animation 而非 transition——切片是被 animation 撐在 opacity: 1 的，
   換成另一支 animation 才接得上（改 transition 會直接跳回基準值 0 而閃一下）。 */
@keyframes pyramidPieceFade {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
/* 手機版放大鏡的漂移：左下 → 右上 → 左下，來回一次。
   每一格都必須帶著 -61.6% / -32.1% 這組**定位用**的基準位移
   （.bannerLens 靠它把鏡片圓心對到 left/top 上），
   只寫位移量的話會蓋掉基準值、放大鏡會整顆跳位。 */
@keyframes bannerLensDrift {
  0%, 100% {
    transform: translate(calc(-61.6% - 9px), calc(-32.1% + 9px));
  }
  50% {
    transform: translate(calc(-61.6% + 9px), calc(-32.1% - 9px));
  }
}
/* 手機版比較表「往右滑動看更多」的雙箭頭：往右推出並淡出，兩個 chevron 錯拍循環 */
@keyframes swipeHint {
  0% {
    transform: translateX(-4px);
    opacity: 0.3;
  }
  40% {
    transform: translateX(2px);
    opacity: 1;
  }
  70% {
    transform: translateX(6px);
    opacity: 0.6;
  }
  100% {
    transform: translateX(8px);
    opacity: 0;
  }
}
/* 手機版 Banner 膠囊「定點冒出」（2026-09-11 第三版：淡入淡出放慢）：
   從無限小放大到固定尺寸並淡入（0.8s）→ 微微上移 12px（0.4s）→ 定住 1.5s → 再上移到 24px、慢慢縮小淡出（1.8s）。
   每顆可見 4.5s；週期 6s，之後到 100% 都是隱藏（＝下一次冒出前的等待）。
   只動 transform／opacity，交給 GPU；冒出位置由 scss/index.scss 的 .b1～.b5 各自的 bottom 決定。
   要調淡出快慢：改 45% → 75% 這段的長度；要調停留：改 20% → 45%。 */
@keyframes badgeBubble {
  0% {
    opacity: 0;
    transform: translateY(0) scale(0);
  }
  13.3% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  20%, 45% {
    opacity: 1;
    transform: translateY(-12px) scale(1);
  }
  75%, 100% {
    opacity: 0;
    transform: translateY(-24px) scale(0.7);
  }
}
/* ---- 檢測中 loading（scanArea） ---- */
/* 雷達扇形沿刻度環順時針轉 */
@keyframes scanSweep {
  to {
    transform: rotate(360deg);
  }
}
/* 核心圓內的橫向掃描光束上下來回 */
@keyframes scanBeam {
  0% {
    top: 8%;
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    top: 92%;
    opacity: 0;
  }
}
/* 完成膠囊彈出＋果凍彈跳 3 下（使用者 2026-09-11）：先放大出現，再橫豎交替擠壓／拉伸三次收斂 */
@keyframes scanPop {
  0% {
    transform: translateX(-50%) scale(0.4);
    opacity: 0;
  }
  18% {
    transform: translateX(-50%) scale(1.15, 0.85);
    opacity: 1;
  }
  32% {
    transform: translateX(-50%) scale(0.9, 1.1);
  }
  46% {
    transform: translateX(-50%) scale(1.08, 0.94);
  }
  60% {
    transform: translateX(-50%) scale(0.96, 1.04);
  }
  74% {
    transform: translateX(-50%) scale(1.03, 0.98);
  }
  88% {
    transform: translateX(-50%) scale(0.99, 1.01);
  }
  100% {
    transform: translateX(-50%) scale(1);
    opacity: 1;
  }
}
/* 進行中步驟的圓點呼吸 */
@keyframes scanDot {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(255, 80, 1, 0.35);
  }
  50% {
    box-shadow: 0 0 0 6px rgba(255, 80, 1, 0);
  }
}
/* 儀表板進場 */
@keyframes scanIn {
  from {
    opacity: 0;
    transform: scale(0.92);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}
/* ---- 檢測步驟的階段小動畫（.scanStep.isActive 內的 SVG） ---- */
/* ① 連線畫出 */
@keyframes stepDraw {
  0% {
    stroke-dashoffset: 16;
  }
  50% {
    stroke-dashoffset: 0;
  }
  100% {
    stroke-dashoffset: 0;
  }
}
/* ① 節點依序放大亮起 */
@keyframes stepNode {
  0%, 100% {
    transform: scale(0.7);
    opacity: 0.4;
  }
  40%, 70% {
    transform: scale(1);
    opacity: 1;
  }
}
/* ② 文件線條由左長出 */
@keyframes stepLine {
  0% {
    transform: scaleX(0);
    opacity: 0.3;
  }
  45% {
    transform: scaleX(1);
    opacity: 1;
  }
  80% {
    transform: scaleX(1);
    opacity: 1;
  }
  100% {
    transform: scaleX(1);
    opacity: 0.3;
  }
}
/* ③ 放大鏡左右掃 */
@keyframes stepScan {
  from {
    transform: translate(-4px, -2px);
  }
  to {
    transform: translate(4px, 2px);
  }
}
/* ③ 文字列跟著微微變淡，突顯放大鏡 */
@keyframes stepLineDim {
  from {
    opacity: 0.5;
  }
  to {
    opacity: 1;
  }
}
/* ④ 燈泡填色亮起 */
@keyframes stepBulb {
  0%, 100% {
    fill: transparent;
  }
  50% {
    fill: rgba(255, 80, 1, 0.35);
  }
}
/* ④ 光芒閃爍 */
@keyframes stepRay {
  0%, 100% {
    opacity: 0;
    transform: scale(0.6);
  }
  50% {
    opacity: 1;
    transform: scale(1);
  }
}
/* 檢測中「...」三個點依序上下跳 */
@keyframes scanDotBounce {
  0%, 60%, 100% {
    transform: translateY(0);
  }
  30% {
    transform: translateY(-5px);
  }
}
/* 檢測完成的橘色漣漪：從核心圓邊緣向外擴散淡出 */
@keyframes scanRipple {
  0% {
    transform: scale(1);
    opacity: 0.7;
  }
  100% {
    transform: scale(1.75);
    opacity: 0;
  }
}
/* ==========================================================
   表單元件
   ========================================================== */
/* 底線式欄位（聯絡表單） */
.seoCheck .formGroup{
  position: relative;
}
.seoCheck .formGroup label{
  display: block;
  font-size: var(--textSize);
  color: var(--secondColor);
  margin-bottom: 4px;
}
.seoCheck .formGroup label .required{
  color: var(--mainColor);
  margin-left: 2px;
}
.seoCheck .formGroup input[type=text],
.seoCheck .formGroup input[type=tel],
.seoCheck .formGroup input[type=email],
.seoCheck .formGroup input[type=url],
.seoCheck .formGroup textarea{
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--lineColor);
  background: transparent;
  padding: 6px 0 12px;
  font-family: inherit;
  font-size: var(--textSize);
  color: var(--secondColor);
  outline: none;
  border-radius: 0;
  transition: border-color 0.3s;
}
.seoCheck .formGroup input[type=text]:focus,
.seoCheck .formGroup input[type=tel]:focus,
.seoCheck .formGroup input[type=email]:focus,
.seoCheck .formGroup input[type=url]:focus,
.seoCheck .formGroup textarea:focus{
  border-bottom-color: var(--mainColor);
}
.seoCheck .formGroup textarea{
  min-height: 90px;
  resize: vertical;
}

/* 稱謂 radio */
.seoCheck .radioGroup{
  display: flex;
  align-items: center;
  gap: 24px;
  font-size: var(--dataTextSize);
}
.seoCheck .radioGroup label{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}
.seoCheck .radioGroup input[type=radio]{
  appearance: none;
  width: 16px;
  height: 16px;
  margin: 0;
  border: 1px solid #999;
  border-radius: 50%;
  display: grid;
  place-content: center;
  cursor: pointer;
}
.seoCheck .radioGroup input[type=radio]::before{
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--mainColor);
  transform: scale(0);
  transition: transform 0.2s;
}
.seoCheck .radioGroup input[type=radio]:checked{
  border-color: var(--mainColor);
}
.seoCheck .radioGroup input[type=radio]:checked::before{
  transform: scale(1);
}

/* 膠囊式輸入（Hero 檢測） */
.seoCheck .pillInput{
  display: flex;
  align-items: center;
  min-height: 66px;
  padding: 0 40px;
  background: #fff;
  border-radius: 999px;
  box-shadow: var(--cardShadow);
}
.seoCheck .pillInput input{
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: none;
  background: transparent;
  font-family: inherit;
  font-size: var(--textSize);
  color: var(--secondColor);
}
.seoCheck .pillInput input::placeholder{
  color: #7d7d7d; /* 原 #555，使用者指定 2026-09-11 */
}

@media (max-width: 768px) {
  .seoCheck .formGroup label,
.seoCheck .formGroup input,
.seoCheck .formGroup textarea,
.seoCheck .pillInput input{
    font-size: var(--textSizeSmall);
  }
  .seoCheck .pillInput{
    min-height: 56px;
    padding: 0 24px;
  }
}
/* ==========================================================
   共用：卡片 hover 的「白底＋橘色外框」樣式
   problemArea 與 blogArea 共用同一組，改這裡兩區會一起變。

   用真實 border 而非 box-shadow 假外框：box-shadow 的環畫在 border-box
   外側，hover 時卡片看起來會外擴 2px；真實 border 搭配 box-sizing: border-box
   則完全不位移。使用端的 .item 基底要先寫 `border: 2px solid transparent` 佔位。
   ========================================================== */
/* ==========================================================
   bannerArea — Hero 檢測
   ========================================================== */
.seoCheck .bannerArea{
  /* 版面高：設計稿首屏 932px（含 header 90px）。
     內容起點 = header(95) + 120 = 215，與設計稿 featureTitle 上緣 215 對齊。 */
  position: relative;
  min-height: 932px;
  padding: calc(var(--headerHeight) + 120px) 0 70px;
  display: flex;
  align-items: flex-start;
  overflow: hidden;
  /* 背景：設計端匯出的幾何線框圖（banner-bg-1.5x.jpg，2880×1380），橘色光暈疊在上方 */
  background: radial-gradient(60% 50% at 85% 40%, rgba(255, 138, 61, 0.22) 0%, rgba(255, 138, 61, 0) 70%), radial-gradient(40% 40% at 10% 90%, rgba(255, 138, 61, 0.15) 0%, rgba(255, 138, 61, 0) 70%), url("../images/index/banner-bg-1.5x.jpg") center/cover no-repeat, #f4f4f6;
  /* 設計稿 banner 是破格版心：內容左右各距視窗 211px（其他區塊仍是 1430 版心）。
     1538 = (1920 - 211×2) + .wrap 左右 padding 20×2 */
}
.seoCheck .bannerArea .wrap{
  max-width: 1538px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  z-index: 1;
}
.seoCheck .bannerArea{
  /* 左側文字（字級／間距全部取自設計稿 1920 量測值） */
}
.seoCheck .bannerArea .bannerTxt .featureList{
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 20px;
  margin-bottom: 30px;
}
.seoCheck .bannerArea .bannerTxt{
  /* 設計稿：品牌句自成一行，3 個特色排第二行 */
}
.seoCheck .bannerArea .bannerTxt .featureTitle{
  flex: 0 0 100%;
  color: var(--mainColor);
  font-size: 20px;
  font-weight: 500;
  margin-bottom: 12px;
  white-space: nowrap;
}
.seoCheck .bannerArea .bannerTxt .featureItem{
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: 15px;
  color: #555;
  white-space: nowrap;
  padding-right: 22px;
  border-right: 1px solid var(--lineColor);
}
.seoCheck .bannerArea .bannerTxt .featureItem:last-child{
  border-right: 0;
  padding-right: 0;
}
.seoCheck .bannerArea .bannerTxt .featureItem svg{
  width: 24px;
  height: 24px;
  color: var(--mainColor);
}
.seoCheck .bannerArea .bannerTxt{
  /* 設計稿：60px／字距 0.02em（字元間距實測 61px）／行距 84px = 1.4，兩行。
     字級流體：1920 → 60、1280 → 56（原本 ≤1400 固定 54，1281 → 1280 會由 54 跳回 56），
     ≤1280 由另一段 clamp 接手（56 → 48）。推導：斜率 = 4 ÷ 640 每 px ＝ 0.625vw；value = 0.625vw + 48px。 */
}
.seoCheck .bannerArea .bannerTxt .title{
  font-size: clamp(56px, 0.625vw + 48px, var(--heroTitleSize));
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.02em;
  color: #000;
}
.seoCheck .bannerArea .bannerTxt .titleLine{
  display: block;
  width: 90px;
  height: 3px;
  background: var(--mainColor);
  margin: 40px 0 50px;
}
.seoCheck .bannerArea .bannerTxt{
  /* max-width 480：設計稿此段斷成兩行（實測第一行寬 472） */
}
.seoCheck .bannerArea .bannerTxt .text{
  font-size: 20px;
  line-height: 1.6;
  color: #666;
  /* 原 #555，內文統一 #666（使用者 2026-09-11） */
  max-width: 480px;
}
.seoCheck .bannerArea{
  /* 檢測表單（設計稿：186×70 ＋ 21 ＋ 380×70，總寬 586，送出鈕 142×48 右內縮 13） */
}
.seoCheck .bannerArea .checkForm{
  display: flex;
  gap: 21px;
  margin-top: 42px;
  /* 「網站 SEO 快速健檢」只在手機版設計圖出現，桌機不顯示 */
}
.seoCheck .bannerArea .checkForm .formTitle{
  display: none;
}
.seoCheck .bannerArea .checkForm .pillInput{
  min-height: 70px;
}
.seoCheck .bannerArea .checkForm .pillInput input{
  font-size: 16px;
}
.seoCheck .bannerArea .checkForm .pillInput.company{
  flex: 0 0 auto;
  width: 186px;
  padding: 0 20px;
  justify-content: center;
  /* 設計稿 placeholder 置中；但 text-align:center 會讓空值時的游標也停在
     正中央，所以一聚焦（或已有輸入內容）就切回靠左，游標才會在文字左方。
     不可改用 ::placeholder { text-align:left }：::placeholder 只吃
     ::first-line 允許的屬性，text-align 不在其中。 */
}
.seoCheck .bannerArea .checkForm .pillInput.company input{
  text-align: center;
}
.seoCheck .bannerArea .checkForm .pillInput.company input:focus,
.seoCheck .bannerArea .checkForm .pillInput.company input:not(:placeholder-shown){
  text-align: left;
}
.seoCheck .bannerArea .checkForm .pillInput.url{
  flex: 0 0 auto;
  width: 380px;
  padding: 0 13px 0 42px;
}
.seoCheck .bannerArea .checkForm .pillInput.url .btn{
  flex: 0 0 auto;
  width: 142px;
  min-height: 48px;
  padding: 0;
  font-size: 16px;
}
.seoCheck .bannerArea{
  /* 右側螢幕圖
     以 hero-monitor.png（1000×784）的螢幕外框特徵點（右緣 993‰、
     中段左緣 189‰、中央上緣 50‰）對位設計稿量到的右緣 1651、左緣 1045、上緣 245，
     解得圖框 754×591、左上角 (902, 207)、右緣 1656。
     .wrap 內緣右側為 1709，故 margin-right 53；內容上緣 215 → margin-top -8。 */
}
.seoCheck .bannerArea .bannerImg{
  position: relative;
  justify-self: end;
  /* 圖寬與 margin-right 為流體公式，推導見下方「螢幕圖寬度」註解（緊接在 .bannerArea 之後） */
  --imgW: clamp(680px, calc(11.5625vw + 532px), 754px);
  width: var(--imgW);
  margin-top: -8px;
  margin-right: max(53px, min(729px + var(--imgW) * 0.2122 - 50vw, var(--imgW) * 0.2122 - 40px));
  /* 膠囊縮放單位（2026-09-11 由階梯 --capScale 改為流體 --capUnit）。
     .badgeItem 的寬高／字級／icon／gap／padding 都寫成 calc(N * var(--capUnit))，
     N 就是設計稿 1920 時的 px 值，所以 --capUnit: 1px ＝ 原尺寸。
     為什麼是長度不是係數：CSS 的 calc() 無法把 vw 轉成無單位數，
     變數必須帶單位才能用 clamp() + vw 做連續縮放（改回無單位就只能寫階梯值）。

     曲線：1920 → 1.0（設計稿原尺寸），視窗越窄膠囊越大，1200 → 1.05。
     （峰值 2026-09-11 兩次下修：1.326 → 1.15 → 1.05，使用者回報中段字太大；
       1200 的字級 19.9px → 17.3px → 15.8px，仍比設計稿原尺寸大 5%。）
     峰值就在 1200，之後由兩個斷點接力往下收（≤1200 收到 991 的 0.88、
     ≤991 再收到 768 的 0.8＝手機版原設定）。三段是「上升 → 下降 → 下降」，
     接點數值兩邊一致，全程無跳動。
     推導：斜率 = (1.05 − 1) ÷ 720 每 px ＝ 0.0069444vw；
           value = 1.133333 − 0.0069444vw；1920→1.000、1600→1.022、1400→1.036、1200→1.050。 */
  --capUnit: clamp(1px, calc(1.133333px - 0.0069444vw), 1.05px);
  /* 螢幕圖懸浮：幅度由 12px 減半為 6px（--floatY 覆寫 keyframes 的預設值） */
}
.seoCheck .bannerArea .bannerImg .Img{
  position: relative;
  --floatY: 6px;
  animation: floatY 6s ease-in-out infinite;
}
.seoCheck .bannerArea .bannerImg{
  /* 手機版才出現的靜態放大鏡；桌機由 .lensFly 那顆負責，兩者不會同時出現 */
}
.seoCheck .bannerArea .bannerImg .bannerLens{
  display: none;
}
.seoCheck .bannerArea .bannerImg{
  /* 螢幕下方的光暈（設計稿有、原本漏掉）：light-effect.png 原尺寸 584×253，
     設計稿左上角 (970,746) → 換算到圖框 754×591 @ (902,207)。
     z-index:-1 讓螢幕底座壓在光暈上面（設計稿就是這個層次）；
     下緣超出 banner 的部分由 .bannerArea 的 overflow:hidden 裁掉。 */
}
.seoCheck .bannerArea .bannerImg::before{
  content: "";
  position: absolute;
  left: 5%;
  top: 91.2%;
  width: 77.45%;
  aspect-ratio: 584/253;
  background: url("../images/index/light-effect.png") center/100% 100% no-repeat;
  pointer-events: none;
  z-index: -1;
}
.seoCheck .bannerArea .bannerImg{
  /* 浮動勾選標籤
     底圖 btn-1～5.png 是**含透明陰影留白**的整張圖（例：btn-1 253×97，
     膠囊本體只有 212×56，本體起點 (20,18)）。設計稿量到的膠囊本體寬度
     （163／200／212／180／180）剛好等於各 PNG 的本體寬，代表它們本來就是
     1:1 匯出，不需要拉伸 —— 所以直接用整張圖當背景、盒子等於 PNG 尺寸即可，
     不可再用 border-image 去切端蓋（舊寫法把含陰影的 96px 壓成 50px，
     膠囊本體只剩 28.6px，等於設計稿的一半）。

     底圖對應（依本體寬度比對設計稿，五張是不同角度的 3D 反光，不可錯位）：
     品牌實體一致性 200→btn-4、內容新鮮度 163→btn-5、結構化 212→btn-1、
     內容可摘要性 180→btn-2、AI 爬蟲可讀性 180→btn-3。

     內距：本體左緣→勾勾 20px（＋左側陰影 20 ＝ 盒子左緣 40）、
     勾勾→文字 13px、文字 15px、內容靠左不置中（設計稿右內距約 43）。
     本體在圖框內不置中（上留白 18、下留白 23），故 padding-bottom 5 讓內容上移 2.5px。

     座標：以圖框 754×591 @ (902,207) 換算，盒子（含陰影）左上角百分比；
     b3～b5 的負 right 是設計稿原本就溢出圖框右緣（最遠到 x 1816）。 */
  /* 2026-09-11：膠囊改為「定點冒出」動效（keyframes badgeBubble，與手機版同一支）。
     badgeBubble 只動 transform／opacity，不碰 left/top/right，
     所以設計稿的座標（b1～b5）完全不受影響。
     delay 照視覺動線排：左上 b2 → 左下 b1 → 右上 b3 → 右中 b4 → 右下 b5，每 0.9s 冒一顆。 */
}
.seoCheck .bannerArea .bannerImg .badgeItem{
  position: absolute;
  display: inline-flex;
  align-items: center;
  opacity: 0;
  transform-origin: center;
  animation: badgeBubble 4.5s ease-in-out infinite;
  will-change: transform, opacity;
  gap: calc(13 * var(--capUnit));
  height: calc(96 * var(--capUnit));
  padding: 0 0 calc(5 * var(--capUnit)) calc(40 * var(--capUnit));
  background: center/100% 100% no-repeat;
  font-size: calc(15 * var(--capUnit));
  font-weight: 500;
  color: var(--secondColor);
  white-space: nowrap;
}
.seoCheck .bannerArea .bannerImg .badgeItem svg{
  width: calc(18 * var(--capUnit));
  height: calc(18 * var(--capUnit));
  flex: 0 0 auto;
  color: var(--mainColor);
}
.seoCheck .bannerArea .bannerImg .badgeItem{
  /* 品牌實體一致性：本體 (966,340) 200×55 → 盒子 (946,322) 242×96 */
}
.seoCheck .bannerArea .bannerImg .badgeItem.b1{
  width: calc(242 * var(--capUnit));
  background-image: url("../images/index/btn-4.png");
  left: 5.84%;
  top: 19.46%;
  animation-delay: 0.9s;
}
.seoCheck .bannerArea .bannerImg .badgeItem{
  /* 內容新鮮度：本體 (931,260) 163×55 → 盒子 (911,242) 203×96 */
}
.seoCheck .bannerArea .bannerImg .badgeItem.b2{
  width: calc(203 * var(--capUnit));
  background-image: url("../images/index/btn-5.png");
  left: 1.19%;
  top: 5.92%;
  animation-delay: 0s;
}
.seoCheck .bannerArea .bannerImg .badgeItem{
  /* 結構化資料完整度：本體 (1541,405) 212×55 → 盒子右緣 1774 */
}
.seoCheck .bannerArea .bannerImg .badgeItem.b3{
  width: calc(253 * var(--capUnit));
  background-image: url("../images/index/btn-1.png");
  right: -15.65%;
  top: 30.46%;
  animation-delay: 1.8s;
}
.seoCheck .bannerArea .bannerImg .badgeItem{
  /* 內容可摘要性：本體 (1615,483) 180×55 → 盒子右緣 1816 */
}
.seoCheck .bannerArea .bannerImg .badgeItem.b4{
  width: calc(221 * var(--capUnit));
  background-image: url("../images/index/btn-2.png");
  right: -21.22%;
  top: 43.65%;
  animation-delay: 2.7s;
}
.seoCheck .bannerArea .bannerImg .badgeItem{
  /* AI 爬蟲可讀性：本體 (1586,568) 180×55 → 盒子右緣 1787 */
}
.seoCheck .bannerArea .bannerImg .badgeItem.b5{
  width: calc(221 * var(--capUnit));
  background-image: url("../images/index/btn-3.png");
  right: -17.37%;
  top: 58.04%;
  animation-delay: 3.6s;
}
.seoCheck .bannerArea .bannerImg .badgeItem{
  /* 動效偏好關閉：_setting.scss 已把 .badgeItem 的 animation 關掉，
     這裡把 opacity 補回 1，五顆就停在設計稿座標（手機版斷點內另有一份同樣的覆寫） */
}
@media (prefers-reduced-motion: reduce) {
  .seoCheck .bannerArea .bannerImg .badgeItem{
    opacity: 1;
  }
}
.seoCheck .bannerArea{
  /* Scroll down（設計稿：圓心 x 960、文字下緣 872、區塊下緣 940） */
}
.seoCheck .bannerArea .scrollDown{
  position: absolute;
  left: 50%;
  bottom: 60px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  letter-spacing: 0.15em;
  color: #999;
  z-index: 1;
}
.seoCheck .bannerArea .scrollDown .line{
  width: 1px;
  height: 60px;
  /* 抵銷 .scrollDown 的 gap: 10px，讓線的下緣直接接到圓點上緣
     （不改 gap 本身，否則圓點與 SCROLL DOWN 文字的間距也會歸零） */
  margin-bottom: -10px;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.2) 100%);
  /* 跟著 .dot 同步伸長，讓圓始終貼在線段末端（用 scaleY 不改 height，避免推動下方文字） */
  transform-origin: top center;
  animation: scrollLine 1.8s ease-in-out infinite;
}
.seoCheck .bannerArea .scrollDown .dot{
  width: 18px;
  height: 18px;
  border: 1px solid var(--mainColor);
  border-radius: 50%;
  position: relative;
  /* 動畫掛在外層，外環與內圓一起移動才會始終同心 */
  animation: scrollDot 1.8s ease-in-out infinite;
}
.seoCheck .bannerArea .scrollDown .dot::after{
  content: "";
  position: absolute;
  inset: 5px;
  border-radius: 50%;
  background: var(--mainColor);
}

/* 螢幕圖寬度：1920～1281 改為一條流體 --imgW（2026-09-11 RWD 斷點整理）。
   原本 1680／1540／1460／1400 四段階梯（680 → 620 → 665 → 600）在 1540 → 1460 會「先縮再放大」，
   且每段都要手算一組 --glowDrop、margin-right。現在只留一條線，兩端接上既有定案值：
   1920 → 754（設計稿原尺寸）、1280 → 680（接 ≤1280 那段的上限，無跳動；
   原 620，2026-09-11 使用者回報 1200～990 太小，整條曲線上抬）。
   推導：斜率 = (754 − 680) ÷ 640 每 px ＝ 11.5625vw；value = 11.5625vw + 532px。
   對照舊階梯：1680 → 726（舊 680）、1540 → 710（舊 620）、1460 → 701（舊 665）、1400 → 694（舊 600）。

   margin-right（把圖往左推、讓 b3～b5 溢出的膠囊本體不被 .bannerArea 的 overflow: hidden 切掉）改用公式：
   膠囊本體超出圖框 ＝ 0.2122 × 圖寬 − 20（陰影），需要的推力 ＝ 本體右緣 − 視窗右緣。
   .wrap 未滿版（>1538）時內緣在 50vw + 749，→ 需求 ＝ 729px + 0.2122 × 圖寬 − 50vw；
   .wrap 已滿版（≤1538）時內緣在視窗 − 20，→ 需求 ＝ 0.2122 × 圖寬 − 40px。
   兩者取 min（滿版後前者會高估），再與設計稿的 53 取 max。
   驗算：1920 → 53、1600 → 84、1540 → 111、1461 → 109；左欄剩餘 1461 → 1421 − 701 − 109 ＝ 611 ≥ 表單 587 ✓。
   ≤1440 膠囊溢出收成 −8%，那裡 margin-right 直接給 20（需求 0.08 × 699 − 40 ＝ 15.9），
   同時表單收窄成 170 ＋ 320（1281 左欄只剩 1241 − 680 − 20 ＝ 541 < 587）。
   實際宣告寫在上方 .bannerArea .bannerImg 基準樣式內。 */
/* 橘色光暈改成「貼齊區塊底緣」（使用者 2026-09-11）。
   1920 時光暈本來就會溢出區塊底緣、被 .bannerArea 的 overflow: hidden 裁掉；
   但寬度一縮，螢幕圖變小而區塊仍有 min-height: 932px，光暈就停在半空中。
   所以這裡改成下緣定位：--glowDrop ＝「螢幕圖底 → 區塊底」的落差再加約 40px（確保被裁到）。
   glowDrop = 765 − 圖高，圖高 = 圖寬 × 591/754 = 圖寬 × 0.7838；圖寬已是流體，直接用 calc
   （≤1180 因為區塊 padding-bottom 由 70 變 150，常數改用 807.9；≤991 單欄另給固定 130）。
   之後若再動區塊 min-height／padding，只要改常數即可。水平位置（left: 5%、寬 77.45%）不動，仍跟著螢幕圖。 */
@media (max-width: 1680px) {
  .seoCheck .bannerArea .bannerImg::before{
    --glowDrop: calc(765px - var(--imgW) * 0.7838);
    top: auto;
    bottom: calc(var(--glowDrop) * -1);
  }
}
@media (max-width: 1536px) {
  .seoCheck .bannerArea .bannerImg{
    /* 膠囊垂直間距重新拉開（2026-09-11 使用者回報 1400～990 三顆貼在一起）。
       根因：膠囊高度改用流體 --capUnit 後已與螢幕圖脫鉤，但 top 仍是「佔 .bannerImg 高度的
       百分比」，而圖寬仍在縮（容器高 ＝ 圖寬 × 591/754）→ 間距的 px 值跟著縮，
       膠囊卻沒縮那麼多，就追上來重疊了。
       本體間距 ＝ Δtop × 容器高 − 56 × capUnit（PNG 96 高裡本體只有 56，上下是透明陰影；
       top 的 18px 陰影偏移在相減時會抵銷）。設計稿 Δtop 只有 13～14%，
       實測 1400 時本體間距已經是 −0.1px、1200 是 −7.1px。
       改成五顆等距 Δ19%：19% 取自最擠的 1200（容器高 392、capUnit 1.05，本體佔 15.0%），
       留 4% ≈ 16px 餘裕。驗算 1400 = 25px、1200 = 15.7px、1024 = 14.8px、900 = 10.5px。
       b5 盒子下緣 58% + 96 × capUnit ÷ 容器高，1200 時 = 83.7%，不會被 overflow: hidden 切到。
       ≤768 手機版把 top 設成 auto 改用 bottom 定位，所以不受這裡影響。 */
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b2{
    top: 5%;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b1{
    top: 24%;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b3{
    top: 20%;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b4{
    top: 39%;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b5{
    top: 58%;
  }
}
/* 2026-09-11 使用者要求：1460 以下螢幕圖要大一點（斷點整理後歸到專案斷點表的 1440）。
   空間怎麼來的：右欄 ＝ 圖寬 ＋ margin-right，而 margin-right 原本是留給
   b3～b5 溢出圖框的膠囊本體。作法是把溢出量收窄，再把省下來的 margin-right 全部還給圖。
   需求公式：膠囊盒子左右各含 20px 透明陰影，本體超出圖框 ＝ |right%| × 圖寬 − 20，
   而 .wrap 內緣距視窗 20px，所以 margin-right ≥ |right%| × 圖寬 − 40。
   收成 −8%（b4 最大）後：699 → 15.9px、680 → 14.4px，給 20 即可。
   驗算左欄：1440 → 1400 − 699 − 20 ＝ 681 ≥ 表單 587 ✓；1281 → 1241 − 680 − 20 ＝ 541 < 587，
   所以表單收窄（170 ＋ 320 ＝ 511）從這個斷點就開始（原本在 ≤1280）。 */
@media (max-width: 1440px) {
  /* 左欄剩餘寬度已不足設計稿表單的 587px，等比收窄兩個輸入框 */
  .seoCheck .bannerArea .checkForm .pillInput.company{
    width: 170px;
  }
  .seoCheck .bannerArea .checkForm .pillInput.url{
    width: 320px;
  }
  .seoCheck .bannerArea .bannerImg{
    margin-right: 20px;
    /* 溢出量收窄（與 ≤991 已在用的 −2% 同一個策略，只是收得沒那麼多），
       仍保留「突破圖框」的設計感。改這裡一定要同步確認上面的 margin-right。 */
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b3{
    right: -6%;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b4{
    right: -8%;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b5{
    right: -7%;
  }
}
/* 1280～992 整體放大（2026-09-11 使用者兩次回報這段電腦尺寸太小：第一次 540/480 階梯 → 620～490 流體，
   第二次再抬到 680～560）。螢幕圖寬流體 --imgW 第二段：1280 → 680、1180 → 638、1100 → 605、992 → 560，
   992 直接接上 ≤991 單欄版的 max-width: 560，無跳動。
   推導：斜率 = (680 − 560) ÷ 288 每 px ＝ 41.667vw；value = 41.667vw + 146.7px。
   驗算左欄（.wrap 實寬 − 圖寬 − margin-right ≥ 左欄需求）：
   1280 → 1240 − 680 − 20 ＝ 540 ≥ 表單 511 ✓；1181 → 1141 − 639 − 20 ＝ 482 ≥ 特色列 13px 約 452 ✓；
   992 → 952 − 560 − 20 ＝ 372 ≥ 主標 48px「你網站的 AI SEO」約 365 ✓、≤1180 收小後的特色列約 370 ✓
   （表單已直排、內文 max-width 480 會多折一行，可接受）。
   膠囊溢出 margin-right 需求 = 8% × 680 − 40 ＝ 14.4px ≤ 20 ✓。 */
@media (max-width: 1280px) {
  /* 主標第二段：1280 → 56、992 → 48。推導：斜率 = 8 ÷ 288 每 px ＝ 2.778vw；value = 2.778vw + 20.4px。 */
  .seoCheck .bannerArea .bannerTxt .title{
    font-size: clamp(48px, 2.778vw + 20.4px, 56px);
  }
  /* 三個特色一律一行（使用者 2026-09-11 不要斷成兩行）。
     原本寫在 ≤1180，但 1181～1280 左欄只剩約 493～540px、15px 版本的特色列約 500px，1210 以下仍會折，故提前到這裡。
     992 左欄只剩約 372px：字級 15 → 12、分隔間距 20+22 → 14+14、icon 24 → 20、icon 與文字 12 → 8，整列約 380px，
     多出的幾 px 落在右側 20px margin-right 內，不會折行、也碰不到螢幕圖。 */
  .seoCheck .bannerArea .bannerTxt .featureList{
    /* 不能只寫 flex-wrap: nowrap：featureTitle 是 flex-basis 100% 的同層項目，
       nowrap 會把它和三個特色擠到同一行。改 grid：標題獨占一列、三個特色固定三欄 */
    display: grid;
    grid-template-columns: repeat(3, auto);
    justify-content: start;
    gap: 0 14px;
  }
  .seoCheck .bannerArea .bannerTxt .featureTitle{
    grid-column: 1/-1;
  }
  .seoCheck .bannerArea .bannerTxt .featureItem{
    font-size: 12px;
    gap: 8px;
    padding-right: 14px;
  }
  .seoCheck .bannerArea .bannerTxt .featureItem svg{
    width: 20px;
    height: 20px;
  }
  .seoCheck .bannerArea .bannerImg{
    --imgW: clamp(560px, calc(41.667vw + 146.7px), 680px);
    /* 膠囊流體曲線第二段（2026-09-11 使用者回報平板太大而新增）：
       峰值在 1200，從那裡開始往下收，991 交棒給 ≤991 那段（0.88）。
       原本獨立寫在 ≤1200，併進這裡結果相同：1201～1280 算出來 > 1.05，被 clamp 上限鎖在峰值。
       推導：斜率 = (1.05 − 0.88) ÷ 209 每 px ＝ 0.08134vw；
             value = 0.08134vw + 0.07392；1200→1.050、1100→0.969、1024→0.907、991→0.880。
       ≤1180 沒有宣告 --capUnit，所以這裡的值會一路帶到 991。 */
    --capUnit: clamp(0.88px, calc(0.08134vw + 0.07392px), 1.05px);
  }
}
@media (max-width: 1180px) {
  /* 常數 807.9 見 ≤1680 的說明（區塊 padding-bottom 由 70 變 150、min-height 歸零） */
  .seoCheck .bannerArea .bannerImg::before{
    --glowDrop: calc(807.9px - var(--imgW) * 0.7838);
  }
  .seoCheck .bannerArea{
    min-height: 0;
    padding: calc(var(--headerHeight) + 60px) 0 150px;
    /* .title 字級由 ≤1280 的流體 clamp 接手，不再另外覆寫 --heroTitleSizeMedium */
  }
  .seoCheck .bannerArea .bannerTxt .featureTitle{
    font-size: 18px;
  }
  .seoCheck .bannerArea .bannerTxt{
    /* 特色列不斷行的規則已提前到 ≤1280（1181～1280 左欄約 493～540px，15px 版本約 500px 也會折） */
  }
  .seoCheck .bannerArea{
    /* 圖寬沿用 ≤1280 的流體 --imgW（1180 → 638、992 → 560），margin-right 沿用 20px */
  }
  .seoCheck .bannerArea .checkForm{
    flex-direction: column;
    gap: 16px;
  }
  .seoCheck .bannerArea .checkForm .pillInput.company,
.seoCheck .bannerArea .checkForm .pillInput.url{
    width: auto;
    max-width: 420px;
  }
}
@media (max-width: 991px) {
  /* 這個寬度版面改單欄，螢幕圖離區塊底只剩 90px，落差跟著縮 */
  .seoCheck .bannerArea .bannerImg::before{
    --glowDrop: 130px;
  }
  .seoCheck .bannerArea{
    min-height: 0;
    padding: calc(var(--headerHeightSmall) + 50px) 0 90px;
  }
  .seoCheck .bannerArea .wrap{
    grid-template-columns: 1fr;
    gap: 40px;
  }
  .seoCheck .bannerArea{
    /* 單欄之後左欄文案改為置中（使用者 2026-09-11，附 975 寬截圖） */
  }
  .seoCheck .bannerArea .bannerTxt{
    text-align: center;
    /* 主標題不斷行（使用者 2026-09-11）：HTML 裡的 <br> 是桌機兩行設計用的，
       單欄置中後 48px 一行放得下（769 寬時約 640px < 729），把它關掉；≤768 再放回來 */
  }
  .seoCheck .bannerArea .bannerTxt .title br{
    display: none;
  }
  .seoCheck .bannerArea .bannerTxt{
    /* .featureList 是 flex，吃不到 text-align，要用 justify-content */
  }
  .seoCheck .bannerArea .bannerTxt .featureList{
    justify-content: center;
  }
  .seoCheck .bannerArea .bannerTxt{
    /* 90×3 的橘色短線是 block，要靠 auto margin 才會跟著置中 */
  }
  .seoCheck .bannerArea .bannerTxt .titleLine{
    margin-left: auto;
    margin-right: auto;
  }
  .seoCheck .bannerArea .bannerTxt .text{
    max-width: 560px;
    margin-left: auto;
    margin-right: auto;
  }
  .seoCheck .bannerArea{
    /* 表單改回電腦版那樣水平並排（覆寫 ≤1180 的 column ＋ max-width: 420px）。
       空間夠：.wrap 實寬 ≒ 視窗 − 40，975 → 935px、769 → 729px，
       而表單總寬只要 180 + 16 + 400 = 596，兩端都放得下，不必再壓縮膠囊。 */
  }
  .seoCheck .bannerArea .checkForm{
    flex-direction: row;
    justify-content: center;
    gap: 16px;
  }
  .seoCheck .bannerArea .checkForm .pillInput.company{
    width: 180px;
    max-width: none;
  }
  .seoCheck .bannerArea .checkForm .pillInput.url{
    flex: 0 1 400px;
    width: auto;
    max-width: none;
    /* .checkForm 是 .bannerTxt 的子層，上面的 text-align: center 會繼承進 input。
       公司欄本來就設計成置中，網址欄要拉回靠左才正常。 */
  }
  .seoCheck .bannerArea .checkForm .pillInput.url input{
    text-align: left;
  }
  .seoCheck .bannerArea .bannerImg{
    justify-self: center;
    width: 100%;
    max-width: 560px;
    margin: 0;
    /* 螢幕本體在 PNG 內偏右（本體中心在圖寬 58.6%），圖框置中後視覺上偏右約 48px，
       整組（含膠囊、放大鏡、光暈）往左拉回；≤768 改由 .Img 的負 margin 處理，那裡會把這個值歸 0 */
    left: -44px;
    /* 膠囊流體曲線第三段：991 = 0.88（接住 ≤1200 那段的 clamp 下限，不讓膠囊跳一下）、
       768 = 0.8（接住 ≤768 手機版的固定值），中間線性過渡。
       上限 0.88 必須等於 ≤1200 那段的**下限**，不然 991 會出現跳動。
       推導：斜率 = (0.88 − 0.8) ÷ 223 每 px ＝ 0.035874vw；
             value = 0.035874vw + 0.52449；991→0.880、900→0.847、820→0.819、768→0.800。 */
    --capUnit: clamp(0.8px, calc(0.035874vw + 0.52449px), 0.88px);
    /* 放大鏡：桌機的 .lensFly 在此斷點是 display: none，769～991 之間原本沒有放大鏡（使用者 2026-09-11 要求補上）。
       改用靜態 .bannerLens，座標直接沿用桌機 .lensAnchor.isStart（鏡片圓心在圖框 63.13%／55.33%），
       寬度 43.5% = 桌機 328px ÷ 圖框 754px；這個斷點 .bannerImg 沒有上下 padding、就是圖框本身，比例可直接套。
       translate 把 magnifier.png 的鏡片圓心 (61.6%, 32.1%) 拉到定位點上。≤768 有自己的一組值會覆蓋。 */
  }
  .seoCheck .bannerArea .bannerImg .bannerLens{
    display: block;
    position: absolute;
    left: 63.13%;
    top: 55.33%;
    width: 43.5%;
    height: auto;
    transform: translate(-61.6%, -32.1%);
    pointer-events: none;
    filter: drop-shadow(0 12px 18px rgba(120, 90, 70, 0.18));
    animation: bannerLensDrift 5.5s ease-in-out infinite;
  }
  .seoCheck .bannerArea .bannerImg{
    /* 窄螢幕不再讓膠囊溢出，全部收回圖框內（本體再往內 20px 陰影） */
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b3{
    right: -2%;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b4{
    right: -2%;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b5{
    right: -2%;
  }
  .seoCheck .bannerArea .scrollDown{
    display: none;
  }
}
/* 手機版 banner（依 2026-09-10 使用者提供的 390 寬設計圖重排）
   版序：橘色小標 → 主標 → 內文 → 螢幕圖 → 網站 SEO 快速健檢 → 表單 */
@media (max-width: 768px) {
  .seoCheck .bannerArea{
    /* 下 padding 70px：使用者先要求延伸（50→110）、表單下移 36px 後再要求縮短（110→70），2026-09-11。
       底部橘光 ::after 釘在區塊底緣，會自動跟著調整 */
    padding: calc(var(--headerHeightSmall) + 30px) 0 70px;
    /* 表單是 .bannerTxt 的子層、圖是 .wrap 的子層，本來沒辦法把「圖」排到兩者中間。
       .bannerTxt 設 display: contents 讓它自己不生盒子、子項直接變成 .wrap 的 flex item，
       就能單純用 order 排出設計圖的順序，HTML 結構不用動。
       gap 必須歸 0：contents 拆開後 gap 會套在「每一個」文字子項之間，間距改由各自的 margin 給。 */
  }
  .seoCheck .bannerArea .wrap{
    display: flex;
    flex-direction: column;
    /* 一定要覆寫掉桌機 grid 的 align-items: start：
       在 column flex 裡它是「交叉軸靠左」，每個項目會縮成內容寬並靠左，
       標題、小標、輸入框就不會滿版也不會置中（實測 768 時輸入框只有 246px）。 */
    align-items: stretch;
    gap: 0;
    text-align: center;
  }
  .seoCheck .bannerArea{
    /* 這些選擇器都必須留著 .bannerTxt 這一層：桌機版寫的是 `.bannerArea .bannerTxt .xxx`（0,3,0），
       在斷點裡少寫一層會變 0,2,0 而輸掉——media query 不加特異度。 */
  }
  .seoCheck .bannerArea .bannerTxt{
    display: contents;
  }
  .seoCheck .bannerArea .bannerTxt .featureList{
    display: block;
    margin-bottom: 10px;
  }
  .seoCheck .bannerArea .bannerTxt .featureTitle{
    font-size: 15px;
    margin-bottom: 0;
  }
  .seoCheck .bannerArea .bannerTxt{
    /* 設計圖手機版沒有這三個特色與標題下的橘色短線 */
  }
  .seoCheck .bannerArea .bannerTxt .featureItem,
.seoCheck .bannerArea .bannerTxt .titleLine{
    display: none;
  }
  .seoCheck .bannerArea .bannerTxt .title{
    font-size: var(--heroTitleSizeSmall);
    /* ≤991 關掉的 <br> 在手機版放回來：38px 在 390 寬本來就是兩行，維持設計的斷點位置 */
  }
  .seoCheck .bannerArea .bannerTxt .title br{
    display: inline;
  }
  .seoCheck .bannerArea .bannerTxt{
    /* 字級樣式照 .titleBox .text（_setting.scss：20 / 1.6 / 0.3px），
       與 blogArea 標題下文案一致（使用者 2026-09-11）；字變大後 max-width 放寬到 400 才不會折成三行 */
  }
  .seoCheck .bannerArea .bannerTxt .text{
    font-size: 20px;
    line-height: 1.6;
    letter-spacing: 0.3px;
    max-width: 400px;
    margin: 18px auto 0;
  }
  .seoCheck .bannerArea{
    /* 螢幕圖排在文字之後、表單之前 */
  }
  .seoCheck .bannerArea .bannerImg{
    order: 1;
    width: 100%;
    max-width: 420px;
    /* 上下 padding 是留給溢出圖框的膠囊（截圖裡最上面那顆超出螢幕圖約 127px、
       最下面那顆超出約 107px），膠囊的 top 百分比是以這個「含 padding 的盒子」為基準算的，
       改這裡一定要一併重算下面那組座標。 */
    margin: 20px auto 0;
    /* ≤991 的 left: -44px 在這裡歸 0：手機版由下方 .Img 的 margin-left: -15.4% 負責把本體拉正 */
    left: 0;
    /* 2026-09-11 padding 130/105 → 70/40：定點泡泡不再溢出那麼多；容器變矮（約 498px @420 寬），
       .bannerLens 的 top 與 b1～b5 的 bottom 都已依新高度重算，再改這裡要一併重算 */
    padding: 70px 0 40px;
    /* 膠囊本體約 170px（253 × 0.8）。2026-09-11 由 0.95 縮小：改成泡泡冒出後，
       太大顆會搶過螢幕圖的視覺重心。
       ≤991 那段流體到 768 剛好收斂到 0.8，所以這裡接得上、不會跳。 */
    --capUnit: 0.8px;
    /* 螢幕圖比容器再放大一圈（設計圖上的螢幕幾乎滿版）。
       hero-monitor.png 是滿版輸出、但螢幕本體只佔圖寬的 81.3% 且**偏右**（左緣在圖寬 18% 處），
       所以放大之外還要往左拉 15.4%，本體才會落在設計圖的位置（390 寬時本體 x 40～376）。
       放大的是 .Img 不是 .bannerImg：膠囊的座標是以 .bannerImg 為基準算的，動它會整組跑掉。 */
  }
  .seoCheck .bannerArea .bannerImg .Img{
    width: 118%;
    margin-left: -15.4%;
  }
  .seoCheck .bannerArea .bannerImg{
    /* .Img 不可以加 z-index：加了會讓螢幕圖蓋在膠囊上面，
       左右兩顆疊在螢幕上的膠囊會被圖的透明陰影切掉半截（實測過）。
       膠囊是後面的絕對定位元素，維持預設層級就會自然疊在圖上。 */
    /* 手機版膠囊＝「定點冒出的泡泡」（2026-09-11，取代舊的 4 槽位 JS 輪播）：
       5 顆各自跑同一支 badgeBubble keyframes（本檔 @keyframes badgeBubble）：
       在自己的固定位置從 0 放大出現 → 微上移 → 停 1.5s → 上移＋縮小淡出，不會一路飄過畫面。
       animation-delay 各錯開 0.9s（週期 4.5s ÷ 5 顆），每顆可見 3.4s → 同時約 3～4 顆在畫面上。
       要調「同時幾顆」：改 delay 間隔／週期；要調停留時間：改 keyframes 的 46% 節點。
       位置左右交錯、高度錯開；左側三顆刻意避開儀表板（容器 bottom 36%～60% 那段），
       右側沒有儀表板所以不用避。5 顆是奇數，b5 → b1 銜接時會連兩顆在左側，屬已知、可接受。
       left/right/top 都要寫在 .b1～.b5 這層：桌機座標特異度同為 0,4,0，
       寫在 .badgeItem（0,3,0）會輸掉；top 一旦生效 bottom 就沒作用（實測過）。 */
  }
  .seoCheck .bannerArea .bannerImg .badgeItem{
    text-align: left;
    /* 字級不跟 --capUnit 縮（0.8 → 12px 太小），固定 14px；膠囊本體尺寸不變 */
    font-size: 14px;
    opacity: 0;
    transform-origin: center;
    animation: badgeBubble 4.5s ease-in-out infinite;
    will-change: transform, opacity;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b1,
.seoCheck .bannerArea .bannerImg .badgeItem.b3,
.seoCheck .bannerArea .bannerImg .badgeItem.b5{
    left: -4%;
    right: auto;
    top: auto;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b2,
.seoCheck .bannerArea .bannerImg .badgeItem.b4{
    right: -4%;
    left: auto;
    top: auto;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b1{
    bottom: 17.5%;
    animation-delay: 0s;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b2{
    bottom: 24.3%;
    animation-delay: 0.9s;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b3{
    bottom: 63.9%;
    animation-delay: 1.8s;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b4{
    bottom: 63%;
    animation-delay: 2.7s;
  }
  .seoCheck .bannerArea .bannerImg .badgeItem.b5{
    bottom: 78.5%;
    animation-delay: 3.6s;
  }
  .seoCheck .bannerArea .bannerImg{
    /* 動效偏好關閉：_setting.scss 已把 .badgeItem 的 animation 關掉，
       這裡把 opacity 補回 1，5 顆就停在各自的冒出位置（本來就左右交錯、不遮儀表板） */
    /* 靜態放大鏡：定位點＝鏡片圓心（沿用桌機 .lensAnchor.isStart 的比例 63%／55% 附近）。
       magnifier.png 的鏡片圓心在原圖的 (61.6%, 32.1%)，所以用 translate 把圓心拉到定位點上，
       不必再算一組 margin（寬度是百分比，margin 沒辦法跟著換算）。
       不加 z-index：膠囊在 DOM 裡排在 .Img 後面，本來就會疊在放大鏡之上。 */
  }
  .seoCheck .bannerArea{
    /* 表單排到最後。margin-top 40px（原 4）：使用者要求與上方螢幕圖拉開距離（2026-09-11）；
       只動 margin 不動 .bannerImg 的 padding-bottom，放大鏡與膠囊的百分比定位才不用重算 */
    /* 橘色光暈（light-effect.png）：手機版不再掛在螢幕圖下方（.bannerImg::before），
       改畫在 .bannerArea::after、釘在區塊底部正中央。
       translate(-50%, 50%) 讓光暈的垂直中心剛好落在區塊底緣，下半截由 overflow:hidden 裁掉，
       看起來就是從底部往上暈開；寬度取 90vw（設計稿手機版光暈幾乎滿版）。 */
  }
}
@media (max-width: 768px) and (prefers-reduced-motion: reduce) {
  .seoCheck .bannerArea .bannerImg .badgeItem{
    opacity: 1;
    animation: none;
  }
}
@media (max-width: 768px) {
  .seoCheck .bannerArea .bannerImg .bannerLens{
    display: block;
    position: absolute;
    left: 76%;
    /* 2026-09-11 由 68% → 72% → 76% 逐步右移 */
    top: 49.8%;
    /* 圓心距容器上緣約 248px（容器高 498 時）；padding 改了要重算 */
    width: 45%;
    height: auto;
    transform: translate(-61.6%, -32.1%);
    pointer-events: none;
    filter: drop-shadow(0 12px 18px rgba(120, 90, 70, 0.18));
    /* 右上 ↔ 左下 的小幅漂移。keyframes 內每一格都重寫了上面那組基準位移，
       改 left/top/width 時記得 keyframes 的 -61.6%／-32.1% 也要同步。 */
    animation: bannerLensDrift 5.5s ease-in-out infinite;
  }
  .seoCheck .bannerArea .checkForm{
    order: 2;
    flex-direction: column;
    gap: 12px;
    margin-top: 40px;
  }
  .seoCheck .bannerArea .checkForm .formTitle{
    display: block;
    font-size: 22px;
    font-weight: 700;
    color: var(--titleColor);
    margin-bottom: 6px;
  }
  .seoCheck .bannerArea .checkForm .pillInput{
    width: 100%;
    min-height: 56px;
    padding: 0 22px;
    /* 設計圖是圓角矩形＋淡邊框，不是桌機的膠囊 */
    border-radius: 14px;
    border: 1px solid var(--lineColor);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.04);
  }
  .seoCheck .bannerArea .checkForm{
    /* ≤991 用 .pillInput.company / .pillInput.url（特異度 0,2,0）設了固定寬與 flex-basis，
       會蓋過上面那條 .pillInput（0,1,0）而殘留到手機版：公司欄只剩 180px；
       網址欄的 `flex: 0 1 400px` 在直排（column）時 basis 是**高度**，整欄會變成 400px 高。
       這裡用同層級選擇器把兩欄拉回全寬，與下方「免費檢測網站」按鈕等寬（使用者 2026-09-11）。 */
  }
  .seoCheck .bannerArea .checkForm .pillInput.company,
.seoCheck .bannerArea .checkForm .pillInput.url{
    flex: 0 0 auto;
    width: 100%;
    max-width: none;
  }
  .seoCheck .bannerArea .checkForm .pillInput.company input{
    text-align: left;
  }
  .seoCheck .bannerArea .checkForm{
    /* 送出鈕在設計圖是**獨立**的全寬橘色膠囊，不再包在網址欄那顆白框裡：
       .pillInput.url 退化成單純的直排容器（自己的白底／邊框／陰影全部拿掉），
       白框改由裡面的 input 自己畫。 */
  }
  .seoCheck .bannerArea .checkForm .pillInput.url{
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-height: 0;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }
  .seoCheck .bannerArea .checkForm .pillInput.url input{
    width: 100%;
    min-height: 56px;
    padding: 0 22px;
    background: #fff;
    border: 1px solid var(--lineColor);
    border-radius: 14px;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.04);
  }
  .seoCheck .bannerArea .checkForm .pillInput.url .btn{
    width: 100%;
    min-height: 56px;
    font-size: 17px;
  }
  .seoCheck .bannerArea .bannerImg::before{
    display: none;
  }
  .seoCheck .bannerArea::after{
    content: "";
    position: absolute;
    left: 50%;
    bottom: 0;
    width: 90vw;
    aspect-ratio: 584/253;
    background: url("../images/index/light-effect.png") center/100% 100% no-repeat;
    transform: translate(-50%, 50%);
    pointer-events: none;
    z-index: 0;
  }
}
/* ==========================================================
   problemArea — 四大問題
   ========================================================== */
/* 卡片 active 樣式：新稿改為「白底＋橘色外框」，不再是實心橘底白字
   （設計稿 03 卡右下畫了游標 icon，表示那是 hover 示意）。
   桌機由 :hover 觸發；觸控裝置沒有 hover，固定套在 03 以保留設計稿觀感。 */
/* 手機版輪播控制列：左右箭頭＋圓點（problemArea .problemNav、blogArea .blogDots 共用，
   外觀與 conceptArea .tipNav 同一套，照 2608-ai-robot 案例的 .valueNav／.valueDots（2026-09-11 使用者指定）：
   箭頭無圓框無底色、SVG round cap／join 小圓角、點擊區 40×44；點點用 ::before 畫（7px 灰 → 作用中 20px 橘長條）。
   圓點是 slick 以 appendDots 產生的 <ul class="slick-dots">，CDN 的 slick.min.css 會給它
   position:absolute／bottom:-25px 及 button 的 font-size:0／::before 內容，這裡全部覆寫。
   預設 display:none，各區在自己的斷點打開。 */
.seoCheck .problemArea{
  position: relative;
  z-index: 0;
  /* 建立堆疊脈絡，讓 ::before 背景的 z-index: -1 留在本區內 */
  padding: 116px 0 var(--bgCut);
  overflow: hidden;
  /* 背景要裁掉的高度 = padding-bottom。
     電腦版背景底緣要切齊插畫下緣（插畫是區塊最後一個元素，它下方就只剩 padding-bottom），
     但插畫與下一區的位置都不能動，所以 padding 保留、只把背景搬到 ::before 並從底部內縮同樣的高度。
     下方露出來的那段是頁面白底。≤991 設回 0 → 平板／手機仍是滿版背景。 */
  --bgCut: 50px;
  /* 背景：設計端匯出的柔和漸層底（problem-bg-1.5x.jpg，2880×1641 = 1920×1094 的 1.5x）。
     原本是手刻的 180deg linear-gradient，改用實圖以保留右上淺灰與左下／右下兩團淡橘光暈。
     圖比區塊矮，用 cover 讓它撐滿；底色 fallback 取圖最亮處的白，圖未載入時不會出現色差。 */
}
.seoCheck .problemArea::before{
  content: "";
  position: absolute;
  inset: 0 0 var(--bgCut);
  z-index: -1;
  pointer-events: none;
  background: url("../images/index/problem-bg-1.5x.jpg") center/cover no-repeat, #fafafb;
}
.seoCheck .problemArea{
  /* 右上角淡橘警示三角（svg 本身已含 10% 透明度）

     設計稿量測：三角形本體 x 1418–1682（寬 265）、y 947–1187（高 240）。
     但 problemArea-alert.svg 檔案是 360×360、三角形只佔 viewBox 的 71.1%×64.4%
     （左緣佔比 0.142、上緣佔比 0.103），所以 <img> 要放大到 265 ÷ 0.711 ≈ 371px。

     定位改用 left:50% + margin-left 而非 right：三角形在設計稿上是貼著置中的標題橘卡
     （左緣 = 卡右緣 −40、上緣 = 卡上緣 −49），用 right 從視窗右緣算的話，
     視窗變窄時卡片會往左移、三角形卻不動，兩者就分家了。
     margin-left = 卡半寬 486 − 40 − 圖左側留白(0.142×371≈53) = 393px */
}
.seoCheck .problemArea .alertDeco{
  position: absolute;
  left: 50%;
  margin-left: 393px;
  top: 29px;
  width: 371px;
  pointer-events: none;
  z-index: 0;
}
.seoCheck .problemArea{
  /* ==========================================================
     標題橘卡（設計稿 x 486–1458、y 996–1245 → 972×249、圓角 40）
     ========================================================== */
}
.seoCheck .problemArea .headCard{
  position: relative;
  z-index: 2;
  max-width: 972px;
  margin: 0 auto 58px;
  padding: 34px 70px 40px;
  border-radius: var(--radiusLg);
  background: var(--mainGradient);
  box-shadow: 0 26px 55px rgba(255, 80, 1, 0.22);
  /* 卡片已是橘底，三段文字全部改白（含原本的 .textMain 強調字） */
}
.seoCheck .problemArea .headCard .decoTitle{
  color: rgba(255, 255, 255, 0.85);
}
.seoCheck .problemArea .headCard .title{
  color: #fff;
}
.seoCheck .problemArea .headCard .textMain{
  color: #fff;
}
.seoCheck .problemArea .headCard .text{
  color: rgba(255, 255, 255, 0.95);
  max-width: 600px;
  margin: 14px auto 0;
}
.seoCheck .problemArea{
  /* 左側 3D 物件群：以橘卡為定位基準，座標取自設計稿量測。
     文字區最寬 640px、置中，左右各留 166px，物件最右到 159px 剛好不壓到字。 */
}
.seoCheck .problemArea .headIcon{
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.seoCheck .problemArea .headIcon img{
  position: absolute;
}
.seoCheck .problemArea .headIcon .hiFolder{
  left: 28px;
  top: 30px;
  width: 32px;
}
.seoCheck .problemArea .headIcon .hiDoc{
  left: 40px;
  top: 78px;
  width: 74px;
}
.seoCheck .problemArea .headIcon{
  /* 靜態放大鏡預設不顯示——這顆由 bannerArea 飛過來的 .lensFly 擔任。
     只有 lensFly 失效的情境（≤991 隱藏、prefers-reduced-motion 停在起點）才顯示，
     兩者不會同時出現。
     magnifier.png 原圖 302×302、鏡片圓心 (186, 97)、鏡片直徑 = 圖寬 × 0.564。
     設計稿量到的鏡片直徑 133px → 圖寬 236px，圓心偏移 (145, 76)，
     故 left = 31 - 145 = -114、top = 44% - 76（44% 是 2026-09-10 依需求由 52% 上移 8% 的結果）。
     改這個 top 時，.lensAnchor.isEnd 的 top 必須同步改同樣的量。 */
}
.seoCheck .problemArea .headIcon .hiLens{
  display: none;
  left: -114px;
  top: calc(44% - 76px);
  width: 236px;
  /* 到站後的「檢視」動畫。它在文件流裡，不像 .lensFly 那樣要靠 JS 追捲動，
     所以可以放心做位移＋旋轉＋縮放，也不會有捲動抖動。
     transform-origin 對準鏡片圓心（236px 寬時是 145,76），縮放才不會歪。 */
  transform-origin: 145px 76px;
  animation: lensInspect 7s ease-in-out infinite;
  will-change: transform;
}
.seoCheck .problemArea{
  /* ==========================================================
     四張卡片：一橫排 4 欄階梯狀（舊版是 2+2 交錯）
     ========================================================== */
}
.seoCheck .problemArea .problemList{
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: 70px;
  align-items: start;
}
.seoCheck .problemArea{
  /* 背景大字 AI SEARCH：設計稿為白色，壓在卡片下半部。
     字級 300px 取自量測（大寫字高 210px ÷ 0.7）；
     top 用 em 表示（相對自身字級），斷點縮小字級時落點會自動等比跟著縮。 */
}
.seoCheck .problemArea .bgWord{
  font-size: 300px;
  letter-spacing: 0.06em;
  top: 0.62em;
  color: #fff;
  /* 白色實心改為直式漸層：上下維持接近全白、垂直中段降到 35% 透明度，
     卡片列正好疊在大字的中段，淡掉這一段可降低文字與卡片互相干擾。
     用 background-clip: text 上色，不支援的瀏覽器會落回上面的 color: #fff。 */
}
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .seoCheck .problemArea .bgWord{
    background: linear-gradient(180deg, rgb(255, 255, 255) 0%, rgba(255, 255, 255, 0.35) 50%, rgb(255, 255, 255) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}
.seoCheck .problemArea .problemItem{
  position: relative;
  z-index: 1;
  /* 持續微弱懸浮（±5px、4s），掛在外層；hover 的上移在內層 .item，
     兩層 transform 分開才不會互相覆蓋。delay 錯開避免四張同步起伏。 */
  animation: floatCard 4s ease-in-out infinite;
  /* 設計稿各卡上緣相對位移：01=0 / 02=+78 / 03=+17 / 04=+93（高低交錯、整體緩降） */
}
.seoCheck .problemArea .problemItem.n1{
  margin-top: 0;
  animation-delay: 0s;
}
.seoCheck .problemArea .problemItem.n2{
  margin-top: 78px;
  animation-delay: -1.3s;
}
.seoCheck .problemArea .problemItem.n3{
  margin-top: 17px;
  animation-delay: -2.4s;
}
.seoCheck .problemArea .problemItem.n4{
  margin-top: 93px;
  animation-delay: -3.1s;
}
.seoCheck .problemArea .problemItem .item{
  position: relative;
  padding: 34px 32px 34px;
  min-height: 282px;
  background: #fff;
  /* 透明外框先佔位，hover 只換 border-color 才不會位移 */
  border: 2px solid transparent;
  border-radius: var(--radiusSm);
  box-shadow: var(--cardShadow);
}
.seoCheck .problemArea .problemItem{
  /* 警示圖示：新稿移到卡片左緣外、距卡片頂 45px（舊版是壓在左上角）。
     視覺與動態改為沿用插畫 problemIllu 那顆三角（#iconAlertGlass + alertPulse），
     以中心為軸緩慢脈動，取代原本的 alertShake 鬧鐘式左右晃動。 */
}
.seoCheck .problemArea .problemItem .badgeAlert{
  left: -40px;
  /* 2026-09-11 由 45 → 22px：原本視覺上偏下，往上靠近卡片頂 */
  top: 22px;
  transform-origin: center;
  animation: alertPulse 2.6s ease-in-out infinite;
}
.seoCheck .problemArea .problemItem{
  /* 設計稿桌機只有 01／03 帶驚嘆號；02／04 的 svg 為手機版（≤768）而寫在 HTML 內，這裡先關掉 */
}
.seoCheck .problemArea .problemItem.n2 .badgeAlert,
.seoCheck .problemArea .problemItem.n4 .badgeAlert{
  display: none;
}
.seoCheck .problemArea .problemItem .num{
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  font-size: 44px;
  font-weight: 300;
  line-height: 1;
  color: #9b9b9d;
  margin-bottom: 28px;
}
.seoCheck .problemArea .problemItem{
  /* icon：problem-icon-1～4.svg（70×70，橘線稿＋橘色細環，底透明），白底圓由 CSS 給 */
}
.seoCheck .problemArea .problemItem .icon{
  width: 74px;
  height: 74px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
}
.seoCheck .problemArea .problemItem .icon img{
  width: 100%;
  height: 100%;
  display: block;
}
.seoCheck .problemArea .problemItem .Txt .title{
  font-size: var(--textTitleSize);
  font-weight: 700;
  margin-bottom: 14px;
}
.seoCheck .problemArea .problemItem .Txt .text{
  font-size: var(--dataTextSize);
  color: var(--textColor);
  line-height: 1.8;
}
.seoCheck .problemArea{
  /* 觸控裝置沒有 hover，固定把 active 樣式套在 03（設計稿即以 03 呈現該狀態）。
     只限平板（769~）：≤768 手機是一張張輪播，03 單獨變橘框反而像被 hover，
     使用者要求手機版不要有 hover 效果（2026-09-11） */
}
@media (hover: none) and (min-width: 769px) {
  .seoCheck .problemArea .problemItem.highlight .item{
    border-color: var(--mainColor);
    box-shadow: 0 22px 45px rgba(255, 80, 1, 0.18);
    /* 外圈補一道細橘環，對應設計稿 03 卡 icon 的雙環 */
  }
  .seoCheck .problemArea .problemItem.highlight .item .icon{
    box-shadow: 0 0 0 7px #fff, 0 0 0 8px rgba(255, 80, 1, 0.5);
  }
}
.seoCheck .problemArea{
  /* 插圖：新稿改為置中於卡片下方（舊版在左下、與卡片同在一個 grid） */
}
.seoCheck .problemArea .problemImg{
  position: relative;
  z-index: 1;
  /* 435×270 = 原稿 425×264 再往左 10、往上 6 的留白：
     女生擺動時頭髮會超出原本的 viewBox 左緣（原稿 bbox 就從 x=0.4 開始），
     不留這段餘裕會被 SVG viewport 裁出一條直邊。右緣與下緣座標不變。 */
  max-width: 435px;
  /* 上距 90px = 原 60px + 30px：背景底緣下移 30px（--bgCut 80→50），插畫跟著下移才能維持切齊；
     兩者一減一加，區塊總高不變。之後要再調，--bgCut 與這裡必須同量反向改。 */
  margin: 90px auto 0;
}
.seoCheck .problemArea .problemImg .problemIllu{
  width: 100%;
  height: auto;
}
.seoCheck .problemArea{
  /* 手機版（≤768）卡片輪播控制列，外觀見 @mixin carouselNav；平板／桌機卡片是 grid 全部攤開，不需要，預設隱藏 */
}
.seoCheck .problemArea .problemNav{
  display: none;
  align-items: center;
  justify-content: center;
  gap: 2px;
}
.seoCheck .problemArea .problemNav .navBtn{
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: rgba(0, 0, 0, 0.32);
  cursor: pointer;
  transition: color 0.3s;
  -webkit-tap-highlight-color: transparent;
}
.seoCheck .problemArea .problemNav .navBtn svg{
  width: 20px;
  height: 20px;
}
.seoCheck .problemArea .problemNav .navBtn:active{
  color: var(--mainColor);
}
.seoCheck .problemArea .problemNav .slick-dots{
  position: static;
  display: flex;
  align-items: center;
  width: auto;
  list-style: none;
  margin: 0;
  padding: 0;
  text-align: left;
}
.seoCheck .problemArea .problemNav .slick-dots li{
  display: block;
  width: auto;
  height: auto;
  margin: 0;
  padding: 0;
}
.seoCheck .problemArea .problemNav .slick-dots button{
  position: relative;
  display: block;
  width: 20px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  font-size: 0;
  line-height: 0;
  color: transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  /* 蓋掉 slick.min.css 的 ::before（"•"、opacity .25、font-size 6px、20×20 絕對定位） */
}
.seoCheck .problemArea .problemNav .slick-dots button::before{
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 7px;
  height: 7px;
  font-size: 0;
  line-height: 0;
  opacity: 1;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.18);
  transform: translate(-50%, -50%);
  transition: width 0.35s, background-color 0.35s;
}
.seoCheck .problemArea .problemNav .slick-dots .slick-active button::before{
  width: 20px;
  background: var(--mainColor);
  opacity: 1;
}
@media (hover: hover) and (pointer: fine) {
  .seoCheck .problemArea .problemNav .navBtn:hover{
    color: var(--mainColor);
  }
  .seoCheck .problemArea .problemNav .slick-dots li:not(.slick-active) button:hover::before{
    background: rgba(0, 0, 0, 0.32);
  }
}
.seoCheck .problemArea .problemNav{
  margin-top: 18px;
}
.seoCheck .problemArea{
  /* 插圖循環動畫：人物（呼吸／點頭／指螢幕）＋物件（長條圖、資料點、盆栽、閃電、!!、警示三角）。
     分組是把 Figma 匯出的 130 個扁平 path 依 getBBox 座標包成 <g>，對應關係見 index.html 內的註解。
     pivot 用 transform-box: view-box + px 座標（＝SVG user unit），這樣「頭髮」與「臉」這種
     在 DOM 上不相鄰、無法包成同一個 <g> 的元素，也能繞同一個支點同步轉動。
     持續性的動作一律「單向 keyframes ＋ alternate」＝正播一次、反播一次無限循環，
     animation 上寫的時長是單程（來回一趟為 2 倍）。
     警示三兄弟（閃電 → !! → 三角）維持原本 2.6s 的重音節拍與 keyframes，不加 alternate。 */
}
.seoCheck .problemArea .problemIllu .psMan,
.seoCheck .problemArea .problemIllu .psManHead,
.seoCheck .problemArea .problemIllu .psManArm,
.seoCheck .problemArea .problemIllu .psWoman,
.seoCheck .problemArea .problemIllu .psWomanHair,
.seoCheck .problemArea .problemIllu .psWomanHead,
.seoCheck .problemArea .problemIllu .psLeaves,
.seoCheck .problemArea .problemIllu .psBars > path,
.seoCheck .problemArea .problemIllu .piBolt,
.seoCheck .problemArea .problemIllu .pmA,
.seoCheck .problemArea .problemIllu .pmB,
.seoCheck .problemArea .problemIllu .piAlert{
  transform-box: view-box;
  will-change: transform, opacity;
}
.seoCheck .problemArea .problemIllu{
  /* ---- 人物：外層做呼吸，內層各自動作（同一元素掛兩個 animation 會互搶 transform，故分層）---- */
}
.seoCheck .problemArea .problemIllu .psMan{
  transform-origin: 130px 247px;
  /* 桌面線 */
  animation: psBreath 2.1s ease-in-out infinite alternate;
}
.seoCheck .problemArea .problemIllu .psManHead{
  transform-origin: 166px 126px;
  /* 脖子 */
  animation: psNod 1.8s ease-in-out 0.8s infinite alternate;
}
.seoCheck .problemArea .problemIllu .psManArm{
  transform-origin: 249px 222px;
  /* 手肘 */
  animation: psPoint 1.3s ease-in-out infinite alternate;
}
.seoCheck .problemArea .problemIllu .psWoman{
  transform-origin: 70px 263px;
  /* 腳下 */
  animation: psWomanSway 1.9s ease-in-out 0.6s infinite alternate;
}
.seoCheck .problemArea .problemIllu{
  /* 頭髮（畫在身體之前）與臉（畫在身體之後）必須同 pivot、同參數，才會像同一顆頭 */
}
.seoCheck .problemArea .problemIllu .psWomanHair,
.seoCheck .problemArea .problemIllu .psWomanHead{
  transform-origin: 100px 92px;
  animation: psTilt 2.3s ease-in-out infinite alternate;
}
.seoCheck .problemArea .problemIllu{
  /* ---- 物件 ---- */
}
.seoCheck .problemArea .problemIllu .psLeaves{
  transform-origin: 393px 232px;
  /* 盆口 */
  animation: psSway 2.5s ease-in-out infinite alternate;
}
.seoCheck .problemArea .problemIllu .psBars > path{
  transform-origin: 0 95px;
  /* 長條圖底線；只做 scaleY，x 不影響結果 */
  animation: psBarGrow 1.4s ease-in-out infinite alternate;
}
.seoCheck .problemArea .problemIllu .psBars > path:nth-child(2){
  animation-delay: 0.12s;
}
.seoCheck .problemArea .problemIllu .psBars > path:nth-child(3){
  animation-delay: 0.24s;
}
.seoCheck .problemArea .problemIllu .psBars > path:nth-child(4){
  animation-delay: 0.36s;
}
.seoCheck .problemArea .problemIllu .psBars > path:nth-child(5){
  animation-delay: 0.48s;
}
.seoCheck .problemArea .problemIllu .psBars > path:nth-child(6){
  animation-delay: 0.6s;
}
.seoCheck .problemArea .problemIllu .psDots > path{
  transform-box: fill-box;
  transform-origin: center;
  will-change: transform, opacity;
  animation: psDotBlink 1.2s ease-in-out infinite alternate;
}
.seoCheck .problemArea .problemIllu .psDots > path:nth-child(2){
  animation-delay: 0.2s;
}
.seoCheck .problemArea .problemIllu .psDots > path:nth-child(3){
  animation-delay: 0.4s;
}
.seoCheck .problemArea .problemIllu .psDots > path:nth-child(4){
  animation-delay: 0.6s;
}
.seoCheck .problemArea .problemIllu .psDots > path:nth-child(5){
  animation-delay: 0.8s;
}
.seoCheck .problemArea .problemIllu .psDots > path:nth-child(6){
  animation-delay: 1s;
}
.seoCheck .problemArea .problemIllu{
  /* ---- 進場：電腦由小而大展開 → 螢幕內容依序淡入 → 警示三角彈入 ----
     由 js/main.js 的 IntersectionObserver 在 .problemIllu 上加 .isReady／.isShow 控制。
     .isReady＝JS 已接手（先壓成起始態），.isShow＝進入視窗、開始播；離開視窗會移除
     .isShow，下次捲回來會重播。沒有 JS 兩個 class 都不會加，插圖就是靜態完整顯示。 */
}
.seoCheck .problemArea .problemIllu.isReady .psMonitor,
.seoCheck .problemArea .problemIllu.isReady .psCard,
.seoCheck .problemArea .problemIllu.isReady .psRow,
.seoCheck .problemArea .problemIllu.isReady .piAlert{
  opacity: 0;
}
.seoCheck .problemArea .problemIllu.isShow .psMonitor{
  transform-box: view-box;
  transform-origin: 322px 241px;
  /* 底座著地點 */
  animation: psScreenOpen 0.85s cubic-bezier(0.22, 0.9, 0.3, 1) both;
}
.seoCheck .problemArea .problemIllu.isShow .psCard,
.seoCheck .problemArea .problemIllu.isShow .psRow{
  transform-box: fill-box;
  transform-origin: center;
  animation: psFadeUp 0.5s ease-out both;
}
.seoCheck .problemArea .problemIllu.isShow .c1{
  animation-delay: 0.42s;
}
.seoCheck .problemArea .problemIllu.isShow .c2{
  animation-delay: 0.52s;
}
.seoCheck .problemArea .problemIllu.isShow .c3{
  animation-delay: 0.62s;
}
.seoCheck .problemArea .problemIllu.isShow .psRow{
  animation-delay: 0.72s;
}
.seoCheck .problemArea .problemIllu.isShow{
  /* 進場（both，前）＋循環（帶 delay、不 fill，後）：delay 期間循環不參與運算，
     時間一到才接手，兩個 animation 才不會互搶 transform */
}
.seoCheck .problemArea .problemIllu.isShow .piAlert{
  animation: psPop 0.55s cubic-bezier(0.34, 1.4, 0.5, 1) 0.85s both, alertPulse 2.6s ease-in-out 1.4s infinite;
}
.seoCheck .problemArea .problemIllu{
  /* ---- 警示：閃電快閃 → 「!!」彈跳 → 三角持續脈動 ---- */
}
.seoCheck .problemArea .problemIllu .piBolt{
  transform-box: fill-box;
  transform-origin: center;
  animation: boltFlash 2.6s ease-in-out infinite;
}
.seoCheck .problemArea .problemIllu .pmA,
.seoCheck .problemArea .problemIllu .pmB{
  transform-box: fill-box;
  transform-origin: center bottom;
  animation: markBounce 2.6s ease-in-out infinite;
}
.seoCheck .problemArea .problemIllu .pmA{
  animation-delay: 0.15s;
}
.seoCheck .problemArea .problemIllu .pmB{
  animation-delay: 0.28s;
}
.seoCheck .problemArea .problemIllu .piAlert{
  transform-box: fill-box;
  transform-origin: center;
  animation: alertPulse 2.6s ease-in-out infinite;
}

/* lensFly 停用時（動效偏好關閉），改用靜態放大鏡補位 */
@media (prefers-reduced-motion: reduce) {
  .seoCheck .problemArea .headIcon .hiLens{
    display: block;
    animation: none;
  }
}
@media (hover: hover) and (pointer: fine) {
  .seoCheck .problemArea .problemItem .item{
    transition: transform 0.5s ease-in-out, border-color 0.4s ease-in-out, box-shadow 0.5s ease-in-out;
  }
  .seoCheck .problemArea .problemItem .item .icon{
    transition: transform 0.5s ease-in-out, box-shadow 0.4s ease-in-out;
  }
  .seoCheck .problemArea .problemItem .item{
    /* 任一張卡 hover 都變成白底橘框，icon 同步微放大並補上外環 */
  }
  .seoCheck .problemArea .problemItem .item:hover{
    transform: translateY(-8px);
    border-color: var(--mainColor);
    box-shadow: 0 22px 45px rgba(255, 80, 1, 0.18);
    /* 外圈補一道細橘環，對應設計稿 03 卡 icon 的雙環 */
  }
  .seoCheck .problemArea .problemItem .item:hover .icon{
    box-shadow: 0 0 0 7px #fff, 0 0 0 8px rgba(255, 80, 1, 0.5);
  }
  .seoCheck .problemArea .problemItem .item:hover .icon{
    transform: scale(1.08);
  }
}
/* .wrap（max-width 1430 ＋ 左右 padding 20）在視窗變窄後會貼到畫面邊，
   卡片 01 左緣只剩 20px，而 .badgeAlert 是 left: -40px 掛在卡片外，
   多出來的部分會被 .problemArea 的 overflow: hidden 切掉（1280 實測切掉 18px）。
   解法是整排卡片往內縮 30px、再把 column-gap 收 18px 補回寬度，卡片尺寸幾乎不變。
   ≤1180 另有一組規則（badgeAlert left -14px、column-gap 34px）會接手，那裡要把 padding 歸 0。
   （原 1540，2026-09-11 斷點整理歸到專案斷點表的 1536；.wrap 1430 版心在 1536 早已滿版，效果相同。） */
@media (max-width: 1536px) {
  .seoCheck .problemArea .problemList{
    padding: 0 30px;
    column-gap: 52px;
  }
}
/* 視窗變窄時，卡片右緣到視窗右邊剩下的空間不夠放設計稿比例的三角形，
   等比縮小並往卡片方向收（margin-left = 卡半寬 − (40+53)×縮放比）。
   基底已改用 left:50%，這裡不能再寫 right（同時有 left/right/width 時 right 會被忽略）。 */
@media (max-width: 1440px) {
  .seoCheck .problemArea .alertDeco{
    margin-left: 360px;
    width: 320px;
  }
}
@media (max-width: 1180px) {
  .seoCheck .problemArea{
    --bgCut: 40px;
    /* 同 base：原 70 − 30 */
    padding: 90px 0 var(--bgCut);
  }
  .seoCheck .problemArea .headCard{
    max-width: 820px;
    margin-bottom: 46px;
    padding: 28px 46px 32px;
  }
  .seoCheck .problemArea .headCard .text{
    max-width: 560px;
  }
  .seoCheck .problemArea{
    /* 卡片縮到 820（半寬 410），三角形同步縮並重算 margin-left */
  }
  .seoCheck .problemArea .alertDeco{
    margin-left: 300px;
    width: 280px;
  }
  .seoCheck .problemArea{
    /* 3D 物件等比縮到約 0.77，維持鏡片圓心仍在卡片左緣內 */
  }
  .seoCheck .problemArea .headIcon .hiFolder{
    left: 20px;
    top: 18px;
    width: 25px;
  }
  .seoCheck .problemArea .headIcon .hiDoc{
    left: 29px;
    top: 60px;
    width: 58px;
  }
  .seoCheck .problemArea .headIcon .hiLens{
    left: -88px;
    top: calc(37% - 58px);
    width: 182px;
  }
  .seoCheck .problemArea .bgWord{
    font-size: 200px;
  }
  .seoCheck .problemArea .problemList{
    /* 驚嘆號要外突 33px，卡片不能貼齊 wrap 邊，所以保留左右內距（比 ≤1540 的 30px 再收一點） */
    padding: 0 26px;
    column-gap: 34px;
  }
  .seoCheck .problemArea .problemItem.n2{
    margin-top: 48px;
  }
  .seoCheck .problemArea .problemItem.n3{
    margin-top: 10px;
  }
  .seoCheck .problemArea .problemItem.n4{
    margin-top: 58px;
  }
  .seoCheck .problemArea .problemItem .item{
    padding: 26px 22px 30px;
    min-height: 262px;
  }
  .seoCheck .problemArea .problemItem{
    /* 比照電腦版等比換算（電腦版 56px 圖示：left -40 / top 22）：
       46 ÷ 56 = 0.82 → left -33px（同樣約 71% 在卡片外）、top 18px。
       外突空間由上面 .problemList 的 padding: 0 26px 讓出，不會被 section 的 overflow 切掉。 */
  }
  .seoCheck .problemArea .problemItem .badgeAlert{
    left: -33px;
    top: 18px;
    width: 46px;
    height: 46px;
  }
  .seoCheck .problemArea .problemItem .num{
    font-size: 36px;
    margin-bottom: 26px;
  }
  .seoCheck .problemArea .problemItem .icon{
    width: 56px;
    height: 56px;
  }
  .seoCheck .problemArea .problemItem .Txt .title{
    font-size: var(--textTitleSizeMedium);
    margin-bottom: 12px;
  }
  .seoCheck .problemArea .problemItem .Txt .text{
    font-size: var(--dataTextSizeMedium);
  }
  .seoCheck .problemArea .problemImg{
    margin-top: 70px;
  }
  .seoCheck .problemArea{
    /* 原 40 + 30，與 --bgCut 連動 */
  }
}
@media (max-width: 991px) {
  .seoCheck .problemArea{
    /* 背景裁短只做電腦版：這裡設回 0，背景重新撐滿整個區塊；
       padding-bottom 寫死 70px（≤768 另有自己的 60px），不再跟 --bgCut 連動 */
    --bgCut: 0px;
    padding-bottom: 70px;
    /* 3D 物件群在窄版沒有安全的擺放空間（會壓到置中文字），整組收起；
       lensFly 在此斷點本來就 display:none，所以標題卡純文字呈現。 */
  }
  .seoCheck .problemArea .headIcon{
    display: none;
  }
  .seoCheck .problemArea .headCard{
    max-width: 100%;
    padding: 26px 30px 30px;
  }
  .seoCheck .problemArea .problemList{
    grid-template-columns: repeat(2, minmax(0, 1fr));
    /* 驚嘆號改放卡片內（見下方），≤1180 為了外突留的 26px 內距歸 0 */
    padding: 0;
    column-gap: 26px;
    row-gap: 34px;
  }
  .seoCheck .problemArea .problemItem.n1,
.seoCheck .problemArea .problemItem.n2,
.seoCheck .problemArea .problemItem.n3,
.seoCheck .problemArea .problemItem.n4{
    margin-top: 0;
  }
  .seoCheck .problemArea .problemItem{
    /* 四張卡都要有驚嘆號（使用者 2026-09-11）：打開桌機基礎規則關掉的 02／04 */
  }
  .seoCheck .problemArea .problemItem.n2 .badgeAlert,
.seoCheck .problemArea .problemItem.n4 .badgeAlert{
    display: block;
  }
  .seoCheck .problemArea .problemItem{
    /* 驚嘆號由卡片左緣外收進卡片內，與 .num 數字同一列、左緣切齊卡片文字（水平內距 22px）。
       .num line-height 1 × 36px、padding-top 26px → 數字視覺中心約 y=44；
       42px 圖示放 top 23 中心剛好對齊。數字往右讓位 42 + 12 = 54px。
       （與 ≤768 同一套算式，該斷點的卡片上內距與 .num 字級都相同） */
  }
  .seoCheck .problemArea .problemItem .badgeAlert{
    left: 22px;
    top: 23px;
    width: 42px;
    height: 42px;
  }
  .seoCheck .problemArea .problemItem .badgeAlert + .num{
    padding-left: 54px;
  }
  .seoCheck .problemArea .bgWord{
    display: none;
  }
  .seoCheck .problemArea .alertDeco{
    display: none;
  }
}
@media (max-width: 768px) {
  .seoCheck .problemArea{
    /* 下 padding 歸 0：插畫是區塊最後一個元素，下緣直接貼齊背景底緣（使用者 2026-09-11）。
       原本的 60px 加到 .problemImg 的 margin-top（36 → 96），區塊總高不變、插畫整體往下 60px。 */
    padding: 70px 0 0;
    /* 與下方問題卡的距離：40 → 32（使用者 2026-09-11 要近一點；舊版實際看到的是 40+26=66，見下方 margin-top 註解） */
  }
  .seoCheck .problemArea .headCard{
    padding: 22px 22px 26px;
    margin-bottom: 32px;
    /* 說明文字字級 20 → 16，與 banner 輸入框「請輸入網站網址」相同（使用者 2026-09-11） */
  }
  .seoCheck .problemArea .headCard .text{
    font-size: var(--textSizeMedium);
  }
  .seoCheck .problemArea{
    /* 卡片改 slick 輪播（js/main.js 依 matchMedia 在此斷點 init）。
       grid 拿掉改回 block 讓 slick-track 自己排；JS 未載入時退回單欄直排。
       左右各 -20px 把軌道拉到視窗邊，slide 內再 padding 20px 補回，
       這樣卡片陰影（--cardShadow 50px 模糊）不會被 .slick-list 的 overflow:hidden 在 wrap 邊緣切出直線；
       上下同理用 padding／負 margin 留出陰影空間。 */
  }
  .seoCheck .problemArea .problemList{
    display: block;
    /* ≤1180 那組的左右內距在這裡歸 0：手機版是 slick 軌道自己用負 margin 拉到視窗邊，
       驚嘆號也已改成放在卡片內（left: 22px），不需要外突空間 */
    padding: 0;
    margin: 0 -20px;
    /* 上下留白要蓋過整個陰影範圍：--cardShadow 是 0 20px 50px，
       往下延伸約 70px（偏移 20 + 模糊 50）、往上約 30px；原本的 40 / 20 會把陰影切平（2026-09-11 使用者截圖） */
  }
  .seoCheck .problemArea .problemList .slick-list{
    padding: 30px 0 80px;
    margin: -30px 0 -80px;
  }
  .seoCheck .problemArea .problemList{
    /* slick 讓 .slick-track 以 flex 排，卡片高度取最高那張，切換時下方控制列不跳動 */
  }
  .seoCheck .problemArea .problemList .slick-track{
    display: flex;
    align-items: stretch;
  }
  .seoCheck .problemArea .problemItem{
    padding: 0 20px;
    /* 輪播中卡片一張張切，持續上下懸浮反而像沒對齊，關掉 */
    animation: none;
    /* 未初始化（無 JS）時退回直排，靠 margin 隔開。
       一定要限定在 :not(.slick-initialized)：slick-track 是 flex，這個 margin-top 會套到
       第 2 張起的每一張 slide，整條軌道除了第一張（通常是 clone）之外全部往下掉 26px，
       看到的卡片與標題卡的距離就多了 26px（2026-09-11 實測踩到）。 */
  }
  .seoCheck .problemList:not(.slick-initialized) .problemArea .problemItem + .problemItem{
    margin-top: 26px;
  }
  .seoCheck .problemArea .problemItem .item{
    min-height: 0;
    height: 100%;
  }
  .seoCheck .problemArea .problemItem .item .icon{
    transition: transform 0.5s ease-in-out;
  }
  .seoCheck .problemArea .problemItem{
    /* 滑到哪張卡，該卡的 icon 就微放大＋外圈漣漪；
       卡片本身不加外框、陰影、上浮，桌機 hover 那圈 8px 靜態橘環也不要（使用者 2026-09-11）。
       用 .slick-active 而非 .slick-current：infinite 輪播跨頭尾時短暫顯示的 clone 也要有效果；
       slick 在切換開始就更新 class，過場跟著滑動一起走。 */
  }
  .seoCheck .problemArea .problemItem.slick-active .item .icon{
    position: relative;
    transform: scale(1.08);
    /* 外圈漣漪（使用者 2026-09-11）：兩個橘色細環沿用 solutionArea 的 iconRipple，
       錯開半週期連續往外擴散。128% 是桌機靜態橘環的直徑（icon 56 + 8×2 = 72），
       環從那個位置開始擴。負延遲直接從週期中段起跑，避免空窗期環歪在一邊。 */
  }
  .seoCheck .problemArea .problemItem.slick-active .item .icon::before,
.seoCheck .problemArea .problemItem.slick-active .item .icon::after{
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 128%;
    height: 128%;
    border: 2px solid rgba(255, 80, 1, 0.5);
    border-radius: 50%;
    pointer-events: none;
    transform: translate(-50%, -50%) scale(0.9);
    opacity: 0;
    animation: iconRipple 3.2s ease-out infinite;
  }
  .seoCheck .problemArea .problemItem.slick-active .item .icon::after{
    animation-delay: -1.6s;
  }
  .seoCheck .problemArea .problemItem{
    /* 驚嘆號由卡片左緣外（-16px）收進卡片內，與 .num 數字同一列、左緣切齊卡片文字（padding 22px）。
       .num line-height 1 × 36px、padding-top 26px → 數字視覺中心約 y=44；
       驚嘆號 42px 放 top 23px 中心剛好對齊。數字往右讓位 42 + 12 = 54px（只有有驚嘆號的卡才讓）。 */
    /* 手機版四張卡都要有驚嘆號（使用者 2026-09-11）：打開 base 關掉的 02／04 */
  }
  .seoCheck .problemArea .problemItem.n2 .badgeAlert,
.seoCheck .problemArea .problemItem.n4 .badgeAlert{
    display: block;
  }
  .seoCheck .problemArea .problemItem .badgeAlert{
    left: 22px;
    top: 23px;
    width: 42px;
    height: 42px;
  }
  .seoCheck .problemArea .problemItem .badgeAlert + .num{
    padding-left: 54px;
  }
  .seoCheck .problemArea .problemItem .Txt .title{
    font-size: var(--textTitleSizeSmall);
  }
  .seoCheck .problemArea .problemItem{
    /* 內文字級照 conceptArea .checkList li（15px / 1.7），使用者 2026-09-11 */
  }
  .seoCheck .problemArea .problemItem .Txt .text{
    font-size: var(--textSizeSmall);
    line-height: 1.7;
  }
  .seoCheck .problemArea{
    /* slick 初始化後才顯示控制列；沒有 JS 就維持隱藏（卡片是直排，不需要切換）。
       卡片底緣 → 控制列頂緣 10px：手機版各輪播區統一值，以金字塔 .tipNav 為基準（2026-09-11 使用者定案） */
  }
  .seoCheck .problemArea .problemList.slick-initialized ~ .problemNav{
    display: flex;
    margin-top: 10px;
  }
  .seoCheck .problemArea{
    /* 插畫縮小：435 → 300px（約 0.7 倍）。
       上距 56：區塊 padding-bottom 已歸 0、插畫是最後一個元素，這個值直接決定「控制列 → 插畫」的距離，
       也等於決定背景底緣的位置（插畫下緣永遠＝背景底緣）。2026-09-11 使用者：96 → 56 再往上一點 */
  }
  .seoCheck .problemArea .problemImg{
    max-width: 300px;
    margin-top: 56px;
  }
}
/* 小手機（360 寬機型）：橘卡標題「網站有內容，不代表 AI 看得懂」在 .titleBox 的 24px 會折成兩行
   （約 13.5 字寬 × 24 ＋ 字距 ＋ 卡片內距 44 ≈ 374 > 320），降到 20px（≈ 320）保持一行；
   22px 實測仍會折行。390 寬本來就放得下，不受影響。 */
@media (max-width: 375px) {
  .seoCheck .problemArea .headCard .title{
    font-size: 20px;
  }
}
/* 手機版區塊標題字級統一（使用者 2026-09-11）：conceptArea／solutionArea／blogArea 的 .titleBox .title
   比照 contactArea——30px 且 ≤480 不再降到 24px（選擇器 0,3,0 蓋過 _setting 的 0,2,0），
   折成兩行時行距同樣放寬到 1.5。problemArea 橘卡標題另有自己的規則，不在此列。 */
@media (max-width: 768px) {
  .seoCheck .conceptArea .titleBox .title,
.seoCheck .solutionArea .titleBox .title,
.seoCheck .blogArea .titleBox .title{
    font-size: 30px;
    line-height: 1.5;
  }
}
/* ==========================================================
   conceptArea — AI 搜尋與 SEO
   ========================================================== */
.seoCheck .conceptArea{
  position: relative;
  /* 上方原為 60px（偏緊）→ 110px（過寬）→ 90 → 100 → 定案 115px；下方 100px 不動 */
  padding: 115px 0 100px;
  overflow: hidden;
  background: #fff;
  /* 底部橘色漸層帶 */
}
.seoCheck .conceptArea::after{
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 120px;
  background: linear-gradient(180deg, rgba(255, 138, 61, 0) 0%, rgba(255, 138, 61, 0.12) 100%);
  pointer-events: none;
}
.seoCheck .conceptArea .wrap{
  display: grid;
  grid-template-columns: minmax(0, 660px) minmax(0, 1fr);
  gap: 40px;
  align-items: start;
  z-index: 1;
}
.seoCheck .conceptArea{
  /* 左欄文字：比右欄金字塔再高一點。.wrap 是 align-items: start，
     左欄上緣本來就貼齊區塊 padding，用負 margin 往上帶。
     ≤991 單欄後這個負值會直接吃掉區塊上方留白，故該斷點歸 0。 */
}
.seoCheck .conceptArea .conceptTxt{
  margin-top: -24px;
}
.seoCheck .conceptArea .conceptBox{
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 80px;
}
.seoCheck .conceptArea .conceptItem{
  position: relative;
  /* hover 時小項目灰底往左右溢出的量，必須等於當前斷點 .content 的水平 padding，
     否則會蓋到左邊的橘色標籤／頂到卡片圓角（912 寬曾因此爆版，2026-09-11）。 */
  --liBleed: 40px;
  /* 同上，垂直方向：第一列往上、最後一列往下要補到卡片上下緣，值＝.content 的垂直 padding */
  --liBleedY: 16px;
  /* ::before 橘色外框的定位基準 */
  display: flex;
  border-radius: var(--radiusSm);
  overflow: hidden;
  box-shadow: var(--cardShadow);
  background: #fff;
  transition: box-shadow 0.4s ease-in-out;
  /* hover 橘色外框。不直接加在 .conceptItem 的 border：
     全站 box-sizing: border-box，2px 框線會把內容往內壓 2px，hover 時整排文字會抖一下。
     橘色光暈則必須掛在 .conceptItem 自己身上——掛這顆 pseudo 上會被 overflow: hidden 裁掉。 */
}
.seoCheck .conceptArea .conceptItem::before{
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid transparent;
  border-radius: inherit;
  pointer-events: none;
  z-index: 2;
  transition: border-color 0.4s ease-in-out;
}
.seoCheck .conceptArea .conceptItem .label{
  flex: 0 0 180px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-size: 20px;
  font-weight: 700;
  padding: 30px 20px;
  text-align: center;
}
.seoCheck .conceptArea .conceptItem .label svg{
  width: 28px;
  height: 28px;
  color: var(--mainColor);
}
.seoCheck .conceptArea .conceptItem .content{
  flex: 1 1 auto;
  padding: 28px 40px;
}
.seoCheck .conceptArea .conceptItem.myth .label{
  background: #e6e6e6;
  color: var(--secondColor);
  /* 警示三角：放大＋左右晃動提醒，3s 一輪（與右側畫叉叉同週期） */
}
.seoCheck .conceptArea .conceptItem.myth .label svg{
  animation: mythAlertShake 3s ease-in-out infinite;
  transform-origin: 50% 60%;
}
.seoCheck .conceptArea .conceptItem.myth .content{
  display: flex;
  align-items: center;
  gap: 20px;
  font-size: 28px;
  font-weight: 700;
  line-height: 1.4;
}
.seoCheck .conceptArea .conceptItem.myth .content .cross{
  width: 24px;
  height: 24px;
  color: var(--mainColor);
  flex: 0 0 auto;
}
.seoCheck .conceptArea .conceptItem.myth .content{
  /* 兩劃分別描出來：dasharray 18 > 單劃長度 17，dashoffset 由 18 收到 0 就是「畫出來」 */
}
.seoCheck .conceptArea .conceptItem.myth .content .crossLine{
  stroke-dasharray: 18;
  stroke-dashoffset: 18;
}
.seoCheck .conceptArea .conceptItem.myth .content .l1{
  animation: mythCrossL1 3s ease-in-out infinite;
}
.seoCheck .conceptArea .conceptItem.myth .content .l2{
  animation: mythCrossL2 3s ease-in-out infinite;
}
.seoCheck .conceptArea .conceptItem.myth .content{
  /* 底線改用假底線才能做動畫（text-decoration 不能 transition／animate）。
     ::before 是始終存在的底線「軌道」（淡橘），::after 是畫出來的實色線，兩條同長度、同位置。 */
}
.seoCheck .conceptArea .conceptItem.myth .content .textMain{
  position: relative;
  text-decoration: none;
}
.seoCheck .conceptArea .conceptItem.myth .content .textMain::before,
.seoCheck .conceptArea .conceptItem.myth .content .textMain::after{
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -8px;
  height: 2px;
}
.seoCheck .conceptArea .conceptItem.myth .content .textMain{
  /* 軌道：不動，35% 透明度的橘 */
}
.seoCheck .conceptArea .conceptItem.myth .content .textMain::before{
  background: rgba(255, 80, 1, 0.35);
}
.seoCheck .conceptArea .conceptItem.myth .content .textMain{
  /* 畫出來的那條：實色，疊在軌道上 */
}
.seoCheck .conceptArea .conceptItem.myth .content .textMain::after{
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  animation: mythUnderline 3s ease-in-out infinite;
}
.seoCheck .conceptArea .conceptItem.correct .label{
  background: var(--mainGradient);
  color: #fff;
}
.seoCheck .conceptArea .conceptItem.correct .content{
  padding: 16px 40px;
}
.seoCheck .conceptArea .conceptItem.correct .checkList li{
  display: flex;
  align-items: flex-start;
  gap: 20px;
  padding: 22px 0;
  font-size: var(--textSize);
  line-height: 1.7;
  color: #666;
  /* 原 #444，內文統一 #666（使用者 2026-09-11） */
  border-bottom: 1px solid var(--lineColor);
}
.seoCheck .conceptArea .conceptItem.correct .checkList li:last-child{
  border-bottom: 0;
}
.seoCheck .conceptArea .conceptItem.correct .checkList li .iconCheck{
  margin-top: 2px;
}
.seoCheck .conceptArea .conceptItem{
  /* hover：整張卡浮現橘框、滑到的小項目換淺灰底（比照 solutionArea「重度陪跑型」欄） */
}
@media (hover: hover) and (pointer: fine) {
  .seoCheck .conceptArea .conceptItem{
    /* 「錯誤迷思」卡依需求**完全不做 hover**，所以這裡排掉 .myth */
  }
  .seoCheck .conceptArea .conceptItem:not(.myth):hover{
    box-shadow: 0 14px 30px rgba(255, 80, 1, 0.18);
  }
  .seoCheck .conceptArea .conceptItem:not(.myth):hover::before{
    border-color: var(--mainColor);
  }
  .seoCheck .conceptArea .conceptItem{
    /* 小項目淺灰底。li 左右沒有 padding（22px 0），只上 background 會變成只有文字寬的一條，
       所以用左右各 --liBleed 的同色 box-shadow 把底色撐滿（--liBleed ＝ 當前斷點 .content 的水平 padding）。
       不改 padding／margin：那會連帶把分隔線 border-bottom 拉寬、動到現有版面。 */
  }
  .seoCheck .conceptArea .conceptItem.correct .checkList li{
    /* 起始值要寫成同形狀的透明陰影：從 none 起跳不會有過渡 */
    box-shadow: calc(var(--liBleed) * -1) 0 0 rgba(245, 245, 245, 0), var(--liBleed) 0 0 rgba(245, 245, 245, 0);
    transition: background-color 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
  }
  .seoCheck .conceptArea .conceptItem.correct .checkList li:hover{
    background-color: var(--grayColor);
    box-shadow: calc(var(--liBleed) * -1) 0 0 var(--grayColor), var(--liBleed) 0 0 var(--grayColor);
  }
  .seoCheck .conceptArea .conceptItem.correct .checkList li{
    /* 第一列要補到卡片上緣（.content 的上 padding = --liBleedY）。
       三層缺一不可：單純往上那層只有 li 的文字寬，左右 --liBleed 的角落會缺角，
       所以再加「上左」「上右」兩層把整條帶子補滿。
       transition 要能跑，未 hover 的狀態必須是同樣層數的透明陰影。 */
  }
  .seoCheck .conceptArea .conceptItem.correct .checkList li:first-child{
    box-shadow: calc(var(--liBleed) * -1) 0 0 rgba(245, 245, 245, 0), var(--liBleed) 0 0 rgba(245, 245, 245, 0), 0 calc(var(--liBleedY) * -1) 0 rgba(245, 245, 245, 0), calc(var(--liBleed) * -1) calc(var(--liBleedY) * -1) 0 rgba(245, 245, 245, 0), var(--liBleed) calc(var(--liBleedY) * -1) 0 rgba(245, 245, 245, 0);
  }
  .seoCheck .conceptArea .conceptItem.correct .checkList li:first-child:hover{
    box-shadow: calc(var(--liBleed) * -1) 0 0 var(--grayColor), var(--liBleed) 0 0 var(--grayColor), 0 calc(var(--liBleedY) * -1) 0 var(--grayColor), calc(var(--liBleed) * -1) calc(var(--liBleedY) * -1) 0 var(--grayColor), var(--liBleed) calc(var(--liBleedY) * -1) 0 var(--grayColor);
  }
  .seoCheck .conceptArea .conceptItem.correct .checkList li{
    /* 最後一列同理，補卡片下緣 */
  }
  .seoCheck .conceptArea .conceptItem.correct .checkList li:last-child{
    box-shadow: calc(var(--liBleed) * -1) 0 0 rgba(245, 245, 245, 0), var(--liBleed) 0 0 rgba(245, 245, 245, 0), 0 var(--liBleedY) 0 rgba(245, 245, 245, 0), calc(var(--liBleed) * -1) var(--liBleedY) 0 rgba(245, 245, 245, 0), var(--liBleed) var(--liBleedY) 0 rgba(245, 245, 245, 0);
  }
  .seoCheck .conceptArea .conceptItem.correct .checkList li:last-child:hover{
    box-shadow: calc(var(--liBleed) * -1) 0 0 var(--grayColor), var(--liBleed) 0 0 var(--grayColor), 0 var(--liBleedY) 0 var(--grayColor), calc(var(--liBleed) * -1) var(--liBleedY) 0 var(--grayColor), var(--liBleed) var(--liBleedY) 0 var(--grayColor);
  }
}
.seoCheck .conceptArea .conceptImg{
  /* 卡片位置（RWD 時只要覆寫這個變數即可）。光暈已改為固定值，不隨階段變化。 */
  /* 三張卡片各自的定點（卡片上緣），對應金字塔三層。RWD 要把卡片收到金字塔正上方時，
     三個一起設 0 即可，不必再用 .isStageX 拉特異度 */
  --tip1: 70%;
  --tip2: 45%;
  --tip3: 17%;
  /* SEO／AEO 卡片各自額外的水平位移（GEO 不動） */
  --tip1X: -40px;
  --tip2X: -20px;
  /* 金字塔單獨位移用的變數。2026-09-10 使用者要求「金字塔連同卡牌一起右移」，
     所以整組位移改由下面 .conceptImg 的 left 負責，這個值歸 0（機制保留，
     日後若只想單獨挪金字塔而不動卡片再調它）。 */
  --pyShiftX: 0px;
  position: relative;
  /* 整組（金字塔＋三層文字＋三張卡片＋光暈）往右移。用 left 而非 margin，
     才不會改到 grid 欄寬；≤1180 已歸 0。 */
  left: 80px;
  justify-self: end;
  width: 100%;
  /* 設計稿金字塔實際 581×662，原本 720 偏大，收到 600 */
  max-width: 600px;
  padding-top: 80px;
}
.seoCheck .conceptArea .conceptImg .Img{
  position: relative;
  z-index: 1;
  animation: floatY 7s ease-in-out infinite;
}
.seoCheck .conceptArea .conceptImg{
  /* 金字塔三階段（pyramid-1/2/3：SEO 亮 → SEO+AEO 亮 → 全亮）
     三張疊放，JS 在 .conceptImg 上輪流切換 isStage1／2／3，純粹由圖片淡入淡出，
     不外加任何光暈或閃光（使用者 2026-09-10 要求全部移除，勿再加回來） */
}
.seoCheck .conceptArea .conceptImg .pyramid{
  position: relative;
  /* 用 left 而非 transform：.Img 身上掛著 floatY，
     該 keyframe 會寫 transform: translateY()，自己再加 transform 會被整個覆蓋掉。
     .pyLabel 以百分比定位在 .pyramid 內，所以標籤會自動跟著位移。 */
  left: var(--pyShiftX);
}
.seoCheck .conceptArea .conceptImg .pyramid .stage{
  display: block;
  width: 100%;
}
.seoCheck .conceptArea .conceptImg .pyramid{
  /* 分層素材是「全灰」的，掉落結束交還給 .s1 時底層才亮成橘色；
     給 .s1 一個淡入，讀起來就是「組裝完成 → SEO 那層亮起」 */
}
.seoCheck .conceptArea .conceptImg .pyramid .s1{
  transition: opacity 0.6s ease;
}
.seoCheck .conceptArea .conceptImg .pyramid .s2,
.seoCheck .conceptArea .conceptImg .pyramid .s3{
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.6s ease-in-out;
}
.seoCheck .conceptArea .conceptImg .pyramid{
  /* 回到 stage1 時 s2、s3 若同時淡出，兩層都在半透明會互相混疊、亮度暴衝＝「閃一下」。
     讓中層晚 0.3s 才退，變成 3 → 2 → 1 逐層降。
     亮起來時不需要這個延遲，下面的 .isStageX 規則會把 delay 歸零。 */
}
.seoCheck .conceptArea .conceptImg .pyramid .s2{
  transition-delay: 0.3s;
}
.seoCheck .conceptArea .conceptImg .pyramid{
  /* 進場掉落用的三層：使用者提供的分層素材 pyramid-layer-1~3.png，
     三張都是 889×1013 同畫布、各層已在正確座標上，直接疊滿整個框即可對位（不必偏移、不必 clip）。
     transform-origin 各自設在「該層自己的底緣」（由素材不透明範圍換算），
     觸地壓實才會像被地面頂住，而不是整片等比縮小。 */
}
.seoCheck .conceptArea .conceptImg .pyramid .pyLayer{
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.seoCheck .conceptArea .conceptImg .pyramid .dropPiece{
  position: absolute;
  inset: 0;
  background: 0 0/100% 100% no-repeat;
  opacity: 0;
  pointer-events: none;
}
.seoCheck .conceptArea .conceptImg .pyramid .d1 .dropPiece{
  background-image: url("../images/index/pyramid-layer-1.png");
}
.seoCheck .conceptArea .conceptImg .pyramid .d1{
  transform-origin: 50% 97.7%;
}
.seoCheck .conceptArea .conceptImg .pyramid .d2 .dropPiece{
  background-image: url("../images/index/pyramid-layer-2.png");
}
.seoCheck .conceptArea .conceptImg .pyramid .d2{
  transform-origin: 50% 61.3%;
}
.seoCheck .conceptArea .conceptImg .pyramid .d3 .dropPiece{
  background-image: url("../images/index/pyramid-layer-3.png");
}
.seoCheck .conceptArea .conceptImg .pyramid .d3{
  transform-origin: 50% 33.8%;
}
.seoCheck .conceptArea .conceptImg .pyramid{
  /* 各層文字：left／top 為設計稿量到的百分比（x 逐層左移是 3D 透視造成的）。
     三層文字恆常顯示，不隨階段淡入淡出。 */
}
.seoCheck .conceptArea .conceptImg .pyramid .pyLabel{
  position: absolute;
  transform: translate(-50%, -50%);
  font-size: 40px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #fff;
  /* 三層恆常顯示後，白字也會壓在「未點亮的淺灰玻璃」上，
     陰影要夠深才讀得到（原本只有點亮的橘色層要考慮，所以很淡） */
  text-shadow: 0 2px 8px rgba(110, 55, 15, 0.5), 0 0 2px rgba(110, 55, 15, 0.35);
  white-space: nowrap;
  pointer-events: none;
  transition: opacity 0.5s ease;
}
.seoCheck .conceptArea .conceptImg .pyramid .l3{
  left: 51%;
  top: 24%;
}
.seoCheck .conceptArea .conceptImg .pyramid .l2{
  left: 49%;
  top: 49%;
}
.seoCheck .conceptArea .conceptImg .pyramid .l1{
  left: 46%;
  top: 80%;
}
.seoCheck .conceptArea .conceptImg{
  /* Animate each block and its label as one rigid layer. */
}
.seoCheck .conceptArea .conceptImg.isDrop .pyramid .stage{
  opacity: 0;
}
.seoCheck .conceptArea .conceptImg.isDrop .pyLayer{
  animation: pyramidHeavyDrop 0.75s cubic-bezier(0.55, 0, 0.9, 0.35) both, pyramidSway 0.75s ease-in-out both;
}
.seoCheck .conceptArea .conceptImg.isDrop .dropPiece{
  opacity: 1;
}
.seoCheck .conceptArea .conceptImg.isDrop .d1{
  animation-delay: 0s;
}
.seoCheck .conceptArea .conceptImg.isDrop .d2{
  animation-delay: 0.32s;
}
.seoCheck .conceptArea .conceptImg.isDrop .d3{
  animation-delay: 0.64s;
}
.seoCheck .conceptArea .conceptImg{
  /* 落定後的交接：切片在上、.s1 在下（DOM 順序如此），
     所以要「切片淡出、露出 .s1」，不是「.s1 淡入」——後者會被切片擋住，
     等切片消失才突然出現，那就是使用者看到的「閃一下」。 */
}
.seoCheck .conceptArea .conceptImg.isDrop.isLanded .pyramid .s1{
  opacity: 1;
  transition: none;
}
.seoCheck .conceptArea .conceptImg.isDrop.isLanded .dropPiece{
  animation: pyramidPieceFade 0.6s ease forwards;
}
.seoCheck .conceptArea .conceptImg.isStage2 .pyramid .s2,
.seoCheck .conceptArea .conceptImg.isStage3 .pyramid .s2,
.seoCheck .conceptArea .conceptImg.isStage3 .pyramid .s3{
  opacity: 1;
  transition-delay: 0s;
}
.seoCheck .conceptArea .conceptImg{
  /* 手機版可用圓點／滑動直接從 SEO 跳到 GEO：s2、s3 若同時亮會像一次全亮。
     讓頂層晚 0.25s 才亮 → 永遠是 AEO 先亮、GEO 再亮，讀起來仍是一層一層點亮；
     自動輪播 2→3 也會吃到這 0.25s，肉眼幾乎無感。 */
}
.seoCheck .conceptArea .conceptImg.isStage3 .pyramid .s3{
  transition-delay: 0.25s;
}
.seoCheck .conceptArea .conceptImg{
  /* .tip 只是定位框，本身沒有外觀；三張卡片各自絕對定位在自己的 top，只做淡入淡出 */
}
.seoCheck .conceptArea .conceptImg .tip{
  position: absolute;
  /* 設計稿量測：卡片右緣落在金字塔寬度的 35%，卡片往左長（左緣會超出金字塔左邊界）。
     錨右緣而非 left: 0，卡片才不會蓋住 51% 位置的 GEO 文字；各斷點卡片寬度不同也不必重算。 */
  left: auto;
  right: 65%;
  top: 0;
  bottom: 0;
  z-index: 3;
  /* 320 而非 370：左欄卡片右緣 917、SEO 文字左緣 1283（1920 實測），
     中間只剩 366px；340 會剛好貼死左欄，320 兩側各留約 20px。 */
  width: 320px;
}
.seoCheck .conceptArea .conceptImg .tip .tipItem{
  position: absolute;
  left: 0;
  width: 100%;
  opacity: 0;
  visibility: hidden;
  /* 淡出不延遲；淡入的那張延遲 0.45s（見下方 .isStageX 規則），
     讓上一張先完全淡掉，才輪到下一張在自己的定點浮現 */
  transition: opacity 0.45s ease, visibility 0.45s;
}
.seoCheck .conceptArea .conceptImg .tip{
  /* SEO 那張單獨再往左（光暈／指示線／圓點都在 .tipItem 內，跟著一起走）。
     指示線長度與顏色也各卡自訂：SEO 壓在橘色底座上所以走白線，AEO／GEO 走橘線；
     SEO、AEO 兩條刻意比 GEO 短。 */
}
.seoCheck .conceptArea .conceptImg .tip .t1{
  top: var(--tip1);
  left: var(--tip1X);
  --lineW: 55px;
  --lineColor: #fff;
}
.seoCheck .conceptArea .conceptImg .tip .t2{
  top: var(--tip2);
  left: var(--tip2X);
  --lineW: 45px;
  --lineColor: var(--mainColor);
}
.seoCheck .conceptArea .conceptImg .tip .t3{
  top: var(--tip3);
  --lineW: 110px;
  --lineColor: var(--mainColor);
}
.seoCheck .conceptArea .conceptImg .tip{
  /* 橘暈與白卡是兄弟，且排在白卡前面 → 真正疊在卡片後方（不是染在白底上） */
}
.seoCheck .conceptArea .conceptImg .tip .tipGlow{
  position: absolute;
  left: 88%;
  top: 50%;
  width: 72%;
  height: 130%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 138, 61, 0.45) 0%, rgba(255, 138, 61, 0.2) 45%, rgba(255, 138, 61, 0) 100%);
  filter: blur(18px);
  z-index: 0;
  pointer-events: none;
}
.seoCheck .conceptArea .conceptImg .tip .tipCard{
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 124px;
  padding: 22px 36px;
  background: #fff;
  border-radius: 16px;
  box-shadow: var(--cardShadow);
  border-bottom: 2px solid var(--mainColor);
  /* 指示線：靠卡片端是實色、遠離卡片的右端漸層淡出，不做硬切。
     長度與顏色由各張卡的 --lineW／--lineColor 決定（見下方 .t1/.t2/.t3）。
     寬度要再 +21px（＝ .tipDot 圓心距卡片右緣的距離），
     讓線的左側硬邊延伸進卡片、剛好被圓點蓋住。 */
}
.seoCheck .conceptArea .conceptImg .tip .tipCard::after{
  content: "";
  position: absolute;
  right: calc(var(--lineW) * -1);
  top: 50%;
  width: calc(var(--lineW) + 21px);
  height: 1px;
  background: linear-gradient(90deg, var(--lineColor) 0%, transparent 100%);
}
.seoCheck .conceptArea .conceptImg .tip .tipTitle{
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 22px;
  font-weight: 700;
}
.seoCheck .conceptArea .conceptImg .tip .tipTitle::before{
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--mainColor);
}
.seoCheck .conceptArea .conceptImg .tip{
  /* 手機版標題編號（圓點 → 01 → SEO）；桌機卡片疊在金字塔旁不顯示，≤991 才打開（見下方斷點） */
}
.seoCheck .conceptArea .conceptImg .tip .tipNum{
  display: none;
  color: var(--mainColor);
  font-size: 0.95em;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.seoCheck .conceptArea .conceptImg .tip .tipText{
  font-size: 15px;
  color: #666;
  /* 原 #444，內文統一 #666（使用者 2026-09-11） */
  margin-top: 6px;
}
.seoCheck .conceptArea .conceptImg .tip{
  /* 整顆圓點收進卡片內，距右緣 16px 留餘裕（外圈 4px 光暈到 12px 處仍在卡內）。
     z-index: 2 是必要的——`.tipCard::after` 在繪製順序上晚於 .tipDot，
     不指定的話灰線會壓過圓點。 */
}
.seoCheck .conceptArea .conceptImg .tip .tipDot{
  position: absolute;
  z-index: 2;
  right: 16px;
  top: calc(50% - 5px);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--mainColor);
  box-shadow: 0 0 0 4px rgba(255, 80, 1, 0.2);
}
.seoCheck .conceptArea .conceptImg.isStage1 .tip .tipItem.t1,
.seoCheck .conceptArea .conceptImg.isStage2 .tip .tipItem.t2,
.seoCheck .conceptArea .conceptImg.isStage3 .tip .tipItem.t3{
  opacity: 1;
  visibility: visible;
  transition-delay: 0.45s;
}
.seoCheck .conceptArea .conceptImg{
  /* 手機版（≤991）提示卡輪播控制：左右箭頭＋圓點。桌機版卡片疊在金字塔旁自動輪播，不需要，故預設隱藏。
     樣式照 2608-ai-robot 案例的 .valueNav／.valueDots（2026-09-11 使用者指定）：
     箭頭無圓框無底色、SVG 用 round cap／join 做小圓角，點擊區 40×44；
     點點本體用 ::before 畫（7px 灰 → 作用中 20px 橘長條），按鈕本身撐成 20×44 點擊區。 */
}
.seoCheck .conceptArea .conceptImg .tipNav{
  display: none;
  align-items: center;
  justify-content: center;
  gap: 2px;
  margin-top: 14px;
}
.seoCheck .conceptArea .conceptImg .tipNav .navBtn{
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: rgba(0, 0, 0, 0.32);
  cursor: pointer;
  transition: color 0.3s;
  -webkit-tap-highlight-color: transparent;
}
.seoCheck .conceptArea .conceptImg .tipNav .navBtn svg{
  width: 20px;
  height: 20px;
}
.seoCheck .conceptArea .conceptImg .tipNav .navBtn:active{
  color: var(--mainColor);
}
.seoCheck .conceptArea .conceptImg .tipNav .dots{
  display: flex;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}
.seoCheck .conceptArea .conceptImg .tipNav .dot{
  position: relative;
  display: block;
  width: 20px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.seoCheck .conceptArea .conceptImg .tipNav .dot::before{
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 7px;
  height: 7px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.18);
  transform: translate(-50%, -50%);
  transition: width 0.35s, background-color 0.35s;
}
.seoCheck .conceptArea .conceptImg .tipNav .dot.isActive::before{
  width: 20px;
  background: var(--mainColor);
}
@media (hover: hover) and (pointer: fine) {
  .seoCheck .conceptArea .conceptImg .tipNav .navBtn:hover{
    color: var(--mainColor);
  }
  .seoCheck .conceptArea .conceptImg .tipNav .dot:not(.isActive):hover::before{
    background: rgba(0, 0, 0, 0.32);
  }
}

@media (max-width: 1440px) {
  .seoCheck .conceptArea .conceptImg .tip{
    width: 320px;
    /* 版面變窄，三條線一起縮短（顏色不變；+21px 的卡內延伸由 .tipCard::after 自己算） */
  }
  .seoCheck .conceptArea .conceptImg .tip .t1{
    --lineW: 40px;
  }
  .seoCheck .conceptArea .conceptImg .tip .t2{
    --lineW: 35px;
  }
  .seoCheck .conceptArea .conceptImg .tip .t3{
    --lineW: 60px;
  }
}
/* 1180 < 螢幕 ≤ 1280：版心已經吃緊，但還沒到 ≤1180 的「卡片疊到金字塔正上方」那套。
   這段解決 1200 左右的兩個問題（使用者 2026-09-11 回報）：
   1. 提示卡牌（.tip）壓在左欄白卡上 —— 實測 1200 時白卡 x 20..680、卡牌 x 590..910，重疊 90px。
      解法是「左欄縮窄 ＋ 卡牌縮窄並往右挪」兩邊一起讓，單改一邊要動的幅度太大。
   2. 白卡內文 18px 在這個寬度顯得太擠，改成與比較表格內文同級（--dataTextSize 16px）。 */
@media (max-width: 1280px) {
  .seoCheck .conceptArea .wrap{
    /* 660 → 520：讓出 140px 給右欄，卡牌才有地方往右站 */
    grid-template-columns: minmax(0, 520px) minmax(0, 1fr);
  }
  .seoCheck .conceptArea .conceptItem{
    /* 左欄縮到 520 後「有了 AI，SEO 已經不重要」會斷成兩行，這裡三邊一起收讓它維持單行：
       label 180 → 150px（字級 17px，「錯誤迷思」四個字仍單行）、內距收窄、標題 28 → 23px。
       可用寬度 = 520 − 150（label）− 52（內距）− 38（✕ 與 gap）≈ 280，23px × 11 字 ≈ 253。 */
  }
  .seoCheck .conceptArea .conceptItem .label{
    flex: 0 0 150px;
    font-size: 17px;
    padding: 24px 10px;
  }
  .seoCheck .conceptArea .conceptItem.myth .content{
    font-size: 23px;
    gap: 14px;
    padding: 22px 26px;
  }
  .seoCheck .conceptArea .conceptItem.correct .content{
    padding: 12px 30px;
  }
  .seoCheck .conceptArea .conceptItem{
    /* hover 灰底的溢出量跟著 .content 的水平 padding 走（見 .conceptItem 的 --liBleed 註解） */
  }
  .seoCheck .conceptArea .conceptItem.correct{
    --liBleed: 30px;
    --liBleedY: 12px;
  }
  .seoCheck .conceptArea .conceptItem.correct .checkList li{
    /* 比照 .solutionArea .cell.plan（--dataTextSize），使用者指定兩處字級一致 */
    font-size: var(--dataTextSize);
    padding: 18px 0;
    gap: 14px;
  }
  .seoCheck .conceptArea .conceptImg{
    /* 欄位變窄，整組再右移會溢出 wrap；金字塔本身也一併縮小 */
    left: 0;
    max-width: 500px;
    /* SEO／AEO 兩張卡在桌機各自再往左偏 40／20px。這個寬度曾經一律歸 0（怕卡片推到左欄白卡邊上），
       但實測 SEO 卡右緣會比金字塔上的「SEO」字左緣多出 10px、把字遮掉（使用者 2026-09-11 回報），
       所以 SEO 卡改讓 30px：1181 最窄處卡右緣距 SEO 字 20px、卡左緣距白卡 31px，兩邊都留得住。
       AEO 卡（t2）位置較高、不會壓到字，維持 0。 */
    --tip1X: -30px;
    --tip2X: 0px;
  }
  .seoCheck .conceptArea .conceptImg .tip{
    /* 卡牌縮窄（字級不動，改的是盒寬與內距）並往右挪：
       right 60% → 卡片右緣落在金字塔寬度的 40% 處，左緣約 x 589，
       與左欄白卡右緣（x 540）留約 49px，不再重疊。 */
    width: 260px;
    right: 60%;
  }
  .seoCheck .conceptArea .conceptImg .tip .tipCard{
    padding: 20px 24px;
  }
}
@media (max-width: 1180px) {
  .seoCheck .conceptArea{
    padding: 74px 0 80px;
  }
  .seoCheck .conceptArea .wrap{
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
  .seoCheck .conceptArea .conceptBox{
    margin-top: 40px;
  }
  .seoCheck .conceptArea .conceptItem .label{
    flex: 0 0 130px;
    font-size: 17px;
    padding: 20px 12px;
  }
  .seoCheck .conceptArea .conceptItem .content{
    padding: 20px 24px;
  }
  .seoCheck .conceptArea .conceptItem.myth .content{
    font-size: 22px;
  }
  .seoCheck .conceptArea .conceptItem.correct .content{
    padding: 8px 24px;
  }
  .seoCheck .conceptArea .conceptItem{
    /* hover 灰底的溢出量跟著 .content 的水平 padding 走（見 .conceptItem 的 --liBleed 註解） */
  }
  .seoCheck .conceptArea .conceptItem.correct{
    --liBleed: 24px;
    --liBleedY: 8px;
  }
  .seoCheck .conceptArea .conceptItem.correct .checkList li{
    font-size: var(--textSizeMedium);
    padding: 16px 0;
    gap: 12px;
  }
  .seoCheck .conceptArea .conceptImg{
    /* 金字塔底緣要「始終」對齊左欄卡片下緣（使用者 2026-09-11）。
       原本用固定的 padding-top: 120px 決定位置，左欄高度一變（文字折行）就對不上，
       改成「右欄拉滿列高、金字塔用 flex 貼底」，與左欄高度無關。 */
    align-self: stretch;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding-top: 0;
    /* 此斷點起提示卡改為疊在金字塔正上方，整組再右移會超出欄位 */
    --pyShiftX: 0px;
    left: 0;
    /* 欄位剩一半寬，金字塔再收一級（≤1280 是 500）：使用者 2026-09-11 */
    max-width: 400px;
  }
  .seoCheck .conceptArea .conceptImg .pyramid .pyLabel{
    font-size: 34px;
  }
  .seoCheck .conceptArea .conceptImg{
    /* 欄位變窄，卡片再往左會壓到左欄文字；三張卡改為疊在金字塔正上方同一點淡入淡出 */
    --tip1: 0px;
    --tip2: 0px;
    --tip3: 0px;
    --tip1X: 0px;
    --tip2X: 0px;
  }
  .seoCheck .conceptArea .conceptImg .tip{
    /* 金字塔尖端在 .conceptImg 的水平中央，卡片也置中才對得上
       （原本 left: 0 靠左緣，卡片會偏到尖端左邊）。卡寬 280 < 容器 400，不會溢出。
       垂直改以「金字塔上緣」為基準（容器現在會被拉高，貼容器頂的話卡片會飄太上面）：
       bottom 480 = 金字塔高 456（此區間容器恆 400 寬、圖比例 1:1.14）＋ 24px 間距；
       高度給 0、卡片改 bottom: 0 往上長，卡片行數不同也不會推到金字塔。 */
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    top: auto;
    bottom: 480px;
    height: 0;
    width: 280px;
  }
  .seoCheck .conceptArea .conceptImg .tip .tipItem{
    top: auto;
    bottom: 0;
  }
  .seoCheck .conceptArea .conceptImg .tip .tipCard{
    min-height: 96px;
    padding: 16px 24px;
  }
  .seoCheck .conceptArea .conceptImg .tip .tipCard::after{
    display: none;
  }
  .seoCheck .conceptArea .conceptImg .tip .tipTitle{
    font-size: 18px;
  }
  .seoCheck .conceptArea .conceptImg .tip .tipText{
    font-size: 14px;
  }
  .seoCheck .conceptArea .conceptImg .tip .tipDot{
    display: none;
  }
}
@media (max-width: 991px) {
  .seoCheck .conceptArea .wrap{
    grid-template-columns: 1fr;
  }
  .seoCheck .conceptArea{
    /* 單欄後文字欄變成第一列，負 margin 會吃掉區塊上方留白 */
  }
  .seoCheck .conceptArea .conceptTxt{
    margin-top: 0;
  }
  .seoCheck .conceptArea{
    /* 單欄後標題區（小標／大標／說明文）一律置中。
       原本只寫在 ≤768，但版面從 ≤991 就已經是單欄，976～991 與 769～975 會靠左看起來歪
       （使用者 2026-09-11 於 975 寬回報）。 */
  }
  .seoCheck .conceptArea .conceptTxt .titleBox{
    text-align: center;
  }
  .seoCheck .conceptArea{
    /* 單欄後提示卡不再疊在金字塔上方，改排到金字塔下方（2026-09-11 使用者截圖需求）：
       .conceptImg 轉 flex column，DOM 順序是 .tip → .tipNav → .pyramid，用 order 反轉成
       金字塔 → 卡片 → 箭頭／圓點；.tip 從絕對定位改回文件流，三張卡以 grid 疊在同一格
       （高度取最高那張，切換時版面不跳動），仍由 .isStageX 控制淡入淡出。 */
  }
  .seoCheck .conceptArea .conceptImg{
    display: flex;
    flex-direction: column;
    justify-self: center;
    max-width: 520px;
    /* 原 90px 是留給疊在上方的卡片；卡片下移後這裡就是金字塔與上方觀念卡片的間距（2026-09-11 使用者要求拉開） */
    padding-top: 56px;
  }
  .seoCheck .conceptArea .conceptImg .pyramid{
    order: 1;
  }
  .seoCheck .conceptArea .conceptImg .pyramid .pyLabel{
    font-size: 30px;
  }
  .seoCheck .conceptArea .conceptImg .tip{
    order: 2;
    position: relative;
    inset: auto;
    /* ≤1180 的置中位移要清掉，否則單欄時整塊會往左偏半個寬度 */
    transform: none;
    height: auto;
    display: grid;
    width: 100%;
    margin-top: 28px;
  }
  .seoCheck .conceptArea .conceptImg .tip .tipItem{
    position: relative;
    grid-area: 1/1;
    top: auto;
    left: auto;
  }
  .seoCheck .conceptArea .conceptImg .tip .tipCard{
    text-align: center;
    align-items: center;
  }
  .seoCheck .conceptArea .conceptImg .tip{
    /* 標題編號只在手機版顯示：圓點 → 01 → SEO */
  }
  .seoCheck .conceptArea .conceptImg .tip .tipNum{
    display: inline;
  }
  .seoCheck .conceptArea .conceptImg .tipNav{
    order: 3;
    display: flex;
  }
}
@media (max-width: 768px) {
  .seoCheck .conceptArea{
    padding: 70px 0 60px;
    /* 兩張觀念卡之間的距離（桌機 16px，手機拉開；2026-09-11 使用者要求）。
       margin-top 覆寫 ≤991 的 40px：原為 70（與 padding-top 均等），
       使用者後續要求標題區與第一張卡再靠近一點，改 44（2026-09-11） */
  }
  .seoCheck .conceptArea .conceptBox{
    margin-top: 44px;
    gap: 28px;
  }
  .seoCheck .conceptArea .conceptItem{
    flex-direction: column;
    /* 手機版標籤列（錯誤迷思／正確觀念）置中（2026-09-11 使用者要求） */
  }
  .seoCheck .conceptArea .conceptItem .label{
    flex: 0 0 auto;
    padding: 14px;
    justify-content: center;
  }
  .seoCheck .conceptArea .conceptItem.myth .content{
    font-size: 19px;
    gap: 12px;
  }
  .seoCheck .conceptArea .conceptItem.correct .checkList li{
    font-size: var(--textSizeSmall);
  }
  .seoCheck .conceptArea .conceptImg{
    padding-top: 44px;
  }
  .seoCheck .conceptArea .conceptImg .pyramid .pyLabel{
    font-size: 24px;
  }
  .seoCheck .conceptArea .conceptImg{
    /* 卡片已在 ≤991 移到金字塔下方，這裡只縮間距 */
  }
  .seoCheck .conceptArea .conceptImg .tip{
    margin-top: 20px;
  }
  .seoCheck .conceptArea .conceptImg .tipNav{
    margin-top: 10px;
  }
}
/* ==========================================================
   solutionArea — 方案比較
   ========================================================== */
.seoCheck .solutionArea{
  position: relative;
  padding: 90px 0 140px;
  overflow: hidden;
  background: linear-gradient(180deg, #f9f9fb 0%, #f2f2f4 100%);
}
.seoCheck .solutionArea .bgWord{
  top: 80px;
}
.seoCheck .solutionArea .wrap{
  z-index: 1;
}
.seoCheck .solutionArea .titleBox{
  margin-bottom: 110px;
}
.seoCheck .solutionArea .titleBox .text{
  max-width: 520px;
  margin-left: auto;
  margin-right: auto;
}
.seoCheck .solutionArea .solutionBox{
  position: relative;
  max-width: 1240px;
  margin: 0 auto;
}
.seoCheck .solutionArea{
  /* 推薦方案標籤的定位基準。桌機時 .compareWrap／.compareScroll／.compareInner 都只是一般區塊、
     寬度＝.solutionBox，所以標籤公式跟以前掛在 .solutionBox 上時完全一樣。
     標籤放在 .compareWrap 層而不是捲動內容裡：≤768 圓角切在 .compareScroll 視窗上，
     留在捲動內容裡會被裁掉（見 ≤768 區塊）。 */
}
.seoCheck .solutionArea .compareWrap{
  position: relative;
}
.seoCheck .solutionArea{
  /* 方案頁籤與滑動提示只有手機版（≤768）用，樣式寫在該斷點內 */
}
.seoCheck .solutionArea .planTab,
.seoCheck .solutionArea .compareMask,
.seoCheck .solutionArea .compareHint{
  display: none;
}
.seoCheck .solutionArea{
  /* 推薦方案標籤（plan-badge.svg 286×117，內含皇冠、文字、陰影與左下折角）
     設計稿量測：折角三角形的右邊緣（svg x≈60.2）＝ 推薦欄左邊界，
     svg y=59 ＝ 推薦欄上緣（膠囊底邊 svg y=82 會壓進橘色區 23px），
     故偏移為 -60px / -59px；折角往左下掛在表格外，推薦欄左上角必須是直角。 */
}
.seoCheck .solutionArea .recommendTag{
  position: absolute;
  left: calc(270px + (100% - 270px) / 2 - 60px);
  top: -59px;
  width: 286px;
  height: auto;
  z-index: 3;
  pointer-events: none;
  overflow: visible;
  /* 皇冠上浮時不要被 svg viewport 裁掉 */
  /* 皇冠輕微懸浮。transform-box: fill-box 讓 transform 以皇冠自身的
     bbox 為基準，不然會以整個 svg viewport 計算。 */
}
.seoCheck .solutionArea .recommendTag .tagCrown{
  transform-box: fill-box;
  transform-origin: center;
  animation: crownFloat 2.6s ease-in-out infinite;
}
.seoCheck .solutionArea .recommendTag{
  /* 膠囊反光：白色斜光帶由左掃到右（已用 clipPath 裁成膠囊形）。
     CSS transform 套在 svg 元素上是以 svg 使用者座標為單位，
     所以 translateX 的 px 會跟著標籤縮放，RWD 不用另調。 */
}
.seoCheck .solutionArea .recommendTag .tagShine{
  animation: tagShine 4s ease-in-out infinite;
  mix-blend-mode: screen;
}
.seoCheck .solutionArea{
  /* 左側標籤欄寬度。grid 與 .colFrame 共用同一個值，改斷點時只需改這裡 */
  --labelW: 270px;
}
.seoCheck .solutionArea .compareTable{
  position: relative;
  /* .colFrame 的定位基準 */
  display: grid;
  grid-template-columns: var(--labelW) minmax(0, 1fr) minmax(0, 1fr);
  background: #fff;
  border-radius: var(--radiusLg);
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.06);
  overflow: hidden;
}
.seoCheck .solutionArea{
  /* 重度陪跑型欄的 hover 外框（第 2 欄）
     用絕對定位而非 grid-column/grid-row：明確放置的格線項目會讓後面 21 個 auto-placement 的
     .cell 避開被佔用的格子而整張表錯位；絕對定位則完全脫離 grid 排版流。

     四邊與第 2 欄**完全切齊**（上下貼表格上下緣，左右貼欄位邊界），所以不能有圓角：
     表格白底是 .compareTable 一整片方形背景，圓角只發生在 border 上，
     若框有圓角又跟欄位切齊，每個圓弧外側都會露出一塊方形白楔形；
     第 2 欄是表格內側欄位、上下本來就是直邊，改成直角矩形反而完美吻合。
     （全站 box-sizing: border-box，2px 框線畫在盒內，不會擐到還好的橘底推薦欄上。） */
}
.seoCheck .solutionArea .colFrame{
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--labelW);
  width: calc((100% - var(--labelW)) / 2);
  border: 2px solid transparent;
  /* 只圓左側兩角：它們的外側仍在表格白底內（白對白），不會露出方形白楔形；
     右側兩角貼著橘底推薦欄，必須維持直角才不會割到那塊橘色。 */
  border-radius: var(--radiusSm) 0 0 var(--radiusSm);
  pointer-events: none;
  z-index: 2;
  transition: border-color 0.4s ease-in-out, box-shadow 0.4s ease-in-out;
}
.seoCheck .solutionArea .cell{
  padding: 28px 40px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 104px;
}
.seoCheck .solutionArea .cell.label{
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 12px;
  padding-left: 80px;
  font-size: var(--textSize);
  font-weight: 700;
  line-height: 1.5;
}
.seoCheck .solutionArea .cell.label::before{
  content: "";
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--mainColor);
}
.seoCheck .solutionArea .cell.label.even{
  background: var(--grayColor);
}
.seoCheck .solutionArea .cell.label{
  /* 表頭左上空白格：不顯示圓點 */
}
.seoCheck .solutionArea .cell.label.head::before{
  display: none;
}
.seoCheck .solutionArea .cell.plan{
  font-size: var(--dataTextSize);
  line-height: 1.8;
  color: #666;
  /* 原 #444，內文統一 #666（使用者 2026-09-11） */
  padding: 26px 40px;
  /* 重度陪跑型欄 hover 變淡灰底用的。transition 寫在 base，滑開時才會也漸變回去。
     這欄格子本來就沒背景色（白底是 .compareTable 一整片），
     transparent → 純色可以直接插值，不像推薦欄的漸層底還得另疊遮罩層。 */
  transition: background-color 0.6s ease-in-out;
  /* z-index: 1 是為了壓在推薦欄 hover 黑底遮罩層（.recommend.plan::after）上方 */
}
.seoCheck .solutionArea .cell.plan p{
  position: relative;
  z-index: 1;
}
.seoCheck .solutionArea .cell.plan{
  /* 預算門檻的價格（參考 2608-ai-robot 方案價格，2026-09-11）：
     數字 <b> 放大加粗（Poppins 由 --mainFont fallback 自動接手）、單位 <span> 維持格子字級與灰字。
     數字由 js/main.js initPlanPrice() 拆成 .priceChar（overflow hidden 遮罩）＋ .priceRoll（疊 3 份同字元），
     進場時各字元從遮罩下半滾入（播一次後常駐），hover 該方案欄時再滾入一次。高度多留 .16em 給逗號／小數點下伸。 */
}
.seoCheck .solutionArea .cell.plan .price{
  display: flex;
  align-items: baseline;
  gap: 8px;
  line-height: 1;
}
.seoCheck .solutionArea .cell.plan .price b{
  display: inline-flex;
  font-size: var(--priceSize);
  font-weight: 700;
  line-height: 1;
  color: #000;
}
.seoCheck .solutionArea .cell.plan .price{
  /* 限直接子層：不加 > 會連 JS 拆字產生的 .priceChar／.priceRoll 一併選中 */
}
.seoCheck .solutionArea .cell.plan .price > span{
  font-size: inherit;
  line-height: 1.8;
}
.seoCheck .solutionArea .cell.plan .price .priceChar{
  display: block;
  overflow: hidden;
  height: 1.16em;
}
.seoCheck .solutionArea .cell.plan .price .priceRoll{
  display: block;
  will-change: transform;
  /* 3 份字元疊成一條（高 3 × 1.16em）。起始 +33.33%：第 1 份整個在遮罩下方（空白）；
     終點 −33.33%：第 2 份對準遮罩，途中第 1 份先經過 → 字滾 2 圈（使用者 2026-09-11） */
  transform: translateY(33.33%);
}
.seoCheck .solutionArea .cell.plan .price .priceRoll i{
  display: block;
  height: 1.16em;
  font-style: normal;
  line-height: 1.16;
}
.seoCheck .solutionArea .cell.plan .price{
  /* 進場：1.1s power3.out 滾 2 圈，逐字 delay 由 JS 寫在 --rollDelay；播過一次後 .isIn 常駐。
     hover 方案欄要重播時，JS 先加 .isSnap（無過場）拿掉 .isIn 讓字瞬間回到遮罩下方，再加回 .isIn */
}
.seoCheck .solutionArea .cell.plan .price.isIn .priceRoll{
  transform: translateY(-33.33%);
  transition: transform 1.1s cubic-bezier(0.215, 0.61, 0.355, 1);
  transition-delay: var(--rollDelay, 0s);
}
.seoCheck .solutionArea .cell.plan .price.isSnap .priceRoll{
  transition: none;
}
.seoCheck .solutionArea .cell.head{
  min-height: 200px;
  padding-top: 56px;
  padding-bottom: 40px;
  justify-content: flex-start;
  font-size: 30px;
  font-weight: 700;
  color: var(--titleColor);
}
.seoCheck .solutionArea .cell.head .planTitle{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.seoCheck .solutionArea .cell.head{
  /* solutionArea-icon.svg 本身含白圓與雙環，不再另外裁圓／加陰影 */
}
.seoCheck .solutionArea .cell.head .planIcon{
  position: relative;
  width: 117px;
  height: 117px;
  flex: 0 0 auto;
  margin: -10px -10px -10px 0;
}
.seoCheck .solutionArea .cell.head .planIcon img{
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  animation: iconBreath 3.2s ease-in-out infinite;
}
.seoCheck .solutionArea .cell.head .planIcon{
  /* 圓形漣漪：兩圈同樣的環，第二圈錯開半個週期，看起來就是連續往外擴散。
     translate(-50%,-50%) 必須寫進 keyframes 一起帶，否則 scale 會把定位覆蓋掉；
     base 這裡也要寫一份同樣的 transform，動畫還沒接手時才不會跳位。 */
}
.seoCheck .solutionArea .cell.head .planIcon::before,
.seoCheck .solutionArea .cell.head .planIcon::after{
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100%;
  height: 100%;
  border: 2px solid rgba(255, 255, 255, 0.75);
  border-radius: 50%;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0.9);
  opacity: 0;
  animation: iconRipple 3.2s ease-out infinite;
}
.seoCheck .solutionArea .cell.head .planIcon{
  /* 負延遲：直接從週期中段開始跑。
     用正的 1.6s 會有一段「還沒開始」的空窗，那期間套用的是 base 樣式而非 keyframe 的 0%，
     圓環會先歪在一邊再跳回中心。 */
}
.seoCheck .solutionArea .cell.head .planIcon::after{
  animation-delay: -1.6s;
}
.seoCheck .solutionArea .cell.head{
  /* 重度陪跑型欄的 icon：預設透明，滑到本欄才淡入（hover 規則在下方 :has 那塊）。
     尺寸 82px 不是隨便取的：icon-1 的 viewBox 是 82、icon-2 是 117，但兩者內圓都是直徑 70，
     所以 82px 才跟推薦欄的 117px 目測同大。
     繼承來的漣漪與呼吸動畫一律關掉：那是為橘底推薦欄做的白色圓環，在白底上看不見。 */
}
.seoCheck .solutionArea .cell.head .planIcon.hoverIcon{
  width: 82px;
  height: 82px;
  margin: 0;
  opacity: 0;
  transition: opacity 0.4s ease-in-out;
  /* 漣漪與呼吸預設都不跑，滑到本欄才接（規則在下方 :has 那塊）。
     圓環改成橘色：這欄是白底，照抄推薦欄的白環會完全看不見。 */
}
.seoCheck .solutionArea .cell.head .planIcon.hoverIcon .iconSvg{
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
}
.seoCheck .solutionArea .cell.head .planIcon.hoverIcon{
  /* SVG 最外圈的淡橘細環：hover 漣漪一出來就先收掉（比 icon 淡入快），
     不然會跟擴散中的圓環疊在一起看起來很摻。 */
}
.seoCheck .solutionArea .cell.head .planIcon.hoverIcon .outerRing{
  transition: opacity 0.2s ease-in-out;
}
.seoCheck .solutionArea .cell.head .planIcon.hoverIcon::before,
.seoCheck .solutionArea .cell.head .planIcon.hoverIcon::after{
  border-color: rgba(254, 80, 0, 0.45);
  animation: none;
}
.seoCheck .solutionArea .cell.head .headLine{
  display: block;
  width: 32px;
  height: 3px;
  background: var(--mainColor);
  margin-top: 22px;
}
.seoCheck .solutionArea .cell{
  /* 中間欄的分隔線（除最後一列） */
}
.seoCheck .solutionArea .cell.plan:not(.last){
  border-bottom: 1px solid var(--lineColor);
}
.seoCheck .solutionArea .cell{
  /* 推薦欄 */
}
.seoCheck .solutionArea .cell.recommend{
  background: var(--mainGradient);
  color: #fff;
}
.seoCheck .solutionArea .cell.recommend.head{
  color: #fff;
  /* 左上角維持直角，讓標籤折角能貼齊（設計稿即為直角） */
  border-top-left-radius: 0;
}
.seoCheck .solutionArea .cell.recommend.head .headLine{
  background: #fff;
}
.seoCheck .solutionArea .cell.recommend.plan{
  position: relative;
  color: #fff;
  /* 推薦欄的價格數字跟著白字 */
}
.seoCheck .solutionArea .cell.recommend.plan .price b{
  color: #fff;
}
.seoCheck .solutionArea .cell.recommend.plan{
  border-bottom-color: rgba(255, 255, 255, 0.35);
  /* hover 黑底的遮罩層。不能直接改 background：
     推薦欄底色是 var(--mainGradient)，屬於 background-image，
     而 background-image 無法與純色 transition，直接改只會瞬間跳色。
     改成疊一層黑底、漸變 opacity（可插值、也能交給 GPU）。

     不能用 z-index: -1 把遮罩層壓到文字下方：`.cell` 雖然是 position: relative，
     但 z-index 是 auto、**沒有建立堆疊脈絡**，負 z-index 子元素會一路排到更外層的堆疊脈絡，
     結果是畫在格子橘底的**後面**，完全看不見（實測過）。
     改成不設 z-index，改由 `.cell.plan p` 的 z-index: 1 把文字壓在遮罩層上方。 */
  /* 下邊要多蓋 1px：絕對定位的 inset 參考的是 padding box，
     寫 0 的話格子自己的 border-bottom（分隔線）會留在黑底外，變成一道橘線。 */
}
.seoCheck .solutionArea .cell.recommend.plan::after{
  content: "";
  position: absolute;
  inset: 0 0 -1px;
  background: var(--titleColor);
  opacity: 0;
  transition: opacity 0.6s ease-in-out;
}
.seoCheck .solutionArea{
  /* 兩欄的小項目 hover 底色：推薦欄轉黑（遮罩層）、重度陪跑型欄轉淡灰（直接插值） */
}
@media (hover: hover) and (pointer: fine) {
  .seoCheck .solutionArea .cell.recommend.plan:hover::after{
    opacity: 1;
  }
  .seoCheck .solutionArea .cell.plan:not(.recommend):hover{
    background-color: var(--grayColor);
  }
}
.seoCheck .solutionArea{
  /* 讓推薦欄整體為連續橘底：head + 6 列 */
}
.seoCheck .solutionArea .cell.recommend.head{
  box-shadow: 0 -30px 60px rgba(255, 80, 1, 0.2);
}

/* 「重度陪跑型」欄的強調狀態（橘框＋光暈、內容上浮、icon 淡入＋漣漪）。
   兩個入口共用同一組規則：桌機是滑到該欄任一格（:has(:hover)）、
   手機是頁籤選到／畫面停在該欄時由 js/main.js 加上 .compareTable.isHeavy。
   三欄靠現有 class 就能區分：標籤欄有 .label、推薦欄有 .recommend、重度陪跑型欄兩者皆無，
   所以不必替 21 個 cell 另外加欄位 class。 */
@media (hover: hover) and (pointer: fine) {
  .seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover){
    /* 外框：橘線 ＋ 橘色光暈。
       框本身**不**跟著 translateY(-4px)：它已經貼齊表格上下緣，再上浮的話
       上邊框會被 .compareTable 的 overflow: hidden 裁掉、下邊框則會跑出一道 4px 縫。
       浮起的感覺由欄內容（下一條規則）負責。 */
  }
  .seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover) .colFrame{
    border-color: var(--mainColor);
    box-shadow: 0 14px 30px rgba(255, 80, 1, 0.18);
  }
  .seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover){
    /* 欄內容跟著浮起。cell 沒有自己的背景色（白底是 .compareTable 整片），
       所以位移只帶動文字，不會在格子邊緣露出破綻。 */
  }
  .seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover) .cell:not(.label):not(.recommend){
    transform: translateY(-4px);
  }
  .seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover){
    /* 欄頭的 icon 淡入，並接手漣漪＋呼吸 */
  }
  .seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover) .planIcon.hoverIcon{
    opacity: 1;
  }
  .seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover) .planIcon.hoverIcon .iconSvg{
    animation: iconBreath 3.2s ease-in-out infinite;
  }
  .seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover) .planIcon.hoverIcon .outerRing{
    opacity: 0;
  }
  .seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover) .planIcon.hoverIcon::before{
    animation: iconRipple 3.2s ease-out infinite;
  }
  .seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover) .planIcon.hoverIcon::after{
    animation: iconRipple 3.2s ease-out -1.6s infinite;
  }
  .seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover){
    /* 推薦欄那顆同時停漣漪，兩邊不會一起擴散。
       這裡用 animation: none 而不是 animation-play-state: paused：
       paused 會把圓環凍在當下相位（可能是張一半、半透明的環），看起來像破圖；
       改成 none 會回到 base（base 本來就是 opacity: 0），圓環直接消失。 */
  }
  .seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover) .cell.head.recommend .planIcon::before,
.seoCheck .solutionArea .compareTable:has(.cell:not(.label):not(.recommend):hover) .cell.head.recommend .planIcon::after{
    animation: none;
  }
}
/* 手機版：頁籤選到「重度陪跑型」或畫面停在該欄（js/main.js 切 .isHeavy） */
.seoCheck .solutionArea .compareTable.isHeavy{
  /* 外框：橘線 ＋ 橘色光暈。
     框本身**不**跟著 translateY(-4px)：它已經貼齊表格上下緣，再上浮的話
     上邊框會被 .compareTable 的 overflow: hidden 裁掉、下邊框則會跑出一道 4px 縫。
     浮起的感覺由欄內容（下一條規則）負責。 */
}
.seoCheck .solutionArea .compareTable.isHeavy .colFrame{
  border-color: var(--mainColor);
  box-shadow: 0 14px 30px rgba(255, 80, 1, 0.18);
}
.seoCheck .solutionArea .compareTable.isHeavy{
  /* 欄內容跟著浮起。cell 沒有自己的背景色（白底是 .compareTable 整片），
     所以位移只帶動文字，不會在格子邊緣露出破綻。 */
}
.seoCheck .solutionArea .compareTable.isHeavy .cell:not(.label):not(.recommend){
  transform: translateY(-4px);
}
.seoCheck .solutionArea .compareTable.isHeavy{
  /* 欄頭的 icon 淡入，並接手漣漪＋呼吸 */
}
.seoCheck .solutionArea .compareTable.isHeavy .planIcon.hoverIcon{
  opacity: 1;
}
.seoCheck .solutionArea .compareTable.isHeavy .planIcon.hoverIcon .iconSvg{
  animation: iconBreath 3.2s ease-in-out infinite;
}
.seoCheck .solutionArea .compareTable.isHeavy .planIcon.hoverIcon .outerRing{
  opacity: 0;
}
.seoCheck .solutionArea .compareTable.isHeavy .planIcon.hoverIcon::before{
  animation: iconRipple 3.2s ease-out infinite;
}
.seoCheck .solutionArea .compareTable.isHeavy .planIcon.hoverIcon::after{
  animation: iconRipple 3.2s ease-out -1.6s infinite;
}
.seoCheck .solutionArea .compareTable.isHeavy{
  /* 推薦欄那顆同時停漣漪，兩邊不會一起擴散。
     這裡用 animation: none 而不是 animation-play-state: paused：
     paused 會把圓環凍在當下相位（可能是張一半、半透明的環），看起來像破圖；
     改成 none 會回到 base（base 本來就是 opacity: 0），圓環直接消失。 */
}
.seoCheck .solutionArea .compareTable.isHeavy .cell.head.recommend .planIcon::before,
.seoCheck .solutionArea .compareTable.isHeavy .cell.head.recommend .planIcon::after{
  animation: none;
}

/* 位移要有過場，但 transition 不能只寫在強調規則裡，否則滑開／切走時會瞬間跳回 */
.seoCheck .solutionArea .compareTable .cell:not(.label):not(.recommend){
  transition: transform 0.4s ease-in-out;
}

@media (max-width: 1180px) {
  .seoCheck .solutionArea{
    padding: 70px 0 100px;
    --labelW: 180px;
  }
  .seoCheck .solutionArea .titleBox{
    margin-bottom: 80px;
  }
  .seoCheck .solutionArea{
    /* 標籤縮為 230px（286 的 0.804 倍），偏移同比例縮放 */
  }
  .seoCheck .solutionArea .recommendTag{
    left: calc(180px + (100% - 180px) / 2 - 48px);
    top: -47px;
    width: 230px;
  }
  .seoCheck .solutionArea{
    /* 欄寬由上方 --labelW 控制，此處只調圓角 */
  }
  .seoCheck .solutionArea .compareTable{
    border-radius: var(--radiusMd);
  }
  .seoCheck .solutionArea .cell{
    padding: 20px 24px;
    min-height: 90px;
  }
  .seoCheck .solutionArea .cell.label{
    padding-left: 30px;
    font-size: var(--textSizeMedium);
  }
  .seoCheck .solutionArea .cell.plan{
    font-size: var(--dataTextSizeMedium);
    padding: 20px 24px;
  }
  .seoCheck .solutionArea .cell.plan .price b{
    font-size: var(--priceSizeMedium);
  }
  .seoCheck .solutionArea .cell.head{
    min-height: 160px;
    padding-top: 40px;
    padding-bottom: 28px;
    font-size: 24px;
  }
  .seoCheck .solutionArea .cell.head .planIcon{
    width: 72px;
    height: 72px;
  }
  .seoCheck .solutionArea .cell.head .planIcon.hoverIcon{
    width: 50px;
    height: 50px;
  }
}
@media (max-width: 768px) {
  .seoCheck .solutionArea{
    padding: 60px 0 80px;
    --labelW: 130px;
    /* 手機版隱藏背景大字 SOLUTIONS（使用者 2026-09-11） */
  }
  .seoCheck .solutionArea .bgWord{
    display: none;
  }
  .seoCheck .solutionArea .titleBox{
    margin-bottom: 40px;
  }
  .seoCheck .solutionArea{
    /* 方案頁籤：兩個方案名稱並排，選中的深色粗體＋橘色底線（底線由中央往兩側展開）。
       點擊 → js/main.js 把 .compareScroll 捲到該欄；手滑表格時也會反推同步。 */
  }
  .seoCheck .solutionArea .planTab{
    display: flex;
    justify-content: center;
    align-items: flex-end;
    gap: 28px;
    /* 下方要留出「推薦方案」標籤突出表格上緣的 41px，再加一點呼吸空間 */
    margin: 0 0 60px;
  }
  .seoCheck .solutionArea .planTab .tab{
    position: relative;
    padding: 0 0 10px;
    border: 0;
    background: none;
    color: var(--textColor);
    font-family: inherit;
    font-size: 17px;
    font-weight: 400;
    line-height: 1.4;
    cursor: pointer;
    transition: color 0.3s;
    -webkit-tap-highlight-color: transparent;
  }
  .seoCheck .solutionArea .planTab .tab::after{
    content: "";
    position: absolute;
    left: 50%;
    bottom: 0;
    width: 0;
    height: 2px;
    background: var(--mainColor);
    transform: translateX(-50%);
    transition: width 0.35s ease-in-out;
  }
  .seoCheck .solutionArea .planTab .tab.isActive{
    color: var(--titleColor);
    font-weight: 700;
  }
  .seoCheck .solutionArea .planTab .tab.isActive::after{
    width: 100%;
  }
  .seoCheck .solutionArea{
    /* 滑動提示／遮罩／推薦方案標籤的定位基準＝捲動視窗（盒子＝表格可視範圍）。
       圓角與陰影都在這層：陰影不能放在有 overflow 的 .compareScroll 裡面的元素上（會被裁掉）。 */
  }
  .seoCheck .solutionArea .compareWrap{
    border-radius: var(--radiusMd);
    box-shadow: 0 30px 60px rgba(0, 0, 0, 0.06);
  }
  .seoCheck .solutionArea{
    /* ≤768 表格改橫向捲動。圓角切在**捲動視窗**而不是表格本體：
       表格 570px 寬、視窗只有 350px，圓角若在表格四角，視窗右緣永遠是表格中段（橘底被直直切平），
       捲到兩端時 sticky 左欄又會跟表格圓角交疊出尖角。overflow: auto + border-radius 會依圓角裁內容，
       四個角永遠落在可視區四角，捲到哪都是圓的。
       scroll-snap 讓手滑放開後停在整欄；捲軸藏起來，改由頁籤＋滑動提示告知還有內容。 */
  }
  .seoCheck .solutionArea .compareScroll{
    overflow-x: auto;
    overflow-y: hidden;
    border-radius: var(--radiusMd);
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .seoCheck .solutionArea .compareScroll::-webkit-scrollbar{
    display: none;
  }
  .seoCheck .solutionArea{
    /* 寬度＝表格寬（grid 三欄都是固定 px，max-content 就是三欄總和） */
  }
  .seoCheck .solutionArea .compareInner{
    width: max-content;
    min-width: 100%;
  }
  .seoCheck .solutionArea{
    /* 標籤在 .compareWrap 層、不跟著捲：位置＝捲動為 0 時推薦欄（第 2 欄，緊接左欄）的左邊界 − 42px，
       上緣突出表格 41px（200px = 286 的 0.699 倍，折角／上緣偏移同比例）。
       滑離推薦欄時由 js/main.js 依 scrollLeft 寫 inline opacity 淡出（80px 內淡到 0），
       所以這裡不能寫 opacity transition，否則會跟著手指的捲動慢半拍。 */
  }
  .seoCheck .solutionArea .recommendTag{
    left: calc(var(--labelW) - 42px);
    top: -41px;
    width: 200px;
  }
  .seoCheck .solutionArea{
    /* 「往右滑動看更多」提示還在時先不顯示標籤，提示淡出後才淡入（js/main.js 切 isTagHold）。
       JS 會依 scrollLeft 寫 inline opacity，所以這裡要 !important 才壓得過。 */
  }
  .seoCheck .solutionArea .compareWrap.isTagHold .recommendTag{
    opacity: 0 !important;
  }
  .seoCheck .solutionArea{
    /* 兩個方案欄各佔「捲動容器寬 − 左欄寬」：點頁籤時剛好「左欄＋一個方案欄」填滿畫面。
       --colW 的 CSS 值是保險（.wrap 左右各 20px），js/main.js 會依實測 clientWidth 覆寫成精確 px。
       overflow: hidden 換成 clip-path：overflow: hidden 本身就是 scroll container，
       左欄的 sticky 會黏在表格而不是黏在 .compareScroll 上，等於失效。 */
    /* overflow: hidden 要拿掉：它本身就是 scroll container，左欄的 sticky 會黏在表格而不是黏在 .compareScroll 上。
       圓角與陰影都交給外層（.compareScroll／.compareWrap），表格本體不再切圓角。 */
  }
  .seoCheck .solutionArea .compareTable{
    --colW: calc(100vw - 40px - var(--labelW));
    grid-template-columns: var(--labelW) repeat(2, var(--colW));
    min-width: 0;
    overflow: visible;
    border-radius: 0;
    box-shadow: none;
    /* 手機版方案順序對調：推薦欄（輕量型全代操）排第 2 欄、重度陪跑型排第 3 欄，HTML 不動。
       只指定 grid-column 的項目在預設（sparse）自動排版下，遇到「欄號比游標小」會直接跳下一列，
       推薦欄就會全部錯一列；改 dense 讓每個 cell 找自己那欄最早的空列，三欄各 7 格、列數自然對齊。 */
    grid-auto-flow: row dense;
  }
  .seoCheck .solutionArea .cell.label{
    grid-column: 1;
  }
  .seoCheck .solutionArea .cell.recommend{
    grid-column: 2;
  }
  .seoCheck .solutionArea .cell:not(.label):not(.recommend){
    grid-column: 3;
  }
  .seoCheck .solutionArea{
    /* 重度陪跑型欄現在是第 3 欄（貼著表格右緣），強調外框跟著搬過去。
       右側兩角必須跟表格的 clip-path 同半徑（--radiusMd），否則直角會超出裁切線被切掉（使用者 2026-09-11）；
       左側兩角貼著中間欄、本來就是直邊，維持直角。 */
  }
  .seoCheck .solutionArea .colFrame{
    left: calc(var(--labelW) + var(--colW));
    width: var(--colW);
    border-radius: 0 var(--radiusMd) var(--radiusMd) 0;
  }
  .seoCheck .solutionArea{
    /* 左欄固定在可視區左側，方案欄從它底下滑過；必須有不透明底色蓋住底下的內容。
       z-index 3 要壓過推薦欄的 ::after 遮罩層與 .colFrame（z-index 2）。 */
  }
  .seoCheck .solutionArea .cell.label{
    position: sticky;
    left: 0;
    z-index: 3;
    background: #fff;
  }
  .seoCheck .solutionArea .cell.label.even{
    background: var(--grayColor);
  }
  .seoCheck .solutionArea{
    /* snap 點：每個方案格的左緣，扣掉左欄寬 → 停下來時方案欄剛好接在左欄右邊 */
  }
  .seoCheck .solutionArea .cell:not(.label){
    scroll-snap-align: start;
    scroll-margin-left: var(--labelW);
  }
  .seoCheck .solutionArea{
    /* 滑動提示：遮罩只壓暗表格（不是整個畫面），膠囊在表格範圍內置中。
       兩者都 pointer-events: none，不擋使用者滑動；isShow 由 js/main.js 切換。 */
  }
  .seoCheck .solutionArea .compareMask{
    display: block;
    position: absolute;
    inset: 0;
    z-index: 4;
    border-radius: var(--radiusMd);
    background: rgba(0, 0, 0, 0.45);
    opacity: 0;
    transition: opacity 0.45s;
    pointer-events: none;
  }
  .seoCheck .solutionArea .compareMask.isShow{
    opacity: 1;
  }
  .seoCheck .solutionArea .compareHint{
    display: flex;
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 5;
    align-items: center;
    gap: 10px;
    max-width: calc(100% - 32px);
    padding: 14px 22px;
    border-radius: 999px;
    background: rgba(20, 20, 20, 0.88);
    color: #fff;
    font-size: var(--textSizeSmall);
    line-height: 1.2;
    white-space: nowrap;
    opacity: 0;
    /* 收起狀態略低 10px，淡入時往上帶一點位移 */
    transform: translate(-50%, calc(-50% + 10px));
    transition: opacity 0.45s, transform 0.45s;
    pointer-events: none;
  }
  .seoCheck .solutionArea .compareHint.isShow{
    opacity: 1;
    transform: translate(-50%, -50%);
  }
  .seoCheck .solutionArea .compareHint{
    /* 雙箭頭「>>」：兩個 chevron 錯拍往右推出再從左邊補進來，做出前進感 */
  }
  .seoCheck .solutionArea .compareHint .hintIcon{
    display: flex;
    align-items: center;
    gap: 1px;
  }
  .seoCheck .solutionArea .compareHint .chev{
    width: 15px;
    height: 15px;
    animation: swipeHint 1.3s ease-out infinite;
  }
  .seoCheck .solutionArea .compareHint{
    /* 第一個箭頭固定 60% 透明度（動畫的 opacity 會再乘上這層的 opacity） */
  }
  .seoCheck .solutionArea .compareHint .chev.isFirst{
    opacity: 0.6;
    animation-delay: -0.18s;
  }
  .seoCheck .solutionArea .cell.label{
    font-size: var(--textSizeSmall);
    padding-left: 20px;
  }
  .seoCheck .solutionArea .cell.plan{
    font-size: var(--dataTextSizeSmall);
  }
  .seoCheck .solutionArea .cell.plan .price b{
    font-size: var(--priceSizeSmall);
  }
  .seoCheck .solutionArea .cell{
    /* 方案欄只有 220px 左右（390 寬手機），「輕量型全代操」6 個字 + icon 要擠在一行：
       字級 18、padding 20、icon 48、gap 12 → 文字可用寬 120px ≥ 108px，不會折成兩行 */
  }
  .seoCheck .solutionArea .cell.head{
    /* 上 padding 56px：「推薦方案」標籤膠囊底邊壓進表格 16px，
       再留 40px 才放標題，標籤（含陰影）不會疊到文案 */
    min-height: 148px;
    padding: 56px 20px 22px;
    font-size: 18px;
  }
  .seoCheck .solutionArea .cell.head .planTitle{
    gap: 12px;
  }
  .seoCheck .solutionArea .cell.head .planIcon{
    width: 48px;
    height: 48px;
    margin-right: -6px;
  }
  .seoCheck .solutionArea .cell.head .planIcon.hoverIcon{
    width: 34px;
    height: 34px;
    margin: 0;
  }
}
/* ==========================================================
   blogArea — 部落格
   ========================================================== */
.seoCheck .blogArea{
  position: relative;
  padding: 110px 0 130px;
  overflow: hidden;
  background: radial-gradient(35% 40% at 100% 100%, rgba(255, 138, 61, 0.18) 0%, rgba(255, 138, 61, 0) 70%), #fff;
}
.seoCheck .blogArea .bgWord{
  top: 60px;
}
.seoCheck .blogArea .wrap{
  z-index: 1;
}
.seoCheck .blogArea .blogBox{
  display: grid;
  grid-template-columns: 500px minmax(0, 1fr);
  gap: 90px;
  align-items: center;
}
.seoCheck .blogArea .blogNav{
  display: flex;
  align-items: center;
  gap: 100px;
  margin-top: 90px;
  /* hover 為主站 .btn.arrowStyle.bBorder 的原版機制：
     底線是灰、橘兩條疊在一起，橘線寬度 0 → 100% 且錨點 right→left，
     形成「由左往右刷過灰線、移出時往右收回」；
     箭頭圓圈底色恆為灰、svg 恆為白，換色是靠圓內的橘色漸層由 scale(0) 放大到 scale(1)。 */
}
.seoCheck .blogArea .blogNav .more{
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  position: relative;
  width: 200px;
  padding-bottom: 10px;
  font-size: 17px;
  color: var(--secondColor);
  transition: all 0.5s;
}
.seoCheck .blogArea .blogNav .more::before,
.seoCheck .blogArea .blogNav .more::after{
  content: "";
  display: block;
  position: absolute;
  bottom: 0;
  right: 0;
  height: 1px;
  transition: all 0.5s;
}
.seoCheck .blogArea .blogNav .more{
  /* 灰底線（固定） */
}
.seoCheck .blogArea .blogNav .more::before{
  width: 100%;
  background-color: #d5d5d5;
}
.seoCheck .blogArea .blogNav .more{
  /* 橘線（hover 時撐開） */
}
.seoCheck .blogArea .blogNav .more::after{
  width: 0;
  background-color: var(--mainColor);
}
.seoCheck .blogArea .blogNav .more .arrow{
  position: relative;
  width: 35px;
  height: 35px;
  border-radius: 50%;
  background-color: #d5d5d5;
  display: grid;
  place-content: center;
  margin-left: 20px;
  transition: all 0.5s;
  /* 橘色漸層圓，預設縮到 0 */
}
.seoCheck .blogArea .blogNav .more .arrow::before{
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-image: linear-gradient(to right, rgb(254, 80, 0), rgb(255, 132, 0));
  transform: scale(0);
  transition: all 0.5s;
}
.seoCheck .blogArea .blogNav .more .arrow svg{
  position: relative;
  width: 14px;
  height: 12px;
  color: #fff;
}
.seoCheck .blogArea .blogNav{
  /* 計數器：設計稿為『‹ 01 / 08 ›』，兩側淡灰細箭頭。
     chevron 不用 SVG，以方塊旋轉 45° ＋ 兩條 1px border 組成（方塊旋轉法）：
     直角邊長 9px 旋轉後外接矩形約 6.4 × 12.7px，與設計稿量到的 7 × 13px 差不到 1px。 */
  /* 手機版（≤768）箭頭＋圓點控制列，取代數字計數器；外觀見 @mixin carouselNav */
}
.seoCheck .blogArea .blogNav .blogDots{
  display: none;
  align-items: center;
  justify-content: center;
  gap: 2px;
}
.seoCheck .blogArea .blogNav .blogDots .navBtn{
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: rgba(0, 0, 0, 0.32);
  cursor: pointer;
  transition: color 0.3s;
  -webkit-tap-highlight-color: transparent;
}
.seoCheck .blogArea .blogNav .blogDots .navBtn svg{
  width: 20px;
  height: 20px;
}
.seoCheck .blogArea .blogNav .blogDots .navBtn:active{
  color: var(--mainColor);
}
.seoCheck .blogArea .blogNav .blogDots .slick-dots{
  position: static;
  display: flex;
  align-items: center;
  width: auto;
  list-style: none;
  margin: 0;
  padding: 0;
  text-align: left;
}
.seoCheck .blogArea .blogNav .blogDots .slick-dots li{
  display: block;
  width: auto;
  height: auto;
  margin: 0;
  padding: 0;
}
.seoCheck .blogArea .blogNav .blogDots .slick-dots button{
  position: relative;
  display: block;
  width: 20px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  font-size: 0;
  line-height: 0;
  color: transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  /* 蓋掉 slick.min.css 的 ::before（"•"、opacity .25、font-size 6px、20×20 絕對定位） */
}
.seoCheck .blogArea .blogNav .blogDots .slick-dots button::before{
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 7px;
  height: 7px;
  font-size: 0;
  line-height: 0;
  opacity: 1;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.18);
  transform: translate(-50%, -50%);
  transition: width 0.35s, background-color 0.35s;
}
.seoCheck .blogArea .blogNav .blogDots .slick-dots .slick-active button::before{
  width: 20px;
  background: var(--mainColor);
  opacity: 1;
}
@media (hover: hover) and (pointer: fine) {
  .seoCheck .blogArea .blogNav .blogDots .navBtn:hover{
    color: var(--mainColor);
  }
  .seoCheck .blogArea .blogNav .blogDots .slick-dots li:not(.slick-active) button:hover::before{
    background: rgba(0, 0, 0, 0.32);
  }
}
.seoCheck .blogArea .blogNav .counter{
  display: flex;
  align-items: center;
  font-size: 22px;
  color: #444;
  letter-spacing: 0.05em;
}
.seoCheck .blogArea .blogNav .counter .current{
  color: var(--mainColor);
}
.seoCheck .blogArea .blogNav .counter .divider{
  margin: 0 8px;
  color: #bbb;
}
.seoCheck .blogArea .blogNav .counter{
  /* 點擊區擴到 24 × 24px（chevron 本身只有 ~6px 寬，太難點），
     再用負 margin 把多出來的寬度收回來，視覺間距仍是設計稿的 15px。 */
}
.seoCheck .blogArea .blogNav .counter .navBtn{
  display: grid;
  place-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.seoCheck .blogArea .blogNav .counter .navBtn .chevron{
  display: block;
  width: 9px;
  height: 9px;
  border-left: 1px solid #bebebe;
  border-bottom: 1px solid #bebebe;
  transition: all 0.5s;
}
.seoCheck .blogArea .blogNav .counter .navBtn.prev{
  margin: 0 6px 0 -9px;
}
.seoCheck .blogArea .blogNav .counter .navBtn.prev .chevron{
  transform: rotate(45deg);
}
.seoCheck .blogArea .blogNav .counter .navBtn.next{
  margin: 0 -9px 0 6px;
}
.seoCheck .blogArea .blogNav .counter .navBtn.next .chevron{
  transform: rotate(-135deg);
}
.seoCheck .blogArea{
  /* 輪播：往右溢出視窗，左側裁切（避免 infinite 複製卡片蓋到標題） */
}
.seoCheck .blogArea .blogList{
  margin: 0 -30px;
}
.seoCheck .blogArea .blogList .slick-list{
  overflow: visible;
  padding: 30px 0;
  /* 左側必須切在 list 左緣（0）：相鄰卡的卡身右緣就在 `list.left − .blogItem padding`，
     裁切線只要往左讓一點，就會先看到那張卡最濃的右側陰影（實測 1200 寬讓 29px → 255 直接跳 248，比原本更明顯），
     再往左則整張卡身露出來蓋到左欄標題。
     改用「把卡片陰影的水平擴散縮進 padding 內」來解決左側被切的問題，見下方 .blogItem .item 的 box-shadow。 */
  clip-path: inset(-60px -100vw -60px 0);
}
.seoCheck .blogArea .blogItem{
  padding: 0 30px;
  width: 440px;
}
.seoCheck .blogArea .blogItem .item{
  position: relative;
  display: block;
  background: #fff;
  border-radius: var(--radiusMd);
  /* 陰影不用共用的 --cardShadow（0 20px 50px）：模糊 50 往兩側擴散約 25px，
     但輪播左側被 .slick-list 的 clip-path 切在距卡片 15px（≤1180）／30px（桌機）處，
     左側陰影會被切短、跟右側不對稱（使用者 2026-09-11 於 1200 寬回報）。
     改成模糊 24（側向約 12px）＋提高一點 alpha 維持份量，就完全落在裁切線內側。 */
  box-shadow: 0 18px 24px rgba(0, 0, 0, 0.08);
  padding: 40px 40px 34px;
  min-height: 330px;
  display: flex;
  flex-direction: column;
  /* 透明外框先佔位，hover 只換 border-color 才不會位移（同 problemArea 卡片） */
  border: 2px solid transparent;
  transition: transform 0.5s ease-in-out, border-color 0.4s ease-in-out, box-shadow 0.5s ease-in-out;
}
.seoCheck .blogArea .blogItem .Txt{
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
}
.seoCheck .blogArea .blogItem .title{
  font-size: var(--dataTitleSize);
  font-weight: 700;
  line-height: 1.5;
  color: var(--titleColor);
  min-height: 66px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.seoCheck .blogArea .blogItem .line{
  display: block;
  width: 32px;
  height: 3px;
  background: var(--mainColor);
  margin: 22px 0 26px;
}
.seoCheck .blogArea .blogItem .text{
  font-size: var(--dataTextSize);
  color: var(--textColor);
  line-height: 1.8;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.seoCheck .blogArea .blogItem .meta{
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: auto;
  padding-top: 40px;
}
.seoCheck .blogArea .blogItem .tag{
  display: inline-flex;
  align-items: center;
  padding: 4px 16px;
  border: 1px solid var(--mainColor);
  border-radius: 999px;
  color: var(--mainColor);
  font-size: 15px;
  font-weight: 500;
  transition: all 0.5s;
}
.seoCheck .blogArea .blogItem .date{
  font-size: 15px;
  color: #777;
}

@media (hover: hover) and (pointer: fine) {
  /* 主站原版：橘線由左往右刷過，箭頭圓內的橘色漸層放大；
     此處依需求額外讓文字也同步轉橘。 */
  .seoCheck .blogArea .blogNav .more:hover{
    color: var(--mainColor);
  }
  .seoCheck .blogArea .blogNav .more:hover::after{
    width: 100%;
    right: auto;
    left: 0;
  }
  .seoCheck .blogArea .blogNav .more:hover .arrow::before{
    transform: scale(1);
  }
  .seoCheck .blogArea .blogNav .counter .navBtn:hover .chevron{
    border-color: var(--mainColor);
  }
  /* hover：與 problemArea 卡片共用同一組白底＋橘框樣式 */
  .seoCheck .blogArea .blogItem .item:hover{
    transform: translateY(-8px);
    border-color: var(--mainColor);
    box-shadow: 0 22px 45px rgba(255, 80, 1, 0.18);
    /* 標籤由白底橘字反轉成橘底白字 */
  }
  .seoCheck .blogArea .blogItem .item:hover .tag{
    background: var(--mainColor);
    color: #fff;
  }
}
@media (max-width: 1180px) {
  .seoCheck .blogArea{
    padding: 90px 0 100px;
  }
  .seoCheck .blogArea .blogBox{
    grid-template-columns: 360px minmax(0, 1fr);
    gap: 50px;
  }
  .seoCheck .blogArea .blogNav{
    gap: 40px;
    margin-top: 50px;
  }
  .seoCheck .blogArea .blogNav .more{
    width: 160px;
    font-size: 15px;
  }
  .seoCheck .blogArea .blogNav .counter{
    font-size: 18px;
  }
  .seoCheck .blogArea .blogList{
    margin: 0 -15px;
  }
  .seoCheck .blogArea{
    /* 此斷點 .blogItem padding 縮為 15px，clip-path 的裁切線離卡片只剩 15px，
       陰影水平擴散要再收一點才不會被切（桌機那組是模糊 24 / 側向約 12px，這裡收到 18 / 約 9px）。
       hover 的橘色光暈同理：共用 mixin 的模糊 45（側向約 22px）在這裡會超出裁切線。 */
  }
  .seoCheck .blogArea .blogItem .item{
    box-shadow: 0 14px 18px rgba(0, 0, 0, 0.09);
  }
}
@media (max-width: 1180px) and (hover: hover) and (pointer: fine) {
  .seoCheck .blogArea .blogItem .item:hover{
    box-shadow: 0 12px 22px rgba(255, 80, 1, 0.2);
  }
}
@media (max-width: 1180px) {
  .seoCheck .blogArea .blogItem{
    padding: 0 15px;
    width: 340px;
  }
  .seoCheck .blogArea .blogItem .item{
    padding: 30px 28px 26px;
    min-height: 280px;
  }
  .seoCheck .blogArea .blogItem .title{
    font-size: var(--dataTitleSizeMedium);
    min-height: 60px;
  }
  .seoCheck .blogArea .blogItem .text{
    font-size: var(--dataTextSizeMedium);
  }
  .seoCheck .blogArea .blogItem .meta{
    padding-top: 26px;
  }
}
@media (max-width: 991px) {
  .seoCheck .blogArea .blogBox{
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
  }
  .seoCheck .blogArea{
    /* 「了解更多」與計數器要排到卡片下方，但 HTML 裡它們嵌在 .blogTxt 裡。
       給 .blogTxt 上 display: contents，把 .titleBox 與 .blogNav 提升成 .blogBox 的直接格線項目，
       就能用 order 重排——不用動 HTML，桌機版結構完全不受影響。 */
  }
  .seoCheck .blogArea .blogTxt{
    display: contents;
  }
  .seoCheck .blogArea .titleBox{
    order: 1;
    text-align: center;
  }
  .seoCheck .blogArea .blogList{
    order: 2;
    /* 桌機那條「只裁左側」的 clip-path（防止複製卡蓋到左欄標題）在這裡要拿掉：
       標題已改排在卡片上方，左邊沒有東西要遮，留著只會把第一張卡往左約 50px 的陰影切平。
       list 寬度幾乎等於視窗，左側複製卡整張在視窗外，靠 .blogArea 的 overflow: hidden 擋住就夠了。 */
  }
  .seoCheck .blogArea .blogList .slick-list{
    clip-path: none;
  }
  .seoCheck .blogArea .blogNav{
    order: 3;
    justify-content: center;
    margin-top: 24px;
  }
}
@media (max-width: 768px) {
  .seoCheck .blogArea{
    /* 手機版隱藏背景大字 BLOG（使用者 2026-09-11） */
  }
  .seoCheck .blogArea .bgWord{
    display: none;
  }
  .seoCheck .blogArea{
    /* 下方 68px = 「了解更多」底線到區塊底。沿革：56 → 80 → 60 → 48 →（使用者指定）68。
       注意 769～991 走的是 ≤991 的 padding-bottom: 100px，改這裡不會影響那段寬度 */
    padding: 60px 0 68px;
  }
  .seoCheck .blogArea .blogItem{
    /* 置中模式下左右要各露出一截鄰卡：300 → 280（含左右 15px 間距，卡片本體 250），
       390 寬視窗鄰卡各露約 40px */
    width: 280px;
  }
  .seoCheck .blogArea .blogItem .item{
    padding: 26px 22px 22px;
    min-height: 0;
  }
  .seoCheck .blogArea .blogItem{
    /* 置中模式：兩側鄰卡淡到 40%（原 65%，2026-09-11 使用者再調淡），當前卡（slick-center）維持 100%；切換時淡入淡出 */
  }
  .seoCheck .blogArea .blogItem .item{
    transition: opacity 0.4s ease;
  }
  .seoCheck .blogArea .blogItem:not(.slick-center) .item{
    opacity: 0.4;
  }
  .seoCheck .blogArea .blogItem .title{
    font-size: var(--dataTitleSizeSmall);
  }
  .seoCheck .blogArea .blogItem .text{
    font-size: var(--dataTextSizeSmall);
  }
  .seoCheck .blogArea .blogItem .line{
    margin: 14px 0 16px;
  }
  .seoCheck .blogArea{
    /* 卡片底緣 → 控制列頂緣統一 10px（以金字塔 .tipNav 為基準，2026-09-11 使用者定案）：
       .slick-list 為了陰影留了 padding-bottom 30px、.blogBox grid gap 20px，
       這裡用 -40px 收回 → 30 + 20 − 40 = 10；左右 -15px 維持 ≤1180 的設定 */
  }
  .seoCheck .blogArea .blogList{
    margin-bottom: -40px;
    /* 手機版 slick 為 centerMode（js/main.js responsive 769）：當前卡置中、左右鄰卡各露一截，
       所以桌機那條「只裁左側」的 clip-path 要拿掉；標題在卡片上方，不會被複製卡蓋到 */
  }
  .seoCheck .blogArea .blogList .slick-list{
    clip-path: none;
    /* centerMode 時 slick 會用 inline style 寫 padding: 0px <centerPadding>，把桌機的 30px 上下陰影留白蓋掉，
       上下負 margin（-16／-40）的算式就會失準、圓點列壓到卡片上；用 !important 把 30px 搶回來 */
    padding: 30px 0 !important;
  }
  .seoCheck .blogArea{
    /* 卡片＋圓點整組上移：標題區 → 卡片 50 → 34px（2026-09-11 使用者要求） */
  }
  .seoCheck .blogArea .blogList{
    margin-top: -16px;
  }
  .seoCheck .blogArea{
    /* 數字計數器換成箭頭＋圓點（與 problemArea／金字塔統一），直排：圓點在上、「了解更多」在下、皆水平置中。
       .blogDots 的按鈕點擊區本身有 44px 高，視覺上圓點到「了解更多」的距離 ≈ gap + 18px */
  }
  .seoCheck .blogArea .blogNav{
    flex-direction: column;
    align-items: center;
    /* 圓點列 → 「了解更多」：控制列 44px 高、圓點只有 7px，視覺間距 = gap + 18.5。
       gap 38 → 視覺 56.5px，與按鈕下方到區塊底的 56px 等距（2026-09-11 使用者要求上下視覺等距） */
    gap: 38px;
    margin-top: 0;
  }
  .seoCheck .blogArea .blogNav .counter{
    display: none;
  }
  .seoCheck .blogArea .blogNav .blogDots{
    display: flex;
    order: 1;
  }
  .seoCheck .blogArea .blogNav .more{
    order: 2;
  }
}
/* ==========================================================
   lensFly — 放大鏡跨區位移（bannerArea → problemArea）
   位置與縮放由 js/main.js 依捲動進度內插，這裡只定義外觀與兩個錨點座標。
   錨點是 0 尺寸的 <span>，只用來提供座標，改動落點請調整下方 .lensAnchor 的 left/top。
   ========================================================== */
/* 錨點：不佔空間、不可見 */
.seoCheck .lensAnchor{
  position: absolute;
  width: 0;
  height: 0;
  pointer-events: none;
}

/* 起點：banner 螢幕圖上，壓在 92% 圓環右下。
   用 magnifier.png 的輪廓對設計稿做 template matching，實測鏡片圓心 (1378, 534)，
   換算到現行圖框 754×591 @ (902,207)：
   left = (1378−902)/754 = 63.13%、top = (534−207)/591 = 55.33% */
.seoCheck .bannerArea .bannerImg .lensAnchor.isStart{
  left: 63.13%;
  top: 55.33%;
}

/* 終點：problemArea 標題橘卡左緣的放大鏡。
   設計稿鏡片圓心 (517, 1108)、橘卡 x 486–1458 / y 996–1245 → 圓心在卡片左緣內 31px、卡片高 52%；
   依需求（2026-09-10）整體再上移 8%（約 20px）→ 44%。
   ※ 到站後是由 .headIcon .hiLens 接手，所以這裡的 top 改了，
     .hiLens 的 top 必須同步改同樣的量，否則交接的那一禎會跳位。 */
.seoCheck .problemArea .headCard .lensAnchor.isEnd{
  left: 31px;
  top: 44%;
}

/* ≤1440 的 .hiLens 用的是另一組尺寸與 top，錨點也要跟著覆寫，兩者才會對齊 */
@media (max-width: 1440px) {
  .seoCheck .problemArea .headCard .lensAnchor.isEnd{
    top: 37%;
  }
}
.seoCheck .lensFly{
  position: fixed;
  left: 0;
  top: 0;
  /* magnifier.png 原圖 302×302，放大到 328 讓鏡片直徑 = 185（對齊設計稿） */
  width: 328px;
  height: 328px;
  /* 鏡片圓心（原圖 186,97 × 328/302）：JS 位移時會扣掉這組偏移，
     改動這裡要同步改 js/main.js 的 LENS_CX / LENS_CY */
  transform-origin: 202px 105px;
  pointer-events: none;
  z-index: 50;
  will-change: transform;
  filter: drop-shadow(0 18px 26px rgba(120, 90, 70, 0.18));
  /* 全程不淡入淡出：opacity 只有「JS 還沒寫入 transform 前」是 0，
     第一禎定位完成就固定 100%，之後不再改（也沒有 transition）。
     保留初始 0 是為了避免 fixed 元素在定位前閃現在視窗左上角。 */
  opacity: 0;
}
.seoCheck .lensFly.isVisible{
  opacity: 1;
}
.seoCheck .lensFly{
  /* 閒置時的「搜尋中」巡視。掛在 <img> 而不是 .lensFly：
     .lensFly 的 transform 由 js/main.js 每禎寫入（飛行位移），不能被動畫覆蓋。
     時間軸一定要用 linear：緩進緩出已經寫在 keyframes 的疏密裡（鐘擺參數化），
     這裡再加 ease-in-out 會變成每個關鍵影格都煞一次車，就是「停頓」的來源。
     振幅由 --lensWobble（banner 巡視）與 --lensArc（problemArea 小弧線）控制，
     兩者由 JS 依捲動進度交叉淡入淡出。 */
}
.seoCheck .lensFly img{
  display: block;
  width: 100%;
  height: auto;
  /* 原點＝鏡片圓心（202,105）。img 預設原點是圖片中心 (164,164)，
     不改的話 keyframes 裡的旋轉會把鏡片甩離設計好的路徑。 */
  transform-origin: 202px 105px;
  animation: lensSearch 12s linear infinite;
  /* 這裡**不要**再加 will-change：外層 .lensFly 已經有 will-change + drop-shadow 濾鏡，
     內層再開一個合成層會變成「有濾鏡的父層包著每禎變形的子層」，
     那是 Chrome 已知容易閃爍的組合（濾鏡得跟著子層邊界重算）。 */
}

/* 到站（飛行進度 = 1）之後的接手：
   .lensFly 是 position:fixed、位置由 JS 在 scroll 裡寫 transform 去追文件流中的錨點，
   捲動是合成器在做、JS 慢一禎，所以「到站後繼續捲」會看到上下抖動 —— 這是 fixed+JS
   追捲動的本質問題，改參數沒用。解法是到站就換成橘卡裡文件流的 .hiLens 接手，
   它跟著頁面一起被合成器捲動，完全不抖。
   兩者尺寸本來就對齊（328px × END_SCALE 0.72 = 236px = .hiLens 寬），切換看不出來。
   class 由 js/main.js 掛在 <html> 上。 */
/* 用 visibility 而不是 display:none —— js/main.js 的 lensRender() 開頭有
   「computedStyle.display === 'none' 就 return」的早退（那是給 ≤991 用的），
   如果這裡設 display:none，一旦到站就再也不會重算進度，往回捲時會卡死在 docked。 */
.seoCheck .lensDocked .lensFly{
  visibility: hidden;
}

.seoCheck .lensDocked .problemArea .headIcon .hiLens{
  display: block;
}

/* 窄螢幕：banner 改為單欄堆疊，飛行路徑會很奇怪，直接關閉 */
@media (max-width: 991px) {
  .seoCheck .lensFly{
    display: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  .seoCheck .lensFly{
    transition: none;
  }
  .seoCheck .lensFly img{
    animation: none;
  }
}
/* ==========================================================
   contactArea — 聯絡表單
   ========================================================== */
.seoCheck .contactArea{
  position: relative;
  padding: 110px 0 150px;
  overflow: hidden;
  /* 背景：設計端匯出的灰階漸層＋下緣網點（form-bg-1.5x.jpg，2880×1569 = 1920×1046 的 1.5x），
     2026-09-11 取代原本手刻的 linear-gradient。圖本身沒有橘光，
     左下角那層橘色 radial-gradient 仍疊在圖上；底色 fallback 取圖最亮處的白。 */
  background: radial-gradient(35% 45% at 0% 100%, rgba(255, 138, 61, 0.35) 0%, rgba(255, 138, 61, 0) 70%), url("../images/index/form-bg-1.5x.jpg") center/cover no-repeat, #fafafb;
}
.seoCheck .contactArea .wrap{
  position: relative;
  z-index: 1;
}
.seoCheck .contactArea{
  /* 背景橘色光暈：兩顆光團在區塊內漂移。
     軟邊緣一律交給 radial-gradient 本身的漸層，**不用 filter: blur()**（大面積模糊每張都要重算，成本高），
     動的只有 transform／opacity，能交給 GPU。.contactArea 本身已是 overflow: hidden，光團跑出去會被裁掉。 */
}
.seoCheck .contactArea .glowBox{
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.seoCheck .contactArea .glowBox .glow{
  position: absolute;
  display: block;
  border-radius: 50%;
  will-change: transform;
}
.seoCheck .contactArea .glowBox{
  /* 漫遊那顆：從右側出發，一路跑到左邊再回來，途中淡出淡入。
     外層只跑水平，內層 .core 跑垂直＋縮放＋透明度；
     三條週期 17／23／13s 互質，LCM 5,083 秒（約 85 分鐘）內路徑不會重複。 */
}
.seoCheck .contactArea .glowBox .glowRoam{
  right: -10%;
  top: 12%;
  width: clamp(300px, 38vw, 720px);
  aspect-ratio: 1;
  animation: glowRoamX 17s ease-in-out infinite;
}
.seoCheck .contactArea .glowBox .glowRoam .core{
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 132, 0, 0.2) 0%, rgba(255, 160, 80, 0.1) 45%, rgba(255, 160, 80, 0) 70%);
  will-change: transform, opacity;
  animation: glowRoamY 23s ease-in-out infinite, glowFade 13s ease-in-out infinite;
}
.seoCheck .contactArea .titleBox{
  margin-bottom: 90px;
}
.seoCheck .contactArea{
  /* 價格提示框 */
}
.seoCheck .contactArea .priceBox{
  position: relative;
  max-width: 960px;
  margin: 0 auto 30px;
  padding: 34px 60px 40px 180px;
  background: #fff;
  border-radius: var(--radiusMd);
  box-shadow: var(--cardShadow);
  text-align: center;
  /* 箭靶：靶盤（.targetBase）＋ 箭（.targetArrow）兩張疊合。
     整組仍掋 floatY 懸浮，所以箭射中後會跟靶盤一起浮。 */
}
.seoCheck .contactArea .priceBox .target{
  position: absolute;
  left: -50px;
  top: -30px;
  width: 184px;
  animation: floatY 6s ease-in-out infinite;
  /* 中靶震動專用包層（靶盤＋箭一起抖） */
}
.seoCheck .contactArea .priceBox .target .targetHit{
  display: block;
  position: relative;
}
.seoCheck .contactArea .priceBox .target .targetBase{
  display: block;
  width: 100%;
  height: auto;
}
.seoCheck .contactArea .priceBox .target{
  /* 中靶漣漪：兩圍橘環從靶心擴散淡出。
     靶盤是斜的（量測結果：長軸 52.2°、短/長軸比 0.827），
     所以漣漪不能畫正圓，keyframes 裡每一幀都先 rotate(52.2deg) scaleY(0.827) 再縮放。 */
}
.seoCheck .contactArea .priceBox .target::before,
.seoCheck .contactArea .priceBox .target::after{
  content: "";
  position: absolute;
  left: 44.6%;
  top: 55%;
  width: 96%;
  aspect-ratio: 1;
  margin: -48% 0 0 -48%;
  border: 3px solid rgba(254, 80, 0, 0.85);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  /* 兩波要疊在同一層：::before 是第一個子項、.targetHit 是 position: relative 的正常子項、
     ::after 是最後一個子項，不設 z-index 的話第一波會畫在靶盤「下面」、第二波在「上面」，
     兩波長得不一樣。統一壓在靶盤之上。 */
  z-index: 2;
}
.seoCheck .contactArea .priceBox .target{
  /* 箭的落點換算（以 figure 寬 F 為基準）：
     靶心在靶盤圖的 44.6% 寬 / 55.0% 高；箭尖在箭圖的 2.3% 寬 / 97.8% 高；
     箭寬取 66%，回推得 left = 44.6% - 2.3%×66% ≈ 43.1%、top ≈ 4.7%（已換算到 figure 高）。 */
}
.seoCheck .contactArea .priceBox .target .targetArrow{
  position: absolute;
  left: 43.1%;
  top: 4.7%;
  width: 66%;
  height: auto;
  opacity: 0;
  pointer-events: none;
}
.seoCheck .contactArea .priceBox .target{
  /* 用 keyframes 而不用 transition：
     transition 需要「先有一個已計算的起始值」才會跑，
     若 IntersectionObserver 在首次樣式計算完成前就加上 class（頁面載入時區塊已在視窗內就會），
     箭會直接瞬間出現、沒有飛行過程；animation 則一定會從 0% 跑。
     另一個好處是重新加 class 就會重新播一次，重複觸發不用額外處理。 */
  /* 箭：漸快（ease-in）＋近大遠小（1.35 → 1）。
     transform-origin 固定在箭尖（2.3% 97.8%，就是 arrow.png 內容 bbox 的左下角），
     這樣縮放才不會把落點帶歪，終點箭尖依舊在靶心。 */
}
.seoCheck .contactArea .priceBox .target .targetArrow{
  transform-origin: 2.3% 97.8%;
}
.seoCheck .contactArea .priceBox .target.isShot .targetArrow{
  animation: arrowShot 0.75s cubic-bezier(0.55, 0.05, 0.85, 0.4) forwards;
}
.seoCheck .contactArea .priceBox .target{
  /* 中靶那一瞬間（delay 跟箭的 0.75s 對齊）才發生震動與漣漪 */
}
.seoCheck .contactArea .priceBox .target.isShot .targetHit{
  animation: targetHit 0.55s ease-out 0.74s both;
}
.seoCheck .contactArea .priceBox .target{
  /* fill-mode 只能用 forwards，不能用 both：
     both 含 backwards 回填，delay 的 0.74s 會先把 0%（opacity: 0.85、scale(0.28)）套上去，
     結果箭還在飛、靶心就已經定著一個小橘環（2026-09-10 使用者回報的破綻）。
     forwards 在 delay 期間吃元素自己的 opacity: 0，時間一到才從 0% 開始跑。 */
}
.seoCheck .contactArea .priceBox .target.isShot::before{
  animation: hitRipple 2.2s 0.74s forwards;
}
.seoCheck .contactArea .priceBox .target.isShot::after{
  animation: hitRipple 2.2s 0.96s forwards;
}
.seoCheck .contactArea .priceBox .priceTitle{
  font-size: 30px;
  font-weight: 700;
  line-height: 1.4;
}
.seoCheck .contactArea .priceBox .priceText{
  font-size: var(--textSize);
  color: #666;
  /* 原 #555，內文統一 #666（使用者 2026-09-11） */
  margin-top: 10px;
}
.seoCheck .contactArea{
  /* 表單框 */
}
.seoCheck .contactArea .contactBox{
  position: relative;
  max-width: 960px;
  margin: 0 auto;
}
.seoCheck .contactArea .formBox{
  width: 100%;
  background: #fff;
  border-radius: var(--radiusMd);
  box-shadow: var(--cardShadow);
  padding: 60px 100px 50px;
}
.seoCheck .contactArea .formGrid{
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 26px 60px;
}
.seoCheck .contactArea .formGrid .full{
  grid-column: 1/-1;
}
.seoCheck .contactArea .formGrid .nameRow{
  display: flex;
  align-items: flex-end;
  gap: 40px;
}
.seoCheck .contactArea .formGrid .nameRow .formGroup{
  flex: 1 1 auto;
}
.seoCheck .contactArea .formGrid .nameRow .radioGroup{
  flex: 0 0 auto;
  padding-bottom: 12px;
}
.seoCheck .contactArea .btnBox{
  margin-top: 40px;
}
.seoCheck .contactArea .btnBox .btn{
  width: 100%;
  min-height: 48px;
  border-radius: 999px;
  font-size: 17px;
}
.seoCheck .contactArea{
  /* TOP */
}
.seoCheck .contactArea .goTop{
  position: absolute;
  right: 40px;
  bottom: 30px;
  display: block;
  padding: 0;
  border: 0;
  background: none;
  line-height: 0;
  cursor: pointer;
}
.seoCheck .contactArea .goTop img{
  display: block;
  width: 38px;
  height: 69px;
  transition: all 0.5s;
}
.seoCheck .contactArea .goTop{
  /* 手機版專用排法（≤768 才顯示） */
}
.seoCheck .contactArea .goTop .goTopMobile{
  display: none;
}

@media (max-width: 1180px) {
  .seoCheck .contactArea{
    /* 下 padding 150（原 110）：TOP 鈕是絕對定位（bottom: 30、鈕高 69），
       「表單底 → TOP 鈕頂」＝ padding-bottom − 99，原本只剩 11px 太擠（使用者 2026-09-11），
       拉到 150 讓間距回到與桌機相同的 51px。≤768 TOP 鈕改排在文流內，另有自己的上距。 */
    padding: 90px 0 150px;
  }
  .seoCheck .contactArea .titleBox{
    margin-bottom: 60px;
  }
  .seoCheck .contactArea .priceBox{
    padding: 28px 40px 32px 150px;
  }
  .seoCheck .contactArea .priceBox .target{
    width: 140px;
    left: -20px;
  }
  .seoCheck .contactArea .priceBox .priceTitle{
    font-size: 24px;
  }
  .seoCheck .contactArea .priceBox .priceText{
    font-size: var(--textSizeMedium);
  }
  .seoCheck .contactArea .formBox{
    padding: 44px 50px 40px;
  }
}
@media (max-width: 768px) {
  .seoCheck .contactArea{
    /* 下 padding 縮到 50px：TOP 鈕改為文流內置中，自己帶 40px 上距（見下方 .goTop） */
    padding: 60px 0 50px;
    /* 箭靶在手機版是 top:-62px 疊在 priceBox 上方。
       原 100px（標題與箭靶之間 38px），使用者要求再拉遠 → 140px（約 78px） */
  }
  .seoCheck .contactArea .titleBox{
    margin-bottom: 140px;
  }
  .seoCheck .contactArea{
    /* 使用者要求手機版這段標題大一點（2026-09-11）：≤480 全站 .titleBox .title 會降到 24px，
       這裡選擇器較具體（0,3,0 > 0,2,0），contactArea 維持 30px 不跟著降 */
  }
  .seoCheck .contactArea .titleBox .title{
    font-size: 30px;
    /* 手機版折成兩行，全站 1.2 太擠（使用者 2026-09-11），放寬到 1.5 */
    line-height: 1.5;
  }
  .seoCheck .contactArea .priceBox{
    padding: 105px 24px 28px;
  }
  .seoCheck .contactArea .priceBox .target{
    left: 50%;
    top: -62px;
    width: 135px;
    transform: translateX(-50%);
    animation: none;
  }
  .seoCheck .contactArea .priceBox .priceTitle{
    font-size: 20px;
  }
  .seoCheck .contactArea .priceBox .priceText{
    font-size: var(--textSizeSmall);
  }
  .seoCheck .contactArea .formBox{
    padding: 30px 22px 28px;
    /* 手機版圓角統一 30px，與 .priceBox 相同（使用者 2026-09-11） */
    border-radius: var(--radiusMd);
  }
  .seoCheck .contactArea{
    /* ---- 手機版表單：字級／間距照主站 https://www.ixpert.com.tw/contact/ 的 contact.css（≤550）一模一樣 ----
       主站是 ul.formList > li（每列 padding-bottom 30）＋浮動標籤（label absolute，聚焦或有值時縮小上移）。
       本頁 HTML 結構不同（.formGrid > .formGroup），所以用同樣的數值對應過去：
       列距用 .formGroup 的 padding-bottom 給；浮動標籤用 :has(input:focus / :not(:placeholder-shown))
       取代主站 JS 加的 li.focus（input 都補了 placeholder=" " 才能用 :placeholder-shown）。
       桌機版完全不受影響（只在 ≤768 覆寫）。 */
  }
  .seoCheck .contactArea .formGrid{
    grid-template-columns: 1fr;
    gap: 0;
    padding-bottom: 20px;
    /* 主站 .formList padding-bottom */
    font-size: 16px;
    letter-spacing: 0.05em;
    color: #444;
  }
  .seoCheck .contactArea .formGrid .formGroup{
    padding-bottom: 30px;
    /* 主站 li padding-bottom → 列距 30 */
  }
  .seoCheck .contactArea .formGrid .formGroup label{
    position: absolute;
    left: 0;
    top: 3px;
    margin: 0;
    font-size: 16px;
    line-height: 1.5;
    color: #444;
    letter-spacing: 0.05em;
    pointer-events: none;
    transition: 0.4s;
  }
  .seoCheck .contactArea .formGrid .formGroup label .required{
    font-weight: 400;
    color: #fe5000;
    margin-left: 0;
  }
  .seoCheck .contactArea .formGrid .formGroup{
    /* 主站 li.focus .title */
  }
  .seoCheck .contactArea .formGrid .formGroup:has(input:focus, textarea:focus, input:not(:placeholder-shown), textarea:not(:placeholder-shown)) label{
    font-size: 12px;
    transform: translateY(-12px);
  }
  .seoCheck .contactArea .formGrid .formGroup input[type=text],
.seoCheck .contactArea .formGrid .formGroup input[type=tel],
.seoCheck .contactArea .formGrid .formGroup input[type=email],
.seoCheck .contactArea .formGrid .formGroup input[type=url],
.seoCheck .contactArea .formGrid .formGroup textarea{
    height: 40px;
    padding: 0;
    font-size: 16px;
    font-weight: 300;
    line-height: normal;
    color: #333;
    border-bottom-color: #dbdada;
    transition: 0.5s;
  }
  .seoCheck .contactArea .formGrid .formGroup input[type=text]:focus,
.seoCheck .contactArea .formGrid .formGroup input[type=tel]:focus,
.seoCheck .contactArea .formGrid .formGroup input[type=email]:focus,
.seoCheck .contactArea .formGrid .formGroup input[type=url]:focus,
.seoCheck .contactArea .formGrid .formGroup textarea:focus{
    border-bottom-color: #fe5000;
  }
  .seoCheck .contactArea .formGrid .formGroup textarea{
    display: block;
    margin-top: 12px;
    height: 100px;
    min-height: 0;
    padding: 8px 0;
  }
  .seoCheck .contactArea .formGrid{
    /* 主站 li.nameRow（≤550）：直排、gap 12，列距由 nameRow 自己給 */
  }
  .seoCheck .contactArea .formGrid .nameRow{
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
    padding-bottom: 30px;
  }
  .seoCheck .contactArea .formGrid .nameRow .formGroup{
    padding-bottom: 0;
  }
  .seoCheck .contactArea .formGrid .nameRow{
    /* 主站 .sexBox */
  }
  .seoCheck .contactArea .formGrid .nameRow .radioGroup{
    gap: 20px;
    padding-bottom: 0;
    white-space: nowrap;
  }
  .seoCheck .contactArea .formGrid .nameRow .radioGroup label{
    gap: 6px;
    font-size: 15px;
    line-height: 22px;
    color: #444;
  }
  .seoCheck .contactArea{
    /* 主站 .btnBox（margin-top 20）＋ .btnBox.single .btn（≤480 滿版）＋ .btn 基礎值 */
  }
  .seoCheck .contactArea .btnBox{
    margin-top: 20px;
  }
  .seoCheck .contactArea .btnBox .btn{
    min-height: 0;
    padding: 13px;
    border-radius: 30px;
    font-size: 15px;
    font-weight: 500;
    line-height: 1.4;
  }
  .seoCheck .contactArea{
    /* TOP 鈕：手機版不再釘在右下角，改排在表單下方水平置中，上下各留間距 */
  }
  .seoCheck .contactArea .goTop{
    /* 用 relative 而非 static：要壓在 .glowBox（absolute, z-index 0）上面，需要自己有層級 */
    position: relative;
    right: auto;
    bottom: auto;
    z-index: 1;
    width: fit-content;
    margin: 50px auto 0;
    line-height: 1;
    /* 桌機那張直式 top.svg 收掉，換成「小箭頭在上、橫式 TOP 在下」 */
  }
  .seoCheck .contactArea .goTop img{
    display: none;
  }
  .seoCheck .contactArea .goTop .goTopMobile{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
  }
  .seoCheck .contactArea .goTop .goTopMobile .arrow{
    display: block;
    width: 14px;
    height: 28px;
  }
  .seoCheck .contactArea .goTop .goTopMobile .txt{
    font-family: var(--secondFont);
    font-size: 18px;
    font-weight: 500;
    letter-spacing: 0.12em;
    color: var(--mainColor);
  }
}
/* ==========================================================
   手機版圓角統一（使用者 2026-09-11）
   以 contactArea .priceBox 的 30px（var(--radiusMd)）為基準，
   下列卡片在 ≤768 一律同值；桌機維持各自原本的圓角。
   （.contactArea .formBox 已直接在自己的 ≤768 區塊改成 radiusMd）
   ========================================================== */
@media (max-width: 768px) {
  .seoCheck .problemArea .headCard,
.seoCheck .problemArea .problemItem .item,
.seoCheck .conceptArea .conceptImg .tip .tipCard{
    border-radius: var(--radiusMd);
  }
}
/* ==========================================================
   scanArea — 檢測中 loading（2026-09-11）
   Banner「免費檢測網站」按下後的滿版白幕儀表板，流程由 js/main.js initScanLoading() 驅動：
   進度 0 → 100 更新 .scanPct 數字、.scanRing .bar 的 dashoffset、步驟打勾；100% 彈出「檢測完成」再跳轉。
   ========================================================== */
.seoCheck .scanArea{
  position: fixed;
  inset: 0;
  contain: layout paint; /* 把重繪限制在這一層，不牽動底下的頁面（2026-09-14 修卡頓） */
  z-index: 99998; /* 低於開場 loading（99999）、高於其他所有東西 */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: radial-gradient(60% 50% at 80% 20%, rgba(255, 138, 61, 0.14) 0%, rgba(255, 138, 61, 0) 70%), radial-gradient(50% 40% at 15% 90%, rgba(255, 138, 61, 0.12) 0%, rgba(255, 138, 61, 0) 70%), #f7f7f9;
  opacity: 0;
  transition: opacity 0.35s ease;
}
.seoCheck .scanArea.isShow{
  opacity: 1;
}
.seoCheck .scanArea[hidden]{
  display: none;
}
.seoCheck .scanArea{
  /* 版面：圓環在左、檢測資訊在右（2026-09-14 使用者指定）；≤991 改回上下堆疊置中 */
}
.seoCheck .scanArea .scanBox{
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 110px; /* 原 64，使用者 2026-09-14 要求拉開 */
  animation: scanIn 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.seoCheck .scanArea .scanDial{
  flex: 0 0 auto;
}
.seoCheck .scanArea .scanInfo{
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.seoCheck .scanArea{
  /* ---- 儀表板 ---- */
}
.seoCheck .scanArea .scanDial{
  --dial: 400px; /* 原 320，使用者 2026-09-11 要求整體放大 */
  position: relative;
  width: var(--dial);
  height: var(--dial);
}
.seoCheck .scanArea .scanRing{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.seoCheck .scanArea{
  /* 外圈 HUD（2026-09-11 取代刻度環）：inspect-loading-1／2.svg 兩張輪流出現、整組順時針旋轉。
     兩張 SVG 的圓心都不在 viewBox 中心：svg1 (267.6, 269.7)／svg2 (231.4, 305.3)，
     所以 .scanHud 是 0×0 釘在儀表圓心，兩張圖各自用「−圓心 × 縮放」把圓心對到那個點，transform-origin 同樣對到圓心。
     --hudS 0.85（儀表 400 時）：兩張外圍範圍都約 270 單位 → 230px，橘弧落在進度弧（r 160px）外側 175～205px。
     兩張的切換由 js 在進度 70% 時加 .isAlt 觸發（使用者 2026-09-11），不再自動循環。 */
}
.seoCheck .scanArea .scanHud{
  --hudS: 0.85;
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  animation: scanSweep 16s linear infinite;
  pointer-events: none;
}
.seoCheck .scanArea .hudImg{
  position: absolute;
  display: block;
  max-width: none; /* 全站 img { max-width: 100% } 會因父層 .scanHud 是 0 寬而把圖壓成 0 */
  height: auto;
  transition: opacity 1.2s ease-in-out, transform 1.2s ease-in-out;
}
.seoCheck .scanArea .hudImg.a{
  width: calc(500px * var(--hudS));
  left: calc(-267.6px * var(--hudS));
  top: calc(-269.7px * var(--hudS));
  transform-origin: calc(267.6px * var(--hudS)) calc(269.7px * var(--hudS));
}
.seoCheck .scanArea .hudImg.b{
  width: calc(538px * var(--hudS));
  left: calc(-231.4px * var(--hudS));
  top: calc(-305.3px * var(--hudS));
  transform-origin: calc(231.4px * var(--hudS)) calc(305.3px * var(--hudS));
  opacity: 0;
  transform: scale(0.94);
}
.seoCheck .scanArea{
  /* 70% 時：第一款淡出微放大、第二款淡入回到原尺寸，旋轉持續不中斷 */
}
.seoCheck .scanArea .scanHud.isAlt .hudImg.a{
  opacity: 0;
  transform: scale(1.06);
}
.seoCheck .scanArea .scanHud.isAlt .hudImg.b{
  opacity: 1;
  transform: scale(1);
}
.seoCheck .scanArea{
  /* 進度弧：r 128 → 周長 804.25；stroke-dashoffset 由 JS 從 804.25 收到 0 */
}
.seoCheck .scanArea .scanRing{
  transform: rotate(-90deg);
}
.seoCheck .scanArea .scanRing .track{
  fill: none;
  stroke: #ececf0;
  stroke-width: 10;
}
.seoCheck .scanArea .scanRing .bar{
  fill: none;
  /* 左到右漸層（#FFEEE6 → #FF8400 → 尾端 #FE5000），定義在 index.html 的 .scanRing <defs> 內。
     必須寫在 CSS：CSS 的 stroke 會蓋掉 SVG 的 presentation attribute */
  stroke: url(#scanBarGrad);
  stroke-width: 10;
  stroke-linecap: round;
  stroke-dasharray: 804.25;
  stroke-dashoffset: 804.25;
  filter: drop-shadow(0 0 6px rgba(255, 80, 1, 0.45));
}
.seoCheck .scanArea{
  /* 雷達扇形：conic 漸層轉圈，mask 成只剩進度弧那圈的環帶 */
}
.seoCheck .scanArea .scanSweep{
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 0deg, rgba(255, 80, 1, 0) 0deg, rgba(255, 80, 1, 0.28) 60deg, rgba(255, 80, 1, 0) 62deg);
  -webkit-mask: radial-gradient(circle, transparent 140px, #000 141px, #000 185px, transparent 186px);
  mask: radial-gradient(circle, transparent 140px, #000 141px, #000 185px, transparent 186px);
  animation: scanSweep 1.6s linear infinite;
  pointer-events: none;
}
.seoCheck .scanArea{
  /* 完成漣漪：三圈與核心圓同尺寸的橘色細框，.isDone 時依序放大淡出（使用者 2026-09-11） */
}
.seoCheck .scanArea .scanRipple{
  position: absolute;
  left: 50%;
  top: 50%;
  width: 280px;
  height: 280px;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.seoCheck .scanArea .scanRipple i{
  position: absolute;
  inset: 0;
  border: 2.5px solid var(--mainColor);
  border-radius: 50%;
  opacity: 0;
  transform: scale(1);
}
.seoCheck .scanArea.isDone .scanRipple i{
  animation: scanRipple 1.4s ease-out infinite;
}
.seoCheck .scanArea.isDone .scanRipple i:nth-child(2){
  animation-delay: 0.35s;
}
.seoCheck .scanArea.isDone .scanRipple i:nth-child(3){
  animation-delay: 0.7s;
}
.seoCheck .scanArea{
  /* 白色核心圓 */
}
.seoCheck .scanArea .scanCore{
  position: absolute;
  left: 50%;
  top: 50%;
  width: 280px;
  height: 280px;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.08), inset 0 0 0 1px rgba(0, 0, 0, 0.03);
  overflow: hidden;
  text-align: center;
}
.seoCheck .scanArea{
  /* 橫向掃描光束 */
}
.seoCheck .scanArea .scanBeam{
  position: absolute;
  left: 12%;
  right: 12%;
  top: 8%;
  height: 2px;
  background: linear-gradient(90deg, rgba(255, 80, 1, 0) 0%, var(--mainColor) 50%, rgba(255, 80, 1, 0) 100%);
  box-shadow: 0 0 14px 3px rgba(255, 80, 1, 0.35);
  opacity: 0;
  animation: scanBeam 1.9s ease-in-out infinite;
  pointer-events: none;
}
.seoCheck .scanArea .scanPct{
  display: flex;
  align-items: baseline;
  gap: 4px;
  margin: 0;
  line-height: 1;
  color: var(--mainColor);
}
.seoCheck .scanArea .scanPct b{
  font-size: 72px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.seoCheck .scanArea .scanPct i{
  font-size: 26px;
  font-weight: 700;
  font-style: normal;
}
.seoCheck .scanArea .scanText{
  margin: 0;
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--lineColor);
  min-width: 60%; /* 分隔線至少這麼寬 */
  max-width: 84%;
  font-size: 14px;
  line-height: 1.6;
  color: #666;
  white-space: nowrap; /* 一律一行（文案已精簡到 10 字內，使用者 2026-09-11） */
}
.seoCheck .scanArea{
  /* 「檢測中...」：灰字下方的橘色提示，三個點上下跳動（使用者 2026-09-11） */
}
.seoCheck .scanArea .scanState{
  margin: 4px 0 0;
  font-size: 20px; /* 16 → 20（使用者 2026-09-11 要求再大一點） */
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--mainColor);
  transition: opacity 0.3s ease;
}
.seoCheck .scanArea .scanState .dots i{
  display: inline-block;
  font-style: normal;
  animation: scanDotBounce 0.9s ease-in-out infinite;
}
.seoCheck .scanArea .scanState .dots i:nth-child(2){
  animation-delay: 0.15s;
}
.seoCheck .scanArea .scanState .dots i:nth-child(3){
  animation-delay: 0.3s;
}
.seoCheck .scanArea.isDone .scanState{
  opacity: 0;
}
.seoCheck .scanArea{
  /* 完成膠囊：疊在核心圓下緣（比照設計稿「良好」膠囊） */
}
.seoCheck .scanArea .scanDone{
  position: absolute;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%) scale(0.4);
  padding: 10px 34px;
  border: 2px solid var(--mainColor);
  border-radius: 999px;
  background: #fff; /* 使用者 2026-09-11：白底橘字橘框（原橘漸層底白字） */
  color: var(--mainColor);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.05em;
  white-space: nowrap;
  box-shadow: 0 12px 30px rgba(255, 80, 1, 0.18);
  opacity: 0;
  z-index: 1;
}
.seoCheck .scanArea.isDone .scanDone{
  transform-origin: 50% 100%; /* 以底部為軸擠壓，像果凍落地 */
  animation: scanPop 1.5s ease-out both;
}
.seoCheck .scanArea{
  /* ---- 完成後的過場（使用者 2026-09-11）：其他物件模糊淡出，只留白色核心圓，核心圓放大成滿版白底再跳轉 ----
     --coreScale 由 JS 依視窗對角線算出（保證蓋滿整個畫面）。 */
  /* 離場時整個內容區當成一層淡出（見 .isLeaving 說明） */
}
.seoCheck .scanArea .scanBox{
  transition: opacity 0.4s ease, filter 0.4s ease, transform 0.4s ease;
}
.seoCheck .scanArea{
  /* ---- 離場過場的三層圓形（2026-09-14 使用者指定）----
     固定在視窗中心、z-index 0 壓在所有內容之下（避免看起來像圓蓋在文字上）；
     .isLeaving 後依序從 scale(0) 展開：白圓（0.15s 起）→ 白圓約 45% 時橘圓接力（0.55s）
     → 橘圓約 30% 時第二顆白圓接力（0.82s）→ 整層淡出。
     --wipeScale 由 JS 依視窗對角線算出（基準直徑 200px）。 */
}
.seoCheck .scanArea .scanWipe{
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.seoCheck .scanArea .scanWipe span{
  position: absolute;
  left: 50%;
  top: 50%;
  width: 200px;
  height: 200px;
  margin: -100px 0 0 -100px;
  border-radius: 50%;
  /* translateZ(0) 強制獨立合成層，放大 9～12 倍時走 GPU 合成而不是重繪（2026-09-14 修卡頓） */
  transform: translateZ(0) scale(0);
  transition: transform 0.9s cubic-bezier(0.65, 0, 0.35, 1);
  will-change: transform;
}
.seoCheck .scanArea .scanWipe .w1,
.seoCheck .scanArea .scanWipe .w3{
  background: #fff;
}
.seoCheck .scanArea .scanWipe{
  /* 純色而非漸層：放大時漸層材質要重新繪製，純色可直接由合成器縮放（2026-09-14 修卡頓） */
}
.seoCheck .scanArea .scanWipe .w2{
  background: var(--mainColor);
}
.seoCheck .scanArea .scanWipe .w1{
  transition-delay: 0.15s;
}
.seoCheck .scanArea .scanWipe{
  /* ＝ 白圓跑到約 45% 的時間點 */
}
.seoCheck .scanArea .scanWipe .w2{
  transition-delay: 0.55s;
}
.seoCheck .scanArea .scanWipe{
  /* ＝ 橘圓跑到約 30% 的時間點 */
}
.seoCheck .scanArea .scanWipe .w3{
  transition-delay: 0.82s;
}
.seoCheck .scanArea{
  /* 內容永遠在圓之上 */
}
.seoCheck .scanArea .scanBox{
  position: relative;
  z-index: 1;
}
.seoCheck .scanArea{
  /* 註：曾經在跳轉當下把整層淡出（.isFading）＋ 隱藏 body 內容（.isScanLeaving），
     但那會在導航的那一幀對整個首頁做 style recalc + layout + repaint，造成明顯卡頓（2026-09-14 實測）。
     現在改成白圓蓋滿後整層維持不透明，直到瀏覽器換頁為止——底下本來就看不到，不需要動它。 */
}
.seoCheck .scanArea.isLeaving{
  /* 模糊淡出只掛在 .scanBox 這一個圖層（2026-09-14 修卡頓）：
     原本同時對 8 個大元素跑 filter: blur()，blur 每一幀都要重繪整個圖層，
     多圖層一起跑就掉幀。改成整個內容區當一層處理，子元素只負責把動畫停下來。 */
}
.seoCheck .scanArea.isLeaving .scanBox{
  /* 進場動畫 scanIn 帶 fill-mode: both，會壓過這裡的 opacity，必須先關掉動畫（同膠囊那個坑） */
  animation: none;
  opacity: 0;
  filter: blur(6px);
  transform: scale(0.985);
}
.seoCheck .scanArea.isLeaving{
  /* 停掉還在跑的動畫，免得淡出期間仍在耗繪製資源 */
}
.seoCheck .scanArea.isLeaving .scanHud,
.seoCheck .scanArea.isLeaving .scanRing,
.seoCheck .scanArea.isLeaving .scanSweep,
.seoCheck .scanArea.isLeaving .scanRipple,
.seoCheck .scanArea.isLeaving .scanStep .stepIcon,
.seoCheck .scanArea.isLeaving .scanStep svg *{
  animation-play-state: paused;
}
.seoCheck .scanArea.isLeaving{
  /* 這兩個的 opacity 由 keyframes 的 fill-mode 撐著，暫停動畫蓋不掉，直接關掉 */
}
.seoCheck .scanArea.isLeaving .scanDone,
.seoCheck .scanArea.isLeaving .scanCore .scanBeam{
  animation: none;
}
.seoCheck .scanArea.isLeaving .scanWipe span{
  transform: translateZ(0) scale(var(--wipeScale, 12));
}
.seoCheck .scanArea{
  /* ---- 檢測步驟（垂直排列；未檢測灰字、進行中橘圖示＋專屬小動畫、完成橘底白勾） ---- */
}
.seoCheck .scanArea .scanSteps{
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  margin: 24px 0 0; /* 左右兩欄後只需與「檢測網址」那行留間距 */
  padding: 0;
  list-style: none;
}
.seoCheck .scanArea .scanStep{
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 15px;
  color: #b0b0b5; /* 未檢測：灰字 */
  transition: color 0.3s ease;
  /* 圖示圓底 */
}
.seoCheck .scanArea .scanStep .stepIcon{
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: #ededf0;
  color: #b0b0b5;
  transition: background-color 0.3s ease, color 0.3s ease;
}
.seoCheck .scanArea .scanStep .stepIcon svg{
  width: 20px;
  height: 20px;
  overflow: visible;
}
.seoCheck .scanArea .scanStep{
  /* 完成打勾：與圖示同位置，預設縮成 0 */
}
.seoCheck .scanArea .scanStep .stepCheck{
  position: absolute;
  left: 0;
  top: 50%;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--mainColor);
  transform: translateY(-50%) scale(0);
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
.seoCheck .scanArea .scanStep .stepCheck::after{
  content: "";
  position: absolute;
  left: 10px;
  top: 9px;
  width: 9px;
  height: 5px;
  border-left: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(-45deg);
}
.seoCheck .scanArea .scanStep{
  /* 進行中：黑字、橘色圖示、圓底淡橘＋呼吸光圈，並播該階段的小動畫 */
}
.seoCheck .scanArea .scanStep.isActive{
  color: #000;
}
.seoCheck .scanArea .scanStep.isActive .stepIcon{
  background: rgba(255, 80, 1, 0.1);
  color: var(--mainColor);
  animation: scanDot 1.2s ease-in-out infinite;
}
.seoCheck .scanArea .scanStep.isActive{
  /* ① 節點樹：連線畫出、三顆節點依序亮 */
}
.seoCheck .scanArea .scanStep.isActive .icoTree .l1{
  stroke-dasharray: 16;
  stroke-dashoffset: 16;
  animation: stepDraw 1.6s ease-in-out infinite;
}
.seoCheck .scanArea .scanStep.isActive .icoTree .n1,
.seoCheck .scanArea .scanStep.isActive .icoTree .n2,
.seoCheck .scanArea .scanStep.isActive .icoTree .n3{
  transform-origin: center;
  transform-box: fill-box;
  animation: stepNode 1.6s ease-in-out infinite;
}
.seoCheck .scanArea .scanStep.isActive .icoTree .n2{
  animation-delay: 0.35s;
}
.seoCheck .scanArea .scanStep.isActive .icoTree .n3{
  animation-delay: 0.6s;
}
.seoCheck .scanArea .scanStep.isActive{
  /* ② 文件：三條線由左往右長出 */
}
.seoCheck .scanArea .scanStep.isActive .icoDoc .t1,
.seoCheck .scanArea .scanStep.isActive .icoDoc .t2,
.seoCheck .scanArea .scanStep.isActive .icoDoc .t3{
  transform-origin: left center;
  transform-box: fill-box;
  animation: stepLine 1.5s ease-in-out infinite;
}
.seoCheck .scanArea .scanStep.isActive .icoDoc .t2{
  animation-delay: 0.2s;
}
.seoCheck .scanArea .scanStep.isActive .icoDoc .t3{
  animation-delay: 0.4s;
}
.seoCheck .scanArea .scanStep.isActive{
  /* ③ 放大鏡在文字列上左右掃 */
}
.seoCheck .scanArea .scanStep.isActive .icoScan .lens{
  animation: stepScan 1.4s ease-in-out infinite alternate;
}
.seoCheck .scanArea .scanStep.isActive .icoScan .r1,
.seoCheck .scanArea .scanStep.isActive .icoScan .r2,
.seoCheck .scanArea .scanStep.isActive .icoScan .r3{
  animation: stepLineDim 1.4s ease-in-out infinite alternate;
}
.seoCheck .scanArea .scanStep.isActive{
  /* ④ 燈泡亮起、光芒閃爍 */
}
.seoCheck .scanArea .scanStep.isActive .icoBulb .bulb{
  animation: stepBulb 1.4s ease-in-out infinite;
}
.seoCheck .scanArea .scanStep.isActive .icoBulb .ray{
  transform-origin: center;
  transform-box: fill-box;
  animation: stepRay 1.4s ease-in-out infinite;
}
.seoCheck .scanArea .scanStep.isActive .icoBulb .y2{
  animation-delay: 0.15s;
}
.seoCheck .scanArea .scanStep.isActive .icoBulb .y3{
  animation-delay: 0.3s;
}
.seoCheck .scanArea .scanStep{
  /* 完成：黑字、圖示縮掉換成橘底白勾 */
}
.seoCheck .scanArea .scanStep.isOn{
  color: #000;
}
.seoCheck .scanArea .scanStep.isOn .stepIcon{
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.seoCheck .scanArea .scanStep.isOn .stepCheck{
  transform: translateY(-50%) scale(1);
}
.seoCheck .scanArea{
  /* 右欄第一行：檢測網址 */
}
.seoCheck .scanArea .scanUrl{
  margin: 0;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--lineColor);
  width: 100%;
  min-width: 280px;
  max-width: min(420px, 86vw);
  font-size: 14px;
  color: #999;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.seoCheck .scanArea .scanUrl .urlLabel{
  display: inline-flex;
  align-items: center;
  color: #000;
  font-weight: 500;
  /* 原本是全形冒號，改成淺灰垂直分隔線（使用者 2026-09-14） */
}
.seoCheck .scanArea .scanUrl .urlLabel::after{
  content: "";
  width: 1px;
  height: 14px;
  margin: 0 10px;
  background: #d8d8dd;
}
.seoCheck .scanArea .scanUrl{
  /* 網址本身改橘色（使用者 2026-09-14，原 #999 灰） */
}
.seoCheck .scanArea .scanUrl .urlText{
  color: var(--mainColor);
}
.seoCheck .scanArea .scanUrl[hidden]{
  display: none;
}

/* ≤1180：版心變窄，兩欄間距收一點 */
@media (max-width: 1180px) {
  .seoCheck .scanArea .scanBox{
    gap: 80px;
  }
}
/* ≤991：左右兩欄放不下，改回上下堆疊置中 */
@media (max-width: 991px) {
  .seoCheck .scanArea .scanBox{
    flex-direction: column;
    gap: 40px;
  }
  .seoCheck .scanArea .scanInfo{
    align-items: center;
  }
  .seoCheck .scanArea .scanUrl{
    text-align: center;
  }
}
@media (max-width: 768px) {
  .seoCheck .scanArea .scanDial{
    --dial: 300px;
  }
  .seoCheck .scanArea .scanHud{
    --hudS: 0.6375; /* 0.85 × 300/400 */
  }
  .seoCheck .scanArea .scanSweep{
    -webkit-mask: radial-gradient(circle, transparent 105px, #000 106px, #000 139px, transparent 140px);
    mask: radial-gradient(circle, transparent 105px, #000 106px, #000 139px, transparent 140px);
  }
  .seoCheck .scanArea .scanCore,
.seoCheck .scanArea .scanRipple{
    width: 210px;
    height: 210px;
  }
  .seoCheck .scanArea .scanPct b{
    font-size: 56px;
  }
  .seoCheck .scanArea .scanPct i{
    font-size: 21px;
  }
  .seoCheck .scanArea .scanText{
    font-size: 13px;
  }
  .seoCheck .scanArea .scanState{
    font-size: 18px;
  }
  .seoCheck .scanArea .scanDone{
    bottom: 20px;
    padding: 8px 26px;
    font-size: 17px;
  }
  .seoCheck .scanArea .scanSteps{
    gap: 12px;
    margin-top: 22px;
  }
  .seoCheck .scanArea .scanUrl{
    min-width: 0;
    padding-bottom: 14px;
    font-size: 13px;
  }
  .seoCheck .scanArea .scanStep{
    font-size: 14px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .seoCheck .scanArea .scanSweep,
.seoCheck .scanArea .scanBeam,
.seoCheck .scanArea .scanBox,
.seoCheck .scanArea .scanHud,
.seoCheck .scanArea .hudImg,
.seoCheck .scanArea .scanStep.isActive .stepIcon,
.seoCheck .scanArea .scanStep.isActive svg *,
.seoCheck .scanArea .scanState .dots i,
.seoCheck .scanArea .scanRipple i{
    animation: none;
  }
}

/* ==========================================================
   安全驗證的方塊（js/turnstile.js 插進來的）。平常看不見也不佔位置，
   需要訪客點一下時才出現（那時候 JS 會加上 .isVisible）。
   橫幅的檢測表單：在表單下面、靠左（那一區本來就是靠左排）。
   聯絡表單：在送出按鈕上面、置中。
   ========================================================== */
.seoCheck .seoTurnstile.isVisible{
  margin-top: 12px;
}

.seoCheck .contactArea .contactForm .seoTurnstile.isVisible{
  display: flex;
  justify-content: center;
  margin: 18px 0 0;
}

.seoCheck .contactArea .contactForm .submitLoading{
  color: var(--textColor);
  font-size: 16px;
}

/* ==========================================================
   檢測表單送不出去時的紅字
   放在 .checkForm 外面：那個 flex 不換行，塞進去會被擠成一欄。
   ========================================================== */
.seoCheck .bannerArea .checkFormError{
  margin-top: 14px;
  color: var(--dangerColor);
  font-size: 15px;
  line-height: 1.6;
}

@media (max-width: 768px) {
  .seoCheck .bannerArea .checkFormError{
    font-size: 14px;
    text-align: center;
  }
}

/* ==========================================================
   聯絡表單送不出去時的紅字
   設計稿沒有這一塊。放在送出按鈕下面。
   ========================================================== */
.seoCheck .contactArea .contactForm .contactFormError{
  margin-top: 14px;
  color: var(--dangerColor);
  font-size: 15px;
  line-height: 1.6;
  text-align: center;
  white-space: pre-line;
}

@media (max-width: 768px) {
  .seoCheck .contactArea .contactForm .contactFormError{
    font-size: 14px;
  }
}



body.disableScroll { overflow: hidden; }
