/* =====================================================================
   金华山 GEO · 应用外壳（v1.6）
   左右分栏：左侧功能栏固定，右侧内容区随功能切换。
   与 app.css 分工：app.css 管「组件」（按钮/表格/弹窗…），
                     本文件管「骨架」（侧栏/顶栏/内容区/登录页）。
   ===================================================================== */

/* ---------------------------------------------------------------
   一、外壳骨架
   --------------------------------------------------------------- */
.shell{display:flex; min-height:100vh; background:var(--bg)}

/* 左侧功能栏 —— 固定宽度，内容独立滚动 */
.side{
  flex:0 0 var(--side-w, 238px); width:var(--side-w, 238px);
  background:#fff; border-right:1px solid var(--line);
  display:flex; flex-direction:column;
  position:sticky; top:0; height:100vh;
}
.side-scroll{flex:1; overflow-y:auto; padding:14px 12px 8px}

/* 品牌区 */
.sbrand{display:flex; align-items:center; gap:10px; padding:16px 16px 14px; border-bottom:1px solid var(--line)}
.sbrand .logo{
  flex:0 0 auto; width:34px; height:34px; border-radius:10px;
  background:linear-gradient(135deg,var(--brand),var(--brand2));
  color:#fff; display:flex; align-items:center; justify-content:center;
  font-weight:700; font-size:15px; letter-spacing:.5px;
}
.sbrand .bt{min-width:0}
.sbrand .bt b{display:block; font-size:13.5px; font-weight:700; letter-spacing:.2px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.sbrand .bt span{display:block; font-size:11px; color:var(--ink3); margin-top:1px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}

/* 分组标题 */
.sgrp{font-size:11px; color:var(--ink3); font-weight:600; letter-spacing:.6px;
  padding:14px 10px 6px}

/* 导航项 */
.snav{display:flex; flex-direction:column; gap:2px}
.snav button{
  display:flex; align-items:center; gap:10px;
  padding:9px 10px; border-radius:9px; color:var(--ink2); text-decoration:none;
  font-size:13.5px; cursor:pointer; border:none; background:transparent; width:100%;
  text-align:left; font-family:inherit; transition:background .12s, color .12s;
}
.snav button:hover{background:#F1F5F9; color:var(--ink)}
.snav button.on{background:#EAF2FC; color:var(--brand2); font-weight:600}
.snav button .ic{flex:0 0 auto; width:18px; height:18px; display:flex; align-items:center; justify-content:center;
  opacity:.85}
.snav button .ic svg{width:16px; height:16px; display:block}
.snav button.on .ic{opacity:1}
.snav button .tx{flex:1; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.snav button .bdg{flex:0 0 auto; font-size:10.5px; padding:0 6px; border-radius:999px;
  background:#E2E8F0; color:var(--ink2)}
.snav button.on .bdg{background:var(--brand2); color:#fff}
.snav button.lock{opacity:.45; cursor:not-allowed}

/* ⚠ 图标与文字都是**装饰层**，不参与点击。
   否则点击会落在 <span>/<svg> 上，拿不到按钮上的 data-* 属性。
   JS 侧已统一用 closest()，这里再加一道：双保险，成本为零。 */
.snav button > .ic,
.snav button > .tx,
.snav button > .bdg{pointer-events:none}

/* 侧栏底部：当前用户
   v1.6.2：账号区给出**看得见的**「管理」与「退出」两个按钮。
   原来只有一个 15px 的图标，学生根本看不出那儿能点。 */
.sfoot{border-top:1px solid var(--line); padding:10px 12px}
.suser{display:flex; flex-wrap:wrap; align-items:center; gap:9px; padding:7px 8px; border-radius:9px}
.suser:hover{background:#F8FAFC}
.suser .av{flex:0 0 auto; width:30px; height:30px; border-radius:50%;
  background:#EAF2FC; color:var(--brand2); display:flex; align-items:center; justify-content:center;
  font-size:12.5px; font-weight:700}
.suser .ut{flex:1; min-width:0}
.suser .ut b{display:block; font-size:12.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.suser .ut span{display:block; font-size:11px; color:var(--ink3)}
/* 按钮行：占满整行、贴到第二行去，窄侧栏也放得下 */
.suser .sac{flex:1 0 100%; display:flex; gap:6px; margin-top:7px}
.suser .sac button{
  flex:1; display:inline-flex; align-items:center; justify-content:center; gap:5px;
  border:1px solid var(--line); background:#fff; color:var(--ink2); cursor:pointer;
  font-size:11.5px; padding:5px 8px; border-radius:7px; line-height:1; white-space:nowrap;
}
.suser .sac button:hover{background:#F1F5F9}
.suser .sac button:disabled{opacity:.5; cursor:default}
.suser .sac .out:hover{background:#FEE2E2; border-color:#FECACA; color:var(--danger)}
.suser .sac .acct:hover{background:#EFF6FF; border-color:#BFDBFE; color:var(--brand2)}
/* 图标是装饰层，不参与点击（点它也要能触发按钮） */
.suser .sac button svg{width:14px; height:14px; pointer-events:none}

/* 右侧主区 */
.main{flex:1; min-width:0; display:flex; flex-direction:column}

/* 顶栏 */
.mainbar{
  position:sticky; top:0; z-index:20;
  display:flex; align-items:center; gap:12px;
  padding:12px 22px; background:rgba(255,255,255,.92);
  border-bottom:1px solid var(--line); backdrop-filter:blur(8px);
}
.mainbar .burger{
  display:none; border:1px solid var(--line2); background:#fff; border-radius:9px;
  padding:6px; cursor:pointer; color:var(--ink2)
}
.mainbar .burger svg{width:16px; height:16px; display:block}
.mainbar h1{font-size:16px; font-weight:700}
.mainbar .crumb{font-size:12px; color:var(--ink3); margin-top:1px}
.mainbar .spacer{flex:1}
.chip{display:inline-flex; align-items:center; gap:6px; font-size:12px; color:var(--ink2);
  background:#F1F5F9; border:1px solid var(--line); border-radius:999px; padding:4px 11px}
.chip b{color:var(--ink); font-weight:600}
.chip.gold{background:#FFFBEB; border-color:#FDE68A; color:#92400E}
.chip.gold b{color:#92400E}

/* 内容区 */
.mainbody{flex:1; padding:18px 22px 64px; max-width:1320px; width:100%}
.pagehead{margin-bottom:14px}
.pagehead h2{font-size:17px; font-weight:700}
.pagehead p{font-size:12.5px; color:var(--ink2); margin:5px 0 0}

/* 切换面板时的「我确实切过来了」反馈。
   很短（180ms），目的只是消除「点了没反应」的错觉 —— 特别是那些
   内容很空的面板，切换前后看起来几乎一样。 */
@keyframes wbReveal{from{opacity:0; transform:translateY(5px)} to{opacity:1; transform:none}}
.mainbody > section.reveal{animation:wbReveal .18s ease-out both}
@media (prefers-reduced-motion:reduce){ .mainbody > section.reveal{animation:none} }

/* 移动端：侧栏改为抽屉 */
.scrim{display:none; position:fixed; inset:0; background:rgba(15,23,42,.45); z-index:70}
@media (max-width:900px){
  .side{position:fixed; left:0; top:0; z-index:80; transform:translateX(-100%);
    transition:transform .22s ease; box-shadow:0 0 40px rgba(16,24,40,.2)}
  .side.open{transform:none}
  .scrim.on{display:block}
  .mainbar .burger{display:flex}
  .mainbar{padding:10px 14px}
  .mainbody{padding:14px 14px 80px}
}

/* ---------------------------------------------------------------
   二、工作台首页（总览）
   --------------------------------------------------------------- */
.hero{
  background:linear-gradient(120deg,#123C6E 0%,#1D5FA8 62%,#2E7BC4 100%);
  color:#fff; border-radius:var(--r); padding:22px 26px; margin-bottom:14px;
  display:flex; align-items:center; gap:20px; overflow:hidden; position:relative;
  box-shadow:0 6px 20px rgba(18,60,110,.18);
}
.hero::after{
  content:""; position:absolute; right:-40px; top:-60px; width:220px; height:220px;
  border-radius:50%; background:rgba(255,255,255,.07);
}
.hero::before{
  content:""; position:absolute; right:70px; bottom:-80px; width:160px; height:160px;
  border-radius:50%; background:rgba(255,255,255,.05);
}
.hero .av{flex:0 0 auto; width:54px; height:54px; border-radius:50%;
  background:rgba(255,255,255,.18); border:1px solid rgba(255,255,255,.3);
  display:flex; align-items:center; justify-content:center; font-size:19px; font-weight:700}
.hero .ht{flex:1; min-width:0; position:relative; z-index:1}
.hero .ht h3{font-size:19px; font-weight:700; margin-bottom:5px}
.hero .ht p{font-size:12.5px; color:#C7DBF3; margin:0}
.hero .ha{flex:0 0 auto; position:relative; z-index:1; display:flex; gap:8px; flex-wrap:wrap}
.hero .ha .btn{background:rgba(255,255,255,.14); border-color:rgba(255,255,255,.3); color:#fff}
.hero .ha .btn:hover{background:rgba(255,255,255,.24)}
.hero .ha .btn.primary{background:#fff; border-color:#fff; color:var(--brand)}

/* 指标卡（带图标与说明） */
.kpis{display:grid; grid-template-columns:repeat(auto-fill,minmax(190px,1fr)); gap:12px; margin-bottom:14px}
.kpi{background:#fff; border:1px solid var(--line); border-radius:var(--r); padding:14px 16px;
  box-shadow:var(--sh); display:flex; align-items:flex-start; gap:12px}
.kpi .ki{flex:0 0 auto; width:38px; height:38px; border-radius:10px; display:flex;
  align-items:center; justify-content:center; background:#EAF2FC; color:var(--brand2)}
.kpi .ki svg{width:18px; height:18px}
.kpi.ok .ki{background:var(--okbg); color:var(--ok)}
.kpi.warn .ki{background:var(--warnbg); color:var(--warn)}
.kpi.err .ki{background:var(--dangerbg); color:var(--danger)}
.kpi .kb{flex:1; min-width:0}
.kpi .kb .k{font-size:11.5px; color:var(--ink3)}
.kpi .kb .v{font-size:23px; font-weight:700; line-height:1.25; font-variant-numeric:tabular-nums}
.kpi .kb .d{font-size:11.5px; color:var(--ink3); margin-top:1px}

/* 两栏内容（左宽右窄） */
.cols{display:grid; grid-template-columns:minmax(0,2fr) minmax(260px,1fr); gap:14px; align-items:start}
@media (max-width:1100px){ .cols{grid-template-columns:1fr} }

/* 侧栏里的小卡片（欢迎/进度） */
.minicard{background:#fff; border:1px solid var(--line); border-radius:var(--r);
  box-shadow:var(--sh); margin-bottom:14px; overflow:hidden}
.minicard .hd{padding:12px 16px; border-bottom:1px solid var(--line); font-size:13.5px; font-weight:700;
  display:flex; align-items:center; gap:8px}
.minicard .bd{padding:14px 16px}
.kv{display:flex; justify-content:space-between; gap:10px; font-size:12.5px; padding:6px 0;
  border-bottom:1px dashed var(--line)}
.kv:last-child{border-bottom:none}
.kv .k{color:var(--ink3)}
.kv .v{font-weight:600; font-variant-numeric:tabular-nums}

/* 快捷入口网格 */
.quick{display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:10px}
.quick button{
  font:inherit; text-align:left; cursor:pointer; background:#fff;
  border:1px solid var(--line); border-radius:10px; padding:12px 13px; color:var(--ink);
  transition:border-color .12s, box-shadow .12s, transform .12s;
}
.quick button:hover{border-color:#B9CDE6; box-shadow:0 3px 10px rgba(16,24,40,.07)}
.quick button .qt{font-size:13px; font-weight:600; display:flex; align-items:center; gap:7px}
.quick button .qt svg{width:15px; height:15px; color:var(--brand2)}
.quick button .qd{font-size:11.5px; color:var(--ink3); margin-top:3px}

/* 步骤条（初始化引导用） */
.steps-bar{display:flex; gap:0; margin:4px 0 16px; flex-wrap:wrap}
.steps-bar .sb{display:flex; align-items:center; gap:8px; font-size:12.5px; color:var(--ink3)}
.steps-bar .sb i{width:22px; height:22px; border-radius:50%; background:#E2E8F0; color:var(--ink2);
  display:flex; align-items:center; justify-content:center; font-style:normal; font-size:11.5px; font-weight:700}
.steps-bar .sb.on{color:var(--brand2); font-weight:600}
.steps-bar .sb.on i{background:var(--brand2); color:#fff}
.steps-bar .sep{flex:0 0 26px; height:1px; background:var(--line2); margin:0 10px; align-self:center}

/* ---------------------------------------------------------------
   三、登录页
   --------------------------------------------------------------- */
.login-wrap{min-height:100vh; display:grid; grid-template-columns:1.05fr .95fr}
.login-brand{
  background:linear-gradient(150deg,#0E2E56 0%,#123C6E 40%,#1D5FA8 100%);
  color:#fff; padding:54px 52px; display:flex; flex-direction:column; justify-content:space-between;
  position:relative; overflow:hidden;
}
.login-brand::after{content:""; position:absolute; right:-90px; bottom:-120px; width:360px; height:360px;
  border-radius:50%; background:rgba(255,255,255,.06)}
.login-brand::before{content:""; position:absolute; left:-70px; top:-90px; width:260px; height:260px;
  border-radius:50%; background:rgba(255,255,255,.05)}
.login-brand .lb-top{position:relative; z-index:1}
.login-brand .lb-logo{display:flex; align-items:center; gap:12px; margin-bottom:38px}
.login-brand .lb-logo .lg{width:42px; height:42px; border-radius:12px; background:rgba(255,255,255,.16);
  border:1px solid rgba(255,255,255,.28); display:flex; align-items:center; justify-content:center;
  font-size:18px; font-weight:700}
.login-brand .lb-logo b{font-size:16px; letter-spacing:.3px}
.login-brand h2{font-size:28px; line-height:1.35; font-weight:700; margin-bottom:14px}
.login-brand .lead{font-size:13.5px; color:#BFD5EE; line-height:1.9; max-width:430px}
.login-brand .lb-feat{position:relative; z-index:1; display:flex; flex-direction:column; gap:11px; margin-top:34px}
.login-brand .lb-feat .f{display:flex; gap:10px; align-items:flex-start; font-size:13px; color:#D6E5F5}
.login-brand .lb-feat .f svg{flex:0 0 auto; width:16px; height:16px; margin-top:2px; color:#7FB2E8}
.login-brand .lb-foot{position:relative; z-index:1; font-size:12px; color:#8FB0D0}

.login-panel{background:var(--bg); display:flex; align-items:center; justify-content:center; padding:40px 24px}
.login-card{width:100%; max-width:420px; background:#fff; border:1px solid var(--line);
  border-radius:16px; box-shadow:0 10px 40px rgba(16,24,40,.09); padding:28px 28px 24px}
.login-card > h3{font-size:19px; font-weight:700}
.login-card > .sub{font-size:12.5px; color:var(--ink3); margin:6px 0 18px}

/* 身份切换：两个大按钮，比 tab 更明确 */
.rolepick{display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-bottom:20px}
.rolepick button{
  font:inherit; cursor:pointer; background:#fff; border:1.5px solid var(--line); border-radius:12px;
  padding:14px 12px; text-align:left; color:var(--ink); transition:all .14s;
}
.rolepick button:hover{border-color:#B9CDE6; background:#FBFDFF}
.rolepick button.on{border-color:var(--brand2); background:#F4F9FF; box-shadow:0 0 0 3px rgba(29,95,168,.1)}
.rolepick button .ri{width:32px; height:32px; border-radius:9px; background:#EFF4FA; color:var(--brand2);
  display:flex; align-items:center; justify-content:center; margin-bottom:8px}
.rolepick button.on .ri{background:var(--brand2); color:#fff}
.rolepick button .ri svg{width:17px; height:17px}
.rolepick button b{display:block; font-size:13.5px}
.rolepick button span{display:block; font-size:11.5px; color:var(--ink3); margin-top:2px}

.lfield{margin-bottom:13px}
.lfield label{display:block; font-size:12.5px; color:var(--ink2); font-weight:600; margin-bottom:6px}
.lfield input{width:100%; font:inherit; padding:11px 13px; border:1px solid var(--line2);
  border-radius:10px; outline:none; color:var(--ink); background:#fff}
.lfield input:focus{border-color:var(--brand2); box-shadow:0 0 0 3px rgba(29,95,168,.12)}
.login-card .btn.wide{width:100%; justify-content:center; padding:11px 16px; font-size:14px; margin-top:6px}
.login-note{font-size:11.5px; color:var(--ink3); line-height:1.8; margin-top:16px;
  background:#F8FAFC; border:1px solid var(--line); border-radius:9px; padding:10px 12px}
.login-note b{color:var(--ink2)}
.login-alt{text-align:center; font-size:12.5px; color:var(--ink3); margin-top:16px}
.login-alt a{font-weight:600}
.inputicon{position:relative}
.inputicon svg{position:absolute; left:12px; top:50%; transform:translateY(-50%);
  width:16px; height:16px; color:var(--ink3); pointer-events:none}
.inputicon input{padding-left:36px}

@media (max-width:900px){
  .login-wrap{grid-template-columns:1fr}
  .login-brand{padding:34px 26px 30px}
  .login-brand h2{font-size:22px}
  .login-brand .lb-feat{display:none}
  .login-panel{padding:26px 16px 40px}
}

/* ---------------------------------------------------------------
   四、小工具
   --------------------------------------------------------------- */
.tagline{display:flex; align-items:center; gap:8px; font-size:12px; color:var(--ink3); margin-bottom:10px}
.hr{height:1px; background:var(--line); margin:16px 0; border:none}
.stat-mini{display:inline-flex; align-items:baseline; gap:5px}
.stat-mini b{font-size:17px; font-variant-numeric:tabular-nums}

/* ---------------------------------------------------------------
   五、GEO 可见度指数卡片（工作台总览首屏）
   —— 老师要拿这个界面直接给甲方看，所以"成效那个数"必须一眼看到，
      并且自带口径说明（甲方会问"这分怎么来的"）。
   --------------------------------------------------------------- */
.geocard{display:grid; grid-template-columns:300px 1fr; gap:24px; align-items:center;
  background:linear-gradient(135deg,#1d4ed8,#0f766e); color:#fff;
  border-radius:13px; padding:20px 24px; margin:0 0 14px;
  box-shadow:0 6px 20px rgba(29,78,216,.18)}
.geol .gcap{font-size:12px; letter-spacing:2px; opacity:.86; font-weight:600}
.geol .gcap .small{letter-spacing:0; opacity:.8; margin-left:6px}
.geol .gscore{display:flex; align-items:baseline; gap:8px; margin:5px 0 4px}
.geol .gscore b{font-size:50px; font-weight:800; letter-spacing:-2px; line-height:1}
.geol .gscore span{font-size:14px; opacity:.75}
.gband{display:inline-block; font-size:12.5px; font-weight:700; border-radius:20px; padding:2px 12px;
  background:rgba(255,255,255,.22)}
.gband.b-excellent{background:#fde68a; color:#7c2d12}
.gband.b-good{background:#bbf7d0; color:#14532d}
.gband.b-fair{background:#fef08a; color:#713f12}
.gband.b-weak{background:#fed7aa; color:#7c2d12}
.gband.b-poor{background:#fecaca; color:#7f1d1d}
.geol .gnote{margin:10px 0 0; font-size:12.5px; line-height:1.65; opacity:.92}
.geor .gdelta{font-size:13px; font-weight:650; margin-bottom:8px; opacity:.92}
.geor .gdelta.up{color:#bbf7d0}
.geor .gdelta.down{color:#fecaca}
.geor .gbar{height:11px; background:rgba(255,255,255,.22); border-radius:8px; overflow:hidden}
.geor .gbar i{display:block; height:100%; background:#fff; border-radius:8px; min-width:3px;
  transition:width .4s ease}
.gparts{display:grid; grid-template-columns:repeat(auto-fit,minmax(104px,1fr)); gap:9px; margin-top:14px}
.gparts > div{background:rgba(255,255,255,.14); border-radius:8px; padding:7px 10px}
.gparts span{display:block; font-size:11.5px; opacity:.85}
.gparts b{font-size:16px; font-weight:700; font-variant-numeric:tabular-nums}
.gtrend{display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-top:14px;
  font-size:12px; opacity:.95}
.gtrend .gt{display:inline-flex; align-items:baseline; gap:4px; background:rgba(255,255,255,.14);
  border-radius:7px; padding:3px 9px}
.gtrend .gt b{font-size:15px; font-weight:700}
.gtrend .gt em{font-style:normal; opacity:.7; font-size:10.5px}
.gtrend .gt-ar{opacity:.6; font-style:normal}
.gfoot{margin-top:12px; font-size:10.8px; line-height:1.65; opacity:.72; word-break:break-all}
@media (max-width:860px){
  .geocard{grid-template-columns:1fr; gap:16px}
  .geol .gscore b{font-size:42px}
}
