/* ============================================================
   NAS Manager — 全面改版視覺層 (ui-next)  v4.0

   載入順序:style.css → ui2026.css → ui-next.css(這支最後,靠後載入覆蓋)。
   原則跟前兩層一樣:**只改外觀,不碰功能**。
   - 不新增 / 不改名 / 不移除任何 class、id
   - 不碰 .hidden 的語意,不碰任何 JS 會讀的屬性
   - 把 index.html 裡引用這支(與 ui-next.js)的兩行刪掉 → 一秒退回舊樣子

   ── 這一版做了什麼(2026 的三個主流方向)────────────────
   ① Bento Grid:桌機儀表板整個重排成大小不一的模組磚。
      作法是 .stat-grid / .chart-grid / .dash-bottom 改 display:contents,
      讓底下的卡片直接變成 #dashboard 這個 12 欄格線的格子 —— 純 CSS,
      一行 HTML 都沒動。窄於 1200px 就整組退回原本的三段式版面。
   ② Dark Glassmorphism 2.0:半透明玻璃面疊在會緩慢流動的極光光球上,
      再蓋一層極淡的雜訊顆粒消除漸層色帶(banding)。
   ③ Spatial(空間感):分層陰影 + 滑鼠位置驅動的聚光暈,
      卡片不再是貼在畫面上,而是浮在畫面上。

   刻意「沒有」做的事:
   - 沒有 3D 傾斜卡片。監控數字要好讀,傾斜是特效不是設計。
   - 沒有把 HUD 邊角框加在每張卡上。8 張卡都加會變成模板感,節制才像設計。
   - 沒碰 Chart.js 的設定(那在 app.js 裡),只調整它外面的容器。
   ============================================================ */

/* ============================================================
   1. 調色盤 —— 底色壓深、往藍紫偏,玻璃與光暈才浮得起來
   ============================================================ */
