/* ══════════════════════════════════════════════════════════════════
   Odysec 服務介面 — 與 odysec.org 同一套設計語言
   等寬用於 UI／標題／程式碼，內文用無襯線（CJK 等寬多數系統沒有，
   退回後字寬參差，反而難讀）。

   動態效果全部是 CSS，且「預設狀態＝最終狀態」：
   進場用 @starting-style + transition，瀏覽器不支援時內容照樣可見。
   ══════════════════════════════════════════════════════════════════ */
:root{
  --bg:#07090a; --bg-2:#0c1113; --panel:#0e1417;
  --line:#1b2429; --line-2:#26333a;
  --fg:#dde5e9; --dim:#8b9aa4; --faint:#5a6a74;
  --accent:#4ec9a0; --accent-dim:#2a7f66; --accent-2:#57b8d8;
  --crit:#e0685c; --high:#e08a5a; --med:#d9b04a; --low:#8fbf6a; --info:#7d8a94;
  --ring:rgba(78,201,160,.14);
  --shadow:0 22px 60px -34px rgba(0,0,0,.95);
  --mono:"JetBrains Mono","IBM Plex Mono","SF Mono","Cascadia Mono",Consolas,
         "DejaVu Sans Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --sans:"Noto Sans TC","PingFang TC","Microsoft JhengHei","Hiragino Sans",
         system-ui,-apple-system,sans-serif;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;
  scrollbar-color:var(--line-2) var(--bg);scrollbar-width:thin}
body{
  margin:0;background:var(--bg);color:var(--fg);
  font-family:var(--sans);font-size:15px;line-height:1.9;
  -webkit-font-smoothing:antialiased;
  background-image:
    linear-gradient(var(--line) 1px,transparent 1px),
    linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:64px 64px;background-position:-1px -1px;
}
body::before{content:"";position:fixed;inset:0;pointer-events:none;z-index:0;
  background:
    radial-gradient(ellipse 56% 36% at 24% 0%,rgba(78,201,160,.07),transparent 62%),
    radial-gradient(ellipse 120% 62% at 50% 0%,transparent 0%,var(--bg) 70%)}
body::after{content:"";position:fixed;inset:0;pointer-events:none;z-index:0;opacity:.032;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E")}
.wrap{position:relative;z-index:1;max-width:820px;margin:0 auto;padding:0 24px}
.wrap.narrow{max-width:660px}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:3px}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:3px}
::selection{background:rgba(78,201,160,.26);color:#fff}
strong{color:var(--fg);font-weight:600}
code{font-family:var(--mono);font-size:.88em;background:var(--bg-2);
  border:1px solid var(--line);padding:1px 6px;border-radius:3px;color:var(--fg)}
pre{position:relative;font-family:var(--mono);font-size:12.5px;line-height:1.9;
  background:#050708;border:1px solid var(--line);border-radius:5px;
  padding:16px 18px;overflow-x:auto;margin:12px 0;color:var(--dim);
  box-shadow:var(--shadow)}
.mono{font-family:var(--mono)}

/* ── 頂列 ── */
header{position:sticky;top:0;z-index:20;background:rgba(7,9,10,.86);
  backdrop-filter:blur(12px) saturate(140%);border-bottom:1px solid var(--line)}
.bar{display:flex;align-items:center;justify-content:space-between;min-height:60px;
  gap:18px;max-width:820px;margin:0 auto;padding:0 24px;flex-wrap:wrap}
.brand{font-family:var(--mono);font-weight:700;font-size:15px;letter-spacing:.06em;
  color:var(--fg);display:flex;align-items:center}
.brand:hover{text-decoration:none}
.brand .mk{width:15px;height:15px;border:1.5px solid var(--accent);margin-right:9px;
  position:relative;flex:0 0 auto;transition:box-shadow .25s}
.brand .mk::after{content:"";position:absolute;inset:4px;background:var(--accent)}
.brand:hover .mk{box-shadow:0 0 0 3px rgba(78,201,160,.12),0 0 14px rgba(78,201,160,.35)}
.brand b{color:var(--accent)}
nav{display:flex;gap:2px;font-family:var(--mono);font-size:12.5px;flex-wrap:wrap}
nav a{position:relative;color:var(--dim);padding:6px 11px;border-radius:3px;
  transition:color .18s,background .18s}
nav a::after{content:"";position:absolute;left:11px;right:11px;bottom:2px;height:1px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;
  transition:transform .22s cubic-bezier(.2,.7,.2,1)}
nav a:hover{color:var(--accent);background:rgba(78,201,160,.06);text-decoration:none}
nav a:hover::after{transform:scaleX(1)}

/* ── 標題 ── */
h1{font-family:var(--mono);font-size:26px;margin:52px 0 8px;font-weight:700;
  letter-spacing:-.02em;display:flex;align-items:center;gap:12px;line-height:1.35}
h1::before{content:"";width:5px;height:24px;flex:0 0 auto;
  background:linear-gradient(180deg,var(--accent),var(--accent-dim));
  box-shadow:0 0 18px -2px rgba(78,201,160,.55)}
.lead{color:var(--dim);margin:0 0 34px;font-size:15.5px}
h2{font-family:var(--mono);font-size:17px;margin:46px 0 16px;font-weight:700;
  display:flex;align-items:baseline;gap:13px;scroll-margin-top:78px}
h2 .num{font-size:12px;color:var(--accent);border:1px solid var(--accent-dim);
  padding:2px 8px;border-radius:3px;letter-spacing:.08em;flex:0 0 auto;
  background:rgba(78,201,160,.05);box-shadow:0 0 18px -8px rgba(78,201,160,.6)}
h2 .rule{flex:1;height:1px;background:linear-gradient(90deg,var(--line-2),transparent)}
h3{font-family:var(--mono);font-size:14.5px;margin:0 0 9px;font-weight:700;color:var(--accent)}
p{margin:0 0 15px;color:var(--dim)}
p:last-child{margin-bottom:0}

/* ── 卡片 ── */
.card{position:relative;border:1px solid var(--line);border-radius:5px;
  padding:22px 26px;margin:18px 0;
  background:linear-gradient(180deg,rgba(255,255,255,.022),rgba(255,255,255,0) 46%),
    var(--panel);
  transition:border-color .2s,box-shadow .28s}
.card:hover{border-color:var(--line-2);box-shadow:var(--shadow),0 0 0 1px var(--ring)}
.card::before,.card::after{content:"";position:absolute;width:11px;height:11px;
  border:1.5px solid var(--accent);opacity:.5;transition:opacity .2s,width .22s,height .22s}
.card::before{top:-1px;left:-1px;border-right:0;border-bottom:0}
.card::after{bottom:-1px;right:-1px;border-left:0;border-top:0}
.card:hover::before,.card:hover::after{opacity:1;width:16px;height:16px}

/* ── 步驟 ── */
.step{display:flex;gap:18px;margin:24px 0}
.step .n{position:relative;flex:0 0 34px;height:34px;border:1px solid var(--accent-dim);
  color:var(--accent);display:flex;align-items:center;justify-content:center;
  font-family:var(--mono);font-weight:700;font-size:13px;border-radius:3px;
  background:rgba(78,201,160,.05);box-shadow:0 0 22px -10px rgba(78,201,160,.8)}
.step .b{flex:1;min-width:0}
.step h3{margin:5px 0 8px}

/* ── 清單 ── */
ul{list-style:none;padding:0;margin:14px 0}
li{color:var(--dim);margin:9px 0;padding-left:24px;position:relative}
li::before{content:"▸";position:absolute;left:4px;color:var(--accent);font-size:11px;top:.45em;line-height:1}
ul.no li::before{content:"✕";color:var(--crit);font-size:10px;top:.5em}

/* ── 分欄對照 ── */
.split{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:5px;overflow:hidden;margin:20px 0}
@media(min-width:720px){.split{grid-template-columns:1fr 1fr}}
.split>div{background:var(--panel);padding:20px 24px}
.split h4{font-family:var(--mono);font-size:12.5px;margin:0 0 10px;letter-spacing:.06em;
  font-weight:700;display:flex;align-items:center;gap:9px}
.split h4::before{content:"";width:15px;height:15px;flex:0 0 auto;opacity:.95;
  background:currentColor;mask:center/12px no-repeat;-webkit-mask:center/12px no-repeat}
.split .yes h4{color:var(--accent)}
.split .yes h4::before{mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1 6.4l3.2 3.2L11 2.8' fill='none' stroke='%23fff' stroke-width='2'/%3E%3C/svg%3E");
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1 6.4l3.2 3.2L11 2.8' fill='none' stroke='%23fff' stroke-width='2'/%3E%3C/svg%3E")}
.split .nope h4{color:var(--crit)}
.split .nope h4::before{mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 2l8 8M10 2l-8 8' fill='none' stroke='%23fff' stroke-width='2'/%3E%3C/svg%3E");
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 2l8 8M10 2l-8 8' fill='none' stroke='%23fff' stroke-width='2'/%3E%3C/svg%3E")}
.split li{font-size:14px;margin:8px 0}

/* ── 按鈕與表單 ── */
.btn{position:relative;overflow:hidden;display:inline-block;font-family:var(--mono);
  font-size:13.5px;font-weight:700;padding:12px 24px;border:1px solid var(--accent);
  color:var(--accent);border-radius:3px;cursor:pointer;background:none;
  transition:background .18s,color .18s,box-shadow .25s,transform .18s}
.btn::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(112deg,transparent 34%,rgba(255,255,255,.22) 50%,transparent 66%);
  transform:translateX(-130%)}
.btn:hover{background:var(--accent);color:var(--bg);text-decoration:none;
  box-shadow:0 0 32px -8px rgba(78,201,160,.75)}
.btn:hover::after{transform:translateX(130%);transition:transform .6s ease}
.btn:active{transform:translateY(1px)}
.btn:disabled{opacity:.4;cursor:not-allowed}
.btn:disabled:hover{background:none;color:var(--accent);box-shadow:none}
.btn:disabled:hover::after{transform:translateX(-130%)}
.btn.ghost{border-color:var(--line-2);color:var(--dim)}
.btn.ghost:hover{background:var(--bg-2);color:var(--fg);border-color:var(--faint);box-shadow:none}
.cta{display:flex;gap:12px;flex-wrap:wrap;margin:28px 0}
label.fl{display:block;font-family:var(--mono);font-size:12.5px;font-weight:700;
  margin:22px 0 7px;color:var(--fg);letter-spacing:.04em}
input[type=text]{width:100%;padding:12px 14px;border:1px solid var(--line-2);
  border-radius:3px;background:var(--bg-2);color:var(--fg);font-size:15px;
  font-family:var(--mono);letter-spacing:.08em;
  transition:border-color .18s,box-shadow .22s,background .18s}
input[type=text]:hover{border-color:var(--faint)}
input[type=text]:focus{outline:0;border-color:var(--accent);background:var(--panel);
  box-shadow:0 0 0 3px rgba(78,201,160,.12)}
input[type=file]{width:100%;padding:11px;border:1px solid var(--line-2);
  border-radius:3px;background:var(--bg-2);color:var(--dim);font-family:var(--mono);
  font-size:13px;transition:border-color .18s}
input[type=file]:hover{border-color:var(--faint)}
input[type=file]:focus{outline:0;border-color:var(--accent);
  box-shadow:0 0 0 3px rgba(78,201,160,.12)}

/* ── 拖放區 ── */
.drop{position:relative;display:block;border:1.5px dashed var(--line-2);
  border-radius:6px;padding:38px 22px;text-align:center;cursor:pointer;
  margin:22px 0;overflow:hidden;background:var(--panel);
  transition:border-color .18s,background .18s,box-shadow .25s}
.drop::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:0;
  background:radial-gradient(ellipse 60% 70% at 50% 50%,rgba(78,201,160,.1),transparent 70%);
  transition:opacity .25s}
.drop:hover,.drop.over{border-color:var(--accent);background:var(--bg-2);
  box-shadow:0 0 0 3px rgba(78,201,160,.08)}
.drop:hover::before,.drop.over::before{opacity:1}
.drop.over{border-style:solid}
.drop input{display:none}
.drop .ic{position:relative;width:30px;height:30px;margin:0 auto 12px;color:var(--faint);
  transition:color .2s,transform .25s cubic-bezier(.2,.7,.2,1)}
.drop .ic svg{display:block;width:100%;height:100%}
.drop:hover .ic,.drop.over .ic{color:var(--accent);transform:translateY(-3px)}
.drop .big{position:relative;font-family:var(--mono);font-size:14px;color:var(--fg);font-weight:700}
.drop .sm{position:relative;font-size:13px;color:var(--faint);margin-top:7px}
#list{margin:14px 0;font-family:var(--mono);font-size:13px}
#list .it{padding:9px 13px;background:var(--bg-2);border:1px solid var(--line);
  border-radius:3px;margin:6px 0;display:flex;justify-content:space-between;
  gap:12px;align-items:center;transition:border-color .18s,background .18s}