:root{
  --bg:#070912;
  --bg-grad:
    radial-gradient(1200px 620px at 78% -14%, #16203a 0%, rgba(7,9,18,0) 58%),
    radial-gradient(900px 500px at 8% 108%, #131a2e 0%, rgba(7,9,18,0) 60%),
    #070912;
  --bg-card:#0f1421;
  --bg-elev:#161d2d;
  --bg-hover:#1c2438;
  --bg-inset:#0a0e1a;
  --border:#212a3d;
  --text:#e9eff8;
  --muted:#8792a8;
  --sidebar-bg:rgba(15,20,33,.72);
  --sticky-bg:rgba(7,9,18,.82);
  --login-grad:linear-gradient(160deg, #131a2b, #0c1120);
  --card2-grad:linear-gradient(160deg, #121828, #0d1220);
  --scroll-thumb:#27324a;
  --scroll-thumb-h:#35425e;
}
:root[data-theme="light"]{
  --bg:#eff2f9;
  --bg-grad:
    radial-gradient(1200px 620px at 78% -14%, #dbe6ff 0%, rgba(239,242,249,0) 58%),
    radial-gradient(900px 500px at 8% 108%, #e6ecfb 0%, rgba(239,242,249,0) 60%),
    #eff2f9;
  --bg-card:#ffffff;
  --bg-elev:#f3f6fc;
  --bg-hover:#e8eef9;
  --bg-inset:#eef2f9;
  --border:#dde3ef;
  --text:#141b28;
  --muted:#5f6b80;
  --sidebar-bg:rgba(255,255,255,.74);
  --sticky-bg:rgba(239,242,249,.86);
  --login-grad:linear-gradient(160deg, #ffffff, #eef3fc);
  --card2-grad:linear-gradient(160deg, #ffffff, #f4f8fd);
}

/* ===== 衍生 token ===== */
:root{
  --nx-glass:color-mix(in oklab, var(--bg-card) 72%, transparent);
  --nx-glass-2:color-mix(in oklab, var(--bg-elev) 74%, transparent);
  --nx-blur:blur(18px) saturate(1.35);
  --nx-hair:color-mix(in oklab, var(--text) 11%, transparent);
  --nx-r:20px;                 /* 大圓角 */
  --nx-r-sm:13px;
  --nx-gap:16px;
  --nx-rail:250px;             /* 桌機側邊欄寬 */
  --nx-pad:14px;               /* 側邊欄離視窗邊緣的距離 */
  --nx-tab-h:64px;             /* 手機底部 dock 高 */
  --nx-safe-b:env(safe-area-inset-bottom, 0px);
  --nx-safe-t:env(safe-area-inset-top, 0px);
  --nx-aurora-op:.62;
  --nx-grain-op:.030;
  --nx-grid-op:.55;
  --nx-ease:cubic-bezier(.2,.8,.24,1);
  --nx-spring:cubic-bezier(.16,1,.3,1);
  /* 分層陰影:近距離的硬陰影定義輪廓,遠距離的軟陰影給空間感 */
  --nx-lift:0 1px 2px rgba(0,0,0,.30), 0 6px 16px -6px rgba(0,0,0,.42), 0 26px 56px -28px rgba(0,0,0,.85);
  --nx-lift-hi:0 1px 2px rgba(0,0,0,.34), 0 10px 26px -8px rgba(0,0,0,.5), 0 40px 80px -32px rgba(0,0,0,.95);
}
:root[data-theme="light"]{
  --nx-glass:color-mix(in oklab, var(--bg-card) 70%, transparent);
  --nx-glass-2:color-mix(in oklab, var(--bg-elev) 72%, transparent);
  --nx-hair:color-mix(in oklab, var(--text) 8%, transparent);
  --nx-aurora-op:.42;
  --nx-grain-op:.020;
  --nx-grid-op:.30;
  --nx-lift:0 1px 2px rgba(23,32,54,.05), 0 6px 16px -6px rgba(23,32,54,.10), 0 26px 56px -28px rgba(23,32,54,.28);
  --nx-lift-hi:0 1px 2px rgba(23,32,54,.07), 0 10px 26px -8px rgba(23,32,54,.14), 0 40px 80px -32px rgba(23,32,54,.34);
}

/* ============================================================
   2. 環境層
   body 的背景會傳播到畫布,所以 z-index 為負的固定偽元素會疊在
   畫布之上、所有內容之下 —— 剛好就是我們要的背景層。
   分工:body::before = 極光光球,html::before = 雜訊 + 網格,
        body::after = 頂部捲動進度條。
   ============================================================ */
body::before{
  content:"";
  position:fixed; inset:-30%; z-index:-2; pointer-events:none;
  background:
    radial-gradient(34vw 34vw at 12% 4%,  color-mix(in oklab, var(--accent)   42%, transparent), transparent 60%),
    radial-gradient(30vw 30vw at 88% 0%,  color-mix(in oklab, var(--accent-2) 34%, transparent), transparent 58%),
    radial-gradient(40vw 40vw at 74% 98%, color-mix(in oklab, var(--accent)   22%, transparent), transparent 64%),
    radial-gradient(26vw 26vw at 30% 88%, color-mix(in oklab, var(--accent-2) 18%, transparent), transparent 62%);
  filter:blur(52px) saturate(1.25);
  opacity:var(--nx-aurora-op);
  animation:nx-aurora 34s ease-in-out infinite alternate;
}
@keyframes nx-aurora{
  0%  { transform:translate3d(0,0,0)         scale(1);    }
  50% { transform:translate3d(3%,-2.5%,0)    scale(1.08); }
  100%{ transform:translate3d(-2.5%,3%,0)    scale(1.03); }
}

/* 雜訊顆粒 + 工程網格。
   顆粒是給大面積漸層用的:沒有它,模糊的光球在 8-bit 面板上會出現色帶。 */
html::before{
  content:"";
  position:fixed; inset:0; z-index:-1; pointer-events:none;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity:var(--nx-grain-op);
}
#app-view::before{
  content:"";
  position:fixed; inset:0; z-index:-1; pointer-events:none;
  opacity:var(--nx-grid-op);
  background-image:
    linear-gradient(color-mix(in oklab, var(--text) 4%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in oklab, var(--text) 4%, transparent) 1px, transparent 1px);
  background-size:52px 52px;
  -webkit-mask-image:radial-gradient(140vw 80vh at 50% -14%, #000 0%, transparent 74%);
          mask-image:radial-gradient(140vw 80vh at 50% -14%, #000 0%, transparent 74%);
}

/* 頂部捲動進度條(scroll-driven,零 JS) */
@supports (animation-timeline:scroll()){
  @media (prefers-reduced-motion:no-preference){
    body::after{
      content:"";
      position:fixed; left:0; top:0; width:100%; height:2px; z-index:500;
      background:linear-gradient(90deg, var(--accent), var(--accent-2));
      box-shadow:0 0 12px color-mix(in oklab, var(--accent) 60%, transparent);
      transform-origin:0 50%; transform:scaleX(0);
      pointer-events:none; transition:opacity .2s;
      animation:nx-progress linear both;
      animation-timeline:scroll(root block);
    }
    @keyframes nx-progress{ to{ transform:scaleX(1); } }
    /* 有彈窗開著時收起來,不跟全螢幕預覽 / 編輯器搶視線 */
    body:has(.modal:not(.hidden))::after{ opacity:0; }
  }
}

/* ============================================================
   3. 文字
   ============================================================ */
body{
  font-family:"Inter var", Inter, -apple-system, "PingFang TC",
              "Noto Sans TC", "Microsoft JhengHei", system-ui, sans-serif;
  letter-spacing:-.005em;
}
.content h2{ font-size:23px; font-weight:750; letter-spacing:-.022em; }
.dash-crumb{
  font-size:11px; font-weight:700; letter-spacing:.18em; text-transform:uppercase;
  color:color-mix(in oklab, var(--accent) 62%, var(--muted));
}
.dash-title{ font-size:34px; font-weight:800; letter-spacing:-.035em; line-height:1.08; }
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .dash-title{
    background:linear-gradient(96deg, var(--text) 18%, color-mix(in oklab, var(--accent) 78%, var(--text)) 96%);
    -webkit-background-clip:text; background-clip:text;
    -webkit-text-fill-color:transparent;
  }
}
.card2-h3, .chart2-title{ font-size:15px; font-weight:750; letter-spacing:-.012em; }

/* ============================================================
   4. 材質:玻璃面、漸層髮絲邊、聚光暈
   ============================================================ */
.card, .card2, .data-table, .rep, .transfer-panel, .ctx-menu,
.batch-bar, .modal-box, .upload-status, .file-detail{
  border-radius:var(--nx-r);
  border:1px solid var(--nx-hair);
  box-shadow:var(--nx-lift);
  -webkit-backdrop-filter:var(--nx-blur);
          backdrop-filter:var(--nx-blur);
}
.card, .data-table, .rep, .transfer-panel, .ctx-menu, .batch-bar,
.modal-box, .upload-status, .file-detail{
  background-color:var(--nx-glass);
}
.card2{
  background:linear-gradient(158deg,
    color-mix(in oklab, var(--bg-card) 70%, transparent),
    color-mix(in oklab, var(--bg-elev) 54%, transparent));
  position:relative; overflow:hidden;
  transition:transform .32s var(--nx-spring), box-shadow .32s var(--nx-ease),
             border-color .32s var(--nx-ease);
}
.card{ position:relative; transition:transform .32s var(--nx-spring), box-shadow .32s var(--nx-ease); }
.ctx-flyout{
  background-color:var(--nx-glass-2);
  -webkit-backdrop-filter:var(--nx-blur);
          backdrop-filter:var(--nx-blur);
}

/* 漸層髮絲邊:用 mask 把中間挖掉,只留 1px 的描邊 */
.card2::before, .card::after{
  content:""; position:absolute; inset:0; border-radius:inherit;
  padding:1px; pointer-events:none; z-index:0; opacity:.5;
  background:linear-gradient(152deg,
    color-mix(in oklab, var(--accent) 70%, transparent) 0%,
    transparent 36%, transparent 64%,
    color-mix(in oklab, var(--accent-2) 40%, transparent) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
          mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite:exclude;
  transition:opacity .3s var(--nx-ease);
}
.card2:hover::before, .card:hover::after{ opacity:1; }

/* 聚光暈:ui-next.js 會把游標位置寫進 --nx-mx / --nx-my。
   沒有那支 JS 的話 fallback 是 50%/0%,就退化成一般的頂部微光。
   (ui2026 原本用 .card2::after 做靜態頂緣光,這裡整個換掉) */
.card2::after{
  content:""; position:absolute; inset:0; border-radius:inherit;
  pointer-events:none; z-index:0;
  background:radial-gradient(320px circle at var(--nx-mx, 50%) var(--nx-my, 0%),
    color-mix(in oklab, var(--accent) 16%, transparent), transparent 62%);
  opacity:0; transition:opacity .35s var(--nx-ease);
}
.card2:hover::after{ opacity:1; }
.card2 > *{ position:relative; z-index:1; }

@media (hover:hover){
  .card2:hover{
    transform:translateY(-3px);
    box-shadow:var(--nx-lift-hi);
    border-color:color-mix(in oklab, var(--accent) 30%, var(--nx-hair));
  }
  .card:hover{ transform:translateY(-3px); box-shadow:var(--nx-lift-hi); }
}

@supports (corner-shape:squircle){
  .card, .card2, .modal-box, .data-table, .file-detail,
  .transfer-panel, .batch-bar, .ctx-menu, .login-card, .mtabs{
    corner-shape:squircle;
  }
}

/* ============================================================
   5. 桌機外框:側邊欄改成浮起來的玻璃導覽軌
   只在 ≥769px 生效(手機仍是原本的抽屜)。
   #app-view 只加左側內距 → 內容欄仍貼齊視窗頂端,
   sticky 的 .files-head 才不會在上方露出一條縫。
   ============================================================ */
@media (min-width:769px){
  #app-view{ padding-left:var(--nx-pad); }
  .sidebar{
    width:var(--nx-rail);
    margin:var(--nx-pad) 0;
    height:calc(100dvh - var(--nx-pad) * 2);
    top:var(--nx-pad);
    border:1px solid var(--nx-hair);
    border-radius:calc(var(--nx-r) + 4px);
    box-shadow:var(--nx-lift);
    background:var(--sidebar-bg);
    -webkit-backdrop-filter:blur(24px) saturate(1.4);
            backdrop-filter:blur(24px) saturate(1.4);
    padding:18px 0 14px;
  }
  .content{ padding:26px 34px 40px; }
}

/* ===== 品牌 ===== */
.brand{ padding:0 18px 4px; gap:11px; }
.brand-logo{
  width:40px; height:40px; border-radius:13px;
  background:linear-gradient(140deg, var(--accent), var(--accent-2));
  box-shadow:0 8px 22px -6px color-mix(in oklab, var(--accent) 70%, transparent),
             inset 0 1px 0 rgba(255,255,255,.28);
}
.brand-name{ font-size:16.5px; font-weight:750; letter-spacing:-.02em; }
.brand-sub{ font-size:10px; font-weight:700; letter-spacing:.14em; }
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .brand-sub{
    background:linear-gradient(90deg, var(--accent), var(--accent-2));
    -webkit-background-clip:text; background-clip:text;
    -webkit-text-fill-color:transparent;
  }
}
.nav-label{
  font-size:10.5px; font-weight:750; letter-spacing:.16em;
  padding:18px 22px 8px; text-transform:uppercase;
}

/* ===== 導覽項目 =====
   ui-next.js 會把「📊 監控儀表板」拆成 .ni-ico + .ni-txt 兩個 span,
   兩者都是 pointer-events:none —— 點擊的 e.target 仍然是 <a>,
   app.js 那個靠 e.target.dataset.view 的 delegated handler 不受影響。
   JS 沒跑到的話這裡的樣式對純文字節點一樣安全,只是少了圖示底框。 */
#nav{ padding:0 12px; gap:3px; }
#nav a{
  position:relative;
  display:flex; align-items:center; gap:11px;
  padding:9px 12px; border-radius:13px;
  font-size:14.5px; font-weight:600; letter-spacing:-.01em;
  color:var(--muted); background:transparent; box-shadow:none;
  transition:color .2s var(--nx-ease), background .2s var(--nx-ease);
}
.ni-ico{
  flex:none; pointer-events:none;
  width:30px; height:30px; border-radius:9px;
  display:flex; align-items:center; justify-content:center;
  font-size:15px; line-height:1;
  background:color-mix(in oklab, var(--text) 6%, transparent);
  border:1px solid transparent;
  transition:background .2s var(--nx-ease), border-color .2s var(--nx-ease),
             transform .3s var(--nx-spring);
}
.ni-txt{
  pointer-events:none; flex:1 1 auto; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* 未處理數的紅點靠右對齊,不要黏在文字後面。
   pointer-events:none 是必要的 —— app.js 的 delegated handler 靠
   e.target.dataset.view 判斷要切哪一頁,剛好點到紅點上會拿不到 view。 */
#nav a .nav-dot{ flex:none; margin-left:auto; pointer-events:none; }
#nav a:hover{ color:var(--text); background:color-mix(in oklab, var(--text) 4%, transparent); transform:none; }
#nav a:hover .ni-ico{ transform:scale(1.08); }
#nav a.active{
  color:var(--text);
  background:linear-gradient(100deg,
    color-mix(in oklab, var(--accent) 20%, transparent),
    color-mix(in oklab, var(--accent) 5%, transparent) 82%);
  font-weight:700;
}
#nav a.active .ni-ico{
  background:linear-gradient(140deg, var(--accent), var(--accent-2));
  border-color:transparent;
  box-shadow:0 6px 16px -6px color-mix(in oklab, var(--accent) 80%, transparent);
}
/* 左側指示條:掛 view-transition-name 讓它在切頁時「滑」過去 */
#nav a.active::before{
  content:""; position:absolute; left:-6px; top:9px; bottom:9px; width:3px;
  border-radius:0 4px 4px 0;
  background:linear-gradient(180deg, var(--accent), var(--accent-2));
  box-shadow:0 0 12px color-mix(in oklab, var(--accent) 70%, transparent);
}
@supports (view-transition-name:x){
  #nav a.active::before{ view-transition-name:nav-indicator; }
}

/* ===== 側邊欄底部 ===== */
.user-chip{
  margin:6px 14px 8px; padding:9px 11px; border-radius:14px;
  background:color-mix(in oklab, var(--text) 4%, transparent);
  border:1px solid var(--nx-hair);
}
.uc-avatar{ border-radius:10px; background:linear-gradient(140deg, var(--accent), var(--accent-2)); }
.foot-actions{ margin:0 14px 4px; }
.logout, .icon-btn{ border-radius:13px; border:1px solid var(--nx-hair); }
.logout{ font-weight:600; }
.sidebar-foot{ padding:14px 22px 8px; }
.ws-text{ font-size:12.5px; font-weight:600; }
.sidebar-copyright{ font-size:10.5px; opacity:.6; padding:10px 22px 0; }

/* ============================================================
   6. Bento Grid 儀表板(桌機 ≥1200px)

   .stat-grid / .chart-grid / .dash-bottom 改成 display:contents,
   它們的卡片就直接成為 #dashboard 這個 12 欄格線的格子。
   display:contents 只影響「產生盒子」,不改 DOM 樹 ——
   所以 .chart-grid .chart2:nth-child(n) 這種選擇器照樣有效。
   ============================================================ */
@media (min-width:1200px){
  #dashboard{
    display:grid;
    grid-template-columns:repeat(12, minmax(0, 1fr));
    gap:var(--nx-gap);
    align-content:start;
  }
  .stat-grid, .chart-grid, .dash-bottom{ display:contents; }

  /* 每一塊都要「同時」指定 column 與 row。
     只給 column 的話,自動排版會照 DOM 順序放 —— 而 DOM 裡兩張圖表(.chart-grid)
     排在溫度/容量(.dash-bottom)之前,溫度磚就會被塞到第二張圖表旁邊,
     第一張圖表右邊則開一個大洞。指定 row 才排得出想要的 bento。 */
  .dash-head{ grid-column:1 / -1; grid-row:1; margin-bottom:2px; }

  /* 第一排:四塊等寬的即時數值磚 */
  .sc-cpu { grid-column:1 / 4;   grid-row:2; }
  .sc-mem { grid-column:4 / 7;   grid-row:2; }
  .sc-up  { grid-column:7 / 10;  grid-row:2; }
  .sc-proc{ grid-column:10 / 13; grid-row:2; }

  /* 第二、三排:7 / 5 的非對稱切法 —— 這就是 bento 的核心,
     圖表拿到主要的空間權重,溫度與容量在右側縱向排開。 */
  .chart-grid .chart2:nth-child(1){ grid-column:1 / 8;  grid-row:3; }
  .dash-bottom .temp2             { grid-column:8 / 13; grid-row:3; }
  .chart-grid .chart2:nth-child(2){ grid-column:1 / 8;  grid-row:4; }
  .dash-bottom .storage2          { grid-column:8 / 13; grid-row:4; }

  /* 溫度磚被拉高了,把儀表與文字撐開填滿,不要留一片空白 */
  .temp2{ display:flex; flex-direction:column; }
  .temp2 .temp-gauge-wrap{ flex:1; align-items:center; }
  .storage2{ display:flex; flex-direction:column; }
  .storage2 .dash-volumes{ flex:1; justify-content:center; }
}

/* 超寬螢幕:磚塊再放大一級,不要讓內容擠在中間 */
@media (min-width:1700px){
  #dashboard{ gap:20px; }
  .chart2-body, .chart2-body canvas{ height:268px !important; }
}

/* ===== 儀表板磚塊本體 ===== */
.card2{ border-radius:var(--nx-r); padding:22px 22px 20px; }
.card2 > .sc-bar{ position:absolute; top:0; left:0; right:0; }
.sc-bar{ height:2px; opacity:.9; }
.sc-label{ font-size:12.5px; font-weight:700; letter-spacing:.02em; color:var(--muted); }
.sc-val{
  font-size:42px; font-weight:800; letter-spacing:-.045em; margin-top:16px;
  font-variant-numeric:tabular-nums;
  text-shadow:0 0 34px color-mix(in oklab, var(--accent) 26%, transparent);
}
.sc-val.small{ font-size:26px; letter-spacing:-.03em; }
.sc-val i{ font-size:17px; opacity:.65; }
.sc-sub{ font-size:12px; margin-top:9px; }
.sc-icon{
  width:40px; height:40px; border-radius:12px; font-size:18px;
  background:color-mix(in oklab, var(--text) 5%, transparent);
  border:1px solid var(--nx-hair);
}
.ring .ring-fg{ filter:drop-shadow(0 0 6px currentColor); }

/* 即時更新膠囊:加一道左右掃過的光,一眼看得出「資料是活的」 */
.live-pill{
  position:relative; overflow:hidden;
  border-radius:999px; font-weight:700; letter-spacing:.02em;
  background:color-mix(in oklab, var(--accent-2) 10%, transparent);
  border:1px solid color-mix(in oklab, var(--accent-2) 32%, transparent);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
}
@media (prefers-reduced-motion:no-preference){
  .live-pill::after{
    content:""; position:absolute; inset:0;
    background:linear-gradient(100deg, transparent 20%,
      color-mix(in oklab, var(--accent-2) 26%, transparent) 50%, transparent 80%);
    transform:translateX(-100%);
    animation:nx-sweep 3.6s ease-in-out infinite;
  }
  @keyframes nx-sweep{ 0%,55%{ transform:translateX(-100%);} 100%{ transform:translateX(100%);} }
}
.reboot-btn{ border-radius:999px; font-weight:700; }

.chart2-body{ height:236px; }
.chart2-body canvas{ height:236px !important; }
.chart2-now{ font-size:13.5px; font-weight:700; font-variant-numeric:tabular-nums; }
.dv-bar, .vol-bar{ border-radius:999px; background:color-mix(in oklab, var(--text) 8%, transparent); }
.dv-bar span, .vol-bar span{
  border-radius:999px;
  box-shadow:0 0 14px color-mix(in oklab, var(--accent) 55%, transparent);
}
.temp-status-pill{ font-weight:700; }
.temp-gauge .tg-fg{ filter:drop-shadow(0 0 6px currentColor); }
.tg-val{ font-size:25px; font-weight:800; letter-spacing:-.03em; }

/* 切頁時磚塊依序浮現。用時間軸而非捲動軸 —— 動畫一定會播完,
   不會像 view() 那樣在矮螢幕上卡在半透明的狀態被誤認為壞掉。 */
@media (prefers-reduced-motion:no-preference){
  #dashboard:not(.hidden) .card2,
  #storage:not(.hidden) .card{
    animation:nx-tile-in .46s var(--nx-spring) both;
  }
  .stat-grid > .card2:nth-child(1){ animation-delay:.02s }
  .stat-grid > .card2:nth-child(2){ animation-delay:.06s }
  .stat-grid > .card2:nth-child(3){ animation-delay:.10s }
  .stat-grid > .card2:nth-child(4){ animation-delay:.14s }
  .chart-grid > .card2:nth-child(1){ animation-delay:.16s }
  .chart-grid > .card2:nth-child(2){ animation-delay:.20s }
  .dash-bottom > .card2:nth-child(1){ animation-delay:.18s }
  .dash-bottom > .card2:nth-child(2){ animation-delay:.22s }
  @keyframes nx-tile-in{
    from{ opacity:0; transform:translateY(14px) scale(.985); }
    to  { opacity:1; transform:none; }
  }
}

/* ============================================================
   7. 儲存頁 / 表格 / 按鈕 / 表單
   ============================================================ */
.cards{ grid-template-columns:repeat(auto-fill, minmax(252px, 1fr)); gap:var(--nx-gap); }
/* 第一顆 volume 給雙倍寬,儲存頁也吃到 bento 的節奏 */
@media (min-width:1200px){
  #volumes{ grid-template-columns:repeat(auto-fill, minmax(252px, 1fr)); }
  #volumes .card:first-child{ grid-column:span 2; }
}
.card{ padding:20px 22px; }
.vol-free{ font-size:26px; font-weight:800; letter-spacing:-.035em; }
.stat-label{ font-weight:700; }
.smart-grid{ gap:12px 16px; }

.data-table{ border-radius:var(--nx-r-sm); overflow:hidden; }
.data-table th{
  font-size:11px; font-weight:750; letter-spacing:.12em;
  padding:12px 16px;
  background:color-mix(in oklab, var(--bg-elev) 62%, transparent);
  border-bottom:1px solid var(--nx-hair);
}
.data-table td{ padding:13px 16px; border-bottom:1px solid color-mix(in oklab, var(--text) 6%, transparent); }
.data-table tbody tr{ transition:background .16s var(--nx-ease); }
.data-table tbody tr:nth-child(even) td{ background:color-mix(in oklab, var(--text) 2%, transparent); }
.data-table tbody tr:hover td{ background:color-mix(in oklab, var(--accent) 8%, transparent); }
.data-table tbody tr.selected td{ background:color-mix(in oklab, var(--accent) 15%, transparent); }

/* 按鈕:hover 時一道光掃過 */
.btn-sm, .logout, .icon-btn, .view-btn{
  border-radius:11px; font-weight:600;
  transition:background .2s var(--nx-ease), border-color .2s var(--nx-ease),
             color .2s var(--nx-ease), transform .2s var(--nx-spring);
}
.btn-sm{ border-color:var(--nx-hair); }
.btn-sm:hover{
  transform:translateY(-1px);
  border-color:color-mix(in oklab, var(--accent) 45%, var(--nx-hair));
  background:color-mix(in oklab, var(--accent) 9%, transparent);
}
.btn-sm:active{ transform:translateY(0) scale(.97); }
.file-actions > button, .upload-btn, .share-create-btn, .ui-dialog-ok, .login-card button{
  position:relative; overflow:hidden;
  border-radius:13px; font-weight:700; letter-spacing:-.005em;
  box-shadow:0 6px 18px -8px color-mix(in oklab, var(--accent) 85%, transparent),
             inset 0 1px 0 rgba(255,255,255,.22);
  transition:transform .2s var(--nx-spring), box-shadow .25s var(--nx-ease), filter .2s;
}
.file-actions > button:hover, .upload-btn:hover, .share-create-btn:hover,
.ui-dialog-ok:hover, .login-card button:hover{
  transform:translateY(-2px);
  box-shadow:0 12px 26px -10px color-mix(in oklab, var(--accent) 95%, transparent),
             inset 0 1px 0 rgba(255,255,255,.28);
}
.file-actions > button:active, .upload-btn:active, .share-create-btn:active{ transform:translateY(0) scale(.98); }
.view-toggle{ border-radius:12px; border-color:var(--nx-hair); background:color-mix(in oklab, var(--text) 4%, transparent); }
.view-btn.active{ background:linear-gradient(140deg, var(--accent), var(--accent-2)); }
.badge, .pbadge, .temp-status-pill, .live-pill{ letter-spacing:.01em; }
.badge{ border-radius:999px; font-weight:700; }

.sort-select, .ui-dialog-input, .login-card input, .share-row select,
.share-row input, .share-link-row input{
  border-radius:12px; border-color:var(--nx-hair);
  background-color:color-mix(in oklab, var(--bg-inset) 72%, transparent);
  transition:border-color .2s, box-shadow .2s, background .2s;
}
.sort-select:focus, .ui-dialog-input:focus, .login-card input:focus,
.share-row select:focus, .share-row input:focus{
  border-color:var(--accent);
  box-shadow:0 0 0 3px color-mix(in oklab, var(--accent) 24%, transparent);
}

/* 檔案頁 */
.files-head{ background:var(--sticky-bg); -webkit-backdrop-filter:blur(16px); backdrop-filter:blur(16px); }
.breadcrumb{ font-size:14px; font-weight:600; }
.grid-item{
  border-radius:var(--nx-r-sm); border-color:var(--nx-hair);
  background:var(--nx-glass); box-shadow:var(--nx-lift);
  transition:transform .28s var(--nx-spring), border-color .2s, box-shadow .28s;
}
.grid-item:hover{
  transform:translateY(-5px);
  border-color:color-mix(in oklab, var(--accent) 45%, transparent);
  box-shadow:var(--nx-lift-hi);
}
.grid-thumb-wrap{ border-radius:10px; }
.drop-overlay{
  background:color-mix(in oklab, var(--bg) 62%, transparent);
  border-radius:var(--nx-r); border-width:2px;
}
.file-detail{ border-radius:var(--nx-r); }
.ctx-menu, .ctx-flyout{ border-radius:15px; border-color:var(--nx-hair); }
.ctx-item{ border-radius:10px; font-weight:600; }
.batch-bar{ border-radius:999px; }
.transfer-panel{ border-radius:var(--nx-r); }
.toast{
  border-radius:999px; font-weight:600;
  background:var(--nx-glass-2); border-color:var(--nx-hair);
  -webkit-backdrop-filter:var(--nx-blur); backdrop-filter:var(--nx-blur);
}
.welcome-float{ border-radius:var(--nx-r); }

/* ============================================================
   8. 彈窗
   ============================================================ */
.modal{
  background:color-mix(in oklab, #000 72%, transparent);
  -webkit-backdrop-filter:blur(8px) saturate(.9);
          backdrop-filter:blur(8px) saturate(.9);
}
.modal-box{ padding:20px; }
.modal-head span{ font-weight:700; letter-spacing:-.012em; }
.seg{ border-radius:13px; border-color:var(--nx-hair); }
.seg-btn{ border-radius:10px; font-weight:700; }
.seg-btn.active{ background:linear-gradient(140deg, var(--accent), var(--accent-2)); }
.swatch{ border-radius:12px; }
.perm-row{ border-radius:14px; border-color:var(--nx-hair); }

/* ============================================================
   9. 命令面板(Ctrl / ⌘ + K)—— 由 ui-next.js 建立
   ============================================================ */
.nxp{
  position:fixed; inset:0; z-index:420;
  display:flex; align-items:flex-start; justify-content:center;
  padding:14vh 16px 16px;
  background:color-mix(in oklab, #000 62%, transparent);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
}
.nxp-box{
  width:min(96vw, 580px); max-height:70vh; display:flex; flex-direction:column;
  border-radius:var(--nx-r); border:1px solid var(--nx-hair);
  background:var(--nx-glass); box-shadow:var(--nx-lift-hi);
  -webkit-backdrop-filter:var(--nx-blur); backdrop-filter:var(--nx-blur);
  overflow:hidden;
}
@supports (corner-shape:squircle){ .nxp-box{ corner-shape:squircle; } }
.nxp-input{
  width:100%; padding:17px 20px; border:none; border-bottom:1px solid var(--nx-hair);
  background:transparent; color:var(--text); font:inherit; font-size:16px; font-weight:600;
}
.nxp-input:focus{ outline:none; }
.nxp-input::placeholder{ color:var(--muted); font-weight:500; }
.nxp-list{ overflow-y:auto; padding:8px; display:flex; flex-direction:column; gap:2px; }
.nxp-item{
  display:flex; align-items:center; gap:12px;
  padding:11px 13px; border:none; border-radius:12px; background:transparent;
  color:var(--text); font:inherit; font-size:14.5px; font-weight:600;
  text-align:left; cursor:pointer; width:100%;
}
.nxp-item[aria-selected="true"]{ background:color-mix(in oklab, var(--accent) 16%, transparent); }
.nxp-ico{
  flex:none; width:28px; height:28px; border-radius:9px;
  display:flex; align-items:center; justify-content:center; font-size:14px;
  background:color-mix(in oklab, var(--text) 6%, transparent);
}
.nxp-lab{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.nxp-kind{ flex:none; font-size:11px; font-weight:700; letter-spacing:.08em; color:var(--muted); text-transform:uppercase; }
.nxp-empty{ padding:26px; text-align:center; color:var(--muted); font-size:14px; }
.nxp-foot{
  display:flex; gap:14px; padding:9px 16px; border-top:1px solid var(--nx-hair);
  font-size:11.5px; color:var(--muted);
}
.nxp-foot kbd{
  font:inherit; font-size:11px; padding:1px 6px; border-radius:6px;
  border:1px solid var(--nx-hair); background:color-mix(in oklab, var(--text) 6%, transparent);
}
@media (prefers-reduced-motion:no-preference){
  .nxp{ animation:nx-fade .16s ease both; }
  .nxp-box{ animation:nx-pop .26s var(--nx-spring) both; }
  @keyframes nx-fade{ from{ opacity:0 } }
  @keyframes nx-pop{ from{ opacity:0; transform:translateY(-12px) scale(.97) } }
}
/* 手機不顯示(沒有實體鍵盤,底部 dock 已經夠用) */
@media (max-width:768px){ .nxp{ display:none; } }

/* ============================================================
   10. 登入頁
   ============================================================ */
.login-card{
  width:380px; padding:40px 36px 32px;
  border-radius:26px; border:1px solid var(--nx-hair);
  background:var(--nx-glass); box-shadow:var(--nx-lift-hi);
  -webkit-backdrop-filter:var(--nx-blur); backdrop-filter:var(--nx-blur);
}
@supports (corner-shape:squircle){ .login-card{ corner-shape:squircle; } }
.login-card::before{
  height:3px; margin:-1px -1px 22px;
  border-radius:26px 26px 0 0;
  background:linear-gradient(90deg, var(--accent), var(--accent-2), var(--accent));
  box-shadow:0 0 20px color-mix(in oklab, var(--accent) 60%, transparent);
}
.login-card h1{ font-size:27px; font-weight:800; letter-spacing:-.035em; }
.login-card .sub{ font-size:13.5px; }
.login-card input{ padding:14px 16px; }
.auth-tabs{ border-radius:14px; border-color:var(--nx-hair); }
.auth-tab{ border-radius:10px; font-weight:700; }
.auth-tab.active{ background:linear-gradient(140deg, var(--accent), var(--accent-2)); }

/* ============================================================
   11. 手機:底部 dock
   z-index 刻意壓在 .modal(100)之下 —— 彈窗打開時要被遮罩蓋住。
   ============================================================ */
.mtabs{ display:none; }

@media (max-width:768px){
  .mtabs{
    display:flex; align-items:stretch; gap:2px;
    position:fixed; left:10px; right:10px; bottom:calc(10px + var(--nx-safe-b));
    z-index:95;
    padding:6px;
    border-radius:22px; border:1px solid var(--nx-hair);
    background:color-mix(in oklab, var(--sticky-bg) 82%, transparent);
    -webkit-backdrop-filter:blur(24px) saturate(1.5);
            backdrop-filter:blur(24px) saturate(1.5);
    box-shadow:var(--nx-lift-hi);
  }
  .mtab{
    flex:1 1 0; min-width:0; position:relative;
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
    min-height:50px; padding:5px 2px;
    border:none; border-radius:16px; background:transparent;
    color:var(--muted); font-family:inherit; font-size:10px; font-weight:700; letter-spacing:.01em;
    cursor:pointer; -webkit-tap-highlight-color:transparent;
    transition:color .2s var(--nx-ease);
  }
  .mtab-ico{ font-size:19px; line-height:1; transition:transform .3s var(--nx-spring); }
  .mtab-txt{ max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .mtab:active .mtab-ico{ transform:scale(.86); }
  .mtab.active{ color:var(--accent); }
  .mtab.active .mtab-ico{ transform:translateY(-1px) scale(1.08); }
  /* 會滑動的選取膠囊:所有 tab 共用一個 view-transition-name,
     切頁時瀏覽器會把它從舊位置補間到新位置。 */
  .mtab.active::before{
    content:""; position:absolute; inset:0; z-index:-1;
    border-radius:16px;
    background:color-mix(in oklab, var(--accent) 15%, transparent);
    border:1px solid color-mix(in oklab, var(--accent) 26%, transparent);
  }
  @supports (view-transition-name:x){
    .mtab.active::before{ view-transition-name:nx-dock; }
  }
  .mtab-dot{
    position:absolute; top:4px; right:calc(50% - 21px);
    min-width:8px; height:8px; padding:0; border-radius:99px;
    background:var(--danger);
    box-shadow:0 0 0 2px var(--bg), 0 0 10px var(--danger);
  }

  /* 貼底的浮動元素全部往上讓位 */
  .content{ padding-bottom:calc(var(--nx-tab-h) + var(--nx-safe-b) + 26px); }
  .batch-bar{ bottom:calc(var(--nx-tab-h) + var(--nx-safe-b) + 18px); }
  .transfer-panel{ bottom:calc(var(--nx-tab-h) + var(--nx-safe-b) + 18px); }
  .toast{ bottom:calc(var(--nx-tab-h) + var(--nx-safe-b) + 82px); }
  .welcome-float{ bottom:calc(var(--nx-tab-h) + var(--nx-safe-b) + 20px); }
}

/* ============================================================
   12. 手機版面
   ============================================================ */
@media (max-width:768px){
  /* 網址列會伸縮,100vh 在手機上會多出一段捲動 → 一律用 dvh */
  #app-view, .login-wrap{ min-height:100dvh; }

  .mobile-bar{
    padding:10px 14px; padding-top:calc(10px + var(--nx-safe-t)); gap:12px;
    background:color-mix(in oklab, var(--sticky-bg) 88%, transparent);
    -webkit-backdrop-filter:blur(20px) saturate(1.4);
            backdrop-filter:blur(20px) saturate(1.4);
  }
  .menu-btn{
    width:40px; height:40px; border-radius:13px;
    display:flex; align-items:center; justify-content:center; font-size:19px;
    border:1px solid var(--nx-hair); background:var(--nx-glass-2);
  }
  .mobile-brand{ font-size:15.5px; font-weight:750; letter-spacing:-.015em; }
  .files-head{ top:var(--nx-mbar-h, 46px); }

  /* 抽屜 */
  .sidebar{
    width:min(86vw, 306px); height:100dvh;
    border-radius:0 24px 24px 0; border-right:1px solid var(--nx-hair);
    padding-top:calc(20px + var(--nx-safe-t));
  }
  .sidebar.open{ box-shadow:var(--nx-lift-hi); }
  .overlay{
    background:color-mix(in oklab, #000 52%, transparent);
    -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px);
  }

  /* 觸控熱區:Apple / Google 都建議 ≥44px */
  #nav a{ padding:11px 12px; font-size:15.5px; }
  .ni-ico{ width:34px; height:34px; font-size:16px; }
  .btn-sm{ padding:9px 14px; font-size:13.5px; min-height:40px; }
  .view-btn{ min-width:44px; min-height:42px; }
  .modal-close{ width:40px; height:40px; font-size:24px; }
  .fd-close{ width:38px; height:38px; }
  .ctx-item{ padding:13px 14px; font-size:15px; }
  .img-tool-btn{ width:46px; height:46px; }
  .img-tools{ top:calc(12px + var(--nx-safe-t)); }

  /* iOS:輸入框字級 <16px 會在聚焦時自動放大整頁,把版面推歪 */
  :where(input:not([type=checkbox]):not([type=hidden]), select),
  .ui-dialog-input, .sort-select{ font-size:16px; }

  /* 手機版 bento:CPU 佔滿整排當主角,其餘兩欄 */
  .stat-grid{ grid-template-columns:1fr 1fr; gap:11px; }
  .sc-cpu{ grid-column:1 / -1; }
  .card2{ padding:16px 15px; border-radius:18px; }
  .sc-val{ font-size:29px; margin-top:10px; }
  .sc-cpu .sc-val{ font-size:40px; }
  .sc-val.small{ font-size:19px; }
  .sc-label{ font-size:12px; }
  .sc-sub{ font-size:11.5px; }
  .ring{ width:38px; height:38px; }
  .sc-cpu .ring{ width:46px; height:46px; }
  .sc-icon{ width:34px; height:34px; font-size:16px; border-radius:11px; }
  .dash-title{ font-size:25px; }
  .dash-head{ margin-bottom:16px; }
  .chart2-body, .chart2-body canvas{ height:190px !important; }
  .temp-gauge{ width:100px; height:100px; }
  .temp-gauge-wrap{ gap:16px; }
  .cards{ grid-template-columns:1fr; }

  .files-grid{ grid-template-columns:repeat(auto-fill, minmax(104px, 1fr)); gap:12px; }
  .grid-ops button{ width:30px; height:30px; }
  .ctx-menu{ max-height:70vh; overflow-y:auto; }

  /* 效能:手機一頁最多 8 張 card2,逐張做背景模糊會掉幀。
     保留半透明的質感,只把 backdrop-filter 關掉,肉眼幾乎看不出差別。 */
  .card, .card2, .data-table, .rep, .upload-status, .grid-item{
    -webkit-backdrop-filter:none; backdrop-filter:none;
  }
  body::before{ filter:blur(38px); opacity:calc(var(--nx-aurora-op) * .8); }
  /* 手機不做聚光暈(沒有游標)與 hover 位移 */
  .card2::after{ display:none; }
}

/* 觸控裝置(不分寬度):只在 hover 出現的東西一律直接顯示,否則永遠點不到 */
@media (hover:none){
  .grid-ops{ opacity:1; }
  /* 子選單原本只靠 hover 展開 → 觸控上改成直接內嵌展開 */
  .ctx-sub{ display:flex; flex-direction:column; }
  .ctx-flyout{
    display:flex; position:static; inset:auto;
    margin:2px 0 4px 10px; padding:2px 0 2px 8px;
    border:none; border-left:2px solid var(--border);
    border-radius:0; box-shadow:none; background:transparent;
    -webkit-backdrop-filter:none; backdrop-filter:none;
  }
  .ctx-item .ctx-arrow{ display:none; }
}

/* ============================================================
   13. 手機彈窗 → 底部抽屜(bottom sheet)
   排除三個本來就走全螢幕的:文件預覽、編輯器、照片燈箱。
   :not(#id) 讓特異度足以蓋過 .share-box / .settings-box 等自訂寬度。
   ============================================================ */
@media (max-width:768px){
  /* 修一個 v3.1 就存在的 bug:
     設定齒輪只長在側邊欄裡,手機上得先拉開抽屜才點得到 —— 但 app.js 開設定時
     不會關抽屜,而 .modal 的 z-index 是 100,比 .sidebar(200)與遮罩(150)都低,
     於是彈窗確實開了、卻整個被抽屜蓋住,看起來就是「按了沒反應」。
     手機上把彈窗抬到抽屜之上;.toast(400)與 .ctx-menu(300)仍在它上面,不受影響。 */
  .modal{ z-index:210; }

  .modal:not(.img-modal):not(#doc-modal):not(#editor-modal){
    align-items:flex-end; justify-content:stretch; padding:0;
  }
  .modal:not(.img-modal):not(#doc-modal):not(#editor-modal) > .modal-box{
    width:100%; max-width:none; margin:0;
    max-height:92dvh; overflow-y:auto; overscroll-behavior:contain;
    border-radius:26px 26px 0 0; border-bottom:none;
    padding:10px 18px calc(22px + var(--nx-safe-b));
    transition:translate .34s var(--nx-spring);
  }
  /* 抽屜頂端的握把 */
  .modal:not(.img-modal):not(#doc-modal):not(#editor-modal) > .modal-box::before{
    content:""; display:block; width:40px; height:4px; margin:2px auto 14px;
    border-radius:99px; background:var(--border);
  }
  @starting-style{
    .modal:not(.img-modal):not(#doc-modal):not(#editor-modal) > .modal-box{
      translate:0 100%; scale:1;
    }
  }
  .share-create-btn, .ui-dialog-ok{ min-height:48px; font-size:15px; }
  .ui-dialog-btns .btn-sm{ min-height:48px; padding:0 20px; }
}

/* ============================================================
   14. 手機表格 → 卡片
   ui-next.js 會把每個 <td> 補上 data-label(取自對應的 <th>),
   並在該 table 上加 .mcard。沒有 data-label 也不會壞,只是少了欄位名。
   檔案清單(#files-table)刻意不轉:它有多選 / 拉框 / 右鍵定位,
   維持表格語意比較安全,改用「隱藏修改時間欄」讓它塞得進手機寬度。
   ============================================================ */
@media (max-width:640px){
  .data-table.mcard{
    min-width:0; border:none; background:transparent; box-shadow:none;
    -webkit-backdrop-filter:none; backdrop-filter:none;
  }
  .data-table.mcard thead{ display:none; }
  .data-table.mcard tbody, .data-table.mcard tr, .data-table.mcard td{ display:block; width:100%; }
  .data-table.mcard tr{
    background:var(--nx-glass); border:1px solid var(--nx-hair);
    border-radius:16px; margin-bottom:10px; padding:6px 4px;
    box-shadow:var(--nx-lift);
  }
  .data-table.mcard tr:hover td,
  .data-table.mcard tbody tr:nth-child(even) td{ background:transparent; }
  .data-table.mcard td{
    border-bottom:none; padding:7px 13px;
    display:flex; align-items:flex-start; justify-content:space-between; gap:14px;
    text-align:right; word-break:break-word;
  }
  .data-table.mcard td::before{
    content:attr(data-label);
    flex:0 0 auto; text-align:left;
    color:var(--muted); font-size:11.5px; font-weight:700;
    letter-spacing:.06em; white-space:nowrap;
  }
  /* 「沒有資料」那種 colspan 列維持單行置中 */
  .data-table.mcard td[colspan]{ display:block; text-align:center; }
  .data-table.mcard td[colspan]::before{ content:none; }
  .data-table.mcard td.mcard-ops{ display:flex; flex-wrap:wrap; justify-content:flex-end; gap:6px; }
  .data-table.mcard td.mcard-ops::before{ align-self:center; margin-right:auto; }
  .data-table.mcard td.mcard-ops .btn-sm{ margin-right:0; }
  .table-scroll:has(.data-table.mcard){ overflow-x:visible; }

  /* 檔案清單:砍掉「修改時間」欄就不用左右捲(時間仍可在右側詳細資料看到) */
  #files-table{ min-width:0; }
  #files-table th:nth-child(3), #files-table td:nth-child(3){ display:none; }
  #files-table th, #files-table td{ padding:12px 10px; }
}

@media (max-width:420px){
  .mtab-txt{ font-size:9.5px; }
  .files-grid{ grid-template-columns:repeat(auto-fill, minmax(92px, 1fr)); }
  .dash-title{ font-size:22px; }
}
/* 單欄只留給真的很窄的螢幕。
   iPhone 14 是 390px —— 落在原本的 420px 斷點裡會退成單欄,四張卡疊成一長條、
   要一直捲才看得完。實測 390px 下兩欄每欄約 185px,數值與副標都還讀得清楚。 */
@media (max-width:340px){
  .stat-grid{ grid-template-columns:1fr; }
}

/* ============================================================
   15. 無障礙
   ============================================================ */
:where(a, button, input, select, textarea, [tabindex]):focus-visible{
  outline:2px solid var(--accent);
  outline-offset:2px;
  border-radius:8px;
}
::selection{ background:color-mix(in oklab, var(--accent) 34%, transparent); }

@media (prefers-reduced-motion:reduce){
  body::before{ animation:none; }
  .live-pill::after{ animation:none; display:none; }
}

/* ============================================================
   16. 登入頁:左側標語 + 右側登入卡
   ------------------------------------------------------------
   卡片本身的玻璃質感沿用上面第 10 節,這裡只加「版面」與背景裝飾。
   刪掉這一節就退回單純置中的登入卡,功能不受影響。
   ============================================================ */
.login-wrap{
  position:relative; overflow:hidden;
  display:grid; grid-template-columns:minmax(0,1fr) auto;
  align-items:center; justify-content:center;
  gap:clamp(32px, 7vw, 110px); padding:clamp(24px, 6vw, 72px);
}

/* --- 背景裝飾 --- */
.login-bg{ position:absolute; inset:0; pointer-events:none; z-index:0; }
.lb-blob{ position:absolute; border-radius:50%; filter:blur(10px); }
.lb-blob-1{
  width:68vmax; height:68vmax; right:-26vmax; bottom:-34vmax;
  background:radial-gradient(circle at 34% 30%, var(--accent) 0%, var(--accent-hi) 46%, transparent 72%);
  opacity:.20; animation:lbFloat 22s ease-in-out infinite;
}
.lb-blob-2{
  width:34vmax; height:34vmax; left:-12vmax; top:-14vmax;
  background:radial-gradient(circle at 50% 50%, var(--accent-2) 0%, transparent 70%);
  opacity:.14; animation:lbFloat 28s ease-in-out infinite reverse;
}
.lb-grid{
  position:absolute; inset:0;
  background-image:radial-gradient(currentColor 1px, transparent 1px);
  background-size:26px 26px; color:var(--muted); opacity:.10;
  -webkit-mask-image:radial-gradient(60% 55% at 30% 40%, #000 0%, transparent 100%);
          mask-image:radial-gradient(60% 55% at 30% 40%, #000 0%, transparent 100%);
}
@keyframes lbFloat{
  0%,100%{ transform:translate(0,0) scale(1); }
  50%    { transform:translate(-3%,-4%) scale(1.06); }
}

/* --- 左側品牌區 --- */
.login-hero{ position:relative; z-index:1; max-width:560px; animation:ui-rise .5s ease both; }
.hero-brand{ display:flex; align-items:center; gap:12px; margin-bottom:34px; }
.hero-logo{
  width:46px; height:46px; border-radius:14px; flex:none;
  display:flex; align-items:center; justify-content:center; font-size:24px;
  background:linear-gradient(140deg, var(--accent), var(--accent-2));
  box-shadow:0 8px 22px color-mix(in oklab, var(--accent) 34%, transparent);
}
.hero-word{ display:flex; flex-direction:column; line-height:1.25; }
.hw-name{ font-size:16px; font-weight:800; letter-spacing:.16em; }
.hw-sub{ font-size:10.5px; color:var(--muted); letter-spacing:.14em; }
.hero-eyebrow{ color:var(--accent); font-size:12px; font-weight:800; letter-spacing:.24em; margin-bottom:14px; }
.hero-title{ font-size:clamp(42px, 6.4vw, 78px); font-weight:800; line-height:1.16; letter-spacing:-.04em; }
.hero-title em{
  font-style:normal; white-space:nowrap;
  background:linear-gradient(135deg, var(--accent), var(--accent-2));
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
.hero-lead{ color:var(--muted); font-size:16px; margin-top:20px; max-width:34ch; }
.hero-feats{ list-style:none; display:flex; flex-wrap:wrap; gap:10px; margin-top:30px; padding:0; }
.hero-feats li{
  display:flex; align-items:center; gap:7px;
  padding:8px 14px; border-radius:999px; font-size:13.5px;
  border:1px solid var(--nx-hair); background:var(--nx-glass);
  -webkit-backdrop-filter:var(--nx-blur); backdrop-filter:var(--nx-blur);
}
.hf-ico{ font-size:14px; }

/* --- 右側登入卡:標題改用 h2(h1 讓給左邊的大標語) --- */
.login-card{ position:relative; z-index:1; }
.login-card .lc-head{ margin-bottom:4px; }
.login-card h2{ font-size:24px; font-weight:800; letter-spacing:-.035em; }
.login-card .sub{ text-align:left; color:var(--muted); font-size:13.5px; margin:4px 0 0; }
/* .login-card button 的權重(0,1,1)蓋得過 .auth-tab(0,1,0),沒有這條的話
   兩顆分頁鈕會一起套上送出鈕的漸層底色,看不出目前選的是哪一個。
   同樣的理由見上方 .login-card .linkish。 */
.login-card .auth-tab{ background:transparent; box-shadow:none; }
.login-card .auth-tab.active{
  background:linear-gradient(140deg, var(--accent), var(--accent-2));
  box-shadow:0 6px 16px -8px color-mix(in oklab, var(--accent) 85%, transparent);
}
.login-card .auth-tab:hover{ transform:none; }
/* 瀏覽器自動填入時會強制蓋上自己的底色(深色主題下是一塊灰),改回卡片配色 */
.login-card input:-webkit-autofill,
.login-card input:-webkit-autofill:focus{
  -webkit-text-fill-color:var(--text);
  -webkit-box-shadow:0 0 0 1000px var(--bg-inset) inset;
  caret-color:var(--text);
}

/* --- 窄螢幕:改單欄、品牌區置中縮小 --- */
@media (max-width:960px){
  .login-wrap{ grid-template-columns:minmax(0,1fr); justify-items:center; gap:30px; padding:32px 20px 44px; }
  .login-hero{ text-align:center; max-width:480px; }
  .hero-brand{ justify-content:center; margin-bottom:20px; }
  .hero-title{ font-size:clamp(34px, 9vw, 46px); }
  .hero-lead{ margin-left:auto; margin-right:auto; }
  .hero-feats{ justify-content:center; margin-top:22px; }
  .login-card{ width:min(380px,100%); }
  .lb-grid{
    -webkit-mask-image:radial-gradient(70% 40% at 50% 12%, #000 0%, transparent 100%);
            mask-image:radial-gradient(70% 40% at 50% 12%, #000 0%, transparent 100%);
  }
}
@media (max-width:560px){
  .hero-eyebrow{ font-size:11px; letter-spacing:.18em; }
  .hero-lead{ font-size:14.5px; }
  .login-card{ padding:32px 24px 26px; }
}
@media (prefers-reduced-motion:reduce){
  .lb-blob, .login-hero{ animation:none; }
}

/* ===== 資料夾 PIN 鎖標記 ===== */
.lock-tag{ font-size:12px; vertical-align:middle; opacity:.85; cursor:help; filter:grayscale(.2); }
.lock-tag.on{ opacity:1; filter:none; }     /* 本次已解鎖:顯示 🔓,不做灰化 */
.grid-name .lock-tag{ font-size:11px; }