#list .it:hover{border-color:var(--line-2);background:var(--panel)}
#list .rm{color:var(--faint);cursor:pointer;border:0;background:none;
  font-size:17px;line-height:1;padding:0 4px;font-family:var(--mono);
  transition:color .16s,transform .16s}
#list .rm:hover{color:var(--crit);transform:scale(1.15)}
#list .sz{color:var(--faint)}

/* ── 提示框 ── */
.note{border:1px solid var(--line);border-left:2px solid var(--accent);
  background:linear-gradient(90deg,rgba(78,201,160,.05),transparent 42%),var(--bg-2);
  padding:17px 22px;margin:22px 0;border-radius:0 5px 5px 0;color:var(--dim);font-size:14.5px}
.note.warn{border-left-color:#d9a441;
  background:linear-gradient(90deg,rgba(217,164,65,.05),transparent 42%),var(--bg-2)}
.note strong{display:block;margin-bottom:5px;color:var(--fg);font-family:var(--mono);font-size:13.5px}

/* ── 結果 ── */
#out{margin-top:32px}
.sum{border:1px solid var(--line);border-radius:5px;padding:20px 24px;margin-bottom:22px;
  background:linear-gradient(180deg,rgba(255,255,255,.022),rgba(255,255,255,0) 46%),
    var(--panel);box-shadow:var(--shadow)}
.sum .hd{font-family:var(--mono);font-size:14px;font-weight:700;color:var(--fg);margin-bottom:10px}
.sum .row{font-size:13.5px;color:var(--dim);margin:5px 0}
.tally{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}
.tally span{font-family:var(--mono);font-size:11.5px;padding:3px 10px;border-radius:2px;
  border:1px solid var(--line-2);color:var(--dim);background:var(--bg-2)}
.f{position:relative;border:1px solid var(--line);border-left:3px solid var(--line);
  background:var(--panel);border-radius:0 5px 5px 0;padding:16px 20px;margin:12px 0;
  transition:border-color .18s,box-shadow .25s,transform .18s}
.f:hover{box-shadow:var(--shadow);transform:translateX(2px)}
.f.CRITICAL{border-left-color:var(--crit)} .f.HIGH{border-left-color:var(--high)}
.f.MEDIUM{border-left-color:var(--med)} .f.LOW{border-left-color:var(--low)}
.f.INFO{border-left-color:var(--info)}
.f h4{margin:0 0 7px;font-size:14.5px;font-family:var(--mono);font-weight:700;
  display:flex;gap:11px;align-items:baseline;flex-wrap:wrap;color:var(--fg)}
.sev{font-family:var(--mono);font-size:10.5px;font-weight:700;padding:2px 8px;
  border-radius:2px;color:var(--bg);white-space:nowrap;letter-spacing:.04em}
.sev.CRITICAL{background:var(--crit)} .sev.HIGH{background:var(--high)}
.sev.MEDIUM{background:var(--med)} .sev.LOW{background:var(--low)}
.sev.INFO{background:var(--info)}
.f .loc{font-family:var(--mono);font-size:11.5px;color:var(--faint);margin-bottom:9px;word-break:break-all}
.f .dt{font-size:14px;color:var(--dim);margin:0 0 10px}
.f .fx{background:var(--bg-2);border:1px solid var(--line);border-radius:3px;
  padding:10px 14px;font-size:13.5px;color:var(--fg)}
.f .fx b{color:var(--accent);font-family:var(--mono);font-size:12px;letter-spacing:.04em}
.ok{border:1px solid var(--accent-dim);color:var(--fg);padding:18px 22px;border-radius:5px;
  background:linear-gradient(180deg,rgba(78,201,160,.08),rgba(78,201,160,.02)),#0d1a16;
  box-shadow:0 0 34px -18px rgba(78,201,160,.9)}
.ok .u{font-family:var(--mono);font-size:13px;word-break:break-all;
  display:block;margin:12px 0;color:var(--accent)}
.err{border:1px solid #5c2f33;background:#1a1214;color:#e8b4b8;
  padding:16px 22px;border-radius:5px;font-size:14.5px}
.err strong{color:#f0c8cb;display:block;margin-bottom:4px;font-family:var(--mono)}

/* ── 頁尾 ── */
footer{border-top:1px solid var(--line);margin-top:64px;padding:32px 0 60px;
  color:var(--faint);font-size:12.5px;font-family:var(--mono)}
footer .row{display:flex;gap:20px;flex-wrap:wrap;margin-bottom:14px}
footer a{color:var(--dim)}
footer a:hover{color:var(--accent)}

/* ── 進場動畫刻意「只給結果區」 ──────────────────
   服務頁是工具不是廣告：整頁淡入會讓內容有一瞬間是空白的，
   在慢速裝置上看起來像壞掉。靜態內容一律立刻顯示，
   只有分析完才插進 DOM 的結果卡片淡入（那裡的動態是有意義的回饋）。
   預設狀態仍然是最終狀態，@starting-style 不支援就是直接出現。 */
@media(prefers-reduced-motion:no-preference){
  #out .sum,#out .f,#out .ok,#out .err{
    opacity:1;transform:none;
    transition:opacity .45s ease,transform .45s cubic-bezier(.2,.7,.2,1)}
  @starting-style{
    #out .sum,#out .f,#out .ok,#out .err{opacity:0;transform:translateY(10px)}
  }
}
@media print{
  body::before,body::after{display:none!important}
  header{position:static}
  *{transition:none!important;animation:none!important;
    opacity:1!important;transform:none!important}
}
